Приведу свой последний код.
О, я его сейчас подправил, и он заработал!
Тогда точно приведу:
Код:
β1[λ[x_, f_]∘y_] := ReplaceAll[f, x -> y]
β1[otherexpr_] := otherexpr
-редукция один раз
Код:
β[expr_] := Module[
{results = {}, e = expr},
While[! OccurQ[e, results],
AppendTo[results, e = β1[e]]
];
e
]
OccurQ[elem_, list_] := If[ (* MemberQ здесь непригодно *)
Do[
If[list[[i]] == elem, Break[True]],
{i, Length[list]}
] === Null,
False, True
]
β[λexpr_∘y1_∘y2_] := β[β1[λexpr∘y1]∘y2]
β[y1_?(Head[#] =!= λ &)∘y2_] := y1∘β[y2]
-редукция до повторения
Код:
λ[L_List, f_] := λ[First[L], λ[Rest[L], f]]
λ[{L1_}, f_] := λ[L1, f]
λ[L1_, L2__, f_] := λ[{L1, L2}, f]
SmallCircle[a_, b_, c__] := SmallCircle[SmallCircle[a, b], c]
SmallCircle /: (a∘c) == (b∘c) := a == b
SmallCircle /: (c∘a) == (c∘b) := a == b
λ /: λ[x_, f_] == λ[y_, g_] := β[λ[x, f]∘a$0001] == β[λ[y, f]∘a$0001]
дополнительные правила: для упрощённой записи и для сравнений
Вот пример использования этой писанины:
Код:
In : λ[a, b, a^2 + b^2]∘t∘b // β
Out: b^2 + t^2
Примеры записи (комбинаторы):
Код:
λI = λ[x, x]
λK = λ[x, y, x]
λKs = λ[x, y, y]
λS = λ[x, y, z, x∘z∘(y∘z)]
λY2 = λ[x, f∘(x∘x)] (* Всего лишь кусок из Y *)
λY = λ[f, λY2∘λY2]
Используя пакет Utilities`Notations`, можно ещё и вывод сделать в "традиционной форме".