3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-28 03:15:50 +00:00

merge with unstable

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2014-03-20 14:09:18 -07:00
commit 88df909a6c
32 changed files with 578 additions and 1947 deletions

28
src/duality/duality.h Normal file → Executable file
View file

@ -25,7 +25,7 @@ Revision History:
#include <map>
// make hash_map and hash_set available
#ifndef WIN32
#ifndef _WINDOWS
using namespace stl_ext;
#endif
@ -782,7 +782,7 @@ protected:
};
#ifdef WIN32
#ifdef _WINDOWS
__declspec(dllexport)
#endif
void FromClauses(const std::vector<Term> &clauses);
@ -1184,7 +1184,13 @@ namespace Duality {
hash_map<Edge *, Edge *> EdgeCloneMap;
std::vector<expr> alit_stack;
std::vector<unsigned> alit_stack_sizes;
hash_map<Edge *, uptr<LogicSolver> > edge_solvers;
// to let us use one solver per edge
struct edge_solver {
hash_map<ast,expr> AssumptionLits;
uptr<solver> slvr;
};
hash_map<Edge *, edge_solver > edge_solvers;
#ifdef LIMIT_STACK_WEIGHT
struct weight_counter {
@ -1236,19 +1242,23 @@ namespace Duality {
void GetTermTreeAssertionLiteralsRec(TermTree *assumptions);
LogicSolver *SolverForEdge(Edge *edge, bool models);
edge_solver &SolverForEdge(Edge *edge, bool models, bool axioms);
public:
struct scoped_solver_for_edge {
LogicSolver *orig_ls;
solver *orig_slvr;
RPFP_caching *rpfp;
scoped_solver_for_edge(RPFP_caching *_rpfp, Edge *edge, bool models = false){
edge_solver *es;
scoped_solver_for_edge(RPFP_caching *_rpfp, Edge *edge, bool models = false, bool axioms = false){
rpfp = _rpfp;
orig_ls = rpfp->ls;
rpfp->ls = rpfp->SolverForEdge(edge,models);
orig_slvr = rpfp->ls->slvr;
es = &(rpfp->SolverForEdge(edge,models,axioms));
rpfp->ls->slvr = es->slvr.get();
rpfp->AssumptionLits.swap(es->AssumptionLits);
}
~scoped_solver_for_edge(){
rpfp->ls = orig_ls;
rpfp->ls->slvr = orig_slvr;
rpfp->AssumptionLits.swap(es->AssumptionLits);
}
};

53
src/duality/duality_rpfp.cpp Normal file → Executable file
View file

@ -2711,10 +2711,12 @@ namespace Duality {
const std::vector<expr> &theory = ls->get_axioms();
for(unsigned i = 0; i < theory.size(); i++)
s.add(theory[i]);
if(s.check(lits.size(),&lits[0]) != unsat)
throw "should be unsat";
for(int k = 0; k < 100; k++) // keep trying, maybe MBQI will do something!
if(s.check(lits.size(),&lits[0]) == unsat)
goto is_unsat;
throw "should be unsat";
}
is_unsat:
for(unsigned i = 0; i < conjuncts.size(); ){
std::swap(conjuncts[i],conjuncts.back());
std::swap(lits[i],lits.back());
@ -2747,8 +2749,20 @@ namespace Duality {
// verify
check_result res = CheckCore(lits,full_core);
if(res != unsat)
if(res != unsat){
// add the axioms in the off chance they are useful
const std::vector<expr> &theory = ls->get_axioms();
for(unsigned i = 0; i < theory.size(); i++)
GetAssumptionLits(theory[i],assumps);
lits = assumps;
std::copy(core.begin(),core.end(),std::inserter(lits,lits.end()));
for(int k = 0; k < 100; k++) // keep trying, maybe MBQI will do something!
if((res = CheckCore(lits,full_core)) == unsat)
goto is_unsat;
throw "should be unsat";
}
is_unsat:
FilterCore(core,full_core);
std::vector<expr> dummy;
@ -2889,13 +2903,20 @@ namespace Duality {
timer_stop("Generalize");
}
RPFP::LogicSolver *RPFP_caching::SolverForEdge(Edge *edge, bool models){
uptr<LogicSolver> &p = edge_solvers[edge];
RPFP_caching::edge_solver &RPFP_caching::SolverForEdge(Edge *edge, bool models, bool axioms){
edge_solver &es = edge_solvers[edge];
uptr<solver> &p = es.slvr;
if(!p.get()){
scoped_no_proof no_proofs_please(ctx.m()); // no proofs
p.set(new iZ3LogicSolver(ctx,models)); // no models
p.set(new solver(ctx,true,models)); // no models
if(axioms){
RPFP::LogicSolver *ls = edge->owner->ls;
const std::vector<expr> &axs = ls->get_axioms();
for(unsigned i = 0; i < axs.size(); i++)
p.get()->add(axs[i]);
}
}
return p.get();
return es;
}
@ -3362,6 +3383,8 @@ namespace Duality {
}
}
bool some_labels = false;
// create the edges
for(unsigned i = 0; i < clauses.size(); i++){
@ -3397,17 +3420,23 @@ namespace Duality {
Term labeled = body;
std::vector<label_struct > lbls; // TODO: throw this away for now
body = RemoveLabels(body,lbls);
if(!eq(labeled,body))
some_labels = true; // remember if there are labels, as we then can't do qe_lite
// body = IneqToEq(body); // UFO converts x=y to (x<=y & x >= y). Undo this.
body = body.simplify();
#ifdef USE_QE_LITE
std::set<int> idxs;
for(unsigned j = 0; j < Indparams.size(); j++)
if(Indparams[j].is_var())
idxs.insert(Indparams[j].get_index_value());
body = body.qe_lite(idxs,false);
if(!some_labels){ // can't do qe_lite if we have to reconstruct labels
for(unsigned j = 0; j < Indparams.size(); j++)
if(Indparams[j].is_var())
idxs.insert(Indparams[j].get_index_value());
body = body.qe_lite(idxs,false);
}
hash_map<int,hash_map<ast,Term> > sb_memo;
body = SubstBoundRec(sb_memo,substs[i],0,body);
if(some_labels)
labeled = SubstBoundRec(sb_memo,substs[i],0,labeled);
for(unsigned j = 0; j < Indparams.size(); j++)
Indparams[j] = SubstBoundRec(sb_memo, substs[i], 0, Indparams[j]);
#endif

29
src/duality/duality_solver.cpp Normal file → Executable file
View file

@ -51,12 +51,17 @@ Revision History:
// #define TOP_DOWN
// #define EFFORT_BOUNDED_STRAT
#define SKIP_UNDERAPPROX_NODES
#define USE_RPFP_CLONE
// #define KEEP_EXPANSIONS
// #define USE_CACHING_RPFP
// #define PROPAGATE_BEFORE_CHECK
#define USE_RPFP_CLONE
#define USE_NEW_GEN_CANDS
//#define NO_PROPAGATE
//#define NO_GENERALIZE
//#define NO_DECISIONS
namespace Duality {
// TODO: must be a better place for this...
@ -129,13 +134,11 @@ namespace Duality {
{
scoped_no_proof no_proofs_please(ctx.m());
#ifdef USE_RPFP_CLONE
clone_ls = new RPFP::iZ3LogicSolver(ctx, false); // no models needed for this one
clone_rpfp = new RPFP_caching(clone_ls);
clone_rpfp = new RPFP_caching(rpfp->ls);
clone_rpfp->Clone(rpfp);
#endif
#ifdef USE_NEW_GEN_CANDS
gen_cands_ls = new RPFP::iZ3LogicSolver(ctx);
gen_cands_rpfp = new RPFP_caching(gen_cands_ls);
gen_cands_rpfp = new RPFP_caching(rpfp->ls);
gen_cands_rpfp->Clone(rpfp);
#endif
}
@ -144,20 +147,16 @@ namespace Duality {
~Duality(){
#ifdef USE_RPFP_CLONE
delete clone_rpfp;
delete clone_ls;
#endif
#ifdef USE_NEW_GEN_CANDS
delete gen_cands_rpfp;
delete gen_cands_ls;
#endif
}
#ifdef USE_RPFP_CLONE
RPFP::LogicSolver *clone_ls;
RPFP_caching *clone_rpfp;
#endif
#ifdef USE_NEW_GEN_CANDS
RPFP::LogicSolver *gen_cands_ls;
RPFP_caching *gen_cands_rpfp;
#endif
@ -1255,7 +1254,7 @@ namespace Duality {
slvr.pop(1);
delete checker;
#else
RPFP_caching::scoped_solver_for_edge(gen_cands_rpfp,edge,true /* models */);
RPFP_caching::scoped_solver_for_edge ssfe(gen_cands_rpfp,edge,true /* models */, true /*axioms*/);
gen_cands_rpfp->Push();
Node *root = CheckerForEdgeClone(edge,gen_cands_rpfp);
if(gen_cands_rpfp->Check(root) != unsat){
@ -1940,11 +1939,15 @@ namespace Duality {
for(unsigned i = 0; i < expansions.size(); i++){
Node *node = expansions[i];
tree->SolveSingleNode(top,node);
#ifdef NO_GENERALIZE
node->Annotation.Formula = tree->RemoveRedundancy(node->Annotation.Formula).simplify();
#else
if(expansions.size() == 1 && NodeTooComplicated(node))
SimplifyNode(node);
else
node->Annotation.Formula = tree->RemoveRedundancy(node->Annotation.Formula).simplify();
Generalize(node);
#endif
if(RecordUpdate(node))
update_count++;
else
@ -1984,7 +1987,9 @@ namespace Duality {
if(stack.size() == 1)break;
if(prev_level_used){
Node *node = stack.back().expansions[0];
#ifndef NO_PROPAGATE
if(!Propagate(node)) break;
#endif
if(!RecordUpdate(node)) break; // shouldn't happen!
RemoveUpdateNodesAtCurrentLevel(); // this level is about to be deleted -- remove its children from update list
propagated = true;
@ -2006,11 +2011,13 @@ namespace Duality {
}
else {
was_sat = true;
tree->Push();
tree->Push();
std::vector<Node *> &expansions = stack.back().expansions;
#ifndef NO_DECISIONS
for(unsigned i = 0; i < expansions.size(); i++){
tree->FixCurrentState(expansions[i]->Outgoing);
}
#endif
#if 0
if(tree->slvr().check() == unsat)
throw "help!";

0
src/duality/duality_wrapper.cpp Normal file → Executable file
View file

View file

@ -1402,7 +1402,7 @@ namespace hash_space {
}
// to make Duality::ast hashable in windows
#ifdef WIN32
#ifdef _WINDOWS
template <> inline
size_t stdext::hash_value<Duality::ast >(const Duality::ast& s)
{
@ -1446,7 +1446,7 @@ namespace hash_space {
}
// to make Duality::func_decl hashable in windows
#ifdef WIN32
#ifdef _WINDOWS
template <> inline
size_t stdext::hash_value<Duality::func_decl >(const Duality::func_decl& s)
{