Download | Plain Text | Line Numbers
% Manuel Mausz, 0728348
% unit tests befinden sich in gol.plt
% operator wertigkeit definieren
:- op(425, fy, -).
:- op(450, yfx, &).
:- op(500, yfx, v).
% --------------------------------------------------------------------------
% wenn A atom ist, retourniere A
nnf(A, A) :-
atomic(A).
% wenn A negiert ist und A atom ist, reourniere A negiert
nnf(-A, -A) :-
atomic(A).
% wenn A doppelt negiert ist, entferne die doppelte negation
nnf(-(-A), X) :-
nnf(A, X).
% de morgansche gesetze
nnf(-(A & B), X) :-
nnf(-A v -B, X).
nnf(-(A v B), X) :-
nnf(-A & -B, X).
% akzeptiere kon-/disjunktionen, wenn die subterme in NNF sind
nnf(A & B, X & Y) :-
nnf(A, X), nnf(B, Y).
nnf(A v B, X v Y) :-
nnf(A, X), nnf(B, Y).
% --------------------------------------------------------------------------
% literal check
literalp(A) :-
atomic(A).
literalp(-A) :-
atomic(A).
% --------------------------------------------------------------------------
% anzahl der "oder" (v) zaehlen
no_or(A, X) :-
literalp(A), X is 0.
no_or(A v B, X) :-
no_or(A, Y1), no_or(B, Y2), X is Y1 + Y2 + 1.
no_or(A & B, X) :-
no_or(A, Y1), no_or(B, Y2), X is Y1 + Y2.
% --------------------------------------------------------------------------
% prove2/3 wrapper fuer prove3/4
prove2(F1, F2, NOW) :-
prove2(F1, F2, NOW, _DATA).
% axioms
prove2(A, -A, _NOW, axiom([A, -A])).
prove2(-A, A, _NOW, axiom([A, -A])).
% (&, literal)
prove2((F1 & F2), A, NOW, undRegel([F1 & F2, A], [Praem1, Praem2])) :-
literalp(A), prove2(F1, A, NOW, Praem1), prove2(F2, A, NOW, Praem2).
% (literal, &)
prove2(A, (F1 & F2), NOW, undRegel([A, F1 & F2], [Praem1, Praem2])) :-
literalp(A), prove2(A, F1, NOW, Praem1), prove2(A, F2, NOW, Praem2).
% (v, literal)
prove2((F1 v F2), A, NOW, oderRegel([F1 v F2, A], Praem)) :-
literalp(A), prove2(F1, A, NOW, Praem).
prove2((F1 v F2), A, NOW, oderRegel([F1 v F2, A], Praem)) :-
literalp(A), prove2(F2, A, NOW, Praem).
% (literal, v)
prove2(A, (F1 v F2), NOW, oderRegel([A, F1 v F2], Praem)) :-
literalp(A), prove2(A, F1, NOW, Praem).
prove2(A, (F1 v F2), NOW, oderRegel([A, F1 v F2], Praem)) :-
literalp(A), prove2(A, F2, NOW, Praem).
% (&, &)
prove2((F1 & F2), (F3 & F4), NOW, undRegel([F1 & F2, F3 & F4], [Praem1, Praem2])) :-
prove2(F1, (F3 & F4), NOW, Praem1), prove2(F2, (F3 & F4), NOW, Praem2).
prove2((F1 & F2), (F3 & F4), NOW, undRegel([F1 & F2, F3 & F4], [Praem1, Praem2])) :-
prove2((F1 & F2), F3, NOW, Praem1), prove2((F1 & F2), F4, NOW, Praem2).
% (&, v)
prove2((F1 & F2), (F3 v F4), NOW, undRegel([F1 & F2, F3 v F4], [Praem1, Praem2])) :-
prove2(F1, (F3 v F4), NOW, Praem1), prove2(F2, (F3 v F4), NOW, Praem2).
prove2((F1 & F2), (F3 v F4), NOW, oderRegel([F1 & F2, F3 v F4], Praem)) :-
prove2((F1 & F2), F3, NOW, Praem).
prove2((F1 & F2), (F3 v F4), NOW, oderRegel([F1 & F2, F3 v F4], Praem)) :-
prove2((F1 & F2), F4, NOW, Praem).
% (v, &)
prove2((F1 v F2), (F3 & F4), NOW, oderRegel([F1 v F2, F3 & F4], Praem)) :-
prove2(F1, (F3 & F4), NOW, Praem).
prove2((F1 v F2), (F3 & F4), NOW, oderRegel([F1 v F2, F3 & F4], Praem)) :-
prove2(F2, (F3 & F4), NOW, Praem).
prove2((F1 v F2), (F3 & F4), NOW, undRegel([F1 & F2, F3 v F4], [Praem1, Praem2])) :-
prove2((F1 v F2), F3, NOW, Praem1), prove2((F1 v F2), F4, NOW, Praem2).
% (v, W)
prove2((F1 v F2), Z, NOW, weakening([F1 v F2, Z], Praem)) :-
NOW > 0, Z \== (F1 v F2), Z \== (F2 v F1),
prove2((F1 v F2), (F1 v F2), NOW - 1, Praem).
% (W, v)
prove2(Z, (F1 v F2), NOW, weakening([Z, F1 v F2], Praem)) :-
NOW > 0, Z \== (F1 v F2), Z \== (F2 v F1),
prove2((F1 v F2), (F1 v F2), NOW - 1, Praem).
% (v, v)
prove2((F1 v F2), (F3 v F4), NOW, oderRegel([F1 v F2, F3 v F4], Praem)) :-
prove2(F1, (F3 v F4), NOW, Praem).
prove2((F1 v F2), (F3 v F4), NOW, oderRegel([F1 v F2, F3 v F4], Praem)) :-
prove2(F2, (F3 v F4), NOW, Praem).
prove2((F1 v F2), (F3 v F4), NOW, oderRegel([F1 v F2, F3 v F4], Praem)) :-
prove2((F1 v F2), F3, NOW, Praem).
prove2((F1 v F2), (F3 v F4), NOW, oderRegel([F1 v F2, F3 v F4], Praem)) :-
prove2((F1 v F2), F4, NOW, Praem).
% --------------------------------------------------------------------------
% zusatzaufgabe 1
writelist([]) :- !.
writelist([X]) :- write(X), !.
writelist([H | T] ) :- write(H), write(', '), writelist(T).
writeKonk(Konk) :-
write('|- '), writelist(Konk), nl.
writeRegel(Str, Konk, Praem) :-
call(Praem),
write('-------------------------------------------------- '), write(Str), nl,
writeKonk(Konk).
oderRegel(Konk, Praem) :-
writeRegel('or', Konk, Praem).
undRegel(Konk, [P1, P2]) :-
writeRegel('and', Konk, P1),
write('================================================== '), nl,
writeRegel('and', Konk, P2).
weakening(Konk, Praem) :-
writeRegel('W', Konk, Praem).
axiom(Konk) :-
writeKonk(Konk).
% --------------------------------------------------------------------------
% prover
:- dynamic(prove_print/0).
prove(IN) :-
nnf(IN, NNF), no_or(NNF, NOR), prove2(NNF, NNF, NOR, DATA), (prove_print, call(DATA); true).
% vim: set noet sw=4 ts=4: