Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring models representation #925

Merged
merged 48 commits into from
Dec 21, 2023

Conversation

Halbaroth
Copy link
Collaborator

@Halbaroth Halbaroth commented Nov 7, 2023

This PR changes the way Alt-Ergo stores models.

Before the PR, Alt-Ergo didn't produce a printable model in memory but performed some basic computations in the model printers.

Now, Alt-Ergo will produce in memory a printable model. The PR mostly consists in moving some codes from Models.ml to ModelMap.ml or Uf.ml.

  • All the require computation is now done in the output_concrete_model of the union-find module (included the computation for records).
  • All the printings stuff are in ModelMap.ml.
  • We use Expr.t to store model values.
  • The only reason I kept Models.ml is because we are the printer of constraint model here. This will be remove later.

Besides, as I notice, the symbols we define in models are all Sy.Name. Thus I create an new module to manage identifiers Id.ml and I store identifiers instead of symbols in models.

@Halbaroth Halbaroth added models This issue is related to model generation. clean-up labels Nov 7, 2023
@Halbaroth Halbaroth added this to the 2.6.0 milestone Nov 7, 2023
@Halbaroth Halbaroth force-pushed the refactoring-models-representation branch 2 times, most recently from df20940 to 1d613d7 Compare November 8, 2023 13:59
@Halbaroth Halbaroth marked this pull request as ready for review November 8, 2023 14:00
@Halbaroth Halbaroth requested review from Stevendeo, bclement-ocp and hra687261 and removed request for bclement-ocp November 8, 2023 14:00
src/lib/reasoners/uf.ml Outdated Show resolved Hide resolved
src/lib/reasoners/uf.ml Outdated Show resolved Hide resolved
src/lib/reasoners/uf.ml Outdated Show resolved Hide resolved
src/lib/reasoners/uf.ml Outdated Show resolved Hide resolved
src/lib/reasoners/uf.ml Outdated Show resolved Hide resolved
src/lib/reasoners/uf.ml Outdated Show resolved Hide resolved
src/lib/reasoners/uf.ml Outdated Show resolved Hide resolved
src/lib/structures/modelMap.ml Outdated Show resolved Hide resolved
src/lib/util/util.mli Outdated Show resolved Hide resolved
src/lib/structures/modelMap.ml Outdated Show resolved Hide resolved
Copy link
Collaborator

@bclement-ocp bclement-ocp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR feels like it stops halfway through: from reading the PR description I thought that we would be building a structured representation of the model in memory prior to printing, but we actually build a fairly shallow map where most things are strings. I think we should go all the way and keep the structured representation throughout, rather than build (and intern!) intermediate strings that are only used for printing; although there are maybe blockers to that I don't immediately see — thoughts?

Besides, as I notice, the symbols we define in models are all Sy.Name. Thus I create an new module to manage identifiers Id.ml and I store identifiers instead of symbols in models.

I am not entirely convinced this is a good idea — I am not opposed to it but we may want to include things that are not Sy.Name in the models at some point (namely, values for partially interpreted functions such as division by zero) where we may regret this change.

(Unrelated thought: at some point we should probably use the Id module from Dolmen to represent identifiers as well)

@@ -1,7 +1,7 @@

