Some more tests.

Damn thing seems to be working.
This commit is contained in:
Simon Forman 2018-06-25 06:51:12 -07:00
parent baae1a5b36
commit f1979f35ce
3 changed files with 79 additions and 56 deletions

View File

@ -13,6 +13,7 @@ from itertools import chain, product
import sys import sys
sys.path.append('/home/sforman/Desktop/Joypy-hg') sys.path.append('/home/sforman/Desktop/Joypy-hg')
import joy.library import joy.library
from joy.utils.stack import concat as CONCAT
from joy.utils.types import ( from joy.utils.types import (
AnyJoyType, A, AnyJoyType, A,
C, C,
@ -101,6 +102,9 @@ class FunctionJoyType(AnyJoyType):
return self return self
__radd__ = __add__ __radd__ = __add__
def __repr__(self):
return self.name
class SymbolJoyType(FunctionJoyType): prefix = 'F' class SymbolJoyType(FunctionJoyType): prefix = 'F'
class CombinatorJoyType(FunctionJoyType): prefix = 'C' class CombinatorJoyType(FunctionJoyType): prefix = 'C'
@ -182,11 +186,8 @@ def _lil_uni(u, v, s):
def compose(f, g): def compose(f, g):
(f_in, f_out), (g_in, g_out) = f, g (f_in, f_out), (g_in, g_out) = f, g
s = unify(g_in, f_out) for s in unify(g_in, f_out):
if not s: yield update(s, (f_in, g_out))
raise JoyTypeError('Cannot unify %r and %r.' % (fo, gi))
for result in s:
yield update(result, (f_in, g_out))
def C(f, g): def C(f, g):
@ -198,8 +199,7 @@ def C(f, g):
def meta_compose(F, G): def meta_compose(F, G):
for f, g in product(F, G): for f, g in product(F, G):
try: try:
for result in C(f, g): for result in C(f, g): yield result
yield result
except JoyTypeError: except JoyTypeError:
pass pass
@ -231,6 +231,7 @@ def infer(e, F=ID):
for combinator in n.stack_effects: for combinator in n.stack_effects:
fi, fo = F fi, fo = F
new_fo, ee, _ = combinator(fo, e, {}) new_fo, ee, _ = combinator(fo, e, {})
ee = update(FUNCTIONS, ee) # Fix Symbols.
new_F = fi, new_fo new_F = fi, new_fo
res.extend(infer(ee, new_F)) res.extend(infer(ee, new_F))
else: else:
@ -260,21 +261,18 @@ mul = [
] ]
SYMBOLS = { FUNCTIONS = {
name: SymbolJoyType(name, [DEFS[name]], i) name: SymbolJoyType(name, [DEFS[name]], i)
for i, name in enumerate(''' for i, name in enumerate('''
ccons cons divmod_ dup dupd first ccons cons divmod_ dup dupd first
mul over pm pop popd popdd popop mul over pm pop popd popdd popop
pred rest rolldown rollup rrest pred rest rolldown rollup rrest
second sqrt succ swap swons third second sqrt succ swap swons third
tuck uncons tuck uncons stack swaack
'''.strip().split()) '''.strip().split())
} }
FUNCTIONS['sum'] = SymbolJoyType('sum', [(((Ns[1], s1), s0), (n0, s0))], 100)
SYMBOLS['sum'] = SymbolJoyType('sum', [(((Ns[1], s1), s0), (n0, s0))], 100) FUNCTIONS.update({
COMBINATORS = {
combo.__name__: CombinatorJoyType(combo.__name__, [combo], i) combo.__name__: CombinatorJoyType(combo.__name__, [combo], i)
for i, combo in enumerate(( for i, combo in enumerate((
joy.library.i, joy.library.i,
@ -284,5 +282,21 @@ COMBINATORS = {
joy.library.dupdip, joy.library.dupdip,
joy.library.b, joy.library.b,
joy.library.x, joy.library.x,
joy.library.infra,
)) ))
} })
def branch_true(stack, expression, dictionary):
(then, (else_, (flag, stack))) = stack
return stack, CONCAT(then, expression), dictionary
def branch_false(stack, expression, dictionary):
(then, (else_, (flag, stack))) = stack
return stack, CONCAT(else_, expression), dictionary
FUNCTIONS['branch'] = CombinatorJoyType('branch', [branch_true, branch_false], 100)

View File

@ -264,6 +264,7 @@ def defs():
tuck = __(a2, a1), __(a1, a2, a1) tuck = __(a2, a1), __(a1, a2, a1)
over = __(a2, a1), __(a2, a1, a2) over = __(a2, a1), __(a2, a1, a2)
stack = s0, (s0, s0) stack = s0, (s0, s0)
swaack = (s1, s0), (s0, s1)
stuncons = C(stack, uncons) stuncons = C(stack, uncons)
stununcons = C(stack, uncons, uncons) stununcons = C(stack, uncons, uncons)
first_two = C(uncons, uncons, pop) first_two = C(uncons, uncons, pop)

View File

@ -8,77 +8,85 @@ from joy.utils.stack import list_to_stack as __
infr = lambda e: infer(__(e)) infr = lambda e: infer(__(e))
globals().update(SYMBOLS) globals().update(FUNCTIONS)
globals().update(COMBINATORS)
class TestKleeneStar(unittest.TestCase): class TestKleeneStar(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): def test_sum(self):
expression = [ expression = [
(n1, (n2, (n3, s1))), # Three numbers in a stack. __((n1, n2, n3), s1), # Three numbers in a stack.
sum, # builtin shadowed by SymbolJoyType sum, # builtin shadowed by SymbolJoyType
] ]
# A function that puts a single number on the stack. # A function that puts a single number on the stack.
f = s0, (n0, s0) f = s0, (n0, s0)
self.assertEqual(infr(expression), [f]) self.assertEqual(infr(expression), [f])
def test_BS(self): def test_Yin(self):
expression = pop, swap, rolldown, rest, rest, cons, cons expression = pop, swap, rolldown, rest, rest, cons, cons
# ([a3 a4 ...0] a2 a1 a0 -- [a1 a2 ...0]) # ([a3 a4 ...0] a2 a1 a0 -- [a1 a2 ...0])
f = (a0, (a1, (a2, ((a3, (a4, s0)), s1)))), ((a1, (a2, s0)), s1) f = (a0, (a1, (a2, ((a3, (a4, s0)), s1)))), ((a1, (a2, s0)), s1)
self.assertEqual(infr(expression), [f]) self.assertEqual(infr(expression), [f])
def test_enter(self): def test_cons_dip(self):
expression = a1, (cons, s0), dip # a1 [cons] dip expression = a1, (cons, s0), dip # a1 [cons] dip
# (a0 [...0] -- [a0 ...0] a1) # (a0 [...0] -- [a0 ...0] a1)
f = ((s0, (a0, s1)), (a1, ((a0, s0), s1))) f = ((s0, (a0, s1)), (a1, ((a0, s0), s1)))
self.assertEqual(infr(expression), [f]) self.assertEqual(infr(expression), [f])
def test_2(self): 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 # [cons] i == cons
expression = (cons, s0), i expression = (cons, s0), i
self.assertEqual(infr(expression), infr([cons])) self.assertEqual(infr(expression), infr([cons]))
def test_branch(self):
'''
a1 [dup] [cons] branch
'''
expression = a1, (dup, s0), (cons, s0), branch
f = [
((s0, (a0, s1)), ((a0, s0), s1)), # (a0 [...0] -- [a0 ...0])
((a0, s0), (a0, (a0, s0))), # (a0 -- a0 a0)
]
self.assertEqual(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_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])
## for sec in infr(expression):
## print sec, doc_from_stack_effect(*sec)
##
##for g in MC(dup, mul): ##for g in MC(dup, mul):
## print doc_from_stack_effect(*g) ## print doc_from_stack_effect(*g)
## print doc_from_stack_effect(*f)
## print
## for sec in infer(e):
## print sec, doc_from_stack_effect(*sec)
## self.assertRaises(KeyError, lambda: {}[23])
## def test_leave(self):
## def setUp(self):
## def tearDown(self):
##DIP = CombinatorJoyType('dip', [dip], 44)
##DIPD = CombinatorJoyType('dipd', [dipd], 45)
##l = [(s0, ((CONS, s2), (A[1], s0)))]
##
##e = (DIP, ())
##
##h = infer(e, l[0])
##
##for z in h:
## print doc_from_stack_effect(*z)
##
##
##
##
##
##expression = (a1, (a3, ((CONS, s0), (DIPD, ()))))
##
##for sec in infer(expression):
## print doc_from_stack_effect(*sec)
##
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()