other
(in-package "CGEN")
other
(include-book "basis")
other
(include-book "utilities")
other
(include-book "type")
other
(include-book "infer-enum-shape")
other
(defrec enum-info% (domain-size category expr expr2 min-rec-depth max-rec-depth) nil)
enum-info%-pfunction
(defun enum-info%-p (v) (declare (xargs :guard t)) (case-match v (('enum-info% domain-size category expr expr2 min-rec-depth max-rec-depth) (and (fixnump domain-size) (fixnump min-rec-depth) (fixnump max-rec-depth) (member-eq category '(:singleton :function :defconst :numeric-range :empty)) (pseudo-termp expr) (pseudo-termp expr2)))))
abs/complexfunction
(defun abs/complex (c) (declare (xargs :guard (complex/complex-rationalp c))) (complex (abs (realpart c)) (abs (imagpart c))))
abs/acl2-numberfunction
(defun abs/acl2-number (x) (declare (xargs :guard (acl2-numberp x))) (if (complex/complex-rationalp x) (abs/complex x) (abs x)))
mod/complexfunction
(defun mod/complex (c m) (declare (xargs :guard (and (rationalp m) (> m 0) (complex/complex-rationalp c)))) (complex (mod (realpart c) m) (imagpart c)))
mod/acl2-numberfunction
(defun mod/acl2-number (x m) (declare (xargs :guard (and (acl2-numberp x) (rationalp m) (> m 0)))) (if (complex/complex-rationalp x) (mod/complex x m) (mod x m)))
make-numeric-range-enum-infofunction
(defun make-numeric-range-enum-info (size exp exp2) (make enum-info% :domain-size size :min-rec-depth 0 :max-rec-depth 30 :category :numeric-range :expr exp :expr2 exp2))
other
(include-book "acl2s/defdata/builtin-combinators" :dir :system)
other
(def make-range-enum-info% (interval integer-p) (decl :sig ((non-empty-non-universal-interval-p booleanp) -> enum-info%-p) :doc "given tau-interval interval construct an enum-info% rec with appropriate enum calls") (b* ((lo (access tau-interval interval :lo)) (hi (access tau-interval interval :hi)) (lo-rel (access tau-interval interval :lo-rel)) (hi-rel (access tau-interval interval :hi-rel)) (domain (if integer-p 'integer 'rational)) (dom-size (if (and lo hi integer-p) (- (if hi-rel (1- hi) hi) (if lo-rel (1+ lo) lo)) 't))) (make-numeric-range-enum-info dom-size (make-enum-body-for-range 'r domain lo hi lo-rel hi-rel) (make-enum/acc-body-for-range 'r 'seed. domain lo hi lo-rel hi-rel))))
other
(def get-enum-info% (type range vl wrld) (decl :sig ((possible-defdata-type-p tau-interval fixnum plist-world) -> enum-info%-p) :doc "to fill") (declare (xargs :verify-guards nil)) (if (possible-constant-value-p type) (make enum-info% :domain-size 1 :min-rec-depth 0 :max-rec-depth 1 :category :singleton :expr type :expr2 `(mv ',TYPE seed.)) (let ((entry (assoc-eq type (table-alist 'type-metadata-table wrld)))) (if entry (b* ((al (cdr entry)) (ti.test-enumerator (cdr (assoc-eq :enum/test al))) (ti.test-enumerator/acc (cdr (assoc-eq :enum/test/acc al))) (ti.enumerator (cdr (assoc-eq :enumerator al))) (ti.enum-uniform (cdr (assoc-eq :enum/acc al))) (ti.size (cdr (assoc-eq :domain-size al))) (ti.pred (cdr (assoc-eq :predicate al))) (ti.min (cdr (assoc-eq :min-rec-depth al))) (ti.max (cdr (assoc-eq :max-rec-depth al))) (ti.def (cdr (assoc-eq :def al))) ((when (equal 0 ti.size)) (prog2$ (cw? (verbose-stats-flag vl) "~|Cgen/Error: size in type-info ~x0 is 0.~%" (cdr entry)) (make enum-info% :domain-size 0 :min-rec-depth 0 :max-rec-depth 1 :category :empty :expr nil :expr2 nil))) ((unless (or (eq 't ti.size) (natp ti.size))) (prog2$ (cw? (normal-output-flag vl) "~|Cgen/Error: size in type-info ~x0 should be a natural number or T.~%" (cdr entry)) (make enum-info% :domain-size 0 :min-rec-depth 0 :max-rec-depth 1 :category :empty :expr nil :expr2 nil))) ((when (or (and (consp ti.def) (eq 'range (car ti.def)) (range-subtype-p range (get-tau-int (cadr ti.def) (third ti.def)))) (and (subtype-p ti.pred 'acl2-numberp wrld) (non-empty-non-universal-interval-p range)))) (make-range-enum-info% range (subtype-p ti.pred 'integerp wrld)))) (if ti.test-enumerator (cond ((allows-arity ti.test-enumerator 1 wrld) (make enum-info% :domain-size 't :min-rec-depth 0 :max-rec-depth 30 :category :function :expr (list ti.test-enumerator 'r) :expr2 (list ti.test-enumerator/acc 'm 'seed.))) (t (prog2$ (cw? (normal-output-flag vl) "~|Cgen/Error: ~x0 should be an enum function of arity 1.~%" ti.test-enumerator) (make enum-info% :domain-size 0 :min-rec-depth 0 :max-rec-depth 0 :category :empty :expr nil :expr2 nil)))) (if (eq 't ti.size) (make enum-info% :domain-size ti.size :min-rec-depth ti.min :max-rec-depth ti.max :category :function :expr (list ti.enumerator 'r) :expr2 (list ti.enum-uniform 'm 'seed.)) (let ((stored-defconst (acl2-getprop ti.enumerator 'const wrld))) (if stored-defconst (b* ((values (second stored-defconst)) (len-v (len values)) ((unless (posp len-v)) (prog2$ (cw? (normal-output-flag vl) "~|Cgen/Error: stored-defconst ~x0 has 0 values~%" stored-defconst) (make enum-info% :domain-size 0 :min-rec-depth 0 :max-rec-depth 0 :category :empty :expr nil :expr2 nil)))) (make enum-info% :domain-size len-v :min-rec-depth 0 :max-rec-depth 30 :category (if (= len-v 1) :singleton :defconst) :expr (if (= len-v 1) `',(CAR VALUES) `(nth (mod r ,CGEN::LEN-V) ,CGEN::TI.ENUMERATOR)) :expr2 (if (= len-v 1) `(mv ',(CAR VALUES) seed.) `(mv (nth (mod seed. ,CGEN::LEN-V) ,CGEN::TI.ENUMERATOR) seed.)))) (if (allows-arity ti.enumerator 1 wrld) (make enum-info% :domain-size ti.size :min-rec-depth ti.min :max-rec-depth ti.max :category :function :expr (list ti.enumerator 'r) :expr2 (list ti.enum-uniform 'm 'seed.)) (prog2$ (cw? (normal-output-flag vl) "~|Cgen/Error: ~x0 is neither one of constant, an enum function or a values defconst.~%" ti.enumerator) (make enum-info% :domain-size 0 :category :empty :expr nil :expr2 nil)))))))) (let* ((vsym (modify-symbol "*" type "-VALUES*")) (values (second (acl2-getprop vsym 'const wrld)))) (if values (let ((len-v (len values))) (make enum-info% :domain-size len-v :min-rec-depth 0 :max-rec-depth 30 :category (if (= len-v 1) :singleton :defconst) :expr (if (= len-v 1) `',(CAR VALUES) `(nth (mod r ,CGEN::LEN-V) ,CGEN::VSYM)) :expr2 (if (= len-v 1) `(mv ',(CAR VALUES) seed.) `(mv (nth (mod seed. ,CGEN::LEN-V) ,CGEN::VSYM) seed.)))) (let ((esym (modify-symbol "NTH-" type ""))) (cond ((allows-arity esym 1 wrld) (make enum-info% :domain-size t :min-rec-depth 0 :max-rec-depth 30 :category :function :expr `(,CGEN::ESYM r) :expr2 `(mv-let (r seed.) (random-natural-seed seed.) (mv (,CGEN::ESYM r) seed.)))) (t (prog2$ (cw? (normal-output-flag vl) "~|Cgen/Error: ~x0 doesnt appear to be a type.~%" type) (make enum-info% :domain-size 0 :category :empty :expr nil :expr2 nil)))))))))))
symbol-unsigned-60bits-alistpfunction
(defun symbol-unsigned-60bits-alistp (v) (declare (xargs :guard t)) (if (atom v) (null v) (and (consp (car v)) (symbolp (caar v)) (unsigned-60bits-p (cdar v)) (symbol-unsigned-60bits-alistp (cdr v)))))
other
(defthm symbol-unsigned-60bits-alistp-forwards-to-symbol-alistp (implies (symbol-unsigned-60bits-alistp x) (symbol-alistp x)) :rule-classes :forward-chaining)
|next BE args|function
(defun |next BE args| (be.) "naive bounded exhaustive enumeration." (declare (xargs :guard (and (true-listp be.) (consp be.) (symbol-alistp be.)))) (b* (((cons v m) (car be.)) (m~ (1+ (nfix m)))) (append (cdr be.) (list (cons v m~)))))
other
(def make-guard-var-assoc-eq (vars alst) (decl :sig ((symbol-alistp symbol) -> all) :doc "helper function to make-next-sigma") (if (endp vars) nil (cons `(assoc-eq ',(CAR CGEN::VARS) ,CGEN::ALST) (make-guard-var-assoc-eq (cdr vars) alst))))
other
(def cs%-enumcalls-defdata (cs% vl wrld) (decl :sig ((cs%-p fixnump plist-worldp) -> (mv fixnum (cons pseudo-termp pseudo-termp))) :doc "see cs%-enumcalls") (declare (xargs :verify-guards nil)) (case-match cs% (('cs% defdata-type & & range & &) (b* ((enum-info% (get-enum-info% defdata-type range vl wrld))) (mv (access enum-info% domain-size) (access enum-info% min-rec-depth) (access enum-info% max-rec-depth) (list (access enum-info% expr) (access enum-info% expr2))))) (& (prog2$ (cw? (normal-output-flag vl) "~|Cgen/Error: BAD record cs% passed to cs%-enumcalls") (mv 0 0 0 nil)))))
other
(def cs%-enumcalls (cs% vl wrld bound-vars) (decl :sig ((cs%-p fixnump plist-worldp symbol-listp) -> (mv fixnum (cons pseudo-termp pseudo-termp))) :doc "for each cs% record we translate it into the a (mv size min-rec-depth max-rec-depth (list enumcall enumcall2)), where the enumcall is an expression that when evaluated gives a value (with random distribution) of correct type/constraint and size is the size of the type i.e the set of value satisfied by the constraint. enumcall2 is a similar expression but with the random seed accumulated/threaded uniformly. Return value of (mv 0 nil) stands for an error and is recognized by the caller function as such.") (declare (xargs :verify-guards nil)) (case-match cs% (('cs% defdata-type & 'empty-eq-constraint range 'empty-mem-constraint &) (b* ((enum-info% (get-enum-info% defdata-type range vl wrld))) (mv (access enum-info% domain-size) (access enum-info% min-rec-depth) (access enum-info% max-rec-depth) (list (access enum-info% expr) (access enum-info% expr2))))) (('cs% defdata-type & eq-constraint range 'empty-mem-constraint &) (b* ((?eq-vs (all-vars eq-constraint)) (?remaining (set-difference-eq eq-vs bound-vars))) (if remaining (b* ((enum-info% (get-enum-info% defdata-type range vl wrld))) (mv (access enum-info% domain-size) (access enum-info% min-rec-depth) (access enum-info% max-rec-depth) (list (access enum-info% expr) (access enum-info% expr2)))) (mv 1 0 1 (list eq-constraint (list 'mv eq-constraint 'seed.)))))) (('cs% defdata-type & 'empty-eq-constraint range mem-constraint &) (b* ((mem-vs (all-vars mem-constraint)) (remaining (set-difference-eq mem-vs bound-vars)) (enum-info% (get-enum-info% defdata-type range vl wrld))) (if remaining (mv (access enum-info% domain-size) (access enum-info% min-rec-depth) (access enum-info% max-rec-depth) (list (access enum-info% expr) (access enum-info% expr2))) (mv :mem 0 30 (list `(let ((len-v (len ,CGEN::MEM-CONSTRAINT))) (if (zp len-v) ,(CGEN::ACCESS CGEN::ENUM-INFO% CGEN::EXPR) (nth (mod r len-v) ,CGEN::MEM-CONSTRAINT))) `(let ((len-v (len ,CGEN::MEM-CONSTRAINT))) (if (zp len-v) ,(CGEN::ACCESS CGEN::ENUM-INFO% CGEN::EXPR2) (mv (nth (mod seed. len-v) ,CGEN::MEM-CONSTRAINT) seed.)))))))) (& (prog2$ (cw? (normal-output-flag vl) "~|Cgen/Error: BAD record cs% passed to cs%-enumcalls") (mv 0 0 0 nil)))))
other
(def make-next-sigma_mv-let
(v-cs%-alst seen-vars
n
i
use-fixers-p
vl
wrld
body)
(decl :sig ((symbol-alistp symbol-listp
fixnum
fixnum
booleanp
fixnum
plist-worldp
pseudo-termp) ->
pseudo-termp)
:doc "helper function to make-next-sigma")
(declare (ignorable n i))
(f* ((_mv-value (v min max exp exp2)
`(case sampling-method
(:uniform-random (b* (((mv ?m seed.) (choose-size ,MIN ,MAX seed.)) ((mv val seed.) ,CGEN::EXP2))
(mv seed. be. val)))
(:random (b* (((mv ?r seed.) (random-natural-seed seed.)))
(mv seed. be. ,EXP)))
(:be (b* ((?r (cdr (assoc-eq ',CGEN::V be.))))
(mv seed. (|next BE args| be.) ,EXP)))
(otherwise (mv seed. be. '0)))))
(if (endp v-cs%-alst)
body
(b* (((cons var cs%) (car v-cs%-alst)) ((mv &
min-rec-depth
max-rec-depth
(list exp exp2)) (if use-fixers-p
(cs%-enumcalls-defdata cs% vl wrld)
(cs%-enumcalls cs%
vl
wrld
seen-vars))))
`(mv-let (seed. be. ,CGEN::VAR)
,(CGEN::_MV-VALUE CGEN::VAR CGEN::MIN-REC-DEPTH CGEN::MAX-REC-DEPTH EXP
CGEN::EXP2)
(declare (ignorable ,CGEN::VAR))
,(CGEN::MAKE-NEXT-SIGMA_MV-LET (CDR CGEN::V-CS%-ALST)
(CONS CGEN::VAR CGEN::SEEN-VARS) CGEN::N CGEN::I CGEN::USE-FIXERS-P CGEN::VL
CGEN::WRLD CGEN::BODY))))))
displayed-rangefunction
(defun displayed-range (interval) (b* ((lo (access tau-interval interval :lo)) (hi (access tau-interval interval :hi)) (lo-rel (access tau-interval interval :lo-rel)) (hi-rel (access tau-interval interval :hi-rel))) (cond ((and lo hi) `(,CGEN::LO ,(IF CGEN::LO-REL '< '<=) '_ ,(IF CGEN::HI-REL '< '<=) ,CGEN::HI)) (lo `(,(IF CGEN::LO-REL '> '>=) ,CGEN::LO)) (t `(,(IF CGEN::HI-REL '< '<=) ,CGEN::HI)))))
other
(def displayed-defdata-type/eq-constraint (cs% computed-vars) (decl :sig ((cs%-p symbol-listp) -> (mv fixnum pseudo-termp)) :doc "for each cs% record we translate it to defdata-type or equality constraint that will be used for enumeration. it shadows cs%-enumcall") (case-match cs% (('cs% defdata-type & 'empty-eq-constraint range 'empty-mem-constraint &) (if (non-empty-non-universal-interval-p range) (list :type defdata-type :range (displayed-range range)) defdata-type)) (('cs% defdata-type & eq-constraint range 'empty-mem-constraint &) (b* ((eq-vs (all-vars eq-constraint)) (remaining (set-difference-eq eq-vs computed-vars))) (if remaining (if (non-empty-non-universal-interval-p range) (list :type defdata-type :range (displayed-range range)) defdata-type) eq-constraint))) (('cs% defdata-type & 'empty-eq-constraint range mem-constraint &) (b* ((mem-vs (all-vars mem-constraint)) (remaining (set-difference-eq mem-vs computed-vars))) (if remaining (if (non-empty-non-universal-interval-p range) (list :type defdata-type :range (displayed-range range)) defdata-type) (list :enum mem-constraint)))) (& 'bad-type)))
other
(def displayed-enum-alist (v-cs%-alst ans.) (decl :sig ((symbol-cs%-alist symbol-alist) -> symbol-alist) :doc "given an alist mapping variables to cs% records (in dependency order), we walk down the alist, translating each type constraint to the corresponding enumerator type/expr to be displayed in verbose mode") (if (endp v-cs%-alst) (reverse ans.) (b* (((cons x cs%) (car v-cs%-alst)) (type (displayed-defdata-type/eq-constraint cs% (strip-cars ans.)))) (displayed-enum-alist (cdr v-cs%-alst) (cons (cons x type) ans.)))))