From 0ab8cf84132ea19e6c7a37ab0d11398b2e16e654 Mon Sep 17 00:00:00 2001 From: Andrew Reynolds Date: Tue, 27 Feb 2018 13:58:45 -0600 Subject: Improvements to sygus sampling (#1621) --- src/options/quantifiers_options | 2 +- src/theory/datatypes/datatypes_sygus.cpp | 95 ++++++++++++++++---------------- src/theory/datatypes/datatypes_sygus.h | 43 ++++++++++++--- src/theory/quantifiers/sygus_sampler.cpp | 4 ++ 4 files changed, 90 insertions(+), 54 deletions(-) diff --git a/src/options/quantifiers_options b/src/options/quantifiers_options index e97f11db9..6552b9157 100644 --- a/src/options/quantifiers_options +++ b/src/options/quantifiers_options @@ -306,7 +306,7 @@ option sygusRewSynth --sygus-rr-synth bool :read-write :default false use sygus to enumerate candidate rewrite rules via sampling option sygusRewVerify --sygus-rr-verify bool :read-write :default false use sygus to verify the correctness of rewrite rules via sampling -option sygusSamples --sygus-samples=N int :read-write :default 100 :read-write +option sygusSamples --sygus-samples=N int :read-write :default 1000 :read-write number of points to consider when doing sygus rewriter sample testing option sygusSampleGrammar --sygus-sample-grammar bool :default true when applicable, use grammar for choosing sample points diff --git a/src/theory/datatypes/datatypes_sygus.cpp b/src/theory/datatypes/datatypes_sygus.cpp index 556b07f7f..728cd8135 100644 --- a/src/theory/datatypes/datatypes_sygus.cpp +++ b/src/theory/datatypes/datatypes_sygus.cpp @@ -790,60 +790,63 @@ bool SygusSymBreakNew::registerSearchValue( Node a, Node n, Node nv, unsigned d, if (options::sygusRewVerify()) { // add to the sampler database object - std::map::iterator its = - d_sampler.find(a); - if (its == d_sampler.end()) + std::map::iterator its = + d_sampler[a].find(tn); + if (its == d_sampler[a].end()) { - d_sampler[a].initializeSygus(d_tds, a, options::sygusSamples()); - its = d_sampler.find(a); + d_sampler[a][tn].initializeSygus(d_tds, nv, options::sygusSamples()); + its = d_sampler[a].find(tn); } + Node bvr_sample_ret; + std::map::iterator itsv = + d_cache[a].d_search_val_sample[tn].find(bvr); + if (itsv == d_cache[a].d_search_val_sample[tn].end()) + { + // initialize the sampler for the rewritten form of this node + bvr_sample_ret = its->second.registerTerm(bvr); + d_cache[a].d_search_val_sample[tn][bvr] = bvr_sample_ret; + } + else + { + bvr_sample_ret = itsv->second; + } + + // register the current node with the sampler Node sample_ret = its->second.registerTerm(bv); - d_cache[a].d_search_val_sample[nv] = sample_ret; - if (itsv != d_cache[a].d_search_val[tn].end()) + + // bv and bvr should be equivalent under examples + if (sample_ret != bvr_sample_ret) { - // if the analog of this term and another term were rewritten to the - // same term, then they should be equivalent under examples. - Node prev = itsv->second; - Node prev_sample_ret = d_cache[a].d_search_val_sample[prev]; - if (sample_ret != prev_sample_ret) + // we have detected unsoundness in the rewriter + Options& nodeManagerOptions = NodeManager::currentNM()->getOptions(); + std::ostream* out = nodeManagerOptions.getOut(); + (*out) << "(unsound-rewrite " << bv << " " << bvr << ")" << std::endl; + // debugging information + if (Trace.isOn("sygus-rr-debug")) { - Node prev_bv = d_tds->sygusToBuiltin(prev, tn); - // we have detected unsoundness in the rewriter - Options& nodeManagerOptions = - NodeManager::currentNM()->getOptions(); - std::ostream* out = nodeManagerOptions.getOut(); - (*out) << "(unsound-rewrite " << prev_bv << " " << bv << ")" - << std::endl; - // debugging information - if (Trace.isOn("sygus-rr-debug")) + int pt_index = its->second.getDiffSamplePointIndex(bv, bvr); + if (pt_index >= 0) { - int pt_index = its->second.getDiffSamplePointIndex(bv, prev_bv); - if (pt_index >= 0) + Trace("sygus-rr-debug") + << "; unsound: are not equivalent for : " << std::endl; + std::vector vars; + std::vector pt; + its->second.getSamplePoint(pt_index, vars, pt); + Assert(vars.size() == pt.size()); + for (unsigned i = 0, size = pt.size(); i < size; i++) { - Trace("sygus-rr-debug") - << "; unsound: both ext-rewrite to : " << bvr << std::endl; - Trace("sygus-rr-debug") - << "; unsound: but are not equivalent for : " << std::endl; - std::vector vars; - std::vector pt; - its->second.getSamplePoint(pt_index, vars, pt); - Assert(vars.size() == pt.size()); - for (unsigned i = 0, size = pt.size(); i < size; i++) - { - Trace("sygus-rr-debug") << "; unsound: " << vars[i] - << " -> " << pt[i] << std::endl; - } - Node bv_e = its->second.evaluate(bv, pt_index); - Node pbv_e = its->second.evaluate(prev_bv, pt_index); - Assert(bv_e != pbv_e); - Trace("sygus-rr-debug") << "; unsound: where they evaluate to " - << pbv_e << " and " << bv_e - << std::endl; - } - else - { - Assert(false); + Trace("sygus-rr-debug") << "; unsound: " << vars[i] << " -> " + << pt[i] << std::endl; } + Node bv_e = its->second.evaluate(bv, pt_index); + Node pbv_e = its->second.evaluate(bvr, pt_index); + Assert(bv_e != pbv_e); + Trace("sygus-rr-debug") << "; unsound: where they evaluate to " + << pbv_e << " and " << bv_e << std::endl; + } + else + { + Assert(false); } } } diff --git a/src/theory/datatypes/datatypes_sygus.h b/src/theory/datatypes/datatypes_sygus.h index 2c1f85deb..fa3918270 100644 --- a/src/theory/datatypes/datatypes_sygus.h +++ b/src/theory/datatypes/datatypes_sygus.h @@ -54,10 +54,37 @@ private: NodeSet d_active_terms; IntMap d_currTermSize; Node d_zero; -private: + + private: + /** + * Map from terms (selector chains) to their anchors. The anchor of a + * selector chain S1( ... Sn( x ) ... ) is x. + */ std::map< Node, Node > d_term_to_anchor; + /** + * Map from terms (selector chains) to the conjecture that their anchor is + * associated with. + */ std::map d_term_to_anchor_conj; + /** + * Map from terms (selector chains) to their depth. The depth of a selector + * chain S1( ... Sn( x ) ... ) is: + * weight( S1 ) + ... + weight( Sn ), + * where weight is the selector weight of Si + * (see SygusTermDatabase::getSelectorWeight). + */ std::map< Node, unsigned > d_term_to_depth; + /** + * Map from terms (selector chains) to whether they are the topmost term + * of their type. For example, if: + * S1 : T1 -> T2 + * S2 : T2 -> T2 + * S3 : T2 -> T1 + * S4 : T1 -> T3 + * Then, x, S1( x ), and S4( S3( S2( S1( x ) ) ) ) are top-level terms, + * whereas S2( S1( x ) ) and S3( S2( S1( x ) ) ) are not. + * + */ std::map< Node, bool > d_is_top_level; void registerTerm( Node n, std::vector< Node >& lemmas ); bool computeTopLevel( TypeNode tn, Node n ); @@ -80,22 +107,24 @@ private: std::map< TypeNode, std::map< Node, unsigned > > d_search_val_sz; /** search value sample * - * This is used for the sygusRewVerify() option. For each sygus term we - * register in this cache, this stores the value returned by calling - * SygusSample::registerTerm(...) on its analog. + * This is used for the sygusRewVerify() option. For each sygus term t + * of type tn with anchor a that we register with this cache, we set: + * d_search_val_sample[tn][r] = r' + * where r is the rewritten form of the builtin equivalent of t, and r' + * is the term returned by d_sampler[a][tn].registerTerm( r ). */ - std::map d_search_val_sample; + std::map> d_search_val_sample; /** For each term, whether this cache has processed that term */ std::map< Node, bool > d_search_val_proc; }; // anchor -> cache std::map< Node, SearchCache > d_cache; - /** a sygus sampler object for each anchor + /** a sygus sampler object for each (anchor, sygus type) pair * * This is used for the sygusRewVerify() option to verify the correctness of * the rewriter. */ - std::map d_sampler; + std::map> d_sampler; Node d_null; void assertTesterInternal( int tindex, TNode n, Node exp, std::vector< Node >& lemmas ); // register search term diff --git a/src/theory/quantifiers/sygus_sampler.cpp b/src/theory/quantifiers/sygus_sampler.cpp index aa0a4b778..fa0478ac7 100644 --- a/src/theory/quantifiers/sygus_sampler.cpp +++ b/src/theory/quantifiers/sygus_sampler.cpp @@ -100,6 +100,7 @@ void SygusSampler::initialize(TypeNode tn, << "Type id for " << sv << " is " << tnid << std::endl; d_var_index[sv] = d_type_vars[tnid].size(); d_type_vars[tnid].push_back(sv); + d_type_ids[sv] = tnid; } initializeSamples(nsamples); } @@ -176,6 +177,7 @@ void SygusSampler::initializeSygus(TermDbSygus* tds, Node f, unsigned nsamples) << "Type id for " << sv << " is " << tnid << std::endl; d_var_index[sv] = d_type_vars[tnid].size(); d_type_vars[tnid].push_back(sv); + d_type_ids[sv] = tnid; } initializeSamples(nsamples); @@ -666,6 +668,8 @@ Node SygusSamplerExt::registerTerm(Node n, bool forceKeep) // one of eq_n or n must be ordered bool eqor = isOrdered(eq_n); bool nor = isOrdered(n); + Trace("sygus-synth-rr-debug") + << "Ordered? : " << nor << " " << eqor << std::endl; bool isUnique = false; if (eqor || nor) { -- cgit v1.2.3 From 9f5447f5ca07688ff7e6da7973d7f97d17678427 Mon Sep 17 00:00:00 2001 From: Andrew Reynolds Date: Tue, 27 Feb 2018 15:15:07 -0600 Subject: Option to not use partial function semantics for arithmetic div by zero (#1620) --- src/options/arith_options | 2 + src/theory/arith/theory_arith_private.cpp | 97 +++++++++++++++++++++---------- src/theory/arith/theory_arith_private.h | 46 ++++++++++----- 3 files changed, 100 insertions(+), 45 deletions(-) diff --git a/src/options/arith_options b/src/options/arith_options index e6f7fd6d0..722af1fa1 100644 --- a/src/options/arith_options +++ b/src/options/arith_options @@ -155,6 +155,8 @@ option ppAssertMaxSubSize --pp-assert-max-sub-size unsigned :default 2 option maxReplayTree --max-replay-tree int :default 512 threshold for attempting to replay a tree +option arithNoPartialFun --arith-no-partial-fun bool :default false + do not use partial function semantics for arithmetic (not SMT LIB compliant) option pbRewrites --pb-rewrites bool :default false apply pseudo boolean rewrites diff --git a/src/theory/arith/theory_arith_private.cpp b/src/theory/arith/theory_arith_private.cpp index da17dd2f5..a990e008c 100644 --- a/src/theory/arith/theory_arith_private.cpp +++ b/src/theory/arith/theory_arith_private.cpp @@ -4902,18 +4902,9 @@ Node TheoryArithPrivate::expandDefinition(LogicRequest &logicRequest, Node node) Node ret = nm->mkNode(kind::DIVISION_TOTAL, num, den); if (!den.isConst() || den.getConst().sgn() == 0) { - // partial function: division - if (d_divByZero.isNull()) - { - d_divByZero = - nm->mkSkolem("divByZero", - nm->mkFunctionType(nm->realType(), nm->realType()), - "partial real division", - NodeManager::SKOLEM_EXACT_NAME); - logicRequest.widenLogic(THEORY_UF); - } + Node divByZeroNum = + getArithSkolemApp(logicRequest, num, arith_skolem_div_by_zero); Node denEq0 = nm->mkNode(kind::EQUAL, den, nm->mkConst(Rational(0))); - Node divByZeroNum = nm->mkNode(kind::APPLY_UF, d_divByZero, num); ret = nm->mkNode(kind::ITE, denEq0, divByZeroNum, ret); } return ret; @@ -4927,17 +4918,9 @@ Node TheoryArithPrivate::expandDefinition(LogicRequest &logicRequest, Node node) Node ret = nm->mkNode(kind::INTS_DIVISION_TOTAL, num, den); if (!den.isConst() || den.getConst().sgn() == 0) { - if (d_intDivByZero.isNull()) - { - d_intDivByZero = nm->mkSkolem( - "intDivByZero", - nm->mkFunctionType(nm->integerType(), nm->integerType()), - "partial integer division", - NodeManager::SKOLEM_EXACT_NAME); - logicRequest.widenLogic(THEORY_UF); - } + Node intDivByZeroNum = + getArithSkolemApp(logicRequest, num, arith_skolem_int_div_by_zero); Node denEq0 = nm->mkNode(kind::EQUAL, den, nm->mkConst(Rational(0))); - Node intDivByZeroNum = nm->mkNode(kind::APPLY_UF, d_intDivByZero, num); ret = nm->mkNode(kind::ITE, denEq0, intDivByZeroNum, ret); } return ret; @@ -4951,17 +4934,9 @@ Node TheoryArithPrivate::expandDefinition(LogicRequest &logicRequest, Node node) Node ret = nm->mkNode(kind::INTS_MODULUS_TOTAL, num, den); if (!den.isConst() || den.getConst().sgn() == 0) { - if (d_modZero.isNull()) - { - d_modZero = nm->mkSkolem( - "modZero", - nm->mkFunctionType(nm->integerType(), nm->integerType()), - "partial modulus", - NodeManager::SKOLEM_EXACT_NAME); - logicRequest.widenLogic(THEORY_UF); - } + Node modZeroNum = + getArithSkolemApp(logicRequest, num, arith_skolem_mod_by_zero); Node denEq0 = nm->mkNode(kind::EQUAL, den, nm->mkConst(Rational(0))); - Node modZeroNum = nm->mkNode(kind::APPLY_UF, d_modZero, num); ret = nm->mkNode(kind::ITE, denEq0, modZeroNum, ret); } return ret; @@ -5062,8 +5037,68 @@ Node TheoryArithPrivate::expandDefinition(LogicRequest &logicRequest, Node node) Unreachable(); } +Node TheoryArithPrivate::getArithSkolem(LogicRequest& logicRequest, + ArithSkolemId asi) +{ + std::map::iterator it = d_arith_skolem.find(asi); + if (it == d_arith_skolem.end()) + { + NodeManager* nm = NodeManager::currentNM(); + + TypeNode tn; + std::string name; + std::string desc; + if (asi == arith_skolem_div_by_zero) + { + tn = nm->realType(); + name = std::string("divByZero"); + desc = std::string("partial real division"); + } + else if (asi == arith_skolem_int_div_by_zero) + { + tn = nm->integerType(); + name = std::string("intDivByZero"); + desc = std::string("partial int division"); + } + else if (asi == arith_skolem_mod_by_zero) + { + tn = nm->integerType(); + name = std::string("modZero"); + desc = std::string("partial modulus"); + } + Node skolem; + if (options::arithNoPartialFun()) + { + // partial function: division + skolem = nm->mkSkolem(name, tn, desc, NodeManager::SKOLEM_EXACT_NAME); + } + else + { + // partial function: division + skolem = nm->mkSkolem(name, + nm->mkFunctionType(tn, tn), + desc, + NodeManager::SKOLEM_EXACT_NAME); + logicRequest.widenLogic(THEORY_UF); + } + d_arith_skolem[asi] = skolem; + return skolem; + } + return it->second; +} +Node TheoryArithPrivate::getArithSkolemApp(LogicRequest& logicRequest, + Node n, + ArithSkolemId asi) +{ + Node skolem = getArithSkolem(logicRequest, asi); + if (!options::arithNoPartialFun()) + { + skolem = NodeManager::currentNM()->mkNode(APPLY_UF, skolem, n); + } + return skolem; +} // InferBoundsResult TheoryArithPrivate::inferBound(TNode term, const InferBoundsParameters& param){ // Node t = Rewriter::rewrite(term); diff --git a/src/theory/arith/theory_arith_private.h b/src/theory/arith/theory_arith_private.h index 23712016d..af0012304 100644 --- a/src/theory/arith/theory_arith_private.h +++ b/src/theory/arith/theory_arith_private.h @@ -829,25 +829,43 @@ private: Statistics d_statistics; + enum ArithSkolemId + { + arith_skolem_div_by_zero, + arith_skolem_int_div_by_zero, + arith_skolem_mod_by_zero, + }; /** - * Function symbol used to implement uninterpreted division-by-zero - * semantics. Needed to deal with partial division function ("/"). + * Function symbols used to implement: + * (1) Uninterpreted division-by-zero semantics. Needed to deal with partial + * division function ("/"), + * (2) Uninterpreted int-division-by-zero semantics. Needed to deal with + * partial function "div", + * (3) Uninterpreted mod-zero semantics. Needed to deal with partial + * function "mod". + * + * If the option arithNoPartialFun() is enabled, then the range of this map + * stores Skolem constants instead of Skolem functions, meaning that the + * function-ness of e.g. division by zero is ignored. */ - Node d_divByZero; - - /** - * Function symbol used to implement uninterpreted - * int-division-by-zero semantics. Needed to deal with partial - * function "div". + std::map d_arith_skolem; + /** get arithmetic skolem + * + * Returns the Skolem in the above map for the given id, creating it if it + * does not already exist. If a Skolem function is created, the logic is + * widened to include UF. */ - Node d_intDivByZero; - - /** - * Function symbol used to implement uninterpreted mod-zero - * semantics. Needed to deal with partial function "mod". + Node getArithSkolem(LogicRequest& logicRequest, ArithSkolemId asi); + /** get arithmetic skolem application + * + * By default, this returns the term f( n ), where f is the Skolem function + * for the identifier asi. + * + * If the option arithNoPartialFun is enabled, this returns f, where f is + * the Skolem constant for the identifier asi. */ - Node d_modZero; + Node getArithSkolemApp(LogicRequest& logicRequest, Node n, ArithSkolemId asi); /** * Maps for Skolems for to-integer, real/integer div-by-k, and inverse -- cgit v1.2.3 From 7f33294261869ab8f0caa8660222576a4ff7bcdc Mon Sep 17 00:00:00 2001 From: Andrew Reynolds Date: Tue, 27 Feb 2018 16:52:57 -0600 Subject: Improve rewriter for string indexof (#1592) --- src/theory/strings/theory_strings_rewriter.cpp | 239 ++++++++++++++----------- src/util/regexp.cpp | 5 + src/util/regexp.h | 5 + test/regress/regress0/strings/Makefile.am | 3 +- test/regress/regress0/strings/idof-sem.smt2 | 6 + 5 files changed, 155 insertions(+), 103 deletions(-) create mode 100644 test/regress/regress0/strings/idof-sem.smt2 diff --git a/src/theory/strings/theory_strings_rewriter.cpp b/src/theory/strings/theory_strings_rewriter.cpp index 54a5b4dcb..1555b0aa0 100644 --- a/src/theory/strings/theory_strings_rewriter.cpp +++ b/src/theory/strings/theory_strings_rewriter.cpp @@ -1818,107 +1818,143 @@ Node TheoryStringsRewriter::rewriteContains( Node node ) { Node TheoryStringsRewriter::rewriteIndexof( Node node ) { Assert(node.getKind() == kind::STRING_STRIDOF); - std::vector< Node > children; - getConcat( node[0], children ); - //std::vector< Node > children1; - //getConcat( node[1], children1 ); TODO - std::size_t start = 0; - std::size_t val2 = 0; - if( node[2].isConst() ){ - CVC4::Rational RMAXINT(LONG_MAX); - if( node[2].getConst()>RMAXINT ){ - Assert(node[2].getConst() <= RMAXINT, "Number exceeds LONG_MAX in string index_of"); - return NodeManager::currentNM()->mkConst( ::CVC4::Rational(-1) ); - }else if( node[2].getConst().sgn()==-1 ){ - //constant negative - return NodeManager::currentNM()->mkConst( ::CVC4::Rational(-1) ); - }else{ - val2 = node[2].getConst().getNumerator().toUnsignedInt(); - start = val2; - } - } - bool prefixNoOverlap = false; - CVC4::String t; - if( node[1].isConst() ){ - t = node[1].getConst(); - } - //unsigned ch1_index = 0; - for( unsigned i=0; i(); - if( node[1].isConst() ){ - if( i==0 ){ - std::size_t ret = s.find( t, start ); - if( ret!=std::string::npos ) { - //exact if start value was constant - if( node[2].isConst() ){ - return NodeManager::currentNM()->mkConst( ::CVC4::Rational((unsigned) ret) ); - } - }else{ - //exact if we scanned the entire string - if( node[0].isConst() ){ - return NodeManager::currentNM()->mkConst( ::CVC4::Rational(-1) ); - }else{ - prefixNoOverlap = (s.overlap(t)==0); - Trace("strings-rewrite-debug") << "Prefix no overlap : " << s << " " << t << " " << prefixNoOverlap << std::endl; - } - } - }else if( !node[2].isConst() ){ - break; - }else{ - std::size_t ret = s.find(t, start); - //remove remaining children after finding the string - if( ret!=std::string::npos ){ - Assert( ret+t.size()<=s.size() ); - children[i] = NodeManager::currentNM()->mkConst( ::CVC4::String( s.substr(0,ret+t.size()) ) ); - do_splice = true; - }else{ - //if no overlap on last child, can remove - if( t.overlap( s )==0 && i==children.size()-1 ){ - std::vector< Node > spl; - spl.insert( spl.end(), children.begin(), children.begin()+i ); - return NodeManager::currentNM()->mkNode( kind::STRING_STRIDOF, mkConcat( kind::STRING_CONCAT, spl ), node[1], node[2] ); - } - } - } + NodeManager* nm = NodeManager::currentNM(); + + if (node[2].isConst() && node[2].getConst().sgn() < 0) + { + // z<0 implies str.indexof( x, y, z ) --> -1 + Node negone = nm->mkConst(Rational(-1)); + return returnRewrite(node, negone, "idof-neg"); + } + + if (node[1].isConst()) + { + if (node[1].getConst().size() == 0) + { + // str.indexof( x, "", z ) --> -1 + Node negone = nm->mkConst(Rational(-1)); + return returnRewrite(node, negone, "idof-empty"); + } + } + + // evaluation and simple cases + std::vector children0; + getConcat(node[0], children0); + if (children0[0].isConst() && node[1].isConst() && node[2].isConst()) + { + CVC4::Rational RMAXINT(CVC4::String::maxSize()); + if (node[2].getConst() > RMAXINT) + { + // We know that, due to limitations on the size of string constants + // in our implementation, that accessing a position greater than + // RMAXINT is guaranteed to be out of bounds. + Node negone = nm->mkConst(Rational(-1)); + return returnRewrite(node, negone, "idof-max"); + } + Assert(node[2].getConst().sgn() >= 0); + unsigned start = + node[2].getConst().getNumerator().toUnsignedInt(); + CVC4::String s = children0[0].getConst(); + CVC4::String t = node[1].getConst(); + std::size_t ret = s.find(t, start); + if (ret != std::string::npos) + { + Node retv = nm->mkConst(Rational(static_cast(ret))); + return returnRewrite(node, retv, "idof-find"); + } + else if (children0.size() == 1) + { + Node negone = nm->mkConst(Rational(-1)); + return returnRewrite(node, negone, "idof-nfind"); + } + } + + Node len0 = nm->mkNode(kind::STRING_LENGTH, node[0]); + Node len1 = nm->mkNode(kind::STRING_LENGTH, node[1]); + Node len0m2 = nm->mkNode(kind::MINUS, len0, node[2]); + if (checkEntailArith(len1, len0m2, true)) + { + // len(x)-z < len(y) implies indexof( x, y, z ) ----> -1 + Node negone = nm->mkConst(Rational(-1)); + return returnRewrite(node, negone, "idof-len"); + } + + Node fstr = node[0]; + if (!node[2].isConst() || node[2].getConst().sgn() != 0) + { + fstr = nm->mkNode(kind::STRING_SUBSTR, node[0], node[2], len0); + fstr = Rewriter::rewrite(fstr); + if (fstr.isConst()) + { + CVC4::String fs = fstr.getConst(); + if (fs.size() == 0) + { + // substr( x, z, len(x) ) --> "" implies str.indexof( x, y, z ) --> -1 + Node negone = nm->mkConst(Rational(-1)); + return returnRewrite(node, negone, "idof-base-len"); } - //decrement the start index - if( start>0 ){ - if( s.size()>start ){ - start = 0; - }else{ - start = start - s.size(); + } + } + + Node cmp_con = nm->mkNode(kind::STRING_STRCTN, fstr, node[1]); + Node cmp_conr = Rewriter::rewrite(cmp_con); + if (cmp_conr.isConst()) + { + if (cmp_conr.getConst()) + { + if (node[2].isConst() && node[2].getConst().sgn() == 0) + { + // past the first position in node[0] that contains node[1], we can drop + std::vector children1; + getConcat(node[1], children1); + std::vector nb; + std::vector ne; + int cc = componentContains(children0, children1, nb, ne, true, 1); + if (cc != -1 && !ne.empty()) + { + // For example: + // str.indexof(str.++(x,y,z),y,0) ---> str.indexof(str.++(x,y),y,0) + Node nn = mkConcat(kind::STRING_CONCAT, children0); + Node ret = nm->mkNode(kind::STRING_STRIDOF, nn, node[1], node[2]); + return returnRewrite(node, ret, "idof-def-ctn"); } } - }else if( !node[2].isConst() ){ - break; - }else{ - if( children[i]==node[1] && start==0 ){ - //can remove beyond this - do_splice = true; - } - } - if( do_splice ){ - std::vector< Node > spl; - //since we definitely will find the string, we can safely add the length of the constant non-overlapping prefix - if( prefixNoOverlap ){ - Node pl = Rewriter::rewrite( NodeManager::currentNM()->mkNode( kind::STRING_LENGTH, children[0] ) ); - Assert( pl.isConst() ); - Assert( node[2].isConst() ); - int new_start = val2 - pl.getConst().getNumerator().toUnsignedInt(); - if( new_start<0 ){ - new_start = 0; - } - spl.insert( spl.end(), children.begin()+1, children.begin()+i+1 ); - return NodeManager::currentNM()->mkNode( kind::PLUS, pl, - NodeManager::currentNM()->mkNode( kind::STRING_STRIDOF, mkConcat( kind::STRING_CONCAT, spl ), node[1], NodeManager::currentNM()->mkConst( Rational(new_start) ) ) ); - }else{ - spl.insert( spl.end(), children.begin(), children.begin()+i+1 ); - return NodeManager::currentNM()->mkNode( kind::STRING_STRIDOF, mkConcat( kind::STRING_CONCAT, spl ), node[1], node[2] ); + + // these rewrites are only possible if we will not return -1 + Node l1 = nm->mkNode(kind::STRING_LENGTH, node[1]); + Node zero = NodeManager::currentNM()->mkConst(CVC4::Rational(0)); + bool is_non_empty = checkEntailArith(l1, zero, true); + + if (is_non_empty) + { + // strip symbolic length + Node new_len = node[2]; + std::vector nr; + if (stripSymbolicLength(children0, nr, 1, new_len)) + { + // For example: + // z>str.len( x1 ) and str.len( y )>0 and str.contains( x2, y )-->true + // implies + // str.indexof( str.++( x1, x2 ), y, z ) ---> + // str.len( x1 ) + str.indexof( x2, y, z-str.len(x1) ) + Node nn = mkConcat(kind::STRING_CONCAT, children0); + Node ret = nm->mkNode( + kind::PLUS, + nm->mkNode(kind::MINUS, node[2], new_len), + nm->mkNode(kind::STRING_STRIDOF, nn, node[1], new_len)); + return returnRewrite(node, ret, "idof-strip-sym-len"); + } } } + else + { + // str.contains( x, y ) --> false implies str.indexof(x,y,z) --> -1 + Node negone = nm->mkConst(Rational(-1)); + return returnRewrite(node, negone, "idof-nctn"); + } } + + Trace("strings-rewrite-nf") << "No rewrites for : " << node << std::endl; return node; } @@ -2123,13 +2159,7 @@ Node TheoryStringsRewriter::rewritePrefixSuffix(Node n) if (n[1].isConst()) { CVC4::String s = n[1].getConst(); - if (s.isEmptyString()) - { - Assert(!n[0].isConst()); - Node ret = n[0].eqNode(n[1]); - return returnRewrite(n, ret, "suf/prefix-empty"); - } - else if (n[0].isConst()) + if (n[0].isConst()) { Node ret = NodeManager::currentNM()->mkConst(false); CVC4::String t = n[0].getConst(); @@ -2143,6 +2173,11 @@ Node TheoryStringsRewriter::rewritePrefixSuffix(Node n) } return returnRewrite(n, ret, "suf/prefix-const"); } + else if (s.isEmptyString()) + { + Node ret = n[0].eqNode(n[1]); + return returnRewrite(n, ret, "suf/prefix-empty"); + } else if (s.size() == 1) { // (str.prefix x "A") and (str.suffix x "A") are equivalent to diff --git a/src/util/regexp.cpp b/src/util/regexp.cpp index d93c5426e..a7e5131ec 100644 --- a/src/util/regexp.cpp +++ b/src/util/regexp.cpp @@ -371,6 +371,11 @@ bool String::isDigit(unsigned character) return c >= '0' && c <= '9'; } +size_t String::maxSize() +{ + return std::numeric_limits::max(); +} + int String::toNumber() const { if (isNumber()) { int ret = 0; diff --git a/src/util/regexp.h b/src/util/regexp.h index d51ef4372..efbb4579d 100644 --- a/src/util/regexp.h +++ b/src/util/regexp.h @@ -163,6 +163,11 @@ class CVC4_PUBLIC String { */ static bool isDigit(unsigned character); + /** + * Returns the maximum length of string representable by this class. + * Corresponds to the maximum size of d_str. + */ + static size_t maxSize(); private: // guarded static unsigned char hexToDec(unsigned char c); diff --git a/test/regress/regress0/strings/Makefile.am b/test/regress/regress0/strings/Makefile.am index 23b13aea2..df4e8b84b 100644 --- a/test/regress/regress0/strings/Makefile.am +++ b/test/regress/regress0/strings/Makefile.am @@ -43,7 +43,8 @@ TESTS = \ issue1189.smt2 \ rewrites-v2.smt2 \ substr-rewrites.smt2 \ - repl-rewrites2.smt2 + repl-rewrites2.smt2 \ + idof-sem.smt2 FAILING_TESTS = diff --git a/test/regress/regress0/strings/idof-sem.smt2 b/test/regress/regress0/strings/idof-sem.smt2 new file mode 100644 index 000000000..90dcc83a0 --- /dev/null +++ b/test/regress/regress0/strings/idof-sem.smt2 @@ -0,0 +1,6 @@ +(set-logic SLIA) +(set-option :strings-exp true) +(set-info :status unsat) +(declare-fun x () String) +(assert (not (= (str.indexof x "" 0) (- 1)))) +(check-sat) \ No newline at end of file -- cgit v1.2.3 From db3d2f7ae12e107f771c5683636febe3e27e8716 Mon Sep 17 00:00:00 2001 From: Aina Niemetz Date: Tue, 27 Feb 2018 19:06:58 -0800 Subject: Remove unused code in pushDefineFunRecScop in smt2.cpp. (#1627) --- src/parser/smt2/smt2.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/parser/smt2/smt2.cpp b/src/parser/smt2/smt2.cpp index 77b50af4c..d55b9f54b 100644 --- a/src/parser/smt2/smt2.cpp +++ b/src/parser/smt2/smt2.cpp @@ -397,15 +397,12 @@ void Smt2::pushDefineFunRecScope( { pushScope(bindingLevel); - std::vector f_app; - f_app.push_back(func); // bound variables are those that are explicitly named in the preamble // of the define-fun(s)-rec command, we define them here for (const std::pair& svn : sortedVarNames) { Expr v = mkBoundVar(svn.first, svn.second); bvs.push_back(v); - f_app.push_back(v); } bvs.insert(bvs.end(), flattenVars.begin(), flattenVars.end()); -- cgit v1.2.3 From d39210bb485c13e7f3290e4e7faab9c5830f437d Mon Sep 17 00:00:00 2001 From: Andrew Reynolds Date: Tue, 27 Feb 2018 22:50:47 -0600 Subject: Minor fixes for rec-fun (#1616) --- src/theory/quantifiers/quantifiers_attributes.cpp | 20 ++++++++- src/theory/quantifiers/quantifiers_rewriter.cpp | 50 +++++++++++++++++----- test/regress/regress1/quantifiers/Makefile.am | 3 +- .../regress1/quantifiers/arith-rec-fun.smt2 | 6 +++ 4 files changed, 65 insertions(+), 14 deletions(-) create mode 100644 test/regress/regress1/quantifiers/arith-rec-fun.smt2 diff --git a/src/theory/quantifiers/quantifiers_attributes.cpp b/src/theory/quantifiers/quantifiers_attributes.cpp index d80a7cf82..25e5bbb5f 100644 --- a/src/theory/quantifiers/quantifiers_attributes.cpp +++ b/src/theory/quantifiers/quantifiers_attributes.cpp @@ -14,12 +14,13 @@ #include "theory/quantifiers/quantifiers_attributes.h" -#include "theory/quantifiers_engine.h" #include "options/quantifiers_options.h" -#include "theory/quantifiers/sygus/ce_guided_instantiation.h" +#include "theory/arith/arith_msum.h" #include "theory/quantifiers/fun_def_engine.h" #include "theory/quantifiers/rewrite_engine.h" +#include "theory/quantifiers/sygus/ce_guided_instantiation.h" #include "theory/quantifiers/term_util.h" +#include "theory/quantifiers_engine.h" using namespace std; using namespace CVC4::kind; @@ -146,6 +147,21 @@ Node QuantAttributes::getFunDefBody( Node q ) { }else if( q[1][1]==h ){ return q[1][0]; } + else if (q[1][0].getType().isReal()) + { + // solve for h in the equality + std::map msum; + if (ArithMSum::getMonomialSum(q[1], msum)) + { + Node veq; + int res = ArithMSum::isolate(h, msum, veq, EQUAL); + if (res != 0) + { + Assert(veq.getKind() == EQUAL); + return res == 1 ? veq[0] : veq[1]; + } + } + } }else{ Node atom = q[1].getKind()==NOT ? q[1][0] : q[1]; bool pol = q[1].getKind()!=NOT; diff --git a/src/theory/quantifiers/quantifiers_rewriter.cpp b/src/theory/quantifiers/quantifiers_rewriter.cpp index 5586c04fb..bc298fa9c 100644 --- a/src/theory/quantifiers/quantifiers_rewriter.cpp +++ b/src/theory/quantifiers/quantifiers_rewriter.cpp @@ -517,14 +517,36 @@ Node QuantifiersRewriter::computeProcessTerms( Node body, std::vector< Node >& n Assert( !h.isNull() ); // if it is a function definition, rewrite the body independently Node fbody = QuantAttributes::getFunDefBody( q ); - Assert( !body.isNull() ); Trace("quantifiers-rewrite-debug") << "Decompose " << h << " / " << fbody << " as function definition for " << q << "." << std::endl; - Node r = computeProcessTerms2( fbody, true, true, curr_cond, 0, cache, icache, new_vars, new_conds, false ); - Assert( new_vars.size()==h.getNumChildren() ); - return Rewriter::rewrite( NodeManager::currentNM()->mkNode( EQUAL, h, r ) ); - }else{ - return computeProcessTerms2( body, true, true, curr_cond, 0, cache, icache, new_vars, new_conds, options::elimExtArithQuant() ); - } + if (!fbody.isNull()) + { + Node r = computeProcessTerms2(fbody, + true, + true, + curr_cond, + 0, + cache, + icache, + new_vars, + new_conds, + false); + Assert(new_vars.size() == h.getNumChildren()); + return Rewriter::rewrite(NodeManager::currentNM()->mkNode(EQUAL, h, r)); + } + // It can happen that we can't infer the shape of the function definition, + // for example: forall xy. f( x, y ) = 1 + f( x, y ), this is rewritten to + // forall xy. false. + } + return computeProcessTerms2(body, + true, + true, + curr_cond, + 0, + cache, + icache, + new_vars, + new_conds, + options::elimExtArithQuant()); } Node QuantifiersRewriter::computeProcessTerms2( Node body, bool hasPol, bool pol, std::map< Node, bool >& currCond, int nCurrCond, @@ -1917,7 +1939,16 @@ Node QuantifiersRewriter::preSkolemizeQuantifiers( Node n, bool polarity, std::v Node nn = preSkolemizeQuantifiers( n[0], !polarity, fvTypes, fvs ); return nn.negate(); }else if( n.getKind()==kind::FORALL ){ - if( polarity ){ + if (n.getNumChildren() == 3) + { + // Do not pre-skolemize quantified formulas with three children. + // This includes non-standard quantified formulas + // like recursive function definitions, or sygus conjectures, and + // quantified formulas with triggers. + return n; + } + else if (polarity) + { if( options::preSkolemQuant() && options::preSkolemQuantNested() ){ vector< Node > children; children.push_back( n[0] ); @@ -1932,9 +1963,6 @@ Node QuantifiersRewriter::preSkolemizeQuantifiers( Node n, bool polarity, std::v } //process body children.push_back( preSkolemizeQuantifiers( n[1], polarity, fvt, fvss ) ); - if( n.getNumChildren()==3 ){ - children.push_back( n[2] ); - } //return processed quantifier return NodeManager::currentNM()->mkNode( kind::FORALL, children ); } diff --git a/test/regress/regress1/quantifiers/Makefile.am b/test/regress/regress1/quantifiers/Makefile.am index 7d3da3654..159f2e088 100644 --- a/test/regress/regress1/quantifiers/Makefile.am +++ b/test/regress/regress1/quantifiers/Makefile.am @@ -79,7 +79,8 @@ TESTS = \ RND-small.smt2 \ RNDPRE_4_1-dd-nqe.smt2 \ set8.smt2 \ - z3.620661-no-fv-trigger.smt2 + z3.620661-no-fv-trigger.smt2 \ + arith-rec-fun.smt2 # removed because they take more than 20s # javafe.ast.ArrayInit.35.smt2 diff --git a/test/regress/regress1/quantifiers/arith-rec-fun.smt2 b/test/regress/regress1/quantifiers/arith-rec-fun.smt2 new file mode 100644 index 000000000..8133db8dd --- /dev/null +++ b/test/regress/regress1/quantifiers/arith-rec-fun.smt2 @@ -0,0 +1,6 @@ +(set-logic UFLIA) +(set-info :status unsat) +(define-fun-rec sumr ((x Int)) Int + (+ x (ite (> x 0) (sumr (- x 1)) 0))) +(assert (= (sumr 2) 2)) +(check-sat) -- cgit v1.2.3 From dfcd935acb928ff27c4b24a89de37338411d2543 Mon Sep 17 00:00:00 2001 From: Aina Niemetz Date: Wed, 28 Feb 2018 12:19:25 -0800 Subject: SmtEngine::getAssignment now returns a vector of assignments. (#1628) --- src/smt/command.cpp | 18 ++++++++++++- src/smt/smt_engine.cpp | 70 ++++++++++++++++++++++++-------------------------- src/smt/smt_engine.h | 2 +- 3 files changed, 51 insertions(+), 39 deletions(-) diff --git a/src/smt/command.cpp b/src/smt/command.cpp index 25479a20b..040d87250 100644 --- a/src/smt/command.cpp +++ b/src/smt/command.cpp @@ -1321,7 +1321,23 @@ void GetAssignmentCommand::invoke(SmtEngine* smtEngine) { try { - d_result = smtEngine->getAssignment(); + std::vector> assignments = smtEngine->getAssignment(); + vector sexprs; + for (const auto& p : assignments) + { + vector v; + if (p.first.getKind() == kind::APPLY) + { + v.emplace_back(SExpr::Keyword(p.first.getOperator().toString())); + } + else + { + v.emplace_back(SExpr::Keyword(p.first.toString())); + } + v.emplace_back(SExpr::Keyword(p.second.toString())); + sexprs.emplace_back(v); + } + d_result = SExpr(sexprs); d_commandStatus = CommandSuccess::instance(); } catch (RecoverableModalException& e) diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp index 8176ba3e9..19236f881 100644 --- a/src/smt/smt_engine.cpp +++ b/src/smt/smt_engine.cpp @@ -5148,7 +5148,8 @@ bool SmtEngine::addToAssignment(const Expr& ex) { } // TODO(#1108): Simplify the error reporting of this method. -CVC4::SExpr SmtEngine::getAssignment() { +vector> SmtEngine::getAssignment() +{ Trace("smt") << "SMT getAssignment()" << endl; SmtScope smts(this); finalOptionsAreSet(); @@ -5170,50 +5171,45 @@ CVC4::SExpr SmtEngine::getAssignment() { throw RecoverableModalException(msg); } - if(d_assignments == NULL) { - return SExpr(vector()); - } - - vector sexprs; - TypeNode boolType = d_nodeManager->booleanType(); - TheoryModel* m = d_theoryEngine->getModel(); - for(AssignmentSet::key_iterator i = d_assignments->key_begin(), - iend = d_assignments->key_end(); - i != iend; - ++i) { - Assert((*i).getType() == boolType); + vector> res; + if (d_assignments != nullptr) + { + TypeNode boolType = d_nodeManager->booleanType(); + TheoryModel* m = d_theoryEngine->getModel(); + for (AssignmentSet::key_iterator i = d_assignments->key_begin(), + iend = d_assignments->key_end(); + i != iend; + ++i) + { + Node as = *i; + Assert(as.getType() == boolType); - Trace("smt") << "--- getting value of " << *i << endl; + Trace("smt") << "--- getting value of " << as << endl; - // Expand, then normalize - unordered_map cache; - Node n = d_private->expandDefinitions(*i, cache); - n = Rewriter::rewrite(n); + // Expand, then normalize + unordered_map cache; + Node n = d_private->expandDefinitions(as, cache); + n = Rewriter::rewrite(n); - Trace("smt") << "--- getting value of " << n << endl; - Node resultNode; - if(m != NULL) { - resultNode = m->getValue(n); - } + Trace("smt") << "--- getting value of " << n << endl; + Node resultNode; + if (m != nullptr) + { + resultNode = m->getValue(n); + } - // type-check the result we got - Assert(resultNode.isNull() || resultNode.getType() == boolType); + // type-check the result we got + Assert(resultNode.isNull() || resultNode.getType() == boolType); - // ensure it's a constant - Assert(resultNode.isConst()); + // ensure it's a constant + Assert(resultNode.isConst()); - vector v; - if((*i).getKind() == kind::APPLY) { - Assert((*i).getNumChildren() == 0); - v.push_back(SExpr(SExpr::Keyword((*i).getOperator().toString()))); - } else { - Assert((*i).isVar()); - v.push_back(SExpr(SExpr::Keyword((*i).toString()))); + Assert(as.getKind() == kind::APPLY || as.isVar()); + Assert(as.getKind() != kind::APPLY || as.getNumChildren() == 0); + res.emplace_back(as.toExpr(), resultNode.toExpr()); } - v.push_back(SExpr(SExpr::Keyword(resultNode.toString()))); - sexprs.push_back(SExpr(v)); } - return SExpr(sexprs); + return res; } void SmtEngine::addToModelCommandAndDump(const Command& c, uint32_t flags, bool userVisible, const char* dumpTag) { diff --git a/src/smt/smt_engine.h b/src/smt/smt_engine.h index e768bf826..c8601a23d 100644 --- a/src/smt/smt_engine.h +++ b/src/smt/smt_engine.h @@ -598,7 +598,7 @@ class CVC4_PUBLIC SmtEngine { * INVALID query). Only permitted if the SmtEngine is set to * operate interactively and produce-assignments is on. */ - CVC4::SExpr getAssignment(); + std::vector > getAssignment(); /** * Get the last proof (only if immediately preceded by an UNSAT -- cgit v1.2.3 From 5eafdb88526da64b60009e30bb45b7e0e47d360b Mon Sep 17 00:00:00 2001 From: Andrew Reynolds Date: Thu, 1 Mar 2018 21:32:11 -0600 Subject: Create infrastructure for sygus modules (#1632) --- src/Makefile.am | 4 + .../quantifiers/sygus/ce_guided_conjecture.cpp | 203 ++++-------- .../quantifiers/sygus/ce_guided_conjecture.h | 71 ++--- .../quantifiers/sygus/ce_guided_instantiation.cpp | 144 +-------- .../quantifiers/sygus/ce_guided_instantiation.h | 3 - src/theory/quantifiers/sygus/cegis.cpp | 354 +++++++++++++++++++++ src/theory/quantifiers/sygus/cegis.h | 121 +++++++ src/theory/quantifiers/sygus/sygus_module.cpp | 28 ++ src/theory/quantifiers/sygus/sygus_module.h | 120 +++++++ src/theory/quantifiers/sygus/sygus_pbe.cpp | 31 +- src/theory/quantifiers/sygus/sygus_pbe.h | 68 ++-- 11 files changed, 755 insertions(+), 392 deletions(-) create mode 100644 src/theory/quantifiers/sygus/cegis.cpp create mode 100644 src/theory/quantifiers/sygus/cegis.h create mode 100644 src/theory/quantifiers/sygus/sygus_module.cpp create mode 100644 src/theory/quantifiers/sygus/sygus_module.h diff --git a/src/Makefile.am b/src/Makefile.am index 8e516a00d..4f5730d63 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -448,6 +448,8 @@ libcvc4_la_SOURCES = \ theory/quantifiers/single_inv_partition.h \ theory/quantifiers/skolemize.cpp \ theory/quantifiers/skolemize.h \ + theory/quantifiers/sygus/cegis.cpp \ + theory/quantifiers/sygus/cegis.h \ theory/quantifiers/sygus/ce_guided_conjecture.cpp \ theory/quantifiers/sygus/ce_guided_conjecture.h \ theory/quantifiers/sygus/ce_guided_instantiation.cpp \ @@ -468,6 +470,8 @@ libcvc4_la_SOURCES = \ theory/quantifiers/sygus/sygus_grammar_norm.h \ theory/quantifiers/sygus/sygus_grammar_red.cpp \ theory/quantifiers/sygus/sygus_grammar_red.h \ + theory/quantifiers/sygus/sygus_module.cpp \ + theory/quantifiers/sygus/sygus_module.h \ theory/quantifiers/sygus/sygus_process_conj.cpp \ theory/quantifiers/sygus/sygus_process_conj.h \ theory/quantifiers/sygus/term_database_sygus.cpp \ diff --git a/src/theory/quantifiers/sygus/ce_guided_conjecture.cpp b/src/theory/quantifiers/sygus/ce_guided_conjecture.cpp index 7bcaa0cba..f2a1c334c 100644 --- a/src/theory/quantifiers/sygus/ce_guided_conjecture.cpp +++ b/src/theory/quantifiers/sygus/ce_guided_conjecture.cpp @@ -51,11 +51,20 @@ void collectDisjuncts( Node n, std::vector< Node >& d ) { CegConjecture::CegConjecture(QuantifiersEngine* qe) : d_qe(qe), d_ceg_si(new CegConjectureSingleInv(qe, this)), - d_ceg_pbe(new CegConjecturePbe(qe, this)), d_ceg_proc(new CegConjectureProcess(qe)), d_ceg_gc(new CegGrammarConstructor(qe, this)), + d_ceg_pbe(new CegConjecturePbe(qe, this)), + d_ceg_cegis(new Cegis(qe, this)), + d_master(nullptr), d_refine_count(0), - d_syntax_guided(false) {} + d_syntax_guided(false) +{ + if (options::sygusPbe()) + { + d_modules.push_back(d_ceg_pbe.get()); + } + d_modules.push_back(d_ceg_cegis.get()); +} CegConjecture::~CegConjecture() {} @@ -113,29 +122,21 @@ void CegConjecture::assign( Node q ) { d_base_inst = Rewriter::rewrite(d_qe->getInstantiate()->getInstantiation( d_embed_quant, vars, d_candidates)); Trace("cegqi") << "Base instantiation is : " << d_base_inst << std::endl; - d_base_body = d_base_inst; - if (d_base_body.getKind() == NOT && d_base_body[0].getKind() == FORALL) - { - for (const Node& v : d_base_body[0][0]) - { - d_base_vars.push_back(v); - } - d_base_body = d_base_body[0][1]; - } // register this term with sygus database and other utilities that impact // the enumerative sygus search std::vector< Node > guarded_lemmas; if( !isSingleInvocation() ){ d_ceg_proc->initialize(d_base_inst, d_candidates); - if( options::sygusPbe() ){ - d_ceg_pbe->initialize(d_base_inst, d_candidates, guarded_lemmas); - } else { - for (unsigned i = 0; i < d_candidates.size(); i++) { - Node e = d_candidates[i]; - d_qe->getTermDatabaseSygus()->registerEnumerator(e, e, this); + for (unsigned i = 0, size = d_modules.size(); i < size; i++) + { + if (d_modules[i]->initialize(d_base_inst, d_candidates, guarded_lemmas)) + { + d_master = d_modules[i]; + break; } } + Assert(d_master != nullptr); } if (d_qe->getQuantAttributes()->isSygus(q)) @@ -193,15 +194,6 @@ void CegConjecture::assign( Node q ) { d_qe->getOutputChannel().lemma( lem ); } - // assign the cegis sampler if applicable - if (options::cegisSample() != CEGIS_SAMPLE_NONE) - { - Trace("cegis-sample") << "Initialize sampler for " << d_base_body << "..." - << std::endl; - TypeNode bt = d_base_body.getType(); - d_cegis_sampler.initialize(bt, d_base_vars, options::sygusSamples()); - } - Trace("cegqi") << "...finished, single invocation = " << isSingleInvocation() << std::endl; } @@ -241,10 +233,8 @@ void CegConjecture::doSingleInvCheck(std::vector< Node >& lems) { void CegConjecture::doBasicCheck(std::vector< Node >& lems) { std::vector< Node > model_terms; - std::vector< Node > clist; - getCandidateList( clist, true ); - Assert( clist.size()==d_quant[0].getNumChildren() ); - getModelValues( clist, model_terms ); + Assert(d_candidates.size() == d_quant[0].getNumChildren()); + getModelValues(d_candidates, model_terms); if (d_qe->getInstantiate()->addInstantiation(d_quant, model_terms)) { //record the instantiation @@ -257,62 +247,57 @@ void CegConjecture::doBasicCheck(std::vector< Node >& lems) { bool CegConjecture::needsRefinement() { return !d_ce_sk.empty(); } +void CegConjecture::doCheck(std::vector& lems) +{ + Assert(d_master != nullptr); -void CegConjecture::getCandidateList( std::vector< Node >& clist, bool forceOrig ) { - if( d_ceg_pbe->isPbe() && !forceOrig ){ - d_ceg_pbe->getCandidateList( d_candidates, clist ); - }else{ - clist.insert( clist.end(), d_candidates.begin(), d_candidates.end() ); - } -} + // get the list of terms that the master strategy is interested in + std::vector terms; + d_master->getTermList(d_candidates, terms); -bool CegConjecture::constructCandidates( std::vector< Node >& clist, std::vector< Node >& model_values, std::vector< Node >& candidate_values, - std::vector< Node >& lems ) { - Assert( clist.size()==model_values.size() ); - if( d_ceg_pbe->isPbe() ){ - return d_ceg_pbe->constructCandidates( clist, model_values, d_candidates, candidate_values, lems ); - }else{ - Assert( model_values.size()==d_candidates.size() ); - candidate_values.insert( candidate_values.end(), model_values.begin(), model_values.end() ); - } - return true; -} + // get their model value + std::vector enum_values; + getModelValues(terms, enum_values); -void CegConjecture::doCheck(std::vector< Node >& lems, std::vector< Node >& model_values) { - std::vector< Node > clist; - getCandidateList( clist ); - std::vector< Node > c_model_values; + std::vector candidate_values; Trace("cegqi-check") << "CegConjuncture : check, build candidates..." << std::endl; - bool constructed_cand = constructCandidates( clist, model_values, c_model_values, lems ); + bool constructed_cand = d_master->constructCandidates( + terms, enum_values, d_candidates, candidate_values, lems); + + NodeManager* nm = NodeManager::currentNM(); //must get a counterexample to the value of the current candidate Node inst; if( constructed_cand ){ if( Trace.isOn("cegqi-check") ){ Trace("cegqi-check") << "CegConjuncture : check candidate : " << std::endl; - for( unsigned i=0; i " << c_model_values[i] << std::endl; + for (unsigned i = 0, size = candidate_values.size(); i < size; i++) + { + Trace("cegqi-check") << " " << i << " : " << d_candidates[i] << " -> " + << candidate_values[i] << std::endl; } } - Assert( c_model_values.size()==d_candidates.size() ); - inst = d_base_inst.substitute( d_candidates.begin(), d_candidates.end(), c_model_values.begin(), c_model_values.end() ); + Assert(candidate_values.size() == d_candidates.size()); + inst = d_base_inst.substitute(d_candidates.begin(), + d_candidates.end(), + candidate_values.begin(), + candidate_values.end()); }else{ inst = d_base_inst; } //check whether we will run CEGIS on inner skolem variables - bool sk_refine = ( !isGround() || d_refine_count==0 ) && ( !d_ceg_pbe->isPbe() || constructed_cand ); + bool sk_refine = (!isGround() || d_refine_count == 0) && constructed_cand; if( sk_refine ){ if (options::cegisSample() == CEGIS_SAMPLE_TRUST) { // we have that the current candidate passed a sample test // since we trust sampling in this mode, we assert there is no // counterexample to the conjecture here. - NodeManager* nm = NodeManager::currentNM(); Node lem = nm->mkNode(OR, d_quant.negate(), nm->mkConst(false)); lem = getStreamGuardedLemma(lem); lems.push_back(lem); - recordInstantiation(c_model_values); + recordInstantiation(candidate_values); return; } Assert( d_ce_sk.empty() ); @@ -352,7 +337,7 @@ void CegConjecture::doCheck(std::vector< Node >& lems, std::vector< Node >& mode } } if( constructed_cand ){ - Node lem = NodeManager::currentNM()->mkNode( OR, ic ); + Node lem = nm->mkNode(OR, ic); lem = Rewriter::rewrite( lem ); //eagerly unfold applications of evaluation function if( options::sygusDirectEval() ){ @@ -362,7 +347,7 @@ void CegConjecture::doCheck(std::vector< Node >& lems, std::vector< Node >& mode } lem = getStreamGuardedLemma(lem); lems.push_back( lem ); - recordInstantiation( c_model_values ); + recordInstantiation(candidate_values); } } @@ -433,7 +418,7 @@ void CegConjecture::doRefine( std::vector< Node >& lems ){ base_lem = base_lem.substitute( sk_vars.begin(), sk_vars.end(), sk_subs.begin(), sk_subs.end() ); base_lem = Rewriter::rewrite( base_lem ); - d_refinement_lemmas.push_back(base_lem); + d_master->registerRefinementLemma(base_lem); Node lem = NodeManager::currentNM()->mkNode(OR, getGuard().negate(), base_lem); @@ -533,6 +518,7 @@ Node CegConjecture::getNextDecisionRequest( unsigned& priority ) { return curr_stream_guard; }else{ if( !value ){ + Assert(d_master != nullptr); Trace("cegqi-debug") << "getNextDecision : we have a new solution since stream guard was propagated false: " << curr_stream_guard << std::endl; // we have generated a solution, print it // get the current output stream @@ -545,14 +531,15 @@ Node CegConjecture::getNextDecisionRequest( unsigned& priority ) { // We will not refine the current candidate solution since it is a solution // thus, we clear information regarding the current refinement d_ce_sk.clear(); - // However, we need to exclude the current solution using an explicit refinement - // so that we proceed to the next solution. - std::vector< Node > clist; - getCandidateList( clist ); + // However, we need to exclude the current solution using an + // explicit refinement + // so that we proceed to the next solution. + std::vector terms; + d_master->getTermList(d_candidates, terms); Trace("cegqi-debug") << "getNextDecision : solution was : " << std::endl; std::vector< Node > exp; - for( unsigned i=0; i& vals, - std::vector& lems) -{ - if (Trace.isOn("cegis-sample")) - { - Trace("cegis-sample") << "Check sampling for candidate solution" - << std::endl; - for (unsigned i = 0, size = vals.size(); i < size; i++) - { - Trace("cegis-sample") - << " " << d_candidates[i] << " -> " << vals[i] << std::endl; - } - } - Assert(vals.size() == d_candidates.size()); - Node sbody = d_base_body.substitute( - d_candidates.begin(), d_candidates.end(), vals.begin(), vals.end()); - Trace("cegis-sample-debug") << "Sample " << sbody << std::endl; - // do eager unfolding - std::map visited_n; - sbody = d_qe->getTermDatabaseSygus()->getEagerUnfold(sbody, visited_n); - Trace("cegis-sample") << "Sample (after unfolding): " << sbody << std::endl; - - NodeManager* nm = NodeManager::currentNM(); - for (unsigned i = 0, size = d_cegis_sampler.getNumSamplePoints(); i < size; - i++) - { - if (d_cegis_sample_refine.find(i) == d_cegis_sample_refine.end()) - { - Node ev = d_cegis_sampler.evaluate(sbody, i); - Trace("cegis-sample-debug") - << "...evaluate point #" << i << " to " << ev << std::endl; - Assert(ev.isConst()); - Assert(ev.getType().isBoolean()); - if (!ev.getConst()) - { - Trace("cegis-sample-debug") << "...false for point #" << i << std::endl; - // mark this as a CEGIS point (no longer sampled) - d_cegis_sample_refine.insert(i); - std::vector vars; - std::vector pt; - d_cegis_sampler.getSamplePoint(i, vars, pt); - Assert(d_base_vars.size() == pt.size()); - Node rlem = d_base_body.substitute( - d_base_vars.begin(), d_base_vars.end(), pt.begin(), pt.end()); - rlem = Rewriter::rewrite(rlem); - if (std::find( - d_refinement_lemmas.begin(), d_refinement_lemmas.end(), rlem) - == d_refinement_lemmas.end()) - { - if (Trace.isOn("cegis-sample")) - { - Trace("cegis-sample") << " false for point #" << i << " : "; - for (const Node& cn : pt) - { - Trace("cegis-sample") << cn << " "; - } - Trace("cegis-sample") << std::endl; - } - Trace("cegqi-engine") << " *** Refine by sampling" << std::endl; - d_refinement_lemmas.push_back(rlem); - // if trust, we are not interested in sending out refinement lemmas - if (options::cegisSample() != CEGIS_SAMPLE_TRUST) - { - Node lem = nm->mkNode(OR, getGuard().negate(), rlem); - lems.push_back(lem); - } - return true; - } - else - { - Trace("cegis-sample-debug") << "...duplicate." << std::endl; - } - } - } - } - return false; -} - }/* namespace CVC4::theory::quantifiers */ }/* namespace CVC4::theory */ }/* namespace CVC4 */ diff --git a/src/theory/quantifiers/sygus/ce_guided_conjecture.h b/src/theory/quantifiers/sygus/ce_guided_conjecture.h index 1ef8fef10..9f3335ee2 100644 --- a/src/theory/quantifiers/sygus/ce_guided_conjecture.h +++ b/src/theory/quantifiers/sygus/ce_guided_conjecture.h @@ -20,9 +20,10 @@ #include -#include "theory/quantifiers/sygus/sygus_pbe.h" #include "theory/quantifiers/sygus/ce_guided_single_inv.h" +#include "theory/quantifiers/sygus/cegis.h" #include "theory/quantifiers/sygus/sygus_grammar_cons.h" +#include "theory/quantifiers/sygus/sygus_pbe.h" #include "theory/quantifiers/sygus/sygus_process_conj.h" #include "theory/quantifiers/sygus_sampler.h" #include "theory/quantifiers_engine.h" @@ -57,8 +58,6 @@ public: bool needsCheck( std::vector< Node >& lem ); /** whether the conjecture is waiting for a call to doRefine below */ bool needsRefinement(); - /** get the list of candidates */ - void getCandidateList( std::vector< Node >& clist, bool forceOrig = false ); /** do single invocation check * This updates Gamma for an iteration of step 2 of Figure 1 of Reynolds et al CAV 2015. */ @@ -66,7 +65,7 @@ public: /** do syntax-guided enumerative check * This is step 2(a) of Figure 3 of Reynolds et al CAV 2015. */ - void doCheck(std::vector< Node >& lems, std::vector< Node >& model_values); + void doCheck(std::vector& lems); /** do basic check * This is called for non-SyGuS synthesis conjectures */ @@ -118,26 +117,6 @@ public: /** get model value for term n */ Node getModelValue( Node n ); - //-----------------------------------refinement lemmas - /** get number of refinement lemmas we have added so far */ - unsigned getNumRefinementLemmas() { return d_refinement_lemmas.size(); } - /** get refinement lemma - * - * If d_embed_quant is forall d. exists y. P( d, y ), then a refinement - * lemma is one of the form ~P( d_candidates, c ) for some c. - */ - Node getRefinementLemma( unsigned i ) { return d_refinement_lemmas[i]; } - /** sample add refinement lemma - * - * This function will check if there is a sample point in d_sampler that - * refutes the candidate solution (d_quant_vars->vals). If so, it adds a - * refinement lemma to the lists d_refinement_lemmas that corresponds to that - * sample point, and adds a lemma to lems if cegisSample mode is not trust. - */ - bool sampleAddRefinementLemma(std::vector& vals, - std::vector& lems); - //-----------------------------------end refinement lemmas - /** get program by examples utility */ CegConjecturePbe* getPbe() { return d_ceg_pbe.get(); } /** get utility for static preprocessing and analysis of conjectures */ @@ -152,12 +131,26 @@ private: QuantifiersEngine * d_qe; /** single invocation utility */ std::unique_ptr d_ceg_si; - /** program by examples utility */ - std::unique_ptr d_ceg_pbe; /** utility for static preprocessing and analysis of conjectures */ std::unique_ptr d_ceg_proc; /** grammar utility */ std::unique_ptr d_ceg_gc; + + //------------------------modules + /** program by examples module */ + std::unique_ptr d_ceg_pbe; + /** CEGIS module */ + std::unique_ptr d_ceg_cegis; + /** the set of active modules (subset of the above list) */ + std::vector d_modules; + /** master module + * + * This is the module (one of those above) that takes sole responsibility + * for this conjecture, determined during assign(...). + */ + SygusModule* d_master; + //------------------------end modules + /** list of constants for quantified formula * The outer Skolems for the negation of d_embed_quant. */ @@ -167,13 +160,6 @@ private: * this is the formula exists y. P( d_candidates, y ). */ Node d_base_inst; - /** If d_base_inst is exists y. P( d, y ), then this is y. */ - std::vector d_base_vars; - /** - * If d_base_inst is exists y. P( d, y ), then this is the formula - * P( d_candidates, y ). - */ - Node d_base_body; /** expand base inst to disjuncts */ std::vector< Node > d_base_disj; /** list of variables on inner quantification */ @@ -182,10 +168,6 @@ private: /** current extential quantifeirs whose couterexamples we must refine */ std::vector< std::vector< Node > > d_ce_sk; - //-----------------------------------refinement lemmas - /** refinement lemmas */ - std::vector< Node > d_refinement_lemmas; - //-----------------------------------end refinement lemmas /** the asserted (negated) conjecture */ Node d_quant; @@ -203,9 +185,6 @@ private: std::map< Node, CandidateInfo > d_cinfo; /** number of times we have called doRefine */ unsigned d_refine_count; - /** construct candidates */ - bool constructCandidates( std::vector< Node >& clist, std::vector< Node >& model_values, - std::vector< Node >& candidate_values, std::vector< Node >& lems ); /** get candidadate */ Node getCandidate( unsigned int i ) { return d_candidates[i]; } /** record instantiation (this is used to construct solutions later) */ @@ -262,18 +241,6 @@ private: * rewrite rules. */ std::map d_sampler; - /** sampler object for the option cegisSample() - * - * This samples points of the type of the inner variables of the synthesis - * conjecture (d_base_vars). - */ - SygusSampler d_cegis_sampler; - /** cegis sample refine points - * - * Stores the list of indices of sample points in d_cegis_sampler we have - * added as refinement lemmas. - */ - std::unordered_set d_cegis_sample_refine; }; } /* namespace CVC4::theory::quantifiers */ diff --git a/src/theory/quantifiers/sygus/ce_guided_instantiation.cpp b/src/theory/quantifiers/sygus/ce_guided_instantiation.cpp index 35098f5ea..125682e8c 100644 --- a/src/theory/quantifiers/sygus/ce_guided_instantiation.cpp +++ b/src/theory/quantifiers/sygus/ce_guided_instantiation.cpp @@ -21,8 +21,6 @@ #include "theory/quantifiers/quantifiers_attributes.h" #include "theory/quantifiers/sygus/term_database_sygus.h" #include "theory/quantifiers/term_util.h" -//FIXME : remove this include (github issue #1156) -#include "theory/bv/theory_bv_rewriter.h" using namespace CVC4::kind; using namespace std; @@ -125,61 +123,10 @@ void CegInstantiation::checkCegConjecture( CegConjecture * conj ) { Trace("cegqi-engine") << " ...try single invocation." << std::endl; return; } - //ignore return value here - std::vector< Node > clist; - conj->getCandidateList( clist ); - std::vector< Node > model_values; - conj->getModelValues( clist, model_values ); - if( options::sygusDirectEval() ){ - bool addedEvalLemmas = false; - if( options::sygusCRefEval() ){ - Trace("cegqi-engine") << " *** Do conjecture refinement evaluation..." << std::endl; - // see if any refinement lemma is refuted by evaluation - std::vector< Node > cre_lems; - getCRefEvaluationLemmas( conj, clist, model_values, cre_lems ); - if( !cre_lems.empty() ){ - for( unsigned j=0; jaddLemma( lem ) ){ - Trace("cegqi-lemma") << "Cegqi::Lemma : cref evaluation : " << lem << std::endl; - addedEvalLemmas = true; - } - } - if( addedEvalLemmas ){ - //return; - } - } - } - Trace("cegqi-engine") << " *** Do direct evaluation..." << std::endl; - std::vector< Node > eager_terms; - std::vector< Node > eager_vals; - std::vector< Node > eager_exps; - for( unsigned j=0; j " << model_values[j] << std::endl; - d_quantEngine->getTermDatabaseSygus()->registerModelValue( clist[j], model_values[j], eager_terms, eager_vals, eager_exps ); - } - Trace("cegqi-debug") << "...produced " << eager_terms.size() << " eager evaluation lemmas." << std::endl; - if( !eager_terms.empty() ){ - for( unsigned j=0; jmkNode( kind::OR, eager_exps[j].negate(), eager_terms[j].eqNode( eager_vals[j] ) ); - if( d_quantEngine->getTheoryEngine()->isTheoryEnabled(THEORY_BV) ){ - //FIXME: hack to incorporate hacks from BV for division by zero (github issue #1156) - lem = bv::TheoryBVRewriter::eliminateBVSDiv( lem ); - } - if( d_quantEngine->addLemma( lem ) ){ - Trace("cegqi-lemma") << "Cegqi::Lemma : evaluation : " << lem << std::endl; - addedEvalLemmas = true; - } - } - } - if( addedEvalLemmas ){ - return; - } - } Trace("cegqi-engine") << " *** Check candidate phase..." << std::endl; std::vector< Node > cclems; - conj->doCheck( cclems, model_values ); + conj->doCheck(cclems); bool addedLemma = false; for( unsigned i=0; i& vs, std::vector< Node >& ms, std::vector< Node >& lems ) { - Trace("sygus-cref-eval") << "Cref eval : conjecture has " << conj->getNumRefinementLemmas() << " refinement lemmas." << std::endl; - unsigned nlemmas = conj->getNumRefinementLemmas(); - if (nlemmas > 0 || options::cegisSample() != CEGIS_SAMPLE_NONE) - { - Assert( vs.size()==ms.size() ); - - TermDbSygus* tds = d_quantEngine->getTermDatabaseSygus(); - Node nfalse = d_quantEngine->getTermUtil()->d_false; - Node neg_guard = conj->getGuard().negate(); - for (unsigned i = 0; i <= nlemmas; i++) - { - if (i == nlemmas) - { - bool addedSample = false; - // find a new one by sampling, if applicable - if (options::cegisSample() != CEGIS_SAMPLE_NONE) - { - addedSample = conj->sampleAddRefinementLemma(ms, lems); - } - if (!addedSample) - { - return; - } - } - Node lem; - std::map< Node, Node > visited; - std::map< Node, std::vector< Node > > exp; - lem = conj->getRefinementLemma(i); - if( !lem.isNull() ){ - std::vector< Node > lem_conj; - //break into conjunctions - if( lem.getKind()==kind::AND ){ - for( unsigned i=0; igetTermUtil()->d_false ){ - std::vector< Node > msu; - std::vector< Node > mexp; - msu.insert( msu.end(), ms.begin(), ms.end() ); - for( unsigned k=0; kisAssigned() ) { diff --git a/src/theory/quantifiers/sygus/ce_guided_instantiation.h b/src/theory/quantifiers/sygus/ce_guided_instantiation.h index 087836d5a..1b1d5e44b 100644 --- a/src/theory/quantifiers/sygus/ce_guided_instantiation.h +++ b/src/theory/quantifiers/sygus/ce_guided_instantiation.h @@ -33,9 +33,6 @@ private: CegConjecture * d_conj; /** last instantiation by single invocation module? */ bool d_last_inst_si; -private: //for direct evaluation - /** get refinement evaluation */ - void getCRefEvaluationLemmas( CegConjecture * conj, std::vector< Node >& vs, std::vector< Node >& ms, std::vector< Node >& lems ); private: /** check conjecture */ void checkCegConjecture( CegConjecture * conj ); diff --git a/src/theory/quantifiers/sygus/cegis.cpp b/src/theory/quantifiers/sygus/cegis.cpp new file mode 100644 index 000000000..a571c85fb --- /dev/null +++ b/src/theory/quantifiers/sygus/cegis.cpp @@ -0,0 +1,354 @@ +/********************* */ +/*! \file cegis.cpp + ** \verbatim + ** Top contributors (to current version): + ** Andrew Reynolds + ** This file is part of the CVC4 project. + ** Copyright (c) 2009-2017 by the authors listed in the file AUTHORS + ** in the top-level source directory) and their institutional affiliations. + ** All rights reserved. See the file COPYING in the top-level source + ** directory for licensing information.\endverbatim + ** + ** \brief Implementation of cegis + **/ + +#include "theory/quantifiers/sygus/cegis.h" +#include "options/quantifiers_options.h" +#include "theory/quantifiers/sygus/ce_guided_conjecture.h" +#include "theory/quantifiers/sygus/term_database_sygus.h" +// FIXME : remove these includes (github issue #1156) +#include "theory/bv/theory_bv_rewriter.h" +#include "theory/theory_engine.h" + +using namespace std; +using namespace CVC4::kind; +using namespace CVC4::context; + +namespace CVC4 { +namespace theory { +namespace quantifiers { + +Cegis::Cegis(QuantifiersEngine* qe, CegConjecture* p) : SygusModule(qe, p) {} +bool Cegis::initialize(Node n, + const std::vector& candidates, + std::vector& lemmas) +{ + d_base_body = n; + if (d_base_body.getKind() == NOT && d_base_body[0].getKind() == FORALL) + { + for (const Node& v : d_base_body[0][0]) + { + d_base_vars.push_back(v); + } + d_base_body = d_base_body[0][1]; + } + + // assign the cegis sampler if applicable + if (options::cegisSample() != CEGIS_SAMPLE_NONE) + { + Trace("cegis-sample") << "Initialize sampler for " << d_base_body << "..." + << std::endl; + TypeNode bt = d_base_body.getType(); + d_cegis_sampler.initialize(bt, d_base_vars, options::sygusSamples()); + } + + // initialize an enumerator for each candidate + TermDbSygus* tds = d_qe->getTermDatabaseSygus(); + for (unsigned i = 0; i < candidates.size(); i++) + { + tds->registerEnumerator(candidates[i], candidates[i], d_parent); + } + return true; +} + +void Cegis::getTermList(const std::vector& candidates, + std::vector& enums) +{ + enums.insert(enums.end(), candidates.begin(), candidates.end()); +} + +/** construct candidate */ +bool Cegis::constructCandidates(const std::vector& enums, + const std::vector& enum_values, + const std::vector& candidates, + std::vector& candidate_values, + std::vector& lems) +{ + candidate_values.insert( + candidate_values.end(), enum_values.begin(), enum_values.end()); + + if (options::sygusDirectEval()) + { + NodeManager* nm = NodeManager::currentNM(); + bool addedEvalLemmas = false; + if (options::sygusCRefEval()) + { + Trace("cegqi-engine") << " *** Do conjecture refinement evaluation..." + << std::endl; + // see if any refinement lemma is refuted by evaluation + std::vector cre_lems; + getRefinementEvalLemmas(candidates, candidate_values, cre_lems); + if (!cre_lems.empty()) + { + for (unsigned j = 0; j < cre_lems.size(); j++) + { + Node lem = cre_lems[j]; + if (d_qe->addLemma(lem)) + { + Trace("cegqi-lemma") << "Cegqi::Lemma : cref evaluation : " << lem + << std::endl; + addedEvalLemmas = true; + } + } + // we could, but do not return here. + // experimentally, it is better to add the lemmas below as well, + // in parallel. + } + } + Trace("cegqi-engine") << " *** Do direct evaluation..." << std::endl; + std::vector eager_terms; + std::vector eager_vals; + std::vector eager_exps; + TermDbSygus* tds = d_qe->getTermDatabaseSygus(); + for (unsigned j = 0, size = candidates.size(); j < size; j++) + { + Trace("cegqi-debug") << " register " << candidates[j] << " -> " + << candidate_values[j] << std::endl; + tds->registerModelValue(candidates[j], + candidate_values[j], + eager_terms, + eager_vals, + eager_exps); + } + Trace("cegqi-debug") << "...produced " << eager_terms.size() + << " eager evaluation lemmas." << std::endl; + + for (unsigned j = 0, size = eager_terms.size(); j < size; j++) + { + Node lem = nm->mkNode(kind::OR, + eager_exps[j].negate(), + eager_terms[j].eqNode(eager_vals[j])); + if (d_qe->getTheoryEngine()->isTheoryEnabled(THEORY_BV)) + { + // FIXME: hack to incorporate hacks from BV for division by zero + // (github issue #1156) + lem = bv::TheoryBVRewriter::eliminateBVSDiv(lem); + } + if (d_qe->addLemma(lem)) + { + Trace("cegqi-lemma") << "Cegqi::Lemma : evaluation : " << lem + << std::endl; + addedEvalLemmas = true; + } + } + if (addedEvalLemmas) + { + return false; + } + } + + return true; +} + +void Cegis::registerRefinementLemma(Node lem) +{ + d_refinement_lemmas.push_back(lem); +} + +void Cegis::getRefinementEvalLemmas(const std::vector& vs, + const std::vector& ms, + std::vector& lems) +{ + Trace("sygus-cref-eval") << "Cref eval : conjecture has " + << getNumRefinementLemmas() << " refinement lemmas." + << std::endl; + unsigned nlemmas = getNumRefinementLemmas(); + if (nlemmas > 0 || options::cegisSample() != CEGIS_SAMPLE_NONE) + { + Assert(vs.size() == ms.size()); + + TermDbSygus* tds = d_qe->getTermDatabaseSygus(); + NodeManager* nm = NodeManager::currentNM(); + + Node nfalse = nm->mkConst(false); + Node neg_guard = d_parent->getGuard().negate(); + for (unsigned i = 0; i <= nlemmas; i++) + { + if (i == nlemmas) + { + bool addedSample = false; + // find a new one by sampling, if applicable + if (options::cegisSample() != CEGIS_SAMPLE_NONE) + { + addedSample = sampleAddRefinementLemma(vs, ms, lems); + } + if (!addedSample) + { + return; + } + } + Node lem; + std::map visited; + std::map > exp; + lem = getRefinementLemma(i); + if (!lem.isNull()) + { + std::vector lem_conj; + // break into conjunctions + if (lem.getKind() == kind::AND) + { + for (unsigned i = 0; i < lem.getNumChildren(); i++) + { + lem_conj.push_back(lem[i]); + } + } + else + { + lem_conj.push_back(lem); + } + EvalSygusInvarianceTest vsit; + for (unsigned j = 0; j < lem_conj.size(); j++) + { + Node lemc = lem_conj[j]; + Trace("sygus-cref-eval") << "Check refinement lemma conjunct " << lemc + << " against current model." << std::endl; + Trace("sygus-cref-eval2") << "Check refinement lemma conjunct " + << lemc << " against current model." + << std::endl; + Node cre_lem; + Node lemcs = + lemc.substitute(vs.begin(), vs.end(), ms.begin(), ms.end()); + Trace("sygus-cref-eval2") << "...under substitution it is : " << lemcs + << std::endl; + Node lemcsu = vsit.doEvaluateWithUnfolding(tds, lemcs); + Trace("sygus-cref-eval2") << "...after unfolding is : " << lemcsu + << std::endl; + if (lemcsu.isConst() && !lemcsu.getConst()) + { + std::vector msu; + std::vector mexp; + msu.insert(msu.end(), ms.begin(), ms.end()); + for (unsigned k = 0; k < vs.size(); k++) + { + vsit.setUpdatedTerm(msu[k]); + msu[k] = vs[k]; + // substitute for everything except this + Node sconj = + lemc.substitute(vs.begin(), vs.end(), msu.begin(), msu.end()); + vsit.init(sconj, vs[k], nfalse); + // get minimal explanation for this + Node ut = vsit.getUpdatedTerm(); + Trace("sygus-cref-eval2-debug") + << " compute min explain of : " << vs[k] << " = " << ut + << std::endl; + tds->getExplain()->getExplanationFor(vs[k], ut, mexp, vsit); + msu[k] = ut; + } + if (!mexp.empty()) + { + Node en = + mexp.size() == 1 ? mexp[0] : nm->mkNode(kind::AND, mexp); + cre_lem = nm->mkNode(kind::OR, en.negate(), neg_guard); + } + else + { + cre_lem = neg_guard; + } + } + if (!cre_lem.isNull()) + { + if (std::find(lems.begin(), lems.end(), cre_lem) == lems.end()) + { + Trace("sygus-cref-eval") << "...produced lemma : " << cre_lem + << std::endl; + lems.push_back(cre_lem); + } + } + } + } + } + } +} + +bool Cegis::sampleAddRefinementLemma(const std::vector& candidates, + const std::vector& vals, + std::vector& lems) +{ + if (Trace.isOn("cegis-sample")) + { + Trace("cegis-sample") << "Check sampling for candidate solution" + << std::endl; + for (unsigned i = 0, size = vals.size(); i < size; i++) + { + Trace("cegis-sample") << " " << candidates[i] << " -> " << vals[i] + << std::endl; + } + } + Assert(vals.size() == candidates.size()); + Node sbody = d_base_body.substitute( + candidates.begin(), candidates.end(), vals.begin(), vals.end()); + Trace("cegis-sample-debug") << "Sample " << sbody << std::endl; + // do eager unfolding + std::map visited_n; + sbody = d_qe->getTermDatabaseSygus()->getEagerUnfold(sbody, visited_n); + Trace("cegis-sample") << "Sample (after unfolding): " << sbody << std::endl; + + NodeManager* nm = NodeManager::currentNM(); + for (unsigned i = 0, size = d_cegis_sampler.getNumSamplePoints(); i < size; + i++) + { + if (d_cegis_sample_refine.find(i) == d_cegis_sample_refine.end()) + { + Node ev = d_cegis_sampler.evaluate(sbody, i); + Trace("cegis-sample-debug") << "...evaluate point #" << i << " to " << ev + << std::endl; + Assert(ev.isConst()); + Assert(ev.getType().isBoolean()); + if (!ev.getConst()) + { + Trace("cegis-sample-debug") << "...false for point #" << i << std::endl; + // mark this as a CEGIS point (no longer sampled) + d_cegis_sample_refine.insert(i); + std::vector vars; + std::vector pt; + d_cegis_sampler.getSamplePoint(i, vars, pt); + Assert(d_base_vars.size() == pt.size()); + Node rlem = d_base_body.substitute( + d_base_vars.begin(), d_base_vars.end(), pt.begin(), pt.end()); + rlem = Rewriter::rewrite(rlem); + if (std::find( + d_refinement_lemmas.begin(), d_refinement_lemmas.end(), rlem) + == d_refinement_lemmas.end()) + { + if (Trace.isOn("cegis-sample")) + { + Trace("cegis-sample") << " false for point #" << i << " : "; + for (const Node& cn : pt) + { + Trace("cegis-sample") << cn << " "; + } + Trace("cegis-sample") << std::endl; + } + Trace("cegqi-engine") << " *** Refine by sampling" << std::endl; + d_refinement_lemmas.push_back(rlem); + // if trust, we are not interested in sending out refinement lemmas + if (options::cegisSample() != CEGIS_SAMPLE_TRUST) + { + Node lem = nm->mkNode(OR, d_parent->getGuard().negate(), rlem); + lems.push_back(lem); + } + return true; + } + else + { + Trace("cegis-sample-debug") << "...duplicate." << std::endl; + } + } + } + } + return false; +} + +} /* CVC4::theory::quantifiers namespace */ +} /* CVC4::theory namespace */ +} /* CVC4 namespace */ diff --git a/src/theory/quantifiers/sygus/cegis.h b/src/theory/quantifiers/sygus/cegis.h new file mode 100644 index 000000000..2cb668fa1 --- /dev/null +++ b/src/theory/quantifiers/sygus/cegis.h @@ -0,0 +1,121 @@ +/********************* */ +/*! \file cegis.h + ** \verbatim + ** Top contributors (to current version): + ** Andrew Reynolds + ** This file is part of the CVC4 project. + ** Copyright (c) 2009-2017 by the authors listed in the file AUTHORS + ** in the top-level source directory) and their institutional affiliations. + ** All rights reserved. See the file COPYING in the top-level source + ** directory for licensing information.\endverbatim + ** + ** \brief cegis + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__THEORY__QUANTIFIERS__CEGIS_H +#define __CVC4__THEORY__QUANTIFIERS__CEGIS_H + +#include +#include "theory/quantifiers/sygus/sygus_module.h" +#include "theory/quantifiers/sygus_sampler.h" + +namespace CVC4 { +namespace theory { +namespace quantifiers { + +/** Cegis + * + * The default sygus module for synthesis, counterexample-guided inductive + * synthesis (CEGIS). + * + * It initializes a list of sygus enumerators that are one-to-one with + * candidates, and returns a list of candidates that are the model values + * of these enumerators on calls to constructCandidates. + * + * It implements an optimization (getRefinementEvalLemmas) that evaluates all + * previous refinement lemmas for a term before returning it as a candidate + * in calls to constructCandidates. + */ +class Cegis : public SygusModule +{ + public: + Cegis(QuantifiersEngine* qe, CegConjecture* p); + ~Cegis() {} + /** initialize */ + virtual bool initialize(Node n, + const std::vector& candidates, + std::vector& lemmas) override; + /** get term list */ + virtual void getTermList(const std::vector& candidates, + std::vector& enums) override; + /** construct candidate */ + virtual bool constructCandidates(const std::vector& enums, + const std::vector& enum_values, + const std::vector& candidates, + std::vector& candidate_values, + std::vector& lems) override; + /** register refinement lemma */ + virtual void registerRefinementLemma(Node lem) override; + + private: + /** If CegConjecture::d_base_inst is exists y. P( d, y ), then this is y. */ + std::vector d_base_vars; + /** + * If CegConjecture::d_base_inst is exists y. P( d, y ), then this is the + * formula P( CegConjecture::d_candidates, y ). + */ + Node d_base_body; + + //-----------------------------------refinement lemmas + /** refinement lemmas */ + std::vector d_refinement_lemmas; + /** get number of refinement lemmas we have added so far */ + unsigned getNumRefinementLemmas() { return d_refinement_lemmas.size(); } + /** get refinement lemma + * + * If d_embed_quant is forall d. exists y. P( d, y ), then a refinement + * lemma is one of the form ~P( d_candidates, c ) for some c. + */ + Node getRefinementLemma(unsigned i) { return d_refinement_lemmas[i]; } + /** sample add refinement lemma + * + * This function will check if there is a sample point in d_sampler that + * refutes the candidate solution (d_quant_vars->vals). If so, it adds a + * refinement lemma to the lists d_refinement_lemmas that corresponds to that + * sample point, and adds a lemma to lems if cegisSample mode is not trust. + */ + bool sampleAddRefinementLemma(const std::vector& candidates, + const std::vector& vals, + std::vector& lems); + //-----------------------------------end refinement lemmas + + /** Get refinement evaluation lemmas + * + * Given a candidate solution ms for candidates vs, this function adds lemmas + * to lems based on evaluating the conjecture, instantiated for ms, on lemmas + * for previous refinements (d_refinement_lemmas). + */ + void getRefinementEvalLemmas(const std::vector& vs, + const std::vector& ms, + std::vector& lems); + /** sampler object for the option cegisSample() + * + * This samples points of the type of the inner variables of the synthesis + * conjecture (d_base_vars). + */ + SygusSampler d_cegis_sampler; + /** cegis sample refine points + * + * Stores the list of indices of sample points in d_cegis_sampler we have + * added as refinement lemmas. + */ + std::unordered_set d_cegis_sample_refine; +}; + +} /* CVC4::theory::quantifiers namespace */ +} /* CVC4::theory namespace */ +} /* CVC4 namespace */ + +#endif /* __CVC4__THEORY__QUANTIFIERS__CEGIS_H */ diff --git a/src/theory/quantifiers/sygus/sygus_module.cpp b/src/theory/quantifiers/sygus/sygus_module.cpp new file mode 100644 index 000000000..19e064350 --- /dev/null +++ b/src/theory/quantifiers/sygus/sygus_module.cpp @@ -0,0 +1,28 @@ +/********************* */ +/*! \file sygus_module.cpp + ** \verbatim + ** Top contributors (to current version): + ** Andrew Reynolds + ** This file is part of the CVC4 project. + ** Copyright (c) 2009-2017 by the authors listed in the file AUTHORS + ** in the top-level source directory) and their institutional affiliations. + ** All rights reserved. See the file COPYING in the top-level source + ** directory for licensing information.\endverbatim + ** + ** \brief Implementation of sygus_module + **/ + +#include "theory/quantifiers/sygus/sygus_module.h" + +namespace CVC4 { +namespace theory { +namespace quantifiers { + +SygusModule::SygusModule(QuantifiersEngine* qe, CegConjecture* p) + : d_qe(qe), d_parent(p) +{ +} + +} /* CVC4::theory::quantifiers namespace */ +} /* CVC4::theory namespace */ +} /* CVC4 namespace */ diff --git a/src/theory/quantifiers/sygus/sygus_module.h b/src/theory/quantifiers/sygus/sygus_module.h new file mode 100644 index 000000000..230ea7a61 --- /dev/null +++ b/src/theory/quantifiers/sygus/sygus_module.h @@ -0,0 +1,120 @@ +/********************* */ +/*! \file sygus_module.h + ** \verbatim + ** Top contributors (to current version): + ** Andrew Reynolds + ** This file is part of the CVC4 project. + ** Copyright (c) 2009-2017 by the authors listed in the file AUTHORS + ** in the top-level source directory) and their institutional affiliations. + ** All rights reserved. See the file COPYING in the top-level source + ** directory for licensing information.\endverbatim + ** + ** \brief sygus_module + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__THEORY__QUANTIFIERS__SYGUS_MODULE_H +#define __CVC4__THEORY__QUANTIFIERS__SYGUS_MODULE_H + +#include +#include "expr/node.h" +#include "theory/quantifiers_engine.h" + +namespace CVC4 { +namespace theory { +namespace quantifiers { + +class CegConjecture; + +/** SygusModule + * + * This is the base class of sygus modules, owned by CegConjecture. The purpose + * of this class is to, when applicable, suggest candidate solutions for + * CegConjecture to test. + * + * In more detail, an instance of the conjecture class (CegConjecture) creates + * the negated deep embedding form of the synthesis conjecture. In the + * following, assume this is: + * forall d. exists x. P( d, x ) + * where d are of sygus datatype type. The "base instantiation" of this + * conjecture (see CegConjecture::d_base_inst) is the formula: + * exists y. P( k, y ) + * where k are the "candidate" variables for the conjecture. + * + * Modules implement an initialize function, which determines whether the module + * will take responsibility for the given conjecture. + */ +class SygusModule +{ + public: + SygusModule(QuantifiersEngine* qe, CegConjecture* p); + ~SygusModule() {} + /** initialize + * + * n is the "base instantiation" of the deep-embedding version of the + * synthesis conjecture under candidates (see CegConjecture::d_base_inst). + * + * This function may add lemmas to the argument lemmas, which should be + * sent out on the output channel of quantifiers by the caller. + * + * This function returns true if this module will take responsibility for + * constructing candidates for the given conjecture. + */ + virtual bool initialize(Node n, + const std::vector& candidates, + std::vector& lemmas) = 0; + /** get term list + * + * This gets the list of terms that will appear as arguments to a subsequent + * call to constructCandidates. + */ + virtual void getTermList(const std::vector& candidates, + std::vector& terms) = 0; + /** construct candidate + * + * This function takes as input: + * terms : the terms returned by a call to getTermList, + * term_values : the current model values of terms, + * candidates : the list of candidates. + * + * If this function returns true, it adds to candidate_values a list of terms + * of the same length and type as candidates that are candidate solutions + * to the synthesis conjecture in question. This candidate { v } will then be + * tested by testing the (un)satisfiablity of P( v, k' ) for fresh k' by the + * caller. + * + * This function may also add lemmas to lems, which are sent out as lemmas + * on the output channel of quantifiers by the caller. For an example of + * such lemmas, see SygusPbe::constructCandidates. + * + * This function may return false if it does not have a candidate it wants + * to test on this iteration. In this case, lems should be non-empty. + */ + virtual bool constructCandidates(const std::vector& terms, + const std::vector& term_values, + const std::vector& candidates, + std::vector& candidate_values, + std::vector& lems) = 0; + /** register refinement lemma + * + * Assume this module, on a previous call to constructCandidates, added the + * value { v } to candidate_values for candidates = { k }. This function is + * called if the base instantiation of the synthesis conjecture has a model + * under this substitution. In particular, in the above example, this function + * is called when the refinement lemma P( v, k' ) has a model. The argument + * lem in the call to this function is P( v, k' ). + */ + virtual void registerRefinementLemma(Node lem) {} + protected: + /** reference to quantifier engine */ + QuantifiersEngine* d_qe; + /** reference to the parent conjecture */ + CegConjecture* d_parent; +}; + +} /* CVC4::theory::quantifiers namespace */ +} /* CVC4::theory namespace */ +} /* CVC4 namespace */ + +#endif /* __CVC4__THEORY__QUANTIFIERS__SYGUS_MODULE_H */ diff --git a/src/theory/quantifiers/sygus/sygus_pbe.cpp b/src/theory/quantifiers/sygus/sygus_pbe.cpp index 17c4c482d..36e883848 100644 --- a/src/theory/quantifiers/sygus/sygus_pbe.cpp +++ b/src/theory/quantifiers/sygus/sygus_pbe.cpp @@ -97,8 +97,8 @@ std::ostream& operator<<(std::ostream& os, StrategyType st) } CegConjecturePbe::CegConjecturePbe(QuantifiersEngine* qe, CegConjecture* p) - : d_qe(qe), - d_parent(p){ + : SygusModule(qe, p) +{ d_tds = d_qe->getTermDatabaseSygus(); d_true = NodeManager::currentNM()->mkConst(true); d_false = NodeManager::currentNM()->mkConst(false); @@ -176,8 +176,8 @@ void CegConjecturePbe::collectExamples( Node n, std::map< Node, bool >& visited, } } -void CegConjecturePbe::initialize(Node n, - std::vector& candidates, +bool CegConjecturePbe::initialize(Node n, + const std::vector& candidates, std::vector& lemmas) { Trace("sygus-pbe") << "Initialize PBE : " << n << std::endl; @@ -234,13 +234,7 @@ void CegConjecturePbe::initialize(Node n, } } } - if( !d_is_pbe ){ - Trace("sygus-unif") << "Do not do PBE optimizations, register..." << std::endl; - for( unsigned i=0; igetTermDatabaseSygus()->registerEnumerator( - candidates[i], candidates[i], d_parent); - } - } + return d_is_pbe; } Node CegConjecturePbe::PbeTrie::addPbeExample(TypeNode etn, Node e, Node b, @@ -1077,7 +1071,9 @@ void CegConjecturePbe::staticLearnRedundantOps( // ------------------------------------------- solution construction from enumeration -void CegConjecturePbe::getCandidateList( std::vector< Node >& candidates, std::vector< Node >& clist ) { +void CegConjecturePbe::getTermList(const std::vector& candidates, + std::vector& terms) +{ Valuation& valuation = d_qe->getValuation(); for( unsigned i=0; i& candidates, std::v Node gstatus = valuation.getSatValue(it->second.d_active_guard); if (!gstatus.isNull() && gstatus.getConst()) { - clist.push_back( e ); + terms.push_back(e); } } } } } -bool CegConjecturePbe::constructCandidates( std::vector< Node >& enums, std::vector< Node >& enum_values, - std::vector< Node >& candidates, std::vector< Node >& candidate_values, - std::vector< Node >& lems ) { +bool CegConjecturePbe::constructCandidates(const std::vector& enums, + const std::vector& enum_values, + const std::vector& candidates, + std::vector& candidate_values, + std::vector& lems) +{ Assert( enums.size()==enum_values.size() ); if( !enums.empty() ){ unsigned min_term_size = 0; diff --git a/src/theory/quantifiers/sygus/sygus_pbe.h b/src/theory/quantifiers/sygus/sygus_pbe.h index ce1f2bf5e..2b800db81 100644 --- a/src/theory/quantifiers/sygus/sygus_pbe.h +++ b/src/theory/quantifiers/sygus/sygus_pbe.h @@ -18,7 +18,7 @@ #define __CVC4__THEORY__QUANTIFIERS__CE_GUIDED_PBE_H #include "context/cdhashmap.h" -#include "theory/quantifiers_engine.h" +#include "theory/quantifiers/sygus/sygus_module.h" namespace CVC4 { namespace theory { @@ -158,48 +158,58 @@ class CegConjecture; * This class is not designed to work in incremental mode, since there is no way * to specify incremental problems in SyguS. */ -class CegConjecturePbe { +class CegConjecturePbe : public SygusModule +{ public: CegConjecturePbe(QuantifiersEngine* qe, CegConjecture* p); ~CegConjecturePbe(); /** initialize this class * - * n is the "base instantiation" of the deep-embedding version of - * the synthesis conjecture under "candidates". - * (see CegConjecture::d_base_inst) - * * This function may add lemmas to the vector lemmas corresponding * to initial lemmas regarding static analysis of enumerators it * introduced. For example, we may say that the top-level symbol * of an enumerator is not ITE if it is being used to construct * return values for decision trees. */ - void initialize(Node n, - std::vector& candidates, - std::vector& lemmas); - /** get candidate list + bool initialize(Node n, + const std::vector& candidates, + std::vector& lemmas) override; + /** get term list + * * Adds all active enumerators associated with functions-to-synthesize in - * candidates to clist. + * candidates to terms. */ - void getCandidateList(std::vector& candidates, - std::vector& clist); + void getTermList(const std::vector& candidates, + std::vector& terms) override; /** construct candidates - * (1) Indicates that the list of enumerators in "enums" currently have model - * values "enum_values". - * (2) Asks whether based on these new enumerated values, we can construct a - * solution for - * the functions-to-synthesize in "candidates". If so, this function - * returns "true" and - * adds solutions for candidates into "candidate_values". - * During this class, this class may add auxiliary lemmas to "lems", which the - * caller should send on the output channel via lemma(...). - */ - bool constructCandidates(std::vector& enums, - std::vector& enum_values, - std::vector& candidates, + * + * This function attempts to use unification-based approaches for constructing + * solutions for all functions-to-synthesize (indicated by candidates). These + * approaches include decision tree learning and a divide-and-conquer + * algorithm based on string concatenation. + * + * Calls to this function are such that terms is the list of active + * enumerators (returned by getTermList), and term_values are their current + * model values. This function registers { terms -> terms_values } in + * the database of values that have been enumerated, which are in turn used + * for constructing candidate solutions when possible. + * + * This function also excludes models where (terms = terms_values) by adding + * blocking clauses to lems. For example, for grammar: + * A -> A+A | x | 1 | 0 + * and a call where terms = { d } and term_values = { +( x, 1 ) }, it adds: + * ~G V ~is_+( d ) V ~is_x( d.1 ) V ~is_1( d.2 ) + * to lems, where G is active guard of the enumerator d (see + * TermDatabaseSygus::getActiveGuardForEnumerator). This blocking clause + * indicates that d should not be given the model value +( x, 1 ) anymore, + * since { d -> +( x, 1 ) } has now been added to the database of this class. + */ + bool constructCandidates(const std::vector& terms, + const std::vector& term_values, + const std::vector& candidates, std::vector& candidate_values, - std::vector& lems); + std::vector& lems) override; /** is PBE enabled for any enumerator? */ bool isPbe() { return d_is_pbe; } /** is the enumerator e associated with I/O example pairs? */ @@ -243,15 +253,11 @@ class CegConjecturePbe { Node evaluateBuiltin(TypeNode tn, Node bn, Node e, unsigned i); private: - /** quantifiers engine associated with this class */ - QuantifiersEngine* d_qe; /** sygus term database of d_qe */ quantifiers::TermDbSygus * d_tds; /** true and false nodes */ Node d_true; Node d_false; - /** A reference to the conjecture that owns this class. */ - CegConjecture* d_parent; /** is this a PBE conjecture for any function? */ bool d_is_pbe; /** for each candidate variable f (a function-to-synthesize), whether the -- cgit v1.2.3 From 30398e8552bd372264d99743d39b826e1a2b53be Mon Sep 17 00:00:00 2001 From: Andrew Reynolds Date: Fri, 2 Mar 2018 11:59:42 -0600 Subject: Print candidate rewrites in terms of original grammar (#1635) --- src/theory/datatypes/datatypes_sygus.cpp | 3 +- .../quantifiers/sygus/ce_guided_conjecture.cpp | 25 +++++++++------ src/theory/quantifiers/sygus_sampler.cpp | 37 ++++++++++++++++++---- src/theory/quantifiers/sygus_sampler.h | 22 ++++++++++--- 4 files changed, 66 insertions(+), 21 deletions(-) diff --git a/src/theory/datatypes/datatypes_sygus.cpp b/src/theory/datatypes/datatypes_sygus.cpp index 728cd8135..6f533bfe0 100644 --- a/src/theory/datatypes/datatypes_sygus.cpp +++ b/src/theory/datatypes/datatypes_sygus.cpp @@ -794,7 +794,8 @@ bool SygusSymBreakNew::registerSearchValue( Node a, Node n, Node nv, unsigned d, d_sampler[a].find(tn); if (its == d_sampler[a].end()) { - d_sampler[a][tn].initializeSygus(d_tds, nv, options::sygusSamples()); + d_sampler[a][tn].initializeSygus( + d_tds, nv, options::sygusSamples(), false); its = d_sampler[a].find(tn); } Node bvr_sample_ret; diff --git a/src/theory/quantifiers/sygus/ce_guided_conjecture.cpp b/src/theory/quantifiers/sygus/ce_guided_conjecture.cpp index f2a1c334c..ac0982c4e 100644 --- a/src/theory/quantifiers/sygus/ce_guided_conjecture.cpp +++ b/src/theory/quantifiers/sygus/ce_guided_conjecture.cpp @@ -620,29 +620,34 @@ void CegConjecture::printSynthSolution( std::ostream& out, bool singleInvocation if (its == d_sampler.end()) { d_sampler[prog].initializeSygusExt( - d_qe, prog, options::sygusSamples()); + d_qe, prog, options::sygusSamples(), true); its = d_sampler.find(prog); } - Node solb = sygusDb->sygusToBuiltin(sol, prog.getType()); - Node eq_sol = its->second.registerTerm(solb); + Node eq_sol = its->second.registerTerm(sol); // eq_sol is a candidate solution that is equivalent to sol - if (eq_sol != solb) + if (eq_sol != sol) { ++(cei->d_statistics.d_candidate_rewrites); if (!eq_sol.isNull()) { - // Terms solb and eq_sol are equivalent under sample points but do - // not rewrite to the same term. Hence, this indicates a candidate - // rewrite. - out << "(candidate-rewrite " << solb << " " << eq_sol << ")" - << std::endl; + // The analog of terms sol and eq_sol are equivalent under sample + // points but do not rewrite to the same term. Hence, this indicates + // a candidate rewrite. + Printer* p = Printer::getPrinter(options::outputLanguage()); + out << "(candidate-rewrite "; + p->toStreamSygus(out, sol); + out << " "; + p->toStreamSygus(out, eq_sol); + out << ")" << std::endl; ++(cei->d_statistics.d_candidate_rewrites_print); // debugging information if (Trace.isOn("sygus-rr-debug")) { ExtendedRewriter* er = sygusDb->getExtRewriter(); + Node solb = sygusDb->sygusToBuiltin(sol); Node solbr = er->extendedRewrite(solb); - Node eq_solr = er->extendedRewrite(eq_sol); + Node eq_solb = sygusDb->sygusToBuiltin(eq_sol); + Node eq_solr = er->extendedRewrite(eq_solb); Trace("sygus-rr-debug") << "; candidate #1 ext-rewrites to: " << solbr << std::endl; Trace("sygus-rr-debug") diff --git a/src/theory/quantifiers/sygus_sampler.cpp b/src/theory/quantifiers/sygus_sampler.cpp index fa0478ac7..0b9254818 100644 --- a/src/theory/quantifiers/sygus_sampler.cpp +++ b/src/theory/quantifiers/sygus_sampler.cpp @@ -64,13 +64,17 @@ Node LazyTrie::add(Node n, return Node::null(); } -SygusSampler::SygusSampler() : d_tds(nullptr), d_is_valid(false) {} +SygusSampler::SygusSampler() + : d_tds(nullptr), d_use_sygus_type(false), d_is_valid(false) +{ +} void SygusSampler::initialize(TypeNode tn, std::vector& vars, unsigned nsamples) { d_tds = nullptr; + d_use_sygus_type = false; d_is_valid = true; d_tn = tn; d_ftn = TypeNode::null(); @@ -105,9 +109,13 @@ void SygusSampler::initialize(TypeNode tn, initializeSamples(nsamples); } -void SygusSampler::initializeSygus(TermDbSygus* tds, Node f, unsigned nsamples) +void SygusSampler::initializeSygus(TermDbSygus* tds, + Node f, + unsigned nsamples, + bool useSygusType) { d_tds = tds; + d_use_sygus_type = useSygusType; d_is_valid = true; d_ftn = f.getType(); Assert(d_ftn.isDatatype()); @@ -282,8 +290,23 @@ Node SygusSampler::registerTerm(Node n, bool forceKeep) { if (d_is_valid) { - Assert(n.getType() == d_tn); - return d_trie.add(n, this, 0, d_samples.size(), forceKeep); + Node bn = n; + // if this is a sygus type, get its builtin analog + if (d_use_sygus_type) + { + Assert(!d_ftn.isNull()); + bn = d_tds->sygusToBuiltin(n); + bn = Rewriter::rewrite(bn); + d_builtin_to_sygus[bn] = n; + } + Assert(bn.getType() == d_tn); + Node res = d_trie.add(bn, this, 0, d_samples.size(), forceKeep); + if (d_use_sygus_type) + { + Assert(d_builtin_to_sygus.find(res) == d_builtin_to_sygus.end()); + res = res != bn ? d_builtin_to_sygus[res] : n; + } + return res; } return n; } @@ -645,9 +668,11 @@ void SygusSampler::registerSygusType(TypeNode tn) void SygusSamplerExt::initializeSygusExt(QuantifiersEngine* qe, Node f, - unsigned nsamples) + unsigned nsamples, + bool useSygusType) { - SygusSampler::initializeSygus(qe->getTermDatabaseSygus(), f, nsamples); + SygusSampler::initializeSygus( + qe->getTermDatabaseSygus(), f, nsamples, useSygusType); // initialize the dynamic rewriter std::stringstream ss; diff --git a/src/theory/quantifiers/sygus_sampler.h b/src/theory/quantifiers/sygus_sampler.h index abc9232af..5fcfc1c93 100644 --- a/src/theory/quantifiers/sygus_sampler.h +++ b/src/theory/quantifiers/sygus_sampler.h @@ -148,11 +148,18 @@ class SygusSampler : public LazyTrieEvaluator /** initialize sygus * * tds : pointer to sygus database, - * f : a term of some SyGuS datatype type whose (builtin) values we will be + * f : a term of some SyGuS datatype type whose values we will be * testing under the free variables in the grammar of f, - * nsamples : number of sample points this class will test. + * nsamples : number of sample points this class will test, + * useSygusType : whether we will register terms with this sampler that have + * the same type as f. If this flag is false, then we will be registering + * terms of the analog of the type of f, that is, the builtin type that + * f's type encodes in the deep embedding. */ - void initializeSygus(TermDbSygus* tds, Node f, unsigned nsamples); + void initializeSygus(TermDbSygus* tds, + Node f, + unsigned nsamples, + bool useSygusType); /** register term n with this sampler database * * forceKeep is whether we wish to force that n is chosen as a representative @@ -222,6 +229,10 @@ class SygusSampler : public LazyTrieEvaluator TypeNode d_tn; /** the sygus type for this sampler (if applicable). */ TypeNode d_ftn; + /** whether we are registering terms of type d_ftn */ + bool d_use_sygus_type; + /** map from builtin terms to the sygus term they correspond to */ + std::map d_builtin_to_sygus; /** all variables we are sampling values for */ std::vector d_vars; /** type variables @@ -329,7 +340,10 @@ class SygusSamplerExt : public SygusSampler { public: /** initialize extended */ - void initializeSygusExt(QuantifiersEngine* qe, Node f, unsigned nsamples); + void initializeSygusExt(QuantifiersEngine* qe, + Node f, + unsigned nsamples, + bool useSygusType); /** register term n with this sampler database * * This returns either null, or a term ret with the same guarantees as -- cgit v1.2.3 From 356319744514261f06afced5ee975d49abe83eb4 Mon Sep 17 00:00:00 2001 From: Aina Niemetz Date: Fri, 2 Mar 2018 11:49:49 -0800 Subject: Fixed comments in smt_engine.h. --- src/smt/smt_engine.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/smt/smt_engine.h b/src/smt/smt_engine.h index c8601a23d..16cf90de1 100644 --- a/src/smt/smt_engine.h +++ b/src/smt/smt_engine.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2017 by the authors listed in the file AUTHORS + ** Copyright (c) 2009-2018 by the authors listed in the file AUTHORS ** in the top-level source directory) and their institutional affiliations. ** All rights reserved. See the file COPYING in the top-level source ** directory for licensing information.\endverbatim @@ -186,8 +186,8 @@ class CVC4_PUBLIC SmtEngine { std::vector d_dumpCommands; /** - *A vector of command definitions to be imported in the new - *SmtEngine when checking unsat-cores. + * A vector of command definitions to be imported in the new + * SmtEngine when checking unsat-cores. */ std::vector d_defineCommands; @@ -207,10 +207,10 @@ class CVC4_PUBLIC SmtEngine { unsigned d_pendingPops; /** - * Whether or not this SmtEngine has been fully initialized (that is, - * the ). This post-construction initialization is automatically - * triggered by the use of the SmtEngine; e.g. when setLogic() is - * called, or the first assertion is made, etc. + * Whether or not this SmtEngine is fully initialized (post-construction). + * This post-construction initialization is automatically triggered by the + * use of the SmtEngine; e.g. when setLogic() is called, or the first + * assertion is made, etc. */ bool d_fullyInited; @@ -871,13 +871,13 @@ class CVC4_PUBLIC SmtEngine { * translation. */ void setReplayStream(ExprStream* exprStream); - + /** get expression name * Returns true if e has an expression name in the current context. * If it returns true, the name of e is stored in name. */ bool getExpressionName(Expr e, std::string& name) const; - + /** set expression name * Sets the expression name of e to name. * This information is user-context-dependent. -- cgit v1.2.3 From c8d0db7ee9c48fadd19227d472f60ff0089c34da Mon Sep 17 00:00:00 2001 From: Andrew Reynolds Date: Fri, 2 Mar 2018 14:44:04 -0600 Subject: Simplify sygus wrt miniscoping (#1634) --- .../quantifiers/sygus/ce_guided_conjecture.cpp | 169 ++++++++------------- .../quantifiers/sygus/ce_guided_conjecture.h | 12 +- src/theory/quantifiers/sygus/cegis.cpp | 12 +- src/theory/quantifiers/sygus/cegis.h | 9 +- src/theory/quantifiers/sygus/sygus_module.h | 17 ++- 5 files changed, 102 insertions(+), 117 deletions(-) diff --git a/src/theory/quantifiers/sygus/ce_guided_conjecture.cpp b/src/theory/quantifiers/sygus/ce_guided_conjecture.cpp index ac0982c4e..3e71eedad 100644 --- a/src/theory/quantifiers/sygus/ce_guided_conjecture.cpp +++ b/src/theory/quantifiers/sygus/ce_guided_conjecture.cpp @@ -36,18 +36,6 @@ namespace CVC4 { namespace theory { namespace quantifiers { -// recursion is not an issue since OR nodes are flattened by the (quantifiers) rewriter -// this function is for sanity since solution correctness in SyGuS depends on fully miniscoping based on this function -void collectDisjuncts( Node n, std::vector< Node >& d ) { - if( n.getKind()==OR ){ - for( unsigned i=0; igetQuantAttributes()->isSygus(q)) { - collectDisjuncts( d_base_inst, d_base_disj ); - Trace("cegqi") << "Conjecture has " << d_base_disj.size() << " disjuncts." << std::endl; - //store the inner variables for each disjunct - for( unsigned j=0; j() ); - //if the disjunct is an existential, store it - if( d_base_disj[j].getKind()==NOT && d_base_disj[j][0].getKind()==FORALL ){ - for( unsigned k=0; k& lems) { bool CegConjecture::needsRefinement() { return !d_ce_sk.empty(); } + void CegConjecture::doCheck(std::vector& lems) { Assert(d_master != nullptr); @@ -301,7 +284,6 @@ void CegConjecture::doCheck(std::vector& lems) return; } Assert( d_ce_sk.empty() ); - d_ce_sk.push_back( std::vector< Node >() ); }else{ if( !constructed_cand ){ return; @@ -310,30 +292,33 @@ void CegConjecture::doCheck(std::vector& lems) std::vector< Node > ic; ic.push_back( d_quant.negate() ); - std::vector< Node > d; - collectDisjuncts( inst, d ); - Assert( d.size()==d_base_disj.size() ); + //immediately skolemize inner existentials - for( unsigned i=0; igetSkolemize()->getSkolemizedBody(dr[0]).negate()); - } - if( sk_refine ){ - Assert( !isGround() ); - d_ce_sk.back().push_back( dr[0] ); - } - }else{ - if( constructed_cand ){ - ic.push_back( dr ); - if( !d_inner_vars_disj[i].empty() ){ - Trace("cegqi-debug") << "*** quantified disjunct : " << d[i] << " simplifies to " << dr << std::endl; - } - } - if( sk_refine ){ - d_ce_sk.back().push_back( Node::null() ); - } + Node instr = Rewriter::rewrite(inst); + if (instr.getKind() == NOT && instr[0].getKind() == FORALL) + { + if (constructed_cand) + { + ic.push_back(d_qe->getSkolemize()->getSkolemizedBody(instr[0]).negate()); + } + if (sk_refine) + { + Assert(!isGround()); + d_ce_sk.push_back(instr[0]); + } + } + else + { + if (constructed_cand) + { + // use the instance itself + ic.push_back(instr); + } + if (sk_refine) + { + // we add null so that one test of the conjecture for the empty + // substitution is checked + d_ce_sk.push_back(Node::null()); } } if( constructed_cand ){ @@ -360,69 +345,45 @@ void CegConjecture::doRefine( std::vector< Node >& lems ){ std::vector< Node > sk_vars; std::vector< Node > sk_subs; //collect the substitution over all disjuncts - for( unsigned k=0; k skolems; - d_qe->getSkolemize()->getSkolemConstants(ce_q, skolems); - Assert(d_inner_vars_disj[k].size() == skolems.size()); - std::vector< Node > model_values; - getModelValues(skolems, model_values); - sk_vars.insert( sk_vars.end(), d_inner_vars_disj[k].begin(), d_inner_vars_disj[k].end() ); - sk_subs.insert( sk_subs.end(), model_values.begin(), model_values.end() ); - }else{ - if( !d_inner_vars_disj[k].empty() ){ - //denegrate case : quantified disjunct was trivially true and does not need to be refined - //add trivial substitution (in case we need substitution for previous cex's) - for( unsigned i=0; i skolems; + d_qe->getSkolemize()->getSkolemConstants(ce_q, skolems); + Assert(d_inner_vars.size() == skolems.size()); + std::vector model_values; + getModelValues(skolems, model_values); + sk_vars.insert(sk_vars.end(), d_inner_vars.begin(), d_inner_vars.end()); + sk_subs.insert(sk_subs.end(), model_values.begin(), model_values.end()); + } + else + { + Assert(d_inner_vars.empty()); + } + std::vector< Node > lem_c; - Assert( d_ce_sk[0].size()==d_base_disj.size() ); - std::vector< Node > inst_cond_c; Trace("cegqi-refine") << "doRefine : Construct refinement lemma..." << std::endl; - for( unsigned k=0; kmkNode( AND, lem_c ); - + Trace("cegqi-refine") << "doRefine : construct and finalize lemmas..." << std::endl; - - + base_lem = base_lem.substitute( sk_vars.begin(), sk_vars.end(), sk_subs.begin(), sk_subs.end() ); base_lem = Rewriter::rewrite( base_lem ); - d_master->registerRefinementLemma(base_lem); - - Node lem = - NodeManager::currentNM()->mkNode(OR, getGuard().negate(), base_lem); - lems.push_back( lem ); + d_master->registerRefinementLemma(sk_vars, base_lem, lems); d_ce_sk.clear(); } diff --git a/src/theory/quantifiers/sygus/ce_guided_conjecture.h b/src/theory/quantifiers/sygus/ce_guided_conjecture.h index 9f3335ee2..8ab871d08 100644 --- a/src/theory/quantifiers/sygus/ce_guided_conjecture.h +++ b/src/theory/quantifiers/sygus/ce_guided_conjecture.h @@ -160,14 +160,14 @@ private: * this is the formula exists y. P( d_candidates, y ). */ Node d_base_inst; - /** expand base inst to disjuncts */ - std::vector< Node > d_base_disj; /** list of variables on inner quantification */ std::vector< Node > d_inner_vars; - std::vector< std::vector< Node > > d_inner_vars_disj; - /** current extential quantifeirs whose couterexamples we must refine */ - std::vector< std::vector< Node > > d_ce_sk; - + /** + * The set of current existentially quantified formulas whose couterexamples + * we must refine. This may be added to during calls to doCheck(). The model + * values for skolems of these formulas are analyzed during doRefine(). + */ + std::vector d_ce_sk; /** the asserted (negated) conjecture */ Node d_quant; diff --git a/src/theory/quantifiers/sygus/cegis.cpp b/src/theory/quantifiers/sygus/cegis.cpp index a571c85fb..b778b90be 100644 --- a/src/theory/quantifiers/sygus/cegis.cpp +++ b/src/theory/quantifiers/sygus/cegis.cpp @@ -150,9 +150,19 @@ bool Cegis::constructCandidates(const std::vector& enums, return true; } -void Cegis::registerRefinementLemma(Node lem) +void Cegis::registerRefinementLemma(const std::vector& vars, + Node lem, + std::vector& lems) { d_refinement_lemmas.push_back(lem); + // Make the refinement lemma and add it to lems. + // This lemma is guarded by the parent's guard, which has the semantics + // "this conjecture has a solution", hence this lemma states: + // if the parent conjecture has a solution, it satisfies the specification + // for the given concrete point. + Node rlem = + NodeManager::currentNM()->mkNode(OR, d_parent->getGuard().negate(), lem); + lems.push_back(rlem); } void Cegis::getRefinementEvalLemmas(const std::vector& vs, diff --git a/src/theory/quantifiers/sygus/cegis.h b/src/theory/quantifiers/sygus/cegis.h index 2cb668fa1..358b50536 100644 --- a/src/theory/quantifiers/sygus/cegis.h +++ b/src/theory/quantifiers/sygus/cegis.h @@ -56,8 +56,13 @@ class Cegis : public SygusModule const std::vector& candidates, std::vector& candidate_values, std::vector& lems) override; - /** register refinement lemma */ - virtual void registerRefinementLemma(Node lem) override; + /** register refinement lemma + * + * This function stores lem as a refinement lemma, and adds it to lems. + */ + virtual void registerRefinementLemma(const std::vector& vars, + Node lem, + std::vector& lems) override; private: /** If CegConjecture::d_base_inst is exists y. P( d, y ), then this is y. */ diff --git a/src/theory/quantifiers/sygus/sygus_module.h b/src/theory/quantifiers/sygus/sygus_module.h index 230ea7a61..0a3fa9995 100644 --- a/src/theory/quantifiers/sygus/sygus_module.h +++ b/src/theory/quantifiers/sygus/sygus_module.h @@ -81,7 +81,7 @@ class SygusModule * If this function returns true, it adds to candidate_values a list of terms * of the same length and type as candidates that are candidate solutions * to the synthesis conjecture in question. This candidate { v } will then be - * tested by testing the (un)satisfiablity of P( v, k' ) for fresh k' by the + * tested by testing the (un)satisfiablity of P( v, cex ) for fresh cex by the * caller. * * This function may also add lemmas to lems, which are sent out as lemmas @@ -102,10 +102,19 @@ class SygusModule * value { v } to candidate_values for candidates = { k }. This function is * called if the base instantiation of the synthesis conjecture has a model * under this substitution. In particular, in the above example, this function - * is called when the refinement lemma P( v, k' ) has a model. The argument - * lem in the call to this function is P( v, k' ). + * is called when the refinement lemma P( v, cex ) has a model M. In calls to + * this function, the argument vars is cex and lem is P( k, cex^M ). + * + * This function may also add lemmas to lems, which are sent out as lemmas + * on the output channel of quantifiers by the caller. For an example of + * such lemmas, see Cegis::registerRefinementLemma. */ - virtual void registerRefinementLemma(Node lem) {} + virtual void registerRefinementLemma(const std::vector& vars, + Node lem, + std::vector& lems) + { + } + protected: /** reference to quantifier engine */ QuantifiersEngine* d_qe; -- cgit v1.2.3 From 87fbe99f81b9c72e9acb34e0fae61f56164535c4 Mon Sep 17 00:00:00 2001 From: Andrew Reynolds Date: Fri, 2 Mar 2018 15:56:16 -0600 Subject: Optimization for sygus streaming mode (#1636) --- .../quantifiers/sygus/ce_guided_conjecture.cpp | 109 +++++++++++++-------- .../quantifiers/sygus/ce_guided_conjecture.h | 6 ++ 2 files changed, 72 insertions(+), 43 deletions(-) diff --git a/src/theory/quantifiers/sygus/ce_guided_conjecture.cpp b/src/theory/quantifiers/sygus/ce_guided_conjecture.cpp index 3e71eedad..1dd4dcbeb 100644 --- a/src/theory/quantifiers/sygus/ce_guided_conjecture.cpp +++ b/src/theory/quantifiers/sygus/ce_guided_conjecture.cpp @@ -290,16 +290,14 @@ void CegConjecture::doCheck(std::vector& lems) } } - std::vector< Node > ic; - ic.push_back( d_quant.negate() ); - //immediately skolemize inner existentials Node instr = Rewriter::rewrite(inst); + Node lem; if (instr.getKind() == NOT && instr[0].getKind() == FORALL) { if (constructed_cand) { - ic.push_back(d_qe->getSkolemize()->getSkolemizedBody(instr[0]).negate()); + lem = d_qe->getSkolemize()->getSkolemizedBody(instr[0]).negate(); } if (sk_refine) { @@ -312,7 +310,7 @@ void CegConjecture::doCheck(std::vector& lems) if (constructed_cand) { // use the instance itself - ic.push_back(instr); + lem = instr; } if (sk_refine) { @@ -321,8 +319,8 @@ void CegConjecture::doCheck(std::vector& lems) d_ce_sk.push_back(Node::null()); } } - if( constructed_cand ){ - Node lem = nm->mkNode(OR, ic); + if (!lem.isNull()) + { lem = Rewriter::rewrite( lem ); //eagerly unfold applications of evaluation function if( options::sygusDirectEval() ){ @@ -330,9 +328,25 @@ void CegConjecture::doCheck(std::vector& lems) std::map< Node, Node > visited_n; lem = d_qe->getTermDatabaseSygus()->getEagerUnfold( lem, visited_n ); } - lem = getStreamGuardedLemma(lem); - lems.push_back( lem ); + // record the instantiation + // this is used for remembering the solution recordInstantiation(candidate_values); + if (lem.isConst() && !lem.getConst() && options::sygusStream()) + { + // short circuit the check + // instead, we immediately print the current solution. + // this saves us from introducing a check lemma and a new guard. + printAndContinueStream(); + } + else + { + // This is the "verification lemma", which states + // either this conjecture does not have a solution, or candidate_values + // is a solution for this conjecture. + lem = nm->mkNode(OR, d_quant.negate(), lem); + lem = getStreamGuardedLemma(lem); + lems.push_back(lem); + } } } @@ -479,43 +493,13 @@ Node CegConjecture::getNextDecisionRequest( unsigned& priority ) { return curr_stream_guard; }else{ if( !value ){ - Assert(d_master != nullptr); Trace("cegqi-debug") << "getNextDecision : we have a new solution since stream guard was propagated false: " << curr_stream_guard << std::endl; - // we have generated a solution, print it - // get the current output stream - // this output stream should coincide with wherever --dump-synth is output on - Options& nodeManagerOptions = NodeManager::currentNM()->getOptions(); - printSynthSolution( *nodeManagerOptions.getOut(), false ); // need to make the next stream guard needs_new_stream_guard = true; - - // We will not refine the current candidate solution since it is a solution - // thus, we clear information regarding the current refinement - d_ce_sk.clear(); - // However, we need to exclude the current solution using an - // explicit refinement - // so that we proceed to the next solution. - std::vector terms; - d_master->getTermList(d_candidates, terms); - Trace("cegqi-debug") << "getNextDecision : solution was : " << std::endl; - std::vector< Node > exp; - for (const Node& cprog : terms) - { - Node sol = cprog; - if( !d_cinfo[cprog].d_inst.empty() ){ - sol = d_cinfo[cprog].d_inst.back(); - // add to explanation of exclusion - d_qe->getTermDatabaseSygus() - ->getExplain() - ->getExplanationForConstantEquality(cprog, sol, exp); - } - Trace("cegqi-debug") << " " << cprog << " -> " << sol << std::endl; - } - Assert( !exp.empty() ); - Node exc_lem = exp.size()==1 ? exp[0] : NodeManager::currentNM()->mkNode( kind::AND, exp ); - exc_lem = exc_lem.negate(); - Trace("cegqi-lemma") << "Cegqi::Lemma : stream exclude current solution : " << exc_lem << std::endl; - d_qe->getOutputChannel().lemma( exc_lem ); + // the guard has propagated false, indicating that a verify + // lemma was unsatisfiable. Hence, the previous candidate is + // an actual solution. We print and continue the stream. + printAndContinueStream(); } } } @@ -539,6 +523,45 @@ Node CegConjecture::getNextDecisionRequest( unsigned& priority ) { return Node::null(); } +void CegConjecture::printAndContinueStream() +{ + Assert(d_master != nullptr); + // we have generated a solution, print it + // get the current output stream + // this output stream should coincide with wherever --dump-synth is output on + Options& nodeManagerOptions = NodeManager::currentNM()->getOptions(); + printSynthSolution(*nodeManagerOptions.getOut(), false); + + // We will not refine the current candidate solution since it is a solution + // thus, we clear information regarding the current refinement + d_ce_sk.clear(); + // However, we need to exclude the current solution using an explicit + // blocking clause, so that we proceed to the next solution. + std::vector terms; + d_master->getTermList(d_candidates, terms); + std::vector exp; + for (const Node& cprog : terms) + { + Node sol = cprog; + if (!d_cinfo[cprog].d_inst.empty()) + { + sol = d_cinfo[cprog].d_inst.back(); + // add to explanation of exclusion + d_qe->getTermDatabaseSygus() + ->getExplain() + ->getExplanationForConstantEquality(cprog, sol, exp); + } + } + Assert(!exp.empty()); + Node exc_lem = exp.size() == 1 + ? exp[0] + : NodeManager::currentNM()->mkNode(kind::AND, exp); + exc_lem = exc_lem.negate(); + Trace("cegqi-lemma") << "Cegqi::Lemma : stream exclude current solution : " + << exc_lem << std::endl; + d_qe->getOutputChannel().lemma(exc_lem); +} + void CegConjecture::printSynthSolution( std::ostream& out, bool singleInvocation ) { Trace("cegqi-debug") << "Printing synth solution..." << std::endl; Assert( d_quant[0].getNumChildren()==d_embed_quant[0].getNumChildren() ); diff --git a/src/theory/quantifiers/sygus/ce_guided_conjecture.h b/src/theory/quantifiers/sygus/ce_guided_conjecture.h index 8ab871d08..215a4d161 100644 --- a/src/theory/quantifiers/sygus/ce_guided_conjecture.h +++ b/src/theory/quantifiers/sygus/ce_guided_conjecture.h @@ -226,6 +226,12 @@ private: * returned by getCurrentStreamGuard, otherwise this returns n. */ Node getStreamGuardedLemma(Node n) const; + /** + * Prints the current synthesis solution to the output stream indicated by + * the Options object, send a lemma blocking the current solution to the + * output channel. + */ + void printAndContinueStream(); //-------------------------------- end sygus stream //-------------------------------- non-syntax guided (deprecated) /** Whether we are syntax-guided (e.g. was the input in SyGuS format). -- cgit v1.2.3 From 5325b6e57714b49e8449cd5f962493aeb39d41b4 Mon Sep 17 00:00:00 2001 From: Aina Niemetz Date: Fri, 2 Mar 2018 15:09:43 -0800 Subject: Fixed typo. --- src/expr/node_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/expr/node_manager.cpp b/src/expr/node_manager.cpp index 3c79e96f2..20a011006 100644 --- a/src/expr/node_manager.cpp +++ b/src/expr/node_manager.cpp @@ -402,7 +402,7 @@ std::vector NodeManager::TopologicalSort( TypeNode NodeManager::getType(TNode n, bool check) { // Many theories' type checkers call Node::getType() directly. This - // is incorrect, since "this" might not be the caller's curent node + // is incorrect, since "this" might not be the caller's current node // manager. Rather than force the individual typecheckers not to do // this (by policy, which would be imperfect and lead to // hard-to-find bugs, which it has in the past), we just set this -- cgit v1.2.3 From 78cd7af7b3897d630ad375f72d43b4c67df6d557 Mon Sep 17 00:00:00 2001 From: Aina Niemetz Date: Mon, 5 Mar 2018 11:26:53 -0800 Subject: Add uniform way to serialize containers of Expr to stream. (#1638) --- src/expr/expr_template.cpp | 36 +++++++++++++++++++++++++++++++ src/expr/expr_template.h | 54 ++++++++++++++++++++++++++++++++++++++++++++++ src/expr/node.h | 27 +++++------------------ src/util/utility.h | 13 +++++++++++ 4 files changed, 108 insertions(+), 22 deletions(-) diff --git a/src/expr/expr_template.cpp b/src/expr/expr_template.cpp index f4dd294a7..6bcd15027 100644 --- a/src/expr/expr_template.cpp +++ b/src/expr/expr_template.cpp @@ -54,6 +54,42 @@ std::ostream& operator<<(std::ostream& out, const Expr& e) { } } +std::ostream& operator<<(std::ostream& out, const std::vector& container) +{ + container_to_stream(out, container); + return out; +} + +std::ostream& operator<<(std::ostream& out, const std::set& container) +{ + container_to_stream(out, container); + return out; +} + +std::ostream& operator<<( + std::ostream& out, + const std::unordered_set& container) +{ + container_to_stream(out, container); + return out; +} + +template +std::ostream& operator<<(std::ostream& out, const std::map& container) +{ + container_to_stream(out, container); + return out; +} + +template +std::ostream& operator<<( + std::ostream& out, + const std::unordered_map& container) +{ + container_to_stream(out, container); + return out; +} + TypeCheckingException::TypeCheckingException(const TypeCheckingException& t) : Exception(t.d_msg), d_expr(new Expr(t.getExpression())) { diff --git a/src/expr/expr_template.h b/src/expr/expr_template.h index cc9949c30..f406981a8 100644 --- a/src/expr/expr_template.h +++ b/src/expr/expr_template.h @@ -30,7 +30,10 @@ ${includes} #include #include #include +#include +#include #include +#include #include "base/exception.h" #include "options/language.h" @@ -141,6 +144,57 @@ std::ostream& operator<<(std::ostream& out, */ std::ostream& operator<<(std::ostream& out, const Expr& e) CVC4_PUBLIC; +/** + * Serialize a vector of expressions to given stream. + * + * @param out the output stream to use + * @param container the vector of expressions to output to the stream + * @return the stream + */ +std::ostream& operator<<(std::ostream& out, const std::vector& container); + +/** + * Serialize a set of expressions to the given stream. + * + * @param out the output stream to use + * @param container the set of expressions to output to the stream + * @return the stream + */ +std::ostream& operator<<(std::ostream& out, const std::set& container); + +/** + * Serialize an unordered_set of expressions to the given stream. + * + * @param out the output stream to use + * @param container the unordered_set of expressions to output to the stream + * @return the stream + */ +std::ostream& operator<<( + std::ostream& out, + const std::unordered_set& container); + +/** + * Serialize a map of expressions to the given stream. + * + * @param out the output stream to use + * @param container the map of expressions to output to the stream + * @return the stream + */ +template +std::ostream& operator<<(std::ostream& out, const std::map& container); + +/** + * Serialize an unordered_map of expressions to the given stream. + * + * @param out the output stream to use + * @param container the unordered_map of expressions to output to the stream + * @return the stream + */ +template +std::ostream& operator<<( + std::ostream& out, + const std::unordered_map& container); + // for hash_maps, hash_sets.. struct ExprHashFunction { size_t operator()(CVC4::Expr e) const; diff --git a/src/expr/node.h b/src/expr/node.h index 84278ff8a..e1b979570 100644 --- a/src/expr/node.h +++ b/src/expr/node.h @@ -923,23 +923,6 @@ inline std::ostream& operator<<(std::ostream& out, TNode n) { return out; } -namespace { - -template -void nodeContainerToOut(std::ostream& out, const T& container) -{ - out << "["; - bool is_first = true; - for (const auto& item : container) - { - out << (!is_first ? ", " : "") << item; - is_first = false; - } - out << "]"; -} - -} - /** * Serialize a vector of nodes to given stream. * @@ -951,7 +934,7 @@ template std::ostream& operator<<(std::ostream& out, const std::vector>& container) { - nodeContainerToOut(out, container); + container_to_stream(out, container); return out; } @@ -966,7 +949,7 @@ template std::ostream& operator<<(std::ostream& out, const std::set>& container) { - nodeContainerToOut(out, container); + container_to_stream(out, container); return out; } @@ -982,7 +965,7 @@ std::ostream& operator<<( std::ostream& out, const std::unordered_set, hash_function>& container) { - nodeContainerToOut(out, container); + container_to_stream(out, container); return out; } @@ -998,7 +981,7 @@ std::ostream& operator<<( std::ostream& out, const std::map, V>& container) { - nodeContainerToOut(out, container); + container_to_stream(out, container); return out; } @@ -1014,7 +997,7 @@ std::ostream& operator<<( std::ostream& out, const std::unordered_map, V, HF>& container) { - nodeContainerToOut(out, container); + container_to_stream(out, container); return out; } diff --git a/src/util/utility.h b/src/util/utility.h index adfd2bc64..78a1e94f7 100644 --- a/src/util/utility.h +++ b/src/util/utility.h @@ -67,6 +67,19 @@ inline InputIterator find_if_unique(InputIterator first, InputIterator last, Pre return (match2 == last) ? match : last; } +template +void container_to_stream(std::ostream& out, const T& container) +{ + out << "["; + bool is_first = true; + for (const auto& item : container) + { + out << (!is_first ? ", " : "") << item; + is_first = false; + } + out << "]"; +} + }/* CVC4 namespace */ #endif /* __CVC4__UTILITY_H */ -- cgit v1.2.3 From d1aa4ae101987093a06208650e2ea4878f7437ca Mon Sep 17 00:00:00 2001 From: Aina Niemetz Date: Mon, 5 Mar 2018 12:59:23 -0800 Subject: Add CVC4_PUBLIC keyword to overloads of << for Expr containers. (#1644) --- src/expr/expr_template.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/expr/expr_template.h b/src/expr/expr_template.h index f406981a8..8cc87cfff 100644 --- a/src/expr/expr_template.h +++ b/src/expr/expr_template.h @@ -151,7 +151,8 @@ std::ostream& operator<<(std::ostream& out, const Expr& e) CVC4_PUBLIC; * @param container the vector of expressions to output to the stream * @return the stream */ -std::ostream& operator<<(std::ostream& out, const std::vector& container); +std::ostream& operator<<(std::ostream& out, + const std::vector& container) CVC4_PUBLIC; /** * Serialize a set of expressions to the given stream. @@ -160,7 +161,8 @@ std::ostream& operator<<(std::ostream& out, const std::vector& container); * @param container the set of expressions to output to the stream * @return the stream */ -std::ostream& operator<<(std::ostream& out, const std::set& container); +std::ostream& operator<<(std::ostream& out, + const std::set& container) CVC4_PUBLIC; /** * Serialize an unordered_set of expressions to the given stream. @@ -171,7 +173,7 @@ std::ostream& operator<<(std::ostream& out, const std::set& container); */ std::ostream& operator<<( std::ostream& out, - const std::unordered_set& container); + const std::unordered_set& container) CVC4_PUBLIC; /** * Serialize a map of expressions to the given stream. @@ -181,7 +183,8 @@ std::ostream& operator<<( * @return the stream */ template -std::ostream& operator<<(std::ostream& out, const std::map& container); +std::ostream& operator<<(std::ostream& out, + const std::map& container) CVC4_PUBLIC; /** * Serialize an unordered_map of expressions to the given stream. @@ -193,7 +196,7 @@ std::ostream& operator<<(std::ostream& out, const std::map& container); template std::ostream& operator<<( std::ostream& out, - const std::unordered_map& container); + const std::unordered_map& container) CVC4_PUBLIC; // for hash_maps, hash_sets.. struct ExprHashFunction { -- cgit v1.2.3 From d51c8347a3c6bf7857c474bd3493377f9fed58e5 Mon Sep 17 00:00:00 2001 From: Aina Niemetz Date: Mon, 5 Mar 2018 14:05:26 -0800 Subject: Add support for check-sat-assuming. (#1637) This adds support for check-sat-assuming. It further adds support for SmtEngine::query() over a vector of Expressions, e.g., smtEngine->query({a, b}); checks the validity (of the current input formula) under assumption (not (or a b)). --- examples/api/bitvectors.cpp | 9 +- src/expr/expr_template.cpp | 2 +- src/expr/expr_template.h | 4 +- src/parser/smt2/Smt2.g | 21 +- src/printer/ast/ast_printer.cpp | 11 +- src/printer/cvc/cvc_printer.cpp | 30 +- src/printer/smt2/smt2_printer.cpp | 32 +- src/smt/command.cpp | 334 ++++++++++++++++----- src/smt/command.h | 45 ++- src/smt/smt_engine.cpp | 116 ++++--- src/smt/smt_engine.h | 14 +- test/regress/regress0/push-pop/Makefile.am | 3 +- .../push-pop/bug821-check_sat_assuming.smt2 | 9 + 13 files changed, 491 insertions(+), 139 deletions(-) create mode 100644 test/regress/regress0/push-pop/bug821-check_sat_assuming.smt2 diff --git a/examples/api/bitvectors.cpp b/examples/api/bitvectors.cpp index 90b69b10a..a245d4890 100644 --- a/examples/api/bitvectors.cpp +++ b/examples/api/bitvectors.cpp @@ -2,9 +2,9 @@ /*! \file bitvectors.cpp ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Morgan Deters, Paul Meng + ** Liana Hadarean, Morgan Deters, Aina Niemetz ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2017 by the authors listed in the file AUTHORS + ** Copyright (c) 2009-2018 by the authors listed in the file AUTHORS ** in the top-level source directory) and their institutional affiliations. ** All rights reserved. See the file COPYING in the top-level source ** directory for licensing information.\endverbatim @@ -107,5 +107,10 @@ int main() { cout << " Expect valid. " << endl; cout << " CVC4: " << smt.query(new_x_eq_new_x_) << endl; + Expr x_neq_x = em.mkExpr(kind::EQUAL, x, x).notExpr(); + std::vector v{new_x_eq_new_x_, x_neq_x}; + cout << " Querying: " << v << endl; + cout << " Expect invalid. " << endl; + cout << " CVC4: " << smt.query(v) << endl; return 0; } diff --git a/src/expr/expr_template.cpp b/src/expr/expr_template.cpp index 6bcd15027..010b36e94 100644 --- a/src/expr/expr_template.cpp +++ b/src/expr/expr_template.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Kshitij Bansal, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2017 by the authors listed in the file AUTHORS + ** Copyright (c) 2009-2018 by the authors listed in the file AUTHORS ** in the top-level source directory) and their institutional affiliations. ** All rights reserved. See the file COPYING in the top-level source ** directory for licensing information.\endverbatim diff --git a/src/expr/expr_template.h b/src/expr/expr_template.h index 8cc87cfff..cb4534c08 100644 --- a/src/expr/expr_template.h +++ b/src/expr/expr_template.h @@ -2,9 +2,9 @@ /*! \file expr_template.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Dejan Jovanovic, Christopher L. Conway + ** Morgan Deters, Dejan Jovanovic, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2017 by the authors listed in the file AUTHORS + ** Copyright (c) 2009-2018 by the authors listed in the file AUTHORS ** in the top-level source directory) and their institutional affiliations. ** All rights reserved. See the file COPYING in the top-level source ** directory for licensing information.\endverbatim diff --git a/src/parser/smt2/Smt2.g b/src/parser/smt2/Smt2.g index b9a2a8805..889352299 100644 --- a/src/parser/smt2/Smt2.g +++ b/src/parser/smt2/Smt2.g @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2017 by the authors listed in the file AUTHORS + ** Copyright (c) 2009-2018 by the authors listed in the file AUTHORS ** in the top-level source directory) and their institutional affiliations. ** All rights reserved. See the file COPYING in the top-level source ** directory for licensing information.\endverbatim @@ -431,7 +431,7 @@ command [std::unique_ptr* cmd] } } | /* check-sat */ - CHECKSAT_TOK { PARSER_STATE->checkThatLogicIsSet(); } + CHECK_SAT_TOK { PARSER_STATE->checkThatLogicIsSet(); } { if( PARSER_STATE->sygus() ){ PARSER_STATE->parseError("Sygus does not support check-sat command."); } @@ -446,6 +446,16 @@ command [std::unique_ptr* cmd] | { expr = MK_CONST(bool(true)); } ) { cmd->reset(new CheckSatCommand(expr)); } + | /* check-sat-assuming */ + CHECK_SAT_ASSUMING_TOK { PARSER_STATE->checkThatLogicIsSet(); } + ( LPAREN_TOK termList[terms,expr] RPAREN_TOK + { cmd->reset(new CheckSatAssumingCommand(terms)); } + | ~LPAREN_TOK + { PARSER_STATE->parseError("The check-sat-assuming command expects a " + "list of terms. Perhaps you forgot a pair of " + "parentheses?"); + } + ) | /* get-assertions */ GET_ASSERTIONS_TOK { PARSER_STATE->checkThatLogicIsSet(); } { cmd->reset(new GetAssertionsCommand()); } @@ -1276,7 +1286,6 @@ smt25Command[std::unique_ptr* cmd] } cmd->reset( new DefineFunctionRecCommand(funcs,formals,func_defs)); } - // CHECK_SAT_ASSUMING still being discussed // GET_UNSAT_ASSUMPTIONS ; @@ -1713,7 +1722,8 @@ simpleSymbolicExprNoKeyword[CVC4::SExpr& sexpr] // } | symbol[s,CHECK_NONE,SYM_SORT] { sexpr = SExpr(SExpr::Keyword(s)); } - | tok=(ASSERT_TOK | CHECKSAT_TOK | DECLARE_FUN_TOK | DECLARE_SORT_TOK + | tok=(ASSERT_TOK | CHECK_SAT_TOK | CHECK_SAT_ASSUMING_TOK | DECLARE_FUN_TOK + | DECLARE_SORT_TOK | DEFINE_FUN_TOK | DEFINE_FUN_REC_TOK | DEFINE_FUNS_REC_TOK | DEFINE_SORT_TOK | GET_VALUE_TOK | GET_ASSIGNMENT_TOK | GET_ASSERTIONS_TOK | GET_PROOF_TOK | GET_UNSAT_CORE_TOK | EXIT_TOK @@ -3064,7 +3074,8 @@ selector[CVC4::DatatypeConstructor& ctor] // Base SMT-LIB tokens ASSERT_TOK : 'assert'; -CHECKSAT_TOK : 'check-sat'; +CHECK_SAT_TOK : 'check-sat'; +CHECK_SAT_ASSUMING_TOK : 'check-sat-assuming'; DECLARE_FUN_TOK : 'declare-fun'; DECLARE_SORT_TOK : 'declare-sort'; DEFINE_FUN_TOK : 'define-fun'; diff --git a/src/printer/ast/ast_printer.cpp b/src/printer/ast/ast_printer.cpp index be95c947d..31f9b9c41 100644 --- a/src/printer/ast/ast_printer.cpp +++ b/src/printer/ast/ast_printer.cpp @@ -147,6 +147,7 @@ void AstPrinter::toStream(std::ostream& out, tryToStream(out, c) || tryToStream(out, c) || tryToStream(out, c) || + tryToStream(out, c) || tryToStream(out, c) || tryToStream(out, c) || tryToStream(out, c) || @@ -237,6 +238,14 @@ static void toStream(std::ostream& out, const CheckSatCommand* c) } } +static void toStream(std::ostream& out, const CheckSatAssumingCommand* c) +{ + const vector& terms = c->getTerms(); + out << "CheckSatAssuming( << "; + copy(terms.begin(), terms.end(), ostream_iterator(out, ", ")); + out << ">> )"; +} + static void toStream(std::ostream& out, const QueryCommand* c) { out << "Query(" << c->getExpr() << ')'; @@ -333,7 +342,7 @@ static void toStream(std::ostream& out, const GetValueCommand* c) out << "GetValue( << "; const vector& terms = c->getTerms(); copy(terms.begin(), terms.end(), ostream_iterator(out, ", ")); - out << " >> )"; + out << ">> )"; } static void toStream(std::ostream& out, const GetModelCommand* c) diff --git a/src/printer/cvc/cvc_printer.cpp b/src/printer/cvc/cvc_printer.cpp index 27105c3b4..d778ccc2b 100644 --- a/src/printer/cvc/cvc_printer.cpp +++ b/src/printer/cvc/cvc_printer.cpp @@ -2,9 +2,9 @@ /*! \file cvc_printer.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Dejan Jovanovic, Andrew Reynolds + ** Morgan Deters, Tim King, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2017 by the authors listed in the file AUTHORS + ** Copyright (c) 2009-2018 by the authors listed in the file AUTHORS ** in the top-level source directory) and their institutional affiliations. ** All rights reserved. See the file COPYING in the top-level source ** directory for licensing information.\endverbatim @@ -955,6 +955,7 @@ void CvcPrinter::toStream(std::ostream& out, tryToStream(out, c, d_cvc3Mode) || tryToStream(out, c, d_cvc3Mode) || tryToStream(out, c, d_cvc3Mode) || + tryToStream(out, c, d_cvc3Mode) || tryToStream(out, c, d_cvc3Mode) || tryToStream(out, c, d_cvc3Mode) || tryToStream(out, c, d_cvc3Mode) || @@ -1159,6 +1160,31 @@ static void toStream(std::ostream& out, const CheckSatCommand* c, bool cvc3Mode) } } +static void toStream(std::ostream& out, + const CheckSatAssumingCommand* c, + bool cvc3Mode) +{ + const vector& exprs = c->getTerms(); + if (cvc3Mode) + { + out << "PUSH; "; + } + out << "CHECKSAT"; + if (exprs.size() > 0) + { + out << " " << exprs[0]; + for (size_t i = 1, n = exprs.size(); i < n; ++i) + { + out << " AND " << exprs[i]; + } + } + out << ";"; + if (cvc3Mode) + { + out << " POP;"; + } +} + static void toStream(std::ostream& out, const QueryCommand* c, bool cvc3Mode) { Expr e = c->getExpr(); diff --git a/src/printer/smt2/smt2_printer.cpp b/src/printer/smt2/smt2_printer.cpp index e06f8c062..e025c64f1 100644 --- a/src/printer/smt2/smt2_printer.cpp +++ b/src/printer/smt2/smt2_printer.cpp @@ -2,9 +2,9 @@ /*! \file smt2_printer.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Martin Brain + ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2017 by the authors listed in the file AUTHORS + ** Copyright (c) 2009-2018 by the authors listed in the file AUTHORS ** in the top-level source directory) and their institutional affiliations. ** All rights reserved. See the file COPYING in the top-level source ** directory for licensing information.\endverbatim @@ -1191,7 +1191,8 @@ void Smt2Printer::toStream(std::ostream& out, if (tryToStream(out, c) || tryToStream(out, c) || tryToStream(out, c) || tryToStream(out, c) - || tryToStream(out, c) + || tryToStream(out, c) + || tryToStream(out, c, d_variant) || tryToStream(out, c) || tryToStream(out, c) || tryToStream(out, c) @@ -1511,14 +1512,29 @@ static void toStream(std::ostream& out, const CheckSatCommand* c) } } -static void toStream(std::ostream& out, const QueryCommand* c) +static void toStream(std::ostream& out, const CheckSatAssumingCommand* c) +{ + out << "(check-sat-assuming ( "; + const vector& terms = c->getTerms(); + copy(terms.begin(), terms.end(), ostream_iterator(out, " ")); + out << "))"; +} + +static void toStream(std::ostream& out, const QueryCommand* c, Variant v) { Expr e = c->getExpr(); if(!e.isNull()) { - out << PushCommand() << endl - << AssertCommand(BooleanSimplification::negate(e)) << endl - << CheckSatCommand() << endl - << PopCommand(); + if (v == smt2_0_variant) + { + out << PushCommand() << endl + << AssertCommand(BooleanSimplification::negate(e)) << endl + << CheckSatCommand() << endl + << PopCommand(); + } + else + { + out << CheckSatAssumingCommand(e.notExpr()) << endl; + } } else { out << "(check-sat)"; } diff --git a/src/smt/command.cpp b/src/smt/command.cpp index 040d87250..e61ea868f 100644 --- a/src/smt/command.cpp +++ b/src/smt/command.cpp @@ -2,9 +2,9 @@ /*! \file command.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Francois Bobot + ** Tim King, Morgan Deters, Aina Niemetz ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2017 by the authors listed in the file AUTHORS + ** Copyright (c) 2009-2018 by the authors listed in the file AUTHORS ** in the top-level source directory) and their institutional affiliations. ** All rights reserved. See the file COPYING in the top-level source ** directory for licensing information.\endverbatim @@ -104,7 +104,25 @@ ostream& operator<<(ostream& out, const CommandStatus* s) return out; } -/* class CommandPrintSuccess */ + +/* output stream insertion operator for benchmark statuses */ +std::ostream& operator<<(std::ostream& out, BenchmarkStatus status) +{ + switch (status) + { + case SMT_SATISFIABLE: return out << "sat"; + + case SMT_UNSATISFIABLE: return out << "unsat"; + + case SMT_UNKNOWN: return out << "unknown"; + + default: return out << "BenchmarkStatus::[UNKNOWNSTATUS!]"; + } +} + +/* -------------------------------------------------------------------------- */ +/* class CommandPrintSuccess */ +/* -------------------------------------------------------------------------- */ void CommandPrintSuccess::applyPrintSuccess(std::ostream& out) { @@ -127,7 +145,9 @@ std::ostream& operator<<(std::ostream& out, CommandPrintSuccess cps) return out; } -/* class Command */ +/* -------------------------------------------------------------------------- */ +/* class Command */ +/* -------------------------------------------------------------------------- */ Command::Command() : d_commandStatus(NULL), d_muted(false) {} Command::Command(const Command& cmd) @@ -208,7 +228,9 @@ void Command::printResult(std::ostream& out, uint32_t verbosity) const } } -/* class EmptyCommand */ +/* -------------------------------------------------------------------------- */ +/* class EmptyCommand */ +/* -------------------------------------------------------------------------- */ EmptyCommand::EmptyCommand(std::string name) : d_name(name) {} std::string EmptyCommand::getName() const { return d_name; } @@ -226,7 +248,10 @@ Command* EmptyCommand::exportTo(ExprManager* exprManager, Command* EmptyCommand::clone() const { return new EmptyCommand(d_name); } std::string EmptyCommand::getCommandName() const { return "empty"; } -/* class EchoCommand */ + +/* -------------------------------------------------------------------------- */ +/* class EchoCommand */ +/* -------------------------------------------------------------------------- */ EchoCommand::EchoCommand(std::string output) : d_output(output) {} std::string EchoCommand::getOutput() const { return d_output; } @@ -254,7 +279,10 @@ Command* EchoCommand::exportTo(ExprManager* exprManager, Command* EchoCommand::clone() const { return new EchoCommand(d_output); } std::string EchoCommand::getCommandName() const { return "echo"; } -/* class AssertCommand */ + +/* -------------------------------------------------------------------------- */ +/* class AssertCommand */ +/* -------------------------------------------------------------------------- */ AssertCommand::AssertCommand(const Expr& e, bool inUnsatCore) : d_expr(e), d_inUnsatCore(inUnsatCore) @@ -292,7 +320,10 @@ Command* AssertCommand::clone() const } std::string AssertCommand::getCommandName() const { return "assert"; } -/* class PushCommand */ + +/* -------------------------------------------------------------------------- */ +/* class PushCommand */ +/* -------------------------------------------------------------------------- */ void PushCommand::invoke(SmtEngine* smtEngine) { @@ -319,7 +350,10 @@ Command* PushCommand::exportTo(ExprManager* exprManager, Command* PushCommand::clone() const { return new PushCommand(); } std::string PushCommand::getCommandName() const { return "push"; } -/* class PopCommand */ + +/* -------------------------------------------------------------------------- */ +/* class PopCommand */ +/* -------------------------------------------------------------------------- */ void PopCommand::invoke(SmtEngine* smtEngine) { @@ -346,7 +380,10 @@ Command* PopCommand::exportTo(ExprManager* exprManager, Command* PopCommand::clone() const { return new PopCommand(); } std::string PopCommand::getCommandName() const { return "pop"; } -/* class CheckSatCommand */ + +/* -------------------------------------------------------------------------- */ +/* class CheckSatCommand */ +/* -------------------------------------------------------------------------- */ CheckSatCommand::CheckSatCommand() : d_expr() {} CheckSatCommand::CheckSatCommand(const Expr& expr, bool inUnsatCore) @@ -398,7 +435,90 @@ Command* CheckSatCommand::clone() const } std::string CheckSatCommand::getCommandName() const { return "check-sat"; } -/* class QueryCommand */ + +/* -------------------------------------------------------------------------- */ +/* class CheckSatAssumingCommand */ +/* -------------------------------------------------------------------------- */ + +CheckSatAssumingCommand::CheckSatAssumingCommand(Expr term) : d_terms() +{ + d_terms.push_back(term); +} + +CheckSatAssumingCommand::CheckSatAssumingCommand(const std::vector& terms, + bool inUnsatCore) + : d_terms(terms), d_inUnsatCore(inUnsatCore) +{ + PrettyCheckArgument( + terms.size() >= 1, terms, "cannot get-value of an empty set of terms"); +} + +const std::vector& CheckSatAssumingCommand::getTerms() const +{ + return d_terms; +} + +void CheckSatAssumingCommand::invoke(SmtEngine* smtEngine) +{ + try + { + d_result = smtEngine->checkSat(d_terms); + d_commandStatus = CommandSuccess::instance(); + } + catch (exception& e) + { + d_commandStatus = new CommandFailure(e.what()); + } +} + +Result CheckSatAssumingCommand::getResult() const +{ + return d_result; +} + +void CheckSatAssumingCommand::printResult(std::ostream& out, + uint32_t verbosity) const +{ + if (!ok()) + { + this->Command::printResult(out, verbosity); + } + else + { + out << d_result << endl; + } +} + +Command* CheckSatAssumingCommand::exportTo( + ExprManager* exprManager, ExprManagerMapCollection& variableMap) +{ + vector exportedTerms; + for (const Expr& e : d_terms) + { + exportedTerms.push_back(e.exportTo(exprManager, variableMap)); + } + CheckSatAssumingCommand* c = + new CheckSatAssumingCommand(exportedTerms, d_inUnsatCore); + c->d_result = d_result; + return c; +} + +Command* CheckSatAssumingCommand::clone() const +{ + CheckSatAssumingCommand* c = + new CheckSatAssumingCommand(d_terms, d_inUnsatCore); + c->d_result = d_result; + return c; +} + +std::string CheckSatAssumingCommand::getCommandName() const +{ + return "check-sat-assuming"; +} + +/* -------------------------------------------------------------------------- */ +/* class QueryCommand */ +/* -------------------------------------------------------------------------- */ QueryCommand::QueryCommand(const Expr& e, bool inUnsatCore) : d_expr(e), d_inUnsatCore(inUnsatCore) @@ -449,7 +569,10 @@ Command* QueryCommand::clone() const } std::string QueryCommand::getCommandName() const { return "query"; } -/* class CheckSynthCommand */ + +/* -------------------------------------------------------------------------- */ +/* class CheckSynthCommand */ +/* -------------------------------------------------------------------------- */ CheckSynthCommand::CheckSynthCommand() : d_expr() {} CheckSynthCommand::CheckSynthCommand(const Expr& expr) : d_expr(expr) {} @@ -524,7 +647,10 @@ Command* CheckSynthCommand::clone() const } std::string CheckSynthCommand::getCommandName() const { return "check-synth"; } -/* class ResetCommand */ + +/* -------------------------------------------------------------------------- */ +/* class ResetCommand */ +/* -------------------------------------------------------------------------- */ void ResetCommand::invoke(SmtEngine* smtEngine) { @@ -547,7 +673,10 @@ Command* ResetCommand::exportTo(ExprManager* exprManager, Command* ResetCommand::clone() const { return new ResetCommand(); } std::string ResetCommand::getCommandName() const { return "reset"; } -/* class ResetAssertionsCommand */ + +/* -------------------------------------------------------------------------- */ +/* class ResetAssertionsCommand */ +/* -------------------------------------------------------------------------- */ void ResetAssertionsCommand::invoke(SmtEngine* smtEngine) { @@ -578,7 +707,9 @@ std::string ResetAssertionsCommand::getCommandName() const return "reset-assertions"; } -/* class QuitCommand */ +/* -------------------------------------------------------------------------- */ +/* class QuitCommand */ +/* -------------------------------------------------------------------------- */ void QuitCommand::invoke(SmtEngine* smtEngine) { @@ -594,7 +725,10 @@ Command* QuitCommand::exportTo(ExprManager* exprManager, Command* QuitCommand::clone() const { return new QuitCommand(); } std::string QuitCommand::getCommandName() const { return "exit"; } -/* class CommentCommand */ + +/* -------------------------------------------------------------------------- */ +/* class CommentCommand */ +/* -------------------------------------------------------------------------- */ CommentCommand::CommentCommand(std::string comment) : d_comment(comment) {} std::string CommentCommand::getComment() const { return d_comment; } @@ -612,7 +746,10 @@ Command* CommentCommand::exportTo(ExprManager* exprManager, Command* CommentCommand::clone() const { return new CommentCommand(d_comment); } std::string CommentCommand::getCommandName() const { return "comment"; } -/* class CommandSequence */ + +/* -------------------------------------------------------------------------- */ +/* class CommandSequence */ +/* -------------------------------------------------------------------------- */ CommandSequence::CommandSequence() : d_index(0) {} CommandSequence::~CommandSequence() @@ -712,9 +849,10 @@ CommandSequence::iterator CommandSequence::end() } std::string CommandSequence::getCommandName() const { return "sequence"; } -/* class DeclarationSequenceCommand */ -/* class DeclarationDefinitionCommand */ +/* -------------------------------------------------------------------------- */ +/* class DeclarationDefinitionCommand */ +/* -------------------------------------------------------------------------- */ DeclarationDefinitionCommand::DeclarationDefinitionCommand( const std::string& id) @@ -723,7 +861,10 @@ DeclarationDefinitionCommand::DeclarationDefinitionCommand( } std::string DeclarationDefinitionCommand::getSymbol() const { return d_symbol; } -/* class DeclareFunctionCommand */ + +/* -------------------------------------------------------------------------- */ +/* class DeclareFunctionCommand */ +/* -------------------------------------------------------------------------- */ DeclareFunctionCommand::DeclareFunctionCommand(const std::string& id, Expr func, @@ -781,7 +922,9 @@ std::string DeclareFunctionCommand::getCommandName() const return "declare-fun"; } -/* class DeclareTypeCommand */ +/* -------------------------------------------------------------------------- */ +/* class DeclareTypeCommand */ +/* -------------------------------------------------------------------------- */ DeclareTypeCommand::DeclareTypeCommand(const std::string& id, size_t arity, @@ -814,7 +957,9 @@ std::string DeclareTypeCommand::getCommandName() const return "declare-sort"; } -/* class DefineTypeCommand */ +/* -------------------------------------------------------------------------- */ +/* class DefineTypeCommand */ +/* -------------------------------------------------------------------------- */ DefineTypeCommand::DefineTypeCommand(const std::string& id, Type t) : DeclarationDefinitionCommand(id), d_params(), d_type(t) @@ -857,7 +1002,10 @@ Command* DefineTypeCommand::clone() const } std::string DefineTypeCommand::getCommandName() const { return "define-sort"; } -/* class DefineFunctionCommand */ + +/* -------------------------------------------------------------------------- */ +/* class DefineFunctionCommand */ +/* -------------------------------------------------------------------------- */ DefineFunctionCommand::DefineFunctionCommand(const std::string& id, Expr func, @@ -927,7 +1075,9 @@ std::string DefineFunctionCommand::getCommandName() const return "define-fun"; } -/* class DefineNamedFunctionCommand */ +/* -------------------------------------------------------------------------- */ +/* class DefineNamedFunctionCommand */ +/* -------------------------------------------------------------------------- */ DefineNamedFunctionCommand::DefineNamedFunctionCommand( const std::string& id, @@ -967,7 +1117,9 @@ Command* DefineNamedFunctionCommand::clone() const return new DefineNamedFunctionCommand(d_symbol, d_func, d_formals, d_formula); } -/* class DefineFunctionRecCommand */ +/* -------------------------------------------------------------------------- */ +/* class DefineFunctionRecCommand */ +/* -------------------------------------------------------------------------- */ DefineFunctionRecCommand::DefineFunctionRecCommand( Expr func, const std::vector& formals, Expr formula) @@ -979,7 +1131,7 @@ DefineFunctionRecCommand::DefineFunctionRecCommand( DefineFunctionRecCommand::DefineFunctionRecCommand( const std::vector& funcs, - const std::vector >& formals, + const std::vector>& formals, const std::vector& formulas) { d_funcs.insert(d_funcs.end(), funcs.begin(), funcs.end()); @@ -992,7 +1144,7 @@ const std::vector& DefineFunctionRecCommand::getFunctions() const return d_funcs; } -const std::vector >& DefineFunctionRecCommand::getFormals() +const std::vector>& DefineFunctionRecCommand::getFormals() const { return d_formals; @@ -1026,7 +1178,7 @@ Command* DefineFunctionRecCommand::exportTo( exprManager, variableMap, /* flags = */ ExprManager::VAR_FLAG_DEFINED); funcs.push_back(func); } - std::vector > formals; + std::vector> formals; for (unsigned i = 0, size = d_formals.size(); i < size; i++) { std::vector formals_c; @@ -1055,7 +1207,9 @@ std::string DefineFunctionRecCommand::getCommandName() const return "define-fun-rec"; } -/* class SetUserAttribute */ +/* -------------------------------------------------------------------------- */ +/* class SetUserAttribute */ +/* -------------------------------------------------------------------------- */ SetUserAttributeCommand::SetUserAttributeCommand( const std::string& attr, @@ -1122,7 +1276,9 @@ std::string SetUserAttributeCommand::getCommandName() const return "set-user-attribute"; } -/* class SimplifyCommand */ +/* -------------------------------------------------------------------------- */ +/* class SimplifyCommand */ +/* -------------------------------------------------------------------------- */ SimplifyCommand::SimplifyCommand(Expr term) : d_term(term) {} Expr SimplifyCommand::getTerm() const { return d_term; } @@ -1173,7 +1329,10 @@ Command* SimplifyCommand::clone() const } std::string SimplifyCommand::getCommandName() const { return "simplify"; } -/* class ExpandDefinitionsCommand */ + +/* -------------------------------------------------------------------------- */ +/* class ExpandDefinitionsCommand */ +/* -------------------------------------------------------------------------- */ ExpandDefinitionsCommand::ExpandDefinitionsCommand(Expr term) : d_term(term) {} Expr ExpandDefinitionsCommand::getTerm() const { return d_term; } @@ -1218,7 +1377,9 @@ std::string ExpandDefinitionsCommand::getCommandName() const return "expand-definitions"; } -/* class GetValueCommand */ +/* -------------------------------------------------------------------------- */ +/* class GetValueCommand */ +/* -------------------------------------------------------------------------- */ GetValueCommand::GetValueCommand(Expr term) : d_terms() { @@ -1240,15 +1401,13 @@ void GetValueCommand::invoke(SmtEngine* smtEngine) vector result; ExprManager* em = smtEngine->getExprManager(); NodeManager* nm = NodeManager::fromExprManager(em); - for (std::vector::const_iterator i = d_terms.begin(); - i != d_terms.end(); - ++i) + for (const Expr& e : d_terms) { - Assert(nm == NodeManager::fromExprManager((*i).getExprManager())); + Assert(nm == NodeManager::fromExprManager(e.getExprManager())); smt::SmtScope scope(smtEngine); Node request = Node::fromExpr( - options::expandDefinitions() ? smtEngine->expandDefinitions(*i) : *i); - Node value = Node::fromExpr(smtEngine->getValue(*i)); + options::expandDefinitions() ? smtEngine->expandDefinitions(e) : e); + Node value = Node::fromExpr(smtEngine->getValue(e)); if (value.getType().isInteger() && request.getType() == nm->realType()) { // Need to wrap in special marker so that output printers know this @@ -1314,14 +1473,17 @@ Command* GetValueCommand::clone() const } std::string GetValueCommand::getCommandName() const { return "get-value"; } -/* class GetAssignmentCommand */ + +/* -------------------------------------------------------------------------- */ +/* class GetAssignmentCommand */ +/* -------------------------------------------------------------------------- */ GetAssignmentCommand::GetAssignmentCommand() {} void GetAssignmentCommand::invoke(SmtEngine* smtEngine) { try { - std::vector> assignments = smtEngine->getAssignment(); + std::vector> assignments = smtEngine->getAssignment(); vector sexprs; for (const auto& p : assignments) { @@ -1388,7 +1550,9 @@ std::string GetAssignmentCommand::getCommandName() const return "get-assignment"; } -/* class GetModelCommand */ +/* -------------------------------------------------------------------------- */ +/* class GetModelCommand */ +/* -------------------------------------------------------------------------- */ GetModelCommand::GetModelCommand() : d_result(nullptr), d_smtEngine(nullptr) {} void GetModelCommand::invoke(SmtEngine* smtEngine) @@ -1449,7 +1613,10 @@ Command* GetModelCommand::clone() const } std::string GetModelCommand::getCommandName() const { return "get-model"; } -/* class GetProofCommand */ + +/* -------------------------------------------------------------------------- */ +/* class GetProofCommand */ +/* -------------------------------------------------------------------------- */ GetProofCommand::GetProofCommand() : d_smtEngine(nullptr), d_result(nullptr) {} void GetProofCommand::invoke(SmtEngine* smtEngine) @@ -1506,7 +1673,10 @@ Command* GetProofCommand::clone() const } std::string GetProofCommand::getCommandName() const { return "get-proof"; } -/* class GetInstantiationsCommand */ + +/* -------------------------------------------------------------------------- */ +/* class GetInstantiationsCommand */ +/* -------------------------------------------------------------------------- */ GetInstantiationsCommand::GetInstantiationsCommand() : d_smtEngine(nullptr) {} void GetInstantiationsCommand::invoke(SmtEngine* smtEngine) @@ -1557,7 +1727,9 @@ std::string GetInstantiationsCommand::getCommandName() const return "get-instantiations"; } -/* class GetSynthSolutionCommand */ +/* -------------------------------------------------------------------------- */ +/* class GetSynthSolutionCommand */ +/* -------------------------------------------------------------------------- */ GetSynthSolutionCommand::GetSynthSolutionCommand() : d_smtEngine(nullptr) {} void GetSynthSolutionCommand::invoke(SmtEngine* smtEngine) @@ -1606,7 +1778,9 @@ std::string GetSynthSolutionCommand::getCommandName() const return "get-instantiations"; } -/* class GetQuantifierEliminationCommand */ +/* -------------------------------------------------------------------------- */ +/* class GetQuantifierEliminationCommand */ +/* -------------------------------------------------------------------------- */ GetQuantifierEliminationCommand::GetQuantifierEliminationCommand() : d_expr() {} GetQuantifierEliminationCommand::GetQuantifierEliminationCommand( @@ -1666,7 +1840,9 @@ std::string GetQuantifierEliminationCommand::getCommandName() const return d_doFull ? "get-qe" : "get-qe-disjunct"; } -/* class GetUnsatCoreCommand */ +/* -------------------------------------------------------------------------- */ +/* class GetUnsatCoreCommand */ +/* -------------------------------------------------------------------------- */ GetUnsatCoreCommand::GetUnsatCoreCommand() {} void GetUnsatCoreCommand::invoke(SmtEngine* smtEngine) @@ -1725,7 +1901,9 @@ std::string GetUnsatCoreCommand::getCommandName() const return "get-unsat-core"; } -/* class GetAssertionsCommand */ +/* -------------------------------------------------------------------------- */ +/* class GetAssertionsCommand */ +/* -------------------------------------------------------------------------- */ GetAssertionsCommand::GetAssertionsCommand() {} void GetAssertionsCommand::invoke(SmtEngine* smtEngine) @@ -1780,7 +1958,9 @@ std::string GetAssertionsCommand::getCommandName() const return "get-assertions"; } -/* class SetBenchmarkStatusCommand */ +/* -------------------------------------------------------------------------- */ +/* class SetBenchmarkStatusCommand */ +/* -------------------------------------------------------------------------- */ SetBenchmarkStatusCommand::SetBenchmarkStatusCommand(BenchmarkStatus status) : d_status(status) @@ -1824,7 +2004,9 @@ std::string SetBenchmarkStatusCommand::getCommandName() const return "set-info"; } -/* class SetBenchmarkLogicCommand */ +/* -------------------------------------------------------------------------- */ +/* class SetBenchmarkLogicCommand */ +/* -------------------------------------------------------------------------- */ SetBenchmarkLogicCommand::SetBenchmarkLogicCommand(std::string logic) : d_logic(logic) @@ -1861,7 +2043,9 @@ std::string SetBenchmarkLogicCommand::getCommandName() const return "set-logic"; } -/* class SetInfoCommand */ +/* -------------------------------------------------------------------------- */ +/* class SetInfoCommand */ +/* -------------------------------------------------------------------------- */ SetInfoCommand::SetInfoCommand(std::string flag, const SExpr& sexpr) : d_flag(flag), d_sexpr(sexpr) @@ -1900,7 +2084,10 @@ Command* SetInfoCommand::clone() const } std::string SetInfoCommand::getCommandName() const { return "set-info"; } -/* class GetInfoCommand */ + +/* -------------------------------------------------------------------------- */ +/* class GetInfoCommand */ +/* -------------------------------------------------------------------------- */ GetInfoCommand::GetInfoCommand(std::string flag) : d_flag(flag) {} std::string GetInfoCommand::getFlag() const { return d_flag; } @@ -1959,7 +2146,10 @@ Command* GetInfoCommand::clone() const } std::string GetInfoCommand::getCommandName() const { return "get-info"; } -/* class SetOptionCommand */ + +/* -------------------------------------------------------------------------- */ +/* class SetOptionCommand */ +/* -------------------------------------------------------------------------- */ SetOptionCommand::SetOptionCommand(std::string flag, const SExpr& sexpr) : d_flag(flag), d_sexpr(sexpr) @@ -1997,7 +2187,10 @@ Command* SetOptionCommand::clone() const } std::string SetOptionCommand::getCommandName() const { return "set-option"; } -/* class GetOptionCommand */ + +/* -------------------------------------------------------------------------- */ +/* class GetOptionCommand */ +/* -------------------------------------------------------------------------- */ GetOptionCommand::GetOptionCommand(std::string flag) : d_flag(flag) {} std::string GetOptionCommand::getFlag() const { return d_flag; } @@ -2048,7 +2241,10 @@ Command* GetOptionCommand::clone() const } std::string GetOptionCommand::getCommandName() const { return "get-option"; } -/* class SetExpressionNameCommand */ + +/* -------------------------------------------------------------------------- */ +/* class SetExpressionNameCommand */ +/* -------------------------------------------------------------------------- */ SetExpressionNameCommand::SetExpressionNameCommand(Expr expr, std::string name) : d_expr(expr), d_name(name) @@ -2080,7 +2276,9 @@ std::string SetExpressionNameCommand::getCommandName() const return "set-expr-name"; } -/* class DatatypeDeclarationCommand */ +/* -------------------------------------------------------------------------- */ +/* class DatatypeDeclarationCommand */ +/* -------------------------------------------------------------------------- */ DatatypeDeclarationCommand::DatatypeDeclarationCommand( const DatatypeType& datatype) @@ -2123,7 +2321,9 @@ std::string DatatypeDeclarationCommand::getCommandName() const return "declare-datatypes"; } -/* class RewriteRuleCommand */ +/* -------------------------------------------------------------------------- */ +/* class RewriteRuleCommand */ +/* -------------------------------------------------------------------------- */ RewriteRuleCommand::RewriteRuleCommand(const std::vector& vars, const std::vector& guards, @@ -2235,7 +2435,9 @@ std::string RewriteRuleCommand::getCommandName() const return "rewrite-rule"; } -/* class PropagateRuleCommand */ +/* -------------------------------------------------------------------------- */ +/* class PropagateRuleCommand */ +/* -------------------------------------------------------------------------- */ PropagateRuleCommand::PropagateRuleCommand(const std::vector& vars, const std::vector& guards, @@ -2366,20 +2568,4 @@ std::string PropagateRuleCommand::getCommandName() const { return "propagate-rule"; } - -/* output stream insertion operator for benchmark statuses */ -std::ostream& operator<<(std::ostream& out, BenchmarkStatus status) -{ - switch (status) - { - case SMT_SATISFIABLE: return out << "sat"; - - case SMT_UNSATISFIABLE: return out << "unsat"; - - case SMT_UNKNOWN: return out << "unknown"; - - default: return out << "BenchmarkStatus::[UNKNOWNSTATUS!]"; - } -} - -} /* CVC4 namespace */ +} // namespace CVC4 diff --git a/src/smt/command.h b/src/smt/command.h index 9573e1c22..19bf9fddd 100644 --- a/src/smt/command.h +++ b/src/smt/command.h @@ -2,9 +2,9 @@ /*! \file command.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Andres Noetzli + ** Tim King, Morgan Deters, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2017 by the authors listed in the file AUTHORS + ** Copyright (c) 2009-2018 by the authors listed in the file AUTHORS ** in the top-level source directory) and their institutional affiliations. ** All rights reserved. See the file COPYING in the top-level source ** directory for licensing information.\endverbatim @@ -544,13 +544,12 @@ class CVC4_PUBLIC SetUserAttributeCommand : public Command const std::string d_str_value; }; /* class SetUserAttributeCommand */ +/** + * The command when parsing check-sat. + * This command will check satisfiability of the input formula. + */ class CVC4_PUBLIC CheckSatCommand : public Command { - protected: - Expr d_expr; - Result d_result; - bool d_inUnsatCore; - public: CheckSatCommand(); CheckSatCommand(const Expr& expr, bool inUnsatCore = true); @@ -563,8 +562,40 @@ class CVC4_PUBLIC CheckSatCommand : public Command ExprManagerMapCollection& variableMap) override; Command* clone() const override; std::string getCommandName() const override; + + private: + Expr d_expr; + Result d_result; + bool d_inUnsatCore; }; /* class CheckSatCommand */ +/** + * The command when parsing check-sat-assuming. + * This command will assume a set of formulas and check satisfiability of the + * input formula under these assumptions. + */ +class CVC4_PUBLIC CheckSatAssumingCommand : public Command +{ + public: + CheckSatAssumingCommand(Expr term); + CheckSatAssumingCommand(const std::vector& terms, + bool inUnsatCore = true); + + const std::vector& getTerms() const; + Result getResult() const; + void invoke(SmtEngine* smtEngine) override; + void printResult(std::ostream& out, uint32_t verbosity = 2) const override; + Command* exportTo(ExprManager* exprManager, + ExprManagerMapCollection& variableMap) override; + Command* clone() const override; + std::string getCommandName() const override; + + private: + std::vector d_terms; + Result d_result; + bool d_inUnsatCore; +}; /* class CheckSatAssumingCommand */ + class CVC4_PUBLIC QueryCommand : public Command { protected: diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp index 19236f881..6e90ab152 100644 --- a/src/smt/smt_engine.cpp +++ b/src/smt/smt_engine.cpp @@ -2,9 +2,9 @@ /*! \file smt_engine.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Andrew Reynolds + ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2017 by the authors listed in the file AUTHORS + ** Copyright (c) 2009-2018 by the authors listed in the file AUTHORS ** in the top-level source directory) and their institutional affiliations. ** All rights reserved. See the file COPYING in the top-level source ** directory for licensing information.\endverbatim @@ -4683,22 +4683,46 @@ void SmtEngine::ensureBoolean(const Expr& e) Result SmtEngine::checkSat(const Expr& ex, bool inUnsatCore) { return checkSatisfiability(ex, inUnsatCore, false); -} /* SmtEngine::checkSat() */ +} + +Result SmtEngine::checkSat(const vector& exprs, bool inUnsatCore) +{ + return checkSatisfiability(exprs, inUnsatCore, false); +} Result SmtEngine::query(const Expr& ex, bool inUnsatCore) { Assert(!ex.isNull()); return checkSatisfiability(ex, inUnsatCore, true); -} /* SmtEngine::query() */ +} -Result SmtEngine::checkSatisfiability(const Expr& ex, bool inUnsatCore, bool isQuery) { - try { - Assert(ex.isNull() || ex.getExprManager() == d_exprManager); +Result SmtEngine::query(const vector& exprs, bool inUnsatCore) +{ + return checkSatisfiability(exprs, inUnsatCore, true); +} + +Result SmtEngine::checkSatisfiability(const Expr& expr, + bool inUnsatCore, + bool isQuery) +{ + return checkSatisfiability( + expr.isNull() ? vector() : vector{expr}, + inUnsatCore, + isQuery); +} + +Result SmtEngine::checkSatisfiability(const vector& exprs, + bool inUnsatCore, + bool isQuery) +{ + try + { SmtScope smts(this); finalOptionsAreSet(); doPendingPops(); - Trace("smt") << "SmtEngine::" << (isQuery ? "query" : "checkSat") << "(" << ex << ")" << endl; + Trace("smt") << "SmtEngine::" << (isQuery ? "query" : "checkSat") << "(" + << exprs << ")" << endl; if(d_queryMade && !options::incrementalSolving()) { throw ModalException("Cannot make multiple queries unless " @@ -4706,45 +4730,64 @@ Result SmtEngine::checkSatisfiability(const Expr& ex, bool inUnsatCore, bool isQ "(try --incremental)"); } - Expr e; - if(!ex.isNull()) { - // Substitute out any abstract values in ex. - e = d_private->substituteAbstractValues(Node::fromExpr(ex)).toExpr(); - // Ensure expr is type-checked at this point. - ensureBoolean(e); - } - // check to see if a postsolve() is pending if(d_needPostsolve) { d_theoryEngine->postsolve(); d_needPostsolve = false; } - // Note that a query has been made d_queryMade = true; - // reset global negation d_globalNegation = false; bool didInternalPush = false; - // Add the formula - if(!e.isNull()) { - // Push the context + + vector t_exprs; + if (isQuery) + { + size_t size = exprs.size(); + if (size > 1) + { + /* Assume: not (BIGAND exprs) */ + t_exprs.push_back(d_exprManager->mkExpr(kind::AND, exprs).notExpr()); + } + else if (size == 1) + { + /* Assume: not expr */ + t_exprs.push_back(exprs[0].notExpr()); + } + } + else + { + /* Assume: BIGAND exprs */ + t_exprs = exprs; + } + + Result r(Result::SAT_UNKNOWN, Result::UNKNOWN_REASON); + for (Expr e : t_exprs) + { + // Substitute out any abstract values in ex. + e = d_private->substituteAbstractValues(Node::fromExpr(e)).toExpr(); + Assert(e.getExprManager() == d_exprManager); + // Ensure expr is type-checked at this point. + ensureBoolean(e); + + /* Add assumption */ internalPush(); didInternalPush = true; - d_problemExtended = true; - Expr ea = isQuery ? e.notExpr() : e; - if(d_assertionList != NULL) { - d_assertionList->push_back(ea); + if (d_assertionList != NULL) + { + d_assertionList->push_back(e); } - d_private->addFormula(ea.getNode(), inUnsatCore); + d_private->addFormula(e.getNode(), inUnsatCore); } - Result r(Result::SAT_UNKNOWN, Result::UNKNOWN_REASON); r = isQuery ? check().asValidityResult() : check().asSatisfiabilityResult(); - if ( ( options::solveRealAsInt() || options::solveIntAsBV() > 0 ) && r.asSatisfiabilityResult().isSat() == Result::UNSAT) { + if ((options::solveRealAsInt() || options::solveIntAsBV() > 0) + && r.asSatisfiabilityResult().isSat() == Result::UNSAT) + { r = Result(Result::SAT_UNKNOWN, Result::UNKNOWN_REASON); } // flipped if we did a global negation @@ -4773,12 +4816,16 @@ Result SmtEngine::checkSatisfiability(const Expr& ex, bool inUnsatCore, bool isQ d_needPostsolve = true; // Dump the query if requested - if(Dump.isOn("benchmark")) { + if (Dump.isOn("benchmark")) + { // the expr already got dumped out if assertion-dumping is on - if( isQuery ){ - Dump("benchmark") << QueryCommand(ex); - }else{ - Dump("benchmark") << CheckSatCommand(ex); + if (isQuery && exprs.size() == 1) + { + Dump("benchmark") << QueryCommand(exprs[0]); + } + else + { + Dump("benchmark") << CheckSatAssumingCommand(t_exprs, inUnsatCore); } } @@ -4793,7 +4840,8 @@ Result SmtEngine::checkSatisfiability(const Expr& ex, bool inUnsatCore, bool isQ d_problemExtended = false; - Trace("smt") << "SmtEngine::" << (isQuery ? "query" : "checkSat") << "(" << e << ") => " << r << endl; + Trace("smt") << "SmtEngine::" << (isQuery ? "query" : "checkSat") << "(" + << exprs << ") => " << r << endl; // Check that SAT results generate a model correctly. if(options::checkModels()) { diff --git a/src/smt/smt_engine.h b/src/smt/smt_engine.h index 16cf90de1..bba6b1cef 100644 --- a/src/smt/smt_engine.h +++ b/src/smt/smt_engine.h @@ -400,7 +400,12 @@ class CVC4_PUBLIC SmtEngine { SmtEngine& operator=(const SmtEngine&) CVC4_UNDEFINED; //check satisfiability (for query and check-sat) - Result checkSatisfiability(const Expr& e, bool inUnsatCore, bool isQuery); + Result checkSatisfiability(const Expr& expr, + bool inUnsatCore, + bool isQuery); + Result checkSatisfiability(const std::vector& exprs, + bool inUnsatCore, + bool isQuery); /** * Check that all Expr in formals are of BOUND_VARIABLE kind, where func is @@ -535,7 +540,10 @@ class CVC4_PUBLIC SmtEngine { * of assertions by asserting the query expression's negation and * calling check(). Returns valid, invalid, or unknown result. */ - Result query(const Expr& e, bool inUnsatCore = true) /* throw(Exception) */; + Result query(const Expr& e = Expr(), + bool inUnsatCore = true) /* throw(Exception) */; + Result query(const std::vector& exprs, + bool inUnsatCore = true) /* throw(Exception) */; /** * Assert a formula (if provided) to the current context and call @@ -543,6 +551,8 @@ class CVC4_PUBLIC SmtEngine { */ Result checkSat(const Expr& e = Expr(), bool inUnsatCore = true) /* throw(Exception) */; + Result checkSat(const std::vector& exprs, + bool inUnsatCore = true) /* throw(Exception) */; /** * Assert a synthesis conjecture to the current context and call diff --git a/test/regress/regress0/push-pop/Makefile.am b/test/regress/regress0/push-pop/Makefile.am index 06225dfb6..b78c48549 100644 --- a/test/regress/regress0/push-pop/Makefile.am +++ b/test/regress/regress0/push-pop/Makefile.am @@ -39,7 +39,8 @@ BUG_TESTS = \ inc-define.smt2 \ bug691.smt2 \ simple_unsat_cores.smt2 \ - bug821.smt2 + bug821.smt2 \ + bug821-check_sat_assuming.smt2 TESTS = $(SMT_TESTS) $(SMT2_TESTS) $(CVC_TESTS) $(BUG_TESTS) diff --git a/test/regress/regress0/push-pop/bug821-check_sat_assuming.smt2 b/test/regress/regress0/push-pop/bug821-check_sat_assuming.smt2 new file mode 100644 index 000000000..50e440689 --- /dev/null +++ b/test/regress/regress0/push-pop/bug821-check_sat_assuming.smt2 @@ -0,0 +1,9 @@ +; COMMAND-LINE: --incremental +; EXPECT: sat +; EXPECT: unsat +; EXPECT: sat +(set-logic UF) +(declare-fun _substvar_4_ () Bool) +(check-sat-assuming (_substvar_4_ _substvar_4_)) +(check-sat-assuming (_substvar_4_ false)) +(check-sat-assuming ((= _substvar_4_ _substvar_4_))) -- cgit v1.2.3 From a2e78ec8dd5e935b6ef166154be7ee35bffc6d32 Mon Sep 17 00:00:00 2001 From: Andrew Reynolds Date: Mon, 5 Mar 2018 16:53:44 -0600 Subject: Fix for sampler. (#1639) --- src/theory/quantifiers/sygus_sampler.cpp | 21 ++++++++++++++------- src/theory/quantifiers/sygus_sampler.h | 3 ++- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/theory/quantifiers/sygus_sampler.cpp b/src/theory/quantifiers/sygus_sampler.cpp index 0b9254818..65883502f 100644 --- a/src/theory/quantifiers/sygus_sampler.cpp +++ b/src/theory/quantifiers/sygus_sampler.cpp @@ -303,7 +303,7 @@ Node SygusSampler::registerTerm(Node n, bool forceKeep) Node res = d_trie.add(bn, this, 0, d_samples.size(), forceKeep); if (d_use_sygus_type) { - Assert(d_builtin_to_sygus.find(res) == d_builtin_to_sygus.end()); + Assert(d_builtin_to_sygus.find(res) != d_builtin_to_sygus.end()); res = res != bn ? d_builtin_to_sygus[res] : n; } return res; @@ -690,9 +690,16 @@ Node SygusSamplerExt::registerTerm(Node n, bool forceKeep) { return n; } + Node bn = n; + Node beq_n = eq_n; + if (d_use_sygus_type) + { + bn = d_tds->sygusToBuiltin(n); + beq_n = d_tds->sygusToBuiltin(eq_n); + } // one of eq_n or n must be ordered - bool eqor = isOrdered(eq_n); - bool nor = isOrdered(n); + bool eqor = isOrdered(beq_n); + bool nor = isOrdered(bn); Trace("sygus-synth-rr-debug") << "Ordered? : " << nor << " " << eqor << std::endl; bool isUnique = false; @@ -703,11 +710,11 @@ Node SygusSamplerExt::registerTerm(Node n, bool forceKeep) // free variables of the other if (!eqor) { - isUnique = containsFreeVariables(n, eq_n); + isUnique = containsFreeVariables(bn, beq_n); } else if (!nor) { - isUnique = containsFreeVariables(eq_n, n); + isUnique = containsFreeVariables(beq_n, bn); } } Trace("sygus-synth-rr-debug") << "AlphaEq unique: " << isUnique << std::endl; @@ -715,7 +722,7 @@ Node SygusSamplerExt::registerTerm(Node n, bool forceKeep) if (d_drewrite != nullptr) { Trace("sygus-synth-rr-debug") << "Add rewrite..." << std::endl; - if (!d_drewrite->addRewrite(n, eq_n)) + if (!d_drewrite->addRewrite(bn, beq_n)) { rewRedundant = isUnique; // must be unique according to the dynamic rewriter @@ -731,7 +738,7 @@ Node SygusSamplerExt::registerTerm(Node n, bool forceKeep) // sampler database. if (!eqor) { - registerTerm(n, true); + SygusSampler::registerTerm(n, true); } return eq_n; } diff --git a/src/theory/quantifiers/sygus_sampler.h b/src/theory/quantifiers/sygus_sampler.h index 5fcfc1c93..06576d6ce 100644 --- a/src/theory/quantifiers/sygus_sampler.h +++ b/src/theory/quantifiers/sygus_sampler.h @@ -207,7 +207,8 @@ class SygusSampler : public LazyTrieEvaluator * are those that occur in the range d_type_vars. */ bool containsFreeVariables(Node a, Node b); - private: + + protected: /** sygus term database of d_qe */ TermDbSygus* d_tds; /** samples */ -- cgit v1.2.3 From 3d31caa30e094d337a4919b3d1e6ba9259e461b8 Mon Sep 17 00:00:00 2001 From: Mathias Preiner Date: Mon, 5 Mar 2018 15:36:50 -0800 Subject: Enable -Wsuggest-override by default. (#1643) Adds missing override keywords. --- configure.ac | 4 + src/base/output.h | 2 +- src/context/cdhashmap.h | 14 +- src/context/cdinsert_hashmap.h | 39 +-- src/context/cdlist.h | 25 +- src/context/cdo.h | 6 +- src/context/cdqueue.h | 6 +- src/context/cdtrail_hashmap.h | 34 ++- src/decision/decision_strategy.h | 3 +- src/decision/justification_heuristic.h | 6 +- src/expr/node_manager_listeners.h | 12 +- src/lib/Makefile.am | 4 + src/options/argument_extender_implementation.h | 18 +- src/parser/parser.h | 2 +- src/parser/smt1/smt1.h | 2 +- src/parser/smt2/smt2.h | 8 +- src/proof/arith_proof.h | 24 +- src/proof/array_proof.h | 28 +- src/proof/bitvector_proof.h | 49 ++-- src/proof/cnf_proof.h | 8 +- src/proof/sat_proof.h | 16 +- src/proof/theory_proof.h | 75 ++--- src/proof/uf_proof.h | 35 ++- src/prop/bvminisat/bvminisat.h | 66 +++-- src/prop/bvminisat/simp/SimpSolver.h | 3 +- src/prop/bvminisat/utils/Options.h | 319 ++++++++++++--------- src/prop/cnf_stream.h | 9 +- src/prop/minisat/minisat.h | 45 +-- src/prop/minisat/simp/SimpSolver.h | 3 +- src/prop/minisat/utils/Options.h | 319 ++++++++++++--------- src/prop/registrar.h | 2 +- src/prop/sat_solver.h | 6 - src/smt/managed_ostreams.h | 35 +-- src/smt/smt_engine.cpp | 55 ++-- src/smt/update_ostream.h | 32 +-- src/theory/arith/attempt_solution_simplex.h | 6 +- src/theory/arith/callbacks.h | 10 +- src/theory/arith/congruence_manager.h | 19 +- src/theory/arith/dual_simplex.h | 3 +- src/theory/arith/fc_simplex.h | 2 +- src/theory/arith/linear_equality.h | 12 +- src/theory/arith/matrix.h | 6 +- src/theory/arith/soi_simplex.h | 2 +- src/theory/arrays/theory_arrays.h | 34 ++- src/theory/booleans/circuit_propagator.h | 9 +- src/theory/booleans/theory_bool.h | 6 +- src/theory/builtin/theory_builtin.h | 2 +- src/theory/bv/bitblaster_template.h | 56 ++-- src/theory/bv/bv_inequality_graph.h | 8 +- src/theory/bv/bv_subtheory_algebraic.h | 25 +- src/theory/bv/bv_subtheory_bitblast.h | 16 +- src/theory/bv/bv_subtheory_core.h | 37 +-- src/theory/bv/bv_subtheory_inequality.h | 18 +- src/theory/bv/type_enumerator.h | 7 +- src/theory/datatypes/theory_datatypes.h | 27 +- src/theory/fp/theory_fp.h | 20 +- src/theory/idl/theory_idl.h | 6 +- src/theory/quantifiers/anti_skolem.h | 8 +- src/theory/quantifiers/cegqi/ceg_instantiator.h | 4 +- .../quantifiers/cegqi/ceg_t_instantiator.cpp | 10 +- src/theory/quantifiers/cegqi/ceg_t_instantiator.h | 163 +++++------ src/theory/quantifiers/cegqi/inst_strategy_cbqi.h | 24 +- src/theory/quantifiers/conjecture_generator.h | 53 ++-- src/theory/quantifiers/ematching/ho_trigger.h | 2 +- .../ematching/inst_strategy_e_matching.h | 34 ++- .../quantifiers/ematching/instantiation_engine.h | 16 +- src/theory/quantifiers/equality_query.h | 20 +- src/theory/quantifiers/first_order_model.h | 26 +- src/theory/quantifiers/fmf/bounded_integers.h | 26 +- src/theory/quantifiers/fmf/full_model_check.h | 10 +- src/theory/quantifiers/fmf/model_builder.h | 11 +- src/theory/quantifiers/fmf/model_engine.h | 24 +- src/theory/quantifiers/fun_def_engine.h | 12 +- src/theory/quantifiers/inst_propagator.h | 43 +-- src/theory/quantifiers/instantiate.h | 8 +- src/theory/quantifiers/local_theory_ext.h | 15 +- src/theory/quantifiers/quant_conflict_find.h | 15 +- src/theory/quantifiers/quant_equality_engine.h | 52 +++- src/theory/quantifiers/quant_relevance.h | 6 +- src/theory/quantifiers/quant_split.h | 16 +- src/theory/quantifiers/relevant_domain.h | 6 +- src/theory/quantifiers/rewrite_engine.h | 12 +- .../quantifiers/sygus/ce_guided_instantiation.h | 50 ++-- .../quantifiers/sygus/ce_guided_single_inv.h | 6 +- src/theory/quantifiers/sygus/sygus_invariance.h | 8 +- src/theory/quantifiers/sygus_sampler.h | 4 +- src/theory/quantifiers/term_database.h | 6 +- src/theory/quantifiers/term_util.h | 6 +- src/theory/sep/theory_sep.h | 16 +- src/theory/sets/theory_sets_private.h | 19 +- src/theory/shared_terms_database.h | 27 +- src/theory/strings/theory_strings.h | 27 +- src/theory/substitutions.h | 5 +- src/theory/theory_engine.h | 37 ++- src/theory/theory_model_builder.h | 2 +- src/theory/theory_registrar.h | 4 +- src/theory/type_enumerator.h | 5 +- src/theory/uf/equality_engine.h | 32 ++- src/theory/uf/theory_uf.h | 27 +- src/util/statistics_registry.h | 88 +++--- 100 files changed, 1491 insertions(+), 1139 deletions(-) diff --git a/configure.ac b/configure.ac index ef12e4825..5dd8ae691 100644 --- a/configure.ac +++ b/configure.ac @@ -950,6 +950,7 @@ CVC4_CXX_OPTION([-Wno-tautological-compare], [WNO_TAUTOLOGICAL_COMPARE]) CVC4_CXX_OPTION([-Wno-parentheses], [WNO_PARENTHESES]) CVC4_CXX_OPTION([-Wno-uninitialized], [WNO_UNINITIALIZED]) CVC4_CXX_OPTION([-Wno-unused-variable], [WNO_UNUSED_VARIABLE]) +CVC4_CXX_OPTION([-Wsuggest-override], [W_SUGGEST_OVERRIDE]) CVC4_CXX_OPTION([-fno-strict-aliasing], [FNO_STRICT_ALIASING]) AC_SUBST([WERROR]) AC_SUBST([WNO_CONVERSION_NULL]) @@ -957,8 +958,11 @@ AC_SUBST([WNO_TAUTOLOGICAL_COMPARE]) AC_SUBST([WNO_PARENTHESES]) AC_SUBST([WNO_UNINITIALIZED]) AC_SUBST([WNO_UNUSED_VARIABLE]) +AC_SUBST([W_SUGGEST_OVERRIDE]) AC_SUBST([FNO_STRICT_ALIASING]) +CVC4CXXFLAGS="${CVC4CXXFLAGS:+$CVC4CXXFLAGS }${W_SUGGEST_OVERRIDE}" + # On Mac, we have to fix the visibility of standard library symbols. # Otherwise, exported template instantiations---even though explicitly # CVC4_PUBLIC, can be generated as symbols with internal-only linkage. diff --git a/src/base/output.h b/src/base/output.h index cdc0ac27f..b7f743e56 100644 --- a/src/base/output.h +++ b/src/base/output.h @@ -51,7 +51,7 @@ public: * stream. Perhaps this is not so critical, but recommended; this * way the output stream looks like it's functioning, in a non-error * state. */ - int overflow(int c) { return c; } + int overflow(int c) override { return c; } };/* class null_streambuf */ /** A null stream-buffer singleton */ diff --git a/src/context/cdhashmap.h b/src/context/cdhashmap.h index 82aa90891..14832679d 100644 --- a/src/context/cdhashmap.h +++ b/src/context/cdhashmap.h @@ -111,11 +111,13 @@ class CDOhash_map : public ContextObj { CDOhash_map* d_prev; CDOhash_map* d_next; - virtual ContextObj* save(ContextMemoryManager* pCMM) { + ContextObj* save(ContextMemoryManager* pCMM) override + { return new(pCMM) CDOhash_map(*this); } - virtual void restore(ContextObj* data) { + void restore(ContextObj* data) override + { CDOhash_map* p = static_cast(data); if(d_map != NULL) { if(p->d_map == NULL) { @@ -279,14 +281,10 @@ class CDHashMap : public ContextObj { Context* d_context; // Nothing to save; the elements take care of themselves - virtual ContextObj* save(ContextMemoryManager* pCMM) { - Unreachable(); - } + ContextObj* save(ContextMemoryManager* pCMM) override { Unreachable(); } // Similarly, nothing to restore - virtual void restore(ContextObj* data) { - Unreachable(); - } + void restore(ContextObj* data) override { Unreachable(); } // no copy or assignment CDHashMap(const CDHashMap&) CVC4_UNDEFINED; diff --git a/src/context/cdinsert_hashmap.h b/src/context/cdinsert_hashmap.h index db679c1f7..9211ff7da 100644 --- a/src/context/cdinsert_hashmap.h +++ b/src/context/cdinsert_hashmap.h @@ -221,7 +221,8 @@ private: * restored on a pop). The saved information is allocated using the * ContextMemoryManager. */ - ContextObj* save(ContextMemoryManager* pCMM) { + ContextObj* save(ContextMemoryManager* pCMM) override + { ContextObj* data = new(pCMM) CDInsertHashMap(*this); Debug("CDInsertHashMap") << "save " << this << " at level " << this->getContext()->getLevel() @@ -237,23 +238,25 @@ protected: * of new pushFront calls have happened since saving. * The d_insertMap is untouched and d_pushFronts is also kept. */ - void restore(ContextObj* data) { - Debug("CDInsertHashMap") << "restore " << this - << " level " << this->getContext()->getLevel() - << " data == " << data - << " d_insertMap == " << this->d_insertMap << std::endl; - size_t oldSize = ((CDInsertHashMap*)data)->d_size; - size_t oldPushFronts = ((CDInsertHashMap*)data)->d_pushFronts; - Assert(oldPushFronts <= d_pushFronts); - - // The size to restore to. - size_t restoreSize = oldSize + (d_pushFronts - oldPushFronts); - d_insertMap->pop_to_size(restoreSize); - d_size = restoreSize; - Assert(d_insertMap->size() == d_size); - Debug("CDInsertHashMap") << "restore " << this - << " level " << this->getContext()->getLevel() - << " size back to " << this->d_size << std::endl; + void restore(ContextObj* data) override + { + Debug("CDInsertHashMap") + << "restore " << this << " level " << this->getContext()->getLevel() + << " data == " << data << " d_insertMap == " << this->d_insertMap + << std::endl; + size_t oldSize = ((CDInsertHashMap*)data)->d_size; + size_t oldPushFronts = + ((CDInsertHashMap*)data)->d_pushFronts; + Assert(oldPushFronts <= d_pushFronts); + + // The size to restore to. + size_t restoreSize = oldSize + (d_pushFronts - oldPushFronts); + d_insertMap->pop_to_size(restoreSize); + d_size = restoreSize; + Assert(d_insertMap->size() == d_size); + Debug("CDInsertHashMap") + << "restore " << this << " level " << this->getContext()->getLevel() + << " size back to " << this->d_size << std::endl; } public: diff --git a/src/context/cdlist.h b/src/context/cdlist.h index aeb6567a3..e5f9f2dda 100644 --- a/src/context/cdlist.h +++ b/src/context/cdlist.h @@ -165,7 +165,8 @@ private: * restored on a pop). The saved information is allocated using the * ContextMemoryManager. */ - ContextObj* save(ContextMemoryManager* pCMM) { + ContextObj* save(ContextMemoryManager* pCMM) override + { ContextObj* data = new(pCMM) CDList(*this); Debug("cdlist") << "save " << this << " at level " << this->getContext()->getLevel() @@ -182,17 +183,17 @@ protected: * restores the previous size. Note that the list pointer and the * allocated size are not changed. */ - void restore(ContextObj* data) { - Debug("cdlist") << "restore " << this - << " level " << this->getContext()->getLevel() - << " data == " << data - << " call dtor == " << this->d_callDestructor - << " d_list == " << this->d_list << std::endl; - truncateList(((CDList*)data)->d_size); - Debug("cdlist") << "restore " << this - << " level " << this->getContext()->getLevel() - << " size back to " << this->d_size - << " sizeAlloc at " << this->d_sizeAlloc << std::endl; + void restore(ContextObj* data) override + { + Debug("cdlist") << "restore " << this << " level " + << this->getContext()->getLevel() << " data == " << data + << " call dtor == " << this->d_callDestructor + << " d_list == " << this->d_list << std::endl; + truncateList(((CDList*)data)->d_size); + Debug("cdlist") << "restore " << this << " level " + << this->getContext()->getLevel() << " size back to " + << this->d_size << " sizeAlloc at " << this->d_sizeAlloc + << std::endl; } /** diff --git a/src/context/cdo.h b/src/context/cdo.h index 3142fe8ef..bac9eb360 100644 --- a/src/context/cdo.h +++ b/src/context/cdo.h @@ -57,7 +57,8 @@ protected: * current data to a copy using the copy constructor. Memory is allocated * using the ContextMemoryManager. */ - virtual ContextObj* save(ContextMemoryManager* pCMM) { + ContextObj* save(ContextMemoryManager* pCMM) override + { Debug("context") << "save cdo " << this; ContextObj* p = new(pCMM) CDO(*this); Debug("context") << " to " << p << std::endl; @@ -68,7 +69,8 @@ protected: * Implementation of mandatory ContextObj method restore: simply copies the * saved data back from the saved copy using operator= for T. */ - virtual void restore(ContextObj* pContextObj) { + void restore(ContextObj* pContextObj) override + { //Debug("context") << "restore cdo " << this; CDO* p = static_cast*>(pContextObj); d_data = p->d_data; diff --git a/src/context/cdqueue.h b/src/context/cdqueue.h index 1df985b48..305e2de77 100644 --- a/src/context/cdqueue.h +++ b/src/context/cdqueue.h @@ -60,7 +60,8 @@ protected: /** Implementation of mandatory ContextObj method save: * We assume that the base class do the job inside their copy constructor. */ - ContextObj* save(ContextMemoryManager* pCMM) { + ContextObj* save(ContextMemoryManager* pCMM) override + { ContextObj* data = new(pCMM) CDQueue(*this); // We save the d_size in d_lastsave and we should never destruct below this // indices before the corresponding restore. @@ -80,7 +81,8 @@ protected: * restores the previous size, iter and lastsave indices. Note that * the list pointer and the allocated size are not changed. */ - void restore(ContextObj* data) { + void restore(ContextObj* data) override + { CDQueue* qdata = static_cast*>(data); d_iter = qdata->d_iter; d_lastsave = qdata->d_lastsave; diff --git a/src/context/cdtrail_hashmap.h b/src/context/cdtrail_hashmap.h index bbd71f8cd..771cea960 100644 --- a/src/context/cdtrail_hashmap.h +++ b/src/context/cdtrail_hashmap.h @@ -394,7 +394,8 @@ private: * the current sizes to a copy using the copy constructor, * The saved information is allocated using the ContextMemoryManager. */ - ContextObj* save(ContextMemoryManager* pCMM) { + ContextObj* save(ContextMemoryManager* pCMM) override + { ContextObj* data = new(pCMM) CDTrailHashMap(*this); Debug("CDTrailHashMap") << "save " << this << " at level " << this->getContext()->getLevel() @@ -409,20 +410,23 @@ protected: * restores the previous size. Note that the list pointer and the * allocated size are not changed. */ - void restore(ContextObj* data) { - Debug("CDTrailHashMap") << "restore " << this - << " level " << this->getContext()->getLevel() - << " data == " << data - << " d_trailMap == " << this->d_trailMap << std::endl; - size_t oldSize = ((CDTrailHashMap*)data)->d_trailSize; - d_trailMap->pop_to_size(oldSize); - d_trailSize = oldSize; - Assert(d_trailMap->trailSize() == d_trailSize); - - d_prevTrailSize = ((CDTrailHashMap*)data)->d_prevTrailSize; - Debug("CDTrailHashMap") << "restore " << this - << " level " << this->getContext()->getLevel() - << " size back to " << this->d_trailSize << std::endl; + void restore(ContextObj* data) override + { + Debug("CDTrailHashMap") << "restore " << this << " level " + << this->getContext()->getLevel() + << " data == " << data + << " d_trailMap == " << this->d_trailMap + << std::endl; + size_t oldSize = ((CDTrailHashMap*)data)->d_trailSize; + d_trailMap->pop_to_size(oldSize); + d_trailSize = oldSize; + Assert(d_trailMap->trailSize() == d_trailSize); + + d_prevTrailSize = + ((CDTrailHashMap*)data)->d_prevTrailSize; + Debug("CDTrailHashMap") << "restore " << this << " level " + << this->getContext()->getLevel() << " size back to " + << this->d_trailSize << std::endl; } /** diff --git a/src/decision/decision_strategy.h b/src/decision/decision_strategy.h index 25334b777..9b1033c86 100644 --- a/src/decision/decision_strategy.h +++ b/src/decision/decision_strategy.h @@ -55,8 +55,7 @@ public: DecisionStrategy(de, c) { } - - bool needIteSkolemMap() { return true; } + bool needIteSkolemMap() override { return true; } virtual void addAssertions(const std::vector &assertions, unsigned assertionsEnd, diff --git a/src/decision/justification_heuristic.h b/src/decision/justification_heuristic.h index 210ab4d5c..47cccfbe5 100644 --- a/src/decision/justification_heuristic.h +++ b/src/decision/justification_heuristic.h @@ -117,13 +117,13 @@ public: ~JustificationHeuristic(); - prop::SatLiteral getNext(bool &stopSearch); + prop::SatLiteral getNext(bool &stopSearch) override; void addAssertions(const std::vector &assertions, unsigned assertionsEnd, - IteSkolemMap iteSkolemMap); + IteSkolemMap iteSkolemMap) override; -private: + private: /* getNext with an option to specify threshold */ prop::SatLiteral getNextThresh(bool &stopSearch, DecisionWeight threshold); diff --git a/src/expr/node_manager_listeners.h b/src/expr/node_manager_listeners.h index bdfe5a487..2f2c48ada 100644 --- a/src/expr/node_manager_listeners.h +++ b/src/expr/node_manager_listeners.h @@ -28,7 +28,8 @@ namespace expr { class TlimitListener : public Listener { public: TlimitListener(ResourceManager* rm) : d_rm(rm) {} - virtual void notify(); + void notify() override; + private: ResourceManager* d_rm; }; @@ -36,7 +37,8 @@ class TlimitListener : public Listener { class TlimitPerListener : public Listener { public: TlimitPerListener(ResourceManager* rm) : d_rm(rm) {} - virtual void notify(); + void notify() override; + private: ResourceManager* d_rm; }; @@ -44,7 +46,8 @@ class TlimitPerListener : public Listener { class RlimitListener : public Listener { public: RlimitListener(ResourceManager* rm) : d_rm(rm) {} - virtual void notify(); + void notify() override; + private: ResourceManager* d_rm; }; @@ -52,7 +55,8 @@ class RlimitListener : public Listener { class RlimitPerListener : public Listener { public: RlimitPerListener(ResourceManager* rm) : d_rm(rm) {} - virtual void notify(); + void notify() override; + private: ResourceManager* d_rm; }; diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 8db3d664c..aec9fa634 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -3,6 +3,10 @@ AM_CPPFLAGS = \ -I@builddir@/.. -I@srcdir@/../include -I@srcdir@/.. AM_CFLAGS = -Wall -Wno-unknown-pragmas $(FLAG_VISIBILITY_HIDDEN) AM_CXXFLAGS = -Wall -Wno-unknown-pragmas $(FLAG_VISIBILITY_HIDDEN) +# This is a workaround for now to fix some warnings related to unsupported +# compiler flags since we are compiling C code here. CXXFLAGS is set via +# configure, however, we should actually set AM_CXXFLAGS. +CXXFLAGS = $(AM_CXXFLAGS) noinst_LTLIBRARIES = libreplacements.la diff --git a/src/options/argument_extender_implementation.h b/src/options/argument_extender_implementation.h index 859a88b3e..efcd55cae 100644 --- a/src/options/argument_extender_implementation.h +++ b/src/options/argument_extender_implementation.h @@ -50,39 +50,39 @@ class ArgumentExtenderImplementation : public ArgumentExtender { * Preconditions: * - argc and argv are non-null. */ - void getArguments(int* argc, char*** argv) const; + void getArguments(int* argc, char*** argv) const override; /** Returns the number of arguments that are . */ - size_t numArguments() const; + size_t numArguments() const override; /** * Inserts a copy of element into the front of the arguments list. * Preconditions: element is non-null and 0 terminated. */ - void pushFrontArgument(const char* element); + void pushFrontArgument(const char* element) override; /** * Inserts a copy of element into the back of the arguments list. * Preconditions: element is non-null and 0 terminated. */ - void pushBackArgument(const char* element); + void pushBackArgument(const char* element) override; /** Removes the front of the arguments list.*/ - void popFrontArgument(); + void popFrontArgument() override; /** Adds a new preemption to the arguments list. */ - void pushBackPreemption(const char* element); + void pushBackPreemption(const char* element) override; /** * Moves all of the preemptions into the front of the arguments * list. */ - void movePreemptionsToArguments(); + void movePreemptionsToArguments() override; /** Returns true iff there is a pending preemption.*/ - bool hasPreemptions() const; + bool hasPreemptions() const override; -private: + private: typedef std::list< char* > CharPointerList; diff --git a/src/parser/parser.h b/src/parser/parser.h index 7f64b9580..949c56605 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -794,7 +794,7 @@ public: public: ExprStream(Parser* parser) : d_parser(parser) {} ~ExprStream() { delete d_parser; } - Expr nextExpr() { return d_parser->nextExpression(); } + Expr nextExpr() override { return d_parser->nextExpression(); } };/* class Parser::ExprStream */ //------------------------ operator overloading diff --git a/src/parser/smt1/smt1.h b/src/parser/smt1/smt1.h index 49a4b8000..1c15df5d3 100644 --- a/src/parser/smt1/smt1.h +++ b/src/parser/smt1/smt1.h @@ -103,7 +103,7 @@ public: */ void addTheory(Theory theory); - bool logicIsSet(); + bool logicIsSet() override; /** * Sets the logic for the current benchmark. Declares any logic and theory symbols. diff --git a/src/parser/smt2/smt2.h b/src/parser/smt2/smt2.h index 94bc03235..71aa32492 100644 --- a/src/parser/smt2/smt2.h +++ b/src/parser/smt2/smt2.h @@ -84,12 +84,12 @@ public: bool isTheoryEnabled(Theory theory) const; - bool logicIsSet(); - + bool logicIsSet() override; + /** * Returns the expression that name should be interpreted as. */ - virtual Expr getExpressionForNameAndType(const std::string& name, Type t); + Expr getExpressionForNameAndType(const std::string& name, Type t) override; /** Make function defined by a define-fun(s)-rec command. * @@ -135,7 +135,7 @@ public: std::vector& bvs, bool bindingLevel = false); - void reset(); + void reset() override; void resetAssertions(); diff --git a/src/proof/arith_proof.h b/src/proof/arith_proof.h index 0a44f45c0..677952bf7 100644 --- a/src/proof/arith_proof.h +++ b/src/proof/arith_proof.h @@ -67,7 +67,7 @@ protected: public: ArithProof(theory::arith::TheoryArith* arith, TheoryProofEngine* proofEngine); - virtual void registerTerm(Expr term); + void registerTerm(Expr term) override; }; class LFSCArithProof : public ArithProof { @@ -75,13 +75,21 @@ public: LFSCArithProof(theory::arith::TheoryArith* arith, TheoryProofEngine* proofEngine) : ArithProof(arith, proofEngine) {} - virtual void printOwnedTerm(Expr term, std::ostream& os, const ProofLetMap& map); - virtual void printOwnedSort(Type type, std::ostream& os); - virtual void printTheoryLemmaProof(std::vector& lemma, std::ostream& os, std::ostream& paren, const ProofLetMap& map); - virtual void printSortDeclarations(std::ostream& os, std::ostream& paren); - virtual void printTermDeclarations(std::ostream& os, std::ostream& paren); - virtual void printDeferredDeclarations(std::ostream& os, std::ostream& paren); - virtual void printAliasingDeclarations(std::ostream& os, std::ostream& paren, const ProofLetMap &globalLetMap); + void printOwnedTerm(Expr term, + std::ostream& os, + const ProofLetMap& map) override; + void printOwnedSort(Type type, std::ostream& os) override; + void printTheoryLemmaProof(std::vector& lemma, + std::ostream& os, + std::ostream& paren, + const ProofLetMap& map) override; + void printSortDeclarations(std::ostream& os, std::ostream& paren) override; + void printTermDeclarations(std::ostream& os, std::ostream& paren) override; + void printDeferredDeclarations(std::ostream& os, + std::ostream& paren) override; + void printAliasingDeclarations(std::ostream& os, + std::ostream& paren, + const ProofLetMap& globalLetMap) override; }; diff --git a/src/proof/array_proof.h b/src/proof/array_proof.h index 99ad956a5..779624df0 100644 --- a/src/proof/array_proof.h +++ b/src/proof/array_proof.h @@ -85,7 +85,7 @@ public: std::string skolemToLiteral(Expr skolem); - virtual void registerTerm(Expr term); + void registerTerm(Expr term) override; }; class LFSCArrayProof : public ArrayProof { @@ -94,15 +94,23 @@ public: : ArrayProof(arrays, proofEngine) {} - virtual void printOwnedTerm(Expr term, std::ostream& os, const ProofLetMap& map); - virtual void printOwnedSort(Type type, std::ostream& os); - virtual void printTheoryLemmaProof(std::vector& lemma, std::ostream& os, std::ostream& paren, const ProofLetMap& map); - virtual void printSortDeclarations(std::ostream& os, std::ostream& paren); - virtual void printTermDeclarations(std::ostream& os, std::ostream& paren); - virtual void printDeferredDeclarations(std::ostream& os, std::ostream& paren); - virtual void printAliasingDeclarations(std::ostream& os, std::ostream& paren, const ProofLetMap &globalLetMap); - - bool printsAsBool(const Node &n); + void printOwnedTerm(Expr term, + std::ostream& os, + const ProofLetMap& map) override; + void printOwnedSort(Type type, std::ostream& os) override; + void printTheoryLemmaProof(std::vector& lemma, + std::ostream& os, + std::ostream& paren, + const ProofLetMap& map) override; + void printSortDeclarations(std::ostream& os, std::ostream& paren) override; + void printTermDeclarations(std::ostream& os, std::ostream& paren) override; + void printDeferredDeclarations(std::ostream& os, + std::ostream& paren) override; + void printAliasingDeclarations(std::ostream& os, + std::ostream& paren, + const ProofLetMap& globalLetMap) override; + + bool printsAsBool(const Node& n) override; }; diff --git a/src/proof/bitvector_proof.h b/src/proof/bitvector_proof.h index 69f9e774b..b5487a352 100644 --- a/src/proof/bitvector_proof.h +++ b/src/proof/bitvector_proof.h @@ -110,7 +110,7 @@ public: void registerTermBB(Expr term); void registerAtomBB(Expr atom, Expr atom_bb); - virtual void registerTerm(Expr term); + void registerTerm(Expr term) override; virtual void printTermBitblasting(Expr term, std::ostream& os) = 0; virtual void printAtomBitblasting(Expr term, std::ostream& os, bool swap) = 0; @@ -143,22 +143,37 @@ public: LFSCBitVectorProof(theory::bv::TheoryBV* bv, TheoryProofEngine* proofEngine) :BitVectorProof(bv, proofEngine) {} - virtual void printOwnedTerm(Expr term, std::ostream& os, const ProofLetMap& map); - virtual void printOwnedSort(Type type, std::ostream& os); - virtual void printTermBitblasting(Expr term, std::ostream& os); - virtual void printAtomBitblasting(Expr term, std::ostream& os, bool swap); - virtual void printAtomBitblastingToFalse(Expr term, std::ostream& os); - virtual void printTheoryLemmaProof(std::vector& lemma, std::ostream& os, std::ostream& paren, const ProofLetMap& map); - virtual void printSortDeclarations(std::ostream& os, std::ostream& paren); - virtual void printTermDeclarations(std::ostream& os, std::ostream& paren); - virtual void printDeferredDeclarations(std::ostream& os, std::ostream& paren); - virtual void printAliasingDeclarations(std::ostream& os, std::ostream& paren, const ProofLetMap &globalLetMap); - virtual void printBitblasting(std::ostream& os, std::ostream& paren); - virtual void printResolutionProof(std::ostream& os, std::ostream& paren, ProofLetMap& letMap); - void calculateAtomsInBitblastingProof(); - const std::set* getAtomsInBitblastingProof(); - void printConstantDisequalityProof(std::ostream& os, Expr c1, Expr c2, const ProofLetMap &globalLetMap); - void printRewriteProof(std::ostream& os, const Node &n1, const Node &n2); + void printOwnedTerm(Expr term, + std::ostream& os, + const ProofLetMap& map) override; + void printOwnedSort(Type type, std::ostream& os) override; + void printTermBitblasting(Expr term, std::ostream& os) override; + void printAtomBitblasting(Expr term, std::ostream& os, bool swap) override; + void printAtomBitblastingToFalse(Expr term, std::ostream& os) override; + void printTheoryLemmaProof(std::vector& lemma, + std::ostream& os, + std::ostream& paren, + const ProofLetMap& map) override; + void printSortDeclarations(std::ostream& os, std::ostream& paren) override; + void printTermDeclarations(std::ostream& os, std::ostream& paren) override; + void printDeferredDeclarations(std::ostream& os, + std::ostream& paren) override; + void printAliasingDeclarations(std::ostream& os, + std::ostream& paren, + const ProofLetMap& globalLetMap) override; + void printBitblasting(std::ostream& os, std::ostream& paren) override; + void printResolutionProof(std::ostream& os, + std::ostream& paren, + ProofLetMap& letMap) override; + void calculateAtomsInBitblastingProof() override; + const std::set* getAtomsInBitblastingProof() override; + void printConstantDisequalityProof(std::ostream& os, + Expr c1, + Expr c2, + const ProofLetMap& globalLetMap) override; + void printRewriteProof(std::ostream& os, + const Node& n1, + const Node& n2) override; }; }/* CVC4 namespace */ diff --git a/src/proof/cnf_proof.h b/src/proof/cnf_proof.h index a0d7096c0..9087817b3 100644 --- a/src/proof/cnf_proof.h +++ b/src/proof/cnf_proof.h @@ -171,20 +171,20 @@ public: void printAtomMapping(const std::set& atoms, std::ostream& os, - std::ostream& paren); + std::ostream& paren) override; void printAtomMapping(const std::set& atoms, std::ostream& os, std::ostream& paren, - ProofLetMap &letMap); + ProofLetMap& letMap) override; void printClause(const prop::SatClause& clause, std::ostream& os, - std::ostream& paren); + std::ostream& paren) override; void printCnfProofForClause(ClauseId id, const prop::SatClause* clause, std::ostream& os, - std::ostream& paren); + std::ostream& paren) override; };/* class LFSCCnfProof */ } /* CVC4 namespace */ diff --git a/src/proof/sat_proof.h b/src/proof/sat_proof.h index 4ed2360c2..19a8d30cf 100644 --- a/src/proof/sat_proof.h +++ b/src/proof/sat_proof.h @@ -396,13 +396,15 @@ class LFSCSatProof : public TSatProof { LFSCSatProof(SatSolver* solver, context::Context* context, const std::string& name, bool checkRes = false) : TSatProof(solver, context, name, checkRes) {} - virtual void printResolution(ClauseId id, std::ostream& out, - std::ostream& paren); - virtual void printResolutions(std::ostream& out, std::ostream& paren); - virtual void printResolutionEmptyClause(std::ostream& out, - std::ostream& paren); - virtual void printAssumptionsResolution(ClauseId id, std::ostream& out, - std::ostream& paren); + void printResolution(ClauseId id, + std::ostream& out, + std::ostream& paren) override; + void printResolutions(std::ostream& out, std::ostream& paren) override; + void printResolutionEmptyClause(std::ostream& out, + std::ostream& paren) override; + void printAssumptionsResolution(ClauseId id, + std::ostream& out, + std::ostream& paren) override; }; /* class LFSCSatProof */ template diff --git a/src/proof/theory_proof.h b/src/proof/theory_proof.h index 15ac533b7..4e599f570 100644 --- a/src/proof/theory_proof.h +++ b/src/proof/theory_proof.h @@ -163,23 +163,32 @@ public: LFSCTheoryProofEngine() : TheoryProofEngine() {} - void printTheoryTerm(Expr term, std::ostream& os, const ProofLetMap& map); + void printTheoryTerm(Expr term, + std::ostream& os, + const ProofLetMap& map) override; - void registerTermsFromAssertions(); + void registerTermsFromAssertions() override; void printSortDeclarations(std::ostream& os, std::ostream& paren); void printTermDeclarations(std::ostream& os, std::ostream& paren); - virtual void printCoreTerm(Expr term, std::ostream& os, const ProofLetMap& map); - virtual void printLetTerm(Expr term, std::ostream& os); - virtual void printBoundTerm(Expr term, std::ostream& os, const ProofLetMap& map); - virtual void printAssertions(std::ostream& os, std::ostream& paren); - virtual void printLemmaRewrites(NodePairSet& rewrites, std::ostream& os, std::ostream& paren); - virtual void printDeferredDeclarations(std::ostream& os, std::ostream& paren); - virtual void printAliasingDeclarations(std::ostream& os, std::ostream& paren, const ProofLetMap &globalLetMap); - virtual void printTheoryLemmas(const IdToSatClause& lemmas, - std::ostream& os, + void printCoreTerm(Expr term, std::ostream& os, const ProofLetMap& map); + void printLetTerm(Expr term, std::ostream& os) override; + void printBoundTerm(Expr term, + std::ostream& os, + const ProofLetMap& map) override; + void printAssertions(std::ostream& os, std::ostream& paren) override; + void printLemmaRewrites(NodePairSet& rewrites, + std::ostream& os, + std::ostream& paren); + void printDeferredDeclarations(std::ostream& os, + std::ostream& paren) override; + void printAliasingDeclarations(std::ostream& os, std::ostream& paren, - ProofLetMap& map); - virtual void printSort(Type type, std::ostream& os); + const ProofLetMap& globalLetMap) override; + void printTheoryLemmas(const IdToSatClause& lemmas, + std::ostream& os, + std::ostream& paren, + ProofLetMap& map) override; + void printSort(Type type, std::ostream& os) override; void performExtraRegistrations(); @@ -307,16 +316,7 @@ protected: public: BooleanProof(TheoryProofEngine* proofEngine); - virtual void registerTerm(Expr term); - - virtual void printOwnedTerm(Expr term, std::ostream& os, const ProofLetMap& map) = 0; - - virtual void printOwnedSort(Type type, std::ostream& os) = 0; - virtual void printTheoryLemmaProof(std::vector& lemma, std::ostream& os, std::ostream& paren, const ProofLetMap& map) = 0; - virtual void printSortDeclarations(std::ostream& os, std::ostream& paren) = 0; - virtual void printTermDeclarations(std::ostream& os, std::ostream& paren) = 0; - virtual void printDeferredDeclarations(std::ostream& os, std::ostream& paren) = 0; - virtual void printAliasingDeclarations(std::ostream& os, std::ostream& paren, const ProofLetMap &globalLetMap) = 0; + void registerTerm(Expr term) override; }; class LFSCBooleanProof : public BooleanProof { @@ -324,16 +324,27 @@ public: LFSCBooleanProof(TheoryProofEngine* proofEngine) : BooleanProof(proofEngine) {} - virtual void printOwnedTerm(Expr term, std::ostream& os, const ProofLetMap& map); - virtual void printOwnedSort(Type type, std::ostream& os); - virtual void printTheoryLemmaProof(std::vector& lemma, std::ostream& os, std::ostream& paren, const ProofLetMap& map); - virtual void printSortDeclarations(std::ostream& os, std::ostream& paren); - virtual void printTermDeclarations(std::ostream& os, std::ostream& paren); - virtual void printDeferredDeclarations(std::ostream& os, std::ostream& paren); - virtual void printAliasingDeclarations(std::ostream& os, std::ostream& paren, const ProofLetMap &globalLetMap); + void printOwnedTerm(Expr term, + std::ostream& os, + const ProofLetMap& map) override; + void printOwnedSort(Type type, std::ostream& os) override; + void printTheoryLemmaProof(std::vector& lemma, + std::ostream& os, + std::ostream& paren, + const ProofLetMap& map) override; + void printSortDeclarations(std::ostream& os, std::ostream& paren) override; + void printTermDeclarations(std::ostream& os, std::ostream& paren) override; + void printDeferredDeclarations(std::ostream& os, + std::ostream& paren) override; + void printAliasingDeclarations(std::ostream& os, + std::ostream& paren, + const ProofLetMap& globalLetMap) override; - bool printsAsBool(const Node &n); - void printConstantDisequalityProof(std::ostream& os, Expr c1, Expr c2, const ProofLetMap &globalLetMap); + bool printsAsBool(const Node& n) override; + void printConstantDisequalityProof(std::ostream& os, + Expr c1, + Expr c2, + const ProofLetMap& globalLetMap) override; }; } /* CVC4 namespace */ diff --git a/src/proof/uf_proof.h b/src/proof/uf_proof.h index 1b14bd15f..7aa00cc35 100644 --- a/src/proof/uf_proof.h +++ b/src/proof/uf_proof.h @@ -66,7 +66,7 @@ protected: public: UFProof(theory::uf::TheoryUF* uf, TheoryProofEngine* proofEngine); - virtual void registerTerm(Expr term); + void registerTerm(Expr term) override; }; class LFSCUFProof : public UFProof { @@ -74,17 +74,28 @@ public: LFSCUFProof(theory::uf::TheoryUF* uf, TheoryProofEngine* proofEngine) : UFProof(uf, proofEngine) {} - virtual void printOwnedTerm(Expr term, std::ostream& os, const ProofLetMap& map); - virtual void printOwnedSort(Type type, std::ostream& os); - virtual void printTheoryLemmaProof(std::vector& lemma, std::ostream& os, std::ostream& paren, const ProofLetMap& map); - virtual void printSortDeclarations(std::ostream& os, std::ostream& paren); - virtual void printTermDeclarations(std::ostream& os, std::ostream& paren); - virtual void printDeferredDeclarations(std::ostream& os, std::ostream& paren); - virtual void printAliasingDeclarations(std::ostream& os, std::ostream& paren, const ProofLetMap &globalLetMap); - - bool printsAsBool(const Node &n); - - void printConstantDisequalityProof(std::ostream& os, Expr c1, Expr c2, const ProofLetMap &globalLetMap); + void printOwnedTerm(Expr term, + std::ostream& os, + const ProofLetMap& map) override; + void printOwnedSort(Type type, std::ostream& os) override; + void printTheoryLemmaProof(std::vector& lemma, + std::ostream& os, + std::ostream& paren, + const ProofLetMap& map) override; + void printSortDeclarations(std::ostream& os, std::ostream& paren) override; + void printTermDeclarations(std::ostream& os, std::ostream& paren) override; + void printDeferredDeclarations(std::ostream& os, + std::ostream& paren) override; + void printAliasingDeclarations(std::ostream& os, + std::ostream& paren, + const ProofLetMap& globalLetMap) override; + + bool printsAsBool(const Node& n) override; + + void printConstantDisequalityProof(std::ostream& os, + Expr c1, + Expr c2, + const ProofLetMap& globalLetMap) override; }; diff --git a/src/prop/bvminisat/bvminisat.h b/src/prop/bvminisat/bvminisat.h index 7dd708ca2..4395cdf6d 100644 --- a/src/prop/bvminisat/bvminisat.h +++ b/src/prop/bvminisat/bvminisat.h @@ -37,13 +37,16 @@ class BVMinisatSatSolver : public BVSatSolverInterface, public: MinisatNotify(BVSatSolverInterface::Notify* notify) : d_notify(notify) {} - bool notify(BVMinisat::Lit lit) + bool notify(BVMinisat::Lit lit) override { return d_notify->notify(toSatLiteral(lit)); } - void notify(BVMinisat::vec& clause); - void spendResource(unsigned amount) { d_notify->spendResource(amount); } - void safePoint(unsigned amount) { d_notify->safePoint(amount); } + void notify(BVMinisat::vec& clause) override; + void spendResource(unsigned amount) override + { + d_notify->spendResource(amount); + } + void safePoint(unsigned amount) override { d_notify->safePoint(amount); } }; BVMinisat::SimpSolver* d_minisat; @@ -54,45 +57,46 @@ class BVMinisatSatSolver : public BVSatSolverInterface, context::CDO d_lastPropagation; protected: - - void contextNotifyPop(); + void contextNotifyPop() override; public: BVMinisatSatSolver(StatisticsRegistry* registry, context::Context* mainSatContext, const std::string& name = ""); virtual ~BVMinisatSatSolver(); - void setNotify(Notify* notify); + void setNotify(Notify* notify) override; - ClauseId addClause(SatClause& clause, bool removable); + ClauseId addClause(SatClause& clause, bool removable) override; - ClauseId addXorClause(SatClause& clause, bool rhs, bool removable) { + ClauseId addXorClause(SatClause& clause, bool rhs, bool removable) override + { Unreachable("Minisat does not support native XOR reasoning"); } - - SatValue propagate(); - SatVariable newVar(bool isTheoryAtom = false, bool preRegister = false, bool canErase = true); + SatValue propagate() override; - SatVariable trueVar() { return d_minisat->trueVar(); } - SatVariable falseVar() { return d_minisat->falseVar(); } + SatVariable newVar(bool isTheoryAtom = false, + bool preRegister = false, + bool canErase = true) override; - void markUnremovable(SatLiteral lit); + SatVariable trueVar() override { return d_minisat->trueVar(); } + SatVariable falseVar() override { return d_minisat->falseVar(); } - void interrupt(); + void markUnremovable(SatLiteral lit) override; - SatValue solve(); - SatValue solve(long unsigned int&); - bool ok() const; - void getUnsatCore(SatClause& unsatCore); + void interrupt() override; - SatValue value(SatLiteral l); - SatValue modelValue(SatLiteral l); + SatValue solve() override; + SatValue solve(long unsigned int&) override; + bool ok() const override; + void getUnsatCore(SatClause& unsatCore) override; + + SatValue value(SatLiteral l) override; + SatValue modelValue(SatLiteral l) override; void unregisterVar(SatLiteral lit); void renewVar(SatLiteral lit, int level = -1); - unsigned getAssertionLevel() const; - + unsigned getAssertionLevel() const override; // helper methods for converting from the internal Minisat representation @@ -103,17 +107,17 @@ public: static void toMinisatClause(SatClause& clause, BVMinisat::vec& minisat_clause); static void toSatClause (const BVMinisat::Clause& clause, SatClause& sat_clause); - void addMarkerLiteral(SatLiteral lit); + void addMarkerLiteral(SatLiteral lit) override; - void explain(SatLiteral lit, std::vector& explanation); + void explain(SatLiteral lit, std::vector& explanation) override; - SatValue assertAssumption(SatLiteral lit, bool propagate); + SatValue assertAssumption(SatLiteral lit, bool propagate) override; - void popAssumption(); - - void setProofLog( BitVectorProof * bvp ); + void popAssumption() override; -private: + void setProofLog(BitVectorProof* bvp) override; + + private: /* Disable the default constructor. */ BVMinisatSatSolver() CVC4_UNDEFINED; diff --git a/src/prop/bvminisat/simp/SimpSolver.h b/src/prop/bvminisat/simp/SimpSolver.h index 9854bf77d..246bb7152 100644 --- a/src/prop/bvminisat/simp/SimpSolver.h +++ b/src/prop/bvminisat/simp/SimpSolver.h @@ -69,8 +69,7 @@ class SimpSolver : public Solver { // Memory managment: // - virtual void garbageCollect(); - + void garbageCollect() override; // Generate a (possibly simplified) DIMACS file: // diff --git a/src/prop/bvminisat/utils/Options.h b/src/prop/bvminisat/utils/Options.h index 12321cba2..698035b7c 100644 --- a/src/prop/bvminisat/utils/Options.h +++ b/src/prop/bvminisat/utils/Options.h @@ -135,42 +135,58 @@ class DoubleOption : public Option operator double& (void) { return value; } DoubleOption& operator=(double x) { value = x; return *this; } - virtual bool parse(const char* str){ - const char* span = str; + bool parse(const char* str) override + { + const char* span = str; - if (!match(span, "-") || !match(span, name) || !match(span, "=")) - return false; - - char* end; - double tmp = strtod(span, &end); - - if (end == NULL) - return false; - else if (tmp >= range.end && (!range.end_inclusive || tmp != range.end)){ - fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name); - exit(1); - }else if (tmp <= range.begin && (!range.begin_inclusive || tmp != range.begin)){ - fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name); - exit(1); } + if (!match(span, "-") || !match(span, name) || !match(span, "=")) + return false; - value = tmp; - // fprintf(stderr, "READ VALUE: %g\n", value); + char* end; + double tmp = strtod(span, &end); - return true; + if (end == NULL) + return false; + else if (tmp >= range.end && (!range.end_inclusive || tmp != range.end)) + { + fprintf(stderr, + "ERROR! value <%s> is too large for option \"%s\".\n", + span, + name); + exit(1); + } + else if (tmp <= range.begin + && (!range.begin_inclusive || tmp != range.begin)) + { + fprintf(stderr, + "ERROR! value <%s> is too small for option \"%s\".\n", + span, + name); + exit(1); + } + + value = tmp; + // fprintf(stderr, "READ VALUE: %g\n", value); + + return true; } - virtual void help (bool verbose = false){ - fprintf(stderr, " -%-12s = %-8s %c%4.2g .. %4.2g%c (default: %g)\n", - name, type_name, - range.begin_inclusive ? '[' : '(', - range.begin, - range.end, - range.end_inclusive ? ']' : ')', - value); - if (verbose){ - fprintf(stderr, "\n %s\n", description); - fprintf(stderr, "\n"); - } + void help(bool verbose = false) override + { + fprintf(stderr, + " -%-12s = %-8s %c%4.2g .. %4.2g%c (default: %g)\n", + name, + type_name, + range.begin_inclusive ? '[' : '(', + range.begin, + range.end, + range.end_inclusive ? ']' : ')', + value); + if (verbose) + { + fprintf(stderr, "\n %s\n", description); + fprintf(stderr, "\n"); + } } }; @@ -193,47 +209,60 @@ class IntOption : public Option operator int32_t& (void) { return value; } IntOption& operator= (int32_t x) { value = x; return *this; } - virtual bool parse(const char* str){ - const char* span = str; - - if (!match(span, "-") || !match(span, name) || !match(span, "=")) - return false; + bool parse(const char* str) override + { + const char* span = str; - char* end; - int32_t tmp = strtol(span, &end, 10); - - if (end == NULL) - return false; - else if (tmp > range.end){ - fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name); - exit(1); - }else if (tmp < range.begin){ - fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name); - exit(1); } + if (!match(span, "-") || !match(span, name) || !match(span, "=")) + return false; - value = tmp; + char* end; + int32_t tmp = strtol(span, &end, 10); - return true; + if (end == NULL) + return false; + else if (tmp > range.end) + { + fprintf(stderr, + "ERROR! value <%s> is too large for option \"%s\".\n", + span, + name); + exit(1); + } + else if (tmp < range.begin) + { + fprintf(stderr, + "ERROR! value <%s> is too small for option \"%s\".\n", + span, + name); + exit(1); + } + + value = tmp; + + return true; } - virtual void help (bool verbose = false){ - fprintf(stderr, " -%-12s = %-8s [", name, type_name); - if (range.begin == INT32_MIN) - fprintf(stderr, "imin"); - else - fprintf(stderr, "%4d", range.begin); - - fprintf(stderr, " .. "); - if (range.end == INT32_MAX) - fprintf(stderr, "imax"); - else - fprintf(stderr, "%4d", range.end); - - fprintf(stderr, "] (default: %d)\n", value); - if (verbose){ - fprintf(stderr, "\n %s\n", description); - fprintf(stderr, "\n"); - } + void help(bool verbose = false) override + { + fprintf(stderr, " -%-12s = %-8s [", name, type_name); + if (range.begin == INT32_MIN) + fprintf(stderr, "imin"); + else + fprintf(stderr, "%4d", range.begin); + + fprintf(stderr, " .. "); + if (range.end == INT32_MAX) + fprintf(stderr, "imax"); + else + fprintf(stderr, "%4d", range.end); + + fprintf(stderr, "] (default: %d)\n", value); + if (verbose) + { + fprintf(stderr, "\n %s\n", description); + fprintf(stderr, "\n"); + } } }; @@ -255,47 +284,60 @@ class Int64Option : public Option operator int64_t& (void) { return value; } Int64Option& operator= (int64_t x) { value = x; return *this; } - virtual bool parse(const char* str){ - const char* span = str; - - if (!match(span, "-") || !match(span, name) || !match(span, "=")) - return false; + bool parse(const char* str) override + { + const char* span = str; - char* end; - int64_t tmp = strtoll(span, &end, 10); - - if (end == NULL) - return false; - else if (tmp > range.end){ - fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name); - exit(1); - }else if (tmp < range.begin){ - fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name); - exit(1); } + if (!match(span, "-") || !match(span, name) || !match(span, "=")) + return false; - value = tmp; + char* end; + int64_t tmp = strtoll(span, &end, 10); - return true; + if (end == NULL) + return false; + else if (tmp > range.end) + { + fprintf(stderr, + "ERROR! value <%s> is too large for option \"%s\".\n", + span, + name); + exit(1); + } + else if (tmp < range.begin) + { + fprintf(stderr, + "ERROR! value <%s> is too small for option \"%s\".\n", + span, + name); + exit(1); + } + + value = tmp; + + return true; } - virtual void help (bool verbose = false){ - fprintf(stderr, " -%-12s = %-8s [", name, type_name); - if (range.begin == INT64_MIN) - fprintf(stderr, "imin"); - else - fprintf(stderr, "%4" PRIi64, range.begin); - - fprintf(stderr, " .. "); - if (range.end == INT64_MAX) - fprintf(stderr, "imax"); - else - fprintf(stderr, "%4" PRIi64, range.end); - - fprintf(stderr, "] (default: %" PRIi64")\n", value); - if (verbose){ - fprintf(stderr, "\n %s\n", description); - fprintf(stderr, "\n"); - } + void help(bool verbose = false) override + { + fprintf(stderr, " -%-12s = %-8s [", name, type_name); + if (range.begin == INT64_MIN) + fprintf(stderr, "imin"); + else + fprintf(stderr, "%4" PRIi64, range.begin); + + fprintf(stderr, " .. "); + if (range.end == INT64_MAX) + fprintf(stderr, "imax"); + else + fprintf(stderr, "%4" PRIi64, range.end); + + fprintf(stderr, "] (default: %" PRIi64 ")\n", value); + if (verbose) + { + fprintf(stderr, "\n %s\n", description); + fprintf(stderr, "\n"); + } } }; #endif @@ -315,22 +357,25 @@ class StringOption : public Option operator const char*& (void) { return value; } StringOption& operator= (const char* x) { value = x; return *this; } - virtual bool parse(const char* str){ - const char* span = str; + bool parse(const char* str) override + { + const char* span = str; - if (!match(span, "-") || !match(span, name) || !match(span, "=")) - return false; + if (!match(span, "-") || !match(span, name) || !match(span, "=")) + return false; - value = span; - return true; + value = span; + return true; } - virtual void help (bool verbose = false){ - fprintf(stderr, " -%-10s = %8s\n", name, type_name); - if (verbose){ - fprintf(stderr, "\n %s\n", description); - fprintf(stderr, "\n"); - } + void help(bool verbose = false) override + { + fprintf(stderr, " -%-10s = %8s\n", name, type_name); + if (verbose) + { + fprintf(stderr, "\n %s\n", description); + fprintf(stderr, "\n"); + } } }; @@ -351,33 +396,37 @@ class BoolOption : public Option operator bool& (void) { return value; } BoolOption& operator=(bool b) { value = b; return *this; } - virtual bool parse(const char* str){ - const char* span = str; - - if (match(span, "-")){ - bool b = !match(span, "no-"); + bool parse(const char* str) override + { + const char* span = str; + + if (match(span, "-")) + { + bool b = !match(span, "no-"); - if (strcmp(span, name) == 0){ - value = b; - return true; } + if (strcmp(span, name) == 0) + { + value = b; + return true; } + } - return false; + return false; } - virtual void help (bool verbose = false){ + void help(bool verbose = false) override + { + fprintf(stderr, " -%s, -no-%s", name, name); - fprintf(stderr, " -%s, -no-%s", name, name); + for (uint32_t i = 0; i < 32 - strlen(name) * 2; i++) fprintf(stderr, " "); - for (uint32_t i = 0; i < 32 - strlen(name)*2; i++) - fprintf(stderr, " "); - - fprintf(stderr, " "); - fprintf(stderr, "(default: %s)\n", value ? "on" : "off"); - if (verbose){ - fprintf(stderr, "\n %s\n", description); - fprintf(stderr, "\n"); - } + fprintf(stderr, " "); + fprintf(stderr, "(default: %s)\n", value ? "on" : "off"); + if (verbose) + { + fprintf(stderr, "\n %s\n", description); + fprintf(stderr, "\n"); + } } }; diff --git a/src/prop/cnf_stream.h b/src/prop/cnf_stream.h index 80f8742a3..174263be0 100644 --- a/src/prop/cnf_stream.h +++ b/src/prop/cnf_stream.h @@ -286,8 +286,11 @@ class TseitinCnfStream : public CnfStream { * @param removable is this something that can be erased * @param negated true if negated */ - void convertAndAssert(TNode node, bool removable, bool negated, - ProofRule rule, TNode from = TNode::null()); + void convertAndAssert(TNode node, + bool removable, + bool negated, + ProofRule rule, + TNode from = TNode::null()) override; private: /** @@ -328,7 +331,7 @@ class TseitinCnfStream : public CnfStream { */ SatLiteral toCNF(TNode node, bool negated = false); - void ensureLiteral(TNode n, bool noPreregistration = false); + void ensureLiteral(TNode n, bool noPreregistration = false) override; }; /* class TseitinCnfStream */ diff --git a/src/prop/minisat/minisat.h b/src/prop/minisat/minisat.h index ca179fbc8..58e02179c 100644 --- a/src/prop/minisat/minisat.h +++ b/src/prop/minisat/minisat.h @@ -39,45 +39,48 @@ public: static void toMinisatClause(SatClause& clause, Minisat::vec& minisat_clause); static void toSatClause (const Minisat::Clause& clause, SatClause& sat_clause); - void initialize(context::Context* context, TheoryProxy* theoryProxy); + void initialize(context::Context* context, TheoryProxy* theoryProxy) override; - ClauseId addClause(SatClause& clause, bool removable); - ClauseId addXorClause(SatClause& clause, bool rhs, bool removable) { + ClauseId addClause(SatClause& clause, bool removable) override; + ClauseId addXorClause(SatClause& clause, bool rhs, bool removable) override + { Unreachable("Minisat does not support native XOR reasoning"); } - SatVariable newVar(bool isTheoryAtom, bool preRegister, bool canErase); - SatVariable trueVar() { return d_minisat->trueVar(); } - SatVariable falseVar() { return d_minisat->falseVar(); } + SatVariable newVar(bool isTheoryAtom, + bool preRegister, + bool canErase) override; + SatVariable trueVar() override { return d_minisat->trueVar(); } + SatVariable falseVar() override { return d_minisat->falseVar(); } - SatValue solve(); - SatValue solve(long unsigned int&); + SatValue solve() override; + SatValue solve(long unsigned int&) override; - bool ok() const; - - void interrupt(); + bool ok() const override; - SatValue value(SatLiteral l); + void interrupt() override; - SatValue modelValue(SatLiteral l); + SatValue value(SatLiteral l) override; - bool properExplanation(SatLiteral lit, SatLiteral expl) const; + SatValue modelValue(SatLiteral l) override; + + bool properExplanation(SatLiteral lit, SatLiteral expl) const override; /** Incremental interface */ - unsigned getAssertionLevel() const; + unsigned getAssertionLevel() const override; - void push(); + void push() override; - void pop(); + void pop() override; - void requirePhase(SatLiteral lit); + void requirePhase(SatLiteral lit) override; - bool flipDecision(); + bool flipDecision() override; - bool isDecision(SatVariable decn) const; + bool isDecision(SatVariable decn) const override; -private: + private: /** The SatSolver used */ Minisat::SimpSolver* d_minisat; diff --git a/src/prop/minisat/simp/SimpSolver.h b/src/prop/minisat/simp/SimpSolver.h index a995c1357..335075f09 100644 --- a/src/prop/minisat/simp/SimpSolver.h +++ b/src/prop/minisat/simp/SimpSolver.h @@ -74,8 +74,7 @@ class SimpSolver : public Solver { // Memory managment: // - virtual void garbageCollect(); - + void garbageCollect() override; // Generate a (possibly simplified) DIMACS file: // diff --git a/src/prop/minisat/utils/Options.h b/src/prop/minisat/utils/Options.h index 0577cbbd0..9bddd2b23 100644 --- a/src/prop/minisat/utils/Options.h +++ b/src/prop/minisat/utils/Options.h @@ -135,42 +135,58 @@ class DoubleOption : public Option operator double& (void) { return value; } DoubleOption& operator=(double x) { value = x; return *this; } - virtual bool parse(const char* str){ - const char* span = str; + bool parse(const char* str) override + { + const char* span = str; - if (!match(span, "-") || !match(span, name) || !match(span, "=")) - return false; - - char* end; - double tmp = strtod(span, &end); - - if (end == NULL) - return false; - else if (tmp >= range.end && (!range.end_inclusive || tmp != range.end)){ - fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name); - exit(1); - }else if (tmp <= range.begin && (!range.begin_inclusive || tmp != range.begin)){ - fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name); - exit(1); } + if (!match(span, "-") || !match(span, name) || !match(span, "=")) + return false; - value = tmp; - // fprintf(stderr, "READ VALUE: %g\n", value); + char* end; + double tmp = strtod(span, &end); - return true; + if (end == NULL) + return false; + else if (tmp >= range.end && (!range.end_inclusive || tmp != range.end)) + { + fprintf(stderr, + "ERROR! value <%s> is too large for option \"%s\".\n", + span, + name); + exit(1); + } + else if (tmp <= range.begin + && (!range.begin_inclusive || tmp != range.begin)) + { + fprintf(stderr, + "ERROR! value <%s> is too small for option \"%s\".\n", + span, + name); + exit(1); + } + + value = tmp; + // fprintf(stderr, "READ VALUE: %g\n", value); + + return true; } - virtual void help (bool verbose = false){ - fprintf(stderr, " -%-12s = %-8s %c%4.2g .. %4.2g%c (default: %g)\n", - name, type_name, - range.begin_inclusive ? '[' : '(', - range.begin, - range.end, - range.end_inclusive ? ']' : ')', - value); - if (verbose){ - fprintf(stderr, "\n %s\n", description); - fprintf(stderr, "\n"); - } + void help(bool verbose = false) override + { + fprintf(stderr, + " -%-12s = %-8s %c%4.2g .. %4.2g%c (default: %g)\n", + name, + type_name, + range.begin_inclusive ? '[' : '(', + range.begin, + range.end, + range.end_inclusive ? ']' : ')', + value); + if (verbose) + { + fprintf(stderr, "\n %s\n", description); + fprintf(stderr, "\n"); + } } }; @@ -193,47 +209,60 @@ class IntOption : public Option operator int32_t& (void) { return value; } IntOption& operator= (int32_t x) { value = x; return *this; } - virtual bool parse(const char* str){ - const char* span = str; - - if (!match(span, "-") || !match(span, name) || !match(span, "=")) - return false; + bool parse(const char* str) override + { + const char* span = str; - char* end; - int32_t tmp = strtol(span, &end, 10); - - if (end == NULL) - return false; - else if (tmp > range.end){ - fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name); - exit(1); - }else if (tmp < range.begin){ - fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name); - exit(1); } + if (!match(span, "-") || !match(span, name) || !match(span, "=")) + return false; - value = tmp; + char* end; + int32_t tmp = strtol(span, &end, 10); - return true; + if (end == NULL) + return false; + else if (tmp > range.end) + { + fprintf(stderr, + "ERROR! value <%s> is too large for option \"%s\".\n", + span, + name); + exit(1); + } + else if (tmp < range.begin) + { + fprintf(stderr, + "ERROR! value <%s> is too small for option \"%s\".\n", + span, + name); + exit(1); + } + + value = tmp; + + return true; } - virtual void help (bool verbose = false){ - fprintf(stderr, " -%-12s = %-8s [", name, type_name); - if (range.begin == INT32_MIN) - fprintf(stderr, "imin"); - else - fprintf(stderr, "%4d", range.begin); - - fprintf(stderr, " .. "); - if (range.end == INT32_MAX) - fprintf(stderr, "imax"); - else - fprintf(stderr, "%4d", range.end); - - fprintf(stderr, "] (default: %d)\n", value); - if (verbose){ - fprintf(stderr, "\n %s\n", description); - fprintf(stderr, "\n"); - } + void help(bool verbose = false) override + { + fprintf(stderr, " -%-12s = %-8s [", name, type_name); + if (range.begin == INT32_MIN) + fprintf(stderr, "imin"); + else + fprintf(stderr, "%4d", range.begin); + + fprintf(stderr, " .. "); + if (range.end == INT32_MAX) + fprintf(stderr, "imax"); + else + fprintf(stderr, "%4d", range.end); + + fprintf(stderr, "] (default: %d)\n", value); + if (verbose) + { + fprintf(stderr, "\n %s\n", description); + fprintf(stderr, "\n"); + } } }; @@ -255,47 +284,60 @@ class Int64Option : public Option operator int64_t& (void) { return value; } Int64Option& operator= (int64_t x) { value = x; return *this; } - virtual bool parse(const char* str){ - const char* span = str; - - if (!match(span, "-") || !match(span, name) || !match(span, "=")) - return false; + bool parse(const char* str) override + { + const char* span = str; - char* end; - int64_t tmp = strtoll(span, &end, 10); - - if (end == NULL) - return false; - else if (tmp > range.end){ - fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name); - exit(1); - }else if (tmp < range.begin){ - fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name); - exit(1); } + if (!match(span, "-") || !match(span, name) || !match(span, "=")) + return false; - value = tmp; + char* end; + int64_t tmp = strtoll(span, &end, 10); - return true; + if (end == NULL) + return false; + else if (tmp > range.end) + { + fprintf(stderr, + "ERROR! value <%s> is too large for option \"%s\".\n", + span, + name); + exit(1); + } + else if (tmp < range.begin) + { + fprintf(stderr, + "ERROR! value <%s> is too small for option \"%s\".\n", + span, + name); + exit(1); + } + + value = tmp; + + return true; } - virtual void help (bool verbose = false){ - fprintf(stderr, " -%-12s = %-8s [", name, type_name); - if (range.begin == INT64_MIN) - fprintf(stderr, "imin"); - else - fprintf(stderr, "%4" PRIi64, range.begin); - - fprintf(stderr, " .. "); - if (range.end == INT64_MAX) - fprintf(stderr, "imax"); - else - fprintf(stderr, "%4" PRIi64, range.end); - - fprintf(stderr, "] (default: %" PRIi64")\n", value); - if (verbose){ - fprintf(stderr, "\n %s\n", description); - fprintf(stderr, "\n"); - } + void help(bool verbose = false) override + { + fprintf(stderr, " -%-12s = %-8s [", name, type_name); + if (range.begin == INT64_MIN) + fprintf(stderr, "imin"); + else + fprintf(stderr, "%4" PRIi64, range.begin); + + fprintf(stderr, " .. "); + if (range.end == INT64_MAX) + fprintf(stderr, "imax"); + else + fprintf(stderr, "%4" PRIi64, range.end); + + fprintf(stderr, "] (default: %" PRIi64 ")\n", value); + if (verbose) + { + fprintf(stderr, "\n %s\n", description); + fprintf(stderr, "\n"); + } } }; #endif @@ -315,22 +357,25 @@ class StringOption : public Option operator const char*& (void) { return value; } StringOption& operator= (const char* x) { value = x; return *this; } - virtual bool parse(const char* str){ - const char* span = str; + bool parse(const char* str) override + { + const char* span = str; - if (!match(span, "-") || !match(span, name) || !match(span, "=")) - return false; + if (!match(span, "-") || !match(span, name) || !match(span, "=")) + return false; - value = span; - return true; + value = span; + return true; } - virtual void help (bool verbose = false){ - fprintf(stderr, " -%-10s = %8s\n", name, type_name); - if (verbose){ - fprintf(stderr, "\n %s\n", description); - fprintf(stderr, "\n"); - } + void help(bool verbose = false) override + { + fprintf(stderr, " -%-10s = %8s\n", name, type_name); + if (verbose) + { + fprintf(stderr, "\n %s\n", description); + fprintf(stderr, "\n"); + } } }; @@ -351,33 +396,37 @@ class BoolOption : public Option operator bool& (void) { return value; } BoolOption& operator=(bool b) { value = b; return *this; } - virtual bool parse(const char* str){ - const char* span = str; - - if (match(span, "-")){ - bool b = !match(span, "no-"); + bool parse(const char* str) override + { + const char* span = str; + + if (match(span, "-")) + { + bool b = !match(span, "no-"); - if (strcmp(span, name) == 0){ - value = b; - return true; } + if (strcmp(span, name) == 0) + { + value = b; + return true; } + } - return false; + return false; } - virtual void help (bool verbose = false){ + void help(bool verbose = false) override + { + fprintf(stderr, " -%s, -no-%s", name, name); - fprintf(stderr, " -%s, -no-%s", name, name); + for (uint32_t i = 0; i < 32 - strlen(name) * 2; i++) fprintf(stderr, " "); - for (uint32_t i = 0; i < 32 - strlen(name)*2; i++) - fprintf(stderr, " "); - - fprintf(stderr, " "); - fprintf(stderr, "(default: %s)\n", value ? "on" : "off"); - if (verbose){ - fprintf(stderr, "\n %s\n", description); - fprintf(stderr, "\n"); - } + fprintf(stderr, " "); + fprintf(stderr, "(default: %s)\n", value ? "on" : "off"); + if (verbose) + { + fprintf(stderr, "\n %s\n", description); + fprintf(stderr, "\n"); + } } }; diff --git a/src/prop/registrar.h b/src/prop/registrar.h index ec774e979..9735aa43d 100644 --- a/src/prop/registrar.h +++ b/src/prop/registrar.h @@ -35,7 +35,7 @@ public: class NullRegistrar : public Registrar { public: - void preRegister(Node n) {} + void preRegister(Node n) override {} };/* class NullRegistrar */ diff --git a/src/prop/sat_solver.h b/src/prop/sat_solver.h index 7be5305ad..4dc95e060 100644 --- a/src/prop/sat_solver.h +++ b/src/prop/sat_solver.h @@ -137,10 +137,6 @@ public: virtual void popAssumption() = 0; - virtual bool ok() const = 0; - - virtual void setProofLog( BitVectorProof * bvp ) {} - };/* class BVSatSolverInterface */ @@ -159,8 +155,6 @@ public: virtual bool flipDecision() = 0; virtual bool isDecision(SatVariable decn) const = 0; - - virtual bool ok() const = 0; };/* class DPLLSatSolverInterface */ inline std::ostream& operator <<(std::ostream& out, prop::SatLiteral lit) { diff --git a/src/smt/managed_ostreams.h b/src/smt/managed_ostreams.h index 3114821b3..f2566d35c 100644 --- a/src/smt/managed_ostreams.h +++ b/src/smt/managed_ostreams.h @@ -79,7 +79,8 @@ class SetToDefaultSourceListener : public Listener { SetToDefaultSourceListener(ManagedOstream* managedOstream) : d_managedOstream(managedOstream){} - virtual void notify() { + void notify() override + { d_managedOstream->set(d_managedOstream->defaultSource()); } @@ -97,15 +98,15 @@ class ManagedDumpOStream : public ManagedOstream { ManagedDumpOStream(){} ~ManagedDumpOStream(); - virtual const char* getName() const { return "dump-to"; } - virtual std::string defaultSource() const; + const char* getName() const override { return "dump-to"; } + std::string defaultSource() const override; protected: /** Initializes an output stream. Not necessarily managed. */ - virtual void initialize(std::ostream* outStream); + void initialize(std::ostream* outStream) override; /** Adds special cases to an ostreamopener. */ - virtual void addSpecialCases(OstreamOpener* opener) const; + void addSpecialCases(OstreamOpener* opener) const override; };/* class ManagedDumpOStream */ /** @@ -120,15 +121,15 @@ class ManagedRegularOutputChannel : public ManagedOstream { /** Assumes Options are in scope. */ ~ManagedRegularOutputChannel(); - virtual const char* getName() const { return "regular-output-channel"; } - virtual std::string defaultSource() const; + const char* getName() const override { return "regular-output-channel"; } + std::string defaultSource() const override; protected: /** Initializes an output stream. Not necessarily managed. */ - virtual void initialize(std::ostream* outStream); + void initialize(std::ostream* outStream) override; /** Adds special cases to an ostreamopener. */ - virtual void addSpecialCases(OstreamOpener* opener) const; + void addSpecialCases(OstreamOpener* opener) const override; };/* class ManagedRegularOutputChannel */ @@ -144,15 +145,15 @@ class ManagedDiagnosticOutputChannel : public ManagedOstream { /** Assumes Options are in scope. */ ~ManagedDiagnosticOutputChannel(); - virtual const char* getName() const { return "diagnostic-output-channel"; } - virtual std::string defaultSource() const; + const char* getName() const override { return "diagnostic-output-channel"; } + std::string defaultSource() const override; protected: /** Initializes an output stream. Not necessarily managed. */ - virtual void initialize(std::ostream* outStream); + void initialize(std::ostream* outStream) override; /** Adds special cases to an ostreamopener. */ - virtual void addSpecialCases(OstreamOpener* opener) const; + void addSpecialCases(OstreamOpener* opener) const override; };/* class ManagedRegularOutputChannel */ /** This controls the memory associated with replay-log. */ @@ -162,15 +163,15 @@ class ManagedReplayLogOstream : public ManagedOstream { ~ManagedReplayLogOstream(); std::ostream* getReplayLog() const { return d_replayLog; } - virtual const char* getName() const { return "replay-log"; } - virtual std::string defaultSource() const; + const char* getName() const override { return "replay-log"; } + std::string defaultSource() const override; protected: /** Initializes an output stream. Not necessarily managed. */ - virtual void initialize(std::ostream* outStream); + void initialize(std::ostream* outStream) override; /** Adds special cases to an ostreamopener. */ - virtual void addSpecialCases(OstreamOpener* opener) const; + void addSpecialCases(OstreamOpener* opener) const override; private: std::ostream* d_replayLog; diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp index 6e90ab152..74d6c1b10 100644 --- a/src/smt/smt_engine.cpp +++ b/src/smt/smt_engine.cpp @@ -298,7 +298,8 @@ struct SmtEngineStatistics { class SoftResourceOutListener : public Listener { public: SoftResourceOutListener(SmtEngine& smt) : d_smt(&smt) {} - virtual void notify() { + void notify() override + { SmtScope scope(d_smt); Assert(smt::smtEngineInScope()); d_smt->interrupt(); @@ -311,7 +312,8 @@ class SoftResourceOutListener : public Listener { class HardResourceOutListener : public Listener { public: HardResourceOutListener(SmtEngine& smt) : d_smt(&smt) {} - virtual void notify() { + void notify() override + { SmtScope scope(d_smt); theory::Rewriter::clearCaches(); } @@ -322,7 +324,8 @@ class HardResourceOutListener : public Listener { class SetLogicListener : public Listener { public: SetLogicListener(SmtEngine& smt) : d_smt(&smt) {} - virtual void notify() { + void notify() override + { LogicInfo inOptions(options::forceLogicString()); d_smt->setLogic(inOptions); } @@ -333,9 +336,8 @@ class SetLogicListener : public Listener { class BeforeSearchListener : public Listener { public: BeforeSearchListener(SmtEngine& smt) : d_smt(&smt) {} - virtual void notify() { - d_smt->beforeSearch(); - } + void notify() override { d_smt->beforeSearch(); } + private: SmtEngine* d_smt; }; /* class BeforeSearchListener */ @@ -346,7 +348,8 @@ class UseTheoryListListener : public Listener { : d_theoryEngine(theoryEngine) {} - void notify() { + void notify() override + { std::stringstream commaList(options::useTheoryList()); std::string token; @@ -375,7 +378,8 @@ class UseTheoryListListener : public Listener { class SetDefaultExprDepthListener : public Listener { public: - virtual void notify() { + void notify() override + { int depth = options::defaultExprDepth(); Debug.getStream() << expr::ExprSetDepth(depth); Trace.getStream() << expr::ExprSetDepth(depth); @@ -389,7 +393,8 @@ class SetDefaultExprDepthListener : public Listener { class SetDefaultExprDagListener : public Listener { public: - virtual void notify() { + void notify() override + { int dag = options::defaultDagThresh(); Debug.getStream() << expr::ExprDag(dag); Trace.getStream() << expr::ExprDag(dag); @@ -403,7 +408,8 @@ class SetDefaultExprDagListener : public Listener { class SetPrintExprTypesListener : public Listener { public: - virtual void notify() { + void notify() override + { bool value = options::printExprTypes(); Debug.getStream() << expr::ExprPrintTypes(value); Trace.getStream() << expr::ExprPrintTypes(value); @@ -417,7 +423,8 @@ class SetPrintExprTypesListener : public Listener { class DumpModeListener : public Listener { public: - virtual void notify() { + void notify() override + { const std::string& value = options::dumpModeString(); Dump.setDumpFromString(value); } @@ -425,7 +432,8 @@ class DumpModeListener : public Listener { class PrintSuccessListener : public Listener { public: - virtual void notify() { + void notify() override + { bool value = options::printSuccess(); Debug.getStream() << Command::printsuccess(value); Trace.getStream() << Command::printsuccess(value); @@ -748,7 +756,8 @@ public: d_resourceManager->spendResource(amount); } - void nmNotifyNewSort(TypeNode tn, uint32_t flags) { + void nmNotifyNewSort(TypeNode tn, uint32_t flags) override + { DeclareTypeCommand c(tn.getAttribute(expr::VarNameAttr()), 0, tn.toType()); @@ -757,19 +766,22 @@ public: } } - void nmNotifyNewSortConstructor(TypeNode tn) { + void nmNotifyNewSortConstructor(TypeNode tn) override + { DeclareTypeCommand c(tn.getAttribute(expr::VarNameAttr()), tn.getAttribute(expr::SortArityAttr()), tn.toType()); d_smt.addToModelCommandAndDump(c); } - void nmNotifyNewDatatypes(const std::vector& dtts) { + void nmNotifyNewDatatypes(const std::vector& dtts) override + { DatatypeDeclarationCommand c(dtts); d_smt.addToModelCommandAndDump(c); } - void nmNotifyNewVar(TNode n, uint32_t flags) { + void nmNotifyNewVar(TNode n, uint32_t flags) override + { DeclareFunctionCommand c(n.getAttribute(expr::VarNameAttr()), n.toExpr(), n.getType().toType()); @@ -781,11 +793,12 @@ public: } } - void nmNotifyNewSkolem(TNode n, const std::string& comment, uint32_t flags) { + void nmNotifyNewSkolem(TNode n, + const std::string& comment, + uint32_t flags) override + { string id = n.getAttribute(expr::VarNameAttr()); - DeclareFunctionCommand c(id, - n.toExpr(), - n.getType().toType()); + DeclareFunctionCommand c(id, n.toExpr(), n.getType().toType()); if(Dump.isOn("skolems") && comment != "") { Dump("skolems") << CommentCommand(id + " is " + comment); } @@ -797,7 +810,7 @@ public: } } - void nmNotifyDeleteNode(TNode n) {} + void nmNotifyDeleteNode(TNode n) override {} Node applySubstitutions(TNode node) const { return Rewriter::rewrite(d_topLevelSubstitutions.apply(node)); diff --git a/src/smt/update_ostream.h b/src/smt/update_ostream.h index ce4504279..a161985de 100644 --- a/src/smt/update_ostream.h +++ b/src/smt/update_ostream.h @@ -73,50 +73,50 @@ public: class OptionsErrOstreamUpdate : public OstreamUpdate { public: - virtual std::ostream& get() { return *(options::err()); } - virtual void set(std::ostream* setTo) { return options::err.set(setTo); } + std::ostream& get() override { return *(options::err()); } + void set(std::ostream* setTo) override { return options::err.set(setTo); } }; /* class OptionsErrOstreamUpdate */ class DumpOstreamUpdate : public OstreamUpdate { public: - virtual std::ostream& get() { return Dump.getStream(); } - virtual void set(std::ostream* setTo) { Dump.setStream(setTo); } + std::ostream& get() override { return Dump.getStream(); } + void set(std::ostream* setTo) override { Dump.setStream(setTo); } }; /* class DumpOstreamUpdate */ class DebugOstreamUpdate : public OstreamUpdate { public: - virtual std::ostream& get() { return Debug.getStream(); } - virtual void set(std::ostream* setTo) { Debug.setStream(setTo); } + std::ostream& get() override { return Debug.getStream(); } + void set(std::ostream* setTo) override { Debug.setStream(setTo); } }; /* class DebugOstreamUpdate */ class WarningOstreamUpdate : public OstreamUpdate { public: - virtual std::ostream& get() { return Warning.getStream(); } - virtual void set(std::ostream* setTo) { Warning.setStream(setTo); } + std::ostream& get() override { return Warning.getStream(); } + void set(std::ostream* setTo) override { Warning.setStream(setTo); } }; /* class WarningOstreamUpdate */ class MessageOstreamUpdate : public OstreamUpdate { public: - virtual std::ostream& get() { return Message.getStream(); } - virtual void set(std::ostream* setTo) { Message.setStream(setTo); } + std::ostream& get() override { return Message.getStream(); } + void set(std::ostream* setTo) override { Message.setStream(setTo); } }; /* class MessageOstreamUpdate */ class NoticeOstreamUpdate : public OstreamUpdate { public: - virtual std::ostream& get() { return Notice.getStream(); } - virtual void set(std::ostream* setTo) { Notice.setStream(setTo); } + std::ostream& get() override { return Notice.getStream(); } + void set(std::ostream* setTo) override { Notice.setStream(setTo); } }; /* class NoticeOstreamUpdate */ class ChatOstreamUpdate : public OstreamUpdate { public: - virtual std::ostream& get() { return Chat.getStream(); } - virtual void set(std::ostream* setTo) { Chat.setStream(setTo); } + std::ostream& get() override { return Chat.getStream(); } + void set(std::ostream* setTo) override { Chat.setStream(setTo); } }; /* class ChatOstreamUpdate */ class TraceOstreamUpdate : public OstreamUpdate { public: - virtual std::ostream& get() { return Trace.getStream(); } - virtual void set(std::ostream* setTo) { Trace.setStream(setTo); } + std::ostream& get() override { return Trace.getStream(); } + void set(std::ostream* setTo) override { Trace.setStream(setTo); } }; /* class TraceOstreamUpdate */ }/* CVC4 namespace */ diff --git a/src/theory/arith/attempt_solution_simplex.h b/src/theory/arith/attempt_solution_simplex.h index 73798f94c..fa65214e7 100644 --- a/src/theory/arith/attempt_solution_simplex.h +++ b/src/theory/arith/attempt_solution_simplex.h @@ -67,11 +67,9 @@ public: Result::Sat attempt(const ApproximateSimplex::Solution& sol); - Result::Sat findModel(bool exactResult){ - Unreachable(); - } + Result::Sat findModel(bool exactResult) override { Unreachable(); } -private: + private: bool matchesNewValue(const DenseMap& nv, ArithVar v) const; bool processSignals(){ diff --git a/src/theory/arith/callbacks.h b/src/theory/arith/callbacks.h index 3710ac5c0..f84550dcc 100644 --- a/src/theory/arith/callbacks.h +++ b/src/theory/arith/callbacks.h @@ -73,7 +73,7 @@ private: TheoryArithPrivate& d_arith; public: SetupLiteralCallBack(TheoryArithPrivate& ta); - void operator()(TNode lit); + void operator()(TNode lit) override; }; class DeltaComputeCallback : public RationalCallBack { @@ -81,7 +81,7 @@ private: const TheoryArithPrivate& d_ta; public: DeltaComputeCallback(const TheoryArithPrivate& ta); - Rational operator()() const; + Rational operator()() const override; }; class BasicVarModelUpdateCallBack : public ArithVarCallBack{ @@ -89,7 +89,7 @@ private: TheoryArithPrivate& d_ta; public: BasicVarModelUpdateCallBack(TheoryArithPrivate& ta); - void operator()(ArithVar x); + void operator()(ArithVar x) override; }; class TempVarMalloc : public ArithVarMalloc { @@ -97,8 +97,8 @@ private: TheoryArithPrivate& d_ta; public: TempVarMalloc(TheoryArithPrivate& ta); - ArithVar request(); - void release(ArithVar v); + ArithVar request() override; + void release(ArithVar v) override; }; class RaiseConflict { diff --git a/src/theory/arith/congruence_manager.h b/src/theory/arith/congruence_manager.h index 228f29838..5085dc841 100644 --- a/src/theory/arith/congruence_manager.h +++ b/src/theory/arith/congruence_manager.h @@ -61,17 +61,20 @@ private: public: ArithCongruenceNotify(ArithCongruenceManager& acm); - bool eqNotifyTriggerEquality(TNode equality, bool value); + bool eqNotifyTriggerEquality(TNode equality, bool value) override; - bool eqNotifyTriggerPredicate(TNode predicate, bool value); + bool eqNotifyTriggerPredicate(TNode predicate, bool value) override; - bool eqNotifyTriggerTermEquality(TheoryId tag, TNode t1, TNode t2, bool value); + bool eqNotifyTriggerTermEquality(TheoryId tag, + TNode t1, + TNode t2, + bool value) override; - void eqNotifyConstantTermMerge(TNode t1, TNode t2); - void eqNotifyNewClass(TNode t); - void eqNotifyPreMerge(TNode t1, TNode t2); - void eqNotifyPostMerge(TNode t1, TNode t2); - void eqNotifyDisequal(TNode t1, TNode t2, TNode reason); + void eqNotifyConstantTermMerge(TNode t1, TNode t2) override; + void eqNotifyNewClass(TNode t) override; + void eqNotifyPreMerge(TNode t1, TNode t2) override; + void eqNotifyPostMerge(TNode t1, TNode t2) override; + void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override; }; ArithCongruenceNotify d_notify; diff --git a/src/theory/arith/dual_simplex.h b/src/theory/arith/dual_simplex.h index 2911592c7..10d18170e 100644 --- a/src/theory/arith/dual_simplex.h +++ b/src/theory/arith/dual_simplex.h @@ -63,7 +63,8 @@ class DualSimplexDecisionProcedure : public SimplexDecisionProcedure{ public: DualSimplexDecisionProcedure(LinearEqualityModule& linEq, ErrorSet& errors, RaiseConflict conflictChannel, TempVarMalloc tvmalloc); - Result::Sat findModel(bool exactResult) { + Result::Sat findModel(bool exactResult) override + { return dualFindModel(exactResult); } diff --git a/src/theory/arith/fc_simplex.h b/src/theory/arith/fc_simplex.h index c4f996f9f..a93fa88e8 100644 --- a/src/theory/arith/fc_simplex.h +++ b/src/theory/arith/fc_simplex.h @@ -66,7 +66,7 @@ class FCSimplexDecisionProcedure : public SimplexDecisionProcedure{ public: FCSimplexDecisionProcedure(LinearEqualityModule& linEq, ErrorSet& errors, RaiseConflict conflictChannel, TempVarMalloc tvmalloc); - Result::Sat findModel(bool exactResult); + Result::Sat findModel(bool exactResult) override; // other error variables are dropping WitnessImprovement dualLikeImproveError(ArithVar evar); diff --git a/src/theory/arith/linear_equality.h b/src/theory/arith/linear_equality.h index c2fa99e31..0f2862a72 100644 --- a/src/theory/arith/linear_equality.h +++ b/src/theory/arith/linear_equality.h @@ -588,13 +588,16 @@ private: LinearEqualityModule* d_linEq; public: TrackingCallback(LinearEqualityModule* le) : d_linEq(le) {} - void update(RowIndex ridx, ArithVar nb, int oldSgn, int currSgn){ + void update(RowIndex ridx, ArithVar nb, int oldSgn, int currSgn) override + { d_linEq->trackingCoefficientChange(ridx, nb, oldSgn, currSgn); } - void multiplyRow(RowIndex ridx, int sgn){ + void multiplyRow(RowIndex ridx, int sgn) override + { d_linEq->trackingMultiplyRow(ridx, sgn); } - bool canUseRow(RowIndex ridx) const { + bool canUseRow(RowIndex ridx) const override + { ArithVar basic = d_linEq->getTableau().rowIndexToBasic(ridx); return d_linEq->basicIsTracked(basic); } @@ -746,7 +749,8 @@ private: LinearEqualityModule* d_mod; public: UpdateTrackingCallback(LinearEqualityModule* mod): d_mod(mod){} - void operator()(ArithVar v, const BoundsInfo& bi){ + void operator()(ArithVar v, const BoundsInfo& bi) override + { d_mod->includeBoundUpdate(v, bi); } }; diff --git a/src/theory/arith/matrix.h b/src/theory/arith/matrix.h index 2e0a1ebb2..eda5b9dac 100644 --- a/src/theory/arith/matrix.h +++ b/src/theory/arith/matrix.h @@ -48,9 +48,9 @@ public: class NoEffectCCCB : public CoefficientChangeCallback { public: - void update(RowIndex ridx, ArithVar nb, int oldSgn, int currSgn); - void multiplyRow(RowIndex ridx, int Sgn); - bool canUseRow(RowIndex ridx) const; + void update(RowIndex ridx, ArithVar nb, int oldSgn, int currSgn) override; + void multiplyRow(RowIndex ridx, int Sgn) override; + bool canUseRow(RowIndex ridx) const override; }; template diff --git a/src/theory/arith/soi_simplex.h b/src/theory/arith/soi_simplex.h index 5f2233b3f..54a47ac4d 100644 --- a/src/theory/arith/soi_simplex.h +++ b/src/theory/arith/soi_simplex.h @@ -66,7 +66,7 @@ class SumOfInfeasibilitiesSPD : public SimplexDecisionProcedure { public: SumOfInfeasibilitiesSPD(LinearEqualityModule& linEq, ErrorSet& errors, RaiseConflict conflictChannel, TempVarMalloc tvmalloc); - Result::Sat findModel(bool exactResult); + Result::Sat findModel(bool exactResult) override; // other error variables are dropping WitnessImprovement dualLikeImproveError(ArithVar evar); diff --git a/src/theory/arrays/theory_arrays.h b/src/theory/arrays/theory_arrays.h index caf466c0c..70cb574a8 100644 --- a/src/theory/arrays/theory_arrays.h +++ b/src/theory/arrays/theory_arrays.h @@ -277,7 +277,8 @@ class TheoryArrays : public Theory { public: NotifyClass(TheoryArrays& arrays): d_arrays(arrays) {} - bool eqNotifyTriggerEquality(TNode equality, bool value) { + bool eqNotifyTriggerEquality(TNode equality, bool value) override + { Debug("arrays::propagate") << spaces(d_arrays.getSatContext()->getLevel()) << "NotifyClass::eqNotifyTriggerEquality(" << equality << ", " << (value ? "true" : "false") << ")" << std::endl; // Just forward to arrays if (value) { @@ -287,7 +288,8 @@ class TheoryArrays : public Theory { } } - bool eqNotifyTriggerPredicate(TNode predicate, bool value) { + bool eqNotifyTriggerPredicate(TNode predicate, bool value) override + { Debug("arrays::propagate") << spaces(d_arrays.getSatContext()->getLevel()) << "NotifyClass::eqNotifyTriggerEquality(" << predicate << ", " << (value ? "true" : "false") << ")" << std::endl; // Just forward to arrays if (value) { @@ -297,7 +299,11 @@ class TheoryArrays : public Theory { } } - bool eqNotifyTriggerTermEquality(TheoryId tag, TNode t1, TNode t2, bool value) { + bool eqNotifyTriggerTermEquality(TheoryId tag, + TNode t1, + TNode t2, + bool value) override + { Debug("arrays::propagate") << spaces(d_arrays.getSatContext()->getLevel()) << "NotifyClass::eqNotifyTriggerTermEquality(" << t1 << ", " << t2 << ", " << (value ? "true" : "false") << ")" << std::endl; if (value) { if (t1.getType().isArray()) { @@ -318,19 +324,21 @@ class TheoryArrays : public Theory { return true; } - void eqNotifyConstantTermMerge(TNode t1, TNode t2) { + void eqNotifyConstantTermMerge(TNode t1, TNode t2) override + { Debug("arrays::propagate") << spaces(d_arrays.getSatContext()->getLevel()) << "NotifyClass::eqNotifyConstantTermMerge(" << t1 << ", " << t2 << ")" << std::endl; d_arrays.conflict(t1, t2); } - void eqNotifyNewClass(TNode t) { } - void eqNotifyPreMerge(TNode t1, TNode t2) { } - void eqNotifyPostMerge(TNode t1, TNode t2) { + void eqNotifyNewClass(TNode t) override {} + void eqNotifyPreMerge(TNode t1, TNode t2) override {} + void eqNotifyPostMerge(TNode t1, TNode t2) override + { if (t1.getType().isArray()) { d_arrays.mergeArrays(t1, t2); } } - void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) { } + void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override {} }; /** The notify class for d_equalityEngine */ @@ -386,10 +394,12 @@ class TheoryArrays : public Theory { context::Context* d_satContext; context::Context* d_contextToPop; protected: - void contextNotifyPop() { - if (d_contextToPop->getLevel() > d_satContext->getLevel()) { - d_contextToPop->pop(); - } + void contextNotifyPop() override + { + if (d_contextToPop->getLevel() > d_satContext->getLevel()) + { + d_contextToPop->pop(); + } } public: ContextPopper(context::Context* context, context::Context* contextToPop) diff --git a/src/theory/booleans/circuit_propagator.h b/src/theory/booleans/circuit_propagator.h index 78e01f690..7c60505a5 100644 --- a/src/theory/booleans/circuit_propagator.h +++ b/src/theory/booleans/circuit_propagator.h @@ -79,10 +79,11 @@ private: class DataClearer : context::ContextNotifyObj { T& d_data; protected: - void contextNotifyPop() { - Trace("circuit-prop") << "CircuitPropagator::DataClearer: clearing data " - << "(size was " << d_data.size() << ")" << std::endl; - d_data.clear(); + void contextNotifyPop() override + { + Trace("circuit-prop") << "CircuitPropagator::DataClearer: clearing data " + << "(size was " << d_data.size() << ")" << std::endl; + d_data.clear(); } public: DataClearer(context::Context* context, T& data) : diff --git a/src/theory/booleans/theory_bool.h b/src/theory/booleans/theory_bool.h index 9d5966628..cd9a9f904 100644 --- a/src/theory/booleans/theory_bool.h +++ b/src/theory/booleans/theory_bool.h @@ -33,11 +33,11 @@ public: : Theory(THEORY_BOOL, c, u, out, valuation, logicInfo) {} - PPAssertStatus ppAssert(TNode in, SubstitutionMap& outSubstitutions); + PPAssertStatus ppAssert(TNode in, SubstitutionMap& outSubstitutions) override; //void check(Effort); - - std::string identify() const { return std::string("TheoryBool"); } + + std::string identify() const override { return std::string("TheoryBool"); } };/* class TheoryBool */ }/* CVC4::theory::booleans namespace */ diff --git a/src/theory/builtin/theory_builtin.h b/src/theory/builtin/theory_builtin.h index cfc59272c..14a38660b 100644 --- a/src/theory/builtin/theory_builtin.h +++ b/src/theory/builtin/theory_builtin.h @@ -31,7 +31,7 @@ public: OutputChannel& out, Valuation valuation, const LogicInfo& logicInfo) : Theory(THEORY_BUILTIN, c, u, out, valuation, logicInfo) {} - std::string identify() const { return std::string("TheoryBuiltin"); } + std::string identify() const override { return std::string("TheoryBuiltin"); } };/* class TheoryBuiltin */ }/* CVC4::theory::builtin namespace */ diff --git a/src/theory/bv/bitblaster_template.h b/src/theory/bv/bitblaster_template.h index 1dc2d8b1e..3bb701fdf 100644 --- a/src/theory/bv/bitblaster_template.h +++ b/src/theory/bv/bitblaster_template.h @@ -169,15 +169,15 @@ class TLazyBitblaster : public TBitblaster { void addAtom(TNode atom); bool hasValue(TNode a); - Node getModelFromSatSolver(TNode a, bool fullModel); + Node getModelFromSatSolver(TNode a, bool fullModel) override; -public: - void bbTerm(TNode node, Bits& bits); - void bbAtom(TNode node); - Node getBBAtom(TNode atom) const; - void storeBBAtom(TNode atom, Node atom_bb); - void storeBBTerm(TNode node, const Bits& bits); - bool hasBBAtom(TNode atom) const; + public: + void bbTerm(TNode node, Bits& bits) override; + void bbAtom(TNode node) override; + Node getBBAtom(TNode atom) const override; + void storeBBAtom(TNode atom, Node atom_bb) override; + void storeBBTerm(TNode node, const Bits& bits) override; + bool hasBBAtom(TNode atom) const override; TLazyBitblaster(context::Context* c, bv::TheoryBV* bv, const std::string name="", bool emptyNotify = false); ~TLazyBitblaster(); @@ -219,7 +219,7 @@ public: * * @param var */ - void makeVariable(TNode var, Bits& bits); + void makeVariable(TNode var, Bits& bits) override; bool isSharedTerm(TNode node); uint64_t computeAtomWeight(TNode node, NodeSet& seen); @@ -274,7 +274,7 @@ class EagerBitblaster : public TBitblaster { // This is either an MinisatEmptyNotify or NULL. MinisatEmptyNotify* d_notify; - Node getModelFromSatSolver(TNode a, bool fullModel); + Node getModelFromSatSolver(TNode a, bool fullModel) override; bool isSharedTerm(TNode node); public: @@ -282,14 +282,14 @@ public: ~EagerBitblaster(); void addAtom(TNode atom); - void makeVariable(TNode node, Bits& bits); - void bbTerm(TNode node, Bits& bits); - void bbAtom(TNode node); - Node getBBAtom(TNode node) const; - bool hasBBAtom(TNode atom) const; + void makeVariable(TNode node, Bits& bits) override; + void bbTerm(TNode node, Bits& bits) override; + void bbAtom(TNode node) override; + Node getBBAtom(TNode node) const override; + bool hasBBAtom(TNode atom) const override; void bbFormula(TNode formula); - void storeBBAtom(TNode atom, Node atom_bb); - void storeBBTerm(TNode node, const Bits& bits); + void storeBBAtom(TNode atom, Node atom_bb) override; + void storeBBTerm(TNode node, const Bits& bits) override; bool assertToSat(TNode node, bool propagate = true); bool solve(); @@ -303,7 +303,7 @@ public: BitblastingRegistrar(EagerBitblaster* bb) : d_bitblaster(bb) {} - void preRegister(Node n); + void preRegister(Node n) override; }; /* class Registrar */ class AigBitblaster : public TBitblaster { @@ -322,9 +322,9 @@ class AigBitblaster : public TBitblaster { void addAtom(TNode atom); void simplifyAig(); - void storeBBAtom(TNode atom, Abc_Obj_t* atom_bb); - Abc_Obj_t* getBBAtom(TNode atom) const; - bool hasBBAtom(TNode atom) const; + void storeBBAtom(TNode atom, Abc_Obj_t* atom_bb) override; + Abc_Obj_t* getBBAtom(TNode atom) const override; + bool hasBBAtom(TNode atom) const override; void cacheAig(TNode node, Abc_Obj_t* aig); bool hasAig(TNode node); Abc_Obj_t* getAig(TNode node); @@ -332,14 +332,18 @@ class AigBitblaster : public TBitblaster { bool hasInput(TNode input); void convertToCnfAndAssert(); void assertToSatSolver(Cnf_Dat_t* pCnf); - Node getModelFromSatSolver(TNode a, bool fullModel) { Unreachable(); } -public: + Node getModelFromSatSolver(TNode a, bool fullModel) override + { + Unreachable(); + } + + public: AigBitblaster(); ~AigBitblaster(); - void makeVariable(TNode node, Bits& bits); - void bbTerm(TNode node, Bits& bits); - void bbAtom(TNode node); + void makeVariable(TNode node, Bits& bits) override; + void bbTerm(TNode node, Bits& bits) override; + void bbAtom(TNode node) override; Abc_Obj_t* bbFormula(TNode formula); bool solve(TNode query); static Abc_Aig_t* currentAigM(); diff --git a/src/theory/bv/bv_inequality_graph.h b/src/theory/bv/bv_inequality_graph.h index 30270b3c3..deba84631 100644 --- a/src/theory/bv/bv_inequality_graph.h +++ b/src/theory/bv/bv_inequality_graph.h @@ -201,11 +201,9 @@ class InequalityGraph : public context::ContextNotifyObj{ Node makeDiseqSplitLemma(TNode diseq); /** Backtracking mechanisms **/ std::vector > d_undoStack; - context::CDO d_undoStackIndex; - - void contextNotifyPop() { - backtrack(); - } + context::CDO d_undoStackIndex; + + void contextNotifyPop() override { backtrack(); } void backtrack(); diff --git a/src/theory/bv/bv_subtheory_algebraic.h b/src/theory/bv/bv_subtheory_algebraic.h index 0534c0f17..c963f15d7 100644 --- a/src/theory/bv/bv_subtheory_algebraic.h +++ b/src/theory/bv/bv_subtheory_algebraic.h @@ -224,16 +224,19 @@ public: AlgebraicSolver(context::Context* c, TheoryBV* bv); ~AlgebraicSolver(); - void preRegister(TNode node) {} - bool check(Theory::Effort e); - void explain(TNode literal, std::vector& assumptions) {Unreachable("AlgebraicSolver does not propagate.\n");} - EqualityStatus getEqualityStatus(TNode a, TNode b); - bool collectModelInfo(TheoryModel* m, bool fullModel); - Node getModelValue(TNode node); - bool isComplete(); - virtual void assertFact(TNode fact); + void preRegister(TNode node) override {} + bool check(Theory::Effort e) override; + void explain(TNode literal, std::vector& assumptions) override + { + Unreachable("AlgebraicSolver does not propagate.\n"); + } + EqualityStatus getEqualityStatus(TNode a, TNode b) override; + bool collectModelInfo(TheoryModel* m, bool fullModel) override; + Node getModelValue(TNode node) override; + bool isComplete() override; + void assertFact(TNode fact) override; }; -} -} -} +} // namespace bv +} // namespace theory +} // namespace CVC4 diff --git a/src/theory/bv/bv_subtheory_bitblast.h b/src/theory/bv/bv_subtheory_bitblast.h index 5927feddc..f88810fca 100644 --- a/src/theory/bv/bv_subtheory_bitblast.h +++ b/src/theory/bv/bv_subtheory_bitblast.h @@ -65,17 +65,17 @@ public: BitblastSolver(context::Context* c, TheoryBV* bv); ~BitblastSolver(); - void preRegister(TNode node); - bool check(Theory::Effort e); - void explain(TNode literal, std::vector& assumptions); - EqualityStatus getEqualityStatus(TNode a, TNode b); - bool collectModelInfo(TheoryModel* m, bool fullModel); - Node getModelValue(TNode node); - bool isComplete() { return true; } + void preRegister(TNode node) override; + bool check(Theory::Effort e) override; + void explain(TNode literal, std::vector& assumptions) override; + EqualityStatus getEqualityStatus(TNode a, TNode b) override; + bool collectModelInfo(TheoryModel* m, bool fullModel) override; + Node getModelValue(TNode node) override; + bool isComplete() override { return true; } void bitblastQueue(); void setAbstraction(AbstractionModule* module); uint64_t computeAtomWeight(TNode atom); - void setProofLog( BitVectorProof * bvp ); + void setProofLog(BitVectorProof* bvp) override; }; } /* namespace CVC4::theory::bv */ diff --git a/src/theory/bv/bv_subtheory_core.h b/src/theory/bv/bv_subtheory_core.h index 6cc6253ff..05c9535c3 100644 --- a/src/theory/bv/bv_subtheory_core.h +++ b/src/theory/bv/bv_subtheory_core.h @@ -53,14 +53,17 @@ class CoreSolver : public SubtheorySolver { public: NotifyClass(CoreSolver& solver): d_solver(solver) {} - bool eqNotifyTriggerEquality(TNode equality, bool value); - bool eqNotifyTriggerPredicate(TNode predicate, bool value); - bool eqNotifyTriggerTermEquality(TheoryId tag, TNode t1, TNode t2, bool value); - void eqNotifyConstantTermMerge(TNode t1, TNode t2); - void eqNotifyNewClass(TNode t); - void eqNotifyPreMerge(TNode t1, TNode t2) { } - void eqNotifyPostMerge(TNode t1, TNode t2) { } - void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) { } + bool eqNotifyTriggerEquality(TNode equality, bool value) override; + bool eqNotifyTriggerPredicate(TNode predicate, bool value) override; + bool eqNotifyTriggerTermEquality(TheoryId tag, + TNode t1, + TNode t2, + bool value) override; + void eqNotifyConstantTermMerge(TNode t1, TNode t2) override; + void eqNotifyNewClass(TNode t) override; + void eqNotifyPreMerge(TNode t1, TNode t2) override {} + void eqNotifyPostMerge(TNode t1, TNode t2) override {} + void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override {} }; @@ -100,17 +103,19 @@ class CoreSolver : public SubtheorySolver { public: CoreSolver(context::Context* c, TheoryBV* bv); ~CoreSolver(); - bool isComplete() { return d_isComplete; } + bool isComplete() override { return d_isComplete; } void setMasterEqualityEngine(eq::EqualityEngine* eq); - void preRegister(TNode node); - bool check(Theory::Effort e); - void explain(TNode literal, std::vector& assumptions); - bool collectModelInfo(TheoryModel* m, bool fullModel); - Node getModelValue(TNode var); - void addSharedTerm(TNode t) { + void preRegister(TNode node) override; + bool check(Theory::Effort e) override; + void explain(TNode literal, std::vector& assumptions) override; + bool collectModelInfo(TheoryModel* m, bool fullModel) override; + Node getModelValue(TNode var) override; + void addSharedTerm(TNode t) override + { d_equalityEngine.addTriggerTerm(t, THEORY_BV); } - EqualityStatus getEqualityStatus(TNode a, TNode b) { + EqualityStatus getEqualityStatus(TNode a, TNode b) override + { if (d_equalityEngine.areEqual(a, b)) { // The terms are implied to be equal return EQUALITY_TRUE; diff --git a/src/theory/bv/bv_subtheory_inequality.h b/src/theory/bv/bv_subtheory_inequality.h index be0492125..620cd075b 100644 --- a/src/theory/bv/bv_subtheory_inequality.h +++ b/src/theory/bv/bv_subtheory_inequality.h @@ -65,15 +65,15 @@ public: d_statistics() {} - bool check(Theory::Effort e); - void propagate(Theory::Effort e); - void explain(TNode literal, std::vector& assumptions); - bool isComplete() { return d_isComplete; } - bool collectModelInfo(TheoryModel* m, bool fullModel); - Node getModelValue(TNode var); - EqualityStatus getEqualityStatus(TNode a, TNode b); - void assertFact(TNode fact); - void preRegister(TNode node); + bool check(Theory::Effort e) override; + void propagate(Theory::Effort e) override; + void explain(TNode literal, std::vector& assumptions) override; + bool isComplete() override { return d_isComplete; } + bool collectModelInfo(TheoryModel* m, bool fullModel) override; + Node getModelValue(TNode var) override; + EqualityStatus getEqualityStatus(TNode a, TNode b) override; + void assertFact(TNode fact) override; + void preRegister(TNode node) override; }; } diff --git a/src/theory/bv/type_enumerator.h b/src/theory/bv/type_enumerator.h index 718121499..dd65fc08f 100644 --- a/src/theory/bv/type_enumerator.h +++ b/src/theory/bv/type_enumerator.h @@ -42,20 +42,21 @@ public: d_bits(0) { } - Node operator*() { + Node operator*() override + { if(d_bits != d_bits.modByPow2(d_size)) { throw NoMoreValuesException(getType()); } return utils::mkConst(d_size, d_bits); } - BitVectorEnumerator& operator++() + BitVectorEnumerator& operator++() override { d_bits += 1; return *this; } - bool isFinished() { return d_bits != d_bits.modByPow2(d_size); } + bool isFinished() override { return d_bits != d_bits.modByPow2(d_size); } };/* BitVectorEnumerator */ }/* CVC4::theory::bv namespace */ diff --git a/src/theory/datatypes/theory_datatypes.h b/src/theory/datatypes/theory_datatypes.h index 8052df59a..a27fd5543 100644 --- a/src/theory/datatypes/theory_datatypes.h +++ b/src/theory/datatypes/theory_datatypes.h @@ -64,7 +64,8 @@ class TheoryDatatypes : public Theory { TheoryDatatypes& d_dt; public: NotifyClass(TheoryDatatypes& dt): d_dt(dt) {} - bool eqNotifyTriggerEquality(TNode equality, bool value) { + bool eqNotifyTriggerEquality(TNode equality, bool value) override + { Debug("dt") << "NotifyClass::eqNotifyTriggerEquality(" << equality << ", " << (value ? "true" : "false" )<< ")" << std::endl; if (value) { return d_dt.propagate(equality); @@ -73,7 +74,8 @@ class TheoryDatatypes : public Theory { return d_dt.propagate(equality.notNode()); } } - bool eqNotifyTriggerPredicate(TNode predicate, bool value) { + bool eqNotifyTriggerPredicate(TNode predicate, bool value) override + { Debug("dt") << "NotifyClass::eqNotifyTriggerPredicate(" << predicate << ", " << (value ? "true" : "false") << ")" << std::endl; if (value) { return d_dt.propagate(predicate); @@ -81,7 +83,11 @@ class TheoryDatatypes : public Theory { return d_dt.propagate(predicate.notNode()); } } - bool eqNotifyTriggerTermEquality(TheoryId tag, TNode t1, TNode t2, bool value) { + bool eqNotifyTriggerTermEquality(TheoryId tag, + TNode t1, + TNode t2, + bool value) override + { Debug("dt") << "NotifyClass::eqNotifyTriggerTermMerge(" << tag << ", " << t1 << ", " << t2 << ")" << std::endl; if (value) { return d_dt.propagate(t1.eqNode(t2)); @@ -89,23 +95,28 @@ class TheoryDatatypes : public Theory { return d_dt.propagate(t1.eqNode(t2).notNode()); } } - void eqNotifyConstantTermMerge(TNode t1, TNode t2) { + void eqNotifyConstantTermMerge(TNode t1, TNode t2) override + { Debug("dt") << "NotifyClass::eqNotifyConstantTermMerge(" << t1 << ", " << t2 << ")" << std::endl; d_dt.conflict(t1, t2); } - void eqNotifyNewClass(TNode t) { + void eqNotifyNewClass(TNode t) override + { Debug("dt") << "NotifyClass::eqNotifyNewClass(" << t << ")" << std::endl; d_dt.eqNotifyNewClass(t); } - void eqNotifyPreMerge(TNode t1, TNode t2) { + void eqNotifyPreMerge(TNode t1, TNode t2) override + { Debug("dt") << "NotifyClass::eqNotifyPreMerge(" << t1 << ", " << t2 << ")" << std::endl; d_dt.eqNotifyPreMerge(t1, t2); } - void eqNotifyPostMerge(TNode t1, TNode t2) { + void eqNotifyPostMerge(TNode t1, TNode t2) override + { Debug("dt") << "NotifyClass::eqNotifyPostMerge(" << t1 << ", " << t2 << ")" << std::endl; d_dt.eqNotifyPostMerge(t1, t2); } - void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) { + void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override + { Debug("dt") << "NotifyClass::eqNotifyDisequal(" << t1 << ", " << t2 << ", " << reason << ")" << std::endl; d_dt.eqNotifyDisequal(t1, t2, reason); } diff --git a/src/theory/fp/theory_fp.h b/src/theory/fp/theory_fp.h index ca80546b8..688c6e600 100644 --- a/src/theory/fp/theory_fp.h +++ b/src/theory/fp/theory_fp.h @@ -62,15 +62,17 @@ class TheoryFp : public Theory { public: NotifyClass(TheoryFp& solver) : d_theorySolver(solver) {} - bool eqNotifyTriggerEquality(TNode equality, bool value); - bool eqNotifyTriggerPredicate(TNode predicate, bool value); - bool eqNotifyTriggerTermEquality(TheoryId tag, TNode t1, TNode t2, - bool value); - void eqNotifyConstantTermMerge(TNode t1, TNode t2); - void eqNotifyNewClass(TNode t) {} - void eqNotifyPreMerge(TNode t1, TNode t2) {} - void eqNotifyPostMerge(TNode t1, TNode t2) {} - void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) {} + bool eqNotifyTriggerEquality(TNode equality, bool value) override; + bool eqNotifyTriggerPredicate(TNode predicate, bool value) override; + bool eqNotifyTriggerTermEquality(TheoryId tag, + TNode t1, + TNode t2, + bool value) override; + void eqNotifyConstantTermMerge(TNode t1, TNode t2) override; + void eqNotifyNewClass(TNode t) override {} + void eqNotifyPreMerge(TNode t1, TNode t2) override {} + void eqNotifyPostMerge(TNode t1, TNode t2) override {} + void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override {} }; friend NotifyClass; diff --git a/src/theory/idl/theory_idl.h b/src/theory/idl/theory_idl.h index 625770869..7b05fc890 100644 --- a/src/theory/idl/theory_idl.h +++ b/src/theory/idl/theory_idl.h @@ -48,13 +48,13 @@ public: Valuation valuation, const LogicInfo& logicInfo); /** Pre-processing of input atoms */ - Node ppRewrite(TNode atom); + Node ppRewrite(TNode atom) override; /** Check the assertions for satisfiability */ - void check(Effort effort); + void check(Effort effort) override; /** Identity string */ - std::string identify() const { return "THEORY_IDL"; } + std::string identify() const override { return "THEORY_IDL"; } };/* class TheoryIdl */ diff --git a/src/theory/quantifiers/anti_skolem.h b/src/theory/quantifiers/anti_skolem.h index bf8b99f1c..6967c6c42 100644 --- a/src/theory/quantifiers/anti_skolem.h +++ b/src/theory/quantifiers/anti_skolem.h @@ -40,12 +40,12 @@ public: bool pconnected = true ); /* Call during quantifier engine's check */ - void check(Theory::Effort e, QEffort quant_e); + void check(Theory::Effort e, QEffort quant_e) override; /* Called for new quantifiers */ - void registerQuantifier( Node q ) {} - void assertNode( Node n ) {} + void registerQuantifier(Node q) override {} + void assertNode(Node n) override {} /** Identify this module (for debugging, dynamic configuration, etc..) */ - std::string identify() const { return "QuantAntiSkolem"; } + std::string identify() const override { return "QuantAntiSkolem"; } private: typedef context::CDHashSet NodeSet; diff --git a/src/theory/quantifiers/cegqi/ceg_instantiator.h b/src/theory/quantifiers/cegqi/ceg_instantiator.h index 03983fe1a..c12890b83 100644 --- a/src/theory/quantifiers/cegqi/ceg_instantiator.h +++ b/src/theory/quantifiers/cegqi/ceg_instantiator.h @@ -748,11 +748,11 @@ public: bool useModelValue(CegInstantiator* ci, SolvedForm& sf, Node pv, - CegInstEffort effort) + CegInstEffort effort) override { return true; } - std::string identify() const { return "ModelValue"; } + std::string identify() const override { return "ModelValue"; } }; /** instantiator preprocess diff --git a/src/theory/quantifiers/cegqi/ceg_t_instantiator.cpp b/src/theory/quantifiers/cegqi/ceg_t_instantiator.cpp index e6e64201e..bb210edcc 100644 --- a/src/theory/quantifiers/cegqi/ceg_t_instantiator.cpp +++ b/src/theory/quantifiers/cegqi/ceg_t_instantiator.cpp @@ -934,11 +934,13 @@ class CegInstantiatorBvInverterQuery : public BvInverterQuery } ~CegInstantiatorBvInverterQuery() {} /** return the model value of n */ - Node getModelValue( Node n ) { - return d_ci->getModelValue( n ); - } + Node getModelValue(Node n) override { return d_ci->getModelValue(n); } /** get bound variable of type tn */ - Node getBoundVariable(TypeNode tn) { return d_ci->getBoundVariable(tn); } + Node getBoundVariable(TypeNode tn) override + { + return d_ci->getBoundVariable(tn); + } + protected: // pointer to class that is able to query model values CegInstantiator * d_ci; diff --git a/src/theory/quantifiers/cegqi/ceg_t_instantiator.h b/src/theory/quantifiers/cegqi/ceg_t_instantiator.h index b9c7e2024..eee6747ec 100644 --- a/src/theory/quantifiers/cegqi/ceg_t_instantiator.h +++ b/src/theory/quantifiers/cegqi/ceg_t_instantiator.h @@ -33,57 +33,56 @@ class ArithInstantiator : public Instantiator { public: ArithInstantiator( QuantifiersEngine * qe, TypeNode tn ) : Instantiator( qe, tn ){} virtual ~ArithInstantiator(){} - virtual void reset(CegInstantiator* ci, - SolvedForm& sf, - Node pv, - CegInstEffort effort) override; - virtual bool hasProcessEquality(CegInstantiator* ci, - SolvedForm& sf, - Node pv, - CegInstEffort effort) override + void reset(CegInstantiator* ci, + SolvedForm& sf, + Node pv, + CegInstEffort effort) override; + bool hasProcessEquality(CegInstantiator* ci, + SolvedForm& sf, + Node pv, + CegInstEffort effort) override { return true; } - virtual bool processEquality(CegInstantiator* ci, - SolvedForm& sf, - Node pv, - std::vector& term_props, - std::vector& terms, - CegInstEffort effort) override; - virtual bool hasProcessAssertion(CegInstantiator* ci, - SolvedForm& sf, - Node pv, - CegInstEffort effort) override + bool processEquality(CegInstantiator* ci, + SolvedForm& sf, + Node pv, + std::vector& term_props, + std::vector& terms, + CegInstEffort effort) override; + bool hasProcessAssertion(CegInstantiator* ci, + SolvedForm& sf, + Node pv, + CegInstEffort effort) override { return true; } - virtual Node hasProcessAssertion(CegInstantiator* ci, - SolvedForm& sf, - Node pv, - Node lit, - CegInstEffort effort) override; - virtual bool processAssertion(CegInstantiator* ci, - SolvedForm& sf, - Node pv, - Node lit, - Node alit, - CegInstEffort effort) override; - virtual bool processAssertions(CegInstantiator* ci, - SolvedForm& sf, - Node pv, - CegInstEffort effort) override; - virtual bool needsPostProcessInstantiationForVariable( - CegInstantiator* ci, - SolvedForm& sf, - Node pv, - CegInstEffort effort) override; - virtual bool postProcessInstantiationForVariable( - CegInstantiator* ci, - SolvedForm& sf, - Node pv, - CegInstEffort effort, - std::vector& lemmas) override; - virtual std::string identify() const override { return "Arith"; } + Node hasProcessAssertion(CegInstantiator* ci, + SolvedForm& sf, + Node pv, + Node lit, + CegInstEffort effort) override; + bool processAssertion(CegInstantiator* ci, + SolvedForm& sf, + Node pv, + Node lit, + Node alit, + CegInstEffort effort) override; + bool processAssertions(CegInstantiator* ci, + SolvedForm& sf, + Node pv, + CegInstEffort effort) override; + bool needsPostProcessInstantiationForVariable(CegInstantiator* ci, + SolvedForm& sf, + Node pv, + CegInstEffort effort) override; + bool postProcessInstantiationForVariable(CegInstantiator* ci, + SolvedForm& sf, + Node pv, + CegInstEffort effort, + std::vector& lemmas) override; + std::string identify() const override { return "Arith"; } + private: Node d_vts_sym[2]; std::vector d_mbp_bounds[2]; @@ -113,29 +112,30 @@ class DtInstantiator : public Instantiator { public: DtInstantiator( QuantifiersEngine * qe, TypeNode tn ) : Instantiator( qe, tn ){} virtual ~DtInstantiator(){} - virtual void reset(CegInstantiator* ci, - SolvedForm& sf, - Node pv, - CegInstEffort effort) override; - virtual bool processEqualTerms(CegInstantiator* ci, - SolvedForm& sf, - Node pv, - std::vector& eqc, - CegInstEffort effort) override; - virtual bool hasProcessEquality(CegInstantiator* ci, - SolvedForm& sf, - Node pv, - CegInstEffort effort) override + void reset(CegInstantiator* ci, + SolvedForm& sf, + Node pv, + CegInstEffort effort) override; + bool processEqualTerms(CegInstantiator* ci, + SolvedForm& sf, + Node pv, + std::vector& eqc, + CegInstEffort effort) override; + bool hasProcessEquality(CegInstantiator* ci, + SolvedForm& sf, + Node pv, + CegInstEffort effort) override { return true; } - virtual bool processEquality(CegInstantiator* ci, - SolvedForm& sf, - Node pv, - std::vector& term_props, - std::vector& terms, - CegInstEffort effort) override; - virtual std::string identify() const override { return "Dt"; } + bool processEquality(CegInstantiator* ci, + SolvedForm& sf, + Node pv, + std::vector& term_props, + std::vector& terms, + CegInstEffort effort) override; + std::string identify() const override { return "Dt"; } + private: Node solve_dt(Node v, Node a, Node b, Node sa, Node sb); }; @@ -146,22 +146,23 @@ class EprInstantiator : public Instantiator { public: EprInstantiator( QuantifiersEngine * qe, TypeNode tn ) : Instantiator( qe, tn ){} virtual ~EprInstantiator(){} - virtual void reset(CegInstantiator* ci, - SolvedForm& sf, - Node pv, - CegInstEffort effort) override; - virtual bool processEqualTerm(CegInstantiator* ci, - SolvedForm& sf, - Node pv, - TermProperties& pv_prop, - Node n, - CegInstEffort effort) override; - virtual bool processEqualTerms(CegInstantiator* ci, - SolvedForm& sf, - Node pv, - std::vector& eqc, - CegInstEffort effort) override; - virtual std::string identify() const override { return "Epr"; } + void reset(CegInstantiator* ci, + SolvedForm& sf, + Node pv, + CegInstEffort effort) override; + bool processEqualTerm(CegInstantiator* ci, + SolvedForm& sf, + Node pv, + TermProperties& pv_prop, + Node n, + CegInstEffort effort) override; + bool processEqualTerms(CegInstantiator* ci, + SolvedForm& sf, + Node pv, + std::vector& eqc, + CegInstEffort effort) override; + std::string identify() const override { return "Epr"; } + private: std::vector d_equal_terms; void computeMatchScore(CegInstantiator* ci, diff --git a/src/theory/quantifiers/cegqi/inst_strategy_cbqi.h b/src/theory/quantifiers/cegqi/inst_strategy_cbqi.h index 3443d2c4d..2bc86ef4e 100644 --- a/src/theory/quantifiers/cegqi/inst_strategy_cbqi.h +++ b/src/theory/quantifiers/cegqi/inst_strategy_cbqi.h @@ -103,16 +103,16 @@ class InstStrategyCbqi : public QuantifiersModule { /** whether to do CBQI for quantifier q */ bool doCbqi( Node q ); /** process functions */ - bool needsCheck( Theory::Effort e ); - QEffort needsModel(Theory::Effort e); - void reset_round( Theory::Effort e ); - void check(Theory::Effort e, QEffort quant_e); - bool checkComplete(); - bool checkCompleteFor( Node q ); - void preRegisterQuantifier( Node q ); - void registerQuantifier( Node q ); + bool needsCheck(Theory::Effort e) override; + QEffort needsModel(Theory::Effort e) override; + void reset_round(Theory::Effort e) override; + void check(Theory::Effort e, QEffort quant_e) override; + bool checkComplete() override; + bool checkCompleteFor(Node q) override; + void preRegisterQuantifier(Node q) override; + void registerQuantifier(Node q) override; /** get next decision request */ - Node getNextDecisionRequest( unsigned& priority ); + Node getNextDecisionRequest(unsigned& priority) override; }; //generalized counterexample guided quantifier instantiation @@ -123,9 +123,9 @@ class CegqiOutputInstStrategy : public CegqiOutput { public: CegqiOutputInstStrategy( InstStrategyCegqi * out ) : d_out( out ){} InstStrategyCegqi * d_out; - bool doAddInstantiation( std::vector< Node >& subs ); - bool isEligibleForInstantiation( Node n ); - bool addLemma( Node lem ); + bool doAddInstantiation(std::vector& subs) override; + bool isEligibleForInstantiation(Node n) override; + bool addLemma(Node lem) override; }; class InstStrategyCegqi : public InstStrategyCbqi { diff --git a/src/theory/quantifiers/conjecture_generator.h b/src/theory/quantifiers/conjecture_generator.h index 85a7d3eb4..764379e76 100644 --- a/src/theory/quantifiers/conjecture_generator.h +++ b/src/theory/quantifiers/conjecture_generator.h @@ -237,14 +237,35 @@ private: ConjectureGenerator& d_sg; public: NotifyClass(ConjectureGenerator& sg): d_sg(sg) {} - bool eqNotifyTriggerEquality(TNode equality, bool value) { return true; } - bool eqNotifyTriggerPredicate(TNode predicate, bool value) { return true; } - bool eqNotifyTriggerTermEquality(TheoryId tag, TNode t1, TNode t2, bool value) { return true; } - void eqNotifyConstantTermMerge(TNode t1, TNode t2) { } - void eqNotifyNewClass(TNode t) { d_sg.eqNotifyNewClass(t); } - void eqNotifyPreMerge(TNode t1, TNode t2) { d_sg.eqNotifyPreMerge(t1, t2); } - void eqNotifyPostMerge(TNode t1, TNode t2) { d_sg.eqNotifyPostMerge(t1, t2); } - void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) {d_sg.eqNotifyDisequal(t1, t2, reason); } + bool eqNotifyTriggerEquality(TNode equality, bool value) override + { + return true; + } + bool eqNotifyTriggerPredicate(TNode predicate, bool value) override + { + return true; + } + bool eqNotifyTriggerTermEquality(TheoryId tag, + TNode t1, + TNode t2, + bool value) override + { + return true; + } + void eqNotifyConstantTermMerge(TNode t1, TNode t2) override {} + void eqNotifyNewClass(TNode t) override { d_sg.eqNotifyNewClass(t); } + void eqNotifyPreMerge(TNode t1, TNode t2) override + { + d_sg.eqNotifyPreMerge(t1, t2); + } + void eqNotifyPostMerge(TNode t1, TNode t2) override + { + d_sg.eqNotifyPostMerge(t1, t2); + } + void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override + { + d_sg.eqNotifyDisequal(t1, t2, reason); + } };/* class ConjectureGenerator::NotifyClass */ /** The notify class */ NotifyClass d_notify; @@ -401,18 +422,18 @@ public: ConjectureGenerator( QuantifiersEngine * qe, context::Context* c ); /* needs check */ - bool needsCheck( Theory::Effort e ); + bool needsCheck(Theory::Effort e) override; /* reset at a round */ - void reset_round( Theory::Effort e ); + void reset_round(Theory::Effort e) override; /* Call during quantifier engine's check */ - void check(Theory::Effort e, QEffort quant_e); + void check(Theory::Effort e, QEffort quant_e) override; /* Called for new quantifiers */ - void registerQuantifier( Node q ); - void assertNode( Node n ); + void registerQuantifier(Node q) override; + void assertNode(Node n) override; /** Identify this module (for debugging, dynamic configuration, etc..) */ - std::string identify() const { return "ConjectureGenerator"; } -//options -private: + std::string identify() const override { return "ConjectureGenerator"; } + // options + private: bool optReqDistinctVarPatterns(); bool optFilterUnknown(); int optFilterScoreThreshold(); diff --git a/src/theory/quantifiers/ematching/ho_trigger.h b/src/theory/quantifiers/ematching/ho_trigger.h index 41fec5e5f..85bb09086 100644 --- a/src/theory/quantifiers/ematching/ho_trigger.h +++ b/src/theory/quantifiers/ematching/ho_trigger.h @@ -122,7 +122,7 @@ class HigherOrderTrigger : public Trigger * Extends Trigger::addInstantiations to also send * lemmas based on addHoTypeMatchPredicateLemmas. */ - virtual int addInstantiations() override; + int addInstantiations() override; protected: /** diff --git a/src/theory/quantifiers/ematching/inst_strategy_e_matching.h b/src/theory/quantifiers/ematching/inst_strategy_e_matching.h index 8f11dfedf..eba49fa9a 100644 --- a/src/theory/quantifiers/ematching/inst_strategy_e_matching.h +++ b/src/theory/quantifiers/ematching/inst_strategy_e_matching.h @@ -40,9 +40,10 @@ private: /** counter for quantifiers */ std::map< Node, int > d_counter; /** process functions */ - void processResetInstantiationRound( Theory::Effort effort ); - int process( Node f, Theory::Effort effort, int e ); -public: + void processResetInstantiationRound(Theory::Effort effort) override; + int process(Node f, Theory::Effort effort, int e) override; + + public: InstStrategyUserPatterns( QuantifiersEngine* ie ) : InstStrategy( ie ){} ~InstStrategyUserPatterns(){} @@ -54,7 +55,7 @@ public: /** get user pattern */ inst::Trigger* getUserGenerator( Node q, int i ) { return d_user_gen[q][ i ]; } /** identify */ - std::string identify() const { return std::string("UserPatterns"); } + std::string identify() const override { return std::string("UserPatterns"); } };/* class InstStrategyUserPatterns */ class InstStrategyAutoGenTriggers : public InstStrategy { @@ -89,16 +90,16 @@ private: std::map< Node, Node > d_pat_to_mpat; private: /** process functions */ - void processResetInstantiationRound( Theory::Effort effort ); - int process( Node q, Theory::Effort effort, int e ); - /** generate triggers */ - void generateTriggers( Node q ); - void addPatternToPool( Node q, Node pat, unsigned num_fv, Node mpat ); - void addTrigger( inst::Trigger * tr, Node f ); - /** has user patterns */ - bool hasUserPatterns( Node q ); - /** has user patterns */ - std::map< Node, bool > d_hasUserPatterns; + void processResetInstantiationRound(Theory::Effort effort) override; + int process(Node q, Theory::Effort effort, int e) override; + /** generate triggers */ + void generateTriggers(Node q); + void addPatternToPool(Node q, Node pat, unsigned num_fv, Node mpat); + void addTrigger(inst::Trigger* tr, Node f); + /** has user patterns */ + bool hasUserPatterns(Node q); + /** has user patterns */ + std::map d_hasUserPatterns; public: InstStrategyAutoGenTriggers( QuantifiersEngine* qe ); ~InstStrategyAutoGenTriggers(){} @@ -106,7 +107,10 @@ public: /** get auto-generated trigger */ inst::Trigger* getAutoGenTrigger( Node q ); /** identify */ - std::string identify() const { return std::string("AutoGenTriggers"); } + std::string identify() const override + { + return std::string("AutoGenTriggers"); + } /** add pattern */ void addUserNoPattern( Node q, Node pat ); };/* class InstStrategyAutoGenTriggers */ diff --git a/src/theory/quantifiers/ematching/instantiation_engine.h b/src/theory/quantifiers/ematching/instantiation_engine.h index 18b5ea19c..32ddb19ed 100644 --- a/src/theory/quantifiers/ematching/instantiation_engine.h +++ b/src/theory/quantifiers/ematching/instantiation_engine.h @@ -76,19 +76,19 @@ class InstantiationEngine : public QuantifiersModule { public: InstantiationEngine(QuantifiersEngine* qe); ~InstantiationEngine(); - void presolve(); - bool needsCheck(Theory::Effort e); - void reset_round(Theory::Effort e); - void check(Theory::Effort e, QEffort quant_e); - bool checkCompleteFor(Node q); - void preRegisterQuantifier(Node q); - void registerQuantifier(Node q); + void presolve() override; + bool needsCheck(Theory::Effort e) override; + void reset_round(Theory::Effort e) override; + void check(Theory::Effort e, QEffort quant_e) override; + bool checkCompleteFor(Node q) override; + void preRegisterQuantifier(Node q) override; + void registerQuantifier(Node q) override; Node explain(TNode n) { return Node::null(); } /** add user pattern */ void addUserPattern(Node q, Node pat); void addUserNoPattern(Node q, Node pat); /** Identify this module */ - std::string identify() const { return "InstEngine"; } + std::string identify() const override { return "InstEngine"; } }; /* class InstantiationEngine */ }/* CVC4::theory::quantifiers namespace */ diff --git a/src/theory/quantifiers/equality_query.h b/src/theory/quantifiers/equality_query.h index 0048cc14f..0b28f53c6 100644 --- a/src/theory/quantifiers/equality_query.h +++ b/src/theory/quantifiers/equality_query.h @@ -50,26 +50,26 @@ class EqualityQueryQuantifiersEngine : public EqualityQuery EqualityQueryQuantifiersEngine(context::Context* c, QuantifiersEngine* qe); virtual ~EqualityQueryQuantifiersEngine(); /** reset */ - virtual bool reset(Theory::Effort e); + bool reset(Theory::Effort e) override; /* Called for new quantifiers */ - virtual void registerQuantifier(Node q) {} + void registerQuantifier(Node q) override {} /** identify */ - virtual std::string identify() const { return "EqualityQueryQE"; } + std::string identify() const override { return "EqualityQueryQE"; } /** does the equality engine have term a */ - bool hasTerm(Node a); + bool hasTerm(Node a) override; /** get the representative of a */ - Node getRepresentative(Node a); + Node getRepresentative(Node a) override; /** are a and b equal? */ - bool areEqual(Node a, Node b); + bool areEqual(Node a, Node b) override; /** are a and b disequal? */ - bool areDisequal(Node a, Node b); + bool areDisequal(Node a, Node b) override; /** get equality engine * This may either be the master equality engine or the model's equality * engine. */ - eq::EqualityEngine* getEngine(); + eq::EqualityEngine* getEngine() override; /** get list of members in the equivalence class of a */ - void getEquivalenceClass(Node a, std::vector& eqc); + void getEquivalenceClass(Node a, std::vector& eqc) override; /** get congruent term * If possible, returns a term n such that: * (1) n is a term in the equality engine from getEngine(). @@ -80,7 +80,7 @@ class EqualityQueryQuantifiersEngine : public EqualityQuery * Notice that f should be a "match operator", returned by * TermDb::getMatchOperator. */ - TNode getCongruentTerm(Node f, std::vector& args); + TNode getCongruentTerm(Node f, std::vector& args) override; /** gets the current best representative in the equivalence * class of a, based on some heuristic. Currently, the default heuristic * chooses terms that were previously chosen as representatives diff --git a/src/theory/quantifiers/first_order_model.h b/src/theory/quantifiers/first_order_model.h index f33151b4d..db2f97b16 100644 --- a/src/theory/quantifiers/first_order_model.h +++ b/src/theory/quantifiers/first_order_model.h @@ -67,19 +67,19 @@ class QRepBoundExt : public RepBoundExt QRepBoundExt(QuantifiersEngine* qe) : d_qe(qe) {} virtual ~QRepBoundExt() {} /** set bound */ - virtual RepSetIterator::RsiEnumType setBound( - Node owner, unsigned i, std::vector& elements) override; + RepSetIterator::RsiEnumType setBound(Node owner, + unsigned i, + std::vector& elements) override; /** reset index */ - virtual bool resetIndex(RepSetIterator* rsi, - Node owner, - unsigned i, - bool initial, - std::vector& elements) override; + bool resetIndex(RepSetIterator* rsi, + Node owner, + unsigned i, + bool initial, + std::vector& elements) override; /** initialize representative set for type */ - virtual bool initializeRepresentativesForType(TypeNode tn) override; + bool initializeRepresentativesForType(TypeNode tn) override; /** get variable order */ - virtual bool getVariableOrder(Node owner, - std::vector& varOrder) override; + bool getVariableOrder(Node owner, std::vector& varOrder) override; private: /** quantifiers engine associated with this bound */ @@ -215,11 +215,11 @@ private: public: FirstOrderModelIG(QuantifiersEngine * qe, context::Context* c, std::string name); - FirstOrderModelIG * asFirstOrderModelIG() { return this; } + FirstOrderModelIG* asFirstOrderModelIG() override { return this; } // initialize the model - void processInitialize( bool ispre ); + void processInitialize(bool ispre) override; //for initialize model - void processInitializeModelForTerm( Node n ); + void processInitializeModelForTerm(Node n) override; /** reset evaluation */ void resetEvaluate(); /** evaluate functions */ diff --git a/src/theory/quantifiers/fmf/bounded_integers.h b/src/theory/quantifiers/fmf/bounded_integers.h index 99d77a8e7..3e990067a 100644 --- a/src/theory/quantifiers/fmf/bounded_integers.h +++ b/src/theory/quantifiers/fmf/bounded_integers.h @@ -102,10 +102,10 @@ private: context::CDO< bool > d_has_range; context::CDO< int > d_curr_range; IntBoolMap d_ranges_proxied; - void initialize(); - void assertNode(Node n); - Node getNextDecisionRequest(); - bool proxyCurrentRange(); + void initialize() override; + void assertNode(Node n) override; + Node getNextDecisionRequest() override; + bool proxyCurrentRange() override; }; private: //information for minimizing ranges @@ -142,14 +142,14 @@ private: public: BoundedIntegers( context::Context* c, QuantifiersEngine* qe ); virtual ~BoundedIntegers(); - - void presolve(); - bool needsCheck( Theory::Effort e ); - void check(Theory::Effort e, QEffort quant_e); - void registerQuantifier( Node q ); - void preRegisterQuantifier( Node q ); - void assertNode( Node n ); - Node getNextDecisionRequest( unsigned& priority ); + + void presolve() override; + bool needsCheck(Theory::Effort e) override; + void check(Theory::Effort e, QEffort quant_e) override; + void registerQuantifier(Node q) override; + void preRegisterQuantifier(Node q) override; + void assertNode(Node n) override; + Node getNextDecisionRequest(unsigned& priority) override; bool isBoundVar( Node q, Node v ) { return std::find( d_set[q].begin(), d_set[q].end(), v )!=d_set[q].end(); } unsigned getBoundVarType( Node q, Node v ); unsigned getNumBoundVars( Node q ) { return d_set[q].size(); } @@ -171,7 +171,7 @@ public: bool getBoundElements( RepSetIterator * rsi, bool initial, Node q, Node v, std::vector< Node >& elements ); /** Identify this module */ - std::string identify() const { return "BoundedIntegers"; } + std::string identify() const override { return "BoundedIntegers"; } }; } diff --git a/src/theory/quantifiers/fmf/full_model_check.h b/src/theory/quantifiers/fmf/full_model_check.h index 732f8be07..a64c33303 100644 --- a/src/theory/quantifiers/fmf/full_model_check.h +++ b/src/theory/quantifiers/fmf/full_model_check.h @@ -138,13 +138,15 @@ public: void debugPrintCond(const char * tr, Node n, bool dispStar = false); void debugPrint(const char * tr, Node n, bool dispStar = false); - int doExhaustiveInstantiation( FirstOrderModel * fm, Node f, int effort ); + int doExhaustiveInstantiation(FirstOrderModel* fm, + Node f, + int effort) override; Node getFunctionValue(FirstOrderModelFmc * fm, Node op, const char* argPrefix ); - /** process build model */ - bool preProcessBuildModel(TheoryModel* m); - bool processBuildModel(TheoryModel* m); + /** process build model */ + bool preProcessBuildModel(TheoryModel* m) override; + bool processBuildModel(TheoryModel* m) override; bool useSimpleModels(); };/* class FullModelChecker */ diff --git a/src/theory/quantifiers/fmf/model_builder.h b/src/theory/quantifiers/fmf/model_builder.h index 4eb592b3e..5af1e3451 100644 --- a/src/theory/quantifiers/fmf/model_builder.h +++ b/src/theory/quantifiers/fmf/model_builder.h @@ -31,7 +31,8 @@ class QModelBuilder : public TheoryEngineModelBuilder protected: //quantifiers engine QuantifiersEngine* d_qe; - bool preProcessBuildModel(TheoryModel* m); //must call preProcessBuildModelStd + // must call preProcessBuildModelStd + bool preProcessBuildModel(TheoryModel* m) override; bool preProcessBuildModelStd(TheoryModel* m); /** number of lemmas generated while building model */ unsigned d_addedLemmas; @@ -49,7 +50,7 @@ public: /** exist instantiation ? */ virtual bool existsInstantiation( Node f, InstMatch& m, bool modEq = true, bool modInst = false ) { return false; } //debug model - virtual void debugModel( TheoryModel* m ); + void debugModel(TheoryModel* m) override; //statistics unsigned getNumAddedLemmas() { return d_addedLemmas; } unsigned getNumTriedLemmas() { return d_triedLemmas; } @@ -87,7 +88,7 @@ class QModelBuilderIG : public QModelBuilder //whether inst gen was done bool d_didInstGen; /** process build model */ - virtual bool processBuildModel( TheoryModel* m ); + bool processBuildModel(TheoryModel* m) override; protected: //reset @@ -143,7 +144,9 @@ class QModelBuilderIG : public QModelBuilder // is quantifier active? bool isQuantifierActive( Node f ); //do exhaustive instantiation - int doExhaustiveInstantiation( FirstOrderModel * fm, Node f, int effort ); + int doExhaustiveInstantiation(FirstOrderModel* fm, + Node f, + int effort) override; //temporary stats int d_numQuantSat; diff --git a/src/theory/quantifiers/fmf/model_engine.h b/src/theory/quantifiers/fmf/model_engine.h index 090374744..6412ea81b 100644 --- a/src/theory/quantifiers/fmf/model_engine.h +++ b/src/theory/quantifiers/fmf/model_engine.h @@ -49,18 +49,18 @@ public: ModelEngine( context::Context* c, QuantifiersEngine* qe ); virtual ~ModelEngine(); public: - bool needsCheck( Theory::Effort e ); - QEffort needsModel(Theory::Effort e); - void reset_round( Theory::Effort e ); - void check(Theory::Effort e, QEffort quant_e); - bool checkComplete(); - bool checkCompleteFor( Node q ); - void registerQuantifier( Node f ); - void assertNode( Node f ); - Node explain(TNode n){ return Node::null(); } - void debugPrint( const char* c ); - /** Identify this module */ - std::string identify() const { return "ModelEngine"; } + bool needsCheck(Theory::Effort e) override; + QEffort needsModel(Theory::Effort e) override; + void reset_round(Theory::Effort e) override; + void check(Theory::Effort e, QEffort quant_e) override; + bool checkComplete() override; + bool checkCompleteFor(Node q) override; + void registerQuantifier(Node f) override; + void assertNode(Node f) override; + Node explain(TNode n) { return Node::null(); } + void debugPrint(const char* c); + /** Identify this module */ + std::string identify() const override { return "ModelEngine"; } };/* class ModelEngine */ }/* CVC4::theory::quantifiers namespace */ diff --git a/src/theory/quantifiers/fun_def_engine.h b/src/theory/quantifiers/fun_def_engine.h index 48de4f36c..157eb57fd 100644 --- a/src/theory/quantifiers/fun_def_engine.h +++ b/src/theory/quantifiers/fun_def_engine.h @@ -38,17 +38,17 @@ public: ~FunDefEngine(){} /* whether this module needs to check this round */ - bool needsCheck( Theory::Effort e ); + bool needsCheck(Theory::Effort e) override; /* reset at a round */ - void reset_round( Theory::Effort e ); + void reset_round(Theory::Effort e) override; /* Call during quantifier engine's check */ - void check(Theory::Effort e, QEffort quant_e); + void check(Theory::Effort e, QEffort quant_e) override; /* Called for new quantifiers */ - void registerQuantifier( Node q ); + void registerQuantifier(Node q) override; /** called for everything that gets asserted */ - void assertNode( Node n ); + void assertNode(Node n) override; /** Identify this module (for debugging, dynamic configuration, etc..) */ - std::string identify() const { return "FunDefEngine"; } + std::string identify() const override { return "FunDefEngine"; } }; diff --git a/src/theory/quantifiers/inst_propagator.h b/src/theory/quantifiers/inst_propagator.h index 7f485750a..e0c72c9fa 100644 --- a/src/theory/quantifiers/inst_propagator.h +++ b/src/theory/quantifiers/inst_propagator.h @@ -39,28 +39,29 @@ public: EqualityQueryInstProp( QuantifiersEngine* qe ); ~EqualityQueryInstProp(){}; /** reset */ - virtual bool reset(Theory::Effort e); + bool reset(Theory::Effort e) override; /* Called for new quantifiers */ - virtual void registerQuantifier(Node q) {} + void registerQuantifier(Node q) override {} /** identify */ - virtual std::string identify() const { return "EqualityQueryInstProp"; } + std::string identify() const override { return "EqualityQueryInstProp"; } /** extends engine */ - bool extendsEngine() { return true; } + bool extendsEngine() override { return true; } /** contains term */ - bool hasTerm( Node a ); + bool hasTerm(Node a) override; /** get the representative of the equivalence class of a */ - Node getRepresentative( Node a ); + Node getRepresentative(Node a) override; /** returns true if a and b are equal in the current context */ - bool areEqual( Node a, Node b ); + bool areEqual(Node a, Node b) override; /** returns true is a and b are disequal in the current context */ - bool areDisequal( Node a, Node b ); + bool areDisequal(Node a, Node b) override; /** get the equality engine associated with this query */ - eq::EqualityEngine* getEngine(); + eq::EqualityEngine* getEngine() override; /** get the equivalence class of a */ - void getEquivalenceClass( Node a, std::vector< Node >& eqc ); + void getEquivalenceClass(Node a, std::vector& eqc) override; /** get congruent term */ - TNode getCongruentTerm( Node f, std::vector< TNode >& args ); -public: + TNode getCongruentTerm(Node f, std::vector& args) override; + + public: /** get the representative of the equivalence class of a, with explanation */ Node getRepresentativeExp( Node a, std::vector< Node >& exp ); /** returns true if a and b are equal in the current context */ @@ -114,15 +115,15 @@ private: InstPropagator& d_ip; public: InstantiationNotifyInstPropagator(InstPropagator& ip): d_ip(ip) {} - virtual bool notifyInstantiation(QuantifiersModule::QEffort quant_e, - Node q, - Node lem, - std::vector& terms, - Node body) + bool notifyInstantiation(QuantifiersModule::QEffort quant_e, + Node q, + Node lem, + std::vector& terms, + Node body) override { return d_ip.notifyInstantiation( quant_e, q, lem, terms, body ); } - virtual void filterInstantiations() { d_ip.filterInstantiations(); } + void filterInstantiations() override { d_ip.filterInstantiations(); } }; InstantiationNotifyInstPropagator d_notify; /** notify instantiation method */ @@ -173,11 +174,11 @@ public: InstPropagator( QuantifiersEngine* qe ); ~InstPropagator(){} /** reset */ - virtual bool reset(Theory::Effort e) override; + bool reset(Theory::Effort e) override; /* Called for new quantifiers */ - virtual void registerQuantifier(Node q) override {} + void registerQuantifier(Node q) override {} /** identify */ - virtual std::string identify() const override { return "InstPropagator"; } + std::string identify() const override { return "InstPropagator"; } /** get the notify mechanism */ InstantiationNotify* getInstantiationNotify() { return &d_notify; } }; diff --git a/src/theory/quantifiers/instantiate.h b/src/theory/quantifiers/instantiate.h index d1973eadb..18a06dc3d 100644 --- a/src/theory/quantifiers/instantiate.h +++ b/src/theory/quantifiers/instantiate.h @@ -93,13 +93,13 @@ class Instantiate : public QuantifiersUtil ~Instantiate(); /** reset */ - virtual bool reset(Theory::Effort e) override; + bool reset(Theory::Effort e) override; /** register quantifier */ - virtual void registerQuantifier(Node q) override; + void registerQuantifier(Node q) override; /** identify */ - virtual std::string identify() const override { return "Instantiate"; } + std::string identify() const override { return "Instantiate"; } /** check incomplete */ - virtual bool checkComplete() override; + bool checkComplete() override; //--------------------------------------notify objects /** add instantiation notify diff --git a/src/theory/quantifiers/local_theory_ext.h b/src/theory/quantifiers/local_theory_ext.h index 3b19b8d55..76a781e1c 100644 --- a/src/theory/quantifiers/local_theory_ext.h +++ b/src/theory/quantifiers/local_theory_ext.h @@ -56,22 +56,21 @@ private: public: LtePartialInst( QuantifiersEngine * qe, context::Context* c ); /** determine whether this quantified formula will be reduced */ - void preRegisterQuantifier( Node q ); + void preRegisterQuantifier(Node q) override; /** was invoked */ bool wasInvoked() { return d_wasInvoked; } /* whether this module needs to check this round */ - bool needsCheck( Theory::Effort e ); + bool needsCheck(Theory::Effort e) override; /* Call during quantifier engine's check */ - void check(Theory::Effort e, QEffort quant_e); + void check(Theory::Effort e, QEffort quant_e) override; /* Called for new quantifiers */ - void registerQuantifier( Node q ) {} + void registerQuantifier(Node q) override {} /* check complete */ - bool checkComplete() { return !d_wasInvoked; } - void assertNode( Node n ) {} + bool checkComplete() override { return !d_wasInvoked; } + void assertNode(Node n) override {} /** Identify this module (for debugging, dynamic configuration, etc..) */ - std::string identify() const { return "LtePartialInst"; } - + std::string identify() const override { return "LtePartialInst"; } }; } diff --git a/src/theory/quantifiers/quant_conflict_find.h b/src/theory/quantifiers/quant_conflict_find.h index 3448e967b..77ea530ae 100644 --- a/src/theory/quantifiers/quant_conflict_find.h +++ b/src/theory/quantifiers/quant_conflict_find.h @@ -238,10 +238,11 @@ public: QuantConflictFind( QuantifiersEngine * qe, context::Context* c ); /** register quantifier */ - void registerQuantifier( Node q ); -public: + void registerQuantifier(Node q) override; + + public: /** assert quantifier */ - void assertNode( Node q ); + void assertNode(Node q) override; /** new node */ void newEqClass( Node n ); /** merge */ @@ -249,11 +250,11 @@ public: /** assert disequal */ void assertDisequal( Node a, Node b ); /** needs check */ - bool needsCheck( Theory::Effort level ); + bool needsCheck(Theory::Effort level) override; /** reset round */ - void reset_round( Theory::Effort level ); + void reset_round(Theory::Effort level) override; /** check */ - void check(Theory::Effort level, QEffort quant_e); + void check(Theory::Effort level, QEffort quant_e) override; private: bool d_needs_computeRelEqr; @@ -277,7 +278,7 @@ public: }; Statistics d_statistics; /** Identify this module */ - std::string identify() const { return "QcfEngine"; } + std::string identify() const override { return "QcfEngine"; } }; std::ostream& operator<<(std::ostream& os, const QuantConflictFind::Effort& e); diff --git a/src/theory/quantifiers/quant_equality_engine.h b/src/theory/quantifiers/quant_equality_engine.h index 47adddd9e..aa201bbc3 100644 --- a/src/theory/quantifiers/quant_equality_engine.h +++ b/src/theory/quantifiers/quant_equality_engine.h @@ -37,14 +37,38 @@ private: QuantEqualityEngine& d_qee; public: NotifyClass(QuantEqualityEngine& qee): d_qee(qee) {} - bool eqNotifyTriggerEquality(TNode equality, bool value) { return true; } - bool eqNotifyTriggerPredicate(TNode predicate, bool value) { return true; } - bool eqNotifyTriggerTermEquality(TheoryId tag, TNode t1, TNode t2, bool value) { return true; } - void eqNotifyConstantTermMerge(TNode t1, TNode t2) { d_qee.conflict(t1, t2); } - void eqNotifyNewClass(TNode t) { d_qee.eqNotifyNewClass(t); } - void eqNotifyPreMerge(TNode t1, TNode t2) { d_qee.eqNotifyPreMerge(t1, t2); } - void eqNotifyPostMerge(TNode t1, TNode t2) { d_qee.eqNotifyPostMerge(t1, t2); } - void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) {d_qee.eqNotifyDisequal(t1, t2, reason); } + bool eqNotifyTriggerEquality(TNode equality, bool value) override + { + return true; + } + bool eqNotifyTriggerPredicate(TNode predicate, bool value) override + { + return true; + } + bool eqNotifyTriggerTermEquality(TheoryId tag, + TNode t1, + TNode t2, + bool value) override + { + return true; + } + void eqNotifyConstantTermMerge(TNode t1, TNode t2) override + { + d_qee.conflict(t1, t2); + } + void eqNotifyNewClass(TNode t) override { d_qee.eqNotifyNewClass(t); } + void eqNotifyPreMerge(TNode t1, TNode t2) override + { + d_qee.eqNotifyPreMerge(t1, t2); + } + void eqNotifyPostMerge(TNode t1, TNode t2) override + { + d_qee.eqNotifyPostMerge(t1, t2); + } + void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override + { + d_qee.eqNotifyDisequal(t1, t2, reason); + } };/* class ConjectureGenerator::NotifyClass */ /** The notify class */ NotifyClass d_notify; @@ -75,17 +99,17 @@ public: QuantEqualityEngine( QuantifiersEngine * qe, context::Context* c ); /* whether this module needs to check this round */ - bool needsCheck( Theory::Effort e ); + bool needsCheck(Theory::Effort e) override; /* reset at a round */ - void reset_round( Theory::Effort e ); + void reset_round(Theory::Effort e) override; /* Call during quantifier engine's check */ - void check(Theory::Effort e, QEffort quant_e); + void check(Theory::Effort e, QEffort quant_e) override; /* Called for new quantifiers */ - void registerQuantifier( Node q ); + void registerQuantifier(Node q) override; /** called for everything that gets asserted */ - void assertNode( Node n ); + void assertNode(Node n) override; /** Identify this module (for debugging, dynamic configuration, etc..) */ - std::string identify() const { return "QuantEqualityEngine"; } + std::string identify() const override { return "QuantEqualityEngine"; } /** queries */ bool areUnivDisequal( TNode n1, TNode n2 ); bool areUnivEqual( TNode n1, TNode n2 ); diff --git a/src/theory/quantifiers/quant_relevance.h b/src/theory/quantifiers/quant_relevance.h index 3182df34b..0650b1c42 100644 --- a/src/theory/quantifiers/quant_relevance.h +++ b/src/theory/quantifiers/quant_relevance.h @@ -42,11 +42,11 @@ class QuantRelevance : public QuantifiersUtil QuantRelevance(bool cr) : d_computeRel(cr) {} ~QuantRelevance() {} /** reset */ - virtual bool reset(Theory::Effort e) override { return true; } + bool reset(Theory::Effort e) override { return true; } /** register quantifier */ - virtual void registerQuantifier(Node q) override; + void registerQuantifier(Node q) override; /** identify */ - virtual std::string identify() const override { return "QuantRelevance"; } + std::string identify() const override { return "QuantRelevance"; } /** set relevance of symbol s to r */ void setRelevance(Node s, int r); /** get relevance of symbol s */ diff --git a/src/theory/quantifiers/quant_split.h b/src/theory/quantifiers/quant_split.h index 644583f04..1ea57433a 100644 --- a/src/theory/quantifiers/quant_split.h +++ b/src/theory/quantifiers/quant_split.h @@ -34,18 +34,18 @@ private: public: QuantDSplit( QuantifiersEngine * qe, context::Context* c ); /** determine whether this quantified formula will be reduced */ - void preRegisterQuantifier( Node q ); - + void preRegisterQuantifier(Node q) override; + /* whether this module needs to check this round */ - bool needsCheck( Theory::Effort e ); + bool needsCheck(Theory::Effort e) override; /* Call during quantifier engine's check */ - void check(Theory::Effort e, QEffort quant_e); + void check(Theory::Effort e, QEffort quant_e) override; /* Called for new quantifiers */ - void registerQuantifier( Node q ) {} - void assertNode( Node n ) {} - bool checkCompleteFor( Node q ); + void registerQuantifier(Node q) override {} + void assertNode(Node n) override {} + bool checkCompleteFor(Node q) override; /** Identify this module (for debugging, dynamic configuration, etc..) */ - std::string identify() const { return "QuantDSplit"; } + std::string identify() const override { return "QuantDSplit"; } }; } diff --git a/src/theory/quantifiers/relevant_domain.h b/src/theory/quantifiers/relevant_domain.h index 112530788..a138e4e21 100644 --- a/src/theory/quantifiers/relevant_domain.h +++ b/src/theory/quantifiers/relevant_domain.h @@ -43,11 +43,11 @@ class RelevantDomain : public QuantifiersUtil RelevantDomain(QuantifiersEngine* qe); virtual ~RelevantDomain(); /** Reset. */ - virtual bool reset(Theory::Effort e) override; + bool reset(Theory::Effort e) override; /** Register the quantified formula q */ - virtual void registerQuantifier(Node q) override; + void registerQuantifier(Node q) override; /** identify */ - virtual std::string identify() const override { return "RelevantDomain"; } + std::string identify() const override { return "RelevantDomain"; } /** Compute the relevant domain */ void compute(); /** Relevant domain representation. diff --git a/src/theory/quantifiers/rewrite_engine.h b/src/theory/quantifiers/rewrite_engine.h index 2253ac1da..03cf0c996 100644 --- a/src/theory/quantifiers/rewrite_engine.h +++ b/src/theory/quantifiers/rewrite_engine.h @@ -50,13 +50,13 @@ private: public: RewriteEngine( context::Context* c, QuantifiersEngine* qe ); - bool needsCheck( Theory::Effort e ); - void check(Theory::Effort e, QEffort quant_e); - void registerQuantifier( Node f ); - void assertNode( Node n ); - bool checkCompleteFor( Node q ); + bool needsCheck(Theory::Effort e) override; + void check(Theory::Effort e, QEffort quant_e) override; + void registerQuantifier(Node f) override; + void assertNode(Node n) override; + bool checkCompleteFor(Node q) override; /** Identify this module */ - std::string identify() const { return "RewriteEngine"; } + std::string identify() const override { return "RewriteEngine"; } }; } diff --git a/src/theory/quantifiers/sygus/ce_guided_instantiation.h b/src/theory/quantifiers/sygus/ce_guided_instantiation.h index 1b1d5e44b..e461a08d5 100644 --- a/src/theory/quantifiers/sygus/ce_guided_instantiation.h +++ b/src/theory/quantifiers/sygus/ce_guided_instantiation.h @@ -40,31 +40,31 @@ public: CegInstantiation( QuantifiersEngine * qe, context::Context* c ); ~CegInstantiation(); public: - bool needsCheck( Theory::Effort e ); - QEffort needsModel(Theory::Effort e); - /* Call during quantifier engine's check */ - void check(Theory::Effort e, QEffort quant_e); - /* Called for new quantifiers */ - void registerQuantifier( Node q ); - /** get the next decision request */ - Node getNextDecisionRequest( unsigned& priority ); - /** Identify this module (for debugging, dynamic configuration, etc..) */ - std::string identify() const { return "CegInstantiation"; } - /** print solution for synthesis conjectures */ - void printSynthSolution( std::ostream& out ); - /** get synth solutions - * - * This function adds entries to sol_map that map functions-to-synthesize - * with their solutions, for all active conjectures (currently just the one - * assigned to d_conj). This should be called immediately after the solver - * answers unsat for sygus input. - * - * For details on what is added to sol_map, see - * CegConjecture::getSynthSolutions. - */ - void getSynthSolutions(std::map& sol_map); - /** preregister assertion (before rewrite) */ - void preregisterAssertion( Node n ); + bool needsCheck(Theory::Effort e) override; + QEffort needsModel(Theory::Effort e) override; + /* Call during quantifier engine's check */ + void check(Theory::Effort e, QEffort quant_e) override; + /* Called for new quantifiers */ + void registerQuantifier(Node q) override; + /** get the next decision request */ + Node getNextDecisionRequest(unsigned& priority) override; + /** Identify this module (for debugging, dynamic configuration, etc..) */ + std::string identify() const override { return "CegInstantiation"; } + /** print solution for synthesis conjectures */ + void printSynthSolution(std::ostream& out); + /** get synth solutions + * + * This function adds entries to sol_map that map functions-to-synthesize + * with their solutions, for all active conjectures (currently just the one + * assigned to d_conj). This should be called immediately after the solver + * answers unsat for sygus input. + * + * For details on what is added to sol_map, see + * CegConjecture::getSynthSolutions. + */ + void getSynthSolutions(std::map& sol_map); + /** preregister assertion (before rewrite) */ + void preregisterAssertion(Node n); public: class Statistics { public: diff --git a/src/theory/quantifiers/sygus/ce_guided_single_inv.h b/src/theory/quantifiers/sygus/ce_guided_single_inv.h index abdbef708..70ba2c283 100644 --- a/src/theory/quantifiers/sygus/ce_guided_single_inv.h +++ b/src/theory/quantifiers/sygus/ce_guided_single_inv.h @@ -37,9 +37,9 @@ public: CegqiOutputSingleInv( CegConjectureSingleInv * out ) : d_out( out ){} virtual ~CegqiOutputSingleInv() {} CegConjectureSingleInv * d_out; - bool doAddInstantiation( std::vector< Node >& subs ); - bool isEligibleForInstantiation( Node n ); - bool addLemma( Node lem ); + bool doAddInstantiation(std::vector& subs) override; + bool isEligibleForInstantiation(Node n) override; + bool addLemma(Node lem) override; }; class DetTrace { diff --git a/src/theory/quantifiers/sygus/sygus_invariance.h b/src/theory/quantifiers/sygus/sygus_invariance.h index a43e38719..9e357f928 100644 --- a/src/theory/quantifiers/sygus/sygus_invariance.h +++ b/src/theory/quantifiers/sygus/sygus_invariance.h @@ -112,7 +112,7 @@ class EvalSygusInvarianceTest : public SygusInvarianceTest protected: /** does d_conj{ d_var -> nvn } still rewrite to d_result? */ - bool invariant(TermDbSygus* tds, Node nvn, Node x); + bool invariant(TermDbSygus* tds, Node nvn, Node x) override; private: /** the formula we are evaluating */ @@ -170,7 +170,7 @@ class EquivSygusInvarianceTest : public SygusInvarianceTest protected: /** checks whether the analog of nvn still rewrites to d_bvr */ - bool invariant(TermDbSygus* tds, Node nvn, Node x); + bool invariant(TermDbSygus* tds, Node nvn, Node x) override; private: /** the conjecture associated with the enumerator d_enum */ @@ -202,7 +202,7 @@ class DivByZeroSygusInvarianceTest : public SygusInvarianceTest protected: /** checks whether nvn involves division by zero. */ - bool invariant(TermDbSygus* tds, Node nvn, Node x); + bool invariant(TermDbSygus* tds, Node nvn, Node x) override; }; /** NegContainsSygusInvarianceTest @@ -254,7 +254,7 @@ class NegContainsSygusInvarianceTest : public SygusInvarianceTest protected: /** checks if contains( out_i, nvn[in_i] ) --> false for some I/O pair i. */ - bool invariant(TermDbSygus* tds, Node nvn, Node x); + bool invariant(TermDbSygus* tds, Node nvn, Node x) override; private: /** The enumerator whose value we are considering in this invariance test */ diff --git a/src/theory/quantifiers/sygus_sampler.h b/src/theory/quantifiers/sygus_sampler.h index 06576d6ce..eba1a87b1 100644 --- a/src/theory/quantifiers/sygus_sampler.h +++ b/src/theory/quantifiers/sygus_sampler.h @@ -176,7 +176,7 @@ class SygusSampler : public LazyTrieEvaluator std::vector& vars, std::vector& pt); /** evaluate n on sample point index */ - Node evaluate(Node n, unsigned index); + Node evaluate(Node n, unsigned index) override; /** * Returns the index of a sample point such that the evaluation of a and b * diverge, or -1 if no such sample point exists. @@ -367,7 +367,7 @@ class SygusSamplerExt : public SygusSampler * from the set of all previous input/output pairs based on the * d_drewrite utility. */ - virtual Node registerTerm(Node n, bool forceKeep = false) override; + Node registerTerm(Node n, bool forceKeep = false) override; private: /** dynamic rewriter class */ diff --git a/src/theory/quantifiers/term_database.h b/src/theory/quantifiers/term_database.h index de766cc2a..e440e68e9 100644 --- a/src/theory/quantifiers/term_database.h +++ b/src/theory/quantifiers/term_database.h @@ -141,11 +141,11 @@ class TermDb : public QuantifiersUtil { /** presolve (called once per user check-sat) */ void presolve(); /** reset (calculate which terms are active) */ - virtual bool reset(Theory::Effort effort) override; + bool reset(Theory::Effort effort) override; /** register quantified formula */ - virtual void registerQuantifier(Node q) override; + void registerQuantifier(Node q) override; /** identify */ - virtual std::string identify() const override { return "TermDb"; } + std::string identify() const override { return "TermDb"; } /** get number of operators */ unsigned getNumOperators(); /** get operator at index i */ diff --git a/src/theory/quantifiers/term_util.h b/src/theory/quantifiers/term_util.h index 83d9d7940..bb02b1d6a 100644 --- a/src/theory/quantifiers/term_util.h +++ b/src/theory/quantifiers/term_util.h @@ -117,11 +117,11 @@ public: Node d_one; /** reset */ - virtual bool reset(Theory::Effort e) override { return true; } + bool reset(Theory::Effort e) override { return true; } /** register quantifier */ - virtual void registerQuantifier(Node q) override; + void registerQuantifier(Node q) override; /** identify */ - virtual std::string identify() const override { return "TermUtil"; } + std::string identify() const override { return "TermUtil"; } // for inst constant private: /** map from universal quantifiers to the list of variables */ diff --git a/src/theory/sep/theory_sep.h b/src/theory/sep/theory_sep.h index 7468d2778..9f3134f84 100644 --- a/src/theory/sep/theory_sep.h +++ b/src/theory/sep/theory_sep.h @@ -135,7 +135,7 @@ class TheorySep : public Theory { public: NotifyClass(TheorySep& sep) : d_sep(sep) {} - bool eqNotifyTriggerEquality(TNode equality, bool value) + bool eqNotifyTriggerEquality(TNode equality, bool value) override { Debug("sep::propagate") << "NotifyClass::eqNotifyTriggerEquality(" << equality << ", " @@ -151,7 +151,7 @@ class TheorySep : public Theory { } } - bool eqNotifyTriggerPredicate(TNode predicate, bool value) + bool eqNotifyTriggerPredicate(TNode predicate, bool value) override { Unreachable(); } @@ -159,7 +159,7 @@ class TheorySep : public Theory { bool eqNotifyTriggerTermEquality(TheoryId tag, TNode t1, TNode t2, - bool value) + bool value) override { Debug("sep::propagate") << "NotifyClass::eqNotifyTriggerTermEquality(" << t1 << ", " << t2 @@ -176,23 +176,23 @@ class TheorySep : public Theory { return true; } - void eqNotifyConstantTermMerge(TNode t1, TNode t2) + void eqNotifyConstantTermMerge(TNode t1, TNode t2) override { Debug("sep::propagate") << "NotifyClass::eqNotifyConstantTermMerge(" << t1 << ", " << t2 << ")" << std::endl; d_sep.conflict(t1, t2); } - void eqNotifyNewClass(TNode t) {} - void eqNotifyPreMerge(TNode t1, TNode t2) + void eqNotifyNewClass(TNode t) override {} + void eqNotifyPreMerge(TNode t1, TNode t2) override { d_sep.eqNotifyPreMerge(t1, t2); } - void eqNotifyPostMerge(TNode t1, TNode t2) + void eqNotifyPostMerge(TNode t1, TNode t2) override { d_sep.eqNotifyPostMerge(t1, t2); } - void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) {} + void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override {} }; /** The notify class for d_equalityEngine */ diff --git a/src/theory/sets/theory_sets_private.h b/src/theory/sets/theory_sets_private.h index bd63ff43d..b57f208bd 100644 --- a/src/theory/sets/theory_sets_private.h +++ b/src/theory/sets/theory_sets_private.h @@ -253,14 +253,17 @@ private: public: NotifyClass(TheorySetsPrivate& theory): d_theory(theory) {} - bool eqNotifyTriggerEquality(TNode equality, bool value); - bool eqNotifyTriggerPredicate(TNode predicate, bool value); - bool eqNotifyTriggerTermEquality(TheoryId tag, TNode t1, TNode t2, bool value); - void eqNotifyConstantTermMerge(TNode t1, TNode t2); - void eqNotifyNewClass(TNode t); - void eqNotifyPreMerge(TNode t1, TNode t2); - void eqNotifyPostMerge(TNode t1, TNode t2); - void eqNotifyDisequal(TNode t1, TNode t2, TNode reason); + bool eqNotifyTriggerEquality(TNode equality, bool value) override; + bool eqNotifyTriggerPredicate(TNode predicate, bool value) override; + bool eqNotifyTriggerTermEquality(TheoryId tag, + TNode t1, + TNode t2, + bool value) override; + void eqNotifyConstantTermMerge(TNode t1, TNode t2) override; + void eqNotifyNewClass(TNode t) override; + void eqNotifyPreMerge(TNode t1, TNode t2) override; + void eqNotifyPostMerge(TNode t1, TNode t2) override; + void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override; } d_notify; /** Equality engine */ diff --git a/src/theory/shared_terms_database.h b/src/theory/shared_terms_database.h index 5ca625751..bc4db97ee 100644 --- a/src/theory/shared_terms_database.h +++ b/src/theory/shared_terms_database.h @@ -78,28 +78,35 @@ private: SharedTermsDatabase& d_sharedTerms; public: EENotifyClass(SharedTermsDatabase& shared): d_sharedTerms(shared) {} - bool eqNotifyTriggerEquality(TNode equality, bool value) { + bool eqNotifyTriggerEquality(TNode equality, bool value) override + { d_sharedTerms.propagateEquality(equality, value); return true; } - bool eqNotifyTriggerPredicate(TNode predicate, bool value) { + bool eqNotifyTriggerPredicate(TNode predicate, bool value) override + { Unreachable(); return true; } - bool eqNotifyTriggerTermEquality(theory::TheoryId tag, TNode t1, TNode t2, bool value) { + bool eqNotifyTriggerTermEquality(theory::TheoryId tag, + TNode t1, + TNode t2, + bool value) override + { return d_sharedTerms.propagateSharedEquality(tag, t1, t2, value); } - void eqNotifyConstantTermMerge(TNode t1, TNode t2) { + void eqNotifyConstantTermMerge(TNode t1, TNode t2) override + { d_sharedTerms.conflict(t1, t2, true); } - void eqNotifyNewClass(TNode t) { } - void eqNotifyPreMerge(TNode t1, TNode t2) { } - void eqNotifyPostMerge(TNode t1, TNode t2) { } - void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) { } + void eqNotifyNewClass(TNode t) override {} + void eqNotifyPreMerge(TNode t1, TNode t2) override {} + void eqNotifyPostMerge(TNode t1, TNode t2) override {} + void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override {} }; /** The notify class for d_equalityEngine */ @@ -245,9 +252,7 @@ protected: /** * This method gets called on backtracks from the context manager. */ - void contextNotifyPop() { - backtrack(); - } + void contextNotifyPop() override { backtrack(); } }; } diff --git a/src/theory/strings/theory_strings.h b/src/theory/strings/theory_strings.h index e07cc6b5e..5dbbb93d6 100644 --- a/src/theory/strings/theory_strings.h +++ b/src/theory/strings/theory_strings.h @@ -81,7 +81,8 @@ class TheoryStrings : public Theory { TheoryStrings& d_str; public: NotifyClass(TheoryStrings& t_str): d_str(t_str) {} - bool eqNotifyTriggerEquality(TNode equality, bool value) { + bool eqNotifyTriggerEquality(TNode equality, bool value) override + { Debug("strings") << "NotifyClass::eqNotifyTriggerEquality(" << equality << ", " << (value ? "true" : "false" )<< ")" << std::endl; if (value) { return d_str.propagate(equality); @@ -90,7 +91,8 @@ class TheoryStrings : public Theory { return d_str.propagate(equality.notNode()); } } - bool eqNotifyTriggerPredicate(TNode predicate, bool value) { + bool eqNotifyTriggerPredicate(TNode predicate, bool value) override + { Debug("strings") << "NotifyClass::eqNotifyTriggerPredicate(" << predicate << ", " << (value ? "true" : "false") << ")" << std::endl; if (value) { return d_str.propagate(predicate); @@ -98,7 +100,11 @@ class TheoryStrings : public Theory { return d_str.propagate(predicate.notNode()); } } - bool eqNotifyTriggerTermEquality(TheoryId tag, TNode t1, TNode t2, bool value) { + bool eqNotifyTriggerTermEquality(TheoryId tag, + TNode t1, + TNode t2, + bool value) override + { Debug("strings") << "NotifyClass::eqNotifyTriggerTermMerge(" << tag << ", " << t1 << ", " << t2 << ")" << std::endl; if (value) { return d_str.propagate(t1.eqNode(t2)); @@ -106,23 +112,28 @@ class TheoryStrings : public Theory { return d_str.propagate(t1.eqNode(t2).notNode()); } } - void eqNotifyConstantTermMerge(TNode t1, TNode t2) { + void eqNotifyConstantTermMerge(TNode t1, TNode t2) override + { Debug("strings") << "NotifyClass::eqNotifyConstantTermMerge(" << t1 << ", " << t2 << ")" << std::endl; d_str.conflict(t1, t2); } - void eqNotifyNewClass(TNode t) { + void eqNotifyNewClass(TNode t) override + { Debug("strings") << "NotifyClass::eqNotifyNewClass(" << t << std::endl; d_str.eqNotifyNewClass(t); } - void eqNotifyPreMerge(TNode t1, TNode t2) { + void eqNotifyPreMerge(TNode t1, TNode t2) override + { Debug("strings") << "NotifyClass::eqNotifyPreMerge(" << t1 << ", " << t2 << std::endl; d_str.eqNotifyPreMerge(t1, t2); } - void eqNotifyPostMerge(TNode t1, TNode t2) { + void eqNotifyPostMerge(TNode t1, TNode t2) override + { Debug("strings") << "NotifyClass::eqNotifyPostMerge(" << t1 << ", " << t2 << std::endl; d_str.eqNotifyPostMerge(t1, t2); } - void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) { + void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override + { Debug("strings") << "NotifyClass::eqNotifyDisequal(" << t1 << ", " << t2 << ", " << reason << std::endl; d_str.eqNotifyDisequal(t1, t2, reason); } diff --git a/src/theory/substitutions.h b/src/theory/substitutions.h index cca39a62e..2a2531887 100644 --- a/src/theory/substitutions.h +++ b/src/theory/substitutions.h @@ -76,9 +76,8 @@ private: class CacheInvalidator : public context::ContextNotifyObj { bool& d_cacheInvalidated; protected: - void contextNotifyPop() { - d_cacheInvalidated = true; - } + void contextNotifyPop() override { d_cacheInvalidated = true; } + public: CacheInvalidator(context::Context* context, bool& cacheInvalidated) : context::ContextNotifyObj(context), diff --git a/src/theory/theory_engine.h b/src/theory/theory_engine.h index 7bc95b097..04e3c5697 100644 --- a/src/theory/theory_engine.h +++ b/src/theory/theory_engine.h @@ -157,14 +157,35 @@ class TheoryEngine { TheoryEngine& d_te; public: NotifyClass(TheoryEngine& te): d_te(te) {} - bool eqNotifyTriggerEquality(TNode equality, bool value) { return true; } - bool eqNotifyTriggerPredicate(TNode predicate, bool value) { return true; } - bool eqNotifyTriggerTermEquality(theory::TheoryId tag, TNode t1, TNode t2, bool value) { return true; } - void eqNotifyConstantTermMerge(TNode t1, TNode t2) {} - void eqNotifyNewClass(TNode t) { d_te.eqNotifyNewClass(t); } - void eqNotifyPreMerge(TNode t1, TNode t2) { d_te.eqNotifyPreMerge(t1, t2); } - void eqNotifyPostMerge(TNode t1, TNode t2) { d_te.eqNotifyPostMerge(t1, t2); } - void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) { d_te.eqNotifyDisequal(t1, t2, reason); } + bool eqNotifyTriggerEquality(TNode equality, bool value) override + { + return true; + } + bool eqNotifyTriggerPredicate(TNode predicate, bool value) override + { + return true; + } + bool eqNotifyTriggerTermEquality(theory::TheoryId tag, + TNode t1, + TNode t2, + bool value) override + { + return true; + } + void eqNotifyConstantTermMerge(TNode t1, TNode t2) override {} + void eqNotifyNewClass(TNode t) override { d_te.eqNotifyNewClass(t); } + void eqNotifyPreMerge(TNode t1, TNode t2) override + { + d_te.eqNotifyPreMerge(t1, t2); + } + void eqNotifyPostMerge(TNode t1, TNode t2) override + { + d_te.eqNotifyPostMerge(t1, t2); + } + void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override + { + d_te.eqNotifyDisequal(t1, t2, reason); + } };/* class TheoryEngine::NotifyClass */ NotifyClass d_masterEENotify; diff --git a/src/theory/theory_model_builder.h b/src/theory/theory_model_builder.h index bb74569b7..5b4a2d983 100644 --- a/src/theory/theory_model_builder.h +++ b/src/theory/theory_model_builder.h @@ -67,7 +67,7 @@ class TheoryEngineModelBuilder : public ModelBuilder * builder in steps (2) or (5), for instance, if the model we * are building fails to satisfy a quantified formula. */ - virtual bool buildModel(Model* m) override; + bool buildModel(Model* m) override; /** Debug check model. * * This throws an assertion failure if the model diff --git a/src/theory/theory_registrar.h b/src/theory/theory_registrar.h index df576a694..2514ccce0 100644 --- a/src/theory/theory_registrar.h +++ b/src/theory/theory_registrar.h @@ -37,9 +37,7 @@ public: TheoryRegistrar(TheoryEngine* te) : d_theoryEngine(te) { } - void preRegister(Node n) { - d_theoryEngine->preRegister(n); - } + void preRegister(Node n) override { d_theoryEngine->preRegister(n); } };/* class TheoryRegistrar */ diff --git a/src/theory/type_enumerator.h b/src/theory/type_enumerator.h index 7ca4a6140..736a65ade 100644 --- a/src/theory/type_enumerator.h +++ b/src/theory/type_enumerator.h @@ -84,7 +84,10 @@ public: TypeEnumeratorInterface(type) { } - TypeEnumeratorInterface* clone() const { return new T(static_cast(*this)); } + TypeEnumeratorInterface* clone() const override + { + return new T(static_cast(*this)); + } };/* class TypeEnumeratorBase */ diff --git a/src/theory/uf/equality_engine.h b/src/theory/uf/equality_engine.h index a89e55312..2d757cb28 100644 --- a/src/theory/uf/equality_engine.h +++ b/src/theory/uf/equality_engine.h @@ -131,14 +131,26 @@ public: */ class EqualityEngineNotifyNone : public EqualityEngineNotify { public: - bool eqNotifyTriggerEquality(TNode equality, bool value) { return true; } - bool eqNotifyTriggerPredicate(TNode predicate, bool value) { return true; } - bool eqNotifyTriggerTermEquality(TheoryId tag, TNode t1, TNode t2, bool value) { return true; } - void eqNotifyConstantTermMerge(TNode t1, TNode t2) { } - void eqNotifyNewClass(TNode t) { } - void eqNotifyPreMerge(TNode t1, TNode t2) { } - void eqNotifyPostMerge(TNode t1, TNode t2) { } - void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) { } + bool eqNotifyTriggerEquality(TNode equality, bool value) override + { + return true; + } + bool eqNotifyTriggerPredicate(TNode predicate, bool value) override + { + return true; + } + bool eqNotifyTriggerTermEquality(TheoryId tag, + TNode t1, + TNode t2, + bool value) override + { + return true; + } + void eqNotifyConstantTermMerge(TNode t1, TNode t2) override {} + void eqNotifyNewClass(TNode t) override {} + void eqNotifyPreMerge(TNode t1, TNode t2) override {} + void eqNotifyPostMerge(TNode t1, TNode t2) override {} + void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override {} };/* class EqualityEngineNotifyNone */ /** @@ -538,9 +550,7 @@ private: /** * This method gets called on backtracks from the context manager. */ - void contextNotifyPop() { - backtrack(); - } + void contextNotifyPop() override { backtrack(); } /** * Constructor initialization stuff. diff --git a/src/theory/uf/theory_uf.h b/src/theory/uf/theory_uf.h index 6fde4a9af..bac03c34c 100644 --- a/src/theory/uf/theory_uf.h +++ b/src/theory/uf/theory_uf.h @@ -55,7 +55,8 @@ public: public: NotifyClass(TheoryUF& uf): d_uf(uf) {} - bool eqNotifyTriggerEquality(TNode equality, bool value) { + bool eqNotifyTriggerEquality(TNode equality, bool value) override + { Debug("uf") << "NotifyClass::eqNotifyTriggerEquality(" << equality << ", " << (value ? "true" : "false" )<< ")" << std::endl; if (value) { return d_uf.propagate(equality); @@ -65,7 +66,8 @@ public: } } - bool eqNotifyTriggerPredicate(TNode predicate, bool value) { + bool eqNotifyTriggerPredicate(TNode predicate, bool value) override + { Debug("uf") << "NotifyClass::eqNotifyTriggerPredicate(" << predicate << ", " << (value ? "true" : "false") << ")" << std::endl; if (value) { return d_uf.propagate(predicate); @@ -74,7 +76,11 @@ public: } } - bool eqNotifyTriggerTermEquality(TheoryId tag, TNode t1, TNode t2, bool value) { + bool eqNotifyTriggerTermEquality(TheoryId tag, + TNode t1, + TNode t2, + bool value) override + { Debug("uf") << "NotifyClass::eqNotifyTriggerTermMerge(" << tag << ", " << t1 << ", " << t2 << ")" << std::endl; if (value) { return d_uf.propagate(t1.eqNode(t2)); @@ -83,27 +89,32 @@ public: } } - void eqNotifyConstantTermMerge(TNode t1, TNode t2) { + void eqNotifyConstantTermMerge(TNode t1, TNode t2) override + { Debug("uf-notify") << "NotifyClass::eqNotifyConstantTermMerge(" << t1 << ", " << t2 << ")" << std::endl; d_uf.conflict(t1, t2); } - void eqNotifyNewClass(TNode t) { + void eqNotifyNewClass(TNode t) override + { Debug("uf-notify") << "NotifyClass::eqNotifyNewClass(" << t << ")" << std::endl; d_uf.eqNotifyNewClass(t); } - void eqNotifyPreMerge(TNode t1, TNode t2) { + void eqNotifyPreMerge(TNode t1, TNode t2) override + { Debug("uf-notify") << "NotifyClass::eqNotifyPreMerge(" << t1 << ", " << t2 << ")" << std::endl; d_uf.eqNotifyPreMerge(t1, t2); } - void eqNotifyPostMerge(TNode t1, TNode t2) { + void eqNotifyPostMerge(TNode t1, TNode t2) override + { Debug("uf-notify") << "NotifyClass::eqNotifyPostMerge(" << t1 << ", " << t2 << ")" << std::endl; d_uf.eqNotifyPostMerge(t1, t2); } - void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) { + void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override + { Debug("uf-notify") << "NotifyClass::eqNotifyDisequal(" << t1 << ", " << t2 << ", " << reason << ")" << std::endl; d_uf.eqNotifyDisequal(t1, t2, reason); } diff --git a/src/util/statistics_registry.h b/src/util/statistics_registry.h index 73a545185..b0ce5698a 100644 --- a/src/util/statistics_registry.h +++ b/src/util/statistics_registry.h @@ -228,21 +228,21 @@ public: virtual const T& getDataRef() const = 0; /** Flush the value of the statistic to the given output stream. */ - void flushInformation(std::ostream& out) const { + void flushInformation(std::ostream& out) const override + { if(__CVC4_USE_STATISTICS) { out << getData(); } } - virtual void safeFlushInformation(int fd) const { + void safeFlushInformation(int fd) const override + { if (__CVC4_USE_STATISTICS) { safe_print(fd, getDataRef()); } } - SExpr getValue() const { - return mkSExpr(getData()); - } + SExpr getValue() const override { return mkSExpr(getData()); } };/* class ReadOnlyDataStat */ @@ -315,17 +315,18 @@ public: } /** Set this reference statistic to refer to the given data cell. */ - void setData(const T& t) { + void setData(const T& t) override + { if(__CVC4_USE_STATISTICS) { d_data = &t; } } /** Get the value of the referenced data cell. */ - virtual T getData() const { return *d_data; } + T getData() const override { return *d_data; } /** Get a reference to the value of the referenced data cell. */ - virtual const T& getDataRef() const { return *d_data; } + const T& getDataRef() const override { return *d_data; } };/* class ReferenceStat */ @@ -349,7 +350,8 @@ public: } /** Set the underlying data value to the given value. */ - void setData(const T& t) { + void setData(const T& t) override + { if(__CVC4_USE_STATISTICS) { d_data = t; } @@ -364,10 +366,10 @@ public: } /** Get the underlying data value. */ - virtual T getData() const { return d_data; } + T getData() const override { return d_data; } /** Get a reference to the underlying data value. */ - virtual const T& getDataRef() const { return d_data; } + const T& getDataRef() const override { return d_data; } };/* class BackedStat */ @@ -406,21 +408,20 @@ public: } /** Get the data of the underlying (wrapped) statistic. */ - virtual T getData() const { return d_stat.getData(); } + T getData() const override { return d_stat.getData(); } /** Get a reference to the data of the underlying (wrapped) statistic. */ - virtual const T& getDataRef() const { return d_stat.getDataRef(); } + const T& getDataRef() const override { return d_stat.getDataRef(); } - virtual void safeFlushInformation(int fd) const { + void safeFlushInformation(int fd) const override + { // ReadOnlyDataStat uses getDataRef() to get the information to print, // which might not be appropriate for all wrapped statistics. Delegate the // printing to the wrapped statistic instead. d_stat.safeFlushInformation(fd); } - SExpr getValue() const { - return d_stat.getValue(); - } + SExpr getValue() const override { return d_stat.getValue(); } };/* class WrappedStat */ @@ -474,9 +475,7 @@ public: } } - SExpr getValue() const { - return SExpr(Integer(d_data)); - } + SExpr getValue() const override { return SExpr(Integer(d_data)); } };/* class IntStat */ @@ -489,17 +488,17 @@ public: Stat(name), d_sized(sized) {} ~SizeStat() {} - void flushInformation(std::ostream& out) const { + void flushInformation(std::ostream& out) const override + { out << d_sized.size(); } - void safeFlushInformation(int fd) const { + void safeFlushInformation(int fd) const override + { safe_print(fd, d_sized.size()); } - SExpr getValue() const { - return SExpr(Integer(d_sized.size())); - } + SExpr getValue() const override { return SExpr(Integer(d_sized.size())); } };/* class SizeStat */ @@ -538,7 +537,8 @@ public: } } - SExpr getValue() const { + SExpr getValue() const override + { std::stringstream ss; ss << std::fixed << std::setprecision(8) << d_data; return SExpr(Rational::fromDecimal(ss.str())); @@ -560,19 +560,19 @@ public: SExprStat(const std::string& name, const SExpr& init) : Stat(name), d_data(init){} - virtual void flushInformation(std::ostream& out) const { + void flushInformation(std::ostream& out) const override + { out << d_data << std::endl; } - virtual void safeFlushInformation(int fd) const { + void safeFlushInformation(int fd) const override + { // SExprStat is only used in statistics.cpp in copyFrom, which we cannot // do in a signal handler anyway. safe_print(fd, ""); } - SExpr getValue() const { - return d_data; - } + SExpr getValue() const override { return d_data; } };/* class SExprStat */ @@ -587,7 +587,8 @@ public: HistogramStat(const std::string& name) : Stat(name) {} ~HistogramStat() {} - void flushInformation(std::ostream& out) const{ + void flushInformation(std::ostream& out) const override + { if(__CVC4_USE_STATISTICS) { typename Histogram::const_iterator i = d_hist.begin(); typename Histogram::const_iterator end = d_hist.end(); @@ -605,7 +606,8 @@ public: } } - virtual void safeFlushInformation(int fd) const { + void safeFlushInformation(int fd) const override + { if (__CVC4_USE_STATISTICS) { typename Histogram::const_iterator i = d_hist.begin(); typename Histogram::const_iterator end = d_hist.end(); @@ -665,18 +667,17 @@ public: * Set the name of this statistic registry, used as prefix during * output. (This version overrides StatisticsBase::setPrefix().) */ - void setPrefix(const std::string& name) { - d_prefix = d_name = name; - } + void setPrefix(const std::string& name) override { d_prefix = d_name = name; } /** Overridden to avoid the name being printed */ - void flushStat(std::ostream &out) const; + void flushStat(std::ostream& out) const override; - virtual void flushInformation(std::ostream& out) const; + void flushInformation(std::ostream& out) const override; - virtual void safeFlushInformation(int fd) const; + void safeFlushInformation(int fd) const override; - SExpr getValue() const { + SExpr getValue() const override + { std::vector v; for(StatSet::iterator i = d_stats.begin(); i != d_stats.end(); ++i) { std::vector w; @@ -734,9 +735,10 @@ public: /** If the timer is currently running */ bool running() const; - virtual timespec getData() const; + timespec getData() const override; - virtual void safeFlushInformation(int fd) const { + void safeFlushInformation(int fd) const override + { // Overwrite the implementation in the superclass because we cannot use // getDataRef(): it might return stale data if the timer is currently // running. @@ -744,7 +746,7 @@ public: safe_print(fd, data); } - SExpr getValue() const; + SExpr getValue() const override; };/* class TimerStat */ -- cgit v1.2.3 From b8a89b4dbba79ce79f193008a58f7c36deb2a821 Mon Sep 17 00:00:00 2001 From: Mathias Preiner Date: Mon, 5 Mar 2018 15:37:10 -0800 Subject: Fix boost url in contrib/get-win-dependencies. This fixes the broken windows nightly builds. --- contrib/get-win-dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/get-win-dependencies b/contrib/get-win-dependencies index 964bdbff7..ee33391d7 100755 --- a/contrib/get-win-dependencies +++ b/contrib/get-win-dependencies @@ -98,7 +98,7 @@ echo "Setting up Boost..." echo ( mkdir boost-$BOOSTVERSION && cd boost-$BOOSTVERSION && - webget http://downloads.sourceforge.net/project/boost/boost/$BOOSTVERSION/$BOOSTBASE.tar.gz $BOOSTBASE.tar.gz && + webget https://sourceforge.net/projects/boost/files/boost/$BOOSTVERSION/$BOOSTBASE.tar.gz/download $BOOSTBASE.tar.gz && tar xfz $BOOSTBASE.tar.gz && cd $BOOSTBASE && ./bootstrap.sh --with-toolset=gcc --prefix=`pwd`/.. --with-libraries=thread && -- cgit v1.2.3 From e2d714a0839fb80d9a40e9b6fdd8a6fe325a1664 Mon Sep 17 00:00:00 2001 From: Andrew Reynolds Date: Mon, 5 Mar 2018 20:36:17 -0600 Subject: Update semantics for string indexof and replace (#1630) --- src/theory/datatypes/datatypes_sygus.cpp | 2 +- src/theory/strings/theory_strings_preprocess.cpp | 182 ++++++++++++++------- src/theory/strings/theory_strings_rewriter.cpp | 112 ++++++------- src/theory/strings/theory_strings_rewriter.h | 42 ++++- test/regress/regress0/strings/idof-sem.smt2 | 4 +- test/regress/regress0/strings/repl-rewrites2.smt2 | 5 +- test/regress/regress1/strings/Makefile.am | 4 +- .../regress1/strings/cmu-disagree-0707-dd.smt2 | 22 --- test/regress/regress1/strings/double-replace.smt2 | 3 +- test/regress/regress1/strings/repl-empty-sem.smt2 | 4 +- .../regress1/strings/repl-soundness-sem.smt2 | 4 +- test/regress/regress1/strings/rew-020618.smt2 | 2 +- .../regress1/strings/string-unsound-sem.smt2 | 12 ++ test/regress/regress2/strings/Makefile.am | 3 +- .../regress2/strings/cmu-disagree-0707-dd.smt2 | 22 +++ 15 files changed, 262 insertions(+), 161 deletions(-) delete mode 100644 test/regress/regress1/strings/cmu-disagree-0707-dd.smt2 create mode 100644 test/regress/regress1/strings/string-unsound-sem.smt2 create mode 100644 test/regress/regress2/strings/cmu-disagree-0707-dd.smt2 diff --git a/src/theory/datatypes/datatypes_sygus.cpp b/src/theory/datatypes/datatypes_sygus.cpp index 6f533bfe0..b8185e9c8 100644 --- a/src/theory/datatypes/datatypes_sygus.cpp +++ b/src/theory/datatypes/datatypes_sygus.cpp @@ -843,7 +843,7 @@ bool SygusSymBreakNew::registerSearchValue( Node a, Node n, Node nv, unsigned d, Node pbv_e = its->second.evaluate(bvr, pt_index); Assert(bv_e != pbv_e); Trace("sygus-rr-debug") << "; unsound: where they evaluate to " - << pbv_e << " and " << bv_e << std::endl; + << bv_e << " and " << pbv_e << std::endl; } else { diff --git a/src/theory/strings/theory_strings_preprocess.cpp b/src/theory/strings/theory_strings_preprocess.cpp index 1a61cb449..d412eaa33 100644 --- a/src/theory/strings/theory_strings_preprocess.cpp +++ b/src/theory/strings/theory_strings_preprocess.cpp @@ -72,6 +72,7 @@ Node StringsPreprocess::simplify( Node t, std::vector< Node > &new_nodes ) { unsigned prev_new_nodes = new_nodes.size(); Trace("strings-preprocess-debug") << "StringsPreprocess::simplify: " << t << std::endl; Node retNode = t; + NodeManager *nm = NodeManager::currentNM(); if( t.getKind() == kind::STRING_SUBSTR ) { Node skt; @@ -105,52 +106,87 @@ Node StringsPreprocess::simplify( Node t, std::vector< Node > &new_nodes ) { Node lemma = NodeManager::currentNM()->mkNode( kind::ITE, cond, b1, b2 ); new_nodes.push_back( lemma ); retNode = skt; - } else if( t.getKind() == kind::STRING_STRIDOF ) { - Node sk2 = NodeManager::currentNM()->mkSkolem( "io2", NodeManager::currentNM()->stringType(), "created for indexof" ); - Node sk3 = NodeManager::currentNM()->mkSkolem( "io3", NodeManager::currentNM()->stringType(), "created for indexof" ); - Node sk4 = NodeManager::currentNM()->mkSkolem( "io4", NodeManager::currentNM()->stringType(), "created for indexof" ); + } + else if (t.getKind() == kind::STRING_STRIDOF) + { + // processing term: indexof( x, y, n ) + Node skk; if( options::stringUfReduct() ){ skk = getUfAppForNode( kind::STRING_STRIDOF, t ); }else{ - skk = NodeManager::currentNM()->mkSkolem( "iok", NodeManager::currentNM()->integerType(), "created for indexof" ); + skk = nm->mkSkolem("iok", nm->integerType(), "created for indexof"); } - Node st = NodeManager::currentNM()->mkNode( kind::STRING_SUBSTR, t[0], t[2], NodeManager::currentNM()->mkNode( kind::MINUS, NodeManager::currentNM()->mkNode( kind::STRING_LENGTH, t[0] ), t[2] ) ); - //TODO: simplify this (only applies when idof != -1) - Node eq = st.eqNode( NodeManager::currentNM()->mkNode( kind::STRING_CONCAT, sk2, sk3, sk4 ) ); - new_nodes.push_back( eq ); - - //learn range of idof? - Node negone = NodeManager::currentNM()->mkConst( ::CVC4::Rational(-1) ); - Node krange = NodeManager::currentNM()->mkNode( kind::GEQ, skk, negone ); + + Node negone = nm->mkConst(::CVC4::Rational(-1)); + Node krange = nm->mkNode(kind::GEQ, skk, negone); + // assert: indexof( x, y, n ) >= -1 new_nodes.push_back( krange ); - krange = NodeManager::currentNM()->mkNode( kind::GT, NodeManager::currentNM()->mkNode( kind::STRING_LENGTH, t[0] ), skk); + krange = nm->mkNode(kind::GEQ, nm->mkNode(kind::STRING_LENGTH, t[0]), skk); + // assert: len( x ) >= indexof( x, y, z ) new_nodes.push_back( krange ); - // s2 = "" - Node c1 = t[1].eqNode( NodeManager::currentNM()->mkConst( ::CVC4::String("") ) ); - //~contain(t234, s2) - Node c3 = NodeManager::currentNM()->mkNode( kind::STRING_STRCTN, st, t[1] ).negate(); - //left - Node left = NodeManager::currentNM()->mkNode( kind::OR, c1, c3 ); - //t3 = s2 - Node c4 = t[1].eqNode( sk3 ); - //~contain(t2, s2) - Node c5 = NodeManager::currentNM()->mkNode( kind::STRING_STRCTN, - NodeManager::currentNM()->mkNode(kind::STRING_CONCAT, sk2, - NodeManager::currentNM()->mkNode(kind::STRING_SUBSTR, t[1], d_zero, - NodeManager::currentNM()->mkNode(kind::MINUS, - NodeManager::currentNM()->mkNode(kind::STRING_LENGTH, t[1]), - NodeManager::currentNM()->mkConst( ::CVC4::Rational(1) )))), - t[1] ).negate(); - //k=str.len(s2) - Node c6 = skk.eqNode( NodeManager::currentNM()->mkNode( kind::PLUS, t[2], - NodeManager::currentNM()->mkNode( kind::STRING_LENGTH, sk2 )) ); - //right - Node right = NodeManager::currentNM()->mkNode( kind::AND, c4, c5, c6, c1.negate() ); - Node cond = skk.eqNode( negone ); - Node rr = NodeManager::currentNM()->mkNode( kind::ITE, cond, left, right ); + // substr( x, n, len( x ) - n ) + Node st = nm->mkNode( + kind::STRING_SUBSTR, + t[0], + t[2], + nm->mkNode(kind::MINUS, nm->mkNode(kind::STRING_LENGTH, t[0]), t[2])); + Node io2 = nm->mkSkolem("io2", nm->stringType(), "created for indexof"); + Node io4 = nm->mkSkolem("io4", nm->stringType(), "created for indexof"); + + // ~contains( substr( x, n, len( x ) - n ), y ) + Node c11 = nm->mkNode(kind::STRING_STRCTN, st, t[1]).negate(); + // n > len( x ) + Node c12 = + nm->mkNode(kind::GT, t[2], nm->mkNode(kind::STRING_LENGTH, t[0])); + // 0 > n + Node c13 = nm->mkNode(kind::GT, d_zero, t[2]); + Node cond1 = nm->mkNode(kind::OR, c11, c12, c13); + // skk = -1 + Node cc1 = skk.eqNode(negone); + + // y = "" + Node cond2 = t[1].eqNode(nm->mkConst(CVC4::String(""))); + // skk = n + Node cc2 = skk.eqNode(t[2]); + + // substr( x, n, len( x ) - n ) = str.++( io2, y, io4 ) + Node c31 = st.eqNode(nm->mkNode(kind::STRING_CONCAT, io2, t[1], io4)); + // ~contains( str.++( io2, substr( y, 0, len( y ) - 1) ), y ) + Node c32 = + nm->mkNode( + kind::STRING_STRCTN, + nm->mkNode( + kind::STRING_CONCAT, + io2, + nm->mkNode(kind::STRING_SUBSTR, + t[1], + d_zero, + nm->mkNode(kind::MINUS, + nm->mkNode(kind::STRING_LENGTH, t[1]), + d_one))), + t[1]) + .negate(); + // skk = n + len( io2 ) + Node c33 = skk.eqNode( + nm->mkNode(kind::PLUS, t[2], nm->mkNode(kind::STRING_LENGTH, io2))); + Node cc3 = nm->mkNode(kind::AND, c31, c32, c33); + + // assert: + // IF: ~contains( substr( x, n, len( x ) - n ), y ) OR n > len(x) OR 0 > n + // THEN: skk = -1 + // ELIF: y = "" + // THEN: skk = n + // ELSE: substr( x, n, len( x ) - n ) = str.++( io2, y, io4 ) ^ + // ~contains( str.++( io2, substr( y, 0, len( y ) - 1) ), y ) ^ + // skk = n + len( io2 ) + // for fresh io2, io4. + Node rr = nm->mkNode( + kind::ITE, cond1, cc1, nm->mkNode(kind::ITE, cond2, cc2, cc3)); new_nodes.push_back( rr ); + + // Thus, indexof( x, y, n ) = skk. retNode = skk; } else if( t.getKind() == kind::STRING_ITOS ) { //Node num = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::ITE, @@ -363,28 +399,64 @@ Node StringsPreprocess::simplify( Node t, std::vector< Node > &new_nodes ) { NodeManager::currentNM()->mkNode(kind::OR, cc1, cc2), cc3); new_nodes.push_back( conc ); retNode = pret; - } else if( t.getKind() == kind::STRING_STRREPL ) { + } + else if (t.getKind() == kind::STRING_STRREPL) + { + // processing term: replace( x, y, z ) Node x = t[0]; Node y = t[1]; Node z = t[2]; - Node sk1 = NodeManager::currentNM()->mkSkolem( "rp1", t[0].getType(), "created for replace" ); - Node sk2 = NodeManager::currentNM()->mkSkolem( "rp2", t[0].getType(), "created for replace" ); - Node skw = NodeManager::currentNM()->mkSkolem( "rpw", t[0].getType(), "created for replace" ); - Node cond = NodeManager::currentNM()->mkNode( kind::STRING_STRCTN, x, y ); - cond = NodeManager::currentNM()->mkNode( kind::AND, cond, NodeManager::currentNM()->mkNode(kind::GT, NodeManager::currentNM()->mkNode(kind::STRING_LENGTH, y), d_zero) ); - Node c1 = x.eqNode( NodeManager::currentNM()->mkNode( kind::STRING_CONCAT, sk1, y, sk2 ) ); - Node c2 = skw.eqNode( NodeManager::currentNM()->mkNode( kind::STRING_CONCAT, sk1, z, sk2 ) ); - Node c3 = NodeManager::currentNM()->mkNode(kind::STRING_STRCTN, - NodeManager::currentNM()->mkNode(kind::STRING_CONCAT, sk1, - NodeManager::currentNM()->mkNode(kind::STRING_SUBSTR, y, d_zero, - NodeManager::currentNM()->mkNode(kind::MINUS, - NodeManager::currentNM()->mkNode(kind::STRING_LENGTH, y), - NodeManager::currentNM()->mkConst(::CVC4::Rational(1))))), y).negate(); - Node rr = NodeManager::currentNM()->mkNode( kind::ITE, cond, - NodeManager::currentNM()->mkNode( kind::AND, c1, c2, c3), - skw.eqNode(x) ); + TypeNode tn = t[0].getType(); + Node rp1 = nm->mkSkolem("rp1", tn, "created for replace"); + Node rp2 = nm->mkSkolem("rp2", tn, "created for replace"); + Node rpw = nm->mkSkolem("rpw", tn, "created for replace"); + + // y = "" + Node cond1 = y.eqNode(nm->mkConst(CVC4::String(""))); + // rpw = str.++( z, x ) + Node c1 = rpw.eqNode(nm->mkNode(kind::STRING_CONCAT, z, x)); + + // contains( x, y ) + Node cond2 = nm->mkNode(kind::STRING_STRCTN, x, y); + // x = str.++( rp1, y, rp2 ) + Node c21 = x.eqNode(nm->mkNode(kind::STRING_CONCAT, rp1, y, rp2)); + // rpw = str.++( rp1, z, rp2 ) + Node c22 = rpw.eqNode(nm->mkNode(kind::STRING_CONCAT, rp1, z, rp2)); + // ~contains( str.++( rp1, substr( y, 0, len(y)-1 ) ), y ) + Node c23 = + nm->mkNode(kind::STRING_STRCTN, + nm->mkNode( + kind::STRING_CONCAT, + rp1, + nm->mkNode(kind::STRING_SUBSTR, + y, + d_zero, + nm->mkNode(kind::MINUS, + nm->mkNode(kind::STRING_LENGTH, y), + d_one))), + y) + .negate(); + + // assert: + // IF y="" + // THEN: rpw = str.++( z, x ) + // ELIF: contains( x, y ) + // THEN: x = str.++( rp1, y, rp2 ) ^ + // rpw = str.++( rp1, z, rp2 ) ^ + // ~contains( str.++( rp1, substr( y, 0, len(y)-1 ) ), y ), + // ELSE: rpw = x + // for fresh rp1, rp2, rpw + Node rr = nm->mkNode(kind::ITE, + cond1, + c1, + nm->mkNode(kind::ITE, + cond2, + nm->mkNode(kind::AND, c21, c22, c23), + rpw.eqNode(x))); new_nodes.push_back( rr ); - retNode = skw; + + // Thus, replace( x, y, z ) = rpw. + retNode = rpw; } else if( t.getKind() == kind::STRING_STRCTN ){ Node x = t[0]; Node s = t[1]; diff --git a/src/theory/strings/theory_strings_rewriter.cpp b/src/theory/strings/theory_strings_rewriter.cpp index 1555b0aa0..e66861579 100644 --- a/src/theory/strings/theory_strings_rewriter.cpp +++ b/src/theory/strings/theory_strings_rewriter.cpp @@ -1827,16 +1827,6 @@ Node TheoryStringsRewriter::rewriteIndexof( Node node ) { return returnRewrite(node, negone, "idof-neg"); } - if (node[1].isConst()) - { - if (node[1].getConst().size() == 0) - { - // str.indexof( x, "", z ) --> -1 - Node negone = nm->mkConst(Rational(-1)); - return returnRewrite(node, negone, "idof-empty"); - } - } - // evaluation and simple cases std::vector children0; getConcat(node[0], children0); @@ -1884,16 +1874,6 @@ Node TheoryStringsRewriter::rewriteIndexof( Node node ) { { fstr = nm->mkNode(kind::STRING_SUBSTR, node[0], node[2], len0); fstr = Rewriter::rewrite(fstr); - if (fstr.isConst()) - { - CVC4::String fs = fstr.getConst(); - if (fs.size() == 0) - { - // substr( x, z, len(x) ) --> "" implies str.indexof( x, y, z ) --> -1 - Node negone = nm->mkConst(Rational(-1)); - return returnRewrite(node, negone, "idof-base-len"); - } - } } Node cmp_con = nm->mkNode(kind::STRING_STRCTN, fstr, node[1]); @@ -1960,25 +1940,22 @@ Node TheoryStringsRewriter::rewriteIndexof( Node node ) { Node TheoryStringsRewriter::rewriteReplace( Node node ) { Assert(node.getKind() == kind::STRING_STRREPL); - if( node[1]==node[2] ){ + NodeManager* nm = NodeManager::currentNM(); + + if (node[1] == node[2]) + { return returnRewrite(node, node[0], "rpl-id"); } - if (node[0].isConst()) + + if (node[0] == node[1]) { - CVC4::String s = node[0].getConst(); - if (s.isEmptyString()) - { - return returnRewrite(node, node[0], "rpl-empty"); - } - if (node[0] == node[2] && s.size() == 1) - { - // str.replace( "A", x, "A" ) -> "A" - return returnRewrite(node, node[0], "rpl-char-id"); - } + return returnRewrite(node, node[2], "rpl-replace"); } + if (node[1].isConst() && node[1].getConst().isEmptyString()) { - return returnRewrite(node, node[0], "rpl-rpl-empty"); + Node ret = nm->mkNode(STRING_CONCAT, node[2], node[0]); + return returnRewrite(node, ret, "rpl-rpl-empty"); } std::vector children0; @@ -2047,26 +2024,13 @@ Node TheoryStringsRewriter::rewriteReplace( Node node ) { { if (cmp_conr.getConst()) { - // currently by the semantics of replace, if the second argument is - // empty, then we return the first argument. - // hence, we test whether the second argument must be non-empty here. - // if it definitely non-empty, we can use rules that successfully replace - // node[1]->node[2] among those below. - Node l1 = NodeManager::currentNM()->mkNode(kind::STRING_LENGTH, node[1]); - Node zero = NodeManager::currentNM()->mkConst(CVC4::Rational(0)); - bool is_non_empty = checkEntailArith(l1, zero, true); - - if (node[0] == node[1] && is_non_empty) - { - return returnRewrite(node, node[2], "rpl-replace"); - } // component-wise containment std::vector cb; std::vector ce; int cc = componentContains(children0, children1, cb, ce, true, 1); if (cc != -1) { - if (cc == 0 && children0[0] == children1[0] && is_non_empty) + if (cc == 0 && children0[0] == children1[0]) { // definitely a prefix, can do the replace // for example, @@ -2106,24 +2070,27 @@ Node TheoryStringsRewriter::rewriteReplace( Node node ) { if (cmp_conr != cmp_con) { - // pull endpoints that can be stripped - // for example, - // str.replace( str.++( "b", x, "b" ), "a", y ) ---> - // str.++( "b", str.replace( x, "a", y ), "b" ) - std::vector cb; - std::vector ce; - if (stripConstantEndpoints(children0, children1, cb, ce)) + if (checkEntailNonEmpty(node[1])) { - std::vector cc; - cc.insert(cc.end(), cb.begin(), cb.end()); - cc.push_back(NodeManager::currentNM()->mkNode( - kind::STRING_STRREPL, - mkConcat(kind::STRING_CONCAT, children0), - node[1], - node[2])); - cc.insert(cc.end(), ce.begin(), ce.end()); - Node ret = mkConcat(kind::STRING_CONCAT, cc); - return returnRewrite(node, ret, "rpl-pull-endpt"); + // pull endpoints that can be stripped + // for example, + // str.replace( str.++( "b", x, "b" ), "a", y ) ---> + // str.++( "b", str.replace( x, "a", y ), "b" ) + std::vector cb; + std::vector ce; + if (stripConstantEndpoints(children0, children1, cb, ce)) + { + std::vector cc; + cc.insert(cc.end(), cb.begin(), cb.end()); + cc.push_back(NodeManager::currentNM()->mkNode( + kind::STRING_STRREPL, + mkConcat(kind::STRING_CONCAT, children0), + node[1], + node[2])); + cc.insert(cc.end(), ce.begin(), ce.end()); + Node ret = mkConcat(kind::STRING_CONCAT, cc); + return returnRewrite(node, ret, "rpl-pull-endpt"); + } } } @@ -2661,13 +2628,13 @@ bool TheoryStringsRewriter::componentContainsBase( NodeManager::currentNM()->mkNode(kind::STRING_LENGTH, n2[0]); if (dir == 1) { - // To be suffix, start + length must be greater than + // To be a suffix, start + length must be greater than // or equal to the length of the string. success = checkEntailArith(end_pos, len_n2s); } else if (dir == -1) { - // To be prefix, must literally start at 0, since + // To be a prefix, must literally start at 0, since // if we knew it started at <0, it should be rewritten to "", // if we knew it started at 0, then n2[1] should be rewritten to // 0. @@ -2678,6 +2645,12 @@ bool TheoryStringsRewriter::componentContainsBase( { if (computeRemainder) { + // we can only compute the remainder if start_pos and end_pos + // are known to be non-negative. + if (!checkEntailArith(start_pos) || !checkEntailArith(end_pos)) + { + return false; + } if (dir != 1) { n1rb = NodeManager::currentNM()->mkNode( @@ -2883,6 +2856,13 @@ bool TheoryStringsRewriter::stripConstantEndpoints(std::vector& n1, return changed; } +bool TheoryStringsRewriter::checkEntailNonEmpty(Node a) +{ + Node len = NodeManager::currentNM()->mkNode(STRING_LENGTH, a); + len = Rewriter::rewrite(len); + return checkEntailArith(len, true); +} + bool TheoryStringsRewriter::checkEntailArithEq(Node a, Node b) { if (a == b) diff --git a/src/theory/strings/theory_strings_rewriter.h b/src/theory/strings/theory_strings_rewriter.h index e0d265334..217546c71 100644 --- a/src/theory/strings/theory_strings_rewriter.h +++ b/src/theory/strings/theory_strings_rewriter.h @@ -91,19 +91,24 @@ private: * Context-Dependent Rewriting", CAV 2017. */ static Node rewriteContains(Node node); + /** rewrite indexof + * This is the entry point for post-rewriting terms n of the form + * str.indexof( s, t, n ) + * Returns the rewritten form of node. + */ static Node rewriteIndexof(Node node); /** rewrite replace * This is the entry point for post-rewriting terms n of the form * str.replace( s, t, r ) - * Returns the rewritten form of n. + * Returns the rewritten form of node. */ - static Node rewriteReplace(Node n); + static Node rewriteReplace(Node node); /** rewrite prefix/suffix * This is the entry point for post-rewriting terms n of the form * str.prefixof( s, t ) / str.suffixof( s, t ) - * Returns the rewritten form of n. + * Returns the rewritten form of node. */ - static Node rewritePrefixSuffix(Node n); + static Node rewritePrefixSuffix(Node node); /** gets the "vector form" of term n, adds it to c. * For example: @@ -269,6 +274,29 @@ private: * componentContainsBase(y, str.substr(y,0,5), n1rb, n1re, -1, true) * returns true, * n1re is set to str.substr(y,5,str.len(y)). + * + * + * Notice that this function may return false when it cannot compute a + * remainder when it otherwise would have returned true. For example: + * + * componentContainsBase(y, str.substr(y,x,z), n1rb, n1re, 0, false) + * returns true. + * + * Hence, we know that str.substr(y,x,z) is contained in y. However: + * + * componentContainsBase(y, str.substr(y,x,z), n1rb, n1re, 0, true) + * returns false. + * + * The reason is since computeRemainder=true, it must be that + * y = str.++( n1rb, str.substr(y,x,z), n1re ) + * for some n1rb, n1re. However, to construct such n1rb, n1re would require + * e.g. the terms: + * y = str.++( ite( x+z < 0 OR x < 0, "", str.substr(y,0,x) ), + * str.substr(y,x,z), + * ite( x+z < 0 OR x < 0, y, str.substr(y,x+z,len(y)) ) ) + * + * Since we do not wish to introduce ITE terms in the rewriter, we instead + * return false, indicating that we cannot compute the remainder. */ static bool componentContainsBase( Node n1, Node n2, Node& n1rb, Node& n1re, int dir, bool computeRemainder); @@ -305,6 +333,12 @@ private: std::vector& nb, std::vector& ne, int dir = 0); + /** entail non-empty + * + * Checks whether string a is entailed to be non-empty. Is equivalent to + * the call checkArithEntail( len( a ), true ). + */ + static bool checkEntailNonEmpty(Node a); /** check arithmetic entailment equal * Returns true if it is always the case that a = b. */ diff --git a/test/regress/regress0/strings/idof-sem.smt2 b/test/regress/regress0/strings/idof-sem.smt2 index 90dcc83a0..0de8f6a67 100644 --- a/test/regress/regress0/strings/idof-sem.smt2 +++ b/test/regress/regress0/strings/idof-sem.smt2 @@ -1,6 +1,6 @@ (set-logic SLIA) (set-option :strings-exp true) -(set-info :status unsat) +(set-info :status sat) (declare-fun x () String) (assert (not (= (str.indexof x "" 0) (- 1)))) -(check-sat) \ No newline at end of file +(check-sat) diff --git a/test/regress/regress0/strings/repl-rewrites2.smt2 b/test/regress/regress0/strings/repl-rewrites2.smt2 index 42699bc8b..e56a8ea44 100644 --- a/test/regress/regress0/strings/repl-rewrites2.smt2 +++ b/test/regress/regress0/strings/repl-rewrites2.smt2 @@ -5,10 +5,11 @@ (declare-fun x () String) (declare-fun y () String) (assert (or -(not (= (str.replace "" "" "c") "")) +(not (= (str.replace "" "" "c") "c")) (not (= (str.replace (str.++ "abc" y) "b" x) (str.++ "a" x "c" y))) (not (= (str.replace "" "abc" "de") "")) (not (= (str.replace "ab" "ab" "de") "de")) -(not (= (str.replace "ab" "" "de") "ab")) +(not (= (str.replace "ab" "" "de") "deab")) +(not (= (str.replace "abb" "b" "de") "adeb")) )) (check-sat) diff --git a/test/regress/regress1/strings/Makefile.am b/test/regress/regress1/strings/Makefile.am index 493cd5b6d..f6326e0c6 100644 --- a/test/regress/regress1/strings/Makefile.am +++ b/test/regress/regress1/strings/Makefile.am @@ -25,7 +25,6 @@ TESTS = \ bug768.smt2 \ bug799-min.smt2 \ chapman150408.smt2 \ - cmu-disagree-0707-dd.smt2 \ cmu-inc-nlpp-071516.smt2 \ cmu-substr-rw.smt2 \ crash-1019.smt2 \ @@ -73,7 +72,8 @@ TESTS = \ str002.smt2 \ str007.smt2 \ rew-020618.smt2 \ - double-replace.smt2 + double-replace.smt2 \ + string-unsound-sem.smt2 EXTRA_DIST = $(TESTS) diff --git a/test/regress/regress1/strings/cmu-disagree-0707-dd.smt2 b/test/regress/regress1/strings/cmu-disagree-0707-dd.smt2 deleted file mode 100644 index c44dfa396..000000000 --- a/test/regress/regress1/strings/cmu-disagree-0707-dd.smt2 +++ /dev/null @@ -1,22 +0,0 @@ -(set-logic ALL_SUPPORTED) -(set-info :status sat) -(set-option :strings-exp true) - -(declare-fun url () String) - -(assert -(and -(and -(and -(and - -(= (str.len (str.substr (str.substr url (str.indexof url "#" 2) (- (str.len url) (str.indexof url "#" 2))) (+ (str.indexof (str.substr url (str.indexof url "#" 2) (- (str.len url) (str.indexof url "#" 2))) "#" 0) 1) (- (str.len (str.substr url (str.indexof url "#" 2) (- (str.len url) (str.indexof url "#" 2)))) (+ (str.indexof (str.substr url (str.indexof url "#" 2) (- (str.len url) (str.indexof url "#" 2))) "#" 0) 1)))) 0) - -(not (= (str.substr url 0 (- (str.indexof url ":" 0) 0)) "http"))) -(> (str.indexof url ":" 0) 0)) -(>= (- (str.indexof url "#" 2) 2) 0)) -(>= (str.indexof url ":" 0) 0)) -) - -(check-sat) - diff --git a/test/regress/regress1/strings/double-replace.smt2 b/test/regress/regress1/strings/double-replace.smt2 index 0800592d6..bfbc3afc1 100644 --- a/test/regress/regress1/strings/double-replace.smt2 +++ b/test/regress/regress1/strings/double-replace.smt2 @@ -1,7 +1,8 @@ (set-logic SLIA) +(set-option :strings-fmf true) (set-option :strings-exp true) (set-info :status sat) (declare-fun x () String) (declare-fun y () String) (assert (not (= (str.replace (str.replace x y x) x y) x))) -(check-sat) \ No newline at end of file +(check-sat) diff --git a/test/regress/regress1/strings/repl-empty-sem.smt2 b/test/regress/regress1/strings/repl-empty-sem.smt2 index 61f70bc23..56d4f1b86 100644 --- a/test/regress/regress1/strings/repl-empty-sem.smt2 +++ b/test/regress/regress1/strings/repl-empty-sem.smt2 @@ -1,7 +1,7 @@ ; COMMAND-LINE: --strings-exp -; EXPECT: unsat +; EXPECT: sat (set-logic ALL) -(set-info :status unsat) +(set-info :status sat) (declare-fun x () String) (declare-fun z () String) (assert (= (str.len z) 0)) diff --git a/test/regress/regress1/strings/repl-soundness-sem.smt2 b/test/regress/regress1/strings/repl-soundness-sem.smt2 index d56d7945f..f65b3b56a 100644 --- a/test/regress/regress1/strings/repl-soundness-sem.smt2 +++ b/test/regress/regress1/strings/repl-soundness-sem.smt2 @@ -1,7 +1,7 @@ ; COMMAND-LINE: --strings-exp -; EXPECT: sat +; EXPECT: unsat (set-logic ALL) -(set-info :status sat) +(set-info :status unsat) (declare-fun x () String) (declare-fun y () String) (assert (and diff --git a/test/regress/regress1/strings/rew-020618.smt2 b/test/regress/regress1/strings/rew-020618.smt2 index 5fb58a272..95dbf4d29 100644 --- a/test/regress/regress1/strings/rew-020618.smt2 +++ b/test/regress/regress1/strings/rew-020618.smt2 @@ -9,7 +9,7 @@ (= (str.++ s s) "A") (not (str.contains s "")) (str.contains "" (str.++ s "A")) -(not (= (str.replace "A" s "A") "A")) +(not (= (str.replace "A" "" "A") "AA")) (not (= (str.prefixof s "A") (str.suffixof s "A"))) (not (str.prefixof s s)) (not (str.prefixof "" s)) diff --git a/test/regress/regress1/strings/string-unsound-sem.smt2 b/test/regress/regress1/strings/string-unsound-sem.smt2 new file mode 100644 index 000000000..771d8d4b0 --- /dev/null +++ b/test/regress/regress1/strings/string-unsound-sem.smt2 @@ -0,0 +1,12 @@ +(set-logic ALL) +(set-option :strings-exp true) +(set-info :status sat) +(declare-fun x () String) +(declare-fun y () String) +(declare-fun z () Int) +(assert (and +(not (= (str.replace "A" (int.to.str z) x) (str.++ "A" (str.replace "" (int.to.str z) x)))) +(not (= (str.replace x (str.at x z) "") (str.++ (str.replace (str.++ (str.substr x 0 z) (str.substr x z 1)) (str.substr x z 1) "") (str.substr x (+ 1 z) (str.len x))))) +) +) +(check-sat) diff --git a/test/regress/regress2/strings/Makefile.am b/test/regress/regress2/strings/Makefile.am index 9b397699c..4e6f3aa56 100644 --- a/test/regress/regress2/strings/Makefile.am +++ b/test/regress/regress2/strings/Makefile.am @@ -19,7 +19,8 @@ endif TESTS = \ cmu-dis-0707-3.smt2 \ cmu-prereg-fmf.smt2 \ - cmu-repl-len-nterm.smt2 + cmu-repl-len-nterm.smt2 \ + cmu-disagree-0707-dd.smt2 EXTRA_DIST = $(TESTS) \ diff --git a/test/regress/regress2/strings/cmu-disagree-0707-dd.smt2 b/test/regress/regress2/strings/cmu-disagree-0707-dd.smt2 new file mode 100644 index 000000000..c44dfa396 --- /dev/null +++ b/test/regress/regress2/strings/cmu-disagree-0707-dd.smt2 @@ -0,0 +1,22 @@ +(set-logic ALL_SUPPORTED) +(set-info :status sat) +(set-option :strings-exp true) + +(declare-fun url () String) + +(assert +(and +(and +(and +(and + +(= (str.len (str.substr (str.substr url (str.indexof url "#" 2) (- (str.len url) (str.indexof url "#" 2))) (+ (str.indexof (str.substr url (str.indexof url "#" 2) (- (str.len url) (str.indexof url "#" 2))) "#" 0) 1) (- (str.len (str.substr url (str.indexof url "#" 2) (- (str.len url) (str.indexof url "#" 2)))) (+ (str.indexof (str.substr url (str.indexof url "#" 2) (- (str.len url) (str.indexof url "#" 2))) "#" 0) 1)))) 0) + +(not (= (str.substr url 0 (- (str.indexof url ":" 0) 0)) "http"))) +(> (str.indexof url ":" 0) 0)) +(>= (- (str.indexof url "#" 2) 2) 0)) +(>= (str.indexof url ":" 0) 0)) +) + +(check-sat) + -- cgit v1.2.3