📄 conform.scm
字号:
;;; CONFORM -- Type checker, written by Jim Miller.;;; Functional and unstable(define (sort-list obj pred) (define (loop l) (if (and (pair? l) (pair? (cdr l))) (split-list l '() '()) l)) (define (split-list l one two) (if (pair? l) (split-list (cdr l) two (cons (car l) one)) (merge (loop one) (loop two)))) (define (merge one two) (cond ((null? one) two) ((pred (car two) (car one)) (cons (car two) (merge (cdr two) one))) (else (cons (car one) (merge (cdr one) two))))) (loop obj));; SET OPERATIONS; (representation as lists with distinct elements)(define (adjoin element set) (if (memq element set) set (cons element set)))(define (eliminate element set) (cond ((null? set) set) ((eq? element (car set)) (cdr set)) (else (cons (car set) (eliminate element (cdr set))))))(define (intersect list1 list2) (let loop ((l list1)) (cond ((null? l) '()) ((memq (car l) list2) (cons (car l) (loop (cdr l)))) (else (loop (cdr l))))))(define (union list1 list2) (if (null? list1) list2 (union (cdr list1) (adjoin (car list1) list2))));; GRAPH NODES(define make-internal-node vector)(define (internal-node-name node) (vector-ref node 0))(define (internal-node-green-edges node) (vector-ref node 1))(define (internal-node-red-edges node) (vector-ref node 2))(define (internal-node-blue-edges node) (vector-ref node 3))(define (set-internal-node-name! node name) (vector-set! node 0 name))(define (set-internal-node-green-edges! node edges) (vector-set! node 1 edges))(define (set-internal-node-red-edges! node edges) (vector-set! node 2 edges))(define (set-internal-node-blue-edges! node edges) (vector-set! node 3 edges))(define (make-node name . blue-edges) ; User's constructor (let ((name (if (symbol? name) (symbol->string name) name)) (blue-edges (if (null? blue-edges) 'NOT-A-NODE-YET (car blue-edges)))) (make-internal-node name '() '() blue-edges)))(define (copy-node node) (make-internal-node (name node) '() '() (blue-edges node))); Selectors(define name internal-node-name)(define (make-edge-getter selector) (lambda (node) (if (or (none-node? node) (any-node? node)) (fatal-error "Can't get edges from the ANY or NONE nodes") (selector node))))(define red-edges (make-edge-getter internal-node-red-edges))(define green-edges (make-edge-getter internal-node-green-edges))(define blue-edges (make-edge-getter internal-node-blue-edges)); Mutators(define (make-edge-setter mutator!) (lambda (node value) (cond ((any-node? node) (fatal-error "Can't set edges from the ANY node")) ((none-node? node) 'OK) (else (mutator! node value)))))(define set-red-edges! (make-edge-setter set-internal-node-red-edges!))(define set-green-edges! (make-edge-setter set-internal-node-green-edges!))(define set-blue-edges! (make-edge-setter set-internal-node-blue-edges!));; BLUE EDGES(define make-blue-edge vector)(define (blue-edge-operation edge) (vector-ref edge 0))(define (blue-edge-arg-node edge) (vector-ref edge 1))(define (blue-edge-res-node edge) (vector-ref edge 2))(define (set-blue-edge-operation! edge value) (vector-set! edge 0 value))(define (set-blue-edge-arg-node! edge value) (vector-set! edge 1 value))(define (set-blue-edge-res-node! edge value) (vector-set! edge 2 value)); Selectors(define operation blue-edge-operation)(define arg-node blue-edge-arg-node)(define res-node blue-edge-res-node); Mutators(define set-arg-node! set-blue-edge-arg-node!)(define set-res-node! set-blue-edge-res-node!); Higher level operations on blue edges(define (lookup-op op node) (let loop ((edges (blue-edges node))) (cond ((null? edges) '()) ((eq? op (operation (car edges))) (car edges)) (else (loop (cdr edges))))))(define (has-op? op node) (not (null? (lookup-op op node))));; GRAPHS(define make-internal-graph vector)(define (internal-graph-nodes graph) (vector-ref graph 0))(define (internal-graph-already-met graph) (vector-ref graph 1))(define (internal-graph-already-joined graph) (vector-ref graph 2))(define (set-internal-graph-nodes! graph nodes) (vector-set! graph 0 nodes)); Constructor(define (make-graph . nodes) (make-internal-graph nodes (make-empty-table) (make-empty-table))); Selectors(define graph-nodes internal-graph-nodes)(define already-met internal-graph-already-met)(define already-joined internal-graph-already-joined); Higher level functions on graphs(define (add-graph-nodes! graph nodes) (set-internal-graph-nodes! graph (cons nodes (graph-nodes graph))))(define (copy-graph g) (define (copy-list l) (vector->list (list->vector l))) (make-internal-graph (copy-list (graph-nodes g)) (already-met g) (already-joined g)))(define (clean-graph g) (define (clean-node node) (if (not (or (any-node? node) (none-node? node))) (begin (set-green-edges! node '()) (set-red-edges! node '())))) (for-each clean-node (graph-nodes g)) g)(define (canonicalize-graph graph classes) (define (fix node) (define (fix-set object selector mutator) (mutator object (map (lambda (node) (find-canonical-representative node classes)) (selector object)))) (if (not (or (none-node? node) (any-node? node))) (begin (fix-set node green-edges set-green-edges!) (fix-set node red-edges set-red-edges!) (for-each (lambda (blue-edge) (set-arg-node! blue-edge (find-canonical-representative (arg-node blue-edge) classes)) (set-res-node! blue-edge (find-canonical-representative (res-node blue-edge) classes))) (blue-edges node)))) node) (define (fix-table table) (define (canonical? node) (eq? node (find-canonical-representative node classes))) (define (filter-and-fix predicate-fn update-fn list) (let loop ((list list)) (cond ((null? list) '()) ((predicate-fn (car list)) (cons (update-fn (car list)) (loop (cdr list)))) (else (loop (cdr list)))))) (define (fix-line line) (filter-and-fix (lambda (entry) (canonical? (car entry))) (lambda (entry) (cons (car entry) (find-canonical-representative (cdr entry) classes))) line)) (if (null? table) '() (cons (car table) (filter-and-fix (lambda (entry) (canonical? (car entry))) (lambda (entry) (cons (car entry) (fix-line (cdr entry)))) (cdr table))))) (make-internal-graph (map (lambda (class) (fix (car class))) classes) (fix-table (already-met graph)) (fix-table (already-joined graph))));; USEFUL NODES(define none-node (make-node 'none #t))(define (none-node? node) (eq? node none-node))(define any-node (make-node 'any '()))(define (any-node? node) (eq? node any-node));; COLORED EDGE TESTS(define (green-edge? from-node to-node) (cond ((any-node? from-node) #f) ((none-node? from-node) #t) ((memq to-node (green-edges from-node)) #t) (else #f)))(define (red-edge? from-node to-node) (cond ((any-node? from-node) #f) ((none-node? from-node) #t)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -