Scheme sicp模式匹配-复合?
我正在看SICP的视频讲座。目前我从事4A模式匹配和基于规则的替换 到目前为止,我发现Matcher和实例化器都很简单。但是我不能让我的头脑简单化Scheme sicp模式匹配-复合?,scheme,racket,sicp,Scheme,Racket,Sicp,我正在看SICP的视频讲座。目前我从事4A模式匹配和基于规则的替换 到目前为止,我发现Matcher和实例化器都很简单。但是我不能让我的头脑简单化 (define (simplifier the-rules) (define (simplify-exp exp) (try-rules (if (compound? exp) (map simplify-exp exp) exp))) (define (tr
(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)
我在这里看到了关于这个主题的另一个问题,它定义了
复合物?
,即成对物?
。但是,然后什么简化exp
馈送到try rules
?解决了这个问题。这些规则将按照承诺应用于每个节点。你可以投票删除该问题。但是,我想补充一些关于我是如何使它工作的解释
我更改了一些代码。原始代码似乎在编写时考虑了其他一些语义。我在自己做决定的地方添加了一些评论
#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))))
然后呢?你知道吗?它能用。
:)
你用的是球拍还是诡计?在Scheme和许多Lisp中,空列表是一个atom,因此((null?s)())
在((atom?s)
之后是冗余的。问题标记为,但您的代码以#lang racket
开头。它们是相似的语言,但它们不一样。@JoshuaTaylor,我在用DrRacket。我觉得麻省理工学院的计划不太好。谢谢你的评论。一切都清楚了。事实上,我定义了atom?
,但我认为'()
不应该是一个atom。@JoshuaTaylor Racket是每个标记wiki的一个方案。它也是一种口齿不清的语言。@benrudgers Racket是一种与Scheme有许多相似之处并从Scheme继承而来的语言,但并不是所有适用于Scheme的语言都适用于Racket。不同的Lisp也有不同之处。例如,在许多传统的Lisp(包括Common Lisp)中,空列表与符号NIL相同,是假值。在Scheme中,只有实际的布尔值#f为false。OP提到“原始代码似乎是在考虑其他语义的情况下编写的”,对代码所做的更改之一是在(null?s)
之前的条件中添加(atom?s)
。在许多Lisp中,@benrudgers…(可能包括Racket和Scheme;我不确定OP的所有更改是否都是必要的)(null?s)
将是多余的,因为空列表是一个原子。似乎有一种趋势,人们(可能是因为教练)说他们在使用诡计,但实际上在使用球拍。很多代码可以在这两个地方工作,但不是所有的代码。例如,Racket现在默认使用不可变的cons单元格,因此在Scheme in中您可以(设置car!(cons a b)c)
,但在Racket中您不能。我不认为问OP实际上使用的是什么编程语言是不合理的……你是在使用racket还是scheme?问题标记为,但您的代码以#lang racket
开头。它们是相似的语言,但它们不一样。在Scheme和许多Lisp中,空列表是一个atom,因此((null?s)())
(您在答案中添加的内容)在((atom?s)s)
之后是多余的。