other
(in-package "GL")
other
(include-book "clause-processors/unify-subst" :dir :system)
other
(include-book "glcp-unify-defs")
other
(include-book "clause-processors/magic-ev" :dir :system)
gl-bool-fixfunction
(defun gl-bool-fix (x) (and x t))
other
(defaggregate constraint-rule (thmname lit-alist syntaxp))
other
(defaggregate constraint-tuple
(rule existing-lits
matching-lit
common-vars
existing-vars
sig-table))
gbc-rule-lit-add-catalog-entryfunction
(defun gbc-rule-lit-add-catalog-entry (var pat rule ccat) (b* ((fnsym (car pat)) (tuples (cdr (hons-assoc-equal fnsym ccat))) (new-tuple (constraint-tuple rule nil var nil nil (hons-acons nil (list nil) nil)))) (cons (cons fnsym (cons new-tuple tuples)) ccat)))
gbc-rule-add-catalog-entriesfunction
(defun gbc-rule-add-catalog-entries (lit-alist rule ccat) (b* (((when (atom lit-alist)) ccat) ((cons var pat) (car lit-alist)) (ccat (gbc-rule-lit-add-catalog-entry var pat rule ccat))) (gbc-rule-add-catalog-entries (cdr lit-alist) rule ccat)))
gbc-alist-has-symmetricfunction
(defun gbc-alist-has-symmetric (term alist) (b* (((when (atom alist)) nil) (term2 (cdar alist)) ((mv ok1 &) (simple-one-way-unify term term2 nil)) ((mv ok2 &) (simple-one-way-unify term2 term nil))) (or (and ok1 ok2) (gbc-alist-has-symmetric term (cdr alist)))))
gbc-alist-remove-symmetricfunction
(defun gbc-alist-remove-symmetric (alist) (if (atom alist) nil (if (gbc-alist-has-symmetric (cdar alist) (cdr alist)) (gbc-alist-remove-symmetric (cdr alist)) (cons (car alist) (gbc-alist-remove-symmetric (cdr alist))))))
gbc-rule-add-to-catalogfunction
(defun gbc-rule-add-to-catalog (rule ccat) (b* ((syntaxp (constraint-rule->syntaxp rule)) (alist (constraint-rule->lit-alist rule)) (reduced-alist (if (equal syntaxp ''t) (gbc-alist-remove-symmetric alist) alist))) (hons-shrink-alist (gbc-rule-add-catalog-entries reduced-alist rule ccat) nil)))
gbc-add-rulemacro
(defmacro gbc-add-rule (name lit-alist syntaxp) `(table gl-bool-constraints nil (gbc-rule-add-to-catalog (constraint-rule ',GL::NAME ',GL::LIT-ALIST ',GL::SYNTAXP) (table-alist 'gl-bool-constraints world)) :clear))
gbc-translate-lit-alistfunction
(defun gbc-translate-lit-alist (lit-patterns state) (declare (xargs :mode :program :stobjs state)) (b* (((when (atom lit-patterns)) (value nil)) ((list var term) (car lit-patterns)) ((er trans) (translate term t t nil 'def-gl-boolean-constraint (w state) state)) ((er rest) (gbc-translate-lit-alist (cdr lit-patterns) state))) (value (cons (cons var trans) rest))))
def-gl-boolean-constraint-fnfunction
(defun def-gl-boolean-constraint-fn (name lit-patterns syntaxp body hints state) (declare (xargs :mode :program :stobjs state)) (b* (((er syntaxp-trans) (translate syntaxp t t nil 'def-gl-boolean-constraint (w state) state)) ((er alist) (gbc-translate-lit-alist lit-patterns state)) (body1 `(let ,(GL::PAIRLIS$ (GL::STRIP-CARS GL::LIT-PATTERNS) (GL::PAIRLIS$ (GL::PAIRLIS$ (GL::MAKE-LIST-AC (GL::LEN GL::LIT-PATTERNS) 'GL::GL-BOOL-FIX NIL) (GL::STRIP-CDRS GL::LIT-PATTERNS)) NIL)) ,GL::BODY))) (value `(progn (defthm ,GL::NAME ,GL::BODY1 :hints ,GL::HINTS :rule-classes nil) (gbc-add-rule ,GL::NAME ,GL::ALIST ,GL::SYNTAXP-TRANS)))))
other
(defsection def-gl-boolean-constraint :parents (reference term-level-reasoning) :short "Define a rule that recognizes constraints among GL generated Boolean variables" :long " <p>When using GL in a term-level style (see @(see term-level-reasoning)), GL may generate new Boolean variables from terms that appear as IF tests.</p> <p>Sometimes, the terms from which these variables are generated have interdependent meanings. For example, if Boolean variable @('a') represents @('(logbitp 5 x)') and Boolean variable @('b') represents @('(integerp x)'), it should be impossible for @('a') to be true when @('b') is false. However, by default, the Boolean variables generated this way are unconstrained. When this sort of interdependency among variables exists but is not accounted for, it can cause GL to find @(see false-counterexamples).</p> <p>@('Def-gl-boolean-constraint') provides a mechanism to make such constraints known to GL. While symbolically executing a form, GL maintains a constraint, a Boolean formula known to always be true (under the evolving assignment of Boolean variables to terms). A constraint rule generated by @('def-gl-boolean-constraint') is triggered when a Boolean variable is generated from an IF condition term and can cause the constraint to be updated with a new conjunct.</p> <p>A Boolean constraint rule is formulated as follows:</p> @({ (def-gl-boolean-constraint gl-logbitp-implies-integerp :bindings ((bit (logbitp n x)) (intp (integerp x))) :body (implies bit intp) ;; optional arguments: :syntaxp ... :hints ...) }) <p>This generates a proof obligation:</p> @({ (defthm gl-logbitp-implies-integerp (let ((bit (gl-bool-fix (logbitp n x))) (intp (gl-bool-fix (integerp x)))) (implies bit intp)) :hints ... :rule-classes nil) }) <p>(The optional :hints argument to def-gl-boolean-constraint provides the hints for the proof obligation.)</p> <p>Once this rule is established, GL will generate constraints as follows:</p> <ul> <li>When a Boolean variable @('a') is generated from an IF condition matching @('(logbitp n x)'), GL will search for an existing generated Boolean variable @('b') whose IF condition was @('(integerp x)') and, if it exists, add the constraint @('(implies a b)').</li> <li>Conversely, when a Boolean variable @('b') is generated from an IF condition matching @('(integerp x)'), GL will search for existing generated Boolean variables @('ai') matching @('(logbitp n x)'), and for each of them, add the constraint @('(implies ai b)').</li> </ul> <p>To show that this rule works, you can verify that the following events fail prior to introducing the constraint rule above, but succeed after:</p> @({ (def-gl-thm foo1 :hyp t :concl (if (integerp x) t (not (logbitp n x))) :g-bindings nil :rule-classes nil) (def-gl-thm foo2 :hyp t :concl (if (logbitp n x) (integerp x) t) :g-bindings nil :rule-classes nil) }) " (defmacro def-gl-boolean-constraint (name &key bindings (syntaxp ''t) body hints) `(make-event (def-gl-boolean-constraint-fn ',GL::NAME ',GL::BINDINGS ',GL::SYNTAXP ',GL::BODY ',GL::HINTS state))))
gbc-signaturefunction
(defun gbc-signature (common-vars subst) (if (atom common-vars) nil (hons (cdr (assoc (car common-vars) subst)) (gbc-signature (cdr common-vars) subst))))
gbc-extend-substsfunction
(defun gbc-extend-substs (lit-subst partial-substs) (if (atom partial-substs) nil (cons (append lit-subst (car partial-substs)) (gbc-extend-substs lit-subst (cdr partial-substs)))))
gbc-substs-check-syntaxpfunction
(defun gbc-substs-check-syntaxp (substs thmname syntaxp state) (declare (xargs :stobjs state :verify-guards nil)) (b* (((when (atom substs)) nil) ((mv err ok) (magic-ev syntaxp (car substs) state t t)) ((when (or err (not ok))) (gbc-substs-check-syntaxp (cdr substs) thmname syntaxp state))) (cons (cons thmname (car substs)) (gbc-substs-check-syntaxp (cdr substs) thmname syntaxp state))))
gbc-sort-substs-into-sigtablefunction
(defun gbc-sort-substs-into-sigtable (substs common-vars sigtable) (b* (((when (atom substs)) sigtable) (subst (car substs)) (sig (gbc-signature common-vars subst)) (sig-substs (cdr (hons-get sig sigtable))) (sigtable (hons-acons sig (cons subst sig-substs) sigtable))) (gbc-sort-substs-into-sigtable (cdr substs) common-vars sigtable)))
gbc-unbound-lits-add-to-existing-tuplefunction
(defun gbc-unbound-lits-add-to-existing-tuple (rule existing-lits lit substs tuples) (b* (((when (atom tuples)) (mv nil tuples)) ((constraint-tuple x) (car tuples)) ((unless (and (equal rule x.rule) (equal existing-lits x.existing-lits) (equal lit x.matching-lit))) (b* (((mv found rest) (gbc-unbound-lits-add-to-existing-tuple rule existing-lits lit substs (cdr tuples))) ((when found) (mv t (cons (car tuples) rest)))) (mv nil tuples))) (sigtable (gbc-sort-substs-into-sigtable substs x.common-vars x.sig-table))) (mv t (cons (constraint-tuple rule existing-lits lit x.common-vars x.existing-vars sigtable) (cdr tuples)))))
gbc-unbound-lits-add-tuplesfunction
(defun gbc-unbound-lits-add-tuples (litvars rule existing-lits existing-vars substs ccat) (b* (((when (atom litvars)) ccat) (var (car litvars)) ((constraint-rule r) rule) (lit (cdr (hons-assoc-equal var r.lit-alist))) (fnsym (car lit)) (tuples (cdr (hons-get fnsym ccat))) ((mv found tuples) (gbc-unbound-lits-add-to-existing-tuple rule existing-lits var substs tuples)) ((when found) (hons-acons fnsym tuples ccat)) (lit-vars (mergesort (simple-term-vars lit))) (common-vars (intersect existing-vars lit-vars)) (sigtable (gbc-sort-substs-into-sigtable substs common-vars nil)) (new-tuple (constraint-tuple rule existing-lits var common-vars existing-vars sigtable))) (hons-acons fnsym (cons new-tuple tuples) ccat)))
gbc-process-new-lit-tuplefunction
(defun gbc-process-new-lit-tuple (lit tuple ccat state) (declare (xargs :stobjs state :verify-guards nil)) (b* (((constraint-tuple x) tuple) ((constraint-rule r) x.rule) (pat (cdr (hons-assoc-equal x.matching-lit r.lit-alist))) ((mv ok lit-subst) (glcp-unify-term/gobj pat lit nil)) ((unless ok) (mv nil ccat)) (sig (gbc-signature x.common-vars lit-subst)) (partial-substs (cdr (hons-get sig x.sig-table))) (new-substs (gbc-extend-substs lit-subst partial-substs)) (rest-litvars (set-difference-eq (strip-cars r.lit-alist) (cons x.matching-lit x.existing-lits))) ((unless rest-litvars) (b* ((substs (gbc-substs-check-syntaxp new-substs r.thmname r.syntaxp state))) (mv substs ccat))) (new-existing-vars (union (mergesort (strip-cars lit-subst)) x.existing-vars)) (ccat (gbc-unbound-lits-add-tuples rest-litvars x.rule (insert x.matching-lit x.existing-lits) new-existing-vars new-substs ccat))) (mv nil ccat)))
gbc-process-new-lit-tuplesfunction
(defun gbc-process-new-lit-tuples (lit tuples ccat state) (declare (xargs :stobjs state :verify-guards nil)) (b* (((when (atom tuples)) (mv nil ccat)) ((mv substs1 ccat) (gbc-process-new-lit-tuple lit (car tuples) ccat state)) ((mv substs-rest ccat) (gbc-process-new-lit-tuples lit (cdr tuples) ccat state))) (mv (append substs1 substs-rest) ccat)))
other
(defund gbc-process-new-lit (lit ccat state) (declare (xargs :stobjs state :verify-guards nil)) (b* (((unless (and (consp lit) (eq (tag lit) :g-apply))) (mv nil ccat)) (tuples (cdr (hons-get (g-apply->fn lit) ccat)))) (gbc-process-new-lit-tuples lit tuples ccat state)))
gbc-tuples-make-fastfunction
(defun gbc-tuples-make-fast (x) (if (atom x) nil (cons (change-constraint-tuple (car x) :sig-table (make-fast-alist (constraint-tuple->sig-table (car x)))) (gbc-tuples-make-fast (cdr x)))))
gbc-tuples-freefunction
(defun gbc-tuples-free (x) (if (atom x) nil (prog2$ (fast-alist-free (constraint-tuple->sig-table (car x))) (gbc-tuples-free (cdr x)))))
gbc-db-make-fast-recfunction
(defun gbc-db-make-fast-rec (x acc) (b* (((when (atom x)) acc) (acc (if (and (consp (car x)) (not (hons-get (caar x) acc))) (hons-acons (caar x) (gbc-tuples-make-fast (cdar x)) acc) acc))) (gbc-db-make-fast-rec (cdr x) acc)))
other
(defund gbc-db-make-fast (x) (gbc-db-make-fast-rec x nil))
gbc-db-free-recfunction
(defun gbc-db-free-rec (x) (if (atom x) nil (prog2$ (and (consp (car x)) (gbc-tuples-free (cdar x))) (gbc-db-free-rec (cdr x)))))
other
(defund gbc-db-free (x) (gbc-db-free-rec (fast-alist-free x)))