LMU ☀️ CMSI 585
PROGRAMMING LANGUAGE FOUNDATIONS
HOMEWORK #3 PARTIAL ANSWERS
  1. Answers are at this repl.
  2. (1.4.3)
                   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
    
  3. (5.1.1)
    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))))))))
    
  4. (5.1.2)
    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
              ↑     ↑
    
  5. (5.1.3)
    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)
    
  6. (5.2.3)
    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
    
  7. (5.2.7a)
    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
  8. (8.5.1) Let s = {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
    
  9. (8.5.9) For this one you were required to use SOS. Here it is using the notation from the text:
                          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
    
  10. (8.6.3 a, c) If using SOS:
    
    ────────────────────────────────────────────────────────────────────────────
    ⟦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₂]
    
  11. (8.6.6) If using SOS:
                                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