Technically, the compiler could resolve the type of this expression.
But this is not necessarily as easy as that. Complex expressions can in turn rely on other instance variables being fully typed. This could cause loop dependencies and never work. And it’s not trivial to decide whether an expression can be typed without interdependencies or not. Thus the compiler only infers type from very simple expressions and asks you to annotate in all other cases. Even if technically that wasn’t strictly necessary.
Now instance variables are typed in a separate pass before other methods and local variables. So compiler don’t know about String#split and String#to_i return types at the time it is selecting type of @program.
Of course in theory it is possible to solve, but in general this is not too big problem and as a bonus you get readability (ability to easily see types of all instance variables).