47 lines
1.7 KiB
Agda
47 lines
1.7 KiB
Agda
module Z3
|
|
|
|
import Prelude
|
|
import Node
|
|
|
|
ptype Context
|
|
-- Flag if optimizer or solver
|
|
ptype Solver : Bool → U
|
|
ptype Arith
|
|
ptype Z3Bool
|
|
ptype Model
|
|
ptype Z3
|
|
|
|
pfunc initZ3 : Promise Z3 := `require('z3-solver').init()`
|
|
pfunc z3ResetMemory : Promise Z3 := `(z3) => z3.Z3.reset_memory()`
|
|
pfunc initContext : Z3 → String → Context := `(z3, name) => z3.Context(name)`
|
|
|
|
pfunc newSolver : Context → Solver False := `(Context) => new Context.Solver()`
|
|
pfunc newOptimizer : Context → Solver True := `(Context) => new Context.Optimize()`
|
|
|
|
|
|
-- These probably should be IO or Promise
|
|
pfunc freshInt : {{Context}} → Promise Arith := `(Context) => Promise.resolve(Context.Int.fresh())`
|
|
pfunc z3const : {{Context}} → String → Arith := `(Context, name) => Context.Int.const(name)`
|
|
pfunc arith_add : Arith → Arith → Arith := `(a,b) => a.add(b)`
|
|
pfunc z3int : {{Context}} → Int → Arith := `(Context,a) => Context.Int.val(a)`
|
|
|
|
-- We can't overload operators for these because of the return type
|
|
|
|
pfunc z3eq : Arith → Arith → Z3Bool := `(a,b) => a.eq(b)`
|
|
pfunc z3ge : Arith → Arith → Z3Bool := `(a,b) => a.ge(b)`
|
|
|
|
pfunc z3add : ∀ b. Solver b → Z3Bool → Promise Unit := `(_, solver, exp) => Promise.resolve(solver.add(exp))`
|
|
pfunc z3minimize : Solver True → Arith → Promise Unit := `(solver, exp) => Promise.resolve(solver.minimize(exp))`
|
|
|
|
pfunc z3check : ∀ b. Solver b → Promise String := `(b, solver) => solver.check()`
|
|
|
|
pfunc getModel : ∀ b. Solver b → Promise Model := `(b, solver) => Promise.resolve(solver.model())`
|
|
|
|
pfunc getInt : {{Model}} → Arith → Int := `(model, exp) => {
|
|
let n = +(model.eval(exp).toString())
|
|
return isNaN(n) ? 0 : n
|
|
}`
|
|
|
|
instance Add Arith where
|
|
a + b = arith_add a b
|