1use crate::{
2 ToJson,
3 env::{Atom, BoolExpr, CommonEnv, Env, Var},
4 language::{Disjunction, RiddleError, execute},
5 parse_problem,
6 scope::{BoolType, CommonScope, Field, IntType, Method, Predicate, RealType, Scope, StringType, Type},
7};
8use serde_json::{Value, json};
9use std::{
10 collections::{HashMap, VecDeque},
11 rc::{Rc, Weak},
12};
13
14pub trait Core: Scope + Env {
15 fn new_bool(&self, value: bool) -> Rc<dyn Var>;
16 fn new_bool_var(&self) -> Rc<dyn Var>;
17 fn new_int(&self, value: i64) -> Rc<dyn Var>;
18 fn new_int_var(&self) -> Rc<dyn Var>;
19 fn new_real(&self, num: i64, den: i64) -> Rc<dyn Var>;
20 fn new_real_var(&self) -> Rc<dyn Var>;
21 fn new_string(&self, value: &str) -> Rc<dyn Var>;
22 fn new_string_var(&self) -> Rc<dyn Var>;
23
24 fn sum(&self, sum: &[Rc<dyn Var>]) -> Result<Rc<dyn Var>, RiddleError>;
25 fn opposite(&self, term: Rc<dyn Var>) -> Result<Rc<dyn Var>, RiddleError>;
26 fn mul(&self, mul: &[Rc<dyn Var>]) -> Result<Rc<dyn Var>, RiddleError>;
27 fn div(&self, left: Rc<dyn Var>, right: Rc<dyn Var>) -> Result<Rc<dyn Var>, RiddleError>;
28
29 fn assert(&self, term: Rc<BoolExpr>) -> bool;
30 fn new_var(&self, class: Rc<dyn Type>, instances: &[Rc<dyn Var>]) -> Result<Rc<dyn Var>, RiddleError>;
31 fn new_disjunction(&self, disjunction: Disjunction);
32 fn new_atom(&self, atom: Rc<Atom>);
33
34 fn bool_type(&self) -> Rc<BoolType> {
35 self.get_type("bool").expect("Core should have bool type").as_any().downcast::<BoolType>().expect("Core bool type should be BoolType")
36 }
37
38 fn int_type(&self) -> Rc<IntType> {
39 self.get_type("int").expect("Core should have int type").as_any().downcast::<IntType>().expect("Core int type should be IntType")
40 }
41
42 fn real_type(&self) -> Rc<RealType> {
43 self.get_type("real").expect("Core should have real type").as_any().downcast::<RealType>().expect("Core real type should be RealType")
44 }
45
46 fn string_type(&self) -> Rc<StringType> {
47 self.get_type("string").expect("Core should have string type").as_any().downcast::<StringType>().expect("Core string type should be StringType")
48 }
49}
50
51#[derive(Debug)]
52pub struct CommonCore {
53 scope: Rc<CommonScope>,
54 env: Rc<CommonEnv>,
55}
56
57impl CommonCore {
58 pub fn new(core: Weak<dyn Core>) -> Rc<Self> {
63 let c_core = Rc::new(CommonCore { scope: Rc::new(CommonScope::new(core.clone(), None)), env: Rc::new(CommonEnv::new(None)) });
64 c_core.add_type(Rc::new(BoolType::new(core.clone())));
65 c_core.add_type(Rc::new(IntType::new(core.clone())));
66 c_core.add_type(Rc::new(RealType::new(core.clone())));
67 c_core.add_type(Rc::new(StringType::new(core.clone())));
68 c_core
69 }
70
71 pub fn read(&self, riddle: &str) -> Result<(), RiddleError> {
79 let mut problem = parse_problem(riddle)?;
80 let statments = std::mem::take(&mut problem.statements);
81 self.scope.add_problem(problem);
82 for stmt in statments {
83 execute(self.scope.clone(), self.env.clone(), &stmt)?;
84 }
85 Ok(())
86 }
87
88 pub fn add_type(&self, class: Rc<dyn Type>) {
90 self.scope.classes.borrow_mut().insert(class.name().to_string(), class);
91 }
92}
93
94impl ToJson for CommonCore {
95 fn to_json(&self) -> Value {
96 let mut terms = HashMap::new();
97 let mut atoms = HashMap::new();
98 let mut q = VecDeque::new();
99 for tp in self.scope.classes.borrow().values() {
100 if let Some(class) = tp.clone().as_class() {
101 q.push_back(class.clone());
102 }
103 }
104 while let Some(tp) = q.pop_front() {
105 for instance in tp.instances() {
106 let id = Rc::as_ptr(&instance) as *const () as usize;
107 terms.insert(id, instance.var_type().name().to_string());
108 }
109 for pred in tp.predicates() {
110 for atom in pred.atoms() {
111 let id = Rc::as_ptr(&atom) as *const () as usize;
112 atoms.insert(id, pred.name().to_string());
113 }
114 }
115 for class in tp.classes() {
116 q.push_back(class);
117 }
118 }
119 json!({ "terms": terms, "atoms": atoms })
120 }
121}
122
123impl Scope for CommonCore {
124 fn core(self: Rc<Self>) -> Rc<dyn Core> {
125 self.scope.clone().core()
126 }
127
128 fn scope(&self) -> Option<Rc<dyn Scope>> {
129 None
130 }
131
132 fn get_field(&self, _name: &str) -> Option<Rc<Field>> {
133 self.scope.get_field(_name)
134 }
135
136 fn get_method(&self, _name: &str, _classes: &[Rc<dyn Type>]) -> Option<Rc<Method>> {
137 self.scope.get_method(_name, _classes)
138 }
139
140 fn get_type(&self, name: &str) -> Option<Rc<dyn Type>> {
141 self.scope.get_type(name)
142 }
143
144 fn get_predicate(&self, _name: &str) -> Option<Rc<Predicate>> {
145 self.scope.get_predicate(_name)
146 }
147}
148
149impl Env for CommonCore {
150 fn parent(&self) -> Option<Rc<dyn Env>> {
151 None
152 }
153
154 fn get(&self, name: &str) -> Option<Rc<dyn Var>> {
155 self.env.get(name)
156 }
157
158 fn set(&self, name: String, value: Rc<dyn Var>) {
159 self.env.set(name, value);
160 }
161}
162
163#[cfg(test)]
164mod tests {
165 use super::*;
166 use std::{any::Any, cell::RefCell};
167
168 #[derive(Debug)]
169 struct TestObject {
170 class: Weak<dyn Type>,
171 _id: usize,
172 }
173
174 impl Var for TestObject {
175 fn var_type(&self) -> Rc<dyn Type> {
176 self.class.upgrade().expect("Class should still exist")
177 }
178
179 fn as_any(self: Rc<Self>) -> Rc<dyn Any> {
180 self
181 }
182 }
183
184 #[derive(Debug)]
185 struct TestCore {
186 core: Rc<CommonCore>,
187 id_counter: RefCell<usize>,
188 }
189
190 impl TestCore {
191 fn new() -> Rc<Self> {
192 Rc::new_cyclic(|core| Self {
193 core: {
194 let core: Weak<TestCore> = core.clone();
195 CommonCore::new(core)
196 },
197 id_counter: RefCell::new(0),
198 })
199 }
200
201 fn read(&self, riddle: &str) -> Result<(), RiddleError> {
202 self.core.read(riddle)
203 }
204
205 fn next_id(&self) -> usize {
206 let mut counter = self.id_counter.borrow_mut();
207 let id = *counter;
208 *counter += 1;
209 id
210 }
211 }
212
213 impl Core for TestCore {
214 fn new_bool(&self, _value: bool) -> Rc<dyn Var> {
215 Rc::new(TestObject { class: Rc::downgrade(&(self.bool_type() as Rc<dyn Type>)), _id: self.next_id() })
216 }
217
218 fn new_bool_var(&self) -> Rc<dyn Var> {
219 Rc::new(TestObject { class: Rc::downgrade(&(self.bool_type() as Rc<dyn Type>)), _id: self.next_id() })
220 }
221
222 fn new_int(&self, _value: i64) -> Rc<dyn Var> {
223 Rc::new(TestObject { class: Rc::downgrade(&(self.int_type() as Rc<dyn Type>)), _id: self.next_id() })
224 }
225
226 fn new_int_var(&self) -> Rc<dyn Var> {
227 Rc::new(TestObject { class: Rc::downgrade(&(self.int_type() as Rc<dyn Type>)), _id: self.next_id() })
228 }
229
230 fn new_real(&self, _num: i64, _den: i64) -> Rc<dyn Var> {
231 Rc::new(TestObject { class: Rc::downgrade(&(self.real_type() as Rc<dyn Type>)), _id: self.next_id() })
232 }
233
234 fn new_real_var(&self) -> Rc<dyn Var> {
235 Rc::new(TestObject { class: Rc::downgrade(&(self.real_type() as Rc<dyn Type>)), _id: self.next_id() })
236 }
237
238 fn new_string(&self, _value: &str) -> Rc<dyn Var> {
239 Rc::new(TestObject { class: Rc::downgrade(&(self.string_type() as Rc<dyn Type>)), _id: self.next_id() })
240 }
241
242 fn new_string_var(&self) -> Rc<dyn Var> {
243 Rc::new(TestObject { class: Rc::downgrade(&(self.string_type() as Rc<dyn Type>)), _id: self.next_id() })
244 }
245
246 fn sum(&self, _sum: &[Rc<dyn Var>]) -> Result<Rc<dyn Var>, RiddleError> {
247 Ok(Rc::new(TestObject { class: Rc::downgrade(&(self.int_type() as Rc<dyn Type>)), _id: self.next_id() }))
248 }
249
250 fn opposite(&self, _term: Rc<dyn Var>) -> Result<Rc<dyn Var>, RiddleError> {
251 Ok(Rc::new(TestObject { class: Rc::downgrade(&(self.int_type() as Rc<dyn Type>)), _id: self.next_id() }))
252 }
253
254 fn mul(&self, _mul: &[Rc<dyn Var>]) -> Result<Rc<dyn Var>, RiddleError> {
255 Ok(Rc::new(TestObject { class: Rc::downgrade(&(self.int_type() as Rc<dyn Type>)), _id: self.next_id() }))
256 }
257
258 fn div(&self, _left: Rc<dyn Var>, _right: Rc<dyn Var>) -> Result<Rc<dyn Var>, RiddleError> {
259 Ok(Rc::new(TestObject { class: Rc::downgrade(&(self.int_type() as Rc<dyn Type>)), _id: self.next_id() }))
260 }
261
262 fn assert(&self, _term: Rc<BoolExpr>) -> bool {
263 true
264 }
265
266 fn new_var(&self, class: Rc<dyn Type>, instances: &[Rc<dyn Var>]) -> Result<Rc<dyn Var>, RiddleError> {
267 if instances.is_empty() {
268 return Err(RiddleError::InconsistencyError("Cannot create variable with no instances".into()));
269 }
270 Ok(Rc::new(TestObject { class: Rc::downgrade(&class), _id: self.next_id() }))
271 }
272
273 fn new_disjunction(&self, _disjunction: Disjunction) {}
274
275 fn new_atom(&self, _atom: Rc<Atom>) {}
276 }
277
278 impl Scope for TestCore {
279 fn core(self: Rc<Self>) -> Rc<dyn Core> {
280 self
281 }
282
283 fn scope(&self) -> Option<Rc<dyn Scope>> {
284 None
285 }
286
287 fn get_field(&self, _name: &str) -> Option<Rc<Field>> {
288 None
289 }
290
291 fn get_method(&self, name: &str, classes: &[Rc<dyn Type>]) -> Option<Rc<Method>> {
292 self.core.get_method(name, classes)
293 }
294
295 fn get_type(&self, name: &str) -> Option<Rc<dyn Type>> {
296 self.core.get_type(name)
297 }
298
299 fn get_predicate(&self, name: &str) -> Option<Rc<Predicate>> {
300 self.core.get_predicate(name)
301 }
302 }
303
304 impl Env for TestCore {
305 fn parent(&self) -> Option<Rc<dyn Env>> {
306 None
307 }
308
309 fn get(&self, name: &str) -> Option<Rc<dyn Var>> {
310 self.core.get(name)
311 }
312
313 fn set(&self, name: String, value: Rc<dyn Var>) {
314 self.core.set(name, value);
315 }
316 }
317
318 #[test]
319 fn create_core() {
320 let core = TestCore::new();
321 assert!(core.get_type("bool").is_some());
322 assert!(core.get_type("int").is_some());
323 assert!(core.get_type("real").is_some());
324 assert!(core.get_type("string").is_some());
325 }
326
327 #[test]
328 fn read_problem() {
329 let core = TestCore::new();
330 core.read("bool a, b, c; (a & b) | c;").expect("Failed to read problem with boolean variables and expression");
331 }
332
333 #[test]
334 fn nested_classes_are_registered_in_class_scope() {
335 let core = TestCore::new();
336 core.read(
337 r#"
338 class Outer {
339 class Inner {}
340 }
341 "#,
342 )
343 .expect("Failed to read problem with nested classes");
344
345 let outer = core.get_type("Outer").expect("Outer class should be registered").as_class().expect("Outer should be a class");
346 let inner = outer.get_type("Inner").expect("Inner class should be registered in the enclosing class scope");
347
348 assert_eq!(inner.full_name(), "Outer.Inner");
349 }
350}