September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -0,0 +1,18 @@
1000 PRINT AT 0,0;T$
1010 LET P=1
1020 IF P>LEN T$ THEN LET T$=T$+B$
1030 PRINT AT INT (P/32),P-(32*INT (P/32)+1);CHR$ (CODE T$(P)+128)
1040 LET R=1
1050 IF R$(R,1)=S$ AND R$(R,2)=T$(P) THEN GOTO 1080
1060 LET R=R+1
1070 GOTO 1050
1080 LET T$(P)=R$(R,3)
1090 PRINT AT INT (P/32),P-(32*INT (P/32)+1);T$(P)
1100 IF R$(R,4)="L" THEN LET P=P-1
1110 IF R$(R,4)="R" THEN LET P=P+1
1120 LET S$=R$(R,5)
1130 IF S$=H$ THEN STOP
1140 IF P=0 THEN GOTO 1160
1150 GOTO 1020
1160 LET T$=B$+T$
1170 GOTO 1000

View file

@ -0,0 +1,7 @@
10 DIM R$(2,5)
20 LET S$=CHR$ (CODE "Q"+CODE "0")
30 LET H$=CHR$ (CODE "Q"+CODE "F")
40 LET R$(1)=S$+"11R"+S$
50 LET R$(2)=S$+"B1S"+H$
60 LET B$="B"
70 LET T$="111"

View file

@ -0,0 +1,11 @@
10 DIM R$(6,5)
20 LET R$(1)="A01RB"
30 LET R$(2)="A11LC"
40 LET R$(3)="B01LA"
50 LET R$(4)="B11RB"
60 LET R$(5)="C01LB"
70 LET R$(6)="C11SH"
80 LET T$=""
90 LET S$="A"
100 LET B$="0"
110 LET H$="H"

View file

