March 2014 update
This commit is contained in:
parent
09687c4926
commit
a25938f123
1846 changed files with 21876 additions and 5203 deletions
|
|
@ -0,0 +1,174 @@
|
|||
; By Uberi, http://www.autohotkey.com/board/topic/58599-turing-machine/
|
||||
SetBatchLines, -1
|
||||
OnExit, Exit
|
||||
SaveFilePath := A_ScriptFullPath ".ini"
|
||||
; Defaults are for a 2-state_3-symbol turning machine. Format:
|
||||
; machine state symbol on tape, symbol on tape | tape shift (- is left, + is right, 0 is halt) | machine state
|
||||
, Rule1 := "A0,1|1|B"
|
||||
, Rule2 := "A1,2|-1|A"
|
||||
, Rule3 := "A2,1|-1|A"
|
||||
, Rule4 := "B0,2|-1|A"
|
||||
, Rule5 := "B1,2|1|B"
|
||||
, Rule6 := "B2,0|1|A"
|
||||
; no error check is run on this input, so be sure states and symbols align with actions
|
||||
IniRead, UseSaveFile, %SaveFilePath%, Global, UseSaveFile, 1 ; on exit, save state to text file so I can resume on next run
|
||||
IniRead, MaxIterations, %SaveFilePath%, Global, MaxIterations, 100000 ; set as %A_Space% to run indefinitely
|
||||
IniRead, Section, %SaveFilePath%, Global, Section, 2-state_3-symbol ; The name of the machine to run. Options defined:
|
||||
; 2-state_3-symbol
|
||||
; Simple_incrementer
|
||||
; Three-state_busy_beaver
|
||||
; Probable_busy_beaver_Wikipedia
|
||||
|
||||
IniRead, States, %SaveFilePath%, %Section%, States, A|B ; valid states
|
||||
IniRead, InitialState, %SaveFilePath%, %Section%, InitialState, A ; start state
|
||||
IniRead, TerminalState, %SaveFilePath%, %Section%, TerminalState, C ; end state
|
||||
IniRead, Symbols, %SaveFilePath%, %Section%, Symbols, 0,1,2 ; valid symbols
|
||||
IniRead, DefaultCell, %SaveFilePath%, %Section%, DefaultCell, 0 ; the default symbol of any cell not defined on input tape
|
||||
IniRead, ProgramCode, %SaveFilePath%, %Section%, ProgramCode, 10101|01010 ; start tape
|
||||
Iniread, RuleCount, %SaveFilePath%, %Section%, RuleCount, 6 ; number of actions to read
|
||||
Loop, %RuleCount%
|
||||
{
|
||||
IniRead, Temp1, %SaveFilePath%, %Section%, Rule%A_Index%, % Rule%A_Index%
|
||||
StringSplit, Temp, Temp1, `,
|
||||
Action%Temp1% := Temp2
|
||||
}
|
||||
|
||||
IniRead, Index, %SaveFilePath%, SavedState, Index, 0
|
||||
IniRead, IterationCount, %SaveFilePath%, SavedState, IterationCount, 0
|
||||
IniRead, State, %SaveFilePath%, SavedState, State, %InitialState%
|
||||
If IterationCount > 0
|
||||
IniRead, ProgramCode, %SaveFilePath%, SavedState, ProgramCode, %ProgramCode%
|
||||
|
||||
IfNotInString, ProgramCode, |
|
||||
ProgramCode := "|" ProgramCode
|
||||
StringSplit, Temp, ProgramCode, |
|
||||
NegativeCells := Temp1, PositiveCells := Temp2
|
||||
|
||||
Loop, Parse, Symbols, |
|
||||
Color%A_LoopField% := hex(mod((A_Index+1/(2**((A_Index-1)//7))-1)/7,1)*16777215) ; unlimited number of unique colors
|
||||
Color%DefaultCell% := "White"
|
||||
|
||||
Gui, Color, Black
|
||||
Gui, +ToolWindow +AlwaysOnTop +LastFound -Caption
|
||||
WindowID := WinExist()
|
||||
OnMessage(0x201, "WM_LBUTTONDOWN")
|
||||
Gui, Font, s6 cWhite, Arial
|
||||
Loop, 61 ; display 30 cell symbols on each side of current index
|
||||
{
|
||||
Temp1 := ((A_Index - 1) * 15) + 1
|
||||
Gui, Add, Progress, x%Temp1% y1 w14 h40 vCell%A_Index% BackgroundWhite
|
||||
Gui, Add, Text, x%Temp1% y42 w15 h10 vLabel%A_Index% Center
|
||||
}
|
||||
Gui, Add, Text, x2 y54 w26 h10 vState
|
||||
Gui, Add, Text, x35 y54 w50 h10 vCurrentCell
|
||||
Gui, Add, Text, x350 y54 w158 h10 vActions
|
||||
Gui, Add, Text, x844 y54 w33 h10, Iterations:
|
||||
Gui, Add, Text, x884 y54 w29 h10 vIterations Right
|
||||
Gui, Font, s4 cWhite Bold, Arial
|
||||
Gui, Add, Text, x450 y1 w15 h10 Center, V
|
||||
GuiControl, Move, Cell31, x451 y8 w14 h33
|
||||
Gui, Show, y20 w916 h64, Wolfram's 2-State 3-Symbol Turing Machine ;'
|
||||
|
||||
;MaxIndex := ProgramOffset + StrLen(ProgramCode), MinIndex := ProgramOffset ; not implemented
|
||||
While, ((MaxIterations = "") || IterationCount <= MaxIterations) ; process until limit is reached, if any
|
||||
{
|
||||
Loop, 61 ; color each cell per its current symbol
|
||||
{ ; must run for all displayed cells because they are not directly mapped to shifting tape
|
||||
TempIndex := (Index + A_Index) - 31
|
||||
GuiControl, , Label%A_Index%, %TempIndex%
|
||||
CellColor := CellGet(TempIndex)
|
||||
, CellColor := Color%CellColor%
|
||||
GuiControl, +Background%CellColor%, Cell%A_Index%
|
||||
}
|
||||
CurrentCell := CellGet(Index)
|
||||
GuiControl, , State, State: %State%
|
||||
GuiControl, , CurrentCell, Current Cell: %CurrentCell%
|
||||
GuiControl, , Iterations, %IterationCount%
|
||||
If (State = TerminalState)
|
||||
Break
|
||||
|
||||
StringSplit, Temp, Action%State%%CurrentCell%, |
|
||||
GuiControl, , Actions, % "Actions: Print " . Temp1 . ", Move " . ((Temp2 = -1) ? "left" : "right") . ", " . ((State <> Temp3) ? "Switch to state " . Temp3 : "Do not switch state")
|
||||
|
||||
IterationCount++
|
||||
, CellPut(Index,Temp1)
|
||||
, Index += Temp2
|
||||
, State := Temp3
|
||||
;, (Index > MaxIndex) ? MaxIndex := Index : ""
|
||||
;, (Index < MinIndex) ? MinIndex := Index : ""
|
||||
|
||||
Sleep, 0.1*1000
|
||||
}
|
||||
MsgBox, 64, Complete, Completed %IterationCount% iterations of the Turing machine.
|
||||
Return
|
||||
|
||||
|
||||
; Hotkeys and functions:
|
||||
~Pause::Pause
|
||||
|
||||
GuiEscape:
|
||||
GuiClose:
|
||||
ExitApp
|
||||
|
||||
Exit:
|
||||
If UseSaveFile
|
||||
{
|
||||
IniWrite, %Index%, %SaveFilePath%, %Section%, Index
|
||||
IniWrite, %IterationCount%, %SaveFilePath%, %Section%, IterationCount
|
||||
IniWrite, %State%, %SaveFilePath%, %Section%, State
|
||||
IniWrite, %NegativeCells%|%PositiveCells%, %SaveFilePath%, %Section%, ProgramCode
|
||||
}
|
||||
ExitApp
|
||||
|
||||
CellGet(Index)
|
||||
{
|
||||
global NegativeCells, PositiveCells, DefaultCell
|
||||
Temp1 := (Index < 0) ? SubStr(NegativeCells,Abs(Index),1) : SubStr(PositiveCells,Index + 1,1)
|
||||
Return, (Temp1 = "") ? DefaultCell : Temp1
|
||||
}
|
||||
|
||||
CellPut(Index,Char)
|
||||
{
|
||||
global NegativeCells, PositiveCells, DefaultCell
|
||||
static StrGetFunc := "StrGet" ; workaround to hide function from AHK Basic (which does not have or require it)
|
||||
CharType := A_IsUnicode ? "UShort" : "UChar"
|
||||
, (Index < 0)
|
||||
? (Index := 0 - Index
|
||||
, Temp1 := Index - StrLen(NegativeCells)
|
||||
, (Temp1 > 0)
|
||||
? (VarSetCapacity(Pad,64) ; these three functions are quirks in AHK's memory management (not required)
|
||||
, VarSetCapacity(Pad,0)
|
||||
, VarSetCapacity(Pad,Temp1,Asc(DefaultCell))
|
||||
, NegativeCells .= A_IsUnicode ? %StrGetFunc%(&Pad,Temp1,"CP0") : Pad)
|
||||
: ""
|
||||
, NumPut(Asc(Char),NegativeCells,(Index - 1) << !!A_IsUnicode,CharType) )
|
||||
: (Temp1 := Index - StrLen(PositiveCells) + 1
|
||||
, (Temp1 > 0)
|
||||
? (VarSetCapacity(Pad,64) ; these three functions are quirks in AHK's memory management (not required)
|
||||
, VarSetCapacity(Pad,0)
|
||||
, VarSetCapacity(Pad,Temp1,Asc(DefaultCell))
|
||||
, PositiveCells .= A_IsUnicode ? %StrGetFunc%(&Pad,Temp1,"CP0") : Pad)
|
||||
: ""
|
||||
, NumPut(Asc(Char),PositiveCells,Index << !!A_IsUnicode,CharType) )
|
||||
}
|
||||
|
||||
Hex(p_Integer)
|
||||
{
|
||||
PtrType:=(A_PtrSize=8) ? "Ptr":"UInt"
|
||||
l_Format:="`%0" . 6 . "I64X"
|
||||
VarSetCapacity(l_Argument,8)
|
||||
NumPut(p_Integer,l_Argument,0,"Int64")
|
||||
VarSetCapacity(l_Buffer,A_IsUnicode ? 12:6,0)
|
||||
DllCall(A_IsUnicode ? "msvcrt\_vsnwprintf":"msvcrt\_vsnprintf"
|
||||
,"Str",l_Buffer ;-- Storage location for output
|
||||
,"UInt",6 ;-- Maximum number of characters to write
|
||||
,"Str",l_Format ;-- Format specification
|
||||
,PtrType,&l_Argument) ;-- Argument
|
||||
Return l_Buffer
|
||||
}
|
||||
|
||||
WM_LBUTTONDOWN()
|
||||
{
|
||||
If (A_Gui = 1)
|
||||
PostMessage, 0xA1, 2
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
(defn tape
|
||||
"Creates a new tape with given blank character and tape contents"
|
||||
([blank] (tape () blank () blank))
|
||||
([right blank] (tape () (first right) (rest right) blank))
|
||||
([left head right blank] [(reverse left) (or head blank) (into () right) blank]))
|
||||
|
||||
; Tape operations
|
||||
(defn- left [[[l & ls] _ rs b] c] [ls (or l b) (conj rs c) b])
|
||||
(defn- right [[ls _ [r & rs] b] c] [(conj ls c) (or r b) rs b])
|
||||
(defn- stay [[ls _ rs b] c] [ls c rs b])
|
||||
(defn- head [[_ c _ b]] (or c b))
|
||||
(defn- pretty [[ls c rs b]] (concat (reverse ls) [[(or c b)]] rs))
|
||||
|
||||
(defn new-machine
|
||||
"Returns a function that takes a tape as input, and returns the tape
|
||||
after running the machine specified in `machine`."
|
||||
[machine]
|
||||
(let [rules (into {} (for [[s c c' a s'] (:rules machine)]
|
||||
[[s c] [c' (-> a name symbol resolve) s']]))
|
||||
finished? (into #{} (:terminating machine))]
|
||||
(fn [input-tape]
|
||||
(loop [state (:initial machine) tape input-tape]
|
||||
(if (finished? state)
|
||||
(pretty tape)
|
||||
(let [[out action new-state] (get rules [state (head tape)])]
|
||||
(recur new-state (action tape out))))))))
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
(def simple-incrementer
|
||||
(new-machine {:initial :q0
|
||||
:terminating [:qf]
|
||||
:rules [[:q0 1 1 :right :q0]
|
||||
[:q0 \B 1 :stay :qf]]}))
|
||||
(deftest simple-incrementer-test
|
||||
(is (= [1 1 1 [1]] (simple-incrementer (tape [1 1 1] \B)))))
|
||||
|
||||
|
||||
(def three-state-two-symbol-busy-beaver
|
||||
(new-machine {:initial :a
|
||||
:terminating [:halt]
|
||||
:rules [[:a 0 1 :right :b]
|
||||
[:a 1 1 :left :c]
|
||||
[:b 0 1 :left :a]
|
||||
[:b 1 1 :right :b]
|
||||
[:c 0 1 :left :b]
|
||||
[:c 1 1 :stay :halt]]}))
|
||||
(deftest three-state-two-symbol-busy-beaver-test
|
||||
(is (= [1 1 1 [1] 1 1] (three-state-two-symbol-busy-beaver (tape 0)))))
|
||||
|
||||
|
||||
(def five-state-two-symbol-busy-beaver
|
||||
(new-machine {:initial :A
|
||||
:terminating [:H]
|
||||
:rules [[:A 0 1 :right :B]
|
||||
[:A 1 1 :left :C]
|
||||
[:B 0 1 :right :C]
|
||||
[:B 1 1 :right :B]
|
||||
[:C 0 1 :right :D]
|
||||
[:C 1 0 :left :E]
|
||||
[:D 0 1 :left :A]
|
||||
[:D 1 1 :left :D]
|
||||
[:E 0 1 :stay :H]
|
||||
[:E 1 0 :left :A]]}))
|
||||
(deftest five-state-two-symbol-busy-beaver-test
|
||||
(let [result (flatten (five-state-two-symbol-busy-beaver (tape 0)))
|
||||
freq (frequencies result)]
|
||||
(is (= 4098 (get freq 1)))
|
||||
(is (= 8191 (get freq 0)))))
|
||||
|
|
@ -1,52 +1,18 @@
|
|||
import std.stdio, std.typecons, std.array, std.algorithm, std.string;
|
||||
import std.stdio, std.typecons, std.algorithm, std.string, std.array;
|
||||
|
||||
void turing(Sy, St)(in Sy[] symbols, in Sy blank, in St initialState,
|
||||
in St[] haltStates, in St[] runningStates,
|
||||
in Tuple!(Sy, string, St)[Sy][St] rules,
|
||||
in Sy[] startingTape = []) {
|
||||
Sy[int] tape;
|
||||
foreach (i, sy; startingTape)
|
||||
tape[i] = sy;
|
||||
int pos = 0;
|
||||
St state = initialState;
|
||||
|
||||
while (!haltStates.canFind(state)) {
|
||||
//auto symbol = tape.setDefault(pos, blank);
|
||||
if (pos !in tape)
|
||||
tape[pos] = blank;
|
||||
auto symbol = tape[pos];
|
||||
tape.keys.sort()
|
||||
.map!(i => format(["%s", "(%s)"][i == pos], tape[i]))
|
||||
.join(" ").writeln;
|
||||
//{const outsym, const action, state} = rules[state][symbol];
|
||||
const r = rules[state][symbol];
|
||||
state = r[2];
|
||||
tape[pos] = r[0];
|
||||
pos += ["left": -1, "stay": 0, "right": 1][r[1]];
|
||||
}
|
||||
void turing(Sy, St)(in St state, Sy[int] tape, in int pos,
|
||||
in Tuple!(Sy, int, St)[Sy][St] rules) {
|
||||
if (state.empty) return;
|
||||
const r = rules[state][tape[pos] = tape.get(pos, Sy.init)];
|
||||
writefln("%-(%s%)", tape.keys.sort()
|
||||
.map!(i => format(i == pos ? "(%s)" : " %s ", tape[i])));
|
||||
tape[pos] = r[0];
|
||||
turing(r[2], tape, pos + r[1], rules);
|
||||
}
|
||||
|
||||
void main() {
|
||||
alias t = tuple;
|
||||
|
||||
turing(['b', '1'], // Permitted symbols.
|
||||
'b', // Blank symbol.
|
||||
"q0", // Starting state.
|
||||
["qf"], // Terminating states.
|
||||
["q0"], // Running states.
|
||||
// Operating rules.
|
||||
["q0": ['1': t('1', "right", "q0"),
|
||||
'b': t('1', "stay", "qf")]],
|
||||
['1', '1', '1']); // Starting tape.
|
||||
writeln;
|
||||
|
||||
turing([0, 1], // Permitted symbols.
|
||||
0, // Blank symbol.
|
||||
"a", // Starting state.
|
||||
["halt"], // Terminating states.
|
||||
["a", "b", "c"], // Running states.
|
||||
// Operating rules.
|
||||
["a": [0: t(1, "right", "b"), 1: t(1, "left", "c")],
|
||||
"b": [0: t(1, "left", "a"), 1: t(1, "right", "b")],
|
||||
"c": [0: t(1, "left", "b"), 1: t(1, "stay", "halt")]]);
|
||||
turing("a", null, 0,
|
||||
["a": [0: tuple(1, 1, "b"), 1: tuple(1, -1, "c")],
|
||||
"b": [0: tuple(1, -1, "a"), 1: tuple(1, 1, "b")],
|
||||
"c": [0: tuple(1, -1, "b"), 1: tuple(1, 0, "")]]);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue