非确定性自动机模拟的声明性解释

时间:2013-03-31 09:37:31

标签: prolog declarative

以下Prolog程序模拟非确定性自动机:

final(s3).

trans(s1,a,s2).
trans(s1,b,s1).
trans(s2,b,s3).
trans(s3,b,s4).

silent(s2,s4).
silent(s3,s1).

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

accepts(State, [X|Rest]) :- trans(State,X,State1),
                            accepts(Stat1,Rest).

accepts(State, Rest) :- silent(State, State1),
                        accepts(State1, Rest).

好的我有3种不同的事实:

第一个人说我 s3 最终状态(接受状态) 事实的第二种类型指定了读取字符串字符的自动机的转换。

例如:如果我处于状态s1并且读取了字符a,那么它可以传递到状态s2。

第三个指定空转换:这是从状态到不需要输入字符的其他状态的任意转换。

例如:

silent(s2,s4) 

指定自动机可以任意从s2传递到s4而不读取任何内容。

好的,现在我有规则指定如何从一个状态传递到另一个状态,以及如果它是一个接受状态怎么说。

第一个问题是:

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

它说:空字符串[],如果状态是最终状态,则从状态接受。

第二条规则是:

accepts(State, [X|Rest]) :- trans(State,X,State1),
                            accepts(State1,Rest).

说:字符串它不是EMPTY,如果读取字符串的第一个符号X,自动机可以传递到某个状态State1并接受字符串的其余部分,则该字符串从当前状态State接受来自State1。

第三条规则是:

accepts(State, Rest) :- silent(State, State1),
                        accepts(State1, Rest).

并且它说:如果自动机可以使静默从当前状态状态移动到另一个状态State1并且状态State1可以接受整个输入字符串,则从状态接受字符串。 < / p>

因此,如果在Prolog shell中执行语句:

accepts(s1,[a,a,a,b]).

响应为 true

但是,究竟意味着什么?

这意味着s1状态接受[a,a,a,b]字符串,因为我从初始状态s1到接受状态s3有很多自动机转换?< /强>

第二个疑问是与书上显示的例子有关。

在书上执行此查询(获取从s1带到最终状态s3的3个字符的所有序列)并获得以下输出:

?- accepts(s1, [X1,X2,X3]).

X1 = a
X2 = a
X3 = b;

X1 = b
X2 = a
X3 = b;

no

这是合理的但如果我尝试在我的Prolog shell上执行它,我会获得此输出:

11 ?- accepts(s1, [X1,X2,X3]).
X1 = X2, X2 = a,
X3 = b ;
X1 = X3, X3 = b,
X2 = a ;
false.

为什么?

1 个答案:

答案 0 :(得分:2)

首先,当我查阅你的代码(变量名Stat1)时,我得到一个单例变量警告。当我更正它时,列表[a,a,a,b]是(正确地,假设您声明的转换)不再被接受。此外,我稍微重写了您的代码,以便将最终状态转换为关系:

automaton(State, State, []) :- final(State).
automaton(State0, State, [X|Xs]) :-
        trans(State0, X, State1),
        automaton(State1, State, Xs).
automaton(State0, State, Rest) :-
        silent(State0, State1),
        automaton(State1, State, Rest).

变量命名方案Var0, Var1, ..., Var,其中Var0表示某些上下文中的初始状态,Var表示最终状态,在描述Prolog中的状态转换时是一种通常有用的命名模式。您现在可以使用此关系来查看自动机中达到的最终状态(在您的示例中,它当然始终是唯一的最终状态s3):

?- automaton(s1, State, Xs).
State = s3,
Xs = [a, b] ;
State = s3,
Xs = [a, b, a, b] ;
State = s3,
Xs = [a, b, a, b, a, b] .

关于你的上一个问题:是的,你是对的,答案在声明上是等价的,SWI Prolog只是以不同的方式写出来(X = a, Y = a声明性地等同于X = Y, X = a)。

编辑:您可以概括一下这个想法:在下面的代码中,我使用DCG来描述导致最终状态的状态转换序列:

automaton(State, []) --> { final(State) }.
automaton(State0, [X|Xs]) -->
        [{State0,X}->State1],
        { trans(State0, X, State1) },
        automaton(State1, Xs).
automaton(State0, Rest) -->
        [State0->State1],
        { silent(State0, State1) },
        automaton(State1, Rest).

示例:

?- length(Xs, _), phrase(automaton(s1, Xs), Ts).
Xs = [a, b],
Ts = [ ({s1, a}->s2), ({s2, b}->s3)] ;
Xs = [b, a, b],
Ts = [ ({s1, b}->s1), ({s1, a}->s2), ({s2, b}->s3)] ;
Xs = [a, b, a, b],
Ts = [ ({s1, a}->s2), ({s2, b}->s3), (s3->s1), ({s1, a}->s2), ({s2, b}->s3)] .