Eliminate most static calls to rewrite in quantifiers (#7823)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Thu, 16 Dec 2021 22:16:03 +0000 (16:16 -0600)
committerGitHub <noreply@github.com>
Thu, 16 Dec 2021 22:16:03 +0000 (16:16 -0600)
36 files changed:
src/theory/datatypes/sygus_extension.cpp
src/theory/quantifiers/bv_inverter.cpp
src/theory/quantifiers/bv_inverter.h
src/theory/quantifiers/cegqi/inst_strategy_cegqi.cpp
src/theory/quantifiers/quant_bound_inference.cpp
src/theory/quantifiers/quantifiers_rewriter.cpp
src/theory/quantifiers/single_inv_partition.cpp
src/theory/quantifiers/single_inv_partition.h
src/theory/quantifiers/sygus/ce_guided_single_inv.cpp
src/theory/quantifiers/sygus/cegis.cpp
src/theory/quantifiers/sygus/enum_stream_substitution.cpp
src/theory/quantifiers/sygus/enum_stream_substitution.h
src/theory/quantifiers/sygus/enum_val_generator.h
src/theory/quantifiers/sygus/enum_value_manager.cpp
src/theory/quantifiers/sygus/rcons_type_info.cpp
src/theory/quantifiers/sygus/sygus_enumerator.cpp
src/theory/quantifiers/sygus/sygus_enumerator.h
src/theory/quantifiers/sygus/sygus_enumerator_basic.cpp
src/theory/quantifiers/sygus/sygus_enumerator_basic.h
src/theory/quantifiers/sygus/sygus_enumerator_callback.cpp
src/theory/quantifiers/sygus/sygus_enumerator_callback.h
src/theory/quantifiers/sygus/sygus_eval_unfold.cpp
src/theory/quantifiers/sygus/sygus_grammar_cons.cpp
src/theory/quantifiers/sygus/sygus_grammar_norm.cpp
src/theory/quantifiers/sygus/sygus_grammar_norm.h
src/theory/quantifiers/sygus/sygus_grammar_red.cpp
src/theory/quantifiers/sygus/sygus_grammar_red.h
src/theory/quantifiers/sygus/sygus_invariance.cpp
src/theory/quantifiers/sygus/sygus_invariance.h
src/theory/quantifiers/sygus/sygus_process_conj.cpp
src/theory/quantifiers/sygus/sygus_qe_preproc.cpp
src/theory/quantifiers/sygus/sygus_random_enumerator.cpp
src/theory/quantifiers/sygus/sygus_random_enumerator.h
src/theory/quantifiers/sygus/sygus_unif_io.cpp
src/theory/quantifiers/term_util.cpp
src/theory/quantifiers/term_util.h

index 90511112c1c5e1d0058d5fb0c55032b7b65c2ad9..0318f7da943e3ef965753a2506a5beb9ca98bd8c 100644 (file)
@@ -1052,7 +1052,7 @@ Node SygusExtension::registerSearchValue(Node a,
     Trace("dt-sygus") << "  * DT builtin : " << n << " -> " << bvr << std::endl;
     unsigned sz = utils::getSygusTermSize(nv);
     if( d_tds->involvesDivByZero( bvr ) ){
-      quantifiers::DivByZeroSygusInvarianceTest dbzet;
+      quantifiers::DivByZeroSygusInvarianceTest dbzet(d_env.getRewriter());
       Trace("sygus-sb-mexp-debug") << "Minimize explanation for div-by-zero in "
                                    << bv << std::endl;
       registerSymBreakLemmaForValue(a, nv, dbzet, Node::null(), var_count);
@@ -1161,7 +1161,7 @@ Node SygusExtension::registerSearchValue(Node a,
 
         // generalize the explanation for why the analog of bad_val
         // is equivalent to bvr
-        quantifiers::EquivSygusInvarianceTest eset;
+        quantifiers::EquivSygusInvarianceTest eset(d_env.getRewriter());
         eset.init(d_tds, tn, aconj, a, bvr);
 
         Trace("sygus-sb-mexp-debug") << "Minimize explanation for eval[" << d_tds->sygusToBuiltin( bad_val ) << "] = " << bvr << std::endl;
index cfcc5f5a1fabafaee82b14a9ba599fa193bd735f..75db29207d14e41ff4780eaec915e4e5cd5c9f52 100644 (file)
@@ -31,6 +31,8 @@ namespace cvc5 {
 namespace theory {
 namespace quantifiers {
 
+BvInverter::BvInverter(Rewriter* r) : d_rewriter(r) {}
+
 /*---------------------------------------------------------------------------*/
 
 Node BvInverter::getSolveVariable(TypeNode tn)
@@ -53,12 +55,16 @@ Node BvInverter::getInversionNode(Node cond, TypeNode tn, BvInverterQuery* m)
   TNode solve_var = getSolveVariable(tn);
 
   // condition should be rewritten
-  Node new_cond = Rewriter::rewrite(cond);
-  if (new_cond != cond)
+  Node new_cond = cond;
+  if (d_rewriter != nullptr)
   {
-    Trace("cegqi-bv-skvinv-debug")
-        << "Condition " << cond << " was rewritten to " << new_cond
-        << std::endl;
+    new_cond = d_rewriter->rewrite(cond);
+    if (new_cond != cond)
+    {
+      Trace("cegqi-bv-skvinv-debug")
+          << "Condition " << cond << " was rewritten to " << new_cond
+          << std::endl;
+    }
   }
   // optimization : if condition is ( x = solve_var ) should just return
   // solve_var and not introduce a Skolem this can happen when we ask for
index e840b53de93ebbfce6c41450a70ca8b8b73217a8..835637a306d6c1783d1e0924ba5a9250124d76ae 100644 (file)
@@ -27,6 +27,9 @@
 
 namespace cvc5 {
 namespace theory {
+
+class Rewriter;
+
 namespace quantifiers {
 
 /** BvInverterQuery
@@ -50,7 +53,7 @@ class BvInverterQuery
 class BvInverter
 {
  public:
-  BvInverter() {}
+  BvInverter(Rewriter* r = nullptr);
   ~BvInverter() {}
   /** get dummy fresh variable of type tn, used as argument for sv */
   Node getSolveVariable(TypeNode tn);
@@ -96,9 +99,6 @@ class BvInverter
                   BvInverterQuery* m);
 
  private:
-  /** Dummy variables for each type */
-  std::map<TypeNode, Node> d_solve_var;
-
   /** Helper function for getPathToPv */
   Node getPathToPv(Node lit,
                    Node pv,
@@ -125,6 +125,10 @@ class BvInverter
    * to this call is null.
    */
   Node getInversionNode(Node cond, TypeNode tn, BvInverterQuery* m);
+  /** (Optional) rewriter used as helper in getInversionNode */
+  Rewriter* d_rewriter;
+  /** Dummy variables for each type */
+  std::map<TypeNode, Node> d_solve_var;
 };
 
 }  // namespace quantifiers
index 2555ff6377ade2bd899582b707f543f436fd5188..bbc853ee4da17c72bde2e396ac891295663a4c7f 100644 (file)
@@ -66,7 +66,7 @@ InstStrategyCegqi::InstStrategyCegqi(Env& env,
   if (options().quantifiers.cegqiBv)
   {
     // if doing instantiation for BV, need the inverter class
-    d_bv_invert.reset(new BvInverter);
+    d_bv_invert.reset(new BvInverter(env.getRewriter()));
   }
   if (options().quantifiers.cegqiNestedQE)
   {
index dfffe64cfdace252403311bcb53ab50e4a394796..4094a6638ad457a0d99998043726bd0801e970f0 100644 (file)
@@ -16,7 +16,6 @@
 #include "theory/quantifiers/quant_bound_inference.h"
 
 #include "theory/quantifiers/fmf/bounded_integers.h"
-#include "theory/rewriter.h"
 #include "util/rational.h"
 
 using namespace cvc5::kind;
@@ -60,13 +59,8 @@ bool QuantifiersBoundInference::mayComplete(TypeNode tn, unsigned maxCard)
     Cardinality c = tn.getCardinality();
     if (!c.isLargeFinite())
     {
-      NodeManager* nm = NodeManager::currentNM();
-      Node card = nm->mkConstInt(Rational(c.getFiniteCardinality()));
       // check if less than fixed upper bound
-      Node oth = nm->mkConstInt(Rational(maxCard));
-      Node eq = nm->mkNode(LEQ, card, oth);
-      eq = Rewriter::rewrite(eq);
-      mc = eq.isConst() && eq.getConst<bool>();
+      mc = (c.getFiniteCardinality() < Integer(maxCard));
     }
   }
   return mc;
index c53809d6eb4b755cee4bd580e91fa28b059bbd50..10c0a315bca4705194c5c4ecafea5f1f9b5afe53 100644 (file)
@@ -511,9 +511,9 @@ Node QuantifiersRewriter::computeProcessTerms2(
           {
             // check if it rewrites to a constant
             Node nn = nm->mkNode(EQUAL, no, ret[i][j]);
-            nn = Rewriter::rewrite(nn);
             childrenIte.push_back(nn);
-            if (nn.isConst())
+            // check if it will rewrite to a constant
+            if (no == ret[i][j] || (no.isConst() && ret[i][j].isConst()))
             {
               doRewrite = true;
             }
index 2725e182645181337d2019928a506d08984ed713..8463321dc44a7623c00b7cd8daff46f9b7ec8f69 100644 (file)
@@ -28,6 +28,11 @@ namespace cvc5 {
 namespace theory {
 namespace quantifiers {
 
+SingleInvocationPartition::SingleInvocationPartition(Env& env)
+    : EnvObj(env), d_has_input_funcs(false)
+{
+}
+
 bool SingleInvocationPartition::init(Node n)
 {
   // first, get types of arguments for functions
@@ -220,7 +225,7 @@ bool SingleInvocationPartition::init(std::vector<Node>& funcs,
                                    d_input_funcs.end(),
                                    d_input_func_sks.begin(),
                                    d_input_func_sks.end());
-      cr = TermUtil::getQuantSimplify(cr);
+      cr = getQuantSimplify(cr);
       cr = cr.substitute(d_input_func_sks.begin(),
                          d_input_func_sks.end(),
                          d_input_funcs.begin(),
@@ -614,6 +619,21 @@ void SingleInvocationPartition::debugPrint(const char* c)
   Trace(c) << std::endl;
 }
 
+Node SingleInvocationPartition::getQuantSimplify(TNode n) const
+{
+  std::unordered_set<Node> fvs;
+  expr::getFreeVariables(n, fvs);
+  if (fvs.empty())
+  {
+    return rewrite(n);
+  }
+  std::vector<Node> bvs(fvs.begin(), fvs.end());
+  NodeManager* nm = NodeManager::currentNM();
+  Node q = nm->mkNode(FORALL, nm->mkNode(BOUND_VAR_LIST, bvs), n);
+  q = rewrite(q);
+  return TermUtil::getRemoveQuantifiers(q);
+}
+
 }  // namespace quantifiers
 }  // namespace theory
 }  // namespace cvc5
index 1b4ea62b003ff2ac5b12cdd68ded42be926a81b4..144db934616205cc75a5e75556abbb2672f5f680 100644 (file)
@@ -24,6 +24,7 @@
 #include "expr/node.h"
 #include "expr/subs.h"
 #include "expr/type_node.h"
+#include "smt/env_obj.h"
 
 namespace cvc5 {
 namespace theory {
@@ -56,10 +57,10 @@ namespace quantifiers {
  * see Example 5 of Reynolds et al. SYNT 2017.
  *
  */
-class SingleInvocationPartition
+class SingleInvocationPartition : protected EnvObj
 {
  public:
-  SingleInvocationPartition() : d_has_input_funcs(false) {}
+  SingleInvocationPartition(Env& env);
   ~SingleInvocationPartition() {}
   /** initialize this partition for formula n, with input functions funcs
    *
@@ -289,6 +290,9 @@ class SingleInvocationPartition
 
   /** get the and node corresponding to d_conjuncts[index] */
   Node getConjunct(int index);
+  /** Quantified simplify (treat free variables in n as quantified and run
+   * rewriter) */
+  Node getQuantSimplify(TNode n) const;
 };
 
 }  // namespace quantifiers
index 833abdd222701e327f8934c1f9c8f816e566d624..bcd6ea561c50a0cd37a348081951457c1009d930 100644 (file)
@@ -39,7 +39,7 @@ namespace quantifiers {
 CegSingleInv::CegSingleInv(Env& env, TermRegistry& tr, SygusStatistics& s)
     : EnvObj(env),
       d_isSolved(false),
-      d_sip(new SingleInvocationPartition),
+      d_sip(new SingleInvocationPartition(env)),
       d_srcons(new SygusReconstruct(env, tr.getTermDatabaseSygus(), s)),
       d_single_invocation(false),
       d_treg(tr)
index fdc0b28e07934a5a38bcfb04db53f318d3d621aa..6bb94f41e65af877fd5599c5f14b832c203e1541 100644 (file)
@@ -516,7 +516,7 @@ bool Cegis::getRefinementEvalLemmas(const std::vector<Node>& vs,
       Assert(!lem.isNull());
       std::map<Node, Node> visited;
       std::map<Node, std::vector<Node> > exp;
-      EvalSygusInvarianceTest vsit;
+      EvalSygusInvarianceTest vsit(d_env.getRewriter());
       Trace("sygus-cref-eval") << "Check refinement lemma conjunct " << lem
                                << " against current model." << std::endl;
       Trace("sygus-cref-eval2") << "Check refinement lemma conjunct " << lem
index a5be4ebd6d25a379c16eaeecd9a4d338cbe3e2c1..233d7f17b6d9095610f91f82c87a8bfd5848b262 100644 (file)
@@ -33,8 +33,8 @@ namespace cvc5 {
 namespace theory {
 namespace quantifiers {
 
-EnumStreamPermutation::EnumStreamPermutation(TermDbSygus* tds)
-    : d_tds(tds), d_first(true), d_curr_ind(0)
+EnumStreamPermutation::EnumStreamPermutation(Env& env, TermDbSygus* tds)
+    : EnvObj(env), d_tds(tds), d_first(true), d_curr_ind(0)
 {
 }
 
@@ -125,7 +125,7 @@ Node EnumStreamPermutation::getNext()
   {
     d_first = false;
     Node bultin_value = d_tds->sygusToBuiltin(d_value, d_value.getType());
-    d_perm_values.insert(Rewriter::callExtendedRewrite(bultin_value));
+    d_perm_values.insert(extendedRewrite(bultin_value));
     return d_value;
   }
   unsigned n_classes = d_perm_state_class.size();
@@ -192,9 +192,9 @@ Node EnumStreamPermutation::getNext()
     bultin_perm_value = d_tds->sygusToBuiltin(perm_value, perm_value.getType());
     Trace("synth-stream-concrete-debug")
         << " ......perm builtin is " << bultin_perm_value;
-    if (options::sygusSymBreakDynamic())
+    if (options().datatypes.sygusSymBreakDynamic)
     {
-      bultin_perm_value = Rewriter::callExtendedRewrite(bultin_perm_value);
+      bultin_perm_value = extendedRewrite(bultin_perm_value);
       Trace("synth-stream-concrete-debug")
           << " and rewrites to " << bultin_perm_value;
     }
@@ -327,8 +327,8 @@ bool EnumStreamPermutation::PermutationState::getNextPermutation()
   return true;
 }
 
-EnumStreamSubstitution::EnumStreamSubstitution(quantifiers::TermDbSygus* tds)
-    : d_tds(tds), d_stream_permutations(tds), d_curr_ind(0)
+EnumStreamSubstitution::EnumStreamSubstitution(Env& env, TermDbSygus* tds)
+    : EnvObj(env), d_tds(tds), d_stream_permutations(env, tds), d_curr_ind(0)
 {
 }
 
@@ -512,9 +512,9 @@ Node EnumStreamSubstitution::getNext()
   // construction (unless it's equiv to a constant, e.g. true / false)
   Node builtin_comb_value =
       d_tds->sygusToBuiltin(comb_value, comb_value.getType());
-  if (options::sygusSymBreakDynamic())
+  if (options().datatypes.sygusSymBreakDynamic)
   {
-    builtin_comb_value = Rewriter::callExtendedRewrite(builtin_comb_value);
+    builtin_comb_value = extendedRewrite(builtin_comb_value);
   }
   if (Trace.isOn("synth-stream-concrete"))
   {
@@ -606,6 +606,11 @@ bool EnumStreamSubstitution::CombinationState::getNextCombination()
   return new_comb;
 }
 
+EnumStreamConcrete::EnumStreamConcrete(Env& env, TermDbSygus* tds)
+    : EnumValGenerator(env), d_ess(env, tds)
+{
+}
+
 void EnumStreamConcrete::initialize(Node e) { d_ess.initialize(e.getType()); }
 void EnumStreamConcrete::addValue(Node v)
 {
index 05c693ace11f235c3a9c37ca6daf8156fa96e605..d9161b56f052d6f9ba5c511eacf3cea42ffc9db1 100644 (file)
@@ -19,6 +19,7 @@
 #define CVC5__THEORY__QUANTIFIERS__SYGUS__ENUM_STREAM_SUBSTITUTION_H
 
 #include "expr/node.h"
+#include "smt/env_obj.h"
 #include "theory/quantifiers/sygus/enum_val_generator.h"
 
 namespace cvc5 {
@@ -32,10 +33,10 @@ class TermDbSygus;
  * Generates a new value (modulo rewriting) when queried in which its variables
  * are permuted (see EnumStreamSubstitution for more details).
  */
-class EnumStreamPermutation
+class EnumStreamPermutation : protected EnvObj
 {
  public:
-  EnumStreamPermutation(TermDbSygus* tds);
+  EnumStreamPermutation(Env& env, TermDbSygus* tds);
   ~EnumStreamPermutation() {}
   /** resets utility
    *
@@ -164,10 +165,10 @@ class EnumStreamPermutation
  * Therefore when streaming concrete values, permutations and combinations are
  * generated by the product of the permutations and combinations of each class.
  */
-class EnumStreamSubstitution
+class EnumStreamSubstitution : protected EnvObj
 {
  public:
-  EnumStreamSubstitution(TermDbSygus* tds);
+  EnumStreamSubstitution(Env& env, TermDbSygus* tds);
   ~EnumStreamSubstitution() {}
   /** initializes utility
    *
@@ -283,7 +284,7 @@ class EnumStreamSubstitution
 class EnumStreamConcrete : public EnumValGenerator
 {
  public:
-  EnumStreamConcrete(TermDbSygus* tds) : d_ess(tds) {}
+  EnumStreamConcrete(Env& env, TermDbSygus* tds);
   /** initialize this class with enumerator e */
   void initialize(Node e) override;
   /** get that value v was enumerated */
index 64c0690879a208b259eaa2af7709e3eadeab77c9..ace7cc552045a6e7b0177696c3d78271219a6079 100644 (file)
@@ -19,6 +19,7 @@
 #define CVC5__THEORY__QUANTIFIERS__SYGUS__ENUM_VAL_GENERATOR_H
 
 #include "expr/node.h"
+#include "smt/env_obj.h"
 
 namespace cvc5 {
 namespace theory {
@@ -30,9 +31,10 @@ namespace quantifiers {
  * values" a1, ..., an, ..., and generate a (possibly larger) stream of
  * "concrete values" c11, ..., c1{m_1}, ..., cn1, ... cn{m_n}, ....
  */
-class EnumValGenerator
+class EnumValGenerator : protected EnvObj
 {
  public:
+  EnumValGenerator(Env& env) : EnvObj(env) {}
   virtual ~EnumValGenerator() {}
   /** initialize this class with enumerator e */
   virtual void initialize(Node e) = 0;
index 7fbe1c3cd0dbab8435b3a8a3db682d1bf3bb99c3..b289e984ee50bed2805e0dc0d283a73dbbc4745f 100644 (file)
@@ -82,7 +82,7 @@ Node EnumValueManager::getEnumeratedValue(bool& activeIncomplete)
   {
     if (d_tds->isVariableAgnosticEnumerator(e))
     {
-      d_evg.reset(new EnumStreamConcrete(d_tds));
+      d_evg = std::make_unique<EnumStreamConcrete>(d_env, d_tds);
     }
     else
     {
@@ -93,12 +93,13 @@ Node EnumValueManager::getEnumeratedValue(bool& activeIncomplete)
       if (options().quantifiers.sygusActiveGenMode
           == options::SygusActiveGenMode::ENUM_BASIC)
       {
-        d_evg.reset(new EnumValGeneratorBasic(d_tds, e.getType()));
+        d_evg =
+            std::make_unique<EnumValGeneratorBasic>(d_env, d_tds, e.getType());
       }
       else if (options().quantifiers.sygusActiveGenMode
                == options::SygusActiveGenMode::RANDOM)
       {
-        d_evg.reset(new SygusRandomEnumerator(d_tds));
+        d_evg = std::make_unique<SygusRandomEnumerator>(d_env, d_tds);
       }
       else
       {
@@ -118,17 +119,18 @@ Node EnumValueManager::getEnumeratedValue(bool& activeIncomplete)
             // use the default output for the output of sygusRewVerify
             out = options().base.out;
           }
-          d_secd.reset(new SygusEnumeratorCallbackDefault(
-              e, &d_stats, d_eec.get(), d_samplerRrV.get(), out));
+          d_secd = std::make_unique<SygusEnumeratorCallbackDefault>(
+              d_env, e, &d_stats, d_eec.get(), d_samplerRrV.get(), out);
         }
         // if sygus repair const is enabled, we enumerate terms with free
         // variables as arguments to any-constant constructors
-        d_evg.reset(
-            new SygusEnumerator(d_tds,
-                                d_secd.get(),
-                                &d_stats,
-                                false,
-                                options().quantifiers.sygusRepairConst));
+        d_evg = std::make_unique<SygusEnumerator>(
+            d_env,
+            d_tds,
+            d_secd.get(),
+            &d_stats,
+            false,
+            options().quantifiers.sygusRepairConst);
       }
     }
     Trace("sygus-active-gen")
index 72a8e6a56ce74e0d88e18ebe1000b35b336615fd..20232552a095c0b82fd3a38093730853f16254eb 100644 (file)
@@ -34,7 +34,7 @@ void RConsTypeInfo::initialize(Env& env,
   NodeManager* nm = NodeManager::currentNM();
   SkolemManager* sm = nm->getSkolemManager();
 
-  d_enumerator.reset(new SygusEnumerator(tds, nullptr, &s, true));
+  d_enumerator = std::make_unique<SygusEnumerator>(env, tds, nullptr, &s, true);
   d_enumerator->initialize(sm->mkDummySkolem("sygus_rcons", stn));
   d_crd.reset(new CandidateRewriteDatabase(env, true, false, true, false));
   // since initial samples are not always useful for equivalence checks, set
index 711d390f83d7ad1e54881df7dab95fc5fb7d98d3..b6ee1ca89afd9bf464faeb30ece26a364c89838c 100644 (file)
@@ -33,12 +33,14 @@ namespace cvc5 {
 namespace theory {
 namespace quantifiers {
 
-SygusEnumerator::SygusEnumerator(TermDbSygus* tds,
+SygusEnumerator::SygusEnumerator(Env& env,
+                                 TermDbSygus* tds,
                                  SygusEnumeratorCallback* sec,
                                  SygusStatistics* s,
                                  bool enumShapes,
                                  bool enumAnyConstHoles)
-    : d_tds(tds),
+    : EnumValGenerator(env),
+      d_tds(tds),
       d_sec(sec),
       d_stats(s),
       d_enumShapes(enumShapes),
@@ -55,7 +57,8 @@ void SygusEnumerator::initialize(Node e)
   // allocate the default callback
   if (d_sec == nullptr && options::sygusSymBreakDynamic())
   {
-    d_secd.reset(new SygusEnumeratorCallbackDefault(e, d_stats));
+    d_secd =
+        std::make_unique<SygusEnumeratorCallbackDefault>(d_env, e, d_stats);
     d_sec = d_secd.get();
   }
   d_etype = d_enum.getType();
@@ -88,7 +91,7 @@ void SygusEnumerator::initialize(Node e)
     {
       // substitute its active guard by true and rewrite
       Node slem = lem.substitute(agt, truent);
-      slem = Rewriter::rewrite(slem);
+      slem = rewrite(slem);
       // break into conjuncts
       std::vector<Node> sblc;
       if (slem.getKind() == AND)
index 612a753af8c25d2c6d5baa985b28d34ddee0e9eb..594cde97f0aea0114bcc37aa76855457a62cc5ee 100644 (file)
@@ -59,6 +59,7 @@ class SygusEnumerator : public EnumValGenerator
 {
  public:
   /**
+   * @param env Reference to the environment
    * @param tds Pointer to the term database, required if enumShapes or
    * enumAnyConstHoles is true, or if we want to include symmetry breaking from
    * lemmas stored in the sygus term database,
@@ -70,7 +71,8 @@ class SygusEnumerator : public EnumValGenerator
    * @param enumAnyConstHoles If true, this enumerator will generate terms where
    * free variables are the arguments to any-constant constructors.
    */
-  SygusEnumerator(TermDbSygus* tds = nullptr,
+  SygusEnumerator(Env& env,
+                  TermDbSygus* tds = nullptr,
                   SygusEnumeratorCallback* sec = nullptr,
                   SygusStatistics* s = nullptr,
                   bool enumShapes = false,
index 743f67cec3696dcb080f9440983c38c0262aa04b..b9578a66abfc1611c175a69da0f759f9a4a3cf58 100644 (file)
@@ -24,8 +24,10 @@ namespace cvc5 {
 namespace theory {
 namespace quantifiers {
 
-EnumValGeneratorBasic::EnumValGeneratorBasic(TermDbSygus* tds, TypeNode tn)
-    : d_tds(tds), d_te(tn)
+EnumValGeneratorBasic::EnumValGeneratorBasic(Env& env,
+                                             TermDbSygus* tds,
+                                             TypeNode tn)
+    : EnumValGenerator(env), d_tds(tds), d_te(tn)
 {
 }
 
@@ -38,10 +40,10 @@ bool EnumValGeneratorBasic::increment()
     return false;
   }
   d_currTerm = *d_te;
-  if (options::sygusSymBreakDynamic())
+  if (options().datatypes.sygusSymBreakDynamic)
   {
     Node nextb = d_tds->sygusToBuiltin(d_currTerm);
-    nextb = Rewriter::callExtendedRewrite(nextb);
+    nextb = extendedRewrite(nextb);
     if (d_cache.find(nextb) == d_cache.end())
     {
       d_cache.insert(nextb);
index 42bce471dbbf8016262dfa31338c3bdcda376efc..543598a90043ffdde7936d8a177f1e8b01e356cb 100644 (file)
@@ -39,7 +39,7 @@ namespace quantifiers {
 class EnumValGeneratorBasic : public EnumValGenerator
 {
  public:
-  EnumValGeneratorBasic(TermDbSygus* tds, TypeNode tn);
+  EnumValGeneratorBasic(Env& env, TermDbSygus* tds, TypeNode tn);
   ~EnumValGeneratorBasic() {}
   /** initialize (do nothing) */
   void initialize(Node e) override {}
index 1170eee82f9b0819424474dc301df3604de1e320..bde1fdd67f59fc7a667141cd243576baac7aba41 100644 (file)
@@ -25,8 +25,10 @@ namespace cvc5 {
 namespace theory {
 namespace quantifiers {
 
-SygusEnumeratorCallback::SygusEnumeratorCallback(Node e, SygusStatistics* s)
-    : d_enum(e), d_stats(s)
+SygusEnumeratorCallback::SygusEnumeratorCallback(Env& env,
+                                                 Node e,
+                                                 SygusStatistics* s)
+    : EnvObj(env), d_enum(e), d_stats(s)
 {
   d_tn = e.getType();
 }
@@ -34,7 +36,7 @@ SygusEnumeratorCallback::SygusEnumeratorCallback(Node e, SygusStatistics* s)
 bool SygusEnumeratorCallback::addTerm(Node n, std::unordered_set<Node>& bterms)
 {
   Node bn = datatypes::utils::sygusToBuiltin(n);
-  Node bnr = Rewriter::callExtendedRewrite(bn);
+  Node bnr = extendedRewrite(bn);
   if (d_stats != nullptr)
   {
     ++(d_stats->d_enumTermsRewrite);
@@ -62,12 +64,16 @@ bool SygusEnumeratorCallback::addTerm(Node n, std::unordered_set<Node>& bterms)
 }
 
 SygusEnumeratorCallbackDefault::SygusEnumeratorCallbackDefault(
+    Env& env,
     Node e,
     SygusStatistics* s,
     ExampleEvalCache* eec,
     SygusSampler* ssrv,
     std::ostream* out)
-    : SygusEnumeratorCallback(e, s), d_eec(eec), d_samplerRrV(ssrv), d_out(out)
+    : SygusEnumeratorCallback(env, e, s),
+      d_eec(eec),
+      d_samplerRrV(ssrv),
+      d_out(out)
 {
 }
 void SygusEnumeratorCallbackDefault::notifyTermInternal(Node n,
index 8689d876fbf718fb0af03c7e7842d79f16f79f3e..9b7c3fd98ba9cc57e7b5ccaaed4de09c829ab9fd 100644 (file)
@@ -21,6 +21,7 @@
 #include <unordered_set>
 
 #include "expr/node.h"
+#include "smt/env_obj.h"
 #include "theory/quantifiers/extended_rewrite.h"
 
 namespace cvc5 {
@@ -36,10 +37,10 @@ class SygusSampler;
  * provide custom criteria for whether or not enumerated values should be
  * considered.
  */
-class SygusEnumeratorCallback
+class SygusEnumeratorCallback : protected EnvObj
 {
  public:
-  SygusEnumeratorCallback(Node e, SygusStatistics* s = nullptr);
+  SygusEnumeratorCallback(Env& env, Node e, SygusStatistics* s = nullptr);
   virtual ~SygusEnumeratorCallback() {}
   /**
    * Add term, return true if the term should be considered in the enumeration.
@@ -81,7 +82,8 @@ class SygusEnumeratorCallback
 class SygusEnumeratorCallbackDefault : public SygusEnumeratorCallback
 {
  public:
-  SygusEnumeratorCallbackDefault(Node e,
+  SygusEnumeratorCallbackDefault(Env& env,
+                                 Node e,
                                  SygusStatistics* s = nullptr,
                                  ExampleEvalCache* eec = nullptr,
                                  SygusSampler* ssrv = nullptr,
index 388a4d31f76586be5d23e313df55f066a42693ca..d24ad25b241915c44502594273d8c17213cfef36 100644 (file)
@@ -177,7 +177,7 @@ void SygusEvalUnfold::registerModelValue(Node a,
         }
         else
         {
-          EvalSygusInvarianceTest esit;
+          EvalSygusInvarianceTest esit(d_env.getRewriter());
           eval_children.insert(
               eval_children.end(), it->second[i].begin(), it->second[i].end());
           Node conj = nm->mkNode(DT_SYGUS_EVAL, eval_children);
index 7227b71848473b1a1654701847770e6d3d451712..a783ce2cac09b9ed90c85906ad688bbe288c9e22 100644 (file)
@@ -153,7 +153,7 @@ Node CegGrammarConstructor::process(Node q,
       sfvl = preGrammarType.getDType().getSygusVarList();
       tn = preGrammarType;
       // normalize type, if user-provided
-      SygusGrammarNorm sygus_norm(d_tds);
+      SygusGrammarNorm sygus_norm(d_env, d_tds);
       tn = sygus_norm.normalizeSygusType(tn, sfvl);
     }else{
       sfvl = SygusUtils::getSygusArgumentListForSynthFun(sf);
@@ -1232,7 +1232,6 @@ void CegGrammarConstructor::mkSygusDefaultGrammar(
         // Do beta reduction on the operator so that its arguments match the
         // fresh variables of the lambda (op) we are constructing below.
         sop = datatypes::utils::mkSygusTerm(sop, opLArgs);
-        sop = Rewriter::rewrite(sop);
       }
       opCArgs.push_back(unresAnyConst);
       Node coeff = nm->mkBoundVar(types[i]);
index 209d10297a24839eb58fc976de364814f1dacf79..cf7b71104c62156cbdc3598622a96f175b22195d 100644 (file)
@@ -69,7 +69,10 @@ bool OpPosTrie::getOrMakeType(TypeNode tn,
   return d_children[op_pos[ind]].getOrMakeType(tn, unres_tn, op_pos, ind + 1);
 }
 
-SygusGrammarNorm::SygusGrammarNorm(TermDbSygus* tds) : d_tds(tds) {}
+SygusGrammarNorm::SygusGrammarNorm(Env& env, TermDbSygus* tds)
+    : EnvObj(env), d_tds(tds)
+{
+}
 
 SygusGrammarNorm::TypeObject::TypeObject(TypeNode src_tn, TypeNode unres_tn)
     : d_tn(src_tn),
@@ -282,9 +285,10 @@ std::unique_ptr<SygusGrammarNorm::Transf> SygusGrammarNorm::inferTransf(
   Trace("sygus-gnorm") << "  #cons = " << op_pos.size() << " / "
                        << dt.getNumConstructors() << std::endl;
   // look for redundant constructors to drop
-  if (options::sygusMinGrammar() && dt.getNumConstructors() == op_pos.size())
+  if (options().quantifiers.sygusMinGrammar
+      && dt.getNumConstructors() == op_pos.size())
   {
-    SygusRedundantCons src;
+    SygusRedundantCons src(d_env);
     src.initialize(d_tds, tn);
     std::vector<unsigned> rindices;
     src.getRedundant(rindices);
index f1d8e01e0983cba7b4528926cc13a15dd4bd1f53..cdaf97487db855b2ac1da8a20dbeb54835e78782 100644 (file)
@@ -24,6 +24,7 @@
 #include "expr/node.h"
 #include "expr/sygus_datatype.h"
 #include "expr/type_node.h"
+#include "smt/env_obj.h"
 
 namespace cvc5 {
 namespace theory {
@@ -123,10 +124,10 @@ class OpPosTrie
  * These lighweight transformations are always applied, independently of the
  * normalization option being enabled.
  */
-class SygusGrammarNorm
+class SygusGrammarNorm : protected EnvObj
 {
  public:
-  SygusGrammarNorm(TermDbSygus* tds);
+  SygusGrammarNorm(Env& env, TermDbSygus* tds);
   ~SygusGrammarNorm() {}
   /** creates a normalized typenode from a given one.
    *
index fd84f0c0aedfa1d81e0956d1979ca3375d2ee0ae..a8ff038de135732c7608fec911d72b68ff49ad7c 100644 (file)
@@ -148,7 +148,7 @@ void SygusRedundantCons::getGenericList(TermDbSygus* tds,
   if (index == dt[c].getNumArgs())
   {
     Node gt = tds->mkGeneric(dt, c, pre);
-    gt = Rewriter::callExtendedRewrite(gt);
+    gt = extendedRewrite(gt);
     terms.push_back(gt);
     return;
   }
index 2146e1f73f94a897a2f40b5f744b9d51db7f668a..018bc8fe6b96c0c92f0e0e46fc2de2f6b0623162 100644 (file)
@@ -22,6 +22,7 @@
 #include <vector>
 
 #include "expr/node.h"
+#include "smt/env_obj.h"
 
 namespace cvc5 {
 namespace theory {
@@ -36,10 +37,10 @@ class TermDbSygus;
  * where tn is a sygus tn. Then, use getRedundant and/or isRedundant to get the
  * indicies of the constructors of tn that are redundant.
  */
-class SygusRedundantCons
+class SygusRedundantCons : protected EnvObj
 {
  public:
-  SygusRedundantCons() {}
+  SygusRedundantCons(Env& env) : EnvObj(env) {}
   ~SygusRedundantCons() {}
   /** register type tn
    *
index 8048330e4cb247d2f02901678c3f7b946d45887c..b35b23c9008d52f1f1ca73f3306cb01014ade68c 100644 (file)
@@ -106,7 +106,7 @@ bool EquivSygusInvarianceTest::invariant(TermDbSygus* tds, Node nvn, Node x)
 {
   TypeNode tn = nvn.getType();
   Node nbv = tds->sygusToBuiltin(nvn, tn);
-  Node nbvr = Rewriter::callExtendedRewrite(nbv);
+  Node nbvr = d_rewriter->extendedRewrite(nbv);
   Trace("sygus-sb-mexp-debug") << "  min-exp check : " << nbv << " -> " << nbvr
                                << std::endl;
   bool exc_arg = false;
@@ -176,7 +176,7 @@ bool DivByZeroSygusInvarianceTest::invariant(TermDbSygus* tds, Node nvn, Node x)
 {
   TypeNode tn = nvn.getType();
   Node nbv = tds->sygusToBuiltin(nvn, tn);
-  Node nbvr = Rewriter::callExtendedRewrite(nbv);
+  Node nbvr = d_rewriter->extendedRewrite(nbv);
   if (tds->involvesDivByZero(nbvr))
   {
     Trace("sygus-sb-mexp") << "sb-min-exp : " << tds->sygusToBuiltin(nvn)
@@ -207,7 +207,7 @@ bool NegContainsSygusInvarianceTest::invariant(TermDbSygus* tds,
   {
     TypeNode tn = nvn.getType();
     Node nbv = tds->sygusToBuiltin(nvn, tn);
-    Node nbvr = Rewriter::callExtendedRewrite(nbv);
+    Node nbvr = d_rewriter->extendedRewrite(nbv);
     // if for any of the examples, it is not contained, then we can exclude
     for (unsigned i = 0; i < d_neg_con_indices.size(); i++)
     {
@@ -218,7 +218,7 @@ bool NegContainsSygusInvarianceTest::invariant(TermDbSygus* tds,
       Node cont =
           NodeManager::currentNM()->mkNode(kind::STRING_CONTAINS, out, nbvre);
       Trace("sygus-pbe-cterm-debug") << "Check: " << cont << std::endl;
-      Node contr = Rewriter::rewrite(cont);
+      Node contr = d_rewriter->extendedRewrite(cont);
       if (!contr.isConst())
       {
         if (d_isUniversal)
index afb59bf73263be720408199f3a4436e1a33a6952..16abc541d31991974c06158bd9f30129a0250440 100644 (file)
@@ -25,6 +25,9 @@
 
 namespace cvc5 {
 namespace theory {
+
+class Rewriter;
+
 namespace quantifiers {
 
 class TermDbSygus;
@@ -44,6 +47,7 @@ class SynthConjecture;
 class SygusInvarianceTest
 {
  public:
+  SygusInvarianceTest(Rewriter* r) : d_rewriter(r) {}
   virtual ~SygusInvarianceTest() {}
 
   /** Is nvn invariant with respect to this test ?
@@ -69,6 +73,8 @@ class SygusInvarianceTest
   /** set updated term */
   void setUpdatedTerm(Node n) { d_update_nvn = n; }
  protected:
+  /** Pointer to the rewriter */
+  Rewriter* d_rewriter;
   /** result of the node that satisfies this invariant */
   Node d_update_nvn;
   /** check whether nvn[ x ] is invariant */
@@ -98,8 +104,10 @@ class SygusInvarianceTest
 class EvalSygusInvarianceTest : public SygusInvarianceTest
 {
  public:
-  EvalSygusInvarianceTest()
-      : d_kind(kind::UNDEFINED_KIND), d_is_conjunctive(false)
+  EvalSygusInvarianceTest(Rewriter* r)
+      : SygusInvarianceTest(r),
+        d_kind(kind::UNDEFINED_KIND),
+        d_is_conjunctive(false)
   {
   }
 
@@ -168,7 +176,10 @@ class EvalSygusInvarianceTest : public SygusInvarianceTest
 class EquivSygusInvarianceTest : public SygusInvarianceTest
 {
  public:
-  EquivSygusInvarianceTest() : d_conj(nullptr) {}
+  EquivSygusInvarianceTest(Rewriter* r)
+      : SygusInvarianceTest(r), d_conj(nullptr)
+  {
+  }
 
   /** initialize this invariance test
    * tn is the sygus type for e
@@ -209,7 +220,7 @@ class EquivSygusInvarianceTest : public SygusInvarianceTest
 class DivByZeroSygusInvarianceTest : public SygusInvarianceTest
 {
  public:
-  DivByZeroSygusInvarianceTest() {}
+  DivByZeroSygusInvarianceTest(Rewriter* r) : SygusInvarianceTest(r) {}
 
  protected:
   /** checks whether nvn involves division by zero. */
@@ -245,7 +256,10 @@ class DivByZeroSygusInvarianceTest : public SygusInvarianceTest
 class NegContainsSygusInvarianceTest : public SygusInvarianceTest
 {
  public:
-  NegContainsSygusInvarianceTest() : d_isUniversal(false) {}
+  NegContainsSygusInvarianceTest(Rewriter* r)
+      : SygusInvarianceTest(r), d_isUniversal(false)
+  {
+  }
 
   /** initialize this invariance test
    *  e is the enumerator which we are reasoning about (associated with a synth
index a1f1975962d9cfc047bd25caac1816db8fa07721..18845665c23f8d9f3d4e14987482cd7524ee3396 100644 (file)
@@ -69,8 +69,8 @@ bool SynthConjectureProcessFun::checkMatch(
   }
   Node cn_subs =
       cn.substitute(vars.begin(), vars.end(), subs.begin(), subs.end());
-  cn_subs = Rewriter::rewrite(cn_subs);
-  n = Rewriter::rewrite(n);
+  cn_subs = rewrite(cn_subs);
+  n = rewrite(n);
   return cn_subs == n;
 }
 
index 2400e0e56757e846222f4e373a34adb7494ad7ab..b57c65f0fa47f5753f039a691446d7b12f9b1146 100644 (file)
@@ -39,7 +39,7 @@ Node SygusQePreproc::preprocess(Node q)
   SkolemManager* sm = nm->getSkolemManager();
   Trace("cegqi-qep") << "Compute single invocation for " << q << "..."
                      << std::endl;
-  quantifiers::SingleInvocationPartition sip;
+  quantifiers::SingleInvocationPartition sip(d_env);
   std::vector<Node> funcs0;
   funcs0.insert(funcs0.end(), q[0].begin(), q[0].end());
   sip.init(funcs0, body);
index bf051a897c18037ffc8799843ad0f23f5dd7385d..0711b44ae99aded190decddfc8e3a46f2ca7559c 100644 (file)
@@ -62,7 +62,7 @@ bool SygusRandomEnumerator::increment()
     // Generate the next sygus term.
     n = incrementH();
     bn = d_tds->sygusToBuiltin(n);
-    bn = Rewriter::callExtendedRewrite(bn);
+    bn = extendedRewrite(bn);
     // Ensure that the builtin counterpart is unique (up to rewriting).
   } while (d_cache.find(bn) != d_cache.cend());
   d_cache.insert(bn);
@@ -174,7 +174,7 @@ Node SygusRandomEnumerator::getMin(Node n)
 {
   TypeNode tn = n.getType();
   Node bn = d_tds->sygusToBuiltin(n);
-  bn = Rewriter::callExtendedRewrite(bn);
+  bn = extendedRewrite(bn);
   // Did we calculate the size of `n` before?
   if (d_size.find(n) == d_size.cend())
   {
index b70fe94907243fa81d32eabeadec2fec57ec2946..79fc0a090f8688b77e8dc69eff6581321efa27c6 100644 (file)
@@ -50,7 +50,10 @@ class SygusRandomEnumerator : public EnumValGenerator
    *
    * @param tds pointer to term database sygus.
    */
-  SygusRandomEnumerator(TermDbSygus* tds) : d_tds(tds){};
+  SygusRandomEnumerator(Env& env, TermDbSygus* tds)
+      : EnumValGenerator(env), d_tds(tds)
+  {
+  }
 
   /** Initialize this class with enumerator `e`. */
   void initialize(Node e) override;
index 7aa952600083b58409ee2697db6cde006eef6b21..2144b324ce03f3bcd0e5215a80ce7650a2186e92 100644 (file)
@@ -974,7 +974,7 @@ bool SygusUnifIo::getExplanationForEnumeratorExclude(
     if (!cmp_indices.empty())
     {
       // we check invariance with respect to a negative contains test
-      NegContainsSygusInvarianceTest ncset;
+      NegContainsSygusInvarianceTest ncset(d_env.getRewriter());
       if (isConditional)
       {
         ncset.setUniversal();
index 18f9ec7e234bf9414622b419facba6ee121861fb..4f386c0085fa4f1e8fc5a846b45e2bff18021b50 100644 (file)
@@ -123,22 +123,6 @@ Node TermUtil::getRemoveQuantifiers( Node n ) {
   return getRemoveQuantifiers2( n, visited );
 }
 
-//quantified simplify
-Node TermUtil::getQuantSimplify( Node n ) {
-  std::unordered_set<Node> fvs;
-  expr::getFreeVariables(n, fvs);
-  if (fvs.empty())
-  {
-    return Rewriter::rewrite( n );
-  }
-  std::vector<Node> bvs;
-  bvs.insert(bvs.end(), fvs.begin(), fvs.end());
-  NodeManager* nm = NodeManager::currentNM();
-  Node q = nm->mkNode(FORALL, nm->mkNode(BOUND_VAR_LIST, bvs), n);
-  q = Rewriter::rewrite(q);
-  return getRemoveQuantifiers(q);
-}
-
 void TermUtil::computeInstConstContains(Node n, std::vector<Node>& ics)
 {
   computeVarContainsInternal(n, INST_CONSTANT, ics);
@@ -377,22 +361,22 @@ Node TermUtil::mkTypeValueOffset(TypeNode tn,
                                  int32_t offset,
                                  int32_t& status)
 {
+  Assert(val.isConst() && val.getType() == tn);
   Node val_o;
-  Node offset_val = mkTypeValue(tn, offset);
   status = -1;
-  if (!offset_val.isNull())
+  if (tn.isRealOrInt())
   {
-    if (tn.isRealOrInt())
-    {
-      val_o = Rewriter::rewrite(
-          NodeManager::currentNM()->mkNode(PLUS, val, offset_val));
-      status = 0;
-    }
-    else if (tn.isBitVector())
-    {
-      val_o = Rewriter::rewrite(
-          NodeManager::currentNM()->mkNode(BITVECTOR_ADD, val, offset_val));
-    }
+    Rational vval = val.getConst<Rational>();
+    Rational oval(offset);
+    status = 0;
+    return NodeManager::currentNM()->mkConstRealOrInt(tn, vval + oval);
+  }
+  else if (tn.isBitVector())
+  {
+    BitVector vval = val.getConst<BitVector>();
+    uint32_t uv = static_cast<uint32_t>(offset);
+    BitVector oval(tn.getConst<BitVectorSize>(), uv);
+    return NodeManager::currentNM()->mkConst(vval + oval);
   }
   return val_o;
 }
index fb664dab558e000b6357d68f0d8338f13848ce27..277ce03fcd500f2d6e3a3ae62e4dd305df8a7776 100644 (file)
@@ -78,8 +78,6 @@ private:
 public:
   //remove quantifiers
   static Node getRemoveQuantifiers( Node n );
-  //quantified simplify (treat free variables in n as quantified and run rewriter)
-  static Node getQuantSimplify( Node n );
 
  private:
   /** adds the set of nodes of kind k in n to vars */