use crate::Term;
pub fn compose() -> Term<&'static str> {
lambda!(λ f g x. f (g x))
}
pub fn flip() -> Term<&'static str> {
lambda!(λ f x y. f y x)
}
pub fn id() -> Term<&'static str> {
lambda!(λ x. x)
}
pub fn constant() -> Term<&'static str> {
lambda!(λ x y. x)
}
pub fn omega() -> Term<&'static str> {
app!(app_self(), app_self())
}
pub fn app_rev() -> Term<&'static str> {
lambda!(λ x y. y x)
}
pub fn sub() -> Term<&'static str> {
lambda!(λ x y z. x z (y z))
}
pub fn fix_turing() -> Term<&'static str> {
lambda!((λ x y. y (x x y)) (λ x y. y (x x y)))
}
pub fn dup() -> Term<&'static str> {
lambda!(λ f x. f x x)
}
pub fn fix_lazy() -> Term<&'static str> {
lambda!(λ f. (λ x. f (x x)) (λ x. f (x x)))
}
pub fn fix_strict() -> Term<&'static str> {
lambda!(λ f. (λ x. f (λ y. x x y)) (λ x. f (λ y. x x y)))
}
pub fn universal() -> Term<&'static str> {
abs!(x. app!(var!(x), sub(), constant()))
}
pub fn app_self() -> Term<&'static str> {
lambda!(λ x. x x)
}