lambda-calc-example.k 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. \l lambda-calculus.k
  2. para"lambda expression:"
  3. para s:"(^x.x y x y)z z (^y.z z)"
  4. para""
  5. para"parsed into a tree"
  6. :p:prs[s]
  7. para""
  8. para"displayed in a friendly way"
  9. dsp[s;p]
  10. para""
  11. para"pruned of excess nodes"
  12. :(n;p):alpha/prn[s]
  13. dsp[n;p]
  14. para""
  15. para" .. as a table"
  16. tbl[n;,p]
  17. para""
  18. para"table showing where parens are"
  19. tbl[n;(p;"("=n)]
  20. para""
  21. para"different table showing where parens are"
  22. tblb[n;"("=n]
  23. para""
  24. para"table showing where z's are in last lambda"
  25. tblmb[n;(m;("z"=n)*m:p=*|&"^"=n)]
  26. para""
  27. para"beta reduced"
  28. :(n;p):beta/prn[s]
  29. dsp[n;p]
  30. para""
  31. para"beta reduced (using currying)"
  32. dsp/beta/prn s
  33. para""
  34. para"alpha conversion"
  35. :(n;p):prn \"((^x.xxx)(^x.xxx))"
  36. alpha[n;p]
  37. para""
  38. para"add back in closing parentheses"
  39. dspf[n;p]
  40. para""
  41. para"actually two trees"
  42. para" node at index 8 is its own parent and thus a root"
  43. tbl[s;,prs \s:"(^x.xxx)(^x.xxx)"]
  44. para""
  45. para"remove redundant parentheses"
  46. dspf/(n;p):prn "(((^x.(x(x)x))(^x.(xxx))"
  47. dspf/rrp/(n;p)
  48. para""
  49. para"some expressions"
  50. para"zero: ",z:"(^f.^x.x)"
  51. para"successor: ",sc:"(^n.^f.^x.f(nfx))"
  52. para"one!: ",one:sc,z
  53. para""
  54. para"alpha convert, do one reduction"
  55. para" note that beta reduction automatically adds a root node"
  56. dspf/alpha/prn "(",one,")"
  57. dspf/beta/alpha/prn one
  58. para" canonaclize names"
  59. dspf/alpha/beta/alpha/prn one
  60. para""
  61. para"converge..."
  62. dspf/alpha/(beta/alpha/)/prn one
  63. para""
  64. para"more ints"
  65. :i:{"(",y,x,")"}\(,z),5#,sc
  66. para""
  67. para"reduce three showing steps"
  68. para" three applications of a ..."
  69. dspf/'rr:alpha/'(beta/alpha/)\alpha/prn i[3]
  70. para""
  71. \d t
  72. \l trees.k
  73. \d .
  74. para"pictures!"
  75. para" we don't canoncialize here (not needed) for clarity"
  76. rr:beta/\alpha/prn i[3]
  77. shw:{(tr;lb):t.pad[pd]t.t2[pd:|/#'x]y; `0:,/+(tr;t.ctl@x@lb)}
  78. shw/'rr;
  79. para""
  80. para"numerical variables"
  81. loadNumerical[]
  82. :(n;p):prn \"(((^x.(x(x)x))(^x.(xxx))"
  83. dspf/(n;p)
  84. para"translate to characters"
  85. ALPHA@dspf/(n;p)
  86. para""
  87. para"alpha reduction still works"
  88. ALPHA@dspf/alpha/(n;p)
  89. para""
  90. para"beta reduction too"
  91. ALPHA@dspf/beta/alpha/(n;p)
  92. para""
  93. para"Can now do more complicated reductions..."
  94. para""
  95. rt:{x/,'"()"}
  96. T:rt["^x.^y.x"]
  97. F:rt["^x.^y.y"]
  98. A:rt["^p.^q.p q p"]
  99. O:rt["^p.^q.p p q"]
  100. SX:rt["^n.^f.^x. f(nfx)"]
  101. ADD:rt["^m.^n.^f.^x.m f (nfx)"]
  102. MUL:rt["^m.^n.^f.m(nf)"]
  103. ZP:rt["^n.n",rt["^z.",F],T]
  104. TIMES:!0
  105. clrt:{TIMES::!0}
  106. ev:{(r;n):prn rt[x]
  107. dspf/alpha/{beta/alpha[x;y]}//(r;n)}
  108. /dspf/alpha/{c:`t@0;rr:beta/alpha[x;y];TIMES,:-c-`t@0;rr}//(r;n)}
  109. TF:(dspf/alpha/prn@)'(T;F)
  110. para"OR"
  111. +1("TF"TF?/:ev'.:')\("O,",","/,')'"TF"@+!2 2
  112. para""
  113. para"AND"
  114. +1("TF"TF?/:ev'.:')\("A,",","/,')'"TF"@+!2 2
  115. para""
  116. para"numbers"
  117. N0:{rt y,x}\(,F),15#,SX
  118. N:ev'N0
  119. ALPHA@N@!5
  120. para""
  121. para"addition 10~7+3"
  122. ~/(N[10];ev ADD,N0[7],N0[3])
  123. para""
  124. para"multiplication"
  125. N[6]~ev MUL,N0[2],N0[3]
  126. +t,,~'/(,N@(*/)t),,ev'MUL,/:,/'+N0@t:!5 3
  127. para""
  128. para"is zero"
  129. +1("TF"TF?/:ev'ZP,/:N0@)\0 1 3 7
  130. para""
  131. para"predecessor"
  132. PR:rt["^n.n",rt["^g.^k.",ZP,rt["g",N0[1]],"k",rt[SX,"(gk)"]],rt["^v.",N0[0]],N0[0]]
  133. N[2]~ev e: PR,N0[3]
  134. para""
  135. para"predecessor 2"
  136. PR:rt["^x.^y.^f.fxy"]
  137. FST:rt["^p.p",T]
  138. SND:rt["^p.p",F]
  139. SFT:rt["^p.",PR,rt[SX,rt[FST,"p"]],rt[FST,"p"]]
  140. base:rt[PR,N0[0],N0[0]]
  141. PRE:rt["^n.",SND,rt["n",SFT,base]]
  142. ~/(N[13];ev PRE,N0[14])
  143. para""
  144. Y:rt["^f.(^x.f(xx))(^x.f(xx))"]
  145. TH:,/2#,rt["^x.^y.y(xxy)"]
  146. X:rt["^f.(^x.xx)(^x.f(xx))"]
  147. TRI:rt[TH,rt["^a.^n.",ZP,"n",N0[0],rt[ADD,"n",rt["a",rt[PRE,"n"]]]]]
  148. FAC:rt[TH,rt["^a.^n.",ZP,"n",N0[1],rt[MUL,"n",rt["a",rt[PRE,"n"]]]]]
  149. rr:ev \TRI,ALPHA@N[5]
  150. ~/(N[15];rr)
  151. rr:ev \FAC,ALPHA@N[3]
  152. ~/(N[6];rr)