def cps_convert_unify(x, y, compiler, cont): try: y.cps_convert_unify except: x = x.interlang() y = y.interlang() x1 = compiler.new_var(il.ConstLocalVar(x.name)) return il.begin( il.Assign(x1, il.Deref(x)), #for LogicVar, could be optimized when generate code. il.If(il.IsLogicVar(x1), il.begin(il.SetBinding(x1, y), il.append_failcont(compiler, il.DelBinding(x1)), cont(il.TRUE)), il.If(il.Eq(x1, y), cont(il.TRUE), il.failcont(il.TRUE)))) x = x.interlang() y = y.interlang() x1 = compiler.new_var(il.ConstLocalVar(x.name)) y1 = compiler.new_var(il.ConstLocalVar(y.name)) return il.begin( il.Assign(x1, il.Deref(x)), #for LogicVar, could be optimized when generate code. il.Assign(y1, il.Deref(y)), il.If(il.IsLogicVar(x1), il.begin(il.SetBinding(x1, y1), il.append_failcont(compiler, il.DelBinding(x1)), cont(il.TRUE)), il.begin( il.If(il.IsLogicVar(y1), il.begin(il.SetBinding(y1, x1), il.append_failcont(compiler, il.DelBinding(y1)), cont(il.TRUE)), il.If(il.Eq(x1, y1), cont(il.TRUE), il.failcont(il.TRUE))))))
def string_on_predicate1(compiler, cont, test): '''return current char and step if @test succeed, where @test: a python function with one argument, which tests on one char and return True or False @test must be registered with register_function''' test = test.interlang() text = compiler.new_var(il.ConstLocalVar('text')) pos = compiler.new_var(il.ConstLocalVar('pos')) length = compiler.new_var(il.ConstLocalVar('length')) p = compiler.new_var(il.LocalVar('p')) if not isinstance(test, il.PyFunction): raise DaoCompileTypeError(test) return il.Begin(( il.AssignFromList(text, pos, il.parse_state), il.Assign(length, il.Len(text)), il.If(il.Ge(pos, length), il.failcont(il.FALSE), il.If(il.Call(test, il.GetItem(text, pos)), il.begin( il.Assign(p, il.add(pos, il.Integer(1))), il.While(il.And(il.Lt(p, length), il.Call(test, il.GetItem(text, p))), il.AddAssign(p, il.Integer(1))), il.SetParseState(il.Tuple(text, p)), il.append_failcont(compiler, il.SetParseState(il.Tuple(text, pos))), cont(il.GetItem(text, il.Slice2(pos, p)))), il.failcont(il.FALSE)))))
def unify_macro_head_item2(compiler, cont, arg, head_item): if isinstance(head_item, Var): if not isinstance(head_item, LogicVar): return il.begin( il.Assign(head_item.interlang(), arg), cont(il.TRUE)) else: v = compiler.new_var(il.ConstLocalVar('v')) head_item = head_item.interlang() arg1 = compiler.new_var(il.ConstLocalVar('arg')) head1 = compiler.new_var(il.ConstLocalVar('head')) return il.begin( il.Assign(arg1, il.Deref(arg)), #for LogicVar, could be optimized when generate code. il.Assign(head1, il.Deref(head_item)), il.If(il.IsLogicVar(arg1), il.begin(il.SetBinding(arg1, head1), il.append_failcont(compiler, il.DelBinding(arg1)), cont(il.TRUE)), il.begin( il.If(il.IsLogicVar(head1), il.begin(il.SetBinding(head1, arg1), il.append_failcont(compiler, il.DelBinding(head1)), cont(il.TRUE)), il.If(il.Eq(arg1, head1), cont(il.TRUE), il.failcont(il.FALSE)))))) else: arg1 = compiler.new_var(il.ConstLocalVar('arg')) return il.begin( il.Assign(arg1, il.Deref(arg)), il.If(il.IsLogicVar(arg1), il.begin(il.SetBinding(arg1, head_item), il.append_failcont(compiler, il.DelBinding(arg1)), cont(il.TRUE)), il.If(il.Eq(arg1, head_item), cont(TRUE), il.failcont(TRUE))))
def unify_head_item2(compiler, cont, arg, head_item): # for call with rules variable. arg = arg.interlang() if not isinstance(head_item, Var): # arg should be Var if isinstance(head_item, Cons): v = compiler.new_var(il.ConstLocalVar('v')) return do_unify_head_item2(il.ConsHead(arg), head_item.head, compiler, il.clamda(v, do_unify_head_item2(il.ConsTail(arg), head_item.tail, compiler, cont))) else: head_item = head_item.interlang() arg1 = compiler.new_var(il.ConstLocalVar('arg')) return il.begin( il.Assign(arg1, il.Deref(arg)), il.If(il.IsLogicVar(arg1), il.begin(il.SetBinding(arg1, head_item), il.append_failcont(compiler, il.DelBinding(arg1)), cont(il.TRUE)), il.If(il.Eq(arg1, head_item), cont(TRUE), il.failcont(TRUE)))) else: if not isinstance(head_item, LogicVar): return il.begin( il.Assign(head_item.interlang(), arg), cont(il.TRUE)) else: raise CompileTypeError
def eval_unify(compiler, cont, x, y): x1 = compiler.new_var(il.ConstLocalVar('x')) y1 = compiler.new_var(il.ConstLocalVar('y')) return x.cps( compiler, il.clamda( x1, y.cps( compiler, il.clamda( y1, il.If( il.IsLogicVar(x1), il.begin( il.SetBinding(x1, y1), il.append_failcont(compiler, il.DelBinding(x1)), cont(il.TRUE)), il.If( il.IsLogicVar(y1), il.begin( il.SetBinding(y1, x1), il.append_failcont(compiler, il.DelBinding(y1)), cont(il.TRUE)), il.If(il.Eq(x1, y1), cont(il.TRUE), il.failcont(il.TRUE))))))))
def between(compiler, cont, lower, upper, mid): lower1 = compiler.new_var(il.ConstLocalVar('lower')) upper1 = compiler.new_var(il.ConstLocalVar('upper')) mid1 = compiler.new_var(il.ConstLocalVar('mid')) fc = compiler.new_var(il.ConstLocalVar('fc')) i = compiler.new_var(il.Var('i')) v = compiler.new_var(il.ConstLocalVar('v')) return lower.cps(compiler, il.clamda(lower1, upper.cps(compiler, il.clamda(upper1, mid.cps(compiler, il.clamda(mid1, il.If(il.IsLogicVar(mid1), il.begin( il.Assign(i, lower1), il.Assign(fc, il.failcont), il.SetFailCont(il.clamda(v, il.If(il.Eq(i, upper1), il.Begin(( il.Assign(il.failcont, fc), fc(il.FALSE))), il.Begin(( il.AddAssign(i, il.Integer(1)), il.SetBinding(mid1, i), cont(il.TRUE)))))), il.SetBinding(mid1, lower1), cont(il.TRUE)), il.If(il.Cle(lower1, mid1, upper1), cont(il.TRUE), il.failcont(il.FALSE))))) ))))
def unify_head_item2(compiler, cont, arg, head_item): # for call with rules variable. arg = arg.interlang() if not isinstance(head_item, Var): # arg should be Var if isinstance(head_item, Cons): v = compiler.new_var(il.ConstLocalVar("v")) return do_unify_head_item2( il.ConsHead(arg), head_item.head, compiler, il.clamda(v, do_unify_head_item2(il.ConsTail(arg), head_item.tail, compiler, cont)), ) else: head_item = head_item.interlang() arg1 = compiler.new_var(il.ConstLocalVar("arg")) return il.begin( il.Assign(arg1, il.Deref(arg)), il.If( il.IsLogicVar(arg1), il.begin( il.SetBinding(arg1, head_item), il.append_failcont(compiler, il.DelBinding(arg1)), cont(il.TRUE) ), il.If(il.Eq(arg1, head_item), cont(TRUE), il.failcont(TRUE)), ), ) else: if not isinstance(head_item, LogicVar): return il.begin(il.Assign(head_item.interlang(), arg), cont(il.TRUE)) else: raise CompileTypeError
def literal(compiler, cont, arg): '''any given instance string''' text = compiler.new_var(il.ConstLocalVar('text')) pos = compiler.new_var(il.ConstLocalVar('pos')) p = compiler.new_var(il.LocalVar('p')) i = compiler.new_var(il.LocalVar('i')) x = compiler.new_var(il.ConstLocalVar('x')) length = compiler.new_var(il.ConstLocalVar('length')) length2 = compiler.new_var(il.ConstLocalVar('length2')) if isinstance(arg, Var): return il.Begin(( il.Assign(x, il.Deref(arg)), il.AssignFromList(text, pos, il.parse_state), il.Assign(length, il.Len(text)), il.Assign(length, il.Len(x)), il.Assign(i, il.Integer(0)), il.Assign(p, pos), il.while_(il.and_(il.Lt(i, length2), il.Lt(p, length), il.Eq(il.GetItem(text, p), il.GetItem(x, i))), il.AddAssign(p, il.Integer(1))), il.If(il.Lt(i, length2), il.failcont(il.NONE), il.begin(il.append_failcont(compiler, il.SetParseState(il.Tuple(text, pos))), il.SetParseState(il.Tuple(text, p)), cont(arg))))) elif isinstance(arg, String): arg = arg.interlang() return il.Begin(( il.AssignFromList(text, pos, il.parse_state), il.Assign(length, il.Len(text)), il.Assign(length2, il.Len(arg)), il.Assign(i, il.Integer(0)), il.Assign(p, pos), il.while_(il.and_(il.Lt(i, length2), il.Lt(p, length), il.Eq(il.GetItem(text, p), il.GetItem(arg, i))), il.AddAssign(p, il.Integer(1)), il.AddAssign(i, il.Integer(1)), ), il.If(il.Lt(i, length2), il.failcont(il.NONE), il.begin(il.append_failcont(compiler, il.SetParseState(il.Tuple(text, pos))), il.SetParseState(il.Tuple(text, p)), cont(arg))))) else: raise CompileTypeError
def char(compiler, cont, argument): text = compiler.new_var(il.ConstLocalVar('text')) pos = compiler.new_var(il.ConstLocalVar('pos')) if isinstance(argument, String): argument = argument.interlang() return il.Begin(( il.AssignFromList(text, pos, il.parse_state), il.If(il.Ge(pos, il.Len(text)), il.failcont(il.NONE), il.If(il.Eq(argument, il.GetItem(text, pos)), il.begin(il.append_failcont(compiler, il.SetParseState(il.Tuple(text, pos))), il.SetParseState(il.Tuple(text, il.add(pos, il.Integer(1)))), cont(il.GetItem(text, pos))), il.failcont(il.NONE))))) elif isinstance(argument, Var): v = compiler.new_var(il.ConstLocalVar('v')) argument = argument.interlang() argument1 = compiler.new_var(il.ConstLocalVar('argument')) return il.Begin(( il.AssignFromList(text, pos, il.parse_state), il.If(il.Ge(pos,il.Len(text)), il.failcont(il.FALSE), il.Begin(( il.Assign(argument1, il.Deref(argument)), #il.Prin(text), il.Prin(pos), il.PrintLn(argument1), il.If(il.Isinstance(argument1, il.Symbol('str')), il.If(il.Eq(argument1, il.GetItem(text, pos)), il.begin(il.append_failcont(compiler, il.SetParseState(il.Tuple(text, pos))), il.SetParseState(il.Tuple(text, il.add(pos, il.Integer(1)))), cont(il.GetItem(text, pos))), il.failcont(il.NONE)), il.If(il.IsLogicVar(argument1), il.begin(il.SetParseState(il.Tuple(text, il.add(pos, il.Integer(1)))), il.SetBinding(argument1, il.GetItem(text, pos)), il.append_failcont(compiler, il.SetParseState(il.Tuple(text, pos)), il.DelBinding(argument1)), cont(il.GetItem(text, pos))), il.RaiseTypeError(argument1)))))))) # elif isinstance(argument, il.LogicVar) #how about this? It should be include above. else: raise CompileTypeError(argument)
def unify_parse_sequence(compiler, cont, sequence): x = compiler.new_var(il.ConstLocalVar('x')) try: sequence.cps_convert_unify except: sequence = sequence.interlang() return il.If(il.Eq(sequence, il.GetItem(il.parse_state, il.Integer(0))), cont(TRUE), il.failcont(il.TRUE)) return il.Begin(( il.Assign(x, il.Deref(sequence.interlang())), il.If(il.IsLogicVar(x), il.begin(il.SetBinding(x, il.GetItem(il.parse_state, il.Integer(0))), il.append_failcont(compiler, il.DelBinding(x)), cont(il.TRUE)), il.If(il.Eq(x, il.GetItem(il.parse_state, il.Integer(0))), cont(TRUE), il.failcont(il.TRUE)))))
def test_unify2(self): x = LogicVar('x') result = compile_optimize(unify(x, 2)) x1 = il.LogicVar('x') x2 = il.ConstLocalVar('x') expect = il.begin(il.Assign(x2, il.Deref(LogicVar(x1))), il.If(il.IsLogicVar(x2), il.begin(il.SetBinding(x2, il.Integer(2)), il.TRUE), il.If(il.Eq(x2, il.Integer(2)), il.TRUE, il.failcont(il.TRUE)))) eq_(result, expect)
def unify_macro_head_item2(compiler, cont, arg, head_item): if isinstance(head_item, Var): if not isinstance(head_item, LogicVar): return il.begin(il.Assign(head_item.interlang(), arg), cont(il.TRUE)) else: v = compiler.new_var(il.ConstLocalVar("v")) head_item = head_item.interlang() arg1 = compiler.new_var(il.ConstLocalVar("arg")) head1 = compiler.new_var(il.ConstLocalVar("head")) return il.begin( il.Assign(arg1, il.Deref(arg)), # for LogicVar, could be optimized when generate code. il.Assign(head1, il.Deref(head_item)), il.If( il.IsLogicVar(arg1), il.begin( il.SetBinding(arg1, head1), il.append_failcont(compiler, il.DelBinding(arg1)), cont(il.TRUE) ), il.begin( il.If( il.IsLogicVar(head1), il.begin( il.SetBinding(head1, arg1), il.append_failcont(compiler, il.DelBinding(head1)), cont(il.TRUE), ), il.If(il.Eq(arg1, head1), cont(il.TRUE), il.failcont(il.FALSE)), ) ), ), ) else: arg1 = compiler.new_var(il.ConstLocalVar("arg")) return il.begin( il.Assign(arg1, il.Deref(arg)), il.If( il.IsLogicVar(arg1), il.begin( il.SetBinding(arg1, head_item), il.append_failcont(compiler, il.DelBinding(arg1)), cont(il.TRUE) ), il.If(il.Eq(arg1, head_item), cont(TRUE), il.failcont(TRUE)), ), )
def findall_1(compiler, cont, goal): v = compiler.new_var(il.ConstLocalVar('v')) v2 = compiler.new_var(il.ConstLocalVar('v')) fc = compiler.new_var(il.ConstLocalVar('old_failcont')) return il.begin( il.Assign(fc, il.failcont), il.SetFailCont(il.clamda(v2, il.SetFailCont(fc), cont(v2))), goal.cps(compiler, il.Clamda(v, il.failcont(v))) )
def contain(compiler, cont, container, member): container1 = compiler.new_var(il.ConstLocalVar('container')) container2 = compiler.new_var(il.ConstLocalVar('container')) member1 = compiler.new_var(il.ConstLocalVar('member')) member2 = compiler.new_var(il.ConstLocalVar('member')) return container.cps(compiler, il.clamda(container1, il.Assign(container2, il.GetValue(container1)), member.cps(compiler, il.clamda(member1, il.Assign(member2, il.GetValue(member1)), il.If(il.In(member2, container2), cont(il.TRUE), il.failcont(il.FALSE))))))
def test_unify2(self): x = LogicVar('x') result = compile_optimize(unify(x, 2)) x1 = il.LogicVar('x') x2 = il.ConstLocalVar('x') expect = il.begin( il.Assign(x2, il.Deref(LogicVar(x1))), il.If( il.IsLogicVar(x2), il.begin(il.SetBinding(x2, il.Integer(2)), il.TRUE), il.If(il.Eq(x2, il.Integer(2)), il.TRUE, il.failcont(il.TRUE)))) eq_(result, expect)
def integer(compiler, cont, arg): '''integer''' text = compiler.new_var(il.ConstLocalVar('text')) pos = compiler.new_var(il.ConstLocalVar('pos')) p = compiler.new_var(il.LocalVar('p')) length = compiler.new_var(il.ConstLocalVar('length')) if isinstance(arg, Var): arg = arg.interlang() x = compiler.new_var(il.ConstLocalVar('x')) return il.Begin(( il.AssignFromList(text, pos, il.parse_state), il.Assign(length, il.Len(text)), il.If(il.Ge(pos, length), il.failcont(il.FALSE), il.If(il.Not(il.Cle(il.String('0'), il.GetItem(text, pos), il.String('9'))), il.failcont(il.FALSE), il.Begin(( il.Assign(p, il.add(pos, il.Integer(1))), il.while_(il.And(il.Lt(p, length), il.Cle(il.String('0'),il.GetItem(text, p),il.String('9'))), il.AddAssign(p, il.Integer(1))), il.Assign(x, il.Deref(arg)), il.If(il.IsLogicVar(x), il.begin(il.SetParseState(il.Tuple(text, p)), il.SetBinding(x, il.GetItem(text, il.Slice2(pos, p))), il.append_failcont(compiler, il.SetParseState(il.Tuple(text, pos)), il.DelBinding(x)), cont(il.GetItem(text, pos))), il.If(il.Isinstance(x, il.String('str')), il.If(il.Eq(x, il.GetItem(text, il.Slice2(pos, p))), il.begin(il.append_failcont(compiler, il.SetParseState(il.Tuple(text, pos))), il.SetParseState(il.Tuple(text, p)), cont(il.GetItem(text, pos))), il.failcont(il.NONE)), il.RaiseTypeError(x))))))))) elif isinstance(arg, il.String): return il.Begin(( il.AssignFromList(text, pos, il.parse_state), il.Assign(length, il.Len(text)), il.If(il.Ge(pos, length), il.failcont(il.FALSE), il.If(il.Not(il.Cle(il.String('0'), il.GetItem(text, pos), il.String('9'))), il.failcont(il.FALSE), il.Begin(( il.Assign(p, il.add(pos, il.Integer(1))), il.while_(il.And(il.Lt(p, length), il.Cle(il.String('0'),il.GetItem(text, p),il.String('9'))), il.AddAssign(p, il.Integer(1))), il.If(il.Eq(arg, il.GetItem(text, il.Slice2(pos, p))), il.begin(il.append_failcont(compiler, il.SetParseState(il.Tuple(text, pos))), il.SetParseState(il.Tuple(text, p)), cont(arg)), il.failcont(il.NONE)))))))) else: raise CompileTypeError
def eval_unify(compiler, cont, x, y): x1 = compiler.new_var(il.ConstLocalVar('x')) y1 = compiler.new_var(il.ConstLocalVar('y')) return x.cps(compiler, il.clamda(x1, y.cps(compiler, il.clamda(y1, il.If(il.IsLogicVar(x1), il.begin(il.SetBinding(x1, y1), il.append_failcont(compiler, il.DelBinding(x1)), cont(il.TRUE)), il.If(il.IsLogicVar(y1), il.begin(il.SetBinding(y1, x1), il.append_failcont(compiler, il.DelBinding(y1)), cont(il.TRUE)), il.If(il.Eq(x1, y1), cont(il.TRUE), il.failcont(il.TRUE))))))))
def contain(compiler, cont, container, member): container1 = compiler.new_var(il.ConstLocalVar('container')) container2 = compiler.new_var(il.ConstLocalVar('container')) member1 = compiler.new_var(il.ConstLocalVar('member')) member2 = compiler.new_var(il.ConstLocalVar('member')) return container.cps( compiler, il.clamda( container1, il.Assign(container2, il.GetValue(container1)), member.cps( compiler, il.clamda( member1, il.Assign(member2, il.GetValue(member1)), il.If(il.In(member2, container2), cont(il.TRUE), il.failcont(il.FALSE))))))
def findall_2(compiler, cont, goal, template, bag): v = compiler.new_var(il.ConstLocalVar('v')) v2 = compiler.new_var(il.ConstLocalVar('v')) fc = compiler.new_var(il.ConstLocalVar('old_failcont')) bag = bag.interlang() template = template.interlang() return il.begin( il.Assign(bag, il.empty_list), il.Assign(fc, il.failcont), il.SetFailCont(il.clamda(v2, il.SetFailCont(fc), cont(v2))), goal.cps(compiler, il.clamda(v, il.ListAppend(bag, il.GetValue(template)), il.failcont(v))))
def cps_convert_unify(x, y, compiler, cont): if isinstance(x, Var): if isinstance(y, Var): return cps_convert_unify_two_var(x, y, compiler, cont) else: return cps_convert_unify_one_var(x, y, compiler, cont) else: if isinstance(y, Var): return cps_convert_unify_two_var(y, x, compiler, cont) else: if isinstance(x, Cons) and isinstance(y, Cons): v = compiler.new_var(il.ConstLocalVar('v')) return cps_convert_unify(x.head, y.head, compiler, il.clamda(v, cps_convert_unify(x.tail, y.tail, compiler, cont))) else: if x==y: return cont(il.TRUE) else: return il.failcont(il.FALSE)
def Boi(compiler, cont): '''end of parse_state''' return il.If(il.Le(il.GetItem(il.parse_state, il.Integer(1)),0), cont(TRUE), il.failcont(FALSE))
def test_unify(self): eq_(compile_optimize(unify(1, 2)), il.failcont(True)) eq_(compile_optimize(unify(1, 1)), True)
def test_unify(self): eq_(cps(unify(1, 2)), il.failcont(True)) eq_(cps(unify(1, 1)), done()(True))
def test_fail(self): result = cps(fail) expect = il.failcont(True) eq_(result, expect)
def test_fail(self): result = compile_optimize(fail) expect = il.failcont(True) eq_(result, expect)
def fail(compiler, cont): return il.failcont(TRUE)
def notunify(compiler, cont, x, y): v = compiler.new_var(il.ConstLocalVar('v')) cont1 = il.clamda(v, il.failcont(il.FALSE)) cont2 = il.clamda(v, cont(il.TRUE)) return il.begin(il.SetFailCont(cont2), cps_convert_unify(x, y, compiler, cont1))