This section gives an example of a complete collection of LISP function definitions which were written to define an algorithm. The program was then run on several test cases. The algorithm itself is explained, and is then written in M-expressions. The complete input card deck and the printed output of the run are reprinted here.
The Wang Algorithm8.1 is a method of deciding whether or not a formula in the prepositional calculus is a theorem. The reader will need to know something about the prepositional calculus in order to understand this discussion.
We quote from pages 5 and 6 of Wang's paper:
"The prepositional calculus (System P)
Since we are concerned with practical feasibility, it is
preferable to use more logical connectives to begin with when we
wish actually to apply the procedure to concrete cases. For this
purpose we use the five usual logical constants
(not),
(conjunction),
(disjunction),
(implication),
(biconditional), with their
usual interpretations.
"A prepositional letter P, Q, R, M or N, et cetera, is a formula
(and an "atomic formula"). If
are formulae, then
are formulae. If
are strings of
formulae (each, in particular, might be an empty string or a
single formula) and
is a formula, then
is a string and
is a sequent which, intuitively speaking, is true if and
only if either some formula in the string
(the "antecedent") is
false or some formula in the string
(the "consequent") is true,
i.e., the conjunction of all formulae in the antecedent implies
the disjunction of all formulae in the consequent.
"There are eleven rules of derivation. An initial rule states that a sequent with only atomic formulae (proposition letters) is a theorem if and only if a same formula occurs on both sides of the arrow. There are two rules for each of the five truth functions - one introducing it into the antecedent, one introducing it into the consequent. One need only reflect on the intuitive meaning of the truth functions and the arrow sign to be convinced that these rules are indeed correct. Later on, a proof will be given of their completeness, i.e., all intuitively valid sequents are provable, and of their consistency, i.e., all provable sequents are intuitively valid.
"Pl. Initial rule: if
are strings of atomic formulae, then
is a theorem if some atomic formula occurs on both sides of
the arrow.
"In the ten rules listed below,
and
are always strings
(possibly empty) of atomic formulae. As a proof procedure in the
usual sense, each proof begins with a finite set of cases of Pl
and continues with successive consequences obtained by the other
rules."
"As will be explained below, a proof looks like a tree structure growing in the wrong direction. We shall, however, be chiefly interested in doing the step backwards, thereby incorporating the process of searching for a proof.
"The rules are so designed that given any sequent, we can find the first logical connective, and apply the appropriate rule to eliminate it, thereby resulting in one or two premises which, taken together, are equivalent to the conclusion. This process can be repeated until we reach a finite set of sequents with atomic formulae only. Each connective-free sequent can then be tested for being a theorem or not, by the initial rule. If all of them are theorems, then the original sequent is a theorem and we obtain a proof; otherwise we get a counter example and a disproof. Some simple samples will make this clear.
"For example, given any theorem of "Principia," we can
automatically prefix an arrow to it and apply the rules to look
for a proof. When the main connective is
, it is simpler,
though not necessary, to replace the main connective by an arrow
and proceed. For example:
*2.45.
,
*5.21.
can be rewritten and proved as follows:
*2.45.
(1)
(2)
(3)
VALID
*5.21.
(1)
(2)
(3)
(4)
(5)
VALID
(5)
VALID
P2a. Rule
P2b. Rule
P3a. Rule
P3b. Rule
P4a. Rule
P4b. Rule
P5a. Rule
P5b. Rule
P6a. Rule
P6b. Rule
(2) The LISP Program. We define a function theorem[s] whose value is truth or falsity according to whether the sequent s is theorem.
The sequent
is represented by the S-expression
: (ARROW, (
))
where in each case the ellipsis ...denotes missing terms, and
where
denotes the S-expression for
.
Propositional formulae are represented as follows:
1. For "atomic formulae" (Wang's terminology) we use "atomic symbols" (LISP terminology).
2. The following table gives our "Cambridge Polish" way of representing prepositional formulae with given main connectives.
1.
becomes (NOT
)
2.
becomes (AND
)
3.
becomes (OR
)
4.
becomes (IMPLIES
)
5.
becomes (EQUIV
)
Thus the sequent
is represented by
(ARROW ((AND (NOT P) (NOT Q))) ((EQUIV P Q) (OR R S)))
The S-function theorem[s] is given in terms of auxiliary functions as follows:
theorem[s] = thl[NIL;NIL;cadr[s];caddr[s]]
th1[a1;a2;a;c] = [null[a]
th2[a1;a2;NIL;NIL;c];T
member[car[a];c]
[atom [car [a]]
thl[[member[car[a];a1]
a1;
T
cons[car[a];a1]];a2;cdr[a];c];T
thl[a1;[
member[car[a];a2]
a2;T
cons[
car[a];a2]];cdr[a];c]]]
th2[a1;a2;c1;c2;c] = [null[c]
th[a1;a2;c1;c2];atom[
car[c]]
th2[a1;a2;[member[car[
c];c1]
c1; T
cons[car[c];c1]];
c2;cdr[c]];T
th2[a1;a2;c1;[
member[car[c];c2]
c2;T
cons[
car[c];c2]];cdr[c]]]
th[a1;a2;c1;c2] = [null[a2]
null[c2]
thr[car[c2];
a1;a2;c1;cdr[c2]];T
thl[car[a2];
a1;cdr[a2];c1;c2]]
th is the main predicate through which all the recursions take place, theorem, th1 and th2 break up and sort the information in the sequent for the benefit of th. The four arguments of th are:
a1: atomic formulae on left side of arrow a2: other formulae on left side of arrow c1: atomic formulae on right side of arrow c2: other formulae on right side of arrow
The atomic formulae are kept separate from the others in order to make faster the detection of the occurrence of formula on both sides of the arrow and the finding of the next formula to reduce. Each use of th represents one reduction according to one of the 10 rules. The forumla to be reduced is chosen from the left side of the arrow if possible. According to whether the formula to be reduced is on the left or right we use thl or thr. We have
thl[u;a1;a2;c1;c2] = [
car[u] = NOT
th1r[cadr[u];a1;a2;c1;c2];
car[u] = AND
th2l[cdr[u];a1;a2;c1;c2];
car[u] = OR
th1l[cadr[u];a1;a2;c1;c2]
th1l
caddr[u];a1;a2;c1;c2];
car[u] = IMPLIES
th1l[caddr[u];a1 ;a2;c1;c2]
th1r
cadr[u];a1;a2;c1;c2];
car[u] = EQUIV
th2l[cdr[u];a1;a2;c1;c2]
th2r
cdr[u];a1;a2;c1;c2];
T
error[list[THL;u;a1;a2;c1;c2]]]
thr[u;a1;a2;c1;c2] = [
car[u] = NOT
th1l[cadr[u];a1;a2;c1;c2];
car[u] = AND
th1r[cadr[u];a1;a2;c1;c2]
th1r
caddr[u];a1;a2;c1;c2];
car[u] = OR
th2r[cdr[u];a1;a2;c1;c2];
car[u] = IMPLIES
th11[cadr[u];caddr[u];a1;a2;c1;c2];
car[u] = EQUIV
th11[cadr[u];caddr[u];a1;a2;c1;c2]
th11[caddr[u];cadr[u];a1;a2;c1;c2];
T
error[THR;u;a1;a2;c1;c2]]]
The functions th1l, th1r, th2l, th2r, th11 distribute the parts of the reduced formula to the appropriate places in the reduced sequent.
These functions are
th1l[v;a1;a2;c1;c2] = [atom[v]
member[v;c1]
th[cons[v;a1];a1;c1;c2];T
member[v;c2]
th[a1;cons[v;a2];c1;c2]]
th1r[v;a1;a2;c1;c2] = [atom[v]
member[v;a1]
th[a1;a2;cons[v;c1];c2];T
member[v;a2]
th[a1;a2;c1;cons[v;c2]]]
th2l[v;a1;a2;c1;c2] = [atom[car[v]]
member[car[v];c1]
th1l[cadr[v];cons[car[v];a1];a2;c1;c2];T
member[
car[v];c2]
th1l[cadr[v];a1;cons[car[v];a2];c1;c2]]
th2r[v;a1;a2;c1;c2] = [atom[car[v]]
member[car[v];a1]
th1r[cadr[v];a1;a2;cons[car[v];c1];c2];T
member [
car[v];a2]
th1r[cadr[v];a1;a2;c1;cons [car [v];c2]]]
th1l[v1;v2;a1;a2;c1;c2] = [atom[v1]
member[v1;c1]
thlr[v2;cons[v1;a1];a2;c1;c2];T
member[v1;c2]
th1r[v2;a1;cons[v1;a2];cl ;c2]]
Finally the function member is defined by
member[x;u] =
null[u]
[equal[x;car[u]]
member[x;cdr[u]]]
The entire card deck is reprinted below, with only the two loader cards, which are binary, omitted. The function member is not defined because it is already in the system.
* M948-1207 LEVIN, LISP, TEST, 2,3,250,0
TEST WANG ALGORITHM FOR THE PROPOSITIONAL CALCULUS
DEFINE ((
(THEOREM (LAMBDA (S) (TH1 NIL NIL (CADR S) (CADDR S))))
(TH1 (LAMBDA (A1 A2 A C) (COND ((NULL A)
(TH2 A1 A2 NIL NIL C)) (T
(OR (MEMBER (CAR A) C) (COND ((ATOM (CAR A))
(TH1 (COND ((MEMBER (CAR A) A1) A1)
(T (CONS (CAR A) A1))) A2 (CDR A) C))
(T (TH1 A1 (COND ((MEMBER (CAR A) A2) A2)
(T (CONS (CAR A) A2))) (CDR A) C))))))))
(TH2 (LAMBDA (A1 A2 C1 C2 C) (COND
((NULL C) (TH A1 A2 C1 C2))
((ATOM (CAR C)) (TH2 A1 A2 (COND
((MEMBER (CAR C) C1) C1) (T
(CONS (CAR C) C1))) C2 (CDR C)))
(T (TH2 A1 A2 C1 (COND ((MEMBER
(CAR C) C2) C2) (T (CONS (CAR C) C2)))
(CDR C))))))
(TH (LAMBDA (A1 A2 C1 C2) (COND ((NULL A2) (AND (NOT (NULL C2))
(THR (CAR C2) A1 A2 C1 (CDR C2)))) (T (THL (CAR A2) A1 (CDR A2)
C1 C2)))))
(THL (LAMBDA (U A1 A2 C1 C2) (COND
((EQ (CAR U) (QUOTE NOT)) (TH1R (CADR U) A1 A2 C1 C2))
((EQ (CAR U) (QUOTE AND)) (TH2L (CDR U) A1 A2 C1 C2))
((EQ (CAR U) (QUOTE OR)) (AND (TH1L (CADR U) A1 A2 C1 C2)
(TH1L (CADDR U) A1 A2 C1 C2) ))
((EQ (CAR U) (QUOTE IMPLIES)) (AND (TH1L (CADDR U) A1 A2 C1
C2) (TH1R (CADR U) A1 A2 C1 C2) ))
((EQ (CAR U) (QUOTE EQUIV)) (AND (TH2L (CDR U) A1 A2 C1 C2)
(TH2R (CDR U) A1 A2 C1 C2) ))
(T (ERROR (LIST (QUOTE THL) U A1 A2 C1 C2)))
)))
(THR (LAMBDA (U A1 A2 C1 C2) (COND
((EQ (CAR U) (QUOTE NOT)) (TH1L (CADR U) A1 A2 C1 C2))
((EQ (CAR U) (QUOTE AND)) (AND (TH1R (CADR U) A1 A2 C1 C2)
(TH1R (CADDR U) A1 A2 C1 C2) ))
((EQ (CAR U) (QUOTE OR)) (TH2R (CDR U) A1 A2 C1 C2))
((EQ (CAR U) (QUOTE IMPLIES)) (TH11 (CADR U) (CADDR U)
A1 A2 C1 C2))
((EQ (CAR U) (QUOTE EQUIV)) (AND (TH11 (CADR U) (CADDR U)
A1 A2 C1 C2) (TH11 (CADDR U) (CADR U) A1 A2 C1 C2) ))
(T (ERROR (LIST (QUOTE THR) U A1 A2 C1 C2)))
)))
(TH1L (LAMBDA (V A1 A2 C1 C2) (COND
((ATOM V) (OR (MEMBER V C1)
(TH (CONS V A1) A2 C1 C2) ))
(T (OR (MEMBER V C2) (TH A1 (CONS V A2) C1 C2) ))
)))
(TH1R (LAMBDA (V A1 A2 C1 C2) (COND
((ATOM V) (OR (MEMBER V A1)
(TH A1 A2 (CONS V C1) C2) ))
(T (OR (MEMBER V A2) (TH A1 A2 C1 (CONS V C2))))
)))
(TH2L (LAMBDA (V A1 A2 C1 C2) (COND
((ATOM (CAR V)) (OR (MEMBER (CAR V) C1)
(TH1L (CADR V) (CONS (CAR V) A1) A2 C1 C2)))
(T (OR (MEMBER (CAR V) C2) (TH1L (CADR V) A1 (CONS (CAR V)
A2) C1 C2)))
)))
(TH2R (LAMBDA (V A1 A2 C1 C2) (COND
((ATOM (CAR V)) (OR (MEMBER (CAR V) A1)
(TH1R (CADR V) A1 A2 (CONS (CAR V) C1) C2)))
(T (OR (MEMBER (CAR V) A2) (TH1R (CADR V) A1 A2 C1
(CONS (CAR V) C2))))
)))
(TH11 (LAMBDA (VI V2 A1 A2 C1 C2) (COND
((ATOM VI) (OR (MEMBER VI C1) (TH1R V2 (CONS VI A1) A2 C1
C2)))
(T (OR (MEMBER VI C2) (TH1R V2 A1 (CONS VI A2) C1 C2)))
)))
))
TRACE ((THEOREM TH1 TH2 TH THL THR TH1L TH1R TH2L TH2R TH11))
THEOREM
((ARROW (P) ((OR P Q))))
UNTRACE ((THEOREM TH1 TH2 THR THL TH1L TH1R TH2L TH2R TH11))
THEOREM
((ARROW ((OR A (NOT B))) ((IMPLIES (AND P Q) (EQUIV P Q))) ))
STOP))) ))) ))) )))
FIN END OF LISP RUN M948-1207 LEVIN
This run produced the following output:
* M948-1207 LEVIN, LISP, TEST, 2, 3, 250, 0
TEST WANG ALGORITHM FOR THE PROPOSITIONAL CALCULUS
THE TIME (8/ 8 1506. 1) HAS COME, THE WALRUS SAID, TO TALK OF MANY THINGS
...- LEWIS CARROLL -
FUNCTION EVALQUOTE HAS BEEN ENTERED, ARGUMENTS..
DEFINE
[ The complete list of definitions read in is omitted to save space.]
END OF EVALQUOTE. VALUE IS..
(THEOREM TH1 TH2 TH THL THR TH1L TH1R TH2L TH2R TH11)
FUNCTION EVALQUOTE HAS BEEN ENTERED, ARGUMENTS..
TRACE
((THEOREM TH1 TH2 TH THL THR TH1L TH1R TH2L TH2R TH11))
END OF EVALQUOTE, VALUE IS..
NIL
FUNCTION EVALQUOTE HAS BEEN ENTERED. ARGUMENTS..
THEOREM
((ARROW (P) ((OR P Q))))