ラムダ計算で除算・剰余

sub、iszero、あと再帰でなんとか書けた。

; TRUE := λx y.x
(defvar true
  (lambda (x) (lambda (y) x)))

; FALSE := λx y.y
(defvar false
  (lambda (x) (lambda (y) y)))

; ISZERO := λn.n (λx.false) true
(defvar iszero
  (lambda (n)
    (app n ($ true false) true)))

; PRED := λn f x.n (λg h.h (g f)) (λu.x) (λu.u)
(defvar pred
  (lambda (n)
    (lambda (f)
      (lambda (x)
        (app n
             (lambda (g)
               (lambda (h)
                 ($ h g f)))
             (lambda (u) x)
             (lambda (u) u))))))

; SUB := λm n.n pred m
(defvar sub
  (lambda (m)
    (lambda (n)
      (app n pred m))))

; ISZERO := λn.n TRUE FALSE
(defvar iszero
  (lambda (n)
    (app n ($ true false) true)))

; MOD := λm n.ISZERO (SUB m n)
;                     (ISZERO (SUB n m) zero m)
;                     (MOD (SUB m n) n)
(defvar mod
  (lambda (m)
    (lambda (n)
      (funcall
        (app (app iszero (app sub m n))
             (lambda () (app iszero (app sub n m) zero m))
             (lambda () (app mod (app sub m n) n)))))))

; DIV := λm n.ISZERO (SUB m n)
;                     (ISZERO (SUB n m) one zero)
;                     (SUCC (DIV (SUB m n) n))
(defvar div
  (lambda (m)
    (lambda (n)
      (funcall
        (app (app iszero (app sub m n))
             (lambda () (app iszero (app sub n m) one zero))
             (lambda () (app succ (list div (app sub m n) n))))))))

(time (app mod (cn 40) (cn 11) #'1+ 0))
; 7
; "47 msec"

重っ!

再帰使ってるとこを遅延評価しないと無限ループになっちゃうんでapply使っちゃったんだけど、Grassで遅延評価って…?

MOD := λm n.(λp.p (ISZERO (SUB n m) zero m)
                    (p FALSE MOD (SUB m n) n)) (ISZERO (SUB m n))
DIV := λm n.(λp.p (ISZERO (SUB n m) one zero)
                    (SUCC (p FALSE DIV (SUB m n) n))) (ISZERO (SUB m n))

pに(ISZERO (SUB m n))の結果が入って、pにFALSEとMOD (or DIV)を適用してこれを再帰用の関数にする、という。
FALSEは2引数の関数なら何でもいいんだけど。
こんな感じでいいのかな。


あとPREDをGrassで書くための指針

n f x.n (λg h.h (g f)) (λu.x) (λu.u)

λn f x.n ((λi g h.h (g i)) f) ((λj u.j) x) (λu.u)

こう書けば、中の3つの関数は全部外に出せる。

ググったら

Schemeラムダ計算を解説してるページがあった。
Church numerals and Lambda Calculus
なるほど、>=か…

いかん

DIVは書きかけだった。後で直す。