%% Task 1.1 %% G , A|B, A ==> C iff G, A ==> C %% The "if" direction is just weakening. The "only if": %% Assume G , A|B, A ==> C. %% By identity, G,A ==> A. %% By applying the or right rule to this, G,A ==> A|B. %% By cut with the assumption, G,A ==> C. %% %% The other case is symmetric. %% ---------------------------------------------------------------------- %% Task 2.1 %% Here's the sequence of goals you try to solve (using Tutch notation for the propositions): %% prove([~(P|~P)],F) %% then apply implication-left: prove([~(P|~P)],P|~P) and prove([~(P|~P),F],F) %% then apply or-right-1 to the first subgoal: prove([~(P|~P)],P) %% then apply implication-left: prove([~(P|~P)],P|~P) and prove([~(P|~P),F],P) %% ... %% So the goal prove([~(P|~P)],P|~P) reduces to itself. %% Task 2.2 %% Recall the proof term for LEM: (fn u => u (inr (fn v => u (inl v)))) %% The inner use of u is impossible if the left-rule for implication %% forces you to drop the implication itself from the context. %% ---------------------------------------------------------------------- %% Task 3 choose([X|Xs],X,Xs). choose([X|Xs],Y,[X|Ys]) :- choose(Xs,Y,Ys). %% init prove(G0,atom(P)) :- choose(G0,atom(P),_). %% right rules prove(_,top). prove(G,and(A,B)) :- prove(G,A),prove(G,B). % no right rule for bot prove(G,or(A,_)) :- prove(G,A). prove(G,or(_,B)) :- prove(G,B). prove(G,implies(A,B)) :- prove([A|G],B). % left rules prove(G0,C) :- choose(G0,top,G), prove(G,C). prove(G0,C) :- choose(G0,and(A,B),G), prove([A,B|G],C). prove(G0,_) :- choose(G0,bot,_). prove(G0,C) :- choose(G0,or(A,B),G), prove([A|G],C), prove([B|G],C). %% the six new rules: prove(G0,C) :- choose(G0,implies(top,B),G), %% (top => B) = B prove([B|G],C). prove(G0,C) :- choose(G0,implies(and(A1,A2),B),G), %% (A1 & A2 => B) = A1 => A2 => B prove([implies(A1,implies(A2,B))|G],C). prove(G0,C) :- choose(G0,implies(or(A1,A2),B),G), %% (A1 | A2 => B) = A1 => B & A2 => B prove([implies(A1,B),implies(A2,B)|G],C). prove(G0,C) :- choose(G0,implies(bot,_),G), %% (0 => B) = 1 prove(G,C). prove(G0,C) :- choose(G0,implies(atom(P),B),G), prove(G,atom(P)), prove([B|G],C). prove(G0,C) :- choose(G0,implies(implies(A1,A2),B),G), prove([implies(A2,B),A1|G],A2), prove([B|G],C). %% ---------------------------------------------------------------------- %% Task 3.1 %% Everything but the last two (P => B and (A1 => A2) => B) are invertible. %% Task 3.2 choose([X|Xs],X,Xs). choose([X|Xs],Y,[X|Ys]) :- choose(Xs,Y,Ys). %% init prove(G,atom(P)) :- choose(G,atom(P),_). %% right rules prove(_,top). prove(G,and(A,B)) :- prove(G,A),prove(G,B). % no right rule for bot prove(G,or(A,_)) :- prove(G,A). prove(G,or(_,B)) :- prove(G,B). prove(G,implies(A,B)) :- invert(G,[A],B). %% invertible left rules prove(G0,C) :- choose(G0,implies(atom(P),B),G), choose(G,atom(P),_), invert(G,[B],C). prove(G0,C) :- choose(G0,implies(implies(A1,A2),B),G), invert(G,[implies(A2,B),A1],A2), invert(G,[B],C). %% G = stable context %% D = working to invert % left rules invert(G,[],C) :- prove(G,C). %% nothing left to invert invert(G,[top|D],C) :- invert(G,D,C). invert(G,[and(A,B)|D],C) :- invert(G,[A,B|D],C). invert(_,[bot|_],_). invert(G,[or(A,B)|D],C) :- invert(G,[A|D],C), invert(G,[B|D],C). invert(G,[implies(top,B)|D],C) :- %% (top => B) = B invert(G,[B|D],C). invert(G,[implies(and(A1,A2),B)|D],C) :- %% (A1 & A2 => B) = A1 => A2 => B invert(G,[implies(A1,implies(A2,B))|D],C). invert(G,[implies(or(A1,A2),B)|D],C) :- %% (A1 | A2 => B) = A1 => B & A2 => B invert(G,[implies(A1,B),implies(A2,B)|D],C). invert(G,[implies(bot,_)|D],C) :- %% (0 => B) = 1 invert(G,D,C). %% move the first thing into G if it isn't invertible: invert(G,[atom(P)|D],C) :- invert([atom(P)|G],D,C). invert(G,[implies(atom(P),B)|D],C) :- invert([implies(atom(P),B)|G],D,C). invert(G,[implies(implies(A1,A2),B)|D],C) :- invert([implies(implies(A1,A2),B)|G],D,C). %% if you run the query 'shouldBeTrue(a)' you should get 'yes' shouldBeTrue(a) :- 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)))), 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(a)' you should get 'no' shouldBeFalse(a) :- prove([],or(atom(p),implies(atom(p),bot))). shouldBeFalse(a) :- prove([],implies(atom(p),atom(q))). shouldBeFalse(a) :- prove([],implies(and(atom(p),atom(q)),and(atom(w),atom(p)))). shouldBeFalse(a) :- prove([], implies(implies(implies(atom(a),atom(b)),atom(c)),and(or(atom(a),atom(b)),implies(atom(b),atom(c))))). shouldBeFalse(a) :- prove([], implies(implies(atom(a),or(atom(b),atom(c))),or(implies(atom(a),atom(b)),implies(atom(a),atom(c))))). shouldBeFalse(a) :- prove([], implies(implies(implies(atom(a),atom(b)),atom(a)),atom(a))). shouldBeFalse(a) :- prove([], implies(implies(implies(atom(a),bot),bot),atom(a))). shouldBeFalse(a) :- prove([], implies(implies(and(atom(a),atom(b)),bot),or(implies(atom(a),bot),implies(atom(b),bot)))). shouldBeFalse(a) :- prove([], implies(implies(implies(atom(a),atom(b)),bot),and(atom(a),implies(atom(b),bot)))).