mirror of
https://github.com/Z3Prover/z3
synced 2025-08-27 13:39:49 +00:00
* 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>
281 lines
11 KiB
C++
281 lines
11 KiB
C++
/*++
|
|
Copyright (c) 2012 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
api_context.h
|
|
|
|
Abstract:
|
|
Interface of Z3 with "external world".
|
|
|
|
It was called _Z3_context
|
|
|
|
Author:
|
|
|
|
Leonardo de Moura (leonardo) 2012-02-29.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
#pragma once
|
|
|
|
#include "util/hashtable.h"
|
|
#include "util/mutex.h"
|
|
#include "util/event_handler.h"
|
|
#include "ast/ast.h"
|
|
#include "ast/arith_decl_plugin.h"
|
|
#include "ast/bv_decl_plugin.h"
|
|
#include "ast/seq_decl_plugin.h"
|
|
#include "ast/datatype_decl_plugin.h"
|
|
#include "ast/dl_decl_plugin.h"
|
|
#include "ast/fpa_decl_plugin.h"
|
|
#include "ast/recfun_decl_plugin.h"
|
|
#include "ast/special_relations_decl_plugin.h"
|
|
#include "ast/rewriter/seq_rewriter.h"
|
|
#include "params/smt_params.h"
|
|
#include "smt/smt_kernel.h"
|
|
#include "smt/smt_solver.h"
|
|
#include "cmd_context/tactic_manager.h"
|
|
#include "cmd_context/cmd_context.h"
|
|
#include "solver/solver.h"
|
|
#include "api/z3.h"
|
|
#include "api/api_util.h"
|
|
#include "api/api_polynomial.h"
|
|
|
|
namespace smtlib {
|
|
class parser;
|
|
};
|
|
|
|
namespace realclosure {
|
|
class manager;
|
|
};
|
|
|
|
namespace smt2 {
|
|
class parser;
|
|
void free_parser(parser*);
|
|
};
|
|
|
|
namespace api {
|
|
|
|
|
|
|
|
class context : public tactic_manager {
|
|
struct add_plugins { add_plugins(ast_manager & m); };
|
|
ast_context_params m_params;
|
|
bool m_user_ref_count; //!< if true, the user is responsible for managing reference counters.
|
|
#ifndef SINGLE_THREAD
|
|
bool m_concurrent_dec_ref = false;
|
|
#endif
|
|
scoped_ptr<ast_manager> m_manager;
|
|
scoped_ptr<cmd_context> m_cmd;
|
|
add_plugins m_plugins;
|
|
mutex m_mux;
|
|
|
|
arith_util m_arith_util;
|
|
bv_util m_bv_util;
|
|
datalog::dl_decl_util m_datalog_util;
|
|
fpa_util m_fpa_util;
|
|
seq_util m_sutil;
|
|
recfun::util m_recfun;
|
|
|
|
// Support for old solver API
|
|
smt_params m_fparams;
|
|
// -------------------------------
|
|
|
|
#ifndef SINGLE_THREAD
|
|
ptr_vector<ast> m_asts_to_flush, m_asts_to_flush2;
|
|
ptr_vector<api::object> m_objects_to_flush, m_objects_to_flush2;
|
|
#endif
|
|
|
|
ast_ref_vector m_ast_trail;
|
|
ref<api::object> m_last_obj; //!< reference to the last API object returned by the APIs
|
|
u_map<api::object*> m_allocated_objects; // !< table containing current set of allocated API objects
|
|
unsigned_vector m_free_object_ids; // !< free list of identifiers available for allocated objects.
|
|
|
|
family_id m_array_fid;
|
|
family_id m_bv_fid;
|
|
family_id m_dt_fid;
|
|
family_id m_datalog_fid;
|
|
family_id m_pb_fid;
|
|
family_id m_fpa_fid;
|
|
family_id m_seq_fid;
|
|
family_id m_char_fid;
|
|
family_id m_special_relations_fid;
|
|
datatype_decl_plugin * m_dt_plugin;
|
|
|
|
std::string m_string_buffer; // temporary buffer used to cache strings sent to the "external" world.
|
|
|
|
Z3_error_code m_error_code;
|
|
Z3_error_handler * m_error_handler;
|
|
std::string m_exception_msg; // catch the message associated with a Z3 exception
|
|
Z3_ast_print_mode m_print_mode;
|
|
|
|
ptr_vector<event_handler> m_interruptable; // Reference to an object that can be interrupted by Z3_interrupt
|
|
|
|
public:
|
|
// Scoped obj for setting m_interruptable
|
|
class set_interruptable {
|
|
context & m_ctx;
|
|
public:
|
|
set_interruptable(context & ctx, event_handler & i);
|
|
~set_interruptable();
|
|
};
|
|
|
|
// ------------------------
|
|
//
|
|
// Core
|
|
//
|
|
// ------------------------
|
|
|
|
context(ast_context_params * p, bool user_ref_count = false);
|
|
~context();
|
|
ast_manager & m() const { return *(m_manager.get()); }
|
|
|
|
ast_context_params & params() { m_params.updt_params(); return m_params; }
|
|
scoped_ptr<cmd_context>& cmd() { return m_cmd; }
|
|
bool produce_proofs() const { return m().proofs_enabled(); }
|
|
bool produce_models() const { return m_params.m_model; }
|
|
bool produce_unsat_cores() const { return m_params.m_unsat_core; }
|
|
bool use_auto_config() const { return m_params.m_auto_config; }
|
|
unsigned get_timeout() const { return m_params.m_timeout; }
|
|
unsigned get_rlimit() const { return m_params.rlimit(); }
|
|
arith_util & autil() { return m_arith_util; }
|
|
bv_util & bvutil() { return m_bv_util; }
|
|
datalog::dl_decl_util & datalog_util() { return m_datalog_util; }
|
|
fpa_util & fpautil() { return m_fpa_util; }
|
|
datatype_util& dtutil() { return m_dt_plugin->u(); }
|
|
seq_util& sutil() { return m_sutil; }
|
|
recfun::util& recfun() { return m_recfun; }
|
|
family_id get_basic_fid() const { return basic_family_id; }
|
|
family_id get_array_fid() const { return m_array_fid; }
|
|
family_id get_arith_fid() const { return arith_family_id; }
|
|
family_id get_bv_fid() const { return m_bv_fid; }
|
|
family_id get_dt_fid() const { return m_dt_fid; }
|
|
family_id get_datalog_fid() const { return m_datalog_fid; }
|
|
family_id get_pb_fid() const { return m_pb_fid; }
|
|
family_id get_fpa_fid() const { return m_fpa_fid; }
|
|
family_id get_seq_fid() const { return m_seq_fid; }
|
|
family_id get_char_fid() const { return m_char_fid; }
|
|
datatype_decl_plugin * get_dt_plugin() const { return m_dt_plugin; }
|
|
family_id get_special_relations_fid() const { return m_special_relations_fid; }
|
|
|
|
Z3_error_code get_error_code() const { return m_error_code; }
|
|
void reset_error_code() { m_error_code = Z3_OK; }
|
|
void set_error_code(Z3_error_code err, char const* opt_msg);
|
|
void set_error_code(Z3_error_code err, std::string &&opt_msg);
|
|
void set_error_handler(Z3_error_handler h) { m_error_handler = h; }
|
|
|
|
void enable_concurrent_dec_ref() {
|
|
#ifdef SINGLE_THREAD
|
|
set_error_code(Z3_EXCEPTION, "Can't use concurrent features with a single-thread build");
|
|
#else
|
|
m_concurrent_dec_ref = true;
|
|
#endif
|
|
}
|
|
unsigned add_object(api::object* o);
|
|
void del_object(api::object* o);
|
|
void dec_ref(ast* a);
|
|
void flush_objects();
|
|
|
|
Z3_ast_print_mode get_print_mode() const { return m_print_mode; }
|
|
void set_print_mode(Z3_ast_print_mode m) { m_print_mode = m; }
|
|
|
|
// Store a copy of str in m_string_buffer, and return a reference to it.
|
|
// This method is used to communicate local/internal strings with the "external world"
|
|
const char * mk_external_string(std::string && str);
|
|
sbuffer<char> m_char_buffer;
|
|
|
|
|
|
// Create a numeral of the given sort
|
|
expr * mk_numeral_core(rational const & n, sort * s);
|
|
|
|
// Return a conjunction that will be exposed to the "external" world.
|
|
expr * mk_and(unsigned num_exprs, expr * const * exprs);
|
|
|
|
// Hack for preventing an AST for being GC when ref-count is not used
|
|
// void persist_ast(ast * n, unsigned num_scopes);
|
|
|
|
// "Save" an AST that will exposed to the "external" world.
|
|
void save_ast_trail(ast * n);
|
|
|
|
// Similar to previous method, but it "adds" n to the result.
|
|
void save_multiple_ast_trail(ast * n);
|
|
|
|
// Reset the cache that stores the ASTs exposed in the previous call.
|
|
// This is a NOOP if ref-count is disabled.
|
|
void reset_last_result();
|
|
|
|
// "Save" a reference to an object that is exposed by the API
|
|
void save_object(object * r);
|
|
|
|
// Process exception: save message and set error code.
|
|
void handle_exception(z3_exception & ex);
|
|
char const * get_exception_msg() const { return m_exception_msg.c_str(); }
|
|
|
|
// Interrupt the current interruptible object
|
|
void interrupt();
|
|
|
|
void invoke_error_handler(Z3_error_code c);
|
|
|
|
void check_sorts(ast * n);
|
|
|
|
|
|
// ------------------------------------------------
|
|
//
|
|
// State reused by calls to Z3_eval_smtlib2_string
|
|
//
|
|
// ------------------------------------------------
|
|
//
|
|
// The m_parser field is reused by all calls of Z3_eval_smtlib2_string using this context.
|
|
// It is an optimization to save the cost of recreating these objects on each invocation.
|
|
//
|
|
// See https://github.com/Z3Prover/z3/pull/6422 for the motivation
|
|
smt2::parser* m_parser = nullptr;
|
|
|
|
// ------------------------
|
|
//
|
|
// Polynomial manager & caches
|
|
//
|
|
// -----------------------
|
|
private:
|
|
reslimit m_limit;
|
|
pmanager m_pmanager;
|
|
public:
|
|
polynomial::manager & pm() { return m_pmanager.pm(); }
|
|
reslimit & poly_limit() { return m_limit; }
|
|
|
|
// ------------------------
|
|
//
|
|
// RCF manager
|
|
//
|
|
// -----------------------
|
|
private:
|
|
unsynch_mpq_manager m_rcf_qm;
|
|
scoped_ptr<realclosure::manager> m_rcf_manager;
|
|
public:
|
|
realclosure::manager & rcfm();
|
|
|
|
// ------------------------
|
|
//
|
|
// Solver interface for backward compatibility
|
|
//
|
|
// ------------------------
|
|
smt_params & fparams() { return m_fparams; }
|
|
|
|
};
|
|
|
|
};
|
|
|
|
inline api::context * mk_c(Z3_context c) { return reinterpret_cast<api::context*>(c); }
|
|
#define RESET_ERROR_CODE() { mk_c(c)->reset_error_code(); }
|
|
#define SET_ERROR_CODE(ERR, MSG) { mk_c(c)->set_error_code(ERR, MSG); }
|
|
#define CHECK_NON_NULL(_p_,_ret_) { if (_p_ == nullptr) { SET_ERROR_CODE(Z3_INVALID_ARG, "ast is null"); return _ret_; } }
|
|
#define CHECK_VALID_AST(_a_, _ret_) { if (_a_ == nullptr || !CHECK_REF_COUNT(_a_)) { SET_ERROR_CODE(Z3_INVALID_ARG, "not a valid ast"); return _ret_; } }
|
|
inline bool is_expr(Z3_ast a) { return is_expr(to_ast(a)); }
|
|
#define CHECK_IS_EXPR(_p_, _ret_) { if (_p_ == nullptr || !is_expr(_p_)) { SET_ERROR_CODE(Z3_INVALID_ARG, "ast is not an expression"); return _ret_; } }
|
|
#define CHECK_IS_SORT(_p_, _ret_) { if (_p_ == nullptr || !is_sort(_p_)) { SET_ERROR_CODE(Z3_INVALID_ARG, "ast is not a sort"); return _ret_; } }
|
|
#define CHECK_SORTS(_n_, _ps_, _ret_) { for (unsigned i = 0; i < _n_; ++i) if (!is_sort(_ps_[i])) { SET_ERROR_CODE(Z3_INVALID_ARG, "ast is not a sort"); return _ret_; } }
|
|
|
|
inline bool is_bool_expr(Z3_context c, Z3_ast a) { return is_expr(a) && mk_c(c)->m().is_bool(to_expr(a)); }
|
|
#define CHECK_FORMULA(_a_, _ret_) { if (_a_ == nullptr || !CHECK_REF_COUNT(_a_) || !is_bool_expr(c, _a_)) { SET_ERROR_CODE(Z3_INVALID_ARG, nullptr); return _ret_; } }
|
|
inline void check_sorts(Z3_context c, ast * n) { mk_c(c)->check_sorts(n); }
|