diff --git a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Atom/index.html b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Atom/index.html index f5487505..8541bddb 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Atom/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Atom)

Module S.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Atom)

Module S.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Lit/index.html b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Lit/index.html index 6b5bbf03..1e7d6789 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Lit/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Lit)

Module S.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Lit)

Module S.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Model/index.html b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Model/index.html index 3175d876..ed8ced21 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Model/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Model)

Module S.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Model (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Model)

Module S.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/CC/Actions/index.html b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/CC/Actions/index.html index 094375be..06f30d6c 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/CC/Expl/index.html b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/CC/Expl/index.html index 9413fb7b..342e73e0 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/CC/N/index.html b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/CC/N/index.html index 67db01cb..f3e4df16 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/CC/N/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/CC/index.html b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/CC/index.html index c4037f59..28282b6b 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/CC/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/Simplify/index.html b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/Simplify/index.html index 857d87ce..81a8e682 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/Simplify/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/index.html b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/index.html index 23aad83b..33c1fdf3 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/T/Fun/index.html b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/T/Fun/index.html index f2171a0d..9b4012e4 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/T/Fun/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/T/Term/index.html b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/T/Term/index.html index f7d04f7a..65b140c4 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/T/Term/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/T/Ty/index.html b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/T/Ty/index.html index 7d4dd0a7..57bfa85f 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/T/Ty/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/T/index.html b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/T/index.html index 1d3b9d5a..4928dbbf 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/T/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/T/index.html @@ -1,2 +1,2 @@ -T (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.T)

Module S.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.T)

Module S.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/index.html b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/index.html index 6c3fd37d..dc54ea15 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/index.html @@ -1,2 +1,2 @@ -S (sidekick-arith.Sidekick_arith_lra.Make.1-A.S)

Module 1-A.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +S (sidekick-arith.Sidekick_arith_lra.Make.1-A.S)

Module 1-A.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/module-type-THEORY/index.html b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/module-type-THEORY/index.html index 0b44929a..86110944 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/module-type-THEORY/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/Make/argument-1-A/S/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick-arith.Sidekick_arith_lra.Make.1-A.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Atom/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Atom/index.html index d0f0b510..488a322a 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Atom/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick-arith.Sidekick_arith_lra.ARG.S.Atom)

Module S.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick-arith.Sidekick_arith_lra.ARG.S.Atom)

Module S.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Lit/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Lit/index.html index 0570a036..f5c243fb 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Lit/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick-arith.Sidekick_arith_lra.ARG.S.Lit)

Module S.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick-arith.Sidekick_arith_lra.ARG.S.Lit)

Module S.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Model/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Model/index.html index 929c23f2..7654e471 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Model/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick-arith.Sidekick_arith_lra.ARG.S.Model)

Module S.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Model (sidekick-arith.Sidekick_arith_lra.ARG.S.Model)

Module S.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/CC/Actions/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/CC/Actions/index.html index d8ad0349..03ac227d 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick-arith.Sidekick_arith_lra.ARG.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick-arith.Sidekick_arith_lra.ARG.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/CC/Expl/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/CC/Expl/index.html index 530afbc0..bcf571c7 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick-arith.Sidekick_arith_lra.ARG.S.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick-arith.Sidekick_arith_lra.ARG.S.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/CC/N/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/CC/N/index.html index a530ba0e..b0bdda97 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/CC/N/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick-arith.Sidekick_arith_lra.ARG.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick-arith.Sidekick_arith_lra.ARG.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/CC/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/CC/index.html index 767441bc..90c14af1 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/CC/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick-arith.Sidekick_arith_lra.ARG.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick-arith.Sidekick_arith_lra.ARG.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/Simplify/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/Simplify/index.html index 33ca650e..8b7c530f 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/Simplify/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick-arith.Sidekick_arith_lra.ARG.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick-arith.Sidekick_arith_lra.ARG.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/index.html index 811b383a..52b7f859 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick-arith.Sidekick_arith_lra.ARG.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick-arith.Sidekick_arith_lra.ARG.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/T/Fun/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/T/Fun/index.html index ad68393f..68f7a532 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/T/Fun/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick-arith.Sidekick_arith_lra.ARG.S.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick-arith.Sidekick_arith_lra.ARG.S.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/T/Term/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/T/Term/index.html index 90066480..c8531e3e 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/T/Term/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick-arith.Sidekick_arith_lra.ARG.S.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick-arith.Sidekick_arith_lra.ARG.S.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/T/Ty/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/T/Ty/index.html index 1be93adb..d2b44da4 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/T/Ty/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick-arith.Sidekick_arith_lra.ARG.S.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick-arith.Sidekick_arith_lra.ARG.S.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/T/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/T/index.html index f364c99e..12803fbf 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/T/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/T/index.html @@ -1,2 +1,2 @@ -T (sidekick-arith.Sidekick_arith_lra.ARG.S.T)

Module S.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick-arith.Sidekick_arith_lra.ARG.S.T)

Module S.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/index.html index 04f53261..6efa6e9d 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/index.html @@ -1,2 +1,2 @@ -S (sidekick-arith.Sidekick_arith_lra.ARG.S)

Module ARG.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +S (sidekick-arith.Sidekick_arith_lra.ARG.S)

Module ARG.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/module-type-THEORY/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/module-type-THEORY/index.html index d29f2304..32c53395 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/module-type-THEORY/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-ARG/S/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick-arith.Sidekick_arith_lra.ARG.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick-arith.Sidekick_arith_lra.ARG.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Atom/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Atom/index.html index d5e950d6..dab4799b 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Atom/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick-arith.Sidekick_arith_lra.S.A.S.Atom)

Module S.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick-arith.Sidekick_arith_lra.S.A.S.Atom)

Module S.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Lit/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Lit/index.html index 050d9290..372bf2f8 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Lit/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick-arith.Sidekick_arith_lra.S.A.S.Lit)

Module S.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick-arith.Sidekick_arith_lra.S.A.S.Lit)

Module S.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Model/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Model/index.html index eb9f7da5..585fff68 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Model/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick-arith.Sidekick_arith_lra.S.A.S.Model)

Module S.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Model (sidekick-arith.Sidekick_arith_lra.S.A.S.Model)

Module S.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/CC/Actions/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/CC/Actions/index.html index 1f99b23c..17bd4cbe 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick-arith.Sidekick_arith_lra.S.A.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick-arith.Sidekick_arith_lra.S.A.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/CC/Expl/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/CC/Expl/index.html index 39b24b4b..6a7099e7 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick-arith.Sidekick_arith_lra.S.A.S.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick-arith.Sidekick_arith_lra.S.A.S.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/CC/N/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/CC/N/index.html index 227ec2ad..eec3672f 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/CC/N/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick-arith.Sidekick_arith_lra.S.A.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick-arith.Sidekick_arith_lra.S.A.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/CC/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/CC/index.html index adbdc072..19a2bd8f 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/CC/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick-arith.Sidekick_arith_lra.S.A.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick-arith.Sidekick_arith_lra.S.A.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/Simplify/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/Simplify/index.html index 880e92cb..8fa8a60c 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/Simplify/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick-arith.Sidekick_arith_lra.S.A.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick-arith.Sidekick_arith_lra.S.A.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/index.html index 9cac7d52..9a7cf104 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick-arith.Sidekick_arith_lra.S.A.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick-arith.Sidekick_arith_lra.S.A.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/T/Fun/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/T/Fun/index.html index 9c6a0793..75220d95 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/T/Fun/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick-arith.Sidekick_arith_lra.S.A.S.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick-arith.Sidekick_arith_lra.S.A.S.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/T/Term/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/T/Term/index.html index c07c7f5d..d431877c 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/T/Term/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick-arith.Sidekick_arith_lra.S.A.S.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick-arith.Sidekick_arith_lra.S.A.S.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/T/Ty/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/T/Ty/index.html index f2f1f645..6084fe0b 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/T/Ty/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick-arith.Sidekick_arith_lra.S.A.S.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick-arith.Sidekick_arith_lra.S.A.S.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/T/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/T/index.html index e46ee23a..0215eb4c 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/T/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/T/index.html @@ -1,2 +1,2 @@ -T (sidekick-arith.Sidekick_arith_lra.S.A.S.T)

Module S.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick-arith.Sidekick_arith_lra.S.A.S.T)

Module S.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/index.html index 9ac74a22..a788065e 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/index.html @@ -1,2 +1,2 @@ -S (sidekick-arith.Sidekick_arith_lra.S.A.S)

Module A.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +S (sidekick-arith.Sidekick_arith_lra.S.A.S)

Module A.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/module-type-THEORY/index.html b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/module-type-THEORY/index.html index 5d8069bb..a0b3f282 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/module-type-THEORY/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra/module-type-S/A/S/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick-arith.Sidekick_arith_lra.S.A.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick-arith.Sidekick_arith_lra.S.A.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra__/Simplex_intf/index.html b/dev/sidekick-arith/Sidekick_arith_lra__/Simplex_intf/index.html index 3ffb6777..a74fc05e 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra__/Simplex_intf/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra__/Simplex_intf/index.html @@ -1,2 +1,2 @@ -Simplex_intf (sidekick-arith.Sidekick_arith_lra__.Simplex_intf)

Module Sidekick_arith_lra__.Simplex_intf

Modular and incremental implementation of the general simplex

.

module type S = sig ... end
module type S_FULL = sig ... end
\ No newline at end of file +Simplex_intf (sidekick-arith.Sidekick_arith_lra__.Simplex_intf)

Module Sidekick_arith_lra__.Simplex_intf

Modular and incremental implementation of the general simplex

module type S = sig ... end
module type S_FULL = sig ... end
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_arith_lra__Simplex_intf/index.html b/dev/sidekick-arith/Sidekick_arith_lra__Simplex_intf/index.html index a55eac7f..02644b6b 100644 --- a/dev/sidekick-arith/Sidekick_arith_lra__Simplex_intf/index.html +++ b/dev/sidekick-arith/Sidekick_arith_lra__Simplex_intf/index.html @@ -1,2 +1,2 @@ -Sidekick_arith_lra__Simplex_intf (sidekick-arith.Sidekick_arith_lra__Simplex_intf)

Module Sidekick_arith_lra__Simplex_intf

Modular and incremental implementation of the general simplex

.

module type S = sig ... end
module type S_FULL = sig ... end
\ No newline at end of file +Sidekick_arith_lra__Simplex_intf (sidekick-arith.Sidekick_arith_lra__Simplex_intf)

Module Sidekick_arith_lra__Simplex_intf

Modular and incremental implementation of the general simplex

module type S = sig ... end
module type S_FULL = sig ... end
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_base_term/Arg/Fun/index.html b/dev/sidekick-arith/Sidekick_base_term/Arg/Fun/index.html index b59409ac..820cfdaf 100644 --- a/dev/sidekick-arith/Sidekick_base_term/Arg/Fun/index.html +++ b/dev/sidekick-arith/Sidekick_base_term/Arg/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick-arith.Sidekick_base_term.Arg.Fun)

Module Arg.Fun

type t = Fun.t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick-arith.Sidekick_base_term.Arg.Fun)

Module Arg.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t = Fun.t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_base_term/Arg/Term/index.html b/dev/sidekick-arith/Sidekick_base_term/Arg/Term/index.html index 5105ad98..723a021f 100644 --- a/dev/sidekick-arith/Sidekick_base_term/Arg/Term/index.html +++ b/dev/sidekick-arith/Sidekick_base_term/Arg/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick-arith.Sidekick_base_term.Arg.Term)

Module Arg.Term

type t = Term.t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state = Term.state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick-arith.Sidekick_base_term.Arg.Term)

Module Arg.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t = Term.t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state = Term.state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_base_term/Arg/Ty/index.html b/dev/sidekick-arith/Sidekick_base_term/Arg/Ty/index.html index a2651923..1b1346d7 100644 --- a/dev/sidekick-arith/Sidekick_base_term/Arg/Ty/index.html +++ b/dev/sidekick-arith/Sidekick_base_term/Arg/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick-arith.Sidekick_base_term.Arg.Ty)

Module Arg.Ty

type t = Ty.t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick-arith.Sidekick_base_term.Arg.Ty)

Module Arg.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t = Ty.t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick-arith/Sidekick_base_term/Arg/index.html b/dev/sidekick-arith/Sidekick_base_term/Arg/index.html index 838ad498..02443359 100644 --- a/dev/sidekick-arith/Sidekick_base_term/Arg/index.html +++ b/dev/sidekick-arith/Sidekick_base_term/Arg/index.html @@ -1,2 +1,2 @@ -Arg (sidekick-arith.Sidekick_base_term.Arg)

Module Sidekick_base_term.Arg

module Fun : sig ... end with type t = Fun.t
module Ty : sig ... end with type t = Ty.t
module Term : sig ... end with type t = Term.t and type state = Term.state
\ No newline at end of file +Arg (sidekick-arith.Sidekick_base_term.Arg)

Module Sidekick_base_term.Arg

module Fun : sig ... end with type t = Fun.t

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end with type t = Ty.t

Types

module Term : sig ... end with type t = Term.t and type state = Term.state

Term structure.

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Atom/index.html b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Atom/index.html index d2d7c43f..1afeabe6 100644 --- a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Atom/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick-bin.Sidekick_smtlib.Process.Solver.Atom)

Module Solver.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick-bin.Sidekick_smtlib.Process.Solver.Atom)

Module Solver.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Lit/index.html b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Lit/index.html index d1da2b55..914487af 100644 --- a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Lit/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick-bin.Sidekick_smtlib.Process.Solver.Lit)

Module Solver.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick-bin.Sidekick_smtlib.Process.Solver.Lit)

Module Solver.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Model/index.html b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Model/index.html index 6ecabcea..36058b5f 100644 --- a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Model/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick-bin.Sidekick_smtlib.Process.Solver.Model)

Module Solver.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Model (sidekick-bin.Sidekick_smtlib.Process.Solver.Model)

Module Solver.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/CC/Actions/index.html b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/CC/Actions/index.html index 6dbebf24..570f28d1 100644 --- a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick-bin.Sidekick_smtlib.Process.Solver.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick-bin.Sidekick_smtlib.Process.Solver.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/CC/Expl/index.html b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/CC/Expl/index.html index c5ce0f31..dd76202e 100644 --- a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick-bin.Sidekick_smtlib.Process.Solver.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick-bin.Sidekick_smtlib.Process.Solver.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/CC/N/index.html b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/CC/N/index.html index 71f6a394..08f78f87 100644 --- a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/CC/N/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick-bin.Sidekick_smtlib.Process.Solver.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick-bin.Sidekick_smtlib.Process.Solver.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/CC/index.html b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/CC/index.html index db411b4e..017ade43 100644 --- a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/CC/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick-bin.Sidekick_smtlib.Process.Solver.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick-bin.Sidekick_smtlib.Process.Solver.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/Simplify/index.html b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/Simplify/index.html index bea31ec8..44a98085 100644 --- a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/Simplify/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick-bin.Sidekick_smtlib.Process.Solver.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick-bin.Sidekick_smtlib.Process.Solver.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/index.html b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/index.html index cf07d83a..323a8387 100644 --- a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick-bin.Sidekick_smtlib.Process.Solver.Solver_internal)

Module Solver.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick-bin.Sidekick_smtlib.Process.Solver.Solver_internal)

Module Solver.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/T/Fun/index.html b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/T/Fun/index.html index 2096f3fe..db21fbcb 100644 --- a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/T/Fun/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick-bin.Sidekick_smtlib.Process.Solver.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick-bin.Sidekick_smtlib.Process.Solver.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/T/Term/index.html b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/T/Term/index.html index 14f6e815..4265fdae 100644 --- a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/T/Term/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick-bin.Sidekick_smtlib.Process.Solver.T.Term)

Module T.Term

type t = Sidekick_base_term.Term.t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state = Sidekick_base_term.Term.state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick-bin.Sidekick_smtlib.Process.Solver.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t = Sidekick_base_term.Term.t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state = Sidekick_base_term.Term.state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/T/Ty/index.html b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/T/Ty/index.html index c3fcbd0d..3a689276 100644 --- a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/T/Ty/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick-bin.Sidekick_smtlib.Process.Solver.T.Ty)

Module T.Ty

type t = Sidekick_base_term.Ty.t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state = Sidekick_base_term.Ty.state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick-bin.Sidekick_smtlib.Process.Solver.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t = Sidekick_base_term.Ty.t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state = Sidekick_base_term.Ty.state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/T/index.html b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/T/index.html index 90b86535..841f55b5 100644 --- a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/T/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/T/index.html @@ -1,2 +1,2 @@ -T (sidekick-bin.Sidekick_smtlib.Process.Solver.T)

Module Solver.T

module Fun : sig ... end
module Ty : sig ... end with type t = Sidekick_base_term.Ty.t and type state = Sidekick_base_term.Ty.state
module Term : sig ... end with type t = Sidekick_base_term.Term.t and type state = Sidekick_base_term.Term.state
\ No newline at end of file +T (sidekick-bin.Sidekick_smtlib.Process.Solver.T)

Module Solver.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end with type t = Sidekick_base_term.Ty.t and type state = Sidekick_base_term.Ty.state

Types

module Term : sig ... end with type t = Sidekick_base_term.Term.t and type state = Sidekick_base_term.Term.state

Term structure.

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/index.html b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/index.html index 99eb04a5..c069a0c9 100644 --- a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/index.html @@ -1,2 +1,2 @@ -Solver (sidekick-bin.Sidekick_smtlib.Process.Solver)

Module Process.Solver

