• R/O
  • HTTP
  • SSH
  • HTTPS

提交

标签
No Tags

Frequently used words (click to add to your profile)

javaandroidc++linuxc#windowsobjective-ccocoaqtpython誰得phprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

A categorical programming language


Commit MetaInfo

修订版876b22629fa5fb390cc8631027af540dc08c734b (tree)
时间2022-03-09 10:16:42
作者Corbin <cds@corb...>
CommiterCorbin

Log Message

Clean up pretty-printing for types.

更改概述

差异

--- a/cammy-rpy/cammylib/sexp.py
+++ b/cammy-rpy/cammylib/sexp.py
@@ -39,12 +39,18 @@ class Atom(SExp):
3939 def occurs(self, index):
4040 return False
4141
42- def extractType(self, extractor):
42+ def extractType(self, extractor, formatter, outerPrecedence):
4343 return self.symbol
4444
4545 def buildArrow(self):
4646 return buildUnary(self.symbol)
4747
48+# Precedence levels for operator-style notation.
49+PRECEDENCE = {
50+ "hom": 3,
51+ "pair": 2,
52+ "sum": 1,
53+}
4854
4955 class Functor(SExp):
5056 "A list of S-expressions with a distinguished head."
@@ -77,18 +83,26 @@ class Functor(SExp):
7783 return True
7884 return False
7985
80- def extractType(self, extractor):
81- args = [extractor.extract(unhole(arg)) for arg in self.arguments]
86+ def extractType(self, extractor, formatter, outerPrecedence):
87+ innerPrecedence = PRECEDENCE.get(self.constructor, 0)
88+ args = [extractor.extractWithPrecedence(unhole(arg), innerPrecedence)
89+ for arg in self.arguments]
8290 if self.constructor == "hom":
83- return "[%s, %s]" % (args[0], args[1])
91+ rv = formatter.formatHom(args[0], args[1])
8492 elif self.constructor == "pair":
85- return "(%s x %s)" % (args[0], args[1])
93+ rv = formatter.formatPair(args[0], args[1])
8694 elif self.constructor == "sum":
87- return "(%s + %s)" % (args[0], args[1])
95+ rv = formatter.formatSum(args[0], args[1])
8896 elif self.constructor == "list":
89- return "[%s]" % args[0]
97+ rv = formatter.formatList(args[0])
9098 else:
91- assert False, "whoops"
99+ assert False, "whoopsie-doodle"
100+ # NB: This is traditionally >, not >=
101+ # but that forgets required strictness and would be confusing to read
102+ if (outerPrecedence >= innerPrecedence and
103+ not formatter.resetsBracketsFor(self.constructor)):
104+ rv = formatter.parenthesize(rv)
105+ return rv
92106
93107 def buildArrow(self):
94108 args = [arg.buildArrow() for arg in self.arguments]
@@ -115,7 +129,7 @@ class Hole(SExp):
115129 def occurs(self, index):
116130 return self.index == index
117131
118- def extractType(self, extractor):
132+ def extractType(self, extractor, formatter, outerPrecedence):
119133 return extractor.findTypeAlias(self.index)
120134
121135 def buildArrow(self):
--- a/cammy-rpy/cammylib/types.py
+++ b/cammy-rpy/cammylib/types.py
@@ -80,11 +80,17 @@ class ConstraintStore(object):
8080 (vi.asStr(), vj.asStr()))
8181
8282
83+class TypeFormatter(object):
84+ """
85+ Customize the output of a type-extraction operation.
86+ """
87+
8388 LETTERS = "XYZWSTPQ"
8489
8590 class TypeExtractor(object):
86- def __init__(self, cs):
91+ def __init__(self, cs, formatter):
8792 self.cs = cs
93+ self.formatter = formatter
8894 self.d = {}
8995 self.seen = []
9096
@@ -97,13 +103,16 @@ class TypeExtractor(object):
97103 return self.d[index]
98104
99105 def extract(self, var):
106+ return self.extractWithPrecedence(var, 0)
107+
108+ def extractWithPrecedence(self, var, precedence):
100109 if var in self.seen:
101110 # XXX split exceptions?
102111 raise UnificationFailed("tried to extract infinite type")
103112 self.seen.append(var)
104113
105114 sexp = self.cs.walk(var)
106- rv = sexp.extractType(self)
115+ rv = sexp.extractType(self, self.formatter, precedence)
107116
108117 self.seen.pop()
109118 return rv
--- a/cammy-rpy/repl.py
+++ b/cammy-rpy/repl.py
@@ -8,10 +8,29 @@ from cammylib.arrows import BuildProblem, T
88 from cammylib.hive import Hive, MissingAtom
99 from cammylib.jelly import jellify
1010 from cammylib.parser import parse
11-from cammylib.types import ConstraintStore, TypeExtractor, UnificationFailed
11+from cammylib.types import ConstraintStore, TypeExtractor, TypeFormatter, UnificationFailed
1212
1313 LINE_BUFFER_LENGTH = 1024
1414
15+class PlaintextTypeFormatter(TypeFormatter):
16+ def resetsBracketsFor(self, constructor):
17+ return constructor in ("hom", "list")
18+
19+ def parenthesize(self, x):
20+ return "(%s)" % x
21+
22+ def formatHom(self, x, y):
23+ return "[%s, %s]" % (x, y)
24+
25+ def formatPair(self, x, y):
26+ return "%s x %s" % (x, y)
27+
28+ def formatSum(self, x, y):
29+ return "%s + %s" % (x, y)
30+
31+ def formatList(self, x):
32+ return "[%s]" % x
33+
1534 def command(hive, code, line):
1635 # XXX code e: Edit a file
1736 # os.system("$EDITOR")
@@ -51,7 +70,7 @@ def repl(hive, stdin, stdout):
5170 print "Arrow:", arrow
5271 cs = ConstraintStore()
5372 domain, codomain = arrow.types(cs)
54- extractor = TypeExtractor(cs)
73+ extractor = TypeExtractor(cs, PlaintextTypeFormatter())
5574 for i, (gdom, gcod) in enumerate(cs.knownGivens):
5675 print "Given @%d : %s -> %s" % (i,
5776 extractor.extract(gdom),
--- a/cammy-rpy/weave.py
+++ b/cammy-rpy/weave.py
@@ -7,11 +7,31 @@ from rpython.rlib.listsort import make_timsort_class
77 from cammylib.arrows import BuildProblem
88 from cammylib.hive import Hive, MissingAtom
99 from cammylib.parser import parse
10-from cammylib.types import ConstraintStore, TypeExtractor, UnificationFailed
10+from cammylib.types import ConstraintStore, TypeExtractor, TypeFormatter, UnificationFailed
1111
1212
1313 SortFileNames = make_timsort_class()
1414
15+class LatexTypeFormatter(TypeFormatter):
16+ def resetsBracketsFor(self, constructor):
17+ return constructor == "list"
18+
19+ def parenthesize(self, x):
20+ return "( %s )" % x
21+
22+ def formatHom(self, x, y):
23+ return "{ %s }^{ %s }" % (y, x)
24+
25+ def formatPair(self, x, y):
26+ return r"%s \times %s" % (x, y)
27+
28+ def formatSum(self, x, y):
29+ return r"%s + %s" % (x, y)
30+
31+ def formatList(self, x):
32+ return "[ %s ]" % x
33+
34+
1535 def codeblock(code):
1636 return "```\n" + code + "\n```"
1737
@@ -45,12 +65,12 @@ def main(argv):
4565 arrow = sexp.buildArrow()
4666 cs = ConstraintStore()
4767 domain, codomain = arrow.types(cs)
48- extractor = TypeExtractor(cs)
68+ extractor = TypeExtractor(cs, LatexTypeFormatter())
4969 for i, (gdom, gcod) in enumerate(cs.knownGivens):
50- doc.append("Given @%d : %s -> %s" % (i,
70+ doc.append(r"Given @%d : $%s \to %s$" % (i,
5171 extractor.extract(gdom),
5272 extractor.extract(gcod)))
53- doc.append("Type: %s -> %s" % (extractor.extract(domain),
73+ doc.append(r"Type: $%s \to %s$" % (extractor.extract(domain),
5474 extractor.extract(codomain)))
5575 except MissingAtom as ma:
5676 doc.append(
--- /dev/null
+++ b/hive/baire/add.cammy
@@ -0,0 +1,8 @@
1+(curry
2+ (comp
3+ (pair
4+ (fun/apppair (comp fst fst) snd)
5+ (fun/apppair (comp fst snd) snd))
6+ nat/add))
7+
8+Addition of non-standard natural numbers in Baire space.
--- /dev/null
+++ b/hive/baire/omega.cammy
@@ -0,0 +1,4 @@
1+id
2+
3+As a non-standard natural number, $\omega$ is the smallest natural number
4+greater than all standard natural numbers.
--- a/hive/int/is_zero.cammy
+++ b/hive/int/is_zero.cammy
@@ -1 +1,3 @@
1-(uncurry nat/eq)
1+(case nat/is_zero nat/is_zero)
2+
3+Whether an integer is zero.
--- a/hive/int/neg.cammy
+++ b/hive/int/neg.cammy
@@ -1 +1,3 @@
1-fun/swap
1+sum/swap
2+
3+The negation of an integer.
--- a/hive/int/succ.cammy
+++ b/hive/int/succ.cammy
@@ -1 +1,3 @@
1-(pair (comp fst succ) snd)
1+(case (comp succ left) (comp nat/pred-maybe (case right (comp nat/1 left))))
2+
3+The successor of an integer.
--- a/hive/int/zero.cammy
+++ b/hive/int/zero.cammy
@@ -1 +1,3 @@
1-(pair zero zero)
1+(comp zero left)
2+
3+The integer zero. For no particular reason, we choose positive zero.
--- /dev/null
+++ b/hive/nat/1.cammy
@@ -0,0 +1,3 @@
1+(comp zero succ)
2+
3+One.
--- a/hive/nat/eq.cammy
+++ b/hive/nat/eq.cammy
@@ -1,3 +1,5 @@
1-(pr (curry (comp snd nat/is_zero)) (curry (comp (pair fst (comp snd nat/pred)) fun/app)))
1+(uncurry (pr
2+ (curry (comp snd nat/is_zero))
3+ (curry (comp (pair fst (comp snd nat/pred)) fun/app))))
24
35 Equality on natural numbers is decidable.
--- /dev/null
+++ b/hive/nat/pred-maybe.cammy
@@ -0,0 +1,5 @@
1+(pr
2+ right
3+ (comp (case succ zero) left))
4+
5+The predecessor of a natural number, or a distinguished point for zero.
--- a/hive/nat/pred.cammy
+++ b/hive/nat/pred.cammy
@@ -1 +1,3 @@
11 (comp (pr (comp zero fun/dup) (comp fst (pair succ id))) snd)
2+
3+The predecessor of a natural number. Zero is mapped to itself.
--- /dev/null
+++ b/hive/scott/bool/false.cammy
@@ -0,0 +1 @@
1+(curry snd)
--- /dev/null
+++ b/hive/sum/swap.cammy
@@ -0,0 +1,3 @@
1+(case right left)
2+
3+Swap the two cases of a sum.