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