1use crate::{
2 RiddleError,
3 core::Core,
4 env::{Atom, AtomId, BoolExpr, CommonEnv, Env, ObjectId, Slot, Var},
5 language::{ClassDef, ConstructorDef, Expr, FunctionDef, PredicateDef, ProblemDef, Statement, evaluate, execute},
6};
7use std::{
8 cell::RefCell,
9 collections::HashMap,
10 fmt,
11 rc::{Rc, Weak},
12};
13
14pub trait Type {
15 fn name(&self) -> &str;
17 fn full_name(&self) -> String {
19 self.name().to_string()
20 }
21 fn as_class(self: Rc<Self>) -> Option<Rc<dyn Class>> {
22 None
23 }
24
25 fn new_instance(self: Rc<Self>) -> Slot;
27}
28
29pub struct BoolType {
30 core: Weak<dyn Core>,
31}
32
33impl BoolType {
34 pub fn new(core: Weak<dyn Core>) -> Self {
36 Self { core }
37 }
38}
39
40impl Type for BoolType {
41 fn name(&self) -> &str {
42 "bool"
43 }
44
45 fn new_instance(self: Rc<Self>) -> Slot {
46 let var_type = Rc::downgrade(&self);
47 Slot::Primitive(Rc::new(BoolExpr::Term { var_type, term: self.core.upgrade().unwrap().new_bool_var() }))
48 }
49}
50
51pub struct IntType {
52 core: Weak<dyn Core>,
53}
54
55impl IntType {
56 pub fn new(core: Weak<dyn Core>) -> Self {
58 Self { core }
59 }
60}
61
62impl Type for IntType {
63 fn name(&self) -> &str {
64 "int"
65 }
66
67 fn new_instance(self: Rc<Self>) -> Slot {
68 self.core.upgrade().unwrap().new_int_var()
69 }
70}
71
72pub struct RealType {
73 core: Weak<dyn Core>,
74}
75
76impl RealType {
77 pub fn new(core: Weak<dyn Core>) -> Self {
79 Self { core }
80 }
81}
82
83impl Type for RealType {
84 fn name(&self) -> &str {
85 "real"
86 }
87
88 fn new_instance(self: Rc<Self>) -> Slot {
89 self.core.upgrade().unwrap().new_real_var()
90 }
91}
92
93pub struct StringType {
94 core: Weak<dyn Core>,
95}
96
97impl StringType {
98 pub fn new(core: Weak<dyn Core>) -> Self {
100 Self { core }
101 }
102}
103
104impl Type for StringType {
105 fn name(&self) -> &str {
106 "string"
107 }
108
109 fn new_instance(self: Rc<Self>) -> Slot {
110 self.core.upgrade().unwrap().new_string_var()
111 }
112}
113
114pub struct Field {
115 name: String,
116 field_type: Vec<String>,
117 default: Option<Expr>,
118}
119
120impl Field {
121 pub fn new(name: String, field_type: Vec<String>, default: Option<Expr>) -> Self {
123 Self { name, field_type, default }
124 }
125
126 pub fn name(&self) -> &str {
127 &self.name
128 }
129
130 pub fn field_type(&self) -> &[String] {
131 &self.field_type
132 }
133
134 pub fn default(&self) -> Option<&Expr> {
135 self.default.as_ref()
136 }
137}
138
139pub trait Scope {
140 fn core(&self) -> Rc<dyn Core>;
141 fn scope(&self) -> Option<Rc<dyn Scope>>;
142 fn as_class(self: Rc<Self>) -> Option<Rc<dyn Class>> {
143 None
144 }
145
146 fn get_fields(&self) -> Vec<Rc<Field>>;
147 fn get_field(&self, name: &str) -> Option<Rc<Field>>;
148 fn get_function(&self, name: &str, types: &[Rc<dyn Type>]) -> Option<Rc<Function>>;
149 fn get_type(&self, name: &str) -> Option<Rc<dyn Type>>;
150 fn get_predicate(&self, name: &str) -> Option<Rc<Predicate>>;
151}
152
153pub struct CommonScope {
154 core: Weak<dyn Core>,
155 scope: Option<Weak<dyn Scope>>,
156 fields: RefCell<HashMap<String, Rc<Field>>>,
157 functions: RefCell<HashMap<String, Vec<Rc<Function>>>>,
158 pub(crate) types: RefCell<HashMap<String, Rc<dyn Type>>>,
159 predicates: RefCell<HashMap<String, Rc<Predicate>>>,
160}
161
162impl CommonScope {
163 pub fn new(core: Weak<dyn Core>, scope: Option<Weak<dyn Scope>>) -> Self {
165 Self {
166 core,
167 scope,
168 fields: RefCell::new(HashMap::new()),
169 functions: RefCell::new(HashMap::new()),
170 types: RefCell::new(HashMap::new()),
171 predicates: RefCell::new(HashMap::new()),
172 }
173 }
174
175 pub fn from_class(parent_scope: Weak<dyn Scope>, class: ClassDef) -> Rc<Self> {
177 let scope = Rc::new(Self::new(Rc::downgrade(&parent_scope.upgrade().expect("Scope should be valid when building class scope").core()), Some(parent_scope)));
178 let weak_scope = Rc::downgrade(&scope);
179 for (field_type, fields) in class.fields {
180 for (name, default) in fields {
181 scope.fields.borrow_mut().insert(name.clone(), Rc::new(Field { name, field_type: field_type.clone(), default }));
182 }
183 }
184 for function_def in class.functions {
185 scope.functions.borrow_mut().entry(function_def.name.clone()).or_default().push(Function::new(weak_scope.clone(), function_def));
186 }
187 for class_def in class.classes {
188 let class_name = class_def.name.clone();
189 scope.types.borrow_mut().insert(class_name, CommonClass::new(weak_scope.clone(), class_def));
190 }
191 for predicate_def in class.predicates {
192 scope.predicates.borrow_mut().insert(predicate_def.name.clone(), Predicate::new(weak_scope.clone(), predicate_def));
193 }
194 scope
195 }
196
197 pub fn from_constructor(parent_scope: Weak<dyn Class>, constructor: ConstructorDef) -> Self {
199 let scope = Self::new(Rc::downgrade(&parent_scope.upgrade().expect("Class should be valid when building constructor scope").core()), Some(parent_scope));
200 for (arg_type, arg_name) in constructor.args {
201 scope.fields.borrow_mut().insert(arg_name.clone(), Rc::new(Field { name: arg_name, field_type: arg_type, default: None }));
202 }
203 scope
204 }
205
206 pub fn from_function(parent_scope: Weak<dyn Scope>, function: FunctionDef) -> Self {
208 let scope = Self::new(Rc::downgrade(&parent_scope.upgrade().expect("Scope should be valid when building function scope").core()), Some(parent_scope));
209 for (arg_type, arg_name) in function.args {
210 scope.fields.borrow_mut().insert(arg_name.clone(), Rc::new(Field { name: arg_name, field_type: arg_type, default: None }));
211 }
212 scope
213 }
214
215 pub fn from_predicate(parent_scope: Weak<dyn Scope>, predicate: PredicateDef) -> Self {
217 let scope = Self::new(Rc::downgrade(&parent_scope.upgrade().expect("Scope should be valid when building predicate scope").core()), Some(parent_scope));
218 for (arg_type, arg_name) in predicate.args {
219 scope.fields.borrow_mut().insert(arg_name.clone(), Rc::new(Field { name: arg_name, field_type: arg_type, default: None }));
220 }
221 scope
222 }
223
224 pub fn add_problem(self: Rc<Self>, problem: ProblemDef) {
226 let scope = Rc::downgrade(&self);
227 for function_def in problem.functions {
228 self.functions.borrow_mut().entry(function_def.name.clone()).or_default().push(Function::new(scope.clone(), function_def));
229 }
230 for class_def in problem.classes {
231 self.types.borrow_mut().insert(class_def.name.clone(), CommonClass::new(scope.clone(), class_def));
232 }
233 for predicate_def in problem.predicates {
234 self.predicates.borrow_mut().insert(predicate_def.name.clone(), Predicate::new(scope.clone(), predicate_def));
235 }
236 }
237}
238
239impl Scope for CommonScope {
240 fn core(&self) -> Rc<dyn Core> {
241 self.core.upgrade().expect("Core should never be dropped while scopes exist")
242 }
243
244 fn scope(&self) -> Option<Rc<dyn Scope>> {
245 self.scope.as_ref()?.upgrade()
246 }
247
248 fn get_type(&self, name: &str) -> Option<Rc<dyn Type>> {
249 self.types.borrow().get(name).cloned().or_else(|| self.scope()?.get_type(name))
250 }
251
252 fn get_predicate(&self, name: &str) -> Option<Rc<Predicate>> {
253 self.predicates.borrow().get(name).cloned().or_else(|| self.scope()?.get_predicate(name))
254 }
255
256 fn get_fields(&self) -> Vec<Rc<Field>> {
257 self.fields.borrow().values().cloned().collect()
258 }
259
260 fn get_field(&self, name: &str) -> Option<Rc<Field>> {
261 self.fields.borrow().get(name).cloned().or_else(|| self.scope()?.get_field(name))
262 }
263
264 fn get_function(&self, name: &str, types: &[Rc<dyn Type>]) -> Option<Rc<Function>> {
265 self.functions
266 .borrow()
267 .get(name)
268 .and_then(|functions| {
269 functions
270 .iter()
271 .find(|function| {
272 if function.args().len() != types.len() {
273 return false;
274 }
275 for (class, arg_type) in types.iter().zip(function.args().iter().map(|(t, _)| t)) {
276 if !get_type_by_path(self, arg_type).ok().is_some_and(|t| is_assignable_from(&t, class)) {
277 return false;
278 }
279 }
280 true
281 })
282 .cloned()
283 })
284 .or_else(|| self.scope.as_ref()?.upgrade()?.get_function(name, types))
285 }
286}
287
288pub struct Constructor {
290 scope: Rc<CommonScope>,
291 args: Vec<(Vec<String>, String)>,
292 init: Vec<(Vec<String>, Vec<Expr>)>,
293 statements: Vec<Statement>,
294}
295
296impl Constructor {
297 pub fn new(parent_scope: Weak<dyn Class>, mut constructor: ConstructorDef) -> Self {
299 Self {
300 args: std::mem::take(&mut constructor.args),
301 statements: std::mem::take(&mut constructor.statements),
302 init: std::mem::take(&mut constructor.init),
303 scope: Rc::new(CommonScope::from_constructor(parent_scope, constructor)),
304 }
305 }
306
307 pub fn args(&self) -> &[(Vec<String>, String)] {
308 &self.args
309 }
310
311 pub fn statements(&self) -> &[Statement] {
312 &self.statements
313 }
314
315 pub fn call(&self, object: ObjectId, args: Vec<Slot>) -> Result<(), RiddleError> {
317 if args.len() != self.args.len() {
318 return Err(RiddleError::RuntimeError(format!("Expected {} arguments, got {}", self.args.len(), args.len())));
319 }
320 let obj_env = self.core().get_object(object).ok_or_else(|| RiddleError::NotFound(format!("Object {} not found", *object)))?.as_env().ok_or_else(|| RiddleError::RuntimeError("Object environment not found".into()))?;
321 let constructor_env = Rc::new(CommonEnv::new(Some(obj_env.clone())));
323 constructor_env.set("this".to_string(), Slot::ObjectRef(object));
324 for ((arg_type, arg_name), arg_value) in self.args.iter().zip(args) {
325 let expected_type = get_type_by_path(self.scope.as_ref(), arg_type)?;
326 let arg_value_type = match &arg_value {
327 Slot::Primitive(p) => p.var_type(),
328 Slot::ObjectRef(obj_id) => self.scope.core().get_object(*obj_id).ok_or_else(|| RiddleError::NotFound(format!("Object {}", *obj_id)))?.var_type(),
329 Slot::AtomRef(atom_id) => self.scope.core().get_atom(*atom_id).ok_or_else(|| RiddleError::NotFound(format!("Atom {}", *atom_id)))?.var_type(),
330 };
331 if !is_assignable_from(&expected_type, &arg_value_type) {
332 return Err(RiddleError::TypeError(format!("Argument '{}' expected to be of type '{}', got '{}'", arg_name, expected_type.full_name(), arg_value_type.full_name())));
333 }
334 constructor_env.set(arg_name.clone(), arg_value);
335 }
336
337 let class = self.scope.scope.as_ref().and_then(|s| s.upgrade()).and_then(|s| s.as_class()).ok_or_else(|| RiddleError::RuntimeError("Constructor is not defined within a class".into()))?;
338 for parent in class.parents() {
340 let parent_class = get_type_by_path(self.scope.as_ref(), parent)?.as_class().ok_or_else(|| RiddleError::NotAClass(parent.join(".")))?;
341 if let Some((_, init_exprs)) = self.init.iter().find(|(init_field, _)| init_field.iter().map(|s| s.as_str()).eq(parent.iter().map(|s| s.as_str()))) {
342 let exprs = init_exprs.iter().map(|e| evaluate(self.scope.as_ref(), constructor_env.clone(), e)).collect::<Result<Vec<_>, _>>()?;
343 let types = exprs
344 .iter()
345 .map(|e| match e {
346 Slot::Primitive(p) => Ok(p.var_type()),
347 Slot::ObjectRef(obj_id) => Ok(self.scope.core().get_object(*obj_id).ok_or_else(|| RiddleError::NotFound(format!("Object {}", *obj_id)))?.var_type()),
348 Slot::AtomRef(atom_id) => Ok(self.scope.core().get_atom(*atom_id).ok_or_else(|| RiddleError::NotFound(format!("Atom {}", *atom_id)))?.var_type()),
349 })
350 .collect::<Result<Vec<_>, _>>()?;
351 let constructor = parent_class.constructor(&types).ok_or_else(|| RiddleError::NotFound(format!("Constructor for parent class '{}' with specified argument types", parent_class.full_name())))?;
352 constructor.call(object, exprs)?;
353 } else {
354 let constructor = parent_class.constructor(&[]).ok_or_else(|| RiddleError::NotFound(format!("No-arg constructor for parent class '{}'", parent_class.full_name())))?;
355 constructor.call(object, vec![])?;
356 }
357 }
358
359 for field in class.get_fields() {
361 let fld_tp = get_type_by_path(self.scope.as_ref(), field.field_type())?;
362 if obj_env.get(field.name()).is_none() {
363 if let Some(default_expr) = field.default() {
364 let value = evaluate(self.scope.as_ref(), constructor_env.clone(), default_expr)?;
365 let value_type = match &value {
366 Slot::Primitive(p) => p.var_type(),
367 Slot::ObjectRef(obj_id) => self.scope.core().get_object(*obj_id).ok_or_else(|| RiddleError::NotFound(format!("Object {}", *obj_id)))?.var_type(),
368 Slot::AtomRef(atom_id) => self.scope.core().get_atom(*atom_id).ok_or_else(|| RiddleError::NotFound(format!("Atom {}", *atom_id)))?.var_type(),
369 };
370 if !is_assignable_from(&fld_tp, &value_type) {
371 return Err(RiddleError::TypeError(format!("Field '{}' expected to be of type '{}', got '{}'", field.name(), fld_tp.full_name(), value_type.full_name())));
372 }
373 obj_env.set(field.name().to_string(), value);
374 } else if let Some(class) = fld_tp.clone().as_class() {
375 let instances = class.instances();
376 if instances.is_empty() {
377 return Err(RiddleError::RuntimeError(format!("No instances found for field '{}' of type '{}'", field.name(), class.full_name())));
378 } else if instances.len() == 1 {
379 obj_env.set(field.name().to_string(), Slot::ObjectRef(instances[0]));
380 } else {
381 obj_env.set(field.name().to_string(), self.scope.clone().core().new_var(class, &instances)?);
382 }
383 } else {
384 obj_env.set(field.name().to_string(), fld_tp.clone().new_instance());
385 }
386 }
387 }
388
389 let scope: Rc<dyn Scope> = self.scope.clone();
391 for stmt in &self.statements {
392 execute(&scope, constructor_env.clone(), stmt)?;
393 }
394 Ok(())
395 }
396}
397
398impl Scope for Constructor {
399 fn core(&self) -> Rc<dyn Core> {
400 self.scope.core()
401 }
402
403 fn scope(&self) -> Option<Rc<dyn Scope>> {
404 self.scope.scope()
405 }
406
407 fn get_fields(&self) -> Vec<Rc<Field>> {
408 self.scope.get_fields()
409 }
410
411 fn get_field(&self, name: &str) -> Option<Rc<Field>> {
412 self.scope.get_field(name)
413 }
414
415 fn get_function(&self, name: &str, types: &[Rc<dyn Type>]) -> Option<Rc<Function>> {
416 self.scope.get_function(name, types)
417 }
418
419 fn get_type(&self, name: &str) -> Option<Rc<dyn Type>> {
420 self.scope.get_type(name)
421 }
422
423 fn get_predicate(&self, name: &str) -> Option<Rc<Predicate>> {
424 self.scope.get_predicate(name)
425 }
426}
427
428impl fmt::Display for Constructor {
429 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
430 let class_name = self.scope.scope.as_ref().and_then(|s| s.upgrade()).and_then(|s| s.as_class()).map(|c| c.full_name()).unwrap_or_else(|| "<unknown class>".to_string());
431 let args = self.args.iter().map(|(t, n)| format!("{} {}", t.join("."), n)).collect::<Vec<_>>().join(", ");
432 write!(f, "{}({})", class_name, args)
433 }
434}
435
436pub struct Function {
437 scope: Rc<CommonScope>,
438 name: String,
439 return_type: Option<Vec<String>>,
440 args: Vec<(Vec<String>, String)>,
441 statements: Vec<Statement>,
442}
443
444impl Function {
445 pub fn new(parent_scope: Weak<dyn Scope>, mut function: FunctionDef) -> Rc<Self> {
447 Rc::new(Self {
448 name: std::mem::take(&mut function.name),
449 return_type: std::mem::take(&mut function.return_type),
450 args: std::mem::take(&mut function.args),
451 statements: std::mem::take(&mut function.statements),
452 scope: Rc::new(CommonScope::from_function(parent_scope, function)),
453 })
454 }
455
456 pub fn name(&self) -> &str {
457 &self.name
458 }
459
460 pub fn return_type(&self) -> Option<&[String]> {
461 self.return_type.as_deref()
462 }
463
464 pub fn args(&self) -> &[(Vec<String>, String)] {
465 &self.args
466 }
467
468 pub fn statements(&self) -> &[Statement] {
469 &self.statements
470 }
471
472 pub fn call(&self, env: Rc<dyn Env>, args: Vec<Slot>) -> Result<Option<Slot>, RiddleError> {
477 if args.len() != self.args.len() {
478 return Err(RiddleError::RuntimeError(format!("Expected {} arguments, got {}", self.args.len(), args.len())));
479 }
480 let function_env = Rc::new(CommonEnv::new(Some(env)));
481 for ((arg_type, arg_name), arg_value) in self.args.iter().zip(args) {
482 let expected_type = get_type_by_path(self.scope.as_ref(), arg_type)?;
483 let arg_value_type = match &arg_value {
484 Slot::Primitive(p) => p.var_type(),
485 Slot::ObjectRef(obj_id) => self.scope.core().get_object(*obj_id).ok_or_else(|| RiddleError::NotFound(format!("Object {}", *obj_id)))?.var_type(),
486 Slot::AtomRef(atom_id) => self.scope.core().get_atom(*atom_id).ok_or_else(|| RiddleError::NotFound(format!("Atom {}", *atom_id)))?.var_type(),
487 };
488 if !is_assignable_from(&expected_type, &arg_value_type) {
489 return Err(RiddleError::TypeError(format!("Argument '{}' expected to be of type '{}', got '{}'", arg_name, expected_type.full_name(), arg_value_type.full_name())));
490 }
491 function_env.set(arg_name.clone(), arg_value);
492 }
493 let scope: Rc<dyn Scope> = self.scope.clone();
494 for stmt in &self.statements {
495 execute(&scope, function_env.clone(), stmt)?;
496 }
497 if let Some(return_type) = &self.return_type {
498 function_env.get("__return").ok_or_else(|| RiddleError::RuntimeError("Function did not set return value".into())).and_then(|ret| {
499 let expected_type = get_type_by_path(self.scope.as_ref(), return_type)?;
500 let ret_type = match &ret {
501 Slot::Primitive(p) => p.var_type(),
502 Slot::ObjectRef(obj_id) => self.scope.core().get_object(*obj_id).ok_or_else(|| RiddleError::NotFound(format!("Object {}", *obj_id)))?.var_type(),
503 Slot::AtomRef(atom_id) => self.scope.core().get_atom(*atom_id).ok_or_else(|| RiddleError::NotFound(format!("Atom {}", *atom_id)))?.var_type(),
504 };
505 if !is_assignable_from(&expected_type, &ret_type) { Err(RiddleError::TypeError(format!("Return value expected to be of type '{}', got '{}'", expected_type.full_name(), ret_type.full_name()))) } else { Ok(Some(ret)) }
506 })
507 } else {
508 Ok(None)
509 }
510 }
511}
512
513impl Scope for Function {
514 fn core(&self) -> Rc<dyn Core> {
515 self.scope.core()
516 }
517
518 fn scope(&self) -> Option<Rc<dyn Scope>> {
519 self.scope.scope()
520 }
521
522 fn get_fields(&self) -> Vec<Rc<Field>> {
523 self.scope.get_fields()
524 }
525
526 fn get_field(&self, name: &str) -> Option<Rc<Field>> {
527 self.scope.get_field(name)
528 }
529
530 fn get_function(&self, name: &str, types: &[Rc<dyn Type>]) -> Option<Rc<Function>> {
531 self.scope.get_function(name, types)
532 }
533
534 fn get_type(&self, name: &str) -> Option<Rc<dyn Type>> {
535 self.scope.get_type(name)
536 }
537
538 fn get_predicate(&self, name: &str) -> Option<Rc<Predicate>> {
539 self.scope.get_predicate(name)
540 }
541}
542
543pub trait Class: Type + Scope {
545 fn parents(&self) -> &[Vec<String>];
546 fn constructors(&self) -> Vec<Rc<Constructor>>;
547 fn constructor(&self, args: &[Rc<dyn Type>]) -> Option<Rc<Constructor>>;
548 fn predicates(&self) -> Vec<Rc<Predicate>>;
549 fn classes(&self) -> Vec<Rc<dyn Class>>;
550 fn instances(&self) -> Vec<ObjectId>;
551 fn add_instance(&self, instance: ObjectId);
552}
553
554pub struct CommonClass {
555 scope: Rc<CommonScope>,
556 name: String,
557 parents: Vec<Vec<String>>,
558 constructors: RefCell<Vec<Rc<Constructor>>>,
559 instances: RefCell<Vec<ObjectId>>,
560}
561
562impl CommonClass {
563 pub fn new(parent_scope: Weak<dyn Scope>, mut class: ClassDef) -> Rc<Self> {
565 let name = std::mem::take(&mut class.name);
566 let parents = std::mem::take(&mut class.parents);
567 let constructors_def = if class.constructors.is_empty() { vec![ConstructorDef { args: Vec::new(), init: Vec::new(), statements: Vec::new() }] } else { std::mem::take(&mut class.constructors) };
568 let class = Rc::new(Self {
569 name,
570 parents,
571 constructors: RefCell::new(Vec::new()),
572 scope: CommonScope::from_class(parent_scope, class),
573 instances: RefCell::new(Vec::new()),
574 });
575 let weak_class = Rc::downgrade(&class);
576 class.constructors.borrow_mut().extend(constructors_def.into_iter().map(|c| Rc::new(Constructor::new(weak_class.clone(), c))));
577 class
578 }
579}
580
581impl Type for CommonClass {
582 fn name(&self) -> &str {
583 &self.name
584 }
585
586 fn full_name(&self) -> String {
587 if let Some(scope) = self.scope.scope.as_ref().and_then(|scope| scope.upgrade())
588 && let Some(class) = scope.as_class()
589 {
590 format!("{}.{}", class.full_name(), self.name)
591 } else {
592 self.name.clone()
593 }
594 }
595
596 fn as_class(self: Rc<Self>) -> Option<Rc<dyn Class>> {
597 Some(self)
598 }
599
600 fn new_instance(self: Rc<Self>) -> Slot {
601 let instance = self.core().new_object(self.clone());
602 self.instances.borrow_mut().push(instance);
603 for parent in &self.parents {
604 let parent_class = get_type_by_path(self.as_ref(), parent).expect("Parent class should exist").as_class().expect("Parent class should be a class");
605 parent_class.add_instance(instance);
606 }
607 Slot::ObjectRef(instance)
608 }
609}
610
611impl Scope for CommonClass {
612 fn core(&self) -> Rc<dyn Core> {
613 self.scope.core()
614 }
615
616 fn scope(&self) -> Option<Rc<dyn Scope>> {
617 self.scope.scope()
618 }
619
620 fn as_class(self: Rc<Self>) -> Option<Rc<dyn Class>> {
621 Some(self)
622 }
623
624 fn get_fields(&self) -> Vec<Rc<Field>> {
625 self.scope.get_fields()
626 }
627
628 fn get_field(&self, name: &str) -> Option<Rc<Field>> {
629 self.scope.get_field(name)
630 }
631
632 fn get_function(&self, name: &str, types: &[Rc<dyn Type>]) -> Option<Rc<Function>> {
633 self.scope.get_function(name, types)
634 }
635
636 fn get_type(&self, name: &str) -> Option<Rc<dyn Type>> {
637 self.scope.get_type(name)
638 }
639
640 fn get_predicate(&self, name: &str) -> Option<Rc<Predicate>> {
641 self.scope.get_predicate(name)
642 }
643}
644
645impl Class for CommonClass {
646 fn parents(&self) -> &[Vec<String>] {
647 &self.parents
648 }
649
650 fn constructors(&self) -> Vec<Rc<Constructor>> {
651 self.constructors.borrow().clone()
652 }
653
654 fn constructor(&self, args: &[Rc<dyn Type>]) -> Option<Rc<Constructor>> {
655 self.constructors
656 .borrow()
657 .iter()
658 .find(|c| {
659 if c.args().len() != args.len() {
660 return false;
661 }
662 for ((arg_type, _), tp) in c.args().iter().zip(args.iter()) {
663 if !tp.full_name().split('.').eq(arg_type.iter().map(|s| s.as_str())) {
664 return false;
665 }
666 }
667 true
668 })
669 .cloned()
670 }
671
672 fn predicates(&self) -> Vec<Rc<Predicate>> {
673 self.scope.predicates.borrow().values().cloned().collect()
674 }
675
676 fn classes(&self) -> Vec<Rc<dyn Class>> {
677 self.scope.types.borrow().values().filter_map(|t| t.clone().as_class()).collect()
678 }
679
680 fn instances(&self) -> Vec<ObjectId> {
681 self.instances.borrow().clone()
682 }
683
684 fn add_instance(&self, instance: ObjectId) {
685 self.instances.borrow_mut().push(instance);
686 }
687}
688
689pub fn arith_type(cr: &dyn Core, terms: &[Slot]) -> Result<Rc<dyn Type>, RiddleError> {
694 let types = terms
695 .iter()
696 .map(|t| match t {
697 Slot::Primitive(p) => Ok(p.var_type()),
698 Slot::ObjectRef(obj_id) => Err(RiddleError::TypeError(format!("Expected numeric type, got object reference to object {}", *obj_id))),
699 Slot::AtomRef(atom_id) => Err(RiddleError::TypeError(format!("Expected numeric type, got atom reference to atom {}", *atom_id))),
700 })
701 .collect::<Result<Vec<_>, _>>()?;
702 if types.iter().all(|t| t.name() == "int") {
703 Ok(cr.get_type("int").expect("int class not found"))
704 } else if types.iter().all(|t| t.name() == "int" || t.name() == "real") {
705 Ok(cr.get_type("real").expect("real class not found"))
706 } else {
707 Err(RiddleError::TypeError("Invalid types for arithmetic operation".into()))
708 }
709}
710
711pub fn is_assignable_from(target: &Rc<dyn Type>, source: &Rc<dyn Type>) -> bool {
716 if Rc::ptr_eq(target, source) {
717 return true;
718 }
719
720 if let Some(target_class) = target.clone().as_class()
721 && let Some(source_class) = source.clone().as_class()
722 && is_subclass_of(source_class.clone(), &target_class.full_name())
723 {
724 return true;
725 }
726 false
727}
728
729fn is_subclass_of(current_class: Rc<dyn Class>, target_full_name: &str) -> bool {
730 for parent_path in current_class.parents() {
731 if parent_path.iter().map(|s| s.as_str()).eq(target_full_name.split('.')) {
732 return true;
733 }
734 if let Ok(parent_type) = get_type_by_path(&*current_class, parent_path)
735 && let Some(parent_class) = parent_type.as_class()
736 && is_subclass_of(parent_class, target_full_name)
737 {
738 return true;
739 }
740 }
741 false
742}
743
744pub struct Predicate {
745 scope: CommonScope,
746 name: String,
747 parents: Vec<Vec<String>>,
748 args: Vec<(Vec<String>, String)>,
749 statements: Vec<Statement>,
750 pub(crate) atoms: RefCell<Vec<AtomId>>,
751}
752
753impl Predicate {
754 pub fn new(scope: Weak<dyn Scope>, mut predicate: PredicateDef) -> Rc<Self> {
756 Rc::new(Self {
757 name: std::mem::take(&mut predicate.name),
758 parents: std::mem::take(&mut predicate.parents),
759 args: std::mem::take(&mut predicate.args),
760 statements: std::mem::take(&mut predicate.statements),
761 scope: CommonScope::from_predicate(scope, predicate),
762 atoms: RefCell::new(Vec::new()),
763 })
764 }
765
766 pub fn parents(&self) -> &[Vec<String>] {
767 &self.parents
768 }
769
770 pub fn args(&self) -> &[(Vec<String>, String)] {
771 &self.args
772 }
773
774 pub fn statements(&self) -> &[Statement] {
775 &self.statements
776 }
777
778 pub fn call(self: Rc<Self>, atom: Rc<Atom>) -> Result<(), RiddleError> {
780 for parent in &self.parents {
782 let parent_predicate = get_predicate_by_path(&self.scope, parent)?;
783 parent_predicate.call(atom.clone())?;
784 }
785 let scope: Rc<dyn Scope> = self.clone();
786 for stmt in &self.statements {
787 execute(&scope, atom.clone(), stmt)?;
788 }
789 Ok(())
790 }
791
792 pub fn atoms(&self) -> Vec<AtomId> {
793 self.atoms.borrow().clone()
794 }
795}
796
797impl Type for Predicate {
798 fn name(&self) -> &str {
799 &self.name
800 }
801
802 fn new_instance(self: Rc<Self>) -> Slot {
803 panic!("Cannot create instance of a predicate")
804 }
805}
806
807impl Scope for Predicate {
808 fn core(&self) -> Rc<dyn Core> {
809 self.scope.core()
810 }
811
812 fn scope(&self) -> Option<Rc<dyn Scope>> {
813 self.scope.scope()
814 }
815
816 fn get_fields(&self) -> Vec<Rc<Field>> {
817 self.scope.get_fields()
818 }
819
820 fn get_field(&self, name: &str) -> Option<Rc<Field>> {
821 self.scope.get_field(name)
822 }
823
824 fn get_function(&self, name: &str, types: &[Rc<dyn Type>]) -> Option<Rc<Function>> {
825 self.scope.get_function(name, types)
826 }
827
828 fn get_type(&self, name: &str) -> Option<Rc<dyn Type>> {
829 self.scope.get_type(name)
830 }
831
832 fn get_predicate(&self, name: &str) -> Option<Rc<Predicate>> {
833 self.scope.get_predicate(name)
834 }
835}
836
837pub fn get_type_by_path(scope: &dyn Scope, path: &[String]) -> Result<Rc<dyn Type>, RiddleError> {
849 let (first, rest) = path.split_first().ok_or_else(|| RiddleError::RuntimeError("Empty type path".into()))?;
850 rest.iter().try_fold(scope.get_type(first).ok_or_else(|| RiddleError::NotFound(first.clone()))?, |current, part| current.as_class().ok_or_else(|| RiddleError::NotAClass(first.clone()))?.get_type(part).ok_or_else(|| RiddleError::NotFound(format!("Class '{}' in path", part))))
851}
852
853pub fn get_predicate_by_path(scope: &dyn Scope, path: &[String]) -> Result<Rc<Predicate>, RiddleError> {
867 let (last, rest) = path.split_last().ok_or_else(|| RiddleError::RuntimeError("Empty predicate path".into()))?;
868 if rest.is_empty() {
869 scope.get_predicate(last).ok_or_else(|| RiddleError::NotFound(last.clone()))
870 } else {
871 get_type_by_path(scope, rest)?.as_class().ok_or_else(|| RiddleError::NotAClass(rest.join(".")))?.get_predicate(last).ok_or_else(|| RiddleError::NotFound(format!("Predicate '{}' in path", last)))
872 }
873}