📄 conform.scm
字号:
((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 + -