GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers_engine.cpp Lines: 293 348 84.2 %
Date: 2021-09-29 Branches: 520 1220 42.6 %

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