Bash is a tool that simplifies a term, producing a list of simplified terms such that if all output terms are theorems, then so is the input term.
This utility is defined in community book
"misc/bash.lisp". If you submit (bash term) then roughly
speaking, the result is a list of goals produced by ACL2's simplification
process. That is, ACL2 might reasonably be expected to produce these goals
when simplifying term during a proof attempt. In particular, if the
result is nil, then term is a theorem. More accurately:
(bash term) returns an error-triple,
For related utilities, see bash-term-to-dnf and simp.
First we execute:
(include-book "misc/bash" :dir :system)Then:
ACL2 !>(bash (equal (append x y) (append (car (cons x a)) z))) Goal' ((EQUAL (APPEND X Y) (APPEND X Z))) ACL2 !>(set-gag-mode nil) ; optional; turns off printing of goal names <state> 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 (equal x y)) ACL2 Warning [bash] in BASH: Unable to simplify the input term. ((EQUAL X Y)) ACL2 !>(bash (equal x)) ACL2 Warning [bash] in BASH: Unable to simplify the input term because an error occurred. Try setting the verbose flag to t in order to see what is going on. ((EQUAL X)) ACL2 !>(bash (equal x) :verbose t) ACL2 Error in BASH: EQUAL takes 2 arguments but in the call (EQUAL X) it is given 1 argument. The formal parameters list for EQUAL is (X Y). ACL2 Warning [bash] in BASH: Unable to simplify the input term because an error occurred. ((EQUAL X)) ACL2 !>
Here is how we might use this tool to simplify hypotheses. First execute:
(defstub p1 (x) t) (defstub p2 (x) t) (defun p3 (x) (if (atom x) (p2 x) (p1 (car x)))) (include-book "misc/bash" :dir :system)Then:
ACL2 !>(bash (implies (and (p1 x) (p3 x)) (hide aaa))) ((IMPLIES (AND (P1 X) (CONSP X) (P1 (CAR X))) (HIDE AAA)) (IMPLIES (AND (P1 X) (NOT (CONSP X)) (P2 X)) (HIDE AAA))) ACL2 !>
This utility is similar to the proof-builder's bash command, but for use in the top-level loop. The input term can have user-level syntax; it need not be translated. The output is an error triple (mv nil termlist state) such that either termlist is a one-element list containing the input term, or else termlist is a list of term such that if each term in this list is a theorem, then the input term is a theorem. In practice, these terms are produced by calling the prover with non-simplification processes --- generalize, eliminate-destructors, fertilize (heuristic use of equalities), and eliminate-irrelevance, as well as induction --- turned off, and with forcing rounds skipped (at least the first 15 of them). A keyword argument, :hints, can specify hints using their usual syntax, as with defthm. The other keyword argument, :verbose, is nil by default, to suppress output; use a non-nil value if you want output, including the proof attempt. The keyword values are not evaluated, so for example :hints could be of the form (("Goal" ...)) but not '(("Goal" ...)).
We conclude with an note on the use of hints that may be important if you use computed hints (see computed-hints). Consider the following example, supplied courtesy of Harsh Raju Chamarthi.
(defun drop (n l) (if (zp n) l (drop (1- n) (cdr l)))) (include-book "misc/bash" :dir :system) ; Occur-fn returns the term that has fn has its function symbol. (mutual-recursion (defun occur-fn (fn term2) (cond ((variablep term2) nil) ((fquotep term2) nil) (t (or (and (eq fn (ffn-symb term2)) term2) (occur-fn-lst fn (fargs term2)))))) (defun occur-fn-lst (fn args2) (cond ((endp args2) nil) (t (or (occur-fn fn (car args2)) (occur-fn-lst fn (cdr args2))))))) ; Doesn't work as you might expect (see below): (bash (drop 3 x) :verbose t :hints ((if (occur-fn-lst 'drop clause) `(:computed-hint-replacement t :expand (,(occur-fn-lst 'drop clause))) nil)))The preceding call of bash, at the end of the displayed list of forms above, causes the theorem prover to use destructor elimination, even though that proof process is presumably turned off by bash. What happened? The problem is that the user-supplied hints are put in front of the hints generated by bash to form the full list of hints given to the prover, which cases the :do-not hint on "Goal" to be ignored. Here is a solution.
(bash (drop 3 x) :verbose t :hints ((if (occur-fn-lst 'drop clause) `(:computed-hint-replacement t :do-not-induct :bash :do-not (set-difference-eq *do-not-processes* '(preprocess simplify)) :expand (,(occur-fn-lst 'drop clause))) '(:do-not-induct :bash :do-not (set-difference-eq *do-not-processes* '(preprocess simplify))))))