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