Skip to main content

conjure_cp_core/ast/
variables.rs

1use std::fmt::Display;
2
3use super::categories::{Category, CategoryOf};
4use crate::representation::Representation;
5use conjure_cp_core::ast::DomainPtr;
6use conjure_cp_core::ast::domains::HasDomain;
7use derivative::Derivative;
8use serde::{Deserialize, Serialize};
9
10/// Represents a decision variable within a computational model.
11///
12/// A `DecisionVariable` has a domain that defines the set of values it can take. The domain could be:
13/// - A boolean domain, meaning the variable can only be `true` or `false`.
14/// - An integer domain, meaning the variable can only take specific integer values or a range of integers.
15///
16/// # Fields
17/// - `domain`:
18///   - Type: `Domain`
19///   - Represents the set of possible values that this decision variable can assume. The domain can be a range of integers
20///     (IntDomain) or a boolean domain (BoolDomain).
21///
22/// # Example
23///
24/// use crate::ast::domains::{DecisionVariable, Domain, Range};
25///
26/// let bool_var = DecisionVariable::new(Domain::BoolDomain);
27/// let int_var = DecisionVariable::new(Domain::IntDomain(vec![Range::Bounded(1, 10)]));
28///
29/// println!("Boolean Variable: {}", bool_var);
30/// println!("Integer Variable: {}", int_var);
31
32#[derive(Clone, Debug, Serialize, Deserialize, Derivative)]
33#[derivative(Hash, PartialEq, Eq)]
34pub struct DecisionVariable {
35    pub domain: DomainPtr,
36
37    /// Per-element domains for a matrix find, parallel to the flat elements of a components
38    /// representation.
39    ///
40    /// When present, representation instantiation uses these instead of repeating the declared
41    /// inner domain. Used by the pre-rewrite domain-tightening pass when a `forAll` over a matrix
42    /// of sequences proves a different `|m[i]|` at each index.
43    ///
44    /// Re-inferred each rewrite, so it is not serialised.
45    #[serde(skip)]
46    pub element_domains: Option<Vec<DomainPtr>>,
47
48    // use this through [`Declaration`] - in the future, this probably will be stored in
49    // declaration / domain, not here.
50    #[serde(skip)]
51    #[derivative(Hash = "ignore", PartialEq = "ignore")]
52    pub(super) representations: Vec<Vec<Box<dyn Representation>>>,
53}
54
55impl DecisionVariable {
56    pub fn new(domain: DomainPtr) -> DecisionVariable {
57        DecisionVariable {
58            domain,
59            element_domains: None,
60            representations: vec![],
61        }
62    }
63}
64
65impl CategoryOf for DecisionVariable {
66    fn category_of(&self) -> Category {
67        Category::Decision
68    }
69}
70
71impl HasDomain for DecisionVariable {
72    fn domain_of(&self) -> DomainPtr {
73        self.domain.clone()
74    }
75}
76
77impl Display for DecisionVariable {
78    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79        self.domain.fmt(f)
80    }
81}