1use std::{fmt::Display, marker::PhantomData, ops::RangeInclusive, str::FromStr};
13
14use nom::{
15 branch::alt,
16 bytes::complete::tag,
17 character::complete::{alphanumeric1, char, digit1, multispace0, multispace1},
18 combinator::{all_consuming, map, map_res, opt, recognize, verify},
19 multi::{many0, separated_list0, separated_list1},
20 sequence::{delimited, pair, preceded, separated_pair, terminated},
21 IResult, Parser,
22};
23use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
24
25use crate::{IntVal, VarRef};
26
27pub const RESERVED: &[&str] = &[
29 "abs", "add", "and", "card", "convex", "diff", "disjoint", "dist", "div", "eq", "ge", "gt",
30 "hull", "if", "iff", "imp", "in", "inter", "le", "lt", "max", "min", "mod", "mul", "ne", "neg",
31 "not", "or", "pow", "sdiff", "set", "sqr", "sqrt", "sub", "subseq", "subset", "superseq",
32 "superset", "union", "xor",
33];
34
35#[derive(Clone, Debug, PartialEq, Hash)]
37pub enum BoolExp<Identifier> {
38 Const(bool),
43 Var(VarRef<Identifier>),
45 Not(Box<BoolExp<Identifier>>),
47 And(Vec<BoolExp<Identifier>>),
49 Or(Vec<BoolExp<Identifier>>),
51 Xor(Vec<BoolExp<Identifier>>),
53 Equiv(Vec<BoolExp<Identifier>>),
55 Implies(Box<BoolExp<Identifier>>, Box<BoolExp<Identifier>>),
57 LessThan(Box<IntExp<Identifier>>, Box<IntExp<Identifier>>),
59 LessThanEq(Box<IntExp<Identifier>>, Box<IntExp<Identifier>>),
61 GreaterThan(Box<IntExp<Identifier>>, Box<IntExp<Identifier>>),
63 GreaterThanEq(Box<IntExp<Identifier>>, Box<IntExp<Identifier>>),
65 NotEqual(Box<Exp<Identifier>>, Box<Exp<Identifier>>),
67 Equal(Vec<Exp<Identifier>>),
69 Member(Box<IntExp<Identifier>>, Box<SetExp<Identifier>>),
71 Disjoint(Box<SetExp<Identifier>>, Box<SetExp<Identifier>>),
73 SubSet(Box<SetExp<Identifier>>, Box<SetExp<Identifier>>),
75 SubSetEq(Box<SetExp<Identifier>>, Box<SetExp<Identifier>>),
77 SuperSet(Box<SetExp<Identifier>>, Box<SetExp<Identifier>>),
79 SuperSetEq(Box<SetExp<Identifier>>, Box<SetExp<Identifier>>),
81 Convex(Box<SetExp<Identifier>>),
83}
84
85#[derive(Clone, Debug, PartialEq, Hash)]
87pub enum Exp<Identifier> {
88 Bool(Box<BoolExp<Identifier>>),
90 Int(Box<IntExp<Identifier>>),
92 Set(Box<SetExp<Identifier>>),
94 Var(VarRef<Identifier>),
96}
97
98#[derive(Clone, Debug, PartialEq, Hash)]
100pub enum IntExp<Identifier> {
101 Const(IntVal),
103 Var(VarRef<Identifier>),
105 Neg(Box<IntExp<Identifier>>),
107 Abs(Box<IntExp<Identifier>>),
109 Add(Vec<IntExp<Identifier>>),
111 Sub(Box<IntExp<Identifier>>, Box<IntExp<Identifier>>),
113 Mul(Vec<IntExp<Identifier>>),
115 Div(Box<IntExp<Identifier>>, Box<IntExp<Identifier>>),
117 Mod(Box<IntExp<Identifier>>, Box<IntExp<Identifier>>),
119 Sqr(Box<IntExp<Identifier>>),
121 Pow(Box<IntExp<Identifier>>, Box<IntExp<Identifier>>),
123 Min(Vec<Exp<Identifier>>),
125 Max(Vec<Exp<Identifier>>),
127 Dist(Box<IntExp<Identifier>>, Box<IntExp<Identifier>>),
129 If(
131 BoolExp<Identifier>,
132 Box<IntExp<Identifier>>,
133 Box<IntExp<Identifier>>,
134 ),
135 Bool(BoolExp<Identifier>),
137 Card(Box<SetExp<Identifier>>),
139}
140
141#[derive(Clone, Debug, PartialEq, Hash)]
143pub enum SetExp<Identifier> {
144 Set(Vec<IntExp<Identifier>>),
146 Range((IntExp<Identifier>, IntExp<Identifier>)),
149 Var(VarRef<Identifier>),
151 Hull(Box<SetExp<Identifier>>),
153 Diff(Box<SetExp<Identifier>>, Box<SetExp<Identifier>>),
155 Union(Vec<SetExp<Identifier>>),
157 Inter(Vec<SetExp<Identifier>>),
159 SDiff(Vec<SetExp<Identifier>>),
161}
162
163pub(crate) fn identifier<Identifier: FromStr>(input: &str) -> IResult<&str, Identifier> {
165 let (input, v) = verify(alphanumeric1, |s: &str| {
166 s.chars().next().unwrap().is_ascii_alphabetic() && !RESERVED.contains(&s)
167 })
168 .parse(input)?;
169 Ok((
170 input,
171 match v.parse() {
172 Ok(t) => t,
173 Err(_) => panic!("unable to create identifier"),
174 },
175 ))
176}
177
178pub(crate) fn int(input: &str) -> IResult<&str, IntVal> {
180 let (input, neg) = opt(char('-')).parse(input)?;
181 let (input, i): (_, i64) = map_res(recognize(digit1), str::parse).parse(input)?;
182 Ok((input, if neg.is_some() { -i } else { i }))
183}
184
185pub(crate) fn range(input: &str) -> IResult<&str, RangeInclusive<IntVal>> {
187 let (input, lb) = int(input)?;
188 if let (input, Some(_)) = opt(tag("..")).parse(input)? {
189 let (input, ub) = int(input)?;
190 Ok((input, lb..=ub))
191 } else {
192 Ok((input, lb..=lb))
193 }
194}
195
196pub(crate) fn sequence<'a, O>(
199 p: impl Parser<&'a str, Output = O>,
200) -> impl Parser<&'a str, Output = Vec<O>> {
201 terminated(many0(preceded(multispace0, p)), multispace0)
202}
203
204pub(crate) fn tuple<'a, O>(
207 p: impl Parser<&'a str, Output = O>,
208) -> impl Parser<&'a str, Output = Vec<O>> {
209 delimited(char('('), separated_list1(char(','), p), char(')'))
210}
211
212pub(crate) fn whitespace_seperated<'a, O>(
214 p: impl Parser<&'a str, Output = O>,
215) -> impl Parser<&'a str, Output = Vec<O>> {
216 separated_list1(multispace1, p)
217}
218
219impl<Identifier: FromStr> BoolExp<Identifier> {
220 fn call_arg1(input: &str) -> IResult<&str, Self> {
223 let (input, tag) = tag("not")(input)?;
224 let (input, _) = char('(')(input)?;
225 let (input, e) = Self::parse(input)?;
226 let (input, _) = char(')')(input)?;
227 Ok((
228 input,
229 match tag {
230 "not" => BoolExp::Not,
231 _ => unreachable!(),
232 }(Box::new(e)),
233 ))
234 }
235
236 fn call_arg1_set(input: &str) -> IResult<&str, Self> {
239 let (input, tag) = tag("convex")(input)?;
240 let (input, _) = char('(')(input)?;
241 let (input, e) = SetExp::parse(input)?;
242 let (input, _) = char(')')(input)?;
243 Ok((
244 input,
245 match tag {
246 "convex" => BoolExp::Convex,
247 _ => unreachable!(),
248 }(Box::new(e)),
249 ))
250 }
251
252 fn call_arg2(input: &str) -> IResult<&str, Self> {
255 let (input, tag) = tag("imp")(input)?;
256 let (input, _) = char('(')(input)?;
257 let (input, e1) = Self::parse(input)?;
258 let (input, _) = char(',')(input)?;
259 let (input, e2) = Self::parse(input)?;
260 let (input, _) = char(')')(input)?;
261 Ok((
262 input,
263 match tag {
264 "imp" => BoolExp::Implies,
265 _ => unreachable!(),
266 }(Box::new(e1), Box::new(e2)),
267 ))
268 }
269
270 fn call_arg2_exp(input: &str) -> IResult<&str, Self> {
273 let (input, tag) = tag("ne")(input)?;
274 let (input, _) = char('(')(input)?;
275 let (input, e1) = Exp::parse(input)?;
276 let (input, _) = char(',')(input)?;
277 let (input, e2) = Exp::parse(input)?;
278 let (input, _) = char(')')(input)?;
279 Ok((
280 input,
281 match tag {
282 "imp" => BoolExp::NotEqual,
283 _ => unreachable!(),
284 }(Box::new(e1), Box::new(e2)),
285 ))
286 }
287
288 fn call_arg2_int(input: &str) -> IResult<&str, Self> {
291 let (input, tag) = alt((tag("lt"), tag("le"), tag("gt"), tag("ge"))).parse(input)?;
292 let (input, _) = char('(')(input)?;
293 let (input, e1) = IntExp::parse(input)?;
294 let (input, _) = char(',')(input)?;
295 let (input, e2) = IntExp::parse(input)?;
296 let (input, _) = char(')')(input)?;
297 Ok((
298 input,
299 match tag {
300 "lt" => BoolExp::LessThan,
301 "le" => BoolExp::LessThanEq,
302 "gt" => BoolExp::GreaterThan,
303 "ge" => BoolExp::GreaterThanEq,
304 _ => unreachable!(),
305 }(Box::new(e1), Box::new(e2)),
306 ))
307 }
308
309 fn call_arg2_int_set(input: &str) -> IResult<&str, Self> {
312 let (input, tag) = tag("in")(input)?;
313 let (input, _) = char('(')(input)?;
314 let (input, e1) = IntExp::parse(input)?;
315 let (input, _) = char(',')(input)?;
316 let (input, e2) = SetExp::parse(input)?;
317 let (input, _) = char(')')(input)?;
318 Ok((
319 input,
320 match tag {
321 "in" => BoolExp::Member,
322 _ => unreachable!(),
323 }(Box::new(e1), Box::new(e2)),
324 ))
325 }
326
327 fn call_arg2_set(input: &str) -> IResult<&str, Self> {
330 let (input, tag) = alt((
331 tag("disjoint"),
332 tag("subset"),
333 tag("subseq"),
334 tag("supseq"),
335 tag("supset"),
336 ))
337 .parse(input)?;
338 let (input, _) = char('(')(input)?;
339 let (input, e1) = SetExp::parse(input)?;
340 let (input, _) = char(',')(input)?;
341 let (input, e2) = SetExp::parse(input)?;
342 let (input, _) = char(')')(input)?;
343 Ok((
344 input,
345 match tag {
346 "disjoint" => BoolExp::Disjoint,
347 "subset" => BoolExp::SubSet,
348 "subseq" => BoolExp::SubSetEq,
349 "supseq" => BoolExp::SuperSetEq,
350 "supset" => BoolExp::SuperSet,
351 _ => unreachable!(),
352 }(Box::new(e1), Box::new(e2)),
353 ))
354 }
355
356 fn call_argn(input: &str) -> IResult<&str, Self> {
359 let (input, tag) = alt((tag("and"), tag("or"), tag("xor"), tag("iff"))).parse(input)?;
360 let (input, _) = char('(')(input)?;
361 let (input, es) = separated_list0(char(','), Self::parse).parse(input)?;
362 let (input, _) = char(')')(input)?;
363 Ok((
364 input,
365 match tag {
366 "and" => BoolExp::And,
367 "or" => BoolExp::Or,
368 "xor" => BoolExp::Xor,
369 "iff" => BoolExp::Equiv,
370 _ => unreachable!(),
371 }(es),
372 ))
373 }
374
375 fn call_argn_exp(input: &str) -> IResult<&str, Self> {
378 let (input, tag) = tag("eq")(input)?;
379 let (input, _) = char('(')(input)?;
380 let (input, es) = separated_list1(char(','), Exp::parse).parse(input)?;
381 let (input, _) = char(')')(input)?;
382 Ok((
383 input,
384 match tag {
385 "eq" => BoolExp::Equal,
386 _ => unreachable!(),
387 }(es),
388 ))
389 }
390
391 pub(crate) fn parse(input: &str) -> IResult<&str, Self> {
393 alt((
394 map(verify(digit1, |s| matches!(s, "0" | "1")), |s| {
395 BoolExp::Const(s == "1")
396 }),
397 Self::call_arg1,
398 Self::call_arg1_set,
399 Self::call_arg2,
400 Self::call_arg2_int,
401 Self::call_arg2_int_set,
402 Self::call_arg2_set,
403 Self::call_arg2_exp,
404 Self::call_argn,
405 Self::call_argn_exp,
406 map(VarRef::parse, BoolExp::Var),
407 ))
408 .parse(input)
409 }
410}
411
412impl<'de, Identifier: FromStr> Deserialize<'de> for BoolExp<Identifier> {
413 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<BoolExp<Identifier>, D::Error> {
414 struct V<Ident>(PhantomData<Ident>);
416 impl<Ident: FromStr> Visitor<'_> for V<Ident> {
417 type Value = BoolExp<Ident>;
418
419 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
420 formatter.write_str("a Boolean expression")
421 }
422
423 fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
424 let v = v.trim();
425 let (_, v) = Self::Value::parse(v)
426 .map_err(|e| E::custom(format!("invalid Boolean expression: {e:?}")))?;
427 Ok(v)
428 }
429 }
430 deserializer.deserialize_str(V(PhantomData::<Identifier>))
431 }
432}
433
434impl<Identifier: Display> Display for BoolExp<Identifier> {
435 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
436 match self {
437 BoolExp::Const(b) => write!(f, "{}", if *b { 1 } else { 0 }),
438 BoolExp::Var(id) => write!(f, "{}", id),
439 BoolExp::Not(e) => write!(f, "not({})", e),
440 BoolExp::And(es) => write!(
441 f,
442 "and({})",
443 es.iter()
444 .map(|e| e.to_string())
445 .collect::<Vec<_>>()
446 .join(",")
447 ),
448 BoolExp::Or(es) => write!(
449 f,
450 "or({})",
451 es.iter()
452 .map(|e| e.to_string())
453 .collect::<Vec<_>>()
454 .join(",")
455 ),
456 BoolExp::Xor(es) => write!(
457 f,
458 "xor({})",
459 es.iter()
460 .map(|e| e.to_string())
461 .collect::<Vec<_>>()
462 .join(",")
463 ),
464 BoolExp::Equiv(es) => write!(
465 f,
466 "iff({})",
467 es.iter()
468 .map(|e| e.to_string())
469 .collect::<Vec<_>>()
470 .join(",")
471 ),
472 BoolExp::Implies(e1, e2) => write!(f, "imp({},{})", e1, e2),
473 BoolExp::LessThan(e1, e2) => write!(f, "lt({},{})", e1, e2),
474 BoolExp::LessThanEq(e1, e2) => write!(f, "le({},{})", e1, e2),
475 BoolExp::GreaterThan(e1, e2) => write!(f, "gt({},{})", e1, e2),
476 BoolExp::GreaterThanEq(e1, e2) => write!(f, "ge({},{})", e1, e2),
477 BoolExp::NotEqual(e1, e2) => write!(f, "ne({},{})", e1, e2),
478 BoolExp::Equal(es) => write!(
479 f,
480 "eq({})",
481 es.iter()
482 .map(|e| e.to_string())
483 .collect::<Vec<_>>()
484 .join(",")
485 ),
486 BoolExp::Member(e1, e2) => write!(f, "in({},{})", e1, e2),
487 BoolExp::Disjoint(e1, e2) => write!(f, "disjoint({},{})", e1, e2),
488 BoolExp::SubSet(e1, e2) => write!(f, "subset({},{})", e1, e2),
489 BoolExp::SubSetEq(e1, e2) => write!(f, "subseq({},{})", e1, e2),
490 BoolExp::SuperSet(e1, e2) => write!(f, "supset({},{})", e1, e2),
491 BoolExp::SuperSetEq(e1, e2) => write!(f, "supseq({},{})", e1, e2),
492 BoolExp::Convex(e) => write!(f, "convex({})", e),
493 }
494 }
495}
496
497impl<Identifier: Display> Serialize for BoolExp<Identifier> {
498 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
499 serializer.serialize_str(&self.to_string())
500 }
501}
502
503impl<Identifier: FromStr> Exp<Identifier> {
504 pub(crate) fn parse(input: &str) -> IResult<&str, Self> {
506 alt((
507 map(VarRef::parse, |x| Exp::Var(x)),
508 map(SetExp::parse, |x| Exp::Set(Box::new(x))),
509 map(BoolExp::parse, |x| Exp::Bool(Box::new(x))),
510 map(IntExp::parse, |x| Exp::Int(Box::new(x))),
511 ))
512 .parse(input)
513 }
514
515 pub(crate) fn parse_vec<'de, D: Deserializer<'de>>(
517 deserializer: D,
518 ) -> Result<Vec<Self>, D::Error> {
519 struct V<X>(PhantomData<X>);
521 impl<X: FromStr> Visitor<'_> for V<X> {
522 type Value = Vec<Exp<X>>;
523
524 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
525 formatter.write_str("a list of expressions")
526 }
527
528 fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
529 let v = v.trim();
530 let (_, v) = all_consuming(whitespace_seperated(Exp::parse))
531 .parse(v)
532 .map_err(|_| E::custom(format!("invalid expressions `{v}'")))?;
533 Ok(v)
534 }
535 }
536 let visitor = V::<Identifier>(PhantomData);
537 deserializer.deserialize_str(visitor)
538 }
539}
540
541impl<Identifier: Display> Display for Exp<Identifier> {
542 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
543 match self {
544 Exp::Bool(e) => write!(f, "{}", e),
545 Exp::Int(e) => write!(f, "{}", e),
546 Exp::Set(e) => write!(f, "{}", e),
547 Exp::Var(e) => write!(f, "{}", e),
548 }
549 }
550}
551
552impl<Identifier: FromStr> IntExp<Identifier> {
553 fn call_arg1(input: &str) -> IResult<&str, Self> {
556 let (input, tag) = alt((tag("neg"), tag("abs"), tag("sqr"))).parse(input)?;
557 let (input, _) = char('(')(input)?;
558 let (input, e) = Self::parse(input)?;
559 let (input, _) = char(')')(input)?;
560 Ok((
561 input,
562 match tag {
563 "neg" => IntExp::Neg,
564 "abs" => IntExp::Abs,
565 "sqr" => IntExp::Sqr,
566 _ => unreachable!(),
567 }(Box::new(e)),
568 ))
569 }
570
571 fn call_arg1_set(input: &str) -> IResult<&str, Self> {
574 let (input, tag) = tag("card")(input)?;
575 let (input, _) = char('(')(input)?;
576 let (input, e) = SetExp::parse(input)?;
577 let (input, _) = char(')')(input)?;
578 Ok((
579 input,
580 match tag {
581 "card" => IntExp::Card,
582 _ => unreachable!(),
583 }(Box::new(e)),
584 ))
585 }
586
587 fn call_arg2(input: &str) -> IResult<&str, Self> {
590 let (input, tag) =
591 alt((tag("sub"), tag("div"), tag("mod"), tag("pow"), tag("dist"))).parse(input)?;
592 let (input, _) = char('(')(input)?;
593 let (input, e1) = Self::parse(input)?;
594 let (input, _) = char(',')(input)?;
595 let (input, e2) = Self::parse(input)?;
596 let (input, _) = char(')')(input)?;
597 Ok((
598 input,
599 match tag {
600 "sub" => IntExp::Sub,
601 "div" => IntExp::Div,
602 "mod" => IntExp::Mod,
603 "pow" => IntExp::Pow,
604 "dist" => IntExp::Dist,
605 _ => unreachable!(),
606 }(Box::new(e1), Box::new(e2)),
607 ))
608 }
609
610 fn call_arg3(input: &str) -> IResult<&str, Self> {
613 let (input, tag) = alt((tag("if"),)).parse(input)?;
614 let (input, _) = char('(')(input)?;
615 let (input, e1) = BoolExp::parse(input)?;
616 let (input, _) = char(',')(input)?;
617 let (input, e2) = Self::parse(input)?;
618 let (input, _) = char(',')(input)?;
619 let (input, e3) = Self::parse(input)?;
620 let (input, _) = char(')')(input)?;
621 Ok((
622 input,
623 match tag {
624 "if" => IntExp::If,
625 _ => unreachable!(),
626 }(e1, Box::new(e2), Box::new(e3)),
627 ))
628 }
629
630 fn call_argn(input: &str) -> IResult<&str, Self> {
633 let (input, tag) = alt((tag("add"), tag("mul"))).parse(input)?;
634 let (input, _) = char('(')(input)?;
635 let (input, es) = separated_list1(char(','), Self::parse).parse(input)?;
636 let (input, _) = char(')')(input)?;
637 Ok((
638 input,
639 match tag {
640 "add" => IntExp::Add,
641 "mul" => IntExp::Mul,
642 _ => unreachable!(),
643 }(es),
644 ))
645 }
646
647 fn call_argn_exp(input: &str) -> IResult<&str, Self> {
650 let (input, tag) = alt((tag("min"), tag("max"))).parse(input)?;
651 let (input, _) = char('(')(input)?;
652 let (input, es) = separated_list1(char(','), Exp::parse).parse(input)?;
653 let (input, _) = char(')')(input)?;
654 Ok((
655 input,
656 match tag {
657 "min" => IntExp::Min,
658 "max" => IntExp::Max,
659 _ => unreachable!(),
660 }(es),
661 ))
662 }
663
664 pub(crate) fn parse(input: &str) -> IResult<&str, Self> {
666 alt((
667 map(int, IntExp::Const),
668 IntExp::call_arg1,
669 IntExp::call_arg1_set,
670 IntExp::call_arg2,
671 IntExp::call_arg3,
672 IntExp::call_argn,
673 IntExp::call_argn_exp,
674 map(VarRef::parse, IntExp::Var),
675 map(BoolExp::parse, IntExp::Bool),
676 ))
677 .parse(input)
678 }
679
680 pub(crate) fn parse_vec<'de, D: Deserializer<'de>>(
682 deserializer: D,
683 ) -> Result<Vec<Self>, D::Error> {
684 struct V<X>(PhantomData<X>);
686 impl<X: FromStr> Visitor<'_> for V<X> {
687 type Value = Vec<IntExp<X>>;
688
689 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
690 formatter.write_str("a list of integers expressions")
691 }
692
693 fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
694 let v = v.trim();
695 let (_, v) = all_consuming(whitespace_seperated(IntExp::parse))
696 .parse(v)
697 .map_err(|_| E::custom(format!("invalid integer expressions `{v}'")))?;
698 Ok(v)
699 }
700 }
701 let visitor = V::<Identifier>(PhantomData);
702 deserializer.deserialize_str(visitor)
703 }
704}
705
706impl<'de, Identifier: FromStr> Deserialize<'de> for IntExp<Identifier> {
707 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<IntExp<Identifier>, D::Error> {
708 struct V<Ident>(PhantomData<Ident>);
710 impl<Ident: FromStr> Visitor<'_> for V<Ident> {
711 type Value = IntExp<Ident>;
712
713 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
714 formatter.write_str("an integer expression")
715 }
716
717 fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
718 let v = v.trim();
719 let (_, v) = Self::Value::parse(v)
720 .map_err(|_| E::custom(format!("invalid integer expression `{v}'")))?;
721 Ok(v)
722 }
723 }
724 deserializer.deserialize_str(V(PhantomData::<Identifier>))
725 }
726}
727
728impl<Identifier: Display> Display for IntExp<Identifier> {
729 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
730 match self {
731 IntExp::Const(i) => write!(f, "{}", i),
732 IntExp::Var(id) => write!(f, "{}", id),
733 IntExp::Neg(e) => write!(f, "neg({})", e),
734 IntExp::Abs(e) => write!(f, "abs({})", e),
735 IntExp::Add(es) => write!(
736 f,
737 "add({})",
738 es.iter()
739 .map(|e| e.to_string())
740 .collect::<Vec<_>>()
741 .join(",")
742 ),
743 IntExp::Sub(e1, e2) => write!(f, "sub({},{})", e1, e2),
744 IntExp::Mul(es) => write!(
745 f,
746 "mul({})",
747 es.iter()
748 .map(|e| e.to_string())
749 .collect::<Vec<_>>()
750 .join(",")
751 ),
752 IntExp::Div(e1, e2) => write!(f, "div({},{})", e1, e2),
753 IntExp::Mod(e1, e2) => write!(f, "mod({},{})", e1, e2),
754 IntExp::Sqr(e) => write!(f, "sqr({})", e),
755 IntExp::Pow(e1, e2) => write!(f, "pow({},{})", e1, e2),
756 IntExp::Min(es) => write!(
757 f,
758 "min({})",
759 es.iter()
760 .map(|e| e.to_string())
761 .collect::<Vec<_>>()
762 .join(",")
763 ),
764 IntExp::Max(es) => write!(
765 f,
766 "max({})",
767 es.iter()
768 .map(|e| e.to_string())
769 .collect::<Vec<_>>()
770 .join(",")
771 ),
772 IntExp::Dist(e1, e2) => write!(f, "dist({},{})", e1, e2),
773 IntExp::If(b, e1, e2) => write!(f, "if({},{},{})", b, e1, e2),
774 IntExp::Bool(b) => write!(f, "{}", b),
775 IntExp::Card(s) => write!(f, "card({})", s),
776 }
777 }
778}
779
780impl<Identifier: Display> Serialize for IntExp<Identifier> {
781 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
782 serializer.serialize_str(&self.to_string())
783 }
784}
785
786impl<Identifier: FromStr> SetExp<Identifier> {
787 fn call_arg1(input: &str) -> IResult<&str, Self> {
790 let (input, tag) = tag("hull")(input)?;
791 let (input, _) = char('(')(input)?;
792 let (input, e) = Self::parse(input)?;
793 let (input, _) = char(')')(input)?;
794 Ok((
795 input,
796 match tag {
797 "hull" => SetExp::Hull,
798 _ => unreachable!(),
799 }(Box::new(e)),
800 ))
801 }
802
803 fn call_arg2(input: &str) -> IResult<&str, Self> {
806 let (input, tag) = tag("diff")(input)?;
807 let (input, _) = char('(')(input)?;
808 let (input, e1) = Self::parse(input)?;
809 let (input, _) = char(',')(input)?;
810 let (input, e2) = Self::parse(input)?;
811 let (input, _) = char(')')(input)?;
812 Ok((
813 input,
814 match tag {
815 "diff" => SetExp::Diff,
816 _ => unreachable!(),
817 }(Box::new(e1), Box::new(e2)),
818 ))
819 }
820
821 fn call_arg3(input: &str) -> IResult<&str, Self> {
824 let (input, tag) = alt((tag("union"), tag("inter"), tag("sdiff"))).parse(input)?;
825 let (input, _) = char('(')(input)?;
826 let (input, es) = separated_list1(char(','), Self::parse).parse(input)?;
827 let (input, _) = char(')')(input)?;
828 Ok((
829 input,
830 match tag {
831 "union" => SetExp::Union,
832 "inter" => SetExp::Inter,
833 "sdiff" => SetExp::SDiff,
834 _ => unreachable!(),
835 }(es),
836 ))
837 }
838
839 pub(crate) fn parse(input: &str) -> IResult<&str, Self> {
841 alt((
842 map(
843 separated_pair(IntExp::parse, tag(".."), IntExp::parse),
844 |(from, to)| SetExp::Range((from, to)),
845 ),
846 Self::call_arg1,
847 Self::call_arg2,
848 Self::call_arg3,
849 map(
850 delimited(
851 pair(tag("set"), char('(')),
852 separated_list0(char(','), IntExp::parse),
853 char(')'),
854 ),
855 SetExp::Set,
856 ),
857 map(VarRef::parse, SetExp::Var),
858 ))
859 .parse(input)
860 }
861}
862
863impl<Identifier: Display> Display for SetExp<Identifier> {
864 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
865 match self {
866 SetExp::Var(id) => write!(f, "{}", id),
867 SetExp::Set(es) => write!(
868 f,
869 "{{{}}}",
870 es.iter()
871 .map(|e| e.to_string())
872 .collect::<Vec<_>>()
873 .join(",")
874 ),
875 SetExp::Range((from, to)) => write!(f, "{}..{}", from, to),
876 SetExp::Hull(e) => write!(f, "hull({})", e),
877 SetExp::Diff(e1, e2) => write!(f, "diff({}, {})", e1, e2),
878 SetExp::Union(es) => write!(
879 f,
880 "union({})",
881 es.iter()
882 .map(|e| e.to_string())
883 .collect::<Vec<_>>()
884 .join(",")
885 ),
886 SetExp::Inter(es) => write!(
887 f,
888 "inter({})",
889 es.iter()
890 .map(|e| e.to_string())
891 .collect::<Vec<_>>()
892 .join(",")
893 ),
894 SetExp::SDiff(es) => write!(
895 f,
896 "sdiff({})",
897 es.iter()
898 .map(|e| e.to_string())
899 .collect::<Vec<_>>()
900 .join(",")
901 ),
902 }
903 }
904}