在SICStus Prolog/SWI-Prolog REPL中定义谓词

dev*_*ium 5 prolog prolog-toplevel prolog-assert

我正在阅读http://cs.union.edu/~striegnk/learn-prolog-now/html/node3.html#subsec.l1.kb1,但我在运行以下谓词时遇到问题:

SICStus 4.0.1 (x86-win32-nt-4): Tue May 15 21:17:49 WEST 2007
| ?- woman(mia).
! Existence error in user:woman/1
! procedure user:woman/1 does not exist
! goal:  user:woman(mia)
| ?- 
Run Code Online (Sandbox Code Playgroud)

另一方面,如果我将它写入文件并运行参考文件,它似乎工作正常...

我是否只允许在稍后查询它们的文件中定义谓词?我不能只在编辑器中做到这一点吗?

Owe*_*wen 10

在repl中创建谓词有点烦人.你可以做到

| ?- ['user'].
woman(mia).
^D
Run Code Online (Sandbox Code Playgroud)

即咨询用户输入,或

| ?- assertz(woman(mia)).
Run Code Online (Sandbox Code Playgroud)

断言.两个尴尬的IMO - 可能有更好的方式,但是,我只是不知道它.通常,使用脚本更容易.


sep*_*p2k 7

你应该输入woman(mia).一个文件来断言它作为一个事实.如果将其写入解释器,则将其视为查询,而不是事实.

来自SWI Prolog FAQ:

您在顶层输入的术语是作为查询的进程,而出现在加载到Prolog中的文件中的术语将作为一组规则和事实处理.如果文本如下所示,这是一个规则.

carnivore(X) :- animal(X), eats_meat(X).
Run Code Online (Sandbox Code Playgroud)

试图在顶层输入此值会导致下面的错误.为什么?因为规则是一个术语:-( Head,Body),因为toplevel将术语解释为查询.名称没有谓词: - 和两个参数.

?- carnivore(X) :- animal(X), eats_meat(X). ERROR: Undefined
procedure: (:-)/2 ERROR:   Rules must be loaded from a file ERROR:  
See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt
Run Code Online (Sandbox Code Playgroud)

这不是傻吗?好吧,不.假设我们有一个术语eats_meat(rataplan).如果这出现在文件中,则表明rataplan吃肉的事实.如果它出现在顶层,它要求Prolog尝试证明rataplan是否吃肉.

如果文本读取

:- use_module(library(clpfd)).
Run Code Online (Sandbox Code Playgroud)

这是一个指令.指令与查询类似,但它们不是要求顶层做某事,而是要求编译器执行某些操作.与规则和事实一样,这些术语属于文件.

您也可以assert在顶层中使用,而不是写入文件(如后面的FAQ中所述).

  • 错误消息可能会误导新手。由于规则也可以从用户加载,这不完全是一个文件。但这是创建良好错误消息的普遍问题。 (2认同)