GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/arith/nl/transcendental/transcendental_state.h Lines: 1 1 100.0 %
Date: 2021-09-10 Branches: 3 4 75.0 %

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
 * Utilities for transcendental lemmas.
14
 */
15
16
#ifndef CVC5__THEORY__ARITH__NL__TRANSCENDENTAL__TRANSCENDENTAL_STATE_H
17
#define CVC5__THEORY__ARITH__NL__TRANSCENDENTAL__TRANSCENDENTAL_STATE_H
18
19
#include "expr/node.h"
20
#include "proof/proof_set.h"
21
#include "smt/env.h"
22
#include "theory/arith/nl/nl_lemma_utils.h"
23
#include "theory/arith/nl/transcendental/proof_checker.h"
24
#include "theory/arith/nl/transcendental/taylor_generator.h"
25
26
namespace cvc5 {
27
class CDProof;
28
namespace theory {
29
namespace arith {
30
31
class InferenceManager;
32
33
namespace nl {
34
35
class NlModel;
36
37
namespace transcendental {
38
39
/**
40
 * This enum indicates whether some function is convex, concave or unknown at
41
 * some point.
42
 */
43
enum class Convexity
44
{
45
  CONVEX,
46
  CONCAVE,
47
  UNKNOWN
48
};
49
inline std::ostream& operator<<(std::ostream& os, Convexity c) {
50
  switch (c) {
51
    case Convexity::CONVEX: return os << "CONVEX";
52
    case Convexity::CONCAVE: return os << "CONCAVE";
53
    default: return os << "UNKNOWN";
54
  }
55
}
56
57
/**
58
 * Holds common state and utilities for transcendental solvers.
59
 *
60
 * This includes common lookups and caches as well as generic utilities for
61
 * secant plane lemmas and taylor approximations.
62
 */
63
5191
struct TranscendentalState
64
{
65
  TranscendentalState(InferenceManager& im, NlModel& model, Env& env);
66
67
  /**
68
   * Checks whether proofs are enabled.
69
   */
70
  bool isProofEnabled() const;
71
  /**
72
   * Creates and returns a new LazyCDProof that can be used to prove some lemma.
73
   */
74
  CDProof* getProof();
75
76
  /** init last call
77
   *
78
   * This is called at the beginning of last call effort check xts is the set of
79
   * extended function terms that are active in the current context.
80
   *
81
   * This call may add lemmas to lems based on registering term
82
   * information (for example to ensure congruence of terms).
83
   * It puts terms that need to be treated further as a master term on their own
84
   * (for example purification of sine terms) into needsMaster.
85
   */
86
  void init(const std::vector<Node>& xts, std::vector<Node>& needsMaster);
87
88
  /**
89
   * Checks for terms that are congruent but disequal to a.
90
   * If any are found, appropriate lemmas are sent.
91
   * @param a Some node
92
   * @param argTrie Lookup for equivalence classes
93
   */
94
  void ensureCongruence(TNode a, std::map<Kind, ArgTrie>& argTrie);
95
96
  /** Initialize members for pi-related values */
97
  void mkPi();
98
  /** Get current bounds for pi as a lemma */
99
  void getCurrentPiBounds();
100
101
  /**
102
   * Get the two closest secant points from the once stored already.
103
   * "closest" is determined according to the current model.
104
   * @param e The transcendental term (like (exp t))
105
   * @param center The point currently under consideration (probably the model
106
   * of t)
107
   * @param d The taylor degree.
108
   */
109
  std::pair<Node, Node> getClosestSecantPoints(TNode e,
110
                                               TNode center,
111
                                               unsigned d);
112
113
  /**
114
   * Construct a secant plane as function in arg between lower and upper
115
   * @param arg The argument of the transcendental term
116
   * @param lower Left secant point
117
   * @param upper Right secant point
118
   * @param lval Evaluation at lower
119
   * @param uval Evaluation at upper
120
   */
121
  Node mkSecantPlane(
122
      TNode arg, TNode lower, TNode upper, TNode lval, TNode uval);
123
124
  /**
125
   * Construct a secant lemma between lower and upper for tf.
126
   * @param lower Left secant point
127
   * @param upper Right secant point
128
   * @param concavity Concavity of the current regions
129
   * @param tf Current transcendental term
130
   * @param splane Secant plane as computed by mkSecantPlane()
131
   */
132
  NlLemma mkSecantLemma(TNode lower,
133
                        TNode upper,
134
                        TNode lapprox,
135
                        TNode uapprox,
136
                        int csign,
137
                        Convexity convexity,
138
                        TNode tf,
139
                        TNode splane,
140
                        unsigned actual_d);
141
142
  /**
143
   * Construct and send secant lemmas (if appropriate)
144
   * @param bounds Secant bounds
145
   * @param poly_approx Polynomial approximation
146
   * @param center Current point
147
   * @param cval Evaluation at c
148
   * @param tf Current transcendental term
149
   * @param d Current taylor degree
150
   * @param concavity Concavity in region of c
151
   */
152
  void doSecantLemmas(const std::pair<Node, Node>& bounds,
153
                      TNode poly_approx,
154
                      TNode center,
155
                      TNode cval,
156
                      TNode tf,
157
                      Convexity convexity,
158
                      unsigned d,
159
                      unsigned actual_d);
160
161
  Node d_true;
162
  Node d_false;
163
  Node d_zero;
164
  Node d_one;
165
  Node d_neg_one;
166
167
  /** The inference manager that we push conflicts and lemmas to. */
168
  InferenceManager& d_im;
169
  /** Reference to the non-linear model object */
170
  NlModel& d_model;
171
  /** Reference to the environment */
172
  Env& d_env;
173
  /** Utility to compute taylor approximations */
174
  TaylorGenerator d_taylor;
175
  /**
176
   * A CDProofSet that hands out CDProof objects for lemmas.
177
   */
178
  std::unique_ptr<CDProofSet<CDProof>> d_proof;
179
180
  /** The proof checker for transcendental proofs */
181
  std::unique_ptr<TranscendentalProofRuleChecker> d_proofChecker;
182
183
  /**
184
   * Some transcendental functions f(t) are "purified", e.g. we add
185
   * t = y ^ f(t) = f(y) where y is a fresh variable. Those that are not
186
   * purified we call "master terms".
187
   *
188
   * The maps below maintain a master/slave relationship over
189
   * transcendental functions (SINE, EXPONENTIAL, PI), where above
190
   * f(y) is the master of itself and of f(t).
191
   *
192
   * This is used for ensuring that the argument y of SINE we process is on
193
   * the interval [-pi .. pi], and that exponentials are not applied to
194
   * arguments that contain transcendental functions.
195
   */
196
  std::map<Node, Node> d_trMaster;
197
  std::map<Node, std::unordered_set<Node>> d_trSlaves;
198
199
  /** concavity region for transcendental functions
200
   *
201
   * This stores an integer that identifies an interval in
202
   * which the current model value for an argument of an
203
   * application of a transcendental function resides.
204
   *
205
   * For exp( x ):
206
   *   region #1 is -infty < x < infty
207
   * For sin( x ):
208
   *   region #0 is pi < x < infty (this is an invalid region)
209
   *   region #1 is pi/2 < x <= pi
210
   *   region #2 is 0 < x <= pi/2
211
   *   region #3 is -pi/2 < x <= 0
212
   *   region #4 is -pi < x <= -pi/2
213
   *   region #5 is -infty < x <= -pi (this is an invalid region)
214
   * All regions not listed above, as well as regions 0 and 5
215
   * for SINE are "invalid". We only process applications
216
   * of transcendental functions whose arguments have model
217
   * values that reside in valid regions.
218
   */
219
  std::unordered_map<Node, int> d_tf_region;
220
  /**
221
   * Maps representives of a congruence class to the members of that class.
222
   *
223
   * In detail, a congruence class is a set of terms of the form
224
   *   { f(t1), ..., f(tn) }
225
   * such that t1 = ... = tn in the current context. We choose an arbitrary
226
   * term among these to be the repesentative of this congruence class.
227
   *
228
   * Moreover, notice we compute congruence classes only over terms that
229
   * are transcendental function applications that are "master terms",
230
   * see d_trMaster/d_trSlave.
231
   */
232
  std::map<Node, std::vector<Node>> d_funcCongClass;
233
  /**
234
   * A list of all functions for each kind in { EXPONENTIAL, SINE, POW, PI }
235
   * that are representives of their congruence class.
236
   */
237
  std::map<Kind, std::vector<Node>> d_funcMap;
238
239
  /** secant points (sorted list) for transcendental functions
240
   *
241
   * This is used for tangent plane refinements for
242
   * transcendental functions. This is the set
243
   * "get-previous-secant-points" in "Satisfiability
244
   * Modulo Transcendental Functions via Incremental
245
   * Linearization" by Cimatti et al., CADE 2017, for
246
   * each transcendental function application. We store this set for each
247
   * Taylor degree.
248
   */
249
  std::unordered_map<Node, std::map<unsigned, std::vector<Node>>>
250
      d_secant_points;
251
252
  /** PI
253
   *
254
   * Note that PI is a (symbolic, non-constant) nullary operator. This is
255
   * because its value cannot be computed exactly. We constraint PI to
256
   * concrete lower and upper bounds stored in d_pi_bound below.
257
   */
258
  Node d_pi;
259
  /** PI/2 */
260
  Node d_pi_2;
261
  /** -PI/2 */
262
  Node d_pi_neg_2;
263
  /** -PI */
264
  Node d_pi_neg;
265
  /** the concrete lower and upper bounds for PI */
266
  Node d_pi_bound[2];
267
};
268
269
}  // namespace transcendental
270
}  // namespace nl
271
}  // namespace arith
272
}  // namespace theory
273
}  // namespace cvc5
274
275
#endif /* CVC5__THEORY__ARITH__NL__TRANSCENDENTAL__TRANSCENDENTAL_STATE_H */