choose([X|Xs],X,Xs). choose([X|Xs],Y,[X|Ys]) :- choose(Xs,Y,Ys). % == hypothesis == prove(G0,atom(P)) :- choose(G0,atom(P),_). % == right rules == %% topR prove(_,top). %% andR prove(G,and(A,B)) :- prove(G,A),prove(G,B). %% no rule botR %% orR1 prove(G,or(A,_)) :- prove(G,A). %% orR2 prove(G,or(_,B)) :- prove(G,B). %% impliesR prove(G,implies(A,B)) :- prove([A|G],B). % == left rules == %% topL prove(G0,C) :- choose(G0,top,G), prove(G,C). %% andL prove(G0,C) :- choose(G0,and(A,B),G), prove([A,B|G],C). %% botL prove(G0,_) :- choose(G0,bot,_). %% orL prove(G0,C) :- choose(G0,or(A,B),G), prove([A|G],C), prove([B|G],C). %% impliesL prove(G0,C) :- choose(G0,implies(A,B),G), prove(G0,A), prove([B|G],C). % == tests == %% should succeed (yes) test :- prove([],implies(atom(p),atom(p))), prove([],implies(and(atom(p),atom(q)),and(atom(q),atom(p)))), prove([],implies(or(atom(p),atom(q)),or(atom(q),atom(p)))). %% should fail (no) testfalse :- prove([],or(atom(p),implies(atom(p),bot))). testfalse :- prove([],implies(atom(p),atom(q))). testfalse :- prove([],implies(and(atom(p),atom(q)),and(atom(w),atom(p)))). %% should succeed, but loop instead testloop :- prove([],implies(implies(or(atom(p),implies(atom(p),bot)),bot),bot)), prove([],implies(implies(or(implies(atom(p),atom(q)),implies(atom(q),atom(p))),bot),bot)). %% if you run the query 'shouldBeTrue' you should get 'yes' shouldBeTrue :- prove([],implies(implies(or(atom(p),implies(atom(p),bot)),bot),bot)), prove([],implies(implies(or(implies(atom(p),atom(q)),implies(atom(q),atom(p))),bot),bot)). prove([],and(implies(implies(atom(a),implies(atom(b),atom(c))),implies(and(atom(a),atom(b)),atom(c))),implies(implies(and(atom(a),atom(b)),atom(c)),implies(atom(a),implies(atom(b),atom(c)))))), prove([],and(implies(implies(atom(a),and(atom(b),atom(c))),and(implies(atom(a),atom(b)),implies(atom(a),atom(c)))),implies(and(implies(atom(a),atom(b)),implies(atom(a),atom(c))),implies(atom(a),and(atom(b),atom(c)))))), prove([],implies(or(implies(atom(a),atom(b)),implies(atom(a),atom(c))),implies(atom(a),or(atom(b),atom(c))))), prove([],implies(and(or(atom(a),atom(b)),implies(atom(b),atom(c))),implies(implies(atom(a),atom(b)),atom(c)))), prove([],and(implies(implies(or(atom(a),atom(b)),atom(c)),and(implies(atom(a),atom(c)),implies(atom(b),atom(c)))),implies(and(implies(atom(a),atom(c)),implies(atom(b),atom(c))),implies(or(atom(a),atom(b)),atom(c))))), prove([],and(implies(and(atom(a),or(atom(b),atom(c))),or(and(atom(a),atom(b)),and(atom(a),atom(c)))),implies(or(and(atom(a),atom(b)),and(atom(a),atom(c))),and(atom(a),or(atom(b),atom(c)))))), prove([],and(implies(or(atom(a),and(atom(b),atom(c))),and(or(atom(a),atom(b)),or(atom(a),atom(c)))),implies(and(or(atom(a),atom(b)),or(atom(a),atom(c))),or(atom(a),and(atom(b),atom(c)))))), prove([],implies(or(implies(atom(a),bot),implies(atom(b),bot)),implies(and(atom(a),atom(b)),bot))), prove([],and(implies(implies(or(atom(a),atom(b)),bot),and(implies(atom(a),bot),implies(atom(b),bot))),implies(and(implies(atom(a),bot),implies(atom(b),bot)),implies(or(atom(a),atom(b)),bot)))), prove([],implies(and(atom(a),implies(atom(b),bot)),implies(implies(atom(a),atom(b)),bot))), prove([],implies(atom(a),implies(implies(atom(a),bot),bot))), prove([],and(implies(implies(top,bot),bot),implies(bot,implies(top,bot)))), prove([],and(implies(implies(bot,bot),top),implies(top,implies(bot,bot)))), prove([],and(implies(implies(implies(implies(atom(a),bot),bot),bot),implies(atom(a),bot)),implies(implies(atom(a),bot),implies(implies(implies(atom(a),bot),bot),bot)))), prove([],implies(implies(atom(a),atom(b)),implies(implies(atom(b),atom(c)),implies(implies(atom(c),atom(d)),implies(atom(a),atom(d)))))), prove([],implies(atom(a),implies(atom(b),atom(a)))), prove([],implies(implies(atom(a),atom(b)),implies(implies(atom(a),implies(atom(b),atom(c))),implies(atom(a),atom(c))))). %% if you run the query 'shouldBeFalse' you should get 'no' shouldBeFalse :- prove([], implies(implies(implies(atom(a),atom(b)),atom(c)),and(or(atom(a),atom(b)),implies(atom(b),atom(c))))). shouldBeFalse :- prove([], implies(implies(atom(a),or(atom(b),atom(c))),or(implies(atom(a),atom(b)),implies(atom(a),atom(c))))). shouldBeFalse :- prove([], implies(implies(implies(atom(a),atom(b)),atom(a)),atom(a))). shouldBeFalse :- prove([], implies(implies(implies(atom(a),bot),bot),atom(a))). shouldBeFalse :- prove([], implies(implies(and(atom(a),atom(b)),bot),or(implies(atom(a),bot),implies(atom(b),bot)))). shouldBeFalse :- prove([], implies(implies(implies(atom(a),atom(b)),bot),and(atom(a),implies(atom(b),bot)))).