summaryrefslogtreecommitdiff
path: root/crates/elfmind/src/knowledge
diff options
context:
space:
mode:
Diffstat (limited to 'crates/elfmind/src/knowledge')
-rw-r--r--crates/elfmind/src/knowledge/relation.rs243
-rw-r--r--crates/elfmind/src/knowledge/traits.rs273
2 files changed, 280 insertions, 236 deletions
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<Self::Concrete>;
-}
-impl<A: Clone> Concretizable for Hole<A> {
- type Concrete = A;
- fn concretize(&self) -> Option<Self::Concrete> {
- match self {
- Self::Val(x) => Some(x.clone()),
- _ => None,
- }
- }
-}
-impl<
- A: Clone,
- B: Clone,
- > Concretizable for (Hole<A>, Hole<B>) {
- type Concrete = (A, B);
- fn concretize(&self) -> Option<Self::Concrete> {
- let a = self.0.concretize()?;
- let b = self.1.concretize()?;
- Some((a, b))
- }
-}
-impl<
- A: Clone,
- B: Clone,
- C: Clone,
- > Concretizable for (Hole<A>, Hole<B>, Hole<C>) {
- type Concrete = (A, B, C);
- fn concretize(&self) -> Option<Self::Concrete> {
- 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<A>, Hole<B>, Hole<C>, Hole<D>) {
- type Concrete = (A, B, C, D);
- fn concretize(&self) -> Option<Self::Concrete> {
- 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<A>, Hole<B>, Hole<C>, Hole<D>, Hole<E>) {
- type Concrete = (A, B, C, D, E);
- fn concretize(&self) -> Option<Self::Concrete> {
- 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<A: Clone + TryFrom<Value>> Substitutable for Hole<A> {
- 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<Value>,
- B: Clone + TryFrom<Value>
- > Substitutable for (Hole<A>, Hole<B>) {
- fn substitute(&self, u: &Unification) -> Self {
- let (a, b) = self;
- (a.substitute(u), b.substitute(u))
- }
-}
-impl<
- A: Clone + TryFrom<Value>,
- B: Clone + TryFrom<Value>,
- C: Clone + TryFrom<Value>,
- > Substitutable for (Hole<A>, Hole<B>, Hole<C>) {
- fn substitute(&self, u: &Unification) -> Self {
- let (a, b, c) = self;
- (a.substitute(u), b.substitute(u), c.substitute(u))
- }
-}
-impl<
- A: Clone + TryFrom<Value>,
- B: Clone + TryFrom<Value>,
- C: Clone + TryFrom<Value>,
- D: Clone + TryFrom<Value>,
- > Substitutable for (Hole<A>, Hole<B>, Hole<C>, Hole<D>) {
- 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<Value>,
- B: Clone + TryFrom<Value>,
- C: Clone + TryFrom<Value>,
- D: Clone + TryFrom<Value>,
- E: Clone + TryFrom<Value>,
- > Substitutable for (Hole<A>, Hole<B>, Hole<C>, Hole<D>, Hole<E>) {
- 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<Unification>;
-}
-impl<A> Unifiable for Hole<A> where
- Value: From<A>, A: Copy,
-{
- fn unify(&self, other: &Self, mut u: Unification) -> Option<Unification> {
- if u.unify_hole(self, other) {
- Some(u)
- } else { None }
- }
-}
-impl<A, B> Unifiable for (Hole<A>, Hole<B>) where
- Value: From<A>, A: Copy,
- Value: From<B>, B: Copy,
-{
- fn unify(&self, other: &Self, mut u: Unification) -> Option<Unification> {
- let (a1, b1) = self;
- let (a2, b2) = other;
- if u.unify_hole(a1, a2) && u.unify_hole(b1, b2) {
- Some(u)
- } else { None }
- }
-}
-impl<A, B, C> Unifiable for (Hole<A>, Hole<B>, Hole<C>) where
- Value: From<A>, A: Copy,
- Value: From<B>, B: Copy,
- Value: From<C>, C: Copy,
-{
- fn unify(&self, other: &Self, mut u: Unification) -> Option<Unification> {
- 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<A, B, C, D> Unifiable for (Hole<A>, Hole<B>, Hole<C>, Hole<D>) where
- Value: From<A>, A: Copy,
- Value: From<B>, B: Copy,
- Value: From<C>, C: Copy,
- Value: From<D>, D: Copy,
-{
- fn unify(&self, other: &Self, mut u: Unification) -> Option<Unification> {
- 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<A, B, C, D, E> Unifiable for (Hole<A>, Hole<B>, Hole<C>, Hole<D>, Hole<E>) where
- Value: From<A>, A: Copy,
- Value: From<B>, B: Copy,
- Value: From<C>, C: Copy,
- Value: From<D>, D: Copy,
- Value: From<E>, E: Copy,
-{
- fn unify(&self, other: &Self, mut u: Unification) -> Option<Unification> {
- 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<Character>, Hole<Item>)),
- UsedItemAt((Hole<Character>, Hole<Item>, Hole<Time>)),
- TimeIs(Hole<Time>),
- FriendOf((Hole<Character>, Hole<Character>)),
-}
-impl Relation {
- pub fn is_concrete(&self) -> bool {
- match self {
- Self::HasItem(x) => x.concretize().is_some(),
- Self::UsedItemAt(x) => x.concretize().is_some(),
- Self::TimeIs(x) => x.concretize().is_some(),
- Self::FriendOf(x) => x.concretize().is_some(),
- }
- }
-}
-impl Substitutable for Relation {
- fn substitute(&self, u: &Unification) -> Self {
- match self {
- Self::HasItem(x) => Self::HasItem(x.substitute(u)),
- Self::UsedItemAt(x) => Self::UsedItemAt(x.substitute(u)),
- Self::TimeIs(x) => Self::TimeIs(x.substitute(u)),
- Self::FriendOf(x) => Self::FriendOf(x.substitute(u)),
- }
- }
-}
-impl Unifiable for Relation {
- fn unify(&self, other: &Self, u: Unification) -> Option<Unification> {
- match (self, other) {
- (Self::HasItem(a), Self::HasItem(b)) => a.unify(b, u),
- (Self::UsedItemAt(a), Self::UsedItemAt(b)) => a.unify(b, u),
- (Self::TimeIs(a), Self::TimeIs(b)) => a.unify(b, u),
- (Self::FriendOf(a), Self::FriendOf(b)) => a.unify(b, u),
- _ => None,
- }
- }
+ HasItem((CharacterUnmasked, Item)),
+ UsedItemAt((CharacterUnmasked, Item, Time)),
+ TimeIs(Time),
+ FriendOf((CharacterUnmasked, CharacterUnmasked)),
}
diff --git a/crates/elfmind/src/knowledge/traits.rs b/crates/elfmind/src/knowledge/traits.rs
new file mode 100644
index 0000000..6db9250
--- /dev/null
+++ b/crates/elfmind/src/knowledge/traits.rs
@@ -0,0 +1,273 @@
+use crate::knowledge::*;
+
+pub trait DisplayNoun {
+ fn display_noun(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result;
+}
+
+pub trait DisplayTuple {
+ fn display_tuple(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result;
+}
+impl<A: DisplayNoun> DisplayTuple for A {
+ // display any single noun as a 1-tuple
+ fn display_tuple(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "(")?;
+ self.display_noun(f)?;
+ write!(f, ")")
+ }
+}
+impl<A: DisplayNoun, B: DisplayNoun> DisplayTuple for (A, B) {
+ fn display_tuple(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "(")?;
+ self.0.display_noun(f)?; write!(f, ", ")?;
+ self.1.display_noun(f)?;
+ write!(f, ")")
+ }
+}
+impl<A: DisplayNoun, B: DisplayNoun, C: DisplayNoun> DisplayTuple for (A, B, C) {
+ fn display_tuple(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "(")?;
+ self.0.display_noun(f)?; write!(f, ", ")?;
+ self.1.display_noun(f)?; write!(f, ", ")?;
+ self.2.display_noun(f)?;
+ write!(f, ")")
+ }
+}
+impl<A: DisplayNoun, B: DisplayNoun, C: DisplayNoun, D: DisplayNoun> DisplayTuple for (A, B, C, D) {
+ fn display_tuple(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "(")?;
+ self.0.display_noun(f)?; write!(f, ", ")?;
+ self.1.display_noun(f)?; write!(f, ", ")?;
+ self.2.display_noun(f)?; write!(f, ", ")?;
+ self.3.display_noun(f)?;
+ write!(f, ")")
+ }
+}
+impl<A: DisplayNoun, B: DisplayNoun, C: DisplayNoun, D: DisplayNoun, E: DisplayNoun> DisplayTuple for (A, B, C, D, E) {
+ fn display_tuple(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "(")?;
+ self.0.display_noun(f)?; write!(f, ", ")?;
+ self.1.display_noun(f)?; write!(f, ", ")?;
+ self.2.display_noun(f)?; write!(f, ", ")?;
+ self.3.display_noun(f)?; write!(f, ", ")?;
+ self.4.display_noun(f)?;
+ write!(f, ")")
+ }
+}
+
+pub trait Concretizable {
+ type Concrete;
+ fn concretize(&self) -> Option<Self::Concrete>;
+}
+impl<A: Clone> Concretizable for Hole<A> {
+ type Concrete = A;
+ fn concretize(&self) -> Option<Self::Concrete> {
+ match self {
+ Self::Val(x) => Some(x.clone()),
+ _ => None,
+ }
+ }
+}
+impl<
+ A: Clone,
+ B: Clone,
+ > Concretizable for (Hole<A>, Hole<B>) {
+ type Concrete = (A, B);
+ fn concretize(&self) -> Option<Self::Concrete> {
+ let a = self.0.concretize()?;
+ let b = self.1.concretize()?;
+ Some((a, b))
+ }
+}
+impl<
+ A: Clone,
+ B: Clone,
+ C: Clone,
+ > Concretizable for (Hole<A>, Hole<B>, Hole<C>) {
+ type Concrete = (A, B, C);
+ fn concretize(&self) -> Option<Self::Concrete> {
+ 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<A>, Hole<B>, Hole<C>, Hole<D>) {
+ type Concrete = (A, B, C, D);
+ fn concretize(&self) -> Option<Self::Concrete> {
+ 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<A>, Hole<B>, Hole<C>, Hole<D>, Hole<E>) {
+ type Concrete = (A, B, C, D, E);
+ fn concretize(&self) -> Option<Self::Concrete> {
+ 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<F>(&self, f: &mut F) -> Self where F: FnMut(Var) -> Var;
+}
+impl<A: Clone + TryFrom<Noun>> Substitutable for Hole<A> {
+ 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<F>(&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<Noun>,
+ B: Clone + TryFrom<Noun>
+ > Substitutable for (Hole<A>, Hole<B>) {
+ fn substitute(&self, u: &Unification) -> Self {
+ let (a, b) = self;
+ (a.substitute(u), b.substitute(u))
+ }
+ fn map_variables<F>(&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<Noun>,
+ B: Clone + TryFrom<Noun>,
+ C: Clone + TryFrom<Noun>,
+ > Substitutable for (Hole<A>, Hole<B>, Hole<C>) {
+ fn substitute(&self, u: &Unification) -> Self {
+ let (a, b, c) = self;
+ (a.substitute(u), b.substitute(u), c.substitute(u))
+ }
+ fn map_variables<F>(&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<Noun>,
+ B: Clone + TryFrom<Noun>,
+ C: Clone + TryFrom<Noun>,
+ D: Clone + TryFrom<Noun>,
+ > Substitutable for (Hole<A>, Hole<B>, Hole<C>, Hole<D>) {
+ 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<F>(&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<Noun>,
+ B: Clone + TryFrom<Noun>,
+ C: Clone + TryFrom<Noun>,
+ D: Clone + TryFrom<Noun>,
+ E: Clone + TryFrom<Noun>,
+ > Substitutable for (Hole<A>, Hole<B>, Hole<C>, Hole<D>, Hole<E>) {
+ 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<F>(&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<Unification>;
+}
+impl<A> Unifiable for Hole<A> where
+ Noun: From<A>, A: Copy,
+{
+ fn unify(&self, other: &Self::Concrete, mut u: Unification) -> Option<Unification> {
+ if u.unify_hole(self, other) {
+ Some(u)
+ } else { None }
+ }
+}
+impl<A, B> Unifiable for (Hole<A>, Hole<B>) where
+ Noun: From<A>, A: Copy,
+ Noun: From<B>, B: Copy,
+{
+ fn unify(&self, other: &Self::Concrete, mut u: Unification) -> Option<Unification> {
+ let (a1, b1) = self;
+ let (a2, b2) = other;
+ if u.unify_hole(a1, a2) && u.unify_hole(b1, b2) {
+ Some(u)
+ } else { None }
+ }
+}
+impl<A, B, C> Unifiable for (Hole<A>, Hole<B>, Hole<C>) where
+ Noun: From<A>, A: Copy,
+ Noun: From<B>, B: Copy,
+ Noun: From<C>, C: Copy,
+{
+ fn unify(&self, other: &Self::Concrete, mut u: Unification) -> Option<Unification> {
+ 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<A, B, C, D> Unifiable for (Hole<A>, Hole<B>, Hole<C>, Hole<D>) where
+ Noun: From<A>, A: Copy,
+ Noun: From<B>, B: Copy,
+ Noun: From<C>, C: Copy,
+ Noun: From<D>, D: Copy,
+{
+ fn unify(&self, other: &Self::Concrete, mut u: Unification) -> Option<Unification> {
+ 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<A, B, C, D, E> Unifiable for (Hole<A>, Hole<B>, Hole<C>, Hole<D>, Hole<E>) where
+ Noun: From<A>, A: Copy,
+ Noun: From<B>, B: Copy,
+ Noun: From<C>, C: Copy,
+ Noun: From<D>, D: Copy,
+ Noun: From<E>, E: Copy,
+{
+ fn unify(&self, other: &Self::Concrete, mut u: Unification) -> Option<Unification> {
+ 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 }
+ }
+}