Simplify how user-provided quantifier attributes are handled (#6963)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Fri, 20 Aug 2021 21:08:52 +0000 (16:08 -0500)
committerGitHub <noreply@github.com>
Fri, 20 Aug 2021 21:08:52 +0000 (21:08 +0000)
This makes INST_ATTRIBUTE (optionally) take multiple children, giving a way for the user to set attributes on quantified formulas, which does not require a new API command.

This is a special case of term annotations that occur as the body of a quantified formula.

If we need to extend our API to support further user-provided attributes, we should use a similar approach, e.g. a new kind ANNOTATE.

19 files changed:
src/api/cpp/cvc5_kind.h
src/parser/smt2/Smt2.g
src/smt/command.cpp
src/smt/command.h
src/smt/quant_elim_solver.cpp
src/smt/smt_engine.cpp
src/smt/smt_engine.h
src/theory/engine_output_channel.cpp
src/theory/engine_output_channel.h
src/theory/quantifiers/kinds
src/theory/quantifiers/quantifiers_attributes.cpp
src/theory/quantifiers/quantifiers_attributes.h
src/theory/quantifiers/theory_quantifiers.cpp
src/theory/quantifiers/theory_quantifiers.h
src/theory/quantifiers/theory_quantifiers_type_rules.cpp
src/theory/theory.h
src/theory/theory_engine.cpp
src/theory/theory_engine.h
test/unit/test_smt.h

index 2c5d2873e695156da4ceaa5d1485db848f4046af..e8b876b55ba8b2f1a34d6ad5c6f01ce504d88a1c 100644 (file)
@@ -3348,11 +3348,14 @@ enum CVC5_EXPORT Kind : int32_t
    * Specifies a custom property for a quantified formula given by a
    * term that is ascribed a user attribute.
    *
-   * Parameters:
-   *   - 1: Term with a user attribute.
+   * Parameters: n >= 1
+   *   - 1: The keyword of the attribute (a term with kind CONST_STRING).
+   *   - 2...n: The values of the attribute.
    *
    * Create with:
-   *   - `Solver::mkTerm(Kind kind, const Term& child) const`
+   *   - `mkTerm(Kind kind, Term child1, Term child2)
+   *   - `mkTerm(Kind kind, Term child1, Term child2, Term child3)
+   *   - `mkTerm(Kind kind, const std::vector<Term>& children)
    */
   INST_ATTRIBUTE,
   /**
index 577aeb0a9bc7f6f61c8df885e43ca5b7a3e5b406..c3cf3ea667c25b88eb781befb612542fda817f4c 100644 (file)
@@ -1815,26 +1815,15 @@ attribute[cvc5::api::Term& expr, cvc5::api::Term& retExpr]
     {
       std::stringstream sIntLit;
       sIntLit << $INTEGER_LITERAL;
+      api::Term keyword = SOLVER->mkString("quant-inst-max-level");
       api::Term n = SOLVER->mkInteger(sIntLit.str());
-      std::vector<api::Term> values;
-      values.push_back( n );
-      std::string attr_name(AntlrInput::tokenText($tok));
-      attr_name.erase( attr_name.begin() );
-      api::Sort boolType = SOLVER->getBooleanSort();
-      api::Term avar = PARSER_STATE->bindVar(attr_name, boolType);
-      retExpr = MK_TERM(api::INST_ATTRIBUTE, avar);
-      Command* c = new SetUserAttributeCommand(attr_name, avar, values);
-      c->setMuted(true);
-      PARSER_STATE->preemptCommand(c);
+      retExpr = MK_TERM(api::INST_ATTRIBUTE, keyword, n);
     }
   | tok=( ATTRIBUTE_QUANTIFIER_ID_TOK ) symbolicExpr[sexpr]
     {
-      api::Sort boolType = SOLVER->getBooleanSort();
-      api::Term avar = SOLVER->mkConst(boolType, sexprToString(sexpr));
-      retExpr = MK_TERM(api::INST_ATTRIBUTE, avar);
-      Command* c = new SetUserAttributeCommand("qid", avar);
-      c->setMuted(true);
-      PARSER_STATE->preemptCommand(c);
+      api::Term keyword = SOLVER->mkString("qid");
+      api::Term name = SOLVER->mkString(sexprToString(sexpr));
+      retExpr = MK_TERM(api::INST_ATTRIBUTE, keyword, name);
     }
   | ATTRIBUTE_NAMED_TOK symbolicExpr[sexpr]
     {
index 7aa05dde1bc09d72c780a156a612d2e904fc655b..1981f106395e2b417eac9a7f7f3ee2d941a4dd25 100644 (file)
@@ -1530,78 +1530,6 @@ void DeclareHeapCommand::toStream(std::ostream& out,
       out, sortToTypeNode(d_locSort), sortToTypeNode(d_dataSort));
 }
 
-/* -------------------------------------------------------------------------- */
-/* class SetUserAttributeCommand                                              */
-/* -------------------------------------------------------------------------- */
-
-SetUserAttributeCommand::SetUserAttributeCommand(
-    const std::string& attr,
-    api::Term term,
-    const std::vector<api::Term>& termValues,
-    const std::string& strValue)
-    : d_attr(attr), d_term(term), d_termValues(termValues), d_strValue(strValue)
-{
-}
-
-SetUserAttributeCommand::SetUserAttributeCommand(const std::string& attr,
-                                                 api::Term term)
-    : SetUserAttributeCommand(attr, term, {}, "")
-{
-}
-
-SetUserAttributeCommand::SetUserAttributeCommand(
-    const std::string& attr,
-    api::Term term,
-    const std::vector<api::Term>& values)
-    : SetUserAttributeCommand(attr, term, values, "")
-{
-}
-
-SetUserAttributeCommand::SetUserAttributeCommand(const std::string& attr,
-                                                 api::Term term,
-                                                 const std::string& value)
-    : SetUserAttributeCommand(attr, term, {}, value)
-{
-}
-
-void SetUserAttributeCommand::invoke(api::Solver* solver, SymbolManager* sm)
-{
-  try
-  {
-    if (!d_term.isNull())
-    {
-      solver->getSmtEngine()->setUserAttribute(d_attr,
-                                               termToNode(d_term),
-                                               termVectorToNodes(d_termValues),
-                                               d_strValue);
-    }
-    d_commandStatus = CommandSuccess::instance();
-  }
-  catch (exception& e)
-  {
-    d_commandStatus = new CommandFailure(e.what());
-  }
-}
-
-Command* SetUserAttributeCommand::clone() const
-{
-  return new SetUserAttributeCommand(d_attr, d_term, d_termValues, d_strValue);
-}
-
-std::string SetUserAttributeCommand::getCommandName() const
-{
-  return "set-user-attribute";
-}
-
-void SetUserAttributeCommand::toStream(std::ostream& out,
-                                       int toDepth,
-                                       size_t dag,
-                                       OutputLanguage language) const
-{
-  Printer::getPrinter(language)->toStreamCmdSetUserAttribute(
-      out, d_attr, termToNode(d_term));
-}
-
 /* -------------------------------------------------------------------------- */
 /* class SimplifyCommand                                                      */
 /* -------------------------------------------------------------------------- */
index 5a67e66854a18b8b46409842531c0b87a6dff775..b83da58256a07e16fe6a0af1de3b0adf8adca0a6 100644 (file)
@@ -615,42 +615,6 @@ class CVC5_EXPORT DeclareHeapCommand : public Command
   api::Sort d_dataSort;
 };
 
-/**
- * The command when an attribute is set by a user.  In SMT-LIBv2 this is done
- *  via the syntax (! expr :attr)
- */
-class CVC5_EXPORT SetUserAttributeCommand : public Command
-{
- public:
-  SetUserAttributeCommand(const std::string& attr, api::Term term);
-  SetUserAttributeCommand(const std::string& attr,
-                          api::Term term,
-                          const std::vector<api::Term>& values);
-  SetUserAttributeCommand(const std::string& attr,
-                          api::Term term,
-                          const std::string& value);
-
-  void invoke(api::Solver* solver, SymbolManager* sm) override;
-  Command* clone() const override;
-  std::string getCommandName() const override;
-  void toStream(
-      std::ostream& out,
-      int toDepth = -1,
-      size_t dag = 1,
-      OutputLanguage language = language::output::LANG_AUTO) const override;
-
- private:
-  SetUserAttributeCommand(const std::string& attr,
-                          api::Term term,
-                          const std::vector<api::Term>& termValues,
-                          const std::string& strValue);
-
-  const std::string d_attr;
-  const api::Term d_term;
-  const std::vector<api::Term> d_termValues;
-  const std::string d_strValue;
-}; /* class SetUserAttributeCommand */
-
 /**
  * The command when parsing check-sat.
  * This command will check satisfiability of the input formula.
@@ -1000,9 +964,6 @@ class CVC5_EXPORT GetModelCommand : public Command
 {
  public:
   GetModelCommand();
-
-  // Model is private to the library -- for now
-  // Model* getResult() const ;
   void invoke(api::Solver* solver, SymbolManager* sm) override;
   void printResult(std::ostream& out, uint32_t verbosity = 2) const override;
   Command* clone() const override;
index 185a60e46252055c6e4a6ba6e1714dd9b2e1bf17..e675feaa0a2cfe94b34e6a2191d97693089584fa 100644 (file)
@@ -24,6 +24,7 @@
 #include "theory/quantifiers_engine.h"
 #include "theory/rewriter.h"
 #include "theory/theory_engine.h"
+#include "util/string.h"
 
 using namespace cvc5::theory;
 using namespace cvc5::kind;
@@ -47,7 +48,6 @@ Node QuantElimSolver::getQuantifierElimination(Assertions& as,
         "Expecting a quantified formula as argument to get-qe.");
   }
   NodeManager* nm = NodeManager::currentNM();
-  SkolemManager* sm = nm->getSkolemManager();
   // ensure the body is rewritten
   q = nm->mkNode(q.getKind(), q[0], Rewriter::rewrite(q[1]));
   // do nested quantifier elimination if necessary
@@ -56,14 +56,11 @@ Node QuantElimSolver::getQuantifierElimination(Assertions& as,
                   << q << std::endl;
   // tag the quantified formula with the quant-elim attribute
   TypeNode t = nm->booleanType();
-  Node n_attr = sm->mkDummySkolem("qe", t, "Auxiliary variable for qe attr.");
-  std::vector<Node> node_values;
   TheoryEngine* te = d_smtSolver.getTheoryEngine();
   Assert(te != nullptr);
-  te->setUserAttribute(
-      doFull ? "quant-elim" : "quant-elim-partial", n_attr, node_values, "");
-  QuantifiersEngine* qe = te->getQuantifiersEngine();
-  n_attr = nm->mkNode(INST_ATTRIBUTE, n_attr);
+  Node keyword =
+      nm->mkConst(String(doFull ? "quant-elim" : "quant-elim-partial"));
+  Node n_attr = nm->mkNode(INST_ATTRIBUTE, keyword);
   n_attr = nm->mkNode(INST_PATTERN_LIST, n_attr);
   std::vector<Node> children;
   children.push_back(q[0]);
@@ -87,6 +84,7 @@ Node QuantElimSolver::getQuantifierElimination(Assertions& as,
       // failed, return original
       return q;
     }
+    QuantifiersEngine* qe = te->getQuantifiersEngine();
     // must use original quantified formula to compute QE, which ensures that
     // e.g. term formula removal is not run on the body. Notice that we assume
     // that the (single) quantified formula is preprocessed, rewritten
index 61aed2009b84623957f736e82de9cf2e9be9c78d..f55bfa88bda8b583554be727fd76725d74798988 100644 (file)
@@ -1921,18 +1921,6 @@ void SmtEngine::printStatisticsDiff() const
   d_env->getStatisticsRegistry().storeSnapshot();
 }
 
-void SmtEngine::setUserAttribute(const std::string& attr,
-                                 Node expr,
-                                 const std::vector<Node>& expr_values,
-                                 const std::string& str_value)
-{
-  SmtScope smts(this);
-  finishInit();
-  TheoryEngine* te = getTheoryEngine();
-  Assert(te != nullptr);
-  te->setUserAttribute(attr, expr, expr_values, str_value);
-}
-
 void SmtEngine::setOption(const std::string& key, const std::string& value)
 {
   NodeManagerScope nms(getNodeManager());
index df8346de7fff3962eb6a2f50ecc9ebf21bc6df6c..208c83db80254dee8128c94a1cd243369bb2e40e 100644 (file)
@@ -824,16 +824,6 @@ class CVC5_EXPORT SmtEngine
    */
   void printStatisticsDiff() const;
 
-  /**
-   * Set user attribute.
-   * This function is called when an attribute is set by a user.
-   * In SMT-LIBv2 this is done via the syntax (! expr :attr)
-   */
-  void setUserAttribute(const std::string& attr,
-                        Node expr,
-                        const std::vector<Node>& expr_values,
-                        const std::string& str_value);
-
   /** Get the options object (const and non-const versions) */
   Options& getOptions();
   const Options& getOptions() const;
index ee07dcd5797ec64b5c8f392d5d7df9e6369ae871..218175ee9ad4cba091fe1fd117d7d1bcf1e9e300 100644 (file)
@@ -116,12 +116,6 @@ void EngineOutputChannel::spendResource(Resource r)
   d_engine->spendResource(r);
 }
 
-void EngineOutputChannel::handleUserAttribute(const char* attr,
-                                              theory::Theory* t)
-{
-  d_engine->handleUserAttribute(attr, t);
-}
-
 void EngineOutputChannel::trustedConflict(TrustNode pconf)
 {
   Assert(pconf.getKind() == TrustNodeKind::CONFLICT);
index cc1d8ece73eebd552248ee0a3de97c72e13eb364..468825a7e7917ffa8cb2ebe1b442b3b3b3dce60c 100644 (file)
@@ -61,8 +61,6 @@ class EngineOutputChannel : public theory::OutputChannel
 
   void spendResource(Resource r) override;
 
-  void handleUserAttribute(const char* attr, theory::Theory* t) override;
-
   /**
    * Let pconf be the pair (Node conf, ProofGenerator * pfg). This method
    * sends conf on the output channel of this class whose proof can be generated
index 4561226e1e6c71e298a73f86d00cf6c23655049b..250082952a5d5847ec2b2deef1c00583bab6378d 100644 (file)
@@ -34,7 +34,7 @@ sort INST_PATTERN_TYPE \
 # An instantiation pattern may have more than 1 child, in which case it specifies a multi-trigger.
 operator INST_PATTERN 1: "instantiation pattern"
 operator INST_NO_PATTERN 1 "instantiation no-pattern"
-operator INST_ATTRIBUTE 1 "instantiation attribute"
+operator INST_ATTRIBUTE 1: "instantiation attribute"
 operator INST_POOL 1: "instantiation pool"
 operator INST_ADD_TO_POOL 2 "instantiation add to pool"
 operator SKOLEM_ADD_TO_POOL 2 "skolemization add to pool"
index 33ed6f53662467d6276ee0c593f6da34db1ff4ee..7204a60e185feba72bb4ce9bd8a43a07b3082fec 100644 (file)
@@ -35,7 +35,10 @@ bool QAttributes::isStandard() const
 
 QuantAttributes::QuantAttributes() {}
 
-void QuantAttributes::setUserAttribute( const std::string& attr, Node n, std::vector< Node >& node_values, std::string str_value ){
+void QuantAttributes::setUserAttribute(const std::string& attr,
+                                       TNode n,
+                                       const std::vector<Node>& nodeValues)
+{
   Trace("quant-attr-debug") << "Set " << attr << " " << n << std::endl;
   if (attr == "fun-def")
   {
@@ -50,8 +53,8 @@ void QuantAttributes::setUserAttribute( const std::string& attr, Node n, std::ve
     QuantNameAttribute qna;
     n.setAttribute(qna, true);
   }else if( attr=="quant-inst-max-level" ){
-    Assert(node_values.size() == 1);
-    uint64_t lvl = node_values[0].getConst<Rational>().getNumerator().getLong();
+    Assert(nodeValues.size() == 1);
+    uint64_t lvl = nodeValues[0].getConst<Rational>().getNumerator().getLong();
     Trace("quant-attr-debug") << "Set instantiation level " << n << " to " << lvl << std::endl;
     QuantInstLevelAttribute qila;
     n.setAttribute( qila, lvl );
@@ -183,6 +186,7 @@ void QuantAttributes::computeAttributes( Node q ) {
 void QuantAttributes::computeQuantAttributes( Node q, QAttributes& qa ){
   Trace("quant-attr-debug") << "Compute attributes for " << q << std::endl;
   if( q.getNumChildren()==3 ){
+    NodeManager* nm = NodeManager::currentNM();
     qa.d_ipl = q[2];
     for( unsigned i=0; i<q[2].getNumChildren(); i++ ){
       Kind k = q[2][i].getKind();
@@ -199,7 +203,28 @@ void QuantAttributes::computeQuantAttributes( Node q, QAttributes& qa ){
       }
       else if (k == INST_ATTRIBUTE)
       {
-        Node avar = q[2][i][0];
+        Node avar;
+        // We support two use cases of INST_ATTRIBUTE:
+        // (1) where the user constructs a term of the form
+        // (INST_ATTRIBUTE "keyword" [nodeValues])
+        // (2) where we internally generate nodes of the form
+        // (INST_ATTRIBUTE v) where v has an internal attribute set on it.
+        // We distinguish these two cases by checking the kind of the first
+        // child.
+        if (q[2][i][0].getKind() == CONST_STRING)
+        {
+          // make a dummy variable to be used below
+          avar = nm->mkBoundVar(nm->booleanType());
+          std::vector<Node> nodeValues(q[2][i].begin() + 1, q[2][i].end());
+          // set user attribute on the dummy variable
+          setUserAttribute(
+              q[2][i][0].getConst<String>().toString(), avar, nodeValues);
+        }
+        else
+        {
+          // assume the dummy variable has already had its attributes set
+          avar = q[2][i][0];
+        }
         if( avar.getAttribute(FunDefAttribute()) ){
           Trace("quant-attr") << "Attribute : function definition : " << q << std::endl;
           //get operator directly from pattern
@@ -222,9 +247,21 @@ void QuantAttributes::computeQuantAttributes( Node q, QAttributes& qa ){
         }
         if (avar.getAttribute(QuantNameAttribute()))
         {
-          Trace("quant-attr") << "Attribute : quantifier name : " << avar
-                              << " for " << q << std::endl;
-          qa.d_name = avar;
+          // only set the name if there is a value
+          if (q[2][i].getNumChildren() > 1)
+          {
+            Trace("quant-attr") << "Attribute : quantifier name : "
+                                << q[2][i][1].getConst<String>().toString()
+                                << " for " << q << std::endl;
+            // assign the name to a variable with the given name (to avoid
+            // enclosing the name in quotes)
+            qa.d_name = nm->mkBoundVar(q[2][i][1].getConst<String>().toString(),
+                                       nm->booleanType());
+          }
+          else
+          {
+            Warning() << "Missing name for qid attribute";
+          }
         }
         if( avar.hasAttribute(QuantInstLevelAttribute()) ){
           qa.d_qinstLevel = avar.getAttribute(QuantInstLevelAttribute());
index 910dbab5bca2429be7df2a4b12a4d6355854c50a..48fb4f15908101be8e4c9001b881fb55eb5d2651 100644 (file)
@@ -179,16 +179,15 @@ class QuantAttributes
   QuantAttributes();
   ~QuantAttributes(){}
   /** set user attribute
-  * This function applies an attribute
-  * This can be called when we mark expressions with attributes, e.g. (! q
-  * :attribute attr [node_values, str_value...]),
-  * It can also be called internally in various ways (for SyGus, quantifier
-  * elimination, etc.)
-  */
+   * This function applies an attribute
+   * This can be called when we mark expressions with attributes, e.g. (! q
+   * :attribute attr [nodeValues]),
+   * It can also be called internally in various ways (for SyGus, quantifier
+   * elimination, etc.)
+   */
   static void setUserAttribute(const std::string& attr,
-                               Node q,
-                               std::vector<Node>& node_values,
-                               std::string str_value);
+                               TNode q,
+                               const std::vector<Node>& nodeValues);
 
   /** compute quantifier attributes */
   static void computeQuantAttributes(Node q, QAttributes& qa);
index a108d4614187cf217c7a8097d16b0d8008162d12..2ad475f011054d4df45a77b64a71f06bcbb7ecc2 100644 (file)
@@ -40,12 +40,6 @@ TheoryQuantifiers::TheoryQuantifiers(Env& env,
       d_qim(*this, d_qstate, d_qreg, d_treg, d_pnm),
       d_qengine(nullptr)
 {
-  out.handleUserAttribute( "fun-def", this );
-  out.handleUserAttribute("qid", this);
-  out.handleUserAttribute( "quant-inst-max-level", this );
-  out.handleUserAttribute( "quant-elim", this );
-  out.handleUserAttribute( "quant-elim-partial", this );
-
   // construct the quantifiers engine
   d_qengine.reset(
       new QuantifiersEngine(d_qstate, d_qreg, d_treg, d_qim, d_pnm));
@@ -188,10 +182,6 @@ bool TheoryQuantifiers::preNotifyFact(
   return true;
 }
 
-void TheoryQuantifiers::setUserAttribute(const std::string& attr, Node n, std::vector<Node> node_values, std::string str_value){
-  QuantAttributes::setUserAttribute( attr, n, node_values, str_value );
-}
-
 }  // namespace quantifiers
 }  // namespace theory
 }  // namespace cvc5
index 0ef5cfcbb73eee4a408a34ee3883e3352bc694c8..1d721a0aeb284274aa761196232cfd0d69aef532 100644 (file)
@@ -77,10 +77,6 @@ class TheoryQuantifiers : public Theory {
   {
     return std::string("TheoryQuantifiers");
   }
-  void setUserAttribute(const std::string& attr,
-                        Node n,
-                        std::vector<Node> node_values,
-                        std::string str_value) override;
 
  private:
   /** The theory rewriter for this theory. */
index 6fb377a567d71f09975711b908e3cc2bf87dea8d..14f066ce1d5ac11b1919506cd1d9a3753b16d961 100644 (file)
@@ -106,6 +106,18 @@ TypeNode QuantifierAnnotationTypeRule::computeType(NodeManager* nodeManager,
                                                    TNode n,
                                                    bool check)
 {
+  if (n.getKind() == kind::INST_ATTRIBUTE)
+  {
+    if (n.getNumChildren() > 1)
+    {
+      // first must be a keyword
+      if (n[0].getKind() != kind::CONST_STRING)
+      {
+        throw TypeCheckingExceptionPrivate(
+            n[0], "Expecting a keyword at the head of INST_ATTRIBUTE.");
+      }
+    }
+  }
   return nodeManager->instPatternType();
 }
 
index bde00b908eeeab2fbdcb18c26f6932482e0afb65..44a0e597bd8128aae477352af84c5f232fbc4add 100644 (file)
@@ -775,15 +775,6 @@ class Theory {
    */
   virtual std::string identify() const = 0;
 
-  /** Set user attribute
-    * This function is called when an attribute is set by a user.  In SMT-LIBv2 this is done
-    *  via the syntax (! n :attr)
-    */
-  virtual void setUserAttribute(const std::string& attr, Node n, std::vector<Node> node_values, std::string str_value) {
-    Unimplemented() << "Theory " << identify()
-                    << " doesn't support Theory::setUserAttribute interface";
-  }
-
   typedef context::CDList<Assertion>::const_iterator assertions_iterator;
 
   /**
index bd621126c0dea7c6915710d587bcd44bd63296c1..6bec3dc8fda1b047ffb4b1901479204ea51125f3 100644 (file)
@@ -253,8 +253,7 @@ TheoryEngine::TheoryEngine(Env& env)
       d_false(),
       d_interrupted(false),
       d_inPreregister(false),
-      d_factsAsserted(d_env.getContext(), false),
-      d_attr_handle()
+      d_factsAsserted(d_env.getContext(), false)
 {
   for(TheoryId theoryId = theory::THEORY_FIRST; theoryId != theory::THEORY_LAST;
       ++ theoryId)
@@ -1833,27 +1832,6 @@ TrustNode TheoryEngine::getExplanation(
 
 bool TheoryEngine::isProofEnabled() const { return d_pnm != nullptr; }
 
-void TheoryEngine::setUserAttribute(const std::string& attr,
-                                    Node n,
-                                    const std::vector<Node>& node_values,
-                                    const std::string& str_value)
-{
-  Trace("te-attr") << "set user attribute " << attr << " " << n << endl;
-  if( d_attr_handle.find( attr )!=d_attr_handle.end() ){
-    for( size_t i=0; i<d_attr_handle[attr].size(); i++ ){
-      d_attr_handle[attr][i]->setUserAttribute(attr, n, node_values, str_value);
-    }
-  } else {
-    //unhandled exception?
-  }
-}
-
-void TheoryEngine::handleUserAttribute(const char* attr, Theory* t) {
-  Trace("te-attr") << "Handle user attribute " << attr << " " << t << endl;
-  std::string str( attr );
-  d_attr_handle[ str ].push_back( t );
-}
-
 void TheoryEngine::checkTheoryAssertionsWithModel(bool hardFailure) {
   for(TheoryId theoryId = THEORY_FIRST; theoryId < THEORY_LAST; ++theoryId) {
     Theory* theory = d_theoryTable[theoryId];
index 3f2e589b374fcdbf0b4b1958d4f46690edac1bd4..e610adcf7e1c3df859a83443f90ff68dbbb82e37 100644 (file)
@@ -660,27 +660,7 @@ public:
  /** Prints the assertions to the debug stream */
  void printAssertions(const char* tag);
 
-private:
-
-  std::map< std::string, std::vector< theory::Theory* > > d_attr_handle;
-
  public:
-  /** Set user attribute.
-   *
-   * This function is called when an attribute is set by a user.  In SMT-LIBv2
-   * this is done via the syntax (! n :attr)
-   */
-  void setUserAttribute(const std::string& attr,
-                        Node n,
-                        const std::vector<Node>& node_values,
-                        const std::string& str_value);
-
-  /** Handle user attribute.
-   *
-   * Associates theory t with the attribute attr.  Theory t will be
-   * notified whenever an attribute of name attr is set.
-   */
-  void handleUserAttribute(const char* attr, theory::Theory* t);
 
   /**
    * Check that the theory assertions are satisfied in the model.
index f1644dfcd7bcfb4c8c11baac0aaffc8f431f219f..1cc6b05071bb17e5b79bf4778d2afba3751262c8 100644 (file)
@@ -136,7 +136,6 @@ class DummyOutputChannel : public cvc5::theory::OutputChannel
 
   void requirePhase(TNode, bool) override {}
   void setIncomplete(theory::IncompleteId id) override {}
-  void handleUserAttribute(const char* attr, theory::Theory* t) override {}
 
   void clear() { d_callHistory.clear(); }