1use std::{
16 rc::Rc,
17 cell::Cell,
18 fmt,
19 collections::{HashMap, HashSet},
20 iter,
21 iter::FromIterator,
22 hash::{Hash, Hasher},
23 ops::Deref,
24};
25use razor_fol::syntax::{FApp, Term, V, C, F};
26use crate::chase::{
27 r#impl::basic,
28 E, Rel, Observation, EvaluateResult,
29 WitnessTermTrait, ModelTrait, StrategyTrait, EvaluatorTrait, BounderTrait,
30};
31use itertools::{Itertools, Either};
32
33#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
41pub struct Element(Rc<Cell<E>>);
42
43impl Element {
44 fn deep_clone(&self) -> Self {
53 Element::from(self.get())
54 }
55}
56
57impl From<E> for Element {
58 fn from(e: E) -> Self {
59 Self(Rc::new(Cell::new(e)))
60 }
61}
62
63impl Hash for Element {
64 fn hash<H: Hasher>(&self, state: &mut H) {
65 self.get().hash(state)
66 }
67}
68
69impl Deref for Element {
71 type Target = Rc<Cell<E>>;
72
73 fn deref(&self) -> &Self::Target {
74 &self.0
75 }
76}
77
78impl fmt::Debug for Element {
79 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80 write!(f, "{}", self.get().to_string())
81 }
82}
83
84#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
92pub enum WitnessTerm {
93 Elem { element: Element },
97
98 Const { constant: C },
102
103 App { function: F, terms: Vec<WitnessTerm> },
108}
109
110impl WitnessTerm {
111 pub fn witness(term: &Term, lookup: &impl Fn(&V) -> Element) -> WitnessTerm {
117 match term {
118 Term::Const { constant } => WitnessTerm::Const { constant: constant.clone() },
119 Term::Var { variable } => WitnessTerm::Elem { element: lookup(&variable) },
120 Term::App { function, terms } => {
121 let terms = terms
122 .iter()
123 .map(|t| WitnessTerm::witness(t, lookup))
124 .collect();
125 WitnessTerm::App { function: function.clone(), terms }
126 }
127 }
128 }
129}
130
131impl WitnessTermTrait for WitnessTerm {
132 type ElementType = Element;
133}
134
135impl fmt::Display for WitnessTerm {
136 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
137 match self {
138 WitnessTerm::Elem { element } => write!(f, "{}", element.get()),
139 WitnessTerm::Const { constant } => write!(f, "{}", constant),
140 WitnessTerm::App { function, terms } => {
141 let ts: Vec<String> = terms.iter().map(|t| t.to_string()).collect();
142 write!(f, "{}[{}]", function, ts.join(", "))
143 }
144 }
145 }
146}
147
148impl From<C> for WitnessTerm {
149 fn from(constant: C) -> Self {
150 WitnessTerm::Const { constant }
151 }
152}
153
154impl From<Element> for WitnessTerm {
155 fn from(element: Element) -> Self {
156 WitnessTerm::Elem { element }
157 }
158}
159
160impl FApp for WitnessTerm {
161 fn apply(function: F, terms: Vec<Self>) -> Self {
162 WitnessTerm::App { function, terms }
163 }
164}
165
166pub struct Model {
174 id: u64,
176
177 element_index: i32,
179
180 pub domain: HashSet<Element>,
182
183 rewrites: HashMap<WitnessTerm, Element>,
188
189 facts: HashSet<Observation<WitnessTerm>>,
191
192 equality_history: HashMap<Element, Element>,
208}
209
210impl Model {
211 pub fn new() -> Self {
213 Self {
214 id: rand::random(),
215 element_index: 0,
216 domain: HashSet::new(),
217 rewrites: HashMap::new(),
218 facts: HashSet::new(),
219 equality_history: HashMap::new(),
220 }
221 }
222
223 fn history(&self, element: &Element) -> Element {
226 let mut result = element;
227 let mut next;
228 while {
229 next = self.equality_history.get(result);
230 next.is_some() && next.unwrap() != result
231 } { result = next.unwrap() }
232
233 result.clone()
234 }
235
236 fn new_element(&mut self, witness: WitnessTerm) -> Element {
239 let element = Element::from(E(self.element_index));
240 self.element_index = self.element_index + 1;
241 self.domain.insert(element.clone());
242 self.rewrites.insert(witness, element.clone());
243 element
244 }
245
246 fn record(&mut self, witness: &WitnessTerm) -> Element {
252 match witness {
253 WitnessTerm::Elem { element } => {
254 let element = self.history(element);
255 self.domain.iter().find(|e| element.eq(e)).unwrap().clone()
256 }
257 WitnessTerm::Const { .. } => {
258 if let Some(e) = self.rewrites.get(&witness) {
259 e.clone()
260 } else {
261 self.new_element(witness.clone())
262 }
263 }
264 WitnessTerm::App { function, terms } => {
265 let terms: Vec<WitnessTerm> = terms
266 .into_iter()
267 .map(|t| self.record(t).into())
268 .collect();
269 let witness = WitnessTerm::App { function: function.clone(), terms };
270 if let Some(e) = self.rewrites.get(&witness) {
271 (*e).clone()
272 } else {
273 self.new_element(witness)
274 }
275 }
276 }
277 }
278}
279
280impl ModelTrait for Model {
281 type TermType = WitnessTerm;
282
283 fn get_id(&self) -> u64 { self.id }
284
285 fn domain(&self) -> Vec<&Element> {
286 self.domain.iter().unique().collect()
287 }
288
289 fn facts(&self) -> Vec<&Observation<Self::TermType>> {
290 self.facts.iter().sorted().into_iter().dedup().collect()
291 }
292
293 fn observe(&mut self, observation: &Observation<Self::TermType>) {
294 match observation {
295 Observation::Fact { relation, terms } => {
296 let terms: Vec<WitnessTerm> = terms.into_iter().map(|t| self.record(t).into()).collect();
297 let observation = Observation::Fact { relation: relation.clone(), terms };
298 self.facts.insert(observation);
299 }
300 Observation::Identity { left, right } => {
301 let left = self.record(left);
302 let right = self.record(right);
303 let (src, dest) = if left > right {
304 (right, left)
305 } else {
306 (left, right)
307 };
308 self.equality_history.insert(dest.deep_clone(), src.deep_clone());
309 dest.replace(src.get());
310 }
311 }
312 }
313
314 fn is_observed(&self, observation: &Observation<Self::TermType>) -> bool {
315 match observation {
316 Observation::Fact { relation, terms } => {
317 let terms: Vec<Option<&Element>> = terms.iter().map(|t| self.element(t)).collect();
318 if terms.iter().any(|e| e.is_none()) {
319 false
320 } else {
321 let terms: Vec<WitnessTerm> = terms
322 .into_iter()
323 .map(|e| e.unwrap().clone().into())
324 .collect();
325 let obs = Observation::Fact { relation: relation.clone(), terms };
326 self.facts.iter().find(|f| obs.eq(f)).is_some()
327 }
328 }
329 Observation::Identity { left, right } => {
330 let left = self.element(left);
331 left.is_some() && left == self.element(right)
332 }
333 }
334 }
335
336 fn witness(&self, element: &Element) -> Vec<&Self::TermType> {
337 self.rewrites.iter()
338 .filter(|(_, e)| (*e).eq(element))
339 .map(|(t, _)| t)
340 .sorted()
341 .into_iter()
342 .dedup()
343 .collect()
344 }
345
346 fn element(&self, witness: &Self::TermType) -> Option<&Element> {
347 match witness {
348 WitnessTerm::Elem { element } => {
349 self.domain.iter().find(|e| e == &element)
350 }
351 WitnessTerm::Const { .. } => self.rewrites.get(witness),
352 WitnessTerm::App { function, terms } => {
353 let terms: Vec<Option<&Element>> = terms.iter().map(|t| self.element(t)).collect();
354 if terms.iter().any(|e| e.is_none()) {
355 None
356 } else {
357 let terms: Vec<WitnessTerm> = terms
358 .into_iter()
359 .map(|e| e.unwrap().clone().into())
360 .collect();
361 self.rewrites.get(&WitnessTerm::App { function: (*function).clone(), terms })
362 }
363 }
364 }
365 }
366}
367
368impl Clone for Model {
369 fn clone(&self) -> Self {
370 let domain: HashSet<Element> = HashSet::from_iter(self.domain.iter().map(|e| e.deep_clone()));
371 let map_element = |e: &Element| domain.get(e).unwrap().clone();
372 let map_term = |w: &WitnessTerm| {
373 match w {
374 WitnessTerm::Elem { element } => WitnessTerm::Elem { element: map_element(element) },
375 WitnessTerm::Const { .. } => w.clone(),
376 WitnessTerm::App { function, terms } => {
377 let terms = terms.iter().map(|t| {
378 if let WitnessTerm::Elem { element } = t {
379 WitnessTerm::Elem { element: map_element(element) }
380 } else {
381 panic!("something is wrong: expecting an element")
382 }
383 }).collect();
384 WitnessTerm::App {
385 function: function.clone(),
386 terms,
387 }
388 }
389 }
390 };
391 let map_observation = |o: &Observation<WitnessTerm>| {
392 if let Observation::Fact { relation, terms } = o {
393 Observation::Fact {
394 relation: relation.clone(),
395 terms: terms.iter().map(|t| map_term(t)).collect(),
396 }
397 } else {
398 panic!("something is wrong: expecting a fact")
399 }
400 };
401 let rewrites: HashMap<WitnessTerm, Element> = HashMap::from_iter(self.rewrites.iter().map(|(k, v)| {
402 (map_term(k), map_element(v))
403 }));
404 let facts: HashSet<Observation<WitnessTerm>> = HashSet::from_iter(self.facts.iter().map(|o| map_observation(o)));
405 Model {
406 id: rand::random(),
407 element_index: self.element_index,
408 domain,
409 rewrites,
410 facts,
411 equality_history: self.equality_history.clone(),
414 }
415 }
416}
417
418impl fmt::Display for Model {
419 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
420 let domain: Vec<String> = self.domain().into_iter().map(|e| e.get().to_string()).collect();
421 let elements: Vec<String> = self.domain().iter().sorted().iter().map(|e| {
422 let witnesses: Vec<String> = self.witness(e).iter().map(|w| w.to_string()).collect();
423 let witnesses = witnesses.into_iter().sorted();
424 format!("{} -> {}", witnesses.into_iter().sorted().join(", "), e.get())
425 }).collect();
426 let facts: Vec<String> = self.facts().into_iter().map(|e| e.to_string()).collect();
427 write!(f, "Domain: {{{}}}\nElements:{}\nFacts: {}\n",
428 domain.join(", "),
429 elements.join(", "),
430 facts.join(", "))
431 }
432}
433
434pub struct Evaluator {}
440
441impl<'s, Stg: StrategyTrait<Item=&'s Sequent>, B: BounderTrait> EvaluatorTrait<'s, Stg, B> for Evaluator {
442 type Sequent = Sequent;
443 type Model = Model;
444 fn evaluate(
445 &self,
446 initial_model: &Model,
447 strategy: &mut Stg,
448 bounder: Option<&B>
449 ) -> Option<EvaluateResult<Model>> {
450 let domain: Vec<&Element> = initial_model.domain();
451 let domain_size = domain.len();
452 for sequent in strategy {
453 let vars = &sequent.free_vars;
454 let vars_size = vars.len();
455 if domain_size == 0 && vars_size > 0 {
456 continue; }
458
459 let mut assignment: Vec<usize> = iter::repeat(0).take(vars_size).collect();
461
462 while {
465 let mut assignment_map: HashMap<&V, Element> = HashMap::new();
467 for i in 0..vars_size {
468 assignment_map.insert(vars.get(i).unwrap(), (*domain.get(assignment[i]).unwrap()).clone());
469 }
470 let assignment_func = |v: &V| assignment_map.get(v).unwrap().clone();
472
473 let observe_literal = make_observe_literal(assignment_func);
475
476 let body: Vec<Observation<WitnessTerm>> = sequent.body_literals
478 .iter()
479 .map(&observe_literal)
480 .collect();
481 let head: Vec<Vec<Observation<WitnessTerm>>> = sequent.head_literals
482 .iter()
483 .map(|l| l.iter().map(&observe_literal).collect())
484 .collect();
485
486 if body.iter().all(|o| initial_model.is_observed(o))
489 && !head.iter().any(|os| os.iter().all(|o| initial_model.is_observed(o))) {
490 info!(event = crate::trace::EVALUATE, sequent = %sequent,mapping = ?assignment_map);
491
492 if head.is_empty() {
493 return None; } else {
495 let models: Vec<Either<Model, Model>> = if let Some(bounder) = bounder {
497 let extend = make_bounded_extend(bounder, initial_model);
498 head.iter().map(extend).collect()
499 } else {
500 let extend = make_extend(initial_model);
501 head.iter().map(extend).collect()
502 };
503
504 let result = EvaluateResult::from(models);
505 if !result.empty() {
506 return Some(result);
509 }
510 }
511 }
512
513 domain_size > 0 && next_assignment(&mut assignment, domain_size - 1)
515 } {}
516 }
517 Some(EvaluateResult::new()) }
519}
520
521fn make_extend<'m>(
524 model: &'m Model
525) -> impl FnMut(&'m Vec<Observation<WitnessTerm>>) -> Either<Model, Model>
526{
527 move |os: &'m Vec<Observation<WitnessTerm>>| {
528 let mut model = model.clone();
529 os.iter().foreach(|o| model.observe(o));
530 Either::Left(model)
531 }
532}
533
534fn make_bounded_extend<'m, B: BounderTrait>(
539 bounder: &'m B,
540 model: &'m Model,
541) -> impl FnMut(&'m Vec<Observation<WitnessTerm>>) -> Either<Model, Model>
542{
543 move |os: &Vec<Observation<WitnessTerm>>| {
544 let mut model = model.clone();
545 let mut modified = false;
546 os.iter().foreach(|o| {
547 if bounder.bound(&model, o) {
548 if !model.is_observed(o) {
549 modified = true;
550 }
551 } else {
552 if !model.is_observed(o) {
553 model.observe(o);
554 }
555 }
556 });
557 if modified {
558 Either::Right(model)
559 } else {
560 Either::Left(model)
561 }
562 }
563}
564
565fn make_observe_literal(assignment_func: impl Fn(&V) -> Element)
568 -> impl Fn(&Literal) -> Observation<WitnessTerm> {
569 move |lit: &Literal| {
570 match lit {
571 basic::Literal::Atm { predicate, terms } => {
572 let terms = terms
573 .into_iter()
574 .map(|t| WitnessTerm::witness(t, &assignment_func))
575 .collect();
576 Observation::Fact { relation: Rel(predicate.0.clone()), terms }
577 }
578 basic::Literal::Eql { left, right } => {
579 let left = WitnessTerm::witness(left, &assignment_func);
580 let right = WitnessTerm::witness(right, &assignment_func);
581 Observation::Identity { left, right }
582 }
583 }
584 }
585}
586
587fn next_assignment(vec: &mut Vec<usize>, last: usize) -> bool {
592 let len = vec.len();
593 for i in 0..len {
594 if vec[i] != last {
595 vec[i] += 1;
596 return true;
597 } else {
598 vec[i] = 0;
599 }
600 }
601 false
602}
603
604pub type Sequent = basic::Sequent;
612
613pub type Literal = basic::Literal;
621
622#[cfg(test)]
623mod test_reference {
624 use super::{Model, Sequent, Evaluator, next_assignment};
625 use razor_fol::syntax::Theory;
626 use crate::chase::{SchedulerTrait, StrategyTrait, strategy::{Bootstrap, Fair}
627 , scheduler::FIFO, bounder::DomainSize, chase_all};
628 use crate::test_prelude::*;
629 use std::collections::HashSet;
630 use std::fs;
631
632 #[test]
633 fn test_next_assignment() {
634 {
635 let mut assignment = vec![];
636 assert_eq!(false, next_assignment(&mut assignment, 1));
637 assert!(assignment.is_empty());
638 }
639 {
640 let mut assignment = vec![0];
641 assert_eq!(true, next_assignment(&mut assignment, 1));
642 assert_eq!(vec![1], assignment);
643 }
644 {
645 let mut assignment = vec![1];
646 assert_eq!(false, next_assignment(&mut assignment, 1));
647 assert_eq!(vec![0], assignment);
648 }
649 {
650 let mut assignment = vec![0, 1];
651 assert_eq!(true, next_assignment(&mut assignment, 1));
652 assert_eq!(vec![1, 1], assignment);
653 }
654 {
655 let mut assignment = vec![1, 1];
656 assert_eq!(true, next_assignment(&mut assignment, 2));
657 assert_eq!(vec![2, 1], assignment);
658 }
659 {
660 let mut assignment = vec![2, 1];
661 assert_eq!(true, next_assignment(&mut assignment, 2));
662 assert_eq!(vec![0, 2], assignment);
663 }
664 {
665 let mut assignment = vec![2, 2];
666 assert_eq!(false, next_assignment(&mut assignment, 2));
667 assert_eq!(vec![0, 0], assignment);
668 }
669 {
670 let mut counter = 1;
671 let mut vec = vec![0, 0, 0, 0, 0];
672 while next_assignment(&mut vec, 4) {
673 counter += 1;
674 }
675 assert_eq!(3125, counter);
676 }
677 }
678
679 fn run_test(theory: &Theory) -> Vec<Model> {
680 let geometric_theory = theory.gnf();
681 let sequents: Vec<Sequent> = geometric_theory
682 .formulae
683 .iter()
684 .map(|f| f.into()).collect();
685
686 let evaluator = Evaluator {};
687 let strategy: Bootstrap<Sequent, Fair<Sequent>> = Bootstrap::new(sequents.iter().collect());
688 let mut scheduler = FIFO::new();
689 let bounder: Option<&DomainSize> = None;
690 scheduler.add(Model::new(), strategy);
691 chase_all(&mut scheduler, &evaluator, bounder)
692 }
693
694 #[test]
695 fn test() {
696 for item in fs::read_dir("../theories/core").unwrap() {
697 let theory = read_theory_from_file(item.unwrap().path().display().to_string().as_str());
698 let basic_models = solve_basic(&theory);
699 let test_models = run_test(&theory);
700 let basic_models: HashSet<String> = basic_models.into_iter().map(|m| print_basic_model(m)).collect();
701 let test_models: HashSet<String> = test_models.into_iter().map(|m| print_reference_model(m)).collect();
702 assert_eq!(basic_models, test_models);
703 }
704 }
705}