update guide

This commit is contained in:
Simon Cruanes 2021-07-04 01:29:13 -04:00
parent 57e2290151
commit 9b43630990

View file

@ -160,11 +160,11 @@ Now we can define new terms and constants. Let's try to define
a few boolean constants named "p", "q", "r": a few boolean constants named "p", "q", "r":
```ocaml ```ocaml
# let p = Term.const_undefined_const tstore (ID.make "p") @@ Ty.bool();; # let p = Term.const_undefined tstore (ID.make "p") @@ Ty.bool();;
val p : Term.t = p val p : Term.t = p
# let q = Term.const_undefined_const tstore (ID.make "q") @@ Ty.bool();; # let q = Term.const_undefined tstore (ID.make "q") @@ Ty.bool();;
val q : Term.t = q val q : Term.t = q
# let r = Term.const_undefined_const tstore (ID.make "r") @@ Ty.bool();; # let r = Term.const_undefined tstore (ID.make "r") @@ Ty.bool();;
val r : Term.t = r val r : Term.t = r
# Term.ty p;; # Term.ty p;;
@ -305,7 +305,6 @@ It comes from the fact that `p=q`, but `p` and `q` imply contradictory
formulas (`r` and `¬r`), so when we force `p` to be true, `q` is true too formulas (`r` and `¬r`), so when we force `p` to be true, `q` is true too
and the contradiction is triggered. and the contradiction is triggered.
## A bit of arithmetic ## A bit of arithmetic
We can solve linear real arithmetic problems as well. We can solve linear real arithmetic problems as well.
@ -321,9 +320,9 @@ Create a few arithmetic constants.
```ocaml ```ocaml
# let real = Ty.real ();; # let real = Ty.real ();;
val real : Ty.t = Real val real : Ty.t = Real
# let a = Term.const_undefined_const tstore (ID.make "a") real;; # let a = Term.const_undefined tstore (ID.make "a") real;;
val a : Term.t = a val a : Term.t = a
# let b = Term.const_undefined_const tstore (ID.make "b") real;; # let b = Term.const_undefined tstore (ID.make "b") real;;
val b : Term.t = b val b : Term.t = b
# Term.ty a;; # Term.ty a;;
@ -369,6 +368,74 @@ This just showed that `a=1, b=1/2, a>=b` is unsatisfiable.
The junk assumption `p` was not used during the proof The junk assumption `p` was not used during the proof
and therefore doesn't appear in the unsat core we extract from `res`. and therefore doesn't appear in the unsat core we extract from `res`.
## Functions and congruence closure
We can define function symbols, not just constants. Let's also define `u`,
an uninterpreted type.
```ocaml
# let u = Ty.atomic_uninterpreted (ID.make "u");;
val u : Ty.t = u/12
# let u1 = Term.const_undefined tstore (ID.make "u1") u;;
val u1 : Term.t = u1
# let u2 = Term.const_undefined tstore (ID.make "u2") u;;
val u2 : Term.t = u2
# let u3 = Term.const_undefined tstore (ID.make "u3") u;;
val u3 : Term.t = u3
# let f1 = Fun.mk_undef' (ID.make "f1") [u] u;;
val f1 : Fun.t = f1/16
# Fun.view f1;;
- : Fun.view =
Sidekick_base.Fun.Fun_undef
{Sidekick_base.Base_types.fun_ty_args = [u/12]; fun_ty_ret = u/12}
# let f1_u1 = Term.app_fun_l tstore f1 [u1];;
val f1_u1 : Term.t = (f1 u1)
# Term.ty f1_u1;;
- : Ty.t = u/12
# Term.view f1_u1;;
- : Term.t Term.view = Sidekick_base.Term.App_fun (f1/16, [|u1|])
```
Anyway, Sidekick knows how to reason about functions.
```ocaml
# let solver = Solver.create ~theories:[] tstore () ();;
val solver : Solver.t = <abstr>
# (* helper *)
let appf1 x = Term.app_fun_l tstore f1 x;;
val appf1 : Term.t list -> Term.t = <fun>
# Solver.assert_term solver (Term.eq tstore u2 (appf1 [u1]));;
- : unit = ()
# Solver.assert_term solver (Term.eq tstore u3 (appf1 [u2]));;
- : unit = ()
# Solver.assert_term solver (Term.eq tstore u1 (appf1 [appf1 [u1]]));;
- : unit = ()
# Solver.assert_term solver
(Term.eq tstore u1 (appf1 [appf1 [appf1 [u1]]]));;
- : unit = ()
# Solver.solve solver
~assumptions:[Solver.mk_atom_t' solver ~sign:false (Term.eq tstore u1 (appf1[u1]))];;
- : Solver.res =
Sidekick_base_solver.Solver.Unsat
{Sidekick_base_solver.Solver.proof = <lazy>; unsat_core = <lazy>}
# Solver.solve solver
~assumptions:[Solver.mk_atom_t' solver ~sign:false (Term.eq tstore u2 u3)];;
- : Solver.res =
Sidekick_base_solver.Solver.Unsat
{Sidekick_base_solver.Solver.proof = <lazy>; unsat_core = <lazy>}
```
Assuming: `f1(u1)=u2, f1(u2)=u3, f1^2(u1)=u1, f1^3(u1)=u1`,
we proved that `f1(u1)=u1`, then that `u2=u3` because both are equal to `u1`.
## Extending sidekick ## Extending sidekick
The most important function here is `Solver.add_theory` The most important function here is `Solver.add_theory`