【问题标题】:Defining predicates in SICStus Prolog / SWI-Prolog REPL在 SICStus Prolog / SWI-Prolog REPL 中定义谓词
【发布时间】:2011-11-11 13:57:48
【问题描述】:

我正在阅读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)
| ?- 

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

我是否只允许在文件中定义谓词以便稍后查阅它们?我不能只在编辑器中做吗?

【问题讨论】:

    标签: prolog prolog-toplevel prolog-assert


    【解决方案1】:

    在 repl 中做谓词有点烦人。你可以这样做

    | ?- ['user'].
    woman(mia).
    ^D
    

    即咨询用户输入,或

    | ?- assertz(woman(mia)).
    

    断言它。两者都尴尬 IMO - 可能有更好的方法,但我只是不知道。一般来说,使用脚本更容易。

    【讨论】:

      【解决方案2】:

      您应该在文件中输入woman(mia). 以将其声明为事实。如果你把它写到解释器中,它会被当作一个查询,而不是一个事实。

      来自SWI Prolog FAQ

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

      carnivore(X) :- animal(X), eats_meat(X).
      

      尝试在顶层输入它会导致以下错误。为什么? 因为规则是一个术语 :-(Head, Body),并且因为顶层 将术语解释为查询。没有带有名称的谓词:- 和两个参数。

      ?- 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
      

      这不是傻吗?嗯,没有。假设我们有一个术语 吃肉(rataplan)。如果这出现在文件中,则说明事实 那个rataplan吃肉。如果它出现在顶层,它会询问 Prolog 尝试证明rataplan是否吃肉。

      如果文本阅读

      :- use_module(library(clpfd)).
      

      这是一个指令。指令类似于查询,但不是 要求顶层做某事,他们要求编译器做 某物。与规则和事实一样,此类术语也属于文件。

      除了写入文件之外,您还可以在顶层使用 assert(如后面的常见问题解答中所述)。

      【讨论】:

      • 所以,在这种情况下 assert(woman(mia))。会做我想做的事吗?
      • 错误信息可能会误导新手。由于规则也可以从用户加载,这不完全是一个文件。但这是创建良好错误消息的普遍问题。