• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

A categorical programming language


Commit MetaInfo

修訂dced8f9d1557e94b91e62630f19b29d4c70d0e33 (tree)
時間2022-12-28 12:10:43
作者Corbin <cds@corb...>
CommiterCorbin

Log Message

Rewrite djinn core.

Now we pull apart types first, synthesizing expressions from the pieces.
The results are quite good; with only a few tactics, we are able to
synthesize all of the existing testcases, including the three that used
to fail.

Change Summary

差異

--- a/accept-jelly.py
+++ b/accept-jelly.py
@@ -6,7 +6,7 @@ import sys
66 movelist = sys.argv[-2]
77 jelly = sys.argv[-1]
88 timeout = 5
9-difficulty = 15
9+difficulty = 5
1010
1111 def jellify(expr):
1212 return subprocess.run([jelly], input=expr.encode("utf-8"),
--- a/movelist/cammyo.scm
+++ b/movelist/cammyo.scm
@@ -1,32 +1,12 @@
1-(module cammyo (cammy° normal-form°)
1+(module cammyo (cammy° cammy-prim° cammy-synth°)
22 (import scheme)
3+ (import (chicken pretty-print))
34 (import (mini-kanren))
45
5- ; Require that a Cammy expression is in a basic normal form.
6- (define (normal-form° expr)
7- (fresh (x y)
8- ; NF: disallow (comp id ...) and (comp ... id)
9- (=/= expr `(comp id ,x))
10- (=/= expr `(comp ,x id))
11- ; NF: disallow (comp ... ignore)
12- (=/= expr `(comp ,x ignore))
13- ; NF: disallow (comp left/right (case ...))
14- (=/= expr `(comp left (case ,x ,y)))
15- (=/= expr `(comp right (case ,x ,y)))
16- ; NF: disallow (comp (pair ...) fst/snd)
17- (=/= expr `(comp (pair ,x ,y) fst))
18- (=/= expr `(comp (pair ,x ,y) snd))
19- ; NF: disallow (curry (uncurry ...)) and (uncurry (curry ...))
20- (=/= expr `(curry (uncurry ,x)))
21- (=/= expr `(uncurry (curry ,x)))
22- ))
23-
24- ; Expr <=> Ty × Ty
25- ; Relate a Cammy expression to its input and output types.
26- ; cammy° is functional; expr fixes s and t together.
27- (define (cammy° expr s t)
28- (fresh ()
29- ; (project (expr s t) (begin (pp `(enter ,expr ,s ,t)) succeed))
6+ ; Relate a monomorphic Cammy primitive to its input and output types.
7+ ; This relation is just a table.
8+ ; Expr <-> Ty × Ty
9+ (define (cammy-prim° expr s t)
3010 (conde
3111 ; Boolean algebra
3212 ((== expr 't) (== s '1) (== t '2))
@@ -52,6 +32,20 @@
5232 ((== expr 'f-atan2) (== s '(pair F F)) (== t 'F))
5333 ((== expr 'f-exp) (== s 'F) (== t 'F))
5434 ((== expr 'f-log1p) (== s 'F) (== t '(sum F 1)))
35+ ; NNO
36+ ((== expr 'succ) (== s 'N) (== t 'N))
37+ ((== expr 'zero) (== s '1) (== t 'N))
38+ ((== expr 'n-pred-maybe) (== s 'N) (== t '(sum N 1)))
39+ ((== expr 'n-add) (== s '(pair N N)) (== t 'N))
40+ ))
41+
42+ ; Relate a Cammy expression to its input and output types.
43+ ; cammy° is functional; expr fixes s and t together.
44+ ; Expr <-> Ty × Ty
45+ (define (cammy° expr s t)
46+ (conde
47+ ; Primitives
48+ ((cammy-prim° expr s t))
5549 ; Cartesian Closed Categories
5650 ((fresh (f y z) (== expr `(curry ,f))
5751 (== t `(hom ,y ,z)) (cammy° f `(pair ,s ,y) z)))
@@ -72,24 +66,82 @@
7266 ((fresh (f g s1 s2) (== expr `(case ,f ,g))
7367 (== s `(sum ,s1 ,s2)) (cammy° f s1 t) (cammy° g s2 t)))
7468 ; NNO
75- ((== expr 'succ) (== s 'N) (== t 'N))
76- ((== expr 'zero) (== s '1) (== t 'N))
7769 ((fresh (x f) (== expr `(pr ,x ,f))
7870 (== s 'N) (cammy° x '1 t) (cammy° f t t)))
79- ((== expr 'n-pred-maybe) (== s 'N) (== t '(sum N 1)))
80- ((== expr 'n-add) (== s '(pair N N)) (== t 'N))
8171 ; Free Monoids
8272 ((== expr 'cons) (fresh (l) (== s `(pair ,l ,t)) (== t `(list ,l))))
8373 ((== expr 'nil) (== s '1) (fresh (l) (== t `(list ,l))))
8474 ((fresh (x f l) (== expr `(fold ,x ,f))
8575 (== s `(list ,l)) (cammy° x '1 t) (cammy° f `(pair ,l ,t) t)))
8676 ; Terminal Object
87- ((== expr 'ignore) (== t '1))
77+ ; NB: ignore : X -> 1 but only when X ≠ 1, because otherwise it is the unique
78+ ; arrow, id : 1 -> 1
79+ ((== expr 'ignore) (=/= s '1) (== t '1))
8880 ; Categories
8981 ((== expr 'id) (== s t))
90- ((fresh (f g y) (== expr `(comp ,f ,g))
91- (cammy° f s y) (cammy° g y t)))
92- )
93- ; (project (expr s t) (begin (pp `(exit ,expr ,s ,t)) succeed))
94- ))
82+ ((fresh (f g) (== expr `(comp ,f ,g))
83+ (fresh (y) (cammy° f s y) (cammy° g y t))))
84+ ))
85+
86+ ; Syntactic composition enforcing normal form. This is just a synthesis helper.
87+ ; Cammy × Cammy <-> Cammy
88+ (define (comp-s° f g fg) (=/= f 'id) (=/= g 'id) (== fg `(comp ,f ,g)))
89+
90+ ; Like cammy°, but suitable for type-directed term synthesis. All expressions
91+ ; are normalized, and logical clauses are ordered to try some expert strategies.
92+ ; Cammy <-> Ty × Ty
93+ (define (cammy-synth° expr s t)
94+ ; s, t, u, v are types
95+ ; f, g are Cammy expressions
96+ (fresh (f g u v)
97+ ; (project (expr s t) (begin (pp `(synth? ,expr : ,s -> ,t)) succeed))
98+ (conde
99+ ; Try primitives first.
100+ ((cammy-prim° expr s t))
101+ ; Is it the unique identity arrow?
102+ ((== s t) (== expr 'id))
103+ ; Is it any arrow into 1?
104+ ((== t '1) (=/= s '1) (== expr 'ignore))
105+ ; Is it an NT?
106+ ((== `(pair ,s ,s) t) (== expr 'dup))
107+ ((== s `(pair ,t ,u)) (== expr 'fst))
108+ ((== s `(pair ,u ,t)) (== expr 'snd))
109+ ((== s `(pair ,u ,v)) (== t `(pair ,v ,u)) (== expr 'swap))
110+ ((== s `(pair (hom ,u ,t) ,u)) (== expr 'app))
111+ ((== `(sum ,s ,u) t) (== expr 'left))
112+ ((== `(sum ,u ,s) t) (== expr 'right))
113+ ; Is it a tuple lookup?
114+ ((== s `(pair ,u ,v))
115+ (conde
116+ ((comp-s° 'fst f expr) (cammy-synth° f u t))
117+ ((comp-s° 'snd f expr) (cammy-synth° f v t))))
118+ ; Is it a case analysis?
119+ ((== s `(sum ,u ,v)) (cammy-synth° f u t) (cammy-synth° g v t) (== expr `(case ,f ,g)))
120+ ; Is it a tagging or return value?
121+ ((== t `(sum ,u ,v))
122+ (conde
123+ ((comp-s° f 'left expr) (cammy-synth° f s u))
124+ ((comp-s° f 'right expr) (cammy-synth° f s v))))
125+ ; Is it a graph?
126+ ; NB: Want to disallow (pair id id)
127+ ((== `(pair ,s ,u) t) (=/= f 'id) (cammy-synth° f s u) (== expr `(pair id ,f)))
128+ ((== `(pair ,u ,s) t) (=/= f 'id) (cammy-synth° f s u) (== expr `(pair ,f id)))
129+ ; Is it a curry?
130+ ((== t `(hom ,u ,v)) (cammy-synth° f `(pair ,s ,u) v) (== expr `(curry ,f)))
131+ ; Is it an application?
132+ ((cammy-synth° f s `(hom ,u ,t)) (cammy-synth° g s u) (comp-s° `(pair ,f ,g) 'app expr))
133+ ; Is it a pair-builder?
134+ ((== `(pair ,u ,v) t) (cammy-synth° f s u) (cammy-synth° g s v) (== expr `(pair ,f ,g)))
135+ ; Does it result in a list?
136+ ((== t `(list ,u))
137+ (conde
138+ ((== s '1) (== expr 'nil))
139+ ((== s `(pair ,u (list ,u))) (== expr 'cons))))
140+ ; Is it primitive recursive?
141+ ((== s 'N) (cammy-synth° f '1 t) (=/= g 'id) (cammy-synth° g t t) (== expr `(pr ,f ,g)))
142+ ; Is it a composition?
143+ ; ((comp-s° f g expr) (cammy-synth° f s u) (cammy-synth° g u t))
144+ )
145+ ; (project (expr s t) (begin (pp `(found: ,expr : ,s -> ,t)) succeed))
146+ ))
95147 )
--- a/movelist/movelist.scm
+++ b/movelist/movelist.scm
@@ -5,13 +5,13 @@
55
66 (import (cammyo))
77
8-(define (last xs)
9- (if (null? (cdr xs)) (car xs) (last (cdr xs))))
8+(define (print-each xs)
9+ (if (null? xs) #f
10+ (begin (display (car xs)) (newline) (print-each (cdr xs)))))
1011
1112 (define (djinn x s t)
12- (last (run x (q) (normal-form° q) (cammy° q s t))))
13+ (print-each (run x (q) (cammy-synth° q s t))))
1314
1415 (match (map (lambda (s) (read (open-input-string s)))
1516 (command-line-arguments))
16- [(in out (? number? count)) (begin (display (djinn count in out))
17- (newline))])
17+ [(in out (? number? count)) (djinn count in out)])