Renamed update() to reify() and reinstated recursive substitution.
'''
# 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
_stacky,
_R,
relabel, delabel,
- update,
+ reify,
)
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,
)
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,
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):
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)
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)),
scope = globals().copy()
scope.update(FUNCTIONS)
eval(set_expectations.func_code, scope)
+del scope
# Type Checking...
from collections import Counter
from itertools import imap
from joy.utils.stack import concat
+from joy.parser import Symbol
class AnyJoyType(object):
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):
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:
'''
# 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)
'''
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)
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)
else:
if a in seen:
self.assertEqual(b, seen[a])
- seen[a] = b
+ else:
+ seen[a] = b
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])
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):
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):
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.
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):
if __name__ == '__main__':
- unittest.main() #defaultTest='TestCombinators.test_cons_dip')
+ unittest.main() #defaultTest='TestCombinators.test_branch')