3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-15 15:25:26 +00:00
This commit is contained in:
Nikolaj Bjorner 2020-05-21 21:03:38 -07:00
parent 5307797c32
commit 698d300511
2 changed files with 230 additions and 8 deletions

View file

@ -17,6 +17,8 @@
#pragma once
#include "util/hash.h"
#include "util/hashtable.h"
#include "smt/smt_types.h"
#include "ast/rewriter/value_sweep.h"
#include "ast/datatype_decl_plugin.h"
@ -49,6 +51,44 @@ namespace smt {
* Synthesize induction lemmas from induction candidates
*/
class induction_lemmas {
typedef svector<std::pair<expr*,expr*>> expr_pair_vector;
typedef std::pair<expr_ref_vector, expr_ref> cond_subst_t;
typedef vector<cond_subst_t> cond_substs_t;
typedef std::pair<enode*, unsigned> induction_position_t;
typedef svector<induction_position_t> induction_positions_t;
typedef vector<induction_positions_t> induction_combinations_t;
struct induction_term_and_position_t {
expr* m_term;
induction_positions_t m_positions;
ptr_vector<expr> m_skolems;
induction_term_and_position_t(): m_term(nullptr) {}
induction_term_and_position_t(expr* t, induction_positions_t const& p):
m_term(t), m_positions(p) {}
};
struct it_hash {
unsigned operator()(induction_term_and_position_t const& t) const {
unsigned a = get_node_hash(t.m_term);
for (auto const& p : t.m_positions) {
a = mk_mix(a, p.second, get_node_hash(p.first->get_owner()));
}
return a;
}
};
struct it_eq {
bool operator()(induction_term_and_position_t const& s, induction_term_and_position_t const& t) const {
if (s.m_term != t.m_term || s.m_positions.size() != t.m_positions.size())
return false;
for (unsigned i = s.m_positions.size(); i-- > 0; ) {
auto const& p1 = s.m_positions[i];
auto const& p2 = t.m_positions[i];
if (p1.first != p2.first || p1.second != p2.second)
return false;
}
return true;
}
};
context& ctx;
ast_manager& m;
value_sweep& vs;
@ -57,11 +97,13 @@ namespace smt {
recfun::util m_rec;
unsigned m_num_lemmas;
typedef svector<std::pair<expr*,expr*>> expr_pair_vector;
typedef std::pair<expr_ref_vector, expr_ref> cond_subst_t;
typedef vector<cond_subst_t> cond_substs_t;
typedef std::pair<enode*, unsigned> induction_position_t;
typedef svector<induction_position_t> induction_positions_t;
unsigned m_ts {0};
unsigned_vector m_marks;
vector<ptr_vector<app>> m_depth2terms;
expr_ref_vector m_trail;
hashtable<induction_term_and_position_t, it_hash, it_eq> m_skolems;
bool viable_induction_sort(sort* s);
bool viable_induction_parent(enode* p, enode* n);
@ -69,12 +111,16 @@ namespace smt {
bool viable_induction_term(enode* p , enode* n);
enode_vector induction_positions(enode* n);
induction_positions_t induction_positions2(enode* n);
void initialize_levels(enode* n);
induction_combinations_t induction_combinations(enode* n);
bool positions_dont_overlap(induction_positions_t const& p);
void mk_hypothesis_substs(unsigned depth, expr* x, cond_substs_t& subst);
void mk_hypothesis_substs_rec(unsigned depth, sort* s, expr* y, expr_ref_vector& conds, cond_substs_t& subst);
void mk_hypothesis_lemma(expr_ref_vector const& conds, expr_pair_vector const& subst, literal alpha);
void create_hypotheses(unsigned depth, expr_ref_vector const& sks, literal alpha);
literal mk_literal(expr* e);
void add_th_lemma(literal_vector const& lits);
void apply_induction(literal lit, induction_positions_t const & positions);
public:
induction_lemmas(context& ctx, ast_manager& m, value_sweep& vs);