@ -1,6 +1,7 @@
function tm(d,s,e,i,b,t,... r) {
document.write(d, '<br>')
if (i<0||i>=t.length) return
var re=new RegExp(b,'g')
write('*',s,i,t=t.split(''))
var p={}; r.forEach(e=>((s,r,w,m,n)=>{p[s+'.'+r]={w,n,m:[0,1,-1][1+'RL'.indexOf(m)]}})(... e.split(/[ .:,]+/)))
for (var n=1; s!=e; n+=1) {
@ -13,7 +14,7 @@ function tm(d,s,e,i,b,t,... r) {
function write(n, s, i, t) {
t = t.join('')
t = t.substring(0,i) + '<u>' + t.charAt(i) + '</u>' + t.substr(i+1)
document.write((' '+n).slice(-3).replace(/ /g,'&nbsp;'), ': ', s, ' [', t.replace(b,'&nbsp;','g'), ']', '<br>')
document.write((' '+n).slice(-3).replace(/ /g,'&nbsp;'), ': ', s, ' [', t.replace(re,'&nbsp;'), ']', '<br>')
}
}
@ -24,16 +25,14 @@ tm( 'Unary incrementer',
'a.1: 1, L, a',
'a.B: 1, S, h'
)
tm( 'Unary adder',
1, 0, 0, '0', '1110111',
'1.1: 0, R, 2', // write 0 rigth goto 2
'2.0: 0, S, 0', // if (0) halt
'2.1: 0, R, 3', // write 0 rigth goto 3
'3.1: 1, R, 3', // while (1) rigth
'3.0: 1, S, 0', // write 1 halt
'2.1: 1, R, 2', // while (1) rigth
'2.0: 1, S, 0' // write 1 stay halt
)
tm( 'Three-state busy beaver',
1, 0, 0, '0', '0',
'1.0: 1, R, 2',

View file

@ -0,0 +1,93 @@
enum name, initState, endState, blank, rules
-- Machine definitions
constant incrementer = {
/*name =*/ "Simple incrementer",
/*initState =*/ "q0",
/*endState =*/ "qf",
/*blank =*/ "B",
/*rules =*/ {
{"q0", "1", "1", "right", "q0"},
{"q0", "B", "1", "stay", "qf"}
}
}
constant threeStateBB = {
/*name =*/ "Three-state busy beaver",
/*initState =*/ "a",
/*endState =*/ "halt",
/*blank =*/ "0",
/*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"}
}
}
constant fiveStateBB = {
/*name =*/ "Five-state busy beaver",
/*initState =*/ "A",
/*endState =*/ "H",
/*blank =*/ "0",
/*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"}
}
}
procedure show(string state, integer headpos, sequence tape)
printf(1," %-6s | ",{state})
for p=1 to length(tape) do
printf(1,iff(p=headpos?"[%s]":" %s "),{tape[p]})
end for
printf(1,"\n")
end procedure
-- a universal turing machine
procedure UTM(sequence machine, sequence tape, integer countOnly=0)
string state = machine[initState]
integer headpos = 1, counter = 0
printf(1,"\n\n%s\n%s\n",{machine[name],repeat('=',length(machine[name]))})
if not countOnly then printf(1," State | Tape [head]\n---------------------\n") end if
while 1 do
if headpos>length(tape) then
tape = append(tape,machine[blank])
elsif headpos<1 then
tape = prepend(tape,machine[blank])
headpos = 1
end if
if not countOnly then show(state, headpos, tape) end if
for i=1 to length(machine[rules]) do
sequence rule = machine[rules][i]
if rule[1]=state and rule[2]=tape[headpos] then
tape[headpos] = rule[3]
if rule[4] == "left" then headpos -= 1 end if
if rule[4] == "right" then headpos += 1 end if
state = rule[5]
exit
end if
end for
counter += 1
if state=machine[endState] then exit end if
end while
if countOnly then
printf(1,"Steps taken: %d\n",{counter})
else
show(state, headPos, tape)
end if
end procedure
UTM(incrementer, {"1", "1", "1"})
UTM(threeStateBB, {})
UTM(fiveStateBB, {}, countOnly:=1)

View file

@ -18,8 +18,7 @@ TM: !=1; bot=1; top=1; @er= '***error***' /*start at the tape location
if rMove== 'left' then !=!-1 /*Are we moving left? Then subtract 1*/
if rMove=='right' then !=!+1 /* " " " right? " add 1*/
bot=min(bot, !); top=max(top, !) /*find the tape bottom and top. */
state=rNext /*use this for the next state. */
iterate cycle /*go process another TM instruction. */
state=rNext; iterate cycle /*use this for the next state; and */
end /*k*/
say @er 'unknown state:' state; leave /*oops, we have an unknown state error.*/
end /*cycle*/
@ -27,8 +26,8 @@ TM: !=1; bot=1; top=1; @er= '***error***' /*start at the tape location
do t=bot to top; _=@.t
if _==blank then _=' ' /*do we need to translate a true blank?*/
$=$ || pad || _ /*construct char by char, maybe pad it.*/
end /*t*/ /* [↑] construct the tape's contents.*/
L=length($)
end /*t*/ /* [↑] construct the tape's contents*/
L=length($) /*obtain length of " " " */
if L==0 then $= "[tape is blank.]" /*make an empty tape visible to user.*/
if L>1000 then $=left($, 1000) ... /*truncate tape to 1k bytes, append ···*/
say "tape's contents:" $ /*show the tape's contents (or 1st 1k).*/

View file

@ -0,0 +1,331 @@
(*** Signatures ***)
signature TAPE = sig
datatype move = Left | Right | Stay
type ''a tape
val empty : ''a tape
val moveLeft : ''a tape -> ''a tape
val moveRight : ''a tape -> ''a tape
val move : ''a tape -> move -> ''a tape
val getSymbol : ''a tape -> ''a option
val write : ''a option -> ''a tape -> ''a tape
val leftOf : ''a tape -> ''a option list (* Symbols left of the head in reverse order *)
val rightOf : ''a tape -> ''a option list (* Symbols right of of the head *)
end
signature MACHINE = sig
structure Tape : TAPE
type state = int
(* ''a is band alphabet type *)
type ''a transitions = (state * ''a option Vector.vector) ->
(state * (Tape.move * ''a option) Vector.vector)
type ''a configuration = { state : state, tapes : ''a Tape.tape Vector.vector }
type ''a machine = {
alphabet : ''a Vector.vector, (* (not used) *)
states : state Vector.vector, (* (not used) *)
start : state, (* element of stats *)
final : state, (* element of stats *)
transitions : ''a transitions, (* transitions *)
tapes : ''a Tape.tape Vector.vector (* vector of the initial tapes *)
}
end
signature UNIVERSALMACHINE = sig
structure Machine : MACHINE
val start : ''a Machine.machine -> ''a Machine.configuration
(* Find a holding configuration (limited by n steps)
* Execute the handler for each step *)
val simulate : (''a Machine.configuration -> unit) -> ''a Machine.machine -> int option -> ''a Machine.configuration option
end
(*** Implementation ***)
structure Tape :> TAPE = struct
(*
* NONE => blank field
* SOME a => written field
*)
type ''a symbol = ''a option
datatype move = Left | Right | Stay
(*
* Four cases:
* 1 The tape is complete empty.
* 2 The head is in the written area.
* On the right and on the left handside are symbols,
* On the head is a symbol.
* 3/4 The head is (n-1) fields over the right/left edge of the written area.
* There is at least one entry and a rest list of entries.
*)
datatype ''a tape =
Empty
| Middle of ''a symbol list * ''a symbol * ''a symbol list
| LeftOf of ''a symbol * ''a symbol list * int
| RightOf of ''a symbol * ''a symbol list * int
val empty = Empty
fun rep a 0 = nil
| rep a n = a :: rep a (n-1)
fun leftOf (Empty) = nil
| leftOf (Middle (ls, _, _)) = ls
| leftOf (RightOf (r, rs, i)) = rep NONE i @ r :: rs
| leftOf (LeftOf _) = nil
fun rightOf (Empty) = nil
| rightOf (Middle (_, _, rs)) = rs
| rightOf (RightOf _) = nil
| rightOf (LeftOf (l, ls, i)) = rep NONE i @ l :: ls
fun write (NONE) t = t (* Cannot write a blank field! *)
| write a t = Middle (leftOf t, a, rightOf t)
fun getSymbol (Middle (_, m, _)) = m
| getSymbol _ = NONE (* blank *)
fun moveRight (Empty) = Empty
| moveRight (Middle (ls, m, nil)) = RightOf (m, ls, 0)
| moveRight (Middle (ls, m, r::rs)) = Middle (m::ls, r, rs)
| moveRight (RightOf (l, ls, n)) = RightOf (l, ls, n+1)
| moveRight (LeftOf (r, rs, 0)) = Middle (nil, r, rs)
| moveRight (LeftOf (r, rs, n)) = LeftOf (r, rs, n-1)
fun moveLeft (Empty) = Empty
| moveLeft (Middle (nil, m, rs)) = LeftOf (m, rs, 0)
| moveLeft (Middle (l::ls, m, rs)) = Middle (ls, l, m::rs)
| moveLeft (RightOf (l, ls, 0)) = Middle (ls, l, nil)
| moveLeft (RightOf (l, ls, n)) = RightOf (l, ls, n-1)
| moveLeft (LeftOf (r, rs, n)) = LeftOf (r, rs, n+1)
fun move tape Stay = tape
| move tape Right = moveRight tape
| move tape Left = moveLeft tape
(* Test *)
local
val tape : int tape = empty (* [] *)
val tape = moveRight tape (* [] *)
val NONE = getSymbol tape
val tape = write (SOME 42) tape (* [42] *)
val (SOME 42) = getSymbol tape
val tape = moveRight tape (* 42, [] *)
val tape = moveRight tape (* 42, , [] *)
val NONE = getSymbol tape
val tape = moveLeft tape (* 42, [] *)
val NONE = getSymbol tape
val tape = moveLeft tape (* [42] *)
val (SOME 42) = getSymbol tape
val tape = write NONE tape (* [42] *) (* !!! *)
val (SOME 42) = getSymbol tape
val tape = moveLeft tape (* [], 42 *)
val tape = moveLeft tape (* [], , 42 *)
val tape = write (SOME 47) tape (* [47], , 42 *)
val (SOME 47) = getSymbol tape
val tape = moveRight tape (* 47, [], 42 *)
val NONE = getSymbol tape
val tape = moveRight tape (* 47, , [42] *)
val (SOME 42) = getSymbol tape
in end
end
structure Machine :> MACHINE = struct
structure Tape = Tape
type state = int
(* ''a is band alphabet type *)
type ''a transitions = (state * ''a option Vector.vector) ->
(state * (Tape.move * ''a option) Vector.vector)
type ''a configuration = { state : state, tapes : ''a Tape.tape Vector.vector }
type ''a machine = {
alphabet : ''a Vector.vector,
states : state Vector.vector,
start : state,
final : state,
transitions : ''a transitions,
tapes : ''a Tape.tape Vector.vector
}
end
structure UniversalMachine :> UNIVERSALMACHINE = struct
structure Machine = Machine
fun start ({ start, tapes, ... } : ''a Machine.machine) : ''a Machine.configuration = {
state = start,
tapes = tapes
}
fun doTransition ({ state, tapes } : ''a Machine.configuration)
((state', actions) : (Machine.state * (Machine.Tape.move * ''a option) Vector.vector))
: ''a Machine.configuration = {
state = state',
tapes = Vector.mapi (fn (i, tape) =>
let val (move, write) = Vector.sub (actions, i)
val tape' = Machine.Tape.write write tape
val tape'' = Machine.Tape.move tape' move
in tape'' end) tapes
}
fun getSymbols ({ tapes, ... } : ''a Machine.configuration) : ''a option Vector.vector =
Vector.map (Machine.Tape.getSymbol) tapes
fun step ({ transitions, ... } : ''a Machine.machine) (conf : ''a Machine.configuration) : ''a Machine.configuration =
doTransition conf (transitions (#state conf, getSymbols conf))
fun isFinal ({final, ...} : ''a Machine.machine) ({state, ...} : ''a Machine.configuration) : bool =
final = state
fun iter term (SOME 0) f s = NONE
| iter term (SOME n) f s = if term s then SOME s else iter term (SOME (n-1)) f (f s)
| iter term NONE f s = if term s then SOME s else iter term NONE f (f s)
fun simulate handler (machine : ''a Machine.machine) optcount =
let val endconf = iter (isFinal machine) optcount (fn conf => (handler conf; step machine conf)) (start machine)
in case endconf of NONE => NONE | SOME conf => (handler conf; endconf) end
end
structure ExampleMachines = struct
structure Machine = UniversalMachine.Machine
(* Tranform the 5-Tuple notation into the vector function *)
fun makeTransitions nil : ''a Machine.transitions = (fn (t, vec) => (print (Int.toString t); raise Subscript))
| makeTransitions ((s : Machine.state,
read : ''a option,
write : ''a option,
move : Machine.Tape.move,
s' : Machine.state) :: ts) =
fn (t, vec) =>
if s=t andalso vec=(Vector.fromList [read])
then (s', Vector.fromList [(move, write)])
else makeTransitions ts (t, vec)
(* `createTape xs` creates an tape initialized by xs, where the head stands on the first element of xs *)
fun createTape' nil = Machine.Tape.empty
| createTape' (x::xs) = Machine.Tape.moveLeft (Machine.Tape.write x (createTape' xs))
fun createTape xs = Machine.Tape.moveRight (createTape' (rev xs))
(* Convert a tape into a string to print it. It needs a function that converts each symbol to string *)
fun tapeToStr (symStr : ''a -> string) (tape : ''a Machine.Tape.tape) : string =
let val left : ''a option list = rev (Machine.Tape.leftOf tape)
val right : ''a option list = Machine.Tape.rightOf tape
val current : ''a option = Machine.Tape.getSymbol tape
val symToStr : ''a option -> string = (fn (NONE) => "#" | (SOME a) => symStr a)
in
String.concatWith " " ((map symToStr left) @ [ "|" ^ symToStr current ^ "|" ] @ (map symToStr right))
end
(* Convert a vector to a list *)
fun vectToList vect = List.tabulate (Vector.length vect, fn i => Vector.sub (vect, i))
(* Do this before every step and after the last step. *)
fun handler (symToStr : ''a -> string) ({state, tapes} : ''a Machine.configuration) : unit =
let
val str = "State " ^ Int.toString state ^ "\n" ^
String.concat (vectToList (Vector.mapi (fn (i, tape) => "Tape #" ^ Int.toString i ^ ": " ^
tapeToStr symToStr tape ^ "\n") tapes))
in
print str
end
(* Simulate and make result into string *)
fun simulate (symToStr : ''a -> string) (machine : ''a Machine.machine)
(optcount : int option) : string =
case (UniversalMachine.simulate (handler symToStr) machine optcount) of
NONE => "Did not terminate."
| SOME ({state, tapes} : ''a Machine.configuration) => "Terminated."
(* Now finaly the machines! *)
val incrementer : unit Machine.machine = {
alphabet = Vector.fromList [()],
states = Vector.fromList [0, 1],
start = 0,
final = 1,
tapes = Vector.fromList [createTape (map SOME [(), (), (), ()])],
transitions = makeTransitions [
(0, SOME (), SOME (), Machine.Tape.Right, 0),
(0, NONE, SOME (), Machine.Tape.Stay, 1)]
}
val busybeaver : unit Machine.machine = {
alphabet = Vector.fromList [()],
states = Vector.fromList [0, 1, 2, 3],
start = 0,
final = 3,
tapes = Vector.fromList [Machine.Tape.empty],
transitions = makeTransitions [
(0, NONE, SOME (), Machine.Tape.Right, 1),
(0, SOME (), SOME (), Machine.Tape.Left, 2),
(1, NONE, SOME (), Machine.Tape.Left, 0),
(1, SOME (), SOME (), Machine.Tape.Right, 1),
(2, NONE, SOME (), Machine.Tape.Left, 1),
(2, SOME (), SOME (), Machine.Tape.Stay, 3)]
}
val sorting : int Machine.machine = {
alphabet = Vector.fromList [1,2,3],
states = Vector.fromList [0,1,2,3,4,5],
start = 1,
final = 0,
tapes = Vector.fromList [createTape (map SOME [2, 1, 2, 2, 1, 1])],
transitions = makeTransitions [
(1, SOME 1, SOME 1, Machine.Tape.Right, 1),
(1, SOME 2, SOME 3, Machine.Tape.Right, 2),
(1, NONE, NONE, Machine.Tape.Left, 5),
(2, SOME 1, SOME 1, Machine.Tape.Right, 2),
(2, SOME 2, SOME 2, Machine.Tape.Right, 2),
(2, NONE, NONE, Machine.Tape.Left, 3),
(3, SOME 1, SOME 2, Machine.Tape.Left, 3),
(3, SOME 2, SOME 2, Machine.Tape.Left, 3),
(3, SOME 3, SOME 2, Machine.Tape.Left, 5),
(4, SOME 1, SOME 1, Machine.Tape.Left, 4),
(4, SOME 2, SOME 2, Machine.Tape.Left, 4),
(4, SOME 3, SOME 1, Machine.Tape.Right, 1),
(5, SOME 1, SOME 1, Machine.Tape.Left, 5),
(5, NONE, NONE, Machine.Tape.Right, 0)]
}
end
(** Invoke Simulations **)
local
open ExampleMachines
val unitToString = (fn () => "()")
fun simulate_unit machine optcount = print (simulate unitToString machine optcount ^ "\n")
fun simulate_int machine optcount = print (simulate Int.toString machine optcount ^ "\n")
in
val () = print "Simulate incrementer...\n\n"
val () = simulate_unit incrementer NONE
val () = print "\nSimulate Busy Beaver...\n\n"
val () = simulate_unit busybeaver NONE
val () = print "\nSimulate Sorting...\n\n"
val () = simulate_int sorting NONE
end

View file

@ -0,0 +1,20 @@
var [const] D=Dictionary; // short cut
// blank symbol and terminating state(s) are Void
var Lt=-1, Sy=0, Rt=1; // Left, Stay, Right
fcn printTape(tape,pos){
tape.keys.apply("toInt").sort()
.pump(String,'wrap(i){ ((pos==i) and "(%s)" or " %s ").fmt(tape[i]) })
.println();
}
fcn turing(state,[D]tape,[Int]pos,[D]rules,verbose=True,n=0){
if(not state){
print("%d steps. Length %d. Tape: ".fmt(n,tape.len()));
printTape(tape,Void);
return(tape);
}
r:=rules[state][tape[pos] = tape.find(pos)];
if(verbose) printTape(tape,pos);
tape[pos]=r[0];
return(self.fcn(r[2],tape,pos+r[1],rules,verbose,n+1));
}

View file

@ -0,0 +1,25 @@
println("Simple incrementer");
turing("q0",D(0,Rt, 1,Rt, 2,Rt),0, // Incrementer
D("q0",D(1,T(1,Rt,"q0"), Void,T(1,Sy,Void)) ) );
println("\nThree-state busy beaver");
turing("a",D(),0, // Three-state busy beaver
SD("a",D(Void,T(1,Rt,"b"), 1,T(1,Lt,"c")),
"b",D(Void,T(1,Lt,"a"), 1,T(1,Rt,"b")),
"c",D(Void,T(1,Lt,"b"), 1,T(1,Sy,Void)) ) );
println("\nSort");
turing("A",D(T(2,2,2,1,2,2,1,2,1,2,1,2,1,2).enumerate()),0,
SD("A",D(1,T(1,Rt,"A"), 2,T(3,Rt,"B"), Void,T(Void,Lt,"E")),
"B",D(1,T(1,Rt,"B"), 2,T(2,Rt,"B"), Void,T(Void,Lt,"C")),
"C",D(1,T(2,Lt,"D"), 2,T(2,Lt,"C"), 3, T(2, Lt,"E")),
"D",D(1,T(1,Lt,"D"), 2,T(2,Lt,"D"), 3, T(1, Rt,"A")),
"E",D(1,T(1,Lt,"E"), Void,T(Void,Rt,Void)) ) ,False);
println("\nFive-state busy beaver");
turing("A",D(),0,
SD("A",D(Void,T(1,Rt,"B"), 1,T(1, Lt,"C")),
"B",D(Void,T(1,Rt,"C"), 1,T(1, Rt,"B")),
"C",D(Void,T(1,Rt,"D"), 1,T(Void,Lt,"E")),
"D",D(Void,T(1,Lt,"A"), 1,T(1, Lt,"D")),
"E",D(Void,T(1,Sy,Void), 1,T(Void,Lt,"A")) ) ,False);