|
10 | 10 |
|
11 | 11 | #include <util/arith_tools.h>
|
12 | 12 | #include <util/invariant.h>
|
| 13 | +#include <util/optional.h> |
13 | 14 | #include <util/replace_expr.h>
|
14 | 15 | #include <util/simplify_expr.h>
|
15 | 16 |
|
@@ -135,83 +136,74 @@ exprt get_quantifier_var_max(
|
135 | 136 | return res;
|
136 | 137 | }
|
137 | 138 |
|
138 |
| -bool instantiate_quantifier(exprt &expr, |
139 |
| - const namespacet &ns) |
| 139 | +optionalt<exprt> |
| 140 | +instantiate_quantifier(const quantifier_exprt &expr, const namespacet &ns) |
140 | 141 | {
|
141 | 142 | PRECONDITION(expr.id() == ID_forall || expr.id() == ID_exists);
|
142 | 143 |
|
143 |
| - DATA_INVARIANT( |
144 |
| - expr.operands().size() == 2, |
145 |
| - "quantifier expressions shall have two operands"); |
146 |
| - |
147 |
| - DATA_INVARIANT( |
148 |
| - expr.op0().id() == ID_symbol, "quantified variable shall be a symbol"); |
149 |
| - |
150 |
| - exprt var_expr=expr.op0(); |
| 144 | + const symbol_exprt &var_expr = expr.symbol(); |
151 | 145 |
|
152 | 146 | /**
|
153 | 147 | * We need to rewrite the forall/exists quantifier into
|
154 | 148 | * an OR/AND expr.
|
155 | 149 | **/
|
156 |
| - exprt re(expr); |
157 |
| - exprt tmp(re.op1()); |
158 |
| - re.swap(tmp); |
159 |
| - re=simplify_expr(re, ns); |
| 150 | + |
| 151 | + const exprt &re = simplify_expr(expr.where(), ns); |
160 | 152 |
|
161 | 153 | if(re.is_true() || re.is_false())
|
162 | 154 | {
|
163 |
| - expr=re; |
164 |
| - return true; |
| 155 | + return re; |
165 | 156 | }
|
166 | 157 |
|
167 |
| - exprt min_i=get_quantifier_var_min(var_expr, re); |
168 |
| - exprt max_i=get_quantifier_var_max(var_expr, re); |
169 |
| - exprt body_expr=re; |
170 |
| - if(var_expr.is_false() || |
171 |
| - min_i.is_false() || |
172 |
| - max_i.is_false() || |
173 |
| - body_expr.is_false()) |
174 |
| - return false; |
| 158 | + const exprt &min_i = get_quantifier_var_min(var_expr, re); |
| 159 | + const exprt &max_i = get_quantifier_var_max(var_expr, re); |
175 | 160 |
|
176 |
| - mp_integer lb, ub; |
177 |
| - to_integer(min_i, lb); |
178 |
| - to_integer(max_i, ub); |
| 161 | + if(min_i.is_false() || max_i.is_false()) |
| 162 | + return nullopt; |
| 163 | + |
| 164 | + mp_integer lb = numeric_cast_v<mp_integer>(min_i); |
| 165 | + mp_integer ub = numeric_cast_v<mp_integer>(max_i); |
179 | 166 |
|
180 | 167 | if(lb>ub)
|
181 |
| - return false; |
| 168 | + return nullopt; |
182 | 169 |
|
183 |
| - bool res=true; |
184 | 170 | std::vector<exprt> expr_insts;
|
185 | 171 | for(mp_integer i=lb; i<=ub; ++i)
|
186 | 172 | {
|
187 |
| - exprt constraint_expr=body_expr; |
| 173 | + exprt constraint_expr = re; |
188 | 174 | replace_expr(var_expr,
|
189 | 175 | from_integer(i, var_expr.type()),
|
190 | 176 | constraint_expr);
|
191 | 177 | expr_insts.push_back(constraint_expr);
|
192 | 178 | }
|
| 179 | + |
193 | 180 | if(expr.id()==ID_forall)
|
194 | 181 | {
|
195 |
| - expr=conjunction(expr_insts); |
| 182 | + return conjunction(expr_insts); |
196 | 183 | }
|
197 |
| - if(expr.id()==ID_exists) |
| 184 | + else if(expr.id() == ID_exists) |
198 | 185 | {
|
199 |
| - expr=disjunction(expr_insts); |
| 186 | + return disjunction(expr_insts); |
200 | 187 | }
|
201 | 188 |
|
202 |
| - return res; |
| 189 | + UNREACHABLE; |
| 190 | + return nullopt; |
203 | 191 | }
|
204 | 192 |
|
205 |
| -literalt boolbvt::convert_quantifier(const exprt &src) |
| 193 | +literalt boolbvt::convert_quantifier(const quantifier_exprt &src) |
206 | 194 | {
|
207 | 195 | PRECONDITION(src.id() == ID_forall || src.id() == ID_exists);
|
208 | 196 |
|
209 |
| - exprt expr(src); |
210 |
| - if(!instantiate_quantifier(expr, ns)) |
| 197 | + quantifier_exprt expr(src); |
| 198 | + const auto res = instantiate_quantifier(expr, ns); |
| 199 | + |
| 200 | + if(!res) |
| 201 | + { |
211 | 202 | return SUB::convert_rest(src);
|
| 203 | + } |
212 | 204 |
|
213 | 205 | quantifiert quantifier;
|
214 |
| - quantifier.expr=expr; |
| 206 | + quantifier.expr = *res; |
215 | 207 | quantifier_list.push_back(quantifier);
|
216 | 208 |
|
217 | 209 | literalt l=prop.new_variable();
|
|
0 commit comments