GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/arith/nl/strategy.cpp Lines: 66 108 61.1 %
Date: 2021-09-29 Branches: 77 201 38.3 %

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
7557
inline StepSequence& operator<<(StepSequence& steps, InferStep s)
70
{
71
7557
  steps.emplace_back(s);
72
7557
  return steps;
73
}
74
}  // namespace
75
76
234
void Interleaving::add(const StepSequence& ss, std::size_t constant)
77
{
78
234
  d_branches.emplace_back(Branch{ss, constant});
79
234
  d_size += constant;
80
234
}
81
void Interleaving::resetCounter() { d_counter = 0; }
82
83
1818
const StepSequence& Interleaving::get()
84
{
85
1818
  Assert(!d_branches.empty())
86
      << "Can not get next sequence from an empty interleaving.";
87
1818
  std::size_t cnt = d_counter;
88
  // Increase the counter
89
1818
  d_counter = (d_counter + 1) % d_size;
90
1818
  for (const auto& branch : d_branches)
91
  {
92
1818
    if (cnt < branch.d_interleavingConstant)
93
    {
94
      // This is the current branch
95
1818
      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
1818
bool Interleaving::empty() const { return d_branches.empty(); }
103
104
31359
bool StepGenerator::hasNext() const { return d_next < d_steps.size(); }
105
31068
InferStep StepGenerator::next() { return d_steps[d_next++]; }
106
107
1818
bool Strategy::isStrategyInit() const { return !d_interleaving.empty(); }
108
234
void Strategy::initializeStrategy(const Options& options)
109
{
110
468
  StepSequence one;
111
234
  if (options.arith.nlICP)
112
  {
113
2
    one << InferStep::ICP << InferStep::BREAK;
114
  }
115
234
  if (options.arith.nlExt == options::NlExtMode::FULL
116
31
      || options.arith.nlExt == options::NlExtMode::LIGHT)
117
  {
118
230
    one << InferStep::NL_INIT << InferStep::BREAK;
119
  }
120
234
  if (options.arith.nlExt == options::NlExtMode::FULL)
121
  {
122
203
    one << InferStep::TRANS_INIT << InferStep::BREAK;
123
203
    if (options.arith.nlExtSplitZero)
124
    {
125
      one << InferStep::NL_SPLIT_ZERO << InferStep::BREAK;
126
    }
127
203
    one << InferStep::TRANS_INITIAL << InferStep::BREAK;
128
  }
129
234
  one << InferStep::IAND_INIT;
130
234
  one << InferStep::IAND_INITIAL << InferStep::BREAK;
131
234
  one << InferStep::POW2_INIT;
132
234
  one << InferStep::POW2_INITIAL << InferStep::BREAK;
133
234
  if (options.arith.nlExt == options::NlExtMode::FULL
134
31
      || options.arith.nlExt == options::NlExtMode::LIGHT)
135
  {
136
230
    one << InferStep::NL_MONOMIAL_SIGN << InferStep::BREAK;
137
230
    one << InferStep::NL_MONOMIAL_MAGNITUDE0 << InferStep::BREAK;
138
  }
139
234
  if (options.arith.nlExt == options::NlExtMode::FULL)
140
  {
141
203
    one << InferStep::TRANS_MONOTONIC << InferStep::BREAK;
142
203
    one << InferStep::NL_MONOMIAL_MAGNITUDE1 << InferStep::BREAK;
143
203
    one << InferStep::NL_MONOMIAL_MAGNITUDE2 << InferStep::BREAK;
144
203
    one << InferStep::NL_MONOMIAL_INFER_BOUNDS;
145
203
    if (options.arith.nlExtTangentPlanes
146
28
        && options.arith.nlExtTangentPlanesInterleave)
147
    {
148
      one << InferStep::NL_TANGENT_PLANES;
149
    }
150
203
    one << InferStep::BREAK;
151
203
    one << InferStep::FLUSH_WAITING_LEMMAS << InferStep::BREAK;
152
203
    if (options.arith.nlExtFactor)
153
    {
154
203
      one << InferStep::NL_FACTORING << InferStep::BREAK;
155
    }
156
203
    if (options.arith.nlExtResBound)
157
    {
158
      one << InferStep::NL_MONOMIAL_INFER_BOUNDS << InferStep::BREAK;
159
    }
160
203
    if (options.arith.nlExtTangentPlanes
161
28
        && !options.arith.nlExtTangentPlanesInterleave)
162
    {
163
28
      one << InferStep::NL_TANGENT_PLANES_WAITING;
164
    }
165
203
    if (options.arith.nlExtTfTangentPlanes)
166
    {
167
201
      one << InferStep::TRANS_TANGENT_PLANES;
168
    }
169
203
    one << InferStep::BREAK;
170
  }
171
234
  one << InferStep::IAND_FULL << InferStep::BREAK;
172
234
  one << InferStep::POW2_FULL << InferStep::BREAK;
173
234
  if (options.arith.nlCad)
174
  {
175
51
    one << InferStep::CAD_INIT;
176
  }
177
234
  if (options.arith.nlCad)
178
  {
179
51
    one << InferStep::CAD_FULL << InferStep::BREAK;
180
  }
181
182
234
  d_interleaving.add(one);
183
234
}
184
1818
StepGenerator Strategy::getStrategy()
185
{
186
1818
  return StepGenerator(d_interleaving.get());
187
}
188
189
}  // namespace nl
190
}  // namespace arith
191
}  // namespace theory
192
22746
}  // namespace cvc5