mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-06 03:05:31 -05:00
update guide
This commit is contained in:
parent
57e2290151
commit
9b43630990
1 changed files with 73 additions and 6 deletions
79
doc/guide.md
79
doc/guide.md
|
|
@ -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`
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue