GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers_engine.cpp Lines: 293 349 84.0 %
Date: 2021-05-21 Branches: 531 1250 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
8954
QuantifiersEngine::QuantifiersEngine(
47
    quantifiers::QuantifiersState& qs,
48
    quantifiers::QuantifiersRegistry& qr,
49
    quantifiers::TermRegistry& tr,
50
    quantifiers::QuantifiersInferenceManager& qim,
51
8954
    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
8954
      d_quants_prereg(qs.getUserContext()),
60
17908
      d_quants_red(qs.getUserContext())
61
{
62
17908
  Trace("quant-init-debug")
63
17908
      << "Initialize model engine, mbqi : " << options::mbqiMode() << " "
64
8954
      << 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
17908
  if (options::fmfBound()
69
10284
      || (options::finiteModelFind()
70
247
          && (options::mbqiMode() == options::MbqiMode::FMC
71
15
              || options::mbqiMode() == options::MbqiMode::TRUST)))
72
  {
73
1330
    Trace("quant-init-debug") << "...make fmc builder." << std::endl;
74
2660
    d_builder.reset(
75
1330
        new quantifiers::fmcheck::FullModelChecker(qs, qim, qr, tr));
76
  }
77
  else
78
  {
79
7624
    Trace("quant-init-debug") << "...make default model builder." << std::endl;
80
7624
    d_builder.reset(new quantifiers::QModelBuilder(qs, qim, qr, tr));
81
  }
82
  // set the model object
83
8954
  d_builder->finishInit();
84
8954
  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
8954
  d_treg.finishInit(d_model, &d_qim);
94
95
  // initialize the utilities
96
8954
  d_util.push_back(d_model->getEqualityQuery());
97
  // quantifiers registry must come before the remaining utilities
98
8954
  d_util.push_back(&d_qreg);
99
8954
  d_util.push_back(tr.getTermDatabase());
100
8954
  d_util.push_back(qim.getInstantiate());
101
8954
  d_util.push_back(tr.getTermPools());
102
8954
}
103
104
8954
QuantifiersEngine::~QuantifiersEngine() {}
105
106
6286
void QuantifiersEngine::finishInit(TheoryEngine* te)
107
{
108
  // connect the quantifiers model to the underlying theory model
109
6286
  d_model->finishInit(te->getModel());
110
6286
  d_te = te;
111
  // Initialize the modules and the utilities here.
112
6286
  d_qmodules.reset(new quantifiers::QuantifiersModules);
113
6286
  d_qmodules->initialize(
114
      d_qstate, d_qim, d_qreg, d_treg, d_builder.get(), d_modules);
115
6286
  if (d_qmodules->d_rel_dom.get())
116
  {
117
79
    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
6286
  d_qreg.getQuantifiersBoundInference().finishInit(d_qmodules->d_bint.get());
125
6286
}
126
127
quantifiers::QuantifiersRegistry& QuantifiersEngine::getQuantifiersRegistry()
128
{
129
  return d_qreg;
130
}
131
132
6286
quantifiers::QModelBuilder* QuantifiersEngine::getModelBuilder() const
133
{
134
6286
  return d_builder.get();
135
}
136
137
/// !!!!!!!!!!!!!! temporary (project #15)
138
139
1543
quantifiers::TermDbSygus* QuantifiersEngine::getTermDatabaseSygus() const
140
{
141
1543
  return d_treg.getTermDatabaseSygus();
142
}
143
/// !!!!!!!!!!!!!!
144
145
7066
void QuantifiersEngine::presolve() {
146
7066
  Trace("quant-engine-proc") << "QuantifiersEngine : presolve " << std::endl;
147
7066
  d_qim.clearPending();
148
43163
  for( unsigned i=0; i<d_modules.size(); i++ ){
149
36097
    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
7066
  d_treg.presolve();
154
7066
}
155
156
7051
void QuantifiersEngine::ppNotifyAssertions(
157
    const std::vector<Node>& assertions) {
158
14102
  Trace("quant-engine-proc")
159
14102
      << "ppNotifyAssertions in QE, #assertions = " << assertions.size()
160
7051
      << std::endl;
161
7051
  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
7051
  if (options::sygus())
169
  {
170
1510
    quantifiers::SynthEngine* sye = d_qmodules->d_synth_e.get();
171
5041
    for (const Node& a : assertions)
172
    {
173
3531
      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
7051
  if (options::sygusInst())
180
  {
181
20
    quantifiers::SygusInst* si = d_qmodules->d_sygus_inst.get();
182
20
    si->ppNotifyAssertions(assertions);
183
  }
184
7051
}
185
186
107240
void QuantifiersEngine::check( Theory::Effort e ){
187
107240
  quantifiers::QuantifiersStatistics& stats = d_qstate.getStats();
188
214480
  CodeTimer codeTimer(stats.d_time);
189
107240
  Assert(d_qstate.getEqualityEngine() != nullptr);
190
107240
  if (!d_qstate.getEqualityEngine()->consistent())
191
  {
192
    Trace("quant-engine-debug") << "Master equality engine not consistent, return." << std::endl;
193
    return;
194
  }
195
107240
  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
107240
  bool needsCheck = d_qim.hasPendingLemma();
221
107240
  QuantifiersModule::QEffort needsModelE = QuantifiersModule::QEFFORT_NONE;
222
214480
  std::vector< QuantifiersModule* > qm;
223
107240
  if( d_model->checkNeeded() ){
224
89896
    needsCheck = needsCheck || e>=Theory::EFFORT_LAST_CALL;  //always need to check at or above last call
225
538724
    for (QuantifiersModule*& mdl : d_modules)
226
    {
227
448828
      if (mdl->needsCheck(e))
228
      {
229
58317
        qm.push_back(mdl);
230
58317
        needsCheck = true;
231
        //can only request model at last call since theory combination can find inconsistencies
232
58317
        if( e>=Theory::EFFORT_LAST_CALL ){
233
39017
          QuantifiersModule::QEffort me = mdl->needsModel(e);
234
39017
          needsModelE = me<needsModelE ? me : needsModelE;
235
        }
236
      }
237
    }
238
  }
239
240
107240
  d_qim.reset();
241
107240
  bool setIncomplete = false;
242
107240
  IncompleteId setIncompleteId = IncompleteId::QUANTIFIERS;
243
244
107240
  Trace("quant-engine-debug2") << "Quantifiers Engine call to check, level = " << e << ", needsCheck=" << needsCheck << std::endl;
245
107240
  if( needsCheck ){
246
    //flush previous lemmas (for instance, if was interrupted), or other lemmas to process
247
24335
    d_qim.doPending();
248
24335
    if (d_qim.hasSentLemma())
249
    {
250
      return;
251
    }
252
253
24335
    double clSet = 0;
254
24335
    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
24335
    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
24335
    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
24335
    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
24335
    Trace("quant-engine-debug") << "Resetting all utilities..." << std::endl;
292
147083
    for (QuantifiersUtil*& util : d_util)
293
    {
294
245496
      Trace("quant-engine-debug2") << "Reset " << util->identify().c_str()
295
122748
                                   << "..." << std::endl;
296
122748
      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
24335
    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
24335
    Trace("quant-engine-debug") << "Reset model..." << std::endl;
316
24335
    d_model->reset_round();
317
318
    //reset the modules
319
24335
    Trace("quant-engine-debug") << "Resetting all modules..." << std::endl;
320
149710
    for (QuantifiersModule*& mdl : d_modules)
321
    {
322
250750
      Trace("quant-engine-debug2") << "Reset " << mdl->identify().c_str()
323
125375
                                   << std::endl;
324
125375
      mdl->reset_round(e);
325
    }
326
24335
    Trace("quant-engine-debug") << "Done resetting all modules." << std::endl;
327
    //reset may have added lemmas
328
24335
    d_qim.doPending();
329
24335
    if (d_qim.hasSentLemma())
330
    {
331
      return;
332
    }
333
334
24335
    if( e==Theory::EFFORT_LAST_CALL ){
335
10646
      ++(stats.d_instantiation_rounds_lc);
336
13689
    }else if( e==Theory::EFFORT_FULL ){
337
13689
      ++(stats.d_instantiation_rounds);
338
    }
339
24335
    Trace("quant-engine-debug") << "Check modules that needed check..." << std::endl;
340
93859
    for (unsigned qef = QuantifiersModule::QEFFORT_CONFLICT;
341
93859
         qef <= QuantifiersModule::QEFFORT_LAST_CALL;
342
         ++qef)
343
    {
344
79858
      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
79858
      if (needsModelE == quant_e)
348
      {
349
9745
        Trace("quant-engine-debug") << "Build model..." << std::endl;
350
9745
        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
10324
          break;
356
        }
357
      }
358
79858
      if (!d_qim.hasSentLemma())
359
      {
360
        //check each module
361
260699
        for (QuantifiersModule*& mdl : qm)
362
        {
363
361712
          Trace("quant-engine-debug") << "Check " << mdl->identify().c_str()
364
180856
                                      << " at effort " << quant_e << "..."
365
180856
                                      << std::endl;
366
180856
          mdl->check(e, quant_e);
367
180847
          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
79849
        d_qim.doPending();
375
      }
376
      //if we have added one, stop
377
79848
      if (d_qim.hasSentLemma())
378
      {
379
9841
        break;
380
      }else{
381
70007
        Assert(!d_qstate.isInConflict());
382
70007
        if (quant_e == QuantifiersModule::QEFFORT_CONFLICT)
383
        {
384
22942
          d_qstate.incrementInstRoundCounters(e);
385
        }
386
47065
        else if (quant_e == QuantifiersModule::QEFFORT_MODEL)
387
        {
388
14602
          if( e==Theory::EFFORT_LAST_CALL ){
389
            //sources of incompleteness
390
16193
            for (QuantifiersUtil*& util : d_util)
391
            {
392
13524
              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
2669
            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
2669
            if( !setIncomplete ){
407
              //check if we should set the incomplete flag
408
15907
              for (QuantifiersModule*& mdl : d_modules)
409
              {
410
13306
                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
2668
              if( !setIncomplete ){
421
                //look at individual quantified formulas, one module must claim completeness for each one
422
3889
                for( unsigned i=0; i<d_model->getNumAssertedQuantifiers(); i++ ){
423
3406
                  bool hasCompleteM = false;
424
4694
                  Node q = d_model->getAssertedQuantifier( i );
425
3406
                  QuantifiersModule* qmd = d_qreg.getOwner(q);
426
3406
                  if( qmd!=NULL ){
427
2041
                    hasCompleteM = qmd->checkCompleteFor( q );
428
                  }else{
429
5455
                    for( unsigned j=0; j<d_modules.size(); j++ ){
430
5185
                      if( d_modules[j]->checkCompleteFor( q ) ){
431
1095
                        qmd = d_modules[j];
432
1095
                        hasCompleteM = true;
433
1095
                        break;
434
                      }
435
                    }
436
                  }
437
3406
                  if( !hasCompleteM ){
438
2118
                    Trace("quant-engine-debug") << "Set incomplete because " << q << " was not fully processed." << std::endl;
439
2118
                    setIncomplete = true;
440
2118
                    break;
441
                  }else{
442
1288
                    Assert(qmd != NULL);
443
1288
                    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
2669
            if( !setIncomplete ){
450
483
              break;
451
            }
452
          }
453
        }
454
      }
455
    }
456
24325
    Trace("quant-engine-debug") << "Done check modules that needed check." << std::endl;
457
    // debug print
458
24325
    if (d_qim.hasSentLemma())
459
    {
460
9841
      bool debugInstTrace = Trace.isOn("inst-per-quant-round");
461
9841
      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
24325
    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
24325
    Trace("quant-engine-debug2") << "Finished quantifiers engine check." << std::endl;
476
  }else{
477
82905
    Trace("quant-engine-debug2") << "Quantifiers Engine does not need check." << std::endl;
478
  }
479
480
  //SAT case
481
107230
  if (e == Theory::EFFORT_LAST_CALL && !d_qim.hasSentLemma())
482
  {
483
5254
    if( setIncomplete ){
484
2068
      Trace("quant-engine") << "Set incomplete flag." << std::endl;
485
2068
      d_qim.setIncomplete(setIncompleteId);
486
    }
487
    //output debug stats
488
5254
    d_qim.getInstantiate()->debugPrintModel();
489
  }
490
}
491
492
12347
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
12347
}
497
498
138598
bool QuantifiersEngine::reduceQuantifier( Node q ) {
499
  //TODO: this can be unified with preregistration: AlphaEquivalence takes ownership of reducable quants
500
138598
  BoolMap::const_iterator it = d_quants_red.find( q );
501
138598
  if( it==d_quants_red.end() ){
502
53686
    Node lem;
503
26843
    InferenceId id = InferenceId::UNKNOWN;
504
26843
    std::map< Node, Node >::iterator itr = d_quants_red_lem.find( q );
505
26843
    if( itr==d_quants_red_lem.end() ){
506
26822
      if (d_qmodules->d_alpha_equiv)
507
      {
508
26822
        Trace("quant-engine-red") << "Alpha equivalence " << q << "?" << std::endl;
509
        //add equivalence with another quantified formula
510
26822
        lem = d_qmodules->d_alpha_equiv->reduceQuantifier(q);
511
26822
        id = InferenceId::QUANTIFIERS_REDUCE_ALPHA_EQ;
512
26822
        if( !lem.isNull() ){
513
1880
          Trace("quant-engine-red") << "...alpha equivalence success." << std::endl;
514
1880
          ++(d_qstate.getStats().d_red_alpha_equiv);
515
        }
516
      }
517
26822
      d_quants_red_lem[q] = lem;
518
    }else{
519
21
      lem = itr->second;
520
    }
521
26843
    if( !lem.isNull() ){
522
1880
      d_qim.lemma(lem, id);
523
    }
524
26843
    d_quants_red[q] = !lem.isNull();
525
26843
    return !lem.isNull();
526
  }else{
527
111755
    return (*it).second;
528
  }
529
}
530
531
99764
void QuantifiersEngine::registerQuantifierInternal(Node f)
532
{
533
99764
  std::map< Node, bool >::iterator it = d_quants.find( f );
534
99764
  if( it==d_quants.end() ){
535
24942
    Trace("quant") << "QuantifiersEngine : Register quantifier ";
536
24942
    Trace("quant") << " : " << f << std::endl;
537
24942
    size_t prev_lemma_waiting = d_qim.numPendingLemmas();
538
24942
    ++(d_qstate.getStats().d_num_quant);
539
24942
    Assert(f.getKind() == FORALL);
540
    // register with utilities
541
153344
    for (unsigned i = 0; i < d_util.size(); i++)
542
    {
543
128402
      d_util[i]->registerQuantifier(f);
544
    }
545
546
141269
    for (QuantifiersModule*& mdl : d_modules)
547
    {
548
232654
      Trace("quant-debug") << "check ownership with " << mdl->identify()
549
116327
                           << "..." << std::endl;
550
116327
      mdl->checkOwnership(f);
551
    }
552
24942
    QuantifiersModule* qm = d_qreg.getOwner(f);
553
49884
    Trace("quant") << " Owner : " << (qm == nullptr ? "[none]" : qm->identify())
554
24942
                   << std::endl;
555
    // register with each module
556
141269
    for (QuantifiersModule*& mdl : d_modules)
557
    {
558
232654
      Trace("quant-debug") << "register with " << mdl->identify() << "..."
559
116327
                           << std::endl;
560
116327
      mdl->registerQuantifier(f);
561
      // since this is context-independent, we should not add any lemmas during
562
      // this call
563
116327
      Assert(d_qim.numPendingLemmas() == prev_lemma_waiting);
564
    }
565
24942
    Trace("quant-debug") << "...finish." << std::endl;
566
24942
    d_quants[f] = true;
567
24942
    AlwaysAssert(d_qim.numPendingLemmas() == prev_lemma_waiting);
568
  }
569
99764
}
570
571
31699
void QuantifiersEngine::preRegisterQuantifier(Node q)
572
{
573
31699
  NodeSet::const_iterator it = d_quants_prereg.find(q);
574
31699
  if (it != d_quants_prereg.end())
575
  {
576
11592
    return;
577
  }
578
26843
  Trace("quant-debug") << "QuantifiersEngine : Pre-register " << q << std::endl;
579
26843
  d_quants_prereg.insert(q);
580
  // try to reduce
581
26843
  if (reduceQuantifier(q))
582
  {
583
    // if we can reduce it, nothing left to do
584
1880
    return;
585
  }
586
  // ensure that it is registered
587
24963
  registerQuantifierInternal(q);
588
  // register with each module
589
141392
  for (QuantifiersModule*& mdl : d_modules)
590
  {
591
232860
    Trace("quant-debug") << "pre-register with " << mdl->identify() << "..."
592
116430
                         << std::endl;
593
116431
    mdl->preRegisterQuantifier(q);
594
  }
595
  // flush the lemmas
596
24962
  d_qim.doPending();
597
24962
  Trace("quant-debug") << "...finish pre-register " << q << "..." << std::endl;
598
}
599
600
111755
void QuantifiersEngine::assertQuantifier( Node f, bool pol ){
601
111755
  if (reduceQuantifier(f))
602
  {
603
    // if we can reduce it, nothing left to do
604
13109
    return;
605
  }
606
98646
  if( !pol ){
607
    // do skolemization
608
47690
    TrustNode lem = d_qim.getSkolemize()->process(f);
609
23845
    if (!lem.isNull())
610
    {
611
2461
      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
2461
      d_qim.trustedLemma(lem,
618
                         InferenceId::QUANTIFIERS_SKOLEMIZE,
619
                         LemmaProperty::NEEDS_JUSTIFY);
620
    }
621
23845
    return;
622
  }
623
  // ensure the quantified formula is registered
624
74801
  registerQuantifierInternal(f);
625
  // assert it to each module
626
74801
  d_model->assertQuantifier(f);
627
433352
  for (QuantifiersModule*& mdl : d_modules)
628
  {
629
358551
    mdl->assertNode(f);
630
  }
631
  // add term to the registry
632
74801
  d_treg.addTerm(d_qreg.getInstConstantBody(f), true);
633
}
634
635
705130
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
6
void QuantifiersEngine::getInstantiationTermVectors( std::map< Node, std::vector< std::vector< Node > > >& insts ) {
646
6
  d_qim.getInstantiate()->getInstantiationTermVectors(insts);
647
6
}
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
3
void QuantifiersEngine::printSynthSolution( std::ostream& out ) {
655
3
  if (d_qmodules->d_synth_e)
656
  {
657
3
    d_qmodules->d_synth_e->printSynthSolution(out);
658
  }else{
659
    out << "Internal error : module for synth solution not found." << std::endl;
660
  }
661
3
}
662
663
68
void QuantifiersEngine::getInstantiatedQuantifiedFormulas(std::vector<Node>& qs)
664
{
665
68
  d_qim.getInstantiate()->getInstantiatedQuantifiedFormulas(qs);
666
68
}
667
668
9
void QuantifiersEngine::getSkolemTermVectors(
669
    std::map<Node, std::vector<Node> >& sks) const
670
{
671
9
  d_qim.getSkolemize()->getSkolemTermVectors(sks);
672
9
}
673
674
Node QuantifiersEngine::getNameForQuant(Node q) const
675
{
676
  return d_qreg.getNameForQuant(q);
677
}
678
679
24
bool QuantifiersEngine::getNameForQuant(Node q, Node& name, bool req) const
680
{
681
24
  return d_qreg.getNameForQuant(q, name, req);
682
}
683
684
249
bool QuantifiersEngine::getSynthSolutions(
685
    std::map<Node, std::map<Node, Node> >& sol_map)
686
{
687
249
  return d_qmodules->d_synth_e->getSynthSolutions(sol_map);
688
}
689
5
void QuantifiersEngine::declarePool(Node p, const std::vector<Node>& initValue)
690
{
691
5
  d_treg.declarePool(p, initValue);
692
5
}
693
694
}  // namespace theory
695
27735
}  // namespace cvc5