序言-生成整数“不可逆地”

时间:2018-12-12 04:19:37

标签: prolog

我正在尝试使用De Bruijn索引定义lambda微积分项。我在OS X上使用swi prolog。

如果我使用自然数的title = {content} title3 = {entry} title1 = {entry, entry, entry} title2 = {entry, entry} 表示形式,则可以交互式完成部分指定的术语。

zero|successor

例如,nat(zero). nat(s(X)) :- nat(X). debruijn2(N) :- nat(N). debruijn2(ap(M, N)) :- debruijn2(M), debruijn2(N). debruijn2(lambda(M)) :- debruijn2(M). ZX中的zero统一。

ap(Z, X)

但是,使用?- debruijn2(ap(X, Z)). X = Z, Z = zero . 检查数字like this会产生类型错误,除非length的参数只是一个整数。

debruijn

查询debruijn(N) :- length(_, N). debruijn(ap(M, N)) :- debruijn(M), debruijn(N). debruijn(lambda(M)) :- debruijn(M). 成功,并且debruijn(X).X统一。

0

但是,查询?- debruijn(X). X = 0 . 失败,好像debruijn(ap(Z, X)).不可撤销地将其第二个参数约束为整数。

length(_, ·)

为什么?- debruijn(ap(Z, X)). ERROR: Type error: `integer' expected, found `ap(_2944,_2946)' (a compound) ERROR: In: ERROR: [10] throw(error(type_error(integer,...),context(...,_3008))) ERROR: [8] debruijn(ap(_3036,_3038)) at <...>:2 ERROR: [7] <user> ERROR: ERROR: Note: some frames are missing due to last-call optimization. ERROR: Re-run your program in debug mode (:- debug.) to get more detail. Exception: (8) debruijn(ap(_2362, _2364)) ? creep 会产生类型错误,而不仅仅是不应用于参数?

2 个答案:

答案 0 :(得分:3)

一种在SWI-Prolog上运行而不使用昂贵的对length/2catch/3的调用的替代方法:

debruijn(N)         :- simple(N), nat(N).
debruijn(ap(M, N))  :- debruijn(M), debruijn(N).
debruijn(lambda(M)) :- debruijn(M).

nat(0).
nat(I) :-
    nat(1, I).

nat(I, I).
nat(I, J) :-
    I2 is I + 1,
    nat(I2, J).

如果simple/1谓词未实例化为复合词,则谓词成功。这是一个从未被标准化但仍在某些Prolog系统中发现的传统谓词(例如,它是SWI-Prolog中的一个库谓词,而在SICStus Prolog中是一个内置谓词)。

与基于length/2的解决方案的不同之处可能与您的用例无关,也可能与您的用例无关,这是当使用负数调用debruijn/1时的行为。在这种情况下,此解决方案将陷入循环并最终出错,但是length/2将引发一个异常,catch/3包装器将转换为失败。

答案 1 :(得分:2)

我怀疑是因为Prolog尝试在搜索过程中评估length/2谓词。根据{{​​3}},如果第二个参数绑定到非整数,则会引发错误。不同于仅使检查失败。

您可以使用manual将失败变成错误的谓词:

debruijn(N)          :- catch(length(_, N), _, false).
debruijn(ap(M, N))   :- debruijn(M), debruijn(N).
debruijn(lambda(M))  :- debruijn(M).

Manual说,从异常中恢复很慢。无论如何我都不是Prolog专家,所以也许有更好的解决方案。