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