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 |
9697 |
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 |