1pub mod constraint;
56pub mod error;
57pub mod expression;
58
59use std::{
60 borrow::Cow,
61 collections::{HashMap, VecDeque},
62 fmt::{self, Display},
63 hash::Hash,
64 marker::PhantomData,
65 ops::RangeInclusive,
66};
67
68use itertools::Itertools;
69use nom::{
70 branch::alt,
71 bytes::streaming::tag,
72 character::complete::{char, digit1},
73 combinator::{all_consuming, map, map_res, opt, recognize},
74 multi::many0,
75 sequence::{delimited, pair, preceded},
76 IResult, Parser,
77};
78pub use rangelist::RangeList;
79use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
80
81use crate::{
82 constraint::{Constraint, MetaConstraint},
83 error::UnrollError,
84 expression::{identifier, int, range, sequence, whitespace_seperated, Exp, IntExp},
85};
86
87#[derive(Clone, Debug, PartialEq, Hash)]
89pub struct Array<Identifier = String, Var = VarRef<Identifier>> {
90 pub identifier: Identifier,
92 pub note: Option<String>,
94 pub size: Vec<usize>,
96 pub domains: Vec<(Vec<Var>, RangeList<IntVal>)>,
104}
105
106#[derive(Clone, Debug, Default, PartialEq, Hash, Deserialize, Serialize)]
108#[serde(rename_all = "camelCase")]
109pub enum CombinationType {
110 #[default]
116 Lexico,
117 Pareto,
122}
123
124#[derive(Default, Clone, Copy, PartialEq, Eq, Hash, Debug, Deserialize, Serialize)]
131#[serde(rename_all = "UPPERCASE")]
132pub enum FrameworkType {
133 #[default]
138 Csp,
139 Cop,
146 Wcsp,
151 Fcsp,
159 Qcsp,
164 QcspPlus,
169 Qcop,
174 QcopPlus,
179 Scsp,
181 Scop,
183 Qstr,
185 Tcsp,
191 Ncsp,
196 Ncop,
200 DisCsp,
202 DisWcsp,
204}
205
206#[derive(Clone, Debug, PartialEq, Hash, Eq)]
208pub enum Indexing {
209 Single(usize),
211 Range(usize, usize),
213 Full,
215}
216
217#[derive(Clone, PartialEq, Debug, Hash)]
219pub struct Instance<Identifier = String, Var = VarRef<Identifier>> {
220 pub ty: FrameworkType,
222 pub variables: Vec<Variable<Identifier>>,
224 pub arrays: Vec<Array<Identifier, Var>>,
226 pub constraints: Vec<MetaConstraint<Identifier, Var>>,
228 pub objectives: Objectives<Identifier, Var>,
230}
231
232#[derive(Clone, Debug, PartialEq, Hash, Deserialize)]
237#[serde(bound(deserialize = "Identifier: From<String>, Var: IntoVar"))]
238pub struct Instantiation<Identifier = String, Var = VarRef<Identifier>> {
239 #[serde(flatten)]
241 pub info: MetaInfo<Identifier>,
242 #[serde(rename = "@type", default, skip_serializing_if = "Option::is_none")]
248 pub ty: Option<InstantiationType>,
249 #[serde(rename = "@cost", default, skip_serializing_if = "Option::is_none")]
256 pub cost: Option<IntVal>,
257 #[serde(
258 deserialize_with = "VarRef::parse_vec",
259 serialize_with = "serialize_list"
260 )]
261 pub list: Vec<Var>,
263 #[serde(
268 deserialize_with = "deserialize_opt_int_vals",
269 serialize_with = "serialize_opt_list"
270 )]
271 pub values: Vec<Option<IntVal>>,
272}
273
274#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
276#[serde(rename_all = "camelCase")]
277pub enum InstantiationType {
278 Solution,
280 Optimum,
283}
284
285pub trait IntoVar {
287 fn into_var(var: VarRef) -> Self;
289}
290
291pub type IntVal = i64;
293
294#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
297#[serde(bound(
298 deserialize = "Identifier: From<String>",
299 serialize = "Identifier: Display"
300))]
301pub struct MetaInfo<Identifier> {
302 #[serde(
304 rename = "@id",
305 default,
306 skip_serializing_if = "Option::is_none",
307 deserialize_with = "deserialize_ident",
308 serialize_with = "serialize_ident"
309 )]
310 pub identifier: Option<Identifier>,
311 #[serde(rename = "@note", default, skip_serializing_if = "Option::is_none")]
313 pub note: Option<String>,
314}
315
316#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
318#[serde(
319 rename_all = "camelCase",
320 bound(
321 deserialize = "Identifier: From<String>, Var: IntoVar",
322 serialize = "Identifier: Display, Var: Display"
323 )
324)]
325pub enum Objective<Identifier = String, Var = VarRef<Identifier>> {
326 #[serde(rename = "minimize")]
329 Minimize(ObjExp<Identifier, Var>),
330 #[serde(rename = "maximize")]
333 Maximize(ObjExp<Identifier, Var>),
334}
335
336#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
338#[serde(bound(
339 deserialize = "Identifier: From<String>, Var: IntoVar",
340 serialize = "Identifier: Display, Var: Display"
341))]
342pub struct Objectives<Identifier = String, Var = VarRef<Identifier>> {
343 #[serde(default, rename = "@combination")]
345 pub combination: CombinationType,
346 #[serde(rename = "$value")]
348 pub objectives: Vec<Objective<Identifier, Var>>,
349}
350
351#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
353#[serde(bound(
354 deserialize = "Identifier: From<String>, Var: IntoVar",
355 serialize = "Identifier: Display, Var: Display"
356))]
357pub struct ObjExp<Identifier = String, Var = VarRef<Identifier>> {
358 #[serde(flatten)]
360 pub info: MetaInfo<Identifier>,
361 #[serde(alias = "@type", default)]
363 pub ty: ObjType,
364 #[serde(
366 alias = "$text",
367 deserialize_with = "IntExp::parse_vec",
368 serialize_with = "serialize_list"
369 )]
370 pub list: Vec<IntExp<Var>>,
371 #[serde(
373 default,
374 skip_serializing_if = "Vec::is_empty",
375 deserialize_with = "deserialize_int_vals",
376 serialize_with = "serialize_list"
377 )]
378 pub coeffs: Vec<IntVal>,
379}
380
381#[derive(Clone, Debug, Default, PartialEq, Hash, Deserialize, Serialize)]
383#[serde(rename_all = "camelCase")]
384pub enum ObjType {
385 #[default]
387 Sum,
388 Minimum,
390 Maximum,
392 NValues,
394 Lex,
396}
397
398#[derive(Clone, Debug, Eq, PartialEq, Hash)]
400pub enum Placeholder {
401 Position(usize),
403 Remainder,
406}
407
408#[derive(Clone, Debug, PartialEq, Hash, Eq)]
410pub enum SimpleRef<Identifier> {
411 Ident(Identifier),
413 ArrayAccess(Identifier, Vec<usize>),
415}
416
417#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
419#[serde(bound(
420 deserialize = "Identifier: From<String>",
421 serialize = "Identifier: Display"
422))]
423pub struct Variable<Identifier = String> {
424 #[serde(
426 rename = "@id",
427 deserialize_with = "from_string",
428 serialize_with = "as_str"
429 )]
430 pub identifier: Identifier,
431 #[serde(rename = "@note", default, skip_serializing_if = "Option::is_none")]
433 pub note: Option<String>,
434 #[serde(
436 rename = "$text",
437 deserialize_with = "deserialize_range_list",
438 serialize_with = "serialize_range_list"
439 )]
440 pub domain: RangeList<IntVal>,
441}
442
443#[derive(Clone, Debug, PartialEq, Hash, Eq)]
446pub enum VarRef<Identifier = String> {
447 Ident(Identifier),
449 ArrayAccess(Identifier, Vec<Indexing>),
451 Placeholder(Placeholder),
453}
454
455fn as_str<S: Serializer, I: Display>(value: &I, serializer: S) -> Result<S::Ok, S::Error> {
457 serializer.serialize_str(&value.to_string())
458}
459
460fn collect_range_list<I: IntoIterator<Item = RangeInclusive<IntVal>>>(
462 iter: I,
463) -> RangeList<IntVal> {
464 let mut r: Vec<_> = iter.into_iter().collect();
465 r.sort_by_key(|i| *i.start());
466 let mut it = r.into_iter();
467 let mut ranges = Vec::new();
468 let mut cur = it.next().unwrap();
469 for next in it {
470 if *cur.end() >= (next.start() - 1) {
471 cur = *cur.start()..=*next.end()
472 } else {
473 ranges.push(cur);
474 cur = next;
475 }
476 }
477 ranges.push(cur);
478 ranges.into_iter().collect()
479}
480
481fn deserialize_ident<'de, D: Deserializer<'de>, Identifier: From<String>>(
483 deserializer: D,
484) -> Result<Option<Identifier>, D::Error> {
485 struct V<X>(PhantomData<X>);
487 impl<X: From<String>> Visitor<'_> for V<X> {
488 type Value = Option<X>;
489
490 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
491 formatter.write_str("an identfier")
492 }
493
494 fn visit_str<E: serde::de::Error>(self, s: &str) -> Result<Self::Value, E> {
495 Ok(Some(s.trim().to_owned().into()))
496 }
497 }
498 let visitor = V::<Identifier>(PhantomData);
499 deserializer.deserialize_str(visitor)
500}
501
502fn deserialize_int_vals<'de, D: Deserializer<'de>>(
504 deserializer: D,
505) -> Result<Vec<IntVal>, D::Error> {
506 struct V;
508 impl Visitor<'_> for V {
509 type Value = Vec<IntVal>;
510
511 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
512 formatter.write_str("a list of integers")
513 }
514
515 fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
516 let v = v.trim();
517 let (_, vals) = all_consuming(whitespace_seperated(repeated(int)))
518 .parse(v)
519 .map_err(|_| E::custom(format!("invalid list of integers {v}")))?;
520 Ok(vals.into_iter().flatten().collect())
521 }
522 }
523 deserializer.deserialize_str(V)
524}
525
526fn deserialize_opt_int_vals<'de, D: Deserializer<'de>>(
529 deserializer: D,
530) -> Result<Vec<Option<IntVal>>, D::Error> {
531 struct V;
533 impl Visitor<'_> for V {
534 type Value = Vec<Option<IntVal>>;
535
536 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
537 formatter.write_str("a list of integers")
538 }
539
540 fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
541 let v = v.trim();
542 let (_, vals) = all_consuming(whitespace_seperated(repeated(alt((
543 map(char('*'), |_| None),
544 map(int, Some),
545 )))))
546 .parse(v)
547 .map_err(|_| E::custom(format!("invalid list of integers {v}")))?;
548 Ok(vals.into_iter().flatten().collect())
549 }
550 }
551 deserializer.deserialize_str(V)
552}
553
554fn repeated<'a, O: Clone>(
557 p: impl Parser<&'a str, Output = O, Error = nom::error::Error<&'a str>>,
558) -> impl Parser<&'a str, Output = Vec<O>> {
559 map(pair(p, opt(preceded(char('x'), idx_int))), |(v, n)| {
560 vec![v; n.unwrap_or(1)]
561 })
562}
563
564fn deserialize_range_list<'de, D: Deserializer<'de>>(
566 deserializer: D,
567) -> Result<RangeList<IntVal>, D::Error> {
568 struct V;
570 impl Visitor<'_> for V {
571 type Value = RangeList<IntVal>;
572
573 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
574 formatter.write_str("a list of ranges")
575 }
576
577 fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
578 let v = v.trim();
579 let (_, r) = all_consuming(whitespace_seperated(range))
580 .parse(v)
581 .map_err(|_| E::custom(format!("invalid list of ranges `{v}")))?;
582 Ok(collect_range_list(r))
583 }
584 }
585 let visitor = V;
586 deserializer.deserialize_str(visitor)
587}
588
589fn deserialize_size<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<usize>, D::Error> {
591 struct V;
593 impl Visitor<'_> for V {
594 type Value = Vec<usize>;
595
596 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
597 formatter.write_str("an array size expression")
598 }
599
600 fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
601 let v = v.trim();
602 let (_, r) = all_consuming(sequence(delimited(
603 char::<_, nom::error::Error<&str>>('['),
604 map_res(recognize(digit1), str::parse),
605 char(']'),
606 )))
607 .parse(v)
608 .map_err(|_| E::custom(format!("invalid array size expression `{v}'")))?;
609 Ok(r)
610 }
611 }
612 let visitor = V;
613 deserializer.deserialize_str(visitor)
614}
615
616fn from_string<'de, D: Deserializer<'de>, I: From<String>>(deserializer: D) -> Result<I, D::Error> {
618 let s: Cow<'_, str> = Deserialize::deserialize(deserializer)?;
619 Ok(s.trim().to_owned().into())
620}
621
622fn idx_int(input: &str) -> IResult<&str, usize> {
624 let (input, i): (_, usize) = map_res(recognize(digit1), str::parse).parse(input)?;
625 Ok((input, i))
626}
627
628fn idx_range(input: &str) -> IResult<&str, RangeInclusive<usize>> {
630 let (input, lb) = idx_int(input)?;
631 if let (input, Some(_)) = opt(tag("..")).parse(input)? {
632 let (input, ub) = idx_int(input)?;
633 Ok((input, lb..=ub))
634 } else {
635 Ok((input, lb..=lb))
636 }
637}
638
639fn serialize_list<S: Serializer, T: Display>(exps: &[T], serializer: S) -> Result<S::Ok, S::Error> {
642 serializer.serialize_str(
643 &exps
644 .iter()
645 .map(|e| format!("{}", e))
646 .collect::<Vec<_>>()
647 .join(" "),
648 )
649}
650
651fn serialize_opt_list<S: Serializer, T: Display>(
653 exps: &[Option<T>],
654 serializer: S,
655) -> Result<S::Ok, S::Error> {
656 serializer.serialize_str(
657 &exps
658 .iter()
659 .map(|e| match e {
660 Some(e) => e.to_string(),
661 None => "*".to_owned(),
662 })
663 .collect::<Vec<_>>()
664 .join(" "),
665 )
666}
667
668fn serialize_ident<S: Serializer, Identifier: Display>(
670 identifier: &Option<Identifier>,
671 serializer: S,
672) -> Result<S::Ok, S::Error> {
673 serializer.serialize_str(&format!("{}", identifier.as_ref().unwrap()))
674}
675
676fn serialize_range_list<S: Serializer>(
678 exps: &RangeList<IntVal>,
679 serializer: S,
680) -> Result<S::Ok, S::Error> {
681 serializer.serialize_str(
682 &exps
683 .into_iter()
684 .map(|e| {
685 if e.start() == e.end() {
686 e.start().to_string()
687 } else {
688 format!("{}..{}", e.start(), e.end())
689 }
690 })
691 .collect::<Vec<_>>()
692 .join(" "),
693 )
694}
695
696fn serialize_size<S: Serializer>(exps: &[usize], serializer: S) -> Result<S::Ok, S::Error> {
698 serializer.serialize_str(
699 &exps
700 .iter()
701 .map(|e| format!("[{}]", e))
702 .collect::<Vec<_>>()
703 .join(""),
704 )
705}
706
707impl<Identifier: Clone + Hash + Eq + ToString> Array<Identifier, VarRef<Identifier>> {
708 pub fn unroll(&self) -> Result<Array<Identifier, SimpleRef<Identifier>>, UnrollError> {
711 let size_wrap: HashMap<_, _> = Some((self.identifier.clone(), &self.size[..]))
712 .into_iter()
713 .collect();
714 let mut domains = Vec::with_capacity(self.domains.len());
715 for (v, d) in &self.domains {
716 let mut res: Vec<SimpleRef<_>> = Vec::new();
717 for x in v {
718 res.extend(
719 x.unroll(&size_wrap, &[], &[])?
720 .into_iter()
721 .map(|x| match x {
722 Exp::Var(v) => v,
723 _ => unreachable!(),
724 }),
725 );
726 }
727 domains.push((res, d.clone()));
728 }
729 Ok(Array {
730 identifier: self.identifier.clone(),
731 note: self.note.clone(),
732 size: self.size.clone(),
733 domains,
734 })
735 }
736}
737
738impl<'de, Identifier: From<String>, Var: IntoVar> Deserialize<'de> for Array<Identifier, Var> {
739 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
740 #[derive(Deserialize)]
742 #[serde(bound = "Var: IntoVar")]
743 struct DomainStruct<Var> {
744 #[serde(rename = "@for", deserialize_with = "VarRef::parse_vec")]
746 vars: Vec<Var>,
747 #[serde(rename = "$text", deserialize_with = "deserialize_range_list")]
749 domain: RangeList<IntVal>,
750 }
751 #[derive(Deserialize)]
753 #[serde(bound = " Var: IntoVar")]
754 enum Domain<'a, Var> {
755 #[serde(rename = "domain")]
757 Domain(Vec<DomainStruct<Var>>),
758 #[serde(rename = "$text")]
760 Direct(Cow<'a, str>),
761 }
762 #[derive(Deserialize)]
764 #[serde(bound = "Identifier: From<String>, Var: IntoVar")]
765 struct Array<'a, Identifier, Var> {
766 #[serde(rename = "@id", deserialize_with = "from_string")]
768 identifier: Identifier,
769 #[serde(rename = "@note", default, skip_serializing_if = "Option::is_none")]
771 note: Option<String>,
772 #[serde(rename = "@size", deserialize_with = "deserialize_size")]
774 size: Vec<usize>,
775 #[serde(rename = "$value")]
777 domain: Domain<'a, Var>,
778 }
779 let x = Array::deserialize(deserializer)?;
780 let domains = match x.domain {
781 Domain::Domain(v) => v.into_iter().map(|d| (d.vars, d.domain)).collect(),
782 Domain::Direct(s) => {
783 let s = s.trim();
784 let s = all_consuming(whitespace_seperated(range))
785 .parse(s.as_ref())
786 .map_err(|_| {
787 serde::de::Error::custom(format!("unable to parse ranges from `{s}'"))
788 })?;
789 vec![(
790 vec![Var::into_var(VarRef::Ident("others".to_owned()))],
791 collect_range_list(s.1),
792 )]
793 }
794 };
795 Ok(Self {
796 identifier: x.identifier,
797 note: x.note,
798 size: x.size,
799 domains,
800 })
801 }
802}
803
804impl<Identifier: Display> Serialize for Array<Identifier> {
805 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
806 #[derive(Serialize)]
808 #[serde(bound = "Identifier: Display")]
809 struct DomainStruct<'a, Identifier: Display> {
810 #[serde(rename = "@for", serialize_with = "serialize_list")]
812 vars: &'a Vec<VarRef<Identifier>>,
813 #[serde(rename = "$text", serialize_with = "serialize_range_list")]
815 domain: &'a RangeList<IntVal>,
816 }
817 #[derive(Serialize)]
819 #[serde(bound = "Identifier: Display")]
820 enum Domain<'a, Identifier: Display> {
821 #[serde(rename = "domain")]
823 Domain(DomainStruct<'a, Identifier>),
824 }
825 #[derive(Serialize)]
826 #[serde(bound = "Identifier: Display")]
827 struct Array<'a, Identifier: Display> {
828 #[serde(rename = "@id", serialize_with = "as_str")]
830 identifier: &'a Identifier,
831 #[serde(rename = "@note", default, skip_serializing_if = "Option::is_none")]
833 note: &'a Option<String>,
834 #[serde(rename = "@size", serialize_with = "serialize_size")]
836 size: &'a Vec<usize>,
837 #[serde(rename = "$value")]
839 domain: Vec<Domain<'a, Identifier>>,
840 }
841 let domain = self
842 .domains
843 .iter()
844 .map(|(v, d)| Domain::Domain(DomainStruct { vars: v, domain: d }))
845 .collect();
846 let x = Array {
847 identifier: &self.identifier,
848 note: &self.note,
849 size: &self.size,
850 domain,
851 };
852 x.serialize(serializer)
853 }
854}
855
856impl<Identifier: Clone + Eq + Hash + ToString> Instance<Identifier, VarRef<Identifier>> {
857 pub fn unroll_constraints(
862 &self,
863 ) -> Result<Vec<Constraint<Identifier, SimpleRef<Identifier>>>, UnrollError> {
864 let arrays: HashMap<Identifier, &[usize]> = self
865 .arrays
866 .iter()
867 .map(|arr| (arr.identifier.clone(), &arr.size[..]))
868 .collect();
869
870 let mut flat = Vec::new();
871 let mut metas = VecDeque::new();
872 metas.push_back(&self.constraints);
873 while let Some(cons) = metas.pop_front() {
874 for con in cons {
875 match con {
876 MetaConstraint::Group(group) => flat.extend(group.unroll(&arrays)?),
877 MetaConstraint::Slide(slide) => flat.extend(slide.unroll(&arrays)?),
878 MetaConstraint::Block(block) => metas.push_back(&block.constraints),
879 MetaConstraint::Constraint(c) => flat.push(c.unroll(&arrays, &[], &[])?),
880 }
881 }
882 }
883 Ok(flat)
884 }
885}
886
887impl<Identifier> Default for Instance<Identifier> {
888 fn default() -> Self {
889 Self {
890 ty: Default::default(),
891 variables: Default::default(),
892 arrays: Default::default(),
893 constraints: Default::default(),
894 objectives: Default::default(),
895 }
896 }
897}
898
899impl<'de, Identifier: From<String>, Var: IntoVar> Deserialize<'de> for Instance<Identifier, Var> {
900 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
901 #[derive(Deserialize)]
903 #[serde(bound(deserialize = "Identifier: From<String>, Var: IntoVar"))]
904 enum V<Identifier, Var> {
905 #[serde(rename = "var")]
907 Variable(Variable<Identifier>),
908 #[serde(rename = "array")]
910 Array(Array<Identifier, Var>),
911 }
912 #[derive(Deserialize)]
914 #[serde(bound(deserialize = "Identifier: From<String>, Var: IntoVar"))]
915 struct Variables<Identifier, Var> {
916 #[serde(rename = "$value")]
918 vars: Vec<V<Identifier, Var>>,
919 }
920 #[derive(Deserialize)]
922 #[serde(bound(deserialize = "Identifier: From<String>, Var: IntoVar"))]
923 struct Constraints<Identifier, Var> {
924 #[serde(rename = "$value")]
926 content: Vec<MetaConstraint<Identifier, Var>>,
927 }
928 #[derive(Deserialize)]
930 #[serde(bound(deserialize = "Identifier: From<String>, Var: IntoVar"))]
931 struct Instance<Identifier, Var> {
932 #[serde(rename = "@type")]
934 ty: FrameworkType,
935 variables: Option<Variables<Identifier, Var>>,
937 constraints: Option<Constraints<Identifier, Var>>,
939 #[serde(default = "Objectives::default")]
941 objectives: Objectives<Identifier, Var>,
942 }
943 let inst: Instance<Identifier, Var> = Deserialize::deserialize(deserializer)?;
944 let mut variables = Vec::new();
945 let mut arrays = Vec::new();
946 for v in inst.variables.map(|v| v.vars).into_iter().flatten() {
947 match v {
948 V::Variable(var) => variables.push(var),
949 V::Array(arr) => arrays.push(arr),
950 }
951 }
952 Ok(Self {
953 ty: inst.ty,
954 variables,
955 arrays,
956 constraints: inst.constraints.map_or_else(Vec::new, |c| c.content),
957 objectives: inst.objectives,
958 })
959 }
960}
961
962impl<Identifier: Serialize + Display> Serialize for Instance<Identifier> {
963 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
964 #[derive(Serialize)]
966 struct Variables<'a, Identifier: Display> {
967 var: &'a Vec<Variable<Identifier>>,
969 array: &'a Vec<Array<Identifier>>,
971 }
972 impl<Identifier: Display> Variables<'_, Identifier> {
973 fn is_empty(&self) -> bool {
975 self.var.is_empty() && self.array.is_empty()
976 }
977 }
978 #[derive(Serialize)]
980 struct Constraints<'a, Identifier: Display> {
981 #[serde(rename = "$value")]
983 content: &'a Vec<MetaConstraint<Identifier>>,
984 }
985 impl<Identifier: Display> Constraints<'_, Identifier> {
986 fn is_empty(&self) -> bool {
988 self.content.is_empty()
989 }
990 }
991 #[derive(Serialize)]
993 #[serde(rename = "instance")]
994 struct Instance<'a, Identifier: Display> {
995 #[serde(rename = "@type")]
997 ty: FrameworkType,
998 #[serde(skip_serializing_if = "Variables::is_empty")]
1000 variables: Variables<'a, Identifier>,
1001 #[serde(skip_serializing_if = "Constraints::is_empty")]
1003 constraints: Constraints<'a, Identifier>,
1004 #[serde(skip_serializing_if = "Objectives::is_empty")]
1006 objectives: &'a Objectives<Identifier>,
1007 }
1008 let x = Instance {
1009 ty: self.ty,
1010 variables: Variables {
1011 var: &self.variables,
1012 array: &self.arrays,
1013 },
1014 constraints: Constraints {
1015 content: &self.constraints,
1016 },
1017 objectives: &self.objectives,
1018 };
1019 Serialize::serialize(&x, serializer)
1020 }
1021}
1022
1023impl<Identifier: Display, Var: Display> Serialize for Instantiation<Identifier, Var> {
1026 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1027 #[derive(Serialize)]
1029 #[serde(
1030 rename = "instantiation",
1031 bound(serialize = "Identifier: Display, Var: Display")
1032 )]
1033 struct Instantiation<'a, Identifier, Var> {
1034 #[serde(
1036 rename = "@id",
1037 skip_serializing_if = "Option::is_none",
1038 serialize_with = "serialize_ident"
1039 )]
1040 identifier: &'a Option<Identifier>,
1041 #[serde(rename = "@note", skip_serializing_if = "Option::is_none")]
1043 note: &'a Option<String>,
1044 #[serde(rename = "@type", skip_serializing_if = "Option::is_none")]
1046 ty: &'a Option<InstantiationType>,
1047 #[serde(rename = "@cost", skip_serializing_if = "Option::is_none")]
1049 cost: &'a Option<IntVal>,
1050 #[serde(serialize_with = "serialize_list")]
1052 list: &'a Vec<Var>,
1053 #[serde(serialize_with = "serialize_opt_list")]
1055 values: &'a Vec<Option<IntVal>>,
1056 }
1057 Instantiation {
1058 identifier: &self.info.identifier,
1059 note: &self.info.note,
1060 ty: &self.ty,
1061 cost: &self.cost,
1062 list: &self.list,
1063 values: &self.values,
1064 }
1065 .serialize(serializer)
1066 }
1067}
1068
1069impl<Identifier> Objectives<Identifier> {
1070 pub fn is_empty(&self) -> bool {
1072 self.objectives.is_empty()
1073 }
1074}
1075
1076impl<Identifier: Clone + Hash + Eq + ToString> ObjExp<Identifier, VarRef<Identifier>> {
1077 pub fn unroll(
1080 &self,
1081 instance: &Instance<Identifier, VarRef<Identifier>>,
1082 ) -> Result<ObjExp<Identifier, SimpleRef<Identifier>>, UnrollError> {
1083 let arrays: HashMap<Identifier, &[usize]> = instance
1084 .arrays
1085 .iter()
1086 .map(|arr| (arr.identifier.clone(), &arr.size[..]))
1087 .collect();
1088
1089 let list = self
1090 .list
1091 .iter()
1092 .map(|v| v.unroll(&arrays, &[], &[]))
1093 .collect::<Result<Vec<_>, _>>()?
1094 .into_iter()
1095 .flatten()
1096 .collect();
1097
1098 Ok(ObjExp {
1099 info: self.info.clone(),
1100 ty: self.ty.clone(),
1101 list,
1102 coeffs: self.coeffs.clone(),
1103 })
1104 }
1105}
1106
1107impl<Identifier, Var> Default for Objectives<Identifier, Var> {
1108 fn default() -> Self {
1109 Self {
1110 combination: CombinationType::default(),
1111 objectives: Vec::new(),
1112 }
1113 }
1114}
1115
1116impl Display for Placeholder {
1117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1118 match self {
1119 Placeholder::Position(i) => write!(f, "%{}", i),
1120 Placeholder::Remainder => write!(f, "%..."),
1121 }
1122 }
1123}
1124
1125impl<Identifier: Clone + Hash + Eq + ToString> VarRef<Identifier> {
1126 pub(crate) fn unroll(
1133 &self,
1134 arrays: &HashMap<Identifier, &[usize]>,
1135 args: &[Vec<Exp<SimpleRef<Identifier>>>],
1136 remainder: &[Exp<SimpleRef<Identifier>>],
1137 ) -> Result<Vec<Exp<SimpleRef<Identifier>>>, UnrollError> {
1138 match self {
1139 &VarRef::Placeholder(Placeholder::Position(i)) if i < args.len() => Ok(args[i].clone()),
1140 &VarRef::Placeholder(Placeholder::Position(i)) => Err(UnrollError::ArgMissing {
1141 placeholder: i,
1142 args_len: args.len(),
1143 }),
1144 VarRef::Placeholder(Placeholder::Remainder) => Ok(remainder.to_vec()),
1145 VarRef::Ident(ident) => Ok(vec![Exp::Var(SimpleRef::Ident(ident.clone()))]),
1146 VarRef::ArrayAccess(ident, indexings) => {
1147 let Some(size) = arrays.get(ident) else {
1148 return Err(UnrollError::UnknownIdentifier(ident.to_string()));
1149 };
1150 if indexings.len() != size.len() {
1151 return Err(UnrollError::UnexpectedIndexes {
1152 expected_len: size.len(),
1153 args_len: indexings.len(),
1154 });
1155 }
1156 Ok(indexings
1157 .iter()
1158 .enumerate()
1159 .map(|(i, idx)| match idx {
1160 &Indexing::Single(i) => i..=i,
1161 &Indexing::Range(start, end) => start..=end,
1162 Indexing::Full => 0..=(size[i] - 1),
1163 })
1164 .multi_cartesian_product()
1165 .map(|idxs| Exp::Var(SimpleRef::ArrayAccess(ident.clone(), idxs)))
1166 .collect())
1167 }
1168 }
1169 }
1170
1171 pub(crate) fn unroll_matrix(
1177 &self,
1178 arrays: &HashMap<Identifier, &[usize]>,
1179 args: &[Vec<Exp<SimpleRef<Identifier>>>],
1180 remainder: &[Exp<SimpleRef<Identifier>>],
1181 ) -> Result<Vec<Vec<Exp<SimpleRef<Identifier>>>>, UnrollError> {
1182 let VarRef::ArrayAccess(ident, indexings) = self else {
1183 return Err(UnrollError::UnexpectedIndexes {
1184 expected_len: 2,
1185 args_len: 0,
1186 });
1187 };
1188 let Some(size) = arrays.get(ident) else {
1189 return Err(UnrollError::UnknownIdentifier(ident.to_string()));
1190 };
1191 let flat = self.unroll(arrays, args, remainder)?;
1192 let row_len = match indexings.last() {
1193 Some(&Indexing::Single(_)) => 1,
1194 Some(&Indexing::Range(start, end)) => end - start + 1,
1195 Some(Indexing::Full) => size[indexings.len() - 1],
1198 None => {
1199 return Err(UnrollError::UnexpectedIndexes {
1200 expected_len: 2,
1201 args_len: 0,
1202 })
1203 }
1204 };
1205 Ok(flat.chunks(row_len).map(<[_]>::to_vec).collect())
1206 }
1207
1208 pub(crate) fn unroll_single(
1211 &self,
1212 arrays: &HashMap<Identifier, &[usize]>,
1213 args: &[Vec<Exp<SimpleRef<Identifier>>>],
1214 remainder: &[Exp<SimpleRef<Identifier>>],
1215 ) -> Result<Exp<SimpleRef<Identifier>>, UnrollError> {
1216 let res = self.unroll(arrays, args, remainder)?;
1217 match &res[..] {
1218 [exp] => Ok(exp.clone()),
1219 _ => Err(UnrollError::UnexpectedLength {
1220 expected_len: 1,
1221 args_len: res.len(),
1222 }),
1223 }
1224 }
1225}
1226
1227impl VarRef {
1228 fn parse_vec<'de, D: Deserializer<'de>, R: IntoVar>(
1230 deserializer: D,
1231 ) -> Result<Vec<R>, D::Error> {
1232 struct V<X>(PhantomData<X>);
1234 impl<X: From<String>> Visitor<'_> for V<X> {
1235 type Value = Vec<VarRef<X>>;
1236
1237 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1238 formatter.write_str("a list of variable references")
1239 }
1240
1241 fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
1242 let v = v.trim();
1243 let (_, v) = all_consuming(whitespace_seperated(VarRef::parse))
1244 .parse(v)
1245 .map_err(|_| E::custom(format!("invalid variable references `{v}'")))?;
1246 Ok(v)
1247 }
1248 }
1249 let visitor = V::<String>(PhantomData);
1250 Ok(deserializer
1251 .deserialize_str(visitor)?
1252 .into_iter()
1253 .map(R::into_var)
1254 .collect())
1255 }
1256}
1257
1258impl<Identifier: From<String>> VarRef<Identifier> {
1259 pub(crate) fn parse(input: &str) -> IResult<&str, Self> {
1261 let placeholder: IResult<&str, Placeholder> = preceded(
1263 char('%'),
1264 alt((
1265 map(digit1, |p: &str| Placeholder::Position(p.parse().unwrap())),
1266 map(tag("..."), |_| Placeholder::Remainder),
1267 )),
1268 )
1269 .parse(input);
1270 if let Ok((input, placeholder)) = placeholder {
1271 return Ok((input, Self::Placeholder(placeholder)));
1272 }
1273 let (input, ident) = identifier(input)?;
1275 let (input, v) = many0(delimited(char('['), opt(idx_range), char(']'))).parse(input)?;
1277 Ok((
1279 input,
1280 if v.is_empty() {
1281 VarRef::Ident(ident)
1282 } else {
1283 let v = v
1284 .into_iter()
1285 .map(|r| {
1286 r.map(|r| {
1287 if r.start() == r.end() {
1288 Indexing::Single(*r.start())
1289 } else {
1290 Indexing::Range(*r.start(), *r.end())
1291 }
1292 })
1293 .unwrap_or(Indexing::Full)
1294 })
1295 .collect();
1296 VarRef::ArrayAccess(ident, v)
1297 },
1298 ))
1299 }
1300}
1301
1302impl<Identifier: Display> Display for VarRef<Identifier> {
1303 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1304 match self {
1305 VarRef::Ident(ident) => ident.fmt(f),
1306 VarRef::ArrayAccess(ident, v) => {
1307 write!(
1308 f,
1309 "{}{}",
1310 ident,
1311 v.iter()
1312 .map(|i| format!(
1313 "[{}]",
1314 match i {
1315 Indexing::Single(v) => v.to_string(),
1316 Indexing::Range(a, b) => format!("{}..{}", a, b),
1317 Indexing::Full => String::new(),
1318 }
1319 ))
1320 .collect::<Vec<_>>()
1321 .join("")
1322 )
1323 }
1324 VarRef::Placeholder(placeholder) => placeholder.fmt(f),
1325 }
1326 }
1327}
1328
1329impl<I: From<String>> IntoVar for VarRef<I> {
1330 fn into_var(var: VarRef) -> Self {
1331 match var {
1332 VarRef::Ident(s) => VarRef::Ident(I::from(s)),
1333 VarRef::ArrayAccess(s, idxs) => VarRef::ArrayAccess(I::from(s), idxs),
1334 VarRef::Placeholder(p) => VarRef::Placeholder(p),
1335 }
1336 }
1337}
1338
1339#[cfg(test)]
1340mod tests {
1341 use std::{fmt::Debug, fs::File, io::BufReader, path::Path};
1342
1343 use expect_test::ExpectFile;
1344 use serde::{de::DeserializeOwned, Serialize};
1345
1346 use crate::{Instance, Instantiation};
1347
1348 fn test_successful_serialization<T: Debug + DeserializeOwned + Serialize + PartialEq>(
1349 file: &Path,
1350 exp: ExpectFile,
1351 ) {
1352 let rdr = BufReader::new(File::open(file).unwrap());
1353 let inst: T = quick_xml::de::from_reader(rdr).unwrap();
1354 exp.assert_debug_eq(&inst);
1355 let output = quick_xml::se::to_string(&inst).unwrap();
1356 let inst2: T = quick_xml::de::from_str(&output).unwrap();
1357 assert_eq!(inst, inst2)
1358 }
1359
1360 fn test_successful_unroll(file: &Path, exp: ExpectFile, unrolled: ExpectFile) {
1363 test_successful_serialization::<Instance>(file, exp);
1364 let rdr = BufReader::new(File::open(file).unwrap());
1365 let inst: Instance = quick_xml::de::from_reader(rdr).unwrap();
1366 unrolled.assert_debug_eq(&inst.unroll_constraints().unwrap());
1367 }
1368
1369 macro_rules! test_file {
1370 ($file:ident) => {
1371 test_file!($file, Instance);
1372 };
1373 ($file:ident, $t:ident) => {
1374 #[test]
1375 fn $file() {
1376 test_successful_serialization::<$t>(
1377 std::path::Path::new(&format!("./corpus/{}.xml", stringify!($file))),
1378 expect_test::expect_file![&format!(
1379 "../corpus/{}.debug.txt",
1380 stringify!($file)
1381 )],
1382 )
1383 }
1384 };
1385 }
1386
1387 macro_rules! test_unroll {
1388 ($file:ident) => {
1389 #[test]
1390 fn $file() {
1391 test_successful_unroll(
1392 std::path::Path::new(&format!("./corpus/{}.xml", stringify!($file))),
1393 expect_test::expect_file![&format!(
1394 "../corpus/{}.debug.txt",
1395 stringify!($file)
1396 )],
1397 expect_test::expect_file![&format!(
1398 "../corpus/{}.unroll.txt",
1399 stringify!($file)
1400 )],
1401 )
1402 }
1403 };
1404 }
1405
1406 test_file!(knapsack);
1407 test_unroll!(group_list_arg);
1410
1411 test_file!(xcsp3_ex_001);
1412 test_file!(xcsp3_ex_002);
1413 test_file!(xcsp3_ex_003);
1414 test_file!(xcsp3_ex_004);
1415 test_file!(xcsp3_ex_005);
1416 test_file!(xcsp3_ex_006);
1417 test_file!(xcsp3_ex_007);
1418 test_file!(xcsp3_ex_018);
1429 test_file!(xcsp3_ex_019);
1430 test_file!(xcsp3_ex_021);
1432 test_file!(xcsp3_ex_022);
1433 test_file!(xcsp3_ex_023, Instantiation);
1434 test_file!(xcsp3_ex_024);
1435 test_file!(xcsp3_ex_025, Instantiation);
1436 test_file!(xcsp3_ex_026, Instantiation);
1437 test_file!(xcsp3_ex_027, Instantiation);
1438 test_file!(xcsp3_ex_028, Instantiation);
1439 test_file!(xcsp3_ex_029);
1440 test_file!(xcsp3_ex_030);
1441 test_file!(xcsp3_ex_031);
1442 test_file!(xcsp3_ex_032);
1443 test_file!(xcsp3_ex_033);
1444 test_file!(xcsp3_ex_034);
1445 test_file!(xcsp3_ex_035);
1446 test_file!(xcsp3_ex_036);
1447 test_file!(xcsp3_ex_037);
1448 test_file!(xcsp3_ex_038);
1449 test_file!(xcsp3_ex_039);
1450 test_file!(xcsp3_ex_041);
1452 test_file!(xcsp3_ex_043);
1454 test_file!(xcsp3_ex_044);
1455 test_file!(xcsp3_ex_045);
1456 test_file!(xcsp3_ex_046);
1457 test_file!(xcsp3_ex_047);
1458 test_file!(xcsp3_ex_049);
1460 test_file!(xcsp3_ex_051);
1462 test_file!(xcsp3_ex_052);
1463 test_file!(xcsp3_ex_053);
1464 test_file!(xcsp3_ex_054);
1465 test_file!(xcsp3_ex_055);
1466 test_file!(xcsp3_ex_056);
1467 test_file!(xcsp3_ex_057);
1468 test_file!(xcsp3_ex_058);
1469 test_file!(xcsp3_ex_059);
1470 test_file!(xcsp3_ex_060);
1471 test_file!(xcsp3_ex_063);
1474 test_file!(xcsp3_ex_064);
1475 test_file!(xcsp3_ex_065);
1476 test_file!(xcsp3_ex_066);
1477 test_file!(xcsp3_ex_067);
1478 test_file!(xcsp3_ex_068);
1479 test_file!(xcsp3_ex_069);
1480 test_file!(xcsp3_ex_072);
1483 test_unroll!(xcsp3_ex_073);
1484 test_file!(xcsp3_ex_074);
1485 test_file!(xcsp3_ex_075);
1486 test_file!(xcsp3_ex_076);
1487 test_file!(xcsp3_ex_077);
1488 test_file!(xcsp3_ex_078);
1489 test_unroll!(xcsp3_ex_084);
1495 test_file!(xcsp3_ex_085);
1496 test_file!(xcsp3_ex_086);
1497 test_file!(xcsp3_ex_089);
1500 test_file!(xcsp3_ex_091);
1502 test_file!(xcsp3_ex_097);
1508 test_file!(xcsp3_ex_100);
1511 test_file!(xcsp3_ex_101);
1512 test_unroll!(xcsp3_ex_113);
1524 test_unroll!(xcsp3_ex_115);
1526 test_unroll!(xcsp3_ex_116);
1527 test_unroll!(xcsp3_ex_117);
1528 test_unroll!(xcsp3_ex_118);
1529 test_unroll!(xcsp3_ex_127);
1538 test_unroll!(xcsp3_ex_128);
1539 test_unroll!(xcsp3_ex_130);
1541 test_unroll!(xcsp3_ex_131);
1542 test_unroll!(xcsp3_ex_152);
1563 test_unroll!(xcsp3_ex_153);
1564 test_unroll!(xcsp3_ex_154);
1565 test_unroll!(xcsp3_ex_155);
1566 test_unroll!(xcsp3_ex_156);
1567 test_unroll!(xcsp3_ex_157);
1568 test_unroll!(xcsp3_ex_158);
1569 test_unroll!(xcsp3_ex_161);
1572 test_unroll!(xcsp3_ex_166);
1577 test_file!(xcsp3_ex_167);
1578 }