module T : Sidekick_core.TERM with type Term.t = Sidekick_base_term.Term.t and type Term.state = Sidekick_base_term.Term.state and type Ty.t = Sidekick_base_term.Ty.t and type Ty.state = Sidekick_base_term.Ty.state
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +Solver (sidekick-bin.Sidekick_smtlib.Process.Solver)

Module Process.Solver

module T : Sidekick_core.TERM with type Term.t = Sidekick_base_term.Term.t and type Term.state = Sidekick_base_term.Term.state and type Ty.t = Sidekick_base_term.Ty.t and type Ty.state = Sidekick_base_term.Ty.state
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/module-type-THEORY/index.html b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/module-type-THEORY/index.html index 9a9872e1..2ca0e074 100644 --- a/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/module-type-THEORY/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib/Process/Solver/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick-bin.Sidekick_smtlib.Process.Solver.THEORY)

Module type Solver.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick-bin.Sidekick_smtlib.Process.Solver.THEORY)

Module type Solver.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Atom/index.html b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Atom/index.html index d81b1dc1..daf7ed64 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Atom/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick-bin.Sidekick_smtlib__.Process.Solver.Atom)

Module Solver.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick-bin.Sidekick_smtlib__.Process.Solver.Atom)

Module Solver.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Lit/index.html b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Lit/index.html index 61c82cd5..a1646054 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Lit/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick-bin.Sidekick_smtlib__.Process.Solver.Lit)

Module Solver.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick-bin.Sidekick_smtlib__.Process.Solver.Lit)

Module Solver.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Model/index.html b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Model/index.html index 332b111f..e6fd09e7 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Model/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick-bin.Sidekick_smtlib__.Process.Solver.Model)

Module Solver.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Model (sidekick-bin.Sidekick_smtlib__.Process.Solver.Model)

Module Solver.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/CC/Actions/index.html b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/CC/Actions/index.html index d6dbbc11..d13f3b0e 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick-bin.Sidekick_smtlib__.Process.Solver.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick-bin.Sidekick_smtlib__.Process.Solver.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/CC/Expl/index.html b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/CC/Expl/index.html index 12ea7d96..98f4cb6a 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick-bin.Sidekick_smtlib__.Process.Solver.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick-bin.Sidekick_smtlib__.Process.Solver.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/CC/N/index.html b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/CC/N/index.html index 7eee3a63..302f2422 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/CC/N/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick-bin.Sidekick_smtlib__.Process.Solver.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick-bin.Sidekick_smtlib__.Process.Solver.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/CC/index.html b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/CC/index.html index 8b1edaa6..c4195037 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/CC/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick-bin.Sidekick_smtlib__.Process.Solver.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick-bin.Sidekick_smtlib__.Process.Solver.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/Simplify/index.html b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/Simplify/index.html index eca71cc1..2fba6f5b 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/Simplify/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick-bin.Sidekick_smtlib__.Process.Solver.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick-bin.Sidekick_smtlib__.Process.Solver.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/index.html b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/index.html index 81f67add..17648469 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick-bin.Sidekick_smtlib__.Process.Solver.Solver_internal)

Module Solver.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick-bin.Sidekick_smtlib__.Process.Solver.Solver_internal)

Module Solver.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/T/Fun/index.html b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/T/Fun/index.html index 36844565..dfe1332d 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/T/Fun/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick-bin.Sidekick_smtlib__.Process.Solver.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick-bin.Sidekick_smtlib__.Process.Solver.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/T/Term/index.html b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/T/Term/index.html index e94d3d78..482b4eb6 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/T/Term/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick-bin.Sidekick_smtlib__.Process.Solver.T.Term)

Module T.Term

type t = Sidekick_base_term.Term.t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state = Sidekick_base_term.Term.state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick-bin.Sidekick_smtlib__.Process.Solver.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t = Sidekick_base_term.Term.t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state = Sidekick_base_term.Term.state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/T/Ty/index.html b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/T/Ty/index.html index 50c40a18..2a4db782 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/T/Ty/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick-bin.Sidekick_smtlib__.Process.Solver.T.Ty)

Module T.Ty

type t = Sidekick_base_term.Ty.t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state = Sidekick_base_term.Ty.state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick-bin.Sidekick_smtlib__.Process.Solver.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t = Sidekick_base_term.Ty.t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state = Sidekick_base_term.Ty.state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/T/index.html b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/T/index.html index a8c3df18..28fc3a8c 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/T/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/T/index.html @@ -1,2 +1,2 @@ -T (sidekick-bin.Sidekick_smtlib__.Process.Solver.T)

Module Solver.T

module Fun : sig ... end
module Ty : sig ... end with type t = Sidekick_base_term.Ty.t and type state = Sidekick_base_term.Ty.state
module Term : sig ... end with type t = Sidekick_base_term.Term.t and type state = Sidekick_base_term.Term.state
\ No newline at end of file +T (sidekick-bin.Sidekick_smtlib__.Process.Solver.T)

Module Solver.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end with type t = Sidekick_base_term.Ty.t and type state = Sidekick_base_term.Ty.state

Types

module Term : sig ... end with type t = Sidekick_base_term.Term.t and type state = Sidekick_base_term.Term.state

Term structure.

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/index.html b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/index.html index cf3a9bea..9b992178 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/index.html @@ -1,2 +1,2 @@ -Solver (sidekick-bin.Sidekick_smtlib__.Process.Solver)

Module Process.Solver

module T : Sidekick_core.TERM with type Term.t = Sidekick_base_term.Term.t and type Term.state = Sidekick_base_term.Term.state and type Ty.t = Sidekick_base_term.Ty.t and type Ty.state = Sidekick_base_term.Ty.state
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +Solver (sidekick-bin.Sidekick_smtlib__.Process.Solver)

Module Process.Solver

module T : Sidekick_core.TERM with type Term.t = Sidekick_base_term.Term.t and type Term.state = Sidekick_base_term.Term.state and type Ty.t = Sidekick_base_term.Ty.t and type Ty.state = Sidekick_base_term.Ty.state
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/module-type-THEORY/index.html b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/module-type-THEORY/index.html index 4ea73c4e..dab2b4e1 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/module-type-THEORY/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__/Process/Solver/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick-bin.Sidekick_smtlib__.Process.Solver.THEORY)

Module type Solver.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick-bin.Sidekick_smtlib__.Process.Solver.THEORY)

Module type Solver.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Atom/index.html b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Atom/index.html index e182d3fd..6e447e1a 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Atom/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick-bin.Sidekick_smtlib__Process.Solver.Atom)

Module Solver.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick-bin.Sidekick_smtlib__Process.Solver.Atom)

Module Solver.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Lit/index.html b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Lit/index.html index ac683e93..46fc7aa6 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Lit/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick-bin.Sidekick_smtlib__Process.Solver.Lit)

Module Solver.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick-bin.Sidekick_smtlib__Process.Solver.Lit)

Module Solver.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Model/index.html b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Model/index.html index e6488d1e..2beb2353 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Model/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick-bin.Sidekick_smtlib__Process.Solver.Model)

Module Solver.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Model (sidekick-bin.Sidekick_smtlib__Process.Solver.Model)

Module Solver.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/CC/Actions/index.html b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/CC/Actions/index.html index ec54717f..5b530957 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick-bin.Sidekick_smtlib__Process.Solver.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick-bin.Sidekick_smtlib__Process.Solver.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/CC/Expl/index.html b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/CC/Expl/index.html index b154aac8..9a8c7e81 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick-bin.Sidekick_smtlib__Process.Solver.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick-bin.Sidekick_smtlib__Process.Solver.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/CC/N/index.html b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/CC/N/index.html index a6d553c5..0d033b21 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/CC/N/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick-bin.Sidekick_smtlib__Process.Solver.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick-bin.Sidekick_smtlib__Process.Solver.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/CC/index.html b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/CC/index.html index 97a28f13..9d6477c7 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/CC/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick-bin.Sidekick_smtlib__Process.Solver.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick-bin.Sidekick_smtlib__Process.Solver.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/Simplify/index.html b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/Simplify/index.html index 79c260b9..040fa591 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/Simplify/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick-bin.Sidekick_smtlib__Process.Solver.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick-bin.Sidekick_smtlib__Process.Solver.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/index.html b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/index.html index 6fdc9a72..541d791b 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick-bin.Sidekick_smtlib__Process.Solver.Solver_internal)

Module Solver.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick-bin.Sidekick_smtlib__Process.Solver.Solver_internal)

Module Solver.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/T/Fun/index.html b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/T/Fun/index.html index b7d3c91c..9af8fa31 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/T/Fun/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick-bin.Sidekick_smtlib__Process.Solver.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick-bin.Sidekick_smtlib__Process.Solver.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/T/Term/index.html b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/T/Term/index.html index 0eb34184..36238d0e 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/T/Term/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick-bin.Sidekick_smtlib__Process.Solver.T.Term)

Module T.Term

type t = Sidekick_base_term.Term.t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state = Sidekick_base_term.Term.state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick-bin.Sidekick_smtlib__Process.Solver.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t = Sidekick_base_term.Term.t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state = Sidekick_base_term.Term.state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/T/Ty/index.html b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/T/Ty/index.html index 1cbf4140..8ddfb169 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/T/Ty/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick-bin.Sidekick_smtlib__Process.Solver.T.Ty)

Module T.Ty

type t = Sidekick_base_term.Ty.t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state = Sidekick_base_term.Ty.state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick-bin.Sidekick_smtlib__Process.Solver.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t = Sidekick_base_term.Ty.t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state = Sidekick_base_term.Ty.state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/T/index.html b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/T/index.html index 70ac1f35..30e17a26 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/T/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/T/index.html @@ -1,2 +1,2 @@ -T (sidekick-bin.Sidekick_smtlib__Process.Solver.T)

Module Solver.T

module Fun : sig ... end
module Ty : sig ... end with type t = Sidekick_base_term.Ty.t and type state = Sidekick_base_term.Ty.state
module Term : sig ... end with type t = Sidekick_base_term.Term.t and type state = Sidekick_base_term.Term.state
\ No newline at end of file +T (sidekick-bin.Sidekick_smtlib__Process.Solver.T)

Module Solver.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end with type t = Sidekick_base_term.Ty.t and type state = Sidekick_base_term.Ty.state

Types

module Term : sig ... end with type t = Sidekick_base_term.Term.t and type state = Sidekick_base_term.Term.state

Term structure.

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/index.html b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/index.html index 01ab01b9..84f864c1 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/index.html @@ -1,2 +1,2 @@ -Solver (sidekick-bin.Sidekick_smtlib__Process.Solver)

Module Sidekick_smtlib__Process.Solver

module T : Sidekick_core.TERM with type Term.t = Sidekick_base_term.Term.t and type Term.state = Sidekick_base_term.Term.state and type Ty.t = Sidekick_base_term.Ty.t and type Ty.state = Sidekick_base_term.Ty.state
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +Solver (sidekick-bin.Sidekick_smtlib__Process.Solver)

Module Sidekick_smtlib__Process.Solver

module T : Sidekick_core.TERM with type Term.t = Sidekick_base_term.Term.t and type Term.state = Sidekick_base_term.Term.state and type Ty.t = Sidekick_base_term.Ty.t and type Ty.state = Sidekick_base_term.Ty.state
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/module-type-THEORY/index.html b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/module-type-THEORY/index.html index 2be6b52e..9847a3be 100644 --- a/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/module-type-THEORY/index.html +++ b/dev/sidekick-bin/Sidekick_smtlib__Process/Solver/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick-bin.Sidekick_smtlib__Process.Solver.THEORY)

Module type Solver.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick-bin.Sidekick_smtlib__Process.Solver.THEORY)

Module type Solver.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/Make/Expl/index.html b/dev/sidekick/Sidekick_cc/Make/Expl/index.html index cdde1d64..f736468a 100644 --- a/dev/sidekick/Sidekick_cc/Make/Expl/index.html +++ b/dev/sidekick/Sidekick_cc/Make/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_cc.Make.Expl)

Module Make.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_cc.Make.Expl)

Module Make.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/Make/N/index.html b/dev/sidekick/Sidekick_cc/Make/N/index.html index 2f8c910a..597ac6e5 100644 --- a/dev/sidekick/Sidekick_cc/Make/N/index.html +++ b/dev/sidekick/Sidekick_cc/Make/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_cc.Make.N)

Module Make.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_cc.Make.N)

Module Make.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/Make/argument-1-A/Actions/index.html b/dev/sidekick/Sidekick_cc/Make/argument-1-A/Actions/index.html index 3573c9cd..8831b589 100644 --- a/dev/sidekick/Sidekick_cc/Make/argument-1-A/Actions/index.html +++ b/dev/sidekick/Sidekick_cc/Make/argument-1-A/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_cc.Make.1-A.Actions)

Module 1-A.Actions

module T = T
module P = P
module Lit = Lit
type t
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_cc.Make.1-A.Actions)

Module 1-A.Actions

module T = T
module P = P
module Lit = Lit
type t

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/Make/argument-1-A/Lit/index.html b/dev/sidekick/Sidekick_cc/Make/argument-1-A/Lit/index.html index 974c0eab..b3ae2940 100644 --- a/dev/sidekick/Sidekick_cc/Make/argument-1-A/Lit/index.html +++ b/dev/sidekick/Sidekick_cc/Make/argument-1-A/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_cc.Make.1-A.Lit)

Module 1-A.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_cc.Make.1-A.Lit)

Module 1-A.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/Make/argument-1-A/T/Fun/index.html b/dev/sidekick/Sidekick_cc/Make/argument-1-A/T/Fun/index.html index 832727cd..1047e65f 100644 --- a/dev/sidekick/Sidekick_cc/Make/argument-1-A/T/Fun/index.html +++ b/dev/sidekick/Sidekick_cc/Make/argument-1-A/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_cc.Make.1-A.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_cc.Make.1-A.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/Make/argument-1-A/T/Term/index.html b/dev/sidekick/Sidekick_cc/Make/argument-1-A/T/Term/index.html index 1f7e0d68..455ced84 100644 --- a/dev/sidekick/Sidekick_cc/Make/argument-1-A/T/Term/index.html +++ b/dev/sidekick/Sidekick_cc/Make/argument-1-A/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_cc.Make.1-A.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_cc.Make.1-A.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/Make/argument-1-A/T/Ty/index.html b/dev/sidekick/Sidekick_cc/Make/argument-1-A/T/Ty/index.html index 9cc20abb..db4f2bd3 100644 --- a/dev/sidekick/Sidekick_cc/Make/argument-1-A/T/Ty/index.html +++ b/dev/sidekick/Sidekick_cc/Make/argument-1-A/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_cc.Make.1-A.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_cc.Make.1-A.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/Make/argument-1-A/T/index.html b/dev/sidekick/Sidekick_cc/Make/argument-1-A/T/index.html index 6965bf85..ddf8ade7 100644 --- a/dev/sidekick/Sidekick_cc/Make/argument-1-A/T/index.html +++ b/dev/sidekick/Sidekick_cc/Make/argument-1-A/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_cc.Make.1-A.T)

Module 1-A.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_cc.Make.1-A.T)

Module 1-A.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/Make/index.html b/dev/sidekick/Sidekick_cc/Make/index.html index 4f7dbe8d..30e932e9 100644 --- a/dev/sidekick/Sidekick_cc/Make/index.html +++ b/dev/sidekick/Sidekick_cc/Make/index.html @@ -1,2 +1,2 @@ -Make (sidekick.Sidekick_cc.Make)

Module Sidekick_cc.Make

Parameters

Signature

module T = A.T
module P = A.P
module Lit = A.Lit
module Actions = A.Actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +Make (sidekick.Sidekick_cc.Make)

Module Sidekick_cc.Make

Parameters

Signature

module T = A.T
module P = A.P
module Lit = A.Lit
module Actions = A.Actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/module-type-S/Actions/index.html b/dev/sidekick/Sidekick_cc/module-type-S/Actions/index.html index 36432eee..c0ba38fe 100644 --- a/dev/sidekick/Sidekick_cc/module-type-S/Actions/index.html +++ b/dev/sidekick/Sidekick_cc/module-type-S/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_cc.S.Actions)

Module S.Actions

module T = T
module P = P
module Lit = Lit
type t
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_cc.S.Actions)

Module S.Actions

module T = T
module P = P
module Lit = Lit
type t

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/module-type-S/Expl/index.html b/dev/sidekick/Sidekick_cc/module-type-S/Expl/index.html index 08d95187..af530f38 100644 --- a/dev/sidekick/Sidekick_cc/module-type-S/Expl/index.html +++ b/dev/sidekick/Sidekick_cc/module-type-S/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_cc.S.Expl)

Module S.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_cc.S.Expl)

Module S.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/module-type-S/Lit/index.html b/dev/sidekick/Sidekick_cc/module-type-S/Lit/index.html index 07f7ec1f..dc1cd6ea 100644 --- a/dev/sidekick/Sidekick_cc/module-type-S/Lit/index.html +++ b/dev/sidekick/Sidekick_cc/module-type-S/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_cc.S.Lit)

Module S.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_cc.S.Lit)

Module S.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/module-type-S/N/index.html b/dev/sidekick/Sidekick_cc/module-type-S/N/index.html index 2ce357cb..b43380a8 100644 --- a/dev/sidekick/Sidekick_cc/module-type-S/N/index.html +++ b/dev/sidekick/Sidekick_cc/module-type-S/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_cc.S.N)

Module S.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_cc.S.N)

