git @ Cat's Eye Technologies Arboretuum / rel_1_0_2008_0304 src / tree-rewrite.scm
rel_1_0_2008_0304

Tree @rel_1_0_2008_0304 (Download .tar.gz)

tree-rewrite.scm @rel_1_0_2008_0304raw · history · blame

;
; Bottom-Up Tree-Rewriting (Term-Rewriting)
; Chris Pressey, sometime late January 2006
;

; Copyright (c)2008 Cat's Eye Technologies.  All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions
; are met:
;
; 1. Redistributions of source code must retain the above copyright
;    notices, this list of conditions and the following disclaimer.
; 2. Redistributions in binary form must reproduce the above copyright
;    notices, this list of conditions, and the following disclaimer in
;    the documentation and/or other materials provided with the
;    distribution.
; 3. Neither the names of the copyright holders nor the names of their
;    contributors may be used to endorse or promote products derived
;    from this software without specific prior written permission. 
;
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
; ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES INCLUDING, BUT NOT
; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
; FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
; COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
; CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
; POSSIBILITY OF SUCH DAMAGE.

;
; Try unifying the pattern part of the given rule with the given term;
; if it matches, return a rewritten term based on the unifier and the
; replacement part of the rule; otherwise return #f.
;
(define rewrite-single-term
  (lambda (term rules)
    (cond
      ((null? rules)
        #f)
      (else
        (let* ((rule        (car rules))
               (pattern     (car rule))
               (replacement (cdr rule))
               (unifier     (unify term pattern '())))
          (cond
            (unifier
              (expand-vars replacement unifier))
            (else
              (rewrite-single-term term (cdr rules)))))))))

;
; Rewrite the given term recursively, with the given set of rules,
; from the bottom up (preorder traversal.)  Returns the rewritten
; term if successful, #f if not.  rules is a list of pat-repl pairs.
;
(define rewrite-bottom-up
  (lambda (term rules)
    (cond
      ((list? term)
        (let loop ((subterms term)    ; first try to unify with each child
                   (acc      '()))    ; keep track of subterms we've seen
          (cond
            ((null? subterms)         ; no more children, try rewrite.
              (rewrite-single-term term rules))
            (else
              (let* ((subterm     (car subterms))
                     (rest        (cdr subterms))
                     (new-subterm (rewrite-bottom-up subterm rules)))
                (cond
                  (new-subterm        ; this child succeeded. incorporate it
                    (let* ((front        (reverse acc))
                           (back         (cons new-subterm rest))
                           (spliced-term (append front back)))
                      spliced-term))
                  (else               ; this child failed, try next one
                    (loop (cdr subterms) (cons subterm acc)))))))))
    (else
      (rewrite-single-term term rules)))))

;
; Repeatedly rewrite the given term with the given rules until it
; is reduced into a normal form (if one exists for these rules.)
; Return the reduced term.
;
(define reduce-term
  (lambda (term rules)
    (let* ((new-term (rewrite-bottom-up term rules)))
      (cond
        (new-term
          (reduce-term new-term rules))
        (else
          term)))))