3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-02-25 17:51:20 +00:00
z3/src/smt/qi_queue.h
Nikolaj Bjorner 87f7a20e14 Add (updated and general) solve_for functionality for arithmetic, add congruence_explain to API to retrieve explanation for why two terms are congruent Tweak handling of smt.qi.max_instantations
Add API solve_for(vars).
It takes a list of variables and returns a triangular solved form for the variables.
Currently for arithmetic. The solved form is a list with elements of the form (var, term, guard).
Variables solved in the tail of the list do not occur before in the list.
For example it can return a solution [(x, z, True), (y, x + z, True)] because first x was solved to be z,
then y was solved to be x + z which is the same as 2z.

Add congruent_explain that retuns an explanation for congruent terms.
Terms congruent in the final state after calling SimpleSolver().check() can be queried for
an explanation, i.e., a list of literals that collectively entail the equality under congruence closure.
The literals are asserted in the final state of search.

Adjust smt_context cancellation for the smt.qi.max_instantiations parameter.
It gets checked when qi-queue elements are consumed.
Prior it was checked on insertion time, which didn't allow for processing as many
instantations as there were in the queue. Moreover, it would not cancel the solver.
So it would keep adding instantations to the queue when it was full / depleted the
configuration limit.
2024-12-19 23:27:57 +01:00

101 lines
3.5 KiB
C++

/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
qi_queue.h
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2008-06-15.
Revision History:
--*/
#pragma once
#include "ast/ast.h"
#include "ast/quantifier_stat.h"
#include "ast/rewriter/cached_var_subst.h"
#include "parsers/util/cost_parser.h"
#include "smt/smt_checker.h"
#include "smt/smt_quantifier.h"
#include "smt/fingerprints.h"
#include "smt/params/qi_params.h"
#include "ast/cost_evaluator.h"
#include "util/statistics.h"
namespace smt {
class context;
struct qi_queue_stats {
unsigned m_num_instances, m_num_lazy_instances;
void reset() { memset(this, 0, sizeof(qi_queue_stats)); }
qi_queue_stats() { reset(); }
};
class qi_queue {
quantifier_manager & m_qm;
context & m_context;
ast_manager & m;
qi_params & m_params;
qi_queue_stats m_stats;
checker m_checker;
expr_ref m_cost_function;
expr_ref m_new_gen_function;
cost_parser m_parser;
cost_evaluator m_evaluator;
cached_var_subst m_subst;
svector<float> m_vals;
double m_eager_cost_threshold = 0;
struct entry {
fingerprint * m_qb;
float m_cost;
unsigned m_generation:31;
unsigned m_instantiated:1;
entry(fingerprint * f, float c, unsigned g):m_qb(f), m_cost(c), m_generation(g), m_instantiated(false) {}
};
svector<entry> m_new_entries;
svector<entry> m_delayed_entries;
expr_ref_vector m_instances;
unsigned_vector m_instantiated_trail;
struct scope {
unsigned m_delayed_entries_lim;
unsigned m_instances_lim;
unsigned m_instantiated_trail_lim;
};
svector<scope> m_scopes;
void init_parser_vars();
q::quantifier_stat * set_values(quantifier * q, app * pat, unsigned generation, unsigned min_top_generation, unsigned max_top_generation, float cost);
float get_cost(quantifier * q, app * pat, unsigned generation, unsigned min_top_generation, unsigned max_top_generation);
unsigned get_new_gen(quantifier * q, unsigned generation, float cost);
void instantiate(entry & ent);
void get_min_max_costs(float & min, float & max) const;
void display_instance_profile(fingerprint * f, quantifier * q, unsigned num_bindings, enode * const * bindings, unsigned proof_id, unsigned generation);
public:
qi_queue(quantifier_manager & qm, context & ctx, qi_params & params);
void setup();
/**
\brief Insert a new quantifier in the queue, f contains the quantifier and bindings.
f->get_data() is the quantifier.
*/
void insert(fingerprint * f, app * pat, unsigned generation, unsigned min_top_generation, unsigned max_top_generation);
void instantiate();
bool has_work() const { return !m_new_entries.empty(); }
void init_search_eh();
bool final_check_eh();
void push_scope();
void pop_scope(unsigned num_scopes);
void reset();
void display_delayed_instances_stats(std::ostream & out) const;
void collect_statistics(::statistics & st) const;
};
};