2015-04-02 11 views
8

Die Wikipedia Prolog article umfasst diese Turing-Maschine-Simulator:Bitte erläutern diesen Simulator Turing-Maschine in Prolog geschrieben

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]). 

Es gibt ein Beispielprogramm, das:

  • auf eine "1" zu lesen, den Kopf bewegt Recht.
  • Beim Lesen einer Leerstelle, schreibt eine Eins und geht in den Endzustand.

Programm:

rule(q0, 1, q0, 1, right). 
rule(q0, b, qf, 1, stay). 

Das Programm wird wie gezeigt:

?- turing([1,1,1], Ts). 
Ts = [1, 1, 1, 1] ; 

verstehe ich die Bedeutung einiger der Variablennamen in Regeln/Fakten:

turing(Tape0, Tape)

  • tape0 ist die Eingabeband
  • Band dem Ausgabeband

rule(Q0, Sym, Q1, NewSym, Action)

  • Q0 ist: Startzustand
  • Sym: Symbol lesen
  • Q1: end
  • NewSym Zustand : Symbol zum Schreiben
  • Aktion: wie mo
  • ve der Kopf

Ich verstehe nicht, die Bedeutung der Variablen in dieser Regeln/Fakten:

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]) 

Kann mir jemand erklären?

Antwort

3

In der Turing-Maschine zeigt der Schreibkopf in einem bestimmten Zustand auf eine bestimmte Stelle auf dem Band. Es wird Symbole vom Kopf und Symbole rechts vom Kopf geben.

Mit Blick auf dem ersten, Haupt Prädikat:

turing(Tape0, Tape) :- 
    perform(q0, [], Ls, Tape0, Rs), 
    reverse(Ls, Ls1), 
    append(Ls1, Rs, Tape). 

Es wird „die Maschine läuft“ von perform/5 aufrufen. Die Argumente für perform(Q0, Ls0, Ls, Rs0, Rs) darstellen:

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 

Zu Beginn gibt es keine Symbole des Kopfes nach links. Tape0 enthält zunächst alle Symbole rechts vom Kopf. Um „die Maschine laufen“, ruft das Haupt Prädikat:

perform(Q0, [], Ls, Tape0, Rs) 

Es beginnt mit dem Anfangszustand, Q0, hat keine Symbole des Kopfes nach links mit ([]) zu beginnen und hat die Symbole in Tape0 rechts von der Kopf um zu beginnen.Nach Abschluss der Abfrage wird erwartet, dass Ls instanziiert ist mit dem letzten Satz von Symbolen links vom Kopf und Rs der letzte Satz von Symbolen rechts vom Kopf.

Alles andere unterstützt jetzt perform/5.

symbol([Sym|Rs], Sym, Rs) 

Dies definiert eine Beziehung zwischen der Liste von Symbolen [Sym|Rs], und dem ersten Symbol in der Liste (Sym) und der Rest der Liste (Rs). perform/5 verwendet dieses Prädikat, um das nächste Symbol zu lesen, das sich derzeit rechts vom Kopf befindet.

Damit dies korrekt im Rahmen arbeiten, um es verwendet wird, behält die perform/5 Prädikat die Rs0 Variable, so daß es richtig ist, um, wo der Kopf der Liste das erste Symbol auf der rechten Seite ist, das zweite Element von Die Liste ist das folgende Symbol auf der rechten Seite und so weiter. Beachten Sie, dass dies nicht der Fall der Liste der Symbole auf der linken Seite ist. Die Liste auf der linken Seite wird in umgekehrt Reihenfolge der Symbole auf dem Band angezeigt. Der Grund dafür ist, dass sie in der Reihenfolge der verbleibenden Position der aktuellen Kopfposition betrachtet werden können. Mehr dazu später.

action(left/stay/right, Ls0, Ls, Rs0, Rs) 

