1use crate::prelude::*;
2use std::collections::HashMap;
3
4fn mark_forall_param_name_if_tracked(
8 coverage_by_forall_param: &mut HashMap<IdentifierName, bool>,
9 name: &IdentifierName,
10) {
11 match coverage_by_forall_param.get_mut(name) {
12 Some(is_mentioned) => {
13 *is_mentioned = true;
14 }
15 None => {}
16 }
17}
18
19fn mark_forall_param_coverage_in_param_type(
20 param_type: &ParamType,
21 coverage_by_forall_param: &mut HashMap<IdentifierName, bool>,
22) {
23 match param_type {
24 ParamType::Obj(obj) => {
25 mark_forall_param_coverage_in_obj(obj, coverage_by_forall_param);
26 }
27 ParamType::Set(_) | ParamType::NonemptySet(_) | ParamType::FiniteSet(_) => {}
28 ParamType::Struct(struct_ty) => {
29 for param_obj in struct_ty.args.iter() {
30 mark_forall_param_coverage_in_obj(param_obj, coverage_by_forall_param);
31 }
32 }
33 }
34}
35
36fn mark_forall_param_coverage_in_atom(
37 atom: &Atom,
38 coverage_by_forall_param: &mut HashMap<IdentifierName, bool>,
39) {
40 match atom {
41 Atom::Identifier(identifier) => {
42 mark_forall_param_name_if_tracked(coverage_by_forall_param, &identifier.name);
43 }
44 Atom::IdentifierWithMod(_) => {}
45 Atom::FieldAccess(field_access) => {
46 mark_forall_param_name_if_tracked(coverage_by_forall_param, &field_access.name);
47 }
48 Atom::FieldAccessWithMod(_) => {}
49 }
50}
51
52fn mark_forall_param_coverage_in_obj(
53 obj: &Obj,
54 coverage_by_forall_param: &mut HashMap<IdentifierName, bool>,
55) {
56 match obj {
57 Obj::Identifier(identifier) => {
58 mark_forall_param_name_if_tracked(coverage_by_forall_param, &identifier.name);
59 }
60 Obj::IdentifierWithMod(_) => {}
61 Obj::FieldAccess(field_access) => {
62 mark_forall_param_name_if_tracked(coverage_by_forall_param, &field_access.name);
63 }
64 Obj::FieldAccessWithMod(_) => {}
65 Obj::FnObj(fn_obj) => {
66 mark_forall_param_coverage_in_atom(fn_obj.head.as_ref(), coverage_by_forall_param);
67 for group in fn_obj.body.iter() {
68 for boxed_obj in group.iter() {
69 mark_forall_param_coverage_in_obj(boxed_obj.as_ref(), coverage_by_forall_param);
70 }
71 }
72 }
73 Obj::Number(_) | Obj::StandardSet(_) => {}
74 Obj::Add(binary) => {
75 mark_forall_param_coverage_in_obj(binary.left.as_ref(), coverage_by_forall_param);
76 mark_forall_param_coverage_in_obj(binary.right.as_ref(), coverage_by_forall_param);
77 }
78 Obj::Sub(binary) => {
79 mark_forall_param_coverage_in_obj(binary.left.as_ref(), coverage_by_forall_param);
80 mark_forall_param_coverage_in_obj(binary.right.as_ref(), coverage_by_forall_param);
81 }
82 Obj::Mul(binary) => {
83 mark_forall_param_coverage_in_obj(binary.left.as_ref(), coverage_by_forall_param);
84 mark_forall_param_coverage_in_obj(binary.right.as_ref(), coverage_by_forall_param);
85 }
86 Obj::Div(binary) => {
87 mark_forall_param_coverage_in_obj(binary.left.as_ref(), coverage_by_forall_param);
88 mark_forall_param_coverage_in_obj(binary.right.as_ref(), coverage_by_forall_param);
89 }
90 Obj::Mod(binary) => {
91 mark_forall_param_coverage_in_obj(binary.left.as_ref(), coverage_by_forall_param);
92 mark_forall_param_coverage_in_obj(binary.right.as_ref(), coverage_by_forall_param);
93 }
94 Obj::Pow(binary) => {
95 mark_forall_param_coverage_in_obj(binary.base.as_ref(), coverage_by_forall_param);
96 mark_forall_param_coverage_in_obj(binary.exponent.as_ref(), coverage_by_forall_param);
97 }
98 Obj::MatrixAdd(binary) => {
99 mark_forall_param_coverage_in_obj(binary.left.as_ref(), coverage_by_forall_param);
100 mark_forall_param_coverage_in_obj(binary.right.as_ref(), coverage_by_forall_param);
101 }
102 Obj::MatrixSub(binary) => {
103 mark_forall_param_coverage_in_obj(binary.left.as_ref(), coverage_by_forall_param);
104 mark_forall_param_coverage_in_obj(binary.right.as_ref(), coverage_by_forall_param);
105 }
106 Obj::MatrixMul(binary) => {
107 mark_forall_param_coverage_in_obj(binary.left.as_ref(), coverage_by_forall_param);
108 mark_forall_param_coverage_in_obj(binary.right.as_ref(), coverage_by_forall_param);
109 }
110 Obj::MatrixScalarMul(binary) => {
111 mark_forall_param_coverage_in_obj(binary.scalar.as_ref(), coverage_by_forall_param);
112 mark_forall_param_coverage_in_obj(binary.matrix.as_ref(), coverage_by_forall_param);
113 }
114 Obj::MatrixPow(binary) => {
115 mark_forall_param_coverage_in_obj(binary.base.as_ref(), coverage_by_forall_param);
116 mark_forall_param_coverage_in_obj(binary.exponent.as_ref(), coverage_by_forall_param);
117 }
118 Obj::Abs(unary) => {
119 mark_forall_param_coverage_in_obj(unary.arg.as_ref(), coverage_by_forall_param);
120 }
121 Obj::Log(binary) => {
122 mark_forall_param_coverage_in_obj(binary.base.as_ref(), coverage_by_forall_param);
123 mark_forall_param_coverage_in_obj(binary.arg.as_ref(), coverage_by_forall_param);
124 }
125 Obj::Max(binary) => {
126 mark_forall_param_coverage_in_obj(binary.left.as_ref(), coverage_by_forall_param);
127 mark_forall_param_coverage_in_obj(binary.right.as_ref(), coverage_by_forall_param);
128 }
129 Obj::Min(binary) => {
130 mark_forall_param_coverage_in_obj(binary.left.as_ref(), coverage_by_forall_param);
131 mark_forall_param_coverage_in_obj(binary.right.as_ref(), coverage_by_forall_param);
132 }
133 Obj::Union(binary) => {
134 mark_forall_param_coverage_in_obj(binary.left.as_ref(), coverage_by_forall_param);
135 mark_forall_param_coverage_in_obj(binary.right.as_ref(), coverage_by_forall_param);
136 }
137 Obj::Intersect(binary) => {
138 mark_forall_param_coverage_in_obj(binary.left.as_ref(), coverage_by_forall_param);
139 mark_forall_param_coverage_in_obj(binary.right.as_ref(), coverage_by_forall_param);
140 }
141 Obj::SetMinus(binary) => {
142 mark_forall_param_coverage_in_obj(binary.left.as_ref(), coverage_by_forall_param);
143 mark_forall_param_coverage_in_obj(binary.right.as_ref(), coverage_by_forall_param);
144 }
145 Obj::SetDiff(binary) => {
146 mark_forall_param_coverage_in_obj(binary.left.as_ref(), coverage_by_forall_param);
147 mark_forall_param_coverage_in_obj(binary.right.as_ref(), coverage_by_forall_param);
148 }
149 Obj::Cup(unary) => {
150 mark_forall_param_coverage_in_obj(unary.left.as_ref(), coverage_by_forall_param);
151 }
152 Obj::Cap(unary) => {
153 mark_forall_param_coverage_in_obj(unary.left.as_ref(), coverage_by_forall_param);
154 }
155 Obj::PowerSet(unary) => {
156 mark_forall_param_coverage_in_obj(unary.set.as_ref(), coverage_by_forall_param);
157 }
158 Obj::ListSet(list_set) => {
159 for boxed_obj in list_set.list.iter() {
160 mark_forall_param_coverage_in_obj(boxed_obj.as_ref(), coverage_by_forall_param);
161 }
162 }
163 Obj::SetBuilder(set_builder) => {
164 mark_forall_param_coverage_in_obj(
165 set_builder.param_set.as_ref(),
166 coverage_by_forall_param,
167 );
168 for inner_fact in set_builder.facts.iter() {
169 mark_forall_param_coverage_in_or_and_chain_atomic_fact(
170 inner_fact,
171 coverage_by_forall_param,
172 );
173 }
174 }
175 Obj::FnSet(fn_set) => {
176 for param_def_with_set in fn_set.params_def_with_set.iter() {
177 mark_forall_param_coverage_in_obj(
178 ¶m_def_with_set.set,
179 coverage_by_forall_param,
180 );
181 }
182 for dom_fact in fn_set.dom_facts.iter() {
183 mark_forall_param_coverage_in_or_and_chain_atomic_fact(
184 dom_fact,
185 coverage_by_forall_param,
186 );
187 }
188 mark_forall_param_coverage_in_obj(fn_set.ret_set.as_ref(), coverage_by_forall_param);
189 }
190 Obj::Cart(cart) => {
191 for boxed_arg in cart.args.iter() {
192 mark_forall_param_coverage_in_obj(boxed_arg.as_ref(), coverage_by_forall_param);
193 }
194 }
195 Obj::CartDim(cart_dim) => {
196 mark_forall_param_coverage_in_obj(cart_dim.set.as_ref(), coverage_by_forall_param);
197 }
198 Obj::Proj(proj) => {
199 mark_forall_param_coverage_in_obj(proj.set.as_ref(), coverage_by_forall_param);
200 mark_forall_param_coverage_in_obj(proj.dim.as_ref(), coverage_by_forall_param);
201 }
202 Obj::TupleDim(tuple_dim) => {
203 mark_forall_param_coverage_in_obj(tuple_dim.arg.as_ref(), coverage_by_forall_param);
204 }
205 Obj::Tuple(tuple_obj) => {
206 for boxed_arg in tuple_obj.args.iter() {
207 mark_forall_param_coverage_in_obj(boxed_arg.as_ref(), coverage_by_forall_param);
208 }
209 }
210 Obj::Count(count) => {
211 mark_forall_param_coverage_in_obj(count.set.as_ref(), coverage_by_forall_param);
212 }
213 Obj::Range(range) => {
214 mark_forall_param_coverage_in_obj(range.start.as_ref(), coverage_by_forall_param);
215 mark_forall_param_coverage_in_obj(range.end.as_ref(), coverage_by_forall_param);
216 }
217 Obj::ClosedRange(closed_range) => {
218 mark_forall_param_coverage_in_obj(
219 closed_range.start.as_ref(),
220 coverage_by_forall_param,
221 );
222 mark_forall_param_coverage_in_obj(closed_range.end.as_ref(), coverage_by_forall_param);
223 }
224 Obj::FiniteSeqSet(fs) => {
225 mark_forall_param_coverage_in_obj(fs.set.as_ref(), coverage_by_forall_param);
226 mark_forall_param_coverage_in_obj(fs.n.as_ref(), coverage_by_forall_param);
227 }
228 Obj::SeqSet(ss) => {
229 mark_forall_param_coverage_in_obj(ss.set.as_ref(), coverage_by_forall_param);
230 }
231 Obj::FiniteSeqListObj(v) => {
232 for o in v.objs.iter() {
233 mark_forall_param_coverage_in_obj(o.as_ref(), coverage_by_forall_param);
234 }
235 }
236 Obj::MatrixSet(ms) => {
237 mark_forall_param_coverage_in_obj(ms.set.as_ref(), coverage_by_forall_param);
238 mark_forall_param_coverage_in_obj(ms.row_len.as_ref(), coverage_by_forall_param);
239 mark_forall_param_coverage_in_obj(ms.col_len.as_ref(), coverage_by_forall_param);
240 }
241 Obj::MatrixListObj(v) => {
242 for row in v.rows.iter() {
243 for o in row.iter() {
244 mark_forall_param_coverage_in_obj(o.as_ref(), coverage_by_forall_param);
245 }
246 }
247 }
248 Obj::Choose(choose) => {
249 mark_forall_param_coverage_in_obj(choose.set.as_ref(), coverage_by_forall_param);
250 }
251 Obj::ObjAtIndex(obj_at_index) => {
252 mark_forall_param_coverage_in_obj(obj_at_index.obj.as_ref(), coverage_by_forall_param);
253 mark_forall_param_coverage_in_obj(
254 obj_at_index.index.as_ref(),
255 coverage_by_forall_param,
256 );
257 }
258 Obj::FamilyObj(family) => {
259 for param_obj in family.params.iter() {
260 mark_forall_param_coverage_in_obj(param_obj, coverage_by_forall_param);
261 }
262 }
263 Obj::StructObj(struct_ty) => {
264 for param_obj in struct_ty.args.iter() {
265 mark_forall_param_coverage_in_obj(param_obj, coverage_by_forall_param);
266 }
267 }
268 }
269}
270
271fn mark_forall_param_coverage_in_atomic_fact(
272 atomic_fact: &AtomicFact,
273 coverage_by_forall_param: &mut HashMap<IdentifierName, bool>,
274) {
275 match atomic_fact {
276 AtomicFact::NormalAtomicFact(fact) => {
277 for body_obj in fact.body.iter() {
278 mark_forall_param_coverage_in_obj(body_obj, coverage_by_forall_param);
279 }
280 }
281 AtomicFact::NotNormalAtomicFact(fact) => {
282 for body_obj in fact.body.iter() {
283 mark_forall_param_coverage_in_obj(body_obj, coverage_by_forall_param);
284 }
285 }
286 AtomicFact::EqualFact(fact) => {
287 mark_forall_param_coverage_in_obj(&fact.left, coverage_by_forall_param);
288 mark_forall_param_coverage_in_obj(&fact.right, coverage_by_forall_param);
289 }
290 AtomicFact::LessFact(fact) => {
291 mark_forall_param_coverage_in_obj(&fact.left, coverage_by_forall_param);
292 mark_forall_param_coverage_in_obj(&fact.right, coverage_by_forall_param);
293 }
294 AtomicFact::GreaterFact(fact) => {
295 mark_forall_param_coverage_in_obj(&fact.left, coverage_by_forall_param);
296 mark_forall_param_coverage_in_obj(&fact.right, coverage_by_forall_param);
297 }
298 AtomicFact::LessEqualFact(fact) => {
299 mark_forall_param_coverage_in_obj(&fact.left, coverage_by_forall_param);
300 mark_forall_param_coverage_in_obj(&fact.right, coverage_by_forall_param);
301 }
302 AtomicFact::GreaterEqualFact(fact) => {
303 mark_forall_param_coverage_in_obj(&fact.left, coverage_by_forall_param);
304 mark_forall_param_coverage_in_obj(&fact.right, coverage_by_forall_param);
305 }
306 AtomicFact::NotEqualFact(fact) => {
307 mark_forall_param_coverage_in_obj(&fact.left, coverage_by_forall_param);
308 mark_forall_param_coverage_in_obj(&fact.right, coverage_by_forall_param);
309 }
310 AtomicFact::NotLessFact(fact) => {
311 mark_forall_param_coverage_in_obj(&fact.left, coverage_by_forall_param);
312 mark_forall_param_coverage_in_obj(&fact.right, coverage_by_forall_param);
313 }
314 AtomicFact::NotGreaterFact(fact) => {
315 mark_forall_param_coverage_in_obj(&fact.left, coverage_by_forall_param);
316 mark_forall_param_coverage_in_obj(&fact.right, coverage_by_forall_param);
317 }
318 AtomicFact::NotLessEqualFact(fact) => {
319 mark_forall_param_coverage_in_obj(&fact.left, coverage_by_forall_param);
320 mark_forall_param_coverage_in_obj(&fact.right, coverage_by_forall_param);
321 }
322 AtomicFact::NotGreaterEqualFact(fact) => {
323 mark_forall_param_coverage_in_obj(&fact.left, coverage_by_forall_param);
324 mark_forall_param_coverage_in_obj(&fact.right, coverage_by_forall_param);
325 }
326 AtomicFact::IsSetFact(fact) => {
327 mark_forall_param_coverage_in_obj(&fact.set, coverage_by_forall_param);
328 }
329 AtomicFact::NotIsSetFact(fact) => {
330 mark_forall_param_coverage_in_obj(&fact.set, coverage_by_forall_param);
331 }
332 AtomicFact::IsNonemptySetFact(fact) => {
333 mark_forall_param_coverage_in_obj(&fact.set, coverage_by_forall_param);
334 }
335 AtomicFact::NotIsNonemptySetFact(fact) => {
336 mark_forall_param_coverage_in_obj(&fact.set, coverage_by_forall_param);
337 }
338 AtomicFact::IsFiniteSetFact(fact) => {
339 mark_forall_param_coverage_in_obj(&fact.set, coverage_by_forall_param);
340 }
341 AtomicFact::NotIsFiniteSetFact(fact) => {
342 mark_forall_param_coverage_in_obj(&fact.set, coverage_by_forall_param);
343 }
344 AtomicFact::InFact(fact) => {
345 mark_forall_param_coverage_in_obj(&fact.element, coverage_by_forall_param);
346 mark_forall_param_coverage_in_obj(&fact.set, coverage_by_forall_param);
347 }
348 AtomicFact::NotInFact(fact) => {
349 mark_forall_param_coverage_in_obj(&fact.element, coverage_by_forall_param);
350 mark_forall_param_coverage_in_obj(&fact.set, coverage_by_forall_param);
351 }
352 AtomicFact::IsCartFact(fact) => {
353 mark_forall_param_coverage_in_obj(&fact.set, coverage_by_forall_param);
354 }
355 AtomicFact::NotIsCartFact(fact) => {
356 mark_forall_param_coverage_in_obj(&fact.set, coverage_by_forall_param);
357 }
358 AtomicFact::IsTupleFact(fact) => {
359 mark_forall_param_coverage_in_obj(&fact.set, coverage_by_forall_param);
360 }
361 AtomicFact::NotIsTupleFact(fact) => {
362 mark_forall_param_coverage_in_obj(&fact.set, coverage_by_forall_param);
363 }
364 AtomicFact::SubsetFact(fact) => {
365 mark_forall_param_coverage_in_obj(&fact.left, coverage_by_forall_param);
366 mark_forall_param_coverage_in_obj(&fact.right, coverage_by_forall_param);
367 }
368 AtomicFact::SupersetFact(fact) => {
369 mark_forall_param_coverage_in_obj(&fact.left, coverage_by_forall_param);
370 mark_forall_param_coverage_in_obj(&fact.right, coverage_by_forall_param);
371 }
372 AtomicFact::NotSubsetFact(fact) => {
373 mark_forall_param_coverage_in_obj(&fact.left, coverage_by_forall_param);
374 mark_forall_param_coverage_in_obj(&fact.right, coverage_by_forall_param);
375 }
376 AtomicFact::NotSupersetFact(fact) => {
377 mark_forall_param_coverage_in_obj(&fact.left, coverage_by_forall_param);
378 mark_forall_param_coverage_in_obj(&fact.right, coverage_by_forall_param);
379 }
380 AtomicFact::RestrictFact(fact) => {
381 mark_forall_param_coverage_in_obj(&fact.obj, coverage_by_forall_param);
382 mark_forall_param_coverage_in_obj(
383 &fact.obj_can_restrict_to_fn_set,
384 coverage_by_forall_param,
385 );
386 }
387 AtomicFact::NotRestrictFact(fact) => {
388 mark_forall_param_coverage_in_obj(&fact.obj, coverage_by_forall_param);
389 mark_forall_param_coverage_in_obj(
390 &fact.obj_cannot_restrict_to_fn_set,
391 coverage_by_forall_param,
392 );
393 }
394 }
395}
396
397fn mark_forall_param_coverage_in_and_chain_atomic_fact(
398 parent_fact: &AndChainAtomicFact,
399 coverage_by_forall_param: &mut HashMap<IdentifierName, bool>,
400) {
401 match parent_fact {
402 AndChainAtomicFact::AtomicFact(atomic_fact) => {
403 mark_forall_param_coverage_in_atomic_fact(atomic_fact, coverage_by_forall_param);
404 }
405 AndChainAtomicFact::AndFact(and_fact) => {
406 for inner_atomic in and_fact.facts.iter() {
407 mark_forall_param_coverage_in_atomic_fact(inner_atomic, coverage_by_forall_param);
408 }
409 }
410 AndChainAtomicFact::ChainFact(chain_fact) => {
411 for chain_obj in chain_fact.objs.iter() {
412 mark_forall_param_coverage_in_obj(chain_obj, coverage_by_forall_param);
413 }
414 }
415 }
416}
417
418fn mark_forall_param_coverage_in_or_and_chain_atomic_fact(
419 parent_fact: &OrAndChainAtomicFact,
420 coverage_by_forall_param: &mut HashMap<IdentifierName, bool>,
421) {
422 match parent_fact {
423 OrAndChainAtomicFact::AtomicFact(atomic_fact) => {
424 mark_forall_param_coverage_in_atomic_fact(atomic_fact, coverage_by_forall_param);
425 }
426 OrAndChainAtomicFact::AndFact(and_fact) => {
427 for inner_atomic in and_fact.facts.iter() {
428 mark_forall_param_coverage_in_atomic_fact(inner_atomic, coverage_by_forall_param);
429 }
430 }
431 OrAndChainAtomicFact::ChainFact(chain_fact) => {
432 for chain_obj in chain_fact.objs.iter() {
433 mark_forall_param_coverage_in_obj(chain_obj, coverage_by_forall_param);
434 }
435 }
436 OrAndChainAtomicFact::OrFact(or_fact) => {
437 for branch in or_fact.facts.iter() {
438 mark_forall_param_coverage_in_and_chain_atomic_fact(
439 branch,
440 coverage_by_forall_param,
441 );
442 }
443 }
444 }
445}
446
447fn mark_forall_param_coverage_in_exist_fact(
448 exist_fact: &ExistFact,
449 coverage_by_forall_param: &mut HashMap<IdentifierName, bool>,
450) {
451 for param_def_with_type in exist_fact.params_def_with_type.groups.iter() {
452 mark_forall_param_coverage_in_param_type(
453 ¶m_def_with_type.param_type,
454 coverage_by_forall_param,
455 );
456 }
457 for inner_fact in exist_fact.facts.iter() {
458 mark_forall_param_coverage_in_or_and_chain_atomic_fact(
459 inner_fact,
460 coverage_by_forall_param,
461 );
462 }
463}
464
465fn mark_forall_param_coverage_in_exist_or_and_chain_atomic_fact(
466 parent_fact: &ExistOrAndChainAtomicFact,
467 coverage_by_forall_param: &mut HashMap<IdentifierName, bool>,
468) {
469 match parent_fact {
470 ExistOrAndChainAtomicFact::AtomicFact(atomic_fact) => {
471 mark_forall_param_coverage_in_atomic_fact(atomic_fact, coverage_by_forall_param);
472 }
473 ExistOrAndChainAtomicFact::AndFact(and_fact) => {
474 for inner_atomic in and_fact.facts.iter() {
475 mark_forall_param_coverage_in_atomic_fact(inner_atomic, coverage_by_forall_param);
476 }
477 }
478 ExistOrAndChainAtomicFact::ChainFact(chain_fact) => {
479 for chain_obj in chain_fact.objs.iter() {
480 mark_forall_param_coverage_in_obj(chain_obj, coverage_by_forall_param);
481 }
482 }
483 ExistOrAndChainAtomicFact::OrFact(or_fact) => {
484 for branch in or_fact.facts.iter() {
485 mark_forall_param_coverage_in_and_chain_atomic_fact(
486 branch,
487 coverage_by_forall_param,
488 );
489 }
490 }
491 ExistOrAndChainAtomicFact::ExistFact(exist_fact) => {
492 mark_forall_param_coverage_in_exist_fact(exist_fact, coverage_by_forall_param);
493 }
494 }
495}
496
497impl ForallFact {
498 pub fn error_messages_if_forall_param_missing_in_some_then_clause(
499 &self,
500 ) -> Vec<(usize, String)> {
501 let forall_param_names = self.params_def_with_type.collect_param_names();
502 if forall_param_names.is_empty() {
503 return Vec::new();
504 }
505 let mut error_messages = Vec::new();
506 let mut then_index: usize = 0;
507 while then_index < self.then_facts.len() {
508 let then_fact = &self.then_facts[then_index];
509 let mut coverage_by_forall_param: HashMap<IdentifierName, bool> = HashMap::new();
510 for param_name in forall_param_names.iter() {
511 coverage_by_forall_param.insert(param_name.clone(), false);
512 }
513 mark_forall_param_coverage_in_exist_or_and_chain_atomic_fact(
514 then_fact,
515 &mut coverage_by_forall_param,
516 );
517 let mut missing_param_names = Vec::new();
518 for param_name in forall_param_names.iter() {
519 let is_mentioned_in_then_clause = match coverage_by_forall_param.get(param_name) {
520 Some(flag) => *flag,
521 None => false,
522 };
523 if !is_mentioned_in_then_clause {
524 missing_param_names.push(param_name.clone());
525 }
526 }
527 if !missing_param_names.is_empty() {
528 let missing_list = missing_param_names.join(", ");
529 error_messages.push((
530 then_index,
531 format!(
532 "then-clause `{}` does not mention forall parameter(s) {{{}}}",
533 then_fact, missing_list,
534 ),
535 ));
536 }
537 then_index += 1;
538 }
539 error_messages
540 }
541}
542
543impl ForallFactWithIff {
544 pub fn error_messages_if_forall_param_missing_in_forall_then_clause(
546 &self,
547 ) -> Vec<(usize, String)> {
548 self.forall_fact
549 .error_messages_if_forall_param_missing_in_some_then_clause()
550 }
551}