mirror of
https://github.com/Z3Prover/z3
synced 2025-04-26 18:45:33 +00:00
working on hitting sets
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
commit
960e8ea1d5
38 changed files with 1130 additions and 203 deletions
|
@ -253,6 +253,27 @@ protected:
|
|||
}
|
||||
|
||||
void assert_axiom(const expr &axiom){
|
||||
#if 1
|
||||
// HACK: large "distict" predicates can kill the legacy SMT solver.
|
||||
// encode them with a UIF
|
||||
if(axiom.is_app() && axiom.decl().get_decl_kind() == Distinct)
|
||||
if(axiom.num_args() > 10){
|
||||
sort s = axiom.arg(0).get_sort();
|
||||
std::vector<sort> sv;
|
||||
sv.push_back(s);
|
||||
int nargs = axiom.num_args();
|
||||
std::vector<expr> args(nargs);
|
||||
func_decl f = ctx->fresh_func_decl("@distinct",sv,ctx->int_sort());
|
||||
for(int i = 0; i < nargs; i++){
|
||||
expr a = axiom.arg(i);
|
||||
expr new_cnstr = f(a) == ctx->int_val(i);
|
||||
args[i] = new_cnstr;
|
||||
}
|
||||
expr cnstr = ctx->make(And,args);
|
||||
islvr->AssertInterpolationAxiom(cnstr);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
islvr->AssertInterpolationAxiom(axiom);
|
||||
}
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ namespace Duality {
|
|||
};
|
||||
|
||||
Reporter *CreateStdoutReporter(RPFP *rpfp);
|
||||
Reporter *CreateConjectureFileReporter(RPFP *rpfp, const std::string &fname);
|
||||
|
||||
/** Object we throw in case of catastrophe. */
|
||||
|
||||
|
@ -125,6 +126,7 @@ namespace Duality {
|
|||
{
|
||||
rpfp = _rpfp;
|
||||
reporter = 0;
|
||||
conj_reporter = 0;
|
||||
heuristic = 0;
|
||||
unwinding = 0;
|
||||
FullExpand = false;
|
||||
|
@ -274,6 +276,7 @@ namespace Duality {
|
|||
|
||||
RPFP *rpfp; // the input RPFP
|
||||
Reporter *reporter; // object for logging
|
||||
Reporter *conj_reporter; // object for logging conjectures
|
||||
Heuristic *heuristic; // expansion heuristic
|
||||
context &ctx; // Z3 context
|
||||
solver &slvr; // Z3 solver
|
||||
|
@ -297,6 +300,7 @@ namespace Duality {
|
|||
int last_decisions;
|
||||
hash_set<Node *> overapproxes;
|
||||
std::vector<Proposer *> proposers;
|
||||
std::string ConjectureFile;
|
||||
|
||||
#ifdef BOUNDED
|
||||
struct Counter {
|
||||
|
@ -310,6 +314,7 @@ namespace Duality {
|
|||
/** Solve the problem. */
|
||||
virtual bool Solve(){
|
||||
reporter = Report ? CreateStdoutReporter(rpfp) : new Reporter(rpfp);
|
||||
conj_reporter = ConjectureFile.empty() ? 0 : CreateConjectureFileReporter(rpfp,ConjectureFile);
|
||||
#ifndef LOCALIZE_CONJECTURES
|
||||
heuristic = !cex.get_tree() ? new Heuristic(rpfp) : new ReplayHeuristic(rpfp,cex);
|
||||
#else
|
||||
|
@ -340,6 +345,8 @@ namespace Duality {
|
|||
delete heuristic;
|
||||
// delete unwinding; // keep the unwinding for future mining of predicates
|
||||
delete reporter;
|
||||
if(conj_reporter)
|
||||
delete conj_reporter;
|
||||
for(unsigned i = 0; i < proposers.size(); i++)
|
||||
delete proposers[i];
|
||||
return res;
|
||||
|
@ -449,6 +456,9 @@ namespace Duality {
|
|||
if(option == "recursion_bound"){
|
||||
return SetIntOption(RecursionBound,value);
|
||||
}
|
||||
if(option == "conjecture_file"){
|
||||
ConjectureFile = value;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -728,6 +738,13 @@ namespace Duality {
|
|||
return ctx.constant(name.c_str(),ctx.bool_sort());
|
||||
}
|
||||
|
||||
/** Make a boolean variable to act as a "marker" for a pair of nodes. */
|
||||
expr NodeMarker(Node *node1, Node *node2){
|
||||
std::string name = std::string("@m_") + string_of_int(node1->number);
|
||||
name += std::string("_") + string_of_int(node2->number);
|
||||
return ctx.constant(name.c_str(),ctx.bool_sort());
|
||||
}
|
||||
|
||||
/** Union the annotation of dst into src. If with_markers is
|
||||
true, we conjoin the annotation formula of dst with its
|
||||
marker. This allows us to discover which disjunct is
|
||||
|
@ -1136,19 +1153,19 @@ namespace Duality {
|
|||
}
|
||||
|
||||
|
||||
void GenNodeSolutionWithMarkersAux(Node *node, RPFP::Transformer &annot, expr &marker_disjunction){
|
||||
void GenNodeSolutionWithMarkersAux(Node *node, RPFP::Transformer &annot, expr &marker_disjunction, Node *other_node){
|
||||
#ifdef BOUNDED
|
||||
if(RecursionBound >= 0 && NodePastRecursionBound(node))
|
||||
return;
|
||||
#endif
|
||||
RPFP::Transformer temp = node->Annotation;
|
||||
expr marker = NodeMarker(node);
|
||||
expr marker = (!other_node) ? NodeMarker(node) : NodeMarker(node, other_node);
|
||||
temp.Formula = (!marker || temp.Formula);
|
||||
annot.IntersectWith(temp);
|
||||
marker_disjunction = marker_disjunction || marker;
|
||||
}
|
||||
|
||||
bool GenNodeSolutionWithMarkers(Node *node, RPFP::Transformer &annot, bool expanded_only = false){
|
||||
bool GenNodeSolutionWithMarkers(Node *node, RPFP::Transformer &annot, bool expanded_only = false, Node *other_node = 0){
|
||||
bool res = false;
|
||||
annot.SetFull();
|
||||
expr marker_disjunction = ctx.bool_val(false);
|
||||
|
@ -1156,7 +1173,7 @@ namespace Duality {
|
|||
for(unsigned j = 0; j < insts.size(); j++){
|
||||
Node *node = insts[j];
|
||||
if(indset->Contains(insts[j])){
|
||||
GenNodeSolutionWithMarkersAux(node, annot, marker_disjunction); res = true;
|
||||
GenNodeSolutionWithMarkersAux(node, annot, marker_disjunction, other_node); res = true;
|
||||
}
|
||||
}
|
||||
annot.Formula = annot.Formula && marker_disjunction;
|
||||
|
@ -1253,7 +1270,7 @@ namespace Duality {
|
|||
Node *inst = insts[k];
|
||||
if(indset->Contains(inst)){
|
||||
if(checker->Empty(node) ||
|
||||
eq(lb ? checker->Eval(lb,NodeMarker(inst)) : checker->dualModel.eval(NodeMarker(inst)),ctx.bool_val(true))){
|
||||
eq(lb ? checker->Eval(lb,NodeMarker(inst)) : checker->dualModel.eval(NodeMarker(inst,node)),ctx.bool_val(true))){
|
||||
candidate.Children.push_back(inst);
|
||||
goto next_child;
|
||||
}
|
||||
|
@ -1336,7 +1353,7 @@ namespace Duality {
|
|||
for(unsigned j = 0; j < edge->Children.size(); j++){
|
||||
Node *oc = edge->Children[j];
|
||||
Node *nc = gen_cands_edge->Children[j];
|
||||
GenNodeSolutionWithMarkers(oc,nc->Annotation,true);
|
||||
GenNodeSolutionWithMarkers(oc,nc->Annotation,true,nc);
|
||||
}
|
||||
checker->AssertEdge(gen_cands_edge,1,true);
|
||||
return root;
|
||||
|
@ -1462,6 +1479,8 @@ namespace Duality {
|
|||
bool Update(Node *node, const RPFP::Transformer &fact, bool eager=false){
|
||||
if(!node->Annotation.SubsetEq(fact)){
|
||||
reporter->Update(node,fact,eager);
|
||||
if(conj_reporter)
|
||||
conj_reporter->Update(node,fact,eager);
|
||||
indset->Update(node,fact);
|
||||
updated_nodes.insert(node->map);
|
||||
node->Annotation.IntersectWith(fact);
|
||||
|
@ -2201,7 +2220,7 @@ namespace Duality {
|
|||
#endif
|
||||
int expand_max = 1;
|
||||
if(0&&duality->BatchExpand){
|
||||
int thing = static_cast<int>(stack.size() * 0.1);
|
||||
int thing = stack.size() / 10; // * 0.1;
|
||||
expand_max = std::max(1,thing);
|
||||
if(expand_max > 1)
|
||||
std::cout << "foo!\n";
|
||||
|
@ -3043,6 +3062,7 @@ namespace Duality {
|
|||
};
|
||||
};
|
||||
|
||||
static int stop_event = -1;
|
||||
|
||||
class StreamReporter : public Reporter {
|
||||
std::ostream &s;
|
||||
|
@ -3052,6 +3072,9 @@ namespace Duality {
|
|||
int event;
|
||||
int depth;
|
||||
void ev(){
|
||||
if(stop_event == event){
|
||||
std::cout << "stop!\n";
|
||||
}
|
||||
s << "[" << event++ << "]" ;
|
||||
}
|
||||
virtual void Extend(RPFP::Node *node){
|
||||
|
@ -3129,4 +3152,28 @@ namespace Duality {
|
|||
Reporter *CreateStdoutReporter(RPFP *rpfp){
|
||||
return new StreamReporter(rpfp, std::cout);
|
||||
}
|
||||
|
||||
class ConjectureFileReporter : public Reporter {
|
||||
std::ofstream s;
|
||||
public:
|
||||
ConjectureFileReporter(RPFP *_rpfp, const std::string &fname)
|
||||
: Reporter(_rpfp), s(fname.c_str()) {}
|
||||
virtual void Update(RPFP::Node *node, const RPFP::Transformer &update, bool eager){
|
||||
s << "(define-fun " << node->Name.name() << " (";
|
||||
for(unsigned i = 0; i < update.IndParams.size(); i++){
|
||||
if(i != 0)
|
||||
s << " ";
|
||||
s << "(" << update.IndParams[i] << " " << update.IndParams[i].get_sort() << ")";
|
||||
}
|
||||
s << ") Bool \n";
|
||||
s << update.Formula << ")\n";
|
||||
s << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
Reporter *CreateConjectureFileReporter(RPFP *rpfp, const std::string &fname){
|
||||
return new ConjectureFileReporter(rpfp, fname);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -397,6 +397,11 @@ namespace Duality {
|
|||
|
||||
sort array_domain() const;
|
||||
sort array_range() const;
|
||||
|
||||
friend std::ostream & operator<<(std::ostream & out, sort const & m){
|
||||
m.ctx().print_expr(out,m);
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue