我正在观看SICP的视频讲座。目前我正在进行4A模式匹配和基于规则的替换。
到目前为止,我发现Matcher和Instantiator很容易。但是我无法理解简化器。
(define (simplifier the-rules)
(define (simplify-exp exp)
(try-rules (if (compound? exp)
(map simplify-exp exp)
exp)))
(define (try-rules exp)
(define (scan rules)
(if (null? rules)
exp
(let ((dict (match (pattern (car rules))
exp
(empty-dictionary))))
(if (eq? dict 'failed)
(scan (cdr rules))
(simplify-exp (instantiate (skeleton (car rules)) dict))))))
(scan the-rules))
simplify-exp)
我在这个主题上看到另一个问题,用compound?
来定义pair?
。但是,simplify-exp
向try-rules
提供了什么?
答案 0 :(得分:2)
想出来。规则将按照承诺应用于每个节点。您可以投票删除该问题。但是,我会就如何使其发挥作用添加一些解释。
我改变了一些代码。原始代码似乎与其他语义一起编写。我在自己做出决定的地方添加了一些评论。
#lang racket
;matcher
(define (match pat exp dict)
(cond ((eq? dict 'failed) 'failed)
;matched
((and (null? pat) (null? exp)) dict)
;so far matched, but no more
((or (null? pat) (null? exp)) 'failed)
((atom? pat)
(if (atom? exp)
(if (eq? pat exp)
dict
'failed)
'failed))
((pat-const? pat)
(if (constant? exp)
(extend-dict pat exp dict)
'failed))
((pat-variable? pat)
(if (variable? exp)
(extend-dict pat exp dict)
'failed))
((pat-exp? pat)
(extend-dict pat exp dict))
((atom? exp) 'failed)
(else
(match (cdr pat)
(cdr exp)
(match (car pat) (car exp) dict)))))
(define (pat-const? pat)
(eq? (car pat) '?c))
(define (pat-variable? pat)
(eq? (car pat) '?v))
(define (pat-exp? pat)
(eq? (car pat) '?))
(define constant? number?)
(define variable? symbol?)
;instantiator
(define (instantiate skeleton dict)
(define (loop s)
(cond ((atom? s) s)
;we cant run past the nil line
((null? s) '())
((skeleton-evaluation? s) (evaluate s dict))
(else
(cons (loop (car s)) (loop (cdr s))))))
(loop skeleton))
(define (skeleton-evaluation? s)
(eq? (car s) ':))
;made it simpler, no environment constant, sorry
(define (evaluate s dict)
(let ((data (lookup (cadr s) dict)))
(if (null? data)
(display "error in rules. mismatch")
(cadr data))))
;simplifier
(define (simplifier rules)
(define (simplify-exp exp)
(try-rules (if (list? exp)
(map simplify-exp exp)
exp)))
(define (try-rules exp)
(define (scan rule)
(if (null? rule)
exp
(let ((dict (match (pattern (car rule)) exp (empty-dict))))
(if (eq? dict 'failed)
(scan (cdr rule))
(simplify-exp (instantiate (skeleton (car rule)) dict))))))
(scan rules))
simplify-exp)
(define pattern car)
(define skeleton cadr)
;dictionary
(define (empty-dict)
'())
(define (extend-dict pat exp dict)
(let ((v (lookup (cadr pat) dict)))
(if (null? v)
(cons (list (cadr pat) exp) dict)
(if (eq? (cadr v) exp)
dict
'failed))))
(define (lookup s dict)
(cond ((null? dict) '())
((eq? (caar dict) s) (car dict))
(else (lookup s (cdr dict)))))
;extend racket
(define (atom? a)
(and (not (null? a)) (not (pair? a))))
和?你知道吗?它有效:)