LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory - quantifiers_engine.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 299 360 83.1 %
Date: 2024-08-31 11:49:51 Functions: 24 28 85.7 %
Branches: 214 364 58.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 quantifiers engine class.
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "theory/quantifiers_engine.h"
      17                 :            : 
      18                 :            : #include "options/base_options.h"
      19                 :            : #include "options/printer_options.h"
      20                 :            : #include "options/quantifiers_options.h"
      21                 :            : #include "options/smt_options.h"
      22                 :            : #include "options/strings_options.h"
      23                 :            : #include "options/uf_options.h"
      24                 :            : #include "theory/quantifiers/equality_query.h"
      25                 :            : #include "theory/quantifiers/first_order_model.h"
      26                 :            : #include "theory/quantifiers/fmf/first_order_model_fmc.h"
      27                 :            : #include "theory/quantifiers/fmf/full_model_check.h"
      28                 :            : #include "theory/quantifiers/fmf/model_builder.h"
      29                 :            : #include "theory/quantifiers/ieval/inst_evaluator_manager.h"
      30                 :            : #include "theory/quantifiers/quant_module.h"
      31                 :            : #include "theory/quantifiers/quantifiers_inference_manager.h"
      32                 :            : #include "theory/quantifiers/quantifiers_modules.h"
      33                 :            : #include "theory/quantifiers/quantifiers_registry.h"
      34                 :            : #include "theory/quantifiers/quantifiers_rewriter.h"
      35                 :            : #include "theory/quantifiers/quantifiers_state.h"
      36                 :            : #include "theory/quantifiers/quantifiers_statistics.h"
      37                 :            : #include "theory/quantifiers/relevant_domain.h"
      38                 :            : #include "theory/quantifiers/skolemize.h"
      39                 :            : #include "theory/quantifiers/term_registry.h"
      40                 :            : #include "theory/theory_engine.h"
      41                 :            : 
      42                 :            : using namespace std;
      43                 :            : using namespace cvc5::internal::kind;
      44                 :            : using namespace cvc5::internal::theory::quantifiers;
      45                 :            : 
      46                 :            : namespace cvc5::internal {
      47                 :            : namespace theory {
      48                 :            : 
      49                 :      47593 : QuantifiersEngine::QuantifiersEngine(Env& env,
      50                 :            :                                      QuantifiersState& qs,
      51                 :            :                                      QuantifiersRegistry& qr,
      52                 :            :                                      TermRegistry& tr,
      53                 :            :                                      QuantifiersInferenceManager& qim,
      54                 :      47593 :                                      ProofNodeManager* pnm)
      55                 :            :     : EnvObj(env),
      56                 :            :       d_qstate(qs),
      57                 :            :       d_qim(qim),
      58                 :            :       d_te(nullptr),
      59                 :            :       d_pnm(pnm),
      60                 :            :       d_qreg(qr),
      61                 :            :       d_treg(tr),
      62                 :            :       d_model(nullptr),
      63                 :      95186 :       d_quants_prereg(userContext()),
      64                 :      95186 :       d_quants_red(userContext()),
      65                 :      47593 :       d_numInstRoundsLemma(0)
      66                 :            : {
      67                 :      47593 :   options::FmfMbqiMode mmode = options().quantifiers.fmfMbqiMode;
      68         [ +  - ]:      95186 :   Trace("quant-init-debug")
      69                 :          0 :       << "Initialize model engine, mbqi : " << mmode << " "
      70                 :      47593 :       << options().quantifiers.fmfBound << std::endl;
      71                 :            :   // Finite model finding requires specialized ways of building the model.
      72                 :            :   // We require constructing the model here, since it is required for
      73                 :            :   // initializing the CombinationEngine and the rest of quantifiers engine.
      74         [ +  + ]:      94990 :   if (options().quantifiers.fmfBound || options().strings.stringExp
      75 [ +  + ][ +  + ]:      95161 :       || (options().quantifiers.finiteModelFind
                 [ +  + ]
      76         [ +  + ]:        171 :           && (mmode == options::FmfMbqiMode::FMC
      77         [ -  + ]:          2 :               || mmode == options::FmfMbqiMode::TRUST)))
      78                 :            :   {
      79         [ +  - ]:      30736 :     Trace("quant-init-debug") << "...make fmc builder." << std::endl;
      80                 :      30736 :     d_builder.reset(new fmcheck::FullModelChecker(env, qs, qim, qr, tr));
      81                 :            :   }
      82                 :            :   else
      83                 :            :   {
      84         [ +  - ]:      16857 :     Trace("quant-init-debug") << "...make default model builder." << std::endl;
      85                 :      16857 :     d_builder.reset(new QModelBuilder(env, qs, qim, qr, tr));
      86                 :            :   }
      87                 :            :   // set the model object
      88                 :      47593 :   d_builder->finishInit();
      89                 :      47593 :   d_model = d_builder->getModel();
      90                 :            : 
      91                 :            :   // Finish initializing the term registry by hooking it up to the model and the
      92                 :            :   // inference manager. The former is required since theories are not given
      93                 :            :   // access to the model in their constructors currently.
      94                 :            :   // The latter is required due to a cyclic dependency between the term
      95                 :            :   // database and the instantiate module. Term database needs inference manager
      96                 :            :   // since it sends out lemmas when term indexing is inconsistent, instantiate
      97                 :            :   // needs term database for entailment checks.
      98                 :      47593 :   d_treg.finishInit(d_model, &d_qim);
      99                 :            : 
     100                 :            :   // initialize the utilities
     101                 :      47593 :   d_util.push_back(d_model->getEqualityQuery());
     102                 :            :   // quantifiers registry must come before the remaining utilities
     103                 :      47593 :   d_util.push_back(&d_qreg);
     104                 :      47593 :   d_util.push_back(tr.getTermDatabase());
     105                 :      47593 :   d_util.push_back(qim.getInstantiate());
     106                 :      47593 :   d_util.push_back(tr.getTermPools());
     107                 :      47593 :   d_util.push_back(tr.getInstEvaluatorManager());
     108                 :      47593 : }
     109                 :            : 
     110                 :      94674 : QuantifiersEngine::~QuantifiersEngine() {}
     111                 :            : 
     112                 :      41166 : void QuantifiersEngine::finishInit(TheoryEngine* te)
     113                 :            : {
     114                 :            :   // connect the quantifiers model to the underlying theory model
     115                 :      41166 :   d_model->finishInit(te->getModel());
     116                 :      41166 :   d_te = te;
     117                 :            :   // Initialize the modules and the utilities here.
     118                 :      41166 :   d_qmodules.reset(new QuantifiersModules());
     119                 :      82332 :   d_qmodules->initialize(
     120                 :      41166 :       d_env, d_qstate, d_qim, d_qreg, d_treg, d_builder.get(), d_modules);
     121         [ +  + ]:      41166 :   if (d_qmodules->d_rel_dom.get())
     122                 :            :   {
     123                 :        274 :     d_util.push_back(d_qmodules->d_rel_dom.get());
     124                 :            :   }
     125                 :            : 
     126                 :            :   // handle any circular dependencies
     127                 :            : 
     128                 :            :   // quantifiers bound inference needs to be informed of the bounded integers
     129                 :            :   // module, which has information about which quantifiers have finite bounds
     130                 :      41166 :   d_qreg.getQuantifiersBoundInference().finishInit(d_qmodules->d_bint.get());
     131                 :      41166 : }
     132                 :            : 
     133                 :          0 : QuantifiersRegistry& QuantifiersEngine::getQuantifiersRegistry()
     134                 :            : {
     135                 :          0 :   return d_qreg;
     136                 :            : }
     137                 :            : 
     138                 :      41166 : QModelBuilder* QuantifiersEngine::getModelBuilder() const
     139                 :            : {
     140                 :      41166 :   return d_builder.get();
     141                 :            : }
     142                 :            : 
     143                 :            : /// !!!!!!!!!!!!!! temporary (project #15)
     144                 :            : 
     145                 :       7397 : TermDbSygus* QuantifiersEngine::getTermDatabaseSygus() const
     146                 :            : {
     147                 :       7397 :   return d_treg.getTermDatabaseSygus();
     148                 :            : }
     149                 :            : /// !!!!!!!!!!!!!!
     150                 :            : 
     151                 :      36612 : void QuantifiersEngine::presolve() {
     152         [ +  - ]:      36612 :   Trace("quant-engine-proc") << "QuantifiersEngine : presolve " << std::endl;
     153                 :      36612 :   d_numInstRoundsLemma = 0;
     154                 :      36612 :   d_qim.clearPending();
     155         [ +  + ]:     256552 :   for (QuantifiersUtil*& u : d_util)
     156                 :            :   {
     157                 :     219940 :     u->presolve();
     158                 :            :   }
     159         [ +  + ]:     263118 :   for (QuantifiersModule*& mdl : d_modules)
     160                 :            :   {
     161                 :     226506 :     mdl->presolve();
     162                 :            :   }
     163                 :      36612 : }
     164                 :            : 
     165                 :      46644 : void QuantifiersEngine::ppNotifyAssertions(
     166                 :            :     const std::vector<Node>& assertions) {
     167         [ +  - ]:      93288 :   Trace("quant-engine-proc")
     168                 :      46644 :       << "ppNotifyAssertions in QE, #assertions = " << assertions.size()
     169                 :      46644 :       << std::endl;
     170         [ +  + ]:      46644 :   if (options().quantifiers.instMaxLevel != -1)
     171                 :            :   {
     172         [ +  + ]:        306 :     for (const Node& a : assertions)
     173                 :            :     {
     174                 :        301 :       QuantAttributes::setInstantiationLevelAttr(a, 0);
     175                 :            :     }
     176                 :            :   }
     177         [ +  + ]:      46644 :   if (options().quantifiers.sygus)
     178                 :            :   {
     179                 :       6301 :     SynthEngine* sye = d_qmodules->d_synth_e.get();
     180         [ +  + ]:      19126 :     for (const Node& a : assertions)
     181                 :            :     {
     182                 :      12825 :       sye->ppNotifyAssertion(a);
     183                 :            :     }
     184                 :            :   }
     185                 :            :   /* The SyGuS instantiation module needs a global view of all available
     186                 :            :    * assertions to collect global terms that get added to each grammar.
     187                 :            :    */
     188         [ +  + ]:      46644 :   if (options().quantifiers.sygusInst)
     189                 :            :   {
     190                 :        128 :     SygusInst* si = d_qmodules->d_sygus_inst.get();
     191                 :        128 :     si->ppNotifyAssertions(assertions);
     192                 :            :   }
     193                 :      46644 : }
     194                 :            : 
     195                 :     194793 : void QuantifiersEngine::check( Theory::Effort e ){
     196                 :     194793 :   QuantifiersStatistics& stats = d_qstate.getStats();
     197                 :     194798 :   CodeTimer codeTimer(stats.d_time);
     198 [ -  + ][ -  + ]:     194793 :   Assert(d_qstate.getEqualityEngine() != nullptr);
                 [ -  - ]
     199         [ +  + ]:     194793 :   if (!d_qstate.getEqualityEngine()->consistent())
     200                 :            :   {
     201         [ +  - ]:          2 :     Trace("quant-engine-debug") << "Master equality engine not consistent, return." << std::endl;
     202                 :          2 :     return;
     203                 :            :   }
     204         [ -  + ]:     194791 :   if (d_qstate.isInConflict())
     205                 :            :   {
     206         [ -  - ]:          0 :     if (e < Theory::EFFORT_LAST_CALL)
     207                 :            :     {
     208                 :            :       // this can happen in rare cases when quantifiers is the first to realize
     209                 :            :       // there is a quantifier-free conflict, for example, when it discovers
     210                 :            :       // disequal and congruent terms in the master equality engine during
     211                 :            :       // term indexing. In such cases, quantifiers reports a "conflicting lemma"
     212                 :            :       // that is, one that is entailed to be false by the current assignment.
     213                 :            :       // If this lemma is not a SAT conflict, we may get another call to full
     214                 :            :       // effort check and the quantifier-free solvers still haven't realized
     215                 :            :       // there is a conflict. In this case, we return, trusting that theory
     216                 :            :       // combination will do the right thing (split on equalities until there is
     217                 :            :       // a conflict at the quantifier-free level).
     218         [ -  - ]:          0 :       Trace("quant-engine-debug")
     219                 :          0 :           << "Conflicting lemma already reported by quantifiers, return."
     220                 :          0 :           << std::endl;
     221                 :          0 :       return;
     222                 :            :     }
     223                 :            :     // we reported what we thought was a conflicting lemma, but now we have
     224                 :            :     // gotten a check at LAST_CALL effort, indicating that the lemma we reported
     225                 :            :     // was not conflicting. This should never happen, but in production mode, we
     226                 :            :     // proceed with the check.
     227                 :          0 :     Assert(false);
     228                 :            :   }
     229                 :     194791 :   bool needsCheck = d_qim.hasPendingLemma();
     230                 :     194791 :   QuantifiersModule::QEffort needsModelE = QuantifiersModule::QEFFORT_NONE;
     231                 :     194796 :   std::vector< QuantifiersModule* > qm;
     232         [ +  + ]:     194791 :   if( d_model->checkNeeded() ){
     233 [ +  + ][ +  + ]:     127961 :     needsCheck = needsCheck || e>=Theory::EFFORT_LAST_CALL;  //always need to check at or above last call
     234         [ +  + ]:     871021 :     for (QuantifiersModule*& mdl : d_modules)
     235                 :            :     {
     236         [ +  + ]:     743060 :       if (mdl->needsCheck(e))
     237                 :            :       {
     238                 :     150584 :         qm.push_back(mdl);
     239                 :     150584 :         needsCheck = true;
     240                 :            :         //can only request model at last call since theory combination can find inconsistencies
     241         [ +  + ]:     150584 :         if( e>=Theory::EFFORT_LAST_CALL ){
     242                 :     114269 :           QuantifiersModule::QEffort me = mdl->needsModel(e);
     243         [ +  + ]:     114269 :           needsModelE = me<needsModelE ? me : needsModelE;
     244                 :            :         }
     245                 :            :       }
     246                 :            :     }
     247                 :            :   }
     248                 :            : 
     249                 :     194791 :   d_qim.reset();
     250                 :     194791 :   bool setModelUnsound = false;
     251                 :     194791 :   IncompleteId setModelUnsoundId = IncompleteId::QUANTIFIERS;
     252                 :     194791 :   if (options().quantifiers.instMaxRounds >= 0
     253 [ +  + ][ +  + ]:     201527 :       && d_numInstRoundsLemma
     254         [ +  + ]:       6736 :              >= static_cast<uint32_t>(options().quantifiers.instMaxRounds))
     255                 :            :   {
     256                 :         64 :     needsCheck = false;
     257                 :         64 :     setModelUnsound = true;
     258                 :         64 :     setModelUnsoundId = IncompleteId::QUANTIFIERS_MAX_INST_ROUNDS;
     259                 :            :   }
     260                 :            : 
     261         [ +  - ]:     194791 :   Trace("quant-engine-debug2") << "Quantifiers Engine call to check, level = " << e << ", needsCheck=" << needsCheck << std::endl;
     262         [ +  + ]:     194791 :   if( needsCheck ){
     263                 :            :     //flush previous lemmas (for instance, if was interrupted), or other lemmas to process
     264                 :      51213 :     d_qim.doPending();
     265         [ +  + ]:      51213 :     if (d_qim.hasSentLemma())
     266                 :            :     {
     267                 :        188 :       return;
     268                 :            :     }
     269                 :            : 
     270                 :      51025 :     double clSet = 0;
     271         [ -  + ]:      51025 :     if( TraceIsOn("quant-engine") ){
     272                 :          0 :       clSet = double(clock())/double(CLOCKS_PER_SEC);
     273         [ -  - ]:          0 :       Trace("quant-engine") << ">>>>> Quantifiers Engine Round, effort = " << e << " <<<<<" << std::endl;
     274                 :            :     }
     275                 :            : 
     276         [ -  + ]:      51025 :     if( TraceIsOn("quant-engine-debug") ){
     277         [ -  - ]:          0 :       Trace("quant-engine-debug") << "Quantifiers Engine check, level = " << e << std::endl;
     278         [ -  - ]:          0 :       Trace("quant-engine-debug")
     279                 :          0 :           << "  depth : " << d_qstate.getInstRoundDepth() << std::endl;
     280         [ -  - ]:          0 :       Trace("quant-engine-debug") << "  modules to check : ";
     281         [ -  - ]:          0 :       for( unsigned i=0; i<qm.size(); i++ ){
     282                 :          0 :         Trace("quant-engine-debug") << qm[i]->identify() << " ";
     283                 :            :       }
     284         [ -  - ]:          0 :       Trace("quant-engine-debug") << std::endl;
     285         [ -  - ]:          0 :       Trace("quant-engine-debug") << "  # quantified formulas = " << d_model->getNumAssertedQuantifiers() << std::endl;
     286         [ -  - ]:          0 :       if (d_qim.hasPendingLemma())
     287                 :            :       {
     288         [ -  - ]:          0 :         Trace("quant-engine-debug")
     289                 :          0 :             << "  lemmas waiting = " << d_qim.numPendingLemmas() << std::endl;
     290                 :            :       }
     291         [ -  - ]:          0 :       Trace("quant-engine-debug")
     292                 :          0 :           << "  Theory engine finished : "
     293                 :          0 :           << !d_qstate.getValuation().needCheck() << std::endl;
     294         [ -  - ]:          0 :       Trace("quant-engine-debug") << "  Needs model effort : " << needsModelE << std::endl;
     295         [ -  - ]:          0 :       Trace("quant-engine-debug")
     296                 :          0 :           << "  In conflict : " << d_qstate.isInConflict() << std::endl;
     297                 :            :     }
     298         [ -  + ]:      51025 :     if( TraceIsOn("quant-engine-ee-pre") ){
     299         [ -  - ]:          0 :       Trace("quant-engine-ee-pre") << "Equality engine (pre-inference): " << std::endl;
     300                 :          0 :       d_qstate.debugPrintEqualityEngine("quant-engine-ee-pre");
     301                 :            :     }
     302         [ -  + ]:      51025 :     if( TraceIsOn("quant-engine-assert") ){
     303         [ -  - ]:          0 :       Trace("quant-engine-assert") << "Assertions : " << std::endl;
     304                 :          0 :       d_te->printAssertions("quant-engine-assert");
     305                 :            :     }
     306                 :            : 
     307                 :            :     //reset utilities
     308         [ +  - ]:      51025 :     Trace("quant-engine-debug") << "Resetting all utilities..." << std::endl;
     309         [ +  + ]:     360585 :     for (QuantifiersUtil*& util : d_util)
     310                 :            :     {
     311 [ +  - ][ -  + ]:     619120 :       Trace("quant-engine-debug2") << "Reset " << util->identify().c_str()
                 [ -  - ]
     312                 :     309560 :                                    << "..." << std::endl;
     313         [ -  + ]:     309560 :       if (!util->reset(e))
     314                 :            :       {
     315                 :          0 :         d_qim.doPending();
     316         [ -  - ]:          0 :         if (d_qim.hasSentLemma())
     317                 :            :         {
     318                 :          0 :           return;
     319                 :            :         }else{
     320                 :            :           //should only fail reset if added a lemma
     321                 :          0 :           Assert(false);
     322                 :            :         }
     323                 :            :       }
     324                 :            :     }
     325                 :            : 
     326         [ -  + ]:      51025 :     if( TraceIsOn("quant-engine-ee") ){
     327         [ -  - ]:          0 :       Trace("quant-engine-ee") << "Equality engine : " << std::endl;
     328                 :          0 :       d_qstate.debugPrintEqualityEngine("quant-engine-ee");
     329                 :            :     }
     330                 :            : 
     331                 :            :     //reset the model
     332         [ +  - ]:      51025 :     Trace("quant-engine-debug") << "Reset model..." << std::endl;
     333                 :      51025 :     d_model->reset_round();
     334                 :            : 
     335                 :            :     //reset the modules
     336         [ +  - ]:      51025 :     Trace("quant-engine-debug") << "Resetting all modules..." << std::endl;
     337         [ +  + ]:     346390 :     for (QuantifiersModule*& mdl : d_modules)
     338                 :            :     {
     339 [ +  - ][ -  + ]:     590730 :       Trace("quant-engine-debug2") << "Reset " << mdl->identify().c_str()
                 [ -  - ]
     340                 :     295365 :                                    << std::endl;
     341                 :     295365 :       mdl->reset_round(e);
     342                 :            :     }
     343         [ +  - ]:      51025 :     Trace("quant-engine-debug") << "Done resetting all modules." << std::endl;
     344                 :            :     //reset may have added lemmas
     345                 :      51025 :     d_qim.doPending();
     346         [ -  + ]:      51025 :     if (d_qim.hasSentLemma())
     347                 :            :     {
     348                 :          0 :       return;
     349                 :            :     }
     350                 :            : 
     351         [ +  + ]:      51025 :     if( e==Theory::EFFORT_LAST_CALL ){
     352                 :      26382 :       ++(stats.d_instantiation_rounds_lc);
     353         [ +  + ]:      24643 :     }else if( e==Theory::EFFORT_FULL ){
     354                 :      24516 :       ++(stats.d_instantiation_rounds);
     355                 :            :     }
     356         [ +  - ]:      51025 :     Trace("quant-engine-debug") << "Check modules that needed check..." << std::endl;
     357                 :     190921 :     for (unsigned qef = QuantifiersModule::QEFFORT_CONFLICT;
     358         [ +  + ]:     190921 :          qef <= QuantifiersModule::QEFFORT_LAST_CALL;
     359                 :            :          ++qef)
     360                 :            :     {
     361                 :     163912 :       QuantifiersModule::QEffort quant_e =
     362                 :            :           static_cast<QuantifiersModule::QEffort>(qef);
     363                 :            :       // Force the theory engine to build the model if any module requested it.
     364         [ +  + ]:     163912 :       if (needsModelE == quant_e)
     365                 :            :       {
     366         [ +  - ]:      23944 :         Trace("quant-engine-debug") << "Build model..." << std::endl;
     367         [ +  + ]:      23944 :         if (!d_te->buildModel())
     368                 :            :         {
     369                 :            :           // If we failed to build the model, flush all pending lemmas and
     370                 :            :           // finish.
     371                 :          7 :           d_qim.doPending();
     372                 :      24011 :           break;
     373                 :            :         }
     374                 :            :       }
     375         [ +  - ]:     163905 :       if (!d_qim.hasSentLemma())
     376                 :            :       {
     377                 :            :         //check each module
     378         [ +  + ]:     633908 :         for (QuantifiersModule*& mdl : qm)
     379                 :            :         {
     380 [ +  - ][ -  + ]:     940082 :           Trace("quant-engine-debug") << "Check " << mdl->identify().c_str()
                 [ -  - ]
     381                 :          0 :                                       << " at effort " << quant_e << "..."
     382                 :     470041 :                                       << std::endl;
     383                 :     470041 :           mdl->check(e, quant_e);
     384         [ +  + ]:     470037 :           if (d_qstate.isInConflict())
     385                 :            :           {
     386         [ +  - ]:         34 :             Trace("quant-engine-debug") << "...conflict!" << std::endl;
     387                 :         34 :             break;
     388                 :            :           }
     389                 :            :         }
     390                 :            :         //flush all current lemmas
     391                 :     163901 :         d_qim.doPending();
     392                 :            :       }
     393                 :            :       // If we have added a lemma, stop. We also stop if we are in conflict.
     394                 :            :       // In very rare cases, it may be the case that quantifiers knows there
     395                 :            :       // is a conflict without adding a lemma, e.g. if it sent a duplicate
     396                 :            :       // QUANTIFIERS_TDB_DEQ_CONG lemma, which can occur if it has detected
     397                 :            :       // a quantifier-free conflict during term indexing but the quantifier
     398                 :            :       // free theories haven't caused a backtrack yet. This should never happen
     399                 :            :       // at LAST_CALL effort.
     400 [ +  + ][ -  + ]:     163900 :       if (d_qim.hasSentLemma() || d_qstate.isInConflict())
                 [ +  + ]
     401                 :            :       {
     402 [ -  + ][ -  - ]:      22863 :         Assert(d_qim.hasSentLemma() || e != Theory::EFFORT_LAST_CALL);
         [ -  + ][ -  - ]
     403                 :      22863 :         break;
     404                 :            :       }else{
     405         [ +  + ]:     141037 :         if (quant_e == QuantifiersModule::QEFFORT_CONFLICT)
     406                 :            :         {
     407                 :      47025 :           d_qstate.incrementInstRoundCounters(e);
     408                 :            :         }
     409         [ +  + ]:      94012 :         else if (quant_e == QuantifiersModule::QEFFORT_MODEL)
     410                 :            :         {
     411         [ +  + ]:      28512 :           if( e==Theory::EFFORT_LAST_CALL ){
     412                 :            :             //sources of incompleteness
     413         [ +  + ]:      61514 :             for (QuantifiersUtil*& util : d_util)
     414                 :            :             {
     415         [ +  + ]:      52823 :               if (!util->checkComplete(setModelUnsoundId))
     416                 :            :               {
     417         [ +  - ]:          2 :                 Trace("quant-engine-debug") << "Set incomplete because utility "
     418 [ -  + ][ -  - ]:          1 :                                             << util->identify().c_str()
     419                 :          1 :                                             << " was incomplete." << std::endl;
     420                 :          1 :                 setModelUnsound = true;
     421                 :            :               }
     422                 :            :             }
     423         [ -  + ]:       8691 :             if (d_qstate.isInConflict())
     424                 :            :             {
     425                 :            :               // we reported a conflicting lemma, should return
     426                 :          0 :               setModelUnsound = true;
     427                 :            :             }
     428                 :            :             //if we have a chance not to set incomplete
     429         [ +  + ]:       8691 :             if (!setModelUnsound)
     430                 :            :             {
     431                 :            :               //check if we should set the incomplete flag
     432         [ +  + ]:      58082 :               for (QuantifiersModule*& mdl : d_modules)
     433                 :            :               {
     434         [ +  + ]:      49712 :                 if (!mdl->checkComplete(setModelUnsoundId))
     435                 :            :                 {
     436         [ +  - ]:        640 :                   Trace("quant-engine-debug")
     437                 :          0 :                       << "Set incomplete because module "
     438 [ -  + ][ -  - ]:        320 :                       << mdl->identify().c_str() << " was incomplete."
     439                 :        320 :                       << std::endl;
     440                 :        320 :                   setModelUnsound = true;
     441                 :        320 :                   break;
     442                 :            :                 }
     443                 :            :               }
     444         [ +  + ]:       8690 :               if (!setModelUnsound)
     445                 :            :               {
     446                 :            :                 //look at individual quantified formulas, one module must claim completeness for each one
     447         [ +  + ]:      10478 :                 for( unsigned i=0; i<d_model->getNumAssertedQuantifiers(); i++ ){
     448                 :       9337 :                   bool hasCompleteM = false;
     449                 :       9337 :                   Node q = d_model->getAssertedQuantifier( i );
     450                 :       9337 :                   QuantifiersModule* qmd = d_qreg.getOwner(q);
     451         [ +  + ]:       9337 :                   if( qmd!=NULL ){
     452                 :       6891 :                     hasCompleteM = qmd->checkCompleteFor( q );
     453                 :            :                   }else{
     454         [ +  + ]:      12299 :                     for( unsigned j=0; j<d_modules.size(); j++ ){
     455         [ +  + ]:      11506 :                       if( d_modules[j]->checkCompleteFor( q ) ){
     456                 :       1653 :                         qmd = d_modules[j];
     457                 :       1653 :                         hasCompleteM = true;
     458                 :       1653 :                         break;
     459                 :            :                       }
     460                 :            :                     }
     461                 :            :                   }
     462         [ +  + ]:       9337 :                   if( !hasCompleteM ){
     463         [ +  - ]:       7229 :                     Trace("quant-engine-debug") << "Set incomplete because " << q << " was not fully processed." << std::endl;
     464                 :       7229 :                     setModelUnsound = true;
     465                 :       7229 :                     break;
     466                 :            :                   }else{
     467 [ -  + ][ -  + ]:       2108 :                     Assert(qmd != NULL);
                 [ -  - ]
     468 [ +  - ][ -  + ]:       2108 :                     Trace("quant-engine-debug2") << "Complete for " << q << " due to " << qmd->identify().c_str() << std::endl;
                 [ -  - ]
     469                 :            :                   }
     470                 :            :                 }
     471                 :            :               }
     472                 :            :             }
     473                 :            :             // if setModelUnsound = false, we will answer SAT, otherwise we will
     474                 :            :             // run at quant_e QEFFORT_LAST_CALL
     475         [ +  + ]:       8691 :             if (!setModelUnsound)
     476                 :            :             {
     477                 :       1141 :               break;
     478                 :            :             }
     479                 :            :           }
     480                 :            :         }
     481                 :            :       }
     482                 :            :     }
     483         [ +  - ]:      51020 :     Trace("quant-engine-debug") << "Done check modules that needed check." << std::endl;
     484                 :            :     // debug print
     485         [ +  + ]:      51020 :     if (d_qim.hasSentLemma())
     486                 :            :     {
     487                 :      22863 :       d_qim.getInstantiate()->notifyEndRound();
     488                 :      22863 :       d_numInstRoundsLemma++;
     489                 :            :     }
     490         [ -  + ]:      51020 :     if( TraceIsOn("quant-engine") ){
     491                 :          0 :       double clSet2 = double(clock())/double(CLOCKS_PER_SEC);
     492         [ -  - ]:          0 :       Trace("quant-engine") << "Finished quantifiers engine, total time = " << (clSet2-clSet);
     493         [ -  - ]:          0 :       Trace("quant-engine") << ", sent lemma = " << d_qim.hasSentLemma();
     494         [ -  - ]:          0 :       Trace("quant-engine") << std::endl;
     495                 :            :     }
     496                 :            : 
     497         [ +  - ]:      51020 :     Trace("quant-engine-debug2") << "Finished quantifiers engine check." << std::endl;
     498                 :            :   }else{
     499         [ +  - ]:     143578 :     Trace("quant-engine-debug2") << "Quantifiers Engine does not need check." << std::endl;
     500                 :            :   }
     501                 :            : 
     502                 :            :   //SAT case
     503 [ +  + ][ +  + ]:     194598 :   if (e == Theory::EFFORT_LAST_CALL && !d_qim.hasSentLemma())
                 [ +  + ]
     504                 :            :   {
     505         [ +  + ]:      26490 :     if (setModelUnsound)
     506                 :            :     {
     507         [ +  - ]:       7216 :       Trace("quant-engine") << "Set incomplete flag." << std::endl;
     508                 :       7216 :       d_qim.setModelUnsound(setModelUnsoundId);
     509                 :            :     }
     510                 :            :     //output debug stats
     511                 :      26490 :     d_qim.getInstantiate()->debugPrintModel();
     512                 :            :   }
     513                 :     194598 :   d_qim.clearPending();
     514                 :            : }
     515                 :            : 
     516                 :      43647 : void QuantifiersEngine::notifyCombineTheories() {
     517                 :            :   // If allowing theory combination to happen at most once between instantiation
     518                 :            :   // rounds, this would reset d_ierCounter to 1 and d_ierCounterLastLc to -1
     519                 :            :   // in quantifiers state.
     520                 :      43647 : }
     521                 :            : 
     522                 :     179014 : bool QuantifiersEngine::reduceQuantifier(Node q)
     523                 :            : {
     524                 :            :   // TODO: this can be unified with preregistration: AlphaEquivalence takes
     525                 :            :   // ownership of reducable quants
     526                 :     179014 :   BoolMap::const_iterator it = d_quants_red.find(q);
     527         [ +  + ]:     179014 :   if (it == d_quants_red.end())
     528                 :            :   {
     529                 :      54299 :     TrustNode tlem;
     530                 :      54299 :     InferenceId id = InferenceId::UNKNOWN;
     531         [ +  - ]:      54299 :     if (d_qmodules->d_alpha_equiv)
     532                 :            :     {
     533         [ +  - ]:     108598 :       Trace("quant-engine-red")
     534                 :      54299 :           << "Alpha equivalence " << q << "?" << std::endl;
     535                 :            :       // add equivalence with another quantified formula
     536                 :      54299 :       tlem = d_qmodules->d_alpha_equiv->reduceQuantifier(q);
     537                 :      54299 :       id = InferenceId::QUANTIFIERS_REDUCE_ALPHA_EQ;
     538         [ +  + ]:      54299 :       if (!tlem.isNull())
     539                 :            :       {
     540         [ +  - ]:       4360 :         Trace("quant-engine-red")
     541                 :       2180 :             << "...alpha equivalence success." << std::endl;
     542                 :       2180 :         ++(d_qstate.getStats().d_red_alpha_equiv);
     543                 :            :       }
     544                 :            :     }
     545         [ +  + ]:      54299 :     if (!tlem.isNull())
     546                 :            :     {
     547                 :       2180 :       d_qim.trustedLemma(tlem, id);
     548                 :            :     }
     549                 :      54299 :     d_quants_red[q] = !tlem.isNull();
     550                 :      54299 :     return !tlem.isNull();
     551                 :            :   }
     552                 :     124715 :   return (*it).second;
     553                 :            : }
     554                 :            : 
     555                 :     144923 : void QuantifiersEngine::registerQuantifierInternal(Node f)
     556                 :            : {
     557                 :     144923 :   std::map< Node, bool >::iterator it = d_quants.find( f );
     558         [ +  + ]:     144923 :   if( it==d_quants.end() ){
     559         [ +  - ]:      51624 :     Trace("quant") << "QuantifiersEngine : Register quantifier ";
     560         [ +  - ]:      51624 :     Trace("quant") << " : " << f << std::endl;
     561                 :      51624 :     size_t prev_lemma_waiting = d_qim.numPendingLemmas();
     562                 :      51624 :     ++(d_qstate.getStats().d_num_quant);
     563 [ -  + ][ -  + ]:      51624 :     Assert(f.getKind() == Kind::FORALL);
                 [ -  - ]
     564                 :            :     // register with utilities
     565         [ +  + ]:     373701 :     for (unsigned i = 0; i < d_util.size(); i++)
     566                 :            :     {
     567                 :     322077 :       d_util[i]->registerQuantifier(f);
     568                 :            :     }
     569                 :            : 
     570         [ +  + ]:     346533 :     for (QuantifiersModule*& mdl : d_modules)
     571                 :            :     {
     572 [ +  - ][ -  + ]:     589818 :       Trace("quant-debug") << "check ownership with " << mdl->identify()
                 [ -  - ]
     573                 :     294909 :                            << "..." << std::endl;
     574                 :     294909 :       mdl->checkOwnership(f);
     575                 :            :     }
     576                 :      51624 :     QuantifiersModule* qm = d_qreg.getOwner(f);
     577                 :     103248 :     Trace("quant") << " Owner : " << (qm == nullptr ? "[none]" : qm->identify())
     578                 :      51624 :                    << std::endl;
     579                 :            :     // register with each module
     580         [ +  + ]:     346533 :     for (QuantifiersModule*& mdl : d_modules)
     581                 :            :     {
     582 [ +  - ][ -  + ]:     589818 :       Trace("quant-debug") << "register with " << mdl->identify() << "..."
                 [ -  - ]
     583                 :     294909 :                            << std::endl;
     584                 :     294909 :       mdl->registerQuantifier(f);
     585                 :            :       // since this is context-independent, we should not add any lemmas during
     586                 :            :       // this call
     587 [ -  + ][ -  + ]:     294909 :       Assert(d_qim.numPendingLemmas() == prev_lemma_waiting);
                 [ -  - ]
     588                 :            :     }
     589         [ +  - ]:      51624 :     Trace("quant-debug") << "...finish." << std::endl;
     590                 :      51624 :     d_quants[f] = true;
     591 [ -  + ][ -  + ]:      51624 :     AlwaysAssert(d_qim.numPendingLemmas() == prev_lemma_waiting);
                 [ -  - ]
     592                 :            :   }
     593                 :     144923 : }
     594                 :            : 
     595                 :      60697 : void QuantifiersEngine::preRegisterQuantifier(Node q)
     596                 :            : {
     597                 :      60697 :   NodeSet::const_iterator it = d_quants_prereg.find(q);
     598         [ +  + ]:      60697 :   if (it != d_quants_prereg.end())
     599                 :            :   {
     600                 :       8578 :     return;
     601                 :            :   }
     602         [ +  - ]:      54299 :   Trace("quant-debug") << "QuantifiersEngine : Pre-register " << q << std::endl;
     603                 :      54299 :   d_quants_prereg.insert(q);
     604                 :            :   // try to reduce
     605         [ +  + ]:      54299 :   if (reduceQuantifier(q))
     606                 :            :   {
     607                 :            :     // if we can reduce it, nothing left to do
     608                 :       2180 :     return;
     609                 :            :   }
     610                 :            :   // ensure that it is registered
     611                 :      52119 :   registerQuantifierInternal(q);
     612                 :            :   // register with each module
     613         [ +  + ]:     350426 :   for (QuantifiersModule*& mdl : d_modules)
     614                 :            :   {
     615 [ +  - ][ -  + ]:     596614 :     Trace("quant-debug") << "pre-register with " << mdl->identify() << "..."
                 [ -  - ]
     616                 :     298307 :                          << std::endl;
     617                 :     298307 :     mdl->preRegisterQuantifier(q);
     618                 :            :   }
     619                 :            :   // flush the lemmas
     620                 :      52119 :   d_qim.doPending();
     621         [ +  - ]:      52119 :   Trace("quant-debug") << "...finish pre-register " << q << "..." << std::endl;
     622                 :            : }
     623                 :            : 
     624                 :     124715 : void QuantifiersEngine::assertQuantifier( Node f, bool pol ){
     625         [ +  + ]:     124715 :   if (reduceQuantifier(f))
     626                 :            :   {
     627                 :            :     // if we can reduce it, nothing left to do
     628                 :      11969 :     return;
     629                 :            :   }
     630         [ +  + ]:     112746 :   if( !pol ){
     631                 :            :     // do skolemization
     632                 :      19942 :     TrustNode lem = d_qim.getSkolemize()->process(f);
     633         [ +  + ]:      19942 :     if (!lem.isNull())
     634                 :            :     {
     635         [ -  + ]:       4867 :       if (TraceIsOn("quantifiers-sk-debug"))
     636                 :            :       {
     637                 :          0 :         Node slem = rewrite(lem.getNode());
     638         [ -  - ]:          0 :         Trace("quantifiers-sk-debug")
     639                 :          0 :             << "Skolemize lemma : " << slem << std::endl;
     640                 :            :       }
     641                 :       4867 :       d_qim.trustedLemma(lem,
     642                 :            :                          InferenceId::QUANTIFIERS_SKOLEMIZE,
     643                 :            :                          LemmaProperty::NEEDS_JUSTIFY);
     644                 :            :     }
     645                 :      19942 :     return;
     646                 :            :   }
     647                 :            :   // ensure the quantified formula is registered
     648                 :      92804 :   registerQuantifierInternal(f);
     649                 :            :   // assert it to each module
     650                 :      92804 :   d_model->assertQuantifier(f);
     651         [ +  + ]:     632620 :   for (QuantifiersModule*& mdl : d_modules)
     652                 :            :   {
     653                 :     539816 :     mdl->assertNode(f);
     654                 :            :   }
     655                 :            :   // add term to the registry
     656                 :      92804 :   d_treg.addTerm(d_qreg.getInstConstantBody(f), true);
     657                 :            : }
     658                 :            : 
     659                 :    1453240 : void QuantifiersEngine::eqNotifyNewClass(TNode t) { d_treg.addTerm(t); }
     660                 :            : 
     661                 :          0 : void QuantifiersEngine::markRelevant( Node q ) {
     662                 :          0 :   d_model->markRelevant( q );
     663                 :          0 : }
     664                 :            : 
     665                 :         70 : void QuantifiersEngine::getInstantiationTermVectors( Node q, std::vector< std::vector< Node > >& tvecs ) {
     666                 :         70 :   d_qim.getInstantiate()->getInstantiationTermVectors(q, tvecs);
     667                 :         70 : }
     668                 :            : 
     669                 :         69 : void QuantifiersEngine::getInstantiationTermVectors( std::map< Node, std::vector< std::vector< Node > > >& insts ) {
     670                 :         69 :   d_qim.getInstantiate()->getInstantiationTermVectors(insts);
     671                 :         69 : }
     672                 :            : 
     673                 :         31 : void QuantifiersEngine::getInstantiations(Node q, std::vector<Node>& insts)
     674                 :            : {
     675                 :         31 :   d_qim.getInstantiate()->getInstantiations(q, insts);
     676                 :         31 : }
     677                 :            : 
     678                 :        101 : void QuantifiersEngine::getInstantiatedQuantifiedFormulas(std::vector<Node>& qs)
     679                 :            : {
     680                 :        101 :   d_qim.getInstantiate()->getInstantiatedQuantifiedFormulas(qs);
     681                 :        101 : }
     682                 :            : 
     683                 :         69 : void QuantifiersEngine::getSkolemTermVectors(
     684                 :            :     std::map<Node, std::vector<Node> >& sks) const
     685                 :            : {
     686                 :         69 :   d_qim.getSkolemize()->getSkolemTermVectors(sks);
     687                 :         69 : }
     688                 :            : 
     689                 :          0 : Node QuantifiersEngine::getNameForQuant(Node q) const
     690                 :            : {
     691                 :          0 :   return d_qreg.getNameForQuant(q);
     692                 :            : }
     693                 :            : 
     694                 :         89 : bool QuantifiersEngine::getNameForQuant(Node q, Node& name, bool req) const
     695                 :            : {
     696                 :         89 :   return d_qreg.getNameForQuant(q, name, req);
     697                 :            : }
     698                 :            : 
     699                 :       3000 : bool QuantifiersEngine::getSynthSolutions(
     700                 :            :     std::map<Node, std::map<Node, Node> >& sol_map)
     701                 :            : {
     702                 :       3000 :   return d_qmodules->d_synth_e->getSynthSolutions(sol_map);
     703                 :            : }
     704                 :        508 : void QuantifiersEngine::declarePool(Node p, const std::vector<Node>& initValue)
     705                 :            : {
     706                 :        508 :   d_treg.declarePool(p, initValue);
     707                 :        508 : }
     708                 :            : 
     709                 :        654 : void QuantifiersEngine::declareOracleFun(Node f)
     710                 :            : {
     711         [ -  + ]:        654 :   if (d_qmodules->d_oracleEngine.get() == nullptr)
     712                 :            :   {
     713                 :          0 :     warning() << "Cannot declare oracle function when oracles are disabled"
     714                 :          0 :               << std::endl;
     715                 :          0 :     return;
     716                 :            :   }
     717                 :        654 :   d_qmodules->d_oracleEngine->declareOracleFun(f);
     718                 :            : }
     719                 :          0 : std::vector<Node> QuantifiersEngine::getOracleFuns() const
     720                 :            : {
     721         [ -  - ]:          0 :   if (d_qmodules->d_oracleEngine.get() == nullptr)
     722                 :            :   {
     723                 :          0 :     return {};
     724                 :            :   }
     725                 :          0 :   return d_qmodules->d_oracleEngine->getOracleFuns();
     726                 :            : }
     727                 :            : 
     728                 :            : }  // namespace theory
     729                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14