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