Module S.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/module-type-S/T/Fun/index.html b/dev/sidekick/Sidekick_cc/module-type-S/T/Fun/index.html index f6a16292..d54ff8ae 100644 --- a/dev/sidekick/Sidekick_cc/module-type-S/T/Fun/index.html +++ b/dev/sidekick/Sidekick_cc/module-type-S/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_cc.S.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_cc.S.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/module-type-S/T/Term/index.html b/dev/sidekick/Sidekick_cc/module-type-S/T/Term/index.html index e38ac849..9e51a4a5 100644 --- a/dev/sidekick/Sidekick_cc/module-type-S/T/Term/index.html +++ b/dev/sidekick/Sidekick_cc/module-type-S/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_cc.S.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_cc.S.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/module-type-S/T/Ty/index.html b/dev/sidekick/Sidekick_cc/module-type-S/T/Ty/index.html index 514208ab..35c8f779 100644 --- a/dev/sidekick/Sidekick_cc/module-type-S/T/Ty/index.html +++ b/dev/sidekick/Sidekick_cc/module-type-S/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_cc.S.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_cc.S.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/module-type-S/T/index.html b/dev/sidekick/Sidekick_cc/module-type-S/T/index.html index d6715ca5..dceb784a 100644 --- a/dev/sidekick/Sidekick_cc/module-type-S/T/index.html +++ b/dev/sidekick/Sidekick_cc/module-type-S/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_cc.S.T)

Module S.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_cc.S.T)

Module S.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_cc/module-type-S/index.html b/dev/sidekick/Sidekick_cc/module-type-S/index.html index abb645be..dd3b2862 100644 --- a/dev/sidekick/Sidekick_cc/module-type-S/index.html +++ b/dev/sidekick/Sidekick_cc/module-type-S/index.html @@ -1,2 +1,2 @@ -S (sidekick.Sidekick_cc.S)

Module type Sidekick_cc.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +S (sidekick.Sidekick_cc.S)

Module type Sidekick_cc.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/CC/Actions/index.html b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/CC/Actions/index.html index a4dbca98..ced5aeba 100644 --- a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/CC/Actions/index.html +++ b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

  • reason() should return a list of literals that are currently true.
  • lit should be a literal of interest (see CC_S.set_as_lit).

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/CC/Expl/index.html b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/CC/Expl/index.html index a13623ce..7bd495e4 100644 --- a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/CC/Expl/index.html +++ b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.CC.Expl)

Module CC.Expl

type t
val pp : t Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/CC/N/index.html b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/CC/N/index.html index e4924f41..04c2234c 100644 --- a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/CC/N/index.html +++ b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/CC/index.html b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/CC/index.html index 542ce95a..3546cc83 100644 --- a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/CC/index.html +++ b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.CC)

Module SI.CC

module T = T
module P = P
module Lit = Lit
module Actions : CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.CC)

Module SI.CC

module T = T
module P = P
module Lit = Lit
module Actions : CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/Lit/index.html b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/Lit/index.html index b4c8ca2b..4a8621a3 100644 --- a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/Lit/index.html +++ b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.Lit)

Module SI.Lit

Literals

A literal is a (preprocessed) term along with its sign. It is directly manipulated by the SAT solver.

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.Lit)

Module SI.Lit

Literals

A literal is a (preprocessed) term along with its sign. It is directly manipulated by the SAT solver.

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/Simplify/index.html b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/Simplify/index.html index f14e493d..1e286499 100644 --- a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/Simplify/index.html +++ b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.Simplify)

Module SI.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.Simplify)

Module SI.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/T/Fun/index.html b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/T/Fun/index.html index 763943db..8886b880 100644 --- a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/T/Fun/index.html +++ b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/T/Term/index.html b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/T/Term/index.html index 05369faf..ac8a1cf5 100644 --- a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/T/Term/index.html +++ b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/T/Ty/index.html b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/T/Ty/index.html index e03e14f7..a190ac83 100644 --- a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/T/Ty/index.html +++ b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/T/index.html b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/T/index.html index 754959f2..f898a41d 100644 --- a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/T/index.html +++ b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.T)

Module SI.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI.T)

Module SI.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/index.html b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/index.html index 522c2dfe..da7adbf6 100644 --- a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/index.html +++ b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/SI/index.html @@ -1,2 +1,2 @@ -SI (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI)

Module 1-M.SI

module T : TERM
module P : PROOF
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit : LIT with module T = T
type lit = Lit.t

Congruence Closure

module CC : CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +SI (sidekick.Sidekick_core.Monoid_of_repr.1-M.SI)

Module 1-M.SI

module T : TERM
module P : PROOF
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit : LIT with module T = T
type lit = Lit.t

Congruence Closure

module CC : CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/index.html b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/index.html index 4d16f268..06851994 100644 --- a/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/index.html +++ b/dev/sidekick/Sidekick_core/Monoid_of_repr/argument-1-M/index.html @@ -1,2 +1,2 @@ -1-M (sidekick.Sidekick_core.Monoid_of_repr.1-M)

Parameter Monoid_of_repr.1-M

module SI : SOLVER_INTERNAL
type t
val pp : t Fmt.printer
val name : string

name of the monoid's value (short)

val of_term : SI.CC.t -> SI.CC.N.t -> SI.T.Term.t -> t option * (SI.CC.N.t * t) list

of_term n t, where t is the term annotating node n, returns maybe_m, l, where:

  • maybe_m = Some m if t has monoid value m; otherwise maybe_m=None
  • l is a list of (u, m_u) where each u's term is a direct subterm of t and m_u is the monoid value attached to u.
val merge : SI.CC.t -> SI.CC.N.t -> t -> SI.CC.N.t -> t -> SI.CC.Expl.t -> (tSI.CC.Expl.t) Stdlib.result
\ No newline at end of file +1-M (sidekick.Sidekick_core.Monoid_of_repr.1-M)

Parameter Monoid_of_repr.1-M

module SI : SOLVER_INTERNAL
type t

Some type with a monoid structure

val pp : t Fmt.printer
val name : string

name of the monoid structure (short)

val of_term : SI.CC.t -> SI.CC.N.t -> SI.T.Term.t -> t option * (SI.CC.N.t * t) list

of_term n t, where t is the term annotating node n, must return maybe_m, l, where:

  • maybe_m = Some m if t has monoid value m; otherwise maybe_m=None
  • l is a list of (u, m_u) where each u's term is a direct subterm of t and m_u is the monoid value attached to u.
val merge : SI.CC.t -> SI.CC.N.t -> t -> SI.CC.N.t -> t -> SI.CC.Expl.t -> (tSI.CC.Expl.t) Stdlib.result

Monoidal combination of two values.

merge cc n1 mon1 n2 mon2 expl returns the result of merging monoid values mon1 (for class n1) and mon2 (for class n2) when n1 and n2 are merged with explanation expl.

returns

Ok mon if the merge is acceptable, annotating the class of n1 ∪ n2; or Error expl' if the merge is unsatisfiable. expl' can then be used to trigger a conflict and undo the merge.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/Monoid_of_repr/index.html b/dev/sidekick/Sidekick_core/Monoid_of_repr/index.html index c2548f36..a059cbd3 100644 --- a/dev/sidekick/Sidekick_core/Monoid_of_repr/index.html +++ b/dev/sidekick/Sidekick_core/Monoid_of_repr/index.html @@ -1,2 +1,2 @@ -Monoid_of_repr (sidekick.Sidekick_core.Monoid_of_repr)

Module Sidekick_core.Monoid_of_repr

Keep track of monoid state per equivalence class

Parameters

Signature

type t
val create_and_setup : ?⁠size:int -> M.SI.t -> t
val push_level : t -> unit
val pop_levels : t -> int -> unit
val mem : t -> M.SI.CC.N.t -> bool
val get : t -> M.SI.CC.N.t -> M.t option
val iter_all : t -> (M.SI.CC.repr * M.t) Iter.t
val pp : t Fmt.printer
\ No newline at end of file +Monoid_of_repr (sidekick.Sidekick_core.Monoid_of_repr)

Module Sidekick_core.Monoid_of_repr

State for a per-equivalence-class monoid.

Helps keep track of monoid state per equivalence class. A theory might use one or more instance(s) of this to aggregate some theory-specific state over all terms, with the information of what terms are already known to be equal potentially saving work for the theory.

Parameters

Signature

type t
val create_and_setup : ?⁠size:int -> M.SI.t -> t

Create a new monoid state

val push_level : t -> unit

Push backtracking point

val pop_levels : t -> int -> unit

Pop n backtracking points

val mem : t -> M.SI.CC.N.t -> bool

Does the CC node have a monoid value?

val get : t -> M.SI.CC.N.t -> M.t option

Get monoid value for this CC node, if any

val iter_all : t -> (M.SI.CC.repr * M.t) Iter.t
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/index.html b/dev/sidekick/Sidekick_core/index.html index 1e22e6e8..f536239f 100644 --- a/dev/sidekick/Sidekick_core/index.html +++ b/dev/sidekick/Sidekick_core/index.html @@ -1,2 +1,2 @@ -Sidekick_core (sidekick.Sidekick_core)

Module Sidekick_core

Main Environment

Theories and concrete solvers rely on an environment that defines several important types:

module Fmt = CCFormat
module CC_view : sig ... end

View terms through the lens of the Congruence Closure

module type TERM = sig ... end

Main representation of Terms and Types

module type PROOF = sig ... end
module type LIT = sig ... end
module type CC_ACTIONS = sig ... end

Actions provided to the congruence closure.

module type CC_ARG = sig ... end
module type CC_S = sig ... end
module type SOLVER_INTERNAL = sig ... end

A view of the solver from a theory's point of view

module type SOLVER = sig ... end

Public view of the solver

module type MONOID_ARG = sig ... end
module Monoid_of_repr : functor (M : MONOID_ARG) -> sig ... end

Keep track of monoid state per equivalence class

\ No newline at end of file +Sidekick_core (sidekick.Sidekick_core)

Module Sidekick_core

Main Signatures

Theories and concrete solvers rely on an environment that defines several important types:

In this module we define most of the main signatures used throughout Sidekick.

module Fmt = CCFormat
module CC_view : sig ... end

View terms through the lens of the Congruence Closure

module type TERM = sig ... end

Main representation of Terms and Types

module type PROOF = sig ... end
module type LIT = sig ... end

Literals

module type CC_ACTIONS = sig ... end

Actions provided to the congruence closure.

module type CC_ARG = sig ... end

Arguments to a congruence closure's implementation

module type CC_S = sig ... end

Signature of the congruence closure

module type SOLVER_INTERNAL = sig ... end

A view of the solver from a theory's point of view.

module type SOLVER = sig ... end

User facing view of the solver

module type MONOID_ARG = sig ... end

Helper for the congruence closure

module Monoid_of_repr : functor (M : MONOID_ARG) -> sig ... end

State for a per-equivalence-class monoid.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/Lit/index.html b/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/Lit/index.html index 2603fa3f..d4772774 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/Lit/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_core.CC_ACTIONS.Lit)

Module CC_ACTIONS.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_core.CC_ACTIONS.Lit)

Module CC_ACTIONS.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/T/Fun/index.html b/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/T/Fun/index.html index 7ee596a2..f3847fc9 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/T/Fun/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_core.CC_ACTIONS.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_core.CC_ACTIONS.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/T/Term/index.html b/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/T/Term/index.html index 3cc17045..9971d00b 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/T/Term/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_core.CC_ACTIONS.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_core.CC_ACTIONS.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/T/Ty/index.html b/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/T/Ty/index.html index b31ce147..a2bcdc75 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/T/Ty/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_core.CC_ACTIONS.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_core.CC_ACTIONS.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/T/index.html b/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/T/index.html index 1c0b827a..e5f8c1c0 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/T/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_core.CC_ACTIONS.T)

Module CC_ACTIONS.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_core.CC_ACTIONS.T)

Module CC_ACTIONS.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/index.html b/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/index.html index cbdfd9be..4a832454 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_ACTIONS/index.html @@ -1,2 +1,2 @@ -CC_ACTIONS (sidekick.Sidekick_core.CC_ACTIONS)

Module type Sidekick_core.CC_ACTIONS

Actions provided to the congruence closure.

The congruence closure must be able to propagate literals when it detects that they are true or false; it must also be able to create conflicts when the set of (dis)equalities is inconsistent

module T : TERM
module P : PROOF
module Lit : LIT with module T = T
type t
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +CC_ACTIONS (sidekick.Sidekick_core.CC_ACTIONS)

Module type Sidekick_core.CC_ACTIONS

Actions provided to the congruence closure.

The congruence closure must be able to propagate literals when it detects that they are true or false; it must also be able to create conflicts when the set of (dis)equalities is inconsistent

module T : TERM
module P : PROOF
module Lit : LIT with module T = T
type t

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

  • reason() should return a list of literals that are currently true.
  • lit should be a literal of interest (see CC_S.set_as_lit).

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_ARG/Actions/index.html b/dev/sidekick/Sidekick_core/module-type-CC_ARG/Actions/index.html index 4f5cbb0b..58d96019 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_ARG/Actions/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_ARG/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_core.CC_ARG.Actions)

Module CC_ARG.Actions

module T = T
module P = P
module Lit = Lit
type t
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_core.CC_ARG.Actions)

Module CC_ARG.Actions

module T = T
module P = P
module Lit = Lit
type t

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

  • reason() should return a list of literals that are currently true.
  • lit should be a literal of interest (see CC_S.set_as_lit).

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_ARG/Lit/index.html b/dev/sidekick/Sidekick_core/module-type-CC_ARG/Lit/index.html index 6ec78ed1..9f40dbc8 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_ARG/Lit/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_ARG/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_core.CC_ARG.Lit)

Module CC_ARG.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_core.CC_ARG.Lit)

Module CC_ARG.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_ARG/T/Fun/index.html b/dev/sidekick/Sidekick_core/module-type-CC_ARG/T/Fun/index.html index 3211e614..6baddb98 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_ARG/T/Fun/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_ARG/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_core.CC_ARG.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_core.CC_ARG.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_ARG/T/Term/index.html b/dev/sidekick/Sidekick_core/module-type-CC_ARG/T/Term/index.html index edd504d2..e2e456ef 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_ARG/T/Term/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_ARG/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_core.CC_ARG.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_core.CC_ARG.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_ARG/T/Ty/index.html b/dev/sidekick/Sidekick_core/module-type-CC_ARG/T/Ty/index.html index 771b0a81..bc55619a 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_ARG/T/Ty/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_ARG/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_core.CC_ARG.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_core.CC_ARG.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_ARG/T/index.html b/dev/sidekick/Sidekick_core/module-type-CC_ARG/T/index.html index 366fc529..16347797 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_ARG/T/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_ARG/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_core.CC_ARG.T)

Module CC_ARG.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_core.CC_ARG.T)

Module CC_ARG.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_ARG/index.html b/dev/sidekick/Sidekick_core/module-type-CC_ARG/index.html index 0741e3ca..4e029c32 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_ARG/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_ARG/index.html @@ -1,2 +1,2 @@ -CC_ARG (sidekick.Sidekick_core.CC_ARG)

Module type Sidekick_core.CC_ARG

module T : TERM
module P : PROOF
module Lit : LIT with module T = T
module Actions : CC_ACTIONS with module T = T and module P = P and module Lit = Lit
val cc_view : T.Term.t -> (T.Fun.tT.Term.tT.Term.t Iter.t) CC_view.t

View the term through the lens of the congruence closure

\ No newline at end of file +CC_ARG (sidekick.Sidekick_core.CC_ARG)

Module type Sidekick_core.CC_ARG

Arguments to a congruence closure's implementation

module T : TERM
module P : PROOF
module Lit : LIT with module T = T
module Actions : CC_ACTIONS with module T = T and module P = P and module Lit = Lit
val cc_view : T.Term.t -> (T.Fun.tT.Term.tT.Term.t Iter.t) CC_view.t

View the term through the lens of the congruence closure

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_S/Actions/index.html b/dev/sidekick/Sidekick_core/module-type-CC_S/Actions/index.html index 049552a2..f8a327bb 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_S/Actions/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_S/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_core.CC_S.Actions)

Module CC_S.Actions

module T = T
module P = P
module Lit = Lit
type t
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_core.CC_S.Actions)

Module CC_S.Actions

module T = T
module P = P
module Lit = Lit
type t

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

  • reason() should return a list of literals that are currently true.
  • lit should be a literal of interest (see CC_S.set_as_lit).

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_S/Expl/index.html b/dev/sidekick/Sidekick_core/module-type-CC_S/Expl/index.html index 60dc299a..6e72af80 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_S/Expl/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_S/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_core.CC_S.Expl)

Module CC_S.Expl

type t
val pp : t Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_core.CC_S.Expl)

Module CC_S.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_S/Lit/index.html b/dev/sidekick/Sidekick_core/module-type-CC_S/Lit/index.html index 32d429d1..b6d309cc 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_S/Lit/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_S/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_core.CC_S.Lit)

Module CC_S.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_core.CC_S.Lit)

Module CC_S.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_S/N/index.html b/dev/sidekick/Sidekick_core/module-type-CC_S/N/index.html index a8d8758a..b8007f08 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_S/N/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_S/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_core.CC_S.N)

Module CC_S.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_core.CC_S.N)

Module CC_S.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_S/T/Fun/index.html b/dev/sidekick/Sidekick_core/module-type-CC_S/T/Fun/index.html index da7047e2..6d5dec6a 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_S/T/Fun/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_S/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_core.CC_S.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_core.CC_S.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_S/T/Term/index.html b/dev/sidekick/Sidekick_core/module-type-CC_S/T/Term/index.html index 2f920eec..2d0e4dfd 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_S/T/Term/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_S/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_core.CC_S.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_core.CC_S.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_S/T/Ty/index.html b/dev/sidekick/Sidekick_core/module-type-CC_S/T/Ty/index.html index 1e895d7c..f8dfee11 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_S/T/Ty/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_S/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_core.CC_S.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_core.CC_S.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_S/T/index.html b/dev/sidekick/Sidekick_core/module-type-CC_S/T/index.html index 3d12f780..2f6dd867 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_S/T/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_S/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_core.CC_S.T)

