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