Included Books
other
(in-package "ACL2")
include-book
(include-book "xdoc/top" :dir :system)
other
(program)
other
(defxdoc rulesets :parents (theories deftheory) :short "Table-based alternative to ACL2's named theories." :long "<p>Rulesets are like @(see theories), but can be extended with additional rules after first being defined. That is, you can build up a ruleset incrementally, across many books, instead of having to define it all at once and having it be forever fixed.</p> <p>Basic usage of rulesets is just like theories. You can:</p> <ul> <li>Introduce rulesets with @(see def-ruleset)</li> <li>Extend existing rulesets with @(see add-to-ruleset).</li> <li>Enable/disable rulesets with @(see enable*), @(see disable*), and @(see e/d*)</li> </ul> <p>When we define a new package @('FOO'), we often set up @('FOO::enable') as an alias for @('enable*'), to make using rulesets more convenient.</p> <p>Advanced users can do some nifty things with rulesets, e.g., you can have a superior ruleset that contains other rulesets, and it will grow as you add rules to the contained rulesets.</p> <p>A ruleset is actually a list of so-called <i>ruleset designators</i>. All ruleset operators, such as @(tsee e/d*) and @(tsee def-ruleset), take arguments that are rulesets. See @(see expand-ruleset) for a discussion of ruleset designators and the corresponding @(see theories) that they represent.</p>")
other
(defsection get-ruleset :parents (rulesets) :short "The @(see ruleset) associated with a given name" :long "<p>Example usage:</p> @({ (get-ruleset 'my-ruleset (w state)) }) <p>Also see @(see ruleset). For a more powerful operator that recursively expands ruleset names within a given ruleset, see @(see expand-ruleset).</p>" (defun get-ruleset (name world) (let* ((ruleset-alist (table-alist 'ruleset-table world))) (cdr (assoc name ruleset-alist)))))
other
(defsection ruleset :parents (rulesets) :short "The ruleset associated with a given name" :long "<p>See @(see rulesets) for an introduction to rulesets.</p> <p>Examples of calls of @('ruleset'):</p> @({ (ruleset 'my-ruleset) ; assumes that WORLD is bound (ruleset 'my-ruleset (w state)) ; ruleset currently associated with MY-RULESET }) <p>Also see @(see get-ruleset). For a more powerful operator that recursively expands ruleset names within a given ruleset, see @(see expand-ruleset).</p>" (defmacro ruleset (name &optional (world 'world)) `(get-ruleset ,NAME ,WORLD)))
is-rulesetfunction
(defun is-ruleset (name world) (let* ((ruleset-alist (table-alist 'ruleset-table world))) (consp (assoc name ruleset-alist))))
ruleset-designatorpfunction
(defun ruleset-designatorp (x world) (cond ((rule-name-designatorp x (macro-aliases world) world)) ((symbolp x) (or (is-ruleset x world) (cw "~ **NOTE**:~%~x0 is not a rune, theory name, or ruleset name.~%" x))) (t (and (consp x) (case-match x ((':ruleset ruleset) (or (is-ruleset ruleset world) (cw "**NOTE**:~%~x0 is not a ruleset.~%" ruleset))) ((':executable-counterpart-theory &) t) ((':current-theory &) t) ((':theory &) t) ((':rules-of-class & &) t) (& (cw "~ **NOTE**:~%~x0 is neither a rune nor a valid ruleset designator.~%" x)))))))
ruleset-designator-listp1function
(defun ruleset-designator-listp1 (x world ok) (if (atom x) (and (eq x nil) ok) (ruleset-designator-listp1 (cdr x) world (and (ruleset-designatorp (car x) world) ok))))
ruleset-designator-listpfunction
(defun ruleset-designator-listp (x world) (ruleset-designator-listp1 x world t))
rules-of-class1function
(defun rules-of-class1 (class theory) (declare (xargs :mode :program)) (if (atom theory) nil (if (and (consp (car theory)) (eq (caar theory) class)) (cons (car theory) (rules-of-class1 class (cdr theory))) (rules-of-class1 class (cdr theory)))))
rules-of-classmacro
(defmacro rules-of-class (class name) `(rules-of-class1 ,CLASS (universal-theory ,NAME)))
def-ruleset-corefunction
(defun def-ruleset-core (name rules world state) (declare (xargs :stobjs state)) (if (ruleset-designator-listp rules world) (value `(table ruleset-table ',NAME ',RULES)) (er soft 'def-ruleset "Invalid ruleset specified~%")))
add-to-ruleset-corefunction
(defun add-to-ruleset-core (name rules world state) (declare (xargs :stobjs state)) (if (ruleset-designator-listp rules world) (value `(table ruleset-table ',NAME (union-equal ',RULES (ruleset ',NAME)))) (er soft 'add-to-ruleset "Invalid ruleset specified~%")))
check-not-rulesetfunction
(defun check-not-ruleset (name world state) (declare (xargs :stobjs state)) (if (is-ruleset name world) (er soft 'def-ruleset "~x0 is already a ruleset. Use add-to-ruleset or def-ruleset! ~ instead.~%" name) (value 'ok)))
check-rulesetfunction
(defun check-ruleset (name world state) (declare (xargs :stobjs state)) (if (is-ruleset name world) (value 'ok) (er soft 'add-to-ruleset "~x0 is not already a ruleset. Use def-ruleset, def-ruleset! ~ or add-to-ruleset! instead.~%" name)))
ruleset-form-preprocessfunction
(defun ruleset-form-preprocess (form) (if (and (symbolp form) (not (booleanp form))) `'(,FORM) form))
other
(defsection def-ruleset :parents (rulesets) :short "@(call def-ruleset) creates a new @(see ruleset)." :long "<p>Examples:</p> @({ (def-ruleset my-rules '(append reverse)) (def-ruleset other-rules '(member-equal my-rules revappend)) }) <p>The first example creates a new ruleset, @('my-rules'), with only the definitions of @('append') and @('reverse').</p> <p>The section example creates a new ruleset, @('other-rules'), with the definitions of @('member-equal') and @('revappend'), and also a link to @('my-rules'). When rules are added to @('my-rules'), @('other-rules') also grows.</p> <p>See @(see def-ruleset!) for a version that's more friendly towards redundant calls.</p>" (defmacro def-ruleset (name form) (declare (xargs :guard (symbolp name))) `(make-event (let ((world (w state)) (name ',NAME)) (er-progn (check-not-ruleset name world state) (let ((rules ,(RULESET-FORM-PREPROCESS FORM))) (def-ruleset-core name rules world state)))))))
other
(defsection add-to-ruleset :parents (rulesets) :short "@(call add-to-ruleset) adds additional rules to an existing @(see ruleset)." :long "<p>Examples:</p> @({ (add-to-ruleset my-rules '(foop)) (add-to-ruleset other-rules '(car-cons cdr-cons (force))) })" (defmacro add-to-ruleset (name form) (declare (xargs :guard (symbolp name))) `(make-event (let ((world (w state)) (name ',NAME)) (er-progn (check-ruleset name world state) (let ((rules ,(RULESET-FORM-PREPROCESS FORM))) (add-to-ruleset-core name rules world state)))))))
other
(defsection def-ruleset! :parents (rulesets) :short "Same as @(see def-ruleset) except that it does not complain if the @(see ruleset) already exists, instead acting like @('add-to-ruleset') in that case." (defmacro def-ruleset! (name form) (declare (xargs :guard (symbolp name))) `(make-event (let* ((world (w state)) (name ',NAME) (rules ,(RULESET-FORM-PREPROCESS FORM))) (if (is-ruleset name world) (add-to-ruleset-core name rules world state) (def-ruleset-core name rules world state))))))
set-ruleset!macro
(defmacro set-ruleset! (name form) (declare (xargs :guard (symbolp name))) `(make-event (let* ((world (w state)) (name ',NAME) (rules ,(RULESET-FORM-PREPROCESS FORM))) (def-ruleset-core name rules world state))))
add-to-ruleset!macro
(defmacro add-to-ruleset! (name form) (declare (xargs :guard (symbolp name))) `(make-event (let* ((world (w state)) (name ',NAME) (rules ,(RULESET-FORM-PREPROCESS FORM))) (add-to-ruleset-core name rules world state))))
expand-ruleset1function
(defun expand-ruleset1 (x world) (if (atom x) nil (let ((des (car x))) (cond ((rule-name-designatorp des (macro-aliases world) world) (cons des (expand-ruleset1 (cdr x) world))) ((atom des) (append (expand-ruleset1 (ruleset des) world) (expand-ruleset1 (cdr x) world))) (t (case (car des) (:ruleset (append (expand-ruleset1 (ruleset (cadr des)) world) (expand-ruleset1 (cdr x) world))) (:executable-counterpart-theory (append (executable-counterpart-theory (cadr des)) (expand-ruleset1 (cdr x) world))) (:rules-of-class (append (rules-of-class (cadr des) (caddr des)) (expand-ruleset1 (cdr x) world))) (:theory (append (theory (cadr des)) (expand-ruleset1 (cdr x) world))) (:current-theory (append (current-theory (cadr des)) (expand-ruleset1 (cdr x) world)))))))))
other
(defsection expand-ruleset :parents (rulesets) :short "Expand @(see rulesets) to @(see theories)." :long "<p>A @(see ruleset) is a list of so-called <i>ruleset designators</i>. The @(see ruleset) operators, such as @(tsee e/d*) and @(tsee def-ruleset), expect arguments that are (or evaluate to) rulesets. Every ruleset represents an ACL2 <i>theory</i>, called its ``expansion''. Consider for example these ruleset definitions.</p> @({ (def-ruleset my-rules '(append reverse)) (def-ruleset other-rules '(member-equal my-rules revappend)) }) <p>Then the symbol @('my-rules') is a ruleset designator, which represents the theory containing @('append') and @('reverse'). The symbol @('other-rules') is a ruleset designator, which represents the theory containing @('member-equal'), @('append'), @('reverse'), and @('revappend'). The function @('expand-ruleset') returns the theory obtained by expanding every ruleset designator in a given ruleset, for example:</p> @({ ACL2 !>(expand-ruleset '(car-cons (:d nth) other-rules) (w state)) (CAR-CONS (:D NTH) MEMBER-EQUAL APPEND REVERSE REVAPPEND) ACL2 !> }) <p>We now list the valid ruleset designators and indicate the corresponding expansion, a theory, for each.</p> <ul> <li>A symbol that names a rule (e.g., from a definition or a theorem) or names a @(see theory) is a ruleset designator. More generally, every <i>runic designator</i> @('x') is also a ruleset designator, which expands to the theory containing exactly @('x'). See @(see theories) for a discussion of runic designators.</li> <li>If @('N') is a symbol that is the name of a ruleset @('S'), then @('N') and @('(:ruleset N)') are ruleset designators. They expand to the union of the expansions of the ruleset designators in @('S').</li> <li>The ruleset designators @('(:executable-counterpart-theory name)'), @('(:current-theory name)'), and @('(:theory name)') expand to the values in the current ACL2 @(see world) of the forms @('(executable-counterpart-theory name)'), @('(current-theory name)'), and @('(theory name)'), respectively.</li> <li>The ruleset designator @('(:rules-of-class class name)') represent the runes of the indicated class (see @(see rule-classes)) in the value of @('(universal-theory name)').</li> </ul>" (defun expand-ruleset (x world) (if (ruleset-designator-listp x world) (expand-ruleset1 x world) (er hard 'expand-ruleset "~x0 is not a valid ruleset.~%" x))))
other
(defsection enable* :parents (rulesets) :short "@(csee Ruleset)-aware version of @(see enable)." :long "<p>Examples:</p> @({ (in-theory (enable* my-rules append car-cons)) (defthm ... :hints (("Goal" :in-theory (enable* foo ...)))) })" (defmacro enable* (&rest x) `(union-current-theory-fn (expand-ruleset ',X world) nil world)))
other
(defsection disable* :parents (rulesets) :short "@(csee Ruleset)-aware version of @(see disable)." :long "<p>Examples:</p> @({ (in-theory (disable* my-rules append car-cons)) (defthm ... :hints (("Goal" :in-theory (disable* foo ...)))) })" (defmacro disable* (&rest x) `(set-difference-current-theory-fn (expand-ruleset ',X world) nil world)))
other
(defsection e/d* :parents (rulesets) :short "@(csee Ruleset)-aware version of @(see e/d)." :long "<p>Examples:</p> @({ (in-theory (e/d* (unusual-rules append) (expensive-rules default-car default-cdr))) (defthm ... :hints (("Goal" :in-theory (e/d* (unusual-rules append) (expensive-rules default-car default-cdr))))) })" (defun e/d*-fn (theory e/d-list enable-p) (declare (xargs :guard (and (true-list-listp e/d-list) (or (eq enable-p t) (eq enable-p nil))))) (cond ((atom e/d-list) theory) (enable-p (e/d*-fn `(union-theories ,THEORY (expand-ruleset ',(CAR E/D-LIST) world)) (cdr e/d-list) nil)) (t (e/d*-fn `(set-difference-theories ,THEORY (expand-ruleset ',(CAR E/D-LIST) world)) (cdr e/d-list) t)))) (defmacro e/d** (&rest theories) (declare (xargs :guard (true-list-listp theories))) (cond ((atom theories) nil) (t (e/d*-fn nil theories t)))) (defmacro e/d* (&rest theories) (declare (xargs :guard (true-list-listp theories))) (cond ((atom theories) '(current-theory :here)) (t (e/d*-fn '(current-theory :here) theories t)))))
ruleset-theorymacro
(defmacro ruleset-theory (ruleset) `(expand-ruleset (ruleset ,RULESET) world))