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:
commit
88df909a6c
32 changed files with 578 additions and 1947 deletions
28
src/duality/duality.h
Normal file → Executable file
28
src/duality/duality.h
Normal file → Executable 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
53
src/duality/duality_rpfp.cpp
Normal file → Executable 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
29
src/duality/duality_solver.cpp
Normal file → Executable 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
0
src/duality/duality_wrapper.cpp
Normal file → Executable 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)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue