Try using spy - this helps to understand the reasoning.
?- (define do-calculation { arith-expr --> arith-expr }
[X + Y] -> (+ (do-calculation X) (do-calculation Y))
[X - Y] -> (- (do-calculation X) (do-calculation Y))
[X * Y] -> (* (do-calculation X) (do-calculation Y))
[X / Y] -> (/ (do-calculation X) (do-calculation Y))
X -> X) : Var2
The first steps establish the integrity condition - that the structure of the input conforms to the type definition for arith-exprs.
____________________________________________________________ 24 inferences
?- [&&X + &&Y] : arith-expr
1. &&X : Var10
2. &&Y : Var13
3. do-calculation : (arith-expr --> arith-expr)
>
____________________________________________________________ 43 inferences
?- [&&X + &&Y] : number
1. &&X : Var10
2. &&Y : Var13
3. do-calculation : (arith-expr --> arith-expr)
>
____________________________________________________________ 68 inferences
?- &&X : arith-expr
1. &&X : Var10
2. &&Y : Var13
3. do-calculation : (arith-expr --> arith-expr)
>
____________________________________________________________ 75 inferences
?- &&Y : arith-expr
1. &&X : arith-expr
2. &&Y : Var13
3. do-calculation : (arith-expr --> arith-expr)
>
This concludes the integrity test; so far so good. Shen now tries to prove that the result has the expected type assuming that the input(s) conform(s) to the type(s) allotted to them.
____________________________________________________________ 86 inferences
?- ((+ (do-calculation &&X)) (do-calculation &&Y)) : arith-expr
1. [&&X + &&Y] : arith-expr
2. do-calculation : (arith-expr --> arith-expr)
This first attempt fails because + does not output arith-expr.
>____________________________________________________________ 95 inferences
?- (+ (do-calculation &&X)) : (Var46 --> arith-expr)
1. [&&X + &&Y] : arith-expr
2. do-calculation : (arith-expr --> arith-expr)
>
____________________________________________________________ 104 inferences
?- + : (Var48 --> (Var46 --> arith-expr))
1. [&&X + &&Y] : arith-expr
2. do-calculation : (arith-expr --> arith-expr)
>
____________________________________________________________ 122 inferences
?- + : (Var48 --> (Var46 --> arith-expr))
1. &&X : arith-expr
2. &&Y : arith-expr
3. do-calculation : (arith-expr --> arith-expr)
>
____________________________________________________________ 156 inferences
?- (+ (do-calculation &&X)) : (Var46 --> arith-expr)
1. &&X : arith-expr
2. &&Y : arith-expr
3. do-calculation : (arith-expr --> arith-expr)
>
____________________________________________________________ 167 inferences
?- + : (Var92 --> (Var46 --> arith-expr))
1. &&X : arith-expr
2. &&Y : arith-expr
3. do-calculation : (arith-expr --> arith-expr)
>
At this point Shen gives up and tries the first rule that you cite. Prove that an arith-expr is delivered because a number is delivered.
____________________________________________________________ 211 inferences
?- ((+ (do-calculation &&X)) (do-calculation &&Y)) : number
1. [&&X + &&Y] : arith-expr
2. do-calculation : (arith-expr --> arith-expr)
>
____________________________________________________________ 221 inferences
?- (+ (do-calculation &&X)) : (Var136 --> number)
1. [&&X + &&Y] : arith-expr
2. do-calculation : (arith-expr --> arith-expr)
>
____________________________________________________________ 230 inferences
?- + : (Var138 --> (Var136 --> number))
1. [&&X + &&Y] : arith-expr
2. do-calculation : (arith-expr --> arith-expr)
>
Going well; but now we hit the snag - we have to show do-calculation itself produces a number. Shen cannot prove that because do-calculation produces an arith-expr. The type checker wanders fruitlessly trying different ways to prove that conclusion before exhausting all possibilities.
____________________________________________________________ 233 inferences
?- (do-calculation &&X) : number
1. [&&X + &&Y] : arith-expr
2. do-calculation : (arith-expr --> arith-expr)
>
____________________________________________________________ 243 inferences
?- do-calculation : (Var141 --> number)
1. [&&X + &&Y] : arith-expr
2. do-calculation : (arith-expr --> arith-expr)
>
...............................
type error in rule 1 of do-calculation