スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

F#で入門 コンパイラ 、インタプリタ編 チューリング・マシン(2)

 今回はチューリングマシンのWinソフト版です。 
次のようなソフトを作成します。 
 
1044-1.jpg
  
まずは使い方の説明から 
(1)プログラムを入力 
読み込み時の状態と読み込みの値から次のする動作の対応を入力します。 
前回の例なら次の様に入力します。 
 
1,0,2,_,1 
1,1,3,_,1 
2,0,4,_,1 
2,1,5,_,1 
2,_,7,_,-1 
3,0,5,_,1 
3,1,6,_,1 
3,_,7,_,-1 
4,+,2,0,1 
4,*,2,0,1 
5,+,3,1,1 
5,*,2,0,1 
6,+,2,0,1 
6,*,3,1,1 
 
これで「Set」ボタンを押します。 
 
画面はこうなります。 
 
1044-2.jpg
   
(2)テープ初期値を入力します。 
01+1*を計算させるなら次のような入力となります。 
 
 
これで「Set」ボタンを押します。 
 
画面はこうなります。 
 
1044-3.jpg 
 
(3)終了状態(accept state No.)を入力します。 
 
 
1044-4.jpg
 
 
あとは右の「OneStepExec」ボタンを押すと、一ステップごと進行します。 
 
なおテープは、位置が0以上の部分と、負の部分を分けて表示するようにしてあります。 
 
1044-5.jpg
 
なお、チューリングマシンでエラーの場合は、無限ループに陥って終了しないのが本義なのですが、このプログラムの場合は、エラー表示をして終了するようにしてあります。 
テープ初期値を色々変えて計算させてみてください。(8通りしか計算できませんが。) 
 
今回のソースは次の通りです。 
 open System  
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
open System.Windows.Forms    
open System.Drawing   
 
//"1,0,2,*,1" -> ((1,'0'),(2,Some('*'),1))と変換 
//"1,'0',2,_,1" -> ((1,'0'),(2,None,1))と変換 
let convOneLineToChangeTB (str:string) = 
    let splitedEles = str.Replace(" ","").Split([|','|])  
    let s1 = Int32.Parse (splitedEles.[0]) 
    let s2 = char (splitedEles.[1]) 
    let t1 = Int32.Parse (splitedEles.[2]) 
    let t2 = 
            if splitedEles.[3] = "_" then 
                None 
            else 
                Some(char(splitedEles.[3])) 
    let t3 = Int32.Parse (splitedEles.[4]) 
    ((s1,s2),(t1,t2,t3)) 
 
let f2c x = x :> System.Windows.Forms.Control  
let label1= new Label(AutoSize = true,Location = new Point(12, 9),Name = "label1",Size = new Size(287, 12),TabIndex = 0,Text = "状態番号、ヘッド値、遷移状態番号、書き込み動作、移動") 
let changeTB_tb= new TextBox(Font = new Font("MS UI Gothic", 12.0f, FontStyle.Regular, GraphicsUnit.Point, ((byte)(128))),Location = new Point(12, 24),Multiline = true,Name = "changeTB_tb",Size = new Size(287, 425),TabIndex = 1) 
let label2= new Label(AutoSize = true,Location = new Point(322, 9),Name = "label2",Size = new Size(69, 12),TabIndex = 2,Text = "テープ初期値") 
let init_tb= new TextBox(Font = new Font("MS UI Gothic", 12.0f, FontStyle.Regular, GraphicsUnit.Point, ((byte)(128))),Location = new Point(319, 24),Multiline = true,Name = "init_tb",Size = new Size(100, 425),TabIndex = 3) 
let changeTB_set_btn= new Button(Location = new Point(14, 464),Name = "changeTB_set_btn",Size = new Size(285, 23),TabIndex = 4,Text = "Set",UseVisualStyleBackColor = true) 
let init_set_btn= new Button(Location = new Point(319, 464),Name = "init_set_btn",Size = new Size(161, 23),TabIndex = 5,Text = "Set",UseVisualStyleBackColor = true) 
let reset_btn= new Button(Location = new Point(543, 31),Name = "reset_btn",Size = new Size(83, 51),TabIndex = 6,Text = "Reset",UseVisualStyleBackColor = true) 
let oneStep_btn= new Button(Location = new Point(543, 101),Name = "oneStep_btn",Size = new Size(83, 51),TabIndex = 7,Text = "OneStepExec",UseVisualStyleBackColor = true) 
let tapeMinus_lb= new ListBox(FormattingEnabled = true,ItemHeight = 12,Location = new Point(645, 31),Name = "tapeMinus_lb",Size = new Size(90, 544),TabIndex = 8) 
let tapePlus_lb= new ListBox(FormattingEnabled = true,ItemHeight = 12,Location = new Point(760, 31),Name = "tapePlus_lb",Size = new Size(90, 544),TabIndex = 9) 
let label3= new Label(AutoSize = true,Location = new Point(647, 9),Name = "label3",Size = new Size(82, 12),TabIndex = 10,Text = "テープ(マイナス)") 
let label4= new Label(AutoSize = true,Location = new Point(758, 9),Name = "label4",Size = new Size(77, 12),TabIndex = 11,Text = "テープ(0以上)") 
let changeTBSave_btn= new Button(Location = new Point(154, 493),Name = "changeTBSave_btn",Size = new Size(145, 23),TabIndex = 59,Text = "Save",UseVisualStyleBackColor = true) 
let changeTBLoad_btn= new Button(Location = new Point(14, 493),Name = "changeTBLoad_btn",Size = new Size(134, 23),TabIndex = 58,Text = "Load",UseVisualStyleBackColor = true) 
let initSabe_btn= new Button(Location = new Point(394, 493),Name = "initSabe_btn",Size = new Size(86, 23),TabIndex = 61,Text = "Save",UseVisualStyleBackColor = true) 
let intLoad_btn= new Button(Location = new Point(317, 493),Name = "intLoad_btn",Size = new Size(71, 23),TabIndex = 60,Text = "Load",UseVisualStyleBackColor = true) 
let error_tb= new TextBox(Location = new Point(14, 549),Multiline = true,Name = "error_tb",Size = new Size(612, 70),TabIndex = 62) 
let label5= new Label(AutoSize = true,Location = new Point(17, 527),Name = "label5",Size = new Size(32, 12),TabIndex = 63,Text = "エラー") 
let label6= new Label(AutoSize = true,Location = new Point(427, 9),Name = "label6",Size = new Size(89, 12),TabIndex = 64,Text = "accpet state No.") 
let accept_STN_tb= new TextBox(Location = new Point(429, 24),Name = "accept_STN_tb",Size = new Size(96, 19),TabIndex = 65,TextAlign = HorizontalAlignment.Center) 
let label7= new Label(AutoSize = true,Location = new Point(657, 599),Name = "label7",Size = new Size(85, 12),TabIndex = 66,Text = "現在のstate No.") 
let cur_stateNo_tb= new TextBox(Location = new Point(658, 618),Name = "cur_stateNo_tb",Size = new Size(84, 19),TabIndex = 67,TextAlign = HorizontalAlignment.Center) 
let Form1= new Form(AutoScaleDimensions = new SizeF(6.0f, 12.0f),AutoScaleMode = AutoScaleMode.Font,ClientSize = new Size(863, 678),Name = "Form1",Text = "TuringMachine") 
[ f2c cur_stateNo_tb; f2c label7; f2c accept_STN_tb; f2c label6; f2c label5; f2c error_tb; f2c initSabe_btn; f2c intLoad_btn; f2c changeTBSave_btn; f2c changeTBLoad_btn; f2c label4; f2c label3; f2c tapePlus_lb; f2c tapeMinus_lb; f2c oneStep_btn; f2c reset_btn; f2c init_set_btn; f2c changeTB_set_btn; f2c init_tb; f2c label2; f2c changeTB_tb; f2c label1] |> List.iter(fun cnt -> Form1.Controls.Add cnt) 
 
let GL_TapeIndex = ref 0 
let GL_CurStateNo = ref 1 //状態No は 1から始まるのがお約束とする 
let GL_AcceptStateNo = ref -99 
let mutable GL_changeTB : Map<(int * char),(int * char option * int)> = Map.empty  
 
 
let showIndexPos () = 
    if !GL_TapeIndex >= 0 then 
        tapeMinus_lb.SelectedIndex <- -1 
        tapePlus_lb.SelectedIndex <- !GL_TapeIndex 
 
    else 
       tapePlus_lb.SelectedIndex <- -1 
       let negConvIndex = (-1)*(!GL_TapeIndex) - 1 
       tapeMinus_lb.SelectedIndex <-negConvIndex 
 
 
let getCharAtCurIndex () = 
    if !GL_TapeIndex >= 0 then 
         
        System.Char.Parse(tapePlus_lb.Items.[!GL_TapeIndex].ToString()) 
    else 
        System.Char.Parse(tapeMinus_lb.Items.[ (-1)*(!GL_TapeIndex) - 1].ToString()) 
 
let moveRight () = 
        GL_TapeIndex := !GL_TapeIndex + 1 
        if !GL_TapeIndex >= tapePlus_lb.Items.Count then 
            tapePlus_lb.Items.Add('_') |> ignore 
let moveLeft () = 
        GL_TapeIndex := !GL_TapeIndex - 1 
        let t = ((-1) * !GL_TapeIndex) 
        if  t > tapeMinus_lb.Items.Count then 
            tapeMinus_lb.Items.Add('_') |> ignore 
 
let writeCharAtCurIndex (ch : char) = 
    if !GL_TapeIndex >= 0 then 
           tapePlus_lb.Items.[!GL_TapeIndex] <- ch 
    else   
           tapeMinus_lb.Items.[ (-1)*(!GL_TapeIndex) - 1] <-ch 
  
