GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/arith/nl/nonlinear_extension.cpp Lines: 291 325 89.5 %
Date: 2021-09-18 Branches: 499 981 50.9 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Gereon Kremer, Tim King
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
 * [[ Add one-line brief description here ]]
14
 *
15
 * [[ Add lengthier description here ]]
16
 * \todo document this file
17
 */
18
19
#include "theory/arith/nl/nonlinear_extension.h"
20
21
#include "options/arith_options.h"
22
#include "options/smt_options.h"
23
#include "theory/arith/arith_state.h"
24
#include "theory/arith/bound_inference.h"
25
#include "theory/arith/inference_manager.h"
26
#include "theory/arith/nl/nl_lemma_utils.h"
27
#include "theory/arith/theory_arith.h"
28
#include "theory/ext_theory.h"
29
#include "theory/rewriter.h"
30
#include "theory/theory_model.h"
31
#include "util/rational.h"
32
33
using namespace cvc5::kind;
34
35
namespace cvc5 {
36
namespace theory {
37
namespace arith {
38
namespace nl {
39
40
5203
NonlinearExtension::NonlinearExtension(Env& env,
41
                                       TheoryArith& containing,
42
5203
                                       ArithState& state)
43
    : EnvObj(env),
44
      d_containing(containing),
45
      d_astate(state),
46
5203
      d_im(containing.getInferenceManager()),
47
      d_needsLastCall(false),
48
      d_checkCounter(0),
49
      d_extTheoryCb(state.getEqualityEngine()),
50
5203
      d_extTheory(d_extTheoryCb, context(), userContext(), d_im),
51
      d_model(),
52
      d_trSlv(d_im, d_model, d_env),
53
      d_extState(d_im, d_model, d_env),
54
      d_factoringSlv(&d_extState),
55
      d_monomialBoundsSlv(&d_extState),
56
      d_monomialSlv(&d_extState),
57
      d_splitZeroSlv(&d_extState),
58
      d_tangentPlaneSlv(&d_extState),
59
      d_cadSlv(d_env, d_im, d_model),
60
      d_icpSlv(d_im),
61
      d_iandSlv(env, d_im, state, d_model),
62
15609
      d_pow2Slv(env, d_im, state, d_model)
63
{
64
5203
  d_extTheory.addFunctionKind(kind::NONLINEAR_MULT);
65
5203
  d_extTheory.addFunctionKind(kind::EXPONENTIAL);
66
5203
  d_extTheory.addFunctionKind(kind::SINE);
67
5203
  d_extTheory.addFunctionKind(kind::PI);
68
5203
  d_extTheory.addFunctionKind(kind::IAND);
69
5203
  d_extTheory.addFunctionKind(kind::POW2);
70
5203
  d_true = NodeManager::currentNM()->mkConst(true);
71
5203
  d_zero = NodeManager::currentNM()->mkConst(Rational(0));
72
5203
  d_one = NodeManager::currentNM()->mkConst(Rational(1));
73
5203
  d_neg_one = NodeManager::currentNM()->mkConst(Rational(-1));
74
75
5203
  if (d_env.isTheoryProofProducing())
76
  {
77
593
    ProofChecker* pc = d_env.getProofNodeManager()->getChecker();
78
593
    d_proofChecker.registerTo(pc);
79
  }
80
5203
}
81
82
10402
NonlinearExtension::~NonlinearExtension() {}
83
84
410394
void NonlinearExtension::preRegisterTerm(TNode n)
85
{
86
  // register terms with extended theory, to find extended terms that can be
87
  // eliminated by context-depedendent simplification.
88
410394
  d_extTheory.registerTerm(n);
89
410394
}
90
91
void NonlinearExtension::processSideEffect(const NlLemma& se)
92
{
93
  d_trSlv.processSideEffect(se);
94
}
95
96
void NonlinearExtension::computeRelevantAssertions(
97
    const std::vector<Node>& assertions, std::vector<Node>& keep)
98
{
99
  Trace("nl-ext-rlv") << "Compute relevant assertions..." << std::endl;
100
  Valuation v = d_containing.getValuation();
101
  for (const Node& a : assertions)
102
  {
103
    if (v.isRelevant(a))
104
    {
105
      keep.push_back(a);
106
    }
107
  }
108
  Trace("nl-ext-rlv") << "...keep " << keep.size() << "/" << assertions.size()
109
                      << " assertions" << std::endl;
110
}
111
112
4433
void NonlinearExtension::getAssertions(std::vector<Node>& assertions)
113
{
114
4433
  Trace("nl-ext-assert-debug") << "Getting assertions..." << std::endl;
115
4433
  bool useRelevance = false;
116
4433
  if (options().arith.nlRlvMode == options::NlRlvMode::INTERLEAVE)
117
  {
118
607
    useRelevance = (d_checkCounter % 2);
119
  }
120
3826
  else if (options().arith.nlRlvMode == options::NlRlvMode::ALWAYS)
121
  {
122
31
    useRelevance = true;
123
  }
124
4433
  Valuation v = d_containing.getValuation();
125
126
8866
  BoundInference bounds;
127
128
8866
  std::unordered_set<Node> init_assertions;
129
130
531283
  for (Theory::assertions_iterator it = d_containing.facts_begin();
131
531283
       it != d_containing.facts_end();
132
       ++it)
133
  {
134
526850
    const Assertion& assertion = *it;
135
1053700
    Trace("nl-ext-assert-debug")
136
526850
        << "Loaded " << assertion.d_assertion << " from theory" << std::endl;
137
795900
    Node lit = assertion.d_assertion;
138
526850
    if (useRelevance && !v.isRelevant(lit))
139
    {
140
      // not relevant, skip
141
2146
      continue;
142
    }
143
    // if using the bound inference utility
144
524704
    if (options().arith.nlRlvAssertBounds && bounds.add(lit, false))
145
    {
146
255654
      continue;
147
    }
148
269050
    init_assertions.insert(lit);
149
  }
150
151
138010
  for (const auto& vb : bounds.get())
152
  {
153
133577
    const Bounds& b = vb.second;
154
133577
    if (!b.lower_bound.isNull())
155
    {
156
88577
      init_assertions.insert(b.lower_bound);
157
    }
158
133577
    if (!b.upper_bound.isNull())
159
    {
160
77345
      init_assertions.insert(b.upper_bound);
161
    }
162
  }
163
164
  // Try to be "more deterministic" by adding assertions in the order they were
165
  // given
166
531283
  for (auto it = d_containing.facts_begin(); it != d_containing.facts_end();
167
       ++it)
168
  {
169
1053700
    Node lit = (*it).d_assertion;
170
526850
    auto iait = init_assertions.find(lit);
171
526850
    if (iait != init_assertions.end())
172
    {
173
407027
      Trace("nl-ext-assert-debug") << "Adding " << lit << std::endl;
174
407027
      assertions.push_back(lit);
175
407027
      init_assertions.erase(iait);
176
    }
177
  }
178
  // Now add left over assertions that have been newly created within this
179
  // function by the code above.
180
6034
  for (const Node& a : init_assertions)
181
  {
182
1601
    Trace("nl-ext-assert-debug") << "Adding " << a << std::endl;
183
1601
    assertions.push_back(a);
184
  }
185
8866
  Trace("nl-ext") << "...keep " << assertions.size() << " / "
186
8866
                  << d_containing.numAssertions() << " assertions."
187
4433
                  << std::endl;
188
4433
}
189
190
4433
std::vector<Node> NonlinearExtension::checkModelEval(
191
    const std::vector<Node>& assertions)
192
{
193
4433
  std::vector<Node> false_asserts;
194
413061
  for (size_t i = 0; i < assertions.size(); ++i)
195
  {
196
817256
    Node lit = assertions[i];
197
817256
    Node atom = lit.getKind() == NOT ? lit[0] : lit;
198
817256
    Node litv = d_model.computeConcreteModelValue(lit);
199
408628
    Trace("nl-ext-mv-assert") << "M[[ " << lit << " ]] -> " << litv;
200
408628
    if (litv != d_true)
201
    {
202
59940
      Trace("nl-ext-mv-assert") << " [model-false]" << std::endl;
203
59940
      false_asserts.push_back(lit);
204
    }
205
    else
206
    {
207
348688
      Trace("nl-ext-mv-assert") << std::endl;
208
    }
209
  }
210
4433
  return false_asserts;
211
}
212
213
262
bool NonlinearExtension::checkModel(const std::vector<Node>& assertions)
214
{
215
262
  Trace("nl-ext-cm") << "--- check-model ---" << std::endl;
216
217
  // get the presubstitution
218
262
  Trace("nl-ext-cm-debug") << "  apply pre-substitution..." << std::endl;
219
  // Notice that we do not consider relevance here, since assertions were
220
  // already filtered based on relevance. It is incorrect to filter based on
221
  // relevance here, since we may have discarded literals that are relevant
222
  // that are entailed based on the techniques in getAssertions.
223
524
  std::vector<Node> passertions = assertions;
224
262
  if (options().arith.nlExt == options::NlExtMode::FULL)
225
  {
226
    // preprocess the assertions with the trancendental solver
227
246
    if (!d_trSlv.preprocessAssertionsCheckModel(passertions))
228
    {
229
      return false;
230
    }
231
  }
232
262
  if (options().arith.nlCad)
233
  {
234
16
    d_cadSlv.constructModelIfAvailable(passertions);
235
  }
236
237
262
  Trace("nl-ext-cm") << "-----" << std::endl;
238
262
  unsigned tdegree = d_trSlv.getTaylorDegree();
239
524
  std::vector<NlLemma> lemmas;
240
262
  bool ret = d_model.checkModel(passertions, tdegree, lemmas);
241
262
  for (const auto& al: lemmas)
242
  {
243
    d_im.addPendingLemma(al);
244
  }
245
262
  return ret;
246
}
247
248
37747
void NonlinearExtension::check(Theory::Effort e)
249
{
250
37747
  Trace("nl-ext") << std::endl;
251
37747
  Trace("nl-ext") << "NonlinearExtension::check, effort = " << e << std::endl;
252
37747
  if (e == Theory::EFFORT_FULL)
253
  {
254
34450
    d_needsLastCall = true;
255
34450
    if (options().arith.nlExtRewrites)
256
    {
257
68900
      std::vector<Node> nred;
258
34450
      if (!d_extTheory.doInferences(0, nred))
259
      {
260
67642
        Trace("nl-ext") << "...sent no lemmas, # extf to reduce = "
261
33821
                        << nred.size() << std::endl;
262
33821
        if (nred.empty())
263
        {
264
30017
          d_needsLastCall = false;
265
        }
266
      }
267
      else
268
      {
269
629
        Trace("nl-ext") << "...sent lemmas." << std::endl;
270
      }
271
    }
272
  }
273
  else
274
  {
275
    // If we computed lemmas during collectModelInfo, send them now.
276
3297
    if (d_im.hasPendingLemma())
277
    {
278
3017
      d_im.doPendingFacts();
279
3017
      d_im.doPendingLemmas();
280
3017
      d_im.doPendingPhaseRequirements();
281
3017
      return;
282
    }
283
    // Otherwise, we will answer SAT. The values that we approximated are
284
    // recorded as approximations here.
285
280
    TheoryModel* tm = d_containing.getValuation().getModel();
286
302
    for (std::pair<const Node, std::pair<Node, Node>>& a : d_approximations)
287
    {
288
22
      if (a.second.second.isNull())
289
      {
290
22
        tm->recordApproximation(a.first, a.second.first);
291
      }
292
      else
293
      {
294
        tm->recordApproximation(a.first, a.second.first, a.second.second);
295
      }
296
    }
297
287
    for (const auto& vw : d_witnesses)
298
    {
299
7
      tm->recordApproximation(vw.first, vw.second);
300
    }
301
  }
302
}
303
304
4433
Result::Sat NonlinearExtension::modelBasedRefinement(const std::set<Node>& termSet)
305
{
306
4433
  ++(d_stats.d_mbrRuns);
307
4433
  d_checkCounter++;
308
309
  // get the assertions
310
8866
  std::vector<Node> assertions;
311
4433
  getAssertions(assertions);
312
313
8866
  Trace("nl-ext-mv-assert")
314
4433
      << "Getting model values... check for [model-false]" << std::endl;
315
  // get the assertions that are false in the model
316
8866
  const std::vector<Node> false_asserts = checkModelEval(assertions);
317
4433
  Trace("nl-ext") << "# false asserts = " << false_asserts.size() << std::endl;
318
319
  // get the extended terms belonging to this theory
320
8866
  std::vector<Node> xtsAll;
321
4433
  d_extTheory.getTerms(xtsAll);
322
  // only consider those that are currently relevant based on the current
323
  // assertions, i.e. those contained in termSet
324
8866
  std::vector<Node> xts;
325
38348
  for (const Node& x : xtsAll)
326
  {
327
33915
    if (termSet.find(x) != termSet.end())
328
    {
329
32879
      xts.push_back(x);
330
    }
331
  }
332
333
4433
  if (Trace.isOn("nl-ext-debug"))
334
  {
335
    Trace("nl-ext-debug") << "  processing NonlinearExtension::check : "
336
                          << std::endl;
337
    Trace("nl-ext-debug") << "     " << false_asserts.size()
338
                          << " false assertions" << std::endl;
339
    Trace("nl-ext-debug") << "     " << xts.size()
340
                          << " extended terms: " << std::endl;
341
    Trace("nl-ext-debug") << "       ";
342
    for (unsigned j = 0; j < xts.size(); j++)
343
    {
344
      Trace("nl-ext-debug") << xts[j] << " ";
345
    }
346
    Trace("nl-ext-debug") << std::endl;
347
  }
348
349
  // compute whether shared terms have correct values
350
4433
  unsigned num_shared_wrong_value = 0;
351
8866
  std::vector<Node> shared_term_value_splits;
352
  // must ensure that shared terms are equal to their concrete value
353
4433
  Trace("nl-ext-mv") << "Shared terms : " << std::endl;
354
49186
  for (context::CDList<TNode>::const_iterator its =
355
4433
           d_containing.shared_terms_begin();
356
53619
       its != d_containing.shared_terms_end();
357
       ++its)
358
  {
359
98372
    TNode shared_term = *its;
360
    // compute its value in the model, and its evaluation in the model
361
98372
    Node stv0 = d_model.computeConcreteModelValue(shared_term);
362
98372
    Node stv1 = d_model.computeAbstractModelValue(shared_term);
363
49186
    d_model.printModelValue("nl-ext-mv", shared_term);
364
49186
    if (stv0 != stv1)
365
    {
366
5175
      num_shared_wrong_value++;
367
10350
      Trace("nl-ext-mv") << "Bad shared term value : " << shared_term
368
5175
                         << std::endl;
369
5175
      if (shared_term != stv0)
370
      {
371
        // split on the value, this is non-terminating in general, TODO :
372
        // improve this
373
10318
        Node eq = shared_term.eqNode(stv0);
374
5159
        shared_term_value_splits.push_back(eq);
375
      }
376
      else
377
      {
378
        // this can happen for transcendental functions
379
        // the problem is that we cannot evaluate transcendental functions
380
        // (they don't have a rewriter that returns constants)
381
        // thus, the actual value in their model can be themselves, hence we
382
        // have no reference point to rule out the current model.  In this
383
        // case, we may set incomplete below.
384
      }
385
    }
386
  }
387
8866
  Trace("nl-ext-debug") << "     " << num_shared_wrong_value
388
4433
                        << " shared terms with wrong model value." << std::endl;
389
  bool needsRecheck;
390
534
  do
391
  {
392
4449
    d_model.resetCheck();
393
4449
    needsRecheck = false;
394
    // complete_status:
395
    //   1 : we may answer SAT, -1 : we may not answer SAT, 0 : unknown
396
4449
    int complete_status = 1;
397
    // We require a check either if an assertion is false or a shared term has
398
    // a wrong value
399
4449
    if (!false_asserts.empty() || num_shared_wrong_value > 0)
400
    {
401
4009
      complete_status = num_shared_wrong_value > 0 ? -1 : 0;
402
4009
      runStrategy(Theory::Effort::EFFORT_FULL, assertions, false_asserts, xts);
403
4009
      if (d_im.hasSentLemma() || d_im.hasPendingLemma())
404
      {
405
3626
        d_im.clearWaitingLemmas();
406
7557
        return Result::Sat::UNSAT;
407
      }
408
    }
409
1646
    Trace("nl-ext") << "Finished check with status : " << complete_status
410
823
                    << std::endl;
411
412
    // if we did not add a lemma during check and there is a chance for SAT
413
823
    if (complete_status == 0)
414
    {
415
524
      Trace("nl-ext")
416
262
          << "Check model based on bounds for irrational-valued functions..."
417
262
          << std::endl;
418
      // check the model based on simple solving of equalities and using
419
      // error bounds on the Taylor approximation of transcendental functions.
420
262
      if (checkModel(assertions))
421
      {
422
62
        complete_status = 1;
423
      }
424
262
      if (d_im.hasUsed())
425
      {
426
        d_im.clearWaitingLemmas();
427
        return Result::Sat::UNSAT;
428
      }
429
    }
430
431
    // if we have not concluded SAT
432
823
    if (complete_status != 1)
433
    {
434
      // flush the waiting lemmas
435
321
      if (d_im.hasWaitingLemma())
436
      {
437
287
        std::size_t count = d_im.numWaitingLemmas();
438
287
        d_im.flushWaitingLemmas();
439
574
        Trace("nl-ext") << "...added " << count << " waiting lemmas."
440
287
                        << std::endl;
441
287
        return Result::Sat::UNSAT;
442
      }
443
      // resort to splitting on shared terms with their model value
444
      // if we did not add any lemmas
445
34
      if (num_shared_wrong_value > 0)
446
      {
447
18
        complete_status = -1;
448
18
        if (!shared_term_value_splits.empty())
449
        {
450
88
          for (const Node& eq : shared_term_value_splits)
451
          {
452
144
            Node req = Rewriter::rewrite(eq);
453
144
            Node literal = d_containing.getValuation().ensureLiteral(req);
454
72
            d_containing.getOutputChannel().requirePhase(literal, true);
455
72
            Trace("nl-ext-debug") << "Split on : " << literal << std::endl;
456
144
            Node split = literal.orNode(literal.negate());
457
72
            d_im.addPendingLemma(split,
458
                                 InferenceId::ARITH_NL_SHARED_TERM_VALUE_SPLIT,
459
                                 nullptr,
460
                                 true);
461
          }
462
16
          if (d_im.hasWaitingLemma())
463
          {
464
14
            d_im.flushWaitingLemmas();
465
28
            Trace("nl-ext") << "...added " << d_im.numPendingLemmas()
466
14
                            << " shared term value split lemmas." << std::endl;
467
14
            return Result::Sat::UNSAT;
468
          }
469
        }
470
        else
471
        {
472
          // this can happen if we are trying to do theory combination with
473
          // trancendental functions
474
          // since their model value cannot even be computed exactly
475
        }
476
      }
477
478
      // we are incomplete
479
40
      if (options().arith.nlExt == options::NlExtMode::FULL
480
20
          && options().arith.nlExtIncPrecision && d_model.usedApproximate())
481
      {
482
16
        d_trSlv.incrementTaylorDegree();
483
16
        needsRecheck = true;
484
        // increase precision for PI?
485
        // Difficult since Taylor series is very slow to converge
486
32
        Trace("nl-ext") << "...increment Taylor degree to "
487
16
                        << d_trSlv.getTaylorDegree() << std::endl;
488
      }
489
      else
490
      {
491
8
        Trace("nl-ext") << "...failed to send lemma in "
492
4
                           "NonLinearExtension, set incomplete"
493
4
                        << std::endl;
494
4
        d_containing.getOutputChannel().setIncomplete(IncompleteId::ARITH_NL);
495
4
        return Result::Sat::SAT_UNKNOWN;
496
      }
497
    }
498
518
    d_im.clearWaitingLemmas();
499
  } while (needsRecheck);
500
501
  // did not add lemmas
502
502
  return Result::Sat::SAT;
503
}
504
505
34450
void NonlinearExtension::interceptModel(std::map<Node, Node>& arithModel,
506
                                        const std::set<Node>& termSet)
507
{
508
34450
  if (!needsCheckLastEffort())
509
  {
510
    // no non-linear constraints, we are done
511
30017
    return;
512
  }
513
4433
  Trace("nl-ext") << "NonlinearExtension::interceptModel begin" << std::endl;
514
4433
  d_model.reset(d_containing.getValuation().getModel(), arithModel);
515
  // run a last call effort check
516
4433
  Trace("nl-ext") << "interceptModel: do model-based refinement" << std::endl;
517
4433
  Result::Sat res = modelBasedRefinement(termSet);
518
4433
  if (res == Result::Sat::SAT)
519
  {
520
502
    Trace("nl-ext") << "interceptModel: do model repair" << std::endl;
521
502
    d_approximations.clear();
522
502
    d_witnesses.clear();
523
    // modify the model values
524
1004
    d_model.getModelValueRepair(arithModel,
525
                                d_approximations,
526
                                d_witnesses,
527
502
                                options().smt.modelWitnessValue);
528
  }
529
}
530
531
6433
void NonlinearExtension::presolve()
532
{
533
6433
  Trace("nl-ext") << "NonlinearExtension::presolve" << std::endl;
534
6433
}
535
536
4009
void NonlinearExtension::runStrategy(Theory::Effort effort,
537
                                     const std::vector<Node>& assertions,
538
                                     const std::vector<Node>& false_asserts,
539
                                     const std::vector<Node>& xts)
540
{
541
4009
  ++(d_stats.d_checkRuns);
542
543
4009
  if (Trace.isOn("nl-strategy"))
544
  {
545
    for (const auto& a : assertions)
546
    {
547
      Trace("nl-strategy") << "Input assertion: " << a << std::endl;
548
    }
549
  }
550
4009
  if (!d_strategy.isStrategyInit())
551
  {
552
493
    d_strategy.initializeStrategy(options());
553
  }
554
555
4009
  auto steps = d_strategy.getStrategy();
556
4009
  bool stop = false;
557
134281
  while (!stop && steps.hasNext())
558
  {
559
65136
    InferStep step = steps.next();
560
65136
    Trace("nl-strategy") << "Step " << step << std::endl;
561
65136
    switch (step)
562
    {
563
29308
      case InferStep::BREAK: stop = d_im.hasPendingLemma(); break;
564
526
      case InferStep::FLUSH_WAITING_LEMMAS: d_im.flushWaitingLemmas(); break;
565
56
      case InferStep::CAD_FULL: d_cadSlv.checkFull(); break;
566
56
      case InferStep::CAD_INIT: d_cadSlv.initLastCall(assertions); break;
567
426
      case InferStep::NL_FACTORING:
568
426
        d_factoringSlv.check(assertions, false_asserts);
569
426
        break;
570
3253
      case InferStep::IAND_INIT:
571
3253
        d_iandSlv.initLastCall(assertions, false_asserts, xts);
572
3253
        break;
573
452
      case InferStep::IAND_FULL: d_iandSlv.checkFullRefine(); break;
574
3253
      case InferStep::IAND_INITIAL: d_iandSlv.checkInitialRefine(); break;
575
3188
      case InferStep::POW2_INIT:
576
3188
        d_pow2Slv.initLastCall(assertions, false_asserts, xts);
577
3188
        break;
578
452
      case InferStep::POW2_FULL: d_pow2Slv.checkFullRefine(); break;
579
3188
      case InferStep::POW2_INITIAL: d_pow2Slv.checkInitialRefine(); break;
580
48
      case InferStep::ICP:
581
48
        d_icpSlv.reset(assertions);
582
48
        d_icpSlv.check();
583
48
        break;
584
3990
      case InferStep::NL_INIT:
585
3990
        d_extState.init(xts);
586
3990
        d_monomialBoundsSlv.init();
587
3990
        d_monomialSlv.init(xts);
588
3990
        break;
589
743
      case InferStep::NL_MONOMIAL_INFER_BOUNDS:
590
743
        d_monomialBoundsSlv.checkBounds(assertions, false_asserts);
591
743
        break;
592
2005
      case InferStep::NL_MONOMIAL_MAGNITUDE0:
593
2005
        d_monomialSlv.checkMagnitude(0);
594
2005
        break;
595
1405
      case InferStep::NL_MONOMIAL_MAGNITUDE1:
596
1405
        d_monomialSlv.checkMagnitude(1);
597
1405
        break;
598
1024
      case InferStep::NL_MONOMIAL_MAGNITUDE2:
599
1024
        d_monomialSlv.checkMagnitude(2);
600
1024
        break;
601
3161
      case InferStep::NL_MONOMIAL_SIGN: d_monomialSlv.checkSign(); break;
602
      case InferStep::NL_RESOLUTION_BOUNDS:
603
        d_monomialBoundsSlv.checkResBounds();
604
        break;
605
      case InferStep::NL_SPLIT_ZERO: d_splitZeroSlv.check(); break;
606
      case InferStep::NL_TANGENT_PLANES: d_tangentPlaneSlv.check(false); break;
607
25
      case InferStep::NL_TANGENT_PLANES_WAITING:
608
25
        d_tangentPlaneSlv.check(true);
609
25
        break;
610
3461
      case InferStep::TRANS_INIT:
611
3461
        d_trSlv.initLastCall(xts);
612
3461
        break;
613
3290
      case InferStep::TRANS_INITIAL:
614
3290
        d_trSlv.checkTranscendentalInitialRefine();
615
3290
        break;
616
1432
      case InferStep::TRANS_MONOTONIC:
617
1432
        d_trSlv.checkTranscendentalMonotonic();
618
1432
        break;
619
394
      case InferStep::TRANS_TANGENT_PLANES:
620
394
        d_trSlv.checkTranscendentalTangentPlanes();
621
394
        break;
622
    }
623
  }
624
625
4009
  Trace("nl-ext") << "finished strategy" << std::endl;
626
8018
  Trace("nl-ext") << "  ...finished with " << d_im.numWaitingLemmas()
627
4009
                  << " waiting lemmas." << std::endl;
628
8018
  Trace("nl-ext") << "  ...finished with " << d_im.numPendingLemmas()
629
4009
                  << " pending lemmas." << std::endl;
630
4009
}
631
632
}  // namespace nl
633
}  // namespace arith
634
}  // namespace theory
635
29574
}  // namespace cvc5