OSDN Git Service

Minor cleanup.
authorSimon Forman <sforman@hushmail.com>
Wed, 4 Jul 2018 17:37:43 +0000 (10:37 -0700)
committerSimon Forman <sforman@hushmail.com>
Wed, 4 Jul 2018 17:37:43 +0000 (10:37 -0700)
Renamed update() to reify() and reinstated recursive substitution.

joy/library.py
joy/utils/polytypes.py
joy/utils/types.py
test/test_type_inference.py

index 975efda..bedad4c 100644 (file)
@@ -127,7 +127,8 @@ make_generator == [codireco] ccons
 '''
 # ifte == [nullary not] dipd branch
 # ifte == [nullary] dipd swap branch
-              
+# genrec == [[genrec] cons cons cons cons] nullary swons concat ifte
+
 ##ccons == cons cons
 ##unit == [] cons
 ##second == rest first
index cd29265..e7cb851 100644 (file)
@@ -34,7 +34,7 @@ from joy.utils.types import (
   _stacky,
   _R,
   relabel, delabel,
-  update,
+  reify,
   )
 
 
@@ -155,12 +155,12 @@ class CombinatorJoyType(FunctionJoyType):
 
 def _log_uni(U):
   def inner(u, v, s=None):
-    _log.info(
+    _log.debug(
       '%3i %s U %s   w/ %s',
       len(inspect_stack()), u, v, s,
       )
     res = U(u, v, s)
-    _log.info(
+    _log.debug(
       '%3i %s U %s   w/ %s => %s',
       len(inspect_stack()), u, v, s, res,
       )
@@ -176,8 +176,8 @@ def unify(u, v, s=None):
     if s is None:
         s = {}
     elif s:
-        u = update(s, u)
-        v = update(s, v)
+        u = reify(s, u)
+        v = reify(s, v)
 
     if u == v:
         res = s,
@@ -243,7 +243,7 @@ def _lil_uni(u, v, s):
 def _compose(f, g, e):
     (f_in, f_out), (g_in, g_out) = f, g
     for s in unify(g_in, f_out):
-        yield update(s, (e, (f_in, g_out)))
+        yield reify(s, (e, (f_in, g_out)))
 
 
 def compose(f, g, e):
@@ -311,7 +311,7 @@ def _infer(e, F=ID):
 
 def _interpret(f, fi, fo, e):
   new_fo, ee, _ = f(fo, e, {})
-  ee = update(FUNCTIONS, ee)  # Fix Symbols.
+  ee = reify(FUNCTIONS, ee)  # Fix Symbols.
   new_F = fi, new_fo
   return _infer(ee, new_F)
 
@@ -376,6 +376,8 @@ def defs():
 
     sum_ = product = [(((Ns[1], s1), s0), (n0, s0))]
 
+    clear = [((As[1], s0), s1)]
+
     add = mul = sub = floordiv = modulus = [
         ((i2, (i1, s0)), (i3, s0)),
         ((f2, (i1, s0)), (f3, s0)),
@@ -466,6 +468,7 @@ def set_expectations():
 scope = globals().copy()
 scope.update(FUNCTIONS)
 eval(set_expectations.func_code, scope)
+del scope
 
 
 # Type Checking...
index 5575bc8..6251f24 100644 (file)
@@ -1,6 +1,7 @@
 from collections import Counter
 from itertools import imap
 from joy.utils.stack import concat
+from joy.parser import Symbol
 
 
 class AnyJoyType(object):
@@ -53,27 +54,19 @@ class StackJoyType(AnyJoyType):
 class JoyTypeError(Exception): pass
 
 
-def update(s, term):
-    '''
-    Apply substitution dict to term, returning new term.
-    '''
-    t = _update(s, term)
-    n = 10
-    while t != term:
-        n -= 1
-        if not n:
-            print t
-            print term
-            print 'lalala'
-            1/0
-        term = t
-        t = _update(s, term)
-    return term
-
-def _update(s, term):
-    if not isinstance(term, tuple):
-        return s.get(term, term)
-    return tuple(_update(s, inner) for inner in term)
+def reify(meaning, name, seen=None):
+  '''
+  Apply substitution dict to term, returning new term.
+  '''
+  if isinstance(name, tuple):
+    return tuple(reify(meaning, inner) for inner in name)
+  safety = 101
+  while name in meaning and safety:
+    safety -= 1
+    name = meaning[name]
+  if not safety:
+      raise ValueError('Cycle in substitution dict: %s' % (meaning,))
+  return name
 
 
 def relabel(left, right):
@@ -121,8 +114,8 @@ def unify(u, v, s=None):
     if s is None:
         s = {}
     elif s:
-        u = update(s, u)
-        v = update(s, v)
+        u = reify(s, u)
+        v = reify(s, v)
 
     if isinstance(u, AnyJoyType) and isinstance(v, AnyJoyType):
         if u >= v:
@@ -164,7 +157,7 @@ def _compose(f, g):
     '''
     # Relabel, unify, update, delabel.
     (f_in, f_out), (g_in, g_out) = relabel(f, g)
