In the previous post, the denotational semantics I gave for the lambda calculus could not deal with self application, such as the program (λf.ff)(λg.42)
A straightforward way to solve this problem is to allow cycles by representing all the functions created by the program as a graph of tables. A function value will just contain an index, i.e. it will have the form fun[i] with index i, and the graph will map the index to a table. So we define values as follows. numbersn∈Nvaluesv∈V::=n∣fun[i]graph=N→(V×V)list
Example 1. Let's consider again the program (λf.ff)(λg.42)
- (fun[0],G)∈E[|(λf.ff)|]∅.
So we need to show
(42,G)∈E[|ff|](f:=fun[1])which we have because (fun[1],42)∈fun[1].
- (fun[1],G)∈E[|(λg.42)|]∅.
We need
(42,G)∈E[|42|](f:=fun[1])which is immediate.
- (fun[1],42)∈tab(fun[0]). This is immediate.
Example 2. We shall compute the factorial of 3 using the strict version of the Y combinator, that is, the Z combinator. R≡λv.(xx)vM≡λx.fRZ≡λf.MMF≡λn.ifn=0then1elsen×r(n−1)H≡λr.Ffact≡ZH
- (fun[4],G)∈E[ZH]∅
- (3,6)∈G(4)
- (fun[0],G)∈E[|Z|]∅
- (fun[4],G)∈E[|MM|](f:=fun[1])
- (fun[2],G)∈E[|M|](f:=fun[1])
- (fun[4],G)∈E[|fR|](f:=fun[1],x:=fun[2])
- (fun[3],G)∈E[|R|](f:=fun[1],x:=fun[2])
- (1,G)∈E[|(xx)v|](f:=fun[1],x:=fun[2],v:=0) and (0,1)∈G(4)
- (1,G)∈E[|(xx)v|](f:=fun[1],x:=fun[2],v:=1) and (1,1)∈G(4)
- (2,G)∈E[|(xx)v|](f:=fun[1],x:=fun[2],v:=2) and (2,2)∈G(4)
- (fun[2],fun[4])∈G(2)
- (fun[1],G)∈E[|H|]∅
- (fun[4],G)∈E[|F|](r:=fun[3])
- (1,G)∈E[|ifn=0then1elsen×r(n−1)|](r:=fun[3],n:=0)
- (1,G)∈E[|ifn=0then1elsen×r(n−1)|](r:=fun[3],n:=1)
- (2,G)∈E[|ifn=0then1elsen×r(n−1)|](r:=fun[3],n:=2)
- (6,G)∈E[|ifn=0then1elsen×r(n−1)|](r:=fun[3],n:=3)
The next step is to update the proof of soundness wrt. the big-step semantics. The graphs will make it a bit more challenging. But hopefully they will make it possible to also prove completeness!
No comments:
Post a Comment