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