Skip to content

Commit

Permalink
feat: Term::is_isomorphic_to and associated tests
Browse files Browse the repository at this point in the history
  • Loading branch information
AgentElement committed May 29, 2024
1 parent e10c296 commit f9b593f
Showing 1 changed file with 51 additions and 0 deletions.
51 changes: 51 additions & 0 deletions src/term.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,48 @@ impl Term {
}
}
}

/// Returns `true` if `self` is structurally isomorphic to `other`.
///
/// # Example
/// ```
/// use lambda_calculus::*;
///
/// let term1 = abs(Var(1)); // λ 1
/// let term2 = abs(Var(2)); // λ 2
/// let term3 = abs(Var(1)); // λ 1
///
/// assert_eq!(term1.is_isomorphic_to(&term2), false);
/// assert_eq!(term1.is_isomorphic_to(&term3), true);
///
/// ```
pub fn is_isomorphic_to(&self, other: &Term) -> bool {
match self {
Var(x) => {
if let Var(y) = other {
x == y
} else {
false
}
}
Abs(p) => {
if let Abs(q) = other {
p.is_isomorphic_to(q)
} else {
false
}
}
App(p_boxed) => {
if let App(q_boxed) = other {
let (ref fp, ref ap) = **p_boxed;
let (ref fq, ref aq) = **q_boxed;
fp.is_isomorphic_to(fq) && ap.is_isomorphic_to(aq)
} else {
false
}
}
}
}
}

/// Wraps a `Term` in an `Abs`traction. Consumes its argument.
Expand Down Expand Up @@ -677,4 +719,13 @@ mod tests {
9
);
}

#[test]
fn is_isomorphic_to() {
assert!(abs(Var(1)).is_isomorphic_to(&abs(Var(1))));
assert!(!abs(Var(1)).is_isomorphic_to(&abs(Var(2))));
assert!(!app(abs(Var(1)), Var(1)).is_isomorphic_to(&app(abs(Var(1)), Var(2))));
assert!(app(abs(Var(1)), Var(1)).is_isomorphic_to(&app(abs(Var(1)), Var(1))));
assert!(!app(abs(Var(1)), Var(1)).is_isomorphic_to(&app(Var(2), abs(Var(1)))));
}
}

0 comments on commit f9b593f

Please sign in to comment.