GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/arith/nl/strategy.cpp Lines: 66 108 61.1 %
Date: 2021-08-06 Branches: 124 297 41.8 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Gereon Kremer, Andrew Reynolds
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 non-linear solver.
14
 */
15
16
#include "theory/arith/nl/strategy.h"
17
18
#include <iostream>
19
20
#include "base/check.h"
21
#include "options/arith_options.h"
22
23
namespace cvc5 {
24
namespace theory {
25
namespace arith {
26
namespace nl {
27
28
std::ostream& operator<<(std::ostream& os, InferStep step)
29
{
30
  switch (step)
31
  {
32
    case InferStep::BREAK: return os << "BREAK";
33
    case InferStep::FLUSH_WAITING_LEMMAS: return os << "FLUSH_WAITING_LEMMAS";
34
    case InferStep::CAD_INIT: return os << "CAD_INIT";
35
    case InferStep::CAD_FULL: return os << "CAD_FULL";
36
    case InferStep::NL_FACTORING: return os << "NL_FACTORING";
37
    case InferStep::IAND_INIT: return os << "IAND_INIT";
38
    case InferStep::IAND_FULL: return os << "IAND_FULL";
39
    case InferStep::IAND_INITIAL: return os << "IAND_INITIAL";
40
    case InferStep::POW2_INIT: return os << "POW2_INIT";
41
    case InferStep::POW2_FULL: return os << "POW2_FULL";
42
    case InferStep::POW2_INITIAL: return os << "POW2_INITIAL";
43
    case InferStep::ICP: return os << "ICP";
44
    case InferStep::NL_INIT: return os << "NL_INIT";
45
    case InferStep::NL_MONOMIAL_INFER_BOUNDS:
46
      return os << "NL_MONOMIAL_INFER_BOUNDS";
47
    case InferStep::NL_MONOMIAL_MAGNITUDE0:
48
      return os << "NL_MONOMIAL_MAGNITUDE0";
49
    case InferStep::NL_MONOMIAL_MAGNITUDE1:
50
      return os << "NL_MONOMIAL_MAGNITUDE1";
51
    case InferStep::NL_MONOMIAL_MAGNITUDE2:
52
      return os << "NL_MONOMIAL_MAGNITUDE2";
53
    case InferStep::NL_MONOMIAL_SIGN: return os << "NL_MONOMIAL_SIGN";
54
    case InferStep::NL_RESOLUTION_BOUNDS: return os << "NL_RESOLUTION_BOUNDS";
55
    case InferStep::NL_SPLIT_ZERO: return os << "NL_SPLIT_ZERO";
56
    case InferStep::NL_TANGENT_PLANES: return os << "NL_TANGENT_PLANES";
57
    case InferStep::NL_TANGENT_PLANES_WAITING:
58
      return os << "NL_TANGENT_PLANES_WAITING";
59
    case InferStep::TRANS_INIT: return os << "TRANS_INIT";
60
    case InferStep::TRANS_INITIAL: return os << "TRANS_INITIAL";
61
    case InferStep::TRANS_MONOTONIC: return os << "TRANS_MONOTONIC";
62
    case InferStep::TRANS_TANGENT_PLANES: return os << "TRANS_TANGENT_PLANES";
63
    default: Unreachable(); return os << "UNKNOWN_STEP";
64
  }
65
}
66
67
namespace {
68
/** Puts a new InferStep into a StepSequence */
69
15246
inline StepSequence& operator<<(StepSequence& steps, InferStep s)
70
{
71
15246
  steps.emplace_back(s);
72
15246
  return steps;
73
}
74
}  // namespace
75
76
458
void Interleaving::add(const StepSequence& ss, std::size_t constant)
77
{
78
458
  d_branches.emplace_back(Branch{ss, constant});
79
458
  d_size += constant;
80
458
}
81
void Interleaving::resetCounter() { d_counter = 0; }
82
83
2814
const StepSequence& Interleaving::get()
84
{
85
2814
  Assert(!d_branches.empty())
86
      << "Can not get next sequence from an empty interleaving.";
87
2814
  std::size_t cnt = d_counter;
88
  // Increase the counter
89
2814
  d_counter = (d_counter + 1) % d_size;
90
2814
  for (const auto& branch : d_branches)
91
  {
92
2814
    if (cnt < branch.d_interleavingConstant)
93
    {
94
      // This is the current branch
95
2814
      return branch.d_steps;
96
    }
97
    cnt -= branch.d_interleavingConstant;
98
  }
99
  Assert(false) << "Something went wrong.";
100
  return d_branches[0].d_steps;
101
}
102
2814
bool Interleaving::empty() const { return d_branches.empty(); }
103
104
48891
bool StepGenerator::hasNext() const { return d_next < d_steps.size(); }
105
48608
InferStep StepGenerator::next() { return d_steps[d_next++]; }
106
107
2814
bool Strategy::isStrategyInit() const { return !d_interleaving.empty(); }
108
458
void Strategy::initializeStrategy()
109
{
110
916
  StepSequence one;
111
916
  if (options::nlICP())
112
  {
113
2
    one << InferStep::ICP << InferStep::BREAK;
114
  }
115
916
  if (options::nlExt() == options::NlExtMode::FULL
116
458
      || options::nlExt() == options::NlExtMode::LIGHT)
117
  {
118
451
    one << InferStep::NL_INIT << InferStep::BREAK;
119
  }
120
458
  if (options::nlExt() == options::NlExtMode::FULL)
121
  {
122
425
    one << InferStep::TRANS_INIT << InferStep::BREAK;
123
850
    if (options::nlExtSplitZero())
124
    {
125
      one << InferStep::NL_SPLIT_ZERO << InferStep::BREAK;
126
    }
127
425
    one << InferStep::TRANS_INITIAL << InferStep::BREAK;
128
  }
129
458
  one << InferStep::IAND_INIT;
130
458
  one << InferStep::IAND_INITIAL << InferStep::BREAK;
131
458
  one << InferStep::POW2_INIT;
132
458
  one << InferStep::POW2_INITIAL << InferStep::BREAK;
133
916
  if (options::nlExt() == options::NlExtMode::FULL
134
458
      || options::nlExt() == options::NlExtMode::LIGHT)
135
  {
136
451
    one << InferStep::NL_MONOMIAL_SIGN << InferStep::BREAK;
137
451
    one << InferStep::NL_MONOMIAL_MAGNITUDE0 << InferStep::BREAK;
138
  }
139
458
  if (options::nlExt() == options::NlExtMode::FULL)
140
  {
141
425
    one << InferStep::TRANS_MONOTONIC << InferStep::BREAK;
142
425
    one << InferStep::NL_MONOMIAL_MAGNITUDE1 << InferStep::BREAK;
143
425
    one << InferStep::NL_MONOMIAL_MAGNITUDE2 << InferStep::BREAK;
144
425
    one << InferStep::NL_MONOMIAL_INFER_BOUNDS;
145
850
    if (options::nlExtTangentPlanes()
146
567
        && options::nlExtTangentPlanesInterleave())
147
    {
148
      one << InferStep::NL_TANGENT_PLANES;
149
    }
150
425
    one << InferStep::BREAK;
151
425
    one << InferStep::FLUSH_WAITING_LEMMAS << InferStep::BREAK;
152
850
    if (options::nlExtFactor())
153
    {
154
425
      one << InferStep::NL_FACTORING << InferStep::BREAK;
155
    }
156
850
    if (options::nlExtResBound())
157
    {
158
      one << InferStep::NL_MONOMIAL_INFER_BOUNDS << InferStep::BREAK;
159
    }
160
850
    if (options::nlExtTangentPlanes()
161
425
        && !options::nlExtTangentPlanesInterleave())
162
    {
163
71
      one << InferStep::NL_TANGENT_PLANES_WAITING;
164
    }
165
850
    if (options::nlExtTfTangentPlanes())
166
    {
167
423
      one << InferStep::TRANS_TANGENT_PLANES;
168
    }
169
425
    one << InferStep::BREAK;
170
  }
171
458
  one << InferStep::IAND_FULL << InferStep::BREAK;
172
458
  one << InferStep::POW2_FULL << InferStep::BREAK;
173
458
  if (options::nlCad())
174
  {
175
79
    one << InferStep::CAD_INIT;
176
  }
177
458
  if (options::nlCad())
178
  {
179
79
    one << InferStep::CAD_FULL << InferStep::BREAK;
180
  }
181
182
458
  d_interleaving.add(one);
183
458
}
184
2814
StepGenerator Strategy::getStrategy()
185
{
186
2814
  return StepGenerator(d_interleaving.get());
187
}
188
189
}  // namespace nl
190
}  // namespace arith
191
}  // namespace theory
192
31622
}  // namespace cvc5