GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers_engine.cpp Lines: 289 344 84.0 %
Date: 2021-05-24 Branches: 530 1248 42.5 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Morgan Deters, Mathias Preiner
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 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/printer_options.h"
19
#include "options/quantifiers_options.h"
20
#include "options/smt_options.h"
21
#include "options/uf_options.h"
22
#include "smt/smt_engine_scope.h"
23
#include "theory/quantifiers/equality_query.h"
24
#include "theory/quantifiers/first_order_model.h"
25
#include "theory/quantifiers/fmf/first_order_model_fmc.h"
26
#include "theory/quantifiers/fmf/full_model_check.h"
27
#include "theory/quantifiers/fmf/model_builder.h"
28
#include "theory/quantifiers/quant_module.h"
29
#include "theory/quantifiers/quantifiers_inference_manager.h"
30
#include "theory/quantifiers/quantifiers_modules.h"
31
#include "theory/quantifiers/quantifiers_registry.h"
32
#include "theory/quantifiers/quantifiers_rewriter.h"
33
#include "theory/quantifiers/quantifiers_state.h"
34
#include "theory/quantifiers/quantifiers_statistics.h"
35
#include "theory/quantifiers/relevant_domain.h"
36
#include "theory/quantifiers/skolemize.h"
37
#include "theory/quantifiers/term_registry.h"
38
#include "theory/theory_engine.h"
39
40
using namespace std;
41
using namespace cvc5::kind;
42
43
namespace cvc5 {
44
namespace theory {
45
46
9459
QuantifiersEngine::QuantifiersEngine(
47
    quantifiers::QuantifiersState& qs,
48
    quantifiers::QuantifiersRegistry& qr,
49
    quantifiers::TermRegistry& tr,
50
    quantifiers::QuantifiersInferenceManager& qim,
51
9459
    ProofNodeManager* pnm)
52
    : d_qstate(qs),
53
      d_qim(qim),
54
      d_te(nullptr),
55
      d_pnm(pnm),
56
      d_qreg(qr),
57
      d_treg(tr),
58
      d_model(nullptr),
59
9459
      d_quants_prereg(qs.getUserContext()),
60
18918
      d_quants_red(qs.getUserContext())
61
{
62
18918
  Trace("quant-init-debug")
63
18918
      << "Initialize model engine, mbqi : " << options::mbqiMode() << " "
64
9459
      << options::fmfBound() << std::endl;
65
  // Finite model finding requires specialized ways of building the model.
66
  // We require constructing the model here, since it is required for
67
  // initializing the CombinationEngine and the rest of quantifiers engine.
68
18918
  if (options::fmfBound()
69
10799
      || (options::finiteModelFind()
70
258
          && (options::mbqiMode() == options::MbqiMode::FMC
71
15
              || options::mbqiMode() == options::MbqiMode::TRUST)))
72
  {
73
1340
    Trace("quant-init-debug") << "...make fmc builder." << std::endl;
74
2680
    d_builder.reset(
75
1340
        new quantifiers::fmcheck::FullModelChecker(qs, qim, qr, tr));
76
  }
77
  else
78
  {
79
8119
    Trace("quant-init-debug") << "...make default model builder." << std::endl;
80
8119
    d_builder.reset(new quantifiers::QModelBuilder(qs, qim, qr, tr));
81
  }
82
  // set the model object
83
9459
  d_builder->finishInit();
84
9459
  d_model = d_builder->getModel();
85
86
  // Finish initializing the term registry by hooking it up to the model and the
87
  // inference manager. The former is required since theories are not given
88
  // access to the model in their constructors currently.
89
  // The latter is required due to a cyclic dependency between the term
90
  // database and the instantiate module. Term database needs inference manager
91
  // since it sends out lemmas when term indexing is inconsistent, instantiate
92
  // needs term database for entailment checks.
93
9459
  d_treg.finishInit(d_model, &d_qim);
94
95
  // initialize the utilities
96
9459
  d_util.push_back(d_model->getEqualityQuery());
97
  // quantifiers registry must come before the remaining utilities
98
9459
  d_util.push_back(&d_qreg);
99
9459
  d_util.push_back(tr.getTermDatabase());
100
9459
  d_util.push_back(qim.getInstantiate());
101
9459
  d_util.push_back(tr.getTermPools());
102
9459
}
103
104
9459
QuantifiersEngine::~QuantifiersEngine() {}
105
106
6413
void QuantifiersEngine::finishInit(TheoryEngine* te)
107
{
108
  // connect the quantifiers model to the underlying theory model
109
6413
  d_model->finishInit(te->getModel());
110
6413
  d_te = te;
111
  // Initialize the modules and the utilities here.
112
6413
  d_qmodules.reset(new quantifiers::QuantifiersModules);
113
6413
  d_qmodules->initialize(
114
      d_qstate, d_qim, d_qreg, d_treg, d_builder.get(), d_modules);
115
6413
  if (d_qmodules->d_rel_dom.get())
116
  {
117
83
    d_util.push_back(d_qmodules->d_rel_dom.get());
118
  }
119
120
  // handle any circular dependencies
121
122
  // quantifiers bound inference needs to be informed of the bounded integers
123
  // module, which has information about which quantifiers have finite bounds
124
6413
  d_qreg.getQuantifiersBoundInference().finishInit(d_qmodules->d_bint.get());
125
6413
}
126
127
quantifiers::QuantifiersRegistry& QuantifiersEngine::getQuantifiersRegistry()
128
{
129
  return d_qreg;
130
}
131
132
6413
quantifiers::QModelBuilder* QuantifiersEngine::getModelBuilder() const
133
{
134
6413
  return d_builder.get();
135
}
136
137
/// !!!!!!!!!!!!!! temporary (project #15)
138
139
1529
quantifiers::TermDbSygus* QuantifiersEngine::getTermDatabaseSygus() const
140
{
141
1529
  return d_treg.getTermDatabaseSygus();
142
}
143
/// !!!!!!!!!!!!!!
144
145
7327
void QuantifiersEngine::presolve() {
146
7327
  Trace("quant-engine-proc") << "QuantifiersEngine : presolve " << std::endl;
147
7327
  d_qim.clearPending();
148
44668
  for( unsigned i=0; i<d_modules.size(); i++ ){
149
37341
    d_modules[i]->presolve();
150
  }
151
  // presolve with term registry, which populates the term database based on
152
  // terms registered before presolve when in incremental mode
153
7327
  d_treg.presolve();
154
7327
}
155
156
7319
void QuantifiersEngine::ppNotifyAssertions(
157
    const std::vector<Node>& assertions) {
158
14638
  Trace("quant-engine-proc")
159
14638
      << "ppNotifyAssertions in QE, #assertions = " << assertions.size()
160
7319
      << std::endl;
161
7319
  if (options::instLevelInputOnly() && options::instMaxLevel() != -1)
162
  {
163
234
    for (const Node& a : assertions)
164
    {
165
230
      quantifiers::QuantAttributes::setInstantiationLevelAttr(a, 0);
166
    }
167
  }
168
7319
  if (options::sygus())
169
  {
170
1498
    quantifiers::SynthEngine* sye = d_qmodules->d_synth_e.get();
171
4987
    for (const Node& a : assertions)
172
    {
173
3489
      sye->preregisterAssertion(a);
174
    }
175
  }
176
  /* The SyGuS instantiation module needs a global view of all available
177
   * assertions to collect global terms that get added to each grammar.
178
   */
179
7319
  if (options::sygusInst())
180
  {
181
20
    quantifiers::SygusInst* si = d_qmodules->d_sygus_inst.get();
182
20
    si->ppNotifyAssertions(assertions);
183
  }
184
7319
}
185
186
108632
void QuantifiersEngine::check( Theory::Effort e ){
187
108632
  quantifiers::QuantifiersStatistics& stats = d_qstate.getStats();
188
217264
  CodeTimer codeTimer(stats.d_time);
189
108632
  Assert(d_qstate.getEqualityEngine() != nullptr);
190
108632
  if (!d_qstate.getEqualityEngine()->consistent())
191
  {
192
    Trace("quant-engine-debug") << "Master equality engine not consistent, return." << std::endl;
193
    return;
194
  }
195
108632
  if (d_qstate.isInConflict())
196
  {
197
    if (e < Theory::EFFORT_LAST_CALL)
198
    {
199
      // this can happen in rare cases when quantifiers is the first to realize
200
      // there is a quantifier-free conflict, for example, when it discovers
201
      // disequal and congruent terms in the master equality engine during
202
      // term indexing. In such cases, quantifiers reports a "conflicting lemma"
203
      // that is, one that is entailed to be false by the current assignment.
204
      // If this lemma is not a SAT conflict, we may get another call to full
205
      // effort check and the quantifier-free solvers still haven't realized
206
      // there is a conflict. In this case, we return, trusting that theory
207
      // combination will do the right thing (split on equalities until there is
208
      // a conflict at the quantifier-free level).
209
      Trace("quant-engine-debug")
210
          << "Conflicting lemma already reported by quantifiers, return."
211
          << std::endl;
212
      return;
213
    }
214
    // we reported what we thought was a conflicting lemma, but now we have
215
    // gotten a check at LAST_CALL effort, indicating that the lemma we reported
216
    // was not conflicting. This should never happen, but in production mode, we
217
    // proceed with the check.
218
    Assert(false);
219
  }
220
108632
  bool needsCheck = d_qim.hasPendingLemma();
221
108632
  QuantifiersModule::QEffort needsModelE = QuantifiersModule::QEFFORT_NONE;
222
217264
  std::vector< QuantifiersModule* > qm;
223
108632
  if( d_model->checkNeeded() ){
224
90885
    needsCheck = needsCheck || e>=Theory::EFFORT_LAST_CALL;  //always need to check at or above last call
225
544292
    for (QuantifiersModule*& mdl : d_modules)
226
    {
227
453407
      if (mdl->needsCheck(e))
228
      {
229
58564
        qm.push_back(mdl);
230
58564
        needsCheck = true;
231
        //can only request model at last call since theory combination can find inconsistencies
232
58564
        if( e>=Theory::EFFORT_LAST_CALL ){
233
39091
          QuantifiersModule::QEffort me = mdl->needsModel(e);
234
39091
          needsModelE = me<needsModelE ? me : needsModelE;
235
        }
236
      }
237
    }
238
  }
239
240
108632
  d_qim.reset();
241
108632
  bool setIncomplete = false;
242
108632
  IncompleteId setIncompleteId = IncompleteId::QUANTIFIERS;
243
244
108632
  Trace("quant-engine-debug2") << "Quantifiers Engine call to check, level = " << e << ", needsCheck=" << needsCheck << std::endl;
245
108632
  if( needsCheck ){
246
    //flush previous lemmas (for instance, if was interrupted), or other lemmas to process
247
24502
    d_qim.doPending();
248
24502
    if (d_qim.hasSentLemma())
249
    {
250
      return;
251
    }
252
253
24502
    double clSet = 0;
254
24502
    if( Trace.isOn("quant-engine") ){
255
      clSet = double(clock())/double(CLOCKS_PER_SEC);
256
      Trace("quant-engine") << ">>>>> Quantifiers Engine Round, effort = " << e << " <<<<<" << std::endl;
257
    }
258
259
24502
    if( Trace.isOn("quant-engine-debug") ){
260
      Trace("quant-engine-debug") << "Quantifiers Engine check, level = " << e << std::endl;
261
      Trace("quant-engine-debug")
262
          << "  depth : " << d_qstate.getInstRoundDepth() << std::endl;
263
      Trace("quant-engine-debug") << "  modules to check : ";
264
      for( unsigned i=0; i<qm.size(); i++ ){
265
        Trace("quant-engine-debug") << qm[i]->identify() << " ";
266
      }
267
      Trace("quant-engine-debug") << std::endl;
268
      Trace("quant-engine-debug") << "  # quantified formulas = " << d_model->getNumAssertedQuantifiers() << std::endl;
269
      if (d_qim.hasPendingLemma())
270
      {
271
        Trace("quant-engine-debug")
272
            << "  lemmas waiting = " << d_qim.numPendingLemmas() << std::endl;
273
      }
274
      Trace("quant-engine-debug")
275
          << "  Theory engine finished : "
276
          << !d_qstate.getValuation().needCheck() << std::endl;
277
      Trace("quant-engine-debug") << "  Needs model effort : " << needsModelE << std::endl;
278
      Trace("quant-engine-debug")
279
          << "  In conflict : " << d_qstate.isInConflict() << std::endl;
280
    }
281
24502
    if( Trace.isOn("quant-engine-ee-pre") ){
282
      Trace("quant-engine-ee-pre") << "Equality engine (pre-inference): " << std::endl;
283
      d_qstate.debugPrintEqualityEngine("quant-engine-ee-pre");
284
    }
285
24502
    if( Trace.isOn("quant-engine-assert") ){
286
      Trace("quant-engine-assert") << "Assertions : " << std::endl;
287
      d_te->printAssertions("quant-engine-assert");
288
    }
289
290
    //reset utilities
291
24502
    Trace("quant-engine-debug") << "Resetting all utilities..." << std::endl;
292
148097
    for (QuantifiersUtil*& util : d_util)
293
    {
294
247190
      Trace("quant-engine-debug2") << "Reset " << util->identify().c_str()
295
123595
                                   << "..." << std::endl;
296
123595
      if (!util->reset(e))
297
      {
298
        d_qim.doPending();
299
        if (d_qim.hasSentLemma())
300
        {
301
          return;
302
        }else{
303
          //should only fail reset if added a lemma
304
          Assert(false);
305
        }
306
      }
307
    }
308
309
24502
    if( Trace.isOn("quant-engine-ee") ){
310
      Trace("quant-engine-ee") << "Equality engine : " << std::endl;
311
      d_qstate.debugPrintEqualityEngine("quant-engine-ee");
312
    }
313
314
    //reset the model
315
24502
    Trace("quant-engine-debug") << "Reset model..." << std::endl;
316
24502
    d_model->reset_round();
317
318
    //reset the modules
319
24502
    Trace("quant-engine-debug") << "Resetting all modules..." << std::endl;
320
150578
    for (QuantifiersModule*& mdl : d_modules)
321
    {
322
252152
      Trace("quant-engine-debug2") << "Reset " << mdl->identify().c_str()
323
126076
                                   << std::endl;
324
126076
      mdl->reset_round(e);
325
    }
326
24502
    Trace("quant-engine-debug") << "Done resetting all modules." << std::endl;
327
    //reset may have added lemmas
328
24502
    d_qim.doPending();
329
24502
    if (d_qim.hasSentLemma())
330
    {
331
      return;
332
    }
333
334
24502
    if( e==Theory::EFFORT_LAST_CALL ){
335
10679
      ++(stats.d_instantiation_rounds_lc);
336
13823
    }else if( e==Theory::EFFORT_FULL ){
337
13823
      ++(stats.d_instantiation_rounds);
338
    }
339
24502
    Trace("quant-engine-debug") << "Check modules that needed check..." << std::endl;
340
94402
    for (unsigned qef = QuantifiersModule::QEFFORT_CONFLICT;
341
94402
         qef <= QuantifiersModule::QEFFORT_LAST_CALL;
342
         ++qef)
343
    {
344
80323
      QuantifiersModule::QEffort quant_e =
345
          static_cast<QuantifiersModule::QEffort>(qef);
346
      // Force the theory engine to build the model if any module requested it.
347
80323
      if (needsModelE == quant_e)
348
      {
349
9760
        Trace("quant-engine-debug") << "Build model..." << std::endl;
350
9760
        if (!d_te->buildModel())
351
        {
352
          // If we failed to build the model, flush all pending lemmas and
353
          // finish.
354
          d_qim.doPending();
355
10413
          break;
356
        }
357
      }
358
80323
      if (!d_qim.hasSentLemma())
359
      {
360
        //check each module
361
261812
        for (QuantifiersModule*& mdl : qm)
362
        {
363
363008
          Trace("quant-engine-debug") << "Check " << mdl->identify().c_str()
364
181504
                                      << " at effort " << quant_e << "..."
365
181504
                                      << std::endl;
366
181504
          mdl->check(e, quant_e);
367
181495
          if (d_qstate.isInConflict())
368
          {
369
6
            Trace("quant-engine-debug") << "...conflict!" << std::endl;
370
6
            break;
371
          }
372
        }
373
        //flush all current lemmas
374
80314
        d_qim.doPending();
375
      }
376
      //if we have added one, stop
377
80313
      if (d_qim.hasSentLemma())
378
      {
379
9924
        break;
380
      }else{
381
70389
        Assert(!d_qstate.isInConflict());
382
70389
        if (quant_e == QuantifiersModule::QEFFORT_CONFLICT)
383
        {
384
23062
          d_qstate.incrementInstRoundCounters(e);
385
        }
386
47327
        else if (quant_e == QuantifiersModule::QEFFORT_MODEL)
387
        {
388
14686
          if( e==Theory::EFFORT_LAST_CALL ){
389
            //sources of incompleteness
390
16217
            for (QuantifiersUtil*& util : d_util)
391
            {
392
13544
              if (!util->checkComplete(setIncompleteId))
393
              {
394
2
                Trace("quant-engine-debug") << "Set incomplete because utility "
395
2
                                            << util->identify().c_str()
396
1
                                            << " was incomplete." << std::endl;
397
1
                setIncomplete = true;
398
              }
399
            }
400
2673
            if (d_qstate.isInConflict())
401
            {
402
              // we reported a conflicting lemma, should return
403
              setIncomplete = true;
404
            }
405
            //if we have a chance not to set incomplete
406
2673
            if( !setIncomplete ){
407
              //check if we should set the incomplete flag
408
15923
              for (QuantifiersModule*& mdl : d_modules)
409
              {
410
13318
                if (!mdl->checkComplete(setIncompleteId))
411
                {
412
134
                  Trace("quant-engine-debug")
413
67
                      << "Set incomplete because module "
414
134
                      << mdl->identify().c_str() << " was incomplete."
415
67
                      << std::endl;
416
67
                  setIncomplete = true;
417
67
                  break;
418
                }
419
              }
420
2672
              if( !setIncomplete ){
421
                //look at individual quantified formulas, one module must claim completeness for each one
422
3904
                for( unsigned i=0; i<d_model->getNumAssertedQuantifiers(); i++ ){
423
3415
                  bool hasCompleteM = false;
424
4714
                  Node q = d_model->getAssertedQuantifier( i );
425
3415
                  QuantifiersModule* qmd = d_qreg.getOwner(q);
426
3415
                  if( qmd!=NULL ){
427
2035
                    hasCompleteM = qmd->checkCompleteFor( q );
428
                  }else{
429
5514
                    for( unsigned j=0; j<d_modules.size(); j++ ){
430
5240
                      if( d_modules[j]->checkCompleteFor( q ) ){
431
1106
                        qmd = d_modules[j];
432
1106
                        hasCompleteM = true;
433
1106
                        break;
434
                      }
435
                    }
436
                  }
437
3415
                  if( !hasCompleteM ){
438
2116
                    Trace("quant-engine-debug") << "Set incomplete because " << q << " was not fully processed." << std::endl;
439
2116
                    setIncomplete = true;
440
2116
                    break;
441
                  }else{
442
1299
                    Assert(qmd != NULL);
443
1299
                    Trace("quant-engine-debug2") << "Complete for " << q << " due to " << qmd->identify().c_str() << std::endl;
444
                  }
445
                }
446
              }
447
            }
448
            //if setIncomplete = false, we will answer SAT, otherwise we will run at quant_e QEFFORT_LAST_CALL
449
2673
            if( !setIncomplete ){
450
489
              break;
451
            }
452
          }
453
        }
454
      }
455
    }
456
24492
    Trace("quant-engine-debug") << "Done check modules that needed check." << std::endl;
457
    // debug print
458
24492
    if (d_qim.hasSentLemma())
459
    {
460
9924
      bool debugInstTrace = Trace.isOn("inst-per-quant-round");
461
9924
      if (options::debugInst() || debugInstTrace)
462
      {
463
2
        Options& sopts = smt::currentSmtEngine()->getOptions();
464
2
        std::ostream& out = *sopts.getOut();
465
2
        d_qim.getInstantiate()->debugPrint(out);
466
      }
467
    }
468
24492
    if( Trace.isOn("quant-engine") ){
469
      double clSet2 = double(clock())/double(CLOCKS_PER_SEC);
470
      Trace("quant-engine") << "Finished quantifiers engine, total time = " << (clSet2-clSet);
471
      Trace("quant-engine") << ", sent lemma = " << d_qim.hasSentLemma();
472
      Trace("quant-engine") << std::endl;
473
    }
474
475
24492
    Trace("quant-engine-debug2") << "Finished quantifiers engine check." << std::endl;
476
  }else{
477
84130
    Trace("quant-engine-debug2") << "Quantifiers Engine does not need check." << std::endl;
478
  }
479
480
  //SAT case
481
108622
  if (e == Theory::EFFORT_LAST_CALL && !d_qim.hasSentLemma())
482
  {
483
5358
    if( setIncomplete ){
484
2066
      Trace("quant-engine") << "Set incomplete flag." << std::endl;
485
2066
      d_qim.setIncomplete(setIncompleteId);
486
    }
487
    //output debug stats
488
5358
    d_qim.getInstantiate()->debugPrintModel();
489
  }
490
}
491
492
12483
void QuantifiersEngine::notifyCombineTheories() {
493
  // If allowing theory combination to happen at most once between instantiation
494
  // rounds, this would reset d_ierCounter to 1 and d_ierCounterLastLc to -1
495
  // in quantifiers state.
496
12483
}
497
498
139761
bool QuantifiersEngine::reduceQuantifier( Node q ) {
499
  //TODO: this can be unified with preregistration: AlphaEquivalence takes ownership of reducable quants
500
139761
  BoolMap::const_iterator it = d_quants_red.find( q );
501
139761
  if( it==d_quants_red.end() ){
502
53914
    Node lem;
503
26957
    InferenceId id = InferenceId::UNKNOWN;
504
26957
    std::map< Node, Node >::iterator itr = d_quants_red_lem.find( q );
505
26957
    if( itr==d_quants_red_lem.end() ){
506
26930
      if (d_qmodules->d_alpha_equiv)
507
      {
508
26930
        Trace("quant-engine-red") << "Alpha equivalence " << q << "?" << std::endl;
509
        //add equivalence with another quantified formula
510
26930
        lem = d_qmodules->d_alpha_equiv->reduceQuantifier(q);
511
26930
        id = InferenceId::QUANTIFIERS_REDUCE_ALPHA_EQ;
512
26930
        if( !lem.isNull() ){
513
1882
          Trace("quant-engine-red") << "...alpha equivalence success." << std::endl;
514
1882
          ++(d_qstate.getStats().d_red_alpha_equiv);
515
        }
516
      }
517
26930
      d_quants_red_lem[q] = lem;
518
    }else{
519
27
      lem = itr->second;
520
    }
521
26957
    if( !lem.isNull() ){
522
1882
      d_qim.lemma(lem, id);
523
    }
524
26957
    d_quants_red[q] = !lem.isNull();
525
26957
    return !lem.isNull();
526
  }else{
527
112804
    return (*it).second;
528
  }
529
}
530
531
100502
void QuantifiersEngine::registerQuantifierInternal(Node f)
532
{
533
100502
  std::map< Node, bool >::iterator it = d_quants.find( f );
534
100502
  if( it==d_quants.end() ){
535
25048
    Trace("quant") << "QuantifiersEngine : Register quantifier ";
536
25048
    Trace("quant") << " : " << f << std::endl;
537
25048
    size_t prev_lemma_waiting = d_qim.numPendingLemmas();
538
25048
    ++(d_qstate.getStats().d_num_quant);
539
25048
    Assert(f.getKind() == FORALL);
540
    // register with utilities
541
153984
    for (unsigned i = 0; i < d_util.size(); i++)
542
    {
543
128936
      d_util[i]->registerQuantifier(f);
544
    }
545
546
141807
    for (QuantifiersModule*& mdl : d_modules)
547
    {
548
233518
      Trace("quant-debug") << "check ownership with " << mdl->identify()
549
116759
                           << "..." << std::endl;
550
116759
      mdl->checkOwnership(f);
551
    }
552
25048
    QuantifiersModule* qm = d_qreg.getOwner(f);
553
50096
    Trace("quant") << " Owner : " << (qm == nullptr ? "[none]" : qm->identify())
554
25048
                   << std::endl;
555
    // register with each module
556
141807
    for (QuantifiersModule*& mdl : d_modules)
557
    {
558
233518
      Trace("quant-debug") << "register with " << mdl->identify() << "..."
559
116759
                           << std::endl;
560
116759
      mdl->registerQuantifier(f);
561
      // since this is context-independent, we should not add any lemmas during
562
      // this call
563
116759
      Assert(d_qim.numPendingLemmas() == prev_lemma_waiting);
564
    }
565
25048
    Trace("quant-debug") << "...finish." << std::endl;
566
25048
    d_quants[f] = true;
567
25048
    AlwaysAssert(d_qim.numPendingLemmas() == prev_lemma_waiting);
568
  }
569
100502
}
570
571
31871
void QuantifiersEngine::preRegisterQuantifier(Node q)
572
{
573
31871
  NodeSet::const_iterator it = d_quants_prereg.find(q);
574
31871
  if (it != d_quants_prereg.end())
575
  {
576
11710
    return;
577
  }
578
26957
  Trace("quant-debug") << "QuantifiersEngine : Pre-register " << q << std::endl;
579
26957
  d_quants_prereg.insert(q);
580
  // try to reduce
581
26957
  if (reduceQuantifier(q))
582
  {
583
    // if we can reduce it, nothing left to do
584
1882
    return;
585
  }
586
  // ensure that it is registered
587
25075
  registerQuantifierInternal(q);
588
  // register with each module
589
141963
  for (QuantifiersModule*& mdl : d_modules)
590
  {
591
233778
    Trace("quant-debug") << "pre-register with " << mdl->identify() << "..."
592
116889
                         << std::endl;
593
116890
    mdl->preRegisterQuantifier(q);
594
  }
595
  // flush the lemmas
596
25074
  d_qim.doPending();
597
25074
  Trace("quant-debug") << "...finish pre-register " << q << "..." << std::endl;
598
}
599
600
112804
void QuantifiersEngine::assertQuantifier( Node f, bool pol ){
601
112804
  if (reduceQuantifier(f))
602
  {
603
    // if we can reduce it, nothing left to do
604
13204
    return;
605
  }
606
99600
  if( !pol ){
607
    // do skolemization
608
48346
    TrustNode lem = d_qim.getSkolemize()->process(f);
609
24173
    if (!lem.isNull())
610
    {
611
2501
      if (Trace.isOn("quantifiers-sk-debug"))
612
      {
613
        Node slem = Rewriter::rewrite(lem.getNode());
614
        Trace("quantifiers-sk-debug")
615
            << "Skolemize lemma : " << slem << std::endl;
616
      }
617
2501
      d_qim.trustedLemma(lem,
618
                         InferenceId::QUANTIFIERS_SKOLEMIZE,
619
                         LemmaProperty::NEEDS_JUSTIFY);
620
    }
621
24173
    return;
622
  }
623
  // ensure the quantified formula is registered
624
75427
  registerQuantifierInternal(f);
625
  // assert it to each module
626
75427
  d_model->assertQuantifier(f);
627
436860
  for (QuantifiersModule*& mdl : d_modules)
628
  {
629
361433
    mdl->assertNode(f);
630
  }
631
  // add term to the registry
632
75427
  d_treg.addTerm(d_qreg.getInstConstantBody(f), true);
633
}
634
635
739262
void QuantifiersEngine::eqNotifyNewClass(TNode t) { d_treg.addTerm(t); }
636
637
void QuantifiersEngine::markRelevant( Node q ) {
638
  d_model->markRelevant( q );
639
}
640
641
42
void QuantifiersEngine::getInstantiationTermVectors( Node q, std::vector< std::vector< Node > >& tvecs ) {
642
42
  d_qim.getInstantiate()->getInstantiationTermVectors(q, tvecs);
643
42
}
644
645
8
void QuantifiersEngine::getInstantiationTermVectors( std::map< Node, std::vector< std::vector< Node > > >& insts ) {
646
8
  d_qim.getInstantiate()->getInstantiationTermVectors(insts);
647
8
}
648
649
16
void QuantifiersEngine::getInstantiations(Node q, std::vector<Node>& insts)
650
{
651
16
  d_qim.getInstantiate()->getInstantiations(q, insts);
652
16
}
653
654
68
void QuantifiersEngine::getInstantiatedQuantifiedFormulas(std::vector<Node>& qs)
655
{
656
68
  d_qim.getInstantiate()->getInstantiatedQuantifiedFormulas(qs);
657
68
}
658
659
12
void QuantifiersEngine::getSkolemTermVectors(
660
    std::map<Node, std::vector<Node> >& sks) const
661
{
662
12
  d_qim.getSkolemize()->getSkolemTermVectors(sks);
663
12
}
664
665
Node QuantifiersEngine::getNameForQuant(Node q) const
666
{
667
  return d_qreg.getNameForQuant(q);
668
}
669
670
30
bool QuantifiersEngine::getNameForQuant(Node q, Node& name, bool req) const
671
{
672
30
  return d_qreg.getNameForQuant(q, name, req);
673
}
674
675
253
bool QuantifiersEngine::getSynthSolutions(
676
    std::map<Node, std::map<Node, Node> >& sol_map)
677
{
678
253
  return d_qmodules->d_synth_e->getSynthSolutions(sol_map);
679
}
680
5
void QuantifiersEngine::declarePool(Node p, const std::vector<Node>& initValue)
681
{
682
5
  d_treg.declarePool(p, initValue);
683
5
}
684
685
}  // namespace theory
686
28191
}  // namespace cvc5