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