other
(in-package "ACL2")
install-new-pc-meta-or-macromacro
(defmacro install-new-pc-meta-or-macro (command-type raw-name name formals doc body) `(progn ,(PC-META-OR-MACRO-DEFUN RAW-NAME NAME FORMALS DOC BODY) (add-pc-command ,NAME ',COMMAND-TYPE)))
define-pc-meta-or-macro-fnfunction
(defun define-pc-meta-or-macro-fn (command-type raw-name formals body) (let ((name (make-official-pc-command raw-name))) `(install-new-pc-meta-or-macro ,COMMAND-TYPE ,RAW-NAME ,NAME ,FORMALS nil ,BODY)))
define-pc-metamacro
(defmacro define-pc-meta (raw-name formals &rest body) (define-pc-meta-or-macro-fn 'meta raw-name formals body))
define-pc-macromacro
(defmacro define-pc-macro (raw-name formals &rest body) (define-pc-meta-or-macro-fn 'macro raw-name formals body))
define-pc-atomic-macromacro
(defmacro define-pc-atomic-macro (raw-name formals &rest body) (define-pc-meta-or-macro-fn 'atomic-macro raw-name formals body))
toggle-pc-macromacro
(defmacro toggle-pc-macro (name &optional new-tp) (declare (xargs :guard (and (symbolp new-tp) (or (null new-tp) (member-equal (symbol-name new-tp) '("MACRO" "ATOMIC-MACRO")))))) `(toggle-pc-macro-fn ',(MAKE-OFFICIAL-PC-COMMAND NAME) ',NEW-TP state))
define-pc-primitivemacro
(defmacro define-pc-primitive (raw-name formals &rest body) (let ((name (make-official-pc-command raw-name))) `(progn ,(PC-PRIMITIVE-DEFUN-FORM RAW-NAME NAME FORMALS NIL BODY) (add-pc-command ,NAME 'primitive))))
other
(define-pc-primitive comment (&rest x) (declare (ignore x)) (mv pc-state state))
non-bounded-numsfunction
(defun non-bounded-nums (nums lower upper) (declare (xargs :guard (and (rationalp lower) (rationalp upper) (true-listp nums)))) (if (consp nums) (if (and (integerp (car nums)) (<= lower (car nums)) (<= (car nums) upper)) (non-bounded-nums (cdr nums) lower upper) (cons (car nums) (non-bounded-nums (cdr nums) lower upper))) nil))
delete-by-positionfunction
(defun delete-by-position (lst current-index nums) (declare (xargs :guard (and (true-listp nums) (integerp current-index)))) (if (consp lst) (if (member current-index nums) (delete-by-position (cdr lst) (1+ current-index) nums) (cons (car lst) (delete-by-position (cdr lst) (1+ current-index) nums))) nil))
other
(define-pc-primitive drop (&rest nums) (if nums (let ((bad-nums (non-bounded-nums nums 1 (length hyps)))) (if bad-nums (print-no-change2 "The following are not in-range hypothesis numbers: ~&0." (list (cons #\0 bad-nums))) (mv (change-pc-state pc-state :goals (cons (change goal (car goals) :hyps (delete-by-position hyps 1 nums)) (cdr goals))) state))) (if hyps (mv (change-pc-state pc-state :goals (cons (change goal (car goals) :hyps nil) (cdr goals))) state) (print-no-change2 "There are no hypotheses to drop!"))))
other
(define-pc-meta lisp (form) (cond ((not (f-get-global 'in-verify-flg state)) (er soft 'lisp "You may only invoke the proof-builder LISP command when ~ you are inside the interactive loop.")) ((and (symbolp form) (or (eq form t) (eq form nil) (keywordp form))) (value form)) (t (mv-let (erp stobjs-out/vals state) (trans-eval-default-warning form :lisp state t) (let ((stobjs-out (car stobjs-out/vals)) (vals (cdr stobjs-out/vals))) (if (equal stobjs-out *error-triple-sig*) (mv (or erp (car vals)) (cadr vals) state) (mv erp vals state)))))))
other
(define-pc-primitive fail-primitive nil (declare (ignore pc-state)) (mv nil state))
other
(define-pc-macro fail (&optional hard) (if hard (value '(lisp (mv hard nil state))) (value 'fail-primitive)))
other
(define-pc-macro illegal (instr) (pprogn (print-no-change "Illegal interactive instruction, ~x0.~% An instruction must be a ~ symbol or a proper list headed by a symbol." (list (cons #\0 instr))) (value :fail)))
chk-assumption-free-ttree-1function
(defun chk-assumption-free-ttree-1 (ttree ctx) (cond ((tagged-objectsp 'assumption ttree) (er hard ctx "The 'assumption ~x0 was found in the final ttree!" (car (tagged-objects 'assumption ttree)))) ((tagged-objectsp 'fc-derivation ttree) (er hard ctx "The 'fc-derivation ~x0 was found in the final ttree!" (car (tagged-objects 'fc-derivation ttree)))) (t t)))
put-cdr-assoc-query-idfunction
(defun put-cdr-assoc-query-id (id val alist) (cond ((atom alist) (cons (cons id val) alist)) ((eq id (caar alist)) (cons (cons id val) (cdr alist))) (t (cons (car alist) (put-cdr-assoc-query-id id val (cdr alist))))))
set-query-valfunction
(defun set-query-val (id val state) (let ((alist (ld-query-control-alist state))) (set-ld-query-control-alist (put-cdr-assoc-query-id id (if (eq val 'toggle) (not (cdr-assoc-query-id id alist)) val) alist) state)))
query-on-exitmacro
(defmacro query-on-exit (&optional (val 'toggle)) `(set-query-val 'exit ',VAL state))
replay-queryfunction
(defun replay-query (state) (acl2-query 'exit '("~%Do you want to submit this event? Possible replies are:~%~ Y (Yes), R (yes and Replay commands), N (No, but exit), A (Abort exiting).~|~ " :y :y :r :r :n :n :a :a) nil state))
other
(define-pc-meta exit (&optional event-name rule-classes do-it-flg) (if (not (f-get-global 'in-verify-flg state)) (er soft 'exit "You may not invoke the EXIT command unless inside the ~ interactive loop.") (if args (let* ((event-name-and-types-and-raw-term (event-name-and-types-and-raw-term state-stack)) (event-name (or event-name (car event-name-and-types-and-raw-term))) (instructions (instructions-of-state-stack state-stack nil))) (er-let* ((event-name (if event-name (value event-name) (pprogn (io? proof-builder nil state nil (fms0 "Please supply an event name (or :A to ~ abort)~%>> ")) (read-object *standard-oi* state))))) (if (eq event-name :a) (pprogn (io? proof-builder nil state nil (fms0 "~|Exit aborted.~%")) (mv nil nil state)) (if (null (goals t)) (let* ((rule-classes (if (consp (cdr args)) rule-classes (if (and (consp args) (eq (car args) nil)) (cadr event-name-and-types-and-raw-term) '(:rewrite)))) (event-form `(defthm ,EVENT-NAME ,(CADDR EVENT-NAME-AND-TYPES-AND-RAW-TERM) ,@(IF (EQUAL RULE-CLASSES '(:REWRITE)) NIL (LIST :RULE-CLASSES RULE-CLASSES)) :instructions ,INSTRUCTIONS))) (mv-let (erp stobjs-out/vals state) (pprogn (print-pc-defthm event-form state) (mv-let (erp ans state) (cond (do-it-flg (value :y)) ((eq event-name t) (value :n)) (t (replay-query state))) (declare (ignore erp)) (case ans (:y (trans-eval-default-warning event-form 'exit state t)) (:r (pprogn (state-from-instructions (caddr event-form) event-name rule-classes instructions '(signal value) state) (trans-eval-default-warning event-form 'exit state t))) (:a (mv t '(nil . t) state)) (otherwise (mv t '(nil) state))))) (if (or erp (null (car stobjs-out/vals))) (if (eq (cdr stobjs-out/vals) t) (pprogn (io? proof-builder nil state nil (fms0 "~|Exit aborted.~%")) (mv nil nil state)) (mv *pc-complete-signal* nil state)) (mv *pc-complete-signal* event-name state)))) (pprogn (io? proof-builder nil state (instructions event-name-and-types-and-raw-term state-stack) (fms0 "~%Not exiting, as there remain unproved ~ goals: ~&0.~%The original goal is:~%~ ~ ~ ~ ~ ~y1~| Here is the current instruction ~ list, starting with the first:~%~ ~ ~ ~ ~ ~y2~|" (list (cons #\0 (goal-names (goals t))) (cons #\1 (caddr event-name-and-types-and-raw-term)) (cons #\2 instructions)))) (mv nil nil state)))))) (pprogn (io? proof-builder nil state nil (fms0 "~|Exiting....~%")) (mv *pc-complete-signal* nil state)))))
other
(define-pc-meta undo (&optional n) (if (and args (not (and (integerp n) (< 0 n)))) (pprogn (print-no-change "The optional argument to undo must be a positive integer.") (mv nil nil state)) (let ((m (min (or n 1) (1- (length state-stack))))) (if (null (cdr state-stack)) (pprogn (print-no-change "Already at the start.") (mv nil nil state)) (pprogn (pc-assign old-ss state-stack) (io? proof-builder nil state (state-stack m) (fms0 "~|Undoing: ~y0~|" (list (cons #\0 (access pc-state (car (nthcdr (1- m) state-stack)) :instruction))))) (pc-assign state-stack (nthcdr m state-stack)) (if (consp (cdr (state-stack))) state (io? proof-builder nil state nil (fms0 "Back to the start.~%"))) (mv nil t state))))))
other
(define-pc-meta restore nil (let ((old-ss (pc-value old-ss))) (if (null old-ss) (pprogn (io? proof-builder nil state nil (fms0 "~%Nothing to restore from!~%")) (mv nil nil state)) (let ((saved-ss state-stack)) (pprogn (pc-assign state-stack old-ss) (pc-assign old-ss saved-ss) (mv nil t state))))))
print-commandsfunction
(defun print-commands (indexed-instrs state) (if (null indexed-instrs) state (if (null (caar indexed-instrs)) (io? proof-builder nil state (indexed-instrs) (fms0 (car (cdar indexed-instrs)) (cdr (cdar indexed-instrs)))) (pprogn (io? proof-builder nil state (indexed-instrs) (fms0 "~|~x0. ~y1~|" (list (cons #\0 (caar indexed-instrs)) (cons #\1 (cdar indexed-instrs))))) (print-commands (cdr indexed-instrs) state)))))
make-pretty-start-instrfunction
(defun make-pretty-start-instr (state-stack) (let* ((triple (event-name-and-types-and-raw-term state-stack)) (name (car triple)) (types (cadr triple))) (if name (list "~|[started with (~x0 ~x1 ...)]~%" (cons #\0 name) (cons #\1 types)) (list "~|<< no event name specified at start >>~%"))))
raw-indexed-instrsfunction
(defun raw-indexed-instrs (start-index finish-index state-stack) (declare (xargs :guard (and (integerp start-index) (integerp finish-index) (<= start-index finish-index) (true-listp state-stack)))) (if (< start-index finish-index) (cons (cons start-index (access pc-state (car state-stack) :instruction)) (raw-indexed-instrs (1+ start-index) finish-index (cdr state-stack))) (if (cdr state-stack) (list (cons start-index (access pc-state (car state-stack) :instruction))) (list (cons nil (make-pretty-start-instr state-stack))))))
other
(define-pc-macro sequence-no-restore (instr-list) (value `(sequence ,INSTR-LIST nil nil nil nil t)))
other
(define-pc-macro skip nil (value '(sequence-no-restore nil)))
define-pc-helpmacro
(defmacro define-pc-help (name args &rest body) `(define-pc-macro ,NAME ,ARGS ,@(BUTLAST BODY 1) (pprogn ,(CAR (LAST BODY)) (value 'skip))))
evisc-indexed-instrs-1function
(defun evisc-indexed-instrs-1 (name rev-indexed-instrs) (if (consp rev-indexed-instrs) (let ((instr (cdr (car rev-indexed-instrs)))) (case-match instr ((comm ':end x . &) (if (and (eq comm (make-pretty-pc-command :comment)) (equal x name)) rev-indexed-instrs (evisc-indexed-instrs-1 name (cdr rev-indexed-instrs)))) (& (evisc-indexed-instrs-1 name (cdr rev-indexed-instrs))))) nil))
evisc-indexed-instrs-recfunction
(defun evisc-indexed-instrs-rec (rev-indexed-instrs) (if (consp rev-indexed-instrs) (let ((instr (cdr (car rev-indexed-instrs))) (evisc-cdr (evisc-indexed-instrs-rec (cdr rev-indexed-instrs)))) (case-match instr ((comm ':begin name . &) (if (eq comm (make-pretty-pc-command :comment)) (let ((rst (evisc-indexed-instrs-1 name evisc-cdr))) (if rst (cons (cons (car (car rev-indexed-instrs)) (cons "***HIDING***" instr)) (cdr rst)) (cons (car rev-indexed-instrs) evisc-cdr))) (cons (car rev-indexed-instrs) evisc-cdr))) (& (cons (car rev-indexed-instrs) evisc-cdr)))) nil))
mark-unfinished-instrsfunction
(defun mark-unfinished-instrs (indexed-instrs) (if (consp indexed-instrs) (let ((instr (cdr (car indexed-instrs)))) (case-match instr ((comm ':begin & . &) (if (eq comm (make-pretty-pc-command :comment)) (cons (cons (car (car indexed-instrs)) (cons "***UNFINISHED***" instr)) (mark-unfinished-instrs (cdr indexed-instrs))) (cons (car indexed-instrs) (mark-unfinished-instrs (cdr indexed-instrs))))) (& (cons (car indexed-instrs) (mark-unfinished-instrs (cdr indexed-instrs)))))) nil))
evisc-indexed-instrsfunction
(defun evisc-indexed-instrs (indexed-instrs) (mark-unfinished-instrs (reverse (evisc-indexed-instrs-rec (reverse indexed-instrs)))))
other
(define-pc-help commands (&optional n evisc-p) (if (and n (not (and (integerp n) (> n 0)))) (io? proof-builder nil state (n) (fms0 "*** The first optional argument to the COMMANDS command must ~ be a positive integer, but ~x0 is not.~|" (list (cons #\0 n)))) (let* ((indexed-instrs (raw-indexed-instrs 1 (if n (min n (length state-stack)) (length state-stack)) state-stack))) (print-commands (if evisc-p (evisc-indexed-instrs indexed-instrs) indexed-instrs) state))))
other
(define-pc-macro comm (&optional n) (value (list 'commands n t)))
promote-gutsfunction
(defun promote-guts (pc-state goals hyps x y no-flatten-flg) (change-pc-state pc-state :goals (cons (change goal (car goals) :hyps (append hyps (if no-flatten-flg (list x) (flatten-ands-in-lit x))) :conc y) (cdr goals))))
other
(define-pc-primitive promote (&optional do-not-flatten-flag) (if current-addr (print-no-change2 "You must be at the top ~ of the goal in order to promote the ~ antecedents of an implication. Try TOP first.") (case-match conc (('implies x y) (mv (promote-guts pc-state goals hyps x y do-not-flatten-flag) state)) (('if x y *t*) (mv (promote-guts pc-state goals hyps x y do-not-flatten-flag) state)) (& (print-no-change2 "The goal must be of the form ~x0 or ~x1." (list (cons #\0 '(implies p q)) (cons #\1 '(if p q t))))))))
remove-by-indicesfunction
(defun remove-by-indices (m indices lst) (if (consp lst) (if (member-equal m indices) (remove-by-indices (1+ m) indices (cdr lst)) (cons (car lst) (remove-by-indices (1+ m) indices (cdr lst)))) nil))
other
(define-pc-macro print (form &optional without-evisc) (let ((print-form `(fms0 "~|~y0~|" (list (cons #\0 ,FORM))))) (value `(lisp ,(IF WITHOUT-EVISC `(WITHOUT-EVISC ,PRINT-FORM) PRINT-FORM)))))
fetch-term-and-clfunction
(defun fetch-term-and-cl (term addr cl) (declare (xargs :guard (bounded-integer-listp 1 'infinity addr))) (cond ((eq cl t) (mv nil t)) ((null addr) (mv term cl)) ((or (variablep term) (fquotep term)) (mv nil t)) ((and (integerp (car addr)) (< 0 (car addr)) (< (car addr) (length term))) (case-match term (('if t1 t2 t3) (cond ((= 1 (car addr)) (fetch-term-and-cl t1 (cdr addr) cl)) ((= 2 (car addr)) (fetch-term-and-cl t2 (cdr addr) (cons t1 cl))) (t (fetch-term-and-cl t3 (cdr addr) (cons (dumb-negate-lit t1) cl))))) (('implies t1 t2) (cond ((= 1 (car addr)) (fetch-term-and-cl t1 (cdr addr) (cons (dumb-negate-lit t2) cl))) (t (fetch-term-and-cl t2 (cdr addr) (cons t1 cl))))) (& (fetch-term-and-cl (nth (1- (car addr)) (fargs term)) (cdr addr) cl)))) (t (mv nil t))))
fetch-termfunction
(defun fetch-term (term addr) (mv-let (term cl) (fetch-term-and-cl term addr nil) (if (eq cl t) (er hard 'fetch-term "FETCH-TERM-AND-CL did not find a subterm of ~x0 at address ~x1." term addr) term)))
governorsfunction
(defun governors (term addr) (mv-let (term cl) (fetch-term-and-cl term addr nil) (declare (ignore term)) cl))
term-id-ifffunction
(defun term-id-iff (term address iff-flg) (if (null address) iff-flg (term-id-iff (nth (car address) term) (cdr address) (cond ((eq (ffn-symb term) 'if) (if (= (car address) 1) t iff-flg)) ((member-eq (ffn-symb term) '(implies iff not)) t) (t nil)))))
abbreviations-alistfunction
(defun abbreviations-alist (abbreviations) (if (consp abbreviations) (cons (cons (fcons-term* '?-fn (kwote (caar abbreviations))) (cdar abbreviations)) (abbreviations-alist (cdr abbreviations))) nil))
chk-?smutual-recursion
(mutual-recursion (defun chk-?s (term ctx state) (cond ((or (variablep term) (fquotep term)) (value nil)) ((eq (ffn-symb term) '?-fn) (case-match term ((& ('quote var)) (if (variablep var) (er soft ctx "The variable ~x0 is not among the current abbreviations." var) (er soft ctx "Expected a variable in place of ~x0." var))) (& (value (er hard ctx "Bad call of ?-FN, ~x0. ?-FN must be called on the quotation of ~ a variable." term))))) ((flambdap (ffn-symb term)) (er-progn (chk-?s (lambda-body (ffn-symb term)) ctx state) (chk-?s-lst (fargs term) ctx state))) (t (chk-?s-lst (fargs term) ctx state)))) (defun chk-?s-lst (term-lst ctx state) (if (consp term-lst) (er-progn (chk-?s (car term-lst) ctx state) (chk-?s-lst (cdr term-lst) ctx state)) (value nil))))
remove-?sfunction
(defun remove-?s (term abbreviations-alist ctx state) (let ((newterm (sublis-expr-non-quoteps abbreviations-alist term))) (er-progn (chk-?s newterm ctx state) (value newterm))))
translate-abbfunction
(defun translate-abb (x abbreviations ctx state) (mv-let (erp term state) (translate x t t t ctx (w state) state) (if erp (mv erp term state) (remove-?s term (abbreviations-alist abbreviations) ctx state))))
trans0macro
(defmacro trans0 (x &optional abbreviations ctx) `(translate-abb ,X ,ABBREVIATIONS ,(OR CTX ''TRANS0) state))
p-bodyfunction
(defun p-body (conc current-addr abbreviations state) (io? proof-builder nil state (abbreviations current-addr conc) (fms0 "~|~y0~|" (list (cons #\0 (untrans0 (fetch-term conc current-addr) (term-id-iff conc current-addr t) abbreviations))))))
other
(define-pc-help p nil (when-goals (p-body (conc t) (current-addr t) (abbreviations t) state)))
other
(define-pc-help pp nil (when-goals (io? proof-builder nil state (state-stack) (fms0 "~|~y0~|" (list (cons #\0 (fetch-term (conc t) (current-addr t))))))))
take-by-indicesfunction
(defun take-by-indices (m indices lst) (if (consp lst) (if (member-equal m indices) (cons (car lst) (take-by-indices (1+ m) indices (cdr lst))) (take-by-indices (1+ m) indices (cdr lst))) nil))
print-hypsfunction
(defun print-hyps (indexed-hyps ndigits abbreviations state) (declare (xargs :guard (and (eqlable-alistp indexed-hyps) (integerp ndigits) (> ndigits 0)))) (if (null indexed-hyps) state (pprogn (io? proof-builder nil state (abbreviations ndigits indexed-hyps) (fms0 "~c0. ~y1~|" (list (cons #\0 (cons (caar indexed-hyps) ndigits)) (cons #\1 (untrans0 (cdar indexed-hyps) t abbreviations))))) (print-hyps (cdr indexed-hyps) ndigits abbreviations state))))
some->function
(defun some-> (lst n) (declare (xargs :guard (and (rational-listp lst) (rationalp n)))) (if lst (or (> (car lst) n) (some-> (cdr lst) n)) nil))
print-hyps-topfunction
(defun print-hyps-top (indexed-hyps abbreviations state) (declare (xargs :guard (eqlable-alistp indexed-hyps))) (if (null indexed-hyps) (io? proof-builder nil state nil (fms0 "~|There are no top-level hypotheses.~|")) (print-hyps indexed-hyps (if (some-> (strip-cars indexed-hyps) 9) 2 1) abbreviations state)))
print-governors-topfunction
(defun print-governors-top (indexed-hyps abbreviations state) (declare (xargs :guard (eqlable-alistp indexed-hyps))) (if (null indexed-hyps) (io? proof-builder nil state nil (fms0 "~|There are no governors.~|")) (print-hyps indexed-hyps (if (some-> (strip-cars indexed-hyps) 9) 2 1) abbreviations state)))
pair-indicesfunction
(defun pair-indices (seed indices lst) (declare (xargs :guard (and (integerp seed) (true-listp lst) (bounded-integer-listp 1 (length lst) indices)))) (if lst (let ((rest-lst (pair-indices (1+ seed) indices (cdr lst)))) (if (member seed indices) (cons (cons seed (car lst)) rest-lst) rest-lst)) nil))
other
(define-pc-macro hyps (&optional hyps-indices govs-indices) (when-goals-trip (let* ((hyps (hyps t)) (len-hyps (length hyps)) (govs (and govs-indices (governors (conc t) (current-addr t)))) (len-govs (length govs)) (abbs (abbreviations t)) (hyps-indices (or hyps-indices (null args)))) (cond ((not (or (eq hyps-indices t) (bounded-integer-listp 1 len-hyps hyps-indices))) (pprogn (io? proof-builder nil state (len-hyps hyps-indices) (fms0 "~|Bad hypothesis-list argument to HYPS, ~X0n. The ~ hypothesis-list argument should either be T or should be a ~ list of integers between 1 and the number of top-level ~ hypotheses, ~x1.~%" (list (cons #\0 hyps-indices) (cons #\n nil) (cons #\1 len-hyps)))) (value :fail))) ((not (or (eq govs-indices t) (bounded-integer-listp 1 len-govs govs-indices))) (pprogn (io? proof-builder nil state (len-govs govs-indices) (fms0 "~|Bad governors-list argument to HYPS,~% ~X0n.~%The ~ governors-list argument should either be T or should be a ~ list of integers between 1 and the number of top-level ~ governors, ~x1." (list (cons #\0 govs-indices) (cons #\n nil) (cons #\1 len-govs)))) (value :fail))) ((and (null hyps-indices) (null govs-indices)) (pprogn (io? proof-builder nil state nil (fms0 "~|You have specified no printing of either hypotheses or ~ governors! Perhaps you should read the documentation for ~ the HYPS command.~|")) (value :fail))) (t (let ((hyps-to-print (if (eq hyps-indices t) (count-off 1 hyps) (pair-indices 1 hyps-indices hyps))) (govs-to-print (if (eq govs-indices t) (count-off 1 govs) (pair-indices 1 govs-indices govs)))) (pprogn (if hyps-indices (pprogn (if (eq hyps-indices t) (io? proof-builder nil state nil (fms0 "~|*** Top-level hypotheses:~|")) (io? proof-builder nil state nil (fms0 "~|*** Specified top-level hypotheses:~|"))) (print-hyps-top hyps-to-print abbs state)) state) (if govs-indices (pprogn (if (eq govs-indices t) (io? proof-builder nil state nil (fms0 "~|~%*** Governors:~|")) (io? proof-builder nil state nil (fms0 "~|~%*** Specified governors:~|"))) (print-governors-top govs-to-print abbs state)) state) (value 'skip))))))))
other
(define-pc-primitive demote (&rest rest-args) (cond (current-addr (print-no-change2 "You must be at the top of the conclusion in order to ~ demote hypotheses. Try TOP first.")) ((null hyps) (print-no-change2 "There are no top-level hypotheses.")) (t (let ((badindices (non-bounded-nums rest-args 1 (length hyps)))) (if badindices (print-no-change2 "The arguments to DEMOTE ~ must be indices of active top-level hypotheses, ~ but the following are not: ~&0." (list (cons #\0 badindices))) (mv (change-pc-state pc-state :goals (cons (change goal (car goals) :hyps (if rest-args (remove-by-indices 1 rest-args hyps) nil) :conc (make-implication (if rest-args (take-by-indices 1 rest-args hyps) hyps) conc)) (cdr goals))) state))))))
pair-keywordsfunction
(defun pair-keywords (keywords lst) (declare (xargs :guard (and (keyword-listp keywords) (keyword-value-listp lst)))) (if (consp keywords) (mv-let (alist rst) (pair-keywords (cdr keywords) lst) (let ((tail (assoc-keyword (car keywords) rst))) (if tail (mv (cons (cons (car tail) (cadr tail)) alist) (remove-keyword (car keywords) rst)) (mv alist rst)))) (mv nil lst)))
null-poolfunction
(defun null-pool (pool) (cond ((null pool) t) ((eq (access pool-element (car pool) :tag) 'being-proved-by-induction) (null-pool (cdr pool))) (t nil)))
initial-pspvfunction
(defun initial-pspv (term displayed-goal otf-flg ens wrld state splitter-output orig-hints) (change prove-spec-var *empty-prove-spec-var* :rewrite-constant (initial-rcnst-from-ens ens wrld state splitter-output) :user-supplied-term term :displayed-goal displayed-goal :otf-flg otf-flg :orig-hints orig-hints))
pc-provefunction
(defun pc-prove (term displayed-goal hints otf-flg ens wrld ctx state) (er-let* ((ttree (let ((pspv (initial-pspv term displayed-goal otf-flg ens wrld state (splitter-output) hints)) (clauses (list (list term)))) (if (f-get-global 'in-verify-flg state) (state-global-let* ((saved-output-p t) (saved-output-token-lst :all)) (pprogn (f-put-global 'saved-output-reversed nil state) (push-current-acl2-world 'saved-output-reversed state) (prove-loop clauses pspv hints ens wrld ctx state))) (prove-loop clauses pspv hints ens wrld ctx state))))) (er-progn (chk-assumption-free-ttree ttree ctx state) (value ttree))))
abbreviations-alist-?function
(defun abbreviations-alist-? (abbreviations) (if (consp abbreviations) (cons (cons (fcons-term* '? (caar abbreviations)) (cdar abbreviations)) (abbreviations-alist-? (cdr abbreviations))) nil))
find-?-fnfunction
(defun find-?-fn (x) (if (atom x) nil (if (eq (car x) '?-fn) (list (cadr x)) (union-equal (find-?-fn (car x)) (find-?-fn (cdr x))))))
unproved-pc-prove-clausesfunction
(defun unproved-pc-prove-clauses (ttree) (reverse-strip-cdrs (tagged-objects :bye ttree) nil))
prover-callfunction
(defun prover-call (comm term-to-prove rest-args pc-state state) (declare (xargs :guard (keywordp comm))) (let ((prover-call-abbreviations (access pc-state pc-state :abbreviations)) (prover-call-wrld (w state))) (let ((prover-call-pc-ens (make-pc-ens (access pc-state pc-state :pc-ens) state))) (mv-let (prover-call-pairs prover-call-tail) (pair-keywords '(:otf-flg :hints) rest-args) (if prover-call-tail (pprogn (print-no-change "The only keywords allowed in the arguments to the ~x0 command ~ are :otf-flg and :hints. Your ~ instruction ~x1 violates this requirement." (list (cons #\0 comm) (cons #\1 (make-pretty-pc-instr (cons comm rest-args))))) (mv t nil state)) (mv-let (prover-call-erp prover-call-hints state) (let ((un-?-hints (sublis-equal (abbreviations-alist-? prover-call-abbreviations) (cdr (assoc-eq :hints prover-call-pairs))))) (let ((?-exprs (find-?-fn un-?-hints))) (if ?-exprs (pprogn (print-no-change "You appear to have attempted to use the following ~ abbreviation variable~#0~[~/~/s~], which however ~ ~#0~[~/is~/are~] not among ~ the current abbreviation variables (see SHOW-ABBREVIATIONS): ~&1." (list (cons #\0 (zero-one-or-more (length ?-exprs))) (cons #\1 ?-exprs))) (mv t nil state)) (pprogn (io? proof-builder nil state nil (fms0 "~|***** Now entering the theorem ~ prover *****~|")) (translate-hints+ 'proof-builder un-?-hints (default-hints prover-call-wrld) comm prover-call-wrld state))))) (if prover-call-erp (pprogn (print-no-change "Failed to translate hints successfully.") (mv t nil state)) (let ((prover-call-otf-flg (cdr (assoc-eq :otf-flg prover-call-pairs)))) (mv-let (prover-call-erp prover-call-ttree state) (pc-prove term-to-prove (untranslate term-to-prove t prover-call-wrld) prover-call-hints prover-call-otf-flg prover-call-pc-ens prover-call-wrld comm state) (pprogn (io? proof-builder nil state nil (fms0 "~%")) (if prover-call-erp (pprogn (print-no-change "Proof failed.") (mv t nil state)) (mv nil prover-call-ttree state))))))))))))
make-new-goalsfunction
(defun make-new-goals (cl-set goal-name start-index) (if (consp cl-set) (cons (make goal :conc (car (last (car cl-set))) :hyps (dumb-negate-lit-lst (butlast (car cl-set) 1)) :current-addr nil :goal-name (cons goal-name start-index) :depends-on 1) (make-new-goals (cdr cl-set) goal-name (1+ start-index))) nil))
same-goalfunction
(defun same-goal (goal1 goal2) (and (equal (access goal goal1 :hyps) (access goal goal2 :hyps)) (equal (access goal goal1 :conc) (access goal goal2 :conc))))
remove-byes-from-tag-treefunction
(defun remove-byes-from-tag-tree (ttree) (remove-tag-from-tag-tree :bye ttree))
other
(define-pc-primitive prove (&rest rest-args) (cond (current-addr (print-no-change2 "The PROVE command should only be used at ~ the top. Use (= T) if that is what you want.")) ((not (keyword-value-listp rest-args)) (print-no-change2 "The argument list for the PROVE command should ~ be empty or a list of even length with keywords in the odd ~ positions. See the documentation for examples and details.")) (t (mv-let (erp ttree state) (prover-call :prove (make-implication hyps conc) rest-args pc-state state) (cond (erp (mv nil state)) (t (let* ((new-clauses (unproved-pc-prove-clauses ttree)) (new-goals (make-new-goals new-clauses goal-name depends-on)) (len-new-goals (length new-goals))) (cond ((and (equal len-new-goals 1) (same-goal (car new-goals) (car goals))) (print-no-change2 "Exactly one new goal was created by your PROVE ~ command, and it has exactly the same hypotheses ~ and conclusion as did the current goal.")) ((tagged-objects 'assumption ttree) (mv (change-pc-state pc-state :goals (cons (change goal (car goals) :conc *t* :depends-on (+ (access goal (car goals) :depends-on) len-new-goals)) (append new-goals (cdr goals))) :local-tag-tree (remove-byes-from-tag-tree ttree)) state)) (t (mv (change-pc-state pc-state :goals (append new-goals (cdr goals)) :local-tag-tree (remove-byes-from-tag-tree ttree)) state))))))))))
add-string-val-pair-to-string-val-alist-1function
(defun add-string-val-pair-to-string-val-alist-1 (key key1 val alist replace-p) (cond ((null alist) (list (list key key1 val))) ((and (stringp (caar alist)) (string-equal key (caar alist))) (if (assoc-keyword key1 (cdar alist)) (if replace-p (cons (list* (caar alist) key1 val (remove-keyword key1 (cdar alist))) (cdr alist)) alist) (cons (list* (caar alist) key1 val (cdar alist)) (cdr alist)))) (t (cons (car alist) (add-string-val-pair-to-string-val-alist-1 key key1 val (cdr alist) replace-p)))))
add-string-val-pair-to-string-val-alistfunction
(defun add-string-val-pair-to-string-val-alist (key key1 val alist) (add-string-val-pair-to-string-val-alist-1 key key1 val alist nil))
add-string-val-pair-to-string-val-alist!function
(defun add-string-val-pair-to-string-val-alist! (key key1 val alist) (add-string-val-pair-to-string-val-alist-1 key key1 val alist t))
*bash-skip-forcing-round-hints*constant
(defconst *bash-skip-forcing-round-hints* '(("[1]Goal" :by nil) ("[1]Subgoal 1" :by nil) ("[1]Subgoal 2" :by nil) ("[1]Subgoal 3" :by nil) ("[1]Subgoal 4" :by nil) ("[1]Subgoal 5" :by nil) ("[1]Subgoal 6" :by nil) ("[1]Subgoal 7" :by nil) ("[1]Subgoal 8" :by nil) ("[1]Subgoal 9" :by nil) ("[1]Subgoal 10" :by nil) ("[1]Subgoal 11" :by nil) ("[1]Subgoal 12" :by nil) ("[1]Subgoal 13" :by nil) ("[1]Subgoal 14" :by nil) ("[1]Subgoal 15" :by nil)))
other
(define-pc-atomic-macro bash (&rest hints) (if (alistp hints) (value (list :prove :hints (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 'proof-builder hints))) :otf-flg t)) (pprogn (print-no-change "A BASH instruction must be of the form~%~ ~ ~ (:BASH (goal_name_1 ...) ... (goal_name_n ...)),~%and hence ~ your instruction,~%~ ~ ~x0,~%is not legal." (list (cons #\0 (cons :bash hints)))) (value :fail))))
other
(define-pc-primitive dive (n &rest rest-addr) (if (not (bounded-integer-listp 1 'infinity args)) (print-no-change2 "The arguments to DIVE must all be positive integers.") (mv-let (subterm cl) (fetch-term-and-cl (fetch-term conc current-addr) args nil) (declare (ignore subterm)) (if (eq cl t) (print-no-change2 "Unable to DIVE according to the address~%~ ~ ~y0." (list (cons #\0 (cons n rest-addr)))) (mv (change-pc-state pc-state :goals (cons (change goal (car goals) :current-addr (append (access goal (car goals) :current-addr) args)) (cdr goals))) state)))))
other
(define-pc-atomic-macro split nil (value '(:prove :hints (("Goal" :do-not-induct proof-builder :do-not '(generalize eliminate-destructors fertilize eliminate-irrelevance) :in-theory (theory 'minimal-theory))))))
other
(define-pc-primitive add-abbreviation (var &optional raw-term) (mv-let (erp term state) (if (cdr args) (trans0 raw-term abbreviations :add-abbreviation) (value (fetch-term conc current-addr))) (cond (erp (mv nil state)) ((variablep var) (if (assoc-eq var abbreviations) (print-no-change2 "The abbreviation ~x0 has already been used, and stands for ~x1." (list (cons #\0 var) (cons #\1 (untrans0 (cdr (assoc-eq var abbreviations)))))) (mv (change-pc-state pc-state :abbreviations (cons (cons var term) abbreviations)) state))) (t (print-no-change2 "An abbreviation must be a variable, but ~x0 is not." (list (cons #\0 var)))))))
not-in-domain-eqfunction
(defun not-in-domain-eq (lst alist) (declare (xargs :guard (if (symbol-listp lst) (alistp alist) (symbol-alistp alist)))) (if (consp lst) (if (assoc-eq (car lst) alist) (not-in-domain-eq (cdr lst) alist) (cons (car lst) (not-in-domain-eq (cdr lst) alist))) nil))
other
(define-pc-primitive remove-abbreviations (&rest vars) (if (null abbreviations) (print-no-change2 "There are currently no abbreviations.") (let ((badvars (and args (not-in-domain-eq vars abbreviations)))) (if (and args badvars) (print-no-change2 "The variable~#0~[~/~/s~] ~&1 ~ ~#0~[~/is not currently an abbreviation variable~/~ are not currently abbreviation variables~]." (list (cons #\0 (zero-one-or-more (length badvars))) (cons #\1 badvars))) (mv (change-pc-state pc-state :abbreviations (if args (remove1-assoc-eq-lst vars abbreviations) nil)) state)))))
print-abbreviationsfunction
(defun print-abbreviations (vars abbreviations state) (declare (xargs :guard (and (true-listp vars) (symbol-alistp abbreviations)))) (if (null vars) state (pprogn (io? proof-builder nil state nil (fms0 "~%")) (let ((pair (assoc-equal (car vars) abbreviations))) (if (null pair) (io? proof-builder nil state (vars) (fms0 "*** ~x0 does not abbreviate a term.~|" (list (cons #\0 (car vars))))) (let ((untrans-1 (untrans0 (cdr pair))) (untrans-2 (untrans0 (cdr pair) nil (remove1-assoc-eq (car pair) abbreviations)))) (pprogn (io? proof-builder nil state (pair) (fms0 "(? ~x0) is an abbreviation for:~%~ ~ " (list (cons #\0 (car pair))))) (io? proof-builder nil state (untrans-1) (fms0 "~y0~|" (list (cons #\0 untrans-1)) 2)) (if (equal untrans-1 untrans-2) state (pprogn (io? proof-builder nil state nil (fms0 "i.e. for~%~ ~ ")) (io? proof-builder nil state (untrans-2) (fms0 "~y0~|" (list (cons #\0 untrans-2)) 2)))))))) (print-abbreviations (cdr vars) abbreviations state))))
other
(define-pc-help show-abbreviations (&rest vars) (if (null (abbreviations t)) (io? proof-builder nil state nil (fms0 "~|There are currently no abbreviations.~%")) (print-abbreviations (or vars (strip-cars (abbreviations t))) (abbreviations t) state)))
drop-from-endfunction
(defun drop-from-end (n l) (declare (xargs :guard (and (integerp n) (not (< n 0)) (true-listp l) (<= n (length l))))) (take (- (length l) n) l))
other
(define-pc-primitive up (&optional n) (let ((n (or n 1))) (cond ((null current-addr) (print-no-change2 "Already at the top.")) ((not (and (integerp n) (> n 0))) (print-no-change2 "If UP is supplied with an argument, it must be ~ a positive integer or NIL, unlike ~x0." (list (cons #\0 n)))) ((<= n (length current-addr)) (mv (change-pc-state pc-state :goals (cons (change goal (car goals) :current-addr (drop-from-end n current-addr)) (cdr goals))) state)) (t (print-no-change2 "Can only go up ~x0 level~#1~[~/~/s~]." (list (cons #\0 (length current-addr)) (cons #\1 (zero-one-or-more (length current-addr)))))))))
other
(define-pc-atomic-macro top nil (when-goals-trip (let ((current-addr (current-addr t))) (value (list :up (length current-addr))))))
expand-address-recursemacro
(defmacro expand-address-recurse (&key (ans '(cons (car addr) rest-addr)) (new-addr '(cdr addr)) (new-raw-term '(nth (car addr) raw-term)) (new-term '(nth (car addr) term)) (new-iff-flg 'nil) (new-accumulated-addr-r '(cons (car addr) accumulated-addr-r))) `(mv-let (erp rest-addr) (expand-address ,NEW-ADDR ,NEW-RAW-TERM ,NEW-TERM abbreviations ,NEW-IFF-FLG ,NEW-ACCUMULATED-ADDR-R wrld) (if erp (mv erp rest-addr) (mv nil ,ANS))))
dive-once-more-errormacro
(defmacro dive-once-more-error nil '(mv "When diving to subterm ~x0 using address ~x1, ~ the additional dive to ~x2 was impossible." (list (cons #\0 raw-term) (cons #\1 (reverse accumulated-addr-r)) (cons #\2 (car addr)))))
abbreviation-raw-term-pfunction
(defun abbreviation-raw-term-p (x) (and (consp x) (eq (car x) '?)))
addr-recurmacro
(defmacro addr-recur (pos b) `(if (integerp ,POS) (mv-let (addr new-term new-iff-flg not-flg) ,B (if (msgp addr) (mv addr nil nil nil) (mv (cons ,POS addr) new-term new-iff-flg not-flg))) (if (eq ,POS 'not) ,(CASE-MATCH B (('MV 'NIL X Y 'NIL) `(MV NIL ,X ,Y T)) (& '(MV "a NOT term unexpected by the code; sorry" NIL NIL NIL))) (mv ,POS nil nil nil))))
or-addrfunction
(defun or-addr (n term iff-flg) (case-match term (('if x1 x1 x2) (declare (ignore x1)) (cond ((int= n 1) (mv "of an ambiguity: the first argument of the OR term occurs ~ twice in the IF term that represents the OR term" nil nil nil)) ((int= n 2) (addr-recur 3 (or-addr (1- n) x2 iff-flg))) (t (mv "of an index that is out of range" nil nil nil)))) (('if x1 x2 *t*) (cond ((int= n 1) (cond ((ffn-symb-p x1 'not) (mv '(1) x1 t t)) (t (mv (msg "that dive has led us to the first argument of ~ the term ~x0, but we expected to reach a call of ~ ~x1" term 'not) nil nil nil)))) (t (addr-recur 2 (or-addr (1- n) x2 iff-flg))))) (('if x1 *t* x2) (cond ((int= n 1) (mv '(1) x1 t nil)) (t (addr-recur 3 (or-addr (1- n) x2 iff-flg))))) (& (cond ((int= n 1) (mv nil term iff-flg nil)) (t (mv "a non-IF term was encountered when diving to the first ~ argument (perhaps because your DV argument was greater than ~ the number of disjuncts)." nil nil nil))))))
and-addrfunction
(defun and-addr (n term iff-flg) (case-match term (('if x1 x2 *nil*) (cond ((int= n 1) (mv '(1) x1 t nil)) (t (addr-recur 2 (and-addr (1- n) x2 iff-flg))))) (('if x1 *nil* x2) (cond ((int= n 1) (cond ((ffn-symb-p x1 'not) (mv '(1) x1 t t)) (t (mv "of an unexpected case of diving to the first ~ argument: for an if-then-else term with THEN branch ~ of nil, the TEST was expected to be a call of NOT" nil nil nil)))) (t (addr-recur 3 (and-addr (1- n) x2 iff-flg))))) (& (cond ((int= n 1) (mv nil term iff-flg nil)) (t (mv "a non-IF term was encountered when diving to the first ~ argument (perhaps because your DV argument was greater than ~ the number of conjuncts)" nil nil nil))))))
other
(set-table-guard dive-into-macros-table (and (symbolp key) (or (and (function-symbolp val world) (equal (stobjs-in val world) '(nil nil nil nil)) (not (assoc-eq val *ttag-fns*)) (not (member-eq val (global-val 'untouchable-fns world)))) (integerp val) (null val))))
add-dive-into-macromacro
(defmacro add-dive-into-macro (name val) `(table dive-into-macros-table ',NAME ',VAL))
remove-dive-into-macromacro
(defmacro remove-dive-into-macro (name) `(table dive-into-macros-table ',NAME nil))
dive-into-macros-tablefunction
(defun dive-into-macros-table (wrld) (declare (xargs :guard (plist-worldp wrld))) (table-alist 'dive-into-macros-table wrld))
rassoc-eq-as-carfunction
(defun rassoc-eq-as-car (key alist) (cond ((endp alist) nil) ((eq key (car (cdr (car alist)))) (car alist)) (t (rassoc-eq-as-car key (cdr alist)))))
*ca<d^n>r-alist*constant
(defconst *ca<d^n>r-alist* '((cadr . 2) (cdar . 2) (caar . 2) (cddr . 2) (caadr . 3) (cdadr . 3) (cadar . 3) (cddar . 3) (caaar . 3) (cdaar . 3) (caddr . 3) (cdddr . 3) (caaadr . 4) (cadadr . 4) (caadar . 4) (caddar . 4) (cdaadr . 4) (cddadr . 4) (cdadar . 4) (cdddar . 4) (caaaar . 4) (cadaar . 4) (caaddr . 4) (cadddr . 4) (cdaaar . 4) (cddaar . 4) (cdaddr . 4) (cddddr . 4)))
car/cdr^nfunction
(defun car/cdr^n (n term) (cond ((zp n) term) ((or (variablep term) (not (member-eq (car term) '(car cdr)))) (er hard 'car/cdr^n "Illegal call: ~x0.~|If you encountered this call in the ~ proof-builder, please contact the ACL2 implementors." `(car/cdr^n ,N ,TERM))) (t (car/cdr^n (1- n) (fargn term 1)))))
expand-address-msgmacro
(defmacro expand-address-msg (str &rest args) `(mv ,STR (cons (cons #\0 (if accumulated-addr-r (msg "The dive via address ~x0 brings us to" (reverse accumulated-addr-r)) "The current subterm is")) (cons (cons #\f (if accumulated-addr-r " further" "")) ,(MAKE-FMT-BINDINGS (CDR *BASE-10-CHARS*) ARGS)))))
expand-addressfunction
(defun expand-address (addr raw-term term abbreviations iff-flg accumulated-addr-r wrld) (cond ((or (null addr) (equal addr '(0))) (mv nil nil)) ((abbreviation-raw-term-p raw-term) (let ((pair (assoc-eq (cadr raw-term) abbreviations))) (if pair (expand-address (cdr addr) (cdr pair) term (remove1-equal pair abbreviations) iff-flg (cons (car addr) accumulated-addr-r) wrld) (mv t (er hard 'expand-address "Found abbreviation variable ~x0 that is not in the ~ current abbreviations alist, ~x1." (cadr raw-term) abbreviations))))) ((not (and (integerp (car addr)) (< 0 (car addr)))) (mv "All members of an address must be positive integers (except ~ that 0 is allowed in circumstances involving CASE, COND, and ~ abbreviations, which do not apply here). ~x0 violates this ~ requirement." (list (cons #\0 (car addr))))) ((or (variablep raw-term) (fquotep raw-term) (not (< (car addr) (length raw-term)))) (dive-once-more-error)) ((flambda-applicationp term) (cond ((eql (car addr) 2) (mv "Unable to dive to the body of a LET, which is really part of ~ the function symbol of the translated LAMBDA term." nil)) ((and (consp raw-term) (eq (car raw-term) 'let) (>= (length addr) 3) (eql (car addr) 1) (natp (cadr addr)) (< (cadr addr) (length (cadr raw-term))) (member (caddr addr) '(0 1))) (cond ((eql (caddr addr) 0) (mv "Unable to dive to a variable of a LET." nil)) (t (expand-address-recurse :ans (cons (1+ (cadr addr)) rest-addr) :new-addr (cdddr addr) :new-raw-term (nth 1 (nth (cadr addr) (nth 1 raw-term))) :new-term (nth (1+ (car addr)) term) :new-accumulated-addr-r (cons (1+ (car addr)) accumulated-addr-r))))) (t (mv "Unable to expand LAMBDA (LET) term." nil)))) ((atom raw-term) (mv t (er hard 'expand-address "Surprise! Found an unexpected raw-term atom, ~x0." raw-term))) (t (let ((dive-fn (cdr (assoc-eq (car raw-term) (dive-into-macros-table wrld))))) (cond (dive-fn (mv-let (erp val) (ev-fncall-w dive-fn (list (car addr) raw-term term wrld) wrld nil nil t nil t) (cond ((or erp (stringp (car val))) (mv (car val) (cdr val))) (t (expand-address-recurse :ans (append val rest-addr) :new-iff-flg nil :new-term (fetch-term term val)))))) ((let ((pair (rassoc-eq-as-car (car raw-term) (untrans-table wrld)))) (and pair (eql (arity (car pair) wrld) 2))) (let* ((lst (cond ((= (car addr) (1- (length raw-term))) (make-list (1- (car addr)) :initial-element 2)) (t (append (make-list (1- (car addr)) :initial-element 2) '(1))))) (subterm (fetch-term term lst))) (if subterm (expand-address-recurse :ans (append lst rest-addr) :new-iff-flg nil :new-term subterm) (dive-once-more-error)))) (t (case (car raw-term) ((list list*) (let* ((lst0 (make-list (1- (car addr)) :initial-element 2)) (lst (if (eq (car raw-term) 'list) (append lst0 '(1)) lst0)) (subterm (fetch-term term lst))) (if subterm (expand-address-recurse :ans (append lst rest-addr) :new-iff-flg nil :new-term subterm) (dive-once-more-error)))) (<= (cond ((not (member (car addr) '(1 2))) (dive-once-more-error)) ((= (car addr) 1) (expand-address-recurse :ans (cons 1 (cons 2 rest-addr)) :new-iff-flg nil :new-term (nth 2 (nth 1 term)))) (t (expand-address-recurse :ans (cons 1 (cons 1 rest-addr)) :new-iff-flg nil :new-term (nth 1 (nth 1 term)))))) ((and or) (mv-let (and-or-addr new-term new-iff-flg finish-not-p) (if (eq (car raw-term) 'and) (and-addr (car addr) (abbreviate term abbreviations) iff-flg) (or-addr (car addr) (abbreviate term abbreviations) iff-flg)) (cond ((msgp and-or-addr) (expand-address-msg "~@0 the ~x4 term~%~ ~ ~y1,~|~%which translates ~ to~%~ ~ ~y2.~|~%The requested dive into this ~x4 ~ term is problematic, because ~@3. Try using DIVE ~ instead (you may use PP to find the appropriate ~ address)." raw-term term and-or-addr (car raw-term))) (finish-not-p (cond ((and (cdr addr) (int= (cadr addr) 1)) (expand-address-recurse :ans (append and-or-addr rest-addr) :new-addr (cddr addr) :new-term new-term :new-iff-flg new-iff-flg :new-accumulated-addr-r (cons 1 (cons (car addr) accumulated-addr-r)))) (t (let ((accumulated-addr-r (cons (car addr) accumulated-addr-r))) (expand-address-msg "~@0 the NOT term ~x1, which does not actually ~ exist in the internal syntax of the current ~ term, namely:~%~x2. Try using DIVE instead ~ (you may use PP to find the appropriate ~ address)." (nth (car addr) raw-term) term))))) (t (expand-address-recurse :ans (append and-or-addr rest-addr) :new-term new-term :new-iff-flg new-iff-flg))))) (case (cond ((= (car addr) 1) (expand-address-msg "~@0 the CASE term~%~ ~ ~x1,~%which corresponds to the ~ translated term~%~ ~ ~x2.~%A~@f dive to the first ~ argument doesn't really make sense here." raw-term term)) ((not (and (consp (cdr addr)) (member-equal (cadr addr) '(0 1)))) (expand-address-msg "~@0 the CASE term~%~ ~ ~x1,~%A~@f dive past argument ~ number ~x2 to the zeroth or first ``argument'' is ~ required at this point.~%" raw-term (car addr))) ((and (= (cadr addr) 0) (= (car addr) (1- (length raw-term)))) (expand-address-msg "~@0 the CASE term~%~ ~ ~x1,~%A~@f dive to the ~ ``otherwise'' expression is not allowed." raw-term)) (t (let* ((lst (if (= (cadr addr) 1) (if (= (car addr) (1- (length raw-term))) (make-list (- (car addr) 2) :initial-element 3) (append (make-list (- (car addr) 2) :initial-element 3) '(2))) (append (make-list (- (car addr) 2) :initial-element 3) '(1 2)))) (subterm (fetch-term term lst))) (if subterm (expand-address-recurse :ans (append lst rest-addr) :new-addr (cddr addr) :new-raw-term (cadr (nth (1+ (car addr)) raw-term)) :new-term subterm :new-iff-flg iff-flg :new-accumulated-addr-r (cons (car addr) (cons (cadr addr) accumulated-addr-r))) (mv t (er hard 'expand-address "Surprise! Unable to dive into raw-term ~x0, ~ which is term ~x1, using list ~x2. So far we ~ have DV-ed using ~x3." raw-term term lst (reverse accumulated-addr-r)))))))) (cond (cond ((not (and (consp (cdr addr)) (member-equal (cadr addr) '(0 1)))) (expand-address-msg "~@0 the COND term~%~ ~ ~x1,~%A~@f dive past argument ~ number ~x2 to the zeroth or first ``argument'' is ~ required at this point.~%" raw-term (car addr))) ((and (= (cadr addr) 0) (= (car addr) (1- (length raw-term)))) (expand-address-msg "~@0 the COND term~%~ ~ ~x1,~%A~@f dive to the ``T'' ~ expression is not allowed." raw-term)) (t (let* ((lst (if (= (cadr addr) 1) (if (= (car addr) (1- (length raw-term))) (make-list (1- (car addr)) :initial-element 3) (append (make-list (1- (car addr)) :initial-element 3) '(2))) (append (make-list (1- (car addr)) :initial-element 3) '(1)))) (subterm (fetch-term term lst))) (if subterm (expand-address-recurse :ans (append lst rest-addr) :new-addr (cddr addr) :new-raw-term (cadr (nth (1+ (car addr)) raw-term)) :new-term subterm :new-iff-flg iff-flg :new-accumulated-addr-r (cons (car addr) (cons (cadr addr) accumulated-addr-r))) (mv t (er hard 'expand-address "Surprise! Unable to dive into raw-term ~x0, ~ which is term ~x1, using list ~x2. So far we ~ have DV-ed using ~x3." raw-term term lst (reverse accumulated-addr-r)))))))) (if (expand-address-recurse :new-iff-flg (if (= (car addr) 1) t iff-flg))) ((implies iff) (expand-address-recurse :new-iff-flg t)) (t (let ((pair (and (consp raw-term) (assoc-eq (car raw-term) *ca<d^n>r-alist*)))) (cond (pair (expand-address-recurse :ans (append (make-list (cdr pair) :initial-element 1) rest-addr) :new-term (car/cdr^n (cdr pair) term))) (t (expand-address-recurse))))))))))))
dv-errormacro
(defmacro dv-error (str alist) `(pprogn (print-no-change (string-append "Unable to perform the requested dive.~|~%" ,STR) (cons (cons #\t current-term) ,ALIST)) (mv t nil state)))
other
(define-pc-atomic-macro dv (&rest rest-args) (let* ((conc (conc t)) (current-addr (current-addr t)) (abbreviations (abbreviations t)) (current-term (fetch-term conc current-addr)) (term-id-iff (term-id-iff conc current-addr t))) (mv-let (erp addr) (expand-address rest-args (untrans0 current-term term-id-iff abbreviations) current-term abbreviations term-id-iff nil (w state)) (if erp (dv-error erp addr) (mv nil (cons ':dive addr) state)))))
deposit-termmutual-recursion
(mutual-recursion (defun deposit-term (term addr subterm) (cond ((null addr) subterm) (t (cons-term (ffn-symb term) (deposit-term-lst (fargs term) (car addr) (cdr addr) subterm))))) (defun deposit-term-lst (lst n addr subterm) (cond ((= 1 n) (cons (deposit-term (car lst) addr subterm) (cdr lst))) (t (cons (car lst) (deposit-term-lst (cdr lst) (1- n) addr subterm))))))
geneqv-at-subtermfunction
(defun geneqv-at-subterm (term addr geneqv pequiv-info ens wrld) (cond ((null addr) geneqv) (t (let ((child-geneqv0 (nth (1- (car addr)) (geneqv-lst (ffn-symb term) geneqv ens wrld)))) (mv-let (deep-pequiv-lst shallow-pequiv-lst) (pequivs-for-rewrite-args (ffn-symb term) geneqv pequiv-info wrld ens) (mv-let (pre-rev cur/post) (split-at-position (car addr) (fargs term) nil) (mv-let (child-geneqv child-pequiv-info) (geneqv-and-pequiv-info-for-rewrite (ffn-symb term) (car addr) pre-rev cur/post nil geneqv child-geneqv0 deep-pequiv-lst shallow-pequiv-lst wrld) (geneqv-at-subterm (car cur/post) (cdr addr) child-geneqv child-pequiv-info ens wrld))))))))
geneqv-at-subterm-topfunction
(defun geneqv-at-subterm-top (term addr ens wrld) (geneqv-at-subterm term addr *geneqv-iff* nil ens wrld))
maybe-truncate-current-addressfunction
(defun maybe-truncate-current-address (addr term orig-addr acc state) (declare (xargs :guard (true-listp addr))) (if addr (cond ((variablep term) (mv (er hard 'maybe-truncate-current-address "Found variable with non-NIL address!") state)) ((fquotep term) (let ((new-addr (reverse acc))) (pprogn (io? proof-builder nil state (new-addr orig-addr) (fms0 "~|NOTE: truncating current address from ~x0 to ~ ~x1. See explanation at end of help for X ~ command.~|" (list (cons #\0 orig-addr) (cons #\1 new-addr)) 0 nil)) (mv new-addr state)))) (t (maybe-truncate-current-address (cdr addr) (nth (1- (car addr)) (fargs term)) orig-addr (cons (car addr) acc) state))) (mv (reverse acc) state)))
deposit-term-in-goalfunction
(defun deposit-term-in-goal (given-goal conc current-addr new-term state) (let ((new-conc (deposit-term conc current-addr new-term))) (if (quotep new-term) (mv-let (new-current-addr state) (maybe-truncate-current-address current-addr new-conc current-addr nil state) (mv (change goal given-goal :conc new-conc :current-addr new-current-addr) state)) (mv (change goal given-goal :conc new-conc) state))))
split-impliesfunction
(defun split-implies (term) (if (not (ffn-symb-p term 'implies)) (mv nil term) (mv-let (h c) (split-implies (fargn term 2)) (mv (append (flatten-ands-in-lit (fargn term 1)) h) c))))
find-equivalence-hyp-termfunction
(defun find-equivalence-hyp-term (term hyps target equiv w) (if (consp hyps) (mv-let (h c) (split-implies (car hyps)) (if (or (variablep c) (fquotep c) (not (symbolp (ffn-symb c))) (not (refinementp (ffn-symb c) equiv w))) (find-equivalence-hyp-term term (cdr hyps) target equiv w) (let ((x (fargn c 1)) (y (fargn c 2))) (or (and (subsetp-equal h hyps) (or (and (equal x term) (equal y target)) (and (equal y term) (equal x target)))) (find-equivalence-hyp-term term (cdr hyps) target equiv w))))) nil))
other
(define-pc-primitive equiv (x y &optional equiv) (mv-let (current-term governors) (fetch-term-and-cl conc current-addr nil) (cond ((eq governors t) (mv (er hard ':= "Found governors of T inside command ~x0!" (cons := args)) state)) (t (let* ((assumptions (append hyps governors)) (w (w state)) (pc-ens (make-pc-ens pc-ens state))) (mv-let (erp new-pc-state state) (er-let* ((old (trans0 x abbreviations :equiv)) (new (trans0 y abbreviations :equiv)) (equiv (if (null equiv) (value 'equal) (if (and (symbolp equiv) (equivalence-relationp equiv w)) (value equiv) (er soft :equiv "The name ~x0 is not currently the name of an ACL2 ~ equivalence relation.~@1 The current list of ~ ACL2 equivalence relations is ~x2." equiv (let ((pair (and (symbolp equiv) (assoc-eq equiv (table-alist 'macro-aliases-table w))))) (if (and pair (equivalence-relationp (cdr pair) w)) (msg " Perhaps you intended the corresponding ~ function for which it is an ~ ``alias''(see :DOC macro-aliases-table), ~ ~x0." (cdr pair)) "")) (getpropc 'equal 'coarsenings nil w)))))) (if (find-equivalence-hyp-term old (flatten-ands-in-lit-lst assumptions) new equiv w) (mv-let (hitp new-current-term new-ttree) (subst-equiv-expr1 equiv new old (geneqv-at-subterm-top conc current-addr pc-ens w) current-term pc-ens w state nil) (if hitp (mv-let (new-goal state) (deposit-term-in-goal (car goals) conc current-addr new-current-term state) (value (change-pc-state pc-state :local-tag-tree new-ttree :goals (cons new-goal (cdr goals))))) (pprogn (print-no-change "The equivalence relation that you specified, namely ~x0, is ~ not appropriate at any occurrence of the ``old'' term ~x1 ~ inside the current term, and hence no substitution has ~ been made." (list (cons #\0 equiv) (cons #\1 x))) (value nil)))) (pprogn (print-no-change "The ~#2~[equivalence~/equality~] of the terms ~x0 and ~x1~#2~[ with respect ~ to the equivalence relation ~x3~/~] is not known at the ~ current subterm from the current hypotheses and governors." (list (cons #\0 x) (cons #\1 y) (cons #\2 (if (eq equiv 'equal) 1 0)) (cons #\3 equiv))) (value nil)))) (if erp (print-no-change2 "EQUIV failed.") (mv new-pc-state state))))))))
other
(define-pc-primitive casesplit (expr &optional use-hyps-flag do-not-flatten-flag) (mv-let (erp term state) (trans0 expr abbreviations :casesplit) (if erp (print-no-change2 "~x0 failed." (list (cons #\0 (cons :casesplit args)))) (let ((claimed-term (if use-hyps-flag (mv-let (current-term governors) (fetch-term-and-cl conc current-addr nil) (declare (ignore current-term)) (cond ((eq governors t) (er hard ':casesplit "Found governors of T inside command ~x0!" (cons :casesplit args))) (governors (fcons-term* 'implies (conjoin governors) term)) (t term))) term))) (mv (change-pc-state pc-state :goals (cons (change goal (car goals) :hyps (append hyps (if do-not-flatten-flag (list claimed-term) (flatten-ands-in-lit claimed-term))) :depends-on (1+ depends-on)) (cons (change goal (car goals) :hyps (append hyps (if do-not-flatten-flag (list (dumb-negate-lit claimed-term)) (flatten-ands-in-lit (dumb-negate-lit claimed-term)))) :goal-name (cons goal-name depends-on) :depends-on 1) (cdr goals)))) state)))))
other
(define-pc-macro top? nil (when-goals-trip (if (current-addr t) (value 'top) (value 'skip))))
other
(define-pc-macro contrapose-last nil (when-goals-trip (let ((hyps (hyps))) (if (null hyps) (pprogn (print-no-change "CONTRAPOSE-LAST failed -- no top-level hypotheses!") (value :fail)) (value (list :contrapose (length hyps)))))))
other
(define-pc-macro drop-last nil (when-goals-trip (let ((hyps (hyps))) (if (null hyps) (pprogn (print-no-change "DROP-LAST failed -- no top-level hypotheses!") (value :fail)) (value (list :drop (length hyps)))))))
other
(define-pc-macro drop-conc nil (value `(do-strict top? contrapose-last drop-last)))
other
(define-pc-atomic-macro claim (expr &rest rest-args) (when-goals-trip (value (let ((rest-args-1 (if (and rest-args (car rest-args) (not (keywordp (car rest-args)))) (list* :hints :none (cdr rest-args)) rest-args))) (mv-let (pairs remaining-rest-args) (pair-keywords '(:do-not-flatten) rest-args-1) (let ((do-not-flatten-flag (cdr (assoc-eq :do-not-flatten pairs))) (temp (cadr (member-eq :hints rest-args-1)))) (if (and temp (atom temp)) `(protect (casesplit ,EXPR nil ,DO-NOT-FLATTEN-FLAG) change-goal drop-conc pro change-goal) `(protect (casesplit ,EXPR nil ,DO-NOT-FLATTEN-FLAG) change-goal drop-conc (prove ,@REMAINING-REST-ARGS)))))))))
other
(define-pc-atomic-macro induct (&optional raw-term) (when-goals-trip (if (and (goals t) (current-addr t)) (pprogn (print-no-change "You must be at the top of the goal in order to use the ~ INDUCT command. Try TOP first.") (value :fail)) (let ((raw-term (or raw-term t))) (value `(prove :hints (("Goal" :induct ,RAW-TERM :do-not-induct proof-builder :do-not *do-not-processes*))))))))
print-on-separate-linesfunction
(defun print-on-separate-lines (vals evisc-tuple chan state) (declare (xargs :guard (true-listp vals))) (if (null vals) (newline chan state) (pprogn (io? proof-builder nil state (evisc-tuple chan vals) (fms "~x0" (list (cons #\0 (car vals))) chan state evisc-tuple)) (print-on-separate-lines (cdr vals) evisc-tuple chan state))))
other
(define-pc-help goals nil (io? proof-builder nil state (state-stack) (when-goals (print-on-separate-lines (goal-names (goals t)) nil (proofs-co state) state))))
modified-error-triple-for-sequencefunction
(defun modified-error-triple-for-sequence (erp val success-expr state) (mv-let (new-erp stobjs-out-and-vals state) (state-global-let* ((pc-erp erp) (pc-val val)) (trans-eval-default-warning success-expr :sequence state t)) (let ((stobjs-out (car stobjs-out-and-vals)) (vals (cdr stobjs-out-and-vals))) (if new-erp (mv new-erp nil state) (if (or (< (length stobjs-out) 2) (car stobjs-out) (cadr stobjs-out)) (pprogn (io? proof-builder nil state (vals success-expr) (fms0 "~|WARNING -- evaluation of ~ `success-expr' argument to ~ :SEQUENCE, ~x0, has been ~ ignored because it returned a ~ single-threaded object in one ~ of its first two values or ~ returned fewer than two values. ~ The value(s) returned was ~ (were):~%~ ~ ~x1.~%" (list (cons #\0 success-expr) (cons #\1 vals)))) (mv erp val state)) (mv (car vals) (cadr vals) state))))))
other
(define-pc-meta sequence (instr-list &optional strict-flg protect-flg success-expr no-prompt-flg no-restore-flg) (if (not (true-listp instr-list)) (pprogn (print-no-change "The first argument to the SEQUENCE command must be ~ a true list, but~%~ ~ ~x0~| is not." (list (cons #\0 instr-list))) (mv t nil state)) (state-global-let* ((pc-info (change pc-info (f-get-global 'pc-info state) :prompt (string-append (pc-prompt-depth-prefix) (pc-prompt))))) (let ((saved-old-ss (old-ss)) (saved-ss (state-stack))) (mv-let (erp val state) (pc-main-loop instr-list (if strict-flg '(signal value) '(signal)) t (and (null no-prompt-flg) (pc-print-prompt-and-instr-flg)) state) (mv-let (erp val state) (if success-expr (modified-error-triple-for-sequence erp val success-expr state) (mv erp val state)) (if (and protect-flg (or erp (null val))) (pprogn (print-no-change "SEQUENCE failed, with protection on. ~ Reverting back to existing state of the ~ proof-builder.~|") (pc-assign state-stack saved-ss) (pc-assign old-ss saved-old-ss) (mv erp val state)) (pprogn (if no-restore-flg state (pc-assign old-ss saved-ss)) (mv erp val state)))))))))
other
(define-pc-macro negate (&rest instr-list) (value (list :sequence instr-list nil nil '(mv nil (if (or (f-get-global 'pc-erp state) (null (f-get-global 'pc-val state))) t nil)))))
other
(define-pc-macro succeed (&rest instr-list) (mv nil (list :sequence instr-list nil nil '(mv nil t)) state))
other
(define-pc-macro do-all (&rest instr-list) (mv nil (list :sequence instr-list) state))
other
(define-pc-macro do-strict (&rest instr-list) (mv nil (list :sequence instr-list t) state))
other
(define-pc-macro do-all-no-prompt (&rest instr-list) (mv nil (list :sequence instr-list nil nil nil t t) state))
other
(define-pc-macro th (&optional hyps-indices govs-indices) (declare (ignore hyps-indices govs-indices)) (when-goals-trip (value `(do-all-no-prompt (hyps ,@ARGS) (lisp (io? proof-builder nil state nil (fms0 "~%The current subterm is:~%"))) p))))
other
(define-pc-macro protect (&rest instr-list) (mv nil (list :sequence instr-list t t) state))
extract-goalfunction
(defun extract-goal (name goals) (if (consp goals) (if (equal (access goal (car goals) :goal-name) name) (mv (car goals) (cdr goals)) (mv-let (goal rest-goals) (extract-goal name (cdr goals)) (mv goal (cons (car goals) rest-goals)))) (mv nil goals)))
other
(define-pc-primitive change-goal (&optional name end-flg) (cond ((null goals) (pprogn (print-all-goals-proved-message state) (mv nil state))) ((null (cdr goals)) (print-no-change2 "The current goal is the only unproved goal.")) ((null name) (pprogn (io? proof-builder nil state (goals) (fms0 "~|Now proving ~X0n.~%" (list (cons #\0 (access goal (cadr goals) :goal-name)) (cons #\n nil)))) (mv (change-pc-state pc-state :goals (if end-flg (cons (cadr goals) (append (cddr goals) (list (car goals)))) (list* (cadr goals) (car goals) (cddr goals)))) state))) ((equal name goal-name) (print-no-change2 "The current goal is already ~x0." (list (cons #\0 name)))) (t (mv-let (gl rest-goals) (extract-goal name (cdr goals)) (if gl (mv (change-pc-state pc-state :goals (if end-flg (cons gl (append rest-goals (list (car goals)))) (cons gl (cons (car goals) rest-goals)))) state) (print-no-change2 "There is no unproved goal named ~x0." (list (cons #\0 name))))))))
other
(define-pc-macro cg (&optional name) (value `(change-goal ,NAME t)))
change-by-positionfunction
(defun change-by-position (lst index new) (declare (xargs :guard (and (true-listp lst) (integerp index) (<= 0 index) (< index (length lst))))) (if (equal index 0) (cons new (cdr lst)) (cons (car lst) (change-by-position (cdr lst) (1- index) new))))
other
(define-pc-primitive contrapose (&optional n) (let ((n (if args n 1))) (if hyps (if current-addr (print-no-change2 "You must be at the top of the conclusion to apply ~ the CONTRAPOSE command. Try TOP first.") (if (and (integerp n) (< 0 n) (<= n (length hyps))) (mv (change-pc-state pc-state :goals (cons (change goal (car goals) :hyps (change-by-position hyps (1- n) (dumb-negate-lit conc)) :conc (dumb-negate-lit (nth (1- n) hyps))) (cdr goals))) state) (print-no-change2 "The argument to CONTRAPOSE must be a positive integer ~ that does not exceed the length of the list of top-level ~ hypotheses. The argument ~x0 fails to meet this requirement." (list (cons #\0 n))))) (print-no-change2 "There are no top-level hypotheses."))))
other
(define-pc-macro contradict (&optional n) (declare (ignore n)) (value (cons :contrapose args)))
other
(define-pc-atomic-macro pro nil (value '(quiet (repeat promote))))
other
(define-pc-atomic-macro nx nil (when-goals-trip (let ((current-addr (current-addr t))) (if current-addr (value `(protect up ,(1+ (CAR (LAST CURRENT-ADDR))))) (pprogn (print-no-change "NX failed: already at the top!") (value :fail))))))
other
(define-pc-atomic-macro bk nil (when-goals-trip (let ((current-addr (current-addr t))) (if current-addr (let ((n (car (last current-addr)))) (if (equal n 1) (pprogn (print-no-change "BK failed: already at the first argument!") (value :fail)) (value `(do-strict up ,(1- N))))) (pprogn (print-no-change "BK failed: already at the top!") (value :fail))))))
other
(define-pc-help p-top nil (when-goals (let ((conc (conc t)) (current-addr (current-addr t)) (stars (intern$ "***" (f-get-global 'current-package state)))) (io? proof-builder nil state (state-stack current-addr conc stars) (fms0 "~|~y0~|" (list (cons #\0 (untrans0 (deposit-term conc current-addr (list stars (fetch-term conc current-addr) stars)) t (abbreviations t)))))))))
other
(define-pc-macro repeat (instr) (value `(succeed (repeat-rec ,INSTR))))
other
(define-pc-macro repeat-rec (instr) (value `(do-strict ,INSTR (repeat-rec ,INSTR))))
define-pc-bind*macro
(defmacro define-pc-bind* (name &rest args) `(define-pc-meta ,NAME (&rest instr-list) (state-global-let* (,@ARGS) (pc-main-loop instr-list nil t (pc-print-prompt-and-instr-flg) state))))
other
(define-pc-bind* quiet (inhibit-output-lst (union-eq '(prove proof-builder proof-tree warning observation) (f-get-global 'inhibit-output-lst state))))
other
(define-pc-bind* quiet! (print-clause-ids nil) (gag-mode nil) (inhibit-output-lst (if (member-eq 'error (f-get-global 'inhibit-output-lst state)) *valid-output-names* (set-difference-eq *valid-output-names* '(error)))))
other
(define-pc-bind* noise (gag-mode nil) (inhibit-output-lst '(proof-tree)))
other
(define-pc-bind* noise! (gag-mode nil) (inhibit-output-lst nil))
find-equivalence-hyp-term-no-targetfunction
(defun find-equivalence-hyp-term-no-target (index term hyps equiv w) (if (consp hyps) (mv-let (h c) (split-implies (car hyps)) (if (or (variablep c) (fquotep c) (not (symbolp (ffn-symb c))) (not (refinementp (ffn-symb c) equiv w))) (find-equivalence-hyp-term-no-target (1+ index) term (cdr hyps) equiv w) (let* ((x (fargn c 1)) (y (fargn c 2)) (hyp-to-use (and (subsetp-equal h hyps) (or (and (equal x term) y) (and (equal y term) x))))) (if hyp-to-use (mv index hyp-to-use) (find-equivalence-hyp-term-no-target (1+ index) term (cdr hyps) equiv w))))) (mv nil nil)))
other
(define-pc-atomic-macro if-not-proved (goal-name cmd) (if (member-equal goal-name (goal-names (goals t))) (if (equal goal-name (goal-name t)) (value cmd) (mv-let (erp val state) (er soft 'if-not-proved "The proof-builder's atomic macro IF-NOT-PROVED requires the ~ indicated goal to be the current goal. However, the current ~ goal is ~p0 while the first argument to IF-NOT-PROVED is ~p1." (goal-name t) goal-name) (declare (ignore erp val)) (value 'fail))) (value :skip)))
other
(define-pc-atomic-macro = (&optional x y &rest rest-args) (when-goals-trip (let ((conc (conc t)) (hyps (hyps t)) (current-addr (current-addr t)) (abbreviations (abbreviations t)) (w (w state)) (rest-args-1 (if (and rest-args (car rest-args) (not (keywordp (car rest-args)))) (append '(:hints :none) (cdr rest-args)) rest-args))) (if (not (keyword-value-listp rest-args-1)) (pprogn (print-no-change "The ``rest-args'' arguments for the = command should be ~ empty or a list, either (i) containing one element, an ~ atom, or else (ii) of even length with keywords in the odd ~ positions. Thus your command ~p0 is not legal. See the ~ documentation for examples and details." (list (cons #\0 (make-pretty-pc-instr (cons := args))))) (value :fail)) (mv-let (equiv-alist rest-args-1) (if (keyword-value-listp rest-args-1) (pair-keywords '(:equiv) rest-args-1) (mv nil rest-args-1)) (let ((equiv (or (cdr (assoc-eq :equiv equiv-alist)) 'equal))) (mv-let (current-term governors) (fetch-term-and-cl conc current-addr nil) (cond ((eq governors t) (value (er hard ':= "Found governors of T inside command ~p0!" (cons := args)))) ((eq x :&) (pprogn (print-no-change "We do not allow the first argument of the = command ~ to be the keyword :&, because no other symbol with ~ print-name & can be a term (and hence we use it to ~ represent the current subterm), but :& is a ~ legitimate term and -- we can't be really sure ~ whether you intended it to represent the term :& or ~ the current subterm.") (value :fail))) ((not (member-eq equiv (getpropc 'equal 'coarsenings nil w))) (pprogn (print-no-change "The ``equivalence relation'' that you supplied, ~p0, is not ~ known to ACL2 as an equivalence relation.~@1" (list (cons #\0 equiv) (cons #\1 (let ((pair (and (symbolp equiv) (assoc-eq equiv (table-alist 'macro-aliases-table w))))) (if (and pair (equivalence-relationp (cdr pair) w)) (msg " Perhaps you intended the ~ corresponding function for which it ~ is an ``alias''(see :DOC ~ macro-aliases-table), ~x0." (cdr pair)) ""))))) (value :fail))) ((null args) (mv-let (found-hyp new) (find-equivalence-hyp-term-no-target 1 current-term (flatten-ands-in-lit-lst (append hyps governors)) equiv w) (if found-hyp (pprogn (io? proof-builder nil state (found-hyp) (fms0 "Using hypothesis #~x0.~%" (list (cons #\0 found-hyp)))) (value (list :equiv current-term new))) (pprogn (print-no-change "There is no hypothesis or governor that equates ~ the current term ~#0~[under the equivalence ~ relation ~p1 ~/~]with anything." (list (cons #\0 (if (eq equiv 'equal) 1 0)) (cons #\1 equiv))) (value :fail))))) (t (mv-let (rest-args-alist tail) (pair-keywords '(:otf-flg :hints) rest-args-1) (declare (ignore rest-args-alist)) (if tail (pprogn (print-no-change "The only keywords allowed in the arguments to the = ~ command are :otf-flg, :hints, and :equiv. Your ~ instruction ~p1 violates this requirement." (list (cons #\1 (make-pretty-pc-instr (cons := args))))) (value :fail)) (er-let* ((old (if (or (null (cdr args)) (and (symbolp x) (eq (intern-in-keyword-package x) :&))) (value current-term) (trans0 x abbreviations ':=))) (new (if (null (cdr args)) (trans0 x abbreviations ':=) (trans0 y abbreviations ':=)))) (value (list :protect (list* :claim (if governors (fcons-term* 'implies (conjoin governors) (list equiv old new)) (list equiv old new)) :do-not-flatten t rest-args-1) (list :equiv old new equiv) (list :if-not-proved (goal-name t) :drop-last)))))))))))))))
other
(define-pc-macro set-success (instr form) (value `(sequence (,INSTR) nil nil ,FORM)))
other
(define-pc-macro orelse (instr1 instr2) (value `(negate (do-strict (negate ,INSTR1) (negate ,INSTR2)))))
applicable-rewrite-rulesfunction
(defun applicable-rewrite-rules (current-term conc current-addr target-name-or-rune target-index ens wrld) (declare (xargs :guard (not (or (variablep current-term) (fquotep current-term) (flambdap (ffn-symb current-term)))))) (applicable-rewrite-rules1 current-term (geneqv-at-subterm-top conc current-addr ens wrld) (getpropc (ffn-symb current-term) 'lemmas nil wrld) 1 target-name-or-rune target-index wrld))
other
(define-pc-help show-rewrites (&optional rule-id enabled-only-flg) (when-goals (let ((conc (conc t)) (current-addr (current-addr t)) (w (w state))) (let ((ens (make-pc-ens (pc-ens t) state)) (current-term (fetch-term conc current-addr)) (abbreviations (abbreviations t)) (term-id-iff (term-id-iff conc current-addr t)) (all-hyps (union-equal (hyps t) (governors conc current-addr)))) (show-rewrites-linears-fn 'show-rewrites rule-id enabled-only-flg ens current-term abbreviations term-id-iff all-hyps (geneqv-at-subterm-top conc current-addr ens w) nil state)))))
other
(define-pc-macro sr (&rest args) (value (cons :show-rewrites args)))
other
(define-pc-help show-linears (&optional rule-id enabled-only-flg) (when-goals (let ((conc (conc t)) (current-addr (current-addr t)) (w (w state))) (let ((ens (make-pc-ens (pc-ens t) state)) (current-term (fetch-term conc current-addr)) (abbreviations (abbreviations t)) (term-id-iff (term-id-iff conc current-addr t)) (all-hyps (union-equal (hyps t) (governors conc current-addr)))) (show-rewrites-linears-fn 'show-linears rule-id enabled-only-flg ens current-term abbreviations term-id-iff all-hyps (geneqv-at-subterm-top conc current-addr ens w) nil state)))))
other
(define-pc-macro sls (&rest args) (value (cons :show-linears args)))
other
(define-pc-macro pl (&optional x) (cond (x (value `(lisp (pl ',X)))) ((null (goals)) (pprogn (print-all-goals-proved-message state) (value 'skip))) (t (let* ((conc (conc t)) (current-addr (current-addr t)) (current-term (fetch-term conc current-addr))) (cond ((or (variablep current-term) (fquotep current-term) (flambda-applicationp current-term)) (er soft 'pl "The current subterm is not the application of a ~ function symbol.")) (t (value `(lisp (pl ',(FFN-SYMB CURRENT-TERM))))))))))
other
(define-pc-macro pr (&optional x) (cond (x (value `(lisp (pr ',X)))) ((null (goals)) (pprogn (print-all-goals-proved-message state) (value 'skip))) (t (let* ((conc (conc t)) (current-addr (current-addr t)) (current-term (fetch-term conc current-addr))) (cond ((or (variablep current-term) (fquotep current-term) (flambda-applicationp current-term)) (er soft 'pr "The current subterm is not the application of a ~ function symbol.")) (t (value `(lisp (pr ',(FFN-SYMB CURRENT-TERM))))))))))
other
(define-pc-help show-type-prescriptions (&optional rule-id) (when-goals (let ((conc (conc t)) (current-addr (current-addr t))) (let ((ens (make-pc-ens (pc-ens t) state)) (current-term (fetch-term conc current-addr)) (abbreviations (abbreviations t)) (all-hyps (union-equal (hyps t) (governors conc current-addr)))) (show-type-prescription-rules current-term rule-id abbreviations all-hyps ens state)))))
other
(define-pc-macro st (&rest args) (value (cons :show-type-prescriptions args)))
translate-subst-abb1function
(defun translate-subst-abb1 (sub abbreviations state) (declare (xargs :guard (symbol-alistp sub))) (if (consp sub) (mv-let (erp term state) (trans0 (cadar sub) abbreviations 'translate-subst-abb1) (if erp (mv "~|Translation error for ~x0 caused error in ~ translating ~xs.~|" (list (cons #\0 (cadar sub))) state) (mv-let (erp val state) (translate-subst-abb1 (cdr sub) abbreviations state) (if erp (mv erp val state) (mv nil (cons (cons (caar sub) term) val) state))))) (mv nil nil state)))
single-valued-symbolp-alistpfunction
(defun single-valued-symbolp-alistp (alist) (declare (xargs :guard (symbol-alistp alist))) (if alist (and (not (assoc-eq (caar alist) (cdr alist))) (single-valued-symbolp-alistp (cdr alist))) t))
check-cars-are-variablesfunction
(defun check-cars-are-variables (alist state) (declare (xargs :guard (symbol-alistp alist))) (if alist (mv-let (erp val state) (trans0 (caar alist) nil) (if (or erp (not (eq val (caar alist)))) (pprogn (io? proof-builder nil state (alist) (fms0 "~|A substitution must be an alist whose CARs ~ are variables, but the entry ~x0 violates this ~ property.~|" (list (cons #\0 (caar alist))))) (mv t state)) (check-cars-are-variables (cdr alist) state))) (mv nil state)))
translate-subst-abbfunction
(defun translate-subst-abb (sub abbreviations state) (cond ((not (true-listp sub)) (pprogn (io? proof-builder nil state (sub) (fms0 "~|A substitution must be a true (nil-terminated) ~ list, but~%~x0 is not.~|" (list (cons #\0 sub)))) (mv t nil state))) ((not (and (symbol-alistp sub) (single-valued-symbolp-alistp sub))) (pprogn (io? proof-builder nil state (sub) (fms0 "~|A substitution must be an alist of pairs without ~ duplicate keys, but ~x0 is not.~|" (list (cons #\0 sub)))) (mv t nil state))) (t (mv-let (erp state) (check-cars-are-variables sub state) (if erp (mv t nil state) (mv-let (erp val state) (translate-subst-abb1 sub abbreviations state) (if erp (pprogn (io? proof-builder nil state (val sub erp) (fms0 erp (cons (cons #\s sub) val))) (mv t nil state)) (mv nil val state))))))))
make-rewrite-instrfunction
(defun make-rewrite-instr (lemma-id raw-subst instantiate-free) (list* (make-pretty-pc-command :rewrite) lemma-id (cond (instantiate-free (list raw-subst instantiate-free)) (raw-subst (list raw-subst)) (t nil))))
other
(define-pc-primitive rewrite (&optional rule-id raw-sub instantiate-free) (mv-let (erp sub state) (translate-subst-abb raw-sub abbreviations state) (if erp (print-no-change2 "~x0 failed." (list (cons #\0 (cons :rewrite args)))) (let ((name (and (symbolp rule-id) rule-id)) (rune (and (consp rule-id) (member-eq (car rule-id) '(:rewrite :definition)) rule-id)) (index (if (and (integerp rule-id) (< 0 rule-id)) rule-id (if rule-id nil 1))) (pc-ens (make-pc-ens pc-ens state)) (w (w state)) (current-term (fetch-term conc current-addr)) (assumptions (union-equal hyps (governors conc current-addr)))) (cond ((or (variablep current-term) (fquotep current-term) (flambdap (ffn-symb current-term))) (print-no-change2 "It is only possible to apply rewrite rules to terms that are not ~ variables, (quoted) constants, or applications of lambda ~ expressions. However, the current term is:~%~ ~ ~y0.~|" (list (cons #\0 current-term)))) ((not (or name index rune)) (print-no-change2 "The rule-id argument to REWRITE must be a name, a positive ~ integer, or a :rewrite or :definition rune, but ~x0 is none of ~ these.~|" (list (cons #\0 rule-id)))) (t (mv-let (flg hyps-type-alist ttree) (hyps-type-alist assumptions pc-ens w state) (declare (ignore ttree)) (if flg (print-no-change2 "Contradiction in the hypotheses!~%The S command should ~ complete this goal.~|") (let ((app-rewrite-rules (applicable-rewrite-rules current-term conc current-addr (or name rune) index pc-ens w))) (if (null app-rewrite-rules) (if (and index (> index 1)) (print-no-change2 "There are fewer than ~x0 applicable rewrite rules.~%" (list (cons #\0 index))) (print-no-change2 "There are no applicable rewrite rules.~%")) (let* ((sar (car app-rewrite-rules)) (lemma (access sar sar :lemma)) (start-alist (access sar sar :alist)) (alist (append start-alist sub)) (rhs (access rewrite-rule lemma :rhs)) (lemma-hyps (access rewrite-rule lemma :hyps)) (lemma-rune (access rewrite-rule lemma :rune)) (lemma-name (base-symbol lemma-rune)) (lemma-id (if (cddr lemma-rune) lemma-rune lemma-name)) (non-free (union-eq (intersection-domains sub start-alist) (set-difference-eq (strip-cars sub) (append (all-vars rhs) (all-vars1-lst lemma-hyps nil)))))) (if non-free (print-no-change2 "The variable~#0~[~/~/s~] ~&1 supplied by the ~ substitution in this instruction ~#0~[~/is~/are~] not ~ free for instantiation in the current context.~|" (list (cons #\0 (zero-one-or-more (length non-free))) (cons #\1 non-free))) (mv-let (subst-hyps unify-subst ttree2) (unrelieved-hyps lemma-rune lemma-hyps alist hyps-type-alist instantiate-free w state pc-ens nil) (pprogn (let ((extra-alist (alist-difference-eq unify-subst alist))) (if extra-alist (io? proof-builder nil state (abbreviations extra-alist sub lemma-id) (fms0 "~|Rewriting with ~x0 under the ~ following extension of the ~ substitution generated by matching ~ that rewrite rule with the current ~ term~#1~[ (after extending it with ~ the substitution ~x2 supplied in the ~ instruction)~/~]:~|~x3.~|" (list (cons #\0 lemma-id) (cons #\1 (if sub 0 1)) (cons #\2 sub) (cons #\3 (untranslate-subst-abb extra-alist abbreviations state))))) (io? proof-builder nil state (lemma-id) (fms0 "~|Rewriting with ~x0.~|" (list (cons #\0 lemma-id)))))) (let ((runes (all-runes-in-ttree ttree2 nil))) (if runes (io? proof-builder nil state (runes) (fms0 "~|--NOTE-- Using the following runes ~ in addition to the indicated rule:~% ~ ~x0.~|" (list (cons #\0 runes)))) state)) (let ((new-goals (make-new-goals-fixed-hyps subst-hyps assumptions goal-name depends-on))) (mv-let (changed-goal state) (deposit-term-in-goal (car goals) conc current-addr (sublis-var unify-subst (access rewrite-rule lemma :rhs)) state) (mv (change-pc-state pc-state :instruction (make-rewrite-instr lemma-id raw-sub instantiate-free) :goals (cons (change goal changed-goal :depends-on (+ depends-on (length new-goals))) (append new-goals (cdr goals))) :local-tag-tree (push-lemma lemma-rune ttree2)) state)))))))))))))))))
applicable-linear-rulesfunction
(defun applicable-linear-rules (current-term target-name-or-rune target-index wrld) (declare (xargs :guard (not (or (variablep current-term) (fquotep current-term) (flambdap (ffn-symb current-term)))))) (applicable-linear-rules1 current-term (getpropc (ffn-symb current-term) 'linear-lemmas nil wrld) 1 target-name-or-rune target-index))
make-linear-instrfunction
(defun make-linear-instr (lemma-id raw-subst instantiate-free) (list* (make-pretty-pc-command :apply-linear) lemma-id (cond (instantiate-free (list raw-subst instantiate-free)) (raw-subst (list raw-subst)) (t nil))))
other
(define-pc-primitive apply-linear (&optional rule-id raw-sub instantiate-free) (mv-let (erp sub state) (translate-subst-abb raw-sub abbreviations state) (if erp (print-no-change2 "~x0 failed." (list (cons #\0 (cons :rewrite args)))) (let ((name (and (symbolp rule-id) rule-id)) (rune (and (consp rule-id) (member-eq (car rule-id) '(:linear)) rule-id)) (index (if (and (integerp rule-id) (< 0 rule-id)) rule-id (if rule-id nil 1))) (pc-ens (make-pc-ens pc-ens state)) (w (w state)) (current-term (fetch-term conc current-addr)) (assumptions (union-equal hyps (governors conc current-addr)))) (cond ((or (variablep current-term) (fquotep current-term) (flambdap (ffn-symb current-term))) (print-no-change2 "It is only possible to apply linear rules to terms that are not ~ variables, (quoted) constants, or applications of lambda ~ expressions. However, the current term is:~%~ ~ ~y0.~|" (list (cons #\0 current-term)))) ((not (or name index rune)) (print-no-change2 "The rule-id argument to REWRITE must be a name, a positive ~ integer, or a :linear rune, but ~x0 is none of these.~|" (list (cons #\0 rule-id)))) (t (mv-let (flg hyps-type-alist ttree) (hyps-type-alist assumptions pc-ens w state) (declare (ignore ttree)) (if flg (print-no-change2 "Contradiction in the hypotheses!~%The S command should ~ complete this goal.~|") (let ((app-linear-rules (applicable-linear-rules current-term (or name rune) index w))) (if (null app-linear-rules) (if (and index (> index 1)) (print-no-change2 "There are fewer than ~x0 applicable linear rules.~%" (list (cons #\0 index))) (print-no-change2 "There are no applicable linear rules.~%")) (let* ((sar (car app-linear-rules)) (lemma (access sar sar :lemma)) (start-alist (access sar sar :alist)) (alist (append start-alist sub)) (lemma-concl (access linear-lemma lemma :concl)) (lemma-hyps (access linear-lemma lemma :hyps)) (lemma-rune (access linear-lemma lemma :rune)) (lemma-name (base-symbol lemma-rune)) (lemma-id (if (cddr lemma-rune) lemma-rune lemma-name)) (non-free (union-eq (intersection-domains sub start-alist) (set-difference-eq (strip-cars sub) (append (all-vars lemma-concl) (all-vars1-lst lemma-hyps nil)))))) (if non-free (print-no-change2 "The variable~#0~[~/~/s~] ~&1 supplied by the ~ substitution in this instruction ~#0~[~/is~/are~] not ~ free for instantiation in the current context.~|" (list (cons #\0 (zero-one-or-more (length non-free))) (cons #\1 non-free))) (mv-let (subst-hyps unify-subst ttree2) (unrelieved-hyps lemma-rune lemma-hyps alist hyps-type-alist instantiate-free w state pc-ens nil) (pprogn (let ((extra-alist (alist-difference-eq unify-subst alist))) (if extra-alist (io? proof-builder nil state (abbreviations extra-alist sub lemma-id) (fms0 "~|Apply linear rule ~x0 under the ~ following extension of the ~ substitution generated by matching ~ that rule's trigger term with the ~ current term ~#1~[ (after extending ~ it with the substitution ~x2 supplied ~ in the instruction)~/~]: ~x3.~|" (list (cons #\0 lemma-id) (cons #\1 (if sub 0 1)) (cons #\2 sub) (cons #\3 (untranslate-subst-abb extra-alist abbreviations state))))) (io? proof-builder nil state (lemma-id) (fms0 "~|Applying linear rule ~x0.~|" (list (cons #\0 lemma-id)))))) (let ((runes (all-runes-in-ttree ttree2 nil))) (if runes (io? proof-builder nil state (runes) (fms0 "~|--NOTE-- Using the following runes ~ in addition to the indicated rule:~% ~ ~x0.~|" (list (cons #\0 runes)))) state)) (let ((new-goals (make-new-goals-fixed-hyps subst-hyps assumptions goal-name depends-on))) (let ((changed-goal (change goal (car goals) :hyps (append hyps (list (sublis-var unify-subst lemma-concl))) :depends-on (+ depends-on (length new-goals))))) (mv (change-pc-state pc-state :instruction (make-linear-instr lemma-id raw-sub instantiate-free) :goals (cons changed-goal (append new-goals (cdr goals))) :local-tag-tree (push-lemma lemma-rune ttree2)) state)))))))))))))))))
other
(define-pc-macro al (&rest args) (value (cons :apply-linear args)))
other
(define-pc-macro doc (&optional name) (let ((name (or name (make-official-pc-command 'doc)))) (cond ((and (equal (assoc-eq :doc (ld-keyword-aliases state)) '(:doc 1 xdoc)) (function-symbolp 'colon-xdoc-initialized (w state))) (value `(lisp (if (colon-xdoc-initialized state) (xdoc ',NAME) (pprogn (fms0 "Note: Using built-in :doc command. To use ~ :xdoc command, exit the proof-builder and ~ run :doc in the top-level loop.~|~%") (doc ',NAME)))))) (t (value `(lisp (doc ',NAME)))))))
other
(define-pc-macro help (&optional name) (cond ((not (symbolp name)) (pprogn (print-no-change "The argument for :HELP requires a symbol, but ~x0 ~ is not a symbol." (list (cons #\0 name))) (value :fail))) (t (let ((name (if (equal (symbol-name name) "ALL") 'proof-builder-commands (make-official-pc-command (or name 'help))))) (value `(doc ,NAME))))))
pc-rewrite*-1function
(defun pc-rewrite*-1 (term type-alist geneqv iff-flg wrld rcnst old-ttree pot-lst normalize-flg rewrite-flg ens state repeat backchain-limit step-limit) (mv-let (nterm old-ttree) (if normalize-flg (normalize term iff-flg type-alist ens wrld old-ttree (backchain-limit wrld :ts)) (mv term old-ttree)) (sl-let (newterm ttree) (if rewrite-flg (let ((gstack nil)) (rewrite-entry (rewrite nterm nil 'proof-builder) :pequiv-info nil :rdepth (rewrite-stack-limit wrld) :step-limit step-limit :obj '? :fnstack nil :ancestors nil :simplify-clause-pot-lst pot-lst :rcnst (change rewrite-constant rcnst :current-literal (make current-literal :atm nterm :not-flg nil)) :gstack gstack :ttree old-ttree)) (mv 0 nterm old-ttree)) (declare (ignorable step-limit)) (cond ((equal newterm nterm) (mv step-limit newterm old-ttree state)) ((<= repeat 0) (mv step-limit newterm ttree state)) (t (pc-rewrite*-1 newterm type-alist geneqv iff-flg wrld rcnst ttree pot-lst normalize-flg rewrite-flg ens state (1- repeat) backchain-limit step-limit))))))
pc-rewrite*function
(defun pc-rewrite* (term type-alist geneqv iff-flg wrld rcnst old-ttree pot-lst normalize-flg rewrite-flg ens state repeat backchain-limit step-limit) (sl-let (newterm ttree state) (catch-step-limit (pc-rewrite*-1 term type-alist geneqv iff-flg wrld rcnst old-ttree pot-lst normalize-flg rewrite-flg ens state repeat backchain-limit step-limit)) (cond ((eql step-limit -1) (mv step-limit term old-ttree state)) (t (mv step-limit newterm ttree state)))))
make-goals-from-assumptionsfunction
(defun make-goals-from-assumptions (assumptions conc hyps current-addr goal-name start-index) (if assumptions (cons (make goal :conc conc :hyps (cons (dumb-negate-lit (car assumptions)) hyps) :current-addr current-addr :goal-name (cons goal-name start-index) :depends-on 1) (make-goals-from-assumptions (cdr assumptions) conc hyps current-addr goal-name (1+ start-index))) nil))
make-new-goals-from-assumptionsfunction
(defun make-new-goals-from-assumptions (assumptions goal) (and assumptions (make-goals-from-assumptions assumptions (access goal goal :conc) (access goal goal :hyps) (access goal goal :current-addr) (access goal goal :goal-name) (access goal goal :depends-on))))
*default-s-repeat-limit*constant
(defconst *default-s-repeat-limit* 10)
hyps-type-alist-and-pot-lstfunction
(defun hyps-type-alist-and-pot-lst (assumptions rcnst ens wrld state) (mv-let (flg type-alist ttree-or-fc-pair-lst) (hyps-type-alist assumptions ens wrld state) (cond ((or (not rcnst) flg) (mv flg type-alist nil ttree-or-fc-pair-lst)) (t (mv-let (step-limit contradictionp pot-lst) (setup-simplify-clause-pot-lst (dumb-negate-lit-lst assumptions) nil ttree-or-fc-pair-lst type-alist rcnst wrld state *default-step-limit*) (declare (ignore step-limit)) (cond (contradictionp (mv t nil nil (push-lemma *fake-rune-for-linear* (access poly contradictionp :ttree)))) (t (mv nil type-alist pot-lst ttree-or-fc-pair-lst))))))))
other
(define-pc-primitive s (&rest args) (cond ((not (keyword-value-listp args)) (print-no-change2 "The argument list to S must be a KEYWORD-VALUE-LISTP, i.e. a list of ~ the form (:kw-1 val-1 ... :kw-n val-n), where each of the arguments ~ :kw-i is a keyword. Your argument list ~x0 does not have this ~ property. Try (HELP S)." (list (cons #\0 args)))) (t (let ((comm (make-official-pc-command 's)) (w (w state)) (current-term (fetch-term conc current-addr)) (assumptions (union-equal hyps (flatten-ands-in-lit-lst (governors conc current-addr))))) (let ((pc-ens (make-pc-ens pc-ens state))) (mv-let (bcl-alist rst) (pair-keywords '(:backchain-limit :normalize :rewrite :repeat) args) (let* ((local-backchain-limit (or (cdr (assoc-eq :backchain-limit bcl-alist)) 0)) (normalize (let ((pair (assoc-eq :normalize bcl-alist))) (if pair (cdr pair) t))) (rewrite (let ((pair (assoc-eq :rewrite bcl-alist))) (if pair (cdr pair) t))) (linear (let ((pair (assoc-eq :linear bcl-alist))) (if pair (cdr pair) rewrite))) (repeat (let ((pair (assoc-eq :repeat bcl-alist))) (if pair (if (equal (cdr pair) t) *default-s-repeat-limit* (cdr pair)) 0)))) (cond ((not (natp repeat)) (print-no-change2 "The :REPEAT argument provided to S (or a command that invoked ~ S), which was ~x0, is illegal. ~ It must be T or a natural ~ number." (list (cons #\0 repeat)))) ((not (natp local-backchain-limit)) (print-no-change2 "The :BACKCHAIN-LIMIT argument provided to S (or a command ~ that invoked S), which was ~x0, is illegal. It must be NIL ~ or a natural number." (list (cons #\0 local-backchain-limit)))) ((not (or normalize rewrite)) (print-no-change2 "You may not specify in the S command that ~ neither IF normalization nor rewriting is to ~ take place.")) ((and (null rewrite) (or (assoc-eq :backchain-limit bcl-alist) (assoc-eq :repeat bcl-alist) rst)) (print-no-change2 "When the :REWRITE NIL option is specified, ~ it is not allowed to provide arguments other ~ than :NORMALIZE T. The argument list ~x0 ~ violates this requirement." (list (cons #\0 args)))) (t (mv-let (key-alist new-rst) (pair-keywords '(:in-theory :hands-off :expand) rst) (declare (ignore key-alist)) (cond (new-rst (print-no-change2 "The arguments to the S command must all be &KEY ~ arguments, which should be among ~&0. Your argument list ~ ~x1 violates this requirement." (list (cons #\0 '(:rewrite :normalize :backchain-limit :repeat :in-theory :hands-off :expand)) (cons #\1 args)))) (t (mv-let (erp hint-settings state) (translate-hint-settings comm "Goal" rst (if args (cons comm (car args)) comm) w state) (cond (erp (print-no-change2 "S failed.")) (t (let ((base-rcnst (and rewrite (make-rcnst pc-ens w state :force-info t)))) (mv-let (flg hyps-type-alist pot-lst ttree) (hyps-type-alist-and-pot-lst assumptions (and linear base-rcnst) pc-ens w state) (cond (flg (cond ((or (null current-addr) (equal assumptions hyps) (mv-let (flg hyps-type-alist ttree) (hyps-type-alist hyps pc-ens w state) (declare (ignore hyps-type-alist ttree)) flg)) (pprogn (io? proof-builder nil state nil (fms0 "~|Goal proved: Contradiction in ~ the hypotheses!~|")) (mv (change-pc-state pc-state :goals (cond ((tagged-objects 'assumption ttree) (cons (change goal (car goals) :conc *t*) (cdr goals))) (t (cdr goals))) :local-tag-tree ttree) state))) (t (print-no-change2 "A contradiction was found in the current ~ context using both the top-level hypotheses ~ and the IF tests governing the current term, ~ but not using the top-level hypotheses alone. ~ ~ You may want to issue the TOP command and ~ then issue s-prop to prune some branches of ~ the conclusion.")))) (t (mv-let (erp local-rcnst state) (if rewrite (load-hint-settings-into-rcnst hint-settings base-rcnst nil w 's state) (value nil)) (pprogn (if erp (io? proof-builder nil state nil (fms0 "~|Note: Ignoring the above ~ theory invariant error. ~ Proceeding...~|")) state) (if rewrite (maybe-warn-about-theory-from-rcnsts base-rcnst local-rcnst :s pc-ens w state) state) (sl-let (new-term new-ttree state) (pc-rewrite* current-term hyps-type-alist (geneqv-at-subterm-top conc current-addr pc-ens w) (term-id-iff conc current-addr t) w local-rcnst nil pot-lst normalize rewrite pc-ens state repeat local-backchain-limit (initial-step-limit w state)) (pprogn (f-put-global 'last-step-limit step-limit state) (if (equal new-term current-term) (print-no-change2 "No simplification took place.") (pprogn (mv-let (new-goal state) (deposit-term-in-goal (car goals) conc current-addr new-term state) (mv (change-pc-state pc-state :goals (cons new-goal (cdr goals)) :local-tag-tree new-ttree) state)))))))))))))))))))))))))))
build-pc-enabled-structure-from-ensfunction
(defun build-pc-enabled-structure-from-ens (new-suffix ens) (let* ((new-name-root '(#\P #\C #\- #\E #\N #\A #\B #\L #\E #\D #\- #\A #\R #\R #\A #\Y #\-)) (new-name (intern (coerce (append new-name-root (explode-nonnegative-integer new-suffix 10 nil)) 'string) "ACL2")) (old-name (access enabled-structure ens :array-name)) (old-alist (access enabled-structure ens :theory-array))) (change enabled-structure ens :theory-array (cons (list :header :dimensions (dimensions old-name old-alist) :maximum-length (maximum-length old-name old-alist) :default (default old-name old-alist) :name new-name) (cdr old-alist)) :array-name new-name :array-length (access enabled-structure ens :array-length) :array-name-root new-name-root :array-name-suffix new-suffix)))
other
(define-pc-primitive in-theory (&optional theory-expr) (let ((w (w state)) (ens (ens state))) (if args (mv-let (erp hint-setting state) (translate-in-theory-hint theory-expr t 'in-theory w state) (if erp (print-no-change2 "bad theory expression.") (let* ((new-suffix (pc-value next-pc-enabled-array-suffix)) (new-pc-ens1 (build-pc-enabled-structure-from-ens new-suffix ens))) (mv-let (erp new-pc-ens2 state) (load-theory-into-enabled-structure theory-expr hint-setting nil new-pc-ens1 nil nil w 'in-theory state) (cond (erp (print-no-change2 "bad theory expression.")) (t (pprogn (pc-assign next-pc-enabled-array-suffix (1+ new-suffix)) (maybe-warn-about-theory-simple ens new-pc-ens2 :in-theory w state) (mv (change-pc-state pc-state :pc-ens new-pc-ens2) state)))))))) (if (null pc-ens) (print-no-change2 "The proof-builder enabled/disabled state is ~ already set to agree with the global state, so ~ your IN-THEORY command is redundant.") (mv (change-pc-state pc-state :pc-ens nil) state)))))
other
(define-pc-atomic-macro s-prop (&rest names) (value `(s :in-theory ,(IF NAMES `(UNION-THEORIES ',NAMES (THEORY 'MINIMAL-THEORY)) '(THEORY 'MINIMAL-THEORY)))))
other
(define-pc-atomic-macro x (&rest args) (value `(do-strict (expand t) (succeed (s ,@ARGS)))))
other
(define-pc-primitive expand (&optional do-not-expand-lambda-flg) (let ((w (w state)) (term (fetch-term conc current-addr))) (cond ((or (variablep term) (fquotep term)) (print-no-change2 "It is impossible to expand a variable or a constant.")) ((and do-not-expand-lambda-flg (flambdap (ffn-symb term))) (print-no-change2 "Expansion of lambda terms is disabled when do-not-expand-lambda-flg = ~ t; see :DOC acl2-pc::expand.")) (t (let* ((fn (ffn-symb term)) (def-body (and (not (flambdap fn)) (def-body fn w))) (formals (and def-body (access def-body def-body :formals))) (equiv (and def-body (access def-body def-body :equiv))) (body (if (flambdap fn) (lambda-body fn) (and def-body (latest-body (fcons-term fn formals) (access def-body def-body :hyp) (access def-body def-body :concl)))))) (cond ((null body) (assert$ (not (flambdap fn)) (print-no-change2 "Expansion failed. Apparently function ~x0 is ~ constrained, not defined." (list (cons #\0 fn))))) ((and (not (eq equiv 'equal)) (not (flambdap fn)) (not (geneqv-refinementp equiv (geneqv-at-subterm-top conc current-addr (make-pc-ens pc-ens state) w) w))) (print-no-change2 "Expansion failed: the equivalence relation for the definition ~ rule ~x0 is ~x1, which is not sufficient to maintain in the ~ current context." (list (cons #\0 (base-symbol (access def-body def-body :rune))) (cons #\1 equiv)))) (t (let ((new-term (cond (do-not-expand-lambda-flg (fcons-term (make-lambda formals body) (fargs term))) (t (subcor-var (if (flambdap fn) (lambda-formals fn) formals) (fargs term) body))))) (mv-let (new-goal state) (deposit-term-in-goal (car goals) conc current-addr new-term state) (mv (change-pc-state pc-state :goals (cons new-goal (cdr goals)) :local-tag-tree (if (flambdap fn) nil (push-lemma? (access def-body def-body :rune) nil))) state))))))))))
other
(define-pc-atomic-macro x-dumb nil (value `(expand t)))
other
(define-pc-macro bookmark (tag &rest instr-list) (value `(do-all (comment :begin ,TAG) ,@INSTR-LIST (comment :end ,TAG))))
change-lastfunction
(defun change-last (lst val) (if (consp lst) (if (consp (cdr lst)) (cons (car lst) (change-last (cdr lst) val)) (list val)) lst))
assign-event-name-and-rule-classesfunction
(defun assign-event-name-and-rule-classes (event-name rule-classes state) (let* ((state-stack (state-stack)) (triple (event-name-and-types-and-raw-term state-stack)) (old-event-name (car triple)) (old-rule-classes (cadr triple)) (old-raw-term (caddr triple))) (pc-assign state-stack (change-last state-stack (change pc-state (car (last state-stack)) :instruction (list :start (list (or event-name old-event-name) (or rule-classes old-rule-classes) old-raw-term)))))))
save-fnfunction
(defun save-fn (name ss-alist state) (pprogn (assign-event-name-and-rule-classes name nil state) (pc-assign ss-alist (put-assoc-eq name (cons (state-stack) (old-ss)) ss-alist))))
other
(define-pc-macro save (&optional name do-it-flg) (cond ((not (symbolp name)) (pprogn (print-no-change "The first argument supplied to ~x0 must be a symbol, but ~x1 is not a ~ symbol.~@2" (list (cons #\0 :save) (cons #\1 name) (cons #\2 (cond ((and (consp name) (eq (car name) 'quote) (consp (cdr name)) (symbolp (cadr name)) (null (cddr name))) (msg " Perhaps you intended to submit the form ~x0." `(:save ,(CADR NAME) ,@(AND DO-IT-FLG (LIST DO-IT-FLG))))) (t ""))))) (value :fail))) (t (let ((name (or name (car (event-name-and-types-and-raw-term state-stack)))) (ss-alist (ss-alist))) (if name (mv-let (erp reply state) (if (and (assoc-eq name ss-alist) (null do-it-flg)) (acl2-query 'save '("The name ~x0 is already associated with a ~ state-stack. Do you really want to overwrite ~ that existing value?" :y t :n nil) (list (cons #\0 name)) state) (mv nil t state)) (declare (ignore erp)) (if reply (pprogn (save-fn name ss-alist state) (value :succeed)) (pprogn (print-no-change "save aborted.") (value :fail)))) (pprogn (print-no-change "You can't SAVE with no argument, because you didn't ~ originally enter VERIFY using an event name. Try (SAVE ~ <event_name>) instead.") (value :fail)))))))
retrievemacro
(defmacro retrieve (&optional name) `(retrieve-fn ',NAME state))
other
(define-pc-macro retrieve nil (pprogn (print-no-change "RETRIEVE can only be used outside the ~ interactive loop. Please exit first. To ~ save your state upon exit, use EX rather than EXIT.") (value :fail)))
unsave-fnfunction
(defun unsave-fn (name state) (pc-assign ss-alist (remove1-assoc-eq name (ss-alist))))
other
(define-pc-help unsave (&optional name) (let ((name (or name (car (event-name-and-types-and-raw-term state-stack))))) (if (null name) (print-no-change "You must specify a name to UNSAVE, because you didn't ~ originally enter VERIFY using an event name.") (if (assoc-eq name (ss-alist)) (pprogn (unsave-fn name state) (io? proof-builder nil state (name) (fms0 "~|~x0 removed from saved state-stack alist.~%" (list (cons #\0 name))))) (print-no-change "~|~x0 is does not have a value on the saved ~ state-stack alist.~%" (list (cons #\0 name)))))))
show-retrieved-goalfunction
(defun show-retrieved-goal (state-stack state) (let ((raw-term (caddr (event-name-and-types-and-raw-term state-stack)))) (assert$ raw-term (fmt-abbrev "~|~%Resuming proof attempt for~|~y0." (list (cons #\0 raw-term)) 0 (proofs-co state) state "~%"))))
retrieve-fnfunction
(defun retrieve-fn (name state) (let ((ss-alist (ss-alist))) (cond ((f-get-global 'in-verify-flg state) (er soft 'retrieve "You are apparently already inside the VERIFY interactive loop. It is ~ illegal to enter such a loop recursively.")) ((null ss-alist) (pprogn (io? proof-builder nil state nil (fms0 "Sorry -- there is no saved interactive proof to ~ re-enter! Perhaps you meant (VERIFY) rather than ~ (RETRIEVE).~|")) (value :invisible))) ((null name) (if (equal (length ss-alist) 1) (retrieve-fn (caar ss-alist) state) (pprogn (io? proof-builder nil state (ss-alist) (fms0 "Please specify an interactive verification to ~ re-enter. Your options are ~&0.~%(Pick one of the ~ above:) " (list (cons #\0 (strip-cars ss-alist))))) (mv-let (erp val state) (read-object *standard-oi* state) (declare (ignore erp)) (retrieve-fn val state))))) ((not (symbolp name)) (er soft 'retrieve "The argument supplied to ~x0 must be a symbol, but ~x1 is not a ~ symbol.~@2" 'retrieve name (cond ((and (consp name) (eq (car name) 'quote) (consp (cdr name)) (symbolp (cadr name)) (null (cddr name))) (msg " Perhaps you intended to submit the form ~x0." `(retrieve ,(CADR NAME)))) (t "")))) (t (let* ((ss-pair (cdr (assoc-eq name ss-alist))) (saved-ss (car ss-pair)) (saved-old-ss (cdr ss-pair))) (if saved-ss (pprogn (pc-assign old-ss saved-old-ss) (pc-assign state-stack saved-ss) (show-retrieved-goal saved-ss state) (verify)) (pprogn (io? proof-builder nil state (name) (fms0 "~|Sorry -- There is no interactive proof saved ~ under the name ~x0.~|" (list (cons #\0 name)))) (value :invisible))))))))
print-all-goalsfunction
(defun print-all-goals (goals state) (if (null goals) state (pprogn (print-pc-goal (car goals)) (print-all-goals (cdr goals) state))))
other
(define-pc-help print-all-goals nil (print-all-goals (goals t) state))
print-concmacro
(defmacro print-conc (&optional goal) `(let ((goal ,(OR GOAL '(CAR (ACCESS PC-STATE (CAR (STATE-STACK)) :GOALS))))) (io? proof-builder nil state (goal) (if goal (fms0 "~%------- ~x3 -------~|~q0~|" (list (cons #\0 (untranslate (access goal goal :conc) t (w state))) (cons #\3 (access goal goal :goal-name)))) (fms0 "~%No goal in CAR of state-stack.~|")))))
print-all-concsfunction
(defun print-all-concs (goals state) (declare (xargs :mode :program :stobjs state)) (if (null goals) state (pprogn (print-conc (car goals)) (print-all-concs (cdr goals) state))))
other
(define-pc-help print-all-concs nil (print-all-concs (goals t) state))
translate-generalize-alist-1function
(defun translate-generalize-alist-1 (alist state-vars abbreviations state) (cond ((null alist) (value nil)) ((and (true-listp (car alist)) (eql (length (car alist)) 2)) (er-let* ((term (translate-abb (caar alist) abbreviations 'translate-generalize-alist state)) (var (if (gen-var-marker (cadar alist)) (value (cadar alist)) (translate-abb (cadar alist) nil 'translate-generalize-alist state)))) (cond ((member-eq var state-vars) (er soft :generalize "The variable ~x0 already appears in the current goals of ~ the proof-builder state, and hence is not legal as a ~ generalization variable." var)) ((or (variablep var) (gen-var-marker var)) (mv-let (erp val state) (translate-generalize-alist-1 (cdr alist) state-vars abbreviations state) (if erp (mv erp val state) (value (cons (cons term var) val))))) (t (er soft :generalize "The second element of each doublet ~ given to the GENERALIZE command must be a variable or ~ natural number, but ~x0 is neither." (cadar alist)))))) (t (er soft :generalize "Each argument to the GENERALIZE command must be a list of ~ length 2, but ~x0 is not." (car alist)))))
non-gen-var-markersfunction
(defun non-gen-var-markers (alist) (if (consp alist) (if (gen-var-marker (cdar alist)) (non-gen-var-markers (cdr alist)) (cons (cdar alist) (non-gen-var-markers (cdr alist)))) nil))
find-duplicate-generalize-entriesfunction
(defun find-duplicate-generalize-entries (alist var) (declare (xargs :guard (true-listp alist))) (if alist (if (eq (cadar alist) var) (cons (car alist) (find-duplicate-generalize-entries (cdr alist) var)) (find-duplicate-generalize-entries (cdr alist) var)) nil))
translate-generalize-alist-2function
(defun translate-generalize-alist-2 (alist avoid-list) (declare (xargs :guard (true-listp alist))) (if alist (if (gen-var-marker (cdar alist)) (let ((new-var (genvar 'genvar "_" (cdar alist) avoid-list))) (cons (cons (caar alist) new-var) (translate-generalize-alist-2 (cdr alist) (cons new-var avoid-list)))) (cons (car alist) (translate-generalize-alist-2 (cdr alist) avoid-list))) nil))
translate-generalize-alistfunction
(defun translate-generalize-alist (alist state-vars abbreviations state) (er-let* ((alist1 (translate-generalize-alist-1 alist state-vars abbreviations state))) (let ((new-vars (non-gen-var-markers alist1))) (if (no-duplicatesp-equal new-vars) (value (translate-generalize-alist-2 alist1 (append new-vars state-vars))) (let* ((bad-var (car (duplicates new-vars))) (dup-entries (find-duplicate-generalize-entries alist bad-var))) (if (cdr dup-entries) (er soft 'generalize "The pairs ~&0 have the same variable, ~x1, and hence your ~ GENERALIZE instruction is illegal." dup-entries bad-var) (value (er hard 'generalize "Bad call to translate-generalize-alist on ~% ~x0." (list alist state-vars abbreviations)))))))))
all-vars-goalsfunction
(defun all-vars-goals (goals) (if (consp goals) (union-eq (all-vars (access goal (car goals) :conc)) (union-eq (all-vars1-lst (access goal (car goals) :hyps) nil) (all-vars-goals (cdr goals)))) nil))
pc-state-varsfunction
(defun pc-state-vars (pc-state) (union-eq (all-vars1-lst (strip-cdrs (access pc-state pc-state :abbreviations)) nil) (all-vars-goals (access pc-state pc-state :goals))))
other
(define-pc-primitive generalize (&rest args) (cond (current-addr (print-no-change2 "Generalization may only be applied at the top of the current goal. Try TOP first.")) ((null args) (print-no-change2 "GENERALIZE requires at least one argument.")) (t (mv-let (erp alist state) (translate-generalize-alist args (pc-state-vars pc-state) abbreviations state) (if erp (print-no-change2 "GENERALIZE failed.") (mv (change-pc-state pc-state :goals (cons (change goal (car goals) :hyps (sublis-expr-lst alist (access goal (car goals) :hyps)) :conc (sublis-expr alist (access goal (car goals) :conc))) (cdr goals))) state))))))
other
(define-pc-atomic-macro use (&rest args) (value `(prove :hints (("Goal" :use ,ARGS :do-not-induct proof-builder :do-not *do-not-processes*)) :otf-flg t)))
other
(define-pc-atomic-macro clause-processor (&rest cl-proc-hints) (value `(:prove :hints (("Goal" :clause-processor (,@CL-PROC-HINTS) :do-not-induct proof-builder :do-not *do-not-processes*)) :otf-flg t)))
other
(define-pc-macro cl-proc (&rest cl-proc-hints) (value `(:clause-processor ,@CL-PROC-HINTS)))
other
(define-pc-atomic-macro retain (arg1 &rest rest-args) (declare (ignore arg1 rest-args)) (when-goals-trip (let* ((hyps (hyps t)) (bad-nums (non-bounded-nums args 1 (length hyps)))) (if bad-nums (pprogn (print-no-change "The following are not in-range hypothesis numbers: ~&0." (list (cons #\0 bad-nums))) (mv t nil state)) (let ((retained-hyps (set-difference-eq (fromto 1 (length hyps)) args))) (if retained-hyps (value (cons :drop retained-hyps)) (pprogn (print-no-change "All hypotheses are to be retained.") (mv t nil state))))))))
other
(define-pc-atomic-macro reduce (&rest hints) (if (alistp hints) (value (list :prove :hints (add-string-val-pair-to-string-val-alist! "Goal" :do-not-induct 'proof-builder hints) :otf-flg t)) (pprogn (print-no-change "A REDUCE instruction must be of the form~%~ ~ ~ (:REDUCE (goal_name_1 ...) ... (goal_name_n ...)),~%and hence ~ your instruction,~%~ ~ ~x0,~%is not legal." (list (cons #\0 (cons :reduce hints)))) (value :fail))))
other
(define-pc-macro run-instr-on-goal (instr goal-name) (when-goals-trip (if (equal goal-name (goal-name t)) (value instr) (value `(protect (change-goal ,GOAL-NAME) ,INSTR)))))
run-instr-on-goals-gutsfunction
(defun run-instr-on-goals-guts (instr goal-names) (declare (xargs :guard (true-listp goal-names))) (if goal-names (cons `(run-instr-on-goal ,INSTR ,(CAR GOAL-NAMES)) (run-instr-on-goals-guts instr (cdr goal-names))) nil))
other
(define-pc-macro run-instr-on-new-goals (instr existing-goal-names &optional must-succeed-flg) (value (cons 'do-strict (run-instr-on-goals-guts (if must-succeed-flg instr (list :succeed instr)) (set-difference-equal (goal-names (goals t)) existing-goal-names)))))
other
(define-pc-macro then (instr &optional completion must-succeed-flg) (value (list 'do-strict instr (list 'run-instr-on-new-goals (or completion :reduce) (goal-names (goals t)) must-succeed-flg))))
other
(define-pc-macro nil nil (value 'exit))
other
(define-pc-atomic-macro free (var) (er-let* ((var (trans0 var nil :free))) (if (variablep var) (value `(add-abbreviation ,VAR (hide ,VAR))) (pprogn (print-no-change "The FREE command requires an argument that is a variable, ~ which ~x0 is not." (list (cons #\0 var))) (value :fail)))))
other
(define-pc-macro replay (&optional n replacement-instr) (if (or (null n) (and (integerp n) (> n 0))) (let* ((len (length state-stack)) (n (and n (min (1+ n) len))) (instrs (instructions-of-state-stack (if n (take n state-stack) state-stack) nil))) (value `(do-strict (undo ,(1- (OR N LEN))) ,@(IF REPLACEMENT-INSTR (CONS REPLACEMENT-INSTR (CDR INSTRS)) INSTRS)))) (pprogn (print-no-change "The optional argument to the REPLAY command ~ must be a positive integer, but ~x0 is not!" (list (cons #\0 n))) (value :fail))))
instr-namefunction
(defun instr-name (instr) (if (atom instr) instr (car instr)))
pc-free-instr-pfunction
(defun pc-free-instr-p (var pc-state) (let ((instr (access pc-state pc-state :instruction))) (and (eq (instr-name instr) :free) (eq (cadr instr) var))))
find-possible-putfunction
(defun find-possible-put (var state-stack) (if state-stack (if (pc-free-instr-p var (car state-stack)) 1 (let ((n (find-possible-put var (cdr state-stack)))) (and n (1+ n)))) nil))
other
(define-pc-macro put (var expr) (let ((n (find-possible-put var state-stack))) (if n (value `(do-strict (replay ,N (add-abbreviation ,VAR ,EXPR)) (remove-abbreviations ,VAR))) (pprogn (print-no-change "There is no FREE command for ~x0." (list (cons #\0 var))) (value :fail)))))
other
(define-pc-macro reduce-by-induction (&rest hints) (if (alistp hints) (value (cons :reduce (add-string-val-pair-to-string-val-alist "Goal" :induct t hints))) (pprogn (print-no-change "A REDUCE-BY-INDUCTION instruction must be of the form~%~ ~ ~ (:REDUCE-BY-INDUCTION (goal_name_1 ...) ... (goal_name_n ...)),~%and hence ~ your instruction,~%~ ~ ~x0,~%is not legal." (list (cons #\0 (cons :reduce-by-induction hints)))) (value :fail))))
other
(define-pc-macro r (&rest args) (value (cons :rewrite args)))
other
(define-pc-atomic-macro sl (&optional backchain-limit) (value (if backchain-limit `(s :backchain-limit ,BACKCHAIN-LIMIT :in-theory (union-theories (theory 'minimal-theory) (set-difference-theories (current-theory :here) (function-theory :here)))) `(s :in-theory (union-theories (theory 'minimal-theory) (set-difference-theories (current-theory :here) (function-theory :here)))))))
other
(define-pc-atomic-macro elim nil (value (list :prove :otf-flg t :hints '(("Goal" :do-not-induct proof-builder :do-not (set-difference-eq *do-not-processes* '(eliminate-destructors)))))))
other
(define-pc-macro ex nil (value '(do-strict save exit)))
save-fc-report-settingsfunction
(defun save-fc-report-settings nil (declare (xargs :guard t)) (wormhole-eval 'fc-wormhole '(lambda (whs) (let* ((data (wormhole-data whs)) (criteria (cdr (assoc-eq :criteria data))) (flyp (cdr (assoc-eq :report-on-the-flyp data)))) (set-wormhole-data whs (put-assoc-eq :criteria-saved criteria (put-assoc-eq :report-on-the-flyp-saved flyp data))))) nil))
restore-fc-report-settingsfunction
(defun restore-fc-report-settings nil (declare (xargs :guard t)) (wormhole-eval 'fc-wormhole '(lambda (whs) (let* ((data (wormhole-data whs)) (criteria-saved (cdr (assoc-eq :criteria-saved data))) (flyp-saved (cdr (assoc-eq :report-on-the-flyp-saved data)))) (set-wormhole-data whs (put-assoc-eq :criteria criteria-saved (put-assoc-eq :report-on-the-flyp flyp-saved data))))) nil))
proof-builder-assumptionsfunction
(defun proof-builder-assumptions (concl-flg govs-flg conc current-addr state-stack) (cond (concl-flg (union-equal (hyps t) (cond (govs-flg (add-to-set-equal (dumb-negate-lit conc) (governors conc current-addr))) (t (list (dumb-negate-lit conc)))))) (govs-flg (union-equal (hyps t) (governors conc current-addr))) (t (hyps t))))
other
(define-pc-help type-alist (&optional concl-flg govs-flg fc-report-flg alistp) (when-goals (let ((conc (conc t)) (current-addr (current-addr t)) (w (w state)) (govs-flg (if (cdr args) govs-flg (not concl-flg)))) (prog2$ (and fc-report-flg (prog2$ (save-fc-report-settings) (prog2$ (wormhole-eval 'fc-wormhole '(lambda (whs) (set-wormhole-data whs (put-assoc-eq :criteria '((t t t)) (wormhole-data whs)))) nil) (set-fc-report-on-the-fly t)))) (mv-let (flg hyps-type-alist ign) (hyps-type-alist (proof-builder-assumptions concl-flg govs-flg conc current-addr state-stack) (make-pc-ens (pc-ens t) state) w state) (declare (ignore ign)) (prog2$ (and fc-report-flg (restore-fc-report-settings)) (if flg (io? proof-builder nil state nil (fms0 "*** Contradiction in the hypotheses! ***~%The S ~ command should complete this goal.~|")) (io? proof-builder nil state (hyps-type-alist alistp w) (pprogn (fms0 "~|Current type-alist, including forward chaining:~%") (prog2$ (cond ((eq alistp :raw) (cw "~x0~|" hyps-type-alist)) (alistp (cw "~x0~|" (alist-to-doublets (decode-type-alist hyps-type-alist)))) (t (print-type-alist hyps-type-alist w nil))) state))))))))))
other
(define-pc-help pot-lst (&optional concl-flg govs-flg rawp) (when-goals (let* ((conc (conc t)) (current-addr (current-addr t)) (wrld (w state)) (govs-flg (if (cdr args) govs-flg (not concl-flg))) (assumptions (proof-builder-assumptions concl-flg govs-flg conc current-addr state-stack)) (clause (dumb-negate-lit-lst (expand-assumptions assumptions))) (ens (make-pc-ens (pc-ens t) state)) (clause-pts (enumerate-elements clause 0))) (mv-let (contradictionp type-alist fc-pair-lst) (forward-chain-top 'pot-lst clause nil (ok-to-force-ens ens) nil wrld ens (match-free-override wrld) state) (cond (contradictionp (io? proof-builder nil state (concl-flg) (fms0 "*** Contradiction (from forward-chaining, towards ~ building a pot-lst)! ***~|~#0~[The S command should ~ complete this goal.~|~/~]" (list (cons #\0 (if concl-flg 1 0)))))) (t (let ((rcnst (make-rcnst ens wrld state :force-info (if (ffnnamep-lst 'if clause) 'weak t) :top-clause clause :current-clause clause))) (mv-let (step-limit contradictionp pot-lst) (setup-simplify-clause-pot-lst clause (pts-to-ttree-lst clause-pts) fc-pair-lst type-alist rcnst wrld state *default-step-limit*) (declare (ignore step-limit)) (cond (contradictionp (io? proof-builder nil state (concl-flg) (fms0 "*** Contradiction from attempting to build a ~ pot-lst)! ***~|~#0~[The S command should complete ~ this goal.~|~/~]" (list (cons #\0 (if concl-flg 1 0)))))) (t (io? proof-builder nil state (pot-lst rawp) (pprogn (fms0 "~|Current pot-lst:~%") (prog2$ (if rawp (cw "~x0~|" pot-lst) (print-pot-lst pot-lst nil)) state)))))))))))))
other
(define-pc-macro print-main nil (value '(print (caddr (event-name-and-types-and-raw-term (state-stack))))))
other
(define-pc-macro pso nil (value '(lisp (pso))))
other
(define-pc-macro psog nil (value '(lisp (psog))))
other
(define-pc-macro pso! nil (value '(lisp (pso!))))
other
(define-pc-macro acl2-wrap (x) (value `(lisp ,X)))
other
(define-pc-macro check-proved-goal (goal-name cmd) (if (member-equal goal-name (goal-names (goals))) (er soft 'check-proved "The command ~x0 failed to prove the goal ~x1." cmd goal-name) (value 'succeed)))
other
(define-pc-macro check-proved (x) (when-goals-trip (let ((goal-name (goal-name))) (value `(do-all ,X (quiet (check-proved-goal ,GOAL-NAME ,X)))))))
other
(define-pc-atomic-macro forwardchain (hypn &optional hints quiet-flg) (when-goals-trip (let* ((hyps (hyps)) (len (length hyps))) (cond ((null hyps) (mv-let (erp val state) (er soft 'forwardchain "The are no top-level hypotheses. Hence it makes no sense to ~ forward chain here.") (declare (ignore erp val)) (value 'fail))) ((and (integerp hypn) (< 0 hypn) (<= hypn len)) (let ((hyp (nth (1- hypn) hyps))) (case-match hyp (('implies ant consequent) (let ((instr `(protect (claim ,CONSEQUENT 0 :do-not-flatten t) (drop ,HYPN) change-goal (demote ,HYPN) (claim ,ANT ,@(IF HINTS '(:HINTS HINTS) NIL)) (demote ,LEN) (check-proved (s :backchain-limit 0 :in-theory (theory 'minimal-theory)))))) (if quiet-flg (value (list 'quiet instr)) (value instr)))) (& (mv-let (erp val state) (er soft 'forwardchain "The ~n0 hypothesis~| ~x1~|is not of the form (implies x ~ y)." (list hypn) (untrans0 (nth (1- hypn) hyps) t (abbreviations))) (declare (ignore erp val)) (value 'fail)))))) (t (mv-let (erp val state) (er soft 'forwardchain "The index ~x0 is not a valid index into the hypothesis list. ~ The valid indices are the integers from 1 to ~x1." hypn len) (declare (ignore erp val)) (value 'fail)))))))
other
(define-pc-atomic-macro bdd (&rest kw-listp) (let ((bdd-hint (if (assoc-keyword :vars kw-listp) kw-listp (list* :vars nil kw-listp)))) (value `(:prove :hints (("Goal" :bdd ,BDD-HINT))))))
other
(define-pc-macro runes (&optional flg) (value `(print (merge-sort-runes (all-runes-in-ttree (,(IF FLG 'TAG-TREE 'LOCAL-TAG-TREE)) nil)))))
other
(define-pc-macro lemmas-used (&optional flg) (value `(runes ,FLG)))
goal-termsfunction
(defun goal-terms (goals) (if (endp goals) nil (cons (make-implication (access goal (car goals) :hyps) (access goal (car goals) :conc)) (goal-terms (cdr goals)))))
wrap1-aux1function
(defun wrap1-aux1 (kept-goal-names all-goals kept-goals removed-goals) (cond ((endp all-goals) (mv (reverse kept-goals) (reverse removed-goals))) ((member-equal (access goal (car all-goals) :goal-name) kept-goal-names) (wrap1-aux1 kept-goal-names (cdr all-goals) (cons (car all-goals) kept-goals) removed-goals)) (t (wrap1-aux1 kept-goal-names (cdr all-goals) kept-goals (cons (car all-goals) removed-goals)))))
wrap1-aux2function
(defun wrap1-aux2 (sym index goals kept-goals removed-goals) (if (endp goals) (mv (reverse kept-goals) (reverse removed-goals)) (let* ((goal (car goals)) (goal-name (access goal goal :goal-name))) (if (and (consp goal-name) (eq sym (car goal-name)) (<= index (cdr goal-name))) (wrap1-aux2 sym index (cdr goals) kept-goals (cons (car goals) removed-goals)) (wrap1-aux2 sym index (cdr goals) (cons (car goals) kept-goals) removed-goals)))))
other
(define-pc-primitive wrap1 (&optional kept-goal-names) (let* ((current-goal (car goals)) (current-goal-name (access goal current-goal :goal-name))) (cond ((not (true-listp kept-goal-names)) (print-no-change2 "The (optional) argument to wrap1 must be a true list of goal names. ~ ~x0 is thus illegal." (list (cons #\0 kept-goal-names)))) ((and (null kept-goal-names) (not (and (consp current-goal-name) (symbolp (car current-goal-name)) (integerp (cdr current-goal-name))))) (print-no-change2 "The current goal's name, ~x0, is not of the form (SYMBOL . N) for ~ integer N." (list (cons #\0 current-goal-name)))) (t (mv-let (kept-goals removed-goals) (if kept-goal-names (wrap1-aux1 kept-goal-names (cdr goals) nil nil) (wrap1-aux2 (car current-goal-name) (cdr current-goal-name) (cdr goals) nil nil)) (pprogn (io? proof-builder nil state (current-goal-name removed-goals) (if removed-goals (fms0 "~|Conjoining the following goals into the current ~ goal, ~x0:~| ~X1n~%" (list (cons #\0 current-goal-name) (cons #\1 (goal-names removed-goals)) (cons #\n nil))) (fms0 "~|NOTE (wrap1): There are no goals to conjoin into the ~ current goal, but we proceed anyhow.~%"))) (mv (change-pc-state pc-state :goals (cons (change goal current-goal :conc (conjoin (goal-terms (cons current-goal removed-goals))) :hyps nil :current-addr nil) kept-goals)) state)))))))
other
(define-pc-atomic-macro wrap (&rest instrs) (cond ((null instrs) (pprogn (print-no-change "Wrap takes at least one argument.") (value :fail))) (t (let ((goal-names (goal-names (goals t)))) (value `(sequence ((do-all ,@INSTRS) (quiet (wrap1 ,GOAL-NAMES)) (lisp (io? proof-builder nil state nil (let ((new-current-goal-name (access goal (car (goals)) :goal-name)) (state-stack (state-stack))) (when-goals (fms0 (if (member-equal new-current-goal-name ',GOAL-NAMES) "~|~%NOTE: Created no new goals. Current ~ goal:~% ~X0n~|" "~|~%NOTE: Created ONLY one new goal, which ~ is the current goal:~% ~X0n~|") (list (cons #\0 new-current-goal-name) (cons #\n nil)))))))) t nil nil t))))))
other
(define-pc-atomic-macro wrap-induct (&optional raw-term) (value (if raw-term `(wrap (induct ,RAW-TERM)) `(wrap induct))))
other
(define-pc-macro finish-error (instrs) (er soft 'finish "~%The following instruction list created at least one subgoal:~|~x0~|" instrs))
other
(define-pc-macro finish (&rest instrs) (value `(then (check-proved (do-strict ,@INSTRS)) (finish-error ,INSTRS) t)))
other
(define-pc-macro geneqv (&optional with-runes-p) (value `(print (show-geneqv (geneqv-at-subterm-top (conc) (current-addr) (make-pc-ens (pc-ens) state) (w state)) ',WITH-RUNES-P))))
goals-to-clause-listfunction
(defun goals-to-clause-list (goals) (if (endp goals) nil (cons (append (dumb-negate-lit-lst (access goal (car goals) :hyps)) (list (access goal (car goals) :conc))) (goals-to-clause-list (cdr goals)))))
proof-builder-clause-listfunction
(defun proof-builder-clause-list (state) (goals-to-clause-list (goals)))
ttree-to-summary-datafunction
(defun ttree-to-summary-data (ttree) (and ttree (mv-let (use-names by-names cl-proc-fns) (cl-proc-data-in-ttree ttree nil) (make-summary-data :runes (all-runes-in-ttree ttree nil) :use-names (append use-names (use-names-in-ttree ttree nil)) :by-names (append by-names (by-names-in-ttree ttree nil)) :clause-processor-fns cl-proc-fns))))
proof-builder-cl-proc-1function
(defun proof-builder-cl-proc-1 (cl instr-list state) (let ((ctx 'proof-builder-cl-proc)) (cond ((null cl) (er soft ctx "There is no legal way to prove a goal of NIL!")) ((not (true-listp instr-list)) (er soft ctx "The value of the :INSTRUCTIONS hint must be a true ~ (null-terminated) list. The value ~x0 is thus illegal." instr-list)) (t (let ((term (make-implication (dumb-negate-lit-lst (butlast cl 1)) (car (last cl)))) (wrld (w state)) (new-pc-depth (1+ (pc-value pc-depth)))) (er-let* ((new-inhibit-output-lst (cond ((and (consp instr-list) (true-listp (car instr-list)) (eq (make-pretty-pc-command (caar instr-list)) :comment) (eq (cadar instr-list) 'inhibit-output-lst)) (cond ((eq (caddar instr-list) :same) (value (f-get-global 'inhibit-output-lst state))) (t (chk-inhibit-output-lst (caddar instr-list) :instructions state)))) (t (value (union-eq '(prove proof-tree proof-builder) (f-get-global 'inhibit-output-lst state)))))) (outputp (value (not (subsetp-eq '(prove proof-builder proof-tree) new-inhibit-output-lst))))) (state-global-let* ((inhibit-output-lst new-inhibit-output-lst) (pc-output (f-get-global 'pc-output state))) (mv-let (erp clause-list state) (pprogn (pc-assign pc-depth new-pc-depth) (cond (outputp (io? prove nil state (new-pc-depth) (fms0 "~|~%[[~x0> Executing ~ proof-builder instructions]]~%~%" (list (cons #\0 new-pc-depth))))) (t state)) (pc-assign next-pc-enabled-array-suffix (1+ (pc-value next-pc-enabled-array-suffix))) (mv-let (erp pc-val state) (pc-main term (untranslate term t wrld) nil nil instr-list '(signal value) t nil state) (pprogn (cond (outputp (io? prove nil state (new-pc-depth) (fms0 "~|~%[[<~x0 Completed ~ proof-builder ~ instructions]]~%" (list (cons #\0 new-pc-depth))))) (t state)) (cond ((or erp (null pc-val)) (let ((name (intern (concatenate 'string "ERROR" (coerce (explode-atom new-pc-depth 10) 'string)) "KEYWORD"))) (pprogn (io? error nil state (name) (fms0 "~%Saving proof-builder error ~ state; see :DOC instructions. To ~ retrieve:~|~x0" (list (cons #\0 `(retrieve ,NAME))))) (save-fn name (ss-alist) state) (er soft ctx "The above :INSTRUCTIONS hint failed. ~ For a discussion of ``failed'', follow ~ the link to the SEQUENCE command under ~ :DOC proof-builder-commands.")))) (t (value (proof-builder-clause-list state))))))) (cond (erp (silent-error state)) (t (value (cons clause-list (state-stack)))))))))))))
proof-builder-cl-procfunction
(defun proof-builder-cl-proc (cl instr-list state) (mv-let (erp clause-list/state-stack state) (proof-builder-cl-proc-1 cl instr-list state) (cond (erp (mv erp clause-list/state-stack state nil)) (t (mv erp (car clause-list/state-stack) state (let ((state-stack (cdr clause-list/state-stack))) (and (consp state-stack) (ttree-to-summary-data (access pc-state (car state-stack) :tag-tree)))))))))
other
(define-trusted-clause-processor proof-builder-cl-proc nil)
other
(add-custom-keyword-hint :instructions (splice-keyword-alist :instructions (list :clause-processor (list :function 'proof-builder-cl-proc :hint (kwote val))) keyword-alist))