Module CC_S.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_core.CC_S.T)

Module CC_S.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-CC_S/index.html b/dev/sidekick/Sidekick_core/module-type-CC_S/index.html index 1147cfc3..52b50ab6 100644 --- a/dev/sidekick/Sidekick_core/module-type-CC_S/index.html +++ b/dev/sidekick/Sidekick_core/module-type-CC_S/index.html @@ -1,2 +1,2 @@ -CC_S (sidekick.Sidekick_core.CC_S)

Module type Sidekick_core.CC_S

module T : TERM
module P : PROOF
module Lit : LIT with module T = T
module Actions : CC_ACTIONS with module T = T and module Lit = Lit and module P = P
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC_S (sidekick.Sidekick_core.CC_S)

Module type Sidekick_core.CC_S

Signature of the congruence closure

module T : TERM
module P : PROOF
module Lit : LIT with module T = T
module Actions : CC_ACTIONS with module T = T and module Lit = Lit and module P = P
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-LIT/T/Fun/index.html b/dev/sidekick/Sidekick_core/module-type-LIT/T/Fun/index.html index 5f7b96e7..4606ebd6 100644 --- a/dev/sidekick/Sidekick_core/module-type-LIT/T/Fun/index.html +++ b/dev/sidekick/Sidekick_core/module-type-LIT/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_core.LIT.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_core.LIT.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-LIT/T/Term/index.html b/dev/sidekick/Sidekick_core/module-type-LIT/T/Term/index.html index a8fab037..6322b848 100644 --- a/dev/sidekick/Sidekick_core/module-type-LIT/T/Term/index.html +++ b/dev/sidekick/Sidekick_core/module-type-LIT/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_core.LIT.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_core.LIT.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-LIT/T/Ty/index.html b/dev/sidekick/Sidekick_core/module-type-LIT/T/Ty/index.html index b509e749..f0156188 100644 --- a/dev/sidekick/Sidekick_core/module-type-LIT/T/Ty/index.html +++ b/dev/sidekick/Sidekick_core/module-type-LIT/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_core.LIT.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_core.LIT.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-LIT/T/index.html b/dev/sidekick/Sidekick_core/module-type-LIT/T/index.html index 211e1ae9..348e30d8 100644 --- a/dev/sidekick/Sidekick_core/module-type-LIT/T/index.html +++ b/dev/sidekick/Sidekick_core/module-type-LIT/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_core.LIT.T)

Module LIT.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_core.LIT.T)

Module LIT.T

Literals depend on terms

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-LIT/index.html b/dev/sidekick/Sidekick_core/module-type-LIT/index.html index 962638a0..df136457 100644 --- a/dev/sidekick/Sidekick_core/module-type-LIT/index.html +++ b/dev/sidekick/Sidekick_core/module-type-LIT/index.html @@ -1,2 +1,2 @@ -LIT (sidekick.Sidekick_core.LIT)

Module type Sidekick_core.LIT

module T : TERM
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file +LIT (sidekick.Sidekick_core.LIT)

Module type Sidekick_core.LIT

Literals

Literals are a pair of a boolean-sorted term, and a sign. Positive literals are the same as their term, and negative literals are the negation of their term.

The SAT solver deals only in literals and clauses (sets of literals). Everything else belongs in the SMT solver.

module T : TERM

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/CC/Actions/index.html b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/CC/Actions/index.html index 4f2f5374..e82331b5 100644 --- a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/CC/Actions/index.html +++ b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_core.MONOID_ARG.SI.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_core.MONOID_ARG.SI.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

  • reason() should return a list of literals that are currently true.
  • lit should be a literal of interest (see CC_S.set_as_lit).

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/CC/Expl/index.html b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/CC/Expl/index.html index 39edab1b..f90a958e 100644 --- a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/CC/Expl/index.html +++ b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_core.MONOID_ARG.SI.CC.Expl)

Module CC.Expl

type t
val pp : t Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_core.MONOID_ARG.SI.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/CC/N/index.html b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/CC/N/index.html index 5807c539..1062cb57 100644 --- a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/CC/N/index.html +++ b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_core.MONOID_ARG.SI.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_core.MONOID_ARG.SI.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/CC/index.html b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/CC/index.html index 3656f8fa..48387470 100644 --- a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/CC/index.html +++ b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick.Sidekick_core.MONOID_ARG.SI.CC)

Module SI.CC

module T = T
module P = P
module Lit = Lit
module Actions : CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick.Sidekick_core.MONOID_ARG.SI.CC)

Module SI.CC

module T = T
module P = P
module Lit = Lit
module Actions : CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/Lit/index.html b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/Lit/index.html index 062f5952..ec5ed206 100644 --- a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/Lit/index.html +++ b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_core.MONOID_ARG.SI.Lit)

Module SI.Lit

Literals

A literal is a (preprocessed) term along with its sign. It is directly manipulated by the SAT solver.

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_core.MONOID_ARG.SI.Lit)

Module SI.Lit

Literals

A literal is a (preprocessed) term along with its sign. It is directly manipulated by the SAT solver.

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/Simplify/index.html b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/Simplify/index.html index 1af30356..a25e8124 100644 --- a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/Simplify/index.html +++ b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick.Sidekick_core.MONOID_ARG.SI.Simplify)

Module SI.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick.Sidekick_core.MONOID_ARG.SI.Simplify)

Module SI.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/T/Fun/index.html b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/T/Fun/index.html index 98d22357..1ddf0cde 100644 --- a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/T/Fun/index.html +++ b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_core.MONOID_ARG.SI.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_core.MONOID_ARG.SI.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/T/Term/index.html b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/T/Term/index.html index 3d3fbb7b..f6f3b62d 100644 --- a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/T/Term/index.html +++ b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_core.MONOID_ARG.SI.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_core.MONOID_ARG.SI.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/T/Ty/index.html b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/T/Ty/index.html index 6b288b72..f539cc9d 100644 --- a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/T/Ty/index.html +++ b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_core.MONOID_ARG.SI.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_core.MONOID_ARG.SI.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/T/index.html b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/T/index.html index f6fd584c..594bd6a7 100644 --- a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/T/index.html +++ b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_core.MONOID_ARG.SI.T)

Module SI.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_core.MONOID_ARG.SI.T)

Module SI.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/index.html b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/index.html index 9f8a05f8..7922c2e7 100644 --- a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/index.html +++ b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/SI/index.html @@ -1,2 +1,2 @@ -SI (sidekick.Sidekick_core.MONOID_ARG.SI)

Module MONOID_ARG.SI

module T : TERM
module P : PROOF
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit : LIT with module T = T
type lit = Lit.t

Congruence Closure

module CC : CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +SI (sidekick.Sidekick_core.MONOID_ARG.SI)

Module MONOID_ARG.SI

module T : TERM
module P : PROOF
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit : LIT with module T = T
type lit = Lit.t

Congruence Closure

module CC : CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/index.html b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/index.html index 1759c053..83e158a3 100644 --- a/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/index.html +++ b/dev/sidekick/Sidekick_core/module-type-MONOID_ARG/index.html @@ -1,2 +1,2 @@ -MONOID_ARG (sidekick.Sidekick_core.MONOID_ARG)

Module type Sidekick_core.MONOID_ARG

module SI : SOLVER_INTERNAL
type t
val pp : t Fmt.printer
val name : string

name of the monoid's value (short)

val of_term : SI.CC.t -> SI.CC.N.t -> SI.T.Term.t -> t option * (SI.CC.N.t * t) list

of_term n t, where t is the term annotating node n, returns maybe_m, l, where:

  • maybe_m = Some m if t has monoid value m; otherwise maybe_m=None
  • l is a list of (u, m_u) where each u's term is a direct subterm of t and m_u is the monoid value attached to u.
val merge : SI.CC.t -> SI.CC.N.t -> t -> SI.CC.N.t -> t -> SI.CC.Expl.t -> (tSI.CC.Expl.t) Stdlib.result
\ No newline at end of file +MONOID_ARG (sidekick.Sidekick_core.MONOID_ARG)

Module type Sidekick_core.MONOID_ARG

Helper for the congruence closure

This helps theories keeping track of some state for each class. The state of a class is the monoidal combination of the state for each term in the class (for example, the set of terms in the class whose head symbol is a datatype constructor).

module SI : SOLVER_INTERNAL
type t

Some type with a monoid structure

val pp : t Fmt.printer
val name : string

name of the monoid structure (short)

val of_term : SI.CC.t -> SI.CC.N.t -> SI.T.Term.t -> t option * (SI.CC.N.t * t) list

of_term n t, where t is the term annotating node n, must return maybe_m, l, where:

  • maybe_m = Some m if t has monoid value m; otherwise maybe_m=None
  • l is a list of (u, m_u) where each u's term is a direct subterm of t and m_u is the monoid value attached to u.
val merge : SI.CC.t -> SI.CC.N.t -> t -> SI.CC.N.t -> t -> SI.CC.Expl.t -> (tSI.CC.Expl.t) Stdlib.result

Monoidal combination of two values.

merge cc n1 mon1 n2 mon2 expl returns the result of merging monoid values mon1 (for class n1) and mon2 (for class n2) when n1 and n2 are merged with explanation expl.

returns

Ok mon if the merge is acceptable, annotating the class of n1 ∪ n2; or Error expl' if the merge is unsatisfiable. expl' can then be used to trigger a conflict and undo the merge.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER/Atom/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER/Atom/index.html index cfa58bd0..f7e8acd3 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER/Atom/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick.Sidekick_core.SOLVER.Atom)

Module SOLVER.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick.Sidekick_core.SOLVER.Atom)

Module SOLVER.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER/Lit/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER/Lit/index.html index 9a81f59a..660d41d6 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER/Lit/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_core.SOLVER.Lit)

Module SOLVER.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_core.SOLVER.Lit)

Module SOLVER.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER/Model/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER/Model/index.html index 78d48c37..b1049383 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER/Model/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick.Sidekick_core.SOLVER.Model)

Module SOLVER.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Fmt.printer
\ No newline at end of file +Model (sidekick.Sidekick_core.SOLVER.Model)

Module SOLVER.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/CC/Actions/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/CC/Actions/index.html index daf3c279..95cc3ea0 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_core.SOLVER.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_core.SOLVER.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

  • reason() should return a list of literals that are currently true.
  • lit should be a literal of interest (see CC_S.set_as_lit).

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/CC/Expl/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/CC/Expl/index.html index 200aee6f..a4fadcfd 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_core.SOLVER.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_core.SOLVER.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/CC/N/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/CC/N/index.html index 8efeae84..02e94a5f 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/CC/N/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_core.SOLVER.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_core.SOLVER.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/CC/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/CC/index.html index 00250d9c..29c9b058 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/CC/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick.Sidekick_core.SOLVER.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick.Sidekick_core.SOLVER.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/Simplify/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/Simplify/index.html index 32677657..c8fac7fd 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/Simplify/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick.Sidekick_core.SOLVER.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick.Sidekick_core.SOLVER.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/index.html index 70810c73..2fc9b9e4 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick.Sidekick_core.SOLVER.Solver_internal)

Module SOLVER.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick.Sidekick_core.SOLVER.Solver_internal)

Module SOLVER.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER/T/Fun/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER/T/Fun/index.html index 311ce3ba..96099b7b 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER/T/Fun/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_core.SOLVER.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_core.SOLVER.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER/T/Term/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER/T/Term/index.html index 0443fe08..aa6b97d9 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER/T/Term/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_core.SOLVER.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_core.SOLVER.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER/T/Ty/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER/T/Ty/index.html index e62251dd..156fbbf0 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER/T/Ty/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_core.SOLVER.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_core.SOLVER.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER/T/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER/T/index.html index 2b73d9d1..23837ddc 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER/T/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_core.SOLVER.T)

Module SOLVER.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_core.SOLVER.T)

Module SOLVER.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER/index.html index 1bb44c92..57c86868 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER/index.html @@ -1,2 +1,2 @@ -SOLVER (sidekick.Sidekick_core.SOLVER)

Module type Sidekick_core.SOLVER

Public view of the solver

module T : TERM
module P : PROOF
module Lit : LIT with module T = T
module Solver_internal : SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +SOLVER (sidekick.Sidekick_core.SOLVER)

Module type Sidekick_core.SOLVER

User facing view of the solver

This is the solver a user of sidekick can see, after instantiating everything. The user can add some theories, clauses, etc. and asks the solver to check satisfiability.

Theory implementors will mostly interact with SOLVER_INTERNAL.

module T : TERM
module P : PROOF
module Lit : LIT with module T = T
module Solver_internal : SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER/module-type-THEORY/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER/module-type-THEORY/index.html index e78c6214..068d9fc2 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER/module-type-THEORY/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick.Sidekick_core.SOLVER.THEORY)

Module type SOLVER.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick.Sidekick_core.SOLVER.THEORY)

Module type SOLVER.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/CC/Actions/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/CC/Actions/index.html index 5c2f6f8e..5bfff607 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/CC/Actions/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_core.SOLVER_INTERNAL.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_core.SOLVER_INTERNAL.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

  • reason() should return a list of literals that are currently true.
  • lit should be a literal of interest (see CC_S.set_as_lit).

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/CC/Expl/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/CC/Expl/index.html index 4d4a4447..3114e9ba 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/CC/Expl/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_core.SOLVER_INTERNAL.CC.Expl)

Module CC.Expl

type t
val pp : t Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_core.SOLVER_INTERNAL.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/CC/N/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/CC/N/index.html index 47af4fd0..b95daa94 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/CC/N/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_core.SOLVER_INTERNAL.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_core.SOLVER_INTERNAL.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/CC/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/CC/index.html index 56c2a7ca..cc3cba42 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/CC/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick.Sidekick_core.SOLVER_INTERNAL.CC)

Module SOLVER_INTERNAL.CC

module T = T
module P = P
module Lit = Lit
module Actions : CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick.Sidekick_core.SOLVER_INTERNAL.CC)

Module SOLVER_INTERNAL.CC

module T = T
module P = P
module Lit = Lit
module Actions : CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/Lit/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/Lit/index.html index d83d757c..0e8679c4 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/Lit/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_core.SOLVER_INTERNAL.Lit)

Module SOLVER_INTERNAL.Lit

Literals

A literal is a (preprocessed) term along with its sign. It is directly manipulated by the SAT solver.

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_core.SOLVER_INTERNAL.Lit)

Module SOLVER_INTERNAL.Lit

Literals

A literal is a (preprocessed) term along with its sign. It is directly manipulated by the SAT solver.

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/Simplify/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/Simplify/index.html index e09ce3a7..299cfa59 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/Simplify/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick.Sidekick_core.SOLVER_INTERNAL.Simplify)

Module SOLVER_INTERNAL.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick.Sidekick_core.SOLVER_INTERNAL.Simplify)

Module SOLVER_INTERNAL.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/T/Fun/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/T/Fun/index.html index d7339366..c44b2129 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/T/Fun/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_core.SOLVER_INTERNAL.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_core.SOLVER_INTERNAL.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/T/Term/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/T/Term/index.html index 29c0fd8f..845400af 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/T/Term/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_core.SOLVER_INTERNAL.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_core.SOLVER_INTERNAL.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/T/Ty/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/T/Ty/index.html index 7d900e48..f2d588fb 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/T/Ty/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_core.SOLVER_INTERNAL.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_core.SOLVER_INTERNAL.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/T/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/T/index.html index c8597a75..05a763be 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/T/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_core.SOLVER_INTERNAL.T)

Module SOLVER_INTERNAL.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_core.SOLVER_INTERNAL.T)

Module SOLVER_INTERNAL.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/index.html b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/index.html index 6bba3d3c..abfea31d 100644 --- a/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/index.html +++ b/dev/sidekick/Sidekick_core/module-type-SOLVER_INTERNAL/index.html @@ -1,2 +1,2 @@ -SOLVER_INTERNAL (sidekick.Sidekick_core.SOLVER_INTERNAL)

Module type Sidekick_core.SOLVER_INTERNAL

A view of the solver from a theory's point of view

module T : TERM
module P : PROOF
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit : LIT with module T = T
type lit = Lit.t

Congruence Closure

module CC : CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +SOLVER_INTERNAL (sidekick.Sidekick_core.SOLVER_INTERNAL)

Module type Sidekick_core.SOLVER_INTERNAL

A view of the solver from a theory's point of view.

Theories should interact with the solver via this module, to assert new lemmas, propagate literals, access the congruence closure, etc.

module T : TERM
module P : PROOF
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit : LIT with module T = T
type lit = Lit.t

Congruence Closure

module CC : CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-TERM/Fun/index.html b/dev/sidekick/Sidekick_core/module-type-TERM/Fun/index.html index 03c4694c..490824a1 100644 --- a/dev/sidekick/Sidekick_core/module-type-TERM/Fun/index.html +++ b/dev/sidekick/Sidekick_core/module-type-TERM/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_core.TERM.Fun)

Module TERM.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_core.TERM.Fun)

Module TERM.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-TERM/Term/index.html b/dev/sidekick/Sidekick_core/module-type-TERM/Term/index.html index cb62d310..1621961d 100644 --- a/dev/sidekick/Sidekick_core/module-type-TERM/Term/index.html +++ b/dev/sidekick/Sidekick_core/module-type-TERM/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_core.TERM.Term)

Module TERM.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_core.TERM.Term)

Module TERM.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-TERM/Ty/index.html b/dev/sidekick/Sidekick_core/module-type-TERM/Ty/index.html index 74671696..1c205920 100644 --- a/dev/sidekick/Sidekick_core/module-type-TERM/Ty/index.html +++ b/dev/sidekick/Sidekick_core/module-type-TERM/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_core.TERM.Ty)

