def test_assert_retract(): e = get_engine("g(b, b).") assert_true("g(B, B).", e) assert_true("assert(g(c, d)).", e) assert_true("assert(g(a, b)).", e) assert_true("assert(g(a, b)).", e) # assert the same rule multiple times assert_true("g(B, B).", e) assert_true("g(a, b).", e) assert_true("g(c, d).", e) assert_true("retract(g(B, B)).", e) assert_false("g(B, B).", e) assert_true("retract(g(a, b)).", e) assert_true("g(a, b).", e) assert_true("retract(g(a, b)).", e) assert_false("retract(g(a, b)).", e) assert_false("g(a, b).", e) assert_true("g(c, d).", e) e = get_engine(""" g(b, b). f(X) :- g(X, b). f(a). """) assert_true("f(b).", e) assert_true("f(a).", e) assert_true("retract(f(X) :- g(X, Y)), Y == b.", e) assert_false("f(b).", e) assert_true("f(a).", e) prolog_raises("permission_error(X, Y, Z)", "retract(atom(X))")
def test_exception(): e = get_engine(""" f(0). f(X) :- X>0, X0 is X - 1, throw(continue(X0)). g(X) :- catch(f(X), continue(X0), g(X0)).""") query = Callable.build("g", [Number(100)]) e.run_query(query, e.modulewrapper.user_module, CheckContinuation(e))
def test_cut(): e = get_engine(""" f(0). f(X) :- X>0, X0 is X - 1, !, f(X0). f(_).""") query = Callable.build("f", [Number(100)]) e.run_query(query, e.modulewrapper.user_module, CheckContinuation(e))
def test_serialize(): e = get_engine(""" serialise :- serialise([65, 66, 76, 69, 32, 87, 65, 83, 32, 32, 73, 32, 83, 65, 87, 32, 69, 76, 66, 65],_). serialise(L,R) :- pairlists(L,R,A), arrange(A,T), numbered(T,1,_). pairlists([X|L],[Y|R],[pair(X,Y)|A]) :- pairlists(L,R,A). pairlists([],[],[]). arrange([X|L],tree(T1,X,T2)) :- split(L,X,L1,L2), arrange(L1,T1), arrange(L2,T2). arrange([],void). split([X|L],X,L1,L2) :- !, split(L,X,L1,L2). split([X|L],Y,[X|L1],L2) :- before(X,Y), !, split(L,Y,L1,L2). split([X|L],Y,L1,[X|L2]) :- before(Y,X), !, split(L,Y,L1,L2). split([],_,[],[]). before(pair(X1,_),pair(X2,_)) :- X1 < X2. numbered(tree(T1,pair(_,N1),T2),N0,N) :- numbered(T1,N0,N1), N2 is N1+1, numbered(T2,N2,N). numbered(void,N,N). """) query = Callable.build("serialise") e.run_query(query, e.modulewrapper.user_module, CheckContinuation(e))
def test_recurse_with_if(): e = get_engine(""" equal(0, 0). equal(X, X). f(X) :- equal(X, 0) -> true ; Y is X - 1, f(Y). """) query = Callable.build("f", [Number(100)]) e.run_query(query, e.modulewrapper.user_module, CheckContinuation(e))
def test_traceback_print(): e = get_engine(""" h(y). g(a). g(_) :- throw(foo). f(X, Y) :- g(X), h(Y). :- assert((h :- g(b), true)). """) error = get_uncaught_error("f(1, Y).", e) s = error.format_traceback(e) assert s == """\ Traceback (most recent call last): File "<unknown>" lines 5-7 in user:f/2 f(X, Y) :- g(X), h(Y). File "<unknown>" line 4 in user:g/1 g(_) :- throw(foo). Unhandled exception: foo""" error = get_uncaught_error("h.", e) s = error.format_traceback(e) assert s == """\
def test_copy_term_3(): assert_true("copy_term(a, a, []).") assert_true("copy_term(X, Y, []), X \== Y.") assert_false("put_attr(X, foor, bar), copy_term(X, Y, _), X == Y.") assert_false("put_attr(X, foo, bar), copy_term(X, Y, Z), attvar(Y).") assert_true("put_attr(X, foo, bar), copy_term(X, Y, Z), \+ attvar(Y).") assert_true( "put_attr(X, foo, bar), copy_term(X, Y, Z), Z == [put_attr(Y, foo, bar)], X \== Y." ) assert_true( "put_attr(X, foo, bar), put_attr(X, blar, blupp), copy_term(X, Y, Z), Z == [put_attr(Y, foo, bar), put_attr(Y, blar, blupp)], X \== Y." ) e = get_engine("", m=""" :- module(m, []). attr_unify_hook(_, _). """) assert_true("put_attr(X, m, 1), X = a, copy_term(X, a, Z), Z == [].", e) assert_true( "put_attr(X, a, 1), put_attr(Y, b, 2), copy_term(f(X,Y), f(A, B), [put_attr(A, a, 1), put_attr(B, b, 2)]), Z \== f(X, Y)." ) assert_true("put_attr(X, a, Y), copy_term(X, A, [put_attr(A, a, Y)]).") assert_true("(put_attr(X, m, 1), fail; true), copy_term(X, A, []).") assert_true( "copy_term(X, A, []), put_attr(X, m, 1), copy_term(X, A, [put_attr(A, m, 1)])." )
def test_term_attvars(): e = get_engine("", m=""" :- module(m, []). attr_unify_hook(_, _). """) assert_true("term_attvars(a, []).") assert_true("term_attvars([], []).") assert_false("term_attvars([], 1).") assert_true("put_attr(X, m, 1), term_attvars(X, [X]).") assert_true("term_attvars(X,Y), Y == [].") assert_true("put_attr(X, m, 1), term_attvars(f(g(h(X)), X), [X]).") assert_true( "put_attr(X, m, 1), put_attr(Y, m, 2), term_attvars(f(X, Y), [X, Y]).") assert_false( "put_attr(X, m, 1), put_attr(Y, m, 2), X = Y, term_attvars(f(X, Y), [X, Y]).", e) assert_true( "put_attr(X, m, 1), put_attr(Y, m, 2), X = Y, term_attvars(f(X, Y), [X]).", e) assert_true( "put_attr(X, m, 1), put_attr(Y, m, 2), X = Y, term_attvars(f(X, Y), [Y]).", e) assert_true("put_attr(X, m, 1), term_attvars(f(A, X, B, X), [X]).") assert_true("put_attr(X, m, 1), Y = X, term_attvars(f(X, Y), [Y]).") assert_true("put_attr(X, m, 1), Y = X, term_attvars(f(X, Y), [X]).") assert_true("term_attvars(X, []), put_attr(X, m, 1).") assert_true( "put_attr(X, m , 1), term_attvars(X, [X]), del_attr(X, m), term_attvars(X, [])." ) assert_true("put_attr(X, m, Y), term_variables(X, L), L == [X].")
def test_run_hook_once(): e = get_engine("", m=""" :- module(m, []). attr_unify_hook(Attr, Value) :- assert(user:f(Value)). """) assert_true("put_attr(X, m, 1), X = a, X = a.", e) assert_true("findall(Y, f(Y), [a]).", e) assert_true("abolish(f/1).", e) # clear the database assert_true( """ put_attr(X, m, 1), put_attr(Y, m, 2), X = a, (X = a, fail; Y = b), findall(A, f(A), [a, b]). """, e) assert_true("abolish(f/1).", e) assert_true( """ put_attr(X, m, 1), put_attr(Y, m, 2), (f(X, b) = f(a, a); Y = b), findall(A, f(A), [b]). """, e) assert_true("abolish(f/1).", e) assert_true( """ put_attr(X, m, 1), (X = a, fail; true), findall(Z, f(Z), [a]). """, e)
def test_hook_not_defined(): e = get_engine("", m = """ :- module(m2, []). """) prolog_raises("existence_error(A, B)", "put_attr(X, bla, blub), X = 1") prolog_raises("existence_error(A, B)", "put_attr(X, m, blub), X = 1", e)
def test_integration_efficient_bools(): e = get_engine("", swi_bool_pred = """ :- module(swi_bool_pred, [negate/2]). negate(X, Y) :- ( nonvar(X) -> negate3(X, Y) ; nonvar(Y) -> negate3(Y, X) ; get_attr(X, swi_bool_pred, OtherX) -> Y = OtherX, X \== Y, put_attr(Y, swi_bool_pred, X) ; get_attr(Y, swi_bool_pred, OtherY) -> X = OtherY, X \== Y, put_attr(X, swi_bool_pred, Y) ; X \== Y, put_attr(Y, swi_bool_pred, X), put_attr(X, swi_bool_pred, Y) ). negate3(pred_true, pred_false). negate3(pred_false, pred_true). attr_unify_hook(Other, Value) :- (var(Value) -> (get_attr(Value, swi_bool_pred, Other2) -> Other = Other2, Value \== Other ; put_attr(Value, swi_bool_pred, Other) ) ; negate3(Value, Other)). """) assert_true("swi_bool_pred:negate(X,Y), swi_bool_pred:negate(Y,Z), X==Z, Z=pred_true, X==pred_true, Y==pred_false.", e) assert_true("swi_bool_pred:negate(X,Y), swi_bool_pred:negate(Y,Z), X==Z, Z=pred_true, X==pred_true, Y==pred_false.", e) assert_true("swi_bool_pred:negate(X,Y), swi_bool_pred:negate(X2,Y2), X=X2, Y==Y2, Y=pred_false, X2==pred_true.", e) assert_true("swi_bool_pred:negate(X,Y), swi_bool_pred:negate(X,Z), Y==Z, Z=pred_true, X==pred_false.", e) assert_true("swi_bool_pred:negate(X,Y), swi_bool_pred:negate(Y,Z), \+ swi_bool_pred:negate(Z,X).", e) assert_true("swi_bool_pred:negate(X,Y), swi_bool_pred:negate(Y,Z), swi_bool_pred:negate(Z,X2), \+ X2=X.", e) assert_true("swi_bool_pred:negate(X,Y), swi_bool_pred:negate(Y,Z), X2=X, \+ swi_bool_pred:negate(Z,X2).", e) assert_false("swi_bool_pred:negate(X,X).", e)
def test_cut(): e = get_engine(""" f(0). f(X) :- Y is X - 1, !, f(Y). f(X) :- Y is X - 2, !, f(Y). """) assert_true("f(20).", e)
def test_trivial(): e = get_engine(""" f(a). """) t, vars = get_query_and_vars("f(X).") e.run_query_in_current(t) assert vars['X'].dereference(None).name()== "a"
def test_trivial(): e = get_engine(""" f(a). """) t, vars = get_query_and_vars("f(X).") e.run_query_in_current(t) assert vars['X'].dereference(None).name() == "a"
def test_run_hook_once(): e = get_engine("", m = """ :- module(m, []). attr_unify_hook(Attr, Value) :- assert(user:f(Value)). """) assert_true("put_attr(X, m, 1), X = a, X = a.", e) assert_true("findall(Y, f(Y), [a]).", e) assert_true("abolish(f/1).", e) # clear the database assert_true(""" put_attr(X, m, 1), put_attr(Y, m, 2), X = a, (X = a, fail; Y = b), findall(A, f(A), [a, b]). """, e) assert_true("abolish(f/1).", e) assert_true(""" put_attr(X, m, 1), put_attr(Y, m, 2), (f(X, b) = f(a, a); Y = b), findall(A, f(A), [b]). """, e) assert_true("abolish(f/1).", e) assert_true(""" put_attr(X, m, 1), (X = a, fail; true), findall(Z, f(Z), [a]). """, e)
def test_or_and_call_with_cut(): e = get_engine(""" f :- (!, fail); true. g :- (call(!), fail); true. """) assert_false("f.", e) assert_true("g.", e)
def test_block(): e = get_engine(""" :- block f('?', '-', '?'), f('-', '-', '?'). :- block g('?'). :- block h('-', '-', '-', '?'), h('-', '-', '?', '?'), h('-', '?', '?', '?'). f(A, B, C) :- C = 10. g(_) :- assert(gg(1)). h(A, B, C, D) :- D is A + B + C. """, load_system=True) assert_false("f(X, Y, Z), Z == 10.", e) assert_false("f(a, X, Z), Z == 10.", e) assert_true("f(a, b, Z), Z == 10.", e) assert_true("f(a, X, Z), \+ Z == 10, X = 5, Z == 10.", e) assert_true("f(A, B, Z), \+ Z == 10, A = a, \+ Z == 10, B = b, Z == 10.", e) assert_true("f(a, X, Z), (X = 1, fail; true), var(Z).", e) prolog_raises("existence_error(_, _)", "g(5), gg(1)", e) prolog_raises("existence_error(_, _)", "g(X), gg(1)", e) assert_true("h(A, B, C, D), var(D), C = 5, var(D), B = 5, var(D), A = 5, D == 15.", e) prolog_raises("instantiation_error", "h(5, B, C, D)", e) prolog_raises("instantiation_error", "h(5, 1, C, D)", e) assert_true("h(1, 2, 3, 6).", e) assert_true("h(A, B, C, D), var(D), B = 5, var(D), C = 5, var(D), A = 5, D == 15.", e)
def test_or_with_cut(): e = get_engine(""" f(X) :- ((X = 1, !); X = 2), X = 2. g(X) :- ((X = 1, !); X = 2), X = 1. """) assert_false("f(X).", e) assert_true("g(X).", e)
def test_retract_logical_update_view(): e = get_engine(""" p :- retract(p :- true), fail. p :- true. """) assert_true("p.", e) assert_false("p.", e)
def test_numeral(): e = get_engine(""" num(0). num(succ(X)) :- num(X). add(X, 0, X). add(X, succ(Y), Z) :- add(succ(X), Y, Z). mul(X, 0, 0). mul(X, succ(0), X). mul(X, succ(Y), Z) :- mul(X, Y, A), add(A, X, Z). factorial(0, succ(0)). factorial(succ(X), Y) :- factorial(X, Z), mul(Z, succ(X), Y). """) def nstr(n): if n == 0: return "0" return "succ(%s)" % nstr(n - 1) e.run_query_in_current(parse_query_term("num(0).")) e.run_query_in_current(parse_query_term("num(succ(0)).")) t, vars = get_query_and_vars("num(X).") e.run_query_in_current(t) assert vars['X'].dereference(None).num == 0 e.run_query_in_current(parse_query_term("add(0, 0, 0).")) py.test.raises(UnificationFailed, e.run_query_in_current, parse_query_term(""" add(0, 0, succ(0)).""")) e.run_query_in_current(parse_query_term("add(succ(0), succ(0), succ(succ(0))).")) e.run_query_in_current(parse_query_term("mul(succ(0), 0, 0).")) e.run_query_in_current(parse_query_term("mul(succ(succ(0)), succ(0), succ(succ(0))).")) e.run_query_in_current(parse_query_term("mul(succ(succ(0)), succ(succ(0)), succ(succ(succ(succ(0))))).")) e.run_query_in_current(parse_query_term("factorial(0, succ(0)).")) e.run_query_in_current(parse_query_term("factorial(succ(0), succ(0)).")) e.run_query_in_current(parse_query_term("factorial(%s, %s)." % (nstr(5), nstr(120))))
def test_cut_with_throw(): e = get_engine(""" raise_if_var(X) :- var(X), !, throw(unbound). raise_if_var(X) :- X = a. c(X, Y) :- catch((raise_if_var(X), Y = b), E, Y = a). """) assert_true("c(_, Y), Y == a.", e)
def test_fail(): e = get_engine(""" g(a). f(X) :- g(X), fail. f(a). """) heaps = collect_all(e, "f(X).") assert len(heaps) == 1
def test_repeat(): assert_true("repeat, true.") e = Engine() assert_false("repeat, !, fail.") # hard to test repeat differently e = get_engine('f :- repeat, !, fail.') assert_false('f.', e) assert_true('f; true.', e)
def test_runstring(): e = get_engine("foo(a, c).") e.runstring(""" :- op(450, xfy, foo). a foo b. b foo X :- a foo X. """) assert_true("foo(a, b).", e)
def test_two_cuts(): e = get_engine(""" f(>, X) :- X > 0, !. f(=, X) :- X = 0, !. f(<, _). """) assert_true("f(X, 1), X = '>'.", e) assert_true("f(X, 0), X = '='.", e) assert_true("f(X, -1), X = '<'.", e)
def test_call_cut(): e = get_engine(""" f(X) :- call(X). f(!). """) heaps = collect_all(e, "f(!).") assert len(heaps) == 2 assert_true("call(((X = a; X = b), !, X = b)); X = c.") assert_false("(((X = a; X = b), !, X = b)); X = c.")
def test_and_long(): e = get_engine(""" f(x). f(y). f(z). g(a). g(b). g(c). h(d). h(e). h(f). f(X, Y, Z) :- f(X), g(Y), h(Z). """) heaps = collect_all(e, "f(X, Y, Z).") assert len(heaps) == 27
def test_or(): assert_false("fail;fail.") e = get_engine(""" f(X, Y) :- ( fail ; X \== Y ). """) assert_false("f(X,X).", e)
def test_assert_logical_update_view(): e = get_engine(""" g(a). g(c) :- assertz(g(d)). g(b). """) heaps = collect_all(e, "g(X).") assert len(heaps) == 3 e = get_engine(""" p :- assertz(p), fail. p :- fail. """) assert_false("p.", e) e = get_engine(""" q :- fail. q :- assertz(q), fail. """) assert_false("q.", e)
def test_multiple_hooks_one_not_defined(): e = get_engine("", m = """ :- module(m, []). attr_unify_hook(_, _). """) prolog_raises("existence_error(_, _)", "put_attr(X, m, 1), put_attr(X, n, 2), X = a", e) prolog_raises("existence_error(_, _)", "put_attr(X, m, 1), put_attr(Y, n, 2), X = a, Y = X", e) prolog_raises("existence_error(_, _)", "put_attr(X, m, 1), put_attr(Y, n, 2), X = a, X = Y", e)
def test_findall(): assert_true("findall(X, (X = a; X = b; X = c), L), L == [a, b, c].") assert_true("findall(X + Y, (X = 1; X = 2), [1+A, 2+B]), A \== B.") e = get_engine(""" app([], X, X). app([H | T1], T2, [H | T3]) :- app(T1, T2, T3). """) assert_true("findall(X+Y, app(X, Y, [1, 2, 3]), L), L == [[]+[1, 2, 3], [1]+[2, 3], [1, 2]+[3], [1, 2, 3]+[]].", e)
def test_4_queens(): e = get_engine(""" queens(Vars) :- Vars = [_A, _B, _C, _D], safe(Vars), perm([1,2,3,4], Vars). safe([]). safe([H|T]) :- safe(T), attack(H, 1, T). attack(_, _, []). attack(X, N, [H|T]) :- when((nonvar(X), nonvar(H)), (not(X is H + N; X is H - N))), N1 is N + 1, attack(X, N1, T). perm([1,2,3,4], [1,2,3,4]). perm([1,2,3,4], [1,2,4,3]). perm([1,2,3,4], [1,3,2,4]). perm([1,2,3,4], [1,3,4,2]). perm([1,2,3,4], [1,4,2,3]). perm([1,2,3,4], [1,4,3,2]). perm([1,2,3,4], [2,1,3,4]). perm([1,2,3,4], [2,1,4,3]). perm([1,2,3,4], [2,3,1,4]). perm([1,2,3,4], [2,3,4,1]). perm([1,2,3,4], [2,4,1,3]). perm([1,2,3,4], [2,4,2,1]). perm([1,2,3,4], [3,1,2,4]). perm([1,2,3,4], [3,1,4,2]). perm([1,2,3,4], [3,2,1,4]). perm([1,2,3,4], [3,2,4,1]). perm([1,2,3,4], [3,4,1,2]). perm([1,2,3,4], [3,4,2,1]). perm([1,2,3,4], [4,1,3,2]). perm([1,2,3,4], [4,1,2,3]). perm([1,2,3,4], [4,2,1,3]). perm([1,2,3,4], [4,2,3,1]). perm([1,2,3,4], [4,3,1,2]). perm([1,2,3,4], [4,3,2,1]). """, load_system=True) assert_true("queens([2, 4, 1, 3]).", e) assert_true("queens([3, 1, 4, 2]).", e) assert_false("queens([4, 2, 1, 3]).", e) assert_true("queens(X), X == [2, 4, 1, 3].", e) assert_true("queens(X), X == [3, 1, 4, 2].", e) assert_false("queens(X), X == [4, 2, 1, 3].", e) assert_true("findall(X, queens(X), L), L == [[2, 4, 1, 3], [3, 1, 4, 2]].", e)
def test_assert_retract_colon(): e = get_engine(""" :(1, 2, 3). :(a). """) assert_true(":(1, 2, 3), :(a).", e) assert_true("assert(:(a, b, c, d)).", e) assert_true(":(a, b, c, d).", e) assert_true("retract(:(a, b, c, d)).", e) prolog_raises("existence_error(_, _)", ":(a, b, c, d)", e)
def test_abolish_colon(): e = get_engine(""" :(a). :(1, 2, 3). """) assert_true("abolish(:/1).", e) prolog_raises("existence_error(_, _)", ":(a)", e) assert_true(":(1, 2, 3).", e) assert_true("abolish(:/3).", e) prolog_raises("existence_error(_, _)", ":(1, 2, 3)", e)
def test_cut2(): e = get_engine(""" g(a). g(b). h(a, x). h(a, y). f(X, Y) :- g(X), !, !, !, !, !, h(X, Y). """) heaps = collect_all(e, "f(X, Y).") assert len(heaps) == 2
def test_call(): e = get_engine("g(b, b).") assert_true("call(g(X, X)).", e) assert_true("X =.. [g, b, b], call(X).", e) e = get_engine(""" g(X) :- call(f(X)). g(a). g(b). f(X) :- !, h(X). f(a). f(b). h(X) :- fail. withcut(X) :- call(!), fail. withcut(a). """) heaps = collect_all(e, "g(X).") assert len(heaps) == 2 assert_true("withcut(a).", e) assert_true("call((!, true)).")
def test_backtrack_to_same_choice_point(): e = get_engine(""" a(a). b(b). start(Z) :- Z = X, f(X, b), X == b, Z == b. f(X, Y) :- a(Y). f(X, Y) :- X = a, a(Y). f(X, Y) :- X = b, b(Y). """) assert_true("start(Z).", e)
def test_indexing2(): e = get_engine(""" mother(o, j). mother(o, m). mother(o, b). sibling(X, Y) :- mother(Z, X), mother(Z, Y). """) heaps = collect_all(e, "sibling(m, X).") assert len(heaps) == 3