Skip to main content

conjure_cp_core/ast/
mod.rs

1pub mod abstract_comprehension;
2pub mod ac_operators;
3pub mod assertions;
4mod atom;
5pub mod categories;
6mod cnf_clause;
7pub mod comprehension;
8pub mod declaration;
9mod domains;
10pub mod eval;
11mod expressions;
12mod literals;
13pub mod matrix;
14mod metadata;
15mod model;
16mod name;
17pub mod pretty;
18pub mod records;
19mod reference;
20mod sat_encoding;
21pub mod serde;
22mod symbol_table;
23mod types;
24mod variables;
25
26mod moo;
27mod partial_eval;
28
29pub use atom::Atom;
30pub use cnf_clause::CnfClause;
31pub use declaration::{DeclarationKind, DeclarationPtr};
32pub use domains::{
33    BinaryAttr, Domain, DomainOpError, DomainPtr, FuncAttr, GroundDomain, HasDomain, IntVal,
34    JectivityAttr, MSetAttr, PartialityAttr, PartitionAttr, Range, RelAttr, SequenceAttr, SetAttr,
35    UnresolvedDomain,
36};
37pub use eval::eval_constant;
38pub use expressions::{Expression, discriminant_from_value, print_hash_stats};
39pub use literals::AbstractLiteral;
40pub use literals::Literal;
41pub use metadata::Metadata;
42pub use model::*;
43pub use moo::Moo;
44pub use name::Name;
45pub use partial_eval::run_partial_evaluator;
46pub use records::Field;
47pub use reference::Reference;
48pub use sat_encoding::SATIntEncoding;
49pub use symbol_table::{SymbolTable, SymbolTablePtr};
50pub use types::*;
51pub use variables::DecisionVariable;
52
53/// Helper to build a matrix `AbstractLiteral` with given domains
54#[doc(hidden)]
55#[macro_export]
56macro_rules! __matrix_with_domains {
57    // Base case: 1-D list + one domain.
58    ([$($x:expr),* $(,)?]; [$domain:expr $(,)?]) => (
59        $crate::into_matrix![std::vec![$(<_ as ::std::convert::Into<_>>::into($x)),*]; $domain]
60    );
61
62    // Recursive entry: split first domain from remaining domains.
63    ([[$($x:tt)*] $(, [$($xs:tt)*])* $(,)?]; [$domain:expr, $($rest:expr),+ $(,)?]) => (
64        $crate::__matrix_with_domains!(
65            @recurse
66            $domain;
67            [$($rest),+];
68            [$($x)*] $(, [$($xs)*])*
69        )
70    );
71
72    // Recurse with "rest domains" captured as one token tree ($rest:tt).
73    (@recurse $domain:expr; $rest:tt; [$($x:tt)*] $(, [$($xs:tt)*])*) => (
74        $crate::into_matrix![
75            std::vec![
76                <_ as ::std::convert::Into<_>>::into($crate::__matrix_with_domains!([$($x)*]; $rest))
77                $(, <_ as ::std::convert::Into<_>>::into($crate::__matrix_with_domains!([$($xs)*]; $rest)))*
78            ];
79            $domain
80        ]
81    );
82}
83
84/// Helper to build a matrix `Literal` with given domains
85#[doc(hidden)]
86#[macro_export]
87macro_rules! __matrix_lit_with_domains {
88    // Base case: 1-D list + one domain.
89    ([$($x:expr),* $(,)?]; [$domain:expr $(,)?]) => (
90        $crate::ast::Literal::AbstractLiteral(
91            $crate::into_matrix![std::vec![$($crate::ast::Literal::from($x)),*]; $domain]
92        )
93    );
94
95    // Recursive entry: split first domain from remaining domains.
96    ([[$($x:tt)*] $(, [$($xs:tt)*])* $(,)?]; [$domain:expr, $($rest:expr),+ $(,)?]) => (
97        $crate::__matrix_lit_with_domains!(
98            @recurse
99            $domain;
100            [$($rest),+];
101            [$($x)*] $(, [$($xs)*])*
102        )
103    );
104
105    // Recurse with "rest domains" captured as one token tree ($rest:tt).
106    (@recurse $domain:expr; $rest:tt; [$($x:tt)*] $(, [$($xs:tt)*])*) => (
107        $crate::ast::Literal::AbstractLiteral(
108            $crate::into_matrix![
109                std::vec![
110                    $crate::__matrix_lit_with_domains!([$($x)*]; $rest)
111                    $(, $crate::__matrix_lit_with_domains!([$($xs)*]; $rest))*
112                ];
113                $domain
114            ]
115        )
116    );
117}
118
119/// Creates a new matrix [`Literal`] optionally with some index domain.
120///
121///  - `matrix_lit![a,b,c]`
122///  - `matrix_lit![a,b,c;my_domain]`
123///  - `matrix_lit![[a, b, c], [d, e, f]; [domain_1, domain_2]]`
124///
125/// To create one from a (Rust) vector, use [`into_matrix!`].
126#[macro_export]
127macro_rules! matrix_lit {
128    // Empty
129    () => (
130        $crate::ast::Literal::AbstractLiteral($crate::into_matrix![])
131    );
132
133    (;$domain:expr) => (
134        $crate::ast::Literal::AbstractLiteral($crate::into_matrix![;$domain])
135    );
136
137    // Single element
138    ($x:expr) => (
139        $crate::ast::Literal::AbstractLiteral($crate::into_matrix![std::vec![$crate::ast::Literal::from($x)]])
140    );
141
142    ($x:expr;$domain:expr) => (
143        $crate::ast::Literal::AbstractLiteral($crate::into_matrix![std::vec![$crate::ast::Literal::from($x)];$domain])
144    );
145
146    // Multi-dimensional (delegate to matrix! for structural nesting)
147    ([$($x:tt)*] $(, [$($xs:tt)*])* $(,)?) => (
148        $crate::ast::Literal::from(
149            $crate::matrix![
150                $crate::matrix_lit![$($x)*]
151                $(, $crate::matrix_lit![$($xs)*])*
152            ]
153        )
154    );
155
156    ([$($x:tt)*] $(, [$($xs:tt)*])* ; [$domain:expr $(, $domains:expr)+ $(,)?]) => (
157        $crate::__matrix_lit_with_domains!(
158            [[$($x)*] $(, [$($xs)*])*];
159            [$domain $(, $domains)+]
160        )
161    );
162
163    // 1-Dimensional
164    ($($x:expr),*) => (
165        $crate::ast::Literal::AbstractLiteral($crate::into_matrix![std::vec![$($crate::ast::Literal::from($x)),*]])
166    );
167
168    ($($x:expr),*;$domain:expr) => (
169        $crate::ast::Literal::AbstractLiteral($crate::into_matrix![std::vec![$($crate::ast::Literal::from($x)),*];$domain])
170    );
171
172    ($($x:expr,)*) => (
173        $crate::ast::Literal::AbstractLiteral($crate::into_matrix![std::vec![$($crate::ast::Literal::from($x)),*]])
174    );
175
176    ($($x:expr,)*;$domain:expr) => (
177        $crate::ast::Literal::AbstractLiteral($crate::into_matrix![std::vec![$($crate::ast::Literal::from($x)),*];$domain])
178    )
179}
180
181/// Creates a new matrix [`AbstractLiteral`] optionally with some index domain.
182///
183///  - `matrix![a,b,c]`
184///  - `matrix![a,b,c;my_domain]`
185///  - `matrix![[a, b, c], [d, e, f]]`
186///  - `matrix![[a, b, c], [d, e, f]; [domain_1, domain_2]]`
187///
188/// To create one from a (Rust) vector, use [`into_matrix!`].
189///
190/// To create a matrix [`Literal`] (wrapping elements with `Literal::from`), use [`matrix_lit!`].
191#[macro_export]
192macro_rules! matrix {
193    // cases copied from the std vec! macro
194    () => (
195        $crate::into_matrix![]
196    );
197
198    (;$domain:expr) => (
199        $crate::into_matrix![;$domain]
200    );
201
202    ($x:expr) => (
203        $crate::into_matrix![std::vec![<_ as ::std::convert::Into<_>>::into($x)]]
204    );
205
206    ($x:expr;$domain:expr) => (
207        $crate::into_matrix![std::vec![<_ as ::std::convert::Into<_>>::into($x)];$domain]
208    );
209
210    // Multi-dimensional
211    ([$($x:tt)*] $(, [$($xs:tt)*])* $(,)?) => (
212        $crate::into_matrix![
213            std::vec![
214                <_ as ::std::convert::Into<_>>::into($crate::matrix![$($x)*])
215                $(, <_ as ::std::convert::Into<_>>::into($crate::matrix![$($xs)*]))*
216            ]
217        ]
218    );
219
220    ([$($x:tt)*] $(, [$($xs:tt)*])* ; [$domain:expr $(, $domains:expr)+ $(,)?]) => (
221        $crate::__matrix_with_domains!(
222            [[$($x)*] $(, [$($xs)*])*];
223            [$domain $(, $domains)+]
224        )
225    );
226
227    // 1-Dimensional
228    ($($x:expr),*) => (
229        $crate::into_matrix![std::vec![$(<_ as ::std::convert::Into<_>>::into($x)),*]]
230    );
231
232    ($($x:expr),*;$domain:expr) => (
233        $crate::into_matrix![std::vec![$(<_ as ::std::convert::Into<_>>::into($x)),*];$domain]
234    );
235
236    ($($x:expr,)*) => (
237        $crate::into_matrix![std::vec![$(<_ as ::std::convert::Into<_>>::into($x)),*]]
238    );
239
240    ($($x:expr,)*;$domain:expr) => (
241        $crate::into_matrix![std::vec![$(<_ as ::std::convert::Into<_>>::into($x)),*];$domain]
242    )
243}
244
245/// Creates a new matrix [`AbstractLiteral`] from some [`Vec`], optionally with some index domain.
246///
247///  - `matrix![my_vec]`
248///  - `matrix![my_vec;my_domain]`
249///
250/// To create one from a list of elements, use [`matrix!`].
251#[macro_export]
252macro_rules! into_matrix {
253    () => (
254        $crate::into_matrix![std::vec::Vec::new()]
255    );
256
257    (;$domain:expr) => (
258        $crate::into_matrix![std::vec::Vec::new();$domain]
259    );
260    ($x:expr) => (
261        $crate::ast::AbstractLiteral::matrix_implied_indices($x)
262    );
263    ($x:expr;$domain:expr) => (
264        $crate::ast::AbstractLiteral::Matrix($x,$domain)
265    );
266}
267
268/// Creates a new matrix as an [`Expression`], optionally with some index domain.
269///
270/// For usage details, see [`matrix!`].
271///
272/// To create a matrix expression from a [`Vec`], use [`into_matrix_expr!`].
273#[macro_export]
274macro_rules! matrix_expr {
275    () => (
276        $crate::ast::Expression::AbstractLiteral($crate::ast::Metadata::new(),$crate::into_matrix![])
277    );
278
279    (;$domain:expr) => (
280        $crate::ast::Expression::AbstractLiteral($crate::ast::Metadata::new(),$crate::into_matrix![;$domain])
281    );
282
283
284    ($x:expr) => (
285        $crate::ast::Expression::AbstractLiteral($crate::ast::Metadata::new(),$crate::into_matrix![std::vec![$x]])
286    );
287    ($x:expr;$domain:expr) => (
288        $crate::ast::Expression::AbstractLiteral($crate::ast::Metadata::new(),$crate::into_matrix![std::vec![$x];$domain])
289    );
290
291    ($($x:expr),+) => (
292        $crate::ast::Expression::AbstractLiteral($crate::ast::Metadata::new(),$crate::into_matrix![std::vec![$($x),+]])
293    );
294
295    ($($x:expr),+;$domain:expr) => (
296        $crate::ast::Expression::AbstractLiteral($crate::ast::Metadata::new(),$crate::into_matrix![std::vec![$($x),+];$domain])
297    );
298
299    ($($x:expr,)+) => (
300        $crate::ast::Expression::AbstractLiteral($crate::ast::Metadata::new(),$crate::into_matrix![std::vec![$($x),+]])
301    );
302
303    ($($x:expr,)+;$domain:expr) => (
304        $crate::ast::Expression::AbstractLiteral($crate::ast::Metadata::new(),$crate::into_matrix![std::vec![$($x),+];$domain])
305    )
306}
307
308/// Creates a new matrix as an [`Expression`] from a (Rust) vector, optionally with some index
309/// domain.
310///
311/// For usage details, see [`into_matrix!`].
312///
313/// To create a matrix expression from a list of elements, use [`matrix_expr!`].
314#[macro_export]
315macro_rules! into_matrix_expr {
316    () => (
317        $crate::ast::Expression::AbstractLiteral($crate::ast::Metadata::new(),$crate::into_matrix![])
318    );
319
320    (;$domain:expr) => (
321        $crate::ast::Expression::AbstractLiteral($crate::ast::Metadata::new(),$crate::into_matrix![;$domain])
322    );
323    ($x:expr) => (
324        $crate::ast::Expression::AbstractLiteral($crate::ast::Metadata::new(),$crate::into_matrix![$x])
325    );
326    ($x:expr;$domain:expr) => (
327        $crate::ast::Expression::AbstractLiteral($crate::ast::Metadata::new(),$crate::into_matrix![$x;$domain])
328    );
329}