Module TERM.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_core.TERM.Ty)

Module TERM.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_core/module-type-TERM/index.html b/dev/sidekick/Sidekick_core/module-type-TERM/index.html index 31f589c2..5678d465 100644 --- a/dev/sidekick/Sidekick_core/module-type-TERM/index.html +++ b/dev/sidekick/Sidekick_core/module-type-TERM/index.html @@ -1,2 +1,2 @@ -TERM (sidekick.Sidekick_core.TERM)

Module type Sidekick_core.TERM

Main representation of Terms and Types

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +TERM (sidekick.Sidekick_core.TERM)

Module type Sidekick_core.TERM

Main representation of Terms and Types

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_mini_cc/Make/argument-1-A/T/Fun/index.html b/dev/sidekick/Sidekick_mini_cc/Make/argument-1-A/T/Fun/index.html index e331d862..08987768 100644 --- a/dev/sidekick/Sidekick_mini_cc/Make/argument-1-A/T/Fun/index.html +++ b/dev/sidekick/Sidekick_mini_cc/Make/argument-1-A/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_mini_cc.Make.1-A.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_mini_cc.Make.1-A.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_mini_cc/Make/argument-1-A/T/Term/index.html b/dev/sidekick/Sidekick_mini_cc/Make/argument-1-A/T/Term/index.html index f22d9248..49ca68b4 100644 --- a/dev/sidekick/Sidekick_mini_cc/Make/argument-1-A/T/Term/index.html +++ b/dev/sidekick/Sidekick_mini_cc/Make/argument-1-A/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_mini_cc.Make.1-A.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_mini_cc.Make.1-A.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_mini_cc/Make/argument-1-A/T/Ty/index.html b/dev/sidekick/Sidekick_mini_cc/Make/argument-1-A/T/Ty/index.html index 51c85dd4..20f86cb5 100644 --- a/dev/sidekick/Sidekick_mini_cc/Make/argument-1-A/T/Ty/index.html +++ b/dev/sidekick/Sidekick_mini_cc/Make/argument-1-A/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_mini_cc.Make.1-A.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_mini_cc.Make.1-A.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_mini_cc/Make/argument-1-A/T/index.html b/dev/sidekick/Sidekick_mini_cc/Make/argument-1-A/T/index.html index ccfe0c30..4961b908 100644 --- a/dev/sidekick/Sidekick_mini_cc/Make/argument-1-A/T/index.html +++ b/dev/sidekick/Sidekick_mini_cc/Make/argument-1-A/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_mini_cc.Make.1-A.T)

Module 1-A.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_mini_cc.Make.1-A.T)

Module 1-A.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_mini_cc/Make/index.html b/dev/sidekick/Sidekick_mini_cc/Make/index.html index f2a6877a..9c32967e 100644 --- a/dev/sidekick/Sidekick_mini_cc/Make/index.html +++ b/dev/sidekick/Sidekick_mini_cc/Make/index.html @@ -1,2 +1,2 @@ -Make (sidekick.Sidekick_mini_cc.Make)

Module Sidekick_mini_cc.Make

Parameters

Signature

type term = A.T.Term.t
type fun_ = A.T.Fun.t
type term_state = A.T.Term.state
type t
val create : term_state -> t
val clear : t -> unit

Fully reset the congruence closure's state

val add_lit : t -> term -> bool -> unit

add_lit cc p sign asserts that p=sign

val check_sat : t -> bool

check_sat cc returns true if the current state is satisfiable, false if it's unsatisfiable

val classes : t -> term Iter.t Iter.t

Traverse the set of classes in the congruence closure. This should be called only if check returned Sat.

\ No newline at end of file +Make (sidekick.Sidekick_mini_cc.Make)

Module Sidekick_mini_cc.Make

Instantiate the congruence closure for the given term structure.

Parameters

Signature

type term = A.T.Term.t
type fun_ = A.T.Fun.t
type term_state = A.T.Term.state
type t

An instance of the congruence closure. Mutable

val create : term_state -> t

New instance

val clear : t -> unit

Fully reset the congruence closure's state

val add_lit : t -> term -> bool -> unit

add_lit cc p sign asserts that p is true if sign, or p is false if not sign. If p is an equation and sign is true, this adds a new equation to the congruence relation.

val check_sat : t -> bool

check_sat cc returns true if the current state is satisfiable, false if it's unsatisfiable.

val classes : t -> term Iter.t Iter.t

Traverse the set of classes in the congruence closure. This should be called only if check returned Sat.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_mini_cc/index.html b/dev/sidekick/Sidekick_mini_cc/index.html index e217f8fe..0fc2836a 100644 --- a/dev/sidekick/Sidekick_mini_cc/index.html +++ b/dev/sidekick/Sidekick_mini_cc/index.html @@ -1,2 +1,2 @@ -Sidekick_mini_cc (sidekick.Sidekick_mini_cc)

Module Sidekick_mini_cc

Mini congruence closure

This implementation is as simple as possible, and doesn't provide backtracking, theories, or explanations. It just decides the satisfiability of a set of (dis)equations.

module CC_view = Sidekick_core.CC_view
module type ARG = sig ... end
module type S = sig ... end
module Make : functor (A : ARG) -> S with type term = A.T.Term.t and type fun_ = A.T.Fun.t and type term_state = A.T.Term.state
\ No newline at end of file +Sidekick_mini_cc (sidekick.Sidekick_mini_cc)

Module Sidekick_mini_cc

Mini congruence closure

This implementation is as simple as possible, and doesn't provide backtracking, theories, or explanations. It just decides the satisfiability of a set of (dis)equations.

module CC_view = Sidekick_core.CC_view
module type ARG = sig ... end

Argument for the functor Make

module type S = sig ... end

Main signature for an instance of the mini congruence closure

module Make : functor (A : ARG) -> S with type term = A.T.Term.t and type fun_ = A.T.Fun.t and type term_state = A.T.Term.state

Instantiate the congruence closure for the given term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_mini_cc/module-type-ARG/T/Fun/index.html b/dev/sidekick/Sidekick_mini_cc/module-type-ARG/T/Fun/index.html index b950658f..e4797893 100644 --- a/dev/sidekick/Sidekick_mini_cc/module-type-ARG/T/Fun/index.html +++ b/dev/sidekick/Sidekick_mini_cc/module-type-ARG/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_mini_cc.ARG.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_mini_cc.ARG.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_mini_cc/module-type-ARG/T/Term/index.html b/dev/sidekick/Sidekick_mini_cc/module-type-ARG/T/Term/index.html index 73962bf7..1c4b3f57 100644 --- a/dev/sidekick/Sidekick_mini_cc/module-type-ARG/T/Term/index.html +++ b/dev/sidekick/Sidekick_mini_cc/module-type-ARG/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_mini_cc.ARG.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_mini_cc.ARG.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_mini_cc/module-type-ARG/T/Ty/index.html b/dev/sidekick/Sidekick_mini_cc/module-type-ARG/T/Ty/index.html index f62cb84c..e8606a65 100644 --- a/dev/sidekick/Sidekick_mini_cc/module-type-ARG/T/Ty/index.html +++ b/dev/sidekick/Sidekick_mini_cc/module-type-ARG/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_mini_cc.ARG.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_mini_cc.ARG.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_mini_cc/module-type-ARG/T/index.html b/dev/sidekick/Sidekick_mini_cc/module-type-ARG/T/index.html index b7dfd81c..3feffe87 100644 --- a/dev/sidekick/Sidekick_mini_cc/module-type-ARG/T/index.html +++ b/dev/sidekick/Sidekick_mini_cc/module-type-ARG/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_mini_cc.ARG.T)

Module ARG.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_mini_cc.ARG.T)

Module ARG.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_mini_cc/module-type-ARG/index.html b/dev/sidekick/Sidekick_mini_cc/module-type-ARG/index.html index 0ce371da..272d9476 100644 --- a/dev/sidekick/Sidekick_mini_cc/module-type-ARG/index.html +++ b/dev/sidekick/Sidekick_mini_cc/module-type-ARG/index.html @@ -1,2 +1,2 @@ -ARG (sidekick.Sidekick_mini_cc.ARG)

Module type Sidekick_mini_cc.ARG

module T : Sidekick_core.TERM
val cc_view : T.Term.t -> (T.Fun.tT.Term.tT.Term.t Iter.t) CC_view.t
\ No newline at end of file +ARG (sidekick.Sidekick_mini_cc.ARG)

Module type Sidekick_mini_cc.ARG

Argument for the functor Make

It only requires a term structure, and a congruence-oriented view.

module T : Sidekick_core.TERM
val cc_view : T.Term.t -> (T.Fun.tT.Term.tT.Term.t Iter.t) CC_view.t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_mini_cc/module-type-S/index.html b/dev/sidekick/Sidekick_mini_cc/module-type-S/index.html index ba128e02..943684ba 100644 --- a/dev/sidekick/Sidekick_mini_cc/module-type-S/index.html +++ b/dev/sidekick/Sidekick_mini_cc/module-type-S/index.html @@ -1,2 +1,2 @@ -S (sidekick.Sidekick_mini_cc.S)

Module type Sidekick_mini_cc.S

type term
type fun_
type term_state
type t
val create : term_state -> t
val clear : t -> unit

Fully reset the congruence closure's state

val add_lit : t -> term -> bool -> unit

add_lit cc p sign asserts that p=sign

val check_sat : t -> bool

check_sat cc returns true if the current state is satisfiable, false if it's unsatisfiable

val classes : t -> term Iter.t Iter.t

Traverse the set of classes in the congruence closure. This should be called only if check returned Sat.

\ No newline at end of file +S (sidekick.Sidekick_mini_cc.S)

Module type Sidekick_mini_cc.S

Main signature for an instance of the mini congruence closure

type term
type fun_
type term_state
type t

An instance of the congruence closure. Mutable

val create : term_state -> t

New instance

val clear : t -> unit

Fully reset the congruence closure's state

val add_lit : t -> term -> bool -> unit

add_lit cc p sign asserts that p is true if sign, or p is false if not sign. If p is an equation and sign is true, this adds a new equation to the congruence relation.

val check_sat : t -> bool

check_sat cc returns true if the current state is satisfiable, false if it's unsatisfiable.

val classes : t -> term Iter.t Iter.t

Traverse the set of classes in the congruence closure. This should be called only if check returned Sat.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/Make/Atom/index.html b/dev/sidekick/Sidekick_msat_solver/Make/Atom/index.html index d2da4bb7..7978695e 100644 --- a/dev/sidekick/Sidekick_msat_solver/Make/Atom/index.html +++ b/dev/sidekick/Sidekick_msat_solver/Make/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick.Sidekick_msat_solver.Make.Atom)

Module Make.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick.Sidekick_msat_solver.Make.Atom)

Module Make.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/Make/Lit/index.html b/dev/sidekick/Sidekick_msat_solver/Make/Lit/index.html index 29d9bd92..bc6acec4 100644 --- a/dev/sidekick/Sidekick_msat_solver/Make/Lit/index.html +++ b/dev/sidekick/Sidekick_msat_solver/Make/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_msat_solver.Make.Lit)

Module Make.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_msat_solver.Make.Lit)

Module Make.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/Make/Model/index.html b/dev/sidekick/Sidekick_msat_solver/Make/Model/index.html index 235affea..ce95fb73 100644 --- a/dev/sidekick/Sidekick_msat_solver/Make/Model/index.html +++ b/dev/sidekick/Sidekick_msat_solver/Make/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick.Sidekick_msat_solver.Make.Model)

Module Make.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Model (sidekick.Sidekick_msat_solver.Make.Model)

Module Make.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/CC/Actions/index.html b/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/CC/Actions/index.html index 66536d18..bd99253b 100644 --- a/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_msat_solver.Make.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_msat_solver.Make.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/CC/Expl/index.html b/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/CC/Expl/index.html index 16944865..71a51b7d 100644 --- a/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_msat_solver.Make.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_msat_solver.Make.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/CC/N/index.html b/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/CC/N/index.html index cfb12feb..b76f7a95 100644 --- a/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/CC/N/index.html +++ b/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_msat_solver.Make.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_msat_solver.Make.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/CC/index.html b/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/CC/index.html index fb3531d9..72c185ee 100644 --- a/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/CC/index.html +++ b/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick.Sidekick_msat_solver.Make.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick.Sidekick_msat_solver.Make.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/Simplify/index.html b/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/Simplify/index.html index e5ad16a2..7599108f 100644 --- a/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/Simplify/index.html +++ b/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick.Sidekick_msat_solver.Make.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick.Sidekick_msat_solver.Make.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/index.html b/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/index.html index 42493fe0..e1966bc0 100644 --- a/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/index.html +++ b/dev/sidekick/Sidekick_msat_solver/Make/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick.Sidekick_msat_solver.Make.Solver_internal)

Module Make.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick.Sidekick_msat_solver.Make.Solver_internal)

Module Make.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/Make/argument-1-A/T/Fun/index.html b/dev/sidekick/Sidekick_msat_solver/Make/argument-1-A/T/Fun/index.html index df198746..a114c4b0 100644 --- a/dev/sidekick/Sidekick_msat_solver/Make/argument-1-A/T/Fun/index.html +++ b/dev/sidekick/Sidekick_msat_solver/Make/argument-1-A/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_msat_solver.Make.1-A.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_msat_solver.Make.1-A.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/Make/argument-1-A/T/Term/index.html b/dev/sidekick/Sidekick_msat_solver/Make/argument-1-A/T/Term/index.html index fe32f770..ac665f03 100644 --- a/dev/sidekick/Sidekick_msat_solver/Make/argument-1-A/T/Term/index.html +++ b/dev/sidekick/Sidekick_msat_solver/Make/argument-1-A/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_msat_solver.Make.1-A.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_msat_solver.Make.1-A.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/Make/argument-1-A/T/Ty/index.html b/dev/sidekick/Sidekick_msat_solver/Make/argument-1-A/T/Ty/index.html index b25b58e8..5d53bf13 100644 --- a/dev/sidekick/Sidekick_msat_solver/Make/argument-1-A/T/Ty/index.html +++ b/dev/sidekick/Sidekick_msat_solver/Make/argument-1-A/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_msat_solver.Make.1-A.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_msat_solver.Make.1-A.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/Make/argument-1-A/T/index.html b/dev/sidekick/Sidekick_msat_solver/Make/argument-1-A/T/index.html index 60a04294..c7ea0525 100644 --- a/dev/sidekick/Sidekick_msat_solver/Make/argument-1-A/T/index.html +++ b/dev/sidekick/Sidekick_msat_solver/Make/argument-1-A/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_msat_solver.Make.1-A.T)

Module 1-A.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_msat_solver.Make.1-A.T)

Module 1-A.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/Make/index.html b/dev/sidekick/Sidekick_msat_solver/Make/index.html index d650fbfc..8249c1e2 100644 --- a/dev/sidekick/Sidekick_msat_solver/Make/index.html +++ b/dev/sidekick/Sidekick_msat_solver/Make/index.html @@ -1,2 +1,2 @@ -Make (sidekick.Sidekick_msat_solver.Make)

Module Sidekick_msat_solver.Make

Parameters

Signature

module T = A.T
module P = A.P
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +Make (sidekick.Sidekick_msat_solver.Make)

Module Sidekick_msat_solver.Make

Parameters

Signature

module T = A.T
module P = A.P
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/Make/module-type-THEORY/index.html b/dev/sidekick/Sidekick_msat_solver/Make/module-type-THEORY/index.html index dc64403d..c5663e8e 100644 --- a/dev/sidekick/Sidekick_msat_solver/Make/module-type-THEORY/index.html +++ b/dev/sidekick/Sidekick_msat_solver/Make/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick.Sidekick_msat_solver.Make.THEORY)

Module type Make.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick.Sidekick_msat_solver.Make.THEORY)

Module type Make.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-ARG/T/Fun/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-ARG/T/Fun/index.html index 5fb0c89f..59fbe45b 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-ARG/T/Fun/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-ARG/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_msat_solver.ARG.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_msat_solver.ARG.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-ARG/T/Term/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-ARG/T/Term/index.html index 8c7a880d..0112d055 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-ARG/T/Term/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-ARG/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_msat_solver.ARG.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_msat_solver.ARG.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-ARG/T/Ty/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-ARG/T/Ty/index.html index a80cff5d..a23431cf 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-ARG/T/Ty/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-ARG/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_msat_solver.ARG.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_msat_solver.ARG.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-ARG/T/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-ARG/T/index.html index 098fe526..f361e588 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-ARG/T/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-ARG/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_msat_solver.ARG.T)

Module ARG.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_msat_solver.ARG.T)

Module ARG.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-S/Atom/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-S/Atom/index.html index 90c6104b..5c64afb9 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-S/Atom/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-S/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick.Sidekick_msat_solver.S.Atom)

Module S.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick.Sidekick_msat_solver.S.Atom)

Module S.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-S/Lit/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-S/Lit/index.html index 7e912d53..377e0c8d 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-S/Lit/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-S/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_msat_solver.S.Lit)

Module S.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_msat_solver.S.Lit)

Module S.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-S/Model/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-S/Model/index.html index b6cdfacf..dee3dbfa 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-S/Model/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-S/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick.Sidekick_msat_solver.S.Model)

Module S.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Model (sidekick.Sidekick_msat_solver.S.Model)

