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

feat: support (get-info :all-statistics) and refactoring Profiling module #863

Merged
merged 9 commits into from
Oct 10, 2023

Conversation

Stevendeo
Copy link
Collaborator

This PR was initially open to add the get-statistics option. Some bugs and (IMHO) bad design choices in the Timer and Profiling module changed the purpose of this PR to not only add the get-statistics feature, but also to rework it.

@Stevendeo Stevendeo changed the title Get statistics [WIP] Get statistics Oct 5, 2023
@Stevendeo Stevendeo marked this pull request as ready for review October 5, 2023 16:26
@Stevendeo Stevendeo requested review from bclement-ocp, Halbaroth and hra687261 and removed request for bclement-ocp October 5, 2023 16:26
@Stevendeo Stevendeo changed the title [WIP] Get statistics Get statistics Oct 5, 2023
@Halbaroth Halbaroth changed the title Get statistics feat: support (get-info :allt-statistics) and refactoring Profiling module Oct 5, 2023
@Halbaroth Halbaroth changed the title feat: support (get-info :allt-statistics) and refactoring Profiling module feat: support (get-info :all-statistics) and refactoring Profiling module Oct 5, 2023
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 will take a look at the rest of the changes later, but this patch moves the timers from a global constant in the binary (bin/common/signals_profiling.ml) to a global constant in the library (lib/structures/profiling.ml), which is the opposite of the direction we should be going for (see also #377). Please revert that part of the change.

src/lib/structures/profiling.mli Outdated Show resolved Hide resolved
src/lib/structures/profiling.mli Outdated Show resolved Hide resolved
src/bin/common/solving_loop.ml Outdated Show resolved Hide resolved
if Options.get_profiling () then
Printer.print_std "%t" Profiling.print_get_statistics
else
Printer.print_smtlib_err "Profiling disactivated (try --profiling)"
Copy link
Collaborator

Choose a reason for hiding this comment

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

We could add an option to activate profiling: (set-option :produce-statistics true).

Copy link
Collaborator

Choose a reason for hiding this comment

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

If we add a set-option, we should use a name as close to the CLI option as possible to avoid confusion, such as (set-option :profiling true).

Also, (get-info :all-statistics) should not return an error. We should simply return an empty s-expression here (possibly with a warning message on stderr).

Comment on lines 157 to 177
let hash = function
| F_add -> 0
| F_add_lemma -> 1
| F_assume -> 2
| F_class_of -> 3
| F_leaves -> 4
| F_make -> 5
| F_m_lemmas -> 6
| F_m_predicates -> 7
| F_query -> 8
| F_solve -> 9
| F_subst -> 10
| F_union -> 11
| F_unsat -> 12
| F_add_predicate -> 13
| F_add_terms -> 14
| F_are_equal -> 15
| F_none -> 16
| F_new_facts -> 17
| F_apply_subst -> 18
| F_instantiate -> 19
Copy link
Collaborator

Choose a reason for hiding this comment

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

We may use the function Hashtbl.hashhere? I know using this function involves some risks but for a profiling module, the risk is limited.

Copy link
Collaborator

Choose a reason for hiding this comment

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

What are the risks of Hashtbl.hash you have in mind?

(To be fair I am not sure why we have an explicit datatype to describe profiled functions)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I mean the hash function of Hashtbl doesn't always produce a good hash function to get a O(1) lookup function in your hash table but in our case, it doesn't matter as the hash table is tiny.

Copy link
Collaborator Author

@Stevendeo Stevendeo Oct 9, 2023

Choose a reason for hiding this comment

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

We may use the function Hashtbl.hashhere? I know using this function involves some risks but for a profiling module, the risk is limited.

This function already was defined, I just copied it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If we want a shorter version, we can use Obj.magic which would here work like a charm... 😈

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Final choice: ppx_deriving.enum, as it defines the values we want.

src/lib/structures/profiling.ml Outdated Show resolved Hide resolved
src/lib/structures/profiling.ml Outdated Show resolved Hide resolved
src/lib/structures/profiling.ml Outdated Show resolved Hide resolved
src/lib/structures/profiling.ml Outdated Show resolved Hide resolved
statistics_table;
Format.fprintf fmt "@])@,"

(* Now, registering the statistics we want in get-statistics. *)
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is get-statistics here?

if Options.get_profiling () then
Printer.print_std "%t" Profiling.print_get_statistics
else
Printer.print_smtlib_err "Profiling disactivated (try --profiling)"
Copy link
Collaborator

Choose a reason for hiding this comment

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

If we add a set-option, we should use a name as close to the CLI option as possible to avoid confusion, such as (set-option :profiling true).

Also, (get-info :all-statistics) should not return an error. We should simply return an empty s-expression here (possibly with a warning message on stderr).

Comment on lines 258 to 282
(* TODO(Steven): if nobody knows how to use the previous print to debug
anything, I suggest we either remove `d` or get rid the invariant:
#(calls to Profiling.decision) = d. *)
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 a safeguard against wrong code: the profiling module maintains a "shadow" trail of decision levels which is also in the SAT module. They must be kept in sync by the SAT module calling reset_dlevel at the appropriate time. If they get out of sync, the profiling information will be garbage; having this invariant helps ensure this does not happen.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Why not just register the decision level of the SAT instead of incrementing it? This invariant forces the Profiling module to be used in a very specific manner, which is undocumented.

Copy link
Collaborator

Choose a reason for hiding this comment

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

When we make a decision the decision level is always incremented (by definition). As I say, it just looks like a safeguard. It should be correct to call reset_dlevel d here instead of incrementing state.decision_lvl, I'm not sure having the decision level in the profiling matters much anyways.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's why my comment mentions that, if we don't know if there is a deep meaning behind the error message and what it is, maybe we should just get rid of it. If we ever get in that case and get this error message, I'm not sure we know how to interpret it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

This error message means that the SAT solver is not calling the profiling module in the expected way, and that the profiling module may be accumulating incorrect statistics, because the state that the profiling module expects the solver to be in and the state the solver actually is in have diverged (they have different decision levels). I am trying to reply to your comment and explain what the error message 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.

This error message means that the SAT solver is not calling the profiling module in the expected way,

What is this "expected" way? This function is not documented. I reread the function and I noticed my remark was not correct, the invariant I state is false. My understanding of the function is the following : the decision reference counts the number of decisions taken (sounds good), and the decision level is the "depth" of the decision, in the sense that everytime we decide something we go one step deeper. As we can backtrack decisions, there also is a way to reset the decision level to a given value. Now, I really don't think the profiling module should take care of keeping track of how Alt-Ergo decides its environment handles the depth of its reasoning. Alt-Ergo has an environment depth value, which is a good thing to display while profiling, but that should be it. Calculating its decision level in the profiling looks like a hack, and the fact the printed message is in french comforts me in this idea.
I'll remove my comment anyway, we can decide in another PR if this code is relevant or not.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree this code is not very useful and would be fine removing decision_lvl altogether. I was only replying to your comment asking what it meant. Does it make sense to keep track of the decision level twice? Probably not, but that is what we currently do, and this code checks that the two places we keep track of the decision level agree. I was trying to be helpful, I am sorry if I came across any other way.

Comment on lines 307 to 308
Todo(Steven): use Pierre's solution with Printbox and put these function where
they belong (the trash).
Copy link
Collaborator

Choose a reason for hiding this comment

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

Unless you wrote this code, let's not be that harsh, please :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sorry if you actually wrote this code (or to anyone who actually wrote it), for I know the constraints were different when it was written. I use the projects I work on as free expression (maybe I should not) and I would have been as harsh with my own code :) I won't get offended by remarks on my code actually, I use these kinds of remarks as a relief and not to insult the person who wrote it.
Anyway, I'll be more respectful in the future

Copy link
Collaborator

Choose a reason for hiding this comment

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

I didn't write this code, and I know you didn't intend any harm — as you say, this code has served its purpose, even though there are probably better solutions. I just don't think it is necessary to keep disparaging comments, and it makes for an unpleasant codebase to navigate :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Copy link
Collaborator

Choose a reason for hiding this comment

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

Good thing we are not writing C then ;)

Comment on lines 157 to 177
let hash = function
| F_add -> 0
| F_add_lemma -> 1
| F_assume -> 2
| F_class_of -> 3
| F_leaves -> 4
| F_make -> 5
| F_m_lemmas -> 6
| F_m_predicates -> 7
| F_query -> 8
| F_solve -> 9
| F_subst -> 10
| F_union -> 11
| F_unsat -> 12
| F_add_predicate -> 13
| F_add_terms -> 14
| F_are_equal -> 15
| F_none -> 16
| F_new_facts -> 17
| F_apply_subst -> 18
| F_instantiate -> 19
Copy link
Collaborator

Choose a reason for hiding this comment

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

What are the risks of Hashtbl.hash you have in mind?

(To be fair I am not sure why we have an explicit datatype to describe profiled functions)

@Stevendeo
Copy link
Collaborator Author

I will take a look at the rest of the changes later, but this patch moves the timers from a global constant in the binary (bin/common/signals_profiling.ml) to a global constant in the library (lib/structures/profiling.ml), which is the opposite of the direction we should be going for (see also #377). Please revert that part of the change.

There is a fundamental issue in the whole profiling system. You can't have profiling global variables in the library to simplify profiling through the analyzer and want some other in the binary. In the previous architecture, the timer was defined in the library, declared in the binary and sent back to the library for profiling. Maybe you have discussed about it, and I would be glad to know your conclusions on the subject ; IMO I think the best choice, for now, is to centralize the whole profiling in the library because we don't want an extra argument for each module to handle profiling from the outside (but again, tell me if it was not your choice).
You will note I lazyfied the timers so that it is only created when the profiling option is on, so that we keep the same behavior than before, but . What I can do in this PR is to lazify the whole profling value instead of only the timer. One of the possibilities to address #377 would be to have sessions : when using alt-ergo-lib, you initialize a session that is linked to a specific profiling value.

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 had a hard time understanding your message, but I see what you mean: what use is it having a Timers.t object that we pass around if it ends up stored in global timer_start and timer_pause functions anyways?

This is a fair point that I didn't consider, but am still not entirely convinced, because the Timers module does two things currently: it provides a data structure to accumulate and print timers, and hooks to register arbitrary profiling functions (that may or may not use the provided data structure, although realistically always will). This looks like good design, and keeps the use of global state to a minimum.

Regarding having an extra argument to each module for profiling: if we clean up the library, we will probably end up with some sort of Config module that is threaded around and has the role of Options currently, and it makes sense to root the profiling functions there. But you are right, that is an issue we will have anyways.

By the way, what is the reasoning for moving from arrays to hash tables for storing the profiling functions? Based on the comments mentioning hash tables that are in the code, it looks like the inverse change has been made at some point in the past.

src/bin/common/solving_loop.ml Show resolved Hide resolved
src/bin/common/solving_loop.ml Show resolved Hide resolved
@Stevendeo
Copy link
Collaborator Author

I had a hard time understanding your message, but I see what you mean: what use is it having a Timers.t object that we pass around if it ends up stored in global timer_start and timer_pause functions anyways?

This is a fair point that I didn't consider, but am still not entirely convinced, because the Timers module does two things currently: it provides a data structure to accumulate and print timers, and hooks to register arbitrary profiling functions (that may or may not use the provided data structure, although realistically always will). This looks like good design, and keeps the use of global state to a minimum.

I am not sure of the relevance of these hooks. What I expect of a hook is to be applied when a timer is started. Here it is quite different : the hook is the start of the timer. Worse: the hooks are not timer dependent, they are library global references...
Anyway, I am not sure what my changes have to do with your point. In my version, the Timers still have these mutable hooks.

By the way, what is the reasoning for moving from arrays to hash tables for storing the profiling functions? Based on the comments mentioning hash tables that are in the code, it looks like the inverse change has been made at some point in the past.

Using arrays is error prone: by forgetting to update a hardcoded list, the profiling option is broken in next. Also, using hashtables allows to not to have a memory saved for unused timers. This second reason is a bad reason actually; now that I think of it, I understand why they used arrays in the first place. My version allocates memory during the analysis, which alters the time spent actually analyzing stuff. With arrays, everything is allocated before the timers starts.
Hmm. We can either go back to arrays or explicitely create all hashtables with the correct sizes.

@bclement-ocp
Copy link
Collaborator

bclement-ocp commented Oct 9, 2023

Anyway, I am not sure what my changes have to do with your point. In my version, the Timers still have these mutable hooks.

But they are now set in the library rather than the binary. Actually no, they are not set at all — which I think means that no profiling is done at all? Or am I missing something?

Using arrays is error prone: by forgetting to update a hardcoded list, the profiling option is broken in next.

Is this due to all_modules / all_functions not being updated? This should have been caught by the assert on the length, but looks like nb_mtag was not updated either. I think this can be solved by adding an appropriate comment to the type definitions. We could also steal from C's playbook and have M_Last and F_Last as special timers, with nb_mtag = mtag M_Last.

My version allocates memory during the analysis, which alters the time spent actually analyzing stuff. With arrays, everything is allocated before the timers starts.

Yeah, the hash tables allocating during profiling was one thing I was concerned about, indeed.

We can either go back to arrays or explicitely create all hashtables with the correct sizes.

If we initialize the hash tables to have constant sizes, using a hashtable instead of an array will just use more memory and be less efficient, so I'd prefer keeping the arrays. And having a comment (maybe at the top of the module?) that explicitly states "we make sure that functions in this module don't allocate while profiling" or something to that regard.

(Well, "perform minimal allocations" — start will always allocate due to the stack)

@Stevendeo
Copy link
Collaborator Author

But they are now set in the library rather than the binary. Actually no, they are not set at all — which I think means that no profiling is done at all? Or am I missing something?

They are set in the library on a call to Profiling.init (which is made in the binary).

Is this due to all_modules / all_functions not being updated? This should have been caught by the assert on the length, but looks like nb_mtag was not updated either. I think this can be solved by adding an appropriate comment to the type definitions. We could also steal from C's playbook and have M_Last and F_Last as special timers, with nb_mtag = mtag M_Last.

You are right, it was not caught because the counter was not updated either. I'll just go back to arrays and document this design.

@bclement-ocp
Copy link
Collaborator

They are set in the library on a call to Profiling.init (which is made in the binary).

Ah, I got got by the fact that this is hidden by default in GitHub's view. Since Profiling.init is in the library, and the Timers function is in the library, if we are going with this design we need to either document that the Timers function are meant for internal use and should not be called by users of the library, or that calling Profiling.init and Timers.set_timer_{start,pause} are mutually exclusive.

Comment on lines 113 to 117
(** Calls the continuation only when the profiling is on.
This allows to only force the state when the profiling is on. *)
let (let*) state f =
if Options.get_profiling () then
f (Lazy.force state)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I did not notice the use of let* earlier, apologies — I think that using let* here is quite confusing because it leads to let* state = state in whose behavior is unclear. let* is also traditionally used for a monadic bind operator, which this is not.

Why not instead call this something like if_profiling or when_profiling:

let if_profiling f = if Options.get_profiling () then f (Lazy.force state)

and then use it with:

if_profiling @@ fun state ->
...

which makes the intent more precise?

Copy link
Collaborator

Choose a reason for hiding this comment

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

(As an aside: in the current state of the code, this leads to duplicate Options.get_profiling () tests because most calls to the Profiling module are guarded with if Options.get_profiling, which is required in some cases because computation has to be performed prior to calling the corresponding profiling function)

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 usually go for custom lets to avoid the extra indentation. It really is a taste choice, I don't mind going for explicit continuations

Copy link
Collaborator

Choose a reason for hiding this comment

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

You don't have to use extra indentation with @@ fun _ ->, and most styles I am aware of don't (in fact, ocp-indent will not let you use extra indentation in this repo if you use this construct).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh my bad, I was convinced the @@ to add indentation! Okay, I'll go for it then

@Stevendeo
Copy link
Collaborator Author

They are set in the library on a call to Profiling.init (which is made in the binary).

Ah, I got got by the fact that this is hidden by default in GitHub's view. Since Profiling.init is in the library, and the Timers function is in the library, if we are going with this design we need to either document that the Timers function are meant for internal use and should not be called by users of the library, or that calling Profiling.init and Timers.set_timer_{start,pause} are mutually exclusive.

Same would go in the old functionning of timers actually, or did I miss something? Their functionning was meant for internal use, and used in the binary actually set them the only way it should have been set.
I think a better design would be to associate the timers and their hooks, and that the hooks would be triggered on calls to start.

@bclement-ocp
Copy link
Collaborator

bclement-ocp commented Oct 9, 2023

Same would go in the old functionning of timers actually, or did I miss something? Their functionning was meant for internal use, and used in the binary actually set them the only way it should have been set.

With the current design, the set_timer_start and set_timer_pause functions are exposed by the library and are the only way to set the timers. This is (to my knowledge) the only interface that allows users of the library (not using the binary) to setup the timers, and so is the de-facto public API for doing so. Now this PR is changing things so that users of the library should only call Profiling.init, but the old functions are still available, and so we should give the information somewhere that the old way of doing things will no longer work as expected (even if I am not sure anyone actually uses the library…). Alt-Ergo is poorly documented, but we should improve the status-quo by writing more documentation, not less!

I think a better design would be to associate the timers and their hooks, and that the hooks would be triggered on calls to start.

I agree — I actually don't think that the hooks should be in the Timers module at all, but rather in Profiling since that's where the global state is at.

@Stevendeo
Copy link
Collaborator Author

I will leave this PR as it is, and open an issue about documenting/rewriting profiling & timers; I feel like this PR about adding all-statistics went a little too far from it's initial purpose :)

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 am OK with that in this case, but I will note that I find it disingenuous to put it this way when the title of the PR includes "refactoring Profiling module" and most of the lines affected by the PR are not about (get-info :all-statistics) at all.

@bclement-ocp bclement-ocp merged commit 766d123 into OCamlPro:next Oct 10, 2023
14 checks passed
bclement-ocp added a commit to bclement-ocp/alt-ergo that referenced this pull request Nov 17, 2023
As noted in OCamlPro#935 the
--profiling option currently makes Alt-Ergo instantly crash because in
OCamlPro#863 we forgot a slot for the
last element in the array. This patch fixes that.
bclement-ocp added a commit that referenced this pull request Nov 17, 2023
As noted in #935 the
--profiling option currently makes Alt-Ergo instantly crash because in
#863 we forgot a slot for the
last element in the array. This patch fixes that.
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
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants