sicp模式匹配 - 复合?

时间:2015-01-27 03:18:03

标签: scheme racket sicp

我正在观看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-exptry-rules提供了什么?

1 个答案:

答案 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))))

和?你知道吗?它有效:)