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 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 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 pub fn is_constrained(&self) -> bool {
44 self.constraints().any(|_| true)
45 }
46
47 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) -> <erm<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: <erm<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}