Ich habe ein einfaches Hirnfick Interpreter in der Skriptsprache MATLAB. Er wird mit zufälligen bf-Programmen gefüttert, die er ausführen soll (als Teil eines Projekts für einen genetischen Algorithmus). Das Problem, mit dem ich konfrontiert bin, besteht darin, dass das Programm in einer beträchtlichen Anzahl von Fällen eine Endlosschleife enthält und der genetische Algorithmus daher an diesem Punkt stecken bleibt.
Ich brauche also einen Mechanismus, um Endlosschleifen zu erkennen und die Ausführung dieses Codes in bf zu vermeiden.
Ein offensichtlicher (trivialer) Fall ist, wenn ich
[]
Ich kann dies erkennen und mich weigern, das Programm auszuführen.
Für die nicht-trivialen Fälle habe ich herausgefunden, dass die Grundidee darin besteht, zu bestimmen, wie eine Iteration der Schleife die aktuelle Zelle verändert. Wenn die Veränderung negativ ist, erreichen wir irgendwann 0, es ist also eine endliche Schleife. Wenn die Änderung nicht negativ ist, handelt es sich um eine Endlosschleife.
Bei einer einzelnen Schleife ist dies einfach zu realisieren, bei verschachtelten Schleifen wird es jedoch sehr kompliziert. Ein Beispiel: (Im Folgenden bezieht sich (1) auf den Inhalt von Zelle 1 usw. )
++++ Put 4 in 1st cell (1)
>+++ Put 3 in (2)
<[ While( (1) is non zero)
-- Decrease (1) by 2
>[ While( (2) is non zero)
- Decrement (2)
<+ Increment (1)
>]
(2) would be 0 at this point
+++ Increase (2) by 3 making (2) = 3
<] (1) was decreased by 2 and then increased by 3, so net effect is increment
und so läuft der Code weiter und weiter. Eine naive Überprüfung der Anzahl von + und - in Zelle 1 würde jedoch ergeben, dass die Anzahl der - höher ist, so dass die Endlosschleife nicht erkannt würde.
Fällt jemandem ein guter Algorithmus zur Erkennung von Endlosschleifen bei beliebiger Verschachtelung einer beliebigen Anzahl von Schleifen in bf ein?
EDIT: Ich weiß zwar, dass das Halteproblem im Allgemeinen unlösbar ist, aber ich war mir nicht sicher, ob es nicht doch spezielle Ausnahmen gibt. Zum Beispiel könnte Matlab als Super-Turing-Maschine funktionieren, die das Anhalten des bf-Programms bestimmen kann. Ich könnte mich schrecklich irren, aber wenn dem so ist, würde ich gerne genau wissen, wie und warum.
ZWEITE BEARBEITUNG: Ich habe etwas geschrieben, was ich als Endlosschleifen-Detektor bezeichne. Wahrscheinlich übersieht er einige Randfälle (oder, weniger wahrscheinlich, entkommt irgendwie Mr. Turings Fängen), aber für mich scheint er ab jetzt zu funktionieren. In Pseudocode-Form, hier geht es:
subroutine bfexec(bfprogram)
begin
Looping through the bfprogram,
If(current character is '[')
Find the corresponding ']'
Store the code between the two brackets in, say, 'subprog'
Save the value of the current cell in oldval
Call bfexec recursively with subprog
Save the value of the current cell in newval
If(newval >= oldval)
Raise an 'infinite loop' error and exit
EndIf
/* Do other character's processings */
EndIf
EndLoop
end