GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/arith/nl/nonlinear_extension.cpp Lines: 294 328 89.6 %
Date: 2021-09-08 Branches: 494 975 50.7 %

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