unknown
(
(define-fun f ((arg_0 Int)) Int (ite (= arg_0 0) 2 0))
(define-fun f ((arg_0 Int)) Int (ite (= arg_0 (- 2)) 0 2))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did this model change?

Comment on lines 3 to 4
; This model is a best-effort. It includes symbols
; for which model generation is known to be incomplete.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that after #886 model generation should only be incomplete when the FPA prelude is disabled — which I don't think is a configuration we want to support.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this one, it seems the test is running without enabling the fpa theory:

  (rule
   (target test_float2.models_tableaux.output)
   (deps (:input test_float2.models.smt2))
   (package alt-ergo)
   (action
    (chdir %{workspace_root}
     (with-stdout-to %{target}
      (ignore-stderr
       (with-accepted-exit-codes 0
        (run %{bin:alt-ergo}
             --timelimit=2
             --enable-assertions
             --output=smtlib2
             --frontend dolmen
             --sat-solver Tableaux
             %{input})))))))

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My point is that we don't inspect the preludes for the "known to be incomplete" message and that I think we should never print it for the float function (rather than always print it), because we expect users to use them with the preludes (or to know what they are doing).

(BTW the fact that we reply "unknown" and not "sat" is also an indication that the model might be incomplete)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand your point. I don't know if I'm supposed to print something if the user tries to produce models in presence of FPA symbols without loading the FPA theory. I guess we should print something because users can forget flags.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My point is that it is fine to not print anything since replying "unknown" is already saying that the model may be incomplete. At least we should remove this when #917 is taken care of.

Comment on lines 3 to 4
; This model is a best-effort. It includes symbols
; for which model generation is known to be incomplete.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After #886 model generation for bv2nat and int2bv should be complete.

src/lib/util/util.mli Outdated Show resolved Hide resolved
Comment on lines 31 to 32
type sy = Id.t * Ty.t list * Ty.t
(** Typed symbol of function. *)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure how to link the types in the tuple to the description "typed symbol of function". I believe this is: (symbol, args_ty, ret_ty) tuples where symbol is the function name, args_ty the type of arguments, ret_ty the return type?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I add a documentation to explain the meaning of its fields.

Hashtbl.clear abstracts_cache
end

let is_forbidden_symbol f ty =
(* Keep record constructors because models.ml expects them to be there *)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The corresponding code that expects the record constructors to be there in models.ml seems to have been removed, was it intentional?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uhm I'm not sure. The function is_forbidden_symbol is used to filter the symbols on which we will iterate during the model generation. I think the comment means we have to keep Access symbol, even if this symbol is interpreted by the theory of records, otherwise we cannot construct the model value for this theory.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote this comment. It refers to the fact that in we (used to) need to preserve the record constructors for check_records et al in models.ml, but those functions have been removed. This means that either some stuff will no longer be working, or the new code in uf.ml is meant to replace those functions and we don't need to keep the record constructors here anymore (probably the latter).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment isn't relevant anymore as we don't need to fold on all the terms in the union-find to produce model values for record symbols.

LX.save_cache ()
(* Caches used during the computation of the model.
All these caches are flushed before generating a new model. *)
module Cache = struct
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why the caches are stored in global variables? It would be cleaner (and thread-safe) to have a type that bundles the hash tables and is passed to compute_concrete_model_of_val.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No reason, I will create the cache in compute_concrete_model directly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put caches in the closure of the function extract_concrete_model.

Comment on lines 1143 to 1098
(* As arrays are immutable, the result of the set operator is
never a user-defined array and has to be ignored. *)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not true. The result of the set operator can be equal to a user-defined array, as in #929 (in fact this may or may not be the source of #929)

Copy link
Collaborator Author

@Halbaroth Halbaroth Dec 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comment was misleading. In fact Set symbols occur here by accident because X.is_my_symbol isn't the appropriate function to filter terms here. I just removed the comment and I'll do another PR in which a create a better predicate for this use case.

src/lib/reasoners/uf.ml Outdated Show resolved Hide resolved
Comment on lines 1224 to 1229
| Sy.Op (Float | Fixed | Abs_int | Abs_real | Sqrt_real
| Sqrt_real_default | Sqrt_real_excess
| Real_of_int | Int_floor | Int_ceil
| Max_int | Max_real | Min_int | Min_real
| Pow | Integer_log2 | Int2BV _ | BV2Nat
| BVand | BVor | Integer_round) -> true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After #886, BV2Nat, Int2BV and Pow should no longer be treated as suspicious. Further, Float, Abs_int, Abs_real, Sqrt_real_default, Sqrt_real_excess, Real_of_int, Int_floor, Int_ceil, Max_int, Max_real, Min_int, Min_real, Integer_log2 and Integer_round are now only suspicious if the FPA prelude is not loaded.

This is because we now propagate their arguments during model generation, which should prevent us from generating models with invalid values for these functions.

@Halbaroth
Copy link
Collaborator Author

Halbaroth commented Nov 10, 2023

This PR feels like it stops halfway through: from reading the PR description I thought that we would be building a structured representation of the model in memory prior to printing, but we actually build a fairly shallow map where most things are strings. I think we should go all the way and keep the structured representation throughout, rather than build (and intern!) intermediate strings that are only used for printing; although there are maybe blockers to that I don't immediately see — thoughts?

As I explained in the description of this PR, the purpose of it is to solve the issue #833. Actually, this PR comes from a first commit I did in a old PR I've never pushed because we had to merge OptimAE first. I keep it as simple as possible because I want to merge it before #921.

In a next PR, I plan to produce models with the following ADT:

  type simple =
    | Int of Z.t
    | Real of Q.t
    | Bool of bool
    | Constructor of string

  type array =
    | AbstractArray of Id.t * Ty.t * Ty.t
    | Store of array * t * t

  and t =
    | Abstract of sy
    | Constant of simple
    | Array of array
    | Record of string * t list

This should be sufficient to perform evaluation of expression on the model, and so to perform checking models.

Actually, I'm not really happy of the next commits of my old PR. The situation is complicated because we have a conflict between two designs:

  • First, the semantic value type is abstract, which means we cannot using directly the semantic values to get the model values because we have no access to their recursive structures in the uf module.
    The case of records is particularly eloquent here. Generating the model value in shostak would be so easy. You just need to write a recursive function. This is what I did in my old PR. It works very fine with all the current theories but arrays...

  • Second, arrays has no semantic value. In other words, we cannot retrieve directly the model value from the semantic values by a simple recursive call in shostak. Currently, we explore all the union-find in uf and retrieve the mode value by catching all the get expressions and accumulating values in caches.

There is another annoying issue. The current function choose_adequate_model needs the class of the value for which we want a model value. For recursive values, as records or ADT, we will need more as we will perform recursive call. So the new choose_adequate_model requires the state of the union-find.... which means the best place to perform this computation is uf as it is actually? I don't know, may be we should create semantic values for arrays?

I fixed the issue you noticed with records and add some tests.

@Halbaroth
Copy link
Collaborator Author

I am not entirely convinced this is a good idea — I am not opposed to it but we may want to include things that are not Sy.Name in the models at some point (namely, values for partially interpreted functions such as division by zero) where we may regret this change.

If we need some other symbols in the futur, we can create a new type for it in ModelMap. A lot of the symbols of Symbols are fully interpreted and shouldn't appear in the signature of model values.

Copy link
Collaborator

@bclement-ocp bclement-ocp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why these changes are needed to fix #833. #833 is about when we decide to print the model or not. This PR doesn't change that, it changes the way we store the model prior to printing it. Besides, the offending call to Options.get_interpretation that was the source of #833 is no longer present in output_concrete_model, so to me it looks like #833 is already fixed.

Anyways, arrays cannot have (meaningful) semantic values because the theory of arrays cannot have a Shostak solver, so I think we are stuck with a few contorsions for arrays specifically.

That doesn't mean we have to do the same contorsions for records. In fact, for Shostak theories we can (and probably should) use semantic values, as you suggest here and we also discussed a couple months ago. I don't think that the type of semantic values being abstract is a big issue; we just need to figure out the proper API to expose from the Shostak module.

I think that the best way might be to expose:

  • children : r -> r list that returns the list of direct alien children of a semantic value
  • pp_model : r Fmt.t -> r Fmt.t that prints a semantic value, using the first argument for its children

This should be enough for the union-find part to do its job. In fact, since model generation is done through the case split mechanism (case_split ~for_model:true is first called before extracting the model), we may only need pp_model?

This way, we can check with X.is_a_leaf -- if it returns true, this is an uninterpreted term (or AC symbol) and we can either print the associated abstract constant or (if it's an array) the structure reconstructed from UF. And we could get rid of most of the strings laying around…

(As an aside, I am not sure I understand the issue with choose_adequate_model and recursion. At the point we reach choose_adequate_model all values should be (conceptually) ground and have been assigned by the previous calls to assign_value. In fact, I think that arrays (and records, in the current implementation) are the only ones that truly need the equivalence class in choose_adequate_model — in my understanding any other theory needing this equivalence class is a symptom of a bug or a design issue.)

Symbols.t * Ty.t list * Ty.t
module Value : sig
type array =
| AbstractArray of Id.t * Ty.t * Ty.t
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You changed the name from Abstract to AbstractArray but my question remains: what is the difference between Abstract (n, tys, ty) and Array (AbstractArray (n, tys, ty))? I feel like just having Store of t * t * t should be enough here and would avoid this possible confusion.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not relevant anymore.

src/lib/structures/modelMap.ml Show resolved Hide resolved
Comment on lines 3 to 4
; This model is a best-effort. It includes symbols
; for which model generation is known to be incomplete.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My point is that we don't inspect the preludes for the "known to be incomplete" message and that I think we should never print it for the float function (rather than always print it), because we expect users to use them with the preludes (or to know what they are doing).

(BTW the fact that we reply "unknown" and not "sat" is also an indication that the model might be incomplete)

@Halbaroth
Copy link
Collaborator Author

So I close this PR?

@bclement-ocp
Copy link
Collaborator

I think this PR does some things right (even fixes some bugs!), even though it doesn't seem needed to fix #833. In particular, having a structured representation of models is useful (notably because for some theories such as arrays the solver doesn't really store the information in the appropriate way in the first place we we noted), even if we may want to change the way that representation is built in the future.

That said, if it is the first in a sequence of PRs that you are no longer happy with, maybe we should first take some time to brainstorm the API we want to have (my gut feeling is that it should be centered around canonical semantic values, not symbols, associated with an auxiliary mapping for uninterpreted terms that don't have ground semantic values, i.e. arrays, functions) to make sure we are going towards the direction we want and one that fixes the design bugs we can encounter with the current implementation.

@Halbaroth Halbaroth marked this pull request as draft November 10, 2023 16:56
@Halbaroth Halbaroth force-pushed the refactoring-models-representation branch 3 times, most recently from fe49fb5 to caae55f Compare December 6, 2023 15:56
@Halbaroth Halbaroth marked this pull request as ready for review December 7, 2023 16:13
@Halbaroth
Copy link
Collaborator Author

Halbaroth commented Dec 7, 2023

I update this PR to use Expr.t instead of strings in order to store model values. I also add a new function to_const_term in sig.mli. This function returns a constant interpreted term from a constant semantic value. Please refer to the commit message of caae55f for more details.

Copy link
Collaborator

@bclement-ocp bclement-ocp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like there are still some issues with the ways arrays and abstract types are printed.

See for instance:

(set-option :produce-models true)
(set-logic ALL)
(declare-sort S 0)
(declare-const s S)
(declare-datatype Pair ((pair (first (Array Int S)) (second (Array Int S)))))
(declare-const x Pair)
(assert (= (select (first x) 0) s))
(assert (= (first x) (second x)))
(check-sat)
(get-model)

This prints:

unknown
(
  (define-fun s () S (as @a0 S))
  (define-fun x () Pair (pair .k4 .k4))
  (define-fun .k4 () (Array Int S) (store (as @a1 (Array Int S)) 0 s))
)

but the .k4 symbol should not appear in the model as it is an internal name (and only symbols defined by the user should appear in models). The expected output should be along the lines of:

unknown
(
  (define-fun s () S (as @a0 S))
  (define-fun x () Pair
    (pair
      (store (as @a1 (Array Int S)) 0 s)
      (store (as @a1 (Array Int S)) 0 s)))
)

We probably need one last substitution step of fresh array and abstract constants.

arrays : ModelMap.t;
terms_values : (Shostak.Combine.r * string) Expr.Map.t
model : ModelMap.t;
terms_values : Expr.t Expr.Map.t
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this should be term_values.

let fresh_counter = ref 0

let reset_counter () = fresh_counter := 0
(* of module SmtlibCounterExample *)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what this means?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's a rebase artefact. It was used to delimit a module that doesn't exist anymore.

Comment on lines 390 to 401
begin
let Expr.{ f; xs; _ } = Expr.term_view t in
match f, xs with
| Symbols.(True | False | Void), [] -> true
| _ -> false
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a comment here explaining why this is not Expr.is_const_term (because other constants are semantic values).

Copy link
Collaborator Author

@Halbaroth Halbaroth Dec 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, we could use Expr.is_const_term. I didn't use it because when I wrote this code, the predicate Expr.is_const_term should accept variables as we use it in the smart constructor of let bindings. I decided to use two predicates and we don't need to accept variables with Expr.is_const_term anymore. Still, it makes sense to write a specific code here. I add a comment to explain the situation.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After simplifying the code model_repr_of_term in the union-find, we don't need to change X.is_constant anymore. But I think it would be better to have this invariant:

let mk, _ = X.make e in
if Expr.is_const_term e then assert (X.is_constant mk)

In other words, X.make sends model values to constant semantic values.

  let is_constant r =
    match r.v with
    | Arith t -> ARITH.is_constant t
    | Records t -> RECORDS.is_constant t
    | Bitv t -> BITV.is_constant t
    | Arrays t -> ARRAYS.is_constant t
    | Enum t -> ENUM.is_constant t
    | Adt t -> ADT.is_constant t
    | Ite t -> ITE.is_constant t
    | Term t ->
      begin
        let Expr.{ f; xs; _ } = Expr.term_view t in
        match f, xs with
        | Symbols.(True | False | Void | Name _), [] -> true
        | _ -> false
      end
    | Ac _ -> false

*)
val choose_adequate_model : Expr.t -> r -> (Expr.t * r) list -> r * string

val to_const_term : r -> Expr.t option
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be documented here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put the documentation in the second signature. I do a copy.

Comment on lines 1026 to 1028
(* We do this because terms of some semantic values created by CS
aren't created and added to the union-find. *)
X.to_const_term rep
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what this comment means; terms of most semantic values created by Alt-Ergo are not added to env.make. I'd have expected X.to_const_term rep to always be the correct answer (except for arrays). When is that not the case?

(My understanding is that cls is guaranteed to be either [] or [rep] and any other value would break Shostak invariants; is that correct?)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. I reproduced the old code here but we don't need to filter the class at all. This code seems to work:

    let mk = try ME.find t env.make with Not_found -> assert false in
    let rep, _ = try MapX.find mk env.repr with Not_found -> assert false in
    match X.to_const_term rep with 
    | Some v -> v, ME.add t v mrepr
    | None -> assert false

If X.to_const_term rep fails to produce a model term here, it's a bug.

let rty =
match type_info a with
| Tfarray (_, rty) -> rty
| _ -> invalid_arg "[Expr.ArraysEx.select]"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| _ -> invalid_arg "[Expr.ArraysEx.select]"
| _ -> invalid_arg "Expr.ArraysEx.select"

@@ -213,3 +212,25 @@ let rec print_list_pp ~sep ~pp fmt = function

let internal_error msg =
Format.kasprintf (fun s -> raise (Internal_error s)) msg

(* TODO: we have to update the way we manage quoted symbols after
the merge of https://github.com/Gbury/dolmen/pull/198 *)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been merged, I believe (#955 )

Comment on lines 3 to 4
; This model is a best-effort. It includes symbols
; for which model generation is known to be incomplete.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which ones? This problem only uses the builtin < and <= on reals, as far as I can tell.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't fix this issue because I don't understand your point as I explained here: #925 (comment)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I replied there (sorry, it got lost int the notifications somewhere) but I don't think this is related; arith7 doesn't look like it is using any suspicious symbols.

@@ -1015,14 +1023,24 @@ let mk_ite cond th el =
if ty == Ty.Tbool then mk_if cond th el
else mk_term (Sy.Op Sy.Tite) [cond; th; el] ty

let [@inline always] const_term e =
(* we use this function because depth is currently not correct to
let rec is_const_term e =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought this was replacing the pre-existing const_term function. Given that it's not, it is very confusing to have both const_term and is_const_term performing checks but returning different values. Can we maybe call this is_model_term or is_value_term instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

Currently, we produce casesplits for bitvectors in order to generate
models but we cannot reasoning with `BVand`, `BVxor` and `BVor`. It
means we cannot add these symbols as interpreted symbols of the theory
BV (see the function `Bitv.is_mine_symbol`) but these symbols can appear
in the union-find environment. We have to ignore them while computing
the model in UF.
We have to consider every symbol names starting with a dot or a `at` as
an internal symbols. For instance the CDCL SAT solver produces internal
names prefixed by `.PROXY__`.
We don't need to consider the case where a constant semantic value would
be a concatenation of constant simple terms. Now the canonizer eliminate
this case completely.
Variables aren't adequate model values. Now the predicate
`is_model_term` returns `false` on them.
We don't need to inspect the class of a term to retrieve a constant
expression in it. When we call `model_repr_of_term` during the model
generation, we are sure that the representant of the class is a constant
semantic value and `X.to_const_term` cannot fail. Otherwise, it's a bug!
As we rename `Expr.is_const_term` to `Expr.is_model_term`, I rename
this function for consistency purposes.
As arrays can occur into model values, we need to use `Expr.t` to
represent them.

We cannot produce the appropriate model term with `Arrays.to_model_term`
because we haven't semantic values for arrays. Instead we perform two
passes on a pre-model generating with `X.to_model_term`.
- The first pass collects all the values of arrays and generates a model
  term for each array. If the array was declared by the user, we add
  it to the model.
- The second pass substitutes all the array identifiers in the pre-model
  by model terms we have generated in the first pass.
Copy link
Collaborator

@bclement-ocp bclement-ocp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll let you choose whether to use internal identifers or abstract identifiers during model generation; I think on the other points we are ready to merge.

@Halbaroth Halbaroth enabled auto-merge (squash) December 21, 2023 17:37
@Halbaroth Halbaroth dismissed Stevendeo’s stale review December 21, 2023 17:38

The review is outdated.

@Halbaroth Halbaroth merged commit f451ee0 into OCamlPro:next Dec 21, 2023
13 checks passed
bclement-ocp added a commit to bclement-ocp/alt-ergo that referenced this pull request Jan 22, 2024
The `X.is_constant` function is intended to determine whether a semantic
value is a constant value (it is documented to be equivalent to having
an empty `X.leaves`). This invariant is relied upon by the code for
delayed computation in `Rel_utils` that it was introduced for in OCamlPro#869.
While the change only makes the delayed computation code less efficient,
it makes the `X.is_constant` function worthless for its original purpose
in planned patches.

The invariant was broken in OCamlPro#925 which causes `X.is_constant` to now
consider some terms (specifically, names, i.e. uninterpreted constants)
as constants, which is incorrect for the intended and documented purpose
of `X.is_constant` (uninterpreted constants have different values in
different context, they are thus not constant values).

This patch restores the original semantic of `X.is_constant` with
improved documentation, and removes the assertion introduced in OCamlPro#925
which seems to be the only incorrect use.
Halbaroth pushed a commit that referenced this pull request Jan 23, 2024
The `X.is_constant` function is intended to determine whether a semantic
value is a constant value (it is documented to be equivalent to having
an empty `X.leaves`). This invariant is relied upon by the code for
delayed computation in `Rel_utils` that it was introduced for in #869.
While the change only makes the delayed computation code less efficient,
it makes the `X.is_constant` function worthless for its original purpose
in planned patches.

The invariant was broken in #925 which causes `X.is_constant` to now
consider some terms (specifically, names, i.e. uninterpreted constants)
as constants, which is incorrect for the intended and documented purpose
of `X.is_constant` (uninterpreted constants have different values in
different context, they are thus not constant values).

This patch restores the original semantic of `X.is_constant` with
improved documentation, and removes the assertion introduced in #925
which seems to be the only incorrect use.
bclement-ocp added a commit to bclement-ocp/opam-repository that referenced this pull request Sep 24, 2024
CHANGES:

### Command-line interface

 - Enable FPA theory by default (OCamlPro/alt-ergo#1177)
 - Remove deprecated output channels (OCamlPro/alt-ergo#782)
 - Deprecate the --use-underscore since it produces models that are not SMT-LIB
   compliant (OCamlPro/alt-ergo#805)
 - Add --dump-models-on to dump models on a specific output channel (OCamlPro/alt-ergo#838)
 - Use consistent return codes (OCamlPro/alt-ergo#842)
 - Add --continue-on-error flag to set the SMT-LIB error behavior (OCamlPro/alt-ergo#853)
 - Make dolmen the default value for the --frontend option (OCamlPro/alt-ergo#857)
 - Restore functionality to broken `--profiling` option (OCamlPro/alt-ergo#947)
 - Add bare-bones support for interactive input in SMT-LIB format (OCamlPro/alt-ergo#949)
 - Less confusing behavior on timeout (OCamlPro/alt-ergo#982, OCamlPro/alt-ergo#984)
 - Add `--strict` option for SMT-LIB compliant mode (OCamlPro/alt-ergo#916, OCamlPro/alt-ergo#1133)
 - Deprecate `sum`, `typing` and `warnings` debug flags (OCamlPro/alt-ergo#1204)

### SMT-LIB support

 - Add support for the many new SMT-LIB commands (OCamlPro/alt-ergo#837, OCamlPro/alt-ergo#848, OCamlPro/alt-ergo#852, OCamlPro/alt-ergo#863, OCamlPro/alt-ergo#911,
   OCamlPro/alt-ergo#942, OCamlPro/alt-ergo#945, OCamlPro/alt-ergo#961, OCamlPro/alt-ergo#975, OCamlPro/alt-ergo#1069)
 - Expose the FPA rounding builtin in the SMT-LIB format (OCamlPro/alt-ergo#876, OCamlPro/alt-ergo#1135)
 - Allow changing the SAT solver using (set-option) (OCamlPro/alt-ergo#880)
 - Add support for the `:named` attribute (OCamlPro/alt-ergo#957)
 - Add support for quoted identifiers (OCamlPro/alt-ergo#909, OCamlPro/alt-ergo#972)
 - Add support for naming lemmas in SMT-LIB syntax (OCamlPro/alt-ergo#1141, OCamlPro/alt-ergo#1143)

### Model generation

 - Use post-solve SAT environment in model generation, fixing issues where
   incorrect models were generated (OCamlPro/alt-ergo#789)
 - Restore support for records in models (OCamlPro/alt-ergo#793)
 - Use abstract values instead of dummy values in models where the
   actual value does not matter (OCamlPro/alt-ergo#804, OCamlPro/alt-ergo#835)
 - Use fresh names for all abstract values to prevent accidental captures (OCamlPro/alt-ergo#811)
 - Add support for model generation with the default CDCL solver (OCamlPro/alt-ergo#829)
 - Support model generation for the BV theory (OCamlPro/alt-ergo#841, OCamlPro/alt-ergo#968)
 - Add support for optimization (MaxSMT / OptiSMT) with
   lexicographic Int and Real objectives (OCamlPro/alt-ergo#861, OCamlPro/alt-ergo#921)
 - Add a SMT-LIB printer for expressions (OCamlPro/alt-ergo#952, OCamlPro/alt-ergo#981, OCamlPro/alt-ergo#1082, OCamlPro/alt-ergo#931, OCamlPro/alt-ergo#932)
 - Ensure models have a value for all constants in the problem (OCamlPro/alt-ergo#1019)
 - Fix a rare soundness issue with integer constraints when model generation is
   enabled (OCamlPro/alt-ergo#1025)
 - Support model generation for the ADT theory (OCamlPro/alt-ergo#1093, OCamlPro/alt-ergo#1153)

### Theory reasoning

 - Add word-level propagators for the BV theory (OCamlPro/alt-ergo#944, OCamlPro/alt-ergo#1004, OCamlPro/alt-ergo#1007, OCamlPro/alt-ergo#1010,
   OCamlPro/alt-ergo#1011, OCamlPro/alt-ergo#1012, OCamlPro/alt-ergo#1040, OCamlPro/alt-ergo#1044, OCamlPro/alt-ergo#1054, OCamlPro/alt-ergo#1055, OCamlPro/alt-ergo#1056, OCamlPro/alt-ergo#1057, OCamlPro/alt-ergo#1065, OCamlPro/alt-ergo#1073, OCamlPro/alt-ergo#1144,
   OCamlPro/alt-ergo#1152)
 - Add interval domains and arithmetic propagators for the BV theory (OCamlPro/alt-ergo#1058,
   OCamlPro/alt-ergo#1083, OCamlPro/alt-ergo#1084, OCamlPro/alt-ergo#1085)
 - Native support for bv2nat of bit-vector normal forms (OCamlPro/alt-ergo#1154)
 - Fix incompleteness issues in the BV solver (OCamlPro/alt-ergo#978, OCamlPro/alt-ergo#979)
 - Abstract more arguments of AC symbols to avoid infinite loops when
   they contain other AC symbols (OCamlPro/alt-ergo#990)
 - Do not make irrelevant decisions in CDCL solver, improving
   performance slightly (OCamlPro/alt-ergo#1041)
 - Rewrite the ADT theory to use domains and integrate the enum theory into the
   ADT theory (OCamlPro/alt-ergo#1078, OCamlPro/alt-ergo#1086, OCamlPro/alt-ergo#1087, OCamlPro/alt-ergo#1091, OCamlPro/alt-ergo#1094, OCamlPro/alt-ergo#1138)
 - Rewrite the Intervals module entirely (OCamlPro/alt-ergo#1108)
 - Add maximize/minimize terms for matching (OCamlPro/alt-ergo#1166)
 - Internalize `sign_extend` and `repeat` (OCamlPro/alt-ergo#1192)
 - Run cross-propagators to completion (OCamlPro/alt-ergo#1221)
 - Support binary distinct on arbitrary bit-widths (OCamlPro/alt-ergo#1222)
 - Only perform optimization when building a model (OCamlPro/alt-ergo#1224)
 - Make sure domains do not overflow the default domain (OCamlPro/alt-ergo#1225)
 - Do not build unnormalized values in `zero_extend` (OCamlPro/alt-ergo#1226)

### Internal/library changes

 - Rewrite the Vec module (OCamlPro/alt-ergo#607)
 - Move printer definitions closer to type definitions (OCamlPro/alt-ergo#808)
 - Mark proxy names as reserved (OCamlPro/alt-ergo#836)
 - Use a Zarith-based representation for numbers and bit-vectors (OCamlPro/alt-ergo#850, OCamlPro/alt-ergo#943)
 - Add native support for (bvnot) in the BV solver (OCamlPro/alt-ergo#856)
 - Add constant propagators for partially interpreted functions (OCamlPro/alt-ergo#869)
 - Remove `Util.failwith` in favor of `Fmt.failwith` (OCamlPro/alt-ergo#872)
 - Add more `Expr` smart constructors (OCamlPro/alt-ergo#877, OCamlPro/alt-ergo#878)
 - Do not use existential variables for integer division (OCamlPro/alt-ergo#881)
 - Preserve `Subst` literals to prevent accidental incompleteness (OCamlPro/alt-ergo#886)
 - Properly start timers (OCamlPro/alt-ergo#924)
 - Compute a concrete representation of a model instead of performing (OCamlPro/alt-ergo#925)
 - Allow direct access to the SAT API in the Alt-Ergo library computations
   during printing (OCamlPro/alt-ergo#927)
 - Better handling for step limit (OCamlPro/alt-ergo#936)
 - Add a generic option manager to deal with the dolmen state (OCamlPro/alt-ergo#951)
 - Expose an imperative SAT API in the Alt-Ergo library (OCamlPro/alt-ergo#962)
 - Keep track of the SMT-LIB mode (OCamlPro/alt-ergo#971)
 - Add ability to decide on semantic literals (OCamlPro/alt-ergo#1027, OCamlPro/alt-ergo#1118)
 - Preserve trigger order when parsing quantifiers with multiple trigger
   (OCamlPro/alt-ergo#1046).
 - Store domains inside the union-find module (OCamlPro/alt-ergo#1119)
 - Remove some polymorphic hashtables (OCamlPro/alt-ergo#1219)

### Build and integration

 - Drop support for OCaml <4.08.1 (OCamlPro/alt-ergo#803)
 - Use dune-site for the inequalities plugins. External pluginsm ust now be
   registered through the dune-site plugin mechanism in the
   `(alt-ergo plugins)` site to be picked up by Alt-Ergo (OCamlPro/alt-ergo#1049).
 - Add a release workflow (OCamlPro/alt-ergo#827)
 - Add a Windows workflow (OCamlPro/alt-ergo#1203)
 - Mark the dune.inc file as linguist-generated to avoid huge diffs (OCamlPro/alt-ergo#830)
 - Use GitHub Actions badges in the README (OCamlPro/alt-ergo#882)
 - Use `dune build @check` to build the project (OCamlPro/alt-ergo#887)
 - Enable warnings as errors on the CI (OCamlPro/alt-ergo#888)
 - Uniformization of internal identifiers generation (OCamlPro/alt-ergo#905, OCamlPro/alt-ergo#918)
 - Use an efficient `String.starts_with` implementation (OCamlPro/alt-ergo#912)
 - Fix the Makefile (OCamlPro/alt-ergo#914)
 - Add `Logs` dependency (OCamlPro/alt-ergo#1206)
 - Use `dynamic_include` to include the generated file `dune.inc` (OCamlPro/alt-ergo#1199)
 - Support Windows (OCamlPro/alt-ergo#1184,OCamlPro/alt-ergo#1189,OCamlPro/alt-ergo#1195,OCamlPro/alt-ergo#1199,OCamlPro/alt-ergo#1200)
 - Wrap the library `Alt_ergo_prelude` (OCamlPro/alt-ergo#1223)

### Testing

 - Use --enable-assertions in tests (OCamlPro/alt-ergo#809)
 - Add a test for push/pop (OCamlPro/alt-ergo#843)
 - Use the CDCL solver when testing model generation (OCamlPro/alt-ergo#938)
 - Do not test .smt2 files with the legacy frontend (OCamlPro/alt-ergo#939)
 - Restore automatic creation of .expected files (OCamlPro/alt-ergo#941)

### Documentation

 - Add a new example for model generation (OCamlPro/alt-ergo#826)
 - Add a Pygments lexer for the Alt-Ergo native language (OCamlPro/alt-ergo#862)
 - Update the current authors (OCamlPro/alt-ergo#865)
 - Documentation of the `Enum` theory (OCamlPro/alt-ergo#871)
 - Document `Th_util.lit_origin` (OCamlPro/alt-ergo#915)
 - Document the CDCL-Tableaux solver (OCamlPro/alt-ergo#995)
 - Document Windows support (OCamlPro/alt-ergo#1216)
 - Remove instructions to install Alt-Ergo on Debian (OCamlPro/alt-ergo#1217)
 - Document optimization feature (OCamlPro/alt-ergo#1231)
tjammer pushed a commit to tjammer/opam-repository that referenced this pull request Sep 24, 2024
CHANGES:

### Command-line interface

 - Enable FPA theory by default (OCamlPro/alt-ergo#1177)
 - Remove deprecated output channels (OCamlPro/alt-ergo#782)
 - Deprecate the --use-underscore since it produces models that are not SMT-LIB
   compliant (OCamlPro/alt-ergo#805)
 - Add --dump-models-on to dump models on a specific output channel (OCamlPro/alt-ergo#838)
 - Use consistent return codes (OCamlPro/alt-ergo#842)
 - Add --continue-on-error flag to set the SMT-LIB error behavior (OCamlPro/alt-ergo#853)
 - Make dolmen the default value for the --frontend option (OCamlPro/alt-ergo#857)
 - Restore functionality to broken `--profiling` option (OCamlPro/alt-ergo#947)
 - Add bare-bones support for interactive input in SMT-LIB format (OCamlPro/alt-ergo#949)
 - Less confusing behavior on timeout (OCamlPro/alt-ergo#982, OCamlPro/alt-ergo#984)
 - Add `--strict` option for SMT-LIB compliant mode (OCamlPro/alt-ergo#916, OCamlPro/alt-ergo#1133)
 - Deprecate `sum`, `typing` and `warnings` debug flags (OCamlPro/alt-ergo#1204)

### SMT-LIB support

 - Add support for the many new SMT-LIB commands (OCamlPro/alt-ergo#837, OCamlPro/alt-ergo#848, OCamlPro/alt-ergo#852, OCamlPro/alt-ergo#863, OCamlPro/alt-ergo#911,
   OCamlPro/alt-ergo#942, OCamlPro/alt-ergo#945, OCamlPro/alt-ergo#961, OCamlPro/alt-ergo#975, OCamlPro/alt-ergo#1069)
 - Expose the FPA rounding builtin in the SMT-LIB format (OCamlPro/alt-ergo#876, OCamlPro/alt-ergo#1135)
 - Allow changing the SAT solver using (set-option) (OCamlPro/alt-ergo#880)
 - Add support for the `:named` attribute (OCamlPro/alt-ergo#957)
 - Add support for quoted identifiers (OCamlPro/alt-ergo#909, OCamlPro/alt-ergo#972)
 - Add support for naming lemmas in SMT-LIB syntax (OCamlPro/alt-ergo#1141, OCamlPro/alt-ergo#1143)

### Model generation

 - Use post-solve SAT environment in model generation, fixing issues where
   incorrect models were generated (OCamlPro/alt-ergo#789)
 - Restore support for records in models (OCamlPro/alt-ergo#793)
 - Use abstract values instead of dummy values in models where the
   actual value does not matter (OCamlPro/alt-ergo#804, OCamlPro/alt-ergo#835)
 - Use fresh names for all abstract values to prevent accidental captures (OCamlPro/alt-ergo#811)
 - Add support for model generation with the default CDCL solver (OCamlPro/alt-ergo#829)
 - Support model generation for the BV theory (OCamlPro/alt-ergo#841, OCamlPro/alt-ergo#968)
 - Add support for optimization (MaxSMT / OptiSMT) with
   lexicographic Int and Real objectives (OCamlPro/alt-ergo#861, OCamlPro/alt-ergo#921)
 - Add a SMT-LIB printer for expressions (OCamlPro/alt-ergo#952, OCamlPro/alt-ergo#981, OCamlPro/alt-ergo#1082, OCamlPro/alt-ergo#931, OCamlPro/alt-ergo#932)
 - Ensure models have a value for all constants in the problem (OCamlPro/alt-ergo#1019)
 - Fix a rare soundness issue with integer constraints when model generation is
   enabled (OCamlPro/alt-ergo#1025)
 - Support model generation for the ADT theory (OCamlPro/alt-ergo#1093, OCamlPro/alt-ergo#1153)

### Theory reasoning

 - Add word-level propagators for the BV theory (OCamlPro/alt-ergo#944, OCamlPro/alt-ergo#1004, OCamlPro/alt-ergo#1007, OCamlPro/alt-ergo#1010,
   OCamlPro/alt-ergo#1011, OCamlPro/alt-ergo#1012, OCamlPro/alt-ergo#1040, OCamlPro/alt-ergo#1044, OCamlPro/alt-ergo#1054, OCamlPro/alt-ergo#1055, OCamlPro/alt-ergo#1056, OCamlPro/alt-ergo#1057, OCamlPro/alt-ergo#1065, OCamlPro/alt-ergo#1073, OCamlPro/alt-ergo#1144,
   OCamlPro/alt-ergo#1152)
 - Add interval domains and arithmetic propagators for the BV theory (OCamlPro/alt-ergo#1058,
   OCamlPro/alt-ergo#1083, OCamlPro/alt-ergo#1084, OCamlPro/alt-ergo#1085)
 - Native support for bv2nat of bit-vector normal forms (OCamlPro/alt-ergo#1154)
 - Fix incompleteness issues in the BV solver (OCamlPro/alt-ergo#978, OCamlPro/alt-ergo#979)
 - Abstract more arguments of AC symbols to avoid infinite loops when
   they contain other AC symbols (OCamlPro/alt-ergo#990)
 - Do not make irrelevant decisions in CDCL solver, improving
   performance slightly (OCamlPro/alt-ergo#1041)
 - Rewrite the ADT theory to use domains and integrate the enum theory into the
   ADT theory (OCamlPro/alt-ergo#1078, OCamlPro/alt-ergo#1086, OCamlPro/alt-ergo#1087, OCamlPro/alt-ergo#1091, OCamlPro/alt-ergo#1094, OCamlPro/alt-ergo#1138)
 - Rewrite the Intervals module entirely (OCamlPro/alt-ergo#1108)
 - Add maximize/minimize terms for matching (OCamlPro/alt-ergo#1166)
 - Internalize `sign_extend` and `repeat` (OCamlPro/alt-ergo#1192)
 - Run cross-propagators to completion (OCamlPro/alt-ergo#1221)
 - Support binary distinct on arbitrary bit-widths (OCamlPro/alt-ergo#1222)
 - Only perform optimization when building a model (OCamlPro/alt-ergo#1224)
 - Make sure domains do not overflow the default domain (OCamlPro/alt-ergo#1225)
 - Do not build unnormalized values in `zero_extend` (OCamlPro/alt-ergo#1226)

### Internal/library changes

 - Rewrite the Vec module (OCamlPro/alt-ergo#607)
 - Move printer definitions closer to type definitions (OCamlPro/alt-ergo#808)
 - Mark proxy names as reserved (OCamlPro/alt-ergo#836)
 - Use a Zarith-based representation for numbers and bit-vectors (OCamlPro/alt-ergo#850, OCamlPro/alt-ergo#943)
 - Add native support for (bvnot) in the BV solver (OCamlPro/alt-ergo#856)
 - Add constant propagators for partially interpreted functions (OCamlPro/alt-ergo#869)
 - Remove `Util.failwith` in favor of `Fmt.failwith` (OCamlPro/alt-ergo#872)
 - Add more `Expr` smart constructors (OCamlPro/alt-ergo#877, OCamlPro/alt-ergo#878)
 - Do not use existential variables for integer division (OCamlPro/alt-ergo#881)
 - Preserve `Subst` literals to prevent accidental incompleteness (OCamlPro/alt-ergo#886)
 - Properly start timers (OCamlPro/alt-ergo#924)
 - Compute a concrete representation of a model instead of performing (OCamlPro/alt-ergo#925)
 - Allow direct access to the SAT API in the Alt-Ergo library computations
   during printing (OCamlPro/alt-ergo#927)
 - Better handling for step limit (OCamlPro/alt-ergo#936)
 - Add a generic option manager to deal with the dolmen state (OCamlPro/alt-ergo#951)
 - Expose an imperative SAT API in the Alt-Ergo library (OCamlPro/alt-ergo#962)
 - Keep track of the SMT-LIB mode (OCamlPro/alt-ergo#971)
 - Add ability to decide on semantic literals (OCamlPro/alt-ergo#1027, OCamlPro/alt-ergo#1118)
 - Preserve trigger order when parsing quantifiers with multiple trigger
   (OCamlPro/alt-ergo#1046).
 - Store domains inside the union-find module (OCamlPro/alt-ergo#1119)
 - Remove some polymorphic hashtables (OCamlPro/alt-ergo#1219)

### Build and integration

 - Drop support for OCaml <4.08.1 (OCamlPro/alt-ergo#803)
 - Use dune-site for the inequalities plugins. External pluginsm ust now be
   registered through the dune-site plugin mechanism in the
   `(alt-ergo plugins)` site to be picked up by Alt-Ergo (OCamlPro/alt-ergo#1049).
 - Add a release workflow (OCamlPro/alt-ergo#827)
 - Add a Windows workflow (OCamlPro/alt-ergo#1203)
 - Mark the dune.inc file as linguist-generated to avoid huge diffs (OCamlPro/alt-ergo#830)
 - Use GitHub Actions badges in the README (OCamlPro/alt-ergo#882)
 - Use `dune build @check` to build the project (OCamlPro/alt-ergo#887)
 - Enable warnings as errors on the CI (OCamlPro/alt-ergo#888)
 - Uniformization of internal identifiers generation (OCamlPro/alt-ergo#905, OCamlPro/alt-ergo#918)
 - Use an efficient `String.starts_with` implementation (OCamlPro/alt-ergo#912)
 - Fix the Makefile (OCamlPro/alt-ergo#914)
 - Add `Logs` dependency (OCamlPro/alt-ergo#1206)
 - Use `dynamic_include` to include the generated file `dune.inc` (OCamlPro/alt-ergo#1199)
 - Support Windows (OCamlPro/alt-ergo#1184,OCamlPro/alt-ergo#1189,OCamlPro/alt-ergo#1195,OCamlPro/alt-ergo#1199,OCamlPro/alt-ergo#1200)
 - Wrap the library `Alt_ergo_prelude` (OCamlPro/alt-ergo#1223)

### Testing

 - Use --enable-assertions in tests (OCamlPro/alt-ergo#809)
 - Add a test for push/pop (OCamlPro/alt-ergo#843)
 - Use the CDCL solver when testing model generation (OCamlPro/alt-ergo#938)
 - Do not test .smt2 files with the legacy frontend (OCamlPro/alt-ergo#939)
 - Restore automatic creation of .expected files (OCamlPro/alt-ergo#941)

### Documentation

 - Add a new example for model generation (OCamlPro/alt-ergo#826)
 - Add a Pygments lexer for the Alt-Ergo native language (OCamlPro/alt-ergo#862)
 - Update the current authors (OCamlPro/alt-ergo#865)
 - Documentation of the `Enum` theory (OCamlPro/alt-ergo#871)
 - Document `Th_util.lit_origin` (OCamlPro/alt-ergo#915)
 - Document the CDCL-Tableaux solver (OCamlPro/alt-ergo#995)
 - Document Windows support (OCamlPro/alt-ergo#1216)
 - Remove instructions to install Alt-Ergo on Debian (OCamlPro/alt-ergo#1217)
 - Document optimization feature (OCamlPro/alt-ergo#1231)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clean-up models This issue is related to model generation.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants