1use crate::{
7 concrete::Error,
8 visitors::{
9 CommandVisitor, ConstantVisitor, KeywordVisitor, QualIdentifierVisitor, SExprVisitor,
10 Smt2Visitor, SortVisitor, SymbolKind, SymbolVisitor, TermVisitor,
11 },
12 Binary, Decimal, Hexadecimal, Numeral, Position,
13};
14
15use serde::{Deserialize, Serialize};
16use std::collections::BTreeMap;
17
18#[derive(Clone, Eq, PartialEq, Default, Debug, Serialize, Deserialize)]
21pub struct Smt2Counters {
22 pub numeral_constant_count: usize,
23 pub decimal_constant_count: usize,
24 pub hexadecimal_constant_count: usize,
25 pub binary_constant_count: usize,
26 pub string_constant_count: usize,
27 pub fresh_symbol_count: usize,
28 pub bound_symbol_count: usize,
29 pub any_symbol_count: usize,
30 pub keyword_count: usize,
31 pub constant_s_expr_count: usize,
32 pub symbol_s_expr_count: usize,
33 pub keyword_s_expr_count: usize,
34 pub application_s_expr_count: usize,
35 pub simple_sort_count: usize,
36 pub parameterized_sort_count: usize,
37 pub simple_identifier_count: usize,
38 pub sorted_identifier_count: usize,
39 pub constant_count: usize,
40 pub qual_identifier_count: usize,
41 pub application_count: usize,
42 pub let_count: usize,
43 pub forall_count: usize,
44 pub exists_count: usize,
45 pub match_count: usize,
46 pub attributes_count: usize,
47 pub assert_count: usize,
48 pub check_sat_count: usize,
49 pub check_sat_assuming_count: usize,
50 pub declare_const_count: usize,
51 pub declare_datatype_count: usize,
52 pub declare_datatypes_count: usize,
53 pub declare_fun_count: usize,
54 pub declare_sort_count: usize,
55 pub define_fun_count: usize,
56 pub define_fun_rec_count: usize,
57 pub define_funs_rec_count: usize,
58 pub define_sort_count: usize,
59 pub echo_count: usize,
60 pub exit_count: usize,
61 pub get_assertions_count: usize,
62 pub get_assignment_count: usize,
63 pub get_info_count: usize,
64 pub get_model_count: usize,
65 pub get_option_count: usize,
66 pub get_proof_count: usize,
67 pub get_unsat_assumptions_count: usize,
68 pub get_unsat_core_count: usize,
69 pub get_value_count: usize,
70 pub pop_count: usize,
71 pub push_count: usize,
72 pub reset_count: usize,
73 pub reset_assertions_count: usize,
74 pub set_info_count: usize,
75 pub set_logic_count: usize,
76 pub set_option_count: usize,
77
78 pub term_count: usize,
79 pub term_max_depth: usize,
80 pub term_max_size: usize,
81 pub term_sum_depth: usize,
82 pub term_sum_size: usize,
83
84 pub keyword_counts: BTreeMap<String, usize>,
85 pub symbol_counts: BTreeMap<String, usize>,
86}
87
88impl Smt2Counters {
89 pub fn new(keywords: Vec<String>, symbols: Vec<String>) -> Self {
92 let mut state = Self::default();
93 for keyword in keywords {
94 state.keyword_counts.insert(keyword, 0);
95 }
96 for symbol in symbols {
97 state.symbol_counts.insert(symbol, 0);
98 }
99 state
100 }
101
102 fn visit_keyword(&mut self, keyword: &str) {
103 if let Some(entry) = self.keyword_counts.get_mut(keyword) {
104 *entry += 1;
105 }
106 }
107
108 fn visit_symbol(&mut self, symbol: &str) {
109 if let Some(entry) = self.symbol_counts.get_mut(symbol) {
110 *entry += 1;
111 }
112 }
113}
114
115#[derive(Clone, Eq, PartialEq, Default, Debug)]
117pub struct Term {
118 pub tree_depth: usize,
119 pub tree_size: usize,
120}
121
122impl Term {
123 fn node<I>(iter: I) -> Self
124 where
125 I: Iterator<Item = Term>,
126 {
127 let mut result = Term::default();
128 for t in iter {
129 result.tree_depth = std::cmp::max(result.tree_depth, t.tree_depth);
130 result.tree_size += t.tree_size;
131 }
132 result.tree_depth += 1;
133 result.tree_size += 1;
134 result
135 }
136}
137
138impl ConstantVisitor for Smt2Counters {
139 type T = ();
140 type E = Error;
141
142 fn visit_numeral_constant(&mut self, _value: Numeral) -> Result<Self::T, Self::E> {
143 self.numeral_constant_count += 1;
144 Ok(())
145 }
146 fn visit_decimal_constant(&mut self, _value: Decimal) -> Result<Self::T, Self::E> {
147 self.decimal_constant_count += 1;
148 Ok(())
149 }
150 fn visit_hexadecimal_constant(&mut self, _value: Hexadecimal) -> Result<Self::T, Self::E> {
151 self.hexadecimal_constant_count += 1;
152 Ok(())
153 }
154 fn visit_binary_constant(&mut self, _value: Binary) -> Result<Self::T, Self::E> {
155 self.binary_constant_count += 1;
156 Ok(())
157 }
158 fn visit_string_constant(&mut self, _value: String) -> Result<Self::T, Self::E> {
159 self.string_constant_count += 1;
160 Ok(())
161 }
162}
163
164impl SymbolVisitor for Smt2Counters {
165 type T = ();
166 type E = Error;
167
168 fn visit_fresh_symbol(
169 &mut self,
170 _value: String,
171 _kind: SymbolKind,
172 ) -> Result<Self::T, Self::E> {
173 self.fresh_symbol_count += 1;
174 Ok(())
175 }
176
177 fn visit_bound_symbol(&mut self, value: String) -> Result<Self::T, Self::E> {
178 self.bound_symbol_count += 1;
179 self.visit_symbol(&value);
180 Ok(())
181 }
182
183 fn visit_any_symbol(&mut self, _value: String) -> Result<Self::T, Self::E> {
184 self.any_symbol_count += 1;
185 Ok(())
186 }
187}
188
189impl KeywordVisitor for Smt2Counters {
190 type T = ();
191 type E = Error;
192
193 fn visit_keyword(&mut self, value: String) -> Result<Self::T, Self::E> {
194 self.keyword_count += 1;
195 self.visit_keyword(&value);
196 Ok(())
197 }
198}
199
200type Constant = ();
201type Symbol = ();
202type Keyword = ();
203type Sort = ();
204type QualIdentifier = ();
205type SExpr = ();
206
207type Identifier = crate::visitors::Identifier<Symbol>;
208type AttributeValue = crate::visitors::AttributeValue<Constant, Symbol, SExpr>;
209type DatatypeDec = crate::visitors::DatatypeDec<Symbol, Sort>;
210type FunctionDec = crate::visitors::FunctionDec<Symbol, Sort>;
211
212impl SExprVisitor<Constant, Symbol, Keyword> for Smt2Counters {
213 type T = ();
214 type E = Error;
215
216 fn visit_constant_s_expr(&mut self, _value: Constant) -> Result<Self::T, Self::E> {
217 self.constant_s_expr_count += 1;
218 Ok(())
219 }
220
221 fn visit_symbol_s_expr(&mut self, _value: Symbol) -> Result<Self::T, Self::E> {
222 self.symbol_s_expr_count += 1;
223 Ok(())
224 }
225
226 fn visit_keyword_s_expr(&mut self, _value: Keyword) -> Result<Self::T, Self::E> {
227 self.keyword_s_expr_count += 1;
228 Ok(())
229 }
230
231 fn visit_application_s_expr(&mut self, _values: Vec<Self::T>) -> Result<Self::T, Self::E> {
232 self.application_s_expr_count += 1;
233 Ok(())
234 }
235}
236
237impl SortVisitor<Symbol> for Smt2Counters {
238 type T = ();
239 type E = Error;
240
241 fn visit_simple_sort(&mut self, _identifier: Identifier) -> Result<Self::T, Self::E> {
242 self.simple_sort_count += 1;
243 Ok(())
244 }
245
246 fn visit_parameterized_sort(
247 &mut self,
248 _identifier: Identifier,
249 _parameters: Vec<Self::T>,
250 ) -> Result<Self::T, Self::E> {
251 self.parameterized_sort_count += 1;
252 Ok(())
253 }
254}
255
256impl QualIdentifierVisitor<Identifier, Sort> for Smt2Counters {
257 type T = ();
258 type E = Error;
259
260 fn visit_simple_identifier(&mut self, _identifier: Identifier) -> Result<Self::T, Self::E> {
261 self.simple_identifier_count += 1;
262 Ok(())
263 }
264
265 fn visit_sorted_identifier(
266 &mut self,
267 _identifier: Identifier,
268 _sort: Sort,
269 ) -> Result<Self::T, Self::E> {
270 self.sorted_identifier_count += 1;
271 Ok(())
272 }
273}
274
275impl TermVisitor<Constant, QualIdentifier, Keyword, SExpr, Symbol, Sort> for Smt2Counters {
276 type T = Term;
277 type E = Error;
278
279 fn visit_constant(&mut self, _constant: Constant) -> Result<Self::T, Self::E> {
280 self.constant_count += 1;
281 Ok(Term::default())
282 }
283
284 fn visit_qual_identifier(
285 &mut self,
286 _qual_identifier: QualIdentifier,
287 ) -> Result<Self::T, Self::E> {
288 self.qual_identifier_count += 1;
289 Ok(Term::default())
290 }
291
292 fn visit_application(
293 &mut self,
294 _qual_identifier: QualIdentifier,
295 arguments: Vec<Self::T>,
296 ) -> Result<Self::T, Self::E> {
297 self.application_count += 1;
298 Ok(Term::node(arguments.into_iter()))
299 }
300
301 fn visit_let(
302 &mut self,
303 var_bindings: Vec<(Symbol, Self::T)>,
304 term: Self::T,
305 ) -> Result<Self::T, Self::E> {
306 self.let_count += 1;
307 Ok(Term::node(
308 std::iter::once(term).chain(var_bindings.into_iter().map(|(_, t)| t)),
309 ))
310 }
311
312 fn visit_forall(
313 &mut self,
314 _vars: Vec<(Symbol, Sort)>,
315 term: Self::T,
316 ) -> Result<Self::T, Self::E> {
317 self.forall_count += 1;
318 Ok(Term::node(std::iter::once(term)))
319 }
320
321 fn visit_exists(
322 &mut self,
323 _vars: Vec<(Symbol, Sort)>,
324 term: Self::T,
325 ) -> Result<Self::T, Self::E> {
326 self.exists_count += 1;
327 Ok(Term::node(std::iter::once(term)))
328 }
329
330 fn visit_match(
331 &mut self,
332 term: Self::T,
333 cases: Vec<(Vec<Symbol>, Self::T)>,
334 ) -> Result<Self::T, Self::E> {
335 self.match_count += 1;
336 Ok(Term::node(
337 std::iter::once(term).chain(cases.into_iter().map(|(_, t)| t)),
338 ))
339 }
340
341 fn visit_attributes(
342 &mut self,
343 term: Self::T,
344 _attributes: Vec<(Keyword, AttributeValue)>,
345 ) -> Result<Self::T, Self::E> {
346 self.attributes_count += 1;
347 Ok(Term::node(std::iter::once(term)))
348 }
349}
350
351impl Smt2Counters {
352 fn visit_term(&mut self, term: Term) {
353 self.term_count += 1;
354 self.term_max_depth = std::cmp::max(term.tree_depth, self.term_max_depth);
355 self.term_max_size = std::cmp::max(term.tree_size, self.term_max_size);
356 self.term_sum_depth += term.tree_depth;
357 self.term_sum_size += term.tree_size;
358 }
359}
360
361impl CommandVisitor<Term, Symbol, Sort, Keyword, Constant, SExpr> for Smt2Counters {
362 type T = ();
363 type E = Error;
364
365 fn visit_assert(&mut self, term: Term) -> Result<Self::T, Self::E> {
366 self.assert_count += 1;
367 self.visit_term(term);
368 Ok(())
369 }
370
371 fn visit_check_sat(&mut self) -> Result<Self::T, Self::E> {
372 self.check_sat_count += 1;
373 Ok(())
374 }
375
376 fn visit_check_sat_assuming(
377 &mut self,
378 _literals: Vec<(Symbol, bool)>,
379 ) -> Result<Self::T, Self::E> {
380 self.check_sat_assuming_count += 1;
381 Ok(())
382 }
383
384 fn visit_declare_const(&mut self, _symbol: Symbol, _sort: Sort) -> Result<Self::T, Self::E> {
385 self.declare_const_count += 1;
386 Ok(())
387 }
388
389 fn visit_declare_datatype(
390 &mut self,
391 _symbol: Symbol,
392 _datatype: DatatypeDec,
393 ) -> Result<Self::T, Self::E> {
394 self.declare_datatype_count += 1;
395 Ok(())
396 }
397
398 fn visit_declare_datatypes(
399 &mut self,
400 _datatypes: Vec<(Symbol, Numeral, DatatypeDec)>,
401 ) -> Result<Self::T, Self::E> {
402 self.declare_datatypes_count += 1;
403 Ok(())
404 }
405
406 fn visit_declare_fun(
407 &mut self,
408 _symbol: Symbol,
409 _parameters: Vec<Sort>,
410 _sort: Sort,
411 ) -> Result<Self::T, Self::E> {
412 self.declare_fun_count += 1;
413 Ok(())
414 }
415
416 fn visit_declare_sort(&mut self, _symbol: Symbol, _arity: Numeral) -> Result<Self::T, Self::E> {
417 self.declare_sort_count += 1;
418 Ok(())
419 }
420
421 fn visit_define_fun(&mut self, _sig: FunctionDec, term: Term) -> Result<Self::T, Self::E> {
422 self.define_fun_count += 1;
423 self.visit_term(term);
424 Ok(())
425 }
426
427 fn visit_define_fun_rec(&mut self, _sig: FunctionDec, term: Term) -> Result<Self::T, Self::E> {
428 self.define_fun_rec_count += 1;
429 self.visit_term(term);
430 Ok(())
431 }
432
433 fn visit_define_funs_rec(
434 &mut self,
435 funs: Vec<(FunctionDec, Term)>,
436 ) -> Result<Self::T, Self::E> {
437 self.define_funs_rec_count += 1;
438 for (_, term) in funs {
439 self.visit_term(term);
440 }
441 Ok(())
442 }
443
444 fn visit_define_sort(
445 &mut self,
446 _symbol: Symbol,
447 _parameters: Vec<Symbol>,
448 _sort: Sort,
449 ) -> Result<Self::T, Self::E> {
450 self.define_sort_count += 1;
451 Ok(())
452 }
453
454 fn visit_echo(&mut self, _message: String) -> Result<Self::T, Self::E> {
455 self.echo_count += 1;
456 Ok(())
457 }
458
459 fn visit_exit(&mut self) -> Result<Self::T, Self::E> {
460 self.exit_count += 1;
461 Ok(())
462 }
463
464 fn visit_get_assertions(&mut self) -> Result<Self::T, Self::E> {
465 self.get_assertions_count += 1;
466 Ok(())
467 }
468
469 fn visit_get_assignment(&mut self) -> Result<Self::T, Self::E> {
470 self.get_assignment_count += 1;
471 Ok(())
472 }
473
474 fn visit_get_info(&mut self, _flag: Keyword) -> Result<Self::T, Self::E> {
475 self.get_info_count += 1;
476 Ok(())
477 }
478
479 fn visit_get_model(&mut self) -> Result<Self::T, Self::E> {
480 self.get_model_count += 1;
481 Ok(())
482 }
483
484 fn visit_get_option(&mut self, _keyword: Keyword) -> Result<Self::T, Self::E> {
485 self.get_option_count += 1;
486 Ok(())
487 }
488
489 fn visit_get_proof(&mut self) -> Result<Self::T, Self::E> {
490 self.get_proof_count += 1;
491 Ok(())
492 }
493
494 fn visit_get_unsat_assumptions(&mut self) -> Result<Self::T, Self::E> {
495 self.get_unsat_assumptions_count += 1;
496 Ok(())
497 }
498
499 fn visit_get_unsat_core(&mut self) -> Result<Self::T, Self::E> {
500 self.get_unsat_core_count += 1;
501 Ok(())
502 }
503
504 fn visit_get_value(&mut self, terms: Vec<Term>) -> Result<Self::T, Self::E> {
505 self.get_value_count += 1;
506 for term in terms {
507 self.visit_term(term);
508 }
509 Ok(())
510 }
511
512 fn visit_pop(&mut self, _level: Numeral) -> Result<Self::T, Self::E> {
513 self.pop_count += 1;
514 Ok(())
515 }
516
517 fn visit_push(&mut self, _level: Numeral) -> Result<Self::T, Self::E> {
518 self.push_count += 1;
519 Ok(())
520 }
521
522 fn visit_reset(&mut self) -> Result<Self::T, Self::E> {
523 self.reset_count += 1;
524 Ok(())
525 }
526
527 fn visit_reset_assertions(&mut self) -> Result<Self::T, Self::E> {
528 self.reset_assertions_count += 1;
529 Ok(())
530 }
531
532 fn visit_set_info(
533 &mut self,
534 _keyword: Keyword,
535 _value: AttributeValue,
536 ) -> Result<Self::T, Self::E> {
537 self.set_info_count += 1;
538 Ok(())
539 }
540
541 fn visit_set_logic(&mut self, _symbol: Symbol) -> Result<Self::T, Self::E> {
542 self.set_logic_count += 1;
543 Ok(())
544 }
545
546 fn visit_set_option(
547 &mut self,
548 _keyword: Keyword,
549 _value: AttributeValue,
550 ) -> Result<Self::T, Self::E> {
551 self.set_option_count += 1;
552 Ok(())
553 }
554}
555
556impl Smt2Visitor for Smt2Counters {
557 type Error = Error;
558 type Constant = ();
559 type QualIdentifier = ();
560 type Keyword = ();
561 type Sort = ();
562 type SExpr = ();
563 type Symbol = ();
564 type Term = Term;
565 type Command = ();
566
567 fn syntax_error(&mut self, position: Position, s: String) -> Self::Error {
568 Error::SyntaxError(position, s)
569 }
570
571 fn parsing_error(&mut self, position: Position, s: String) -> Self::Error {
572 Error::ParsingError(position, s)
573 }
574}