Module S.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/CC/Actions/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/CC/Actions/index.html index 068d18a8..710bd13a 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_msat_solver.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_msat_solver.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/CC/Expl/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/CC/Expl/index.html index d7f84728..49d1b416 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_msat_solver.S.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_msat_solver.S.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/CC/N/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/CC/N/index.html index 6fdf44e2..46e3e606 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/CC/N/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_msat_solver.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_msat_solver.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/CC/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/CC/index.html index 86195d32..108e4294 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/CC/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick.Sidekick_msat_solver.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick.Sidekick_msat_solver.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/Simplify/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/Simplify/index.html index 176e0523..812548d9 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/Simplify/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick.Sidekick_msat_solver.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick.Sidekick_msat_solver.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/index.html index 890963db..a4a0cba2 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-S/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick.Sidekick_msat_solver.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick.Sidekick_msat_solver.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-S/T/Fun/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-S/T/Fun/index.html index 263803b9..edc490f5 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-S/T/Fun/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-S/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_msat_solver.S.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_msat_solver.S.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-S/T/Term/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-S/T/Term/index.html index c6c0f8b9..4e9eeeab 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-S/T/Term/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-S/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_msat_solver.S.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_msat_solver.S.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-S/T/Ty/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-S/T/Ty/index.html index b7a2379a..d1fa09b7 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-S/T/Ty/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-S/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_msat_solver.S.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_msat_solver.S.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-S/T/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-S/T/index.html index 3ca5d1cc..044ebd30 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-S/T/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-S/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_msat_solver.S.T)

Module S.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_msat_solver.S.T)

Module S.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-S/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-S/index.html index 723da835..ff8052db 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-S/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-S/index.html @@ -1,2 +1,2 @@ -S (sidekick.Sidekick_msat_solver.S)

Module type Sidekick_msat_solver.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +S (sidekick.Sidekick_msat_solver.S)

Module type Sidekick_msat_solver.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_msat_solver/module-type-S/module-type-THEORY/index.html b/dev/sidekick/Sidekick_msat_solver/module-type-S/module-type-THEORY/index.html index a37dc1fc..f0278bfe 100644 --- a/dev/sidekick/Sidekick_msat_solver/module-type-S/module-type-THEORY/index.html +++ b/dev/sidekick/Sidekick_msat_solver/module-type-S/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick.Sidekick_msat_solver.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick.Sidekick_msat_solver.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Atom/index.html b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Atom/index.html index 39aa4d01..f32252aa 100644 --- a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Atom/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick.Sidekick_th_bool_static.Make.1-A.S.Atom)

Module S.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick.Sidekick_th_bool_static.Make.1-A.S.Atom)

Module S.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Lit/index.html b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Lit/index.html index 8f714312..c558cd06 100644 --- a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Lit/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_th_bool_static.Make.1-A.S.Lit)

Module S.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_th_bool_static.Make.1-A.S.Lit)

Module S.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Model/index.html b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Model/index.html index 1669bee8..3927d740 100644 --- a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Model/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick.Sidekick_th_bool_static.Make.1-A.S.Model)

Module S.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Model (sidekick.Sidekick_th_bool_static.Make.1-A.S.Model)

Module S.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/CC/Actions/index.html b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/CC/Actions/index.html index ef0a7635..5afcf581 100644 --- a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_th_bool_static.Make.1-A.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_th_bool_static.Make.1-A.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/CC/Expl/index.html b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/CC/Expl/index.html index 3e1dabe3..0282f9ed 100644 --- a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_th_bool_static.Make.1-A.S.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_th_bool_static.Make.1-A.S.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/CC/N/index.html b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/CC/N/index.html index f5d11643..92329a5a 100644 --- a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/CC/N/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_th_bool_static.Make.1-A.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_th_bool_static.Make.1-A.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/CC/index.html b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/CC/index.html index b02f19e0..0e7ec9d4 100644 --- a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/CC/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick.Sidekick_th_bool_static.Make.1-A.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick.Sidekick_th_bool_static.Make.1-A.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/Simplify/index.html b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/Simplify/index.html index 3acaaedd..f6dd2a40 100644 --- a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/Simplify/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick.Sidekick_th_bool_static.Make.1-A.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick.Sidekick_th_bool_static.Make.1-A.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/index.html b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/index.html index 9e8c964e..6f51e166 100644 --- a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick.Sidekick_th_bool_static.Make.1-A.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick.Sidekick_th_bool_static.Make.1-A.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/T/Fun/index.html b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/T/Fun/index.html index e155bc8f..3bb4aac5 100644 --- a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/T/Fun/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_th_bool_static.Make.1-A.S.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_th_bool_static.Make.1-A.S.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/T/Term/index.html b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/T/Term/index.html index a0ce3fa1..014b0775 100644 --- a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/T/Term/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_th_bool_static.Make.1-A.S.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_th_bool_static.Make.1-A.S.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/T/Ty/index.html b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/T/Ty/index.html index 486c00c6..e62f3868 100644 --- a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/T/Ty/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_th_bool_static.Make.1-A.S.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_th_bool_static.Make.1-A.S.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/T/index.html b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/T/index.html index 88bc3f3f..eff79659 100644 --- a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/T/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_th_bool_static.Make.1-A.S.T)

Module S.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_th_bool_static.Make.1-A.S.T)

Module S.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/index.html b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/index.html index c497d17f..9df30c4e 100644 --- a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/index.html @@ -1,2 +1,2 @@ -S (sidekick.Sidekick_th_bool_static.Make.1-A.S)

Module 1-A.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +S (sidekick.Sidekick_th_bool_static.Make.1-A.S)

Module 1-A.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/module-type-THEORY/index.html b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/module-type-THEORY/index.html index 2da42b78..95238598 100644 --- a/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/module-type-THEORY/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/Make/argument-1-A/S/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick.Sidekick_th_bool_static.Make.1-A.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick.Sidekick_th_bool_static.Make.1-A.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Atom/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Atom/index.html index 7c798b3d..ce40043b 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Atom/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick.Sidekick_th_bool_static.ARG.S.Atom)

Module S.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick.Sidekick_th_bool_static.ARG.S.Atom)

Module S.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Lit/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Lit/index.html index 3fb6198c..212df189 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Lit/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_th_bool_static.ARG.S.Lit)

Module S.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_th_bool_static.ARG.S.Lit)

Module S.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Model/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Model/index.html index cd40b934..87f4babd 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Model/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick.Sidekick_th_bool_static.ARG.S.Model)

Module S.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Model (sidekick.Sidekick_th_bool_static.ARG.S.Model)

Module S.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/CC/Actions/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/CC/Actions/index.html index eb3d8aef..91560772 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_th_bool_static.ARG.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_th_bool_static.ARG.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/CC/Expl/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/CC/Expl/index.html index b57c3ee3..939295c2 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_th_bool_static.ARG.S.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_th_bool_static.ARG.S.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/CC/N/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/CC/N/index.html index f3cfa369..e3e58347 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/CC/N/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_th_bool_static.ARG.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_th_bool_static.ARG.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/CC/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/CC/index.html index af3b7943..320ae0a7 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/CC/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick.Sidekick_th_bool_static.ARG.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick.Sidekick_th_bool_static.ARG.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/Simplify/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/Simplify/index.html index 756e1e17..462f19c5 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/Simplify/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick.Sidekick_th_bool_static.ARG.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick.Sidekick_th_bool_static.ARG.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/index.html index 09453386..a5735dd8 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick.Sidekick_th_bool_static.ARG.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick.Sidekick_th_bool_static.ARG.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/T/Fun/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/T/Fun/index.html index 87981994..af4131a7 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/T/Fun/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_th_bool_static.ARG.S.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_th_bool_static.ARG.S.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/T/Term/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/T/Term/index.html index a06397be..0dbeb122 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/T/Term/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_th_bool_static.ARG.S.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_th_bool_static.ARG.S.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/T/Ty/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/T/Ty/index.html index 3386dfcc..76177a69 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/T/Ty/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_th_bool_static.ARG.S.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_th_bool_static.ARG.S.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/T/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/T/index.html index 698d5c1b..0bc77b90 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/T/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_th_bool_static.ARG.S.T)

Module S.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_th_bool_static.ARG.S.T)

Module S.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/index.html index 91d8f019..472b8075 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/index.html @@ -1,2 +1,2 @@ -S (sidekick.Sidekick_th_bool_static.ARG.S)

Module ARG.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +S (sidekick.Sidekick_th_bool_static.ARG.S)

Module ARG.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/module-type-THEORY/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/module-type-THEORY/index.html index 3eda44d3..eb7dc26d 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/module-type-THEORY/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-ARG/S/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick.Sidekick_th_bool_static.ARG.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick.Sidekick_th_bool_static.ARG.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Atom/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Atom/index.html index b0df5bb7..2fdf4c44 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Atom/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick.Sidekick_th_bool_static.S.A.S.Atom)

Module S.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick.Sidekick_th_bool_static.S.A.S.Atom)

Module S.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Lit/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Lit/index.html index bdde6612..c87504d5 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Lit/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_th_bool_static.S.A.S.Lit)

Module S.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_th_bool_static.S.A.S.Lit)

Module S.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Model/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Model/index.html index f90dc343..e074a6b2 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Model/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick.Sidekick_th_bool_static.S.A.S.Model)

Module S.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Model (sidekick.Sidekick_th_bool_static.S.A.S.Model)

Module S.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/CC/Actions/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/CC/Actions/index.html index 4b3135ca..1766358a 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_th_bool_static.S.A.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_th_bool_static.S.A.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/CC/Expl/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/CC/Expl/index.html index 6cf7cdf7..da69dff5 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_th_bool_static.S.A.S.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_th_bool_static.S.A.S.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/CC/N/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/CC/N/index.html index c48b6021..953d41b7 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/CC/N/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_th_bool_static.S.A.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_th_bool_static.S.A.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/CC/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/CC/index.html index d3b215ca..062d5752 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/CC/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick.Sidekick_th_bool_static.S.A.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick.Sidekick_th_bool_static.S.A.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/Simplify/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/Simplify/index.html index 0e1f4444..93b049d6 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/Simplify/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick.Sidekick_th_bool_static.S.A.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick.Sidekick_th_bool_static.S.A.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/index.html index 3e290c34..b570bebd 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick.Sidekick_th_bool_static.S.A.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick.Sidekick_th_bool_static.S.A.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/T/Fun/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/T/Fun/index.html index bf741bb1..ad05fd68 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/T/Fun/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_th_bool_static.S.A.S.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_th_bool_static.S.A.S.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/T/Term/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/T/Term/index.html index b35b2332..a4ceb86c 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/T/Term/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_th_bool_static.S.A.S.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_th_bool_static.S.A.S.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/T/Ty/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/T/Ty/index.html index 0dd35db5..eeb361f4 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/T/Ty/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_th_bool_static.S.A.S.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_th_bool_static.S.A.S.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/T/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/T/index.html index 64cf2da4..8f10e6ee 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/T/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_th_bool_static.S.A.S.T)

Module S.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_th_bool_static.S.A.S.T)

Module S.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/index.html index 856a34cb..4df8f18f 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/index.html @@ -1,2 +1,2 @@ -S (sidekick.Sidekick_th_bool_static.S.A.S)

Module A.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +S (sidekick.Sidekick_th_bool_static.S.A.S)

Module A.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/module-type-THEORY/index.html b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/module-type-THEORY/index.html index b1c8b6aa..fcd2937a 100644 --- a/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/module-type-THEORY/index.html +++ b/dev/sidekick/Sidekick_th_bool_static/module-type-S/A/S/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick.Sidekick_th_bool_static.S.A.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick.Sidekick_th_bool_static.S.A.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Atom/index.html b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Atom/index.html index 381824ac..a31a20b6 100644 --- a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Atom/index.html +++ b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick.Sidekick_th_cstor.Make.1-A.S.Atom)

Module S.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick.Sidekick_th_cstor.Make.1-A.S.Atom)

Module S.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Lit/index.html b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Lit/index.html index b1ffdb6d..caa2346f 100644 --- a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Lit/index.html +++ b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_th_cstor.Make.1-A.S.Lit)

Module S.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_th_cstor.Make.1-A.S.Lit)

Module S.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Model/index.html b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Model/index.html index 0fad8afd..81302128 100644 --- a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Model/index.html +++ b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick.Sidekick_th_cstor.Make.1-A.S.Model)

Module S.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Model (sidekick.Sidekick_th_cstor.Make.1-A.S.Model)

Module S.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/CC/Actions/index.html b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/CC/Actions/index.html index f430bc36..4dd23f54 100644 --- a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_th_cstor.Make.1-A.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_th_cstor.Make.1-A.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/CC/Expl/index.html b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/CC/Expl/index.html index ce52744b..036a65f5 100644 --- a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_th_cstor.Make.1-A.S.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_th_cstor.Make.1-A.S.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/CC/N/index.html b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/CC/N/index.html index 91d5d34e..4d94d054 100644 --- a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/CC/N/index.html +++ b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_th_cstor.Make.1-A.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_th_cstor.Make.1-A.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/CC/index.html b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/CC/index.html index 8d7057f3..ae3cfbd9 100644 --- a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/CC/index.html +++ b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick.Sidekick_th_cstor.Make.1-A.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick.Sidekick_th_cstor.Make.1-A.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/Simplify/index.html b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/Simplify/index.html index 65d0e5c5..8e778cc4 100644 --- a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/Simplify/index.html +++ b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick.Sidekick_th_cstor.Make.1-A.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick.Sidekick_th_cstor.Make.1-A.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/index.html b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/index.html index 62ffe1f6..1bd2351f 100644 --- a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/index.html +++ b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick.Sidekick_th_cstor.Make.1-A.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick.Sidekick_th_cstor.Make.1-A.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/T/Fun/index.html b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/T/Fun/index.html index 29e2961f..57a87a16 100644 --- a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/T/Fun/index.html +++ b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_th_cstor.Make.1-A.S.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_th_cstor.Make.1-A.S.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/T/Term/index.html b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/T/Term/index.html index 66bdd81f..7152b470 100644 --- a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/T/Term/index.html +++ b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_th_cstor.Make.1-A.S.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_th_cstor.Make.1-A.S.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/T/Ty/index.html b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/T/Ty/index.html index 059f4537..f462779e 100644 --- a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/T/Ty/index.html +++ b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_th_cstor.Make.1-A.S.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_th_cstor.Make.1-A.S.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/T/index.html b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/T/index.html index c49aa022..d3d59ff3 100644 --- a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/T/index.html +++ b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_th_cstor.Make.1-A.S.T)

Module S.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_th_cstor.Make.1-A.S.T)

Module S.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/index.html b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/index.html index 3b86beb8..11be2628 100644 --- a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/index.html +++ b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/index.html @@ -1,2 +1,2 @@ -S (sidekick.Sidekick_th_cstor.Make.1-A.S)

Module 1-A.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +S (sidekick.Sidekick_th_cstor.Make.1-A.S)

Module 1-A.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/module-type-THEORY/index.html b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/module-type-THEORY/index.html index 791aa3b7..3910b929 100644 --- a/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/module-type-THEORY/index.html +++ b/dev/sidekick/Sidekick_th_cstor/Make/argument-1-A/S/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick.Sidekick_th_cstor.Make.1-A.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick.Sidekick_th_cstor.Make.1-A.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Atom/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Atom/index.html index 2b17e975..014fe15d 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Atom/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick.Sidekick_th_cstor.ARG.S.Atom)

Module S.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick.Sidekick_th_cstor.ARG.S.Atom)

Module S.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Lit/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Lit/index.html index c2a32601..be85754b 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Lit/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_th_cstor.ARG.S.Lit)

Module S.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_th_cstor.ARG.S.Lit)

Module S.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Model/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Model/index.html index 59f7dfae..406e1e42 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Model/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick.Sidekick_th_cstor.ARG.S.Model)

Module S.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Model (sidekick.Sidekick_th_cstor.ARG.S.Model)

Module S.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/CC/Actions/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/CC/Actions/index.html index db6a0994..f4dedf06 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_th_cstor.ARG.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_th_cstor.ARG.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/CC/Expl/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/CC/Expl/index.html index b87ae892..8fd1f1ff 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_th_cstor.ARG.S.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_th_cstor.ARG.S.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/CC/N/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/CC/N/index.html index cc86249f..373654ab 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/CC/N/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_th_cstor.ARG.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_th_cstor.ARG.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/CC/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/CC/index.html index cedf6489..05c36921 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/CC/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick.Sidekick_th_cstor.ARG.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick.Sidekick_th_cstor.ARG.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/Simplify/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/Simplify/index.html index b0f834be..67cabbed 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/Simplify/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick.Sidekick_th_cstor.ARG.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick.Sidekick_th_cstor.ARG.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/index.html index 1d128c3e..dd808e5e 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick.Sidekick_th_cstor.ARG.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick.Sidekick_th_cstor.ARG.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/T/Fun/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/T/Fun/index.html index 8d62458d..8a592fc0 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/T/Fun/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_th_cstor.ARG.S.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_th_cstor.ARG.S.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/T/Term/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/T/Term/index.html index 84ceed1c..e3161201 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/T/Term/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_th_cstor.ARG.S.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_th_cstor.ARG.S.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/T/Ty/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/T/Ty/index.html index dc339642..e862fd3d 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/T/Ty/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_th_cstor.ARG.S.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_th_cstor.ARG.S.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/T/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/T/index.html index 65674d6d..410812a6 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/T/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_th_cstor.ARG.S.T)

Module S.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_th_cstor.ARG.S.T)

Module S.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/index.html index 6bf13962..9aac3fcc 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/index.html @@ -1,2 +1,2 @@ -S (sidekick.Sidekick_th_cstor.ARG.S)

Module ARG.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +S (sidekick.Sidekick_th_cstor.ARG.S)

Module ARG.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/module-type-THEORY/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/module-type-THEORY/index.html index 81cc5c53..ba7d7347 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/module-type-THEORY/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-ARG/S/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick.Sidekick_th_cstor.ARG.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick.Sidekick_th_cstor.ARG.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Atom/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Atom/index.html index 37bc8d3c..d3451ba1 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Atom/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick.Sidekick_th_cstor.S.A.S.Atom)

