;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;           __    __        __    __                                        ;;
;;          /  \  /  \      (__)  |  |    ____   ___      __    ____         ;;
;;         /    \/    \      __   |  |   / _  |  \  \ __ /  /  / _  |        ;;
;;        /  /\    /\  \    |  |  |  |  / / | |   \  '  '  /  / / | |        ;;
;;       /  /  \__/  \  \   |  |  |  |  \ \_| |    \  /\  /   \ \_| |        ;;
;;      /__/          \__\  |__|  |__|   \____|     \/  \/     \____|        ;;
;; ~ ~~ \  ~ ~  ~_~~ ~/~ /~ | ~|~ | ~| ~ /~_ ~|~ ~  ~\  ~\~ ~  ~ ~  |~~    ~ ;;
;;  ~ ~  \~ \~ / ~\~ / ~/ ~ |~ | ~|  ~ ~/~/ | |~ ~~/ ~\/ ~~ ~ / / | |~   ~   ;;
;; ~ ~  ~ \ ~\/ ~  \~ ~/ ~~ ~__|  |~ ~  ~ \_~  ~  ~  .__~ ~\ ~\ ~_| ~  ~ ~~  ;;
;;  ~~ ~  ~\  ~ /~ ~  ~ ~  ~ __~  |  ~ ~ \~__~| ~/__~   ~\__~ ~~___~| ~ ~    ;;
;; ~  ~~ ~  \~_/  ~_~/ ~ ~ ~(__~ ~|~_| ~  ~  ~~  ~  ~ ~~    ~  ~   ~~  ~  ~  ;;
;;                                                                           ;;
;;            A   R e f l e c t i v e   P r o o f   C h e c k e r            ;;
;;                                                                           ;;
;;       Copyright (C) 2005-2009 by Jared Davis <jared@cs.utexas.edu>        ;;
;;                                                                           ;;
;; This program is free software; you can redistribute it and/or modify it   ;;
;; under the terms of the GNU General Public License as published by the     ;;
;; Free Software Foundation; either version 2 of the License, or (at your    ;;
;; option) any later version.                                                ;;
;;                                                                           ;;
;; This program is distributed in the hope that it will be useful, but       ;;
;; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABIL-  ;;
;; ITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public      ;;
;; License for more details.                                                 ;;
;;                                                                           ;;
;; You should have received a copy of the GNU General Public License along   ;;
;; with this program (see the file COPYING); if not, write to the Free       ;;
;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA    ;;
;; 02110-1301, USA.                                                          ;;
;;                                                                           ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(in-package "MILAWA")
(include-book "../../build/iff")
(include-book "../../build/not")
(set-verify-guards-eagerness 2)
(set-case-split-limitations nil)
(set-well-founded-relation ord<)
(set-measure-function rank)



(dd.open "if-lemmas.tex")


(deftheorem rw.theorem-iff-implies-pequal-if-1
 :derive (v (!= (iff x1 x2) t)
            (= (if x1 y z) (if x2 y z)))
 :proof  (@derive
          ((v (= (iff x y) nil)
              (= (if x a b) (if y a b)))    (build.theorem (theorem-iff-congruent-if-1)))
          ((v (= (if x a b) (if y a b))
              (= (iff x y) nil))            (build.commute-or @-))
          ((v (= (if x a b) (if y a b))
              (!= (iff x y) t))             (build.disjoined-not-t-from-nil @-))
          ((v (!= (iff x y) t)
              (= (if x a b) (if y a b)))    (build.commute-or @-))
          ((v (!= (iff x1 x2) t)
              (= (if x1 y z) (if x2 y z)))    (build.instantiation @-
                                                                   (@sigma (x . x1) (y . x2) (a . y) (b . z)))))
 :minatbl ((if . 3)
           (iff . 2)))

(deftheorem rw.theorem-equal-implies-pequal-if-2
 :derive (v (= x nil)
            (v (!= (equal y1 y2) t)
               (= (if x y1 z1) (if x y2 z2))))
 :proof  (@derive
          ((v (= x nil) (= (if x y z) y))                                         (build.axiom (axiom-if-when-not-nil))                                              *1)
          ((v (= x nil) (= (if x y1 z1) y1))                                      (build.instantiation @- (@sigma (y . y1) (z . z1))))
          ((v (v (= x nil) (!= (equal y1 y2) t)) (= (if x y1 z1) y1))             (build.multi-assoc-expansion @- (@formulas (= x nil) (!= (equal y1 y2) t)))   *2)
          ;; ---
          ((v (!= y1 y2) (= y1 y2))                                               (build.propositional-schema (@formula (= y1 y2))))
          ((v (= y1 y2) (!= y1 y2))                                               (build.commute-or @-))
          ((v (= y1 y2) (= (equal y1 y2) nil))                                    (build.disjoined-not-equal-from-not-pequal @-))
          ((v (= y1 y2) (!= (equal y1 y2) t))                                     (build.disjoined-not-t-from-nil @-))
          ((v (!= (equal y1 y2) t) (= y1 y2))                                     (build.commute-or @-))
          ((v (v (= x nil) (!= (equal y1 y2) t)) (= y1 y2))                       (build.multi-assoc-expansion @- (@formulas (= x nil) (!= (equal y1 y2) t))))
          ((v (v (= x nil) (!= (equal y1 y2) t)) (= (if x y1 z1) y2))             (build.disjoined-transitivity-of-pequal *2 @-)                                *3)
          ;; ---
          ((v (= x nil) (= (if x y2 z2) y2))                                      (build.instantiation *1 (@sigma (y . y2) (z . z2))))
          ((v (v (= x nil) (!= (equal y1 y2) t)) (= (if x y2 z2) y2))             (build.multi-assoc-expansion @- (@formulas (= x nil) (!= (equal y1 y2) t))))
          ((v (v (= x nil) (!= (equal y1 y2) t)) (= y2 (if x y2 z2)))             (build.disjoined-commute-pequal @-))
          ((v (v (= x nil) (!= (equal y1 y2) t)) (= (if x y1 z2) (if x y2 z2)))   (build.disjoined-transitivity-of-pequal *3 @-))
          ((v (= x nil) (v (!= (equal y1 y2) t) (= (if x y1 z2) (if x y2 z2))))   (build.right-associativity @-)))
 :minatbl ((if . 3)
           (equal . 2)))

(deftheorem rw.theorem-equal-implies-pequal-if-3
 :derive (v (!= x nil)
            (v (!= (equal z1 z2) t)
               (= (if x y1 z1) (if x y2 z2))))
 :proof  (@derive
          ((v (!= x nil) (= (if x y z) z))                                        (build.axiom (axiom-if-when-nil))                                                   *1)
          ((v (!= x nil) (= (if x y1 z1) z1))                                     (build.instantiation @- (@sigma (y . y1) (z . z1))))
          ((v (v (!= x nil) (!= (equal z1 z2) t)) (= (if x y1 z1) z1))            (build.multi-assoc-expansion @- (@formulas (!= x nil) (!= (equal z1 z2) t)))   *2)
          ;; ---
          ((v (!= z1 z2) (= z1 z2))                                               (build.propositional-schema (@formula (= z1 z2))))
          ((v (= z1 z2) (!= z1 z2))                                               (build.commute-or @-))
          ((v (= z1 z2) (= (equal z1 z2) nil))                                    (build.disjoined-not-equal-from-not-pequal @-))
          ((v (= z1 z2) (!= (equal z1 z2) t))                                     (build.disjoined-not-t-from-nil @-))
          ((v (!= (equal z1 z2) t) (= z1 z2))                                     (build.commute-or @-))
          ((v (v (!= x nil) (!= (equal z1 z2) t)) (= z1 z2))                      (build.multi-assoc-expansion @- (@formulas (!= x nil) (!= (equal z1 z2) t))))
          ((v (v (!= x nil) (!= (equal z1 z2) t)) (= (if x y1 z1) z2))            (build.disjoined-transitivity-of-pequal *2 @-)                                 *3)
          ;; ---
          ((v (!= x nil) (= (if x y2 z2) z2))                                     (build.instantiation *1 (@sigma (y . y2) (z . z2))))
          ((v (v (!= x nil) (!= (equal z1 z2) t)) (= (if x y2 z2) z2))            (build.multi-assoc-expansion @- (@formulas (!= x nil) (!= (equal z1 z2) t))))
          ((v (v (!= x nil) (!= (equal z1 z2) t)) (= z2 (if x y2 z2)))            (build.disjoined-commute-pequal @-))
          ((v (v (!= x nil) (!= (equal z1 z2) t)) (= (if x y1 z1) (if x y2 z2)))  (build.disjoined-transitivity-of-pequal *3 @-))
          ((v (!= x nil) (v (!= (equal z1 z2) t) (= (if x y1 z1) (if x y2 z2))))  (build.right-associativity @-)))
 :minatbl ((if . 3)
           (equal . 2)))

(deftheorem rw.theorem-iff-implies-equal-if-combined
  :derive (v (!= (iff x1 x2) t)
             (v (! (v (!= (not x2) nil) (= (equal y1 y2) t)))
                (v (! (v (!= x2 nil) (= (equal z1 z2) t)))
                   (= (equal (if x1 y1 z1) (if x2 y2 z2)) t))))
  :proof (let* ((hyp1 (@formula (!= (iff x1 x2) t)))
                (hyp2 (@formula (! (v (!= (not x2) nil) (= (equal y1 y2) t)))))
                (hyp3 (@formula (! (v (!= x2 nil) (= (equal z1 z2) t)))))
                (hyps (list hyp1 hyp2 hyp3)))
           (@derive
            ((v (!= (iff x1 x2) t) (= (if x1 y z) (if x2 y z)))       (build.theorem (rw.theorem-iff-implies-pequal-if-1)))
            ((v (!= (iff x1 x2) t) (= (if x1 y1 z1) (if x2 y1 z1)))   (build.instantiation @- (@sigma (y . y1) (z . z1))))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (equal y1 y2) t)))
                      (! (v (!= x2 nil) (= (equal z1 z2) t)))))
                (= (if x1 y1 z1) (if x2 y1 z1)))                      (build.multi-assoc-expansion @- hyps)                                                  *0)
            ;; ---
            ((v (! (v (!= (not x2) nil) (= (equal y1 y2) t)))
                (v (!= (not x2) nil) (= (equal y1 y2) t)))                                (build.propositional-schema (@formula (v (!= (not x2) nil) (= (equal y1 y2) t)))))
            ((v (v (!= (not x2) nil) (= (equal y1 y2) t))
                (! (v (!= (not x2) nil) (= (equal y1 y2) t))))                            (build.commute-or @-))
            ((v (!= (not x2) nil)
                (v (= (equal y1 y2) t) (! (v (!= (not x2) nil) (= (equal y1 y2) t)))))    (build.right-associativity @-))
            ((v (v (= (equal y1 y2) t) (! (v (!= (not x2) nil) (= (equal y1 y2) t))))
                (!= (not x2) nil))                                                        (build.commute-or @-))
            ((v (v (= (equal y1 y2) t) (! (v (!= (not x2) nil) (= (equal y1 y2) t))))
                (= x2 nil))                                                               (build.disjoined-pequal-nil-from-negative-lit @-))
            ((v (= x2 nil)
                (v (= (equal y1 y2) t) (! (v (!= (not x2) nil) (= (equal y1 y2) t)))))    (build.commute-or @-))
            ((v (v (= x2 nil) (= (equal y1 y2) t))
                (! (v (!= (not x2) nil) (= (equal y1 y2) t))))                            (build.associativity @-))
            ((v (! (v (!= (not x2) nil) (= (equal y1 y2) t)))
                (v (= x2 nil) (= (equal y1 y2) t)))                                       (build.commute-or @-))
            ((v (v (! (v (!= (not x2) nil) (= (equal y1 y2) t)))
                   (= x2 nil))
                (= (equal y1 y2) t))                                                      (build.associativity @-)                                                                    *1a)
            ((v (= x nil) (v (!= (equal y1 y2) t) (= (if x y1 z1) (if x y2 z2))))         (build.theorem (rw.theorem-equal-implies-pequal-if-2)))
            ((v (= x2 nil) (v (!= (equal y1 y2) t) (= (if x2 y1 z1) (if x2 y2 z2))))      (build.instantiation @- (@sigma (x . x2))))
            ((v (v (! (v (!= (not x2) nil) (= (equal y1 y2) t))) (= x2 nil))
                (v (!= (equal y1 y2) t) (= (if x2 y1 z1) (if x2 y2 z2))))                 (build.multi-assoc-expansion @- (@formulas (! (v (!= (not x2) nil) (= (equal y1 y2) t))) (= x2 nil))))
            ((v (v (! (v (!= (not x2) nil) (= (equal y1 y2) t))) (= x2 nil))
                (= (if x2 y1 z1) (if x2 y2 z2)))                                          (build.disjoined-modus-ponens *1a @-))
            ((v (! (v (!= (not x2) nil) (= (equal y1 y2) t)))
                (v (= x2 nil)
                   (= (if x2 y1 z1) (if x2 y2 z2))))                                      (build.right-associativity @-))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (equal y1 y2) t)))
                      (! (v (!= x2 nil) (= (equal z1 z2) t)))))
                (v (= x2 nil)
                   (= (if x2 y1 z1) (if x2 y2 z2))))                                      (build.multi-assoc-expansion @- hyps)                                                  *1)

            ;; ---
            ((v (! (v (!= x2 nil) (= (equal z1 z2) t)))
                (v (!= x2 nil) (= (equal z1 z2) t)))                  (build.propositional-schema (@formula (v (!= x2 nil) (= (equal z1 z2) t)))))
            ((v (v (! (v (!= x2 nil) (= (equal z1 z2) t)))
                   (!= x2 nil))
                (= (equal z1 z2) t))                                  (build.associativity @-)                                                                    *2a)
            ((v (!= x nil)
                (v (!= (equal z1 z2) t)
                   (= (if x y1 z1) (if x y2 z2))))                    (build.theorem (rw.theorem-equal-implies-pequal-if-3)))
            ((v (!= x2 nil)
                (v (!= (equal y1 y2) t)
                   (= (if x2 y1 z1) (if x2 y2 z2))))                  (build.instantiation @- (@sigma (x . x2))))
            ((v (v (! (v (!= x2 nil) (= (equal z1 z2) t)))
                   (!= x2 nil))
                (v (!= (equal z1 z2) t)
                   (= (if x2 y1 z1) (if x2 y2 z2))))                  (build.multi-assoc-expansion @- (@formulas (! (v (!= x2 nil) (= (equal z1 z2) t))) (!= x2 nil))))
            ((v (v (! (v (!= x2 nil) (= (equal z1 z2) t)))
                   (!= x2 nil))
                (= (if x2 y1 z1) (if x2 y2 z2)))                      (build.disjoined-modus-ponens *2a @-))
            ((v (! (v (!= x2 nil) (= (equal z1 z2) t)))
                (v (!= x2 nil)
                   (= (if x2 y1 z1) (if x2 y2 z2))))                  (build.right-associativity @-))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (equal y1 y2) t)))
                      (! (v (!= x2 nil) (= (equal z1 z2) t)))))
                (v (!= x2 nil)
                   (= (if x2 y1 z1) (if x2 y2 z2))))                  (build.multi-assoc-expansion @- hyps)                                                  *2)
            ;; ---
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (equal y1 y2) t)))
                      (! (v (!= x2 nil) (= (equal z1 z2) t)))))
                (v (= (if x2 y1 z1) (if x2 y2 z2))
                   (= (if x2 y1 z1) (if x2 y2 z2))))                  (build.disjoined-cut *1 *2))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (equal y1 y2) t)))
                      (! (v (!= x2 nil) (= (equal z1 z2) t)))))
                (= (if x2 y1 z1) (if x2 y2 z2)))                      (build.disjoined-contraction @-))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (equal y1 y2) t)))
                      (! (v (!= x2 nil) (= (equal z1 z2) t)))))
                (= (if x1 y1 z1) (if x2 y2 z2)))                      (build.disjoined-transitivity-of-pequal *0 @-))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (equal y1 y2) t)))
                      (! (v (!= x2 nil) (= (equal z1 z2) t)))))
                (= (equal (if x1 y1 z1) (if x2 y2 z2)) t))            (build.disjoined-equal-from-pequal @-))
            ((v (!= (iff x1 x2) t)
                (v (v (! (v (!= (not x2) nil) (= (equal y1 y2) t)))
                      (! (v (!= x2 nil) (= (equal z1 z2) t))))
                   (= (equal (if x1 y1 z1) (if x2 y2 z2)) t)))        (build.right-associativity @-))
            ((v (!= (iff x1 x2) t)
                (v (! (v (!= (not x2) nil) (= (equal y1 y2) t)))
                   (v (! (v (!= x2 nil) (= (equal z1 z2) t)))
                      (= (equal (if x1 y1 z1) (if x2 y2 z2)) t))))    (build.disjoined-right-associativity @-))))
  :minatbl ((if . 3)
            (equal . 2)
            (iff . 2)
            (not . 1)))




