Fix a couple of bug in Kleene Stars.
...and some minor cleanup.
This commit is contained in:
parent
41d979b233
commit
705c95ee28
|
|
@ -56,6 +56,7 @@ class KleeneStar(object):
|
|||
kind = AnyJoyType
|
||||
|
||||
def __init__(self, number):
|
||||
assert number
|
||||
self.number = number
|
||||
self.count = 0
|
||||
self.prefix = repr(self)
|
||||
|
|
@ -129,8 +130,10 @@ def unify(u, v, s=None):
|
|||
|
||||
a, b = v
|
||||
if isinstance(a, KleeneStar):
|
||||
if isinstance(b, KleeneStar):
|
||||
return _lil_uni(a, b, s)
|
||||
c, d = u
|
||||
if isinstance(c, KleeneStar):
|
||||
s = _lil_uni(a, c, s) # Attempt to unify the two K-stars.
|
||||
return unify(d, b, s[0])
|
||||
|
||||
# Two universes, in one the Kleene star disappears and unification
|
||||
# continues without it...
|
||||
|
|
@ -247,7 +250,7 @@ s0, s1, s2, s3, s4, s5, s6, s7, s8, s9 = S
|
|||
f0, f1, f2, f3, f4, f5, f6, f7, f8, f9 = F = map(FloatJoyType, _R)
|
||||
i0, i1, i2, i3, i4, i5, i6, i7, i8, i9 = I = map(IntJoyType, _R)
|
||||
|
||||
|
||||
_R = range(1, 11)
|
||||
As = map(AnyStarJoyType, _R)
|
||||
Ns = map(NumberStarJoyType, _R)
|
||||
Ss = map(StackStarJoyType, _R)
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ def delabel(f, seen=None, c=None):
|
|||
|
||||
if not isinstance(f, tuple):
|
||||
try:
|
||||
seen[f] = f.__class__(c[f.prefix])
|
||||
seen[f] = f.__class__(c[f.prefix] + 1)
|
||||
except TypeError: # FunctionJoyTypes break this.
|
||||
seen[f] = f
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -11,53 +11,37 @@ infr = lambda e: infer(__(e))
|
|||
globals().update(FUNCTIONS)
|
||||
|
||||
|
||||
class TestKleeneStar(unittest.TestCase):
|
||||
class TestMixin(object):
|
||||
|
||||
def assertEqualTypeStructure(self, a, b):
|
||||
# Check shape and types match.
|
||||
self.assert_(a >= b)
|
||||
self.assert_(b >= a)
|
||||
# Check type variables match expected pattern.
|
||||
self._compare_structures(a, b)
|
||||
|
||||
def _compare_structures(self, a, b, seen=None):
|
||||
# Sometimes we change ONLY the "number" attr of our type vars.
|
||||
# We need to make sure the patterns still match our expected, uh,
|
||||
# patterns.
|
||||
if seen is None:
|
||||
seen = {}
|
||||
self.assertEqual(type(a), type(b))
|
||||
if isinstance(a, (tuple, list)):
|
||||
self.assertEqual(len(a), len(b))
|
||||
for aa, bb in zip(a, b):
|
||||
self._compare_structures(aa, bb, seen)
|
||||
else:
|
||||
if a in seen:
|
||||
self.assertIs(b, seen[a])
|
||||
seen[a] = b
|
||||
|
||||
|
||||
class TestCombinators(TestMixin, unittest.TestCase):
|
||||
|
||||
# def setUp(self):
|
||||
# def tearDown(self):
|
||||
|
||||
def test_infra(self):
|
||||
expression = [
|
||||
__((n1, n2, n3), s1), # Three numbers in a stack.
|
||||
(mul, s2),
|
||||
infra
|
||||
]
|
||||
f = (s0, ((n0, (n1, s1)), s2))
|
||||
# (-- [n0 n1 ...1]) Two numbers in a stack.
|
||||
self.assertEqual(infr(expression), [f])
|
||||
|
||||
def test_sum(self):
|
||||
expression = [
|
||||
__((n1, n2, n3), s1), # Three numbers in a stack.
|
||||
sum, # builtin shadowed by SymbolJoyType
|
||||
]
|
||||
# A function that puts a single number on the stack.
|
||||
f = s0, (n0, s0)
|
||||
self.assertEqual(infr(expression), [f])
|
||||
|
||||
def test_Yin(self):
|
||||
expression = pop, swap, rolldown, rest, rest, cons, cons
|
||||
# ([a3 a4 ...0] a2 a1 a0 -- [a1 a2 ...0])
|
||||
f = (a0, (a1, (a2, ((a3, (a4, s0)), s1)))), ((a1, (a2, s0)), s1)
|
||||
self.assertEqual(infr(expression), [f])
|
||||
|
||||
def test_cons_dip(self):
|
||||
expression = a1, (cons, s0), dip # a1 [cons] dip
|
||||
# (a0 [...0] -- [a0 ...0] a1)
|
||||
f = ((s0, (a0, s1)), (a1, ((a0, s0), s1)))
|
||||
self.assertEqual(infr(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)
|
||||
self.assertEqual(infr(expression), [f])
|
||||
|
||||
def test_i(self):
|
||||
# [cons] i == cons
|
||||
expression = (cons, s0), i
|
||||
self.assertEqual(infr(expression), infr([cons]))
|
||||
|
||||
def test_branch(self):
|
||||
'''
|
||||
a1 [dup] [cons] branch
|
||||
|
|
@ -67,25 +51,94 @@ class TestKleeneStar(unittest.TestCase):
|
|||
((s0, (a0, s1)), ((a0, s0), s1)), # (a0 [...0] -- [a0 ...0])
|
||||
((a0, s0), (a0, (a0, s0))), # (a0 -- a0 a0)
|
||||
]
|
||||
self.assertEqual(infr(expression), f)
|
||||
self.assertEqualTypeStructure(infr(expression), f)
|
||||
|
||||
def test_swaack(self):
|
||||
expression = a0, (a1, s0), swaack
|
||||
f = (s0, ((a0, s0), (a1, s1))) # (-- a1 [a0 ...0])
|
||||
self.assertEqual(infr(expression), [f])
|
||||
def test_cons_dip(self):
|
||||
expression = a1, (cons, s0), dip # a1 [cons] dip
|
||||
# (a0 [...0] -- [a0 ...0] a1)
|
||||
f = ((s0, (a0, s1)), (a1, ((a0, s0), s1)))
|
||||
self.assertEqualTypeStructure(infr(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)
|
||||
self.assertEqualTypeStructure(infr(expression), [f])
|
||||
|
||||
def test_i(self):
|
||||
# [cons] i == cons
|
||||
expression = (cons, s0), i
|
||||
self.assertEqualTypeStructure(infr(expression), infr([cons]))
|
||||
|
||||
def test_infra(self):
|
||||
expression = [
|
||||
__((n1, n2, n3), s1), # Three numbers in a stack.
|
||||
(mul, s2),
|
||||
infra
|
||||
]
|
||||
f = (s0, ((n0, (n1, s1)), s2))
|
||||
# (-- [n0 n1 ...1]) Two numbers in a stack.
|
||||
self.assertEqualTypeStructure(infr(expression), [f])
|
||||
|
||||
def test_x(self):
|
||||
expression = (a1, (swap, ((dup, s2), (dip, s0)))), x
|
||||
f = (s0, ((a0, (swap, ((dup, s1), (dip, s2)))), (a1, (a1, s0))))
|
||||
# (-- a1 a1 [a0 swap [dup ...1] dip ...2])
|
||||
self.assertEqual(infr(expression), [f])
|
||||
self.assertEqualTypeStructure(infr(expression), [f])
|
||||
|
||||
|
||||
class TestKleeneStar(TestMixin, unittest.TestCase):
|
||||
|
||||
def test_Astar(self):
|
||||
expression = a1, As[2], a2, cons
|
||||
f = [ # Vanish in one, spawn a new variable in the other...
|
||||
(s1, ((a1, s2), s1)), # (-- [a1 ...2])
|
||||
(s1, ((a1, s2), (As[1], (a2, s1)))), # (-- a2 a1* [a1 ...2])
|
||||
]
|
||||
self.assertEqualTypeStructure(infr(expression), f)
|
||||
|
||||
def test_sum(self):
|
||||
expression = [
|
||||
__((n1, n2, n3), s1), # Three numbers in a stack.
|
||||
sum, # builtin shadowed by SymbolJoyType
|
||||
]
|
||||
# A function that puts a single number on the stack.
|
||||
f = s0, (n0, s0)
|
||||
self.assertEqualTypeStructure(infr(expression), [f])
|
||||
|
||||
def test_no_infinite_loop(self):
|
||||
expression = [
|
||||
(Ns[2], s1), # A stack of numbers.
|
||||
sum, # builtin shadowed by SymbolJoyType.
|
||||
]
|
||||
# A function that puts a single number on the stack.
|
||||
f = s0, (n0, s0)
|
||||
self.assertEqualTypeStructure(infr(expression), [f])
|
||||
|
||||
|
||||
class TestYin(TestMixin, unittest.TestCase):
|
||||
|
||||
def test_MiscYin(self):
|
||||
expression = pop, swap, rolldown, rest, rest, cons, cons
|
||||
# ([a3 a4 ...0] a2 a1 a0 -- [a1 a2 ...0])
|
||||
f = (a0, (a1, (a2, ((a3, (a4, s0)), s1)))), ((a1, (a2, s0)), s1)
|
||||
self.assertEqualTypeStructure(infr(expression), [f])
|
||||
|
||||
def test_swaack(self):
|
||||
expression = a0, (a1, s0), swaack
|
||||
f = (s0, ((a0, s0), (a1, s1))) # (-- a1 [a0 ...0])
|
||||
self.assertEqualTypeStructure(infr(expression), [f])
|
||||
|
||||
|
||||
## def test_(self):
|
||||
## expression = pop, swap, rolldown, rest, rest, cons, cons
|
||||
## f =
|
||||
## for sec in infr(expression):
|
||||
## print sec, doc_from_stack_effect(*sec)
|
||||
## self.assertEqualTypeStructure(infr(expression), [f])
|
||||
|
||||
|
||||
##for g in MC(dup, mul):
|
||||
## print doc_from_stack_effect(*g)
|
||||
## for g in MC(dup, mul):
|
||||
## print doc_from_stack_effect(*g)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
Loading…
Reference in New Issue