Skip to main content

xcsp3_serde/
constraint.rs

1//! # Constraints
2//!
3//! This module contains the definition of the constraints that can be used in a
4//! XCSP3 instance. Each constraint is represented by a struct that contains the
5//! necessary information to represent the constraint in the XCSP3 format. The
6//! enumerated type [`Constraint`] is used to represent any of constraint.
7
8use std::{borrow::Cow, fmt::Display, marker::PhantomData, str::FromStr};
9
10use nom::{
11	branch::alt,
12	bytes::complete::tag,
13	character::complete::char,
14	combinator::{all_consuming, map},
15	sequence::{delimited, separated_pair},
16	IResult, Parser,
17};
18use serde::{
19	de::{self, Visitor},
20	Deserialize, Deserializer, Serialize, Serializer,
21};
22
23use crate::{
24	as_str, deserialize_int_vals,
25	expression::{identifier, int, sequence, tuple, whitespace_seperated, BoolExp, Exp, IntExp},
26	from_str, serialize_list, Instantiation, IntVal, MetaInfo,
27};
28
29/// Constraint forcing a set of expressions to take distinct values
30#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
31#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
32pub struct AllDifferent<Identifier = String> {
33	/// Optional metadata for the constraint
34	#[serde(flatten)]
35	pub info: MetaInfo<Identifier>,
36	#[serde(
37		alias = "$text",
38		deserialize_with = "IntExp::parse_vec",
39		serialize_with = "serialize_list"
40	)]
41	/// List of expressions that must take distinct values
42	pub list: Vec<IntExp<Identifier>>,
43	/// List of values that are excluded from the constraint and can be taken by
44	/// multiple expressions
45	#[serde(
46		default,
47		skip_serializing_if = "Vec::is_empty",
48		deserialize_with = "deserialize_int_vals",
49		serialize_with = "serialize_list"
50	)]
51	pub except: Vec<IntVal>,
52}
53
54/// Constraint forcing a set of expressions to take the same value
55#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
56#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
57pub struct AllEqual<Identifier = String> {
58	/// Optional metadata for the constraint
59	#[serde(flatten)]
60	pub info: MetaInfo<Identifier>,
61	/// List of expressions that must take the same value
62	#[serde(
63		alias = "$text",
64		deserialize_with = "IntExp::parse_vec",
65		serialize_with = "serialize_list"
66	)]
67	pub list: Vec<IntExp<Identifier>>,
68	/// List of values that are excluded from the constraint and can be taken by
69	/// expressions not matching other expressions
70	#[serde(
71		default,
72		skip_serializing_if = "Vec::is_empty",
73		deserialize_with = "deserialize_int_vals",
74		serialize_with = "serialize_list"
75	)]
76	pub except: Vec<IntVal>,
77}
78
79// TODO: Should `condition`, `limits` and `loads` be made mutually exclusive in
80// the struct?
81/// Constraint forcing a list of items, whose sizes are given, are put in
82/// different bins in such a way that the total size of the items in each bin
83/// respects a numerical condition.
84#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
85#[serde(bound(
86	deserialize = "Identifier: std::str::FromStr",
87	serialize = "Identifier: std::fmt::Display"
88))]
89pub struct BinPacking<Identifier = String> {
90	/// Optional metadata for the constraint
91	#[serde(flatten)]
92	pub info: MetaInfo<Identifier>,
93	/// List of expressions representing the bin in which each item is placed
94	#[serde(
95		deserialize_with = "IntExp::parse_vec",
96		serialize_with = "serialize_list"
97	)]
98	pub list: Vec<IntExp<Identifier>>,
99	/// List of expressions representing the size of each item
100	#[serde(
101		deserialize_with = "IntExp::parse_vec",
102		serialize_with = "serialize_list"
103	)]
104	pub sizes: Vec<IntExp<Identifier>>,
105	/// Condition that must be respected by the total size of the items in each bin
106	#[serde(default, skip_serializing_if = "Option::is_none")]
107	pub condition: Option<Condition<Identifier>>,
108	#[serde(
109		default,
110		skip_serializing_if = "Vec::is_empty",
111		deserialize_with = "IntExp::parse_vec",
112		serialize_with = "serialize_list"
113	)]
114	/// List of expressions representing the limit for the total size of the items
115	/// in each bin
116	pub limits: Vec<IntExp<Identifier>>,
117	/// List of expressions representing the load of each bin
118	#[serde(
119		default,
120		skip_serializing_if = "Vec::is_empty",
121		deserialize_with = "IntExp::parse_vec",
122		serialize_with = "serialize_list"
123	)]
124	pub loads: Vec<IntExp<Identifier>>,
125}
126
127/// Constraint enforcing the amount of times certain values are taken by a set
128/// of expressions.
129#[derive(Clone, Debug, PartialEq, Hash)]
130
131pub struct Cardinality<Identifier = String> {
132	/// Optional metadata for the constraint
133	pub info: MetaInfo<Identifier>,
134	/// List of expressions of which the values are observed
135	pub list: Vec<IntExp<Identifier>>,
136	/// List of values that are observed
137	pub values: Vec<IntExp<Identifier>>,
138	/// Whether the expressions are allowed to take values not in the list of
139	/// observed values
140	pub closed: bool,
141	/// List of expressions representing the number of times each value is taken
142	pub occurs: Vec<Exp<Identifier>>,
143}
144
145/// Constraint that enforces that if the ith expression takes the value j, then
146/// the jth expression takes the value i.
147///
148/// If [`Self::inverse_list`] is not empty, then the constraint enforces that if
149/// the ith expression in [`Self::list`] takes the value j, then the jth
150/// expression in [`Self::inverse_list`] takes the value i.
151///
152/// If [`Self::value`] is not empty, then the constraint enforces that the ith
153/// expression in [`Self::list`] takes the value 1 iff the expression in
154/// [`Self::value`] takes the value i.
155#[derive(Clone, Debug, PartialEq, Hash)]
156pub struct Channel<Identifier = String> {
157	/// Optional metadata for the constraint
158	pub info: MetaInfo<Identifier>,
159	/// List of expressions that is being channelled
160	pub list: Vec<IntExp<Identifier>>,
161	/// Inverse list of expressions that is being channelled
162	pub inverse_list: Vec<IntExp<Identifier>>,
163	/// Expression representing the index of the only expression in [`Self::list`]
164	/// that is allowed to take the value 1.
165	pub value: Option<IntExp<Identifier>>,
166}
167
168/// Constraint that ensures that the values of the expressions in [`Self::list`]
169/// form a circuit.
170///
171/// That is to say, each expression takes the value of an list index,
172/// representing an arc in the circuit. The values of the expressions must form
173/// a cycle. Expressions are allowed to take the value of their own index,
174/// effectively making excluding them from the cycle. When [`Self::size`] is
175/// given, then the circuit must have the length of [`Self::size`]. Otherwise,
176/// the circuit must be at least 2 in length.
177#[derive(Clone, Debug, PartialEq, Hash, Serialize)]
178#[serde(bound(serialize = "Identifier: Display"))]
179pub struct Circuit<Identifier = String> {
180	/// Optional metadata for the constraint
181	#[serde(flatten)]
182	pub info: MetaInfo<Identifier>,
183	/// List of expressions that must form a circuit
184	pub list: OffsetList<Identifier>,
185	/// Size of the circuit
186	#[serde(skip_serializing_if = "Option::is_none")]
187	pub size: Option<IntExp<Identifier>>,
188}
189
190/// Condition to be enforced
191///
192/// This type is used as part of a larger constraint type
193#[derive(Clone, Debug, PartialEq, Hash)]
194pub struct Condition<Identifier> {
195	/// Operator of the condition
196	pub operator: Operator,
197	/// Right-side operand of the condition
198	pub operand: Exp<Identifier>,
199}
200
201/// Enumerated type to represent the different possible constraints
202#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
203#[serde(
204	rename_all = "camelCase",
205	bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display")
206)]
207pub enum Constraint<Identifier = String> {
208	/// [`AllDifferent`] constraint
209	AllDifferent(AllDifferent<Identifier>),
210	/// [`AllEqual`] constraint
211	AllEqual(AllEqual<Identifier>),
212	/// [`BinPacking`] constraint
213	BinPacking(BinPacking<Identifier>),
214	/// [`Cardinality`] constraint
215	Cardinality(Cardinality<Identifier>),
216	/// [`Channel`] constraint
217	Channel(Channel<Identifier>),
218	/// [`Circuit`] constraint
219	Circuit(Circuit<Identifier>),
220	/// [`Count`] constraint
221	Count(Count<Identifier>),
222	/// [`Cumulative`] constraint
223	Cumulative(Cumulative<Identifier>),
224	/// [`Element`] constraint
225	Element(Element<Identifier>),
226	/// [`Extension`] constraint
227	Extension(Extension<Identifier>),
228	/// [`Instantiation`] constraint
229	Instantiation(Instantiation<Identifier>),
230	/// [`Intension`] constraint
231	Intension(Intension<Identifier>),
232	/// [`Knapsack`] constraint
233	Knapsack(Knapsack<Identifier>),
234	/// [`Maximum`] constraint
235	Maximum(Maximum<Identifier>),
236	/// [`Mdd`] constraint
237	Mdd(Mdd<Identifier>),
238	/// [`Minimum`] constraint
239	Minimum(Minimum<Identifier>),
240	/// [`NValues`] constraint
241	NValues(NValues<Identifier>),
242	/// [`NoOverlap`] constraint
243	NoOverlap(NoOverlap<Identifier>),
244	/// [`Ordered`] constraint
245	Ordered(Ordered<Identifier>),
246	/// [`Precedence`] constraint
247	Precedence(Precedence<Identifier>),
248	/// [`Regular`] constraint
249	Regular(Regular<Identifier>),
250	/// [`Sum`] constraint
251	Sum(Sum<Identifier>),
252}
253
254/// Constraint that enforced that the number of times expressions in
255/// [`Self::list`] take a value from [`Self::values`] abides by the given
256/// [`Self::condition`].
257#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
258#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
259pub struct Count<Identifier = String> {
260	/// Optional metadata for the constraint
261	#[serde(flatten)]
262	pub info: MetaInfo<Identifier>,
263	/// List of expressions of which the values are observed
264	#[serde(
265		deserialize_with = "IntExp::parse_vec",
266		serialize_with = "serialize_list"
267	)]
268	pub list: Vec<IntExp<Identifier>>,
269	/// List of values that are counted
270	#[serde(
271		deserialize_with = "IntExp::parse_vec",
272		serialize_with = "serialize_list"
273	)]
274	pub values: Vec<IntExp<Identifier>>,
275	/// Condition to be enforced on the count
276	pub condition: Condition<Identifier>,
277}
278
279/// Constraint that enforces that at each point in time, the cumulated height of
280/// tasks that overlap that point, respects the given [`Self::condition`].
281#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
282#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
283pub struct Cumulative<Identifier = String> {
284	/// Optional metadata for the constraint
285	#[serde(flatten)]
286	pub info: MetaInfo<Identifier>,
287	/// List of starting time-points of the tasks
288	#[serde(
289		deserialize_with = "IntExp::parse_vec",
290		serialize_with = "serialize_list"
291	)]
292	pub origins: Vec<IntExp<Identifier>>,
293	/// List of durations of the tasks
294	#[serde(
295		deserialize_with = "IntExp::parse_vec",
296		serialize_with = "serialize_list"
297	)]
298	pub lengths: Vec<IntExp<Identifier>>,
299	/// List of heights of the tasks
300	#[serde(
301		deserialize_with = "IntExp::parse_vec",
302		serialize_with = "serialize_list"
303	)]
304	pub heights: Vec<IntExp<Identifier>>,
305	/// Condition to be enforced on the cumulated height at each time point
306	pub condition: Condition<Identifier>,
307}
308
309/// Constraint that enforces that the value of the expression at
310/// [`Self::index`] abides by the given [`Self::condition`], or alternatively is
311/// equal the expression [`Self::value`].
312#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
313#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
314pub struct Element<Identifier = String> {
315	/// Optional metadata for the constraint
316	#[serde(flatten)]
317	pub info: MetaInfo<Identifier>,
318	/// Indexed list of values
319	pub list: OffsetList<Identifier>,
320	/// Index of the value to be constrained
321	#[serde(default, skip_serializing_if = "Option::is_none")]
322	pub index: Option<IntExp<Identifier>>,
323	/// Value to be assigned to the indexed expression
324	#[serde(default, skip_serializing_if = "Option::is_none")]
325	pub value: Option<IntExp<Identifier>>,
326	/// Condition to be enforced on the indexed expression
327	#[serde(default, skip_serializing_if = "Option::is_none")]
328	pub condition: Option<Condition<Identifier>>,
329}
330
331// TODO: Support for "smart" extension
332/// Constraint that enforces that the expressions in [`Self::list`] either take
333/// the values of one of the rows in [`Self::supports`], or alternatively do not
334/// match any of the rows in [`Self::conflicts`].
335#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
336#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
337pub struct Extension<Identifier = String> {
338	/// Optional metadata for the constraint
339	#[serde(flatten)]
340	pub info: MetaInfo<Identifier>,
341	/// List of expressions to be constrained
342	#[serde(
343		alias = "$text",
344		deserialize_with = "IntExp::parse_vec",
345		serialize_with = "serialize_list"
346	)]
347	pub list: Vec<IntExp<Identifier>>,
348	/// Combinations of values that the expressions are allowed to take
349	#[serde(
350		default,
351		skip_serializing_if = "Vec::is_empty",
352		deserialize_with = "deserialize_int_tuples",
353		serialize_with = "serialize_int_tuples"
354	)]
355	pub supports: Vec<Vec<IntVal>>,
356	/// Combinations of values that the expressions are not allowed to take
357	#[serde(
358		default,
359		skip_serializing_if = "Vec::is_empty",
360		deserialize_with = "deserialize_int_tuples",
361		serialize_with = "serialize_int_tuples"
362	)]
363	pub conflicts: Vec<Vec<IntVal>>,
364}
365
366/// Constraint that enforces that the Boolean Expression [`Self::function`] must
367/// be satisfied.
368#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
369#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
370pub struct Intension<Identifier> {
371	/// Optional metadata for the constraint
372	#[serde(flatten)]
373	pub info: MetaInfo<Identifier>,
374	/// Boolean expression to be satisfied
375	#[serde(alias = "$text")]
376	pub function: BoolExp<Identifier>,
377}
378
379/// Constraint where the expressions in [`Self::list`] depict the amount of an
380/// item chosen. The constraint enforces that the sum of the [`Self::weights`]
381/// abides by the first [`Self::condition`] and the sum of the [`Self::profits`]
382/// abides by the second [`Self::condition`].
383#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
384#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
385pub struct Knapsack<Identifier = String> {
386	/// Optional metadata for the constraint
387	#[serde(flatten)]
388	pub info: MetaInfo<Identifier>,
389	/// List of expressions that depict the amount of an item chosen
390	#[serde(
391		deserialize_with = "IntExp::parse_vec",
392		serialize_with = "serialize_list"
393	)]
394	pub list: Vec<IntExp<Identifier>>,
395	/// List of weights of the items
396	#[serde(
397		deserialize_with = "deserialize_int_vals",
398		serialize_with = "serialize_list"
399	)]
400	pub weights: Vec<IntVal>,
401	/// List of profits of the items
402	#[serde(
403		deserialize_with = "deserialize_int_vals",
404		serialize_with = "serialize_list"
405	)]
406	pub profits: Vec<IntVal>,
407	/// The first `Condition` element is related to weights whereas the second
408	/// [`Condition`] element is related to profits.
409	pub condition: [Condition<Identifier>; 2],
410}
411
412/// Constraint that enforces that the maximum value taken by the expression in
413/// [`Self::list`] abides by the given [`Self::condition`].
414#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
415#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
416pub struct Maximum<Identifier = String> {
417	/// Optional metadata for the constraint
418	#[serde(flatten)]
419	pub info: MetaInfo<Identifier>,
420	/// List of expressions considered
421	#[serde(
422		alias = "$text",
423		deserialize_with = "IntExp::parse_vec",
424		serialize_with = "serialize_list"
425	)]
426	pub list: Vec<IntExp<Identifier>>,
427	/// Condition to be enforced on the maximum value
428	pub condition: Condition<Identifier>,
429}
430
431/// Constraint that enforces that the values of the [`Self::list`] follow a
432/// valid path according to the [`Self::transitions`] that form an Multi-valued
433/// Decision Diagram (MDD).
434#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
435#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
436pub struct Mdd<Identifier = String> {
437	/// Optional metadata for the constraint
438	#[serde(flatten)]
439	pub info: MetaInfo<Identifier>,
440	/// List of expressions to be constrained
441	#[serde(
442		deserialize_with = "IntExp::parse_vec",
443		serialize_with = "serialize_list"
444	)]
445	pub list: Vec<IntExp<Identifier>>,
446	/// List of transitions that form the Multi-valued Decision Diagram (MDD)
447	#[serde(
448		deserialize_with = "Transition::parse_vec",
449		serialize_with = "serialize_list"
450	)]
451	pub transitions: Vec<Transition<Identifier>>,
452}
453
454/// Constraint that enforces that the minimum value taken by the expression in
455/// [`Self::list`] abides by the given [`Self::condition`].
456#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
457#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
458pub struct Minimum<Identifier = String> {
459	/// Optional metadata for the constraint
460	#[serde(flatten)]
461	pub info: MetaInfo<Identifier>,
462	/// List of expressions considered
463	#[serde(
464		alias = "$text",
465		deserialize_with = "IntExp::parse_vec",
466		serialize_with = "serialize_list"
467	)]
468	pub list: Vec<IntExp<Identifier>>,
469	/// Condition to be enforced on the minimum value
470	pub condition: Condition<Identifier>,
471}
472
473/// Cosntraint that enforces a [`Self::condition`] on the number of different
474/// values taken by the expressions in [`Self::list`].
475#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
476#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
477pub struct NValues<Identifier = String> {
478	/// Optional metadata for the constraint
479	#[serde(flatten)]
480	pub info: MetaInfo<Identifier>,
481	/// List of expressions considered
482	#[serde(
483		deserialize_with = "IntExp::parse_vec",
484		serialize_with = "serialize_list"
485	)]
486	pub list: Vec<IntExp<Identifier>>,
487	/// Values that are not counted
488	#[serde(
489		default,
490		skip_serializing_if = "Vec::is_empty",
491		deserialize_with = "deserialize_int_vals",
492		serialize_with = "serialize_list"
493	)]
494	pub except: Vec<IntVal>,
495	/// Condition to be enforced on the number of different values
496	pub condition: Condition<Identifier>,
497}
498
499// TODO: k-dimensional no-overlap constraint
500/// Constraint that enforces that the tasks defined by the [`Self::origins`] and
501/// [`Self::lengths`] do not overlap.
502///
503/// When [`Self::zero_ignored`] field is set to `false`, it indicates that
504/// zero-length tasks cannot be packed anywhere (cannot overlap with other
505/// tasks).
506#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
507#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
508pub struct NoOverlap<Identifier = String> {
509	/// Optional metadata for the constraint
510	#[serde(flatten)]
511	pub info: MetaInfo<Identifier>,
512	#[serde(
513		default = "bool_true",
514		skip_serializing_if = "is_true",
515		rename = "@zeroIgnored"
516	)]
517	/// Indicates whether zero-length tasks can be placed anywhere
518	pub zero_ignored: bool,
519	/// List of starting points of the tasks
520	#[serde(
521		deserialize_with = "IntExp::parse_vec",
522		serialize_with = "serialize_list"
523	)]
524	pub origins: Vec<IntExp<Identifier>>,
525	/// List of lengths of the tasks
526	#[serde(
527		deserialize_with = "IntExp::parse_vec",
528		serialize_with = "serialize_list"
529	)]
530	pub lengths: Vec<IntExp<Identifier>>,
531}
532
533/// List of expressions where the index is considered to start at
534/// [`Self::start_index`].
535#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
536#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
537pub struct OffsetList<Identifier> {
538	/// List of expressions
539	#[serde(
540		alias = "$text",
541		deserialize_with = "IntExp::parse_vec",
542		serialize_with = "serialize_list"
543	)]
544	pub list: Vec<IntExp<Identifier>>,
545	/// Index of the first element in the list
546	#[serde(rename = "@startIndex", default, skip_serializing_if = "is_default")]
547	pub start_index: IntVal,
548}
549
550/// Operator used as part of the [`Condition`] struct or a constraint.
551#[derive(Clone, Debug, PartialEq, Hash, Serialize)]
552#[serde(rename_all = "camelCase")]
553pub enum Operator {
554	/// Less than
555	Lt,
556	/// Less than or equal
557	Le,
558	/// Equal
559	Eq,
560	/// Greater than or equal
561	Ge,
562	/// Greater than
563	Gt,
564	/// Not equal
565	Ne,
566	/// Element of
567	In,
568}
569
570/// Constraint that enforces that values of the expressions in [`Self::list`]
571/// are ordered according to the [`Self::operator`].
572///
573/// The [`Self::lengths`] field indicates the minimum distances between any two
574/// successive variables of [`Self::list`].
575#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
576#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
577pub struct Ordered<Identifier = String> {
578	/// Optional metadata for the constraint
579	#[serde(flatten)]
580	pub info: MetaInfo<Identifier>,
581	/// List of expressions to be constrained
582	#[serde(
583		alias = "$text",
584		deserialize_with = "IntExp::parse_vec",
585		serialize_with = "serialize_list"
586	)]
587	pub list: Vec<IntExp<Identifier>>,
588	/// Minimum distances between any two successive variables
589	#[serde(
590		default,
591		skip_serializing_if = "Vec::is_empty",
592		deserialize_with = "IntExp::parse_vec",
593		serialize_with = "serialize_list"
594	)]
595	pub lengths: Vec<IntExp<Identifier>>,
596	/// The operator used to order the expressions
597	///
598	/// The operator must be either [`Operator::Lt`], [`Operator::Le`],
599	/// [`Operator::Ge`], or [`Operator::Gt`].
600	pub operator: Operator,
601}
602
603/// Cosntraint that enforces that first occurence of each values of the
604/// expressions in [`Self::list`] occur in the same order as the values in
605/// [`Self::values`].
606#[derive(Clone, Debug, PartialEq, Hash)]
607pub struct Precedence<Identifier = String> {
608	/// Optional metadata for the constraint
609	pub info: MetaInfo<Identifier>,
610	/// List of expressions considered
611	pub list: Vec<IntExp<Identifier>>,
612	/// Ordered values considered
613	pub values: Vec<IntVal>,
614	/// Whether the expressions must take one of the values in [`Self::values`]
615	pub covered: bool,
616}
617
618/// Constraint that enforces that the values of the expressions in
619/// [`Self::list`] follow a valid sequence of [`Self::transitions`], starting
620/// from tje [`Self::start`] state and ending at the [`Self::finish`] state.
621#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
622#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
623pub struct Regular<Identifier = String> {
624	/// Optional metadata for the constraint
625	#[serde(flatten)]
626	pub info: MetaInfo<Identifier>,
627	/// List of expressions to be constrained
628	#[serde(
629		deserialize_with = "IntExp::parse_vec",
630		serialize_with = "serialize_list"
631	)]
632	pub list: Vec<IntExp<Identifier>>,
633	/// List of transitions between states
634	#[serde(
635		deserialize_with = "Transition::parse_vec",
636		serialize_with = "serialize_list"
637	)]
638	pub transitions: Vec<Transition<Identifier>>,
639	/// Starting state
640	#[serde(deserialize_with = "from_str", serialize_with = "as_str")]
641	pub start: Identifier,
642	/// Final state
643	#[serde(
644		rename = "final",
645		deserialize_with = "from_str",
646		serialize_with = "as_str"
647	)]
648	pub finish: Identifier,
649}
650
651/// Constraint that enforces that the sum of the values of the expressions in
652/// [`Self::list`], optionally multiplied by [`Self::coeffs`], abides by the
653/// [`Self::condition`].
654#[derive(Clone, Debug, PartialEq, Hash, Deserialize, Serialize)]
655#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
656pub struct Sum<Identifier = String> {
657	/// Optional metadata for the constraint
658	#[serde(flatten)]
659	pub info: MetaInfo<Identifier>,
660	/// List of expressions to be constrained
661	#[serde(
662		deserialize_with = "IntExp::parse_vec",
663		serialize_with = "serialize_list"
664	)]
665	pub list: Vec<IntExp<Identifier>>,
666	/// Coefficient for each expression
667	#[serde(
668		default,
669		skip_serializing_if = "Vec::is_empty",
670		deserialize_with = "deserialize_int_vals",
671		serialize_with = "serialize_list"
672	)]
673	pub coeffs: Vec<IntVal>,
674	/// Condition to be enforced
675	pub condition: Condition<Identifier>,
676}
677
678/// Transition between two state for the regular and MDD constraints.
679#[derive(Clone, Debug, PartialEq, Hash)]
680pub struct Transition<Identifier> {
681	/// Identifier of the source state
682	pub from: Identifier,
683	/// Value to be taken by the expression
684	pub val: IntVal,
685	/// Identifier of the destination state
686	pub to: Identifier,
687}
688
689/// Function returning `true`
690fn bool_true() -> bool {
691	true
692}
693
694/// Deserialize a list of integer tuples visiting a string
695fn deserialize_int_tuples<'de, D: Deserializer<'de>>(
696	deserializer: D,
697) -> Result<Vec<Vec<IntVal>>, D::Error> {
698	/// Visitor to parse a list of integer tuples
699	struct V;
700	impl Visitor<'_> for V {
701		type Value = Vec<Vec<IntVal>>;
702
703		fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
704			formatter.write_str("an integer")
705		}
706
707		fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
708			let v = v.trim();
709			let (_, v) = all_consuming(sequence(tuple(int)))
710				.parse(v)
711				.map_err(|_| E::custom(format!("invalid integer `{v}'")))?;
712			Ok(v)
713		}
714	}
715	deserializer.deserialize_str(V)
716}
717
718/// Whether the value is the default value
719fn is_default<T: Default + PartialEq>(val: &T) -> bool {
720	val == &T::default()
721}
722
723/// Whether the value is `false`
724fn is_false(x: &bool) -> bool {
725	!x
726}
727
728/// Whether the value is `true`
729fn is_true(x: &bool) -> bool {
730	*x
731}
732
733/// Serialize a list of integer tuples as a string
734fn serialize_int_tuples<S: Serializer>(
735	vals: &[Vec<IntVal>],
736	serializer: S,
737) -> Result<S::Ok, S::Error> {
738	serializer.serialize_str(
739		&vals
740			.iter()
741			.map(|e| {
742				format!(
743					"({})",
744					e.iter()
745						.map(|e| format!("{}", e))
746						.collect::<Vec<_>>()
747						.join(",")
748				)
749			})
750			.collect::<Vec<_>>()
751			.join(""),
752	)
753}
754
755impl<'de, Identifier: FromStr> Deserialize<'de> for Cardinality<Identifier> {
756	fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
757		/// Helper struct to deserialize the <values> element of the cardinality constraint
758		#[derive(Deserialize)]
759		#[serde(bound(deserialize = "Identifier: FromStr"))]
760		struct Values<Identifier> {
761			/// closed attribute
762			#[serde(default, rename = "@closed")]
763			closed: Option<bool>,
764			/// content of the <values> element
765			#[serde(rename = "$text", deserialize_with = "IntExp::parse_vec")]
766			list: Vec<IntExp<Identifier>>,
767		}
768		/// Helper struct to deserialize the <cardinality> element of the cardinality constraint
769		#[derive(Deserialize)]
770		#[serde(bound(deserialize = "Identifier: FromStr"))]
771		struct Cardinality<Identifier = String> {
772			/// Metadata for the constraint
773			#[serde(flatten)]
774			info: MetaInfo<Identifier>,
775			/// <list> element
776			#[serde(deserialize_with = "IntExp::parse_vec")]
777			list: Vec<IntExp<Identifier>>,
778			/// <values> element
779			values: Values<Identifier>,
780			/// <occurs> element
781			#[serde(deserialize_with = "Exp::parse_vec")]
782			occurs: Vec<Exp<Identifier>>,
783		}
784		let x = Cardinality::deserialize(deserializer)?;
785		Ok(Self {
786			info: x.info,
787			list: x.list,
788			values: x.values.list,
789			closed: x.values.closed.unwrap_or(false),
790			occurs: x.occurs,
791		})
792	}
793}
794
795impl<Identifier: Display> Serialize for Cardinality<Identifier> {
796	fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
797		/// Serialize a <values> element
798		#[derive(Serialize)]
799		#[serde(bound(serialize = "Identifier: Display"))]
800		struct Values<'a, Identifier> {
801			/// closed attribute
802			#[serde(rename = "@closed", skip_serializing_if = "is_false")]
803			closed: bool,
804			/// content of the <values> element
805			#[serde(rename = "$text", serialize_with = "serialize_list")]
806			list: &'a Vec<IntExp<Identifier>>,
807		}
808		/// Serialize a <cardinality> element
809		#[derive(Serialize)]
810		#[serde(bound(serialize = "Identifier: Display"))]
811		struct Cardinality<'a, Identifier = String> {
812			/// meta information
813			#[serde(flatten)]
814			info: &'a MetaInfo<Identifier>,
815			/// <list> element
816			#[serde(serialize_with = "serialize_list")]
817			list: &'a Vec<IntExp<Identifier>>,
818			/// <values> element
819			values: Values<'a, Identifier>,
820			/// <occurs> element
821			#[serde(serialize_with = "serialize_list")]
822			occurs: &'a Vec<Exp<Identifier>>,
823		}
824		let x = Cardinality {
825			info: &self.info,
826			list: &self.list,
827			values: Values {
828				closed: self.closed,
829				list: &self.values,
830			},
831			occurs: &self.occurs,
832		};
833		x.serialize(serializer)
834	}
835}
836
837impl<'de, Identifier: FromStr> Deserialize<'de> for Channel<Identifier> {
838	fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Channel<Identifier>, D::Error> {
839		/// Deserialize a <channel> element
840		#[derive(Deserialize)]
841		#[serde(bound(deserialize = "I: FromStr"))]
842		struct Channel<'a, I: FromStr> {
843			/// meta information
844			#[serde(flatten)]
845			info: MetaInfo<I>,
846			/// <list> element(s)
847			list: Vec<Cow<'a, str>>,
848			/// <value> element
849			#[serde(default)]
850			value: Option<IntExp<I>>,
851		}
852		let c = Channel::deserialize(deserializer)?;
853		if c.list.is_empty() {
854			return Err(de::Error::missing_field("list"));
855		}
856		let (_, list) = all_consuming(whitespace_seperated(IntExp::parse))
857			.parse(c.list[0].trim())
858			.map_err(|_| {
859				de::Error::custom(format!(
860					"invalid integer expressions `{}'",
861					&c.list[0].trim()
862				))
863			})?;
864		let inverse_list = if let Some(inverse_list) = c.list.get(1) {
865			let inverse_list = inverse_list.trim();
866			all_consuming(whitespace_seperated(IntExp::parse))
867				.parse(inverse_list)
868				.map_err(|_| {
869					de::Error::custom(format!("invalid integer expressions `{inverse_list}'"))
870				})?
871				.1
872		} else {
873			Vec::new()
874		};
875
876		Ok(Self {
877			info: c.info,
878			list,
879			inverse_list,
880			value: c.value,
881		})
882	}
883}
884
885impl<Identifier: Display> Serialize for Channel<Identifier> {
886	fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
887		/// Serialize a <channel> element
888		#[derive(Serialize)]
889		#[serde(bound(serialize = "I: Display"))]
890		struct Channel<'a, I: Display> {
891			/// meta information
892			#[serde(flatten)]
893			info: &'a MetaInfo<I>,
894			/// <list> element(s)
895			list: Vec<String>,
896			/// <value> element
897			#[serde(skip_serializing_if = "Option::is_none")]
898			value: &'a Option<IntExp<I>>,
899		}
900
901		let p = |i: &Vec<IntExp<Identifier>>| -> String {
902			i.iter()
903				.map(|e| format!("{}", e))
904				.collect::<Vec<_>>()
905				.join(" ")
906		};
907
908		let mut c = Channel {
909			info: &self.info,
910			list: vec![p(&self.list)],
911			value: &self.value,
912		};
913		if !self.inverse_list.is_empty() {
914			c.list.push(p(&self.inverse_list))
915		}
916		c.serialize(serializer)
917	}
918}
919
920impl<'de, Identifier: FromStr> Deserialize<'de> for Circuit<Identifier> {
921	fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
922		/// Deserializes a <circuit> element
923		#[derive(Deserialize)]
924		#[serde(bound = "Identifier: FromStr")]
925		struct Circuit<Identifier> {
926			/// meta information
927			#[serde(flatten)]
928			info: MetaInfo<Identifier>,
929			/// textual content of the element
930			#[serde(default, deserialize_with = "IntExp::parse_vec", alias = "$text")]
931			simple: Vec<IntExp<Identifier>>,
932			/// <list> element
933			#[serde(default)]
934			list: OffsetList<Identifier>,
935			/// <size> element
936			#[serde(default)]
937			size: Option<IntExp<Identifier>>,
938		}
939		let mut x = Circuit::deserialize(deserializer)?;
940		if !x.simple.is_empty() {
941			x.list = OffsetList {
942				list: x.simple,
943				start_index: 0,
944			};
945		}
946		Ok(Self {
947			info: x.info,
948			list: x.list,
949			size: x.size,
950		})
951	}
952}
953
954impl<'de, Identifier: FromStr> Deserialize<'de> for Condition<Identifier> {
955	fn deserialize<D: Deserializer<'de>>(
956		deserializer: D,
957	) -> Result<Condition<Identifier>, D::Error> {
958		/// Visitor for parsing a condition.
959		struct V<X>(PhantomData<X>);
960		impl<X: FromStr> Visitor<'_> for V<X> {
961			type Value = Condition<X>;
962
963			fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
964				formatter.write_str("a condition")
965			}
966
967			fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
968				let v = v.trim();
969				let mut parser = delimited(
970					char('('),
971					separated_pair(Operator::parse, char(','), Exp::parse),
972					char(')'),
973				);
974				let (_, (operator, operand)) = parser
975					.parse(v)
976					.map_err(|e| E::custom(format!("invalid condition {e:?}")))?;
977				Ok(Condition { operator, operand })
978			}
979		}
980		deserializer.deserialize_str(V(PhantomData::<Identifier>))
981	}
982}
983
984impl<Identifier: Display> Display for Condition<Identifier> {
985	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
986		write!(f, "({},{})", self.operator, self.operand)
987	}
988}
989
990impl<Identifier: Display> Serialize for Condition<Identifier> {
991	fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
992		serializer.serialize_str(&self.to_string())
993	}
994}
995
996impl<Identifier> Default for OffsetList<Identifier> {
997	fn default() -> Self {
998		Self {
999			list: Vec::new(),
1000			start_index: IntVal::default(),
1001		}
1002	}
1003}
1004
1005impl Operator {
1006	fn parse(input: &str) -> IResult<&str, Self> {
1007		map(
1008			alt((
1009				tag("lt"),
1010				tag("le"),
1011				tag("eq"),
1012				tag("ge"),
1013				tag("gt"),
1014				tag("ne"),
1015				tag("in"),
1016			)),
1017			|op| match op {
1018				"lt" => Self::Lt,
1019				"le" => Self::Le,
1020				"eq" => Self::Eq,
1021				"ge" => Self::Ge,
1022				"gt" => Self::Gt,
1023				"ne" => Self::Ne,
1024				"in" => Self::In,
1025				_ => unreachable!(),
1026			},
1027		)
1028		.parse(input)
1029	}
1030}
1031
1032impl<'de> Deserialize<'de> for Operator {
1033	fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Operator, D::Error> {
1034		/// Visitor for parsing a condition.
1035		struct V;
1036		impl Visitor<'_> for V {
1037			type Value = Operator;
1038
1039			fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
1040				formatter.write_str("an operator")
1041			}
1042
1043			fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
1044				let v = v.trim();
1045				Ok(all_consuming(Operator::parse)
1046					.parse(v)
1047					.map_err(|e| E::custom(format!("invalid condition {e:?}")))?
1048					.1)
1049			}
1050		}
1051		deserializer.deserialize_str(V)
1052	}
1053}
1054
1055impl Display for Operator {
1056	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1057		match self {
1058			Operator::Lt => write!(f, "lt"),
1059			Operator::Le => write!(f, "le"),
1060			Operator::Eq => write!(f, "eq"),
1061			Operator::Ge => write!(f, "ge"),
1062			Operator::Gt => write!(f, "gt"),
1063			Operator::Ne => write!(f, "ne"),
1064			Operator::In => write!(f, "in"),
1065		}
1066	}
1067}
1068
1069impl<'de, Identifier: FromStr> Deserialize<'de> for Precedence<Identifier> {
1070	fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
1071		/// Deserialize the <values> element
1072		#[derive(Default, Deserialize)]
1073		struct Values {
1074			/// covered attribute
1075			#[serde(default, rename = "@covered")]
1076			covered: Option<bool>,
1077			/// content of the element
1078			#[serde(rename = "$text", deserialize_with = "deserialize_int_vals")]
1079			list: Vec<IntVal>,
1080		}
1081		/// Deserialize the <precedence> element
1082		#[derive(Deserialize)]
1083		#[serde(bound(deserialize = "Identifier: FromStr", serialize = "Identifier: Display"))]
1084		struct Precedence<Identifier = String> {
1085			/// Meta information
1086			#[serde(flatten)]
1087			info: MetaInfo<Identifier>,
1088			/// <list> element or content of the element
1089			#[serde(
1090				alias = "$text",
1091				deserialize_with = "IntExp::parse_vec",
1092				serialize_with = "serialize_list"
1093			)]
1094			list: Vec<IntExp<Identifier>>,
1095			/// <values> element
1096			#[serde(default)]
1097			values: Values,
1098		}
1099		let x = Precedence::deserialize(deserializer)?;
1100		Ok(Self {
1101			info: x.info,
1102			list: x.list,
1103			values: x.values.list,
1104			covered: x.values.covered.unwrap_or(false),
1105		})
1106	}
1107}
1108
1109impl<Identifier: Display> Serialize for Precedence<Identifier> {
1110	fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1111		/// Serialize the <values> element
1112		#[derive(Serialize)]
1113		struct Values<'a> {
1114			/// covered attribute
1115			#[serde(rename = "@covered", skip_serializing_if = "is_false")]
1116			covered: bool,
1117			/// content of the <values> element
1118			#[serde(rename = "$text", serialize_with = "serialize_list")]
1119			list: &'a Vec<IntVal>,
1120		}
1121		impl Values<'_> {
1122			/// Whether serializing the <values> element can be skipped
1123			fn skip(&self) -> bool {
1124				!self.covered && self.list.is_empty()
1125			}
1126		}
1127		/// Serialize the <precedence> element
1128		#[derive(Serialize)]
1129		#[serde(bound(serialize = "Identifier: Display"))]
1130		struct Precedence<'a, Identifier = String> {
1131			/// Optional meta information
1132			#[serde(flatten)]
1133			info: &'a MetaInfo<Identifier>,
1134			/// <list> element or string content
1135			#[serde(alias = "$text", serialize_with = "serialize_list")]
1136			list: &'a Vec<IntExp<Identifier>>,
1137			/// <values> element
1138			#[serde(skip_serializing_if = "Values::skip")]
1139			values: Values<'a>,
1140		}
1141		let x = Precedence {
1142			info: &self.info,
1143			list: &self.list,
1144			values: Values {
1145				covered: self.covered,
1146				list: &self.values,
1147			},
1148		};
1149		x.serialize(serializer)
1150	}
1151}
1152
1153impl<Identifier: FromStr> Transition<Identifier> {
1154	/// Parse a list of transitions.
1155	fn parse_vec<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<Self>, D::Error> {
1156		/// Visitor for parsing a list of transitions.
1157		struct V<X>(PhantomData<X>);
1158		impl<X: FromStr> Visitor<'_> for V<X> {
1159			type Value = Vec<Transition<X>>;
1160
1161			fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
1162				formatter.write_str("a list of transitions")
1163			}
1164
1165			fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
1166				let v = v.trim();
1167				let transition = map(
1168					(
1169						char('('),
1170						identifier,
1171						char(','),
1172						int,
1173						char(','),
1174						identifier,
1175						char(')'),
1176					),
1177					|(_, from, _, val, _, to, _)| Transition { from, val, to },
1178				);
1179				let (_, v) = all_consuming(sequence(transition))
1180					.parse(v)
1181					.map_err(|_| E::custom(format!("invalid transitions `{v}'")))?;
1182				Ok(v)
1183			}
1184		}
1185		let visitor = V::<Identifier>(PhantomData);
1186		deserializer.deserialize_str(visitor)
1187	}
1188}
1189
1190impl<Identifier: Display> Display for Transition<Identifier> {
1191	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1192		write!(f, "({},{},{})", self.from, self.val, self.to)
1193	}
1194}