GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/arith/nl/transcendental/sine_solver.h Lines: 24 28 85.7 %
Date: 2021-09-17 Branches: 12 16 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
 * Solving for handling exponential function.
14
 */
15
16
#ifndef CVC5__THEORY__ARITH__NL__TRANSCENDENTAL__SINE_SOLVER_H
17
#define CVC5__THEORY__ARITH__NL__TRANSCENDENTAL__SINE_SOLVER_H
18
19
#include <map>
20
21
#include "expr/node.h"
22
#include "theory/arith/nl/transcendental/transcendental_state.h"
23
24
namespace cvc5 {
25
namespace theory {
26
namespace arith {
27
namespace nl {
28
namespace transcendental {
29
30
/** Transcendental solver class
31
 *
32
 * This class implements model-based refinement schemes
33
 * for transcendental functions, described in:
34
 *
35
 * - "Satisfiability Modulo Transcendental
36
 * Functions via Incremental Linearization" by Cimatti
37
 * et al., CADE 2017.
38
 *
39
 * It's main functionality are methods that implement lemma schemas below,
40
 * which return a set of lemmas that should be sent on the output channel.
41
 */
42
class SineSolver
43
{
44
 public:
45
  SineSolver(TranscendentalState* tstate);
46
  ~SineSolver();
47
48
  /**
49
   * Introduces new_a as purified version of a which is also shifted to the main
50
   * phase (from -pi to pi). y is the new skolem used for purification.
51
   */
52
  void doPhaseShift(TNode a, TNode new_a, TNode y);
53
54
  /**
55
   * check initial refine
56
   *
57
   * Constructs a set of valid theory lemmas, based on
58
   * simple facts about the sine function.
59
   * This mostly follows the initial axioms described in
60
   * Section 4 of "Satisfiability
61
   * Modulo Transcendental Functions via Incremental
62
   * Linearization" by Cimatti et al., CADE 2017.
63
   *
64
   * Examples:
65
   *
66
   * sin( x ) = -sin( -x )
67
   * ( PI > x > 0 ) => 0 < sin( x ) < 1
68
   */
69
  void checkInitialRefine();
70
71
  /**
72
   * check monotonicity
73
   *
74
   * Constructs a set of valid theory lemmas, based on a
75
   * lemma scheme that ensures that applications
76
   * of the sine function respect monotonicity.
77
   *
78
   * Examples:
79
   *
80
   * PI/2 > x > y > 0 => sin( x ) > sin( y )
81
   * PI > x > y > PI/2 => sin( x ) < sin( y )
82
   */
83
  void checkMonotonic();
84
85
  /** Sent tangent lemma around c for e */
86
  void doTangentLemma(
87
      TNode e, TNode c, TNode poly_approx, int region, std::uint64_t d);
88
89
  /** Sent secant lemmas around c for e */
90
  void doSecantLemmas(TNode e,
91
                      TNode poly_approx,
92
                      TNode c,
93
                      TNode poly_approx_c,
94
                      unsigned d,
95
                      unsigned actual_d,
96
                      int region);
97
98
 private:
99
  std::pair<Node, Node> getSecantBounds(TNode e,
100
                                        TNode c,
101
                                        unsigned d,
102
                                        int region);
103
104
  /** region to lower bound
105
   *
106
   * Returns the term corresponding to the lower
107
   * bound of the region of transcendental function
108
   * with kind k. Returns Node::null if the region
109
   * is invalid, or there is no lower bound for the
110
   * region.
111
   */
112
104
  Node regionToLowerBound(int region)
113
  {
114
104
    switch (region)
115
    {
116
10
      case 1: return d_data->d_pi_2;
117
47
      case 2: return d_data->d_zero;
118
30
      case 3: return d_data->d_pi_neg_2;
119
17
      case 4: return d_data->d_pi_neg;
120
      default: return Node();
121
    }
122
  }
123
124
  /** region to upper bound
125
   *
126
   * Returns the term corresponding to the upper
127
   * bound of the region of transcendental function
128
   * with kind k. Returns Node::null if the region
129
   * is invalid, or there is no upper bound for the
130
   * region.
131
   */
132
104
  Node regionToUpperBound(int region)
133
  {
134
104
    switch (region)
135
    {
136
17
      case 1: return d_data->d_pi;
137
30
      case 2: return d_data->d_pi_2;
138
47
      case 3: return d_data->d_zero;
139
10
      case 4: return d_data->d_pi_neg_2;
140
      default: return Node();
141
    }
142
  }
143
144
556
  int regionToMonotonicityDir(int region)
145
  {
146
556
    switch (region)
147
    {
148
228
      case 1:
149
228
      case 4: return -1;
150
328
      case 2:
151
328
      case 3: return 1;
152
      default: return 0;
153
    }
154
  }
155
120
  Convexity regionToConvexity(int region)
156
  {
157
120
    switch (region)
158
    {
159
60
      case 1:
160
60
      case 2: return Convexity::CONCAVE;
161
60
      case 3:
162
60
      case 4: return Convexity::CONVEX;
163
      default: return Convexity::UNKNOWN;
164
    }
165
  }
166
167
  /** Holds common state for transcendental solvers */
168
  TranscendentalState* d_data;
169
170
  /** The transcendental functions we have done initial refinements on */
171
  std::map<Node, bool> d_tf_initial_refine;
172
173
}; /* class SineSolver */
174
175
}  // namespace transcendental
176
}  // namespace nl
177
}  // namespace arith
178
}  // namespace theory
179
}  // namespace cvc5
180
181
#endif /* CVC5__THEORY__ARITH__TRANSCENDENTAL_SOLVER_H */