diff options
Diffstat (limited to 'crates/elfmind/src/knowledge.rs')
| -rw-r--r-- | crates/elfmind/src/knowledge.rs | 74 |
1 files changed, 13 insertions, 61 deletions
diff --git a/crates/elfmind/src/knowledge.rs b/crates/elfmind/src/knowledge.rs index 3b90dee..cbcce28 100644 --- a/crates/elfmind/src/knowledge.rs +++ b/crates/elfmind/src/knowledge.rs @@ -1,12 +1,15 @@ -use std::collections::{HashMap, HashSet}; -use itertools::Itertools; +pub mod relation; +pub use relation::*; -use enum_map::{Enum, EnumMap}; +use crate::time::*; +use crate::item::*; +use crate::character::*; -use crate::item::Item; -use crate::character::Character; +use std::collections::{HashMap, HashSet}; +use itertools::Itertools; -type Time = u64; +use enum_map::EnumMap; +use strum::IntoDiscriminant; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Var { index: u64 } @@ -100,57 +103,6 @@ impl<T: Clone + TryFrom<Value>> Hole<T> { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Enum)] -pub enum RelationSort { - HasItem, - UsedItemAt, - TimeIs, - FriendOf, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum Relation { - HasItem(Hole<Character>, Hole<Item>), - UsedItemAt(Hole<Character>, Hole<Item>, Hole<Time>), - TimeIs(Hole<Time>), - FriendOf(Hole<Character>, Hole<Character>), -} -impl Relation { - pub fn sort(&self) -> RelationSort { - match self { - Self::HasItem{..} => RelationSort::HasItem, - Self::UsedItemAt{..} => RelationSort::UsedItemAt, - Self::TimeIs{..} => RelationSort::TimeIs, - Self::FriendOf{..} => RelationSort::FriendOf, - } - } - pub fn unify(&self, other: &Self, mut u: Unification) -> Option<Unification> { - match (self, other) { - (Self::HasItem(c1, i1), Self::HasItem(c2, i2)) - if u.unify_hole(c1, c2) && u.unify_hole(i1, i2) - => Some(u), - (Self::UsedItemAt(c1, i1, t1), Self::UsedItemAt(c2, i2, t2)) - if u.unify_hole(c1, c2) && u.unify_hole(i1, i2) && u.unify_hole(t1, t2) - => Some(u), - (Self::TimeIs(t1), Self::TimeIs(t2)) - if u.unify_hole(t1, t2) - => Some(u), - (Self::FriendOf(x1, y1), Self::FriendOf(x2, y2)) - if u.unify_hole(x1, x2) && u.unify_hole(y1, y2) - => Some(u), - _ => None, - } - } - pub fn substitute(&self, u: &Unification) -> Self { - match self { - Self::HasItem(c, i) => Self::HasItem(c.substitute(u), i.substitute(u)), - Self::UsedItemAt(c, i, t) => Self::UsedItemAt(c.substitute(u), i.substitute(u), t.substitute(u)), - Self::TimeIs(t) => Self::TimeIs(t.substitute(u)), - Self::FriendOf(x, y) => Self::FriendOf(x.substitute(u), y.substitute(u)), - } - } -} - #[derive(Debug, Clone)] pub struct Rule { pub head: Relation, @@ -169,13 +121,13 @@ impl Rule { #[derive(Debug, Default, Clone)] pub struct Facts { - facts: EnumMap<RelationSort, HashSet<Relation>>, + facts: EnumMap<RelationDiscriminants, HashSet<Relation>>, } impl Facts { pub fn add(&mut self, f: Relation) -> bool { - self.facts[f.sort()].insert(f) + self.facts[f.discriminant()].insert(f) } - pub fn with_sort(&self, s: RelationSort) -> &HashSet<Relation> { + pub fn with_sort(&self, s: RelationDiscriminants) -> &HashSet<Relation> { &self.facts[s] } } @@ -190,7 +142,7 @@ impl Database { pub fn add_rule(&mut self, r: Rule) { self.rules.push(r) } fn apply_rule(r: &Rule, facts: &mut Facts) -> bool { let found: Vec<Unification> = r.body.iter() - .map(|r| facts.with_sort(r.sort())).multi_cartesian_product() + .map(|r| facts.with_sort(r.discriminant())).multi_cartesian_product() .filter_map(|fs| r.unify_body(&fs)) .collect(); let mut changed = false; |
