GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers_engine.cpp Lines: 295 350 84.3 %
Date: 2021-08-14 Branches: 527 1232 42.8 %

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