-    fg = update(unify(g_in, f_out), (f_in, g_out))
+    fg = reify(unify(g_in, f_out), (f_in, g_out))
     return delabel(fg)
 
 
@@ -273,6 +266,8 @@ def defs():
     '''
     Return a dict of named stack effects.
     '''
+    at = __(s0, i1), __(a1)
+    drop = take = __(s0, i1), __(s1)
     cons = __(a1, s0), __((a1, s0),)
     ccons = compose(cons, cons)
     dup = __(a1,), __(a1, a1)
@@ -316,6 +311,7 @@ def defs():
 
     first_two = compose(uncons, uncons, pop)
     fourth = compose(rest, third)
+    of = compose(swap, at)
 
     _Tree_add_Ee = compose(pop, swap, rolldown, rrest, ccons)
     _Tree_get_E = compose(popop, second)
index 2f10558..9d1782d 100644 (file)
@@ -31,7 +31,8 @@ class TestMixin(object):
     else:
       if a in seen:
         self.assertEqual(b, seen[a])
-      seen[a] = b
+      else:
+        seen[a] = b
 
 
 class TestCombinators(TestMixin, unittest.TestCase):
@@ -43,7 +44,7 @@ class TestCombinators(TestMixin, unittest.TestCase):
     '''
     a1 [dup] [cons] branch
     '''
-    expression = a1, (dup, s0), (cons, s0), branch
+    expression = a1, (dup, s1), (cons, s2), branch
     f = [
       ((a0, s0),        (a0, (a0, s0))), #        (a0 -- a0 a0)
       ((s0, (a0, s1)), ((a0, s0), s1)),  # (a0 [...0] -- [a0 ...0])
@@ -51,8 +52,8 @@ class TestCombinators(TestMixin, unittest.TestCase):
     self.assertEqualTypeStructure(infer(*expression), f)
 
   def test_concat(self):
-    expression = (swons, s3), (a4, s0), concat_
-    f = (s1, ((swons, (a1, s1)), s1))  # (... -- ... [swons a1 ...])
+    expression = (swons, s3), (a4, s1), concat_
+    f = (s1, ((swons, (a1, s2)), s1))  # (-- [swons a1 ...2])
     self.assertEqualTypeStructure(infer(*expression), [f])
 
   def test_dip(self):
@@ -67,9 +68,9 @@ class TestCombinators(TestMixin, unittest.TestCase):
     self.assertEqualTypeStructure(infer(*expression), [f])
 
   def test_cons_dipd(self):
-    expression = a1, a3, (cons, s0), dipd
-    f = ((s0, (a0, s1)), (a1, (a2, ((a0, s0), s1))))
-    # (a0 [...0] -- [a0 ...0] a2 a1)
+    expression = (cons, s0), dipd
+    f = ((a2, (a1, (s1, (a3, s2)))), (a2, (a1, ((a3, s1), s2))))
+    # (a3 [...1] a1 a2 -- [a3 ...1] a1 a2)
     self.assertEqualTypeStructure(infer(*expression), [f])
 
   def test_i(self):
@@ -77,6 +78,11 @@ class TestCombinators(TestMixin, unittest.TestCase):
     expression = (cons, s0), i
     self.assertEqualTypeStructure(infer(*expression), infer(cons))
 
+  def test_i_dip(self):
+    expression = (i, s3), dip  # [i] dip
+    f = ((a1, (s1, s2)), (a1, s2))  # ([...1] a1 -- a1)
+    self.assertEqualTypeStructure(infer(*expression), [f])
+
   def test_infra(self):
     expression = [
       __((n1, n2, n3), s1),  # Three numbers in a stack.
@@ -106,11 +112,7 @@ class TestCombinators(TestMixin, unittest.TestCase):
     expression = (stack, s3), dip, infra, first
     f = ((s1, (a1, s2)), (a1, (a1, s2)))  # (a1 [...1] -- a1 a1)
     self.assertEqualTypeStructure(infer(*expression), [f])
-
     expression = nullary,
-    f = ((s1, (a1, s2)), (a1, (a1, s2)))  # (a1 [...1] -- a1 a1)
-    # Something's not quite right here...
-    # e = infer(*expression)
     self.assertEqualTypeStructure(infer(*expression), [f])
 
   def test_x(self):
@@ -192,4 +194,4 @@ class TestYin(TestMixin, unittest.TestCase):
 
 
 if __name__ == '__main__':
-    unittest.main() #defaultTest='TestCombinators.test_cons_dip')
+    unittest.main() #defaultTest='TestCombinators.test_branch')