3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-10-11 10:18:06 +00:00
z3/src/smt/smt_quantifier.h
Ilana Shapiro 6044389446
Parallel solving (#7771)
* very basic setup

* ensure solve_eqs is fully disabled when smt.solve_eqs=false, #7743

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* respect smt configuration parameter in elim_unconstrained simplifier

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* indentation

* add bash files for test runs

* add option to selectively disable variable solving for only ground expressions

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove verbose output

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix #7745

axioms for len(substr(...)) escaped due to nested rewriting

* ensure atomic constraints are processed by arithmetic solver

* #7739 optimization

add simplification rule for at(x, offset) = ""

Introducing j just postpones some rewrites that prevent useful simplifications. Z3 already uses common sub-expressions.
The example highlights some opportunities for simplification, noteworthy at(..) = "".
The example is solved in both versions after adding this simplification.

* fix unsound len(substr) axiom

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* FreshConst is_sort (#7748)

* #7750

add pre-processing simplification

* Add parameter validation for selected API functions

* updates to ac-plugin

fix incrementality bugs by allowing destructive updates during saturation at the cost of redoing saturation after a pop.

* enable passive, add check for bloom up-to-date

* add top-k fixed-sized min-heap priority queue for top scoring literals

* set up worker thread batch manager for multithreaded batch cubes paradigm, need to debug as I am getting segfault still

* fix bug in parallel solving batch setup

* fix bug

* allow for internalize implies

* disable pre-processing during cubing

* debugging

* remove default constructor

* remove a bunch of string copies

* Update euf_ac_plugin.cpp

include reduction rules in forward simplification

* Update euf_completion.cpp

try out restricting scope of equalities added by instantation

* Update smt_parallel.cpp

Drop non-relevant units from shared structures.

* process cubes as lists of individual lits

* merge

* Add support for Algebraic Datatypes in JavaScript/TypeScript bindings (#7734)

* Initial plan

* Add datatype type definitions to types.ts (work in progress)

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

* Complete datatype type definitions with working TypeScript compilation

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

* Implement core datatype functionality with TypeScript compilation success

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

* Complete datatype implementation with full Context integration and tests

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

* chipping away at the new code structure

* comments

* debug infinite recursion and split cubes on existing split atoms that aren't in the cube

* share lemmas, learn from unsat core, try to debug a couple of things, there was a subtle bug that i have a hard time repro'ing

* merge

* fix #7603: race condition in Ctrl-C handling (#7755)

* fix #7603: race condition in Ctrl-C handling

* fix race in cancel_eh

* fix build

* add arithemtic saturation

* add an option to register callback on quantifier instantiation

Suppose a user propagator encodes axioms using quantifiers and uses E-matching for instantiation. If it wants to implement a custom priority scheme or drop some instances based on internal checks it can register a callback with quantifier instantiation

* missing new closure

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add Z3_solver_propagate_on_binding to ml callback declarations

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add python file

Signed-off-by: Lev Nachmanson <levnach@Levs-MacBook-Pro.local>

* debug under defined calls

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* more untangle params

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* precalc parameters to define the eval order

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* remove a printout

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* rename a Python file

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* add on_binding callbacks across APIs

update release notes,
add to Java, .Net, C++

* use jboolean in Native interface

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* register on_binding attribute

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix java build for java bindings

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* avoid interferring side-effects in function calls

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove theory_str and classes that are only used by it

* remove automata from python build

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove ref to theory_str

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* get the finest factorizations before project

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* rename add_lcs to add_lc

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* resolve bad bug about l2g and g2l translators using wrong global context. add some debug prints

* initial attempt at dynamically switching from greedy to frugal splitting strategy in return_cubes. need to test. also there is some bug where the threads take forever to cancel?

* Update RELEASE_NOTES.md

* resolve bug about not translating managers correctly for the second phase of the greedy cubing, and the frugal fallback

---------

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
Signed-off-by: Lev Nachmanson <levnach@Levs-MacBook-Pro.local>
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>
Co-authored-by: humnrdble <83878671+humnrdble@users.noreply.github.com>
Co-authored-by: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
Co-authored-by: Lev Nachmanson <levnach@hotmail.com>
2025-08-11 09:14:20 -07:00

185 lines
5.9 KiB
C++

/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
smt_quantifier.h
Abstract:
Quantifier reasoning support for smt::context.
Author:
Leonardo de Moura (leonardo) 2012-02-16.
Revision History:
--*/
#pragma once
#include "ast/ast.h"
#include "ast/quantifier_stat.h"
#include "util/statistics.h"
#include "util/params.h"
#include "smt/smt_types.h"
#include "tactic/user_propagator_base.h"
#include <tuple>
class proto_model;
struct smt_params;
namespace smt {
class quantifier_manager_plugin;
class quantifier_stat;
class context;
class quantifier_manager {
struct imp;
imp * m_imp;
unsigned m_lazy_scopes;
bool m_lazy;
void flush();
public:
quantifier_manager(context & ctx, smt_params & fp, params_ref const & p);
~quantifier_manager();
context & get_context() const;
void add(quantifier * q, unsigned generation);
void del(quantifier * q);
bool empty() const;
bool is_shared(enode * n) const;
q::quantifier_stat * get_stat(quantifier * q) const;
unsigned get_generation(quantifier * q) const;
static void log_justification_to_root(std::ostream & log, enode *en, obj_hashtable<enode> &already_visited, context &ctx, ast_manager &m);
bool add_instance(quantifier * q, app * pat,
unsigned num_bindings,
enode * const * bindings,
expr* def,
unsigned max_generation,
unsigned min_top_generation,
unsigned max_top_generation,
vector<std::tuple<enode *, enode *>> & used_enodes /*gives the equalities used for the pattern match, see mam.cpp for more info*/);
bool add_instance(quantifier * q, unsigned num_bindings, enode * const * bindings, expr* def, unsigned generation = 0);
void init_search_eh();
void assign_eh(quantifier * q);
void add_eq_eh(enode * n1, enode * n2);
void relevant_eh(enode * n);
final_check_status final_check_eh(bool full);
void restart_eh();
bool can_propagate() const;
void propagate();
enum check_model_result {
SAT, UNKNOWN, RESTART
};
bool model_based() const;
bool has_quantifiers() const;
bool mbqi_enabled(quantifier *q) const; // can mbqi instantiate this quantifier?
void adjust_model(proto_model * m);
check_model_result check_model(proto_model * m, obj_map<enode, app *> const & root2value);
void push();
void pop(unsigned num_scopes);
void reset();
void display(std::ostream & out) const;
void display_stats(std::ostream & out, quantifier * q) const;
void collect_statistics(::statistics & st) const;
void reset_statistics();
void register_on_binding(std::function<bool(quantifier*, expr*)> & f);
ptr_vector<quantifier>::const_iterator begin_quantifiers() const;
ptr_vector<quantifier>::const_iterator end_quantifiers() const;
ptr_vector<quantifier>::const_iterator begin() const { return begin_quantifiers(); }
ptr_vector<quantifier>::const_iterator end() const { return end_quantifiers(); }
unsigned num_quantifiers() const;
};
class quantifier_manager_plugin {
public:
virtual ~quantifier_manager_plugin() = default;
virtual void set_manager(quantifier_manager & qm) = 0;
virtual quantifier_manager_plugin * mk_fresh() = 0;
virtual void add(quantifier * q) = 0;
virtual void del(quantifier * q) = 0;
virtual bool is_shared(enode * n) const = 0;
/**
\brief This method is invoked whenever q is assigned to true.
*/
virtual void assign_eh(quantifier * q) = 0;
/**
\brief This method is invoked whenever n1 and n2 are merged into the same equivalence class.
*/
virtual void add_eq_eh(enode * n1, enode * n2) = 0;
/**
\brief This method is invoked whenever n is marked as relevant.
*/
virtual void relevant_eh(enode * n) = 0;
/**
\brief This method is invoked when a new search() is started.
*/
virtual void init_search_eh() = 0;
/**
\brief Final_check event handler.
*/
virtual final_check_status final_check_eh(bool full) = 0;
/**
\brief This method is invoked whenever the solver restarts.
*/
virtual void restart_eh() = 0;
/**
\brief Return true if the quantifier_manager can propagate information
information back into the core.
*/
virtual bool can_propagate() const = 0;
virtual void propagate() = 0;
/**
\brief Return true if the plugin is "model based"
*/
virtual bool model_based() const = 0;
/**
\brief Is "model based" instantiate allowed to instantiate this quantifier?
*/
virtual bool mbqi_enabled(quantifier *q) const {return true;}
/**
\brief Give a change to the plugin to adjust the interpretation of uninterpreted functions.
It can basically change the "else" of each uninterpreted function.
*/
virtual void adjust_model(proto_model * m) = 0;
/**
\brief Core invokes this method to check whether the candidate interpretation
satisfies the quantifiers in the manager.
It also provides a mapping from enodes to their interpretations.
*/
virtual quantifier_manager::check_model_result check_model(proto_model * m, obj_map<enode, app *> const & root2value) = 0;
virtual void push() = 0;
virtual void pop(unsigned num_scopes) = 0;
};
};