1mod error;
123#[cfg(feature = "fzn")]
124mod fzn;
125pub mod helpers;
126#[cfg(any(feature = "fzn", feature = "serde"))]
127mod intermediate;
128#[cfg(feature = "serde")]
129mod serde_impl;
130
131use std::{
132 cmp::Ordering,
133 collections::HashSet,
134 fmt::{Debug, Display},
135 hash::{Hash, Hasher},
136 sync::{Arc, Weak},
137};
138
139pub use rangelist::RangeList;
140#[cfg(feature = "serde")]
141use serde::{Deserializer, Serialize};
142
143pub use crate::error::{FznParseError, LinkError};
144use crate::helpers::ArcKey;
145
146#[cfg_attr(feature = "serde", derive(Serialize))]
156#[cfg_attr(feature = "serde", serde(untagged))]
157#[derive(Clone, PartialEq, Debug)]
158pub enum Annotation<Identifier = String> {
159 Atom(Identifier),
161 Call(AnnotationCall<Identifier>),
163}
164
165#[cfg_attr(feature = "serde", derive(Serialize))]
167#[cfg_attr(feature = "serde", serde(untagged))]
168#[derive(Clone, Debug)]
169pub enum AnnotationArgument<Identifier = String> {
170 Array(Vec<AnnotationLiteral<Identifier>>),
172 #[cfg_attr(
173 feature = "serde",
174 serde(serialize_with = "serde_impl::serialize_array_weak")
175 )]
176 ArrayNamed(Weak<Array<Identifier>>),
178 Literal(AnnotationLiteral<Identifier>),
180}
181
182#[cfg_attr(feature = "serde", derive(Serialize))]
184#[cfg_attr(feature = "serde", serde(rename = "annotation_call"))]
185#[derive(Clone, PartialEq, Debug)]
186pub struct AnnotationCall<Identifier = String> {
187 pub id: Identifier,
189 pub args: Vec<AnnotationArgument<Identifier>>,
191}
192
193#[cfg_attr(feature = "serde", derive(Serialize))]
195#[cfg_attr(feature = "serde", serde(untagged))]
196#[derive(Clone, Debug)]
197pub enum AnnotationLiteral<Identifier = String> {
198 Int(i64),
200 Float(f64),
202 #[cfg_attr(
204 feature = "serde",
205 serde(serialize_with = "serde_impl::serialize_variable_weak")
206 )]
207 Variable(Weak<Variable<Identifier>>),
208 Bool(bool),
210 #[cfg_attr(
212 feature = "serde",
213 serde(serialize_with = "serde_impl::serialize_encapsulate_set")
214 )]
215 IntSet(RangeList<i64>),
216 #[cfg_attr(
219 feature = "serde",
220 serde(serialize_with = "serde_impl::serialize_encapsulate_set")
221 )]
222 FloatSet(RangeList<f64>),
223 #[cfg_attr(
225 feature = "serde",
226 serde(serialize_with = "serde_impl::serialize_encapsulate_string")
227 )]
228 String(String),
229 Annotation(Annotation<Identifier>),
231}
232
233#[cfg_attr(feature = "serde", derive(Serialize))]
235#[cfg_attr(feature = "serde", serde(untagged))]
236#[derive(Clone, PartialEq, Debug)]
237pub enum Argument<Identifier = String> {
238 Array(Vec<Literal<Identifier>>),
240 #[cfg_attr(
242 feature = "serde",
243 serde(serialize_with = "serde_impl::serialize_array_arc",)
244 )]
245 ArrayNamed(Arc<Array<Identifier>>),
246 Literal(Literal<Identifier>),
248}
249
250#[cfg_attr(feature = "serde", derive(Serialize))]
258#[cfg_attr(feature = "serde", serde(rename = "array"))]
259#[derive(Clone, PartialEq, Debug)]
260pub struct Array<Identifier = String> {
261 #[cfg_attr(feature = "serde", serde(skip))]
265 pub name: String,
266 #[cfg_attr(feature = "serde", serde(rename = "a"))]
268 pub contents: Vec<Literal<Identifier>>,
269 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
271 pub ann: Vec<Annotation<Identifier>>,
272 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "serde_impl::is_false"))]
275 pub defined: bool,
276 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "serde_impl::is_false"))]
280 pub introduced: bool,
281}
282
283#[cfg_attr(feature = "serde", derive(Serialize))]
285#[cfg_attr(feature = "serde", serde(rename = "constraint"))]
286#[derive(Clone, PartialEq, Debug)]
287pub struct Constraint<Identifier = String> {
288 pub id: Identifier,
290 pub args: Vec<Argument<Identifier>>,
292 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
294 pub defines: Option<NamedRef<Identifier>>,
295 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
297 pub ann: Vec<Annotation<Identifier>>,
298}
299
300#[cfg_attr(feature = "serde", derive(Serialize))]
306#[derive(Clone, PartialEq, Debug)]
307pub struct FlatZinc<Identifier = String> {
308 #[cfg_attr(
309 feature = "serde",
310 serde(serialize_with = "serde_impl::serialize_variable_map")
311 )]
312 pub variables: Vec<Arc<Variable<Identifier>>>,
314 #[cfg_attr(
315 feature = "serde",
316 serde(serialize_with = "serde_impl::serialize_array_map")
317 )]
318 pub arrays: Vec<Arc<Array<Identifier>>>,
320 pub constraints: Vec<Constraint<Identifier>>,
323 pub output: Vec<NamedRef<Identifier>>,
326 pub solve: SolveObjective<Identifier>,
328 pub version: String,
330}
331
332#[cfg_attr(feature = "serde", derive(Serialize))]
334#[cfg_attr(feature = "serde", serde(untagged))]
335#[derive(Clone, PartialEq, Debug)]
336pub enum Literal<Identifier = String> {
337 Int(i64),
339 Float(f64),
341 #[cfg_attr(
343 feature = "serde",
344 serde(serialize_with = "serde_impl::serialize_variable_arc",)
345 )]
346 Variable(Arc<Variable<Identifier>>),
347 Bool(bool),
349 #[cfg_attr(
351 feature = "serde",
352 serde(serialize_with = "serde_impl::serialize_encapsulate_set",)
353 )]
354 IntSet(RangeList<i64>),
355 #[cfg_attr(
358 feature = "serde",
359 serde(serialize_with = "serde_impl::serialize_encapsulate_set",)
360 )]
361 FloatSet(RangeList<f64>),
362 #[cfg_attr(
364 feature = "serde",
365 serde(serialize_with = "serde_impl::serialize_encapsulate_string",)
366 )]
367 String(String),
368}
369
370#[derive(Clone, Debug, Default, PartialEq)]
372pub enum Method<Identifier = String> {
373 #[default]
375 Satisfy,
376 Minimize(Literal<Identifier>),
378 Maximize(Literal<Identifier>),
380}
381
382#[derive(Clone, Debug)]
396pub enum NamedRef<Identifier = String> {
397 Variable(Arc<Variable<Identifier>>),
399 Array(Arc<Array<Identifier>>),
401}
402
403#[derive(Clone, PartialEq, Debug)]
405pub struct SolveObjective<Identifier = String> {
406 pub method: Method<Identifier>,
408 pub ann: Vec<Annotation<Identifier>>,
413}
414
415#[derive(Clone, PartialEq, Debug)]
417pub enum Type {
418 Bool,
420 Int(Option<RangeList<i64>>),
422 Float(Option<RangeList<f64>>),
424 IntSet(Option<RangeList<i64>>),
426}
427
428#[derive(Clone, PartialEq, Debug)]
430pub struct Variable<Identifier = String> {
431 pub name: String,
433 pub ty: Type,
440 pub ann: Vec<Annotation<Identifier>>,
442 pub defined: bool,
445 pub introduced: bool,
449}
450
451impl<Identifier: Display> Display for Annotation<Identifier> {
452 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
453 match self {
454 Annotation::Atom(a) => write!(f, "{a}"),
455 Annotation::Call(c) => write!(f, "{c}"),
456 }
457 }
458}
459
460impl<Idenfier: Display> Display for AnnotationArgument<Idenfier> {
461 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
462 match self {
463 AnnotationArgument::Array(arr) => {
464 write!(f, "[")?;
465 let mut first = true;
466 for v in arr {
467 if !first {
468 write!(f, ", ")?
469 }
470 write!(f, "{v}")?;
471 first = false;
472 }
473 write!(f, "]")
474 }
475 AnnotationArgument::ArrayNamed(array) => match array.upgrade() {
476 Some(array) => write!(f, "{}", &array.name),
477 None => write!(f, "[/* dangling array ref */]"),
478 },
479 AnnotationArgument::Literal(lit) => write!(f, "{lit}"),
480 }
481 }
482}
483
484impl<Identifier> From<Argument<Identifier>> for AnnotationArgument<Identifier> {
485 fn from(value: Argument<Identifier>) -> Self {
486 match value {
487 Argument::Array(arr) => {
488 AnnotationArgument::Array(arr.into_iter().map(|l| l.into()).collect())
489 }
490 Argument::ArrayNamed(arr) => AnnotationArgument::ArrayNamed(Arc::downgrade(&arr)),
491 Argument::Literal(l) => AnnotationArgument::Literal(l.into()),
492 }
493 }
494}
495
496impl<Identifier: PartialEq> PartialEq for AnnotationArgument<Identifier> {
497 fn eq(&self, other: &Self) -> bool {
498 match (self, other) {
499 (AnnotationArgument::Array(lhs), AnnotationArgument::Array(rhs)) => lhs == rhs,
500 (AnnotationArgument::ArrayNamed(lhs), AnnotationArgument::ArrayNamed(rhs)) => {
501 match (lhs.upgrade(), rhs.upgrade()) {
502 (Some(lhs), Some(rhs)) => lhs == rhs,
503 (None, None) => true,
504 _ => false,
505 }
506 }
507 (AnnotationArgument::Literal(lhs), AnnotationArgument::Literal(rhs)) => lhs == rhs,
508 _ => false,
509 }
510 }
511}
512
513impl<Identifier: Display> Display for AnnotationCall<Identifier> {
514 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
515 write!(f, "{}(", self.id)?;
516 let mut first = true;
517 for arg in &self.args {
518 if !first {
519 write!(f, ", ")?
520 }
521 write!(f, "{arg}")?;
522 first = false;
523 }
524 write!(f, ")")
525 }
526}
527
528impl<Idenfier: Display> Display for AnnotationLiteral<Idenfier> {
529 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
530 match self {
531 AnnotationLiteral::Int(i) => write!(f, "{i}"),
532 AnnotationLiteral::Float(x) => write!(f, "{x:?}"),
533 AnnotationLiteral::Variable(var) => match var.upgrade() {
534 Some(var) => write!(f, "{}", var.name),
535 None => write!(f, "DANGLING_VARIABLE_REFERENCE"),
536 },
537 AnnotationLiteral::Bool(b) => write!(f, "{b}"),
538 AnnotationLiteral::IntSet(is) => write!(f, "{is}"),
539 AnnotationLiteral::FloatSet(fs) => write!(f, "{fs}"),
540 AnnotationLiteral::String(s) => write!(f, "{s:?}"),
541 AnnotationLiteral::Annotation(ann) => write!(f, "{ann}"),
542 }
543 }
544}
545
546impl<Identifier> From<Literal<Identifier>> for AnnotationLiteral<Identifier> {
547 fn from(value: Literal<Identifier>) -> Self {
548 match value {
549 Literal::Int(i) => AnnotationLiteral::Int(i),
550 Literal::Float(f) => AnnotationLiteral::Float(f),
551 Literal::Bool(b) => AnnotationLiteral::Bool(b),
552 Literal::String(s) => AnnotationLiteral::String(s),
553 Literal::Variable(var) => AnnotationLiteral::Variable(Arc::downgrade(&var)),
554 Literal::IntSet(set) => AnnotationLiteral::IntSet(set),
555 Literal::FloatSet(set) => AnnotationLiteral::FloatSet(set),
556 }
557 }
558}
559
560impl<Identifier: PartialEq> PartialEq for AnnotationLiteral<Identifier> {
561 fn eq(&self, other: &Self) -> bool {
562 match (self, other) {
563 (Self::Int(lhs), Self::Int(rhs)) => lhs == rhs,
564 (Self::Float(lhs), Self::Float(rhs)) => lhs == rhs,
565 (Self::Variable(lhs), Self::Variable(rhs)) => match (lhs.upgrade(), rhs.upgrade()) {
566 (Some(lhs), Some(rhs)) => lhs == rhs,
567 (None, None) => true,
568 _ => false,
569 },
570 (Self::Bool(lhs), Self::Bool(rhs)) => lhs == rhs,
571 (Self::IntSet(lhs), Self::IntSet(rhs)) => lhs == rhs,
572 (Self::FloatSet(lhs), Self::FloatSet(rhs)) => lhs == rhs,
573 (Self::String(lhs), Self::String(rhs)) => lhs == rhs,
574 (Self::Annotation(lhs), Self::Annotation(rhs)) => lhs == rhs,
575 _ => false,
576 }
577 }
578}
579impl<Identifier: Display> Display for Argument<Identifier> {
580 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
581 match self {
582 Argument::Array(arr) => {
583 write!(f, "[")?;
584 let mut first = true;
585 for v in arr {
586 if !first {
587 write!(f, ", ")?
588 }
589 write!(f, "{v}")?;
590 first = false;
591 }
592 write!(f, "]")
593 }
594 Argument::ArrayNamed(arr) => write!(f, "{}", &arr.name),
595 Argument::Literal(lit) => write!(f, "{lit}"),
596 }
597 }
598}
599
600impl<Identifier> Array<Identifier> {
601 pub fn cloned_key(self: &Arc<Self>) -> ArcKey<Self> {
621 ArcKey::new(Arc::clone(self))
622 }
623
624 fn determine_type(&self) -> (&str, bool) {
626 let ty = match self.contents.first().unwrap() {
627 Literal::Int(_) => "int",
628 Literal::Float(_) => "float",
629 Literal::Variable(var) => return (var.ty.base_name(), true),
630 Literal::Bool(_) => "bool",
631 Literal::IntSet(_) => "set of int",
632 Literal::FloatSet(_) => "set of float",
633 Literal::String(_) => "string",
634 };
635 let is_var = self
636 .contents
637 .iter()
638 .any(|lit| matches!(lit, Literal::Variable(_)));
639 (ty, is_var)
640 }
641}
642
643impl<Identifier: Display> Display for Constraint<Identifier> {
644 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
645 write!(f, "{}(", self.id)?;
646 let mut first = true;
647 for arg in &self.args {
648 if !first {
649 write!(f, ", ")?
650 }
651 write!(f, "{arg}")?;
652 first = false;
653 }
654 write!(f, ")")?;
655 if let Some(defines) = &self.defines {
656 write!(f, " ::defines_var({})", defines.name())?
657 }
658 for a in &self.ann {
659 write!(f, " ::{a}")?
660 }
661 Ok(())
662 }
663}
664
665impl<Identifier> FlatZinc<Identifier>
666where
667 Identifier: Clone + Debug,
668{
669 #[cfg(feature = "serde")]
675 pub fn deserialize_with_interner<'de, D, F, E>(
676 deserializer: D,
677 interner: F,
678 ) -> Result<Self, D::Error>
679 where
680 D: Deserializer<'de>,
681 F: FnMut(&str) -> Result<Identifier, E>,
682 E: Display,
683 {
684 use serde::de::{self, DeserializeSeed};
685
686 use crate::intermediate::ParserState;
687
688 let (model, interner) = ParserState::new(interner).deserialize(deserializer)?;
689 FlatZinc::from_intermediate(model, interner).map_err(de::Error::custom)
690 }
691
692 #[cfg(feature = "fzn")]
694 pub fn from_fzn<E>(source: impl std::io::BufRead) -> Result<Self, FznParseError>
695 where
696 for<'a> Identifier: TryFrom<&'a str, Error = E>,
697 E: Display,
698 {
699 fzn::parse(source)
700 }
701
702 #[cfg(feature = "fzn")]
705 pub fn from_fzn_with_interner<F, E>(
706 source: impl std::io::BufRead,
707 interner: F,
708 ) -> Result<Self, FznParseError>
709 where
710 F: FnMut(&str) -> Result<Identifier, E>,
711 E: Display,
712 {
713 fzn::parse_with_interner(source, interner)
714 }
715}
716
717impl<Identifier> Default for FlatZinc<Identifier> {
718 fn default() -> Self {
719 Self {
720 variables: Vec::new(),
721 arrays: Vec::new(),
722 constraints: Vec::new(),
723 output: Vec::new(),
724 solve: Default::default(),
725 version: "1.0".into(),
726 }
727 }
728}
729
730impl<Identifier: Display> Display for FlatZinc<Identifier> {
731 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
732 let output_map: HashSet<_> = self.output.iter().collect();
733
734 for var in &self.variables {
735 write!(f, "var {}", var.ty)?;
736 write!(f, ": {}", var.name)?;
737 let name_ref: NamedRef<_> = Arc::clone(var).into();
738 if output_map.contains(&name_ref) {
739 write!(f, " ::output_var")?;
740 }
741 if var.defined {
742 write!(f, " ::is_defined_var")?;
743 }
744 if var.introduced {
745 write!(f, " ::var_is_introduced")?;
746 }
747 for ann in &var.ann {
748 write!(f, " ::{ann}")?
749 }
750 writeln!(f, ";")?
751 }
752 for arr in &self.arrays {
753 let (ty, is_var) = arr.determine_type();
754 write!(
755 f,
756 "array[1..{}] of {}{ty}: {}",
757 arr.contents.len(),
758 if is_var { "var " } else { "" },
759 arr.name
760 )?;
761 let name_ref: NamedRef<_> = Arc::clone(arr).into();
762 if output_map.contains(&name_ref) {
763 write!(f, " ::output_array([1..{}])", arr.contents.len())?;
764 }
765 if arr.defined {
766 write!(f, " ::is_defined_var")?;
767 }
768 if arr.introduced {
769 write!(f, " ::var_is_introduced")?;
770 }
771 for ann in &arr.ann {
772 write!(f, " ::{ann}")?
773 }
774 write!(f, " = [")?;
775 let mut first = true;
776 for v in &arr.contents {
777 if !first {
778 write!(f, ", ")?;
779 }
780 write!(f, "{v}")?;
781 first = false;
782 }
783 writeln!(f, "];")?
784 }
785 for c in &self.constraints {
786 writeln!(f, "constraint {c};")?;
787 }
788 writeln!(f, "{};", self.solve)
789 }
790}
791
792impl<Identifier: Display> Display for Literal<Identifier> {
793 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
794 match self {
795 Literal::Int(i) => write!(f, "{i}"),
796 Literal::Float(x) => write!(f, "{x:?}"),
797 Literal::Variable(var) => write!(f, "{}", var.name),
798 Literal::Bool(b) => write!(f, "{b}"),
799 Literal::IntSet(is) => write!(f, "{is}"),
800 Literal::FloatSet(fs) => write!(f, "{fs}"),
801 Literal::String(s) => write!(f, "{s:?}"),
802 }
803 }
804}
805
806impl<Identifier: Display> Display for Method<Identifier> {
807 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
808 match self {
809 Method::Satisfy => write!(f, "satisfy"),
810 Method::Minimize(objective) => write!(f, "minimize {objective}"),
811 Method::Maximize(objective) => write!(f, "maximize {objective}"),
812 }
813 }
814}
815
816impl<Identifier> NamedRef<Identifier> {
817 pub fn name(&self) -> &str {
819 match self {
820 NamedRef::Variable(var) => &var.name,
821 NamedRef::Array(array) => &array.name,
822 }
823 }
824}
825
826impl<Identifier> Eq for NamedRef<Identifier> {}
827
828impl<Identifier> From<Arc<Array<Identifier>>> for NamedRef<Identifier> {
829 fn from(arc: Arc<Array<Identifier>>) -> Self {
830 NamedRef::Array(arc)
831 }
832}
833
834impl<Identifier> From<Arc<Variable<Identifier>>> for NamedRef<Identifier> {
835 fn from(arc: Arc<Variable<Identifier>>) -> Self {
836 NamedRef::Variable(arc)
837 }
838}
839
840impl<Identifier> Hash for NamedRef<Identifier> {
841 fn hash<H: Hasher>(&self, state: &mut H) {
842 self.name().hash(state);
843 }
844}
845
846impl<Identifier> Ord for NamedRef<Identifier> {
847 fn cmp(&self, other: &Self) -> Ordering {
848 self.name().cmp(other.name())
849 }
850}
851
852impl<Identifier> PartialEq for NamedRef<Identifier> {
853 fn eq(&self, other: &Self) -> bool {
854 self.name() == other.name()
855 }
856}
857
858impl<Identifier> PartialOrd for NamedRef<Identifier> {
859 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
860 Some(self.cmp(other))
861 }
862}
863
864impl<Identifier> Default for SolveObjective<Identifier> {
865 fn default() -> Self {
866 Self {
867 method: Default::default(),
868 ann: Vec::new(),
869 }
870 }
871}
872
873impl<Identifier: Display> Display for SolveObjective<Identifier> {
874 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
875 write!(f, "solve ")?;
876 for a in &self.ann {
877 write!(f, "::{a} ")?;
878 }
879 write!(f, "{}", self.method)
880 }
881}
882
883impl Type {
884 fn base_name(&self) -> &'static str {
886 match self {
887 Type::Bool => "bool",
888 Type::Int(_) => "int",
889 Type::Float(_) => "float",
890 Type::IntSet(_) => "set of int",
891 }
892 }
893}
894
895impl Display for Type {
896 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
897 match self {
898 Type::Bool => write!(f, "bool"),
899 Type::Int(Some(domain)) => write!(f, "{domain}"),
900 Type::Int(None) => write!(f, "int"),
901 Type::Float(Some(domain)) => write!(f, "{domain}"),
902 Type::Float(None) => write!(f, "float"),
903 Type::IntSet(Some(domain)) => write!(f, "set of {domain}"),
904 Type::IntSet(None) => write!(f, "set of int"),
905 }
906 }
907}
908
909impl<Identifier> Variable<Identifier> {
910 pub fn cloned_key(self: &Arc<Self>) -> ArcKey<Self> {
930 ArcKey::new(Arc::clone(self))
931 }
932}