mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 09:35:32 +00:00
working on hitting sets
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
commit
960e8ea1d5
38 changed files with 1130 additions and 203 deletions
|
@ -260,7 +260,7 @@ void iz3base::check_interp(const std::vector<ast> &itps, std::vector<ast> &theor
|
|||
#endif
|
||||
}
|
||||
|
||||
bool iz3base::is_sat(const std::vector<ast> &q, ast &_proof){
|
||||
bool iz3base::is_sat(const std::vector<ast> &q, ast &_proof, std::vector<ast> &vars){
|
||||
|
||||
params_ref p;
|
||||
p.set_bool("proof", true); // this is currently useless
|
||||
|
@ -277,6 +277,15 @@ bool iz3base::is_sat(const std::vector<ast> &q, ast &_proof){
|
|||
::ast *proof = s.get_proof();
|
||||
_proof = cook(proof);
|
||||
}
|
||||
else if(vars.size()) {
|
||||
model_ref(_m);
|
||||
s.get_model(_m);
|
||||
for(unsigned i = 0; i < vars.size(); i++){
|
||||
expr_ref r(m());
|
||||
_m.get()->eval(to_expr(vars[i].raw()),r,true);
|
||||
vars[i] = cook(r.get());
|
||||
}
|
||||
}
|
||||
dealloc(m_solver);
|
||||
return res != l_false;
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ class iz3base : public iz3mgr, public scopes {
|
|||
void check_interp(const std::vector<ast> &itps, std::vector<ast> &theory);
|
||||
|
||||
/** For convenience -- is this formula SAT? */
|
||||
bool is_sat(const std::vector<ast> &consts, ast &_proof);
|
||||
bool is_sat(const std::vector<ast> &consts, ast &_proof, std::vector<ast> &vars);
|
||||
|
||||
/** Interpolator for clauses, to be implemented */
|
||||
virtual void interpolate_clause(std::vector<ast> &lits, std::vector<ast> &itps){
|
||||
|
|
|
@ -29,6 +29,10 @@ Revision History:
|
|||
#ifndef IZ3_HASH_H
|
||||
#define IZ3_HASH_H
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#pragma warning(disable:4267)
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
|
|
|
@ -387,10 +387,13 @@ class iz3mgr {
|
|||
return UnknownTheory;
|
||||
}
|
||||
|
||||
enum lemma_kind {FarkasKind,Leq2EqKind,Eq2LeqKind,GCDTestKind,AssignBoundsKind,EqPropagateKind,UnknownKind};
|
||||
enum lemma_kind {FarkasKind,Leq2EqKind,Eq2LeqKind,GCDTestKind,AssignBoundsKind,EqPropagateKind,ArithMysteryKind,UnknownKind};
|
||||
|
||||
lemma_kind get_theory_lemma_kind(const ast &proof){
|
||||
symb s = sym(proof);
|
||||
if(s->get_num_parameters() < 2) {
|
||||
return ArithMysteryKind; // Bad -- Z3 hasn't told us
|
||||
}
|
||||
::symbol p0;
|
||||
bool ok = s->get_parameter(1).is_symbol(p0);
|
||||
if(!ok) return UnknownKind;
|
||||
|
|
|
@ -607,7 +607,29 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
return res;
|
||||
}
|
||||
|
||||
ast distribute_coeff(const ast &coeff, const ast &s){
|
||||
if(sym(s) == sum){
|
||||
if(sym(arg(s,2)) == sum)
|
||||
return make(sum,
|
||||
distribute_coeff(coeff,arg(s,0)),
|
||||
make_int(rational(1)),
|
||||
distribute_coeff(make(Times,coeff,arg(s,1)), arg(s,2)));
|
||||
else
|
||||
return make(sum,
|
||||
distribute_coeff(coeff,arg(s,0)),
|
||||
make(Times,coeff,arg(s,1)),
|
||||
arg(s,2));
|
||||
}
|
||||
if(op(s) == Leq && arg(s,1) == make_int(rational(0)) && arg(s,2) == make_int(rational(0)))
|
||||
return s;
|
||||
return make(sum,make(Leq,make_int(rational(0)),make_int(rational(0))),coeff,s);
|
||||
}
|
||||
|
||||
ast simplify_sum(std::vector<ast> &args){
|
||||
if(args[1] != make_int(rational(1))){
|
||||
if(sym(args[2]) == sum)
|
||||
return make(sum,args[0],make_int(rational(1)),distribute_coeff(args[1],args[2]));
|
||||
}
|
||||
ast Aproves = mk_true(), Bproves = mk_true();
|
||||
ast ineq = destruct_cond_ineq(args[0],Aproves,Bproves);
|
||||
if(!is_normal_ineq(ineq)) throw cannot_simplify();
|
||||
|
@ -757,6 +779,22 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
ast Bcond = my_implies(Bproves1,my_and(Aproves1,z3_simplify(ineq2)));
|
||||
// if(!is_true(Aproves1) || !is_true(Bproves1))
|
||||
// std::cout << "foo!\n";;
|
||||
if(y == make_int(rational(0)) && op(x) == Plus && num_args(x) == 2){
|
||||
if(get_term_type(arg(x,0)) == LitA){
|
||||
ast iter = z3_simplify(make(Plus,arg(x,0),get_ineq_rhs(xleqy)));
|
||||
ast rewrite1 = make_rewrite(LitA,pos_add(0,top_pos),Acond,make(Equal,arg(x,0),iter));
|
||||
iter = make(Plus,iter,arg(x,1));
|
||||
ast rewrite2 = make_rewrite(LitB,top_pos,Bcond,make(Equal,iter,y));
|
||||
return chain_cons(chain_cons(mk_true(),rewrite1),rewrite2);
|
||||
}
|
||||
if(get_term_type(arg(x,1)) == LitA){
|
||||
ast iter = z3_simplify(make(Plus,arg(x,1),get_ineq_rhs(xleqy)));
|
||||
ast rewrite1 = make_rewrite(LitA,pos_add(1,top_pos),Acond,make(Equal,arg(x,1),iter));
|
||||
iter = make(Plus,arg(x,0),iter);
|
||||
ast rewrite2 = make_rewrite(LitB,top_pos,Bcond,make(Equal,iter,y));
|
||||
return chain_cons(chain_cons(mk_true(),rewrite1),rewrite2);
|
||||
}
|
||||
}
|
||||
if(get_term_type(x) == LitA){
|
||||
ast iter = z3_simplify(make(Plus,x,get_ineq_rhs(xleqy)));
|
||||
ast rewrite1 = make_rewrite(LitA,top_pos,Acond,make(Equal,x,iter));
|
||||
|
@ -1014,6 +1052,7 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
coeff = argpos ? make_int(rational(-1)) : make_int(rational(1));
|
||||
break;
|
||||
case Not:
|
||||
coeff = make_int(rational(-1));
|
||||
case Plus:
|
||||
break;
|
||||
case Times:
|
||||
|
@ -2568,12 +2607,17 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
break;
|
||||
default: { // mixed equality
|
||||
if(get_term_type(x) == LitMixed || get_term_type(y) == LitMixed){
|
||||
// std::cerr << "WARNING: mixed term in leq2eq\n";
|
||||
std::vector<ast> lits;
|
||||
lits.push_back(con);
|
||||
lits.push_back(make(Not,xleqy));
|
||||
lits.push_back(make(Not,yleqx));
|
||||
return make_axiom(lits);
|
||||
if(y == make_int(rational(0)) && op(x) == Plus && num_args(x) == 2){
|
||||
// std::cerr << "WARNING: untested case in leq2eq\n";
|
||||
}
|
||||
else {
|
||||
// std::cerr << "WARNING: mixed term in leq2eq\n";
|
||||
std::vector<ast> lits;
|
||||
lits.push_back(con);
|
||||
lits.push_back(make(Not,xleqy));
|
||||
lits.push_back(make(Not,yleqx));
|
||||
return make_axiom(lits);
|
||||
}
|
||||
}
|
||||
std::vector<ast> conjs; conjs.resize(3);
|
||||
conjs[0] = mk_not(con);
|
||||
|
@ -2655,8 +2699,13 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
};
|
||||
|
||||
std::vector<LocVar> localization_vars; // localization vars in order of creation
|
||||
hash_map<ast,ast> localization_map; // maps terms to their localization vars
|
||||
hash_map<ast,ast> localization_pf_map; // maps terms to proofs of their localizations
|
||||
|
||||
struct locmaps {
|
||||
hash_map<ast,ast> localization_map; // maps terms to their localization vars
|
||||
hash_map<ast,ast> localization_pf_map; // maps terms to proofs of their localizations
|
||||
};
|
||||
|
||||
hash_map<prover::range,locmaps> localization_maps_per_range;
|
||||
|
||||
/* "localize" a term e to a given frame range, creating new symbols to
|
||||
represent non-local subterms. This returns the localized version e_l,
|
||||
|
@ -2677,7 +2726,24 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
return make(Equal,x,y);
|
||||
}
|
||||
|
||||
bool range_is_global(const prover::range &r){
|
||||
if(pv->range_contained(r,rng))
|
||||
return false;
|
||||
if(!pv->ranges_intersect(r,rng))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
ast localize_term(ast e, const prover::range &rng, ast &pf){
|
||||
|
||||
// we need to memoize this function separately for A, B and global
|
||||
prover::range map_range = rng;
|
||||
if(range_is_global(map_range))
|
||||
map_range = pv->range_full();
|
||||
locmaps &maps = localization_maps_per_range[map_range];
|
||||
hash_map<ast,ast> &localization_map = maps.localization_map;
|
||||
hash_map<ast,ast> &localization_pf_map = maps.localization_pf_map;
|
||||
|
||||
ast orig_e = e;
|
||||
pf = make_refl(e); // proof that e = e
|
||||
|
||||
|
@ -2764,6 +2830,21 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
ast bar = make_assumption(frame,foo);
|
||||
pf = make_transitivity(new_var,e,orig_e,bar,pf);
|
||||
localization_pf_map[orig_e] = pf;
|
||||
|
||||
// HACK: try to bias this term in the future
|
||||
if(!pv->range_is_full(rng)){
|
||||
prover::range rf = pv->range_full();
|
||||
locmaps &fmaps = localization_maps_per_range[rf];
|
||||
hash_map<ast,ast> &flocalization_map = fmaps.localization_map;
|
||||
hash_map<ast,ast> &flocalization_pf_map = fmaps.localization_pf_map;
|
||||
// if(flocalization_map.find(orig_e) == flocalization_map.end())
|
||||
{
|
||||
flocalization_map[orig_e] = new_var;
|
||||
flocalization_pf_map[orig_e] = pf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return new_var;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ Revision History:
|
|||
|
||||
#include <vector>
|
||||
#include <limits.h>
|
||||
#include "iz3hash.h"
|
||||
|
||||
class scopes {
|
||||
|
||||
|
@ -63,6 +64,11 @@ class scopes {
|
|||
return rng.hi < rng.lo;
|
||||
}
|
||||
|
||||
/** is this range full? */
|
||||
bool range_is_full(const range &rng){
|
||||
return rng.lo == SHRT_MIN && rng.hi == SHRT_MAX;
|
||||
}
|
||||
|
||||
/** return an empty range */
|
||||
range range_empty(){
|
||||
range res;
|
||||
|
@ -194,4 +200,23 @@ class scopes {
|
|||
|
||||
|
||||
};
|
||||
|
||||
// let us hash on ranges
|
||||
|
||||
#ifndef FULL_TREE
|
||||
namespace hash_space {
|
||||
template <>
|
||||
class hash<scopes::range> {
|
||||
public:
|
||||
size_t operator()(const scopes::range &p) const {
|
||||
return (size_t)p.lo + (size_t)p.hi;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
inline bool operator==(const scopes::range &x, const scopes::range &y){
|
||||
return x.lo == y.lo && x.hi == y.hi;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1058,36 +1058,66 @@ public:
|
|||
}
|
||||
|
||||
|
||||
rational get_first_coefficient(const ast &t, ast &v){
|
||||
if(op(t) == Plus){
|
||||
unsigned best_id = UINT_MAX;
|
||||
rational best_coeff(0);
|
||||
int nargs = num_args(t);
|
||||
for(int i = 0; i < nargs; i++)
|
||||
if(op(arg(t,i)) != Numeral){
|
||||
ast lv = get_linear_var(arg(t,i));
|
||||
unsigned id = ast_id(lv);
|
||||
if(id < best_id) {
|
||||
v = lv;
|
||||
best_id = id;
|
||||
best_coeff = get_coeff(arg(t,i));
|
||||
}
|
||||
}
|
||||
return best_coeff;
|
||||
}
|
||||
else
|
||||
if(op(t) != Numeral)
|
||||
return(get_coeff(t));
|
||||
return rational(0);
|
||||
}
|
||||
|
||||
ast divide_inequalities(const ast &x, const ast&y){
|
||||
std::vector<rational> xcoeffs,ycoeffs;
|
||||
get_linear_coefficients(arg(x,1),xcoeffs);
|
||||
get_linear_coefficients(arg(y,1),ycoeffs);
|
||||
if(xcoeffs.size() != ycoeffs.size() || xcoeffs.size() == 0)
|
||||
ast xvar, yvar;
|
||||
rational xcoeff = get_first_coefficient(arg(x,0),xvar);
|
||||
rational ycoeff = get_first_coefficient(arg(y,0),yvar);
|
||||
if(xcoeff == rational(0) || ycoeff == rational(0) || xvar != yvar)
|
||||
throw "bad assign-bounds lemma";
|
||||
rational ratio = xcoeff/ycoeff;
|
||||
if(denominator(ratio) != rational(1))
|
||||
throw "bad assign-bounds lemma";
|
||||
rational ratio = xcoeffs[0]/ycoeffs[0];
|
||||
return make_int(ratio); // better be integer!
|
||||
}
|
||||
|
||||
ast AssignBounds2Farkas(const ast &proof, const ast &con){
|
||||
std::vector<ast> farkas_coeffs;
|
||||
get_assign_bounds_coeffs(proof,farkas_coeffs);
|
||||
std::vector<ast> lits;
|
||||
int nargs = num_args(con);
|
||||
if(nargs != (int)(farkas_coeffs.size()))
|
||||
throw "bad assign-bounds theory lemma";
|
||||
#if 0
|
||||
for(int i = 1; i < nargs; i++)
|
||||
lits.push_back(mk_not(arg(con,i)));
|
||||
ast sum = sum_inequalities(farkas_coeffs,lits);
|
||||
ast conseq = rhs_normalize_inequality(arg(con,0));
|
||||
ast d = divide_inequalities(sum,conseq);
|
||||
std::vector<ast> my_coeffs;
|
||||
my_coeffs.push_back(d);
|
||||
for(unsigned i = 0; i < farkas_coeffs.size(); i++)
|
||||
my_coeffs.push_back(farkas_coeffs[i]);
|
||||
if(farkas_coeffs[0] != make_int(rational(1)))
|
||||
farkas_coeffs[0] = make_int(rational(1));
|
||||
#else
|
||||
std::vector<ast> my_coeffs;
|
||||
std::vector<ast> lits, lit_coeffs;
|
||||
for(int i = 1; i < nargs; i++){
|
||||
lits.push_back(mk_not(arg(con,i)));
|
||||
lit_coeffs.push_back(farkas_coeffs[i]);
|
||||
}
|
||||
ast sum = normalize_inequality(sum_inequalities(lit_coeffs,lits));
|
||||
ast conseq = normalize_inequality(arg(con,0));
|
||||
ast d = divide_inequalities(sum,conseq);
|
||||
#if 0
|
||||
if(d != farkas_coeffs[0])
|
||||
std::cout << "wow!\n";
|
||||
#endif
|
||||
farkas_coeffs[0] = d;
|
||||
#endif
|
||||
std::vector<ast> my_coeffs;
|
||||
std::vector<ast> my_cons;
|
||||
for(int i = 1; i < nargs; i++){
|
||||
my_cons.push_back(mk_not(arg(con,i)));
|
||||
|
@ -1107,10 +1137,27 @@ public:
|
|||
ast AssignBoundsRule2Farkas(const ast &proof, const ast &con, std::vector<Iproof::node> prems){
|
||||
std::vector<ast> farkas_coeffs;
|
||||
get_assign_bounds_rule_coeffs(proof,farkas_coeffs);
|
||||
std::vector<ast> lits;
|
||||
int nargs = num_prems(proof)+1;
|
||||
if(nargs != (int)(farkas_coeffs.size()))
|
||||
throw "bad assign-bounds theory lemma";
|
||||
#if 0
|
||||
if(farkas_coeffs[0] != make_int(rational(1)))
|
||||
farkas_coeffs[0] = make_int(rational(1));
|
||||
#else
|
||||
std::vector<ast> lits, lit_coeffs;
|
||||
for(int i = 1; i < nargs; i++){
|
||||
lits.push_back(conc(prem(proof,i-1)));
|
||||
lit_coeffs.push_back(farkas_coeffs[i]);
|
||||
}
|
||||
ast sum = normalize_inequality(sum_inequalities(lit_coeffs,lits));
|
||||
ast conseq = normalize_inequality(con);
|
||||
ast d = divide_inequalities(sum,conseq);
|
||||
#if 0
|
||||
if(d != farkas_coeffs[0])
|
||||
std::cout << "wow!\n";
|
||||
#endif
|
||||
farkas_coeffs[0] = d;
|
||||
#endif
|
||||
std::vector<ast> my_coeffs;
|
||||
std::vector<ast> my_cons;
|
||||
for(int i = 1; i < nargs; i++){
|
||||
|
@ -1278,6 +1325,17 @@ public:
|
|||
return make(Plus,args);
|
||||
}
|
||||
|
||||
void get_sum_as_vector(const ast &t, std::vector<rational> &coeffs, std::vector<ast> &vars){
|
||||
if(!(op(t) == Plus)){
|
||||
coeffs.push_back(get_coeff(t));
|
||||
vars.push_back(get_linear_var(t));
|
||||
}
|
||||
else {
|
||||
int nargs = num_args(t);
|
||||
for(int i = 0; i < nargs; i++)
|
||||
get_sum_as_vector(arg(t,i),coeffs,vars);
|
||||
}
|
||||
}
|
||||
|
||||
ast replace_summands_with_fresh_vars(const ast &t, hash_map<ast,ast> &map){
|
||||
if(op(t) == Plus){
|
||||
|
@ -1294,6 +1352,99 @@ public:
|
|||
return map[t];
|
||||
}
|
||||
|
||||
rational lcd(const std::vector<rational> &rats){
|
||||
rational res = rational(1);
|
||||
for(unsigned i = 0; i < rats.size(); i++){
|
||||
res = lcm(res,denominator(rats[i]));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
Iproof::node reconstruct_farkas_with_dual(const std::vector<ast> &prems, const std::vector<Iproof::node> &pfs, const ast &con){
|
||||
int nprems = prems.size();
|
||||
std::vector<ast> npcons(nprems);
|
||||
hash_map<ast,ast> pain_map; // not needed
|
||||
for(int i = 0; i < nprems; i++){
|
||||
npcons[i] = painfully_normalize_ineq(conc(prems[i]),pain_map);
|
||||
if(op(npcons[i]) == Lt){
|
||||
ast constval = z3_simplify(make(Sub,arg(npcons[i],1),make_int(rational(1))));
|
||||
npcons[i] = make(Leq,arg(npcons[i],0),constval);
|
||||
}
|
||||
}
|
||||
ast ncon = painfully_normalize_ineq(mk_not(con),pain_map);
|
||||
npcons.push_back(ncon);
|
||||
|
||||
hash_map<ast,ast> dual_map;
|
||||
std::vector<ast> cvec, vars_seen;
|
||||
ast rhs = make_real(rational(0));
|
||||
for(unsigned i = 0; i < npcons.size(); i++){
|
||||
ast c= mk_fresh_constant("@c",real_type());
|
||||
cvec.push_back(c);
|
||||
ast lhs = arg(npcons[i],0);
|
||||
std::vector<rational> coeffs;
|
||||
std::vector<ast> vars;
|
||||
get_sum_as_vector(lhs,coeffs,vars);
|
||||
for(unsigned j = 0; j < coeffs.size(); j++){
|
||||
rational coeff = coeffs[j];
|
||||
ast var = vars[j];
|
||||
if(dual_map.find(var) == dual_map.end()){
|
||||
dual_map[var] = make_real(rational(0));
|
||||
vars_seen.push_back(var);
|
||||
}
|
||||
ast foo = make(Plus,dual_map[var],make(Times,make_real(coeff),c));
|
||||
dual_map[var] = foo;
|
||||
}
|
||||
rhs = make(Plus,rhs,make(Times,c,arg(npcons[i],1)));
|
||||
}
|
||||
std::vector<ast> cnstrs;
|
||||
for(unsigned i = 0; i < vars_seen.size(); i++)
|
||||
cnstrs.push_back(make(Equal,dual_map[vars_seen[i]],make_real(rational(0))));
|
||||
cnstrs.push_back(make(Leq,rhs,make_real(rational(0))));
|
||||
for(unsigned i = 0; i < cvec.size() - 1; i++)
|
||||
cnstrs.push_back(make(Geq,cvec[i],make_real(rational(0))));
|
||||
cnstrs.push_back(make(Equal,cvec.back(),make_real(rational(1))));
|
||||
ast new_proof;
|
||||
|
||||
// greedily reduce the core
|
||||
for(unsigned i = 0; i < cvec.size() - 1; i++){
|
||||
std::vector<ast> dummy;
|
||||
cnstrs.push_back(make(Equal,cvec[i],make_real(rational(0))));
|
||||
if(!is_sat(cnstrs,new_proof,dummy))
|
||||
cnstrs.pop_back();
|
||||
}
|
||||
|
||||
std::vector<ast> vals = cvec;
|
||||
if(!is_sat(cnstrs,new_proof,vals))
|
||||
throw "Proof error!";
|
||||
std::vector<rational> rat_farkas_coeffs;
|
||||
for(unsigned i = 0; i < cvec.size(); i++){
|
||||
ast bar = vals[i];
|
||||
rational r;
|
||||
if(is_numeral(bar,r))
|
||||
rat_farkas_coeffs.push_back(r);
|
||||
else
|
||||
throw "Proof error!";
|
||||
}
|
||||
rational the_lcd = lcd(rat_farkas_coeffs);
|
||||
std::vector<ast> farkas_coeffs;
|
||||
std::vector<Iproof::node> my_prems;
|
||||
std::vector<ast> my_pcons;
|
||||
for(unsigned i = 0; i < prems.size(); i++){
|
||||
ast fc = make_int(rat_farkas_coeffs[i] * the_lcd);
|
||||
if(!(fc == make_int(rational(0)))){
|
||||
farkas_coeffs.push_back(fc);
|
||||
my_prems.push_back(pfs[i]);
|
||||
my_pcons.push_back(conc(prems[i]));
|
||||
}
|
||||
}
|
||||
farkas_coeffs.push_back(make_int(the_lcd));
|
||||
my_prems.push_back(iproof->make_hypothesis(mk_not(con)));
|
||||
my_pcons.push_back(mk_not(con));
|
||||
|
||||
Iproof::node res = iproof->make_farkas(mk_false(),my_prems,my_pcons,farkas_coeffs);
|
||||
return res;
|
||||
}
|
||||
|
||||
ast painfully_normalize_ineq(const ast &ineq, hash_map<ast,ast> &map){
|
||||
ast res = normalize_inequality(ineq);
|
||||
ast lhs = arg(res,0);
|
||||
|
@ -1318,7 +1469,8 @@ public:
|
|||
npcons.push_back(ncon);
|
||||
// ast assumps = make(And,pcons);
|
||||
ast new_proof;
|
||||
if(is_sat(npcons,new_proof))
|
||||
std::vector<ast> dummy;
|
||||
if(is_sat(npcons,new_proof,dummy))
|
||||
throw "Proof error!";
|
||||
pfrule dk = pr(new_proof);
|
||||
int nnp = num_prems(new_proof);
|
||||
|
@ -1334,7 +1486,7 @@ public:
|
|||
farkas_coeffs.push_back(make_int(rational(1)));
|
||||
}
|
||||
else
|
||||
throw "cannot reconstruct farkas proof";
|
||||
return reconstruct_farkas_with_dual(prems,pfs,con);
|
||||
|
||||
for(int i = 0; i < nnp; i++){
|
||||
ast p = conc(prem(new_proof,i));
|
||||
|
@ -1348,7 +1500,7 @@ public:
|
|||
my_pcons.push_back(mk_not(con));
|
||||
}
|
||||
else
|
||||
throw "cannot reconstruct farkas proof";
|
||||
return reconstruct_farkas_with_dual(prems,pfs,con);
|
||||
}
|
||||
Iproof::node res = iproof->make_farkas(mk_false(),my_prems,my_pcons,farkas_coeffs);
|
||||
return res;
|
||||
|
@ -1378,7 +1530,8 @@ public:
|
|||
npcons.push_back(ncon);
|
||||
// ast assumps = make(And,pcons);
|
||||
ast new_proof;
|
||||
if(is_sat(npcons,new_proof))
|
||||
std::vector<ast> dummy;
|
||||
if(is_sat(npcons,new_proof,dummy))
|
||||
throw "Proof error!";
|
||||
pfrule dk = pr(new_proof);
|
||||
int nnp = num_prems(new_proof);
|
||||
|
@ -1408,7 +1561,7 @@ public:
|
|||
my_pcons.push_back(mk_not(con));
|
||||
}
|
||||
else
|
||||
throw "cannot reconstruct farkas proof";
|
||||
return painfully_reconstruct_farkas(prems,pfs,con);
|
||||
}
|
||||
Iproof::node res = iproof->make_farkas(mk_false(),my_prems,my_pcons,farkas_coeffs);
|
||||
return res;
|
||||
|
@ -1433,6 +1586,12 @@ public:
|
|||
return res;
|
||||
}
|
||||
|
||||
ast ArithMysteryRule(const ast &con, const std::vector<ast> &prems, const std::vector<Iproof::node> &args){
|
||||
// Hope for the best!
|
||||
Iproof::node guess = reconstruct_farkas(prems,args,con);
|
||||
return guess;
|
||||
}
|
||||
|
||||
struct CannotCombineEqPropagate {};
|
||||
|
||||
void CombineEqPropagateRec(const ast &proof, std::vector<ast> &prems, std::vector<Iproof::node> &args, ast &eqprem){
|
||||
|
@ -1552,6 +1711,13 @@ public:
|
|||
if(dk == PR_MODUS_PONENS && expect_clause && op(con) == Or)
|
||||
std::cout << "foo!\n";
|
||||
|
||||
// no idea why this shows up
|
||||
if(dk == PR_MODUS_PONENS_OEQ)
|
||||
if(conc(prem(proof,0)) == con){
|
||||
res = translate_main(prem(proof,0),expect_clause);
|
||||
return res;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if(1 && dk == PR_TRANSITIVITY && pr(prem(proof,1)) == PR_COMMUTATIVITY){
|
||||
Iproof::node clause = translate_main(prem(proof,0),true);
|
||||
|
@ -1737,6 +1903,14 @@ public:
|
|||
res = EqPropagate(con,prems,args);
|
||||
break;
|
||||
}
|
||||
case ArithMysteryKind: {
|
||||
// Z3 hasn't told us what kind of lemma this is -- maybe we can guess
|
||||
std::vector<ast> prems(nprems);
|
||||
for(unsigned i = 0; i < nprems; i++)
|
||||
prems[i] = prem(proof,i);
|
||||
res = ArithMysteryRule(con,prems,args);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw unsupported();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue