Filtering...

incremental-search

books/acl2s/cgen/incremental-search
other
(in-package "CGEN")
other
(include-book "simple-search")
other
(include-book "select")
other
(defttag t)
other
(set-register-invariant-risk nil)
other
(defttag nil)
other
(defloop contains-var
  (x terms)
  "filter terms that contain variable x"
  (for ((term in terms))
    (append (and (member-eq x (all-vars term))
        (list term)))))
other
(def implied-symbolic-value
  (x type h vl state)
  (decl :sig ((symbol defdata-type
       pseudo-term-listp
       fixnum
       state) ->
      (mv erp pseudo-term state))
    :mode :program :doc "Assign to x: From type get the (recursive) type for
x. then look into additional constraints from H, to infer any lower-bounds or
narrower shape. return (mv exp new-hyps), where new-hyps are
new constraints on the introduced variables")
  (b* ((additional-constraints (contains-var x h)))
    (refine-enum-shape x
      type
      additional-constraints
      vl
      state)))
remove-non-constant-value-entriesfunction
(defun remove-non-constant-value-entries
  (a)
  (declare (xargs :verify-guards nil
      :guard (alistp a)))
  (if (endp a)
    'nil
    (b* (((cons & val) (car a)) ((unless (possible-constant-value-p val)) (remove-non-constant-value-entries (cdr a))))
      (cons (car a)
        (remove-non-constant-value-entries (cdr a))))))
other
(def get-concrete-value
  (cs% partial-a
    sm
    vl
    ctx
    wrld
    state)
  (decl :sig ((fixnum cs%
       symbol-doublet-listp
       sampling-method
       fixnum
       symbol
       plist-world
       state) ->
      (mv erp
        (list pseudo-term keyword nil)
        state))
    :mode :program :doc "How: From cs% get the enumcall. trans-eval enumcall to
get value to be assigned. quote it to obtain a term. return (mv
val :decision nil), if size of type attributed to x is greater than 1,
otherwise return (mv val :implied nil) -- nil stands for empty
additional hyps")
  (f* ((_eval-single-value (call)
       (b* ((vexp (if partial-a
              `(let ,CGEN::PARTIAL-A
                (declare (ignorable ,@CGEN::BOUND-VARS))
                ,CGEN::CALL)
              call)) (- (cw? (debug-flag vl)
               "~|CEgen/Debug/incremental:  ASSIGN x to eval[~x0]~|"
               vexp)))
         (trans-eval-single-value vexp
           ctx
           state))))
    (b* ((- (assert$ (cs%-p cs%)
           'get-concrete-value)) (partial-a (remove-non-constant-value-entries partial-a))
        (bound-vars (strip-cars partial-a))
        ((mv size min max calls) (cs%-enumcalls cs%
            ctx
            wrld
            bound-vars))
        (seed. (getseed state))
        ((mv erp seed. ans state) (case sm
            (:uniform-random (b* (((mv m seed.) (choose-size min max seed.)) (call `(mv-list 2
                      (let ((seed. ,CGEN::SEED.))
                        ,(SUBST CGEN::M 'CGEN::M (SECOND CGEN::CALLS)))))
                  ((mv erp ans2 state) (_eval-single-value call)))
                (mv erp
                  (cadr ans2)
                  (car ans2)
                  state)))
            (otherwise (b* (((mv r seed.) (random-natural-seed seed.)) (call (subst r 'r (first calls)))
                  ((mv erp ans state) (_eval-single-value call)))
                (mv erp seed. ans state)))))
        ((when (or erp (equal size 0))) (mv t nil state))
        (state (putseed seed. state))
        (val-term (kwote ans)))
      (if (equal size 1)
        (value (list val-term :implied))
        (value (list val-term :decision))))))
other
(defloop get-corr-type-hyp
  (fn h)
  (for ((hyp in h))
    (if (and (consp hyp)
        (eq fn (car hyp))
        (proper-symbolp (cadr hyp)))
      (return hyp))))
other
(def assign-value
  (x cs%
    h
    partial-a
    sm
    vl
    ctx
    state)
  (decl :sig ((fixnum cs%
       pseudo-term-listp
       symbol-doublet-listp
       symbol-doublet-listp
       sampling-method
       fixnum
       symbol
       plist-world
       state) ->
      (mv erp
        (list pseudo-term keyword pseudo-term-listp)
        state))
    :mode :program :doc "assign a value (expression) to variable x under given constraints")
  (b* ((type (access cs% defdata-type)) (wrld (w state))
      (m (table-alist 'type-metadata-table wrld))
      (a (table-alist 'type-alias-table wrld))
      ((when (and (not (recursive-type-p type wrld))
           (record-p type wrld))) (b* (((mv rec-expansion field-type-hyps) (expand-record x type wrld)) (type-hyp (get-corr-type-hyp (predicate-name type a m)
                h))
            (updated-h (remove-equal type-hyp
                (union-equal field-type-hyps h))))
          (value (list rec-expansion :expand updated-h))))
      ((er ans) (implied-symbolic-value x
          type
          h
          vl
          state))
      ((list refined-term additional-hyps) ans))
    (if (or (null additional-hyps)
        (equal refined-term x))
      (b* (((er (list cval kind)) (get-concrete-value cs%
             partial-a
             sm
             vl
             ctx
             wrld
             state)))
        (value (list cval kind h)))
      (b* ((type-hyp (get-corr-type-hyp (predicate-name type a m)
             h)))
        (value (list refined-term
            :expand (remove-equal type-hyp
              (union-equal additional-hyps h))))))))
put-val-afunction
(defun put-val-a
  (name val dlist)
  "put list binding name->val in the front"
  (declare (xargs :guard (symbol-doublet-listp dlist)))
  (if (assoc-equal name dlist)
    (put-assoc-equal name
      (list val)
      dlist)
    (acons name (list val) dlist)))
other
(defrec a%
  ((hyps concl
     vars
     partial-a
     elim-bindings
     type-alist
     tau-interval-alist) ((var . cs) val
      kind
      i . inconsistent?))
  nil)
a%-pfunction
(defun a%-p
  (v)
  (declare (xargs :guard t))
  (case-match v
    (('a% (hyps concl
         vars
         partial-a
         elim-bindings
         type-alist
         tau-interval-alist)
       ((var . cs) val
         kind
         i . inconsistent?)) (and (symbol-listp vars)
        (pseudo-term-listp hyps)
        (pseudo-termp concl)
        (symbol-doublet-listp partial-a)
        (symbol-doublet-listp elim-bindings)
        (symbol-alistp type-alist)
        (symbol-alistp tau-interval-alist)
        (symbolp var)
        (pseudo-termp val)
        (member-eq kind
          (list :na :expand :implied :decision))
        (natp i)
        (booleanp inconsistent?)
        (or (null cs) (cs%-p cs))))))
a%-listpfunction
(defun a%-listp
  (v)
  (declare (xargs :guard t))
  (if (atom v)
    (null v)
    (and (a%-p (car v))
      (a%-listp (cdr v)))))
other
(def assign-propagate
  (a% name
    sm
    top-vt-alist
    vl
    ctx
    state)
  (decl :sig ((a% string
       sampling-method
       symbol-doublet-list
       fixnum
       symbol
       state) ->
      (mv erp
        (list pseudo-term-list
          pseudo-term
          symbol-list
          symbol-doublet-list
          symbol-alist
          symbol-alist
          a%)
        state))
    :mode :program :doc "assign a value to a%.x and propagate this new info to obtain the updated a%")
  (b* ((`(a% ,CGEN::LV . &) a%) ((list h
         c
         vars
         partial-a
         elim-bindings
         type-alist
         tau-interval-alist) lv)
      ((mv x i) (mv (access a% var)
          (access a% i)))
      (wrld (w state))
      (acl2-vt-dlist (var-types-alist-from-acl2-type-alist type-alist
          vars
          'nil))
      ((mv erp top+-vt-dlist) (meet-type-alist acl2-vt-dlist
          top-vt-alist
          vl
          (w state)))
      (top+-vt-dlist (if erp
          (make-weakest-type-alist vars)
          top+-vt-dlist))
      (cs% (or (access a% cs)
          (assert$ (member-eq x vars)
            (cdr (assoc-eq x
                (collect-constraints% (cons (cgen-dumb-negate-lit c) h)
                  vars
                  top+-vt-dlist
                  type-alist
                  tau-interval-alist
                  vl
                  wrld))))))
      ((mv erp ans state) (assign-value x
          cs%
          (cons (cgen-dumb-negate-lit c) h)
          partial-a
          sm
          vl
          ctx
          state))
      ((when erp) (progn$ (cw? (normal-output-flag vl)
            "~|CEGen/Error/incremental: assign-value failed (in ~s0).~|"
            name)
          (cw? (verbose-stats-flag vl)
            "~|CEGen/Stats: Call was (assign-value ~x0 ~x1 ...)~|"
            x
            cs%)
          (mv erp nil state)))
      ((list a kind updated-h) ans)
      (i (if (eq kind :decision)
          (1+ i)
          i))
      (a% (change a%
          a%
          :cs cs%
          :val a
          :kind kind
          :i i))
      ((mv erp res state) (propagate x
          a
          updated-h
          c
          vl
          state))
      (str (if erp
          "inconsistent"
          "consistent"))
      (- (cw? (verbose-stats-flag vl)
          "~%CEgen/Stats/incremental: Propagate ~x0 := ~x1 (i:~x3) was ~s2.~|"
          x
          a
          str
          i)))
    (if erp
      (value (list 'nil
          ''t
          'nil
          'nil
          'nil
          'nil
          'nil
          (change a% a% :inconsistent? t)))
      (b* (((list vars~ h~ c~) res) (cl~ (clausify-hyps-concl h~ c~))
          (type-alist~ (get-acl2-type-alist cl~))
          (tau-interval-alist~ (tau-interval-alist-clause cl~ vars~))
          (- (cw? nil
              "~% new ta = ~x0 and old ta = ~x1~%"
              type-alist~
              type-alist))
          (- (cw? nil
              "~% new tau-int-alist = ~x0 and old tau-int-alist = ~x1~%"
              tau-interval-alist~
              tau-interval-alist))
          ((mv partial-a~ elim-bindings~) (if (eq kind :expand)
              (mv partial-a
                (put-val-a x a elim-bindings))
              (mv (put-val-a x a partial-a)
                elim-bindings))))
        (value (list h~
            c~
            vars~
            partial-a~
            elim-bindings~
            type-alist~
            tau-interval-alist~
            (change a% a% :inconsistent? nil)))))))
other
(defs (incremental-search (a% a.
      name
      mv-sig-alist
      test-outcomes%
      gcs%
      vl
      cgen-state
      programp
      ctx
      state)
    (decl :sig ((a% a%-listp
         string
         symbol-alist
         test-outcomes%-p
         gcs%-p
         fixnum
         cgen-state
         booleanp
         symbolp
         state) ->
        (mv erp
          (list boolean test-outcomes% gcs%)
          state))
      :mode :program :doc "DPLL like algorithm that searches for a non-vacuous assignment to
the form P (hyps / nconcl => nil).  This form returns (mv erp (list stop?
test-outcomes% gcs%) state).  The search consists of a Select, Assign, Propagate
loop.  Any inconsistency in P results in non-chronological backtracking to the
last decision made in Assign. For more details refer to the FMCAD paper.")
    (f* ((simple-search... nil
         (simple-search name
           h
           c
           vars
           partial-a
           elim-bindings
           type-alist
           tau-interval-alist
           mv-sig-alist
           test-outcomes%
           gcs%
           vl
           cgen-state
           programp
           t
           ctx
           state)) (backtrack... nil
          (backtrack a%
            a.
            name
            mv-sig-alist
            test-outcomes%
            gcs%
            vl
            cgen-state
            programp
            ctx
            state))
        (recurse... nil
          (incremental-search a%
            a.
            name
            mv-sig-alist
            test-outcomes%
            gcs%
            vl
            cgen-state
            programp
            ctx
            state)))
      (b* (((mv erp ap-res state) (trans-eval `(assign-propagate ',CGEN::A%
               ',CGEN::NAME
               ',(CGEN::CGET CGEN::SAMPLING-METHOD)
               ',(CGEN::CGET CGEN::TOP-VT-ALIST)
               ',CGEN::VL
               ',CGEN::CTX
               state)
             ctx
             state
             t)) ((when erp) (prog2$ (cw? (normal-output-flag vl)
                "~|CEGen/Error: Aborting incremental search!~|")
              (mv t
                (list nil test-outcomes% gcs%)
                state)))
          ((list h
             c
             vars
             partial-a
             elim-bindings
             type-alist
             tau-interval-alist
             a%) (cadr (cdr ap-res))))
        (if (not (access a% inconsistent?))
          (b* (((mv erp ss-result state) (simple-search...)) ((when erp) (mv t nil state))
              ((list stop? test-outcomes% gcs%) ss-result)
              ((when stop?) (mv erp
                  (list stop? test-outcomes% gcs%)
                  state))
              ((when (or (endp vars) (endp (cdr vars)))) (backtrack...))
              (a. (cons a% a.))
              (x1 (select (cons (cgen-dumb-negate-lit c) h)
                  vl
                  (w state)))
              (a% (make a%
                  :vars vars
                  :hyps h
                  :concl c
                  :partial-a partial-a
                  :elim-bindings elim-bindings
                  :type-alist type-alist
                  :tau-interval-alist tau-interval-alist
                  :inconsistent? nil
                  :cs nil
                  :var x1
                  :val ''?
                  :kind :na :i 0)))
            (recurse...))
          (backtrack...)))))
  (backtrack (a% a.
      name
      mv-sig-alist
      test-outcomes%
      gcs%
      vl
      cgen-state
      programp
      ctx
      state)
    (decl :sig ((a%-p a%-listp
         string
         variable-alist
         test-outcomes%-p
         gcs%-p
         fixnump
         cgen-state-p
         boolean
         symbol
         state) ->
        (mv erp
          (list boolean test-outcomes% gcs%)
          state))
      :mode :program :doc "backtrack in dpll like search")
    (if (or (not (eq (access a% kind) :decision))
        (> (access a% i)
          (cget backtrack-limit)))
      (if (null a.)
        (prog2$ (cw? (verbose-stats-flag vl)
            "~|CEGen/Note: Incremental search failed to even satisfy the hypotheses.~|")
          (value (list nil test-outcomes% gcs%)))
        (b* ((a% (car a.)) (x (access a% var))
            (- (cw? (verbose-stats-flag vl)
                "~|CEGen/Stats/incremental:  Backtrack to var : ~x0 -- i = ~x1~|"
                x
                (access a% i))))
          (backtrack a%
            (cdr a.)
            name
            mv-sig-alist
            test-outcomes%
            gcs%
            vl
            cgen-state
            programp
            ctx
            state)))
      (incremental-search a%
        a.
        name
        mv-sig-alist
        test-outcomes%
        gcs%
        vl
        cgen-state
        programp
        ctx
        state))))