;; Note: theorem-iff-implies-iff-if-2 isn't needed, just use theorem-iff-implies-pequal-if-1.

(deftheorem rw.theorem-iff-implies-iff-if-2
 :derive (v (= x nil) (v (!= (iff y1 y2) t) (= (iff (if x y1 z1) (if x y2 z2)) t)))
 :proof  (@derive
          ((v (= x nil) (= (if x y z) y))                                                                            (build.axiom (axiom-if-when-not-nil)))
          ((v (= x nil) (= (if x y1 z1) y1))                                                                         (build.instantiation @- (@sigma (y . y1) (z . z1))))
          ((v (= x nil) (= (if x y2 z2) y2))                                                                         (build.instantiation @-- (@sigma (y . y2) (z . z2))))
          ((v (= x nil) (= (iff (if x y1 z1) (if x y2 z2)) (iff y1 y2)))                                             (build.disjoined-pequal-by-args 'iff (@formula (= x nil)) (list @-- @-)))
          ((v (= x nil) (= (iff y1 y2) (iff (if x y1 z1) (if x y2 z2))))                                             (build.disjoined-commute-pequal @-))
          ((v (v (= x nil) (= (iff (if x y1 z1) (if x y2 z2)) t)) (= (iff y1 y2) (iff (if x y1 z1) (if x y2 z2))))   (build.multi-assoc-expansion @- (@formulas (= x nil) (= (iff (if x y1 z1) (if x y2 z2)) t)))    *1)
          ;; ---
          ((v (= (iff x y) nil) (= (iff x y) t))                                                                     (build.theorem (theorem-iff-nil-or-t)))
          ((v (= (iff (if x y1 z1) (if x y2 z2)) nil) (= (iff (if x y1 z1) (if x y2 z2)) t))                         (build.instantiation @- (@sigma (x . (if x y1 z1)) (y . (if x y2 z2)))))
          ((v (= (iff (if x y1 z1) (if x y2 z2)) t) (= (iff (if x y1 z1) (if x y2 z2)) nil))                         (build.commute-or @-))
          ((v (v (= x nil) (= (iff (if x y1 z1) (if x y2 z2)) t)) (= (iff (if x y1 z1) (if x y2 z2)) nil))           (build.multi-assoc-expansion @- (@formulas (= x nil) (= (iff (if x y1 z1) (if x y2 z2)) t))))
          ;; ---
          ((v (v (= x nil) (= (iff (if x y1 z1) (if x y2 z2)) t)) (= (iff y1 y2) nil))                               (build.disjoined-transitivity-of-pequal *1 @-))
          ((v (v (= x nil) (= (iff (if x y1 z1) (if x y2 z2)) t)) (!= (iff y1 y2) t))                                (build.disjoined-not-t-from-nil @-))
          ((v (= x nil) (v (= (iff (if x y1 z1) (if x y2 z2)) t) (!= (iff y1 y2) t)))                                (build.right-associativity @-))
          ((v (= x nil) (v (!= (iff y1 y2) t) (= (iff (if x y1 z1) (if x y2 z2)) t)))                                (build.disjoined-commute-or @-)))
 :minatbl ((if . 3)
           (iff . 2)))

(deftheorem rw.theorem-iff-implies-iff-if-3
 :derive (v (!= x nil)
            (v (!= (iff z1 z2) t)
               (= (iff (if x y1 z1) (if x y2 z2)) t)))
 :proof  (@derive
          ((v (!= x nil) (= (if x y z) z))                                                                           (build.axiom (axiom-if-when-nil)))
          ((v (!= x nil) (= (if x y1 z1) z1))                                                                        (build.instantiation @- (@sigma (y . y1) (z . z1))))
          ((v (!= x nil) (= (if x y2 z2) z2))                                                                        (build.instantiation @-- (@sigma (y . y2) (z . z2))))
          ((v (!= x nil) (= (iff (if x y1 z1) (if x y2 z2)) (iff z1 z2)))                                            (build.disjoined-pequal-by-args 'iff (@formula (!= x nil)) (list @-- @-)))
          ((v (!= x nil) (= (iff z1 z2) (iff (if x y1 z1) (if x y2 z2))))                                            (build.disjoined-commute-pequal @-))
          ((v (v (!= x nil) (= (iff (if x y1 z1) (if x y2 z2)) t)) (= (iff z1 z2) (iff (if x y1 z1) (if x y2 z2))))  (build.multi-assoc-expansion @- (@formulas (!= x nil) (= (iff (if x y1 z1) (if x y2 z2)) t)))   *1)
          ;; ---
          ((v (= (iff x y) nil) (= (iff x y) t))                                                                     (build.theorem (theorem-iff-nil-or-t)))
          ((v (= (iff (if x y1 z1) (if x y2 z2)) nil) (= (iff (if x y1 z1) (if x y2 z2)) t))                         (build.instantiation @- (@sigma (x . (if x y1 z1)) (y . (if x y2 z2)))))
          ((v (= (iff (if x y1 z1) (if x y2 z2)) t) (= (iff (if x y1 z1) (if x y2 z2)) nil))                         (build.commute-or @-))
          ((v (v (!= x nil) (= (iff (if x y1 z1) (if x y2 z2)) t)) (= (iff (if x y1 z1) (if x y2 z2)) nil))          (build.multi-assoc-expansion @- (@formulas (!= x nil) (= (iff (if x y1 z1) (if x y2 z2)) t))))
          ;; ---
          ((v (v (!= x nil) (= (iff (if x y1 z1) (if x y2 z2)) t)) (= (iff z1 z2) nil))                              (build.disjoined-transitivity-of-pequal *1 @-))
          ((v (v (!= x nil) (= (iff (if x y1 z1) (if x y2 z2)) t)) (!= (iff z1 z2) t))                               (build.disjoined-not-t-from-nil @-))
          ((v (!= x nil) (v (= (iff (if x y1 z1) (if x y2 z2)) t) (!= (iff z1 z2) t)))                               (build.right-associativity @-))
          ((v (!= x nil) (v (!= (iff z1 z2) t) (= (iff (if x y1 z1) (if x y2 z2)) t)))                               (build.disjoined-commute-or @-)))
 :minatbl ((if . 3)
           (iff . 2)))

(deftheorem rw.theorem-iff-implies-iff-if-combined
  :derive (v (!= (iff x1 x2) t)
             (v (! (v (!= (not x2) nil) (= (iff y1 y2) t)))
                (v (! (v (!= x2 nil) (= (iff z1 z2) t)))
                   (= (iff (if x1 y1 z1) (if x2 y2 z2)) t))))
  :proof (let* ((hyp1 (@formula (!= (iff x1 x2) t)))
                (hyp2 (@formula (! (v (!= (not x2) nil) (= (iff y1 y2) t)))))
                (hyp3 (@formula (! (v (!= x2 nil) (= (iff z1 z2) t)))))
                (hyps (list hyp1 hyp2 hyp3)))
           (@derive
            ((v (!= (iff x1 x2) t) (= (if x1 y z) (if x2 y z)))          (build.theorem (rw.theorem-iff-implies-pequal-if-1)))
            ((v (!= (iff x1 x2) t) (= (if x1 y1 z1) (if x2 y1 z1)))      (build.instantiation @- (@sigma (y . y1) (z . z1))))
            ((v (!= (iff x1 x2) t)
                (= (iff (if x1 y1 z1) (if x2 y1 z1)) t))                 (build.disjoined-iff-from-pequal @-))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (iff y1 y2) t)))
                      (! (v (!= x2 nil) (= (iff z1 z2) t)))))
                (= (iff (if x1 y1 z1) (if x2 y1 z1)) t))                 (build.multi-assoc-expansion @- hyps)                                                  *0)
            ;; ---
            ((v (! (v (!= (not x2) nil) (= (iff y1 y2) t)))
                (v (!= (not x2) nil) (= (iff y1 y2) t)))                 (build.propositional-schema (@formula (v (!= (not x2) nil) (= (iff y1 y2) t)))))
            ((v (v (!= (not x2) nil) (= (iff y1 y2) t))
                (! (v (!= (not x2) nil) (= (iff y1 y2) t))))             (build.commute-or @-))
            ((v (!= (not x2) nil)
                (v (= (iff y1 y2) t) (! (v (!= (not x2) nil) (= (iff y1 y2) t)))))         (build.right-associativity @-))
            ((v (v (= (iff y1 y2) t) (! (v (!= (not x2) nil) (= (iff y1 y2) t))))
                (!= (not x2) nil))                                                         (build.commute-or @-))
            ((v (v (= (iff y1 y2) t) (! (v (!= (not x2) nil) (= (iff y1 y2) t))))
                (= x2 nil))                                                                (build.disjoined-pequal-nil-from-negative-lit @-))
            ((v (= x2 nil)
                (v (= (iff y1 y2) t) (! (v (!= (not x2) nil) (= (iff y1 y2) t)))))         (build.commute-or @-))
            ((v (v (= x2 nil) (= (iff y1 y2) t))
                (! (v (!= (not x2) nil) (= (iff y1 y2) t))))                               (build.associativity @-))
            ((v (! (v (!= (not x2) nil) (= (iff y1 y2) t)))
                (v (= x2 nil) (= (iff y1 y2) t)))                                          (build.commute-or @-))
            ((v (v (! (v (!= (not x2) nil) (= (iff y1 y2) t))) (= x2 nil))
                (= (iff y1 y2) t))                                                         (build.associativity @-)                                              *1a)

            ((v (= x nil)
                (v (!= (iff y1 y2) t)
                   (= (iff (if x y1 z1) (if x y2 z2)) t)))               (build.theorem (rw.theorem-iff-implies-iff-if-2)))
            ((v (= x2 nil)
                (v (!= (iff y1 y2) t)
                   (= (iff (if x2 y1 z1) (if x2 y2 z2)) t)))             (build.instantiation @- (@sigma (x . x2))))
            ((v (v (! (v (!= (not x2) nil) (= (iff y1 y2) t)))
                   (= x2 nil))
                (v (!= (iff y1 y2) t)
                   (= (iff (if x2 y1 z1) (if x2 y2 z2)) t)))             (build.multi-assoc-expansion @- (@formulas (! (v (!= (not x2) nil) (= (iff y1 y2) t))) (= x2 nil))))
            ((v (v (! (v (!= (not x2) nil) (= (iff y1 y2) t)))
                   (= x2 nil))
                (= (iff (if x2 y1 z1) (if x2 y2 z2)) t))                 (build.disjoined-modus-ponens *1a @-))
            ((v (! (v (!= (not x2) nil) (= (iff y1 y2) t)))
                (v (= x2 nil)
                   (= (iff (if x2 y1 z1) (if x2 y2 z2)) t)))             (build.right-associativity @-))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (iff y1 y2) t)))
                      (! (v (!= x2 nil) (= (iff z1 z2) t)))))
                (v (= x2 nil)
                   (= (iff (if x2 y1 z1) (if x2 y2 z2)) t)))             (build.multi-assoc-expansion @- hyps)                                                  *1)
            ;; ---
            ((v (! (v (!= x2 nil) (= (iff z1 z2) t)))
                (v (!= x2 nil) (= (iff z1 z2) t)))                       (build.propositional-schema (@formula (v (!= x2 nil) (= (iff z1 z2) t)))))
            ((v (v (! (v (!= x2 nil) (= (iff z1 z2) t)))
                   (!= x2 nil))
                (= (iff z1 z2) t))                                       (build.associativity @-)                                                                    *2a)
            ((v (!= x nil)
                (v (!= (iff z1 z2) t)
                   (= (iff (if x y1 z1) (if x y2 z2)) t)))               (build.theorem (rw.theorem-iff-implies-iff-if-3)))
            ((v (!= x2 nil)
                (v (!= (iff y1 y2) t)
                   (= (iff (if x2 y1 z1) (if x2 y2 z2)) t)))             (build.instantiation @- (@sigma (x . x2))))
            ((v (v (! (v (!= x2 nil) (= (iff z1 z2) t)))
                   (!= x2 nil))
                (v (!= (iff z1 z2) t)
                   (= (iff (if x2 y1 z1) (if x2 y2 z2)) 2)))             (build.multi-assoc-expansion @- (@formulas (! (v (!= x2 nil) (= (iff z1 z2) t))) (!= x2 nil))))
            ((v (v (! (v (!= x2 nil) (= (iff z1 z2) t)))
                   (!= x2 nil))
                (= (iff (if x2 y1 z1) (if x2 y2 z2)) t))                 (build.disjoined-modus-ponens *2a @-))
            ((v (! (v (!= x2 nil) (= (iff z1 z2) t)))
                (v (!= x2 nil)
                   (= (iff (if x2 y1 z1) (if x2 y2 z2)) t)))             (build.right-associativity @-))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (iff y1 y2) t)))
                      (! (v (!= x2 nil) (= (iff z1 z2) t)))))
                (v (!= x2 nil)
                   (= (iff (if x2 y1 z1) (if x2 y2 z2)) t)))             (build.multi-assoc-expansion @- hyps)                                                  *2)
            ;; ---
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (iff y1 y2) t)))
                      (! (v (!= x2 nil) (= (iff z1 z2) t)))))
                (v (= (iff (if x2 y1 z1) (if x2 y2 z2)) t)
                   (= (iff (if x2 y1 z1) (if x2 y2 z2)) t)))             (build.disjoined-cut *1 *2))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (iff y1 y2) t)))
                      (! (v (!= x2 nil) (= (iff z1 z2) t)))))
                (= (iff (if x2 y1 z1) (if x2 y2 z2)) t))                 (build.disjoined-contraction @-))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (iff y1 y2) t)))
                      (! (v (!= x2 nil) (= (iff z1 z2) t)))))
                (= (iff (if x1 y1 z1) (if x2 y2 z2)) t))                 (build.disjoined-transitivity-of-iff *0 @-))
            ((v (!= (iff x1 x2) t)
                (v (v (! (v (!= (not x2) nil) (= (iff y1 y2) t)))
                      (! (v (!= x2 nil) (= (iff z1 z2) t))))
                   (= (iff (if x1 y1 z1) (if x2 y2 z2)) t)))             (build.right-associativity @-))
            ((v (!= (iff x1 x2) t)
                (v (! (v (!= (not x2) nil) (= (iff y1 y2) t)))
                   (v (! (v (!= x2 nil) (= (iff z1 z2) t)))
                      (= (iff (if x1 y1 z1) (if x2 y2 z2)) t))))         (build.disjoined-right-associativity @-))))
  :minatbl ((if . 3)
            (equal . 2)
            (iff . 2)
            (not . 1)))



