• R/O
  • HTTP
  • SSH
  • HTTPS

提交

标签
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-cqtcocoa誰得pythonphprubygameguibathyscaphec翻訳計画中(planning stage)omegatframeworktwittertestdomvb.netdirectxbtronarduinopreviewerゲームエンジン

A categorical programming language


Commit MetaInfo

修订版04c4c704ea2d187daa492eb53b1848319ab619ac (tree)
时间2022-03-08 18:45:59
作者Corbin <cds@corb...>
CommiterCorbin

Log Message

Finish cleanup of type extractor.

更改概述

差异

--- a/cammy-rpy/cammylib/sexp.py
+++ b/cammy-rpy/cammylib/sexp.py
@@ -39,6 +39,9 @@ class Atom(SExp):
3939 def occurs(self, index):
4040 return False
4141
42+ def extractType(self, extractor):
43+ return self.symbol
44+
4245 def buildArrow(self):
4346 return buildUnary(self.symbol)
4447
@@ -74,6 +77,19 @@ class Functor(SExp):
7477 return True
7578 return False
7679
80+ def extractType(self, extractor):
81+ args = [extractor.extract(unhole(arg)) for arg in self.arguments]
82+ if self.constructor == "hom":
83+ return "[%s, %s]" % (args[0], args[1])
84+ elif self.constructor == "pair":
85+ return "(%s x %s)" % (args[0], args[1])
86+ elif self.constructor == "sum":
87+ return "(%s + %s)" % (args[0], args[1])
88+ elif self.constructor == "list":
89+ return "[%s]" % args[0]
90+ else:
91+ assert False, "whoops"
92+
7793 def buildArrow(self):
7894 args = [arg.buildArrow() for arg in self.arguments]
7995 return buildCompound(self.constructor, args)
@@ -99,5 +115,12 @@ class Hole(SExp):
99115 def occurs(self, index):
100116 return self.index == index
101117
118+ def extractType(self, extractor):
119+ return extractor.findTypeAlias(self.index)
120+
102121 def buildArrow(self):
103122 return Given(self.index)
123+
124+def unhole(sexp):
125+ assert isinstance(sexp, Hole), "implementation error"
126+ return sexp.index
--- a/cammy-rpy/cammylib/types.py
+++ b/cammy-rpy/cammylib/types.py
@@ -1,4 +1,4 @@
1-from cammylib.sexp import Atom, Functor, Hole
1+from cammylib.sexp import Atom, Functor, Hole, unhole
22
33 class UnificationFailed(Exception):
44 def __init__(self, message):
@@ -10,10 +10,6 @@ def occursCheck(index, var):
1010 raise UnificationFailed("Occurs check: %d in %s" %
1111 (index, var.asStr()))
1212
13-def unhole(sexp):
14- assert isinstance(sexp, Hole), "implementation error"
15- return sexp.index
16-
1713 class ConstraintStore(object):
1814 "A Kanren-style constraint store."
1915
@@ -87,37 +83,27 @@ class ConstraintStore(object):
8783 LETTERS = "XYZWSTPQ"
8884
8985 class TypeExtractor(object):
90- def __init__(self):
86+ def __init__(self, cs):
87+ self.cs = cs
9188 self.d = {}
89+ self.seen = []
9290
9391 def addTypeAlias(self, index):
9492 self.d[index] = LETTERS[len(self.d)]
9593
96- def extractType(self, cs, var):
97- return self.go(cs, var, [])
98-
99- def go(self, cs, var, seen):
100- sexp = cs.walk(var)
101- if isinstance(sexp, Hole):
102- if sexp.index not in self.d:
103- self.addTypeAlias(sexp.index)
104- return self.d[sexp.index]
105- elif isinstance(sexp, Atom):
106- return sexp.symbol
107- elif isinstance(sexp, Functor):
108- if var in seen:
109- # XXX split exceptions?
110- raise UnificationFailed("tried to extract infinite type")
111- args = [self.go(cs, unhole(arg), seen + [var]) for arg in sexp.arguments]
112- if sexp.constructor == "hom":
113- return "[%s, %s]" % (args[0], args[1])
114- elif sexp.constructor == "pair":
115- return "(%s x %s)" % (args[0], args[1])
116- elif sexp.constructor == "sum":
117- return "(%s + %s)" % (args[0], args[1])
118- elif sexp.constructor == "list":
119- return "[%s]" % args[0]
120- else:
121- assert False, "whoops"
122- else:
123- assert False, "not whoops"
94+ def findTypeAlias(self, index):
95+ if index not in self.d:
96+ self.addTypeAlias(index)
97+ return self.d[index]
98+
99+ def extract(self, var):
100+ if var in self.seen:
101+ # XXX split exceptions?
102+ raise UnificationFailed("tried to extract infinite type")
103+ self.seen.append(var)
104+
105+ sexp = self.cs.walk(var)
106+ rv = sexp.extractType(self)
107+
108+ self.seen.pop()
109+ return rv
--- a/cammy-rpy/repl.py
+++ b/cammy-rpy/repl.py
@@ -16,6 +16,7 @@ def command(hive, code, line):
1616 # XXX code e: Edit a file
1717 # os.system("$EDITOR")
1818 if code == "!":
19+ # Evaluate an element.
1920 sexp, trail = parse(line)
2021 sexp = sexp.canonicalize(hive)
2122 sexp = jellify(sexp)
@@ -50,12 +51,12 @@ def repl(hive, stdin, stdout):
5051 print "Arrow:", arrow
5152 cs = ConstraintStore()
5253 domain, codomain = arrow.types(cs)
53- extractor = TypeExtractor()
54+ extractor = TypeExtractor(cs)
5455 for i, (gdom, gcod) in enumerate(cs.knownGivens):
5556 print "Given @%d : %s -> %s" % (i,
56- extractor.extractType(cs, gdom),
57- extractor.extractType(cs, gcod))
58- print "Type:", extractor.extractType(cs, domain), "->", extractor.extractType(cs, codomain)
57+ extractor.extract(gdom),
58+ extractor.extract(gcod))
59+ print "Type:", extractor.extract(domain), "->", extractor.extract(codomain)
5960 except BuildProblem as bp:
6061 print "Couldn't build arrow:", bp.message
6162 except UnificationFailed as uf:
--- a/cammy-rpy/weave.py
+++ b/cammy-rpy/weave.py
@@ -23,6 +23,7 @@ def main(argv):
2323 prefix = len(hivepath)
2424 doc = []
2525 for dirpath, dirnames, filenames in os.walk(hivepath):
26+ SortFileNames(dirnames).sort()
2627 SortFileNames(filenames).sort()
2728 section = dirpath[prefix:] or "Top level"
2829 doc.append("# " + section)
@@ -44,13 +45,13 @@ def main(argv):
4445 arrow = sexp.buildArrow()
4546 cs = ConstraintStore()
4647 domain, codomain = arrow.types(cs)
47- extractor = TypeExtractor()
48+ extractor = TypeExtractor(cs)
4849 for i, (gdom, gcod) in enumerate(cs.knownGivens):
4950 doc.append("Given @%d : %s -> %s" % (i,
50- extractor.extractType(cs, gdom),
51- extractor.extractType(cs, gcod)))
52- doc.append("Type: %s -> %s" % (extractor.extractType(cs, domain),
53- extractor.extractType(cs, codomain)))
51+ extractor.extract(gdom),
52+ extractor.extract(gcod)))
53+ doc.append("Type: %s -> %s" % (extractor.extract(domain),
54+ extractor.extract(codomain)))
5455 except MissingAtom as ma:
5556 doc.append(
5657 "(Couldn't canonicalize due to missing expression %s)" %
--- /dev/null
+++ b/hive/double/merge.cammy
@@ -0,0 +1,3 @@
1+(case id id)
2+
3+Either side of a double.
--- a/hive/f/cube.cammy
+++ b/hive/f/cube.cammy
@@ -1,3 +1,3 @@
1-(comp (comp (pair id fun/dup) (pair fst (comp snd f-mul))) f-mul)
1+(comp (pair id (comp fun/dup f-mul)) f-mul)
22
33 The cube of a floating-point number.
--- a/hive/f/divpair.cammy
+++ b/hive/f/divpair.cammy
@@ -1,3 +1,3 @@
1-(f/mulpair @0 (comp @1 f-recip))
1+(pair/of f/div @0 @1)
22
33 Apply division to a pair of arrows.
--- a/hive/f/mulpair.cammy
+++ b/hive/f/mulpair.cammy
@@ -1,3 +1,3 @@
1-(comp (pair @0 @1) f-mul)
1+(pair/of f-mul @0 @1)
22
33 Apply multiplication to a pair of arrows.
--- a/hive/fun/flip.cammy
+++ b/hive/fun/flip.cammy
@@ -1 +1,3 @@
1-(curry (curry (comp (pair (comp (pair (comp fst fst) snd) fun/app) (comp fst snd)) fun/app)))
1+(curry (comp fun/swap (uncurry @0)))
2+
3+Swap the order in which arguments are applied onto a curried arrow.
--- /dev/null
+++ b/hive/fun/int-flip.cammy
@@ -0,0 +1 @@
1+(curry (curry (comp (pair (comp (pair (comp fst fst) snd) fun/app) (comp fst snd)) fun/app)))
--- /dev/null
+++ b/hive/pair/of.cammy
@@ -0,0 +1,3 @@
1+(comp (pair @1 @2) @0)
2+
3+Call an arrow of two arguments by building both arguments from a single input.
--- a/jelly/src/main.rs
+++ b/jelly/src/main.rs
@@ -11,6 +11,9 @@ fn load_tree(handle :&mut Read) -> std::io::Result<RecExpr<SymbolLang>> {
1111 // Wadler 1989: https://www2.cs.sfu.ca/CourseCentral/831/burton/Notes/July14/free.pdf
1212 // Elliott 2013: http://conal.net/blog/posts/optimizing-cccs
1313
14+// "R when X is id" means that rule R is being specialized modulo the equality:
15+// (comp id ?f) = ?f = (comp ?f id) = (comp (comp ?f id) id) = ...
16+
1417 // "free for X" means that the polymorphic type of X implies the underlying equality justifying
1518 // the annotated rule, as in Wadler 1989.
1619
@@ -38,10 +41,22 @@ fn main() -> std::io::Result<()> {
3841 // free for snd
3942 rw!("snd-elim-pair"; "(comp (pair ?f ?g) snd)" => "?g"),
4043 rw!("pair-fst-snd"; "(pair fst snd)" => "id"),
44+ rw!("pair-repack"; "(comp (pair ?f ?g) (pair (comp fst ?j) (comp snd ?k)))"
45+ => "(pair (comp ?f ?j) (comp ?g ?k))"),
46+ // pair-repack when ?j is id
47+ rw!("pair-repack-snd"; "(comp (pair ?f ?g) (pair fst (comp snd ?k)))"
48+ => "(pair ?f (comp ?g ?k))"),
49+ // pair-repack when ?k is id
50+ rw!("pair-repack-fst"; "(comp (pair ?f ?g) (pair (comp fst ?j) snd))"
51+ => "(pair (comp ?f ?j) ?g)"),
4152 // Elliott 2013
4253 rw!("pair-precompose"; "(pair (comp ?r ?f) (comp ?r ?g))" => "(comp ?r (pair ?f ?g))"),
43- // Needed with pair-precompose as a special case.
44- rw!("pair-factor"; "(pair ?r ?r)" => "(comp ?r (pair id id))"),
54+ // pair-precompose when ?f is id
55+ rw!("pair-factor-fst"; "(pair ?r (comp ?r ?g))" => "(comp ?r (pair id ?g))"),
56+ // pair-precompose when ?g is id
57+ rw!("pair-factor-snd"; "(pair (comp ?r ?f) ?r)" => "(comp ?r (pair ?f id))"),
58+ // pair-precompose when ?f and ?g are id
59+ rw!("pair-factor-both"; "(pair ?r ?r)" => "(comp ?r (pair id id))"),
4560
4661 // Turn braided products into symmetric products.
4762 rw!("pair-swap-invo"; "(comp (pair snd fst) (pair snd fst))" => "id"),
--- a/todo.txt
+++ b/todo.txt
@@ -1,28 +1,8 @@
1-* Literate Cammy
2- * Entrypoints:
3- - cammy-repl $HIVE: REPL session with a hive
4- - cammy-weave $HIVE: document a hive
5- * cammy-tangle $HIVE: take an expression on stdin, return framed optimized
6- expression on stdout
7- - cammy-frame $HIVE | cammy-jelly
8- - cammy-draw ...: take an expression and canvas params, make a PNG
9- - cammy-frame $HIVE: take an expression on stdin, return framed expression
10- on stdout
11- - cammy-jelly: print an optimized expression on stdout
12- - cammy-djinn $TY $TY: synthesize a function with the given signature
13- - uses last bit of movelist code
141 * REPL improvements
152 * allow mid-functor newlines
16- * jellification
17- * : commands
18- * help, describe commands
19- * edit an atom's trail
20-* Other entrypoints
21- * Split and cleanup movelist
22- * cammy-typecheck: take an expression on stdin, print its type
23- * cammy-djinn: take a closed type, return expression with that type on
24- stdout
25-
3+ * : commands
4+ * help, describe commands
5+ * edit an atom's trail
266 * list/eq : [X × X, 2] → [[X] × [X], 2]
277 * list/zip : [X] × [Y] → [X × Y]
288 * list/tail : [X] → [X]
@@ -33,12 +13,13 @@
3313 * Transcendental and other constants
3414 * Euler's constant e
3515 * Euler's constant gamma
36-* Remove movelist djinn, maybe?
3716 * Double-negation monad for CPS?
3817 * Cont is available but not fully developed
3918 * monads/cont/join, monads/cont/bind, etc.
4019 * fun/name should always start from 1
4120 * Requires changing some callers
21+ * Might not be feasible unless we switch to stricter monoidal categories
22+ * We'd need an equivalence X × 1 → X
4223 * Prove that nat/add is smallest with its behavior
4324 * Streams
4425 * Monad: X → [N, X]
@@ -50,8 +31,23 @@
5031 * Cantor's type of bitstrings: N -> 2
5132 * The square type: For a type X, 2 -> X
5233 * Another special case of reader monad
53-* The double type: For a type X, X + X
5434 * Moore machines: For state type Q and input type S, Q × S -> Q
5535 * Moore transducers: [Q × S, Q] -> [Q × S, Q]
5636 * Mealy machines: For state type Q, input type S, and output type L, Q × S -> Q × L
5737 * Jets
38+ * how to replace e.g. nat/add?
39+ * find its subgraph with E-matching?
40+ * hook the hive to load a specialized routine during codeload?
41+* Search for more optimizations
42+ * Some arrows have inferred types that suggest they should be simplifiable
43+ * X -> X: should be id?
44+ * X -> 1: should be ignore
45+ * 1 -> 2: should be t or f
46+* New int type
47+ * Current type: quotient of N × N under subtraction
48+ * big, tricky case analysis, big quotient overlap
49+ * Proposed type: quotient of N + N gluing zero
50+ * almost minimal, sign bit, quotient glues exactly two elements into one
51+* Refactoring tools
52+ * Find all leaves in a hive
53+ * Rename an expression and change all callers