GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers_engine.cpp Lines: 295 350 84.3 %
Date: 2021-09-18 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
9940
QuantifiersEngine::QuantifiersEngine(
48
    Env& env,
49
    quantifiers::QuantifiersState& qs,
50
    quantifiers::QuantifiersRegistry& qr,
51
    quantifiers::TermRegistry& tr,
52
    quantifiers::QuantifiersInferenceManager& qim,
53
9940
    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
9940
      d_quants_prereg(userContext()),
63
9940
      d_quants_red(userContext()),
64
29820
      d_numInstRoundsLemma(0)
65
{
66
19880
  Trace("quant-init-debug")
67
19880
      << "Initialize model engine, mbqi : " << options::mbqiMode() << " "
68
9940
      << 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
29747
  if (options::fmfBound() || options::stringExp()
73
20131
      || (options::finiteModelFind()
74
264
          && (options::mbqiMode() == options::MbqiMode::FMC
75
13
              || options::mbqiMode() == options::MbqiMode::TRUST)))
76
  {
77
1462
    Trace("quant-init-debug") << "...make fmc builder." << std::endl;
78
2924
    d_builder.reset(
79
1462
        new quantifiers::fmcheck::FullModelChecker(env, qs, qim, qr, tr));
80
  }
81
  else
82
  {
83
8478
    Trace("quant-init-debug") << "...make default model builder." << std::endl;
84
8478
    d_builder.reset(new quantifiers::QModelBuilder(env, qs, qim, qr, tr));
85
  }
86
  // set the model object
87
9940
  d_builder->finishInit();
88
9940
  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
9940
  d_treg.finishInit(d_model, &d_qim);
98
99
  // initialize the utilities
100
9940
  d_util.push_back(d_model->getEqualityQuery());
101
  // quantifiers registry must come before the remaining utilities
102
9940
  d_util.push_back(&d_qreg);
103
9940
  d_util.push_back(tr.getTermDatabase());
104
9940
  d_util.push_back(qim.getInstantiate());
105
9940
  d_util.push_back(tr.getTermPools());
106
9940
}
107
108
19874
QuantifiersEngine::~QuantifiersEngine() {}
109
110
6839
void QuantifiersEngine::finishInit(TheoryEngine* te)
111
{
112
  // connect the quantifiers model to the underlying theory model
113
6839
  d_model->finishInit(te->getModel());
114
6839
  d_te = te;
115
  // Initialize the modules and the utilities here.
116
6839
  d_qmodules.reset(new quantifiers::QuantifiersModules());
117
6839
  d_qmodules->initialize(
118
      d_env, d_qstate, d_qim, d_qreg, d_treg, d_builder.get(), d_modules);
119
6839
  if (d_qmodules->d_rel_dom.get())
120
  {
121
98
    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
6839
  d_qreg.getQuantifiersBoundInference().finishInit(d_qmodules->d_bint.get());
129
6839
}
130
131
quantifiers::QuantifiersRegistry& QuantifiersEngine::getQuantifiersRegistry()
132
{
133
  return d_qreg;
134
}
135
136
6839
quantifiers::QModelBuilder* QuantifiersEngine::getModelBuilder() const
137
{
138
6839
  return d_builder.get();
139
}
140
141
/// !!!!!!!!!!!!!! temporary (project #15)
142
143
1233
quantifiers::TermDbSygus* QuantifiersEngine::getTermDatabaseSygus() const
144
{
145
1233
  return d_treg.getTermDatabaseSygus();
146
}
147
/// !!!!!!!!!!!!!!
148
149
8211
void QuantifiersEngine::presolve() {
150
8211
  Trace("quant-engine-proc") << "QuantifiersEngine : presolve " << std::endl;
151
8211
  d_numInstRoundsLemma = 0;
152
8211
  d_qim.clearPending();
153
49364
  for (QuantifiersUtil*& u : d_util)
154
  {
155
41153
    u->presolve();
156
  }
157
49744
  for (QuantifiersModule*& mdl : d_modules)
158
  {
159
41533
    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
8211
  d_treg.presolve();
164
8211
}
165
166
8167
void QuantifiersEngine::ppNotifyAssertions(
167
    const std::vector<Node>& assertions) {
168
16334
  Trace("quant-engine-proc")
169
16334
      << "ppNotifyAssertions in QE, #assertions = " << assertions.size()
170
8167
      << std::endl;
171
8167
  if (options::instLevelInputOnly() && options::instMaxLevel() != -1)
172
  {
173
234
    for (const Node& a : assertions)
174
    {
175
230
      quantifiers::QuantAttributes::setInstantiationLevelAttr(a, 0);
176
    }
177
  }
178
8167
  if (options::sygus())
179
  {
180
1203
    quantifiers::SynthEngine* sye = d_qmodules->d_synth_e.get();
181
3792
    for (const Node& a : assertions)
182
    {
183
2589
      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
8167
  if (options::sygusInst())
190
  {
191
65
    quantifiers::SygusInst* si = d_qmodules->d_sygus_inst.get();
192
65
    si->ppNotifyAssertions(assertions);
193
  }
194
8167
}
195
196
101722
void QuantifiersEngine::check( Theory::Effort e ){
197
101722
  quantifiers::QuantifiersStatistics& stats = d_qstate.getStats();
198
203444
  CodeTimer codeTimer(stats.d_time);
199
101722
  Assert(d_qstate.getEqualityEngine() != nullptr);
200
101722
  if (!d_qstate.getEqualityEngine()->consistent())
201
  {
202
    Trace("quant-engine-debug") << "Master equality engine not consistent, return." << std::endl;
203
    return;
204
  }
205
101722
  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
101722
  bool needsCheck = d_qim.hasPendingLemma();
231
101722
  QuantifiersModule::QEffort needsModelE = QuantifiersModule::QEFFORT_NONE;
232
203444
  std::vector< QuantifiersModule* > qm;
233
101722
  if( d_model->checkNeeded() ){
234
77883
    needsCheck = needsCheck || e>=Theory::EFFORT_LAST_CALL;  //always need to check at or above last call
235
467685
    for (QuantifiersModule*& mdl : d_modules)
236
    {
237
389802
      if (mdl->needsCheck(e))
238
      {
239
64598
        qm.push_back(mdl);
240
64598
        needsCheck = true;
241
        //can only request model at last call since theory combination can find inconsistencies
242
64598
        if( e>=Theory::EFFORT_LAST_CALL ){
243
41731
          QuantifiersModule::QEffort me = mdl->needsModel(e);
244
41731
          needsModelE = me<needsModelE ? me : needsModelE;
245
        }
246
      }
247
    }
248
  }
249
250
101722
  d_qim.reset();
251
101722
  bool setIncomplete = false;
252
101722
  IncompleteId setIncompleteId = IncompleteId::QUANTIFIERS;
253
203444
  if (options::instMaxRounds() >= 0
254
101722
      && 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
101722
  Trace("quant-engine-debug2") << "Quantifiers Engine call to check, level = " << e << ", needsCheck=" << needsCheck << std::endl;
262
101722
  if( needsCheck ){
263
    //flush previous lemmas (for instance, if was interrupted), or other lemmas to process
264
28109
    d_qim.doPending();
265
28109
    if (d_qim.hasSentLemma())
266
    {
267
      return;
268
    }
269
270
28109
    double clSet = 0;
271
28109
    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
28109
    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
28109
    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
28109
    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
28109
    Trace("quant-engine-debug") << "Resetting all utilities..." << std::endl;
309
169870
    for (QuantifiersUtil*& util : d_util)
310
    {
311
283522
      Trace("quant-engine-debug2") << "Reset " << util->identify().c_str()
312
141761
                                   << "..." << std::endl;
313
141761
      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
28109
    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
28109
    Trace("quant-engine-debug") << "Reset model..." << std::endl;
333
28109
    d_model->reset_round();
334
335
    //reset the modules
336
28109
    Trace("quant-engine-debug") << "Resetting all modules..." << std::endl;
337
175499
    for (QuantifiersModule*& mdl : d_modules)
338
    {
339
294780
      Trace("quant-engine-debug2") << "Reset " << mdl->identify().c_str()
340
147390
                                   << std::endl;
341
147390
      mdl->reset_round(e);
342
    }
343
28109
    Trace("quant-engine-debug") << "Done resetting all modules." << std::endl;
344
    //reset may have added lemmas
345
28109
    d_qim.doPending();
346
28109
    if (d_qim.hasSentLemma())
347
    {
348
      return;
349
    }
350
351
28109
    if( e==Theory::EFFORT_LAST_CALL ){
352
11382
      ++(stats.d_instantiation_rounds_lc);
353
16727
    }else if( e==Theory::EFFORT_FULL ){
354
16727
      ++(stats.d_instantiation_rounds);
355
    }
356
28109
    Trace("quant-engine-debug") << "Check modules that needed check..." << std::endl;
357
109937
    for (unsigned qef = QuantifiersModule::QEFFORT_CONFLICT;
358
109937
         qef <= QuantifiersModule::QEFFORT_LAST_CALL;
359
         ++qef)
360
    {
361
93092
      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
93092
      if (needsModelE == quant_e)
365
      {
366
10345
        Trace("quant-engine-debug") << "Build model..." << std::endl;
367
10345
        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
11254
          break;
373
        }
374
      }
375
93092
      if (!d_qim.hasSentLemma())
376
      {
377
        //check each module
378
292816
        for (QuantifiersModule*& mdl : qm)
379
        {
380
399488
          Trace("quant-engine-debug") << "Check " << mdl->identify().c_str()
381
199744
                                      << " at effort " << quant_e << "..."
382
199744
                                      << std::endl;
383
199744
          mdl->check(e, quant_e);
384
199735
          if (d_qstate.isInConflict())
385
          {
386
11
            Trace("quant-engine-debug") << "...conflict!" << std::endl;
387
11
            break;
388
          }
389
        }
390
        //flush all current lemmas
391
93083
        d_qim.doPending();
392
      }
393
      //if we have added one, stop
394
93082
      if (d_qim.hasSentLemma())
395
      {
396
10732
        break;
397
      }else{
398
82350
        Assert(!d_qstate.isInConflict());
399
82350
        if (quant_e == QuantifiersModule::QEFFORT_CONFLICT)
400
        {
401
26610
          d_qstate.incrementInstRoundCounters(e);
402
        }
403
55740
        else if (quant_e == QuantifiersModule::QEFFORT_MODEL)
404
        {
405
17482
          if( e==Theory::EFFORT_LAST_CALL ){
406
            //sources of incompleteness
407
16037
            for (QuantifiersUtil*& util : d_util)
408
            {
409
13399
              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
2638
            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
2638
            if( !setIncomplete ){
424
              //check if we should set the incomplete flag
425
15789
              for (QuantifiersModule*& mdl : d_modules)
426
              {
427
13215
                if (!mdl->checkComplete(setIncompleteId))
428
                {
429
126
                  Trace("quant-engine-debug")
430
63
                      << "Set incomplete because module "
431
126
                      << mdl->identify().c_str() << " was incomplete."
432
63
                      << std::endl;
433
63
                  setIncomplete = true;
434
63
                  break;
435
                }
436
              }
437
2637
              if( !setIncomplete ){
438
                //look at individual quantified formulas, one module must claim completeness for each one
439
3971
                for( unsigned i=0; i<d_model->getNumAssertedQuantifiers(); i++ ){
440
3449
                  bool hasCompleteM = false;
441
4846
                  Node q = d_model->getAssertedQuantifier( i );
442
3449
                  QuantifiersModule* qmd = d_qreg.getOwner(q);
443
3449
                  if( qmd!=NULL ){
444
1974
                    hasCompleteM = qmd->checkCompleteFor( q );
445
                  }else{
446
5886
                    for( unsigned j=0; j<d_modules.size(); j++ ){
447
5621
                      if( d_modules[j]->checkCompleteFor( q ) ){
448
1210
                        qmd = d_modules[j];
449
1210
                        hasCompleteM = true;
450
1210
                        break;
451
                      }
452
                    }
453
                  }
454
3449
                  if( !hasCompleteM ){
455
2052
                    Trace("quant-engine-debug") << "Set incomplete because " << q << " was not fully processed." << std::endl;
456
2052
                    setIncomplete = true;
457
2052
                    break;
458
                  }else{
459
1397
                    Assert(qmd != NULL);
460
1397
                    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
2638
            if( !setIncomplete ){
467
522
              break;
468
            }
469
          }
470
        }
471
      }
472
    }
473
28099
    Trace("quant-engine-debug") << "Done check modules that needed check." << std::endl;
474
    // debug print
475
28099
    if (d_qim.hasSentLemma())
476
    {
477
10732
      d_qim.getInstantiate()->notifyEndRound();
478
10732
      d_numInstRoundsLemma++;
479
    }
480
28099
    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
28099
    Trace("quant-engine-debug2") << "Finished quantifiers engine check." << std::endl;
488
  }else{
489
73613
    Trace("quant-engine-debug2") << "Quantifiers Engine does not need check." << std::endl;
490
  }
491
492
  //SAT case
493
101712
  if (e == Theory::EFFORT_LAST_CALL && !d_qim.hasSentLemma())
494
  {
495
5909
    if( setIncomplete ){
496
2027
      Trace("quant-engine") << "Set incomplete flag." << std::endl;
497
2027
      d_qim.setIncomplete(setIncompleteId);
498
    }
499
    //output debug stats
500
5909
    d_qim.getInstantiate()->debugPrintModel();
501
  }
502
}
503
504
13373
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
13373
}
509
510
115968
bool QuantifiersEngine::reduceQuantifier( Node q ) {
511
  //TODO: this can be unified with preregistration: AlphaEquivalence takes ownership of reducable quants
512
115968
  BoolMap::const_iterator it = d_quants_red.find( q );
513
115968
  if( it==d_quants_red.end() ){
514
53820
    Node lem;
515
26910
    InferenceId id = InferenceId::UNKNOWN;
516
26910
    std::map< Node, Node >::iterator itr = d_quants_red_lem.find( q );
517
26910
    if( itr==d_quants_red_lem.end() ){
518
26871
      if (d_qmodules->d_alpha_equiv)
519
      {
520
26871
        Trace("quant-engine-red") << "Alpha equivalence " << q << "?" << std::endl;
521
        //add equivalence with another quantified formula
522
26871
        lem = d_qmodules->d_alpha_equiv->reduceQuantifier(q);
523
26871
        id = InferenceId::QUANTIFIERS_REDUCE_ALPHA_EQ;
524
26871
        if( !lem.isNull() ){
525
1795
          Trace("quant-engine-red") << "...alpha equivalence success." << std::endl;
526
1795
          ++(d_qstate.getStats().d_red_alpha_equiv);
527
        }
528
      }
529
26871
      d_quants_red_lem[q] = lem;
530
    }else{
531
39
      lem = itr->second;
532
    }
533
26910
    if( !lem.isNull() ){
534
1795
      d_qim.lemma(lem, id);
535
    }
536
26910
    d_quants_red[q] = !lem.isNull();
537
26910
    return !lem.isNull();
538
  }else{
539
89058
    return (*it).second;
540
  }
541
}
542
543
93307
void QuantifiersEngine::registerQuantifierInternal(Node f)
544
{
545
93307
  std::map< Node, bool >::iterator it = d_quants.find( f );
546
93307
  if( it==d_quants.end() ){
547
25076
    Trace("quant") << "QuantifiersEngine : Register quantifier ";
548
25076
    Trace("quant") << " : " << f << std::endl;
549
25076
    size_t prev_lemma_waiting = d_qim.numPendingLemmas();
550
25076
    ++(d_qstate.getStats().d_num_quant);
551
25076
    Assert(f.getKind() == FORALL);
552
    // register with utilities
553
154188
    for (unsigned i = 0; i < d_util.size(); i++)
554
    {
555
129112
      d_util[i]->registerQuantifier(f);
556
    }
557
558
140155
    for (QuantifiersModule*& mdl : d_modules)
559
    {
560
230158
      Trace("quant-debug") << "check ownership with " << mdl->identify()
561
115079
                           << "..." << std::endl;
562
115079
      mdl->checkOwnership(f);
563
    }
564
25076
    QuantifiersModule* qm = d_qreg.getOwner(f);
565
50152
    Trace("quant") << " Owner : " << (qm == nullptr ? "[none]" : qm->identify())
566
25076
                   << std::endl;
567
    // register with each module
568
140155
    for (QuantifiersModule*& mdl : d_modules)
569
    {
570
230158
      Trace("quant-debug") << "register with " << mdl->identify() << "..."
571
115079
                           << std::endl;
572
115079
      mdl->registerQuantifier(f);
573
      // since this is context-independent, we should not add any lemmas during
574
      // this call
575
115079
      Assert(d_qim.numPendingLemmas() == prev_lemma_waiting);
576
    }
577
25076
    Trace("quant-debug") << "...finish." << std::endl;
578
25076
    d_quants[f] = true;
579
25076
    AlwaysAssert(d_qim.numPendingLemmas() == prev_lemma_waiting);
580
  }
581
93307
}
582
583
31978
void QuantifiersEngine::preRegisterQuantifier(Node q)
584
{
585
31978
  NodeSet::const_iterator it = d_quants_prereg.find(q);
586
31978
  if (it != d_quants_prereg.end())
587
  {
588
11931
    return;
589
  }
590
26910
  Trace("quant-debug") << "QuantifiersEngine : Pre-register " << q << std::endl;
591
26910
  d_quants_prereg.insert(q);
592
  // try to reduce
593
26910
  if (reduceQuantifier(q))
594
  {
595
    // if we can reduce it, nothing left to do
596
1795
    return;
597
  }
598
  // ensure that it is registered
599
25115
  registerQuantifierInternal(q);
600
  // register with each module
601
140395
  for (QuantifiersModule*& mdl : d_modules)
602
  {
603
230562
    Trace("quant-debug") << "pre-register with " << mdl->identify() << "..."
604
115281
                         << std::endl;
605
115282
    mdl->preRegisterQuantifier(q);
606
  }
607
  // flush the lemmas
608
25114
  d_qim.doPending();
609
25114
  Trace("quant-debug") << "...finish pre-register " << q << "..." << std::endl;
610
}
611
612
89058
void QuantifiersEngine::assertQuantifier( Node f, bool pol ){
613
89058
  if (reduceQuantifier(f))
614
  {
615
    // if we can reduce it, nothing left to do
616
10175
    return;
617
  }
618
78883
  if( !pol ){
619
    // do skolemization
620
21382
    TrustNode lem = d_qim.getSkolemize()->process(f);
621
10691
    if (!lem.isNull())
622
    {
623
2398
      if (Trace.isOn("quantifiers-sk-debug"))
624
      {
625
        Node slem = Rewriter::rewrite(lem.getNode());
626
        Trace("quantifiers-sk-debug")
627
            << "Skolemize lemma : " << slem << std::endl;
628
      }
629
2398
      d_qim.trustedLemma(lem,
630
                         InferenceId::QUANTIFIERS_SKOLEMIZE,
631
                         LemmaProperty::NEEDS_JUSTIFY);
632
    }
633
10691
    return;
634
  }
635
  // ensure the quantified formula is registered
636
68192
  registerQuantifierInternal(f);
637
  // assert it to each module
638
68192
  d_model->assertQuantifier(f);
639
394202
  for (QuantifiersModule*& mdl : d_modules)
640
  {
641
326010
    mdl->assertNode(f);
642
  }
643
  // add term to the registry
644
68192
  d_treg.addTerm(d_qreg.getInstConstantBody(f), true);
645
}
646
647
900741
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
8
void QuantifiersEngine::getInstantiationTermVectors( std::map< Node, std::vector< std::vector< Node > > >& insts ) {
658
8
  d_qim.getInstantiate()->getInstantiationTermVectors(insts);
659
8
}
660
661
16
void QuantifiersEngine::getInstantiations(Node q, std::vector<Node>& insts)
662
{
663
16
  d_qim.getInstantiate()->getInstantiations(q, insts);
664
16
}
665
666
69
void QuantifiersEngine::getInstantiatedQuantifiedFormulas(std::vector<Node>& qs)
667
{
668
69
  d_qim.getInstantiate()->getInstantiatedQuantifiedFormulas(qs);
669
69
}
670
671
12
void QuantifiersEngine::getSkolemTermVectors(
672
    std::map<Node, std::vector<Node> >& sks) const
673
{
674
12
  d_qim.getSkolemize()->getSkolemTermVectors(sks);
675
12
}
676
677
Node QuantifiersEngine::getNameForQuant(Node q) const
678
{
679
  return d_qreg.getNameForQuant(q);
680
}
681
682
30
bool QuantifiersEngine::getNameForQuant(Node q, Node& name, bool req) const
683
{
684
30
  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
5
void QuantifiersEngine::declarePool(Node p, const std::vector<Node>& initValue)
693
{
694
5
  d_treg.declarePool(p, initValue);
695
5
}
696
697
}  // namespace theory
698
29574
}  // namespace cvc5