let changeTB_Set () = 
        let sourceTextArr = changeTB_tb.Text.Replace("\r\n", "\n").Split([|'\n'|]) 
        let resArr = 
                sourceTextArr 
                |> Array.filter (fun str -> str <> "" ) 
                |> Array.map (fun str ->  convOneLineToChangeTB str) 
        GL_changeTB <- (Map.ofArray resArr) 
 
let initTape_Set () = 
        tapePlus_lb.Items.Clear() 
        let initSourceTextArr = init_tb.Text.Replace("\r\n", "\n").Split([|'\n'|]) 
        initSourceTextArr 
            |>Array.filter (fun str -> str <> "") 
            |>Array.iter(fun str -> tapePlus_lb.Items.Add (str) |> ignore)  
        GL_TapeIndex := 0 
        showIndexPos () 
 
let reset () = 
        GL_TapeIndex :=  0 
        GL_CurStateNo := 1 
        showIndexPos () 
        GL_AcceptStateNo := System.Int32.Parse(accept_STN_tb.Text) 
        cur_stateNo_tb.Text <- (!GL_CurStateNo).ToString() 
        oneStep_btn.Enabled <- true 
 
let oneStepExec () = 
    if !GL_CurStateNo = !GL_AcceptStateNo then 
        oneStep_btn.Enabled <- false 
    else 
       let charAtPos = getCharAtCurIndex () 
       let (nextStateNo,doWrite,tapeMove) = GL_changeTB.[(!GL_CurStateNo,charAtPos)] 
       if doWrite.IsNone then 
            () 
       else 
          writeCharAtCurIndex (doWrite.Value) 
       if tapeMove = 1 then 
            moveRight () 
       else 
            moveLeft () 
       GL_CurStateNo := nextStateNo 
       cur_stateNo_tb.Text <- (!GL_CurStateNo).ToString()          
 
reset_btn.Click.Add 
    (fun _ ->  
        try 
            changeTB_Set () 
            initTape_Set () 
            reset()  
        with 
              | ex -> error_tb.Text <- ex.Message   
    )                 
 
 
 
changeTB_set_btn.Click.Add 
    (fun _ -> try 
                changeTB_Set () 
              with 
              | ex -> error_tb.Text <- ex.Message    
 
    ) 
 
oneStep_btn.Click.Add 
    (fun _ ->  
         oneStepExec ()  
         showIndexPos () 
    ) 
 
 
 
changeTBLoad_btn.Click.Add 
    (fun _ -> error_tb.Text <- ""  
              try  
                let ofd = new OpenFileDialog(Filter = "ctbファイル(*.ctb)|*.ctb|すべてのファイル(*.*)|*.*")  
                if(ofd.ShowDialog() = DialogResult.OK) then  
                    use sr = new System.IO.StreamReader(ofd.FileName)  
                    changeTB_tb.Text <- sr.ReadToEnd()  
              with  
                | ex -> error_tb.Text <- ex.Message  
    )  
 
changeTBSave_btn.Click.Add  
    (fun _ -> error_tb.Text <- ""   
              try  
                let sfd = new SaveFileDialog(Filter = "ctbファイル(*.ctb)|*.ctb|すべてのファイル(*.*)|*.*",  
                                              RestoreDirectory = true)  
                if (sfd.ShowDialog() = DialogResult.OK) then  
                    use sw = new System.IO.StreamWriter(sfd.FileName)  
                    sw.Write(changeTB_tb.Text)  
              with  
                | ex -> error_tb.Text <- ex.Message  
                  
    )  
 
init_set_btn.Click.Add 
    (fun _ -> error_tb.Text <- ""   
              try  
                initTape_Set () 
              with  
                | ex -> error_tb.Text <- ex.Message  
    )               
 
intLoad_btn.Click.Add 
    (fun _ -> error_tb.Text <- ""  
              try  
                let ofd = new OpenFileDialog(Filter = "itbファイル(*.itb)|*.itb|すべてのファイル(*.*)|*.*")  
                if(ofd.ShowDialog() = DialogResult.OK) then  
                    use sr = new System.IO.StreamReader(ofd.FileName)  
                    init_tb.Text <- sr.ReadToEnd()  
              with  
                | ex -> error_tb.Text <- ex.Message  
    )  
 
initSabe_btn.Click.Add  
    (fun _ -> error_tb.Text <- ""   
              try  
                let sfd = new SaveFileDialog(Filter = "itbファイル(*.itb)|*.itb|すべてのファイル(*.*)|*.*",  
                                              RestoreDirectory = true)  
                if (sfd.ShowDialog() = DialogResult.OK) then  
                    use sw = new System.IO.StreamWriter(sfd.FileName)  
                    sw.Write(init_tb.Text)  
              with  
                | ex -> error_tb.Text <- ex.Message  
                  
    )  
 
[<STAThread()>]   
do Application.Run(Form1) 
 
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

Author:T GYOUTEN
F#と英単語とフリーソフトと読書に興味があります。
ホームページでフリーソフトも公開しています。どぞ御贔屓に。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
フリーエリア
フリーエリア
blogram投票ボタン
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。