我是Prolog的新手,但我被困在这个所谓的简单命令上。我已加载一个没有错误的知识库,每当我尝试断言(甚至帮助)我收到以下消息:
uncaught exception: error(existence_error(procedure,assert/1),top_level/0)
{2}
我到底错过了什么?赞赏。
改用assertz/1
或asserta/1
。GNU-Prolog不提供assert/1
因为标准中只定义了asserta/1
和assertz/1
。
请注意,虽然asserta/1
总是有一个明确的解释,意思是在开头添加子句,但assertz/1
的含义更难解决,因为"在末尾添加子句"并不能完全确定在断言子句之前调用的目标的语义。
使用ISO-Prolog,在assertz/1
之前调用的目标(但也retract/1
)不受影响。这称为逻辑更新视图。引用标准(ISO/IEC 13211-1:1995):
7.5.4 逻辑数据库更新
由于
执行目标(例如,当
子目标是assertz/1
或retract/1
)的调用,应影响
仅之后开始执行的激活。这
更改不会影响当前
正在进行的任何激活 正在执行。注意 — 因此,数据库在执行期间
被冻结 一个目标,定义谓词的子句列表固定在
执行的时刻(见7.7.7 E)。
请注意,在DECsystem 10 Prolog中,手册在assert/1
和assertz/1
之间产生了很大的差异。在 1978 年 DECsystem 10 用户指南的以下引文中,术语"实现定义"只能表示标准中已知的实现依赖性(意味着基本上未定义)。
5.5 元逻辑
。
assert(C)
C
的当前实例被解释为子句并被添加
到当前解释的程序(带有新的私有变量
) 替换任何未实例化的变量)。新
相关程序中的子句是实现定义的。
C
必须实例化为非变量。
asserta(C)
像
assert(C)
一样,除了新子句成为第一个
有关程序的条款。
assertz(C)
像
assert(C)
一样,除了新子句成为最后一个
有关程序的条款。
同样在今天,有些系统assert/1
和assertz/1
不同。 例如,xsb。