GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/arith/nl/ext/monomial_check.h Lines: 1 1 100.0 %
Date: 2021-05-22 Branches: 0 0 0.0 %

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
 * Check for some monomial lemmas.
14
 */
15
16
#ifndef CVC5__THEORY__ARITH__NL__EXT__MONOMIAL_CHECK_H
17
#define CVC5__THEORY__ARITH__NL__EXT__MONOMIAL_CHECK_H
18
19
#include "expr/node.h"
20
#include "theory/arith/nl/ext/monomial.h"
21
#include "theory/theory_inference.h"
22
23
namespace cvc5 {
24
namespace theory {
25
namespace arith {
26
namespace nl {
27
28
struct ExtState;
29
30
4914
class MonomialCheck
31
{
32
 public:
33
  MonomialCheck(ExtState* data);
34
35
  void init(const std::vector<Node>& xts);
36
37
  /** check monomial sign
38
   *
39
   * Returns a set of valid theory lemmas, based on a
40
   * lemma schema which ensures that non-linear monomials
41
   * respect sign information based on their facts.
42
   * For more details, see Section 5 of "Design Theory
43
   * Solvers with Extensions" by Reynolds et al., FroCoS 2017,
44
   * Figure 5, this is the schema "Sign".
45
   *
46
   * Examples:
47
   *
48
   * x > 0 ^ y > 0 => x*y > 0
49
   * x < 0 => x*y*y < 0
50
   * x = 0 => x*y*z = 0
51
   */
52
  void checkSign();
53
54
  /** check monomial magnitude
55
   *
56
   * Returns a set of valid theory lemmas, based on a
57
   * lemma schema which ensures that comparisons between
58
   * non-linear monomials respect the magnitude of their
59
   * factors.
60
   * For more details, see Section 5 of "Design Theory
61
   * Solvers with Extensions" by Reynolds et al., FroCoS 2017,
62
   * Figure 5, this is the schema "Magnitude".
63
   *
64
   * Examples:
65
   *
66
   * |x|>|y| => |x*z|>|y*z|
67
   * |x|>|y| ^ |z|>|w| ^ |x|>=1 => |x*x*z*u|>|y*w|
68
   *
69
   * Argument c indicates the class of inferences to perform for the
70
   * (non-linear) monomials in the vector d_ms. 0 : compare non-linear monomials
71
   * against 1, 1 : compare non-linear monomials against variables, 2 : compare
72
   * non-linear monomials against other non-linear monomials.
73
   */
74
  void checkMagnitude(unsigned c);
75
76
 private:
77
  /** In the following functions, status states a relationship
78
   * between two arithmetic terms, where:
79
   * 0 : equal
80
   * 1 : greater than or equal
81
   * 2 : greater than
82
   * -X : (greater -> less)
83
   * TODO (#1287) make this an enum?
84
   */
85
  /** compute the sign of a.
86
   *
87
   * Calls to this function are such that :
88
   *    exp => ( oa = a ^ a <status> 0 )
89
   *
90
   * This function iterates over the factors of a,
91
   * where a_index is the index of the factor in a
92
   * we are currently looking at.
93
   *
94
   * This function returns a status, which indicates
95
   * a's relationship to 0.
96
   * We add lemmas to lem of the form given by the
97
   * lemma schema checkSign(...).
98
   */
99
  int compareSign(
100
      Node oa, Node a, unsigned a_index, int status, std::vector<Node>& exp);
101
  /** compare monomials a and b
102
   *
103
   * Initially, a call to this function is such that :
104
   *    exp => ( oa = a ^ ob = b )
105
   *
106
   * This function returns true if we can infer a valid
107
   * arithmetic lemma of the form :
108
   *    P => abs( a ) >= abs( b )
109
   * where P is true and abs( a ) >= abs( b ) is false in the
110
   * current model.
111
   *
112
   * This function is implemented by "processing" factors
113
   * of monomials a and b until an inference of the above
114
   * form can be made. For example, if :
115
   *   a = x*x*y and b = z*w
116
   * Assuming we are trying to show abs( a ) >= abs( c ),
117
   * then if abs( M( x ) ) >= abs( M( z ) ) where M is the current model,
118
   * then we can add abs( x ) >= abs( z ) to our explanation, and
119
   * mark one factor of x as processed in a, and
120
   * one factor of z as processed in b. The number of processed factors of a
121
   * and b are stored in a_exp_proc and b_exp_proc respectively.
122
   *
123
   * cmp_infers stores information that is helpful
124
   * in discarding redundant inferences.  For example,
125
   * we do not want to infer abs( x ) >= abs( z ) if
126
   * we have already inferred abs( x ) >= abs( y ) and
127
   * abs( y ) >= abs( z ).
128
   * It stores entries of the form (status,t1,t2)->F,
129
   * which indicates that we constructed a lemma F that
130
   * showed t1 <status> t2.
131
   *
132
   * We add lemmas to lem of the form given by the
133
   * lemma schema checkMagnitude(...).
134
   */
135
  bool compareMonomial(
136
      Node oa,
137
      Node a,
138
      NodeMultiset& a_exp_proc,
139
      Node ob,
140
      Node b,
141
      NodeMultiset& b_exp_proc,
142
      std::vector<Node>& exp,
143
      std::vector<SimpleTheoryLemma>& lem,
144
      std::map<int, std::map<Node, std::map<Node, Node> > >& cmp_infers);
145
  /** helper function for above
146
   *
147
   * The difference is the inputs a_index and b_index, which are the indices of
148
   * children (factors) in monomials a and b which we are currently looking at.
149
   */
150
  bool compareMonomial(
151
      Node oa,
152
      Node a,
153
      unsigned a_index,
154
      NodeMultiset& a_exp_proc,
155
      Node ob,
156
      Node b,
157
      unsigned b_index,
158
      NodeMultiset& b_exp_proc,
159
      int status,
160
      std::vector<Node>& exp,
161
      std::vector<SimpleTheoryLemma>& lem,
162
      std::map<int, std::map<Node, std::map<Node, Node> > >& cmp_infers);
163
  /** Check whether we have already inferred a relationship between monomials
164
   * x and y based on the information in cmp_infers. This computes the
165
   * transitive closure of the relation stored in cmp_infers.
166
   */
167
  bool cmp_holds(Node x,
168
                 Node y,
169
                 std::map<Node, std::map<Node, Node> >& cmp_infers,
170
                 std::vector<Node>& exp,
171
                 std::map<Node, bool>& visited);
172
  /** assign order ids */
173
  void assignOrderIds(std::vector<Node>& vars,
174
                      NodeMultiset& d_order,
175
                      bool isConcrete,
176
                      bool isAbsolute);
177
  /** Make literal */
178
  Node mkLit(Node a, Node b, int status, bool isAbsolute = false) const;
179
  /** register monomial */
180
  void setMonomialFactor(Node a, Node b, const NodeMultiset& common);
181
182
  /** Basic data that is shared with other checks */
183
  ExtState* d_data;
184
185
  std::map<Node, bool> d_ms_proc;
186
  // ordering, stores variables and 0,1,-1
187
  std::map<Node, unsigned> d_order_vars;
188
  std::vector<Node> d_order_points;
189
190
  // list of monomials with factors whose model value is non-constant in model
191
  //  e.g. y*cos( x )
192
  std::map<Node, bool> d_m_nconst_factor;
193
};
194
195
}  // namespace nl
196
}  // namespace arith
197
}  // namespace theory
198
}  // namespace cvc5
199
200
#endif