LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/quantifiers/ieval - state.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 246 293 84.0 %
Date: 2026-09-21 10:07:54 Functions: 24 29 82.8 %
Branches: 157 287 54.7 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * This file is part of the cvc5 project.
       3                 :            :  *
       4                 :            :  * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS
       5                 :            :  * in the top-level source directory and their institutional affiliations.
       6                 :            :  * All rights reserved.  See the file COPYING in the top-level source
       7                 :            :  * directory for licensing information.
       8                 :            :  * ****************************************************************************
       9                 :            :  *
      10                 :            :  * State for instantiation evaluator
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "theory/quantifiers/ieval/state.h"
      14                 :            : 
      15                 :            : #include "expr/node_algorithm.h"
      16                 :            : #include "expr/skolem_manager.h"
      17                 :            : #include "theory/quantifiers/quantifiers_state.h"
      18                 :            : #include "theory/quantifiers/term_database.h"
      19                 :            : 
      20                 :            : using namespace cvc5::internal::kind;
      21                 :            : 
      22                 :            : namespace cvc5::internal {
      23                 :            : namespace theory {
      24                 :            : namespace quantifiers {
      25                 :            : namespace ieval {
      26                 :            : 
      27                 :      69001 : State::State(Env& env, context::Context* c, QuantifiersState& qs, TermDb& tdb)
      28                 :            :     : EnvObj(env),
      29                 :      69001 :       d_ctx(c),
      30                 :      69001 :       d_qstate(qs),
      31                 :      69001 :       d_tdb(tdb),
      32                 :      69001 :       d_tevMode(ieval::TermEvaluatorMode::NONE),
      33                 :      69001 :       d_registeredTerms(c),
      34                 :      69001 :       d_registeredBaseTerms(c),
      35                 :      69001 :       d_initialized(c, false),
      36                 :     138002 :       d_numActiveQuant(c, 0)
      37                 :            : {
      38                 :      69001 :   NodeManager* nm = nodeManager();
      39                 :      69001 :   SkolemManager* sm = nm->getSkolemManager();
      40                 :      69001 :   TypeNode btype = nm->booleanType();
      41                 :      69001 :   d_none = sm->mkInternalSkolemFunction(InternalSkolemId::IEVAL_NONE, btype);
      42                 :      69001 :   d_some = sm->mkInternalSkolemFunction(InternalSkolemId::IEVAL_SOME, btype);
      43                 :      69001 : }
      44                 :            : 
      45                 :    7079770 : bool State::hasInitialized() const { return d_initialized.get(); }
      46                 :            : 
      47                 :     183493 : bool State::initialize()
      48                 :            : {
      49 [ -  + ][ -  + ]:     183493 :   Assert(!d_initialized.get());
                 [ -  - ]
      50         [ +  - ]:     183493 :   Trace("ieval") << "INITIALIZE" << std::endl;
      51                 :            :   // should have set a valid evaluator mode
      52 [ -  + ][ -  + ]:     183493 :   Assert(d_tec != nullptr);
                 [ -  - ]
      53                 :     183493 :   d_initialized = true;
      54         [ +  + ]:     404562 :   for (const Node& b : d_registeredBaseTerms)
      55                 :            :   {
      56                 :     482990 :     Node bev = d_tec->evaluateBase(*this, b);
      57 [ -  + ][ -  + ]:     241495 :     Assert(!bev.isNull());
                 [ -  - ]
      58         [ +  - ]:     482990 :     Trace("ieval") << "  " << b << " := " << bev << " (initialize)"
      59                 :     241495 :                    << std::endl;
      60                 :     241495 :     notifyPatternEqGround(b, bev);
      61         [ +  + ]:     241495 :     if (isFinished())
      62                 :            :     {
      63                 :      20426 :       return false;
      64                 :            :     }
      65 [ +  + ][ +  + ]:     261921 :   }
      66                 :     163067 :   return true;
      67                 :            : }
      68                 :            : 
      69                 :      69001 : void State::setEvaluatorMode(TermEvaluatorMode tev)
      70                 :            : {
      71                 :      69001 :   d_tevMode = tev;
      72                 :            :   // initialize the term evaluator, which is freshly allocated
      73 [ +  + ][ +  + ]:      69001 :   if (tev == TermEvaluatorMode::CONFLICT || tev == TermEvaluatorMode::PROP
      74         [ +  - ]:      28712 :       || tev == TermEvaluatorMode::NO_ENTAIL)
      75                 :            :   {
      76                 :            :     // finding conflict, propagating, or non-entailed instances all
      77                 :            :     // involve the entailment term evaluator
      78                 :      69001 :     d_tec.reset(new TermEvaluatorEntailed(d_env, tev, d_qstate, d_tdb));
      79                 :            :   }
      80                 :      69001 : }
      81                 :            : 
      82                 :      69001 : void State::watch(Node q, const std::vector<Node>& vars, Node body)
      83                 :            : {
      84                 :            :   // Note this method does not rely on d_tec, since evaluation may be
      85                 :            :   // context dependent.
      86                 :      69001 :   std::map<Node, QuantInfo>::iterator it = d_quantInfo.find(q);
      87         [ -  + ]:      69001 :   if (it != d_quantInfo.end())
      88                 :            :   {
      89                 :            :     // already initialized
      90                 :          0 :     return;
      91                 :            :   }
      92                 :      69001 :   d_quantInfo.emplace(q, d_ctx);
      93                 :      69001 :   it = d_quantInfo.find(q);
      94                 :            :   // initialize the quantifier info, which stores basic constraint information
      95                 :      69001 :   it->second.initialize(q, body);
      96                 :            :   // add to free variable lists
      97         [ +  + ]:     236882 :   for (const Node& v : vars)
      98                 :            :   {
      99                 :     167881 :     FreeVarInfo& finfo = getOrMkFreeVarInfo(v);
     100                 :     167881 :     finfo.d_quantList.push_back(q);
     101                 :            :   }
     102                 :            :   // initialize pattern terms
     103                 :      69001 :   NodeSet::const_iterator itr;
     104                 :      69001 :   std::vector<TNode> visit;
     105                 :            :   // we traverse its constraint terms to set up the parent notification lists
     106                 :      69001 :   const std::map<TNode, bool>& cterms = it->second.getConstraints();
     107         [ +  + ]:     197791 :   for (const std::pair<const TNode, bool>& c : cterms)
     108                 :            :   {
     109                 :            :     // we will notify the quantified formula when the pattern becomes set
     110                 :     128790 :     PatTermInfo& pi = getOrMkPatTermInfo(c.first);
     111                 :            :     // when the constraint term is assigned, we notify q
     112                 :     128790 :     pi.d_parentNotify.push_back(q);
     113                 :            :     // we visit the constraint term below
     114                 :     128790 :     visit.push_back(c.first);
     115                 :            :   }
     116                 :            : 
     117                 :      69001 :   TNode cur;
     118                 :            :   do
     119                 :            :   {
     120                 :    1031120 :     cur = visit.back();
     121                 :    1031120 :     visit.pop_back();
     122                 :    1031120 :     itr = d_registeredTerms.find(cur);
     123         [ +  + ]:    1031120 :     if (itr == d_registeredTerms.end())
     124                 :            :     {
     125                 :     700348 :       d_registeredTerms.insert(cur);
     126         [ +  + ]:     700348 :       if (cur.getKind() == Kind::BOUND_VARIABLE)
     127                 :            :       {
     128                 :            :         // should be one of the free variables of the quantified formula
     129 [ -  + ][ -  + ]:     164751 :         Assert(std::find(vars.begin(), vars.end(), cur) != vars.end());
                 [ -  - ]
     130                 :     164751 :         continue;
     131                 :            :       }
     132                 :     535597 :       size_t nchild = 0;
     133         [ +  + ]:     535597 :       if (QuantInfo::isTraverseTerm(cur))
     134                 :            :       {
     135                 :            :         // get the unique children
     136                 :     522920 :         std::set<TNode> children;
     137                 :            :         // we don't traverse into operators here
     138                 :     522920 :         children.insert(cur.begin(), cur.end());
     139         [ +  + ]:    1448723 :         for (TNode cc : children)
     140                 :            :         {
     141                 :            :           // skip constants
     142         [ +  + ]:     925803 :           if (cc.isConst())
     143                 :            :           {
     144                 :      23473 :             continue;
     145                 :            :           }
     146                 :     902330 :           nchild++;
     147                 :            :           // require notifications to parent
     148                 :     902330 :           PatTermInfo& pic = getOrMkPatTermInfo(cc);
     149                 :     902330 :           pic.d_parentNotify.push_back(cur);
     150                 :     902330 :           visit.push_back(cc);
     151         [ +  + ]:     925803 :         }
     152                 :     522920 :       }
     153         [ +  + ]:     535597 :       if (nchild > 0)
     154                 :            :       {
     155                 :            :         // set the number of watched children
     156                 :     429678 :         PatTermInfo& pi = getPatTermInfo(cur);
     157                 :     429678 :         pi.d_numUnassigned = nchild;
     158                 :            :       }
     159                 :            :       else
     160                 :            :       {
     161 [ -  + ][ -  + ]:     105919 :         Assert(d_pInfo.find(cur) != d_pInfo.end());
                 [ -  - ]
     162                 :            :         // no notifying children, this term will be initialized immediately
     163                 :     105919 :         d_registeredBaseTerms.insert(cur);
     164                 :            :       }
     165                 :            :     }
     166         [ +  + ]:    1031120 :   } while (!visit.empty());
     167                 :            :   // increment the count of quantified formulas
     168                 :      69001 :   d_numActiveQuant = d_numActiveQuant + 1;
     169                 :      69001 : }
     170                 :            : 
     171                 :    5371843 : bool State::assignVar(TNode v,
     172                 :            :                       TNode r,
     173                 :            :                       std::vector<Node>& assignedQuants,
     174                 :            :                       bool trackAssignedQuant)
     175                 :            : {
     176                 :            :   // notify that the variable is equal to the ground term
     177         [ +  - ]:    5371843 :   Trace("ieval") << "ASSIGN: " << v << " := " << r << std::endl;
     178 [ -  + ][ -  + ]:    5371843 :   Assert(d_initialized.get());
                 [ -  - ]
     179                 :            :   // note that we allow setting patterns to terms that evaluate to "none",
     180                 :            :   // e.g. for conflict-based instantiation where a variable is entailed
     181                 :            :   // equal to a term in the body of the quantified formula that is not
     182                 :            :   // registered to the term database.
     183                 :   10743686 :   Assert(isNone(getValue(r)) || getValue(r) == r)
     184                 :    5371843 :       << "Unexpected value " << getValue(r) << " for " << r;
     185                 :    5371843 :   notifyPatternEqGround(v, r);
     186                 :            :   // might the inactive now
     187         [ +  + ]:    5371843 :   if (isFinished())
     188                 :            :   {
     189                 :    2960682 :     return false;
     190                 :            :   }
     191         [ -  + ]:    2411161 :   if (trackAssignedQuant)
     192                 :            :   {
     193                 :            :     // decrement the unassigned variable counts for all quantified formulas
     194                 :            :     // containing this variable
     195                 :          0 :     FreeVarInfo& finfo = getFreeVarInfo(v);
     196         [ -  - ]:          0 :     for (const Node& q : finfo.d_quantList)
     197                 :            :     {
     198                 :          0 :       QuantInfo& qinfo = getQuantInfo(q);
     199         [ -  - ]:          0 :       if (!qinfo.isActive())
     200                 :            :       {
     201                 :            :         // marked inactive, skip
     202                 :          0 :         continue;
     203                 :            :       }
     204         [ -  - ]:          0 :       if (qinfo.getNumUnassignedVars() == 1)
     205                 :            :       {
     206                 :            :         // now fully assigned
     207                 :          0 :         assignedQuants.push_back(q);
     208                 :            :         // set inactive
     209                 :          0 :         setQuantInactive(qinfo);
     210                 :            :       }
     211                 :            :       else
     212                 :            :       {
     213                 :            :         // decrement the variable
     214                 :          0 :         qinfo.decrementUnassignedVar();
     215                 :            :       }
     216                 :            :     }
     217                 :            :   }
     218                 :    2411161 :   return true;
     219                 :            : }
     220                 :            : 
     221                 :      73660 : void State::getFailureExp(Node q, std::unordered_set<Node>& processed) const
     222                 :            : {
     223                 :      73660 :   const QuantInfo& qi = getQuantInfo(q);
     224                 :      73660 :   TNode failConstraint = qi.getFailureConstraint();
     225 [ -  + ][ -  + ]:      73660 :   Assert(!failConstraint.isNull());
                 [ -  - ]
     226                 :      73660 :   std::vector<TNode> visit;
     227                 :      73660 :   visit.push_back(failConstraint);
     228                 :            :   do
     229                 :            :   {
     230                 :     347264 :     TNode cur = visit.back();
     231                 :     347264 :     visit.pop_back();
     232         [ +  + ]:     347264 :     if (processed.find(cur) == processed.end())
     233                 :            :     {
     234                 :     336354 :       processed.insert(cur);
     235                 :            :       // as an optimization, only visit children of terms that have bound
     236                 :            :       // variables
     237                 :     336354 :       if (!expr::hasBoundVar(cur) || !QuantInfo::isTraverseTerm(cur))
     238                 :            :       {
     239                 :      23217 :         continue;
     240                 :            :       }
     241                 :     313137 :       Assert(d_pInfo.find(cur) != d_pInfo.end())
     242                 :          0 :           << "Missing pattern info for " << cur;
     243                 :     313137 :       const PatTermInfo& pi = getPatTermInfo(cur);
     244                 :     313137 :       TNode pcexp = pi.d_evalExpChild.get();
     245         [ +  + ]:     313137 :       if (!pcexp.isNull())
     246                 :            :       {
     247                 :            :         // partial evaluation was forced by single child
     248                 :     112948 :         visit.push_back(pcexp);
     249                 :            :       }
     250                 :            :       else
     251                 :            :       {
     252                 :            :         // used all children to evaluate, add all to visit list
     253                 :     200189 :         visit.insert(visit.end(), cur.begin(), cur.end());
     254                 :            :       }
     255                 :     313137 :     }
     256 [ +  + ][ +  + ]:     694528 :   } while (!visit.empty());
     257                 :      73660 : }
     258                 :            : 
     259                 :   15729283 : bool State::isFinished() const { return d_numActiveQuant == 0; }
     260                 :            : 
     261                 :    4653461 : QuantInfo& State::getQuantInfo(TNode q)
     262                 :            : {
     263                 :    4653461 :   std::map<Node, QuantInfo>::iterator it = d_quantInfo.find(q);
     264 [ -  + ][ -  + ]:    4653461 :   Assert(it != d_quantInfo.end());
                 [ -  - ]
     265                 :    4653461 :   return it->second;
     266                 :            : }
     267                 :            : 
     268                 :      73660 : const QuantInfo& State::getQuantInfo(TNode q) const
     269                 :            : {
     270                 :      73660 :   std::map<Node, QuantInfo>::const_iterator it = d_quantInfo.find(q);
     271 [ -  + ][ -  + ]:      73660 :   Assert(it != d_quantInfo.end());
                 [ -  - ]
     272                 :      73660 :   return it->second;
     273                 :            : }
     274                 :            : 
     275                 :     167881 : FreeVarInfo& State::getOrMkFreeVarInfo(TNode v)
     276                 :            : {
     277                 :     167881 :   std::map<Node, FreeVarInfo>::iterator it = d_fvInfo.find(v);
     278         [ +  - ]:     167881 :   if (it == d_fvInfo.end())
     279                 :            :   {
     280                 :     167881 :     d_fvInfo.emplace(v, d_ctx);
     281                 :     167881 :     it = d_fvInfo.find(v);
     282                 :            :   }
     283                 :     167881 :   return it->second;
     284                 :            : }
     285                 :            : 
     286                 :          0 : FreeVarInfo& State::getFreeVarInfo(TNode v)
     287                 :            : {
     288                 :          0 :   std::map<Node, FreeVarInfo>::iterator it = d_fvInfo.find(v);
     289                 :          0 :   Assert(it != d_fvInfo.end());
     290                 :          0 :   return it->second;
     291                 :            : }
     292                 :            : 
     293                 :    1031120 : PatTermInfo& State::getOrMkPatTermInfo(TNode p)
     294                 :            : {
     295                 :    1031120 :   std::map<Node, PatTermInfo>::iterator it = d_pInfo.find(p);
     296         [ +  + ]:    1031120 :   if (it == d_pInfo.end())
     297                 :            :   {
     298                 :     700348 :     it = d_pInfo.emplace(p, d_ctx).first;
     299                 :            :     // initialize the pattern
     300                 :     700348 :     it->second.initialize(p);
     301                 :            :   }
     302                 :    1031120 :   return it->second;
     303                 :            : }
     304                 :            : 
     305                 :     429678 : PatTermInfo& State::getPatTermInfo(TNode p)
     306                 :            : {
     307                 :     429678 :   std::map<Node, PatTermInfo>::iterator it = d_pInfo.find(p);
     308 [ -  + ][ -  + ]:     429678 :   Assert(it != d_pInfo.end());
                 [ -  - ]
     309                 :     429678 :   return it->second;
     310                 :            : }
     311                 :            : 
     312                 :     313137 : const PatTermInfo& State::getPatTermInfo(TNode p) const
     313                 :            : {
     314                 :     313137 :   std::map<Node, PatTermInfo>::const_iterator it = d_pInfo.find(p);
     315 [ -  + ][ -  + ]:     313137 :   Assert(it != d_pInfo.end());
                 [ -  - ]
     316                 :     313137 :   return it->second;
     317                 :            : }
     318                 :            : 
     319                 :    5613338 : void State::notifyPatternEqGround(TNode p, TNode g)
     320                 :            : {
     321         [ +  - ]:   11226676 :   Trace("ieval-state-debug")
     322                 :    5613338 :       << "Notify pattern eq ground: " << p << " == " << g << std::endl;
     323 [ -  + ][ -  + ]:    5613338 :   Assert(!g.isNull());
                 [ -  - ]
     324 [ -  + ][ -  + ]:    5613338 :   Assert(!expr::hasFreeVar(g));
                 [ -  - ]
     325                 :            :   // note that we allow setting patterns to terms that evaluate to "none",
     326                 :            :   // e.g. for conflict-based instantiation where a variable is entailed
     327                 :            :   // equal to a term in the body of the quantified formula that is not
     328                 :            :   // registered to the term database.
     329                 :   11226676 :   Assert(isNone(d_tec->evaluateBase(*this, g))
     330                 :            :          || d_tec->evaluateBase(*this, g) == g)
     331                 :    5613338 :       << "Bad eval: " << d_tec->evaluateBase(*this, g) << " " << g;
     332                 :    5613338 :   std::map<Node, PatTermInfo>::iterator it = d_pInfo.find(p);
     333         [ +  + ]:    5613338 :   if (it == d_pInfo.end())
     334                 :            :   {
     335                 :            :     // in rare cases, we may be considering a quantified formula not containing
     336                 :            :     // one of its bound variables, e.g. if the variable is in an annotation
     337                 :            :     // (pattern) only, or if only in nested quantification.
     338                 :      18832 :     return;
     339                 :            :   }
     340         [ +  + ]:    5594546 :   if (!it->second.isActive())
     341                 :            :   {
     342                 :            :     // already assigned
     343                 :         40 :     return;
     344                 :            :   }
     345                 :    5594506 :   it->second.d_eq = g;
     346                 :            :   // run notifications until fixed point
     347                 :    5594506 :   size_t tnIndex = 0;
     348                 :    5594506 :   std::vector<std::map<Node, PatTermInfo>::iterator> toNotify;
     349                 :    5594506 :   toNotify.push_back(it);
     350         [ +  + ]:   30972093 :   while (tnIndex < toNotify.size())
     351                 :            :   {
     352                 :   25377587 :     it = toNotify[tnIndex];
     353                 :   25377587 :     ++tnIndex;
     354 [ -  + ][ -  + ]:   25377587 :     Assert(it != d_pInfo.end());
                 [ -  - ]
     355                 :   25377587 :     p = it->second.d_pattern;
     356                 :   25377587 :     g = it->second.d_eq;
     357         [ +  - ]:   50755174 :     Trace("ieval-state-debug")
     358                 :   25377587 :         << "process notifications (" << p << ", " << g << ")" << std::endl;
     359 [ -  + ][ -  + ]:   25377587 :     Assert(!g.isNull());
                 [ -  - ]
     360                 :   25377587 :     context::CDList<Node>& notifyList = it->second.d_parentNotify;
     361         [ +  + ]:   58094836 :     for (TNode pp : notifyList)
     362                 :            :     {
     363         [ +  + ]:   35992209 :       if (pp.getKind() == Kind::FORALL)
     364                 :            :       {
     365                 :            :         // if we have a quantified formula as a parent, notify is a special
     366                 :            :         // method, which will test the constraints
     367                 :    4653461 :         notifyQuant(pp, p, g);
     368                 :            :         // could be finished now
     369         [ +  + ]:    4653461 :         if (isFinished())
     370                 :            :         {
     371                 :    3274960 :           break;
     372                 :            :         }
     373                 :    1378501 :         continue;
     374                 :            :       }
     375                 :            :       // otherwise, notify the parent pattern
     376                 :   31338748 :       it = d_pInfo.find(pp);
     377 [ -  + ][ -  + ]:   31338748 :       Assert(it != d_pInfo.end());
                 [ -  - ]
     378                 :            :       // returns true if we have evaluated
     379         [ +  + ]:   31338748 :       if (it->second.notifyChild(*this, p, g, d_tec.get()))
     380                 :            :       {
     381                 :   19783081 :         toNotify.push_back(it);
     382                 :            :       }
     383    [ +  + ][ + ]:   35992209 :     }
     384                 :            :   }
     385                 :    5594506 : }
     386                 :            : 
     387                 :    4653461 : void State::notifyQuant(TNode q, TNode p, TNode val)
     388                 :            : {
     389 [ -  + ][ -  + ]:    4653461 :   Assert(q.getKind() == Kind::FORALL);
                 [ -  - ]
     390                 :    4653461 :   QuantInfo& qi = getQuantInfo(q);
     391         [ +  + ]:    4653461 :   if (!qi.isActive())
     392                 :            :   {
     393                 :            :     // quantified formula is already inactive
     394                 :     293852 :     return;
     395                 :            :   }
     396 [ -  + ][ -  + ]:    4359609 :   Assert(!val.isNull());
                 [ -  - ]
     397 [ -  + ][ -  + ]:    4359609 :   Assert(val.getType().isBoolean());
                 [ -  - ]
     398 [ +  + ][ +  + ]:    4359609 :   if (!val.isConst() && val != d_none)
                 [ +  + ]
     399                 :            :   {
     400                 :            :     // in the rare case that we evaluate to non-constant, we treat this as
     401                 :            :     // "some" here instead. This can happen if a term is congruent to an
     402                 :            :     // (unassigned) Boolean term.
     403                 :     193244 :     val = d_some;
     404                 :            :   }
     405         [ +  - ]:    8719218 :   Trace("ieval-state-debug") << "Notify quant constraint " << q.getId() << " "
     406                 :    4359609 :                              << p << " == " << val << std::endl;
     407 [ -  + ][ -  + ]:    4359609 :   Assert(d_numActiveQuant.get() > 0);
                 [ -  - ]
     408                 :            :   // check whether we should set inactive
     409                 :    4359609 :   bool setInactive = false;
     410                 :    4359609 :   std::stringstream inactiveReason;
     411         [ +  + ]:    4359609 :   if (isNone(val))
     412                 :            :   {
     413                 :            :     // a top-level constraint is "none", i.e. this instantiation will generate
     414                 :            :     // a predicate over new terms.
     415         [ +  + ]:    2179441 :     if (d_tevMode == TermEvaluatorMode::CONFLICT
     416         [ +  + ]:    1089609 :         || d_tevMode == TermEvaluatorMode::PROP)
     417                 :            :     {
     418                 :            :       // if we are looking for conflicts and propagations only, we are now
     419                 :            :       // inactive
     420         [ -  + ]:    1411167 :       if (TraceIsOn("ieval"))
     421                 :            :       {
     422                 :          0 :         inactiveReason << "none, req conflict/prop";
     423                 :            :       }
     424                 :    1411167 :       setInactive = true;
     425                 :            :     }
     426                 :            :     else
     427                 :            :     {
     428                 :     768274 :       qi.setNoConflict();
     429                 :            :     }
     430                 :            :   }
     431         [ +  + ]:    2180168 :   else if (isSome(val))
     432                 :            :   {
     433                 :            :     // it has the "some" value, and we have any constraint, we remain
     434                 :            :     // active but are not strictly a conflict
     435         [ +  + ]:     193244 :     if (d_tevMode == TermEvaluatorMode::CONFLICT)
     436                 :            :     {
     437                 :            :       // if we require conflicts, we are inactive now
     438         [ -  + ]:      54872 :       if (TraceIsOn("ieval"))
     439                 :            :       {
     440                 :          0 :         inactiveReason << "some, req conflict";
     441                 :            :       }
     442                 :      54872 :       setInactive = true;
     443                 :            :     }
     444                 :            :     else
     445                 :            :     {
     446                 :     138372 :       qi.setNoConflict();
     447                 :            :     }
     448                 :            :   }
     449                 :            :   else
     450                 :            :   {
     451 [ -  + ][ -  + ]:    1986924 :     Assert(val.isConst());
                 [ -  - ]
     452                 :    1986924 :     const std::map<TNode, bool>& cs = qi.getConstraints();
     453                 :    1986924 :     std::map<TNode, bool>::const_iterator itm = cs.find(p);
     454 [ -  + ][ -  + ]:    1986924 :     Assert(itm != cs.end());
                 [ -  - ]
     455         [ +  + ]:    1986924 :     if (val.getConst<bool>() != itm->second)
     456                 :            :     {
     457                 :    1515069 :       setInactive = true;
     458         [ -  + ]:    1515069 :       if (TraceIsOn("ieval"))
     459                 :            :       {
     460                 :          0 :         inactiveReason << "constraint-true";
     461                 :            :       }
     462                 :            :     }
     463                 :            :     else
     464                 :            :     {
     465         [ +  - ]:     943710 :       Trace("ieval-state-debug")
     466                 :     471855 :           << "...satisfied constraint " << p << std::endl;
     467                 :            :     }
     468                 :            :   }
     469                 :            :   // if we should set inactive, update qi and decrement d_numActiveQuant
     470         [ +  + ]:    4359609 :   if (setInactive)
     471                 :            :   {
     472                 :    2981108 :     qi.setFailureConstraint(p);
     473                 :    2981108 :     setQuantInactive(qi);
     474         [ +  - ]:    5962216 :     Trace("ieval") << "  -> " << q << " inactive due to "
     475 [ -  + ][ -  - ]:    2981108 :                    << inactiveReason.str() << ", from " << p << std::endl;
     476                 :            :   }
     477                 :            :   else
     478                 :            :   {
     479         [ +  - ]:    1378501 :     Trace("ieval-state-debug") << "...still active" << std::endl;
     480                 :            :   }
     481                 :            :   // otherwise, we could have an instantiation, but we do not check for this
     482                 :            :   // here; instead this is handled based on watching the number of free
     483                 :            :   // variables assigned.
     484                 :    4359609 : }
     485                 :            : 
     486                 :    2981108 : void State::setQuantInactive(QuantInfo& qi)
     487                 :            : {
     488         [ +  - ]:    2981108 :   if (qi.isActive())
     489                 :            :   {
     490                 :    2981108 :     qi.setActive(false);
     491 [ -  + ][ -  + ]:    2981108 :     Assert(d_numActiveQuant.get() > 0);
                 [ -  - ]
     492                 :    2981108 :     d_numActiveQuant = d_numActiveQuant - 1;
     493                 :            :   }
     494                 :    2981108 : }
     495                 :            : 
     496                 :   13367354 : TNode State::getNone() const { return d_none; }
     497                 :            : 
     498                 :   45478121 : bool State::isNone(TNode n) const { return n == d_none; }
     499                 :            : 
     500                 :     491883 : TNode State::getSome() const { return d_some; }
     501                 :            : 
     502                 :   11235505 : bool State::isSome(TNode n) const { return n == d_some; }
     503                 :            : 
     504                 :     633380 : Node State::doRewrite(Node n) const { return rewrite(n); }
     505                 :            : 
     506                 :          0 : bool State::isQuantActive(TNode q) const
     507                 :            : {
     508                 :          0 :   std::map<Node, QuantInfo>::const_iterator it = d_quantInfo.find(q);
     509                 :          0 :   Assert(it != d_quantInfo.end());
     510                 :          0 :   return it->second.isActive();
     511                 :            : }
     512                 :            : 
     513                 :    5375653 : TNode State::evaluate(TNode n) const
     514                 :            : {
     515         [ +  + ]:    5375653 :   if (n.isConst())
     516                 :            :   {
     517                 :    2008704 :     return n;
     518                 :            :   }
     519                 :            :   // all pattern terms should have been assigned pattern term info
     520 [ -  + ][ -  + ]:    3366949 :   Assert(!expr::hasFreeVar(n));
                 [ -  - ]
     521                 :    3366949 :   return d_tec->evaluateBase(*this, n);
     522                 :            : }
     523                 :            : 
     524                 :   37843019 : TNode State::getValue(TNode p) const
     525                 :            : {
     526         [ +  + ]:   37843019 :   if (p.isConst())
     527                 :            :   {
     528                 :    5666643 :     return p;
     529                 :            :   }
     530                 :   32176376 :   std::map<Node, PatTermInfo>::const_iterator it = d_pInfo.find(p);
     531         [ +  + ]:   32176376 :   if (it != d_pInfo.end())
     532                 :            :   {
     533                 :   25688058 :     return it->second.d_eq;
     534                 :            :   }
     535                 :            :   // all pattern terms should have been assigned pattern term info
     536 [ -  + ][ -  + ]:    6488318 :   Assert(!expr::hasFreeVar(p));
                 [ -  - ]
     537                 :    6488318 :   return d_tec->evaluateBase(*this, p);
     538                 :            : }
     539                 :            : 
     540                 :          0 : std::string State::toString() const
     541                 :            : {
     542                 :          0 :   std::stringstream ss;
     543                 :          0 :   ss << "#patterns = " << d_pInfo.size() << std::endl;
     544                 :          0 :   ss << "#freeVars = " << d_fvInfo.size() << std::endl;
     545                 :          0 :   ss << "#quants = " << d_numActiveQuant.get() << " / " << d_quantInfo.size()
     546                 :          0 :      << std::endl;
     547                 :          0 :   return ss.str();
     548                 :          0 : }
     549                 :            : 
     550                 :          0 : std::string State::toStringSearch() const
     551                 :            : {
     552                 :          0 :   std::stringstream ss;
     553                 :          0 :   ss << "activeQuants = " << d_numActiveQuant.get();
     554                 :          0 :   return ss.str();
     555                 :          0 : }
     556                 :            : 
     557                 :          0 : std::string State::toStringDebugSearch() const
     558                 :            : {
     559                 :          0 :   std::stringstream ss;
     560                 :          0 :   ss << "activeQuants = " << d_numActiveQuant.get() << "[";
     561                 :          0 :   size_t nqc = 0;
     562         [ -  - ]:          0 :   for (const std::pair<const Node, QuantInfo>& q : d_quantInfo)
     563                 :            :   {
     564         [ -  - ]:          0 :     if (q.second.isActive())
     565                 :            :     {
     566                 :          0 :       ss << " " << q.first.getId();
     567                 :          0 :       nqc++;
     568                 :            :     }
     569                 :            :   }
     570                 :          0 :   ss << " ]";
     571                 :            :   (void)nqc;
     572                 :          0 :   Assert(nqc == d_numActiveQuant.get()) << "Active quant mismatch " << ss.str();
     573                 :          0 :   return ss.str();
     574                 :          0 : }
     575                 :            : 
     576                 :            : }  // namespace ieval
     577                 :            : }  // namespace quantifiers
     578                 :            : }  // namespace theory
     579                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14