proto_vulcan/
lresult.rs

1use crate::lterm::{LTerm, LTermInner};
2use crate::lvalue::LValue;
3use crate::engine::Engine;
4use crate::relation::diseq::DisequalityConstraint;
5use crate::state::constraint::store::ConstraintStore;
6use crate::state::constraint::Constraint;
7use crate::user::User;
8use std::fmt;
9use std::ops::Deref;
10use std::rc::Rc;
11
12#[derive(Clone, Debug)]
13pub struct LResult<U: User, E: Engine<U>>(pub LTerm<U, E>, pub Rc<ConstraintStore<U, E>>);
14
15impl<U, E> LResult<U, E>
16where
17    U: User,
18    E: Engine<U>,
19{
20    /// Check if the wrapped LTerm is an Any-variable with constraints such that it cannot be
21    /// the `exception`.
22    pub fn is_any_except<T>(&self, exception: &T) -> bool
23    where
24        T: PartialEq<LTerm<U, E>>,
25    {
26        if self.0.is_any() {
27            // result is an `any` variable, see if it has the expected constraint
28            for constraint in self.constraints() {
29                if let Some(tree) = constraint.downcast_ref::<DisequalityConstraint<U, E>>() {
30                    for (cu, cv) in tree.smap_ref().iter() {
31                        if &self.0 == cu && exception == cv || &self.0 == cv && exception == cu {
32                            return true;
33                        }
34                    }
35                }
36            }
37        }
38
39        false
40    }
41
42    /// Check if the wrapped LTerm is constrained by any constraint.
43    pub fn is_constrained(&self) -> bool {
44        self.constraints().any(|_| true)
45    }
46
47    /// Returns iterator to constraints that refer to the wrapped LTerm.
48    pub fn constraints<'a>(&'a self) -> impl Iterator<Item = &'a Rc<dyn Constraint<U, E>>> {
49        let anyvars = self.0.anyvars();
50        self.1.relevant(&anyvars)
51    }
52}
53
54impl<U, E> Deref for LResult<U, E>
55where
56    U: User,
57    E: Engine<U>,
58{
59    type Target = LTerm<U, E>;
60
61    fn deref(&self) -> &LTerm<U, E> {
62        &self.0
63    }
64}
65
66impl<U, E> fmt::Display for LResult<U, E>
67where
68    U: User,
69    E: Engine<U>,
70{
71    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72        fmt::Display::fmt(&self.0, f)?;
73        if self.is_constrained() {
74            write!(f, "  where  {{ ")?;
75            self.1.display_relevant(&self.0, f)?;
76            write!(f, " }}")
77        } else {
78            write!(f, "")
79        }
80    }
81}
82
83impl<U, E> PartialEq<LTerm<U, E>> for LResult<U, E>
84where
85    U: User,
86    E: Engine<U>,
87{
88    fn eq(&self, other: &LTerm<U, E>) -> bool {
89        &self.0 == other
90    }
91}
92
93impl<U, E> PartialEq<LResult<U, E>> for LTerm<U, E>
94where
95    U: User,
96    E: Engine<U>,
97{
98    fn eq(&self, other: &LResult<U, E>) -> bool {
99        &other.0 == self
100    }
101}
102
103impl<U, E> PartialEq<LValue> for LResult<U, E>
104where
105    U: User,
106    E: Engine<U>,
107{
108    fn eq(&self, other: &LValue) -> bool {
109        match self.as_ref() {
110            LTermInner::Val(v) => v == other,
111            _ => false,
112        }
113    }
114}
115
116impl<U, E> PartialEq<LResult<U, E>> for LValue
117where
118    U: User,
119    E: Engine<U>,
120{
121    fn eq(&self, other: &LResult<U, E>) -> bool {
122        match other.as_ref() {
123            LTermInner::Val(v) => v == self,
124            _ => false,
125        }
126    }
127}
128
129impl<U, E> PartialEq<bool> for LResult<U, E>
130where
131    U: User,
132    E: Engine<U>,
133{
134    fn eq(&self, other: &bool) -> bool {
135        match self.as_ref() {
136            LTermInner::Val(LValue::Bool(x)) => x == other,
137            _ => false,
138        }
139    }
140}
141
142impl<U, E> PartialEq<LResult<U, E>> for bool
143where
144    U: User,
145    E: Engine<U>,
146{
147    fn eq(&self, other: &LResult<U, E>) -> bool {
148        match other.as_ref() {
149            LTermInner::Val(LValue::Bool(x)) => x == self,
150            _ => false,
151        }
152    }
153}
154
155impl<U, E> PartialEq<isize> for LResult<U, E>
156where
157    U: User,
158    E: Engine<U>,
159{
160    fn eq(&self, other: &isize) -> bool {
161        match self.as_ref() {
162            LTermInner::Val(LValue::Number(x)) => x == other,
163            _ => false,
164        }
165    }
166}
167
168impl<U, E> PartialEq<LResult<U, E>> for isize
169where
170    U: User,
171    E: Engine<U>,
172{
173    fn eq(&self, other: &LResult<U, E>) -> bool {
174        match other.as_ref() {
175            LTermInner::Val(LValue::Number(x)) => x == self,
176            _ => false,
177        }
178    }
179}
180
181impl<U, E> PartialEq<char> for LResult<U, E>
182where
183    U: User,
184    E: Engine<U>,
185{
186    fn eq(&self, other: &char) -> bool {
187        match self.as_ref() {
188            LTermInner::Val(LValue::Char(x)) => x == other,
189            _ => false,
190        }
191    }
192}
193
194impl<U, E> PartialEq<LResult<U, E>> for char
195where
196    U: User,
197    E: Engine<U>,
198{
199    fn eq(&self, other: &LResult<U, E>) -> bool {
200        match other.as_ref() {
201            LTermInner::Val(LValue::Char(x)) => x == self,
202            _ => false,
203        }
204    }
205}
206
207impl<U, E> PartialEq<String> for LResult<U, E>
208where
209    U: User,
210    E: Engine<U>,
211{
212    fn eq(&self, other: &String) -> bool {
213        match self.as_ref() {
214            LTermInner::Val(LValue::String(x)) => x == other,
215            _ => false,
216        }
217    }
218}
219
220impl<U, E> PartialEq<LResult<U, E>> for String
221where
222    U: User,
223    E: Engine<U>,
224{
225    fn eq(&self, other: &LResult<U, E>) -> bool {
226        match other.as_ref() {
227            LTermInner::Val(LValue::String(x)) => x == self,
228            _ => false,
229        }
230    }
231}
232
233impl<U, E> PartialEq<&str> for LResult<U, E>
234where
235    U: User,
236    E: Engine<U>,
237{
238    fn eq(&self, other: &&str) -> bool {
239        match self.as_ref() {
240            LTermInner::Val(LValue::String(x)) => x == other,
241            _ => false,
242        }
243    }
244}
245
246impl<U, E> PartialEq<LResult<U, E>> for &str
247where
248    U: User,
249    E: Engine<U>,
250{
251    fn eq(&self, other: &LResult<U, E>) -> bool {
252        match other.as_ref() {
253            LTermInner::Val(LValue::String(x)) => x == self,
254            _ => false,
255        }
256    }
257}