Exercise 4.7 We use the notation m[n↦a], where m is a sequence, to mean a sequence which is the same as m, except that the n:th element is a. ⟨GET-n:c, e, m⟩ ⊳ ⟨c, m[N⟦n⟧]:e, m⟩ if k ≥ N⟦n⟧ > 0 where k is the size of m. ⟨PUT-n:c, z:e, m⟩ ⊳ ⟨c, e, m[N⟦n⟧↦z]⟩ if z∈Z and k ≥ N⟦n⟧ > 0 where k is the size of m. Note that we can not use the n directly, as they are numerals – not numbers. A conversion to numbers using the semantic function N is necessary. All the other rules are the same as those of table 4.1, except that s is replaced by m (except the rules for FETCH-x and STORE-x which are dropped.) The side conditions are needed to ensure that we will not access/update at an address which is outside of memory. If we attempt to, then no rule will be applicable and execution is stuck. Without the side conditions the effect of the rules would be undefined instead. This could of course be taken to mean that no transition is possible, but it is better to be explicit. Exercise 4.8 Note that we can't remove the current instruction after each execution step, as we may need it later if we jump backwards. Thus generally the instruction to be executed will not be the first one and the "program counter" is needed to keep track of the current instruction. ⟨pc, c, e, m⟩ ⊳ ⟨pc+1, c, e, m⟩ if c[pc] = LABEL-l ⟨pc, c, e, m⟩ ⊳ ⟨pc', c, e, m⟩ if c[pc] = JUMP-l and c[pc'] = LABEL-l ⟨pc, c, ff:e, m⟩ ⊳ ⟨pc', c, e, m⟩ if c[pc] = JUMPFALSE-l and c[pc'] = LABEL-l ⟨pc, c, tt:e, m⟩ ⊳ ⟨pc+1, c, e, m⟩ if c[pc] = JUMPFALSE-l All existing rules need to be modified (except the rules for BRANCH and LOOP which are dropped). The modification is done in the same way for each rule. I'll show the rule for NOOP as an example. Compare with the rule in table 4.1! ⟨pc, c, e, m⟩ ⊳ ⟨pc+1, c, e, m⟩ if c[pc] = NOOP If the same label is defined multiple times, then it will be undetermined which location is chosen in a jump to that label. The machine becomes non- deterministic. Exercise 4.9 This is actually a simplification compared to exercise 4.8. The label rule is dropped and the jump rules become: ⟨pc, c, e, m⟩ ⊳ ⟨N⟦l⟧, c, e, m⟩ if c[pc] = JUMP-l and k ≥ N⟦l⟧ > 0 where k is the size of c. ⟨pc, c, ff:e, m⟩ ⊳ ⟨N⟦l⟧, c, e, m⟩ if c[pc] = JUMPFALSE-l and k ≥ N⟦l⟧ > 0 where k is the size of c. ⟨pc, c, tt:e, m⟩ ⊳ ⟨pc+1, c, e, m⟩ if c[pc] = JUMPFALSE-l The side conditions are needed to ensure that we will not jump to an address which is outside of the code. If we attempt to, then no rule will be applicable and execution is stuck. Without the side conditions the effect of the rules would be undefined instead. This could of course be taken to mean that no transition is possible, but it is better to be explicit.