summaryrefslogtreecommitdiff
path: root/books/workshops/2007/erickson/bprove
diff options
context:
space:
mode:
Diffstat (limited to 'books/workshops/2007/erickson/bprove')
-rw-r--r--books/workshops/2007/erickson/bprove/Readme.lsp36
-rw-r--r--books/workshops/2007/erickson/bprove/bash.lisp287
-rw-r--r--books/workshops/2007/erickson/bprove/exdefs.lisp41
-rw-r--r--books/workshops/2007/erickson/bprove/gen.lisp337
-rw-r--r--books/workshops/2007/erickson/bprove/lemgen.lisp1373
-rw-r--r--books/workshops/2007/erickson/bprove/refute.lisp302
6 files changed, 2376 insertions, 0 deletions
diff --git a/books/workshops/2007/erickson/bprove/Readme.lsp b/books/workshops/2007/erickson/bprove/Readme.lsp
new file mode 100644
index 0000000..28c6b4e
--- /dev/null
+++ b/books/workshops/2007/erickson/bprove/Readme.lsp
@@ -0,0 +1,36 @@
+; A simple example of a book directory
+; Copyright (C) 2006 University of Texas at Austin
+
+((:FILES ; non-empty list of filenames, generated from Unix command "ls -1R"
+ "
+.:
+Makefile
+Readme.lsp
+bash.lisp
+exdefs.lisp
+gen.lisp
+lemgen.lisp
+refute.lisp
+")
+ (:TITLE "Backtracking Prover")
+ (:AUTHOR/S "J. Erickson") ; non-empty list of author strings
+ (:KEYWORDS ; non-empty list of keywords, case-insensitive
+ "book contributions" "contributed books" "induction" "generalization" "backtracking")
+ (:ABSTRACT "Book for paper ``Backtracking and Induction in ACL2'', ACL2 Workshop 2007")
+ (:PERMISSION ; author/s permission for distribution and copying:
+ "Copyright (C) 2007 John Erickson
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY 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; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA."))
+
diff --git a/books/workshops/2007/erickson/bprove/bash.lisp b/books/workshops/2007/erickson/bprove/bash.lisp
new file mode 100644
index 0000000..915d667
--- /dev/null
+++ b/books/workshops/2007/erickson/bprove/bash.lisp
@@ -0,0 +1,287 @@
+; Copyright (C) 2006 University of Texas at Austin
+
+; This program is free software; you can redistribute it and/or modify it under
+; the terms of Version 2 of the GNU General Public License as published by the
+; Free Software Foundation.
+
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY 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; if not, write to the Free Software
+; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+; Written by: Matt Kaufmann
+; email: Kaufmann@cs.utexas.edu
+; Department of Computer Science
+; University of Texas at Austin
+; Austin, TX 78701 U.S.A.
+
+; October, 2006
+
+; [Note added by Matt Kaufmann on May 5, 2012: I believe that this book, in
+; John Erickson's books/workshops/2007/erickson/bprove/, was based on a version
+; of my books/misc/bash.lisp book. I see a modification to
+; simplify-with-prover that comments out fertilize and eliminate-destructors.
+; I don't know if anything else was modified, but for now I'll just keep this
+; book as it currently stands rather than trying to bring it up to date with
+; books/misc/bash.lisp.]
+
+; In a nutshell:
+
+; If you submit (bash term), then the result is a list of goals to which ACL2
+; can simplify term when attempting to prove it. (In particular, if the result
+; is nil, then ACL2 can prove term.) More accurately: (bash term) returns (mv
+; erp val state), where: erp is nil unless there is an error; and val is a list
+; of terms, in untranslated (user-level) form, whose provability implies the
+; provability of the input term. If ACL2 cannot simplify the input term, then
+; there is an error, i.e., erp is not nil.
+
+; More details:
+
+; This book defines a utility similar to the proof-builder's bash command, but
+; for use in the top-level loop. The input term can be a user-level term,
+; i.e., it need not be translated. Thus this bash utility is given a term, and
+; it returns an error triple (mv erp termlist state) where if erp is not nil,
+; then termlist is the list of goals that ACL2 would get stuck on, if you were
+; to attempt to prove the given term with only simplification, i.e., with a
+; "Goal" hint of :do-not '(generalize eliminate-destructors fertilize
+; eliminate-irrelevance) and with induction turned off. Bash does all the
+; normal simplification stuff, including forward chaining. Use :hints to
+; specify hints using the same syntax as for thm and defthm. Use a non-nil
+; value of :verbose if you want output, including the proof attempt. The
+; keyword values are not evaluated, so :hints could be of the form (("Goal
+; ...)) but not '(("Goal" ...)).
+
+; This book also includes a functional (non-macro) version of bash, bash-fn.
+; At the end is a variant contributed by Dave Greve, bash-term-to-dnf, that
+; returns a list of goals (implicitly conjoined) where each goal has the form
+; (lit1 lit2 ... litk), for which the goal is equivalent to the negation of the
+; conjunction of the liti.
+
+; Examples:
+
+#|
+ACL2 !>(bash (equal (append x y) (append (car (cons x a)) z)))
+ ((EQUAL (APPEND X Y) (APPEND X Z)))
+ACL2 !>(bash (equal (car (cons x y)) x))
+ NIL
+ACL2 !>(bash (implies (true-listp x) (equal (append x y) zzz))
+ :hints (("Goal" :expand ((true-listp x)
+ (true-listp (cdr x))
+ (append x y)))))
+ ((EQUAL Y ZZZ)
+ (IMPLIES (AND (CONSP X)
+ (CONSP (CDR X))
+ (TRUE-LISTP (CDDR X)))
+ (EQUAL (LIST* (CAR X)
+ (CADR X)
+ (APPEND (CDDR X) Y))
+ ZZZ))
+ (IMPLIES (AND (CONSP X) (NOT (CDR X)))
+ (EQUAL (CONS (CAR X) Y) ZZZ)))
+ACL2 !>(bash-term-to-dnf
+ '(implies (true-listp x) (equal (append x y) zzz))
+ '(("Goal" :expand ((true-listp x)
+ (true-listp (cdr x))
+ (append x y))))
+ nil state)
+ (((EQUAL Y ZZZ))
+ ((NOT (CONSP X))
+ (NOT (CONSP (CDR X)))
+ (NOT (TRUE-LISTP (CDDR X)))
+ (EQUAL (LIST* (CAR X)
+ (CADR X)
+ (APPEND (CDDR X) Y))
+ ZZZ))
+ ((NOT (CONSP X))
+ (CDR X)
+ (EQUAL (CONS (CAR X) Y) ZZZ)))
+ACL2 !>
+|# ; |
+
+(in-package "ACL2")
+
+(program)
+
+(set-state-ok t)
+
+; The following appears in the ACL2 source code, but is included temporarily
+; for a few days pending some users updating to a sufficiently recent
+; development snapshot.
+(defun unproved-pc-prove-clauses (ttree)
+ (reverse-strip-cdrs (tagged-objects :bye ttree) nil))
+
+(defun simplify-with-prover (form hints ctx state)
+
+; This is patterned after (define-pc-primitive prove ...).
+
+ (let ((wrld (w state))
+ (ens (ens state))
+ (name-tree 'bash))
+ (er-let*
+ ((thints (translate-hints
+ name-tree
+
+; Keep the following in sync with the definition of the proof-builder :bash
+; command.
+
+ (append
+ *bash-skip-forcing-round-hints*
+ (add-string-val-pair-to-string-val-alist
+ "Goal"
+ :do-not
+ (list 'quote '(generalize ;eliminate-destructors
+ ;fertilize
+ eliminate-irrelevance))
+ (add-string-val-pair-to-string-val-alist
+ "Goal"
+ :do-not-induct
+ name-tree
+ hints))
+ (default-hints wrld))
+ ctx wrld state))
+ (tterm (translate form t t t ctx wrld state)))
+ (mv-let (erp ttree state)
+ (pc-prove tterm form thints t ens wrld ctx state)
+ (cond (erp (mv t nil state))
+ (t (let ((clauses (unproved-pc-prove-clauses ttree)))
+ (cond ((and (eql (length clauses) 1)
+ (eql (length (car clauses)) 1)
+ (eql (caar clauses) tterm))
+ (mv 'no-change nil state))
+ (t (value clauses))))))))))
+
+(defun simplify-with-prover2 (form hints ctx state)
+
+; This is patterned after (define-pc-primitive prove ...).
+
+ (let ((wrld (w state))
+ (ens (ens state))
+ (name-tree 'bash))
+ (er-let*
+ ((thints (translate-hints
+ name-tree
+
+; Keep the following in sync with the definition of the proof-builder :bash
+; command.
+
+ (append
+ *bash-skip-forcing-round-hints*
+ (add-string-val-pair-to-string-val-alist
+ "Goal"
+ :do-not
+ (list 'quote '(generalize eliminate-destructors
+ ;fertilize
+ eliminate-irrelevance))
+ (add-string-val-pair-to-string-val-alist
+ "Goal"
+ :do-not-induct
+ name-tree
+ hints))
+ (default-hints wrld))
+ ctx wrld state))
+ (tterm (translate form t t t ctx wrld state)))
+ (mv-let (erp ttree state)
+ (pc-prove tterm form thints t ens wrld ctx state)
+ (cond (erp (mv t nil state))
+ (t (let ((clauses (unproved-pc-prove-clauses ttree)))
+ (cond ((and (eql (length clauses) 1)
+ (eql (length (car clauses)) 1)
+ (eql (caar clauses) tterm))
+ (mv 'no-change nil state))
+ (t (value clauses))))))))))
+
+(defun bash-fn (form hints verbose ctx state)
+
+; Keep this in sync with bash-term-to-dnf.
+
+ (mv-let
+ (erp clauses state)
+ (cond (verbose
+ (simplify-with-prover form hints ctx state))
+ (t
+ (state-global-let*
+ ((inhibit-output-lst *valid-output-names*))
+ (simplify-with-prover form hints ctx state))))
+ (cond
+ (erp
+ (pprogn
+ (warning$ ctx "bash"
+ "Unable to simplify the input term~@0"
+ (cond ((eq erp 'no-change)
+ ".")
+ (t (msg " because an error occurred.~@0"
+ (cond
+ (verbose "")
+ (t " Try setting the verbose flag to t in ~
+ order to see what is going on."))))))
+ (value (list form))))
+ (t
+ (value (prettyify-clause-lst clauses (let*-abstractionp state) (w state)))))))
+
+(defmacro bash (term &key verbose hints)
+ `(bash-fn ',term ',hints ',verbose 'bash state))
+
+; Dave Greve has contributed the following (only slightly modified here), to
+; create a variant bash-term-to-dnf of bash-fn. This example may suggest other
+; variants; feel free to contribute yours to Matt Kaufmann,
+; kaufmann@cs.utexas.edu.
+
+(defun goals-to-cnf (goals)
+ (cond ((endp goals) nil)
+ (t (cons (append (access goal (car goals) :hyps)
+ (list (dumb-negate-lit (access goal (car goals)
+ :conc))))
+ (goals-to-cnf (cdr goals))))))
+
+(defun untranslate-lst-lst (list iff-flg wrld)
+ (cond
+ ((endp list)
+ nil)
+ (t (cons (untranslate-lst (car list) iff-flg wrld)
+ (untranslate-lst-lst (cdr list) iff-flg wrld)))))
+
+(defun bash-term-to-dnf (form hints verbose state)
+
+; Keep this in sync with bash-fn.
+
+ (let ((ctx 'bash-term-to-dnf))
+ (mv-let
+ (erp clauses state)
+ (cond (verbose
+ (simplify-with-prover form hints ctx state))
+ (t
+ (state-global-let*
+ ((inhibit-output-lst *valid-output-names*))
+ (simplify-with-prover form hints ctx state))))
+ (cond
+ (erp
+ (pprogn
+ (value (list (list form)))))
+ (t
+ (value clauses))))))
+
+
+;no dtor or fertilize
+(defun bash-term-to-dnf2 (form hints verbose state)
+
+; Keep this in sync with bash-fn.
+
+ (let ((ctx 'bash-term-to-dnf))
+ (mv-let
+ (erp clauses state)
+ (cond (verbose
+ (simplify-with-prover2 form hints ctx state))
+ (t
+ (state-global-let*
+ ((inhibit-output-lst *valid-output-names*))
+ (simplify-with-prover2 form hints ctx state))))
+ (cond
+ (erp
+ (pprogn
+ (value (list (list form)))))
+ (t
+ (value clauses))))))
diff --git a/books/workshops/2007/erickson/bprove/exdefs.lisp b/books/workshops/2007/erickson/bprove/exdefs.lisp
new file mode 100644
index 0000000..c831cea
--- /dev/null
+++ b/books/workshops/2007/erickson/bprove/exdefs.lisp
@@ -0,0 +1,41 @@
+(in-package "ACL2")
+
+(include-book "lemgen")
+
+
+(defun ilen (x a)
+ (if (endp x)
+ a
+ (ilen (cdr x) (1+ a))))
+
+(defun rot2 (i x)
+ (if (endp i)
+ x
+ (rot2 (cdr i) (append (cdr x) (list (car x))))))
+
+(defun rv1 (x a)
+ (if (endp x)
+ a
+ (rv1 (cdr x) (cons (car x) a))))
+
+
+(make-event
+
+; Added by Matt K. after v5-0. Apparently bprove doesn't call
+; initialize-summary-accumulators, which is what invokes (time-tracker :tau
+; :init ...). So we take the easy way out here and turn off time-tracker
+; during certification. If someone decides to use bprove outside this
+; directory, that person can figure out how to initialize the time-tracker for
+; tag :tau as it's done in initialize-summary-accumulators.
+
+ (prog2$ (time-tracker nil)
+ (value '(value-triple nil))))
+
+(bprove (equal (rv1 x 'nil) (rv x)))
+
+(bprove (equal (ilen x '0) (len x)))
+
+(bprove (implies (and (true-listp x)) (equal (rot2 x x) x)))
+
+(bprove (implies (and (true-listp x) (true-listp y)) (equal (rot2 x (append x y)) (append y x))))
+
diff --git a/books/workshops/2007/erickson/bprove/gen.lisp b/books/workshops/2007/erickson/bprove/gen.lisp
new file mode 100644
index 0000000..307f555
--- /dev/null
+++ b/books/workshops/2007/erickson/bprove/gen.lisp
@@ -0,0 +1,337 @@
+(in-package "ACL2")
+
+(set-ignore-ok t)
+
+(set-irrelevant-formals-ok t)
+
+(set-state-ok t)
+
+(program)
+
+; And now we do generalization...
+
+(defun collectable-fnp2 (fn ens wrld)
+
+; A common collectable term is a non-quoted term that is an
+; application of a collectable-fnp2. Most functions are common
+; collectable. The ones that are not are cons, open lambdas, and the
+; (enabled) destructors of wrld.
+
+ t)
+
+(mutual-recursion
+
+(defun smallest-common-subterms12 (term1 term2 ens wrld ans)
+
+; This is the workhorse of smallest-common-subterms, but the arguments are
+; arranged so that we know that term1 is the smaller. We add to ans
+; every subterm x of term1 that (a) occurs in term2, (b) is
+; collectable, and (c) has no collectable subterms in common with
+; term2.
+
+; We return two values. The first is the modified ans. The second is
+; t or nil according to whether term1 occurs in term2 but neither it
+; nor any of its subterms is collectable. This latter condition is
+; said to be the ``potential'' of term1 participating in a collection
+; vicariously. What does that mean? Suppose a1, ..., an, all have
+; potential. Then none of them are collected (because they aren't
+; collectable) but each occurs in term2. Thus, a term such as (fn a1
+; ... an) might actually be collected because it may occur in term2
+; (all of its args do, at least), it may be collectable, and none of
+; its subterms are. So those ai have the potential to participate
+; vicariously in a collection.
+
+ (cond ((or (variablep term1)
+ )
+
+; Since term1 is not collectable, we don't add it to ans. But we return
+; t as our second value if term1 occurs in term2, i.e., term1 has
+; potential.
+
+ (mv ans (occur term1 term2)))
+ ((fquotep term1)
+ (if (occur term1 term2)
+ (mv (add-to-set-equal term1 ans)
+ nil)
+ (mv ans nil)))
+
+ (t
+ (if (occur term1 term2)
+ (mv (add-to-set-equal term1 ans)
+ nil)
+ (mv-let
+ (ans all-potentials)
+ (smallest-common-subterms12-lst (fargs term1) term2 ens wrld ans)
+ (cond ((null all-potentials)
+
+; Ok, some arg did not have potential. Either it did not occur or it
+; was collected. In either case, term1 should not be collected and
+; furthermore, has no potential for participating later.
+
+ (mv ans nil))
+ ((not (occur term1 term2))
+
+; Every arg of term1 had potential but term1 doesn't occur in
+; term2. That means we don't collect it and it hasn't got
+; potential.
+ (mv ans nil))
+ ((collectable-fnp2 (ffn-symb term1) ens wrld)
+
+; So term1 occurs, none of its subterms were collected, and term1
+; is collectable. So we collect it, but it no longer has potential
+; (because it got collected).
+
+ (mv (add-to-set-equal term1 ans)
+ nil))
+
+ (t
+
+; Term1 occurs, none of its subterms were collected, and term1
+; was not collected. So it has potential to participate vicariously.
+
+ (mv ans t))))))))
+
+(defun smallest-common-subterms12-lst (terms term2 ens wrld ans)
+
+; We accumulate onto ans every subterm of every element of terms
+; that (a) occurs in term2, (b) is collectable, and (c) has no
+; collectable subterms in common with term2. We return the modified
+; ans and the flag indicating whether all of the terms have potential.
+
+ (cond
+ ((null terms) (mv ans t))
+ (t (mv-let
+ (ans car-potential)
+ (smallest-common-subterms12 (car terms) term2 ens wrld ans)
+ (mv-let
+ (ans cdr-potential)
+ (smallest-common-subterms12-lst (cdr terms) term2 ens wrld ans)
+ (mv ans
+ (and car-potential
+ cdr-potential)))))))
+
+)
+
+(defun dumb-fn-count-1 (flg x acc)
+ (declare (xargs :guard (and (if flg
+ (pseudo-term-listp x)
+ (pseudo-termp x))
+ (natp acc))))
+ (cond (flg (cond ((null x)
+ acc)
+ (t
+ (dumb-fn-count-1 t (cdr x)
+ (dumb-fn-count-1 nil (car x) acc)))))
+ ((or (variablep x) (fquotep x))
+ acc)
+ (t (dumb-fn-count-1 t (fargs x) (1+ acc)))))
+
+(defun dumb-fn-count (x)
+
+; Originally we had this upside-down call tree, where cons-count was a function
+; that counts the number of conses in an object.
+
+; cons-count
+; smallest-common-subterms
+; generalizable-terms-across-relations
+; generalizable-terms
+; generalizable-terms-across-literals1
+; generalizable-terms-across-literals
+; generalizable-terms
+; generalize-clause
+
+; But the role of evgs disappears if we use dumb-occur instead of occur in our
+; algorithm for finding common subterms, which seems anyhow like the right
+; thing to do if the point is to generalize common subterms to variables.
+; Evg-occur is called by occur but not by dumb-occur, and evg-occur is
+; potentially expensive on galactic objects. So we no longer use cons-count to
+; compute the smallest-common-subterms; we use fn-count-dumb.
+
+ (dumb-fn-count-1 nil x 0))
+
+(defun smallest-common-subterms2 (term1 term2 ens wrld ans)
+
+; We accumulate onto ans and return the list of every subterm x of
+; term1 that is also a subterm of term2, provided x is ``collectable''
+; and no subterm of x is collectable. A term is a collectable if it
+; is an application of a collectable-fnp2 and is not an explicit value.
+; Our aim is to collect the ``innermost'' or ``smallest'' collectable
+; subterms.
+
+ (mv-let (ans potential)
+ (cond ((> (dumb-fn-count term1) (dumb-fn-count term2))
+ (smallest-common-subterms12 term2 term1 ens wrld ans))
+ (t (smallest-common-subterms12 term1 term2 ens wrld ans)))
+ (declare (ignore potential))
+ ans))
+
+(defun generalizing-relationp2 (term wrld)
+
+; Term occurs as a literal of a clause. We want to know whether
+; we should generalize common subterms occurring in its arguments.
+; Right now the answer is geared to the special case that term is
+; a binary relation -- or at least that only two of the arguments
+; encourage generalizations. We return three results. The first
+; is t or nil indicating whether the other two are important.
+; The other two are the two terms we should explore for common
+; subterms.
+
+; For example, for (equal lhs rhs), (not (equal lhs rhs)), (< lhs
+; rhs), and (not (< lhs rhs)), we return t, lhs, and rhs. We also
+; generalize across any known equivalence relation, but this code has
+; built into the assumption that all such relations have arity at
+; least 2 and just returns the first two args. For (member x y), we
+; return three nils.
+
+ (mv-let (neg-flg atm)
+ (strip-not term)
+ (declare (ignore neg-flg))
+ (cond ((or (variablep atm)
+ (fquotep atm)
+ (flambda-applicationp atm))
+ (mv nil nil nil))
+ ((or (eq (ffn-symb atm) 'equal)
+ (eq (ffn-symb atm) '<)
+ (equivalence-relationp (ffn-symb atm) wrld))
+ (mv t (fargn atm 1) (fargn atm 2)))
+ (t (mv nil nil nil)))))
+
+(defun generalizable-terms-across-relations2 (cl ens wrld ans)
+
+; We scan clause cl for each literal that is a generalizing-relationp2,
+; e.g., (equal lhs rhs), and collect into ans all the smallest common
+; subterms that occur in each lhs and rhs. We return the final ans.
+
+ (cond ((null cl) ans)
+ (t (mv-let (genp lhs rhs)
+ (generalizing-relationp2 (car cl) wrld)
+ (generalizable-terms-across-relations2
+ (cdr cl) ens wrld
+ (if genp
+ (smallest-common-subterms2 lhs rhs ens wrld ans)
+ ans))))))
+
+(defun generalizable-terms-across-literals12 (lit1 cl ens wrld ans)
+ (cond ((null cl) ans)
+ (t (generalizable-terms-across-literals12
+ lit1 (cdr cl) ens wrld
+ (smallest-common-subterms2 lit1 (car cl) ens wrld ans)))))
+
+(defun generalizable-terms-across-literals2 (cl ens wrld ans)
+
+; We consider each pair of literals, lit1 and lit2, in cl and
+; collect into ans the smallest common subterms that occur in
+; both lit1 and lit2. We return the final ans.
+
+ (cond ((null cl) ans)
+ (t (generalizable-terms-across-literals2
+ (cdr cl) ens wrld
+ (generalizable-terms-across-literals12 (car cl) (cdr cl)
+ ens wrld ans)))))
+
+(defun generalizable-terms2 (cl ens wrld)
+
+; We return the list of all the subterms of cl that we will generalize.
+; We look for common subterms across equalities and inequalities, and
+; for common subterms between the literals of cl.
+
+ (generalizable-terms-across-literals2
+ cl ens wrld
+ (generalizable-terms-across-relations2
+ cl ens wrld nil)))
+
+(mutual-recursion
+ (defun quote-types (x)
+ (if (atom x)
+ nil
+ (if (and (quotep x)
+ (acl2-numberp (cadr x)))
+ `((not (acl2-numberp ,x)))
+ (quote-types-l (cdr x)))))
+ (defun quote-types-l (x)
+ (if (endp x)
+ nil
+ (append (quote-types (car x))
+ (quote-types-l (cdr x))))))
+
+(defun generalize-clause2 (cl hist pspv wrld state)
+
+; A standard clause processor of the waterfall.
+
+; We return 4 values. The first is a signal that is either 'hit, or
+; 'miss. When the signal is 'miss, the other 3 values are irrelevant.
+; When the signal is 'hit, the second result is the list of new
+; clauses, the third is a ttree that will become that component of the
+; history-entry for this generalization, and the fourth is an
+; unmodified pspv. (We return the fourth thing to adhere to the
+; convention used by all clause processors in the waterfall (q.v.).)
+; The ttree we return is 'assumption-free.
+
+ (declare (ignore state))
+ (cond
+ ((not (assoc-eq 'being-proved-by-induction
+ (access prove-spec-var pspv :pool)))
+ (mv 'miss nil nil nil))
+ (t (let* ((ens (access rewrite-constant
+ (access prove-spec-var
+ pspv
+ :rewrite-constant)
+ :current-enabled-structure))
+ (terms (generalizable-terms2 cl ens wrld)))
+ (cond
+ ((null terms)
+ (mv 'miss nil nil nil))
+ (t
+ (let ((cl (append (quote-types-l cl) cl)))
+ (mv-let
+ (contradictionp type-alist ttree)
+ (type-alist-clause cl nil t nil ens wrld
+ nil nil)
+ (declare (ignore ttree))
+ (cond
+ (contradictionp
+
+; We compute the type-alist of the clause to allow us to generate nice
+; variable names and to restrict the coming generalization. We know
+; that a contradiction cannot arise, because this clause survived
+; simplification. However, we will return an accurate answer just to
+; be rugged. We'll report that we couldn't do anything! That's
+; really funny. We just proved our goal and we're saying we can't do
+; anything. But if we made this fn sometimes return the empty set of
+; clauses we'd want to fix the io handler for it and we'd have to
+; respect the 'assumptions in the ttree and we don't. Do we? As
+; usual, we ignore the ttree in this case, and hence we ignore it
+; totally since it is known to be nil when contradictionp is nil.
+
+ (mv 'miss nil nil nil))
+ (t
+ (let ((gen-vars
+ (generate-variable-lst terms
+ (all-vars1-lst cl
+ (owned-vars
+ 'generalize-clause2
+ nil
+ hist))
+ type-alist ens wrld)))
+ (mv-let (generalized-cl restricted-vars var-to-runes-alist ttree)
+ (generalize1 cl type-alist terms gen-vars ens wrld)
+ (mv 'hit
+ (list generalized-cl)
+ (add-to-tag-tree
+ 'variables gen-vars
+ (add-to-tag-tree
+ 'terms terms
+ (add-to-tag-tree
+ 'restricted-vars restricted-vars
+ (add-to-tag-tree
+ 'var-to-runes-alist var-to-runes-alist
+ (add-to-tag-tree
+ 'ts-ttree ttree
+ nil)))))
+ pspv)))))))))))))
+
+
+;(defun unhidden-lit-info (hist clause pos wrld) (mv nil nil nil))
+
+;(defun cross-fertilizep/c (equiv cl direction lhs1 rhs1) t)
+
diff --git a/books/workshops/2007/erickson/bprove/lemgen.lisp b/books/workshops/2007/erickson/bprove/lemgen.lisp
new file mode 100644
index 0000000..9d99b9a
--- /dev/null
+++ b/books/workshops/2007/erickson/bprove/lemgen.lisp
@@ -0,0 +1,1373 @@
+(in-package "ACL2")
+
+(include-book "refute")
+;(include-book "exdefs")
+(include-book "gen")
+
+;(include-book "bash3")
+;(include-book "../induct/myutil")
+;(include-book "cprove")
+
+(set-state-ok t)
+
+;(set-ld-redefinition-action '(:doit . :overwrite) state)
+
+(set-ignore-ok t)
+(set-irrelevant-formals-ok t)
+
+
+(logic)
+
+(defthm car-ap-cons
+ (equal (car (append (cons a b) c))
+ a))
+
+(defthm cdr-ap-cons
+ (equal (cdr (append (cons a nil) c))
+ c))
+
+(defthm append-cons (CONSP (BINARY-APPEND (CONS X3 'NIL) z)) :rule-classes :type-prescription)
+
+(defthm cons-ap
+ (implies (syntaxp (not (equal x ''nil)))
+ (equal (cons a x)
+ (append (cons a nil) x))))
+
+;(defthm cons-ap-ap
+; (implies (syntaxp (not (equal x ''nil)))
+; (equal (append (append (cons a x) y) z)
+; (append (cons a nil) (append x y)))))
+
+
+(defthm ap-ap
+ (equal (append (append x y) z) (append x y z)))
+
+(program)
+
+
+
+(defun basicp (x)
+ (if (endp x)
+ t
+ (and
+ (atom (car x))
+ (basicp (cdr x)))))
+
+(defun basic-on-call (x c)
+ (if (endp x)
+ t
+ (and (or (atom (car c))
+ (atom (car x)))
+ (basic-on-call (cdr x) (cdr c)))))
+
+(defun basic-on-calls (x l)
+ (if (endp l)
+ t
+ (and (basic-on-call (cdr x) (cdr (car l)))
+ (basic-on-calls x (cdr l)))))
+
+(defun get-calls (l)
+ (if (endp l)
+ nil
+ (append (cddr (car l))
+ (get-calls (cdr l)))))
+
+(defun ind-vars-basicp (x state)
+ (let* ((im (getprop (car x) 'induction-machine nil 'current-acl2-world (w state)))
+ (calls (get-calls im)))
+ (if (null im)
+ nil
+ (basic-on-calls x calls))))
+
+;(ind-vars-basicp '(BINARY-APPEND Y (CONS X1 'NIL)) state)
+
+(mutual-recursion
+ (defun get-schemes (x state)
+ (if (atom x)
+ nil
+ (append
+ (if (ind-vars-basicp x state)
+ (list x)
+ nil)
+ (get-schemes-l (cdr x) state))))
+ (defun get-schemes-l (x state)
+ (if (endp x)
+ nil
+ (append (get-schemes (car x) state)
+ (get-schemes-l (cdr x) state)))))
+
+
+;(get-schemes '(implies (equal (rv (rv x)) x)))
+
+;(get-schemes '(implies (and (true-listp x) (true-listp y)) (equal (rot2 x (ap x y)) (ap y x))))
+
+;(TRANSLATE '(implies (and (true-listp x) (true-listp y)) (equal (rot2 x (append x y)) (append y x))) nil NIL nil nil (W state) STATE)
+
+
+(mutual-recursion
+ (defun expand-implies (x)
+ (if (atom x)
+ x
+ (let ((cdrx (expand-implies-l (cdr x))))
+ (if (eq (car x) 'implies)
+ (mv-let (b err) (pmatch-l '(p q) cdrx nil) (declare (ignore err))
+ (inst '(IF P (IF Q T NIL) T) b))
+ (cons (car x) cdrx)))))
+ (defun expand-implies-l (x)
+ (if (endp x)
+ nil
+ (cons (expand-implies (car x))
+ (expand-implies-l (cdr x))))))
+
+#|
+(expand-implies
+ '(IMPLIES (IF (TRUE-LISTP X) (TRUE-LISTP Y) 'NIL)
+ (EQUAL (ROT2 X (BINARY-APPEND X Y))
+ (BINARY-APPEND Y X))))
+|#
+
+
+#|
+(clausify '(IF (IF (TRUE-LISTP X) (TRUE-LISTP Y) 'NIL)
+ (IF (EQUAL (ROT2 X (BINARY-APPEND X Y))
+ (BINARY-APPEND Y X))
+ T NIL)
+ T) nil nil (sr-limit (w state)))
+|#
+
+(defun triv-clause (x)
+ (if (endp x)
+ nil
+ (if (eq (car x) t)
+ t
+ (triv-clause (cdr x)))))
+
+(defun simp-clause (x)
+ (if (endp x)
+ nil
+ (if (eq (car x) nil)
+ (simp-clause (cdr x))
+ (cons (car x) (simp-clause (cdr x))))))
+
+(defun simp-and-filter (x)
+ (if (endp x)
+ nil
+ (if (triv-clause (car x))
+ (simp-and-filter (cdr x))
+ (cons (simp-clause (car x))
+ (simp-and-filter (cdr x))))))
+
+(set-state-ok t)
+(set-ignore-ok t)
+
+
+(defun norm (x state)
+ (mv-let (nop x state) (TRANSLATE x nil NIL nil nil (W state) STATE)
+ (let* ((x (expand-implies x))
+ (x (clausify x nil nil (sr-limit (w state))))
+ (x (simp-and-filter x)))
+ (mv x state))))
+
+(defun norm-l (x state)
+ (if (endp x)
+ (mv nil state)
+ (mv-let (r state) (norm (car x) state)
+ (mv-let (r2 state) (norm-l (cdr x) state)
+ (mv (append r r2) state)))))
+
+
+;(norm '(implies (and (true-listp x) (true-listp y)) (equal (rot2 x (append x y)) (append y x))) state)
+
+#|
+(get-schemes-l '((NOT (TRUE-LISTP X))
+ (NOT (TRUE-LISTP Y))
+ (EQUAL (ROT2 X (BINARY-APPEND X Y))
+ (BINARY-APPEND Y X))))
+
+
+
+|#
+
+
+(defun new-fsymbol (n)
+ (intern (concatenate 'string "G" (coerce (explode-nonnegative-integer n 10 nil) 'string)) "ACL2"))
+
+(defun new-var (n)
+ (intern (concatenate 'string "NV" (coerce (explode-nonnegative-integer n 10 nil) 'string)) "ACL2"))
+
+(defun new-thm (n)
+ (intern (concatenate 'string "T" (coerce (explode-nonnegative-integer n 10 nil) 'string)) "ACL2"))
+
+(defun new-ifn (n)
+ (intern (concatenate 'string "IFN" (coerce (explode-nonnegative-integer n 10 nil) 'string)) "ACL2"))
+
+(defun new-label (n)
+ (intern (concatenate 'string "L" (coerce (explode-nonnegative-integer n 10 nil) 'string)) "ACL2"))
+
+
+
+(program)
+
+
+(defun err-fun () t)
+;(trace! (err-fun :entry (break)))
+
+
+(defrec pv (bind schemes log max-fun max-var max-ifn max-thm max-label depth) t)
+
+
+(mutual-recursion
+(defun intro-constr-funs (x ind-vars all-vars bind pv state)
+ (if (atom x)
+ (if (member x ind-vars)
+ (mv x bind pv state)
+ (if (assoc x bind)
+ (mv (cadr (assoc x bind)) bind pv state)
+ (let* ((nf (new-fsymbol (access pv pv :max-fun)))
+ (nc `(,nf ,@all-vars))
+ (pv (change pv pv :max-fun (1+ (access pv pv :max-fun))))
+ (bind (cons (list x nc) bind)))
+ (mv-let (erp val state) (ld (list `(defstub ,nf (,@all-vars) t)))
+ (if (or erp (equal val :error))
+ (mv (err-fun) bind pv state)
+ (let ((pv (change pv pv :log (append
+ (access pv pv :log)
+ (list `(defstub ,nf (,@all-vars) t))))))
+ (mv nc bind pv state)))))))
+ (if (quotep x)
+ (mv x bind pv state)
+ (mv-let (r bind pv state) (intro-constr-funs-l (cdr x) ind-vars all-vars bind pv state)
+ (mv (cons (car x) r) bind pv state)))))
+(defun intro-constr-funs-l (x ind-vars all-vars bind pv state)
+ (if (endp x)
+ (mv nil bind pv state)
+ (mv-let (r bind pv state) (intro-constr-funs (car x) ind-vars all-vars bind pv state)
+ (mv-let (r2 bind pv state) (intro-constr-funs-l (cdr x) ind-vars all-vars bind pv state)
+ (mv (cons r r2) bind pv state))))))
+
+
+
+(defun rm-nop-subs (x)
+ (if (endp x)
+ nil
+ (if (equal (car (car x)) (cadr (car x)))
+ (rm-nop-subs (cdr x))
+ (cons (car x) (rm-nop-subs (cdr x))))))
+
+(defun strip-unmeas (x m)
+ (if (endp x)
+ nil
+ (if (member-equal (car (car x)) m)
+ (cons (car x) (strip-unmeas (cdr x) m))
+ (strip-unmeas (cdr x) m))))
+
+(defun ih-from-calls (x varsub fcall calls measured pv state)
+ (if (endp calls)
+ (mv nil nil pv state)
+ (let* ((call (car calls)))
+ (mv-let (isub err) (pmatch fcall call nil)
+ (let ((isub (strip-unmeas isub measured)))
+ (let ((realsub (inst-ll isub varsub)))
+ (mv-let (r bind pv state)
+ (intro-constr-funs
+ (inst x realsub)
+ (strip-cars realsub)
+ (all-vars x)
+ nil
+ pv
+ state)
+ (mv-let (r2 calls2 pv state)
+ (ih-from-calls x varsub
+ fcall
+ (cdr calls)
+ measured
+ pv
+ state)
+ (mv (cons r r2) (append (list (append realsub bind)) calls2) pv state)))))))))
+
+
+
+
+(defun subgoal-from-tc (x scheme tests calls just pv state)
+ (let* ((fmls (formals (car scheme) (w state)))
+ (fcall `(,(car scheme) ,@fmls))
+ (measured (cadr just)))
+ (mv-let (varsub err) (pmatch fcall scheme nil) ; a variable may match twice?
+ (mv-let (r subs pv state)
+ (ih-from-calls x varsub fcall calls measured pv state)
+ (mv `(implies
+ (and
+ ,@(inst-l tests varsub)
+ ,@r)
+ ,x)
+ (list (inst-l tests varsub) subs) pv state)))))
+
+
+(defun subgoals-from-im (x scheme im just pv state)
+ (if (endp im)
+ (mv nil nil pv state)
+ (let ((tests (cadr (car im)))
+ (calls (cddr (car im))))
+ (mv-let (r tc pv state) (subgoal-from-tc x scheme tests calls just pv state)
+ (mv-let (r2 tcl pv state) (subgoals-from-im x scheme (cdr im) just pv state)
+ (mv (cons r r2) (cons tc tcl) pv state))))))
+
+(defun get-induct-goals (x scheme pv state)
+ (let ((im (getprop (car scheme) 'induction-machine nil 'current-acl2-world (w state)))
+ (just (getprop (car scheme) 'justification nil 'current-acl2-world (w state))))
+ (mv-let (r tcs pv state) (subgoals-from-im x scheme im just pv state)
+ (mv t r tcs pv state))))
+
+(logic)
+(defstub goo (x y) t)
+
+(defun foo (x)
+ (if (atom x)
+ nil
+ (cons (foo (car x)) (foo (cdr x)))))
+(program)
+
+ ;(get-induct-goals '(goo x y) '(foo x) state)
+
+ ;(get-induct-goals '(implies (and (true-listp x) (true-listp y)) (equal (rot2 x (append x y)) (append y x))) '(true-listp x) 0 state)
+
+ #|
+
+(wfall '(IMPLIES (AND (CONSP X)
+ (IMPLIES (AND (TRUE-LISTP (CDR X))
+ (TRUE-LISTP (G0 Y X)))
+ (EQUAL (ROT2 (CDR X) (APPEND (CDR X) (G0 Y X)))
+ (APPEND (G0 Y X) (CDR X)))))
+ (IMPLIES (AND (TRUE-LISTP X) (TRUE-LISTP Y))
+ (EQUAL (ROT2 X (APPEND X Y))
+ (APPEND Y X)))) state)
+
+(wfall '(IMPLIES (AND (NOT (CONSP X)))
+ (IMPLIES (AND (TRUE-LISTP X) (TRUE-LISTP Y))
+ (EQUAL (ROT2 X (APPEND X Y))
+ (APPEND Y X)))) state)
+
+(wfall '(and (IMPLIES (AND (CONSP X)
+ (IMPLIES (AND (TRUE-LISTP (CDR X))
+ (TRUE-LISTP (G0 Y X)))
+ (EQUAL (ROT2 (CDR X) (APPEND (CDR X) (G0 Y X)))
+ (APPEND (G0 Y X) (CDR X)))))
+ (IMPLIES (AND (TRUE-LISTP X) (TRUE-LISTP Y))
+ (EQUAL (ROT2 X (APPEND X Y))
+ (APPEND Y X))))
+ (IMPLIES (AND (NOT (CONSP X)))
+ (IMPLIES (AND (TRUE-LISTP X) (TRUE-LISTP Y))
+ (EQUAL (ROT2 X (APPEND X Y))
+ (APPEND Y X))))) state)
+
+
+|#
+
+
+(mutual-recursion
+ (defun find-rec2 (x p state)
+ (if (atom x)
+ (mv nil state)
+ (mv-let (r state) (find-rec2-l (cdr x) p 1 state)
+ (if (recp x state)
+ (mv (cons p r) state)
+ (mv r state)))))
+ (defun find-rec2-l (x p n state)
+ (if (endp x)
+ (mv nil state)
+ (mv-let (r state) (find-rec2 (car x) (append p (list n)) state)
+ (mv-let (r2 state) (find-rec2-l (cdr x) p (1+ n) state)
+ (mv (append r r2) state))))))
+
+(defun expand-def (p x state)
+ (mv-let (d state) (getdef (usepath p x) state)
+ (mv-let (x2 err) (rwrite (usepath p x) d)
+ (mv-let (x3 state) (norm `(or ,@(replace-at p x2 x)) state)
+ (if (equal (len x3) 1)
+ (mv t (car x3) state)
+ (mv nil x state))))))
+
+(defun try-paths (l x state)
+ (if (endp l)
+ (mv x state)
+ (mv-let (changed x state) (expand-def (car l) x state)
+ (if changed
+ (mv-let (r state) (find-rec2 (usepath (car l) x) (car l) state)
+ (try-paths (append r (cdr l)) x state))
+ (try-paths (cdr l) x state)))))
+
+(defun expand-defs (x state)
+ (mv-let (pl state) (find-rec2-l x nil 0 state)
+ (try-paths (reverse pl) x state)))
+
+(defun expand-defs-l (x state)
+ (if (endp x)
+ (mv nil state)
+ (mv-let (r state) (expand-defs (car x) state)
+ (mv-let (r2 state) (expand-defs-l (cdr x) state)
+ (mv (cons r r2) state)))))
+
+
+(defun norm-lc (x state)
+ (if (endp x)
+ (mv nil state)
+ (mv-let (r state) (norm (car x) state)
+ (mv-let (r2 state) (norm-lc (cdr x) state)
+ (mv (append r r2) state)))))
+
+
+
+
+
+
+#|
+
+
+
+(NIL (TRUE-LISTP X)
+ (((NOT (CONSP X))
+ (TRUE-LISTP (G0 Y X))
+ (NOT (TRUE-LISTP (CDR X)))
+ (NOT (TRUE-LISTP Y))
+ (EQUAL (ROT2 (CDR X)
+ (BINARY-APPEND (BINARY-APPEND (CDR X) Y)
+ (CONS (CAR X) 'NIL)))
+ (BINARY-APPEND Y X)))
+ ((NOT (CONSP X))
+ (NOT (EQUAL (ROT2 (CDR X)
+ (BINARY-APPEND (CDR X) (G0 Y X)))
+ (BINARY-APPEND (G0 Y X) (CDR X))))
+ (NOT (TRUE-LISTP (CDR X)))
+ (NOT (TRUE-LISTP Y))
+ (EQUAL (ROT2 (CDR X)
+ (BINARY-APPEND (BINARY-APPEND (CDR X) Y)
+ (CONS (CAR X) 'NIL)))
+ (BINARY-APPEND Y X)))
+ ((CONSP X)
+ X (NOT (TRUE-LISTP Y))
+ (EQUAL Y (BINARY-APPEND Y 'NIL))))
+ <state>)
+
+(hl
+ '(EQUAL (ROT2 (CDR X)
+ (BINARY-APPEND (BINARY-APPEND (CDR X) Y)
+ (CONS (CAR X) 'NIL)))
+ (BINARY-APPEND Y X))
+ '(EQUAL (ROT2 (CDR X)
+ (BINARY-APPEND (CDR X) (G0 Y X)))
+ (BINARY-APPEND (G0 Y X) (CDR X))))
+
+(hl
+ (BINARY-APPEND (BINARY-APPEND (CDR X) Y)
+ (CONS (CAR X) 'NIL))
+ (BINARY-APPEND (CDR X) (G0 Y X)))
+
+(hl
+ '(G1 Y X)
+ '(BINARY-APPEND Y (CONS (CAR X) 'NIL))
+ )
+
+(hl
+ '(BINARY-APPEND (G1 Y X) (CDR X))
+ '(BINARY-APPEND Y X)
+ )
+
+|#
+
+
+(defun conp (x state)
+ (getprop (car x) 'constrainedp nil 'current-acl2-world (w state)))
+
+(mutual-recursion
+ (defun constrainedp (x state)
+ (if (atom x)
+ nil
+ (or (conp x state)
+ (constrainedp-l (cdr x) state))))
+ (defun constrainedp-l (x state)
+ (if (endp x)
+ nil
+ (or (constrainedp (car x) state)
+ (constrainedp-l (cdr x) state)))))
+
+
+(defun pairs (x y)
+ (if (endp x)
+ nil
+ (cons (list (car x) (car y))
+ (pairs (cdr x) (cdr y)))))
+
+(defun try-decomp (x y)
+ (if (and (consp x)
+ (consp y)
+ (equal (car x) (car y)))
+ (mv nil (pairs (cdr x) (cdr y)))
+ (mv t nil)))
+
+
+(mutual-recursion
+ (defun use-subst (x y l)
+ (if (atom l)
+ l
+ (mv-let (r err) (rwrite l `(,x ,y))
+ (if err
+ (use-subst-l x y l)
+ r))))
+ (defun use-subst-l (x y l)
+ (if (endp l)
+ nil
+ (cons (use-subst x y (car l))
+ (use-subst-l x y (cdr l))))))
+
+(defun rwritel (b x)
+ (if (endp b)
+ (mv nil t)
+ (mv-let (r err) (rwrite x (car b))
+ (if err
+ (rwritel (cdr b) x)
+ (mv r nil)))))
+
+(mutual-recursion
+ (defun use-substl (b l)
+ (if (atom l)
+ l
+ (mv-let (r err) (rwritel b l)
+ (if err
+ (use-substl-l b l)
+ r))))
+ (defun use-substl-l (b l)
+ (if (endp l)
+ nil
+ (cons (use-substl b (car l))
+ (use-substl-l b(cdr l))))))
+
+
+(program)
+
+(defun rm-el (e x)
+ (if (endp x)
+ nil
+ (if (equal e (car x))
+ (cdr x)
+ (cons (car x) (rm-el e (cdr x))))))
+
+(defun rm-hyps (hyps x)
+ (if (endp hyps)
+ x
+ (rm-hyps (cdr hyps) (rm-el (car hyps) x))))
+
+
+(mutual-recursion
+ (defun find-csub2 (x y e)
+ (if (atom y)
+ (mv t y)
+ (if (equal x y)
+ (mv nil e)
+ (mv-let (err cdry) (find-csub2-l x (cdr y) e)
+ (mv err (cons (car y) cdry))))))
+(defun find-csub2-l (x y e)
+ (if (endp y)
+ (mv t nil)
+ (mv-let (err cary) (find-csub2 x (car y) e)
+ (if err
+ (mv-let (err cdry) (find-csub2-l x (cdr y) e)
+ (mv err (cons (car y) cdry)))
+ (mv err (cons cary (cdr y))))))))
+
+(mutual-recursion
+ (defun find-csub (x y e)
+ (if (atom x)
+ (mv t x y)
+ (mv-let (err y) (find-csub2 x y e)
+ (if err
+ (mv-let (err cdrx y) (find-csub-l (cdr x) y e)
+ (mv err (cons (car x) cdrx) y))
+ (mv err e y)))))
+ (defun find-csub-l (x y e)
+ (if (endp x)
+ (mv t nil y)
+ (mv-let (err carx y) (find-csub (car x) y e)
+ (if err
+ (mv-let (err cdrx y) (find-csub-l (cdr x) y e)
+ (mv err (cons (car x) cdrx) y))
+ (mv err (cons carx (cdr x)) y))))))
+
+
+(defun gen-common (x)
+ (let ((a (cadr x))
+ (b (caddr x)))
+ (mv-let (err a b) (find-csub a b 'x0)
+ `(equal ,a ,b))))
+
+(defun orient-eq (x state)
+ (let ((a (cadr x))
+ (b (caddr x)))
+ (if (and
+ (consp a)
+ (conp a state))
+ x
+ `(equal ,b ,a))))
+
+(mutual-recursion
+(defun replace-consts (x max-var)
+ (if (atom x)
+ (mv x max-var)
+ (if (quotep x)
+ (let ((max-var (1+ max-var)))
+ (mv (new-var max-var) max-var))
+ (mv-let (r max-var) (replace-consts-l (cdr x) max-var)
+ (mv (cons (car x) r) max-var)))))
+(defun replace-consts-l (x max-var)
+ (if (endp x)
+ (mv nil max-var)
+ (mv-let (r1 max-var) (replace-consts (car x) max-var)
+ (mv-let (r2 max-var) (replace-consts-l (cdr x) max-var)
+ (mv (cons r1 r2) max-var))))))
+
+; replace any constants on the left side with new variables
+(defun gen-unused (x max-var)
+ (let* ((a (cadr x))
+ (b (caddr x))
+ )
+ (mv-let (r max-var) (replace-consts a max-var)
+ (mv `(equal ,r ,b) max-var))))
+
+
+(defun csubstp (d1 state)
+ (and (consp d1)
+ (equal (car d1) 'equal)
+ (consp (cdr d1))
+ (consp (cddr d1))
+ (let* ( (x (cadr d1))
+ (y (caddr d1)))
+ (or (and
+ (consp x)
+ (conp x state))
+ (and
+ (consp y)
+ (conp y state))))))
+
+
+ ;(access pv (change pv (make pv) :max-fun 1) :max-fun)
+
+
+(mutual-recursion
+ (defun find-rec-nocon (x state)
+ (if (atom x)
+ (mv nil t state)
+ (if (conp x state)
+ (mv nil t state)
+ (mv-let (p err state) (find-rec-nocon-l (cdr x) 1 state)
+ (if err
+ (if (recp x state)
+ (mv nil nil state)
+ (mv nil t state))
+ (mv p nil state))))))
+ (defun find-rec-nocon-l (x n state)
+ (if (endp x)
+ (mv nil t state)
+ (mv-let (p err state) (find-rec-nocon (car x) state)
+ (if err
+ (find-rec-nocon-l (cdr x) (1+ n) state)
+ (mv (cons n p) nil state))))))
+
+
+(defun add-disj2 (d x)
+ (if (endp x)
+ nil
+ (cons
+ `(case (and ,@(cons d (cdr (cadr (car x))))) ,(caddr (car x)))
+ (add-disj2 d (cdr x)))))
+
+ ; we assume x is the body of a recursive function which
+ ; is composed of an if tree with terms at the leaves
+ ; rl is the list of recursive functions for this
+ ; body
+(defun get-cases12 (x rl)
+ (if (atom x)
+ (mv `((case (and) ,x)) 1)
+ (if (equal (car x) 'if)
+ (mv-let (c b) (get-cases12 (caddr x) rl)
+ (mv-let (c2 b2) (get-cases12 (cadddr x) rl)
+ (if (< b b2)
+ (mv (append (add-disj2 (cadr x) c2)
+ (add-disj2 `(not ,(cadr x)) c))
+ (+ b b2))
+ (mv (append (add-disj2 `(not ,(cadr x)) c)
+ (add-disj2 (cadr x) c2))
+ (+ b b2)))))
+ (mv `((case (and) ,x)) (if (contains-call rl x) 0 1)))))
+
+(defun get-cases2 (x rl)
+ (mv-let (c b) (get-cases12 x rl) (declare (ignore b))
+ c))
+
+(defun new-clauses2 (p l x)
+ (if (endp l)
+ nil
+ (cons
+ (append (cdr (cadr (car l))) (replace-at p (caddr (car l)) x))
+ (new-clauses2 p (cdr l) x))))
+
+(defun str-cat (m s)
+ (intern (concatenate 'string (symbol-name m) s) "ACL2"))
+
+
+(defmacro simp-term-trans (name args base cond trans)
+ `(mutual-recursion
+ (defun ,name ,args
+ (if (atom ,(car args))
+ ,base
+ (if ,cond
+ ,trans
+ (cons (car ,(car args)) (,(str-cat name "-L") (cdr ,(car args)) ,@(cdr args))))))
+ (defun ,(str-cat name "-L") ,args
+ (if (endp ,(car args))
+ nil
+ (cons (,name (car ,(car args)) ,@(cdr args))
+ (,(str-cat name "-L") (cdr ,(car args)) ,@(cdr args)))))))
+
+(simp-term-trans hide-constr (x state) x (conp x state) `(hide ,x))
+
+(simp-term-trans rm-hide (x) x (equal (car x) 'hide) (cadr x))
+
+
+#|
+
+(hide-constr
+'(OR (NOT (CONSP (BINARY-APPEND (CONS X1 'NIL) X2)))
+ (NOT (TRUE-LISTP X2))
+ (NOT (TRUE-LISTP Y))
+ (CONSP X2)
+ (EQUAL (G0 Y (BINARY-APPEND (CONS X1 'NIL) X2))
+ (BINARY-APPEND (BINARY-APPEND X2 Y)
+ (CONS X1 'NIL))))
+state)
+
+
+|#
+
+
+(defun find-csubst (x state)
+ (if (endp x)
+ (mv t nil)
+ (if (csubstp (car x) state)
+ (mv nil (orient-eq (car x) state))
+ (find-csubst (cdr x) state))))
+
+; take the clause x and simplify it by locating a
+; recursive function and assuming a base case for that
+; function
+(defun gen-constr (x hyps pv state)
+ (mv-let (p err state) (find-rec-nocon-l x 0 state)
+ (if err
+ (mv t nil pv state)
+ (mv-let (def state) (getdef (usepath p x) state)
+ (mv-let (bind err) (pmatch (car def) (usepath p x) nil)
+ (let* (
+ (rn (recp (usepath p x) state))
+ (cases (get-cases2 (cadr def) rn))
+ (icases (inst-l cases bind)))
+ ; hide g0? f
+ (mv-let (err r state) (bash-term-to-dnf `(or ,@hyps ,@(hide-constr-l (car (new-clauses2 p icases x)) state)) nil nil state) (declare (ignore err)) ;elim dtors ?
+ (if (equal (len r) 1)
+ (mv-let (err subst) (find-csubst (rm-hide-l (car r)) state)
+ (if err
+ (mv t nil pv state)
+ ;(mv-let (r max-var) (gen-unused (orient-eq subst state) (access pv pv :max-var))
+ (mv nil (orient-eq subst state) pv state)))
+ (mv t nil pv state)))))))))
+
+
+
+;(untrace$ bash-term-to-dnf find-csubst gen-unused getdef get-cases1 hide-constr new-clauses2 find-rec-nocon add-disj2 get-cases2)
+
+;(use-subst '(g x y) '(binary-append (cdr y) (cons (car x) nil)) '((g (cdr x) y)))
+
+; d is a list of differences that we are trying to resolve
+; we are at a base case when one side of an equality is a
+; basic constrained function
+
+(defun remove-nth (n x)
+ (if (zp n)
+ (cdr x)
+ (cons (car x)
+ (remove-nth (1- n) (cdr x)))))
+
+
+
+
+
+
+(defun clausify-diffs (x)
+ (if (endp x)
+ nil
+ (cons `((equal ,(car (car x)) ,(cadr (car x))))
+ (clausify-diffs (cdr x)))))
+
+
+(defun gnext (s)
+ (cons (list (remove-nth (cadr (car s)) (car (car s))) 0) s))
+
+(defun bnext (s)
+ (if (endp s)
+ nil
+ (if (< (1+ (cadr (car s))) (len (car (car s))))
+ (cons (list (car (car s)) (1+ (cadr (car s)))) (cdr s))
+ (bnext (cdr s)))))
+
+;(gnext '(((1 2) 0) ((0 1 2) 0)))
+
+;(bnext '(((2) 0) ((1 2) 0) ((0 1 2) 0)))
+
+(defun trav (s)
+ (if (endp s)
+ nil
+ (if (< 2 (len s))
+ (trav (bnext s))
+ (trav (gnext s)))))
+
+;(trav '(((0 1 2) 0)))
+
+
+
+(defun cons-calls (l fcall)
+ (if (endp l)
+ nil
+ `(cons ,(inst fcall (car l))
+ ,(cons-calls (cdr l) fcall))))
+
+
+
+#|
+(mutual-recursion
+ (defun all-vars (x)
+ (if (atom x)
+ (if (constant x)
+ nil
+ (list x))
+ (if (eq (car x) 'quote)
+ nil
+ (all-vars-l (cdr x)))))
+ (defun all-vars-l (x)
+ (if (endp x)
+ nil
+ (append (all-vars (car x))
+ (all-vars-l (cdr x))))))
+|#
+
+(defun all-terms-c2 (l)
+ (if (endp l)
+ nil
+ (list* (car (car l))
+ (cadr (car l))
+ (all-terms-c2 (cdr l)))))
+
+(defun all-terms-c (l)
+ (if (endp l)
+ nil
+ (append (all-terms-c2 (car l))
+ (all-terms-c (cdr l)))))
+
+(defun all-terms-tcs (l)
+ (if (endp l)
+ nil
+ (append (car (car l))
+ (all-terms-c (cadr (car l)))
+ (all-terms-tcs (cdr l)))))
+
+(defun tcs-to-ifun2 (l fcall)
+ (if (endp l)
+ nil
+ (let ((tests (car (car l)))
+ (calls (cadr (car l))))
+ (cons `((and ,@tests) ,(cons-calls calls fcall))
+ (tcs-to-ifun2 (cdr l) fcall)))))
+
+(mutual-recursion
+ (defun expand-conses (x al)
+ (if (atom x)
+ (if (or (member-equal `(not (endp ,x)) al)
+ (member-equal `(consp ,x) al))
+ `(binary-append (cons (car ,x) 'nil) (cdr ,x))
+ x)
+ (if (quotep x)
+ x
+ (if (equal (car x) 'if)
+ `(if ,(cadr x)
+ ,(expand-conses (caddr x) (cons (cadr x) al))
+ ,(expand-conses (cadddr x) (cons (dumb-negate-lit (cadr x)) al)))
+ (cons (car x) (expand-conses-l (cdr x) al))))))
+ (defun expand-conses-l (x al)
+ (if (endp x)
+ nil
+ (cons (expand-conses (car x) al)
+ (expand-conses-l (cdr x) al)))))
+
+(defun cdrs-to-cadrs (x)
+ (if (endp x)
+ nil
+ (cons (list (car (car x)) (cdr (car x)))
+ (cdrs-to-cadrs (cdr x)))))
+
+(defun blrewrite (l x)
+ (if (endp l)
+ (mv t x)
+ (let ((lhs (car (car l)))
+ (rhs (cadr (car l))))
+ (mv-let (good bind) (one-way-unify lhs x)
+ (if (not good)
+ (blrewrite (cdr l) x)
+ (mv nil (inst rhs (cdrs-to-cadrs bind))))))))
+
+(mutual-recursion
+ (defun lrewrite (x l)
+ (if (atom x)
+ (mv t x)
+ (if (quotep x)
+ (mv t x)
+ (mv-let (err r) (lrewrite-l (cdr x) l)
+ (mv-let (err r) (blrewrite l (cons (car x) r))
+ (if err
+ (mv t r)
+ (lrewrite r l)))))))
+ (defun lrewrite-l (x l)
+ (if (endp x)
+ (mv t nil)
+ (mv-let (err r1) (lrewrite (car x) l)
+ (mv-let (err r2) (lrewrite-l (cdr x) l)
+ (mv t (cons r1 r2)))))))
+
+(defun simp (x r)
+ (mv-let (err r) (lrewrite x r) r))
+
+(defun cond-simp (tbody bind)
+ (let ((body2 (expand-conses tbody nil)))
+ (simp (simp body2 bind) `(((cons (car x) (cdr x)) x)) )))
+
+
+(defun tcs-to-ifun (tcs fn bind state)
+ (let* ((fmls (all-vars (cons 'dummy (all-terms-tcs tcs))))
+ (body (tcs-to-ifun2 tcs (cons fn fmls)))
+ (body `(cond ,@body)))
+ (mv-let (err val state) (ld (list `(defun ,fn (,@fmls) nil)))
+ (mv-let (nop tbody state) (TRANSLATE body nil NIL nil nil (W state) STATE)
+ (let ((sbody (cond-simp tbody bind)))
+ (mv-let (err val state) (ld (list (list 'ubt! (list 'quote fn))))
+ (mv
+ `(defun ,fn (,@fmls)
+ ,sbody)
+ `(,fn ,@fmls)
+ state)))))))
+
+
+
+; rl must contain err and pv2 and must not contain pv
+(defmacro try-ubt (rl call err nerr)
+ `(let ((nl (new-label (access pv pv :max-label)))
+ (pv (change pv pv :max-label (1+ (access pv pv :max-label)))))
+ (mv-let (err val state) (ld (list (list 'deflabel nl)))
+ (mv-let ,rl ,call
+ (if err
+ (let ((pv (change pv pv :max-label (1- (access pv pv :max-label)))))
+ (mv-let (er val state) (ld (list (list 'ubt! (list 'quote nl))))
+ ,err))
+ (let ((pv pv2))
+ ,nerr))))))
+
+
+(defun prune-clause (p x state)
+ (declare (xargs :mode :program))
+ (if (endp x)
+ (mv p state)
+ (mv-let (err nop state) (refute5 (append p (cdr x)) 6 state)
+ (if err
+ (prune-clause (append p (list (car x))) (cdr x) state)
+ (prune-clause p (cdr x) state)))))
+
+(defun insert-sorted (a lst)
+ (if (or (endp lst)
+ (>= (acl2-count a) (acl2-count (car lst))))
+ (cons a lst)
+ (cons (car lst) (insert-sorted a (cdr lst)))))
+
+(defun insertion-sort (lst)
+ (if (endp lst)
+ lst
+ (insert-sorted (car lst) (insertion-sort (cdr lst)))))
+
+
+
+
+(defun find-equal (x)
+ (if (endp x)
+ 0
+ (if (and (consp (car x))
+ (equal (car (car x)) 'equal))
+ 0
+ (1+ (find-equal (cdr x))))))
+
+
+(defun tcmp (x y)
+ (if (atom x)
+ (if (consp y)
+ 1
+ 0)
+ (if (atom y)
+ -1
+ (let ((r (tcmp (car x) (car y))))
+ (if (equal r 0)
+ (tcmp (cdr x) (cdr y))
+ r)))))
+
+(defun align-equal (x)
+ (if (or
+ (not (consp x))
+ (not (equal (car x) 'equal)))
+ x
+ (if (< (acl2-count (cadr x)) (acl2-count (caddr x)))
+ `(equal ,(caddr x) ,(cadr x))
+ (if (= (acl2-count (cadr x)) (acl2-count (caddr x)))
+ (if (equal (tcmp (cadr x) (caddr x)) 1)
+ `(equal ,(caddr x) ,(cadr x))
+ x)
+ x))))
+
+(defun make-rewrite (x)
+ (let ((disj (cdr x)))
+ (if (equal (len disj) 1)
+ (align-equal (car disj))
+ (let ((eqd (find-equal disj)))
+ (let ((eqd (if (equal eqd (len disj)) 0 eqd)))
+ `(implies
+ (and
+ ,@(dumb-negate-lit-lst (remove-nth eqd disj)))
+ ,(align-equal (nth eqd disj))))))))
+
+(defmacro inc-depth (bind call rest)
+ `(if (< 2 (access pv pv :depth))
+ (mv t nil pv state)
+ (mv-let ,bind
+ (let ((pv (change pv pv :depth (1+ (access pv pv :depth)))))
+ ,call)
+ (let ((pv (change pv pv :depth (1- (access pv pv :depth)))))
+ ,rest))))
+
+(mutual-recursion
+ (defun match2-0 (d hyps pv state)
+ (declare (xargs :mode :program))
+ (if (endp d)
+ (mv nil nil pv state)
+ (let* ((d1 (car d))
+ (x (car d1))
+ (y (cadr d1)))
+ (if (and (atom x)
+ (atom y))
+ (if (not (equal x y))
+ (mv t nil pv state)
+ (match2-0 (cdr d) hyps pv state))
+ (if (not (constrainedp `(equal ,x ,y) state))
+ (mv-let (err r pv state) (prove2 `(equal ,x ,y) pv state)
+ (if err
+ (mv t nil pv state)
+ (match2-0 (cdr d) hyps pv state)))
+ (if (and
+ (consp x)
+ (conp x state))
+ (mv-let (err r pv2 state) (match2-0 (use-subst-l x y (cdr d)) hyps (change pv pv :bind (append (access pv pv :bind) (list (list x y)))) state)
+ (if err
+ (mv t nil pv state)
+ (mv nil nil pv2 state)))
+ (if (and
+ (consp y)
+ (conp y state))
+ (mv-let (err r pv2 state) (match2-0 (use-subst-l y x (cdr d)) hyps (change pv pv :bind (append (access pv pv :bind) (list (list y x)))) state)
+ (if err
+ (mv t nil pv state)
+ (mv nil nil pv2 state)))
+
+ (mv-let (err r) (try-decomp x y) ; if x and y have the same top function symbol, then decompose them
+ (if (not err)
+ (mv-let (err r pv state) (match2-0 (append r (cdr d)) hyps pv state)
+ (if err
+ (mv-let (err r pv state) (gen-constr `((equal ,@(car d))) hyps pv state)
+ (if err
+ (mv t nil pv state)
+ (mv-let (err r pv state)
+ (match2-0 (cons (list (cadr r) (caddr r)) (cdr d)) hyps pv state)
+ (if err
+ (mv t r pv state)
+ (match2-0 (list (use-substl-l (access pv pv :bind) (car d))) hyps pv state)))))
+ (mv nil r pv state)))
+ (mv-let (err r pv state) (gen-constr `((equal ,@(car d))) hyps pv state)
+ (if err
+ (mv t nil pv state)
+ (mv-let (err r pv state)
+ (match2-0 (cons (list (cadr r) (caddr r)) (cdr d)) hyps pv state)
+ (if err
+ (mv t r pv state)
+ (match2-0 (list (use-substl-l (access pv pv :bind) (car d))) hyps pv state))))))))))))))
+
+; take an equality and attempt to match it against another disjunct.
+; if a match is found, use any bindings present to substitute rhs for lhs
+; and return the new y.
+; we check that the top symbol of rhs and lhs are the same before attempting a match.
+ (defun match2-0-fert (x y hyps pv state)
+ (if (atom y)
+ (mv t nil pv state)
+ (mv-let (err r pv state) (match2-0-fert-l x (cdr y) hyps pv state)
+ (if err
+ (if (and (consp (cadr x)) ; if the top symbols are equal, attempt a match
+ (equal (car (cadr x))
+ (car y)))
+ (mv-let (err r pv state) (match2-0 (list (list (cadr x) y)) hyps pv state)
+ (if err
+ (mv t nil pv state)
+ ;replace lhs with rhs in y and attempt to prove new clause
+ (mv nil (caddr x) pv state)))
+ (mv t nil pv state))
+ (mv nil (cons (car y) r) pv state)))))
+
+ (defun match2-0-fert-l (x y hyps pv state)
+ (if (endp y)
+ (mv t nil pv state)
+ (mv-let (err r pv state) (match2-0-fert x (car y) hyps pv state)
+ (if err
+ (mv-let (err r pv state) (match2-0-fert-l x (cdr y) hyps pv state)
+ (if err
+ (mv t nil pv state)
+ (mv nil (cons (car y) r) pv state)))
+ (mv nil (cons r (cdr y)) pv state)))))
+
+
+
+ (defun match2 (x y hyps pv state)
+ (declare (xargs :mode :program))
+ (if (or (atom x) (atom y))
+ (mv t nil pv state)
+ (if (equal (car x) 'not)
+ (if (and (consp (cdr x))
+ (equal (car (cadr x)) 'equal))
+ (mv-let (err r pv state) (match2-0-fert (cadr x) y hyps pv state) ;we should probably match the eq oriented the other way too
+ (if err
+ (mv t nil pv state)
+ (prove2 (use-substl-l (access pv pv :bind) `(or ,@hyps ,x ,r)) pv state)))
+ (match2-0 (list (list (cadr x) y)) hyps pv state))
+ (if (equal (car y) 'not)
+ (match2-0 (list (list x (cadr y))) hyps pv state)
+ (mv t nil pv state)))))
+
+; i and j are the indices of two disjuncts in clause x
+; that we are trying to match against each other
+ (defun match-l (i j x pv state)
+ (declare (xargs :mode :program))
+ (if (<= (len x) j)
+ (mv t nil pv state)
+ (if (or (constrainedp (nth i x) state)
+ (constrainedp (nth j x) state))
+ (try-ubt
+ (err r pv2 state)
+ (match2 (nth i x) (nth j x) (remove-nth i (remove-nth j x)) pv state)
+ (match-l i (1+ j) x pv state)
+ (mv nil r pv2 state))
+ (match-l i (1+ j) x pv state))))
+
+; try to prove a clause that has constraints in it by finding
+; definitions that allow two disjuncts to match modulo negation.
+; cross fertilization is performed if possible.
+ (defun try-match (i x pv state)
+ (declare (xargs :mode :program))
+ (if (<= (len x) i)
+ (mv t nil pv state)
+ (try-ubt
+ (err r pv2 state)
+ (match-l i (1+ i) x pv state)
+ (try-match (1+ i) x pv state)
+ (mv nil r pv2 state))))
+
+(defun induct1 (schemes x pv state)
+ (declare (xargs :mode :program))
+ (if (endp schemes)
+ (mv t nil pv state)
+ (try-ubt (err pv2 r tcs state)
+ (mv-let (err r tcs pv state) (get-induct-goals x (car schemes) pv state)
+ (mv-let (err r pv state) (prove2 `(and ,@r) pv state)
+ (mv err pv r tcs state)))
+ (induct1 (cdr schemes) x pv state)
+ (let* ((nthm (new-thm (access pv pv :max-thm)))
+ (pv (change pv pv :max-thm (1+ (access pv pv :max-thm))))
+ (ifn (new-ifn (access pv pv :max-ifn)))
+ (pv (change pv pv :max-ifn (1+ (access pv pv :max-ifn)))))
+ (mv-let (ifun ifun-call state) (tcs-to-ifun tcs ifn (access pv pv :bind) state)
+ (let ((xrr (make-rewrite x)))
+ (let ((ithm `(defthm
+ ,nthm
+ ,xrr
+ :hints
+ (("Goal" :induct ,ifun-call :do-not-induct t :do-not '(generalize)))
+ )))
+ (mv-let (err val state) (ld (list ifun))
+ (if err
+ (mv (err-fun) r pv state)
+ (mv-let (err val state) (ld (list ithm))
+ (if err
+ (mv (err-fun) r pv state)
+ (mv nil
+ r
+ (change pv pv :log (append (access pv pv :log)
+ `(,ifun
+ ,ithm)))
+ state))))))))))))
+
+ (defun ind (x pv state)
+ (declare (xargs :mode :program))
+ (induct1 (get-schemes x state) x pv state))
+
+; x is a clause to prove
+(defun prove2-0 (x pv state)
+ (declare (xargs :mode :program))
+ (if (constrainedp-l x state)
+ (try-match 0 x pv state)
+ (mv-let
+ (err r state)
+ (bash-term-to-dnf `(or ,@x) nil nil state) (declare (ignore err)) ;removes tautolgies introduced by constrained defs
+ (if (null r)
+ (mv nil t pv state)
+ (mv-let
+ (err nop state)
+ (refute5 x 6 state)
+ (if err
+ (mv err nil pv state)
+;(inc-depth (err r pv state)
+; (ind `(or ,@x) pv state)
+; (if err
+ (mv-let
+ (x state)
+ (prune-clause nil (insertion-sort x) state) ;how reliable is prune? used to throw away ih after xfert
+
+ (mv-let
+ (hit lcl tt pspv)
+ (generalize-clause2
+ x
+ nil
+ (change prove-spec-var
+ (initial-pspv *t* ; term (don't-care)
+ *t* ; displayed-goal (don't-care)
+ nil ; otf-flg (don't-care)
+ (ens state)
+ (w state)
+ state
+ nil)
+ :pool '((being-proved-by-induction . nil)))
+ (w state)
+ state)
+ (if (equal hit 'hit)
+ (inc-depth (err r pv state)
+ (ind `(or ,@(car lcl))
+ pv
+ state)
+ (if err
+ (mv err r pv state)
+ (mv nil r pv state)))
+ (inc-depth (err r pv state)
+ (ind `(or ,@x) pv state)
+ (if err
+ (mv err r pv state)
+ (mv nil r pv state))))
+
+ ))))))))
+
+; (mv err r pv state))))))
+
+; eventually we should change this to try each clause independently and
+; generate a list of all possible binding for the constrained functions,
+; then try each possibility instead of doing this exponential backtracking
+(defun prove2-l (x n pv state)
+ (declare (xargs :mode :program))
+ (if (<= (len x) n)
+ (if (< 0 (len x))
+ (mv t nil pv state)
+ (mv nil nil pv state))
+ (try-ubt (err r pv2 state)
+ (mv-let (err r pv state) (prove2-0 (nth n x) pv state)
+ (if err
+ (mv t nil pv state)
+ (prove2-l (use-substl-l (access pv pv :bind) (remove-nth n x)) 0 pv state)))
+ (prove2-l x (1+ n) pv state)
+ (mv nil nil pv state))))
+
+ (defun prove2 (x pv state)
+ (declare (xargs :mode :program))
+ (mv-let (err r state)
+ (bash-term-to-dnf x nil nil state) (declare (ignore err))
+ (prove2-l (insertion-sort r) 0 pv state))))
+
+
+(defmacro bprove (x)
+ `(encapsulate nil
+ (set-ignore-ok t)
+ (set-irrelevant-formals-ok t)
+ (make-event
+ (mv-let (err max-fun state) (table bprove 'max-fun)
+ (mv-let (err max-var state) (table bprove 'max-var)
+ (mv-let (err max-ifn state) (table bprove 'max-ifn)
+ (mv-let (err max-thm state) (table bprove 'max-thm)
+ (mv-let (err max-label state) (table bprove 'max-label)
+ (mv-let (err r pv state)
+ (prove2 ',x (make pv :bind nil :schemes nil :log nil :max-fun (or max-fun 0) :max-var (or max-var 0) :max-ifn (or max-ifn 0) :max-thm (or max-thm 0) :max-label (or max-label 0) :depth 0) state)
+ (mv nil (cons 'progn (append
+ (list
+ `(table bprove 'max-fun ,(access pv pv :max-fun))
+ `(table bprove 'max-var ,(access pv pv :max-var))
+ `(table bprove 'max-ifn ,(access pv pv :max-ifn))
+ `(table bprove 'max-thm ,(access pv pv :max-thm))
+ `(table bprove 'max-label ,(access pv pv :max-label)))
+ (access pv pv :log))) state))))))))))
+
+
+
+;(prove2 '(equal (rv1 x 'nil) (rv x)) (make pv :bind nil :schemes nil :log nil :max-fun 0 :max-var 0 :max-ifn 0 :max-thm 0 :max-label 0 :depth 0) state)
+
+;(GENERALize-clause '((equal (f (rv x)) (g (rv x)))) nil (change prove-spec-var nil :pool '((being-proved-by-induction . nil))) (w state) state)
+
+;(GENERALize-clause '((equal (f (rv (cons x1 'nil))) (g (rv (cons x1 'nil))))) nil (change prove-spec-var nil :pool '((being-proved-by-induction . nil))) (w state) state)
+
+;(GENERALize-clause2 '((equal (f (cons x1 'nil)) (g (cons x1 'nil)))) nil (change prove-spec-var nil :pool '((being-proved-by-induction . nil))) (w state) state)
+
+;(GENERALize-clause2 '((EQUAL (ROT2 X2 (BINARY-APPEND X2 (CONS X1 'NIL))) (BINARY-APPEND (CONS X1 'NIL) X2))) nil (change prove-spec-var nil :pool '((being-proved-by-induction . nil))) (w state) state)
+
+;(fertilize-clause 0 '((not (equal (f (rv x)) (g (rv x)))) (p (f (rv x)))) nil (change prove-spec-var nil :pool '((being-proved-by-induction . nil))) (w state) state)
+
+
+;(trace$ match2 match2-0 try-match match-l)
+;(trace$ bash-term-to-dnf)
+
+;(trace$ prove2-l prove2-0 ind induct1 get-induct-goals)
+
+;(trace$ gen-constr try-decomp rm-hyps get-induct-goals)
+
+;(set-ld-redefinition-action '(:query . :overwrite) state)
+
+;(set-ld-redefinition-action nil state)
+
+;(proclaim '(optimize (speed 2) (safety 1) (space 1) (debug 3)))
+
+(comp t)
+
+(logic)
+
+
+
+
+;(prove2 '(implies (and (true-listp x) (true-listp y)) (equal (rot2 x (append x y)) (append y x))) (make pv :bind nil :schemes nil :log nil :max-fun 0 :max-var 0 :max-ifn 0 :max-thm 0 :max-label 0 :depth 0) state)
+
+;(prove2 '(implies (and (true-listp x)) (equal (rot2 x x) x)) (make pv :bind nil :schemes nil :log nil :max-fun 0 :max-var 0 :max-ifn 0 :max-thm 0 :max-label 0 :depth 0) state)
+
+
+;(prove2 '(equal (ilen x '0) (len x)) (make pv :bind nil :schemes nil :log nil :max-fun 0 :max-var 0 :max-ifn 0 :max-thm 0 :max-label 0 :depth 0) state)
+
+;fails?
+;(prove2 '(equal (rv1 x 'nil) (rv x)) (make pv :bind nil :schemes nil :log nil :max-fun 0 :max-var 0 :max-ifn 0 :max-thm 0 :max-label 0 :depth 0) state)
+
+
+
diff --git a/books/workshops/2007/erickson/bprove/refute.lisp b/books/workshops/2007/erickson/bprove/refute.lisp
new file mode 100644
index 0000000..a2b69a8
--- /dev/null
+++ b/books/workshops/2007/erickson/bprove/refute.lisp
@@ -0,0 +1,302 @@
+(in-package "ACL2")
+
+(include-book "bash")
+
+#|
+
+PATH=/projects/hvg/SULFA/linux-bin:$PATH
+
+/projects/hvg/SULFA/acl2/saved_acl2
+
+|#
+
+;(include-book "/projects/hvg/SULFA/books/sat/sat")
+;(include-book "/projects/hvg/SULFA/books/sat/sat-setup")
+;(include-book "/projects/hvg/SULFA/books/clause-processors/sat-clause-processor")
+
+
+(defun rv (x)
+ (if (endp x)
+ nil
+ (append (rv (cdr x)) (list (car x)))))
+
+
+(set-state-ok t)
+
+(defun usepath (p x)
+ (if (endp p)
+ x
+ (usepath (cdr p) (nth (car p) x))))
+
+(defun recp (x state)
+ (getprop (car x) 'recursivep nil 'current-acl2-world (w state)))
+
+
+; find the left innermost recursive term in x
+; returns (path err state)
+(mutual-recursion
+ (defun find-rec (x state)
+ (if (atom x)
+ (mv nil t state)
+ (mv-let (p err state) (find-rec-l (cdr x) 1 state)
+ (if err
+ (if (recp x state)
+ (mv nil nil state)
+ (mv nil t state))
+ (mv p nil state)))))
+ (defun find-rec-l (x n state)
+ (if (endp x)
+ (mv nil t state)
+ (mv-let (p err state) (find-rec (car x) state)
+ (if err
+ (find-rec-l (cdr x) (1+ n) state)
+ (mv (cons n p) nil state))))))
+
+(defun find-def (x)
+ (if (endp x)
+ nil
+ (if (equal (car (cadr (car x)))
+ ':definition)
+ (car x)
+ (find-def (cdr x)))))
+
+(defun getdef (x state)
+ (let* ((lems
+ (getprop (car x) 'lemmas nil 'current-acl2-world (w state)))
+ (def
+ (find-def lems))
+ (body (nth 6 def))
+ (fmls (nth 5 def)))
+ (mv `(,fmls ,body)
+ state)))
+
+
+(defun bind (pat tgt b)
+ (let ((a (assoc pat b)))
+ (if a
+ (if (equal (cadr a) tgt)
+ (mv b nil)
+ (mv nil t))
+ (mv (cons (list pat tgt) b) nil))))
+
+(defun rep-l (x l)
+ (if (endp l)
+ x
+ (if (equal x (caar l))
+ (cadar l)
+ (rep-l x (cdr l)))))
+
+(mutual-recursion
+ (defun inst (tm bind)
+ (if (atom tm)
+ (rep-l tm bind)
+ (if (quotep tm)
+ tm
+ (cons (car tm)
+ (inst-l (cdr tm) bind)))))
+ (defun inst-l (tm bind)
+ (if (endp tm)
+ nil
+ (cons (inst (car tm) bind)
+ (inst-l (cdr tm) bind)))))
+
+(defun inst-ll (l bind)
+ (if (endp l)
+ nil
+ (cons (inst-l (car l) bind)
+ (inst-ll (cdr l) bind))))
+
+(defun constant (x)
+ (or
+ (integerp x)
+ (stringp x)
+ (characterp x)))
+
+(mutual-recursion
+ (defun pmatch (pat tgt b)
+ (if (atom pat)
+ (if (constant pat)
+ (mv b (not (equal pat tgt)))
+ (mv-let (b err) (bind pat tgt b)
+ (if err
+ (mv nil t)
+ (mv b nil))))
+ (if (or (not (consp tgt))
+ (not (eq (car pat) (car tgt))))
+ (mv nil t)
+ (if (equal (car pat) 'quote)
+ (mv b (not (equal (cadr pat) (cadr tgt))))
+ (pmatch-l (cdr pat) (cdr tgt) b)))))
+ (defun pmatch-l (pat tgt b)
+ (if (endp pat)
+ (if (eq pat tgt) (mv b nil) (mv nil t))
+ (if (endp tgt)
+ (mv nil t)
+ (mv-let (b1 err) (pmatch (car pat) (car tgt) b)
+ (if err
+ (mv nil t)
+ (pmatch-l (cdr pat) (cdr tgt) b1)))))))
+
+(defun rwrite (tm rl)
+ (let ((lhs (car rl))
+ (rhs (cadr rl)))
+ (mv-let (bind err) (pmatch lhs tm nil)
+ (if err
+ (mv nil t)
+ (mv (inst rhs bind) nil)))))
+
+(defun add-disj (d x)
+ (if (endp x)
+ nil
+ (cons
+ (list (cons d (caar x)) (cadar x))
+ (add-disj d (cdr x)))))
+
+(mutual-recursion
+ (defun contains-call (rl x)
+ (if (atom x)
+ nil
+ (if (member-eq (car x) rl)
+ t
+ (contains-call-l rl (cdr x)))))
+(defun contains-call-l (rl x)
+ (if (endp x)
+ nil
+ (or (contains-call rl (car x))
+ (contains-call-l rl (cdr x))))))
+
+; we assume x is the body of a recursive function which
+; is composed of an if tree with terms at the leaves
+; rl is the list of recursive functions for this
+; body
+(defun get-cases1 (x rl)
+ (if (atom x)
+ (mv (list (list nil x)) 1)
+ (if (equal (car x) 'if)
+ (mv-let (c b) (get-cases1 (caddr x) rl)
+ (mv-let (c2 b2) (get-cases1 (cadddr x) rl)
+ (if (< b b2)
+ (mv (append (add-disj (cadr x) c2)
+ (add-disj `(not ,(cadr x)) c))
+ (+ b b2))
+ (mv (append (add-disj `(not ,(cadr x)) c)
+ (add-disj (cadr x) c2))
+ (+ b b2)))))
+ (mv (list (list nil x)) (if (contains-call rl x) 0 1)))))
+
+(defun get-cases (x rl)
+ (mv-let (c b) (get-cases1 x rl) (declare (ignore b))
+ c))
+
+(mutual-recursion
+ (defun decidable (x state)
+ (if (atom x)
+ t
+ (and
+ (not (recp x state))
+ (decidable-l (cdr x) state))))
+ (defun decidable-l (x state)
+ (if (endp x)
+ t
+ (and
+ (decidable (car x) state)
+ (decidable-l (cdr x) state)))))
+
+
+(defun replace-at (p nt x)
+ (if (endp p)
+ nt
+ (if (atom x)
+ x
+ (update-nth (car p) (replace-at (cdr p) nt (nth (car p) x)) x))))
+
+
+; l is a list of tuples (c r) where c is a clause and r is the new value
+; for x at p under that clause
+; we create a new clause that replaces r at p in x for each tuple
+(defun new-clauses (p l x)
+ (if (endp l)
+ nil
+ (cons
+ (append (caar l) (replace-at p (cadar l) x))
+ (new-clauses p (cdr l) x))))
+
+
+#|
+(mutual-recursion
+ (defun refute (x depth sat::$sat state)
+ (declare (xargs :stobjs sat::$sat :mode :program))
+ (if (decidable-l x state)
+ (acl2::sat x nil sat::$sat state)
+ (if (zp depth)
+ (mv nil nil sat::$sat state)
+ (mv-let (p err state) (find-rec-l x 0 state) (declare (ignore err))
+ (mv-let (def state) (getdef (usepath p x) state)
+ (mv-let (x2 err) (rwrite (usepath p x) def) (declare (ignore err))
+ (let ((rn (recp (usepath p x) state)))
+ (let ((xl (get-cases x2 rn)))
+ (refute-l (new-clauses p xl x) (1- depth) sat::$sat state)))))))))
+ (defun refute-l (x depth sat::$sat state)
+ (declare (xargs :stobjs sat::$sat :mode :program))
+ (if (endp x)
+ (mv nil nil sat::$sat state)
+ (mv-let (r nop sat::$sat state)
+ (refute (car x) depth sat::$sat state) (declare (ignore nop))
+ (if r
+ (mv r nil sat::$sat state)
+ (refute-l (cdr x) depth sat::$sat state))))))
+
+(set-ignore-ok t)
+
+
+
+(defun refute4 (x depth sat::$sat state)
+ (declare (xargs :stobjs sat::$sat :mode :program))
+ (let ((nop (cw "~x0~%" x))) (declare (ignore nop))
+ (refute x depth sat::$sat state)))
+
+|#
+
+(mutual-recursion
+ (defun refute5 (x depth state)
+ (declare (xargs :mode :program))
+ (if (decidable-l x state)
+ (mv-let (err r state) (bash-term-to-dnf2 `(or ,@x) nil nil state) (declare (ignore err))
+ (mv r nil state))
+ (if (zp depth)
+ (mv nil nil state)
+ (mv-let (p err state) (find-rec-l x 0 state) (declare (ignore err))
+ (mv-let (def state) (getdef (usepath p x) state)
+ (mv-let (x2 err) (rwrite (usepath p x) def) (declare (ignore err))
+ (let ((rn (recp (usepath p x) state)))
+ (let ((xl (get-cases x2 rn)))
+ (refute5-l (new-clauses p xl x) (1- depth) state)))))))))
+ (defun refute5-l (x depth state)
+ (declare (xargs :mode :program))
+ (if (endp x)
+ (mv nil nil state)
+ (mv-let (r nop state)
+ (refute5 (car x) depth state) (declare (ignore nop))
+ (if r
+ (mv r nil state)
+ (refute5-l (cdr x) depth state))))))
+
+(defun refute6 (x depth state)
+ (declare (xargs :mode :program))
+ (let ((nop (cw "~x0~%" x))) (declare (ignore nop))
+ (refute5 x depth state)))
+
+(defmacro refute (x)
+ `(let ((nop (cw "~%ATTEMPTING TO REFUTE~%~%~x0~%~%" ',x))) (declare (ignore nop))
+ (mv-let (err r state)
+ (refute5 (list ',x) 6 state)
+ (declare (ignore r))
+ (if err
+ (let ((nop (cw "CEX~%~%~x0~%~%REFUTED~%" err))) (declare (ignore nop))
+ (mv nil nil state))
+ (let ((nop (cw "NO CEX FOUND~%"))) (declare (ignore nop))
+ (mv nil nil state))))))
+
+
+
+