我是一个通过 HTDP2(Felleisen 等人)独自工作的新手,但一直被困在第四章的问题 #380 -Intertwined Data 上。问题出在创建 DSL 的上下文中,但我首先重新熟悉了一个通用的 FSM 模拟器,并提供了以下代码:
; An FSM is a [List-of 1Transition]
; A 1Transition is a list of two items:
; (cons FSM-State (cons FSM-State '()))
; An FSM-State is a String that specifies a color
; data examples
(define fsm-traffic
'(("red" "green") ("green" "yellow") ("yellow" "red")))
; FSM FSM-State -> FSM-State
; matches the keys pressed by a player with the given FSM
(define (simulate state0 transitions)
(big-bang state0 ; FSM-State
[to-draw
(lambda (current)
(overlay (text current 12 "black")
(square 100 "solid" current)))]
[on-key
(lambda (current key-event)
(find transitions current))]))
; [X Y] [List-of [List X Y]] X -> Y
; finds the matching Y for the given X in alist
(define (find alist x)
(local ((define fm (assoc x alist)))
(if (cons? fm) (second fm) (error "not found"))))
那么问题表述如下:
重新制定 1Transition 的数据定义,以便可以将转换限制为某些击键。尝试制定变化,以便在find
没有变化的情况下继续工作。您还需要进行哪些更改才能使完整的程序正常运行?设计配方的哪一部分提供了答案?原始练习陈述见练习 229。
练习 229 引入了一个结构类型定义来跟踪状态和转换,但是由于问题陈述要求我留在提供的find
函数内,我很难想出一个类似的结构类型定义。相反,我想出了以下数据定义:
; An FSM is a [List-of Transition]
; A Transition is a two-item list of the following form:
; (cons FSM-State (cons (cons KeyEvent (cons FSM-State '()))'()))
; data example
(define fsm-traffic (list (list "red" (list "r" "green"))
(list "green" (list "g" "yellow"))
(list "yellow" (list "y" "red"))))
因此调用(find fsm-traffic "green")
I get(list "g" "yellow")
我已将on-key
子句修改如下:
(lambda (current key-event)
(if (string=? key-event (first (first (rest (first transitions)))))
(second (find transitions current))
(error "invalid input")))
现在,如果我启动程序,(simulate "red" fsm-traffic)
State0 被渲染,如果我按“r”,它会进入“绿色”FSM-State,但它不会接受“g”进入下一个状态,依此类推。
如果我开始这个世界程序,(simulate "yellow" fsm-traffic)
那么 FSM 状态“黄色”会被渲染,但它不会转换到任何其他状态(该error
子句被激活);同样以“绿色”为起始状态。
我的预感是,由于我fsm-traffic
首先定义了“红色”状态,因此它接受其输入以转换为“绿色”,但由于其他状态没有发生同样的情况,因此big-bang
不会“处理”transitions
参数正确。但我只是不知道如何解决这个问题。我也不知道从我的数据定义开始我是否出错了。
预先感谢您帮助我。
PD 请让我知道我是否遵守了在 stackoverflow 上发帖的规则(这是我的第一篇文章 :)。