Hier wird die Aktion ist. :) Es ist die Aufgabe, die gegebene Aktion auszuführen und die korrekt aktualisierten Listen darüber zu liefern, was links und rechts von der neuen Kopfposition ist, nachdem diese eine Aktion ausgeführt wurde. Ls0 und Rs0 sind die Listen der Symbole links und rechts des Kopfes bzw. vor die Aktion durchgeführt wird. Und Ls und Rs sind die Symbole links und rechts des Kopfes bzw. nach die Aktion durchgeführt wird.

action(stay, Ls, Ls, Rs, Rs). 

Aktion sagt, dass, wenn ich, die Symbole auf der linken Seite und auf der rechten Seite des Kopfes nicht ändern bleiben .

action(right, Ls0, [Sym|Ls0], [Sym|Rs], Rs). 

Aktion sagt, dass, wenn ich Sie den Kopf rechts einer Symbolposition, das Symbol sofort dem rechts (die Sym ist, da die rechten Satz von Symbolen ist [Sym|Rs]) unmittelbar das Symbol wird nach links. Der linke Satz von Symbolen war ursprünglich Ls0 und wird [Sym|Ls0]. Die Liste der Symbole auf der rechten Seite war ursprünglich [Sym|Rs] und wird Rs.

Die left Aktion ein wenig komplizierter wird als stay oder right, weil, wenn es keine weiteren Symbole auf der linken Seite und einer Bewegung links sind angezeigt wird, bewegt sich der Kopf noch links und eine leere erscheint auf der rechten Seite.So left ist es ausgebrochen in ein separates, kleines Prädikat:

action(left, Ls0, Ls, Rs0, Rs) :- left(Ls0, Ls, Rs0, Rs). 

left([], [], Rs0, [b|Rs0]). 

Wenn hier die links von Symbolen eingestellt ist leer ([]), dann bewegen links bedeutet, dass die linken Symbole leer bleiben ([]) und ein Eine neue Leerstelle (b) erscheint auf der rechten Seite des Kopfes, am Anfang der ursprünglichen Gruppe von rechten Symbolen (die rechte Liste ändert sich von Rs0 zu [b|Rs0]).

left([L|Ls], Ls, Rs, [L|Rs]). 

Hier sind einige Symbole auf der linken Seite und die Aktion ist nach links zu bewegen. Die erste Gruppe von Symbolen auf der linken Seite ist [L|Ls] (L ist das Symbol unmittelbar links vom Kopf) und die erste Reihe von Symbolen rechts vom Kopf sind Rs. Wenn sich der Kopf bewegt links, dann wird das erste Symbol auf der linken Seite das erste Symbol auf der rechten Seite. Der aktualisierte linke Satz von Symbolen ist also Ls und der aktualisierte rechte Satz von Symbolen ist [L|Rs].

Das action(left, ...) Prädikat ohne Hilfs Prädikat geschrieben worden sein könnte, left/4, auf diese Weise:

action(left, [], [], Rs0, [b|Rs0]). 
action(left, [L|Ls], Ls, Rs, [L|Rs]). 

Zurück zur linken Liste und das ursprünglichen turing/2 Prädikat: nach turing/2 Anrufen perform(q0, [], Ls, Tape0, Rs), hat es einen letzten Satz von Symbole auf der rechts (Rs), die in der richtigen Reihenfolge sind, von links nach rechts. Die letzten Symbole auf der linken Seite (Ls) werden jedoch von rechts nach links aufgelistet (da sie in der Reihenfolge ihrer Nähe zur aktuellen Kopfposition sind). Um das gesamte Band in der richtigen Reihenfolge zu zeigen, muss daher die linke Liste von Symbolen umgekehrt und dann der richtigen Menge von Symbolen vorangestellt werden. Somit werden die Anrufe:

reverse(Ls, Ls1), 
append(Ls1, Rs, Tape). 

Aufbrechen der perform/5 Prädikat:

perform(qf, Ls, Ls, Rs, Rs) :- !. 

Dies sagt, dass, wenn wir im Endzustand sind qf, dann ist die letzte Liste von links Symbole, Ls, wird unser aktueller Satz links Symbole. Ähnlich für die richtigen Symbole.

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). 
+0

Vielen Dank. –

Verwandte Themen