⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 conform.scm

📁 Scheme跨平台编译器
💻 SCM
📖 第 1 页 / 共 2 页
字号:
        ((memq to-node (red-edges from-node)) #t)        (else #f)));; SIGNATURE; Return signature (i.e. <arg, res>) given an operation and a node(define sig  (let ((none-comma-any (cons none-node any-node)))    (lambda (op node)                   ; Returns (arg, res)      (let ((the-edge (lookup-op op node)))        (if (not (null? the-edge))            (cons (arg-node the-edge) (res-node the-edge))            none-comma-any))))); Selectors from signature(define (arg pair) (car pair))(define (res pair) (cdr pair));; CONFORMITY(define (conforms? t1 t2)  (define nodes-with-red-edges-out '())  (define (add-red-edge! from-node to-node)    (set-red-edges! from-node (adjoin to-node (red-edges from-node)))    (set! nodes-with-red-edges-out          (adjoin from-node nodes-with-red-edges-out)))  (define (greenify-red-edges! from-node)    (set-green-edges! from-node                      (append (red-edges from-node) (green-edges from-node)))    (set-red-edges! from-node '()))  (define (delete-red-edges! from-node)    (set-red-edges! from-node '()))  (define (does-conform t1 t2)    (cond ((or (none-node? t1) (any-node? t2)) #t)          ((or (any-node? t1) (none-node? t2)) #f)          ((green-edge? t1 t2) #t)          ((red-edge? t1 t2) #t)          (else           (add-red-edge! t1 t2)           (let loop ((blues (blue-edges t2)))             (if (null? blues)                 #t                 (let* ((current-edge (car blues))                        (phi (operation current-edge)))                   (and (has-op? phi t1)                        (does-conform                         (res (sig phi t1))                         (res (sig phi t2)))                        (does-conform                         (arg (sig phi t2))                         (arg (sig phi t1)))                        (loop (cdr blues)))))))))  (let ((result (does-conform t1 t2)))    (for-each (if result greenify-red-edges! delete-red-edges!)              nodes-with-red-edges-out)    result))(define (equivalent? a b)  (and (conforms? a b) (conforms? b a)));; EQUIVALENCE CLASSIFICATION; Given a list of nodes, return a list of equivalence classes(define (classify nodes)  (let node-loop ((classes '())                  (nodes nodes))    (if (null? nodes)        (map (lambda (class)               (sort-list class                          (lambda (node1 node2)                            (< (string-length (name node1))                               (string-length (name node2))))))             classes)        (let ((this-node (car nodes)))          (define (add-node classes)            (cond ((null? classes) (list (list this-node)))                  ((equivalent? this-node (caar classes))                   (cons (cons this-node (car classes))                         (cdr classes)))                  (else (cons (car classes)                              (add-node (cdr classes))))))          (node-loop (add-node classes)                     (cdr nodes)))))); Given a node N and a classified set of nodes,; find the canonical member corresponding to N(define (find-canonical-representative element classification)  (let loop ((classes classification))    (cond ((null? classes) (fatal-error "Can't classify" element))           ((memq element (car classes)) (car (car classes)))          (else (loop (cdr classes)))))); Reduce a graph by taking only one member of each equivalence ; class and canonicalizing all outbound pointers(define (reduce graph)  (let ((classes (classify (graph-nodes graph))))    (canonicalize-graph graph classes)));; TWO DIMENSIONAL TABLES(define (make-empty-table) (list 'TABLE))(define (lookup table x y)  (let ((one (assq x (cdr table))))    (if one        (let ((two (assq y (cdr one))))          (if two (cdr two) #f))        #f)))(define (insert! table x y value)  (define (make-singleton-table x y)    (list (cons x y)))  (let ((one (assq x (cdr table))))    (if one        (set-cdr! one (cons (cons y value) (cdr one)))        (set-cdr! table (cons (cons x (make-singleton-table y value))                              (cdr table))))));; MEET/JOIN ; These update the graph when computing the node for node1*node2(define (blue-edge-operate arg-fn res-fn graph op sig1 sig2)  (make-blue-edge op                  (arg-fn graph (arg sig1) (arg sig2))                  (res-fn graph (res sig1) (res sig2))))(define (meet graph node1 node2)  (cond ((eq? node1 node2) node1)        ((or (any-node? node1) (any-node? node2)) any-node) ; canonicalize        ((none-node? node1) node2)        ((none-node? node2) node1)        ((lookup (already-met graph) node1 node2)) ; return it if found        ((conforms? node1 node2) node2)        ((conforms? node2 node1) node1)        (else         (let ((result                (make-node (string-append "(" (name node1) " ^ " (name node2) ")"))))           (add-graph-nodes! graph result)           (insert! (already-met graph) node1 node2 result)           (set-blue-edges! result             (map              (lambda (op)                (blue-edge-operate join meet graph op (sig op node1) (sig op node2)))              (intersect (map operation (blue-edges node1))                         (map operation (blue-edges node2)))))           result))))(define (join graph node1 node2)  (cond ((eq? node1 node2) node1)        ((any-node? node1) node2)        ((any-node? node2) node1)        ((or (none-node? node1) (none-node? node2)) none-node) ; canonicalize        ((lookup (already-joined graph) node1 node2)) ; return it if found        ((conforms? node1 node2) node1)        ((conforms? node2 node1) node2)        (else         (let ((result                (make-node (string-append "(" (name node1) " v " (name node2) ")"))))           (add-graph-nodes! graph result)           (insert! (already-joined graph) node1 node2 result)           (set-blue-edges! result             (map              (lambda (op)                (blue-edge-operate meet join graph op (sig op node1) (sig op node2)))              (union (map operation (blue-edges node1))                     (map operation (blue-edges node2)))))           result))));; MAKE A LATTICE FROM A GRAPH(define (make-lattice g print?)  (define (step g)    (let* ((copy (copy-graph g))           (nodes (graph-nodes copy)))      (for-each (lambda (first)                  (for-each (lambda (second)                              (meet copy first second) (join copy first second))                            nodes))                nodes)      copy))  (define (loop g count)    (if print? (display count))    (let ((lattice (step g)))      (if print? (begin (display " -> ") (display (length (graph-nodes lattice)))))      (let* ((new-g (reduce lattice))             (new-count (length (graph-nodes new-g))))        (if (= new-count count)            (begin              (if print? (newline))              new-g)            (begin              (if print? (begin (display " -> ") (display new-count) (newline)))              (loop new-g new-count))))))  (let ((graph         (apply make-graph                (adjoin any-node (adjoin none-node (graph-nodes (clean-graph g)))))))    (loop graph (length (graph-nodes graph)))));; DEBUG and TEST(define a '())(define b '())(define c '())(define d '())(define (setup)  (set! a (make-node 'a))  (set! b (make-node 'b))  (set-blue-edges! a (list (make-blue-edge 'phi any-node b)))  (set-blue-edges! b (list (make-blue-edge 'phi any-node a)                           (make-blue-edge 'theta any-node b)))  (set! c (make-node "c"))  (set! d (make-node "d"))  (set-blue-edges! c (list (make-blue-edge 'theta any-node b)))  (set-blue-edges! d (list (make-blue-edge 'phi any-node c)                           (make-blue-edge 'theta any-node d)))  '(made a b c d))(define (test)  (setup)  (map name       (graph-nodes (make-lattice (make-graph a b c d any-node none-node) #f))))(time (test))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -