3

我用我能想到的最好的方式来写标题,但让我说清楚。在 Prolog 中编写 DFA 时,这是一种典型的做法:

start(q0).
final(q2).

transition(q0, a, q1).
transition(q1, b, q1).
transition(q1, c, q2).

accept(Symbols) :- start(StartState), accept(Symbols, StartState).

accept([], State) :- final(State).

accept([Symbol|Symbols], State) :- transition(State, Symbol, NextState), 
                                accept(Symbols, NextState).

我了解这段代码的作用,它的目标是什么,以及所有这些。令我难以置信的是“接受”规则。同样,我了解正在执行的操作背后的逻辑,但我不明白的是 StartState 和 NextState 的突然使用。这些都是凭空出现的,我不明白 start(StartState) 是如何开始返回 true 的,更不用说值的来源了。使用 NextState 也是如此。Prolog“认为”这些价值是什么?过渡事实如何接受它们?

如果我从事实开始:start(q0).,那么 start(StartState) 是怎样的。真的?

4

2 回答 2

3

虽然 mat 的回答是正确的,但我将在这里给您一些操作语义,即它是如何发生的。

你问,“如果我从事实开始:start(q0).,那么如何是start(StartState).真的?”

答:StartState是一个逻辑变量。它还没有设置任何值。是我们写了这个名字,“不知从何而来”——它可以是我们选择的任何名字;Prolog 看到它,看到它是一个新名称(以大写字母开头),并使用该名称创建一个新的 logvar,该名称尚未实例化(分配一个值)。它就像一个 NULL 指针,它只能在以后设置一次(除非系统回溯,但这是一个正交问题)。

这就是 Prolog 的工作方式:它看到一个查询start(X);它看到X的是一个新的 logvar;现在它试图证明这个查询。这意味着,它会在所有已知的事实和规则中搜索与我们的查询匹配的头部。

有一个:这是事实start(q0)。注意q0以小写字母开头。这意味着它是一个原子,一个符号数据。变量以大写字母开头。

Prolog 如何发现事实start(q0)?它就是这样。这是给定 Prolog 实现的细节。它在构成我们编写的程序的所有事实和规则中找到它,并加载到 Prolog 中。

现在系统start(q0)start(X). 这称为统一

start(q0) = start(X)

这成功了,与X = q0. 一个 logvarX被分配了它的值,并且匹配成功。因此,使用替换 { X = q0 }证明了该查询。

这就是 Prolog 的工作原理。

但实际上,您应该阅读一个好的 Prolog 教程,以便您理解上面所有的斜体字。在那之后会有更多的问题需要学习,所以你最终可以确信你“理解”了 Prolog。

于 2013-10-28T11:50:28.300 回答
2

嗯,这真的是最琐碎和最基本的事情:鉴于一个事实

start(q0).

查询:

?- start(State).

successyield State = q0,这显然可以从给定的事实中推断出来,因为这正是事实所说的:start(S)true if S = q0

以声明的方式阅读您的子句,例如:如果 从 开始接受start(State)成立 则成立。试着以同样的方式阅读其他从句,你就会清楚他们在说什么。SymbolsState accept(Symbols)

于 2013-10-28T08:07:29.520 回答