3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-06 06:03:23 +00:00

added restarts options to duality (plus some other disabled features)

This commit is contained in:
Ken McMillan 2014-09-30 12:42:30 -07:00
parent 4763532501
commit 301cb51bbb
5 changed files with 446 additions and 20 deletions

View file

@ -104,6 +104,8 @@ namespace Duality {
FuncDecl RenumberPred(const FuncDecl &f, int n); FuncDecl RenumberPred(const FuncDecl &f, int n);
FuncDecl NumberPred(const FuncDecl &f, int n);
Term ExtractStores(hash_map<ast, Term> &memo, const Term &t, std::vector<expr> &cnstrs, hash_map<ast,expr> &renaming); Term ExtractStores(hash_map<ast, Term> &memo, const Term &t, std::vector<expr> &cnstrs, hash_map<ast,expr> &renaming);
@ -903,6 +905,10 @@ protected:
int CumulativeDecisions(); int CumulativeDecisions();
void GreedyReduceNodes(std::vector<Node *> &nodes);
check_result CheckWithConstrainedNodes(std::vector<Node *> &posnodes,std::vector<Node *> &negnodes);
solver &slvr(){ solver &slvr(){
return *ls->slvr; return *ls->slvr;
} }

View file

@ -2816,6 +2816,62 @@ namespace Duality {
} }
} }
void foobar(){
}
void RPFP::GreedyReduceNodes(std::vector<Node *> &nodes){
std::vector<expr> lits;
for(unsigned i = 0; i < nodes.size(); i++){
Term b; std::vector<Term> v;
RedVars(nodes[i], b, v);
lits.push_back(!b);
expr bv = dualModel.eval(b);
if(eq(bv,ctx.bool_val(true))){
check_result res = slvr_check(lits.size(),&lits[0]);
if(res == unsat)
lits.pop_back();
else
foobar();
}
}
}
check_result RPFP::CheckWithConstrainedNodes(std::vector<Node *> &posnodes,std::vector<Node *> &negnodes){
timer_start("Check");
std::vector<expr> lits;
for(unsigned i = 0; i < posnodes.size(); i++){
Term b; std::vector<Term> v;
RedVars(posnodes[i], b, v);
lits.push_back(b);
}
for(unsigned i = 0; i < negnodes.size(); i++){
Term b; std::vector<Term> v;
RedVars(negnodes[i], b, v);
lits.push_back(!b);
}
check_result res = slvr_check(lits.size(),&lits[0]);
if(res == unsat && posnodes.size()){
lits.resize(posnodes.size());
res = slvr_check(lits.size(),&lits[0]);
}
dualModel = slvr().get_model();
#if 0
if(!dualModel.null()){
std::cout << "posnodes called:\n";
for(unsigned i = 0; i < posnodes.size(); i++)
if(!Empty(posnodes[i]))
std::cout << posnodes[i]->Name.name() << "\n";
std::cout << "negnodes called:\n";
for(unsigned i = 0; i < negnodes.size(); i++)
if(!Empty(negnodes[i]))
std::cout << negnodes[i]->Name.name() << "\n";
}
#endif
timer_stop("Check");
return res;
}
void RPFP_caching::FilterCore(std::vector<expr> &core, std::vector<expr> &full_core){ void RPFP_caching::FilterCore(std::vector<expr> &core, std::vector<expr> &full_core){
hash_set<ast> core_set; hash_set<ast> core_set;
std::copy(full_core.begin(),full_core.end(),std::inserter(core_set,core_set.begin())); std::copy(full_core.begin(),full_core.end(),std::inserter(core_set,core_set.begin()));
@ -3333,6 +3389,17 @@ namespace Duality {
return ctx.function(name.c_str(), arity, &domain[0], f.range()); return ctx.function(name.c_str(), arity, &domain[0], f.range());
} }
Z3User::FuncDecl Z3User::NumberPred(const FuncDecl &f, int n)
{
std::string name = f.name().str();
name = name + "_" + string_of_int(n);
int arity = f.arity();
std::vector<sort> domain;
for(int i = 0; i < arity; i++)
domain.push_back(f.domain(i));
return ctx.function(name.c_str(), arity, &domain[0], f.range());
}
// Scan the clause body for occurrences of the predicate unknowns // Scan the clause body for occurrences of the predicate unknowns
RPFP::Term RPFP::ScanBody(hash_map<ast,Term> &memo, RPFP::Term RPFP::ScanBody(hash_map<ast,Term> &memo,

View file

@ -255,6 +255,13 @@ namespace Duality {
/** Called when done expanding a tree */ /** Called when done expanding a tree */
virtual void Done() {} virtual void Done() {}
/** Ask whether a node should be used/unused in the tree. Returns,
1 if yes, -1 if no, and 0 if don't care. */
virtual int UseNode(Node *node){
return 0;
}
}; };
/** The Proposer class proposes conjectures eagerly. These can come /** The Proposer class proposes conjectures eagerly. These can come
@ -302,6 +309,7 @@ namespace Duality {
hash_set<Node *> overapproxes; hash_set<Node *> overapproxes;
std::vector<Proposer *> proposers; std::vector<Proposer *> proposers;
std::string ConjectureFile; std::string ConjectureFile;
bool stratified_inlining_done;
#ifdef BOUNDED #ifdef BOUNDED
struct Counter { struct Counter {
@ -314,6 +322,13 @@ namespace Duality {
/** Solve the problem. */ /** Solve the problem. */
virtual bool Solve(){ virtual bool Solve(){
PreSolve();
bool res = SolveMain(); // does the actual work
PostSolve();
return res;
}
void PreSolve(){
reporter = Report ? CreateStdoutReporter(rpfp) : new Reporter(rpfp); reporter = Report ? CreateStdoutReporter(rpfp) : new Reporter(rpfp);
conj_reporter = ConjectureFile.empty() ? 0 : CreateConjectureFileReporter(rpfp,ConjectureFile); conj_reporter = ConjectureFile.empty() ? 0 : CreateConjectureFileReporter(rpfp,ConjectureFile);
#ifndef LOCALIZE_CONJECTURES #ifndef LOCALIZE_CONJECTURES
@ -342,9 +357,10 @@ namespace Duality {
return false; return false;
#endif #endif
StratifiedLeafCount = -1; StratifiedLeafCount = -1;
timer_start("SolveMain"); stratified_inlining_done = false;
bool res = SolveMain(); // does the actual work }
timer_stop("SolveMain");
void PostSolve(){
// print_profile(std::cout); // print_profile(std::cout);
delete indset; delete indset;
delete heuristic; delete heuristic;
@ -354,7 +370,16 @@ namespace Duality {
delete conj_reporter; delete conj_reporter;
for(unsigned i = 0; i < proposers.size(); i++) for(unsigned i = 0; i < proposers.size(); i++)
delete proposers[i]; delete proposers[i];
return res; }
bool RecheckBounds(){
for(unsigned i = 0; i < unwinding->nodes.size(); i++){
Node *node = unwinding->nodes[i];
node->Bound = node->map->Bound;
if(!SatisfyUpperBound(node))
return false;
}
return true;
} }
void CreateInitialUnwinding(){ void CreateInitialUnwinding(){
@ -417,6 +442,7 @@ namespace Duality {
bool StratifiedInlining; // Do stratified inlining as preprocessing step bool StratifiedInlining; // Do stratified inlining as preprocessing step
int RecursionBound; // Recursion bound for bounded verification int RecursionBound; // Recursion bound for bounded verification
bool BatchExpand; bool BatchExpand;
bool EnableRestarts;
bool SetBoolOption(bool &opt, const std::string &value){ bool SetBoolOption(bool &opt, const std::string &value){
if(value == "0") { if(value == "0") {
@ -464,6 +490,9 @@ namespace Duality {
if(option == "conjecture_file"){ if(option == "conjecture_file"){
ConjectureFile = value; ConjectureFile = value;
} }
if(option == "enable_restarts"){
return SetBoolOption(EnableRestarts,value);
}
return false; return false;
} }
@ -901,6 +930,9 @@ namespace Duality {
*/ */
bool DoStratifiedInlining(){ bool DoStratifiedInlining(){
if(stratified_inlining_done)
return true;
stratified_inlining_done = true;
DoTopoSort(); DoTopoSort();
int depth = 1; // TODO: make this an option int depth = 1; // TODO: make this an option
std::vector<hash_map<Node *,Node *> > unfolding_levels(depth+1); std::vector<hash_map<Node *,Node *> > unfolding_levels(depth+1);
@ -1043,10 +1075,17 @@ namespace Duality {
h->SetOldNode(node); h->SetOldNode(node);
} }
bool SolveMain(){
timer_start("SolveMain");
bool res = SolveMainInt(); // does the actual work
timer_stop("SolveMain");
return res;
}
/** This does the actual solving work. We try to generate /** This does the actual solving work. We try to generate
candidates for extension. If we succed, we extend the candidates for extension. If we succed, we extend the
unwinding. If we fail, we have a solution. */ unwinding. If we fail, we have a solution. */
bool SolveMain(){ bool SolveMainInt(){
if(StratifiedInlining && !DoStratifiedInlining()) if(StratifiedInlining && !DoStratifiedInlining())
return false; return false;
#ifdef BOUNDED #ifdef BOUNDED
@ -1776,6 +1815,7 @@ namespace Duality {
} }
timer_stop("Propagate"); timer_stop("Propagate");
} }
/** This class represents a derivation tree. */ /** This class represents a derivation tree. */
class DerivationTree { class DerivationTree {
@ -2127,6 +2167,8 @@ namespace Duality {
hash_map<Node *, expr> updates; hash_map<Node *, expr> updates;
int restart_interval;
DerivationTreeSlow(Duality *_duality, RPFP *rpfp, Reporter *_reporter, Heuristic *_heuristic, bool _full_expand) DerivationTreeSlow(Duality *_duality, RPFP *rpfp, Reporter *_reporter, Heuristic *_heuristic, bool _full_expand)
: DerivationTree(_duality, rpfp, _reporter, _heuristic, _full_expand) { : DerivationTree(_duality, rpfp, _reporter, _heuristic, _full_expand) {
stack.push_back(stack_entry()); stack.push_back(stack_entry());
@ -2135,6 +2177,7 @@ namespace Duality {
struct DoRestart {}; struct DoRestart {};
virtual bool Build(){ virtual bool Build(){
restart_interval = 3;
while (true) { while (true) {
try { try {
return BuildMain(); return BuildMain();
@ -2145,15 +2188,47 @@ namespace Duality {
while(stack.size() > 1) while(stack.size() > 1)
PopLevel(); PopLevel();
reporter->Message("restarted"); reporter->Message("restarted");
restart_interval += 1;
} }
} }
} }
// When we check, try to use the same children that were used in the
// previous counterexample.
check_result Check(){
#if 0
std::vector<Node *> posnodes, negnodes;
std::vector<Node *> &expansions = stack.back().expansions;
for(unsigned i = 0; i < expansions.size(); i++){
Node *node = expansions[i];
std::vector<Node*> &chs = node->Outgoing->Children;
for(unsigned j = 0; j < chs.size(); j++){
Node *ch = chs[j];
int use = heuristic->UseNode(ch);
if(use == 1)
posnodes.push_back(ch);
else if (use == -1)
negnodes.push_back(ch);
}
}
if(!(posnodes.empty() && negnodes.empty())){
check_result res = tree->CheckWithConstrainedNodes(posnodes,negnodes);
if(res != unsat){
reporter->Message("matched previous counterexample");
return res;
}
}
#endif
return tree->Check(top);
}
bool BuildMain(){ bool BuildMain(){
stack.back().level = tree->slvr().get_scope_level(); stack.back().level = tree->slvr().get_scope_level();
bool was_sat = true; bool was_sat = true;
int update_failures = 0; int update_failures = 0;
int total_updates = 0;
while (true) while (true)
{ {
@ -2165,7 +2240,7 @@ namespace Duality {
reporter->Depth(stack.size()); reporter->Depth(stack.size());
// res = tree->Solve(top, 1); // incremental solve, keep interpolants for one pop // res = tree->Solve(top, 1); // incremental solve, keep interpolants for one pop
check_result foo = tree->Check(top); check_result foo = Check();
res = foo == unsat ? l_false : l_true; res = foo == unsat ? l_false : l_true;
if (res == l_false) { if (res == l_false) {
@ -2193,11 +2268,18 @@ namespace Duality {
throw DoRestart(); throw DoRestart();
} }
#endif #endif
if(RecordUpdate(node)) if(RecordUpdate(node)){
update_count++; update_count++;
total_updates++;
}
else else
heuristic->Update(node->map); // make it less likely to expand this node in future heuristic->Update(node->map); // make it less likely to expand this node in future
} }
#if 1
if(duality->EnableRestarts)
if(total_updates >= restart_interval)
throw DoRestart();
#endif
if(update_count == 0){ if(update_count == 0){
if(was_sat){ if(was_sat){
update_failures++; update_failures++;
@ -2243,6 +2325,10 @@ namespace Duality {
tree->Push(); tree->Push();
std::vector<Node *> &expansions = stack.back().expansions; std::vector<Node *> &expansions = stack.back().expansions;
#ifndef NO_DECISIONS #ifndef NO_DECISIONS
#if 0
if(expansions.size() > 0)
tree->GreedyReduceNodes(expansions[0]->Outgoing->Children); // try to reduce number of children
#endif
for(unsigned i = 0; i < expansions.size(); i++){ for(unsigned i = 0; i < expansions.size(); i++){
tree->FixCurrentState(expansions[i]->Outgoing); tree->FixCurrentState(expansions[i]->Outgoing);
} }
@ -2262,15 +2348,42 @@ namespace Duality {
if(ExpandSomeNodes(false,expand_max)) if(ExpandSomeNodes(false,expand_max))
continue; continue;
tree->Pop(1); tree->Pop(1);
node_order.clear();
while(stack.size() > 1){ while(stack.size() > 1){
tree->Pop(1); tree->Pop(1);
std::vector<Node *> &expansions = stack.back().expansions;
for(unsigned i = 0; i < expansions.size(); i++)
node_order.push_back(expansions[i]);
stack.pop_back(); stack.pop_back();
} }
#if 0
Reduce();
#endif
return true; return true;
} }
} }
} }
std::vector<Node *> node_order;
void Reduce(){
tree->Push();
// tree->AssertNode(top); // assert the negation of the top-level spec
for(int i = node_order.size()-1; i >= 0; --i){
Edge *edge = node_order[i]->Outgoing;
if(edge){
for(unsigned j = 0; j < edge->Children.size(); j++){
Node *ch = edge->Children[j];
if(!ch->Outgoing)
ch->Annotation.SetEmpty();
}
tree->AssertEdge(edge,0,true);
}
}
tree->GreedyReduceNodes(node_order); // try to reduce the counterexample size
tree->Pop(1);
}
void PopLevel(){ void PopLevel(){
std::vector<Node *> &expansions = stack.back().expansions; std::vector<Node *> &expansions = stack.back().expansions;
tree->Pop(1); tree->Pop(1);
@ -2869,17 +2982,7 @@ namespace Duality {
return name; return name;
} }
virtual void ChooseExpand(const std::set<RPFP::Node *> &choices, std::set<RPFP::Node *> &best, bool high_priority, bool best_only){ Node *MatchNode(Node *node){
if(!high_priority || !old_cex.get_tree()){
Heuristic::ChooseExpand(choices,best,false);
return;
}
// first, try to match the derivatino tree nodes to the old cex
std::set<Node *> matched, unmatched;
for(std::set<Node *>::iterator it = choices.begin(), en = choices.end(); it != en; ++it){
Node *node = (*it);
if(cex_map.empty())
cex_map[node] = old_cex.get_root(); // match the root nodes
if(cex_map.find(node) == cex_map.end()){ // try to match an unmatched node if(cex_map.find(node) == cex_map.end()){ // try to match an unmatched node
Node *parent = node->Incoming[0]->Parent; // assumes we are a tree! Node *parent = node->Incoming[0]->Parent; // assumes we are a tree!
if(cex_map.find(parent) == cex_map.end()) if(cex_map.find(parent) == cex_map.end())
@ -2902,7 +3005,30 @@ namespace Duality {
cex_map[chs[i]] = 0; cex_map[chs[i]] = 0;
} }
matching_done: matching_done:
Node *old_node = cex_map[node]; return cex_map[node];
}
int UseNode(Node *node){
if (!old_cex.get_tree())
return 0;
Node *old_node = MatchNode(node);
if(!old_node)
return 0;
return old_cex.get_tree()->Empty(old_node) ? -1 : 1;
}
virtual void ChooseExpand(const std::set<RPFP::Node *> &choices, std::set<RPFP::Node *> &best, bool high_priority, bool best_only){
if(cex_map.empty())
cex_map[*(choices.begin())] = old_cex.get_root(); // match the root nodes
if(!high_priority || !old_cex.get_tree()){
Heuristic::ChooseExpand(choices,best,false);
return;
}
// first, try to match the derivatino tree nodes to the old cex
std::set<Node *> matched, unmatched;
for(std::set<Node *>::iterator it = choices.begin(), en = choices.end(); it != en; ++it){
Node *node = (*it);
Node *old_node = MatchNode(node);
if(!old_node) if(!old_node)
unmatched.insert(node); unmatched.insert(node);
else if(old_cex.get_tree()->Empty(old_node)) else if(old_cex.get_tree()->Empty(old_node))
@ -3177,8 +3303,233 @@ namespace Duality {
}; };
class DualityDepthBounded : public Solver {
Duality *duality;
context &ctx; // Z3 context
solver &slvr; // Z3 solver
public:
DualityDepthBounded(RPFP *_rpfp) :
ctx(_rpfp->ctx),
slvr(_rpfp->slvr()){
rpfp = _rpfp;
DepthBoundRPFP();
duality = alloc(Duality,drpfp);
}
~DualityDepthBounded(){
dealloc(duality);
delete drpfp;
}
bool Solve(){
int depth_bound = 10;
bool res;
SetMaxDepthRPFP(depth_bound);
duality->PreSolve();
while(true){
res = duality->SolveMain();
if(!res || GetSolution())
break;
depth_bound++;
SetMaxDepthRPFP(depth_bound);
res = duality->RecheckBounds();
if(!res)
break;
}
duality->PostSolve();
if(!res)
ConvertCex();
return res;
}
Counterexample &GetCounterexample(){
return cex;
}
bool SetOption(const std::string &option, const std::string &value){
return duality->SetOption(option,value);
}
virtual void LearnFrom(Solver *old_solver){
DualityDepthBounded *old = dynamic_cast<DualityDepthBounded *>(old_solver);
if(old){
duality->LearnFrom(old->duality);
}
}
bool IsResultRecursionBounded(){
return duality->IsResultRecursionBounded();
}
void Cancel(){
duality->Cancel();
}
typedef RPFP::Node Node;
typedef RPFP::Edge Edge;
RPFP *rpfp, *drpfp;
hash_map<Node *, Node *> db_map, db_rev_map;
hash_map<Edge *, Edge *> db_edge_rev_map;
std::vector<expr> db_saved_bounds;
Counterexample cex;
expr AddParamToRels(hash_map<ast,expr> &memo, hash_map<func_decl,func_decl> &rmap, const expr &p, const expr &t) {
std::pair<ast,expr> foo(t,expr(ctx));
std::pair<hash_map<ast,expr>::iterator, bool> bar = memo.insert(foo);
expr &res = bar.first->second;
if(!bar.second) return res;
if (t.is_app())
{
func_decl f = t.decl();
std::vector<expr> args;
int nargs = t.num_args();
for(int i = 0; i < nargs; i++)
args.push_back(AddParamToRels(memo, rmap, p, t.arg(i)));
hash_map<func_decl,func_decl>::iterator rit = rmap.find(f);
if(rit != rmap.end()){
args.push_back(p);
res = (rit->second)(args);
res = ctx.make(And,res,ctx.make(Geq,p,ctx.int_val(0)));
}
else
res = f(args);
}
else if (t.is_quantifier())
{
expr body = AddParamToRels(memo, rmap, p, t.body());
res = clone_quantifier(t, body);
}
else res = t;
return res;
}
void DepthBoundRPFP(){
drpfp = new RPFP(rpfp->ls);
expr dvar = ctx.int_const("@depth");
expr dmax = ctx.int_const("@depth_max");
for(unsigned i = 0; i < rpfp->nodes.size(); i++){
Node *node = rpfp->nodes[i];
std::vector<sort> arg_sorts;
const std::vector<expr> &params = node->Annotation.IndParams;
for(unsigned j = 0; j < params.size(); j++)
arg_sorts.push_back(params[j].get_sort());
arg_sorts.push_back(ctx.int_sort());
std::string new_name = std::string("@db@") + node->Name.name().str();
func_decl f = ctx.function(new_name.c_str(),arg_sorts.size(), &arg_sorts[0],ctx.bool_sort());
std::vector<expr> args = params;
args.push_back(dvar);
expr pat = f(args);
Node *dnode = drpfp->CreateNode(pat);
db_map[node] = dnode;
db_rev_map[dnode] = node;
expr bound_fmla = node->Bound.Formula;
if(!eq(bound_fmla,ctx.bool_val(true))){
bound_fmla = implies(dvar == dmax,bound_fmla);
dnode->Bound.Formula = bound_fmla;
}
db_saved_bounds.push_back(bound_fmla);
// dnode->Annotation.Formula = ctx.make(And,node->Annotation.Formula,ctx.make(Geq,dvar,ctx.int_val(0)));
}
for(unsigned i = 0; i < rpfp->edges.size(); i++){
Edge *edge = rpfp->edges[i];
std::vector<Node *> new_children;
std::vector<func_decl> new_relparams;
hash_map<func_decl,func_decl> rmap;
for(unsigned j = 0; j < edge->Children.size(); j++){
Node *ch = edge->Children[j];
Node *nch = db_map[ch];
func_decl f = nch->Name;
func_decl sf = drpfp->NumberPred(f,j);
new_children.push_back(nch);
new_relparams.push_back(sf);
rmap[edge->F.RelParams[j]] = sf;
}
std::vector<expr> new_indparams = edge->F.IndParams;
new_indparams.push_back(dvar);
hash_map<ast,expr> memo;
expr new_fmla = AddParamToRels(memo,rmap,ctx.make(Sub,dvar,ctx.int_val(1)),edge->F.Formula);
RPFP::Transformer new_t = drpfp->CreateTransformer(new_relparams,new_indparams,new_fmla);
Node *new_parent = db_map[edge->Parent];
db_edge_rev_map[drpfp->CreateEdge(new_parent,new_t,new_children)] = edge;
}
}
void SetMaxDepthRPFP(int depth){
hash_map<ast,expr> subst;
expr dmax = ctx.int_const("@depth_max");
subst[dmax] = ctx.int_val(depth);
for(unsigned i = 0; i < drpfp->nodes.size(); i++){
Node *node = drpfp->nodes[i];
expr fmla = db_saved_bounds[i];
fmla = drpfp->SubstRec(subst,fmla);
node->Bound.Formula = fmla;
}
}
void ConvertCex(){
cex.clear();
RPFP *tree = new RPFP(rpfp->ls);
Node *root;
Counterexample &dctx = duality->GetCounterexample();
hash_map<Node *, Node *> ctx_node_map;
for(unsigned i = 0; i < dctx.get_tree()->nodes.size(); i++){
Node *dnode = dctx.get_tree()->nodes[i];
Node *onode = db_rev_map[dnode->map->map];
Node *node = tree->CloneNode(onode);
node->number = dnode->number; // numbers have to match for model to make sense
ctx_node_map[dnode] = node;
if(dnode == dctx.get_root())
root = node;
}
for(unsigned i = 0; i < dctx.get_tree()->edges.size(); i++){
Edge *dedge = dctx.get_tree()->edges[i];
Edge *oedge = db_edge_rev_map[dedge->map];
Node *parent = ctx_node_map[dedge->Parent];
std::vector<Node *> chs;
for(unsigned j = 0; j < dedge->Children.size(); j++)
chs.push_back(ctx_node_map[dedge->Children[j]]);
Edge *edge = tree->CreateEdge(parent,oedge->F,chs);
edge->number = dedge->number; // numbers have to match for model to make sense
edge->map = oedge;
}
tree->dualModel = dctx.get_tree()->dualModel;
cex.set(tree,root);
}
bool GetSolution(){
for(unsigned i = 0; i < rpfp->nodes.size(); i++)
if(!drpfp->nodes[i]->Annotation.SubsetEq(rpfp->nodes[i]->Bound))
return false;
expr dvar = ctx.int_const("@depth");
hash_map<ast,expr> subst;
subst[dvar] = ctx.int_val(INT_MAX);
for(unsigned i = 0; i < rpfp->nodes.size(); i++){
expr fmla = drpfp->nodes[i]->Annotation.Formula;
fmla = drpfp->SubstRec(subst,fmla);
fmla = fmla.simplify();
rpfp->nodes[i]->Annotation.Formula = fmla;
}
return true;
}
void UndoDepthBoundRPFP(){
#if 0
if(cex.get_tree()){
// here, need to map the cex back...
}
// also need to map the proof back, but we don't...
#endif
}
};
Solver *Solver::Create(const std::string &solver_class, RPFP *rpfp){ Solver *Solver::Create(const std::string &solver_class, RPFP *rpfp){
Duality *s = alloc(Duality,rpfp); // Solver *s = alloc(DualityDepthBounded,rpfp);
Solver *s = alloc(Duality,rpfp);
return s; return s;
} }

View file

@ -78,6 +78,7 @@ def_module_params('fixedpoint',
('batch_expand', BOOL, False, 'DUALITY: use batch expansion'), ('batch_expand', BOOL, False, 'DUALITY: use batch expansion'),
('dump_aig', SYMBOL, '', 'Dump clauses in AIG text format (AAG) to the given file name'), ('dump_aig', SYMBOL, '', 'Dump clauses in AIG text format (AAG) to the given file name'),
('conjecture_file', STRING, '', 'DUALITY: save conjectures to file'), ('conjecture_file', STRING, '', 'DUALITY: save conjectures to file'),
('enable_restarts', BOOL, False, 'DUALITY: enable restarts'),
)) ))

View file

@ -281,6 +281,7 @@ lbool dl_interface::query(::expr * query) {
rs->SetOption("stratified_inlining",m_ctx.get_params().stratified_inlining() ? "1" : "0"); rs->SetOption("stratified_inlining",m_ctx.get_params().stratified_inlining() ? "1" : "0");
rs->SetOption("batch_expand",m_ctx.get_params().batch_expand() ? "1" : "0"); rs->SetOption("batch_expand",m_ctx.get_params().batch_expand() ? "1" : "0");
rs->SetOption("conjecture_file",m_ctx.get_params().conjecture_file()); rs->SetOption("conjecture_file",m_ctx.get_params().conjecture_file());
rs->SetOption("enable_restarts",m_ctx.get_params().enable_restarts() ? "1" : "0");
#if 0 #if 0
if(rb != UINT_MAX){ if(rb != UINT_MAX){
std::ostringstream os; os << rb; std::ostringstream os; os << rb;