:- dynamic([diverge/0,member_/2,append_/3,insert/3,perm/2]). :- dynamic([edge/2,path/2]). % test(+P, -D, -G, -N, -J) % test a single atom goal P = p(ts) which does not depend on others % D = reified program for p, G = reified goal, N = next free variable % J = success or failure test(P, D, G, N, J) :- P =.. [Pred|Xs], length(Xs, Arity), reify(Pred/Arity, D), reify_goal(P, G, N), % N-1 = # of free vars in goal solve(G, [prog(Pred/Arity, D)], N, J). % test2([Pred1/Arity1, ..., Predn/Arityn], A, J) % reify Pred1...Predn, solve goal A, J = success or failure, backtrackable test2(Preds, A, J) :- resid_prog(Preds, Gamma), reify_goal(A, G, N), solve(G, Gamma, N, J). test3(Preds, A, J) :- resid_prog(Preds, Gamma), reify_goal(A, G, N), prove(G, Gamma, N, J). /* test(member_(1, [2,1,3]), D, G, N, J). test(member_(1, [2,4,3]), D, G, N, J). test(member_(X, [1,2,3,4]), D, G, N, J). test(append_([1,2],[3,4],[1,2,3,4]), D, G, N, J). test(append_([1,2],[3,4],Zs), D, G, N, J). test(append_(Xs, Ys, [1,2,3,4]), D, G, N, J). test2([insert/3],insert(1, [1,2,3], Zs), J). test2([perm/2,insert/3], perm([1,2,3], _), J). */ % Test predicates % All test predicates must be declared dynamic % member_(X, Ys) iff X is a member of the list Ys % will succeed multiple times for each member of Ys equal to X. member_(X, [X|_]). member_(X, [_|Ys]) :- member_(X, Ys). % append_(Xs, Ys, Zs) iff Zs is the result of appending list Ys to list Xs append_([], Ys, Ys). append_([X|Xs], Ys, [X|Zs]) :- append_(Xs, Ys, Zs). % insert(X, Ys, Zs) iff Zs is result of insert X somewhere in Ys insert(X, Ys, [X|Ys]). insert(X, [Y|Ys], [Y|Zs]) :- insert(X, Ys, Zs). % perm(Xs, Zs) iff Zs is a permutation of Xs perm([], []). perm([X|Xs], Zs) :- perm(Xs, Ys), insert(X, Ys, Zs). % only good under breadth-first edge(a,d). edge(d,a). edge(a,b). edge(b,c). path(X,Y) :- edge(X,Y). path(X,Z) :- path(X,Y), path(Y,Z). /* test2([edge/2,path/2],path(a,c),J). will not terminate test3([edge/2,path/2],path(a,c),J). will succeed once, then diverge (only one path) */ % diverge will never terminate diverge :- diverge ; true.