Module S.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick.Sidekick_th_cstor.S.A.S.Atom)

Module S.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Lit/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Lit/index.html index 0ef604b5..ade1d22f 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Lit/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_th_cstor.S.A.S.Lit)

Module S.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_th_cstor.S.A.S.Lit)

Module S.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Model/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Model/index.html index e8959e93..df8a9581 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Model/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick.Sidekick_th_cstor.S.A.S.Model)

Module S.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Model (sidekick.Sidekick_th_cstor.S.A.S.Model)

Module S.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/CC/Actions/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/CC/Actions/index.html index 852d4ba5..d52a4178 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_th_cstor.S.A.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_th_cstor.S.A.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/CC/Expl/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/CC/Expl/index.html index b163bf3e..2c24798f 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_th_cstor.S.A.S.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_th_cstor.S.A.S.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/CC/N/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/CC/N/index.html index 5512b0cd..aac8bc4b 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/CC/N/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_th_cstor.S.A.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_th_cstor.S.A.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/CC/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/CC/index.html index 3e7a2f75..2120a624 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/CC/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick.Sidekick_th_cstor.S.A.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick.Sidekick_th_cstor.S.A.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/Simplify/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/Simplify/index.html index 35f054be..08457e48 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/Simplify/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick.Sidekick_th_cstor.S.A.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick.Sidekick_th_cstor.S.A.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/index.html index 2eadf6c9..7d847274 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick.Sidekick_th_cstor.S.A.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick.Sidekick_th_cstor.S.A.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/T/Fun/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/T/Fun/index.html index 0f27b90b..8c2dbadb 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/T/Fun/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_th_cstor.S.A.S.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_th_cstor.S.A.S.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/T/Term/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/T/Term/index.html index 6a29f5ac..29c6de86 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/T/Term/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_th_cstor.S.A.S.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_th_cstor.S.A.S.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/T/Ty/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/T/Ty/index.html index 7251ed97..82996f2a 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/T/Ty/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_th_cstor.S.A.S.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_th_cstor.S.A.S.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/T/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/T/index.html index 2679a26a..23244eb6 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/T/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_th_cstor.S.A.S.T)

Module S.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_th_cstor.S.A.S.T)

Module S.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/index.html index 127e5b2d..236956c9 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/index.html @@ -1,2 +1,2 @@ -S (sidekick.Sidekick_th_cstor.S.A.S)

Module A.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +S (sidekick.Sidekick_th_cstor.S.A.S)

Module A.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/module-type-THEORY/index.html b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/module-type-THEORY/index.html index ce9e52a2..03b58536 100644 --- a/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/module-type-THEORY/index.html +++ b/dev/sidekick/Sidekick_th_cstor/module-type-S/A/S/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick.Sidekick_th_cstor.S.A.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick.Sidekick_th_cstor.S.A.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Atom/index.html b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Atom/index.html index 978ef2a4..b60727cd 100644 --- a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Atom/index.html +++ b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick.Sidekick_th_data.Make.1-A.S.Atom)

Module S.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick.Sidekick_th_data.Make.1-A.S.Atom)

Module S.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Lit/index.html b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Lit/index.html index 737c52cc..5af98cca 100644 --- a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Lit/index.html +++ b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_th_data.Make.1-A.S.Lit)

Module S.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_th_data.Make.1-A.S.Lit)

Module S.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Model/index.html b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Model/index.html index 26ca4315..2d5fc9ec 100644 --- a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Model/index.html +++ b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick.Sidekick_th_data.Make.1-A.S.Model)

Module S.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Model (sidekick.Sidekick_th_data.Make.1-A.S.Model)

Module S.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/CC/Actions/index.html b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/CC/Actions/index.html index a9a573a8..8ea32905 100644 --- a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_th_data.Make.1-A.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_th_data.Make.1-A.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/CC/Expl/index.html b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/CC/Expl/index.html index 615c8964..8519ce95 100644 --- a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_th_data.Make.1-A.S.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_th_data.Make.1-A.S.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/CC/N/index.html b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/CC/N/index.html index 4b033802..538b4560 100644 --- a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/CC/N/index.html +++ b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_th_data.Make.1-A.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_th_data.Make.1-A.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/CC/index.html b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/CC/index.html index fad9557d..ecf2aca6 100644 --- a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/CC/index.html +++ b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick.Sidekick_th_data.Make.1-A.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick.Sidekick_th_data.Make.1-A.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/Simplify/index.html b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/Simplify/index.html index 5d66f7a6..8e1b97ad 100644 --- a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/Simplify/index.html +++ b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick.Sidekick_th_data.Make.1-A.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick.Sidekick_th_data.Make.1-A.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/index.html b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/index.html index 3140dd19..a74a2b93 100644 --- a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/index.html +++ b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick.Sidekick_th_data.Make.1-A.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick.Sidekick_th_data.Make.1-A.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/T/Fun/index.html b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/T/Fun/index.html index 698b169d..764bd918 100644 --- a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/T/Fun/index.html +++ b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_th_data.Make.1-A.S.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_th_data.Make.1-A.S.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/T/Term/index.html b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/T/Term/index.html index 11a605d6..bb667af7 100644 --- a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/T/Term/index.html +++ b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_th_data.Make.1-A.S.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_th_data.Make.1-A.S.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/T/Ty/index.html b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/T/Ty/index.html index f82d410c..0f8fa41f 100644 --- a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/T/Ty/index.html +++ b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_th_data.Make.1-A.S.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_th_data.Make.1-A.S.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/T/index.html b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/T/index.html index 844d87e2..f06eada7 100644 --- a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/T/index.html +++ b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_th_data.Make.1-A.S.T)

Module S.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_th_data.Make.1-A.S.T)

Module S.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/index.html b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/index.html index 958ce69d..2a60ded2 100644 --- a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/index.html +++ b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/index.html @@ -1,2 +1,2 @@ -S (sidekick.Sidekick_th_data.Make.1-A.S)

Module 1-A.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +S (sidekick.Sidekick_th_data.Make.1-A.S)

Module 1-A.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/module-type-THEORY/index.html b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/module-type-THEORY/index.html index 2762ef3f..bb50a1bf 100644 --- a/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/module-type-THEORY/index.html +++ b/dev/sidekick/Sidekick_th_data/Make/argument-1-A/S/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick.Sidekick_th_data.Make.1-A.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick.Sidekick_th_data.Make.1-A.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Atom/index.html b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Atom/index.html index b6599b4e..f08fdf3e 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Atom/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick.Sidekick_th_data.ARG.S.Atom)

Module S.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick.Sidekick_th_data.ARG.S.Atom)

Module S.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Lit/index.html b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Lit/index.html index 562b34db..024e944c 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Lit/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_th_data.ARG.S.Lit)

Module S.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_th_data.ARG.S.Lit)

Module S.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Model/index.html b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Model/index.html index c78bb237..853bb721 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Model/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick.Sidekick_th_data.ARG.S.Model)

Module S.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Model (sidekick.Sidekick_th_data.ARG.S.Model)

Module S.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/CC/Actions/index.html b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/CC/Actions/index.html index d2fb9b2d..384bc4fa 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_th_data.ARG.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_th_data.ARG.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/CC/Expl/index.html b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/CC/Expl/index.html index 73b5e2c9..80375283 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_th_data.ARG.S.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_th_data.ARG.S.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/CC/N/index.html b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/CC/N/index.html index 4efa6433..f3be4bbf 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/CC/N/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_th_data.ARG.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_th_data.ARG.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/CC/index.html b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/CC/index.html index 3bafe023..495fd686 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/CC/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick.Sidekick_th_data.ARG.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick.Sidekick_th_data.ARG.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/Simplify/index.html b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/Simplify/index.html index 75cfaac4..b83fe424 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/Simplify/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick.Sidekick_th_data.ARG.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick.Sidekick_th_data.ARG.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/index.html b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/index.html index 82cd782c..e8cb2e49 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick.Sidekick_th_data.ARG.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick.Sidekick_th_data.ARG.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/T/Fun/index.html b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/T/Fun/index.html index 464bb1fc..b4989f56 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/T/Fun/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_th_data.ARG.S.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_th_data.ARG.S.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/T/Term/index.html b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/T/Term/index.html index afc321dc..8aa3f8a1 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/T/Term/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_th_data.ARG.S.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_th_data.ARG.S.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/T/Ty/index.html b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/T/Ty/index.html index 44316351..e4c670eb 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/T/Ty/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_th_data.ARG.S.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_th_data.ARG.S.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/T/index.html b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/T/index.html index bfe4f8fa..1d61bf91 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/T/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_th_data.ARG.S.T)

Module S.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_th_data.ARG.S.T)

Module S.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/index.html b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/index.html index 88ddff0e..6e938a87 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/index.html @@ -1,2 +1,2 @@ -S (sidekick.Sidekick_th_data.ARG.S)

Module ARG.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +S (sidekick.Sidekick_th_data.ARG.S)

Module ARG.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/module-type-THEORY/index.html b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/module-type-THEORY/index.html index 15597ec7..d1e8b3dd 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-ARG/S/module-type-THEORY/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-ARG/S/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick.Sidekick_th_data.ARG.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick.Sidekick_th_data.ARG.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Atom/index.html b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Atom/index.html index b72afa7f..ed5e5a90 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Atom/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Atom/index.html @@ -1,2 +1,2 @@ -Atom (sidekick.Sidekick_th_data.S.A.S.Atom)

Module S.Atom

Boolean Atoms

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file +Atom (sidekick.Sidekick_th_data.S.A.S.Atom)

Module S.Atom

Boolean Atoms

Atoms are the SAT solver's version of our boolean literals (they may have a different representation).

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t CCFormat.printer
val neg : t -> t
val formula : t -> lit
val sign : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Lit/index.html b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Lit/index.html index 339d6b44..8a5fe21a 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Lit/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Lit/index.html @@ -1,2 +1,2 @@ -Lit (sidekick.Sidekick_th_data.S.A.S.Lit)

Module S.Lit

module T = T
type t
val term : t -> T.Term.t
val sign : t -> bool
val neg : t -> t
val abs : t -> t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Lit (sidekick.Sidekick_th_data.S.A.S.Lit)

Module S.Lit

module T = T

Literals depend on terms

type t

A literal

val term : t -> T.Term.t

Get the (positive) term

val sign : t -> bool

Get the sign. A negated literal has sign false.

val neg : t -> t

Take negation of literal. sign (neg lit) = not (sign lit).

val abs : t -> t

abs lit is like lit but always positive, i.e. sign (abs lit) = true

val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Model/index.html b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Model/index.html index 35c3fa3f..8de45187 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Model/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Model/index.html @@ -1,2 +1,2 @@ -Model (sidekick.Sidekick_th_data.S.A.S.Model)

Module S.Model

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Model (sidekick.Sidekick_th_data.S.A.S.Model)

Module S.Model

Models

A model can be produced when the solver is found to be in a satisfiable state after a call to solve.

