Filtering...

run

books/projects/smtlink/trusted/run
other
(in-package "SMT")
other
(include-book "std/io/read-string" :dir :system)
other
(include-book "centaur/misc/tshell" :dir :system)
other
(include-book "system/f-put-global" :dir :system)
other
(include-book "../verified/hint-interface")
other
(defttag :tshell)
other
(value-triple (tshell-ensure))
other
(defttag :read-string)
other
(set-state-ok t)
other
(defsection smt-run
  :parents (trusted)
  :short "SMT-run runs the configured SMT solver then interprets the result and feed it back to ACL2."
  (define smt-run
    ((fname stringp) (smt-conf smtlink-config-p)
      state)
    :returns (mv (exit-status natp)
      (lines string-listp)
      (state state-p1 :hyp (state-p1 state)))
    (let ((cmd (concatenate 'string
           (smtlink-config->smt-cmd smt-conf)
           " "
           fname)))
      (time$ (tshell-call cmd :print nil :save t)
        :msg "; SMT solver: `~s0`: ~st sec, ~sa bytes~%"
        :args (list cmd))))
  (define smt-interpret
    ((fname stringp) (rm-file booleanp)
      (smt-conf smtlink-config-p)
      (state))
    (declare (xargs :stobjs state))
    :returns (mv (proved? booleanp) (state))
    :verify-guards nil
    (b* (((mv exit-status lines state) (smt-run fname smt-conf state)) ((unless (equal exit-status 0)) (mv (er hard?
              'smt-run=>smt-interpret
              "Z3 failure: ~q0"
              lines)
            state))
        ((if (equal lines nil)) (mv (er hard?
              'smt-run=>smt-interpret
              "Nothing returned from SMT solver.")
            state))
        ((if (equal (car lines) "proved")) (b* (((unless (equal rm-file nil)) (mv t state)) (cmd (concatenate 'string "rm -f " fname))
              ((mv exit-status-rm lines-rm state) (time$ (tshell-call cmd :print nil :save t)
                  :msg ""
                  :args (list cmd))))
            (if (equal exit-status-rm 0)
              (mv t state)
              (mv (er hard?
                  'smt-run=>smt-interpret
                  "Remove file error.~% ~p0~%"
                  lines-rm)
                state))))
        ((mv err str state) (read-string (car lines) nil :state state))
        ((unless (equal err nil)) (prog2$ (er hard?
              'smt-run=>smt-interpret
              "Read-string error.~%~p0~%"
              err)
            (mv nil state)))
        ((unless (and (true-listp str)
             (listp (car str))
             (equal (caar str) 'quote)
             (consp (cdar str)))) (prog2$ (er hard?
              'smt-run=>smt-interpret
              "We can't prove anything about the ~
thing returned by read-string. So we add a check for it. It's surprising that ~
the check for (true-listp str) and (consp (car str)) failed: ~q0"
              str)
            (mv nil state)))
        (- (cw "Possible counter-example found: ~p0~%One can access it ~
                 through global variable SMT-cex by doing (@ SMT-cex).~%"
            (unquote (car str))))
        (state (f-put-global 'smt-cex nil state))
        (state (f-put-global 'smt-cex (car str) state)))
      (mv nil state)))
  (encapsulate nil
    (local (defthm endp-of-not-consp-of-string-listp
        (implies (and (string-listp x) (not (consp x)))
          (not x))
        :rule-classes nil))
    (local (defthm stringp-of-consp-of-string-listp
        (implies (and (string-listp x) (consp x))
          (stringp (car x)))
        :rule-classes nil))
    (verify-guards smt-interpret
      :guard-debug t
      :hints (("goal" :in-theory (disable f-put-global)
         :use ((:instance endp-of-not-consp-of-string-listp
            (x (mv-nth 1
                (smt-run fname smt-conf state)))) (:instance stringp-of-consp-of-string-listp
             (x (mv-nth 1
                 (smt-run fname smt-conf state))))))))))