prolog - prolog - 生成整数“unwindably”
问题描述
我正在尝试用 De Bruijn 指数定义 lambda 演算术语。我在 OS X 上使用 swi prolog。
如果我使用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).
例如,Z
并与inX
统一。zero
ap(Z, X)
?- debruijn2(ap(X, Z)).
X = Z, Z = zero .
但是,使用length
to 检查这样的数字会产生类型错误,除非参数 todebruijn
只是一个整数。
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
为什么会length/2
产生类型错误而不是仅仅未能应用于参数?
解决方案
在 SWI-Prolog 上运行的替代方案,无需对length/2
and进行昂贵的调用catch/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
包装器将转换为失败。
推荐阅读
- flutter - Flutter - 具有 3D 效果的页面之间的过渡
- ios - 使用 GET 请求快速登录用户
- sql - 将带有 GET 变量的 API Gateway URL 共享给测试人员
- c# - Exchange2010_SP2 版本的 Exchange api 过滤问题
- api - 如何首次将与会者添加到日历活动?
- jena - 为什么 Jena fuseki 对猫头鹰的推理没有反应?
- google-apps-script - 从子文件夹(在 Google Drive 上)获取特定文件(Google Sheet),然后更改单元格的值
- postgresql - 是否可以在“创建物化视图为”形式的物化视图上创建新索引?
- reactjs - 迭代和 Typescript 优化
- c# - .NET 是在新的不同线程池线程上恢复等待继续,还是重用以前恢复的线程?