program / \ binary block / \ dec \ / \ \ integer /\ | n p | | +-----+---------+-----------+-----------------+ | | | | | read assign while assign while | / \ / \ / \ / \ n p 2 <= assign p div > \ / \ / \ / \ / \ /\ p n p * p 2 p 0 / \ / \ / \ 2 p ifelse assign / | \ / \ >= | write p div / \ | | / \ n p | 0 p 2 / \ / \ write assign | / \ 1 n - / \ n p
a. (λx. (x (λy. (y x)))) b. (((λx. x) (λy. y)) (λx. ((x (λy. y)) z))) c. (((λf. (λy. (λz. (((f z) y) z)))) p) x) d. (λx. (x (λy. (y (λz. (z (λw. (((w z) y) x))))))))
a. λx. x y λz. x z ↑ b. (λx. x y) λz. w λw. w z y x ↑ ↑ ↑ ↑ c. x λz. x λw. w z y ↑ ↑ ↑ d. λx. x y λx. y x ↑ ↑
a. (f (λx. x y) λz. g y z) b. (λx. λy. f x y) c. ((λy. g x y) λf. f x) d. (λg. λz. g (f y) z)
a. (λf. f add (f mul (f add 5))) (λg. λx. g x x) => (λg. λx. g x x) add ((λg. λx. g x x) mul ((λg. λx. g x x) add 5)) => (λx. add x x) ((λg. λx. g x x) mul ((λg. λx. g x x) add 5)) => (λx. add x x) ((λx. mul x x) ((λg. λx. g x x) add 5)) => (λx. add x x) ((λx. mul x x) ((λx. add x x) 5)) => (λx. add x x) ((λx. mul x x) (add 5 5)) => (λx. add x x) ((λx. mul x x) 10) => (λx. add x x) (mul 10 10) => (λx. add x x) 100 => add 100 100 => 200 b. (λx. λf. f (f x)) ((λy. (add y 2)) ((λz. (sqr z)) ((λy. (succ y)) 1))) sqr => (λx. λf. f (f x)) ((λy. (add y 2)) ((λz. (sqr z)) (succ 1))) sqr => (λx. λf. f (f x)) ((λy. (add y 2)) ((λz. (sqr z)) 2)) sqr => (λx. λf. f (f x)) ((λy. (add y 2)) (sqr 2)) sqr => (λx. λf. f (f x)) ((λy. (add y 2)) 4) sqr => (λx. λf. f (f x)) (add 4 2) sqr => (λx. λf. f (f x)) 6 sqr => (λf. f (f 6)) sqr => sqr (sqr 6) => sqr 36 => 1296
let x = 5 in let y = (add x 3) in (mul x y) => (λx. (λy. mul x y) (add x 3)) 5 => (λy. mul 5 y) (add 5 3) => (λy. mul 5 y) 8 => mul 5 8 => 40
Rewriting the let to a where:
(mul x y) where (y = add x 3) where x = 5
{x: 17, y:25}
⟦x⟧,s → 17,s ⟦y⟧,s → 25,s ─────────────────────────── ⟦x+y⟧,s → 42,s ⟦6⟧,s → 6,s ────────────────────────────────────── ⟦(x+y)+6⟧,s → 48,s
be,s → be′,s ───────────────────────────────────────────────────────── ⟦if be then ie₁ else ie₂⟧,s → ⟦if be′ then ie₁ else ie₂⟧,s ───────────────────────────────────── ⟦if true then ie₁ else ie₂⟧,s → ie₁,s ────────────────────────────────────── ⟦if false then ie₁ else ie₂⟧,s → ie₂,s
Even though you were required to use SOS, you may be interested in the Natural Semantics way. This works:
be,s ⇒ F ie₂,s ⇒ x ─────────────────────────────── ⟦if be then ie₁ else ie₂⟧,s ⇒ x be,s ⇒ T ie₁,s ⇒ x ─────────────────────────────── ⟦if be then ie₁ else ie₂⟧,s ⇒ x
──────────────────────────────────────────────────────────────────────────── ⟦repeat c until be⟧,i,o,s → ⟦c; if be then skip else repeat c until be⟧,i,o,s ─────────────────────────────────────────────────────────── ⟦swap id₁, id₂⟧,i,o,s → ⟦skip⟧,i,o,s[s(id₂)/id₁][s(id₁)/id₂]
Note that with SOS we use that “expansion” trick, rewriting the code to a larger construct. If using Natural Semantics, we don’t do that! We compute all the down to a value or a new state:
c,i,o,s ⇒ i′,o′,s′ be,s′ ⇒ T ──────────────────────────────────── ⟦repeat c until be⟧,i,o,s ⇒ i′,o′,s′ c,i,o,s ⇒ i′,o′,s′ be,s′ ⇒ F ⟦repeat c until be⟧,i′,o′,s′ ⇒ i″,o″,s″ ───────────────────────────────────────────────────────────────────────── ⟦repeat c until be⟧,i,o,s ⇒ i″,o″,s″ ──────────────────────────────────────────────────── ⟦swap id₁, id₂⟧,i,o,s ⇒ i,o,s[s(id₂)/id₁][s(id₁)/id₂]
ie₁,s → ie₁′,s ───────────────────────────────────────────────────────────────────── ⟦for id := ie₁ to ie₂ do c⟧,i,o,s → ⟦for id := ie₁′ to ie₂ do c⟧,i,o,s ie₂,s → ie₂′,s ───────────────────────────────────────────────────────────────── ⟦for id := n to ie₂ do c⟧,i,o,s → ⟦for id := n to ie₂′ do c⟧,i,o,s n1 > n2 ───────────────────────────────────────────── ⟦for id := n1 to n2 do c⟧,i,o,s → ⟦skip⟧,i,o,s n1 <= n2 ────────────────────────────────────────────────────────────────────────────── ⟦for id := n1 to n2 do c⟧,i,o,s → ⟦c; for id := (n1+1) to n2 do c⟧,i,o,s[n1/id]
If using Natural Semantics:
ie₁,s ⇒ x ie₂,s ⇒ y x > y
─────────────────────────────────────────
⟦for id := ie₁ to ie₂ do c⟧,i,o,s ⇒ i,o,s
ie₁,s ⇒ x ie₂,s ⇒ y x >= y
(c[j/id],ij,oj,sj ⇒ ij+1,oj+1,sj+1)y
j=x
───────────────────────────────────────────────────
⟦for id := ie₁ to ie₂ do c⟧,ix,ox,sx ⇒ iy+1,oy+1,sy+1