我正在尝试在 ECLiPSe Prolog 中实现一个元程序,这是我编写的代码 -
:- dynamic go/1.
sol(true):- !.
sol((A,B)):- !, sol(A), sol(B).
sol(A):- clause(A, Body), sol(Body).
go(X):- X is 5.
现在,当我使用 sol(go(X)).
查询时,出现错误访问子句中另一个模块中定义的过程(X is 5, _292)
然后它就中止了。我尝试清除所有顶级模块并重新打开 ECLiPSe 然后运行,但仍然出现相同的错误。
可能是什么原因?
谢谢!
最佳答案
谓词p/1
正在使用内置谓词(is)/2
。请注意,X is 5
在语法上是一种更方便的书写 is(X,5)
的方式。但是您的元解释器只期望用户定义的谓词,并且控制构造 (',')/2
和 true/0
。如果您想处理 (is)/2
您必须为其引入一个单独的子句。
sol(X is Y) :- !, X is Y.
在 ISO Prolog 中,目标 predicate_property(Goal,built_in)
可用于测试 Goal
是否为内置谓词。这适用于许多系统,如 B、GNU、SICStus、SWI、XSB、YAP。所以你可以写:
sol(Bip) :- predicate_property(Bip, built_in), !, Bip.
在 ECLiPSe 中,这个内置函数不能直接使用。您必须加载一个库。 index of the manual建议使用库 swi
或 quintus
。由于某些(不清楚)原因,它不是 ECLiPSe 库 iso
的一部分,但它是 ISO。所以说
:- use_module(library(swi)).
首先在您的文件(或顶层)中。
如果您希望元解释器涵盖完整的 Prolog 语言,您将必须显式处理所有控制结构。它们在这里 - 按照标准(7.8 控制结构)中的定义。
true/0
失败/0
调用/1
!/0
(',')/2
(;)/2
- 析取(->)/2
(;)/2
- if-then-elsecatch/3
抛出/1
请注意,只有少数情况可以通过直接调用目标来处理。其中大多数必须明确处理!
关于prolog - 在 prolog 中编译数据程序时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9342460/