From c4ee47647a5bf1a06ae88ebb9410117c927868ee Mon Sep 17 00:00:00 2001 From: LLLL Colonq Date: Mon, 12 Oct 2026 01:31:00 -0400 Subject: Major refactor, generate relation traits with macros --- crates/elfmind/src/knowledge/relation.rs | 243 +-------------------------- crates/elfmind/src/knowledge/traits.rs | 273 +++++++++++++++++++++++++++++++ 2 files changed, 280 insertions(+), 236 deletions(-) create mode 100644 crates/elfmind/src/knowledge/traits.rs (limited to 'crates/elfmind/src/knowledge') diff --git a/crates/elfmind/src/knowledge/relation.rs b/crates/elfmind/src/knowledge/relation.rs index b738aa1..82c795d 100644 --- a/crates/elfmind/src/knowledge/relation.rs +++ b/crates/elfmind/src/knowledge/relation.rs @@ -1,243 +1,14 @@ -use super::{Value, Hole, Unification}; - -use crate::time::*; -use crate::item::*; -use crate::character::*; +use crate::knowledge::*; +use crate::noun::*; use enum_map::Enum; use strum::EnumDiscriminants; -pub trait Concretizable { - type Concrete; - fn concretize(&self) -> Option; -} -impl Concretizable for Hole { - type Concrete = A; - fn concretize(&self) -> Option { - match self { - Self::Val(x) => Some(x.clone()), - _ => None, - } - } -} -impl< - A: Clone, - B: Clone, - > Concretizable for (Hole, Hole) { - type Concrete = (A, B); - fn concretize(&self) -> Option { - let a = self.0.concretize()?; - let b = self.1.concretize()?; - Some((a, b)) - } -} -impl< - A: Clone, - B: Clone, - C: Clone, - > Concretizable for (Hole, Hole, Hole) { - type Concrete = (A, B, C); - fn concretize(&self) -> Option { - let a = self.0.concretize()?; - let b = self.1.concretize()?; - let c = self.2.concretize()?; - Some((a, b, c)) - } -} -impl< - A: Clone, - B: Clone, - C: Clone, - D: Clone, - > Concretizable for (Hole, Hole, Hole, Hole) { - type Concrete = (A, B, C, D); - fn concretize(&self) -> Option { - let a = self.0.concretize()?; - let b = self.1.concretize()?; - let c = self.2.concretize()?; - let d = self.3.concretize()?; - Some((a, b, c, d)) - } -} -impl< - A: Clone, - B: Clone, - C: Clone, - D: Clone, - E: Clone, - > Concretizable for (Hole, Hole, Hole, Hole, Hole) { - type Concrete = (A, B, C, D, E); - fn concretize(&self) -> Option { - let a = self.0.concretize()?; - let b = self.1.concretize()?; - let c = self.2.concretize()?; - let d = self.3.concretize()?; - let e = self.4.concretize()?; - Some((a, b, c, d, e)) - } -} - -pub trait Substitutable { - fn substitute(&self, u: &Unification) -> Self; -} -impl> Substitutable for Hole { - fn substitute(&self, u: &Unification) -> Self { - match self { - x@Self::Var(v) => if let Some(y) = u.lookup(v) && let Ok(z) = A::try_from(y) { - Hole::Val(z) - } else { - x.clone() - } - x => x.clone(), - } - } -} -impl< - A: Clone + TryFrom, - B: Clone + TryFrom - > Substitutable for (Hole, Hole) { - fn substitute(&self, u: &Unification) -> Self { - let (a, b) = self; - (a.substitute(u), b.substitute(u)) - } -} -impl< - A: Clone + TryFrom, - B: Clone + TryFrom, - C: Clone + TryFrom, - > Substitutable for (Hole, Hole, Hole) { - fn substitute(&self, u: &Unification) -> Self { - let (a, b, c) = self; - (a.substitute(u), b.substitute(u), c.substitute(u)) - } -} -impl< - A: Clone + TryFrom, - B: Clone + TryFrom, - C: Clone + TryFrom, - D: Clone + TryFrom, - > Substitutable for (Hole, Hole, Hole, Hole) { - fn substitute(&self, u: &Unification) -> Self { - let (a, b, c, d) = self; - (a.substitute(u), b.substitute(u), c.substitute(u), d.substitute(u)) - } -} -impl< - A: Clone + TryFrom, - B: Clone + TryFrom, - C: Clone + TryFrom, - D: Clone + TryFrom, - E: Clone + TryFrom, - > Substitutable for (Hole, Hole, Hole, Hole, Hole) { - fn substitute(&self, u: &Unification) -> Self { - let (a, b, c, d, e) = self; - (a.substitute(u), b.substitute(u), c.substitute(u), d.substitute(u), e.substitute(u)) - } -} - -pub trait Unifiable { - fn unify(&self, other: &Self, u: Unification) -> Option; -} -impl Unifiable for Hole where - Value: From, A: Copy, -{ - fn unify(&self, other: &Self, mut u: Unification) -> Option { - if u.unify_hole(self, other) { - Some(u) - } else { None } - } -} -impl Unifiable for (Hole, Hole) where - Value: From, A: Copy, - Value: From, B: Copy, -{ - fn unify(&self, other: &Self, mut u: Unification) -> Option { - let (a1, b1) = self; - let (a2, b2) = other; - if u.unify_hole(a1, a2) && u.unify_hole(b1, b2) { - Some(u) - } else { None } - } -} -impl Unifiable for (Hole, Hole, Hole) where - Value: From, A: Copy, - Value: From, B: Copy, - Value: From, C: Copy, -{ - fn unify(&self, other: &Self, mut u: Unification) -> Option { - let (a1, b1, c1) = self; - let (a2, b2, c2) = other; - if u.unify_hole(a1, a2) && u.unify_hole(b1, b2) && u.unify_hole(c1, c2) { - Some(u) - } else { None } - } -} -impl Unifiable for (Hole, Hole, Hole, Hole) where - Value: From, A: Copy, - Value: From, B: Copy, - Value: From, C: Copy, - Value: From, D: Copy, -{ - fn unify(&self, other: &Self, mut u: Unification) -> Option { - let (a1, b1, c1, d1) = self; - let (a2, b2, c2, d2) = other; - if u.unify_hole(a1, a2) && u.unify_hole(b1, b2) && u.unify_hole(c1, c2) && u.unify_hole(d1, d2) { - Some(u) - } else { None } - } -} -impl Unifiable for (Hole, Hole, Hole, Hole, Hole) where - Value: From, A: Copy, - Value: From, B: Copy, - Value: From, C: Copy, - Value: From, D: Copy, - Value: From, E: Copy, -{ - fn unify(&self, other: &Self, mut u: Unification) -> Option { - let (a1, b1, c1, d1, e1) = self; - let (a2, b2, c2, d2, e2) = other; - if u.unify_hole(a1, a2) && u.unify_hole(b1, b2) && u.unify_hole(c1, c2) && u.unify_hole(d1, d2) && u.unify_hole(e1, e2) { - Some(u) - } else { None } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash, EnumDiscriminants)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, EnumDiscriminants, elfmacros::Concrete)] #[strum_discriminants(derive(Enum))] pub enum Relation { - HasItem((Hole, Hole)), - UsedItemAt((Hole, Hole, Hole { + type Concrete = A; + fn concretize(&self) -> Option { + match self { + Self::Val(x) => Some(x.clone()), + _ => None, + } + } +} +impl< + A: Clone, + B: Clone, + > Concretizable for (Hole, Hole) { + type Concrete = (A, B); + fn concretize(&self) -> Option { + let a = self.0.concretize()?; + let b = self.1.concretize()?; + Some((a, b)) + } +} +impl< + A: Clone, + B: Clone, + C: Clone, + > Concretizable for (Hole, Hole, Hole) { + type Concrete = (A, B, C); + fn concretize(&self) -> Option { + let a = self.0.concretize()?; + let b = self.1.concretize()?; + let c = self.2.concretize()?; + Some((a, b, c)) + } +} +impl< + A: Clone, + B: Clone, + C: Clone, + D: Clone, + > Concretizable for (Hole, Hole, Hole, Hole) { + type Concrete = (A, B, C, D); + fn concretize(&self) -> Option { + let a = self.0.concretize()?; + let b = self.1.concretize()?; + let c = self.2.concretize()?; + let d = self.3.concretize()?; + Some((a, b, c, d)) + } +} +impl< + A: Clone, + B: Clone, + C: Clone, + D: Clone, + E: Clone, + > Concretizable for (Hole, Hole, Hole, Hole, Hole) { + type Concrete = (A, B, C, D, E); + fn concretize(&self) -> Option { + let a = self.0.concretize()?; + let b = self.1.concretize()?; + let c = self.2.concretize()?; + let d = self.3.concretize()?; + let e = self.4.concretize()?; + Some((a, b, c, d, e)) + } +} + +pub trait Substitutable { + fn substitute(&self, u: &Unification) -> Self; + fn map_variables(&self, f: &mut F) -> Self where F: FnMut(Var) -> Var; +} +impl> Substitutable for Hole { + fn substitute(&self, u: &Unification) -> Self { + match self { + x@Self::Var(v) => if let Some(y) = u.lookup(v) && let Ok(z) = A::try_from(y) { + Hole::Val(z) + } else { + x.clone() + } + x => x.clone(), + } + } + fn map_variables(&self, f: &mut F) -> Self where F: FnMut(Var) -> Var { + match self { + Self::Var(v) => Self::Var(f(*v)), + x => x.clone(), + } + } +} +impl< + A: Clone + TryFrom, + B: Clone + TryFrom + > Substitutable for (Hole, Hole) { + fn substitute(&self, u: &Unification) -> Self { + let (a, b) = self; + (a.substitute(u), b.substitute(u)) + } + fn map_variables(&self, f: &mut F) -> Self where F: FnMut(Var) -> Var { + let (a, b) = self; + (a.map_variables(f), b.map_variables(f)) + } +} +impl< + A: Clone + TryFrom, + B: Clone + TryFrom, + C: Clone + TryFrom, + > Substitutable for (Hole, Hole, Hole) { + fn substitute(&self, u: &Unification) -> Self { + let (a, b, c) = self; + (a.substitute(u), b.substitute(u), c.substitute(u)) + } + fn map_variables(&self, f: &mut F) -> Self where F: FnMut(Var) -> Var { + let (a, b, c) = self; + (a.map_variables(f), b.map_variables(f), c.map_variables(f)) + } +} +impl< + A: Clone + TryFrom, + B: Clone + TryFrom, + C: Clone + TryFrom, + D: Clone + TryFrom, + > Substitutable for (Hole, Hole, Hole, Hole) { + fn substitute(&self, u: &Unification) -> Self { + let (a, b, c, d) = self; + (a.substitute(u), b.substitute(u), c.substitute(u), d.substitute(u)) + } + fn map_variables(&self, f: &mut F) -> Self where F: FnMut(Var) -> Var { + let (a, b, c, d) = self; + (a.map_variables(f), b.map_variables(f), c.map_variables(f), d.map_variables(f)) + } +} +impl< + A: Clone + TryFrom, + B: Clone + TryFrom, + C: Clone + TryFrom, + D: Clone + TryFrom, + E: Clone + TryFrom, + > Substitutable for (Hole, Hole, Hole, Hole, Hole) { + fn substitute(&self, u: &Unification) -> Self { + let (a, b, c, d, e) = self; + (a.substitute(u), b.substitute(u), c.substitute(u), d.substitute(u), e.substitute(u)) + } + fn map_variables(&self, f: &mut F) -> Self where F: FnMut(Var) -> Var { + let (a, b, c, d, e) = self; + (a.map_variables(f), b.map_variables(f), c.map_variables(f), d.map_variables(f), e.map_variables(f)) + } +} + +pub trait Unifiable: Concretizable { + fn unify(&self, other: &Self::Concrete, u: Unification) -> Option; +} +impl Unifiable for Hole where + Noun: From, A: Copy, +{ + fn unify(&self, other: &Self::Concrete, mut u: Unification) -> Option { + if u.unify_hole(self, other) { + Some(u) + } else { None } + } +} +impl Unifiable for (Hole, Hole) where + Noun: From, A: Copy, + Noun: From, B: Copy, +{ + fn unify(&self, other: &Self::Concrete, mut u: Unification) -> Option { + let (a1, b1) = self; + let (a2, b2) = other; + if u.unify_hole(a1, a2) && u.unify_hole(b1, b2) { + Some(u) + } else { None } + } +} +impl Unifiable for (Hole, Hole, Hole) where + Noun: From, A: Copy, + Noun: From, B: Copy, + Noun: From, C: Copy, +{ + fn unify(&self, other: &Self::Concrete, mut u: Unification) -> Option { + let (a1, b1, c1) = self; + let (a2, b2, c2) = other; + if u.unify_hole(a1, a2) && u.unify_hole(b1, b2) && u.unify_hole(c1, c2) { + Some(u) + } else { None } + } +} +impl Unifiable for (Hole, Hole, Hole, Hole) where + Noun: From, A: Copy, + Noun: From, B: Copy, + Noun: From, C: Copy, + Noun: From, D: Copy, +{ + fn unify(&self, other: &Self::Concrete, mut u: Unification) -> Option { + let (a1, b1, c1, d1) = self; + let (a2, b2, c2, d2) = other; + if u.unify_hole(a1, a2) && u.unify_hole(b1, b2) && u.unify_hole(c1, c2) && u.unify_hole(d1, d2) { + Some(u) + } else { None } + } +} +impl Unifiable for (Hole, Hole, Hole, Hole, Hole) where + Noun: From, A: Copy, + Noun: From, B: Copy, + Noun: From, C: Copy, + Noun: From, D: Copy, + Noun: From, E: Copy, +{ + fn unify(&self, other: &Self::Concrete, mut u: Unification) -> Option { + let (a1, b1, c1, d1, e1) = self; + let (a2, b2, c2, d2, e2) = other; + if u.unify_hole(a1, a2) && u.unify_hole(b1, b2) && u.unify_hole(c1, c2) && u.unify_hole(d1, d2) && u.unify_hole(e1, e2) { + Some(u) + } else { None } + } +} -- cgit v1.3.1