(deftheorem rw.theorem-iff-implies-equal-if-specialcase-nil
  :derive (v (!= (iff x1 nil) t)
             (v (!= (equal z1 z2) t)
                (= (equal (if x1 y1 z1) z2) t)))
  :proof (@derive
          ((v (= x nil) (= (iff x nil) nil))                             (build.theorem (theorem-iff-nil-when-not-nil)))
          ((v (= x nil) (!= (iff x nil) t))                              (build.disjoined-not-t-from-nil @-))
          ((v (!= (iff x nil) t) (= x nil))                              (build.commute-or @-))
          ((v (!= (iff x1 nil) t) (= x1 nil))                            (build.instantiation @- (@sigma (x . x1)))                                                  *1)
          ;; ---
          ((v (!= x nil) (= (if x y z) z))                               (build.axiom (axiom-if-when-nil)))
          ((v (!= x1 nil) (= (if x1 y1 z1) z1))                          (build.instantiation @- (@sigma (x . x1) (y . y1) (z . z1))))
          ((v (!= (iff x1 nil) t) (v (!= x1 nil) (= (if x1 y1 z1) z1)))  (build.expansion (@formula (!= (iff x1 nil) t)) @-))
          ((v (!= (iff x1 nil) t) (= (if x1 y1 z1) z1))                  (build.disjoined-modus-ponens *1 @-))
          ((v (v (!= (iff x1 nil) t) (!= (equal z1 z2) t))
              (= (if x1 y1 z1) z1))                                      (build.multi-assoc-expansion @- (@formulas (!= (iff x1 nil) t) (!= (equal z1 z2) t)))  *2)
          ;; ---
          ((v (!= z1 z2) (= z1 z2))                                      (build.propositional-schema (@formula (= z1 z2))))
          ((v (= z1 z2) (!= z1 z2))                                      (build.commute-or @-))
          ((v (= z1 z2) (= (equal z1 z2) nil))                           (build.disjoined-not-equal-from-not-pequal @-))
          ((v (= z1 z2) (!= (equal z1 z2) t))                            (build.disjoined-not-t-from-nil @-))
          ((v (!= (equal z1 z2) t) (= z1 z2))                            (build.commute-or @-))
          ((v (v (!= (iff x1 nil) t) (!= (equal z1 z2) t)) (= z1 z2))    (build.multi-assoc-expansion @- (@formulas (!= (iff x1 nil) t) (!= (equal z1 z2) t))))
          ((v (v (!= (iff x1 nil) t) (!= (equal z1 z2) t))
              (= (if x1 y1 z1) z2))                                      (build.disjoined-transitivity-of-pequal *2 @-))
          ((v (v (!= (iff x1 nil) t) (!= (equal z1 z2) t))
              (= (equal (if x1 y1 z1) z2) t))                            (build.disjoined-equal-from-pequal @-))
          ((v (!= (iff x1 nil) t)
              (v (!= (equal z1 z2) t)
                 (= (equal (if x1 y1 z1) z2) t)))                        (build.right-associativity @-)))
  :minatbl ((iff . 2)
            (equal . 2)
            (if . 3)))

(deftheorem rw.theorem-iff-implies-iff-if-specialcase-nil
  :derive (v (!= (iff x1 nil) t)
             (v (!= (iff z1 z2) t)
                (= (iff (if x1 y1 z1) z2) t)))
  :proof  (@derive
           ((v (= x nil) (= (iff x nil) nil))                                    (build.theorem (theorem-iff-nil-when-not-nil)))
           ((v (= x1 nil) (= (iff x1 nil) nil))                                  (build.instantiation @- (@sigma (x . x1))))
           ((v (= x1 nil) (!= (iff x1 nil) t))                                   (build.disjoined-not-t-from-nil @-)                                          *1)
           ;; ---
           ((v (!= x nil) (= (if x y z) z))                                      (build.axiom (axiom-if-when-nil)))
           ((v (!= x1 nil) (= (if x1 y1 z1) z1))                                 (build.instantiation @- (@sigma (x . x1) (y . y1) (z . z1)))                      *2)
           ((= z2 z2)                                                            (build.reflexivity (@term z2)))
           ((v (!= x1 nil) (= z2 z2))                                            (build.expansion (@formula (!= x1 nil)) @-))
           ((v (!= x1 nil) (= (iff (if x1 y1 z1) z2) (iff z1 z2)))               (build.disjoined-pequal-by-args 'iff (@formula (!= x1 nil)) (list *2 @-)))
           ((v (v (!= x1 nil) (!= (iff z1 z2) t))
               (= (iff (if x1 y1 z1) z2) (iff z1 z2)))                           (build.multi-assoc-expansion @- (@formulas (!= x1 nil) (!= (iff z1 z2) t)))  *3)
           ;; ---
           ((v (!= (iff z1 z2) t) (= (iff z1 z2) t))                             (build.propositional-schema (@formula (= (iff z1 z2) t))))
           ((v (v (!= x1 nil) (!= (iff z1 z2) t)) (= (iff z1 z2) t))             (build.multi-assoc-expansion @- (@formulas (!= x1 nil) (!= (iff z1 z2) t))))
           ((v (v (!= x1 nil) (!= (iff z1 z2) t)) (= (iff (if x1 y1 z1) z2) t))  (build.disjoined-transitivity-of-pequal *3 @-))
           ((v (!= x1 nil) (v (!= (iff z1 z2) t) (= (iff (if x1 y1 z1) z2) t)))  (build.right-associativity @-))
           ((v (!= (iff x1 nil) t)
               (v (!= (iff z1 z2) t)
                  (= (iff (if x1 y1 z1) z2) t)))                                 (build.cut *1 @-)))
  :minatbl ((iff . 2)
            (if . 3)))




(deftheorem rw.theorem-iff-implies-equal-if-specialcase-t
 :derive (v (!= (iff x1 x2) t)
            (v (= x2 nil)
               (v (!= (equal y1 y2) t)
                  (= (equal (if x1 y1 z1) y2) t))))
 :proof  (@derive
          ((v (= x nil) (v (!= (equal y1 y2) t) (= (if x y1 z1) (if x y2 z2))))         (build.theorem (rw.theorem-equal-implies-pequal-if-2)))
          ((v (= x1 nil) (v (!= (equal y1 y2) t) (= (if x1 y1 z1) (if x1 y2 z2))))      (build.instantiation @- (@sigma (x . x1))))
          ((v (v (= x1 nil) (!= (equal y1 y2) t)) (= (if x1 y1 z1) (if x1 y2 z2)))      (build.associativity @-)                                                   *1)
          ;; ---
          ((v (= x nil) (= (if x y z) y))                                               (build.axiom (axiom-if-when-not-nil)))
          ((v (= x1 nil) (= (if x1 y2 z2) y2))                                          (build.instantiation @- (@sigma (x . x1) (y . y2) (z . z2))))
          ((v (v (= x1 nil) (!= (equal y1 y2) t)) (= (if x1 y2 z2) y2))                 (build.multi-assoc-expansion @- (@formulas (= x1 nil) (!= (equal y1 y2) t))))
          ((v (v (= x1 nil) (!= (equal y1 y2) t)) (= (if x1 y1 z1) y2))                 (build.disjoined-transitivity-of-pequal *1 @-))
          ((v (v (= x1 nil) (!= (equal y1 y2) t)) (= (equal (if x1 y1 z1) y2) t))       (build.disjoined-equal-from-pequal @-))
          ((v (= x1 nil) (v (!= (equal y1 y2) t) (= (if x1 y1 z1) y2)))                 (build.right-associativity @-)                                        *2)
          ;; ---
          ((v (!= x nil) (v (= y nil) (= (iff x y) nil)))                               (build.theorem (theorem-iff-false-true)))
          ((v (v (!= x nil) (= y nil)) (= (iff x y) nil))                               (build.associativity @-))
          ((v (v (!= x nil) (= y nil)) (!= (iff x y) t))                                (build.disjoined-not-t-from-nil @-))
          ((v (!= x nil) (v (= y nil) (!= (iff x y) t)))                                (build.right-associativity @-))
          ((v (!= x1 nil) (v (= x2 nil) (!= (iff x1 x2) t)))                            (build.instantiation @- (@sigma (x . x1) (y . x2))))
          ((v (!= x1 nil) (v (!= (iff x1 x2) t) (= x2 nil)))                            (build.disjoined-commute-or @-))
          ;; ---
          ((v (v (!= (equal y1 y2) t)
                 (= (equal (if x1 y1 z1) y2) t)) (v (!= (iff x1 x2) t) (= x2 nil)))     (build.cut *2 @-))
          ((v (v (!= (iff x1 x2) t) (= x2 nil))
              (v (!= (equal y1 y2) t) (= (equal (if x1 y1 z1) y2) t)))                  (build.commute-or @-))
          ((v (!= (iff x1 x2) t)
              (v (= x2 nil)
                 (v (!= (equal y1 y2) t)
                    (= (equal (if x1 y1 z1) y2) t))))                                   (build.right-associativity @-)))
 :minatbl ((iff . 2)
           (equal . 2)
           (if . 3)))

(deftheorem rw.theorem-iff-implies-iff-if-specialcase-t
  :derive (v (!= (iff x1 x2) t)
             (v (= x2 nil)
                (v (!= (iff y1 y2) t)
                   (= (iff (if x1 y1 z1) y2) t))))
  :proof  (@derive
           ((v (= x nil) (= (if x y z) y))                                           (build.axiom (axiom-if-when-not-nil)))
           ((v (= x1 nil) (= (if x1 y1 z1) y1))                                      (build.instantiation @- (@sigma (x . x1) (y . y1) (z . z1)))                      *1)
           ((= y2 y2)                                                                (build.reflexivity (@term y2)))
           ((v (= x1 nil) (= y2 y2))                                                 (build.expansion (@formula (= x1 nil)) @-))
           ((v (= x1 nil) (= (iff (if x1 y1 z1) y2) (iff y1 y2)))                    (build.disjoined-pequal-by-args 'iff (@formula (= x1 nil)) (list *1 @-)))
           ((v (v (= x1 nil) (!= (iff y1 y2) t))
               (= (iff (if x1 y1 z1) y2) (iff y1 y2)))                               (build.multi-assoc-expansion @- (@formulas (= x1 nil) (!= (iff y1 y2) t)))   *2)
           ((v (!= (iff y1 y2) t) (= (iff y1 y2) t))                                 (build.propositional-schema (@formula (= (iff y1 y2) t))))
           ((v (v (= x1 nil) (!= (iff y1 y2) t))
               (= (iff y1 y2) t))                                                    (build.multi-assoc-expansion @- (@formulas (= x1 nil) (!= (iff y1 y2) t))))
           ((v (v (= x1 nil) (!= (iff y1 y2) t))
               (= (iff (if x1 y1 z1) y2) t))                                         (build.disjoined-transitivity-of-pequal *2 @-))
           ((v (= x1 nil) (v (!= (iff y1 y2) t) (= (iff (if x1 y1 z1) y2) t)))       (build.right-associativity @-)                                               *3)
           ;; ---
           ((v (!= x nil) (v (= y nil) (= (iff x y) nil)))                           (build.theorem (theorem-iff-false-true)))
           ((v (v (!= x nil) (= y nil)) (= (iff x y) nil))                           (build.associativity @-))
           ((v (v (!= x nil) (= y nil)) (!= (iff x y) t))                            (build.disjoined-not-t-from-nil @-))
           ((v (!= x nil) (v (= y nil) (!= (iff x y) t)))                            (build.right-associativity @-))
           ((v (!= x1 nil) (v (= x2 nil) (!= (iff x1 x2) t)))                        (build.instantiation @- (@sigma (x . x1) (y . x2))))
           ((v (!= x1 nil) (v (!= (iff x1 x2) t) (= x2 nil)))                        (build.disjoined-commute-or @-))
           ((v (v (!= (iff y1 y2) t) (= (iff (if x1 y1 z1) y2) t))
               (v (!= (iff x1 x2) t) (= x2 nil)))                                    (build.cut *3 @-))
           ((v (v (!= (iff x1 x2) t) (= x2 nil))
               (v (!= (iff y1 y2) t) (= (iff (if x1 y1 z1) y2) t)))                  (build.commute-or @-))
           ((v (!= (iff x1 x2) t) (v (= x2 nil) (v (!= (iff y1 y2) t)
                                                   (= (iff (if x1 y1 z1) y2) t))))   (build.right-associativity @-)))
  :minatbl ((iff . 2)
            (if . 3)))




(deftheorem rw.theorem-equal-of-if-x-y-y
  :derive (v (!= (iff x1 x2) t)
             (v (! (v (!= (not x2) nil) (= (equal y w) t)))
                (v (! (v (!= x2 nil) (= (equal z w) t)))
                   (= (equal (if x1 y z) w) t))))
  :proof (let* ((hyp1 (@formula (!= (iff x1 x2) t)))
                (hyp2 (@formula (! (v (!= (not x2) nil) (= (equal y w) t)))))
                (hyp3 (@formula (! (v (!= x2 nil) (= (equal z w) t)))))
                (hyps (list hyp1 hyp2 hyp3)))
           (@derive
            ((v (!= (iff x1 x2) t) (= (if x1 y z) (if x2 y z)))           (build.theorem (rw.theorem-iff-implies-pequal-if-1)))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (equal y w) t)))
                      (! (v (!= x2 nil) (= (equal z w) t)))))
                (= (if x1 y z) (if x2 y z)))                              (build.multi-assoc-expansion @- hyps)                                                                *0)
            ;; ---
            ((v (! (v (!= (not x2) nil) (= (equal y w) t))) (v (!= (not x2) nil) (= (equal y w) t)))  (build.propositional-schema (logic.~arg hyp2)))
            ((v (v (!= (not x2) nil) (= (equal y w) t)) (! (v (!= (not x2) nil) (= (equal y w) t))))  (build.commute-or @-))
            ((v (!= (not x2) nil) (v (= (equal y w) t) (! (v (!= (not x2) nil) (= (equal y w) t)))))  (build.right-associativity @-))
            ((v (v (= (equal y w) t) (! (v (!= (not x2) nil) (= (equal y w) t)))) (!= (not x2) nil))  (build.commute-or @-))
            ((v (v (= (equal y w) t) (! (v (!= (not x2) nil) (= (equal y w) t)))) (= x2 nil))         (build.disjoined-pequal-nil-from-negative-lit @-))
            ((v (= x2 nil) (v (= (equal y w) t) (! (v (!= (not x2) nil) (= (equal y w) t)))))         (build.commute-or @-))
            ((v (= x2 nil) (v (! (v (!= (not x2) nil) (= (equal y w) t))) (= (equal y w) t)))         (build.disjoined-commute-or @-))
            ((v (v (= x2 nil) (! (v (!= (not x2) nil) (= (equal y w) t)))) (= (equal y w) t))         (build.associativity @-))
            ((v (v (= x2 nil) (! (v (!= (not x2) nil) (= (equal y w) t)))) (= y w))                   (build.disjoined-pequal-from-equal @-)                                   *1a)
            ((v (= x nil) (= (if x y z) y))                                                           (build.axiom (axiom-if-when-not-nil)))
            ((v (= x2 nil) (= (if x2 y z) y))                                                         (build.instantiation @- (@sigma (x . x2))))
            ((v (v (= x2 nil) (! (v (!= (not x2) nil) (= (equal y w) t)))) (= (if x2 y z) y))         (build.multi-assoc-expansion @- (list (@formula (= x2 nil)) hyp2)))
            ((v (v (= x2 nil) (! (v (!= (not x2) nil) (= (equal y w) t)))) (= (if x2 y z) w))         (build.disjoined-transitivity-of-pequal @- *1a))
            ((v (= x2 nil) (v (! (v (!= (not x2) nil) (= (equal y w) t))) (= (if x2 y z) w)))         (build.right-associativity @-)                                               *1)
            ;; ---
            ((v (! (v (!= x2 nil) (= (equal z w) t))) (v (!= x2 nil) (= (equal z w) t)))          (build.propositional-schema (logic.~arg hyp3)))
            ((v (v (!= x2 nil) (= (equal z w) t)) (! (v (!= x2 nil) (= (equal z w) t))))          (build.commute-or @-))
            ((v (!= x2 nil) (v (= (equal z w) t) (! (v (!= x2 nil) (= (equal z w) t)))))          (build.right-associativity @-))
            ((v (!= x2 nil) (v (! (v (!= x2 nil) (= (equal z w) t))) (= (equal z w) t)))          (build.disjoined-commute-or @-))
            ((v (v (!= x2 nil) (! (v (!= x2 nil) (= (equal z w) t)))) (= (equal z w) t))          (build.associativity @-))
            ((v (v (!= x2 nil) (! (v (!= x2 nil) (= (equal z w) t)))) (= z w))                    (build.disjoined-pequal-from-equal @-)                                       *2a)
            ((v (!= x nil) (= (if x y z) z))                                                      (build.axiom (axiom-if-when-nil)))
            ((v (!= x2 nil) (= (if x2 y z) z))                                                    (build.instantiation @- (@sigma (x . x2))))
            ((v (v (!= x2 nil) (! (v (!= x2 nil) (= (equal z w) t)))) (= (if x2 y z) z))          (build.multi-assoc-expansion @- (list (@formula (!= x2 nil)) hyp3)))
            ((v (v (!= x2 nil) (! (v (!= x2 nil) (= (equal z w) t)))) (= (if x2 y z) w))          (build.disjoined-transitivity-of-pequal @- *2a))
            ((v (!= x2 nil) (v (! (v (!= x2 nil) (= (equal z w) t))) (= (if x2 y z) w)))          (build.right-associativity @-))
            ((v (!= x2 nil) (v (= (if x2 y z) w) (! (v (!= x2 nil) (= (equal z w) t)))))          (build.disjoined-commute-or @-)                                              *2)
            ;; ---
            ((v (v (! (v (!= (not x2) nil) (= (equal y w) t))) (= (if x2 y z) w))
                (v (= (if x2 y z) w) (! (v (!= x2 nil) (= (equal z w) t)))))                      (build.cut *1 *2))
            ((v (! (v (!= (not x2) nil) (= (equal y w) t)))
                (v (= (if x2 y z) w)
                   (v (= (if x2 y z) w)
                      (! (v (!= x2 nil) (= (equal z w) t))))))                                    (build.right-associativity @-))
            ((v (! (v (!= (not x2) nil) (= (equal y w) t)))
                (v (v (= (if x2 y z) w) (= (if x2 y z) w))
                   (! (v (!= x2 nil) (= (equal z w) t)))))                                        (build.disjoined-associativity @-))
            ((v (! (v (!= (not x2) nil) (= (equal y w) t)))
                (v (! (v (!= x2 nil) (= (equal z w) t)))
                   (v (= (if x2 y z) w) (= (if x2 y z) w))))                                      (build.disjoined-commute-or @-))
            ((v (v (! (v (!= (not x2) nil) (= (equal y w) t)))
                   (! (v (!= x2 nil) (= (equal z w) t))))
                (v (= (if x2 y z) w) (= (if x2 y z) w)))                                          (build.associativity @-))
            ((v (v (! (v (!= (not x2) nil) (= (equal y w) t)))
                   (! (v (!= x2 nil) (= (equal z w) t))))
                (= (if x2 y z) w))                                                                (build.disjoined-contraction @-))
            ((v (!= (iff x1 x2) t)
                (v (v (! (v (!= (not x2) nil) (= (equal y w) t)))
                      (! (v (!= x2 nil) (= (equal z w) t))))
                   (= (if x2 y z) w)))                                                            (build.expansion (@formula (!= (iff x1 x2) t)) @-))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (equal y w) t)))
                      (! (v (!= x2 nil) (= (equal z w) t)))))
                (= (if x2 y z) w))                                                                (build.associativity @-))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (equal y w) t)))
                      (! (v (!= x2 nil) (= (equal z w) t)))))
                (= (if x1 y z) w))                                                                (build.disjoined-transitivity-of-pequal *0 @-))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (equal y w) t)))
                      (! (v (!= x2 nil) (= (equal z w) t)))))
                (= (equal (if x1 y w) w) t))                                                      (build.disjoined-equal-from-pequal @-))
            ((v (!= (iff x1 x2) t)
                (v (v (! (v (!= (not x2) nil) (= (equal y w) t)))
                      (! (v (!= x2 nil) (= (equal z w) t))))
                   (= (equal (if x1 y z) w) t)))                                                  (build.right-associativity @-))
            ((v (!= (iff x1 x2) t)
                (v (! (v (!= (not x2) nil) (= (equal y w) t)))
                   (v (! (v (!= x2 nil) (= (equal z w) t)))
                      (= (equal (if x1 y z) w) t))))                                              (build.disjoined-right-associativity @-))))
  :minatbl ((if . 3)
            (equal . 2)
            (iff . 2)
            (not . 1)))


(deftheorem rw.theorem-iff-of-if-x-y-y
  :derive (v (!= (iff x1 x2) t)
             (v (! (v (!= (not x2) nil) (= (iff y w) t)))
                (v (! (v (!= x2 nil) (= (iff z w) t)))
                   (= (iff (if x1 y z) w) t))))
  :proof (let* ((hyp1 (@formula (!= (iff x1 x2) t)))
                (hyp2 (@formula (! (v (!= (not x2) nil) (= (iff y w) t)))))
                (hyp3 (@formula (! (v (!= x2 nil) (= (iff z w) t)))))
                (hyps (list hyp1 hyp2 hyp3)))
           (@derive
            ((v (!= (iff x1 x2) t) (= (if x1 y z) (if x2 y z)))                                       (build.theorem (rw.theorem-iff-implies-pequal-if-1)))
            ((v (!= (iff x1 x2) t) (= (iff (if x1 y z) (if x2 y z)) t))                               (build.disjoined-iff-from-pequal @-))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (equal y w) t)))
                      (! (v (!= x2 nil) (= (equal z w) t)))))
                (= (iff (if x1 y z) (if x2 y z)) t))                                                  (build.multi-assoc-expansion @- hyps)   *0)
            ;; ---
            ((v (! (v (!= (not x2) nil) (= (iff y w) t))) (v (!= (not x2) nil) (= (iff y w) t)))          (build.propositional-schema (logic.~arg hyp2)))
            ((v (v (!= (not x2) nil) (= (iff y w) t)) (! (v (!= (not x2) nil) (= (iff y w) t))))          (build.commute-or @-))
            ((v (!= (not x2) nil) (v (= (iff y w) t) (! (v (!= (not x2) nil) (= (iff y w) t)))))          (build.right-associativity @-))
            ((v (v (= (iff y w) t) (! (v (!= (not x2) nil) (= (iff y w) t)))) (!= (not x2) nil))          (build.commute-or @-))
            ((v (v (= (iff y w) t) (! (v (!= (not x2) nil) (= (iff y w) t)))) (= x2 nil))                 (build.disjoined-pequal-nil-from-negative-lit @-))
            ((v (= x2 nil) (v (= (iff y w) t) (! (v (!= (not x2) nil) (= (iff y w) t)))))                 (build.commute-or @-))
            ((v (= x2 nil) (v (! (v (!= (not x2) nil) (= (iff y w) t))) (= (iff y w) t)))                 (build.disjoined-commute-or @-))
            ((v (v (= x2 nil) (! (v (!= (not x2) nil) (= (iff y w) t)))) (= (iff y w) t))                 (build.associativity @-)                                                          *1a)
            ((v (= x nil) (= (if x y z) y))                                                               (build.axiom (axiom-if-when-not-nil)))
            ((v (= x2 nil) (= (if x2 y z) y))                                                             (build.instantiation @- (@sigma (x . x2))))
            ((v (v (= x2 nil) (! (v (!= (not x2) nil) (= (iff y w) t)))) (= (if x2 y z) y))               (build.multi-assoc-expansion @- (list (@formula (= x2 nil)) hyp2)))
            ((v (v (= x2 nil) (! (v (!= (not x2) nil) (= (iff y w) t)))) (= (iff (if x2 y z) y) t))       (build.disjoined-iff-from-pequal @-))
            ((v (v (= x2 nil) (! (v (!= (not x2) nil) (= (iff y w) t)))) (= (iff (if x2 y z) w) t))       (build.disjoined-transitivity-of-iff @- *1a))
            ((v (= x2 nil) (v (! (v (!= (not x2) nil) (= (iff y w) t))) (= (iff (if x2 y z) w) t)))       (build.right-associativity @-)                                               *1)
            ;; ---
            ((v (! (v (!= x2 nil) (= (iff z w) t))) (v (!= x2 nil) (= (iff z w) t)))                     (build.propositional-schema (logic.~arg hyp3)))
            ((v (v (!= x2 nil) (= (iff z w) t)) (! (v (!= x2 nil) (= (iff z w) t))))                     (build.commute-or @-))
            ((v (!= x2 nil) (v (= (iff z w) t) (! (v (!= x2 nil) (= (iff z w) t)))))                     (build.right-associativity @-))
            ((v (!= x2 nil) (v (! (v (!= x2 nil) (= (iff z w) t))) (= (iff z w) t)))                     (build.disjoined-commute-or @-))
            ((v (v (!= x2 nil) (! (v (!= x2 nil) (= (iff z w) t)))) (= (iff z w) t))                     (build.associativity @-)                                                          *2a)
            ((v (!= x nil) (= (if x y z) z))                                                             (build.axiom (axiom-if-when-nil)))
            ((v (!= x2 nil) (= (if x2 y z) z))                                                           (build.instantiation @- (@sigma (x . x2))))
            ((v (v (!= x2 nil) (! (v (!= x2 nil) (= (iff z w) t)))) (= (if x2 y z) z))                   (build.multi-assoc-expansion @- (list (@formula (!= x2 nil)) hyp3)))
            ((v (v (!= x2 nil) (! (v (!= x2 nil) (= (iff z w) t)))) (= (iff (if x2 y z) z) t))           (build.disjoined-iff-from-pequal @-))
            ((v (v (!= x2 nil) (! (v (!= x2 nil) (= (iff z w) t)))) (= (iff (if x2 y z) w) t))           (build.disjoined-transitivity-of-iff @- *2a))
            ((v (!= x2 nil) (v (! (v (!= x2 nil) (= (iff z w) t))) (= (iff (if x2 y z) w) t)))           (build.right-associativity @-))
            ((v (!= x2 nil) (v (= (if x2 y z) w) (! (v (!= x2 nil) (= (iff z w) t)))))                   (build.disjoined-commute-or @-)                                              *2)
            ;; ---
            ((v (v (! (v (!= (not x2) nil) (= (iff y w) t))) (= (iff (if x2 y z) w) t))
                (v (= (iff (if x2 y z) w) t) (! (v (!= x2 nil) (= (iff z w) t)))))                    (build.cut *1 *2))
            ((v (! (v (!= (not x2) nil) (= (iff y w) t)))
                (v (= (iff (if x2 y z) w) t)
                   (v (= (iff (if x2 y z) w) t)
                      (! (v (!= x2 nil) (= (iff z w) t))))))                                          (build.right-associativity @-))
            ((v (! (v (!= (not x2) nil) (= (iff y w) t)))
                (v (v (= (iff (if x2 y z) w) t) (= (iff (if x2 y z) w) t))
                   (! (v (!= x2 nil) (= (iff z w) t)))))                                              (build.disjoined-associativity @-))
            ((v (! (v (!= (not x2) nil) (= (iff y w) t)))
                (v (! (v (!= x2 nil) (= (iff z w) t)))
                   (v (= (iff (if x2 y z) w) t) (= (iff (if x2 y z) w) t))))                          (build.disjoined-commute-or @-))
            ((v (v (! (v (!= (not x2) nil) (= (iff y w) t)))
                   (! (v (!= x2 nil) (= (iff z w) t))))
                (v (= (iff (if x2 y z) w) t) (= (iff (if x2 y z) w) t)))                              (build.associativity @-))
            ((v (v (! (v (!= (not x2) nil) (= (iff y w) t)))
                   (! (v (!= x2 nil) (= (iff z w) t))))
                (= (iff (if x2 y z) w) t))                                                            (build.disjoined-contraction @-))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (iff y w) t)))
                      (! (v (!= x2 nil) (= (iff z w) t)))))
                (= (iff (if x2 y z) w) t))                                                            (build.multi-assoc-expansion @- (list hyp1 (logic.por hyp2 hyp3))))
            ((v (v (!= (iff x1 x2) t)
                   (v (! (v (!= (not x2) nil) (= (iff y w) t)))
                      (! (v (!= x2 nil) (= (iff z w) t)))))
                (= (iff (if x1 y z) w) t))                                                            (build.disjoined-transitivity-of-iff *0 @-))
            ((v (!= (iff x1 x2) t)
                (v (v (! (v (!= (not x2) nil) (= (iff y w) t)))
                      (! (v (!= x2 nil) (= (iff z w) t))))
                   (= (iff (if x1 y z) w) t)))                                                        (build.right-associativity @-))
            ((v (!= (iff x1 x2) t)
                (v (! (v (!= (not x2) nil) (= (iff y w) t)))
                   (v (! (v (!= x2 nil) (= (iff z w) t)))
                      (= (iff (if x1 y z) w) t))))                                                    (build.disjoined-right-associativity @-))
           ))
  :minatbl ((iff . 2)
            (if . 3)
            (not . 1)))


(defderiv rw.two-modus-ponens
  :derive C
  :from   ((proof x A)
           (proof y B)
           (proof z (v (! A) (v (! B) C))))
  :proof  (@derive
           ((v (! A) (v (! B) C))    (@given z))
           (A                        (@given x))
           ((v (! B) C)              (build.modus-ponens @- @--))
           (B                        (@given y))
           (C                        (build.modus-ponens @- @--))))

(defderiv rw.two-disjoined-modus-ponens
  :derive (v P C)
  :from   ((proof x (v P A))
           (proof y (v P B))
           (proof z (v (! A) (v (! B) C))))
  :proof  (@derive
           ((v (! A) (v (! B) C))         (@given z))
           ((v P (v (! A) (v (! B) C)))   (build.expansion (@formula P) @-))
           ((v P A)                       (@given x))
           ((v P (v (! B) C))             (build.disjoined-modus-ponens @- @--))
           ((v P B)                       (@given y))
           ((v P C)                       (build.disjoined-modus-ponens @- @--))))


(defderiv rw.three-modus-ponens
  :derive D
  :from   ((proof w A)
           (proof x B)
           (proof y C)
           (proof z (v (! A) (v (! B) (v (! C) D)))))
  :proof  (@derive
           ((v (! A) (v (! B) (v (! C) D)))     (@given z))
           (A                                   (@given w))
           ((v (! B) (v (! C) D))               (build.modus-ponens @- @--))
           (B                                   (@given x))
           ((v (! C) D)                         (build.modus-ponens @- @--))
           (C                                   (@given y))
           (D                                   (build.modus-ponens @- @--))))

(defderiv rw.three-disjoined-modus-ponens
  :derive (v P D)
  :from   ((proof w (v P A))
           (proof x (v P B))
           (proof y (v P C))
           (proof z (v (! A) (v (! B) (v (! C) D)))))
  :proof  (@derive
           ((v (! A) (v (! B) (v (! C) D)))            (@given z))
           ((v P (v (! A) (v (! B) (v (! C) D))))      (build.expansion (@formula P) @-))
           ((v P A)                                    (@given w))
           ((v P (v (! B) (v (! C) D)))                (build.disjoined-modus-ponens @- @--))
           ((v P B)                                    (@given x))
           ((v P (v (! C) D))                          (build.disjoined-modus-ponens @- @--))
           ((v P C)                                    (@given y))
           ((v P D)                                    (build.disjoined-modus-ponens @- @--))))


(defderiv rw.mp-mp2-mp
  :derive D
  :from   ((proof w A)
           (proof x (! B))
           (proof y C)
           (proof z (v (! A) (v B (v (! C) D)))))
  :proof  (@derive
           ((v (! A) (v B (v (! C) D)))   (@given z))
           (A                             (@given w))
           ((v B (v (! C) D))             (build.modus-ponens @- @--))
           ((! B)                         (@given x))
           ((v (! C) D)                   (build.modus-ponens-2 @- @--))
           (C                             (@given y))
           (D                             (build.modus-ponens @- @--))))

(defderiv rw.disjoined-mp-mp2-mp
  :derive (v P D)
  :from   ((proof w (v P A))
           (proof x (v P (! B)))
           (proof y (v P C))
           (proof z (v (! A) (v B (v (! C) D)))))
  :proof  (@derive
           ((v (! A) (v B (v (! C) D)))         (@given z))
           ((v P (v (! A) (v B (v (! C) D))))   (build.expansion (@formula P) @-))
           ((v P A)                             (@given w))
           ((v P (v B (v (! C) D)))             (build.disjoined-modus-ponens @- @--))
           ((v P (! B))                         (@given x))
           ((v P (v (! C) D))                   (build.disjoined-modus-ponens-2 @- @--))
           ((v P C)                             (@given y))
           ((v P D)                             (build.disjoined-modus-ponens @- @--))))



(dd.close)
