GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers_engine.cpp Lines: 295 350 84.3 %
Date: 2021-11-07 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
15273
QuantifiersEngine::QuantifiersEngine(
48
    Env& env,
49
    quantifiers::QuantifiersState& qs,
50
    quantifiers::QuantifiersRegistry& qr,
51
    quantifiers::TermRegistry& tr,
52
    quantifiers::QuantifiersInferenceManager& qim,
53
15273
    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
15273
      d_quants_prereg(userContext()),
63
15273
      d_quants_red(userContext()),
64
45819
      d_numInstRoundsLemma(0)
65
{
66
30546
  Trace("quant-init-debug")
67
15273
      << "Initialize model engine, mbqi : " << options().quantifiers.mbqiMode
68
15273
      << " " << options().quantifiers.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
45732
  if (options().quantifiers.fmfBound || options().strings.stringExp
73
30803
      || (options().quantifiers.finiteModelFind
74
270
          && (options().quantifiers.mbqiMode == options::MbqiMode::FMC
75
13
              || options().quantifiers.mbqiMode == options::MbqiMode::TRUST)))
76
  {
77
1559
    Trace("quant-init-debug") << "...make fmc builder." << std::endl;
78
3118
    d_builder.reset(
79
1559
        new quantifiers::fmcheck::FullModelChecker(env, qs, qim, qr, tr));
80
  }
81
  else
82
  {
83
13714
    Trace("quant-init-debug") << "...make default model builder." << std::endl;
84
13714
    d_builder.reset(new quantifiers::QModelBuilder(env, qs, qim, qr, tr));
85
  }
86
  // set the model object
87
15273
  d_builder->finishInit();
88
15273
  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
15273
  d_treg.finishInit(d_model, &d_qim);
98
99
  // initialize the utilities
100
15273
  d_util.push_back(d_model->getEqualityQuery());
101
  // quantifiers registry must come before the remaining utilities
102
15273
  d_util.push_back(&d_qreg);
103
15273
  d_util.push_back(tr.getTermDatabase());
104
15273
  d_util.push_back(qim.getInstantiate());
105
15273
  d_util.push_back(tr.getTermPools());
106
15273
}
107
108
30536
QuantifiersEngine::~QuantifiersEngine() {}
109
110
12150
void QuantifiersEngine::finishInit(TheoryEngine* te)
111
{
112
  // connect the quantifiers model to the underlying theory model
113
12150
  d_model->finishInit(te->getModel());
114
12150
  d_te = te;
115
  // Initialize the modules and the utilities here.
116
12150
  d_qmodules.reset(new quantifiers::QuantifiersModules());
117
12150
  d_qmodules->initialize(
118
      d_env, d_qstate, d_qim, d_qreg, d_treg, d_builder.get(), d_modules);
119
12150
  if (d_qmodules->d_rel_dom.get())
120
  {
121
111
    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
12150
  d_qreg.getQuantifiersBoundInference().finishInit(d_qmodules->d_bint.get());
129
12150
}
130
131
quantifiers::QuantifiersRegistry& QuantifiersEngine::getQuantifiersRegistry()
132
{
133
  return d_qreg;
134
}
135
136
12150
quantifiers::QModelBuilder* QuantifiersEngine::getModelBuilder() const
137
{
138
12150
  return d_builder.get();
139
}
140
141
/// !!!!!!!!!!!!!! temporary (project #15)
142
143
1900
quantifiers::TermDbSygus* QuantifiersEngine::getTermDatabaseSygus() const
144
{
145
1900
  return d_treg.getTermDatabaseSygus();
146
}
147
/// !!!!!!!!!!!!!!
148
149
13467
void QuantifiersEngine::presolve() {
150
13467
  Trace("quant-engine-proc") << "QuantifiersEngine : presolve " << std::endl;
151
13467
  d_numInstRoundsLemma = 0;
152
13467
  d_qim.clearPending();
153
80913
  for (QuantifiersUtil*& u : d_util)
154
  {
155
67446
    u->presolve();
156
  }
157
80970
  for (QuantifiersModule*& mdl : d_modules)
158
  {
159
67503
    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
13467
  d_treg.presolve();
164
13467
}
165
166
13433
void QuantifiersEngine::ppNotifyAssertions(
167
    const std::vector<Node>& assertions) {
168
26866
  Trace("quant-engine-proc")
169
26866
      << "ppNotifyAssertions in QE, #assertions = " << assertions.size()
170
13433
      << std::endl;
171
26866
  if (options().quantifiers.instLevelInputOnly
172
13433
      && options().quantifiers.instMaxLevel != -1)
173
  {
174
234
    for (const Node& a : assertions)
175
    {
176
230
      quantifiers::QuantAttributes::setInstantiationLevelAttr(a, 0);
177
    }
178
  }
179
13433
  if (options().quantifiers.sygus)
180
  {
181
1834
    quantifiers::SynthEngine* sye = d_qmodules->d_synth_e.get();
182
5632
    for (const Node& a : assertions)
183
    {
184
3798
      sye->preregisterAssertion(a);
185
    }
186
  }
187
  /* The SyGuS instantiation module needs a global view of all available
188
   * assertions to collect global terms that get added to each grammar.
189
   */
190
13433
  if (options().quantifiers.sygusInst)
191
  {
192
32
    quantifiers::SygusInst* si = d_qmodules->d_sygus_inst.get();
193
32
    si->ppNotifyAssertions(assertions);
194
  }
195
13433
}
196
197
122822
void QuantifiersEngine::check( Theory::Effort e ){
198
122822
  quantifiers::QuantifiersStatistics& stats = d_qstate.getStats();
199
245644
  CodeTimer codeTimer(stats.d_time);
200
122822
  Assert(d_qstate.getEqualityEngine() != nullptr);
201
122822
  if (!d_qstate.getEqualityEngine()->consistent())
202
  {
203
    Trace("quant-engine-debug") << "Master equality engine not consistent, return." << std::endl;
204
    return;
205
  }
206
122822
  if (d_qstate.isInConflict())
207
  {
208
    if (e < Theory::EFFORT_LAST_CALL)
209
    {
210
      // this can happen in rare cases when quantifiers is the first to realize
211
      // there is a quantifier-free conflict, for example, when it discovers
212
      // disequal and congruent terms in the master equality engine during
213
      // term indexing. In such cases, quantifiers reports a "conflicting lemma"
214
      // that is, one that is entailed to be false by the current assignment.
215
      // If this lemma is not a SAT conflict, we may get another call to full
216
      // effort check and the quantifier-free solvers still haven't realized
217
      // there is a conflict. In this case, we return, trusting that theory
218
      // combination will do the right thing (split on equalities until there is
219
      // a conflict at the quantifier-free level).
220
      Trace("quant-engine-debug")
221
          << "Conflicting lemma already reported by quantifiers, return."
222
          << std::endl;
223
      return;
224
    }
225
    // we reported what we thought was a conflicting lemma, but now we have
226
    // gotten a check at LAST_CALL effort, indicating that the lemma we reported
227
    // was not conflicting. This should never happen, but in production mode, we
228
    // proceed with the check.
229
    Assert(false);
230
  }
231
122822
  bool needsCheck = d_qim.hasPendingLemma();
232
122822
  QuantifiersModule::QEffort needsModelE = QuantifiersModule::QEFFORT_NONE;
233
245644
  std::vector< QuantifiersModule* > qm;
234
122822
  if( d_model->checkNeeded() ){
235
93453
    needsCheck = needsCheck || e>=Theory::EFFORT_LAST_CALL;  //always need to check at or above last call
236
560343
    for (QuantifiersModule*& mdl : d_modules)
237
    {
238
466890
      if (mdl->needsCheck(e))
239
      {
240
90923
        qm.push_back(mdl);
241
90923
        needsCheck = true;
242
        //can only request model at last call since theory combination can find inconsistencies
243
90923
        if( e>=Theory::EFFORT_LAST_CALL ){
244
67209
          QuantifiersModule::QEffort me = mdl->needsModel(e);
245
67209
          needsModelE = me<needsModelE ? me : needsModelE;
246
        }
247
      }
248
    }
249
  }
250
251
122822
  d_qim.reset();
252
122822
  bool setIncomplete = false;
253
122822
  IncompleteId setIncompleteId = IncompleteId::QUANTIFIERS;
254
245644
  if (options().quantifiers.instMaxRounds >= 0
255
124654
      && d_numInstRoundsLemma
256
1832
             >= static_cast<uint32_t>(options().quantifiers.instMaxRounds))
257
  {
258
168
    needsCheck = false;
259
168
    setIncomplete = true;
260
168
    setIncompleteId = IncompleteId::QUANTIFIERS_MAX_INST_ROUNDS;
261
  }
262
263
122822
  Trace("quant-engine-debug2") << "Quantifiers Engine call to check, level = " << e << ", needsCheck=" << needsCheck << std::endl;
264
122822
  if( needsCheck ){
265
    //flush previous lemmas (for instance, if was interrupted), or other lemmas to process
266
34975
    d_qim.doPending();
267
34975
    if (d_qim.hasSentLemma())
268
    {
269
      return;
270
    }
271
272
34975
    double clSet = 0;
273
34975
    if( Trace.isOn("quant-engine") ){
274
      clSet = double(clock())/double(CLOCKS_PER_SEC);
275
      Trace("quant-engine") << ">>>>> Quantifiers Engine Round, effort = " << e << " <<<<<" << std::endl;
276
    }
277
278
34975
    if( Trace.isOn("quant-engine-debug") ){
279
      Trace("quant-engine-debug") << "Quantifiers Engine check, level = " << e << std::endl;
280
      Trace("quant-engine-debug")
281
          << "  depth : " << d_qstate.getInstRoundDepth() << std::endl;
282
      Trace("quant-engine-debug") << "  modules to check : ";
283
      for( unsigned i=0; i<qm.size(); i++ ){
284
        Trace("quant-engine-debug") << qm[i]->identify() << " ";
285
      }
286
      Trace("quant-engine-debug") << std::endl;
287
      Trace("quant-engine-debug") << "  # quantified formulas = " << d_model->getNumAssertedQuantifiers() << std::endl;
288
      if (d_qim.hasPendingLemma())
289
      {
290
        Trace("quant-engine-debug")
291
            << "  lemmas waiting = " << d_qim.numPendingLemmas() << std::endl;
292
      }
293
      Trace("quant-engine-debug")
294
          << "  Theory engine finished : "
295
          << !d_qstate.getValuation().needCheck() << std::endl;
296
      Trace("quant-engine-debug") << "  Needs model effort : " << needsModelE << std::endl;
297
      Trace("quant-engine-debug")
298
          << "  In conflict : " << d_qstate.isInConflict() << std::endl;
299
    }
300
34975
    if( Trace.isOn("quant-engine-ee-pre") ){
301
      Trace("quant-engine-ee-pre") << "Equality engine (pre-inference): " << std::endl;
302
      d_qstate.debugPrintEqualityEngine("quant-engine-ee-pre");
303
    }
304
34975
    if( Trace.isOn("quant-engine-assert") ){
305
      Trace("quant-engine-assert") << "Assertions : " << std::endl;
306
      d_te->printAssertions("quant-engine-assert");
307
    }
308
309
    //reset utilities
310
34975
    Trace("quant-engine-debug") << "Resetting all utilities..." << std::endl;
311
211299
    for (QuantifiersUtil*& util : d_util)
312
    {
313
352648
      Trace("quant-engine-debug2") << "Reset " << util->identify().c_str()
314
176324
                                   << "..." << std::endl;
315
176324
      if (!util->reset(e))
316
      {
317
        d_qim.doPending();
318
        if (d_qim.hasSentLemma())
319
        {
320
          return;
321
        }else{
322
          //should only fail reset if added a lemma
323
          Assert(false);
324
        }
325
      }
326
    }
327
328
34975
    if( Trace.isOn("quant-engine-ee") ){
329
      Trace("quant-engine-ee") << "Equality engine : " << std::endl;
330
      d_qstate.debugPrintEqualityEngine("quant-engine-ee");
331
    }
332
333
    //reset the model
334
34975
    Trace("quant-engine-debug") << "Reset model..." << std::endl;
335
34975
    d_model->reset_round();
336
337
    //reset the modules
338
34975
    Trace("quant-engine-debug") << "Resetting all modules..." << std::endl;
339
216708
    for (QuantifiersModule*& mdl : d_modules)
340
    {
341
363466
      Trace("quant-engine-debug2") << "Reset " << mdl->identify().c_str()
342
181733
                                   << std::endl;
343
181733
      mdl->reset_round(e);
344
    }
345
34975
    Trace("quant-engine-debug") << "Done resetting all modules." << std::endl;
346
    //reset may have added lemmas
347
34975
    d_qim.doPending();
348
34975
    if (d_qim.hasSentLemma())
349
    {
350
      return;
351
    }
352
353
34975
    if( e==Theory::EFFORT_LAST_CALL ){
354
17778
      ++(stats.d_instantiation_rounds_lc);
355
17197
    }else if( e==Theory::EFFORT_FULL ){
356
17197
      ++(stats.d_instantiation_rounds);
357
    }
358
34975
    Trace("quant-engine-debug") << "Check modules that needed check..." << std::endl;
359
136829
    for (unsigned qef = QuantifiersModule::QEFFORT_CONFLICT;
360
136829
         qef <= QuantifiersModule::QEFFORT_LAST_CALL;
361
         ++qef)
362
    {
363
116689
      QuantifiersModule::QEffort quant_e =
364
          static_cast<QuantifiersModule::QEffort>(qef);
365
      // Force the theory engine to build the model if any module requested it.
366
116689
      if (needsModelE == quant_e)
367
      {
368
16552
        Trace("quant-engine-debug") << "Build model..." << std::endl;
369
16552
        if (!d_te->buildModel())
370
        {
371
          // If we failed to build the model, flush all pending lemmas and
372
          // finish.
373
          d_qim.doPending();
374
14820
          break;
375
        }
376
      }
377
116689
      if (!d_qim.hasSentLemma())
378
      {
379
        //check each module
380
406365
        for (QuantifiersModule*& mdl : qm)
381
        {
382
579402
          Trace("quant-engine-debug") << "Check " << mdl->identify().c_str()
383
289701
                                      << " at effort " << quant_e << "..."
384
289701
                                      << std::endl;
385
289701
          mdl->check(e, quant_e);
386
289687
          if (d_qstate.isInConflict())
387
          {
388
11
            Trace("quant-engine-debug") << "...conflict!" << std::endl;
389
11
            break;
390
          }
391
        }
392
        //flush all current lemmas
393
116675
        d_qim.doPending();
394
      }
395
      //if we have added one, stop
396
116674
      if (d_qim.hasSentLemma())
397
      {
398
14298
        break;
399
      }else{
400
102376
        Assert(!d_qstate.isInConflict());
401
102376
        if (quant_e == QuantifiersModule::QEFFORT_CONFLICT)
402
        {
403
33448
          d_qstate.incrementInstRoundCounters(e);
404
        }
405
68928
        else if (quant_e == QuantifiersModule::QEFFORT_MODEL)
406
        {
407
20801
          if( e==Theory::EFFORT_LAST_CALL ){
408
            //sources of incompleteness
409
33513
            for (QuantifiersUtil*& util : d_util)
410
            {
411
27973
              if (!util->checkComplete(setIncompleteId))
412
              {
413
2
                Trace("quant-engine-debug") << "Set incomplete because utility "
414
2
                                            << util->identify().c_str()
415
1
                                            << " was incomplete." << std::endl;
416
1
                setIncomplete = true;
417
              }
418
            }
419
5540
            if (d_qstate.isInConflict())
420
            {
421
              // we reported a conflicting lemma, should return
422
              setIncomplete = true;
423
            }
424
            //if we have a chance not to set incomplete
425
5540
            if( !setIncomplete ){
426
              //check if we should set the incomplete flag
427
33139
              for (QuantifiersModule*& mdl : d_modules)
428
              {
429
27664
                if (!mdl->checkComplete(setIncompleteId))
430
                {
431
128
                  Trace("quant-engine-debug")
432
64
                      << "Set incomplete because module "
433
128
                      << mdl->identify().c_str() << " was incomplete."
434
64
                      << std::endl;
435
64
                  setIncomplete = true;
436
64
                  break;
437
                }
438
              }
439
5539
              if( !setIncomplete ){
440
                //look at individual quantified formulas, one module must claim completeness for each one
441
6879
                for( unsigned i=0; i<d_model->getNumAssertedQuantifiers(); i++ ){
442
6357
                  bool hasCompleteM = false;
443
7761
                  Node q = d_model->getAssertedQuantifier( i );
444
6357
                  QuantifiersModule* qmd = d_qreg.getOwner(q);
445
6357
                  if( qmd!=NULL ){
446
4805
                    hasCompleteM = qmd->checkCompleteFor( q );
447
                  }else{
448
6324
                    for( unsigned j=0; j<d_modules.size(); j++ ){
449
5997
                      if( d_modules[j]->checkCompleteFor( q ) ){
450
1225
                        qmd = d_modules[j];
451
1225
                        hasCompleteM = true;
452
1225
                        break;
453
                      }
454
                    }
455
                  }
456
6357
                  if( !hasCompleteM ){
457
4953
                    Trace("quant-engine-debug") << "Set incomplete because " << q << " was not fully processed." << std::endl;
458
4953
                    setIncomplete = true;
459
4953
                    break;
460
                  }else{
461
1404
                    Assert(qmd != NULL);
462
1404
                    Trace("quant-engine-debug2") << "Complete for " << q << " due to " << qmd->identify().c_str() << std::endl;
463
                  }
464
                }
465
              }
466
            }
467
            //if setIncomplete = false, we will answer SAT, otherwise we will run at quant_e QEFFORT_LAST_CALL
468
5540
            if( !setIncomplete ){
469
522
              break;
470
            }
471
          }
472
        }
473
      }
474
    }
475
34960
    Trace("quant-engine-debug") << "Done check modules that needed check." << std::endl;
476
    // debug print
477
34960
    if (d_qim.hasSentLemma())
478
    {
479
14298
      d_qim.getInstantiate()->notifyEndRound();
480
14298
      d_numInstRoundsLemma++;
481
    }
482
34960
    if( Trace.isOn("quant-engine") ){
483
      double clSet2 = double(clock())/double(CLOCKS_PER_SEC);
484
      Trace("quant-engine") << "Finished quantifiers engine, total time = " << (clSet2-clSet);
485
      Trace("quant-engine") << ", sent lemma = " << d_qim.hasSentLemma();
486
      Trace("quant-engine") << std::endl;
487
    }
488
489
34960
    Trace("quant-engine-debug2") << "Finished quantifiers engine check." << std::endl;
490
  }else{
491
87847
    Trace("quant-engine-debug2") << "Quantifiers Engine does not need check." << std::endl;
492
  }
493
494
  //SAT case
495
122807
  if (e == Theory::EFFORT_LAST_CALL && !d_qim.hasSentLemma())
496
  {
497
11015
    if( setIncomplete ){
498
4935
      Trace("quant-engine") << "Set incomplete flag." << std::endl;
499
4935
      d_qim.setIncomplete(setIncompleteId);
500
    }
501
    //output debug stats
502
11015
    d_qim.getInstantiate()->debugPrintModel();
503
  }
504
}
505
506
22130
void QuantifiersEngine::notifyCombineTheories() {
507
  // If allowing theory combination to happen at most once between instantiation
508
  // rounds, this would reset d_ierCounter to 1 and d_ierCounterLastLc to -1
509
  // in quantifiers state.
510
22130
}
511
512
119384
bool QuantifiersEngine::reduceQuantifier(Node q)
513
{
514
  // TODO: this can be unified with preregistration: AlphaEquivalence takes
515
  // ownership of reducable quants
516
119384
  BoolMap::const_iterator it = d_quants_red.find(q);
517
119384
  if (it == d_quants_red.end())
518
  {
519
55936
    TrustNode tlem;
520
27968
    InferenceId id = InferenceId::UNKNOWN;
521
27968
    if (d_qmodules->d_alpha_equiv)
522
    {
523
55936
      Trace("quant-engine-red")
524
27968
          << "Alpha equivalence " << q << "?" << std::endl;
525
      // add equivalence with another quantified formula
526
27968
      tlem = d_qmodules->d_alpha_equiv->reduceQuantifier(q);
527
27968
      id = InferenceId::QUANTIFIERS_REDUCE_ALPHA_EQ;
528
27968
      if (!tlem.isNull())
529
      {
530
3650
        Trace("quant-engine-red")
531
1825
            << "...alpha equivalence success." << std::endl;
532
1825
        ++(d_qstate.getStats().d_red_alpha_equiv);
533
      }
534
    }
535
27968
    if (!tlem.isNull())
536
    {
537
1825
      d_qim.trustedLemma(tlem, id);
538
    }
539
27968
    d_quants_red[q] = !tlem.isNull();
540
27968
    return !tlem.isNull();
541
  }
542
91416
  return (*it).second;
543
}
544
545
95471
void QuantifiersEngine::registerQuantifierInternal(Node f)
546
{
547
95471
  std::map< Node, bool >::iterator it = d_quants.find( f );
548
95471
  if( it==d_quants.end() ){
549
26099
    Trace("quant") << "QuantifiersEngine : Register quantifier ";
550
26099
    Trace("quant") << " : " << f << std::endl;
551
26099
    size_t prev_lemma_waiting = d_qim.numPendingLemmas();
552
26099
    ++(d_qstate.getStats().d_num_quant);
553
26099
    Assert(f.getKind() == FORALL);
554
    // register with utilities
555
160475
    for (unsigned i = 0; i < d_util.size(); i++)
556
    {
557
134376
      d_util[i]->registerQuantifier(f);
558
    }
559
560
146249
    for (QuantifiersModule*& mdl : d_modules)
561
    {
562
240300
      Trace("quant-debug") << "check ownership with " << mdl->identify()
563
120150
                           << "..." << std::endl;
564
120150
      mdl->checkOwnership(f);
565
    }
566
26099
    QuantifiersModule* qm = d_qreg.getOwner(f);
567
52198
    Trace("quant") << " Owner : " << (qm == nullptr ? "[none]" : qm->identify())
568
26099
                   << std::endl;
569
    // register with each module
570
146249
    for (QuantifiersModule*& mdl : d_modules)
571
    {
572
240300
      Trace("quant-debug") << "register with " << mdl->identify() << "..."
573
120150
                           << std::endl;
574
120150
      mdl->registerQuantifier(f);
575
      // since this is context-independent, we should not add any lemmas during
576
      // this call
577
120150
      Assert(d_qim.numPendingLemmas() == prev_lemma_waiting);
578
    }
579
26099
    Trace("quant-debug") << "...finish." << std::endl;
580
26099
    d_quants[f] = true;
581
26099
    AlwaysAssert(d_qim.numPendingLemmas() == prev_lemma_waiting);
582
  }
583
95471
}
584
585
33149
void QuantifiersEngine::preRegisterQuantifier(Node q)
586
{
587
33149
  NodeSet::const_iterator it = d_quants_prereg.find(q);
588
33149
  if (it != d_quants_prereg.end())
589
  {
590
12187
    return;
591
  }
592
27968
  Trace("quant-debug") << "QuantifiersEngine : Pre-register " << q << std::endl;
593
27968
  d_quants_prereg.insert(q);
594
  // try to reduce
595
27968
  if (reduceQuantifier(q))
596
  {
597
    // if we can reduce it, nothing left to do
598
1825
    return;
599
  }
600
  // ensure that it is registered
601
26143
  registerQuantifierInternal(q);
602
  // register with each module
603
146520
  for (QuantifiersModule*& mdl : d_modules)
604
  {
605
240756
    Trace("quant-debug") << "pre-register with " << mdl->identify() << "..."
606
120378
                         << std::endl;
607
120379
    mdl->preRegisterQuantifier(q);
608
  }
609
  // flush the lemmas
610
26142
  d_qim.doPending();
611
26142
  Trace("quant-debug") << "...finish pre-register " << q << "..." << std::endl;
612
}
613
614
91416
void QuantifiersEngine::assertQuantifier( Node f, bool pol ){
615
91416
  if (reduceQuantifier(f))
616
  {
617
    // if we can reduce it, nothing left to do
618
10272
    return;
619
  }
620
81144
  if( !pol ){
621
    // do skolemization
622
23632
    TrustNode lem = d_qim.getSkolemize()->process(f);
623
11816
    if (!lem.isNull())
624
    {
625
2681
      if (Trace.isOn("quantifiers-sk-debug"))
626
      {
627
        Node slem = rewrite(lem.getNode());
628
        Trace("quantifiers-sk-debug")
629
            << "Skolemize lemma : " << slem << std::endl;
630
      }
631
2681
      d_qim.trustedLemma(lem,
632
                         InferenceId::QUANTIFIERS_SKOLEMIZE,
633
                         LemmaProperty::NEEDS_JUSTIFY);
634
    }
635
11816
    return;
636
  }
637
  // ensure the quantified formula is registered
638
69328
  registerQuantifierInternal(f);
639
  // assert it to each module
640
69328
  d_model->assertQuantifier(f);
641
401059
  for (QuantifiersModule*& mdl : d_modules)
642
  {
643
331731
    mdl->assertNode(f);
644
  }
645
  // add term to the registry
646
69328
  d_treg.addTerm(d_qreg.getInstConstantBody(f), true);
647
}
648
649
1076488
void QuantifiersEngine::eqNotifyNewClass(TNode t) { d_treg.addTerm(t); }
650
651
void QuantifiersEngine::markRelevant( Node q ) {
652
  d_model->markRelevant( q );
653
}
654
655
62
void QuantifiersEngine::getInstantiationTermVectors( Node q, std::vector< std::vector< Node > >& tvecs ) {
656
62
  d_qim.getInstantiate()->getInstantiationTermVectors(q, tvecs);
657
62
}
658
659
8
void QuantifiersEngine::getInstantiationTermVectors( std::map< Node, std::vector< std::vector< Node > > >& insts ) {
660
8
  d_qim.getInstantiate()->getInstantiationTermVectors(insts);
661
8
}
662
663
18
void QuantifiersEngine::getInstantiations(Node q, std::vector<Node>& insts)
664
{
665
18
  d_qim.getInstantiate()->getInstantiations(q, insts);
666
18
}
667
668
93
void QuantifiersEngine::getInstantiatedQuantifiedFormulas(std::vector<Node>& qs)
669
{
670
93
  d_qim.getInstantiate()->getInstantiatedQuantifiedFormulas(qs);
671
93
}
672
673
12
void QuantifiersEngine::getSkolemTermVectors(
674
    std::map<Node, std::vector<Node> >& sks) const
675
{
676
12
  d_qim.getSkolemize()->getSkolemTermVectors(sks);
677
12
}
678
679
Node QuantifiersEngine::getNameForQuant(Node q) const
680
{
681
  return d_qreg.getNameForQuant(q);
682
}
683
684
30
bool QuantifiersEngine::getNameForQuant(Node q, Node& name, bool req) const
685
{
686
30
  return d_qreg.getNameForQuant(q, name, req);
687
}
688
689
288
bool QuantifiersEngine::getSynthSolutions(
690
    std::map<Node, std::map<Node, Node> >& sol_map)
691
{
692
288
  return d_qmodules->d_synth_e->getSynthSolutions(sol_map);
693
}
694
5
void QuantifiersEngine::declarePool(Node p, const std::vector<Node>& initValue)
695
{
696
5
  d_treg.declarePool(p, initValue);
697
5
}
698
699
}  // namespace theory
700
31137
}  // namespace cvc5