原子与变量
以大写字母开头的字符串,如Hermione
,,是一个变量。如果它以小写字母开头,例如hermione
,它是一个原子(将其视为其他语言中的“常量”)。或者,如果它在单引号中,例如'Hermione'
,它也是一个原子。
以下是事实:
witch(hermione).
它可以读作:hermione
是一个witch
. 它的真正阅读方式(或者更具体地说,它的语义含义是什么)取决于你,程序员。
如果我在 Prolog 提示符下查询这个事实,它将成功:
| ?- witch(hermione).
yes
(注意,这是gprolog
,所以它产生yes
。我认为 SWI Prolog 会说true
,但它们都表示“成功”。)
我还可以使用变量进行查询,Prolog 会告诉您变量的哪些实例化(设置)将使它成为真的:
| ?- witch(Hermione).
Hermione = hermione ? ;
Hermione = 'McGonagall' ? ;
Hermione = rita_skeeter
(1 ms) yes
请记住:Hermione
是一个变量,并且hermione
是一个原子。它们不是同一件事。因此,变量Hermione
可以具有上述任何一个值以使其witch(Hermione)
为真。您也可以使用而不是查询,witch(Fred)
并得到与上面相同的结果。Fred
Hermione
基本谓词逻辑
现在让我们看看谓词,magic/1
(1
这里表示arity,或者参数magic
有多少):
magic(X):- house_elf(X).
magic(X):- wizard(X).
magic(X):- witch(X).
从语义上讲,您可以将其解读为X
is magic
if X
is a house_elf
,OR X
is magic
if X
is a wizard
,OR X
is magic
if X
is awitch
。
如果我们再查询:
| ?- magic(Hermione).
Prolog 将尝试找出哪些实例化Hermione
将使此成功,并告诉您这些值是什么。在您的所有事实和谓词中,它会在 子句 处找到第一个匹配项magic(X):- house_elf(X).
,使用Hermione
代替 的变量X
,它会发现 if Hermione = dobby
, thenhouse_elf(Hermione)
为真,因此magic(Hermione)
也为真。它将显示作为第一个解决方案Hermione = dobby
:
| ?- magic(Hermione).
Hermione = dobby ? ;
通过按;
这里(或空格),Prolog 将尝试找到下一个解决方案,在这种情况下,它不会找到下一个成功,直到它进入下一个子句,magic(X):- wizard(X).
. 假设您有一些事实wizard/1
,它将在这些方面取得成功。如果wizard/1
未在您的事实或谓词中定义,那么您将从 Prolog 收到一个存在错误,指出它不知道wizard/1
. Prolog 将继续遍历您的谓词从句,寻找使其成功的方法,并告诉您什么值(实例化)Hermione
将使它如此,直到它用尽所有情况。然后它最终会停止。
我将把它作为一个练习来计算搜索树,但在“Prolog 搜索树”上进行 Google 搜索以找到一些好的示例。我假设您有 Prolog 解释器,您可以在其中输入代码并使用查询来查看会发生什么。您可以启用跟踪 (enter trace.
) 以查看有关 Prolog 在查询中所做的一些详细信息。所有这些方法都可以帮助理解 Prolog 操作的某些方面。