Filtering...

aig-sat

books/centaur/aig/aig-sat

Included Books

other
(in-package "ACL2")
include-book
(include-book "centaur/aignet/aig-cnf" :dir :system)
include-book
(include-book "centaur/satlink/top" :dir :system)
local
(local (include-book "centaur/satlink/cnf-basics" :dir :system))
local
(local (in-theory (disable nth update-nth aig-eval)))
local
(local (defthm true-listp-accumulate-aig-vars
    (equal (true-listp (mv-nth 1 (accumulate-aig-vars x nodetable acc)))
      (true-listp acc))
    :hints (("Goal" :in-theory (enable accumulate-aig-vars)))))
other
(define aig-sat
  :parents (aig)
  :short "Determine whether an AIG is satisfiable."
  ((aig "The AIG to inspect.") &key
    ((config config-p "How to invoke the SAT solver.") '*default-config*)
    ((gatesimp gatesimp-p) '(default-gatesimp))
    ((transform-config) 'nil))
  :returns (mv (status "Either :sat, :unsat, or :failed")
    (env "When :sat, an (ordinary, slow) alist binding the
                        aig vars to t/nil."))
  :long "<p>This is a convenient, high level way to ask a SAT solver whether a
Hons AIG is satisfiable.  When the AIG is satisfiable, you get back a
satisfying assignment in terms of the Hons AIG's variables.</p>

<p>This function should only fail if there is some problem with the SAT solver,
e.g., it produces output that @(see satlink) does not understand.</p>

<p>The underlying mechanism takes advantage of @(see aignet) to carry out the
<see topic='@(url aignet::aignet-cnf)'>cnf conversion</see> and @(see satlink)
to call the SAT solver.  As a picture:</p>

@({
           convert                export              dimacs
    AIG -------------> AIGNET -----------------> CNF -------> Solver
     ||                  ||                       ||            |
     ||                  ||                       ||            | interpret
  satisfying          satisfying               satisfying       |  output
   alist or  <-------  array or   <-----------  assign or  <----'
   'unsat'    convert  'unsat'      translate   'unsat'
})

<p>We simply trust the SAT solver if it says @('unsat'), but the other
translation and conversion steps are all verified.</p>"
  (b* (((local-stobjs env$ sat-lits aignet) (mv status
         env
         env$
         sat-lits
         aignet)) ((mv cnf ?lit vars sat-lits aignet) (aig->cnf aig
          sat-lits
          aignet
          :transform-config transform-config
          :gatesimp gatesimp))
      ((mv result env$) (sat cnf env$ :config config))
      ((unless (eq result :sat)) (mv result nil env$ sat-lits aignet))
      (env (aig-cnf-vals->env env$
          vars
          sat-lits
          aignet)))
    (mv :sat env env$ sat-lits aignet))
  ///
  (defthm aig-sat-when-sat
    (b* (((mv status env) (aig-sat aig
           :config config
           :transform-config transform-config
           :gatesimp gatesimp)))
      (implies (equal status :sat) (aig-eval aig env)))
    :hints (("Goal" :in-theory (disable vars-of-aig->cnf))))
  (defthm aig-sat-when-unsat
    (b* (((mv status &) (aig-sat aig
           :config config
           :transform-config transform-config
           :gatesimp gatesimp)))
      (implies (aig-eval aig env) (not (equal status :unsat))))
    :hints (("goal" :use ((:instance aig-satisfying-assign-induces-aig->cnf-satisfying-assign
          (aig aig)
          (env env)
          (gatesimp gatesimp)
          (transform-config transform-config)
          (sat-lits (create-sat-lits))
          (aignet (create-aignet))))
       :in-theory (disable aig-satisfying-assign-induces-aig->cnf-satisfying-assign)))))