home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
educatin
/
csa.arc
/
CSA.LSP
< prev
next >
Wrap
Lisp/Scheme
|
1987-05-21
|
34KB
|
783 lines
;************************************************************************
;* *
;* program : CSA *
;* author : Chris Lord *
;* version : 3.17 (5/21/87) *
;* date : February 18, 1987 *
;* *
;* Copyright (c) 1987 by Chris Lord *
;* *
;* This program was written for a course in logic and lisp at FSC *
;* as a learning experience. Having served its purpose, the author *
;* contributes this code to the public domain so that others may also *
;* learn. I would be interested in any suggestions/improvements/bugs *
;* anyone finds. Please address all comments to: *
;* *
;* Chris Lord *
;* 38 Main Street *
;* Princeton, MA 01541 *
;* DEC ENET RAINBO::LORD *
;* *
;************************************************************************
;************************************************************************
;* *
;* program description *
;* *
;* This program is the first step in determining the validity of *
;* standard (and some non-standard) categorical syllogisms. The *
;* the validity of a syllogism is based on a collection of eight *
;* rules, seven of which are implemented in this version. See the *
;* accompanying manual for a completed description as well as a *
;* short tutorial in syllogism logic. *
;* *
;* edit history *
;* *
;* 3.15 add check for same premisses in main routine CSA to catch *
;* some other bad syllogism (ccl 5/13/87) *
;* 3.16 add further syllogism checks in function CSA (ccl 5/14/87) *
;* 3.17 add heuristic for dealing with subjects that are single *
;* atoms to format_prop (ccl 5/21/87) *
;* 3.18 add list of atoms to strip from props when parsing such as *
;* (the an a) (not yet) *
;* *
;************************************************************************
;************************************************************************
;* *
;* data declarations *
;* *
;* these are global symbols that are currently used by only single *
;* functions -- this is likely to change. *
;* *
;************************************************************************
;+
; this is the set of univeral-affirmative quantifiers that may appear
; in the proposition. Any member is replaced with the standard
; quantifier ALL
;-
(setq universal_affirm '(all every any everything anything everyone
anyone whoever whoso who whatever a an the))
;+
; this is the set of univeral-negative quantifiers that may appear
; in the proposition. Any member is replaced with the standard
; quantifier NO
;-
(setq universal_neg '(no none nothing no-one))
;+
; this is the set of particular quantifiers (quality is determined
; by the verb adjunct 'not') that may appear in the propostion.
; Any member is replaced with the standard quantifier SOME
;-
(setq particular_quantifiers '(some most many few))
;+
; this is the set of words that precede a form of the verb 'to be'
; an indicate (generally) that it is not the verb of the proposition
; as in: all men who are green are frogs
;-
(setq non_verb_preds '(who whom that))
;+
; this is the error code table, each error has a code followed
; by the actual error text
;-
(setq error_codes '(badprop "bad proposition encountered"
badquan "bad quantifier encountered"
badsubj "bad subject encountered"
badverb "bad verb encountered"
badpred "bad predicate encountered"
badform "bad form encountered"
badsyll "bad syllogism encountered"))
;************************************************************************
;* *
;* rule base *
;* *
;* the following functions are each responsible for checking a given *
;* form against one of the rules for valid functions. Rules return *
;* nil if they pass, something else otherwise. Every rule is passed *
;* the form of the syllogism in (n x x x) form. *
;* *
;************************************************************************
;+
; the following are inherent characteristics of each type of syllogism
; used in creating the rules:
;
; type quantity quality S P
; ---- ---------- ----------- --- ---
; A universal affirmative D U
; E universal negative D D
; I particular affirmative U U
; O particular negative U D
;
; where: U is undistributed S is subject
; D is distributed P is predicate
;-
;+
; Rule 1: A categorical syllogism must contain three and only
; three terms or it commits the fallacy of four terms.
;
; this rule cannot be implemented without an extensive knowledge of
; english vocabulary. It is in this rule that ambiguous class
; descriptors and the misuse of synonyms are caught. Often times
; this rule is also used to catch syllogisms with no middle term.
;-
(defun rule_1 (form)
nil)
;+
; Rule 2: The middle term must be distributed at least once
; or it commits the fallacy of undistributed middle.
;-
(defun rule_2 (form)
(setq p1 (cadr form)) ; type of prop 1
(setq p2 (caddr form)) ; type of prop 2
(not (case (car form)
(1 (or (member p1 '(A E)) (member p2 '(E O))))
(2 (or (member p1 '(E O)) (member p2 '(E O))))
(3 (or (member p1 '(A E)) (member p2 '(A E))))
(4 (or (member p1 '(E O)) (member p2 '(A E)))))))
;+
; Rule 3: No term may be distributed in the conclusion which
; is undistributed in the premisses or it commits the fallacy
; of illicit major or minor.
;
; this rule is in two parts. Part A checks for illicit major;
; part B checks for illicit minor.
;-
(defun rule_3A (form)
(setq p1 (cadr form)) ; type of prop 1
(setq p2 (caddr form)) ; type of prop 2
(and
(member (cadddr form) '(E O))
(case (car form)
(1 (member p1 '(A I)))
(2 (member p1 '(I O)))
(3 (member p1 '(A I)))
(4 (member p1 '(I O))))))
(defun rule_3B (form)
(setq p1 (cadr form)) ; type of prop 1
(setq p2 (caddr form)) ; type of prop 2
(and
(member (cadddr form) '(A E))
(case (car form)
(1 (member p1 '(I O)))
(2 (member p1 '(I O)))
(3 (member p1 '(A I)))
(4 (member p1 '(A I))))))
;+
; Rule 4: No categorical syllogism can have two negative
; premisses or it commits the fallacy of exclusive
; premisses.
;-
(defun rule_4 (form)
(setq p1 (cadr form)) ; type of prop 1
(setq p2 (caddr form)) ; type of prop 2
(and (member p1 '(E O)) (member p2 '(E O))))
;+
; Rule 5: If either premiss if negative, the conclusion must
; be negative or it commits the fallacy of drawing an
; affirmative conclusion from a negative premiss.
;-
(defun rule_5 (form)
(setq p1 (cadr form)) ; type of prop 1
(setq p2 (caddr form)) ; type of prop 2
(and (or (member p1 '(E O)) (member p2 '(E O)))
(member (cadddr form) '(A I))))
;+
; Rule 6: A categorical proposition must have at least on
; universal premiss or it commits the fallacy of two
; particulars.
;-
(defun rule_6 (form)
(setq p1 (cadr form)) ; type of prop 1
(setq p2 (caddr form)) ; type of prop 2
(and (member p1 '(I O)) (member p2 '(I O))))
;+
; Rule 7: If one premiss is particular, the conclusion must
; be particular or it commits the fallacy of drawing a
; universal conclusion from a particular premiss.
;-
(defun rule_7 (form)
(setq p1 (cadr form)) ; type of prop 1
(setq p2 (caddr form)) ; type of prop 2
(and (or (member p1 '(I O)) (member p2 '(I O)))
(member (cadddr form) '(A E))))
;+
; Rule 8: (existential interpretation only) A particular
; conclusion cannot have two universal premisses or it
; commits the existential fallacy.
;-
(defun rule_8 (form)
(setq p1 (cadr form)) ; type of prop 1
(setq p2 (caddr form)) ; type of prop 2
(and (and (member p1 '(A E)) (member p2 '(A E)))
(member (cadddr form) '(I O))))
(defun rule_check (form)
(cond
((rule_2 form)
(princ "this syllogism commits the fallacy")
(princ " of an undistributed middle term"))
((rule_3A form)
(princ "this syllogism commits the fallacy")
(princ " of illicit major"))
((rule_3B form)
(princ "this syllogism commits the fallacy")
(princ " of illicit minor"))
((rule_4 form)
(princ "this syllogism commits the fallacy")
(princ " of exclusive premisses"))
((rule_5 form)
(princ "this syllogism commits the fallacy")
(princ " of drawing an") (terpri)
(princ "affirmative conclusion from a negative premiss"))
((rule_6 form)
(princ "this syllogism commits the fallacy")
(princ " of two particulars"))
((rule_7 form)
(princ "this syllogism commits the fallacy")
(princ " of drawing a universal") (terpri)
(princ "conclusion from a particular premiss"))
((rule_8 form)
(princ "this syllogism commits the existential")
(princ " fallacy under boolean interpretation") (terpri)
(princ "under aristotelean interpretation, this syllogism is valid"))
(T (princ "this is a valid syllogism under both boolean") (terpri)
(princ "and aristotelean interpretation"))))
;************************************************************************
;* *
;* error reporter *
;* *
;* this function isolates our error-trapping (without binding the *
;* code to XLISP specific features). It uses the error_code list. *
;* Any call to this must include the error code, function/routine, *
;* and the offending expression. This function does not return! *
;* *
;************************************************************************
(defun error (code operation expr)
(princ "error: ")
(princ (cadr (member code error_codes)))
(terpri)
(princ " ")
(princ operation)
(terpri)
(princ " in ")
(print expr)
(terpri)
(top-level))
;************************************************************************
;* *
;* toolbox functions *
;* *
;* the following are a collection of very short utility functions. *
;* In most cases, they serve to isolate the main functions from the *
;* actual data structures used. In others, they provide useful *
;* functions that may be shared (some are currently only used by *
;* single functions). *
;* *
;************************************************************************
;+
; these four functions return various components of a formatted
; proposition: quantifier, subject, verb, predicate. Here we
; also do some checking and return an appropriate error if we
; can't get the needed component
;-
(defun quantifier (prop) ; returns quantifier as atom
(cond
((caar prop))
((error 'badquan "while fetching quantifier" prop))))
(defun subject (prop) ; returns subject as list
(cond
((cadr prop))
((error 'badsubj "while fetching subject" prop))))
(defun verb_copula (prop) ; returns verb as list
(cond
((caddr prop))
((error 'badverb "while fetching verb" prop))))
(defun predicate (prop) ; returns predicate as list
(cond
((cadddr prop))
((error 'badpred "while fetching predicate" prop))))
;+
; these three functions return the terms of a syllogism.
; Note: the syllogism mus be formatted (major,minor,conc form)
;-
(defun major_term (syl)
(predicate (caddr syl)))
(defun minor_term (syl)
(subject (caddr syl)))
(defun middle_term (syl)
(cond
((equal (predicate (car syl)) (major_term syl)) (subject (car syl)))
(T (predicate (car syl)))))
;+
; function converts anything that looks like a verb form of 'to be'
; into either 'are' or 'are not'. This is for analysis in the
; proposition formatter.
;-
(defun is_to_are (prop)
(cond
((null prop) nil)
((eq (car prop) 'is) (cons 'are (is_to_are (cdr prop))))
((eq (car prop) 'was) (cons 'are (is_to_are (cdr prop))))
((eq (car prop) 'were) (cons 'are (is_to_are (cdr prop))))
((eq (car prop) 'wasnt) (append '(are not) (is_to_are (cdr prop))))
((eq (car prop) 'werent) (append '(are not) (is_to_are (cdr prop))))
((eq (car prop) 'isnt) (append '(are not) (is_to_are (cdr prop))))
((eq (car prop) 'arent) (append '(are not) (is_to_are (cdr prop))))
(T (cons (car prop) (is_to_are (cdr prop))))))
;+
; simple function to count the number of are's in the passed
; proposition (unformatted).
;-
(defun count_are (prop)
(cond
((null prop) 0)
((eq (car prop) 'are) (1+ (count_are (cdr prop))))
(T (count_are (cdr prop)))))
;+
; simple function to return leftmost len s-exprs in a list
;-
(defun left (prop len)
(cond
((= len 0) nil)
(T (cons (car prop) (left (cdr prop) (1- len))))))
;+
; simple function to return rightmost len s-exprs in a list
;-
(defun right (prop len)
(reverse (left (reverse prop) len)))
;************************************************************************
;* *
;* proposition formatter *
;* *
;* function accepts a prop in (quantifier subject verb predicate) *
;* form where parts are not necessarily atoms as in (all men that are *
;* green are jealous men). Returns the same prop broken into lists *
;* that represent the various components as in ((quantifier) (subject) *
;* (verb) (predicate)). *
;* *
;************************************************************************
(defun format_prop (prop)
;+
; fist step is to convert all forms of the verb 'to be' into something
; common -- are. Proposition is then broken into predicate and
; subject based on the number of are's in it
;-
(setq old_prop (is_to_are prop)) ; old_prop use to be prop (unedited)
(setq temp_prop old_prop) ; this has been added for debugging
(case (count_are temp_prop)
;+
; if there are 0 or 4 are's then we have an invalid proposition
;-
(0 (error 'badprop "while trying to format" prop))
(4 (error 'badprop "while trying to format" prop))
;+
; if there is one are, then it is most likely the verb of the
; proposition
;-
(1 (setq temp_subject
(reverse (cdr (member 'are (reverse temp_prop)))))
(setq temp_predicate (cdr (member 'are temp_prop))))
;+
; new routine to format for two are's -- this is the most difficult
; case. This uses the presence of certain key words before one
; of the ares (that who whom) to identify the one that is NOT the
; verb. This will work in the majority cases and definitely more
; often than the old routine which was based on placement.
;-
(2 (cond
((member (cadr (member 'are (reverse temp_prop))) non_verb_preds)
(setq temp_subject (reverse (cdr (member 'are (cdr (member 'are (reverse temp_prop)))))))
(setq temp_predicate (cdr (member 'are temp_prop))))
((member (cadr (member 'are (cdr (member 'are (reverse temp_prop))))) non_verb_preds)
(setq temp_subject (reverse (cdr (member 'are (reverse temp_prop)))))
(setq temp_predicate (cdr (member 'are (cdr (member 'are temp_prop))))))
(T (error 'badverb "while determining verb copula" old_prop))
))
;+
; old routine to handle presence of two are's
;
; (2 (cond
; ((<= (length (member 'are (cdr (member 'are (cdr temp_prop)))))
; ((<= (length (cdr (member 'are (cdr (member 'are (cdr temp_prop))))))
; (- (length (cdr temp_prop))
; (length (member 'are (cdr temp_prop)))))
; (setq temp_subject
; (left old_prop
; (length (cdr (member 'are
; (reverse temp_prop))))))
; (setq temp_predicate
; (cdr (member 'are (cdr (member 'are temp_prop))))))
; (T (setq temp_subject
; (left old_prop (length (cdr (member 'are
; (cdr (member 'are (reverse temp_prop))))))))
; (setq temp_predicate
; (right old_prop (length (cdr (member 'are temp_prop))))))))
;-
;+
; if there are three are's in the temp prop, then the verb is
; most likely the middle one
;-
(3 (setq temp_subject
(left old_prop (length (cdr (member 'are
(cdr (member 'are (reverse temp_prop))))))))
(setq temp_predicate
(right old_prop (length (cdr (member 'are
(cdr (member 'are temp_prop)))))))))
(setq temp_verb (last (left old_prop (1+ (length temp_subject)))))
(cond
( (eq (car temp_predicate) 'not)
(setq temp_verb (append temp_verb '(not)))
(setq temp_predicate (cdr temp_predicate))))
; (ccl 5/21/87 3.17)
(cond
((equal (length temp_subject) 1)
(setq temp_quantifier '(all)))
(T
(setq temp_quantifier (list (car temp_subject)))
(setq temp_subject (cdr temp_subject))))
(list temp_quantifier temp_subject temp_verb temp_predicate))
;************************************************************************
;* *
;* proposition evaluator *
;* *
;* simply returns the type of the passed propositon. Works on the *
;* assumption that quantifier in (all no some) and verb in (is, are, *
;* is not, are not). *
;* *
;************************************************************************
(defun eval_prop (prop)
(case (quantifier prop)
('all 'a)
('no 'e)
('some (if (= (length (verb_copula prop)) 2) 'o 'i))))
;************************************************************************
;* *
;* propositon filter *
;* *
;* function filters non-standard terms from the proposition. *
;* Presently, only handle easy non-standard quantifers, but in the *
;* future, will likely allow the filtering of synonyms, antonyms and *
;* plural forms to common terms. *
;* *
;************************************************************************
(defun filter_prop (prop)
(cond
((member (quantifier prop) universal_affirm)
(cons (list (car universal_affirm)) (cdr prop)))
((member (quantifier prop) universal_neg)
(cons (list (car universal_neg)) (cdr prop)))
((member (quantifier prop) particular_quantifiers)
(cons (list (car particular_quantifiers)) (cdr prop)))
((error 'badquan "while filtering quantifiers" prop))))
;************************************************************************
;* *
;* syllogism reader *
;* *
;* Reads the syllogism from stdin in premiss, premiss, conclusion *
;* order; returns all propositions in a list. *
;* *
;************************************************************************
(defun read_syl ()
(princ "enter a premiss ")
(setq temp_prop1 (read))
(princ "enter a premiss ")
(setq temp_prop2 (read))
(princ "enter conclusion")
(setq temp_conc (read))
(list temp_prop1 temp_prop2 temp_conc))
;************************************************************************
;* *
;* syllogism formatter *
;* *
;* The syllogism formatter takes as input a complete syllogism in *
;* which the conclusion is last and the premisses are in either order. *
;* It returns the syllogism with the major premiss first followed *
;* by the minor premiss and the conclusion. *
;* *
;************************************************************************
;+
; conclusion does the main work of format_syl
;-
(defun conclusion (prop1 prop2 prop3)
(cond
((and
(or (equal (predicate prop1) (subject prop2))
(equal (predicate prop1) (subject prop3))
(equal (predicate prop1) (predicate prop2))
(equal (predicate prop1) (predicate prop3)))
(or (equal (subject prop1) (subject prop2))
(equal (subject prop1) (subject prop3))
(equal (subject prop1) (predicate prop2))
(equal (subject prop1) (predicate prop3))))
(list (cond
((equal (predicate prop1) (subject prop2)) prop2)
((equal (predicate prop1) (subject prop3)) prop3)
((equal (predicate prop1) (predicate prop2)) prop2)
((equal (predicate prop1) (predicate prop3)) prop3)
((error 'badprop "while finding major premiss"
prop1)))
(cond
((equal (subject prop1) (subject prop2)) prop2)
((equal (subject prop1) (subject prop3)) prop3)
((equal (subject prop1) (predicate prop2)) prop2)
((equal (subject prop1) (predicate prop3)) prop3)
((error 'badprop "while finding minor premiss" prop1)))
prop1))
(T nil)))
;+
; format_syl was more adventurous at first, until it was discovered
; it was not possible to determine the premisses and conclusion
; given the props in any order, hence the breaking of of the fns
;-
(defun format_syl (syl)
(cond
((conclusion (caddr syl) (car syl) (cadr syl)))
; ((conclusion (car syl) (cadr syl) (caddr syl)))
; ((conclusion (cadr syl) (caddr syl) (car syl)))
((error 'badsyll "while determining major/minor premisses"
(caddr syl)))))
;************************************************************************
;* *
;* syllogism form *
;* *
;* this function determines the form of the syllogism based on the *
;* position of the middle term in the premisses and the type of each *
;* proposition. *
;* *
;************************************************************************
(defun form (syl)
(cons
(cond
( (and (equal (middle_term syl) (subject (car syl)))
(equal (middle_term syl) (predicate (cadr syl)))) '1)
( (and (equal (middle_term syl) (predicate (car syl)))
(equal (middle_term syl) (predicate (cadr syl)))) '2)
( (and (equal (middle_term syl) (subject (car syl)))
(equal (middle_term syl) (subject (cadr syl)))) '3)
( (and (equal (middle_term syl) (predicate (car syl)))
(equal (middle_term syl) (subject (cadr syl)))) '4)
((error 'badform "while finding figure" syl)))
(list (eval_prop (car syllogism))
(eval_prop (cadr syllogism))
(eval_prop (caddr syllogism)))))
;************************************************************************
;* *
;* csa (main) *
;* *
;* this is the main function; it reads the syllogism, parses it and *
;* returns the results. Note that some of the information (such as *
;* how it was parsed) was left here for my use, it is not necessary *
;* for the casual user. *
;* *
;************************************************************************
(defun csa ()
(setq temp_syl (read_syl))
(setq syllogism (format_syl (list
(filter_prop (format_prop (car temp_syl)))
(filter_prop (format_prop (cadr temp_syl)))
(filter_prop (format_prop (caddr temp_syl))))))
; (ccl 5/13/87 3.15)
; (ccl 5/14/87 3.16)
(if (or (equal (car syllogism) (cadr syllogism))
(equal (car syllogism) (caddr syllogism))
(equal (cadr syllogism) (caddr syllogism)))
(error 'badsyll "after formatting major/minor premisses"
(caddr syllogism)))
(terpri)
(princ "major premiss: ") (print (car syllogism))
(princ "minor premiss: ") (print (cadr syllogism))
(princ "conclusion: ") (print (caddr syllogism))
(terpri)
(princ "major term: ") (print (major_term syllogism))
(princ "minor term: ") (print (minor_term syllogism))
(princ "middle term: ") (print (middle_term syllogism))
(terpri)
(setq syl_form (form syllogism))
(princ "mood: ") (print (cdr syl_form))
(princ "figure: ") (print (car syl_form))
(terpri)
(rule_check syl_form)
(terpri)
(terpri))
;************************************************************************
;* *
;* csa test *
;* *
;* this function accepts a syllogism ( (prop) (prop) (conc) ) and *
;* procedes like function csa, used mostly as a debug routine to test *
;* a set of test syllogisms. *
;* *
;************************************************************************
(defun csa_test (temp_syl)
(princ "testing the following proposition:") (terpri) (terpri)
(princ "premiss 1: ") (print (car temp_syl))
(princ "premiss 2: ") (print (cadr temp_syl))
(princ "conclusion: ") (print (caddr temp_syl)) (terpri)
(setq syllogism (format_syl (list
(filter_prop (format_prop (car temp_syl)))
(filter_prop (format_prop (cadr temp_syl)))
(filter_prop (format_prop (caddr temp_syl))))))
; (ccl 5/13/87 3.15)
; (ccl 5/14/87 3.16)
(if (or (equal (car syllogism) (cadr syllogism))
(equal (car syllogism) (caddr syllogism))
(equal (cadr syllogism) (caddr syllogism)))
(error 'badsyll "after formatting major/minor premisses"
(caddr syllogism)))
(princ "major premiss: ") (print (car syllogism))
(princ "minor premiss: ") (print (cadr syllogism))
(princ "conclusion: ") (print (caddr syllogism))
(terpri)
(princ "major term: ") (print (major_term syllogism))
(princ "minor term: ") (print (minor_term syllogism))
(princ "middle term: ") (print (middle_term syllogism))
(terpri)
(setq syl_form (form syllogism))
(princ "mood: ") (print (cdr syl_form))
(princ "figure: ") (print (car syl_form))
(terpri)
(rule_check syl_form)
(terpri)
(terpri))
;************************************************************************
;* *
;* rule test and verify *
;* *
;* these functions check the validity of all possible (256) standard *
;* form categorical syllogisms. It is assumed the file CSA_GEN.LSP *
;* has been created by CSA_GEN.COM; output will go to stdout and *
;* CSA_GEN.TXT for verification by a logical human beastie. *
;* *
;************************************************************************
(defun rule_test (form)
(princ "form: ")
(print form)
(rule_check form)
(terpri)
(princ "----------------------------------------------")
(terpri))
(defun rule_verify ()
(princ "generating a list of validity checks for all 256") (terpri)
(princ "possible syllogism forms as stored in csa_gen.lsp") (terpri)
(princ "output will be in csa_gen.txtas well as here") (terpri)
(terpri)
(transcript "csa_gen.txt")
(load 'csa_gen.lsp)
(transcript))
;************************************************************************
;* *
;* *
;************************************************************************
(terpri)
(princ "Catagorical Syllogism Analyzer") (terpri)
(princ "Version 3.17 May 21, 1987") (terpri)
(princ "(c) Copyright 1987, Chris Lord") (terpri) (terpri)
(top-level)