Ell*_*tus 8 prolog turing-machines
在维基百科文章的Prolog包括该图灵机模拟器:
turing(Tape0, Tape) :-
perform(q0, [], Ls, Tape0, Rs),
reverse(Ls, Ls1),
append(Ls1, Rs, Tape).
perform(qf, Ls, Ls, Rs, Rs) :- !.
perform(Q0, Ls0, Ls, Rs0, Rs) :-
symbol(Rs0, Sym, RsRest),
once(rule(Q0, Sym, Q1, NewSym, Action)),
action(Action, Ls0, Ls1, [NewSym|RsRest], Rs1),
perform(Q1, Ls1, Ls, Rs1, Rs).
symbol([], b, []).
symbol([Sym|Rs], Sym, Rs).
action(left, Ls0, Ls, Rs0, Rs) :- left(Ls0, Ls, Rs0, Rs).
action(stay, Ls, Ls, Rs, Rs).
action(right, Ls0, [Sym|Ls0], [Sym|Rs], Rs).
left([], [], Rs0, [b|Rs0]).
left([L|Ls], Ls, Rs, [L|Rs]).
Run Code Online (Sandbox Code Playgroud)
它给出了一个示例程序:
程序:
rule(q0, 1, q0, 1, right).
rule(q0, b, qf, 1, stay).
Run Code Online (Sandbox Code Playgroud)
程序运行如下:
?- turing([1,1,1], Ts).
Ts = [1, 1, 1, 1] ;
Run Code Online (Sandbox Code Playgroud)
我理解规则/事实中一些变量名称的含义:
turing(Tape0, Tape)
rule(Q0, Sym, Q1, NewSym, Action)
我不明白这些规则/事实中变量的含义:
perform(Q0, Ls0, Ls, Rs0, Rs)
symbol([Sym|Rs], Sym, Rs)
action(left/stay/right, Ls0, Ls, Rs0, Rs)
left([L|Ls], Ls, Rs, [L|Rs])
Run Code Online (Sandbox Code Playgroud)
谁能解释一下?
在图灵机中,在任何给定状态下,写入头都指向磁带上的特定位置。头部左侧有符号,头部右侧有符号。
看第一个主要谓词:
turing(Tape0, Tape) :-
perform(q0, [], Ls, Tape0, Rs),
reverse(Ls, Ls1),
append(Ls1, Rs, Tape).
Run Code Online (Sandbox Code Playgroud)
它将通过调用“运行机器” perform/5
。的参数perform(Q0, Ls0, Ls, Rs0, Rs)
代表:
Q0 - the current state (or initial state before the "perform")
Ls0 - the current set of symbols that are LEFT of the head
Ls - the FINAL set of symbols that WILL BE left of the head after perform
Rs0 - the current set of symbols that are RIGHT of the head
Rs - the FINAL set of symbols that WILL BE right of the head after perform
Run Code Online (Sandbox Code Playgroud)
最初,头部没有留下任何符号。Tape0
最初包含头部右侧的所有符号。为了“运行机器”,主要谓词调用:
perform(Q0, [], Ls, Tape0, Rs)
Run Code Online (Sandbox Code Playgroud)
它从初始状态 开始,Q0
头部左侧没有符号以 ( []
) 开头,并且头部右侧有符号Tape0
开始。查询完成后,期望Ls
用头部左侧的最终符号集和Rs
头部右侧的最终符号集进行实例化。
其他一切现在都支持perform/5
.
symbol([Sym|Rs], Sym, Rs)
Run Code Online (Sandbox Code Playgroud)
这定义了符号列表[Sym|Rs]
与该列表中的第一个符号 ( Sym
) 和列表的其余部分 ( Rs
) 之间的关系。perform/5
使用此谓词读取当前位于头部右侧的下一个符号。
为了使其在使用的上下文中正确工作,谓词perform/5
维护Rs0
变量,使其顺序正确,其中列表的头部是右侧的第一个符号,列表的第二个元素是右侧的下一个符号对,等等。请注意,左侧符号列表的情况并非如此。左侧列表按照符号在磁带上出现的相反顺序进行维护。原因是可以按照距离当前头部位置有多远的顺序来考虑它们。稍后会详细介绍这一点。
action(left/stay/right, Ls0, Ls, Rs0, Rs)
Run Code Online (Sandbox Code Playgroud)
这就是行动的地方。:) 它的作用是执行给定的操作,并在执行该操作后提供新头部位置左侧和右侧的正确更新列表。Ls0
和分别是执行动作之前头部左侧和右侧Rs0
的符号列表。和和分别是动作执行后头部左侧和右侧的符号。Ls
Rs
action(stay, Ls, Ls, Rs, Rs).
Run Code Online (Sandbox Code Playgroud)
这个动作表示当我停留时,头部左侧和右侧的符号不会改变。
action(right, Ls0, [Sym|Ls0], [Sym|Rs], Rs).
Run Code Online (Sandbox Code Playgroud)
这个动作表示,当我将头部向右移动一个符号位置时,紧邻右侧的符号(这是Sym
因为右侧的符号集是[Sym|Rs]
)变成紧邻左侧的符号。左边的一组符号原来是 ,Ls0
变成[Sym|Ls0]
。右侧的符号列表最初是[Sym|Rs]
,现在变为Rs
。
动作比orleft
稍微复杂一些,因为当左侧没有更多符号并且指示向左移动时,头部仍然向左移动,并且右侧出现空白。所以它被分解成一个单独的小谓词:stay
right
left
action(left, Ls0, Ls, Rs0, Rs) :- left(Ls0, Ls, Rs0, Rs).
left([], [], Rs0, [b|Rs0]).
Run Code Online (Sandbox Code Playgroud)
这里,如果左侧符号集为空([]
),则向左移动意味着左侧符号保持为空([]
),并且b
在头部右侧出现一个新的空白( ),位于原始右侧符号集的头部(右侧符号) - 手列表从 更改为Rs0
) [b|Rs0]
。
left([L|Ls], Ls, Rs, [L|Rs]).
Run Code Online (Sandbox Code Playgroud)
这里左边有一些符号,动作是向左移动。左侧的初始符号集是[L|Ls]
(L
是紧邻头部左侧的符号),头部右侧的初始符号集是Rs
。当头部向左移动时,左侧的第一个符号将成为右侧的第一个符号。所以更新后的左符号集是Ls
,更新后的右符号集是[L|Rs]
。
谓词action(left, ...)
可以在没有辅助谓词 的情况下编写,left/4
如下所示:
action(left, [], [], Rs0, [b|Rs0]).
action(left, [L|Ls], Ls, Rs, [L|Rs]).
Run Code Online (Sandbox Code Playgroud)
回到左侧列表和原始turing/2
谓词:在turing/2
调用后,它在右侧perform(q0, [], Ls, Tape0, Rs)
有最后一组符号( ),这些符号的顺序正确,从左到右。然而,左侧 ( ) 的最后一组符号是从右到左列出的(因为它们是按照它们与当前头部位置的接近程度排列的)。因此,为了以正确的顺序显示整个磁带,必须反转左侧的符号列表,然后将其添加到右侧的符号集之前。因此,调用:Rs
Ls
reverse(Ls, Ls1),
append(Ls1, Rs, Tape).
Run Code Online (Sandbox Code Playgroud)
分解perform/5
谓词:
perform(qf, Ls, Ls, Rs, Rs) :- !.
Run Code Online (Sandbox Code Playgroud)
这表示,如果我们处于最终状态qf
,则左侧符号的最终Ls
列表,将成为我们当前的左侧符号集。对于正确的符号也是如此。
perform(Q0, Ls0, Ls, Rs0, Rs) :-
% Read the symbol to the right of the head (Sym)
%
symbol(Rs0, Sym, RsRest),
% Apply first found matching rule to the current state (Q0)
% and the current symbol on the right (Sym), resulting in
% a new symbol (NewSym) and an action (Action)
%
once(rule(Q0, Sym, Q1, NewSym, Action)),
% Perform the action using the current list of symbols on the left (Ls0)
% and the updates list of symbols on the right (old right symbol (Sym)
% replaced by the new right symbol (NewSym), which is [NewSym|RsRest]
% with the action resulting in new left Ls1 and new right Ls2
% sets of symbols
%
action(Action, Ls0, Ls1, [NewSym|RsRest], Rs1),
% Recursively perform the Turing engine on the new state, left,
% and right sets of symbols until we hit the final state (qf)
% with final result being left symbols, Ls, and right symbols, Rs
%
perform(Q1, Ls1, Ls, Rs1, Rs).
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1086 次 |
最近记录: |