我有一个自动机。 这里的问题是:如何找到给定的有限自动机接受的至少一个偶数长度的单词?
states /* states(Q) <=> Q is the list of automata's states */
symbols /* symbols(Sigma) <=> Sigma is the list of automata's input symbols */
transition /* transition(X, A, Y) <=> δ(X, A)=Y */
startState /* startState(S) <=> S is the start state of automata */
finalStates /* finalStates(F) <=> F is the list of automata's final states */
states([q0, q1, q2]).
symbols([a, b]).
transition(q0, a, q1).
transition(q0, b, q2).
transition(q1, a, q2).
transition(q1, b, q0).
transition(q2, a, q1).
transition(q2, b, q2).
startState(q0).
finalStates([q2]).
答案 0 :(得分:1)
您似乎已经在Prolog中成功编码了自动机。您实际上缺少的是执行它的代码。因此,让我们考虑一下这样做的必要性。首先,我们需要通过将输入传递给运行的东西来开始执行。第一件事将找到开始状态并使用它。然后,我们将运行一个循环,查找此状态以及下一个输入值和下一个状态的过渡。如果我们用光了输入并处于最终状态,那么我们就成功了。因此,似乎第一个调用的唯一特别之处在于它查找了初始状态。
以真正的归纳方式,让我们先写终止条件。
step(State, []) :- finalStates(FinalStates), memberchk(State, FinalStates).
这只是说,如果我们在输入不足的情况下尝试执行某个步骤,则所处的状态将在最终状态列表中。现在,让我们尝试运行不是最后一步的步骤。我们将递归调用step/2
来实现循环。
step(State, [Sym|Tape]) :-
transition(State, Sym, NextState),
step(NextState, Tape),
!.
这只是剥离磁带上的下一个符号,并根据它找到正确的下一个状态,然后重复执行。我在此处添加了剪切,以防止其尝试查找其他过渡。如果您要建立NFA,则可能要删除它。现在我们缺少的是初始驱动程序,我将其称为评估:
evaluate(Tape) :-
startState(Start),
step(Start, Tape).
让我们在一些输入上尝试一下:
?- evaluate([a,a,a,a]).
true.
之所以成功,是因为它从q0-> q1-> q2-> q1-> q2过渡并且q2是最终状态。
?- evaluate([a,a,a]).
false.
此操作失败,因为它是从q0-> q1-> q2-> q1过渡而q1不是最终状态。
现在继续查找匹配的字符串。因为手头上有一组符号,所以我们可以很容易地生成它们。让我们做一个辅助谓词:
symbol(X) :- symbols(Symbols), member(X, Symbols).
这是我们可以方便地与maplist/2
一起使用来生成示例输入的内容:
?- length(L, 3), maplist(symbol, L).
L = [a, a, a] ;
L = [a, a, b] ;
L = [a, b, a] ;
L = [a, b, b] ;
L = [b, a, a] ;
L = [b, a, b] ;
L = [b, b, a] ;
L = [b, b, b].
现在,您可以使用Prolog进行经典的生成和测试:
?- length(L, 3), maplist(symbol, L), evaluate(L).
L = [a, a, b] ;
L = [a, b, b] ;
L = [b, a, a] ;
L = [b, b, b].
要找到有效的符号偶数列表,请使用辅助函数查找偶数,我们将使用between/3
生成这些长度的列表,然后执行相同的操作:
even(X) :- 0 is X mod 2.
尝试:
?- between(1,100,X), even(X).
X = 2 ;
X = 4 ;
X = 6 ;
X = 8 .
?- between(1,100,X), even(X), length(L, X).
X = 2,
L = [_2954, _2960] ;
X = 4,
L = [_2954, _2960, _2966, _2972] ;
X = 6,
L = [_2954, _2960, _2966, _2972, _2978, _2984] .
?- between(1,100,X), even(X), length(L, X), maplist(symbol, L).
X = 2,
L = [a, a] ;
X = 2,
L = [a, b] ;
X = 2,
L = [b, a] ;
X = 2,
L = [b, b] ;
X = 4,
L = [a, a, a, a] ;
X = 4,
L = [a, a, a, b] ;
X = 4,
L = [a, a, b, a] ;
X = 4,
L = [a, a, b, b] ;
X = 4,
L = [a, b, a, a] ;
X = 4,
L = [a, b, a, b] ;
X = 4,
L = [a, b, b, a] ;
X = 4,
L = [a, b, b, b] ;
X = 4,
L = [b, a, a, a] .
?- between(1,100,X), even(X), length(L, X), maplist(symbol, L), evaluate(L).
X = 2,
L = [a, a] ;
X = 2,
L = [b, b] ;
X = 4,
L = [a, a, a, a] ;
X = 4,
L = [a, a, b, b] ;
X = 4,
L = [a, b, a, a] ;
X = 4,
L = [a, b, b, b] ;
X = 4,
L = [b, a, a, b] ;
X = 4,
L = [b, a, b, b] ;
X = 4,
L = [b, b, a, a] ;
X = 4,
L = [b, b, b, b] ;
X = 6,
L = [a, a, a, a, a, a]