diff --git a/src/duality/duality.h b/src/duality/duality.h index 1ee9eca08..e77fbe5c2 100644 --- a/src/duality/duality.h +++ b/src/duality/duality.h @@ -622,11 +622,20 @@ namespace Duality { */ + struct label_struct { + symbol name; + expr value; + bool pos; + label_struct(const symbol &s, const expr &e, bool b) + : name(s), value(e), pos(b) {} + }; + #ifdef WIN32 __declspec(dllexport) #endif - void FromClauses(const std::vector &clauses); + void FromClauses(const std::vector &clauses, + std::vector > &clause_labels); void FromFixpointContext(fixedpoint fp, std::vector &queries); @@ -707,10 +716,9 @@ namespace Duality { std::vector &res, std::vector &nodes); + Term RemoveLabelsRec(hash_map &memo, const Term &t, std::vector &lbls); - Term RemoveLabelsRec(hash_map &memo, const Term &t); - - Term RemoveLabels(const Term &t); + Term RemoveLabels(const Term &t, std::vector &lbls); Term GetAnnotation(Node *n); diff --git a/src/duality/duality_rpfp.cpp b/src/duality/duality_rpfp.cpp index 78c2b6955..38f00b4b0 100644 --- a/src/duality/duality_rpfp.cpp +++ b/src/duality/duality_rpfp.cpp @@ -1631,34 +1631,39 @@ namespace Duality { && t.num_args() == 0; } - RPFP::Term RPFP::RemoveLabelsRec(hash_map &memo, const Term &t){ + RPFP::Term RPFP::RemoveLabelsRec(hash_map &memo, const Term &t, + std::vector &lbls){ if(memo.find(t) != memo.end()) return memo[t]; Term res(ctx); if (t.is_app()){ func_decl f = t.decl(); - if(t.num_args() == 1 && f.name().str().substr(0,3) == "lbl"){ - res = RemoveLabelsRec(memo,t.arg(0)); + std::vector names; + bool pos; + if(t.is_label(pos,names)){ + res = RemoveLabelsRec(memo,t.arg(0),lbls); + for(unsigned i = 0; i < names.size(); i++) + lbls.push_back(label_struct(names[i],res,pos)); } else { int nargs = t.num_args(); std::vector args; for(int i = 0; i < nargs; i++) - args.push_back(RemoveLabelsRec(memo,t.arg(i))); + args.push_back(RemoveLabelsRec(memo,t.arg(i),lbls)); res = f(nargs,&args[0]); } } else if (t.is_quantifier()) - res = CloneQuantifier(t,RemoveLabelsRec(memo,t.body())); + res = CloneQuantifier(t,RemoveLabelsRec(memo,t.body(),lbls)); else res = t; memo[t] = res; return res; } - RPFP::Term RPFP::RemoveLabels(const Term &t){ + RPFP::Term RPFP::RemoveLabels(const Term &t, std::vector &lbls){ hash_map memo ; - return RemoveLabelsRec(memo,t); + return RemoveLabelsRec(memo,t,lbls); } Z3User::Term Z3User::SubstBoundRec(hash_map > &memo, hash_map &subst, int level, const Term &t) @@ -1733,7 +1738,8 @@ namespace Duality { arg.decl().get_decl_kind() == Uninterpreted); } - void RPFP::FromClauses(const std::vector &unskolemized_clauses){ + void RPFP::FromClauses(const std::vector &unskolemized_clauses, + std::vector > &clause_labels){ hash_map pmap; func_decl fail_pred = ctx.fresh_func_decl("@Fail", ctx.bool_sort()); @@ -1800,6 +1806,7 @@ namespace Duality { // create the edges + clause_labels.resize(clauses.size()); for(unsigned i = 0; i < clauses.size(); i++){ Term clause = clauses[i]; Term body = clause.arg(0); @@ -1830,7 +1837,7 @@ namespace Duality { hash_map scan_memo; std::vector Children; body = ScanBody(scan_memo,body,pmap,Relparams,Children); - body = RemoveLabels(body); + body = RemoveLabels(body,clause_labels[i]); body = body.simplify(); // Create the edge diff --git a/src/duality/duality_wrapper.cpp b/src/duality/duality_wrapper.cpp index 17638335d..0603b5a4a 100644 --- a/src/duality/duality_wrapper.cpp +++ b/src/duality/duality_wrapper.cpp @@ -545,6 +545,15 @@ expr context::make_quant(decl_kind op, const std::vector &_sorts, const st a.show(); } + bool expr::is_label (bool &pos,std::vector &names) const { + buffer< ::symbol> _names; + bool res = m().is_label(to_expr(raw()),pos,_names); + if(res) + for(unsigned i = 0; i < _names.size(); i++) + names.push_back(symbol(ctx(),_names[i])); + return res; + } + } diff --git a/src/duality/duality_wrapper.h b/src/duality/duality_wrapper.h index 20557e3e2..284d1c527 100755 --- a/src/duality/duality_wrapper.h +++ b/src/duality/duality_wrapper.h @@ -454,6 +454,7 @@ namespace Duality { bool is_app() const {return raw()->get_kind() == AST_APP;} bool is_quantifier() const {return raw()->get_kind() == AST_QUANTIFIER;} bool is_var() const {return raw()->get_kind() == AST_VAR;} + bool is_label (bool &pos,std::vector &names) const ; // operator Z3_app() const { assert(is_app()); return reinterpret_cast(m_ast); } func_decl decl() const {return func_decl(ctx(),to_app(raw())->get_decl());} diff --git a/src/muz_qe/duality_dl_interface.cpp b/src/muz_qe/duality_dl_interface.cpp index ee1eca712..304e5773d 100644 --- a/src/muz_qe/duality_dl_interface.cpp +++ b/src/muz_qe/duality_dl_interface.cpp @@ -52,6 +52,7 @@ namespace Duality { DualityStatus status; std::vector clauses; + std::vector > clause_labels; hash_map map; // edges to clauses Solver::Counterexample cex; @@ -157,7 +158,7 @@ void dl_interface::check_reset() { } // creates 1-1 map between clauses and rpfp edges - _d->rpfp->FromClauses(clauses); + _d->rpfp->FromClauses(clauses,_d->clause_labels); // populate the edge-to-clause map for(unsigned i = 0; i < _d->rpfp->edges.size(); ++i) @@ -256,6 +257,7 @@ static void print_proof(dl_interface *d, std::ostream& out, Solver::Counterexamp } out << " )\n"; + // reference the proofs of all the children, in syntactic order // "true" means the child is not needed