;; The first three lines of this file were inserted by DrScheme. They record metadata ;; about the language level of this file in a form that our tools can easily process. #reader(lib "htdp-beginner-reader.ss" "lang")((modname 1-2) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ()))) ;; ----------------------------------------------------------------------------- ;; Problem: visualize an FSM that accepts strings of the shape: a (b | c)* d . ;; An error state should signal that some bad input came in. Ignore special key ;; events. (require 2htdp/universe) ;; World is one of: ;; -- "a" want to see an "a" ;; -- "b" have seen an "a" and wish to see "b", "c", or "d" ;; -- "d" final success state ;; -- "error" final stop state ;; constants: (define SIZE 100) ;; graphical constants: (define A (nw:rectangle SIZE SIZE "solid" "white")) (define B (nw:rectangle SIZE SIZE "solid" "yellow")) (define D (nw:rectangle SIZE SIZE "solid" "green")) (define ERROR (nw:rectangle SIZE SIZE "solid" "red")) ;; ----------------------------------------------------------------------------- ;; World -> World ;; start the program from some initial state (define (main s0) (big-bang s0 (on-key next) (on-draw image) (stop-when final?))) ;; ----------------------------------------------------------------------------- ;; World KeyEvent -> World ;; recognize 'strings' of the shape a(b|c)*d (check-expect (next "a" "b") "error") (check-expect (next "a" "a") "b") (check-expect (next "b" "a") "error") ;; more examples in TEST SECTION (define (next w ke) (cond [(> (string-length ke) 1) w] ;; ignore special keys [(string=? ke "a") (good w "a" "b")] [(string=? ke "b") (good w "b" "b")] [(string=? ke "c") (good w "b" "b")] [(string=? ke "d") (good w "b" "d")] [else "error"])) ;; error our on keys outside of core alphabet ;; World World World -> World ;; if the world is in the current-state, go to next-state, else error (define (good w current-state next-state) (if (string=? w current-state) next-state "error")) ;; ----------------------------------------------------------------------------- ;; World -> Image ;; render the current state as a SIZE x SIZE rectangle of the appropriate color (check-expect (image "a") A) ;; more examples in TEST SECTION (define (image w) (cond [(string=? w "a") A] [(string=? w "b") B] [(string=? w "d") D] [(string=? w "error") ERROR])) ;; ----------------------------------------------------------------------------- ;; World -> Boolean ;; is this state a final state? (check-expect (final? "error") true) ;; more examples in TEST SECTION (define (final? w) (or (string=? w "d") (string=? w "error"))) ;; ----------------------------------------------------------------------------- ;; TEST SECTION: ;; next (check-expect (next "b" "b") "b") (check-expect (next "b" "c") "b") (check-expect (next "a" "c") "error") (check-expect (next "b" "d") "d") (check-expect (next "a" "d") "error") (check-expect (next "b" "e") "error") (check-expect (next "a" "left") "a") ;; image (check-expect (image "b") B) (check-expect (image "d") D) (check-expect (image "error") ERROR) ;; final? (check-expect (final? "d") true) (check-expect (final? "a") false)