All pastes #200784 Raw Edit

Mine

public text v1 · immutable
#200784 ·published 2006-10-13 11:38 UTC
rendered paste body
/* declaring operators with precedence classes. precedence used is as follows:
 ~(not) higher than /\ (and).
 /\ higher than \/ (or).
 \/ higher than -> (implication).
*/

:- op(400, xfx, /\) .
:- op(800, xfx, nand) .
:- op(500, xfx, \/).
:- op(900, xfx, xor).
:- op(600, xfx, ->).
:- op(700, xfx, <->).
:- op(300, fx, ~).

/* the rules for the logical operators.
   basic principle is that they evaluate to true if the eval of their
   arguments evaluate to true within certain conditions.

   /\ evaluates to true if both its arguments are true.
   /\ evaluates to true if either or both its arguments evaluate to true.
   ~ evaluates to true if its argument evaluates to false (and vice versa)
   => evaluates to true if both its arguments evaluate to true, or its first
      argument evaluates to false.

   the eval functions catch each logical operator and combine the result
   of evaluating its arguments to match the structure of the operator.

   the eval(X) is the base case that checks that X is an atom and that it is tru
e.
*/

eval(X) :- atom(X), true(X).
eval(~X) :- \+ eval(X).
eval(X /\ Y) :- eval(X), eval(Y).
eval(X \/ Y) :- eval(X).
eval(X \/ _) :- eval(Y).
eval(_ \/ Y) :- eval(X), eval(Y).
eval(X xor Y) :- eval(X), \+ eval(Y).
eval(X xor Y) :- eval(Y), \+ eval(X).
eval(X -> _) :- \+ eval(X).
eval(X -> Y) :- eval(X), eval(Y).
eval(X <-> Y) :- \+ eval(X), \+ eval(Y).
eval(X <-> Y) :- eval(X), eval(Y).
eval(X nand Y) :- \+ eval(X /\ Y).

/* any atoms that are to be true within the formula provided are declared as
   true here
*/
true(p).

latom(X) :- atom(X).
latom(~ X) :- atom(X).

/* operator elimination */
elim(X, Z) :- latom(X), Z = (X).
elim(~ X, Z) :- elim(X, P), Z = (~ (P)).
elim(X /\ Y, Z) :- elim(X, P), elim(Y, Q), Z = ((P) /\ (Q)).
elim(X \/ Y, Z) :- elim(X, P), elim(Y, Q), Z = ((P) \/ (Q)).
elim(X -> Y, Z) :- elim(X, P), elim(Y, Q), Z = (~(P) \/ (Q)).
elim(X <-> Y, Z) :- elim(X, P), elim(Y, Q), Z = (((P) /\ (Q)) \/ (~(Q) /\ ~(P)))
.
elim(X nand Y, Z) :- elim(X, P), elim(Y, Q), Z = (~ ((P) /\ (Q))).
elim(X xor Y, Z) :- elim(X, P), elim(Y, Q), elim((P <-> Q), R), Z = (~(R)) .

elimWrite(X) :- elim(X, Z), write(Z).

/* negative normal form */
nnf(X, Z) :- latom(X), Z = (X).
nnf(~ (~ (X)), Z) :- nnf(X, P), Z = P.
nnf(~ (X \/ Y), Z) :- nnf(~ X, P), nnf(~ Y, Q), Z = ((P) /\ (Q)).
nnf(X /\ Y, Z) :- nnf(X, P), nnf(Y, Q), Z = ((P) /\ (Q)).
nnf(X \/ Y, Z) :- nnf(X, P), nnf(Y, Q), Z = ((P) \/ (Q)).
nnf(~ (X /\ Y), Z) :- nnf(~ X, P), nnf(~ Y, Q), Z = ((P) \/ (Q)).

nnfWrite(X) :- nnf(X, Z), write(Z).

/* conjuctive normal form */

cnf(X, Z) :- latom(X), Z = (X).
cnf(X /\ Y, Z) :- cnf(X, P), cnf(Y, Q), Z = ((P) /\ (Q)).
cnf((X /\ Y) \/ W, Z) :- cnf(X, P), cnf(Y, Q), cnf(W, R), Z = (((P) \/ (R)) /\ (
(Q) \/ (R))).
cnf(W \/ (X /\ Y), Z) :- cnf(W, R), cnf(X, P), cnf(Y, Q), Z = ((P) \/ (R)) /\ ((
Q) \/ (R)).
cnf(X \/ Y, Z) :- cnf(X, P), latom(Y), Z = ((P) \/ (Y)).
cnf(X \/ Y, Z) :- latom(X), cnf(Y, P), Z = ((X) \/ (P)).

cnfWrite(X) :- cnf(X, Z), write(Z).