;; Equational Proof Procedures Using Matching ;; Albert R. Meyer 2/24/03 (define (axioms) '( ((?e = ?e) reflexivity) ((((?e + ?f) + ?g) = (?e + (?f + ?g))) associativity+) ((((?e * ?f) * ?g) = (?e * (?f * ?g))) associativity*) (((?e + ?f) = (?f + ?e)) commutativity+) (((?e * ?f) = (?f * ?e)) commutativity*) (((0 + ?e) = ?e) identity+) (((1 * ?e) = ?e) identity*) (((?e + (- ?e)) = 0) inverse+) (((?e * (?f + ?g)) = ((?e * ?f) + (?e * ?g))) distributivity) )) (define (one-antecedent-inferences) ;of the form (?consequent ?name ~antecedents) '( ((?f = ?e) symmetry (?e = ?f)) (((- ?e) = (- ?f)) congruence- (?e = ?f)) )) (define (two-antecedent-inferences) ;of the form (?consequent ?name ~antecedents) ;two versions of each inference so the order of the antecedents doesn't matter '( (((?e1 + ?f1) = (?e2 + ?f2)) congruence+ (?e1 = ?e2) (?f1 = ?f2)) (((?e1 + ?f1) = (?e2 + ?f2)) congruence+ (?f1 = ?f2) (?e1 = ?e2)) (((?e1 * ?f1) = (?e2 * ?f2)) congruence* (?e1 = ?e2) (?f1 = ?f2)) (((?e1 * ?f1) = (?e2 * ?f2)) congruence* (?f1 = ?f2) (?e1 = ?e2)) ((?e = ?g) transitivity (?e = ?f) (?f = ?g)) ((?e = ?g) transitivity (?f = ?g) (?e = ?f)) )) (define (try-axiom axiom proof-sequence) ;returns tree-proof if proof-sequence ends with an instance of an axiom, ;otherwise returns #f (let* ((consequent (inference.consequent axiom)) (dicts (match `(,consequent ~aeqs) proof-sequence))) (and dicts (instantiate `(,consequent ,(inference.name axiom)) (car dicts))))) (define (try-one-antecedent-inference inference proof-sequence) ;returns tree-proof if final equation of proof-sequence follows from inference, ;otherwise returns #f (let* ((consequent (inference.consequent inference)) (antecedent (car (inference.antecedents inference))) (dicts (match `(,consequent ~aeqs1 ,antecedent ~aeqs2) proof-sequence))) (and dicts (let ((dict (car dicts))) (make-proof-tree (instantiate consequent dict) (inference.name inference) (linear->tree (instantiate `(,antecedent ~aeqs2) dict))))))) (define (try-two-antecedent-inference inference proof-sequence) ;returns tree-proof if final equation of proof-sequence follows from inference, ;otherwise returns #f (let* ((consequent (inference.consequent inference)) (antecedent1 (car (inference.antecedents inference))) (antecedent2 (cadr (inference.antecedents inference))) (dicts (match `(,consequent ~aeqs1 ,antecedent1 ~aeqs2 ,antecedent2 ~aeqs3) proof-sequence))) (and dicts (let ((dict (car dicts))) (make-proof-tree (instantiate consequent dict) (inference.name inference) (linear->tree (instantiate `(,antecedent1 ~aeqs2 ,antecedent2 ~aeqs3) dict)) (linear->tree (instantiate `(,antecedent2 ~aeqs3) dict))))))) (define (linear->tree proof-sequence) (or (for-some (map (lambda (axiom) (lambda (proof) (try-axiom axiom proof))) (axioms)) proof-sequence) (for-some (map (lambda (inference) (lambda (proof) (try-one-antecedent-inference inference proof))) (one-antecedent-inferences)) proof-sequence) (for-some (map (lambda (inference) (lambda (proof) (try-two-antecedent-inference inference proof))) (two-antecedent-inferences)) proof-sequence))) ;; PROOF DATA TYPES (define inference.consequent car) (define inference.name cadr) (define inference.antecedents cddr) (define make-proof-tree list) ;; UTILITY (define (for-some tests object) ;;Return first non-#f result of applying a test to object; ;;return #f if all tests return #f (and tests (or ((car tests) object) (for-some (cdr tests) object)))) ;; EXAMPLES (define (test) (reverse '(((g + (- g)) = 0) (f = f) ((f + (g + (- g))) = (f + 0)) (((f + g) + (- g)) = (f + (g + (- g)))) (((f + g) + (- g)) = (f + 0)) ((f + 0) = (0 + f)) (((f + g) + (- g)) = (0 + f)) ((0 + f) = f) (((f + g) + (- g)) = f)))) (define (test1) '( ((a + (0 + b)) = (b + a)) ((a + (0 + b)) = (a + b)) (a = a) ((0 + b) = b) ((a + b) = (b + a)) )) (define (test2) (reverse '(((0 + 1) = 1) (e = e) ((e * (0 + 1)) = (e * 1)) ((e * 1) = (e * (0 + 1))) ((e * (0 + 1)) = ((e * 0) + (e * 1))) ((e * 1) = ((e * 0) + (e * 1))) ((- (e * 1)) = (- (e * 1))) (((e * 1) + (- (e * 1))) = (((e * 0) + (e * 1)) + (- (e * 1)))) (((e * 1) + (- (e * 1))) = 0) ((e * 0) = (e * 0)) (((e * 0) + ((e * 1) + (- (e * 1)))) = ((e * 0) + 0)) ((((e * 0) + (e * 1)) + (- (e * 1))) = ((e * 0) + ((e * 1) + (- (e * 1))))) ((((e * 0) + (e * 1)) + (- (e * 1))) = ((e * 0) + 0)) (((e * 0) + 0) = (0 + (e * 0))) ((((e * 0) + (e * 1)) + (- (e * 1))) = (0 + (e * 0))) ((0 + (e * 0)) = (e * 0)) ((((e * 0) + (e * 1)) + (- (e * 1))) = (e * 0)) (((e * 1) + (- (e * 1))) = (e * 0)) (((e * 1) + (- (e * 1))) = 0) (0 = ((e * 1) + (- (e * 1)))) (0 = ( e * 0)) ))) #! (pretty-print (linear->tree (test))) ((((f + g) + (- g)) = f) transitivity (((0 + f) = f) identity+) ((((f + g) + (- g)) = (0 + f)) transitivity (((f + 0) = (0 + f)) commutativity+) ((((f + g) + (- g)) = (f + 0)) transitivity ((((f + g) + (- g)) = (f + (g + (- g)))) associativity+) (((f + (g + (- g))) = (f + 0)) congruence+ ((f = f) reflexivity) (((g + (- g)) = 0) inverse+))))) (pretty-print (linear->tree (test1))) (((a + (0 + b)) = (b + a)) transitivity (((a + (0 + b)) = (a + b)) congruence+ ((a = a) reflexivity) (((0 + b) = b) identity+)) (((a + b) = (b + a)) commutativity+)) (pretty-print (linear->tree (test2))) ((0 = (e * 0)) transitivity ((0 = ((e * 1) + (- (e * 1)))) symmetry ((((e * 1) + (- (e * 1))) = 0) inverse+)) ((((e * 1) + (- (e * 1))) = (e * 0)) transitivity (((((e * 0) + (e * 1)) + (- (e * 1))) = (e * 0)) transitivity (((0 + (e * 0)) = (e * 0)) identity+) (((((e * 0) + (e * 1)) + (- (e * 1))) = (0 + (e * 0))) transitivity ((((e * 0) + 0) = (0 + (e * 0))) commutativity+) (((((e * 0) + (e * 1)) + (- (e * 1))) = ((e * 0) + 0)) transitivity (((((e * 0) + (e * 1)) + (- (e * 1))) = ((e * 0) + ((e * 1) + (- (e * 1))))) associativity+) ((((e * 0) + ((e * 1) + (- (e * 1)))) = ((e * 0) + 0)) congruence+ (((e * 0) = (e * 0)) reflexivity) ((((e * 1) + (- (e * 1))) = 0) inverse+))))) ((((e * 1) + (- (e * 1))) = (((e * 0) + (e * 1)) + (- (e * 1)))) congruence+ (((- (e * 1)) = (- (e * 1))) reflexivity) (((e * 1) = ((e * 0) + (e * 1))) transitivity (((e * (0 + 1)) = ((e * 0) + (e * 1))) distributivity) (((e * 1) = (e * (0 + 1))) symmetry (((e * (0 + 1)) = (e * 1)) congruence* ((e = e) reflexivity) (((0 + 1) = 1) identity+))))))) |#