3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-27 02:45:51 +00:00

adding recursion bounds to duality

This commit is contained in:
Ken McMillan 2014-09-09 14:02:46 -07:00
parent 672b8e1022
commit 13b61d894c
7 changed files with 60 additions and 23 deletions

View file

@ -488,9 +488,10 @@ protected:
std::vector<Edge *> Incoming;
Term dual;
Node *map;
unsigned recursion_bound;
Node(const FuncDecl &_Name, const Transformer &_Annotation, const Transformer &_Bound, const Transformer &_Underapprox, const Term &_dual, RPFP *_owner, int _number)
: Name(_Name), Annotation(_Annotation), Bound(_Bound), Underapprox(_Underapprox), dual(_dual) {owner = _owner; number = _number; Outgoing = 0;}
: Name(_Name), Annotation(_Annotation), Bound(_Bound), Underapprox(_Underapprox), dual(_dual) {owner = _owner; number = _number; Outgoing = 0; recursion_bound = UINT_MAX;}
};
/** Create a node in the graph. The input is a term R(v_1...v_n)
@ -829,7 +830,7 @@ protected:
#ifdef _WINDOWS
__declspec(dllexport)
#endif
void FromClauses(const std::vector<Term> &clauses);
void FromClauses(const std::vector<Term> &clauses, const std::vector<unsigned> *bounds = 0);
void FromFixpointContext(fixedpoint fp, std::vector<Term> &queries);

View file

@ -3570,7 +3570,7 @@ namespace Duality {
#define USE_QE_LITE
void RPFP::FromClauses(const std::vector<Term> &unskolemized_clauses){
void RPFP::FromClauses(const std::vector<Term> &unskolemized_clauses, const std::vector<unsigned> *bounds){
hash_map<func_decl,Node *> pmap;
func_decl fail_pred = ctx.fresh_func_decl("@Fail", ctx.bool_sort());
@ -3663,6 +3663,7 @@ namespace Duality {
pmap[R] = node;
if (is_query)
node->Bound = CreateRelation(std::vector<Term>(), ctx.bool_val(false));
node->recursion_bound = bounds ? 0 : UINT_MAX;
}
}
@ -3728,6 +3729,8 @@ namespace Duality {
Transformer T = CreateTransformer(Relparams,Indparams,body);
Edge *edge = CreateEdge(Parent,T,Children);
edge->labeled = labeled;; // remember for label extraction
if(bounds)
Parent->recursion_bound = std::max(Parent->recursion_bound,(*bounds)[i]);
// edges.push_back(edge);
}

View file

@ -33,6 +33,7 @@ Revision History:
#include <map>
#include <list>
#include <iterator>
#include <sstream>
// TODO: make these official options or get rid of them
@ -304,7 +305,7 @@ namespace Duality {
#ifdef BOUNDED
struct Counter {
int val;
unsigned val;
Counter(){val = 0;}
};
typedef std::map<Node *,Counter> NodeToCounter;
@ -321,6 +322,10 @@ namespace Duality {
heuristic = !cex.get_tree() ? (Heuristic *)(new LocalHeuristic(rpfp))
: (Heuristic *)(new ReplayHeuristic(rpfp,cex));
#endif
// determine if we are recursion bounded
for(unsigned i = 0; i < rpfp->nodes.size(); i++)
if(rpfp->nodes[i]->recursion_bound < UINT_MAX)
RecursionBound = 0;
cex.clear(); // in case we didn't use it for heuristic
if(unwinding) delete unwinding;
unwinding = new RPFP(rpfp->ls);
@ -461,7 +466,7 @@ namespace Duality {
}
return false;
}
/** Create an instance of a node in the unwinding. Set its
annotation to true, and mark it unexpanded. */
Node* CreateNodeInstance(Node *node, int number = 0){
@ -780,10 +785,8 @@ namespace Duality {
std::vector<Node *> &insts = insts_of_node[node];
for(unsigned j = 0; j < insts.size(); j++)
if(indset->Contains(insts[j]))
if(NodePastRecursionBound(insts[j])){
if(NodePastRecursionBound(insts[j],true))
recursionBounded = true;
return;
}
}
}
@ -801,12 +804,18 @@ namespace Duality {
}
#ifdef BOUNDED
bool NodePastRecursionBound(Node *node){
bool NodePastRecursionBound(Node *node, bool report = false){
if(RecursionBound < 0) return false;
NodeToCounter &backs = back_edges[node];
for(NodeToCounter::iterator it = backs.begin(), en = backs.end(); it != en; ++it){
if(it->second.val > RecursionBound)
if(it->second.val > it->first->recursion_bound){
if(report){
std::ostringstream os;
os << "cut off " << it->first->Name.name() << " at depth " << it->second.val;
reporter->Message(os.str());
}
return true;
}
}
return false;
}