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: 2024-09-04 11:14:07 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-2024 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                 :      40493 : InstantiationEngine::InstantiationEngine(Env& env,
      36                 :            :                                          QuantifiersState& qs,
      37                 :            :                                          QuantifiersInferenceManager& qim,
      38                 :            :                                          QuantifiersRegistry& qr,
      39                 :      40493 :                                          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                 :      40493 :       d_quant_rel(nullptr)
      47                 :            : {
      48         [ +  + ]:      40493 :   if (options().quantifiers.relevantTriggers)
      49                 :            :   {
      50                 :          5 :     d_quant_rel.reset(new quantifiers::QuantRelevance(env));
      51                 :            :   }
      52         [ +  - ]:      40493 :   if (options().quantifiers.eMatching)
      53                 :            :   {
      54                 :            :     // these are the instantiation strategies for E-matching
      55                 :            :     // user-provided patterns
      56         [ +  - ]:      40493 :     if (options().quantifiers.userPatternsQuant != options::UserPatMode::IGNORE)
      57                 :            :     {
      58                 :      40493 :       d_isup.reset(
      59                 :      40493 :           new InstStrategyUserPatterns(d_env, d_trdb, qs, qim, qr, tr));
      60                 :      40493 :       d_instStrategies.push_back(d_isup.get());
      61                 :            :     }
      62                 :            : 
      63                 :            :     // auto-generated patterns
      64                 :      40493 :     d_i_ag.reset(new InstStrategyAutoGenTriggers(
      65                 :      40493 :         d_env, d_trdb, qs, qim, qr, tr, d_quant_rel.get()));
      66                 :      40493 :     d_instStrategies.push_back(d_i_ag.get());
      67                 :            :   }
      68                 :      40493 : }
      69                 :            : 
      70                 :      80494 : InstantiationEngine::~InstantiationEngine() {}
      71                 :            : 
      72                 :          0 : std::string InstantiationEngine::identify() const { return "ematching"; }
      73                 :            : 
      74                 :      35932 : void InstantiationEngine::presolve() {
      75         [ +  + ]:     107796 :   for( unsigned i=0; i<d_instStrategies.size(); ++i ){
      76                 :      71864 :     d_instStrategies[i]->presolve();
      77                 :            :   }
      78                 :      35932 : }
      79                 :            : 
      80                 :       5117 : void InstantiationEngine::doInstantiationRound( Theory::Effort effort ){
      81                 :       5117 :   size_t lastWaiting = d_qim.numPendingLemmas();
      82                 :            :   //iterate over an internal effort level e
      83                 :       5117 :   int e = 0;
      84         [ +  + ]:       5117 :   int eLimit = effort==Theory::EFFORT_LAST_CALL ? 10 : 2;
      85                 :       5117 :   bool finished = false;
      86                 :            :   //while unfinished, try effort level=0,1,2....
      87 [ +  + ][ +  - ]:      15353 :   while( !finished && e<=eLimit ){
      88         [ +  - ]:      10241 :     Trace("inst-engine-debug") << "IE: Prepare instantiation (" << e << ")." << std::endl;
      89                 :      10241 :     finished = true;
      90                 :            :     //instantiate each quantifier
      91         [ +  + ]:     184904 :     for( unsigned i=0; i<d_quants.size(); i++ ){
      92                 :     174668 :       Node q = d_quants[i];
      93         [ +  - ]:     174668 :       Trace("inst-engine-debug") << "IE: Instantiate " << q << "..." << std::endl;
      94                 :            :       //int e_use = d_quantEngine->getRelevance( q )==-1 ? e - 1 : e;
      95                 :     174668 :       int e_use = e;
      96         [ +  - ]:     174668 :       if( e_use>=0 ){
      97         [ +  - ]:     174668 :         Trace("inst-engine-debug") << "inst-engine : " << q << std::endl;
      98                 :            :         //check each instantiation strategy
      99         [ +  + ]:     523999 :         for( unsigned j=0; j<d_instStrategies.size(); j++ ){
     100                 :     349336 :           InstStrategy* is = d_instStrategies[j];
     101 [ +  - ][ -  + ]:     349336 :           Trace("inst-engine-debug") << "Do " << is->identify() << " " << e_use << std::endl;
                 [ -  - ]
     102                 :     349336 :           InstStrategyStatus quantStatus = is->process(q, effort, e_use);
     103         [ +  - ]:     698672 :           Trace("inst-engine-debug")
     104                 :          0 :               << " -> unfinished= "
     105                 :          0 :               << (quantStatus == InstStrategyStatus::STATUS_UNFINISHED)
     106                 :     349336 :               << ", conflict=" << d_qstate.isInConflict() << std::endl;
     107         [ +  + ]:     349336 :           if (d_qstate.isInConflict())
     108                 :            :           {
     109                 :          5 :             return;
     110                 :            :           }
     111         [ +  + ]:     349331 :           else if (quantStatus == InstStrategyStatus::STATUS_UNFINISHED)
     112                 :            :           {
     113                 :     146016 :             finished = false;
     114                 :            :           }
     115                 :            :         }
     116                 :            :       }
     117                 :            :     }
     118                 :            :     //do not consider another level if already added lemma at this level
     119         [ +  + ]:      10236 :     if (d_qim.numPendingLemmas() > lastWaiting)
     120                 :            :     {
     121                 :       2879 :       finished = true;
     122                 :            :     }
     123                 :      10236 :     e++;
     124                 :            :   }
     125                 :            : }
     126                 :            : 
     127                 :     112214 : bool InstantiationEngine::needsCheck( Theory::Effort e ){
     128                 :     112214 :   return d_qstate.getInstWhenNeedsCheck(e);
     129                 :            : }
     130                 :            : 
     131                 :      45016 : void InstantiationEngine::reset_round( Theory::Effort e ){
     132                 :            :   //if not, proceed to instantiation round
     133                 :            :   //reset the instantiation strategies
     134         [ +  + ]:     135048 :   for( unsigned i=0; i<d_instStrategies.size(); ++i ){
     135                 :      90032 :     InstStrategy* is = d_instStrategies[i];
     136                 :      90032 :     is->processResetInstantiationRound( e );
     137                 :            :   }
     138                 :      45016 : }
     139                 :            : 
     140                 :      87815 : void InstantiationEngine::check(Theory::Effort e, QEffort quant_e)
     141                 :            : {
     142                 :      87815 :   CodeTimer codeTimer(d_qstate.getStats().d_ematching_time);
     143         [ +  + ]:      87815 :   if (quant_e != QEFFORT_STANDARD)
     144                 :            :   {
     145                 :      59454 :     return;
     146                 :            :   }
     147                 :      28361 :   beginCallDebug();
     148                 :            :   // collect all active quantified formulas belonging to this
     149                 :      28361 :   bool quantActive = false;
     150                 :      28361 :   d_quants.clear();
     151                 :      28361 :   FirstOrderModel* m = d_treg.getModel();
     152                 :      28361 :   size_t nquant = m->getNumAssertedQuantifiers();
     153         [ +  + ]:     144226 :   for (size_t i = 0; i < nquant; i++)
     154                 :            :   {
     155                 :     231730 :     Node q = m->getAssertedQuantifier(i, true);
     156                 :     115865 :     if (shouldProcess(q) && m->isQuantifierActive(q))
     157                 :            :     {
     158                 :      87333 :       quantActive = true;
     159                 :      87333 :       d_quants.push_back(q);
     160                 :            :     }
     161                 :            :   }
     162         [ +  - ]:      56722 :   Trace("inst-engine-debug")
     163                 :      28361 :       << "InstEngine: check: # asserted quantifiers " << d_quants.size() << "/";
     164         [ +  - ]:      28361 :   Trace("inst-engine-debug") << nquant << " " << quantActive << std::endl;
     165         [ +  + ]:      28361 :   if (quantActive)
     166                 :            :   {
     167                 :       5117 :     doInstantiationRound(e);
     168                 :            :   }
     169                 :            :   else
     170                 :            :   {
     171                 :      23244 :     d_quants.clear();
     172                 :            :   }
     173                 :      28361 :   endCallDebug();
     174                 :            : }
     175                 :            : 
     176                 :       1257 : bool InstantiationEngine::checkCompleteFor( Node q ) {
     177                 :            :   //TODO?
     178                 :       1257 :   return false;
     179                 :            : }
     180                 :            : 
     181                 :      48163 : void InstantiationEngine::checkOwnership(Node q)
     182                 :            : {
     183                 :      48163 :   if (options().quantifiers.userPatternsQuant == options::UserPatMode::STRICT
     184 [ +  + ][ +  - ]:      48163 :       && q.getNumChildren() == 3)
                 [ +  + ]
     185                 :            :   {
     186                 :            :     //if strict triggers, take ownership of this quantified formula
     187         [ +  + ]:         35 :     if (QuantAttributes::hasPattern(q))
     188                 :            :     {
     189                 :          5 :       d_qreg.setOwner(q, this, 1);
     190                 :            :     }
     191                 :            :   }
     192                 :      48163 : }
     193                 :            : 
     194                 :      48163 : void InstantiationEngine::registerQuantifier(Node q)
     195                 :            : {
     196         [ +  + ]:      48163 :   if (!shouldProcess(q))
     197                 :            :   {
     198                 :       6157 :     return;
     199                 :            :   }
     200         [ +  + ]:      42006 :   if (d_quant_rel)
     201                 :            :   {
     202                 :        458 :     d_quant_rel->registerQuantifier(q);
     203                 :            :   }
     204                 :            :   // take into account user patterns
     205         [ +  + ]:      42006 :   if (q.getNumChildren() == 3)
     206                 :            :   {
     207                 :      23703 :     Node subsPat = d_qreg.substituteBoundVariablesToInstConstants(q[2], q);
     208                 :            :     // add patterns
     209         [ +  + ]:      16318 :     for (const Node& p : subsPat)
     210                 :            :     {
     211         [ +  + ]:       8417 :       if (p.getKind() == Kind::INST_PATTERN)
     212                 :            :       {
     213                 :       7329 :         addUserPattern(q, p);
     214                 :            :       }
     215         [ +  + ]:       1088 :       else if (p.getKind() == Kind::INST_NO_PATTERN)
     216                 :            :       {
     217                 :         10 :         addUserNoPattern(q, p);
     218                 :            :       }
     219                 :            :     }
     220                 :            :   }
     221                 :            : }
     222                 :            : 
     223                 :       7329 : void InstantiationEngine::addUserPattern(Node q, Node pat) {
     224         [ +  - ]:       7329 :   if (d_isup) {
     225                 :       7329 :     d_isup->addUserPattern(q, pat);
     226                 :            :   }
     227                 :       7329 : }
     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                 :     164028 : bool InstantiationEngine::shouldProcess(Node q)
     236                 :            : {
     237         [ +  + ]:     164028 :   if (!d_qreg.hasOwnership(q, this))
     238                 :            :   {
     239                 :      30479 :     return false;
     240                 :            :   }
     241                 :            :   // also ignore internal quantifiers
     242                 :     133549 :   QuantAttributes& qattr = d_qreg.getQuantAttributes();
     243         [ +  + ]:     133549 :   if (qattr.isQuantBounded(q))
     244                 :            :   {
     245                 :       4158 :     return false;
     246                 :            :   }
     247                 :     129391 :   return true;
     248                 :            : }
     249                 :            : 
     250                 :            : }  // namespace quantifiers
     251                 :            : }  // namespace theory
     252                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14