2011-05-25 125 views
2

我正試圖在Scheme中完成一個有限狀態機。問題是,我不知道如何告訴它應該測試哪些字符。如果我想測試一個字符串「abc112」,那我該怎麼做?計劃中的有限狀態機

下面是代碼:

#lang racket  
(define (chartest ch) 
    (lambda (x) (char=? x ch))) 
;; A transition is (list state char!boolean state) 
(define fsmtrlst 
    (list 
    (list 'start char-alphabetic? 'name) 
    (list 'start char-numeric? 'number) 
    (list 'start (chartest #\() 'lparen) 
    (list 'start (chartest #\)) 'rparen) 
    (list 'name char-alphabetic? 'name) 
    (list 'name char-numeric? 'name) 
    (list 'number char-numeric? 'number))) 

(define (find-next-state state ch trl) 
    (cond 
    [(empty? trl) false] 
    [(and (symbol=? state (first (first trl))) 
      ((second (first trl)) ch)) 
    (third (first trl))] 
    [else (find-next-state state ch (rest trl))])) 

(define fsmfinal '(name number lparen rparen)) 

(define (run-fsm start trl final input) 
    (cond 
    [(empty? input) 
    (cond 
     [(member start final) true] 
     [else false])] 
    [else 
    (local ((define next (find-next-state start (first input) trl))) 
     (cond 
     [(boolean? next) false] 
     [else (run-fsm next trl final (rest input))]))])) 

這裏是我想測試的啓動代碼:

(fsmtrlst (list 'start (lambda (abc112) (char=? abc112)))) 

編輯:

OK ..整體產品okey,但是我的導師不滿意它,..他希望我創建一個帶有轉換函數的有限狀態機 - >類似於全局定義,它會說:當狀態X中字符Y轉到Z時那麼我會測試一個字符列表,看看它是錯誤還是真實的......所以唯一的區別是代碼不應該只使用數字和字母,而是使用任何字符...是不是有可能?謝謝您的回答

編輯2:現在我有基本的信息應該如何看起來像:

也就是說,整機看起來像

一個---------> B ----------> C ----------> D ---------->(E) 字母數字編號字母

(define fsmtrlst 
(list 
    (list 'A char-alphabetic? 'B) 
    (list 'B char-numeric? 'C) 
    (list 'C char-numeric? 'D) 
    (list 'D char-alphabetic 'E))) 

(define fsmfinal '(E)) 

(define fsmstart 'A) 

但我不知道如何編寫fsmstart的定義。

謝謝你的回答。

它接受正好是字母,數字,數字,字母和其他的字符序列。編輯3:我在線上使用教程和我的導師老師提供的一本書。我想出了我想製作的fsm。感謝您的幫助。

只是出於好奇:

如何將不同有相當具體的FSM?

實施例:

START ---- 「B」 ----->狀態A ----- 「一個」 ---->狀態B ----- 「C」 - ----> FINAL STATE

只有當字符列表是「bac」而沒有其他字符時,fsm纔會成立。 這可能嗎?

感謝您的反饋。

編輯4:

好吧,我能夠做到寫,但再一次,我不知道如何使文字的輸入。這是代碼:

有3個狀態,但是從狀態A到狀態時只有C.

(define (chartest ch) 
    (lambda (x) (char=? x ch))) 

    (define fsm-trans 
     '((A, "a", B), (A, "b", A), (B, "c", C))) 

    (define (find-next-state state ch trl) 
     (cond 
     [(empty? trl) false] 
     [(and (symbol=? state (first (first trl))) 
       ((second (first trl)) ch)) <- And also this line returns an error 
     (third (first trl))] 
     [else (find-next-state state ch (rest trl))])) 


    (define fsm-final '(C)) 

    (define start-state 'A) 

    (define (run-fsm start trl final input) 
     (cond 
     [(empty? input) 
     (cond 
      [(member start final) true] 
      [else false])] 
     [else 
     (local ((define next (find-next-state start (first input) trl))) 
      (cond 
      [(boolean? next) false] 
      [else (run-fsm next trl final (rest input))]))])) 


    (run-fsm start-state fsm-trans fsm-final (list '("a", "c"))) <- I know this is the last problem with the code, the definition of the input. How can I tell Scheme what characters I want to test? 

謝謝你的回答會是真的!

+2

請縮進您的代碼以使其可讀。另外,有限狀態機應該做什麼? – Heatsink 2011-05-25 19:36:48

+0

@Heatsink:我將代碼導入dr-scheme,並使用製表鍵 – ccoakley 2011-05-26 04:06:23

+1

與Emacs進行了緊密合作。在Emacs中,您可以剛剛完成C-A- \。只是在說'。 – JasonFruit 2011-05-30 11:37:11

回答

4

我很好奇:我認爲你沒有寫這個fsm?這是做家庭作業還是你想教自己? FSM的代碼看起來很好(實際上很好)。然而,你的啓動行:

(fsmtrlst (list 'start (lambda (abc112) (char=? abc112)))) 

是沒有意義的。這是爲什麼:fsmtrlst是有限狀態機轉換列表。它是在第一大代碼塊中定義的。它是而不是一個被調用的函數。我相信你想要調用的功能是run-fsm。這需要一個開始符號,一個轉換列表,一個最終狀態列表和一個輸入。輸入實際上不是一個字符串,而是一個列表。因此,你可以用下面的行啓動它:

(run-fsm 'start fsmtrlst fsmfinal (string->list "abc112")) 

,將調用run-fsm與定義的過渡列表fsmtrlst,所定義的最終狀態的列表,字符串「abc112」的輸入就緒形式。

順便提一下,除'start之外的所有內容都被定義爲最終(接受)狀態。不過,並非所有投入都接受投入。例如,取代「abc122」,「ABC(122」是接受

這是你想要的

更新:?

您的修改,澄清事情你的fsmstart定義你確實錯過了char-alphabetic?用法中的一個問號(?)fsmtrlst。難道你不知道如何使用你的新定義嗎?首先,你應該刪除舊的定義fsmtrlstfsmfinal。 ,你可能會得到一個重複的定義錯誤。從你的新defi定義,你行執行應該是這樣的:

(run-fsm fsmstart fsmtrlst fsmfinal (string->list "w00t")) 

這將返回#T,因爲「w00t」是一個字符,後跟兩個數字,後跟一個字符。

我推測你仍然有計劃的語法規則的困難,而不僅僅是你的特定程序的邏輯問題。你可能想嘗試一個更簡單的練習。

更新2:你不應該考慮制定一個新的問題嗎?

您最近的更新已打破該守則。 FSM的過渡部分的工作,因爲過渡被定義爲一個列表:

(from-state test-function to-state) 

您試圖創建一個過渡:

(from-state string-literal to-state) 

你可以改變(A, "a", B)(A (lambda (x) (string=? x "a") B)

當您嘗試調用函數時,您使用了一個函數,該函數需要一個字符列表併爲其提供了一個字符串列表。這些不是一回事。另外,您是否注意到您在列表中添加了逗號,但是它們在代碼中沒有其他地方存在?這些錯誤是爲什麼我建議你開始計劃教程。這些是基本的計劃問題,與您的特定練習無關。我建議你將編輯回放到你昨天所做的。

很抱歉,我們不能再更新此答案。我想更新我的答案,以便如果有人帶着類似的問題提出你的問題,他們會看到一個完整的答案。但是,您提供了一個移動目標。請考慮停止編輯並在有問題時提交新問題。

+0

我編輯了(幾次)我的問題。在完成fsm之前,我面臨着最後的問題。 – Vojtech 2011-06-08 13:26:35