1use std::fmt;
2
3use indexmap::IndexMap;
4use itertools::Itertools;
5
6use crate::{
7 BinOp, BinRel, Bind, Constant, Expr, Identifier, Pred, Sort, SortCtor, ThyFunc, Types,
8 constraint::Quantifier,
9 sexp::{Atom, ParseError as SexpParseError, Sexp},
10};
11
12#[derive(Debug)]
13pub enum ParseError {
14 SexpParseError(SexpParseError),
15 MalformedSexpError(String),
16}
17
18impl ParseError {
19 pub fn err(msg: impl Into<String>) -> Self {
20 ParseError::MalformedSexpError(msg.into())
21 }
22}
23
24impl Identifier for String {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 write!(f, "{self}")
27 }
28}
29
30pub trait FromSexp<T: Types> {
31 fn fresh_var(&mut self) -> T::Var;
32 fn var(&self, name: &str) -> Result<T::Var, ParseError>;
34 fn kvar(&self, name: &str) -> Result<T::KVar, ParseError>;
35 fn string(&self, s: &str) -> Result<T::String, ParseError>;
36 fn sort(&self, name: &str) -> Result<T::Sort, ParseError>;
37 fn into_wrapper(self) -> FromSexpWrapper<T, Self>
38 where
39 Self: Sized,
40 {
41 FromSexpWrapper { parser: self, _phantom: std::marker::PhantomData, scopes: vec![] }
42 }
43}
44
45pub struct FromSexpWrapper<T: Types, Parser> {
46 pub parser: Parser,
47 pub _phantom: std::marker::PhantomData<T>,
48 scopes: Vec<IndexMap<String, T::Var>>,
49}
50
51type KvarSolution<T> = (Vec<(<T as Types>::Var, Sort<T>)>, Expr<T>);
52
53impl<T, Parser: FromSexp<T>> FromSexpWrapper<T, Parser>
54where
55 T: Types,
56{
57 fn parse_bv_size(&self, sexp: &Sexp) -> Result<Sort<T>, ParseError> {
58 match sexp {
59 Sexp::Atom(Atom::S(s)) if s.starts_with("Size") => {
60 let maybe_size = s
61 .strip_prefix("Size")
62 .and_then(|sz_str| sz_str.parse::<u32>().ok());
63 if let Some(size) = maybe_size {
64 Ok(Sort::BvSize(size))
65 } else {
66 Err(ParseError::err("Could not parse number for bvsize"))
67 }
68 }
69 _ => Err(ParseError::err("Expected bitvec size to be in the form Size{\\d+}")),
70 }
71 }
72
73 pub fn parse_name(&self, sexp: &Sexp) -> Result<T::Var, ParseError> {
74 let name = match sexp {
75 Sexp::Atom(Atom::S(s)) => self.parser.var(s),
76 _ => Err(ParseError::err("Expected bind name to be a string")),
77 }?;
78 Ok(name)
79 }
80
81 pub fn parse_bind(&mut self, sexp: &Sexp) -> Result<Bind<T>, ParseError> {
82 match sexp {
83 Sexp::List(items) => {
84 match &items[0] {
85 Sexp::List(name_and_sort) => {
86 let name = self.parse_name(&name_and_sort[0])?;
87 let sort = self.parse_sort(&name_and_sort[1])?;
88 let pred = self.parse_pred_inner(&items[1])?;
89 Ok(Bind { name, sort, pred })
90 }
91 _ => Err(ParseError::err("Expected list for name and sort in bind")),
92 }
93 }
94 _ => Err(ParseError::err("Expected list for bind")),
95 }
96 }
97
98 fn parse_pred_inner(&mut self, sexp: &Sexp) -> Result<Pred<T>, ParseError> {
99 match sexp {
100 Sexp::List(items) => {
101 match &items[0] {
102 Sexp::Atom(Atom::S(s)) if s == "and" => {
103 items[1..]
104 .to_vec()
105 .iter()
106 .map(|item| self.parse_pred_inner(item))
107 .try_collect()
108 .map(Pred::And)
109 }
110 Sexp::Atom(Atom::S(s)) if s.starts_with("$") => self.parse_kvar(sexp),
111 _ => self.parse_expr_possibly_nested(sexp).map(Pred::Expr),
112 }
113 }
114 _ => Err(ParseError::err("Expected list for pred")),
115 }
116 }
117
118 pub fn parse_kvar(&self, sexp: &Sexp) -> Result<Pred<T>, ParseError> {
119 match sexp {
120 Sexp::List(items) => {
121 if items.len() < 2 {
122 Err(ParseError::err("Kvar application requires at least two elements"))
123 } else {
124 let maybe_strs: Option<Vec<String>> = items
125 .iter()
126 .map(|s| {
127 if let Sexp::Atom(Atom::S(sym)) = s { Some(sym.clone()) } else { None }
128 })
129 .collect();
130 match maybe_strs {
131 Some(strs) => {
132 let kvar = self.parser.kvar(&strs[0])?;
133 let mut args = vec![];
134 for s in &strs[1..] {
135 args.push(Expr::Var(self.parser.var(s)?));
136 }
137 Ok(Pred::KVar(kvar, args))
138 }
139 _ => Err(ParseError::err("Expected all list elements to be strings")),
140 }
141 }
142 }
143 _ => Err(ParseError::err("Expected list for kvar")),
144 }
145 }
146
147 fn parse_expr_possibly_nested(&mut self, sexp: &Sexp) -> Result<Expr<T>, ParseError> {
148 through_nested_list(sexp, |s| self.parse_expr(s))
149 }
150
151 fn parse_is_ctor(&mut self, ctor_name: &str, arg: &Sexp) -> Result<Expr<T>, ParseError> {
152 let ctor = self.parser.var(ctor_name)?;
153 let arg = self.parse_expr(arg)?;
154 Ok(Expr::IsCtor(ctor, Box::new(arg)))
155 }
156
157 fn parse_if(&mut self, sexp: &Sexp) -> Result<Expr<T>, ParseError> {
158 match sexp {
159 Sexp::List(items) => {
160 let condition = self.parse_expr_possibly_nested(&items[1])?;
161 let pos_val = self.parse_expr_possibly_nested(&items[2])?;
162 let neg_val = self.parse_expr_possibly_nested(&items[3])?;
163 Ok(Expr::IfThenElse(Box::new([condition, pos_val, neg_val])))
164 }
165 _ => Err(ParseError::err("Expected list for if-else")),
166 }
167 }
168
169 pub fn parse_expr(&mut self, sexp: &Sexp) -> Result<Expr<T>, ParseError> {
170 match sexp {
171 Sexp::List(items) => {
172 if let Sexp::Atom(Atom::S(s)) = &items[0] {
173 match s.as_str() {
174 "cast" => self.parse_expr(&items[1]),
175 "exists" => self.parse_exists(&items[1..]),
176 "let" => self.parse_let(sexp),
177 "not" => self.parse_not(sexp),
178 "or" => self.parse_or(sexp),
179 "and" => self.parse_and(sexp),
180 "lit" => parse_bitvec(sexp),
181 "if" => self.parse_if(sexp),
182 "-" if items.len() == 2 => self.parse_neg(sexp),
183 "+" | "-" | "*" | "/" | "mod" => self.parse_binary_op(sexp),
184 "=" | "!=" | "<" | "<=" | ">" | ">=" => self.parse_atom(sexp),
185 "<=>" => self.parse_iff(sexp),
186 "=>" => self.parse_imp(sexp),
187 "cast_as_int" => self.parse_expr(&items[1]), _ if s.starts_with("is$") => self.parse_is_ctor(&s[3..], &items[1]),
189 _ => self.parse_app(sexp),
190 }
191 } else {
192 self.parse_app(sexp)
193 }
194 }
195 Sexp::Atom(Atom::S(s)) => {
196 if let Some(thy_func) = parse_thy_func(s) {
197 Ok(Expr::ThyFunc(thy_func))
198 } else if let Some(bv) = self.parse_bound_var(s) {
199 Ok(bv)
200 } else {
201 Ok(Expr::Var(self.parser.var(s)?))
202 }
203 }
204 Sexp::Atom(Atom::Q(s)) => Ok(Expr::Constant(Constant::String(self.parser.string(s)?))),
205 Sexp::Atom(Atom::B(b)) => Ok(Expr::Constant(Constant::Boolean(*b))),
206 Sexp::Atom(Atom::I(i)) => Ok(Expr::Constant(Constant::Numeral(*i))),
207 Sexp::Atom(Atom::F(_f)) => {
208 unimplemented!("Float parsing not supported in fixpoint (see Constant::Real)")
209 }
210 }
211 }
212
213 fn parse_neg(&mut self, sexp: &Sexp) -> Result<Expr<T>, ParseError> {
214 match sexp {
215 Sexp::List(items) => {
216 Ok(Expr::Neg(Box::new(self.parse_expr_possibly_nested(&items[1])?)))
217 }
218 _ => Err(ParseError::err("Expected list for neg")),
219 }
220 }
221
222 fn parse_not(&mut self, sexp: &Sexp) -> Result<Expr<T>, ParseError> {
223 match sexp {
224 Sexp::List(items) => {
225 Ok(Expr::Not(Box::new(self.parse_expr_possibly_nested(&items[1])?)))
226 }
227 _ => Err(ParseError::err("Expected list for \"not\"")),
228 }
229 }
230
231 fn parse_iff(&mut self, sexp: &Sexp) -> Result<Expr<T>, ParseError> {
232 match sexp {
233 Sexp::List(items) => {
234 match &items[0] {
235 Sexp::Atom(Atom::S(s)) if s == "<=>" => {
236 let exp1 = self.parse_expr_possibly_nested(&items[1])?;
237 let exp2 = self.parse_expr_possibly_nested(&items[2])?;
238 Ok(Expr::Iff(Box::new([exp1, exp2])))
239 }
240 _ => Err(ParseError::err("Expected iff to start with \"<=>\"")),
241 }
242 }
243 _ => Err(ParseError::err("Expected list for iff")),
244 }
245 }
246
247 fn parse_imp(&mut self, sexp: &Sexp) -> Result<Expr<T>, ParseError> {
248 match sexp {
249 Sexp::List(items) => {
250 match &items[0] {
251 Sexp::Atom(Atom::S(s)) if s == "=>" => {
252 let exp1 = self.parse_expr_possibly_nested(&items[1])?;
253 let exp2 = self.parse_expr_possibly_nested(&items[2])?;
254 Ok(Expr::Imp(Box::new([exp1, exp2])))
255 }
256 _ => Err(ParseError::err("Expected imp to start with \"=>\"")),
257 }
258 }
259 _ => Err(ParseError::err("Expected list for implication")),
260 }
261 }
262
263 fn parse_and(&mut self, sexp: &Sexp) -> Result<Expr<T>, ParseError> {
264 match sexp {
265 Sexp::List(items) => {
266 match &items[0] {
267 Sexp::Atom(Atom::S(s)) if s == "and" => {
268 items[1..]
269 .to_vec()
270 .iter()
271 .map(|sexp| self.parse_expr_possibly_nested(sexp))
272 .try_collect()
273 .map(Expr::And)
274 }
275 _ => Err(ParseError::err("Expected \"and\" expression to start with \"and\"")),
276 }
277 }
278 _ => Err(ParseError::err("Expected list for \"and\"")),
279 }
280 }
281
282 fn parse_or(&mut self, sexp: &Sexp) -> Result<Expr<T>, ParseError> {
283 match sexp {
284 Sexp::List(items) => {
285 match &items[0] {
286 Sexp::Atom(Atom::S(s)) if s == "or" => {
287 items[1..]
288 .to_vec()
289 .iter()
290 .map(|sexp| self.parse_expr_possibly_nested(sexp))
291 .try_collect()
292 .map(Expr::Or)
293 }
294 _ => Err(ParseError::err("Expected \"or\" expression to start with \"or\"")),
295 }
296 }
297 _ => Err(ParseError::err("Expected list for \"or\"")),
298 }
299 }
300
301 fn parse_atom(&mut self, sexp: &Sexp) -> Result<Expr<T>, ParseError> {
302 match sexp {
303 Sexp::List(items) => {
304 let exp1 = self.parse_expr_possibly_nested(&items[1])?;
305 let exp2 = self.parse_expr_possibly_nested(&items[2])?;
306 let exp_pair = Box::new([exp1, exp2]);
307 match &items[0] {
308 Sexp::Atom(Atom::S(s)) if s == "=" => Ok(Expr::Atom(BinRel::Eq, exp_pair)),
309 Sexp::Atom(Atom::S(s)) if s == "!=" => Ok(Expr::Atom(BinRel::Ne, exp_pair)),
310 Sexp::Atom(Atom::S(s)) if s == "<=" => Ok(Expr::Atom(BinRel::Le, exp_pair)),
311 Sexp::Atom(Atom::S(s)) if s == "<" => Ok(Expr::Atom(BinRel::Lt, exp_pair)),
312 Sexp::Atom(Atom::S(s)) if s == ">=" => Ok(Expr::Atom(BinRel::Ge, exp_pair)),
313 Sexp::Atom(Atom::S(s)) if s == ">" => Ok(Expr::Atom(BinRel::Gt, exp_pair)),
314 _ => Err(ParseError::err("Unsupported atom")),
315 }
316 }
317 _ => Err(ParseError::err("Expected list for atom")),
318 }
319 }
320
321 fn parse_app(&mut self, sexp: &Sexp) -> Result<Expr<T>, ParseError> {
322 match sexp {
323 Sexp::List(items) => {
324 let Sexp::List(inner) = &items[0] else {
325 Err(ParseError::err("Expected list for inner func"))?
326 };
327 match &inner[1] {
328 Sexp::Atom(Atom::S(s)) if s == "apply" => {
329 let func_sort = self.parse_sort(&inner[2])?;
330 let func = self.parse_expr_possibly_nested(&items[1])?;
331 Ok(Expr::App(Box::new(func), None, vec![], Some(func_sort)))
332 }
333 _ => {
334 let args: Vec<Expr<T>> = items[1..]
335 .to_vec()
336 .iter()
337 .map(|sexp| self.parse_expr_possibly_nested(sexp))
338 .try_collect()?;
339 Ok(Expr::App(
340 Box::new(self.parse_expr_possibly_nested(&items[0])?),
341 None,
342 args,
343 None,
344 ))
345 }
346 }
347 }
348 _ => Err(ParseError::err("Expected list for app")),
349 }
350 }
351
352 fn parse_binary_op(&mut self, sexp: &Sexp) -> Result<Expr<T>, ParseError> {
353 match sexp {
354 Sexp::List(items) => {
355 let exp1 = self.parse_expr_possibly_nested(&items[1])?;
356 let exp2 = self.parse_expr_possibly_nested(&items[2])?;
357 let exp_pair = Box::new([exp1, exp2]);
358 match &items[0] {
359 Sexp::Atom(Atom::S(s)) if s == "+" => Ok(Expr::BinaryOp(BinOp::Add, exp_pair)),
360 Sexp::Atom(Atom::S(s)) if s == "-" => Ok(Expr::BinaryOp(BinOp::Sub, exp_pair)),
361 Sexp::Atom(Atom::S(s)) if s == "*" => Ok(Expr::BinaryOp(BinOp::Mul, exp_pair)),
362 Sexp::Atom(Atom::S(s)) if s == "/" => Ok(Expr::BinaryOp(BinOp::Div, exp_pair)),
363 Sexp::Atom(Atom::S(s)) if s == "mod" => {
364 Ok(Expr::BinaryOp(BinOp::Mod, exp_pair))
365 }
366 _ => Err(ParseError::err("Unsupported atom")),
367 }
368 }
369 _ => Err(ParseError::err("Expected list for binary operation")),
370 }
371 }
372
373 fn parse_exists(&mut self, items: &[Sexp]) -> Result<Expr<T>, ParseError> {
374 let [Sexp::List(var_sorts), body] = items else {
375 return Err(ParseError::err("Expected list for vars and sorts in exists"));
376 };
377 let mut names = Vec::new();
378 let mut sorts = Vec::new();
379 for var_sort in var_sorts {
380 if let Sexp::List(items) = var_sort
381 && let [var, sort] = &items[..]
382 {
383 let Sexp::Atom(Atom::S(name)) = var else {
384 return Err(ParseError::err("Expected variable name to be string {var:?}"));
385 };
386 names.push(name.clone());
387 sorts.push(self.parse_sort(sort)?);
388 } else {
389 return Err(ParseError::err(format!(
390 "Expected list for var and sort in exists {var_sort:?}"
391 )));
392 }
393 }
394 self.push_scope(&names);
395 let body = self.parse_expr_possibly_nested(body)?;
396 let mut scope = self.pop_scope().unwrap();
397 let bound = names
398 .iter()
399 .zip(sorts)
400 .map(|(name, sort)| (scope.swap_remove(name).unwrap(), sort))
401 .collect();
402 Ok(Expr::Quantifier(Quantifier::Exists, bound, Box::new(body)))
403 }
404
405 fn parse_let(&mut self, sexp: &Sexp) -> Result<Expr<T>, ParseError> {
406 match sexp {
407 Sexp::List(items) => {
408 through_nested_list(&items[1], |bottom| {
409 match bottom {
410 Sexp::List(var_and_binding) => {
411 match &var_and_binding[0] {
412 Sexp::Atom(Atom::S(s)) => {
413 let binding =
414 self.parse_expr_possibly_nested(&var_and_binding[1])?;
415 let body = self.parse_expr_possibly_nested(&items[2])?;
416 let var = self.parser.var(s)?;
417 Ok(Expr::Let(var, Box::new([binding, body])))
418 }
419 _ => Err(ParseError::err("Expected variable name to be string")),
420 }
421 }
422 _ => Err(ParseError::err("Expected list for var and binding")),
423 }
424 })
425 }
426 _ => Err(ParseError::err("Expected list for let")),
427 }
428 }
429
430 fn parse_list_sort(&self, sexp: &Sexp) -> Result<Sort<T>, ParseError> {
431 let Sexp::List(items) = sexp else {
432 return Err(ParseError::err("Expected list for func or app sort"));
433 };
434 if items.is_empty() {
435 return Err(ParseError::err("Empty list encountered when parsing sort"));
436 }
437 let Sexp::Atom(Atom::S(ctor)) = &items[0] else {
438 return Err(ParseError::err("Unexpected sort constructor encountered"));
439 };
440 if ctor == "func" && items.len() == 4 {
441 return self.parse_func_sort(&items[1..]);
442 }
443 if ctor == "function" && items.len() == 3 {
444 let input = self.parse_sort(&items[1])?;
445 let output = self.parse_sort(&items[2])?;
446 return Ok(Sort::mk_func(0, vec![input], output));
447 }
448 let args: Vec<_> = items[1..]
449 .to_vec()
450 .iter()
451 .map(|sexp| self.parse_sort(sexp))
452 .try_collect()?;
453 if ctor == "Set_Set" && args.len() == 1 {
454 return Ok(Sort::App(SortCtor::Set, args));
455 }
456 if (ctor == "Map_t" || ctor == "Array_t") && args.len() == 2 {
457 return Ok(Sort::App(SortCtor::Map, args));
458 }
459 if ctor == "BitVec" && args.len() == 1 {
460 return parse_bitvec_sort(sexp);
461 }
462 let ctor = SortCtor::Data(self.parser.sort(ctor)?);
463 Ok(Sort::App(ctor, args))
464 }
465
466 pub fn parse_sort(&self, sexp: &Sexp) -> Result<Sort<T>, ParseError> {
467 match sexp {
468 Sexp::List(_items) => self.parse_list_sort(sexp),
469 Sexp::Atom(Atom::S(s)) => {
470 if s == "Int" || s == "int" {
471 Ok(Sort::Int)
472 } else if s == "Bool" || s == "bool" {
473 Ok(Sort::Bool)
474 } else if s == "Real" || s == "real" {
475 Ok(Sort::Real)
476 } else if s == "Str" || s == "str" {
477 Ok(Sort::Str)
478 } else if s.starts_with("Size") {
479 self.parse_bv_size(sexp)
480 } else if let Some(idx_rparen) = s.strip_prefix("@(")
481 && let Some(s_idx) = idx_rparen.strip_suffix(")")
482 && let Ok(idx) = s_idx.parse::<usize>()
483 {
484 Ok(Sort::Var(idx))
485 } else {
486 let ctor = SortCtor::Data(self.parser.sort(s)?);
487 Ok(Sort::App(ctor, vec![]))
488 }
489 }
490 _ => panic!("Unknown sort encountered {sexp:?}"), }
493 }
494
495 fn parse_func_sort(&self, items: &[Sexp]) -> Result<Sort<T>, ParseError> {
496 if let Sexp::Atom(Atom::I(params)) = &items[0]
497 && let Sexp::List(inputs) = &items[1]
498 {
499 let params = *params as usize;
500 let inputs: Vec<_> = inputs
501 .iter()
502 .map(|sexp| self.parse_sort(sexp))
503 .try_collect()?;
504 let output = self.parse_sort(&items[2])?;
505 Ok(Sort::mk_func(params, inputs, output))
506 } else {
507 Err(ParseError::err("Expected arity to be an integer"))
508 }
509 }
510
511 pub fn parse_solution(&mut self, sexp: &Sexp) -> Result<KvarSolution<T>, ParseError> {
512 if let Sexp::List(items) = sexp
513 && let [_lambda, params, body] = &items[..]
514 && let Sexp::List(sexp_params) = params
515 {
516 let mut kvar_args = vec![];
517 let mut sorts = vec![];
518
519 for param in sexp_params {
520 if let Sexp::List(bind) = param
521 && let [_name, sort] = &bind[..]
522 && let Sexp::Atom(Atom::S(s)) = _name
523 {
524 kvar_args.push(s.clone());
525 sorts.push(sort);
526 } else {
527 return Err(ParseError::err("expected parameter names to be symbols"));
528 }
529 }
530 let sorts: Vec<_> = sorts
531 .into_iter()
532 .map(|sexp| self.parse_sort(sexp))
533 .try_collect()?;
534 self.push_scope(&kvar_args);
535
536 let expr = self.parse_expr(body)?;
537
538 let mut scope = self.pop_scope().unwrap();
539 let bound = kvar_args
540 .iter()
541 .zip(sorts)
542 .map(|(name, sort)| (scope.swap_remove(name).unwrap(), sort))
543 .collect();
544 Ok((bound, expr))
545 } else {
546 Err(ParseError::err("expected (lambda (params) body)"))
547 }
548 }
549
550 fn push_scope(&mut self, names: &[String]) {
551 self.scopes.push(
552 names
553 .iter()
554 .cloned()
555 .map(|name| (name, self.parser.fresh_var()))
556 .collect(),
557 );
558 }
559
560 fn pop_scope(&mut self) -> Option<IndexMap<String, T::Var>> {
561 self.scopes.pop()
562 }
563
564 fn parse_bound_var(&self, name: &str) -> Option<Expr<T>> {
565 for scope in self.scopes.iter().rev() {
566 if let Some(var) = scope.get(name) {
567 return Some(Expr::Var(var.clone()));
568 }
569 }
570 None
571 }
572}
573
574fn parse_bv_size<T: Types>(sexp: &Sexp) -> Result<Sort<T>, ParseError> {
575 match sexp {
576 Sexp::Atom(Atom::S(s)) if s.starts_with("Size") => {
577 let maybe_size = s
578 .strip_prefix("Size")
579 .and_then(|sz_str| sz_str.parse::<u32>().ok());
580 if let Some(size) = maybe_size {
581 Ok(Sort::BvSize(size))
582 } else {
583 Err(ParseError::err("Could not parse number for bvsize"))
584 }
585 }
586 _ => Err(ParseError::err("Expected bitvec size to be in the form Size{\\d+}")),
587 }
588}
589
590fn parse_bitvec_sort<T: Types>(sexp: &Sexp) -> Result<Sort<T>, ParseError> {
591 match sexp {
592 Sexp::List(items) if items.len() == 2 => {
593 let bitvec_size = parse_bv_size(&items[1])?;
594 Ok(Sort::BitVec(Box::new(bitvec_size)))
595 }
596 _ => Err(ParseError::err("Expected list of length 2 for bitvec sort")),
597 }
598}
599
600fn size_form_bv_sort(sort: Sort<StringTypes>) -> Result<u32, ParseError> {
601 match sort {
602 Sort::BitVec(ref bv_size_box) => {
603 match **bv_size_box {
604 Sort::BvSize(size) => Ok(size),
605 _ => Err(ParseError::err("BitVec sort should contain BvSize sort")),
606 }
607 }
608 _ => Err(ParseError::err("Expected BitVec variant to be provided")),
609 }
610}
611
612fn parse_bitvec<PT: Types>(sexp: &Sexp) -> Result<Expr<PT>, ParseError> {
613 match sexp {
614 Sexp::List(items) => {
615 match &items[1] {
616 Sexp::Atom(Atom::Q(lit)) if lit.starts_with("#b") => {
617 let bitvec = u128::from_str_radix(&lit[3..], 2).expect("Invalid binary string");
618 let bvsize = size_form_bv_sort(parse_bitvec_sort(&items[2])?)?;
619 Ok(Expr::Constant(Constant::BitVec(bitvec, bvsize)))
620 }
621 _ => Err(ParseError::err("Expected binary literal for bitvec")),
622 }
623 }
624 _ => Err(ParseError::err("Expected list for bitvector literal")),
625 }
626}
627
628fn parse_thy_func(name: &str) -> Option<ThyFunc> {
629 match name {
630 "strLen" => Some(ThyFunc::StrLen),
632
633 "int_to_bv8" => Some(ThyFunc::IntToBv8),
635 "bv8_to_int" => Some(ThyFunc::Bv8ToInt),
636 "int_to_bv32" => Some(ThyFunc::IntToBv32),
637 "bv32_to_int" => Some(ThyFunc::Bv32ToInt),
638 "int_to_bv64" => Some(ThyFunc::IntToBv64),
639 "bv64_to_int" => Some(ThyFunc::Bv64ToInt),
640
641 "bvule" => Some(ThyFunc::BvUle),
643 "bvsle" => Some(ThyFunc::BvSle),
644 "bvuge" => Some(ThyFunc::BvUge),
645 "bvsge" => Some(ThyFunc::BvSge),
646 "bvugt" => Some(ThyFunc::BvUgt),
647 "bvsgt" => Some(ThyFunc::BvSgt),
648 "bvult" => Some(ThyFunc::BvUlt),
649 "bvslt" => Some(ThyFunc::BvSlt),
650
651 "bvudiv" => Some(ThyFunc::BvUdiv),
653 "bvsdiv" => Some(ThyFunc::BvSdiv),
654 "bvurem" => Some(ThyFunc::BvUrem),
655 "bvsrem" => Some(ThyFunc::BvSrem),
656 "bvlshr" => Some(ThyFunc::BvLshr),
657 "bvashr" => Some(ThyFunc::BvAshr),
658 "bvand" => Some(ThyFunc::BvAnd),
659 "bvor" => Some(ThyFunc::BvOr),
660 "bvxor" => Some(ThyFunc::BvXor),
661 "bvnot" => Some(ThyFunc::BvNot),
662 "bvadd" => Some(ThyFunc::BvAdd),
663 "bvneg" => Some(ThyFunc::BvNeg),
664 "bvsub" => Some(ThyFunc::BvSub),
665 "bvmul" => Some(ThyFunc::BvMul),
666 "bvshl" => Some(ThyFunc::BvShl),
667
668 "Set_empty" => Some(ThyFunc::SetEmpty),
670 "Set_sng" => Some(ThyFunc::SetSng),
671 "Set_cup" => Some(ThyFunc::SetCup),
672 "Set_cap" => Some(ThyFunc::SetCap),
673 "Set_dif" => Some(ThyFunc::SetDif),
674 "Set_mem" => Some(ThyFunc::SetMem),
675 "Set_sub" => Some(ThyFunc::SetSub),
676
677 "Map_default" => Some(ThyFunc::MapDefault),
679 "Map_select" | "arr_select_m" => Some(ThyFunc::MapSelect),
680 "Map_store" | "arr_store_m" => Some(ThyFunc::MapStore),
681
682 _ => None,
685 }
686}
687
688fn through_nested_list<T, F>(sexp: &Sexp, mut at_bottom: F) -> T
689where
690 F: FnMut(&Sexp) -> T,
691{
692 let mut current = sexp;
693 while let Sexp::List(items) = current {
694 if items.len() == 1 {
695 current = &items[0];
696 } else {
697 break;
698 }
699 }
700 at_bottom(current)
701}
702
703pub struct StringTypes;
705impl Types for StringTypes {
706 type Sort = String;
707 type KVar = String;
708 type Var = String;
709 type Tag = String;
710 type String = String;
711 type Real = String;
712}
713
714impl FromSexp<StringTypes> for StringTypes {
715 fn fresh_var(&mut self) -> <StringTypes as Types>::Var {
716 todo!()
717 }
718 fn var(&self, name: &str) -> Result<String, ParseError> {
719 Ok(name.to_string())
720 }
721
722 fn kvar(&self, name: &str) -> Result<String, ParseError> {
723 Ok(name.to_string())
724 }
725
726 fn string(&self, s: &str) -> Result<String, ParseError> {
727 Ok(s.to_string())
728 }
729
730 fn sort(&self, name: &str) -> Result<String, ParseError> {
731 Ok(name.to_string())
732 }
733}