De Bruijn 索引是用于替换比 Prolog 中更困难的设置的工具。逻辑变量是一种优越的工具。我认为您永远不会想编写 Prolog 代码来处理 de Bruijn 索引。(元问题在下面回复你。)
无论如何,从问题链接的 PDF的第二页包含所需的一切的 Prolog 实现。它只是使用非标准的、所谓的“函数式”语法。
这是正确语法中的转换关系:
funny_arrow(I, C, Term, Shifted) :-
( number(Term)
-> ( Term < C
-> Shifted = Term
; Shifted is Term + I )
; Term = lambda(E)
-> Shifted = lambda(Shifted1),
C1 is C + 1,
funny_arrow(I, C1, E, Shifted1)
; Term = apply(E1, E2)
-> Shifted = apply(Shifted1, Shifted2),
funny_arrow(I, C, E1, Shifted1),
funny_arrow(I, C, E2, Shifted2) ).
这是替换:
substitute(Term, E, M, Substituted) :-
( number(Term)
-> ( Term = M
-> Substituted = E
; Substituted = Term )
; Term = lambda(E1)
-> Substituted = lambda(E1Subst),
funny_arrow(1, 0, E, EShifted),
M1 is M + 1,
substitute(E1, EShifted, M1, E1Subst)
; Term = apply(E1, E2)
-> Substituted = apply(E1Subst, E2Subst), % typo in original?
substitute(E1, E, M, E1Subst),
substitute(E2, E, M, E2Subst) ).
您可以以相同的方式转录 beta 减少规则。
然后我们可以测试一下。在 PDF 中使用的搞笑语言中,每个基本术语都必须编码为数字,因此我们将选择a
as123
和b
as456
任意编码。减少术语(K a) b
将通过减少应用两个减少步骤来完成,首先减少K a
到KA
,然后应用KA
到b
。干得好:
?- K = lambda(lambda(1)),
A = 123,
B = 456,
reduce(apply(K, A), KA),
reduce(apply(KA, B), KAB).
K = lambda(lambda(1)),
A = KAB, KAB = 123,
B = 456,
KA = lambda(124).
结果KAB
与 相同A
。您可以通过定义更简单、更有效地获得相同的结果:
apply(lambda(X, E), X, E).
接着:
?- K = lambda(X, lambda(Y, X)),
apply(K, a, KA),
apply(KA, b, KAB).
K = lambda(a, lambda(b, a)),
X = KAB, KAB = a,
Y = b,
KA = lambda(b, a).
你当然知道这一点。
Meta:您关于从符号逻辑中编码晦涩主题的问题并没有引起很大的关注。部分原因是它们中的大多数都不是很有趣。部分原因是他们缺乏所有细节和展示你所做的任何努力. 但我认为第三部分是社区不理解您对这些问题的全部意义。你是一个有成就的 Prolog 程序员和实现者并不是什么秘密。显然,您可以将一些简单的方程式转录到 Prolog 中。那么为什么要问别人呢?这是否意味着某种项目来建立“社区维基”或标准符号算法的 Prolog 实现数据库?这甚至可能很有趣,但如果您传达项目存在以及它的目的是什么,您可能会在该项目中获得更多参与者。