type t
val empty : t
val mem : t -> term -> bool
val find : t -> term -> term option
val eval : t -> term -> term option
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/CC/Actions/index.html b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/CC/Actions/index.html index a0647d6e..536b8f44 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/CC/Actions/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/CC/Actions/index.html @@ -1,2 +1,2 @@ -Actions (sidekick.Sidekick_th_data.S.A.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions
val raise_conflict : t -> Lit.t list -> P.t -> 'a
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit
\ No newline at end of file +Actions (sidekick.Sidekick_th_data.S.A.S.Solver_internal.CC.Actions)

Module CC.Actions

module T = T
module P = P
module Lit = Lit
type t = actions

An action handle. It is used by the congruence closure to perform the actions below. How it performs the actions is not specified and is solver-specific.

val raise_conflict : t -> Lit.t list -> P.t -> 'a

raise_conflict acts c pr declares that c is a tautology of the theory of congruence. This does not return (it should raise an exception).

parameter pr

the proof of c being a tautology

val propagate : t -> Lit.t -> reason:(unit -> Lit.t list) -> P.t -> unit

propagate acts lit ~reason pr declares that reason() => lit is a tautology.

This function might never be called, a congruence closure has the right to not propagate and only trigger conflicts.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/CC/Expl/index.html b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/CC/Expl/index.html index f6110696..b215cc06 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/CC/Expl/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/CC/Expl/index.html @@ -1,2 +1,2 @@ -Expl (sidekick.Sidekick_th_data.S.A.S.Solver_internal.CC.Expl)

Module CC.Expl

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file +Expl (sidekick.Sidekick_th_data.S.A.S.Solver_internal.CC.Expl)

Module CC.Expl

Explanations

Explanations are specialized proofs, created by the congruence closure when asked to justify why 2 terms are equal.

type t
val pp : t Sidekick_core.Fmt.printer
val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t
val mk_lit : lit -> t
val mk_list : t list -> t
val mk_theory : t -> t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/CC/N/index.html b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/CC/N/index.html index de281dc7..b6fc9910 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/CC/N/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/CC/N/index.html @@ -1,2 +1,2 @@ -N (sidekick.Sidekick_th_data.S.A.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t
val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)?

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool
\ No newline at end of file +N (sidekick.Sidekick_th_data.S.A.S.Solver_internal.CC.N)

Module CC.N

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

All information pertaining to the whole equivalence class is stored in this representative's node.

When two classes become equal (are "merged"), one of the two representatives is picked as the representative of the new class. The new class contains the union of the two old classes' nodes.

We also allow theories to store additional information in the representative. This information can be used when two classes are merged, to detect conflicts and solve equations à la Shostak.

type t

An equivalent class, containing terms that are proved to be equal.

A value of type t points to a particular term, but see find to get the representative of the class.

val term : t -> term
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
val is_root : t -> bool

Is the node a root (ie the representative of its class)? See find to get the root.

val iter_class : t -> t Iter.t

Traverse the congruence class. Precondition: is_root n (see find below)

val iter_parents : t -> t Iter.t

Traverse the parents of the class. Precondition: is_root n (see find below)

type bitfield

A field in the bitfield of this node. This should only be allocated when a theory is initialized.

All fields are initially 0, are backtracked automatically, and are merged automatically when classes are merged.

val get_field : bitfield -> t -> bool

Access the bit field

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/CC/index.html b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/CC/index.html index f77ec49e..3a2b10db 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/CC/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/CC/index.html @@ -1,2 +1,2 @@ -CC (sidekick.Sidekick_th_data.S.A.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

Global state of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end
type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t
val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit
type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit
type ev_on_new_term = t -> N.t -> term -> unit
type ev_on_conflict = t -> th:bool -> lit list -> unit
type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit
type ev_on_is_subterm = N.t -> term -> unit
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t
val n_false : t -> N.t
val n_bool : t -> bool -> N.t
val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file +CC (sidekick.Sidekick_th_data.S.A.S.Solver_internal.CC)

Module Solver_internal.CC

module T = T
module P = P
module Lit = Lit
module Actions : Sidekick_core.CC_ACTIONS with module T = T and module Lit = Lit and module P = P and type t = actions
type term_state = T.Term.state
type term = T.Term.t
type fun_ = T.Fun.t
type lit = Lit.t
type proof = P.t
type actions = Actions.t
type t

State of the congruence closure

module N : sig ... end

An equivalence class is a set of terms that are currently equal in the partial model built by the solver. The class is represented by a collection of nodes, one of which is distinguished and is called the "representative".

module Expl : sig ... end

Explanations

type node = N.t

A node of the congruence closure

type repr = N.t

Node that is currently a representative

type explanation = Expl.t

Accessors

val term_state : t -> term_state
val find : t -> node -> repr

Current representative

val add_term : t -> term -> node

Add the term to the congruence closure, if not present already. Will be backtracked.

val mem_term : t -> term -> bool

Returns true if the term is explicitly present in the congruence closure

Events

Events triggered by the congruence closure, to which other plugins can subscribe.

type ev_on_pre_merge = t -> actions -> N.t -> N.t -> Expl.t -> unit

ev_on_pre_merge cc acts n1 n2 expl is called right before n1 and n2 are merged with explanation expl.

type ev_on_post_merge = t -> actions -> N.t -> N.t -> unit

ev_on_post_merge cc acts n1 n2 is called right after n1 and n2 were merged. find cc n1 and find cc n2 will return the same node.

type ev_on_new_term = t -> N.t -> term -> unit

ev_on_new_term cc n t is called whenever a new term t is added to the congruence closure. Its node is n.

type ev_on_conflict = t -> th:bool -> lit list -> unit

ev_on_conflict acts ~th c is called when the congruence closure triggers a conflict by asserting the tautology c.

parameter th

true if the explanation for this conflict involves at least one "theory" explanation; i.e. some of the equations participating in the conflict are purely syntactic theories like injectivity of constructors.

type ev_on_propagate = t -> lit -> (unit -> lit list) -> unit

ev_on_propagate cc lit reason is called whenever reason() => lit is a propagated lemma. See Sidekick_core.CC_ACTIONS.propagate.

type ev_on_is_subterm = N.t -> term -> unit

ev_on_is_subterm n t is called when n is a subterm of another node for the first time. t is the term corresponding to the node n. This can be useful for theory combination.

val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠on_pre_merge:ev_on_pre_merge list -> ?⁠on_post_merge:ev_on_post_merge list -> ?⁠on_new_term:ev_on_new_term list -> ?⁠on_conflict:ev_on_conflict list -> ?⁠on_propagate:ev_on_propagate list -> ?⁠on_is_subterm:ev_on_is_subterm list -> ?⁠size:[ `Small | `Big ] -> term_state -> t

Create a new congruence closure.

parameter term_state

used to be able to create new terms. All terms interacting with this congruence closure must belong in this term state as well.

val allocate_bitfield : descr:string -> t -> N.bitfield

Allocate a new bitfield for the nodes. See N.bitfield.

val set_bitfield : t -> N.bitfield -> bool -> N.t -> unit

Set the bitfield for the node. This will be backtracked. See N.bitfield.

val on_pre_merge : t -> ev_on_pre_merge -> unit

Add a function to be called when two classes are merged

val on_post_merge : t -> ev_on_post_merge -> unit

Add a function to be called when two classes are merged

val on_new_term : t -> ev_on_new_term -> unit

Add a function to be called when a new node is created

val on_conflict : t -> ev_on_conflict -> unit

Called when the congruence closure finds a conflict

val on_propagate : t -> ev_on_propagate -> unit

Called when the congruence closure propagates a literal

val on_is_subterm : t -> ev_on_is_subterm -> unit

Called on terms that are subterms of function symbols

val set_as_lit : t -> N.t -> lit -> unit

map the given node to a literal.

val find_t : t -> term -> repr

Current representative of the term.

raises Not_found

if the term is not already add-ed.

val add_seq : t -> term Iter.t -> unit

Add a sequence of terms to the congruence closure

val all_classes : t -> repr Iter.t

All current classes. This is costly, only use if there is no other solution

val assert_lit : t -> lit -> unit

Given a literal, assume it in the congruence closure and propagate its consequences. Will be backtracked.

Useful for the theory combination or the SAT solver's functor

val assert_lits : t -> lit Iter.t -> unit

Addition of many literals

val explain_eq : t -> N.t -> N.t -> lit list

Explain why the two nodes are equal. Fails if they are not, in an unspecified way

val raise_conflict_from_expl : t -> actions -> Expl.t -> 'a

Raise a conflict with the given explanation it must be a theory tautology that expl ==> absurd. To be used in theories.

val n_true : t -> N.t

Node for true

val n_false : t -> N.t

Node for false

val n_bool : t -> bool -> N.t

Node for either true or false

val merge : t -> N.t -> N.t -> Expl.t -> unit

Merge these two nodes given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val merge_t : t -> term -> term -> Expl.t -> unit

Shortcut for adding + merging

val check : t -> actions -> unit

Perform all pending operations done via assert_eq, assert_lit, etc. Will use the actions to propagate literals, declare conflicts, etc.

val new_merges : t -> bool

Called after check, returns true if some pairs of classes were merged.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Restore to state n calls to push_level earlier. Used during backtracking.

val get_model : t -> N.t Iter.t Iter.t

get all the equivalence classes so they can be merged in the model

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/Simplify/index.html b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/Simplify/index.html index e6dc1a8d..5f21952f 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/Simplify/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/Simplify/index.html @@ -1,2 +1,2 @@ -Simplify (sidekick.Sidekick_th_data.S.A.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

val normalize : t -> term -> term

Normalize a term using all the hooks.

\ No newline at end of file +Simplify (sidekick.Sidekick_th_data.S.A.S.Solver_internal.Simplify)

Module Solver_internal.Simplify

Simplify terms

type t
val tst : t -> term_state
val ty_st : t -> ty_state
val clear : t -> unit

Reset internal cache, etc.

type hook = t -> term -> term option

Given a term, try to simplify it. Return None if it didn't change.

A simple example could be a hook that takes a term t, and if t is app "+" (const x) (const y) where x and y are number, returns Some (const (x+y)), and None otherwise.

val normalize : t -> term -> term

Normalize a term using all the hooks. This performs a fixpoint, i.e. it only stops when no hook applies anywhere inside the term.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/index.html b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/index.html index 8e4e81b6..6504cc72 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/Solver_internal/index.html @@ -1,2 +1,2 @@ -Solver_internal (sidekick.Sidekick_th_data.S.A.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions
module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end
type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit
val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class.

val on_model_gen : t -> model_hook -> unit
\ No newline at end of file +Solver_internal (sidekick.Sidekick_th_data.S.A.S.Solver_internal)

Module S.Solver_internal

Internal solver, available to theories.

module T = T
module P = P
type ty = T.Ty.t
type term = T.Term.t
type term_state = T.Term.state
type ty_state = T.Ty.state
type proof = P.t
type t

Main type for a solver

type solver = t
val tst : t -> term_state
val ty_st : t -> ty_state
val stats : t -> Sidekick_util.Stat.t

Actions for the theories

type actions

Handle that the theories can use to perform actions.

module Lit = Lit
type lit = Lit.t

Congruence Closure

module CC : Sidekick_core.CC_S with module T = T and module P = P and module Lit = Lit and type Actions.t = actions
val cc : t -> CC.t

Congruence closure for this solver

Simplifiers

module Simplify : sig ... end

Simplify terms

type simplify_hook = Simplify.hook
val add_simplifier : t -> Simplify.hook -> unit

Add a simplifier hook for preprocessing.

val simplifier : t -> Simplify.t
val simp_t : t -> term -> term

Simplify the term using the solver's simplifier (see simplifier)

hooks for the theory

val propagate : t -> actions -> lit -> reason:(unit -> lit list) -> proof -> unit

Propagate a literal for a reason. This is similar to asserting the clause reason => lit, but more lightweight, and in a way that is backtrackable.

val raise_conflict : t -> actions -> lit list -> proof -> 'a

Give a conflict clause to the solver

val push_decision : t -> actions -> lit -> unit

Ask the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.

val propagate : t -> actions -> lit -> (unit -> lit list) -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val propagate_l : t -> actions -> lit -> lit list -> unit

Propagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology

val add_clause_temp : t -> actions -> lit list -> unit

Add local clause to the SAT solver. This clause will be removed when the solver backtracks.

val add_clause_permanent : t -> actions -> lit list -> unit

Add toplevel clause to the SAT solver. This clause will not be backtracked.

val mk_lit : t -> actions -> ?⁠sign:bool -> term -> lit

Create a literal. This automatically preprocesses the term.

val preprocess_term : t -> add_clause:(Lit.t list -> unit) -> term -> term

Preprocess a term.

val add_lit : t -> actions -> lit -> unit

Add the given literal to the SAT solver, so it gets assigned a boolean value

val add_lit_t : t -> actions -> ?⁠sign:bool -> term -> unit

Add the given (signed) bool term to the SAT solver, so it gets assigned a boolean value

val cc_raise_conflict_expl : t -> actions -> CC.Expl.t -> 'a

Raise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.

val cc_find : t -> CC.N.t -> CC.N.t

Find representative of the node

val cc_are_equal : t -> term -> term -> bool

Are these two terms equal in the congruence closure?

val cc_merge : t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit

Merge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.

val cc_merge_t : t -> actions -> term -> term -> CC.Expl.t -> unit

Merge these two terms in the congruence closure, given this explanation. See cc_merge

val cc_add_term : t -> term -> CC.N.t

Add/retrieve congruence closure node for this term. To be used in theories

val cc_mem_term : t -> term -> bool

Return true if the term is explicitly in the congruence closure. To be used in theories

val on_cc_pre_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called before)

val on_cc_post_merge : t -> (CC.t -> actions -> CC.N.t -> CC.N.t -> unit) -> unit

Callback for when two classes containing data for this key are merged (called after)

val on_cc_new_term : t -> (CC.t -> CC.N.t -> term -> unit) -> unit

Callback to add data on terms when they are added to the congruence closure

val on_cc_is_subterm : t -> (CC.N.t -> term -> unit) -> unit

Callback for when a term is a subterm of another term in the congruence closure

val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit

Callback called on every CC conflict

val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list) -> unit) -> unit

Callback called on every CC propagation

val on_partial_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callbacked to be called with the slice of literals newly added on the trail.

This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.

val on_final_check : t -> (t -> actions -> lit Iter.t -> unit) -> unit

Register callback to be called during the final check.

Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.

Preprocessors

These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.

type preprocess_hook = t -> mk_lit:(term -> lit) -> add_clause:(lit list -> unit) -> term -> term option

Given a term, try to preprocess it. Return None if it didn't change. Can also add clauses to define new terms.

Preprocessing might transform terms to make them more amenable to reasoning, e.g. by removing boolean formulas via Tseitin encoding, adding clauses that encode their meaning in the same move.

parameter mk_lit

creates a new literal for a boolean term.

parameter add_clause

pushes a new clause into the SAT solver.

val on_preprocess : t -> preprocess_hook -> unit

Add a hook that will be called when terms are preprocessed

Model production

type model_hook = recurse:(t -> CC.N.t -> term) -> t -> CC.N.t -> term option

A model-production hook. It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.

If no hook assigns a value to a class, a fake value is created for it.

val on_model_gen : t -> model_hook -> unit

Add a hook that will be called when a model is being produced

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/T/Fun/index.html b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/T/Fun/index.html index ac3f3634..3eb9969a 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/T/Fun/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/T/Fun/index.html @@ -1,2 +1,2 @@ -Fun (sidekick.Sidekick_th_data.S.A.S.T.Fun)

Module T.Fun

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file +Fun (sidekick.Sidekick_th_data.S.A.S.T.Fun)

Module T.Fun

A function symbol, like "f" or "plus" or "is_human" or "socrates"

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/T/Term/index.html b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/T/Term/index.html index 1dc5fb03..cc05a1a3 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/T/Term/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/T/Term/index.html @@ -1,2 +1,8 @@ -Term (sidekick.Sidekick_th_data.S.A.S.T.Term)

Module T.Term

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val ty : t -> Ty.t
val bool : state -> bool -> t
val as_bool : t -> bool option
val abs : state -> t -> t * bool
val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms

val iter_dag : t -> (t -> unit) -> unit
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file +Term (sidekick.Sidekick_th_data.S.A.S.T.Term)

Module T.Term

Term structure.

Terms should be hashconsed, with perfect sharing. This allows, for example, Term.Tbl and Term.iter_dag to be efficient.

type t
val equal : t -> t -> bool
val compare : t -> t -> int
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state

A state used to create new terms. It is where the hashconsing table should live, along with other all-terms related state.

val ty : t -> Ty.t
val bool : state -> bool -> t

build true/false

val as_bool : t -> bool option

as_bool t is Some true if t is the term true, and similarly for false. For other terms it is None.

val abs : state -> t -> t * bool

abs t returns an "absolute value" for the term, along with the sign of t.

The idea is that we want to turn not a into (a, false), or (a != b) into (a=b, false). For terms without a negation this should return (t, true).

The state is passed in case a new term needs to be created.

val map_shallow : state -> (t -> t) -> t -> t

Map function on immediate subterms. This should not be recursive.

val iter_dag : t -> (t -> unit) -> unit

iter_dag t f calls f once on each subterm of t, t included. It must not traverse t as a tree, but rather as a perfectly shared DAG.

For example, in:

let x = 2 in
+let y = f x x in
+let z = g y x in
+z = z

the DAG has the following nodes:

n1: 2
+n2: f n1 n1
+n3: g n2 n1
+n4: = n3 n3
module Tbl : CCHashtbl.S with type Tbl.key = t
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/T/Ty/index.html b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/T/Ty/index.html index bb47799e..da6e68ff 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/T/Ty/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/T/Ty/index.html @@ -1,2 +1,2 @@ -Ty (sidekick.Sidekick_th_data.S.A.S.T.Ty)

Module T.Ty

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file +Ty (sidekick.Sidekick_th_data.S.A.S.T.Ty)

Module T.Ty

Types

Types should be comparable (ideally, in O(1)), and have at least a boolean type available.

type t
val equal : t -> t -> bool
val hash : t -> int
val pp : t Sidekick_core.Fmt.printer
type state
val bool : state -> t
val is_bool : t -> bool
\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/T/index.html b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/T/index.html index 0460fcf2..f4c17fd9 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/T/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/T/index.html @@ -1,2 +1,2 @@ -T (sidekick.Sidekick_th_data.S.A.S.T)

Module S.T

module Fun : sig ... end
module Ty : sig ... end
module Term : sig ... end
\ No newline at end of file +T (sidekick.Sidekick_th_data.S.A.S.T)

Module S.T

module Fun : sig ... end

A function symbol, like "f" or "plus" or "is_human" or "socrates"

module Ty : sig ... end

Types

module Term : sig ... end

Term structure.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/index.html b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/index.html index 51bfd341..e2654fb4 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/index.html @@ -1,2 +1,2 @@ -S (sidekick.Sidekick_th_data.S.A.S)

Module A.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t
type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory

module Atom : sig ... end
module Model : sig ... end
module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

parameter theories

theories to load from the start.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t
val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t
val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit
val add_clause_l : t -> Atom.t list -> unit
type res =
| Sat of Model.t
| Unsat of {
proof : proof option lazy_t;
unsat_core : Atom.t list lazy_t;
}
| Unknown of Unknown.t

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the statement added so far to s

parameter check

if true, the model is checked before returning

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer
\ No newline at end of file +S (sidekick.Sidekick_th_data.S.A.S)

Module A.S

module T : Sidekick_core.TERM
module P : Sidekick_core.PROOF
module Lit : Sidekick_core.LIT with module T = T
module Solver_internal : Sidekick_core.SOLVER_INTERNAL with module T = T and module P = P and module Lit = Lit

Internal solver, available to theories.

type t

The solver's state.

type solver = t
type term = T.Term.t
type ty = T.Ty.t
type lit = Lit.t
type lemma = P.t
module type THEORY = sig ... end
type theory = (module THEORY)

A theory that can be used for this particular solver.

type 'a theory_p = (module THEORY with type t = 'a)

A theory that can be used for this particular solver, with state of type 'a.

val mk_theory : name:string -> create_and_setup:(Solver_internal.t -> 'th) -> ?⁠push_level:('th -> unit) -> ?⁠pop_levels:('th -> int -> unit) -> unit -> theory

Helper to create a theory.

module Atom : sig ... end
module Model : sig ... end

Models

module Unknown : sig ... end
module Proof : sig ... end
type proof = Proof.t

Main API

val stats : t -> Sidekick_util.Stat.t
val tst : t -> T.Term.state
val ty_st : t -> T.Ty.state
val create : ?⁠stat:Sidekick_util.Stat.t -> ?⁠size:[ `Big | `Tiny | `Small ] -> ?⁠store_proof:bool -> theories:theory list -> T.Term.state -> T.Ty.state -> unit -> t

Create a new solver.

It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.

parameter store_proof

if true, proofs from the SAT solver and theories are retained and potentially accessible after solve returns UNSAT.

parameter size

influences the size of initial allocations.

parameter theories

theories to load from the start. Other theories can be added using add_theory.

val add_theory : t -> theory -> unit

Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).

val add_theory_p : t -> 'a theory_p -> 'a

Add the given theory and obtain its state

val add_theory_l : t -> theory list -> unit
val mk_atom_lit : t -> lit -> Atom.t

Turn a literal into a SAT solver literal.

val mk_atom_t : t -> ?⁠sign:bool -> term -> Atom.t

Turn a boolean term, with a sign, into a SAT solver's literal.

val add_clause : t -> Atom.t Sidekick_util.IArray.t -> unit

add_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.

val add_clause_l : t -> Atom.t list -> unit

Same as add_clause but with a list of atoms.

type res =
| Sat of Model.t

Satisfiable

| Unsat of {
proof : proof option lazy_t;

proof of unsat

unsat_core : Atom.t list lazy_t;

subset of assumptions responsible for unsat

}

Unsatisfiable

| Unknown of Unknown.t

Unknown, obtained after a timeout, memory limit, etc.

Result of solving for the current set of clauses

val solve : ?⁠on_exit:(unit -> unit) list -> ?⁠check:bool -> ?⁠on_progress:(t -> unit) -> assumptions:Atom.t list -> t -> res

solve s checks the satisfiability of the clauses added so far to s.

parameter check

if true, the model is checked before returning.

parameter on_progress

called regularly during solving.

parameter assumptions

a set of atoms held to be true. The unsat core, if any, will be a subset of assumptions.

parameter on_exit

functions to be run before this returns

val pp_stats : t CCFormat.printer

Print some statistics. What it prints exactly is unspecified.

\ No newline at end of file diff --git a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/module-type-THEORY/index.html b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/module-type-THEORY/index.html index 73b98b3d..029de097 100644 --- a/dev/sidekick/Sidekick_th_data/module-type-S/A/S/module-type-THEORY/index.html +++ b/dev/sidekick/Sidekick_th_data/module-type-S/A/S/module-type-THEORY/index.html @@ -1,2 +1,2 @@ -THEORY (sidekick.Sidekick_th_data.S.A.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

val push_level : t -> unit

Push backtracking level

val pop_levels : t -> int -> unit

Pop backtracking levels, restoring the theory to its former state

\ No newline at end of file +THEORY (sidekick.Sidekick_th_data.S.A.S.THEORY)

Module type S.THEORY

A theory

Theories are abstracted over the concrete implementation of the solver, so they can work with any implementation.

Typically a theory should be a functor taking an argument containing a SOLVER_INTERNAL or even a full SOLVER, and some additional views on terms, literals, etc. that are specific to the theory (e.g. to map terms to linear expressions). The theory can then be instantiated on any kind of solver for any term representation that also satisfies the additional theory-specific requirements. Instantiated theories (ie values of type Sidekick_core.SOLVER.theory) can be added to the solver.

type t

The theory's state

val name : string

Name of the theory (ideally, unique and short)

val create_and_setup : Solver_internal.t -> t

Instantiate the theory's state for the given (internal) solver, register callbacks, create keys, etc.

Called once for every solver this theory is added to.

val push_level : t -> unit

Push backtracking level. When the corresponding pop is called, the theory's state should be restored to a state equivalent to what it was just before push_level.

it does not have to be exactly the same state, it just needs to be equivalent.

val pop_levels : t -> int -> unit

pop_levels theory n pops n backtracking levels, restoring theory to its state before calling push_level n times.

\ No newline at end of file