LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/quantifiers/ematching - instantiation_engine.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 109 112 97.3 %
Date: 2025-02-10 13:35:52 Functions: 14 15 93.3 %
Branches: 63 80 78.8 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Andrew Reynolds, Morgan Deters, Gereon Kremer
       4                 :            :  *
       5                 :            :  * This file is part of the cvc5 project.
       6                 :            :  *
       7                 :            :  * Copyright (c) 2009-2025 by the authors listed in the file AUTHORS
       8                 :            :  * in the top-level source directory and their institutional affiliations.
       9                 :            :  * All rights reserved.  See the file COPYING in the top-level source
      10                 :            :  * directory for licensing information.
      11                 :            :  * ****************************************************************************
      12                 :            :  *
      13                 :            :  * Implementation of instantiation engine class
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "theory/quantifiers/ematching/instantiation_engine.h"
      17                 :            : 
      18                 :            : #include "options/quantifiers_options.h"
      19                 :            : #include "theory/quantifiers/ematching/inst_strategy_e_matching.h"
      20                 :            : #include "theory/quantifiers/ematching/inst_strategy_e_matching_user.h"
      21                 :            : #include "theory/quantifiers/ematching/trigger.h"
      22                 :            : #include "theory/quantifiers/first_order_model.h"
      23                 :            : #include "theory/quantifiers/quantifiers_attributes.h"
      24                 :            : #include "theory/quantifiers/term_database.h"
      25                 :            : #include "theory/quantifiers/term_util.h"
      26                 :            : 
      27                 :            : using namespace cvc5::internal::kind;
      28                 :            : using namespace cvc5::context;
      29                 :            : using namespace cvc5::internal::theory::quantifiers::inst;
      30                 :            : 
      31                 :            : namespace cvc5::internal {
      32                 :            : namespace theory {
      33                 :            : namespace quantifiers {
      34                 :            : 
      35                 :      42907 : InstantiationEngine::InstantiationEngine(Env& env,
      36                 :            :                                          QuantifiersState& qs,
      37                 :            :                                          QuantifiersInferenceManager& qim,
      38                 :            :                                          QuantifiersRegistry& qr,
      39                 :      42907 :                                          TermRegistry& tr)
      40                 :            :     : QuantifiersModule(env, qs, qim, qr, tr),
      41                 :            :       d_instStrategies(),
      42                 :            :       d_isup(),
      43                 :            :       d_i_ag(),
      44                 :            :       d_quants(),
      45                 :            :       d_trdb(d_env, qs, qim, qr, tr),
      46                 :      42907 :       d_quant_rel(nullptr)
      47                 :            : {
      48         [ +  + ]:      42907 :   if (options().quantifiers.relevantTriggers)
      49                 :            :   {
      50                 :          5 :     d_quant_rel.reset(new quantifiers::QuantRelevance(env));
      51                 :            :   }
      52         [ +  - ]:      42907 :   if (options().quantifiers.eMatching)
      53                 :            :   {
      54                 :            :     // these are the instantiation strategies for E-matching
      55                 :            :     // user-provided patterns
      56         [ +  - ]:      42907 :     if (options().quantifiers.userPatternsQuant != options::UserPatMode::IGNORE)
      57                 :            :     {
      58                 :      42907 :       d_isup.reset(
      59                 :      42907 :           new InstStrategyUserPatterns(d_env, d_trdb, qs, qim, qr, tr));
      60                 :      42907 :       d_instStrategies.push_back(d_isup.get());
      61                 :            :     }
      62                 :            : 
      63                 :            :     // auto-generated patterns
      64                 :      42907 :     d_i_ag.reset(new InstStrategyAutoGenTriggers(
      65                 :      42907 :         d_env, d_trdb, qs, qim, qr, tr, d_quant_rel.get()));
      66                 :      42907 :     d_instStrategies.push_back(d_i_ag.get());
      67                 :            :   }
      68                 :      42907 : }
      69                 :            : 
      70                 :      85322 : InstantiationEngine::~InstantiationEngine() {}
      71                 :            : 
      72                 :          0 : std::string InstantiationEngine::identify() const { return "ematching"; }
      73                 :            : 
      74                 :      38272 : void InstantiationEngine::presolve() {
      75         [ +  + ]:     114816 :   for( unsigned i=0; i<d_instStrategies.size(); ++i ){
      76                 :      76544 :     d_instStrategies[i]->presolve();
      77                 :            :   }
      78                 :      38272 : }
      79                 :            : 
      80                 :       6544 : void InstantiationEngine::doInstantiationRound( Theory::Effort effort ){
      81                 :       6544 :   size_t lastWaiting = d_qim.numPendingLemmas();
      82                 :            :   //iterate over an internal effort level e
      83                 :       6544 :   int e = 0;
      84         [ +  + ]:       6544 :   int eLimit = effort==Theory::EFFORT_LAST_CALL ? 10 : 2;
      85                 :       6544 :   bool finished = false;
      86                 :            :   //while unfinished, try effort level=0,1,2....
      87 [ +  + ][ +  - ]:      19633 :   while( !finished && e<=eLimit ){
      88         [ +  - ]:      13096 :     Trace("inst-engine-debug") << "IE: Prepare instantiation (" << e << ")." << std::endl;
      89                 :      13096 :     finished = true;
      90                 :            :     //instantiate each quantifier
      91         [ +  + ]:     219006 :     for( unsigned i=0; i<d_quants.size(); i++ ){
      92                 :     205917 :       Node q = d_quants[i];
      93         [ +  - ]:     205917 :       Trace("inst-engine-debug") << "IE: Instantiate " << q << "..." << std::endl;
      94                 :            :       //int e_use = d_quantEngine->getRelevance( q )==-1 ? e - 1 : e;
      95                 :     205917 :       int e_use = e;
      96         [ +  - ]:     205917 :       if( e_use>=0 ){
      97         [ +  - ]:     205917 :         Trace("inst-engine-debug") << "inst-engine : " << q << std::endl;
      98                 :            :         //check each instantiation strategy
      99         [ +  + ]:     617744 :         for( unsigned j=0; j<d_instStrategies.size(); j++ ){
     100                 :     411834 :           InstStrategy* is = d_instStrategies[j];
     101 [ +  - ][ -  + ]:     411834 :           Trace("inst-engine-debug") << "Do " << is->identify() << " " << e_use << std::endl;
                 [ -  - ]
     102                 :     411834 :           InstStrategyStatus quantStatus = is->process(q, effort, e_use);
     103         [ +  - ]:     823668 :           Trace("inst-engine-debug")
     104                 :          0 :               << " -> unfinished= "
     105                 :          0 :               << (quantStatus == InstStrategyStatus::STATUS_UNFINISHED)
     106                 :     411834 :               << ", conflict=" << d_qstate.isInConflict() << std::endl;
     107         [ +  + ]:     411834 :           if (d_qstate.isInConflict())
     108                 :            :           {
     109                 :          7 :             return;
     110                 :            :           }
     111         [ +  + ]:     411827 :           else if (quantStatus == InstStrategyStatus::STATUS_UNFINISHED)
     112                 :            :           {
     113                 :     174063 :             finished = false;
     114                 :            :           }
     115                 :            :         }
     116                 :            :       }
     117                 :            :     }
     118                 :            :     //do not consider another level if already added lemma at this level
     119         [ +  + ]:      13089 :     if (d_qim.numPendingLemmas() > lastWaiting)
     120                 :            :     {
     121                 :       3744 :       finished = true;
     122                 :            :     }
     123                 :      13089 :     e++;
     124                 :            :   }
     125                 :            : }
     126                 :            : 
     127                 :     126889 : bool InstantiationEngine::needsCheck( Theory::Effort e ){
     128                 :     126889 :   return d_qstate.getInstWhenNeedsCheck(e);
     129                 :            : }
     130                 :            : 
     131                 :      53206 : void InstantiationEngine::reset_round( Theory::Effort e ){
     132                 :            :   //if not, proceed to instantiation round
     133                 :            :   //reset the instantiation strategies
     134         [ +  + ]:     159618 :   for( unsigned i=0; i<d_instStrategies.size(); ++i ){
     135                 :     106412 :     InstStrategy* is = d_instStrategies[i];
     136                 :     106412 :     is->processResetInstantiationRound( e );
     137                 :            :   }
     138                 :      53206 : }
     139                 :            : 
     140                 :      98739 : void InstantiationEngine::check(Theory::Effort e, QEffort quant_e)
     141                 :            : {
     142                 :      98739 :   CodeTimer codeTimer(d_qstate.getStats().d_ematching_time);
     143         [ +  + ]:      98739 :   if (quant_e != QEFFORT_STANDARD)
     144                 :            :   {
     145                 :      66518 :     return;
     146                 :            :   }
     147                 :      32221 :   beginCallDebug();
     148                 :            :   // collect all active quantified formulas belonging to this
     149                 :      32221 :   bool quantActive = false;
     150                 :      32221 :   d_quants.clear();
     151                 :      32221 :   FirstOrderModel* m = d_treg.getModel();
     152                 :      32221 :   size_t nquant = m->getNumAssertedQuantifiers();
     153         [ +  + ]:     166578 :   for (size_t i = 0; i < nquant; i++)
     154                 :            :   {
     155                 :     268714 :     Node q = m->getAssertedQuantifier(i, true);
     156                 :     134357 :     if (shouldProcess(q) && m->isQuantifierActive(q))
     157                 :            :     {
     158                 :     102959 :       quantActive = true;
     159                 :     102959 :       d_quants.push_back(q);
     160                 :            :     }
     161                 :            :   }
     162         [ +  - ]:      64442 :   Trace("inst-engine-debug")
     163                 :      32221 :       << "InstEngine: check: # asserted quantifiers " << d_quants.size() << "/";
     164         [ +  - ]:      32221 :   Trace("inst-engine-debug") << nquant << " " << quantActive << std::endl;
     165         [ +  + ]:      32221 :   if (quantActive)
     166                 :            :   {
     167                 :       6544 :     doInstantiationRound(e);
     168                 :            :   }
     169                 :            :   else
     170                 :            :   {
     171                 :      25677 :     d_quants.clear();
     172                 :            :   }
     173                 :      32221 :   endCallDebug();
     174                 :            : }
     175                 :            : 
     176                 :       1461 : bool InstantiationEngine::checkCompleteFor( Node q ) {
     177                 :            :   //TODO?
     178                 :       1461 :   return false;
     179                 :            : }
     180                 :            : 
     181                 :      55608 : void InstantiationEngine::checkOwnership(Node q)
     182                 :            : {
     183                 :      55608 :   if (options().quantifiers.userPatternsQuant == options::UserPatMode::STRICT
     184 [ +  + ][ +  - ]:      55608 :       && q.getNumChildren() == 3)
                 [ +  + ]
     185                 :            :   {
     186                 :            :     //if strict triggers, take ownership of this quantified formula
     187         [ +  + ]:         42 :     if (QuantAttributes::hasPattern(q))
     188                 :            :     {
     189                 :          6 :       d_qreg.setOwner(q, this, 1);
     190                 :            :     }
     191                 :            :   }
     192                 :      55608 : }
     193                 :            : 
     194                 :      55608 : void InstantiationEngine::registerQuantifier(Node q)
     195                 :            : {
     196         [ +  + ]:      55608 :   if (!shouldProcess(q))
     197                 :            :   {
     198                 :       6345 :     return;
     199                 :            :   }
     200         [ +  + ]:      49263 :   if (d_quant_rel)
     201                 :            :   {
     202                 :        458 :     d_quant_rel->registerQuantifier(q);
     203                 :            :   }
     204                 :            :   // take into account user patterns
     205         [ +  + ]:      49263 :   if (q.getNumChildren() == 3)
     206                 :            :   {
     207                 :      26013 :     Node subsPat = d_qreg.substituteBoundVariablesToInstConstants(q[2], q);
     208                 :            :     // add patterns
     209         [ +  + ]:      17833 :     for (const Node& p : subsPat)
     210                 :            :     {
     211         [ +  + ]:       9162 :       if (p.getKind() == Kind::INST_PATTERN)
     212                 :            :       {
     213                 :       7819 :         addUserPattern(q, p);
     214                 :            :       }
     215         [ +  + ]:       1343 :       else if (p.getKind() == Kind::INST_NO_PATTERN)
     216                 :            :       {
     217                 :         10 :         addUserNoPattern(q, p);
     218                 :            :       }
     219                 :            :     }
     220                 :            :   }
     221                 :            : }
     222                 :            : 
     223                 :       7819 : void InstantiationEngine::addUserPattern(Node q, Node pat) {
     224         [ +  - ]:       7819 :   if (d_isup) {
     225                 :       7819 :     d_isup->addUserPattern(q, pat);
     226                 :            :   }
     227                 :       7819 : }
     228                 :            : 
     229                 :         10 : void InstantiationEngine::addUserNoPattern(Node q, Node pat) {
     230         [ +  - ]:         10 :   if (d_i_ag) {
     231                 :         10 :     d_i_ag->addUserNoPattern(q, pat);
     232                 :            :   }
     233                 :         10 : }
     234                 :            : 
     235                 :     189965 : bool InstantiationEngine::shouldProcess(Node q)
     236                 :            : {
     237         [ +  + ]:     189965 :   if (!d_qreg.hasOwnership(q, this))
     238                 :            :   {
     239                 :      33262 :     return false;
     240                 :            :   }
     241                 :            :   // also ignore internal quantifiers
     242                 :     156703 :   QuantAttributes& qattr = d_qreg.getQuantAttributes();
     243         [ +  + ]:     156703 :   if (qattr.isQuantBounded(q))
     244                 :            :   {
     245                 :       4429 :     return false;
     246                 :            :   }
     247                 :     152274 :   return true;
     248                 :            : }
     249                 :            : 
     250                 :            : }  // namespace quantifiers
     251                 :            : }  // namespace theory
     252                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14