;;; ;;; merge(?) sort for general purpose: ;;; ================================== ;;; ;;; (sort predicate list-to-be-sorted to-sort-in-list) ---> sorted-list ;;; ;;; where ;;; ;;; predicate : (lambda (a b) ...) with a x b ---> {#t, #f} ;;; e.g. (lambda (a b) (> a b)) ;;; list-to-be-sorted : e.g. '(4 2 5 1 3) ;;; to-sort-in-list : e.g. '(6) ;;; ;;; will produce the result '(6 5 4 3 2 1). ;;; (define (sort pred todo done) (if (null? todo) done (sort pred (cdr todo) (insert pred (car todo) done)))) (define (insert pred item ls) (if (or (null? ls) (pred item (car ls))) (cons item ls) (cons (car ls) (insert pred item (cdr ls))))) (define-enumerated-type color :color is-color? the-colors color-name color-index (white grey black)) ;;; ;;; DFS: ;;; ==== ;;; ;;; (make-dfs node-name adjacencies ignored-data) ---> #{:dfs} ;;; ;;; node-name : "this is a node name" ;;; adjacencies : (list "another node name" "no node name") ;;; ignored-data : "anything you need in each node, eg. a long list..." ;;; ;;; (dfs->list node) ---> '(node-name adjacencies ignored-data) ;;; ;;; node : #{:dfs} ;;; ;;; (dfs-name node) ---> node-name ;;; (dfs-adjacencies node) ---> adjacencies ;;; (dfs-color node) ---> #{:color} ;;; (dfs-ftime node) ---> finishing-time ;;; (dfs-ignored node) ---> ignored-data ;;; (define-record-type :dfs (really-make-dfs name adjacencies color ftime ignored) is-dfs? (name dfs-name) (adjacencies dfs-adjacencies) ;; color (white by default) (color dfs-color) ;; finishing-time (ftime dfs-ftime) ;; put in there what you like (ignored dfs-ignored)) (define (make-dfs node-name adjacencies ignored-data) (really-make-dfs node-name adjacencies (color white) 0 ignored-data)) (define (dfs->list dfs-node) (list (dfs-name dfs-node) (dfs-adjacencies dfs-node) (dfs-ignored dfs-node))) (define (resolve-adj pred adj dag) (find (lambda (candidate) (pred (dfs-name candidate) adj)) dag)) (define (replace-node dag old new) (let ((new-dag (delete old dag))) (cons new new-dag))) (define (paint-node node color) (let ((name (dfs-name node)) (adjs (dfs-adjacencies node)) (time (dfs-ftime node)) (ignored (dfs-ignored node))) (really-make-dfs name adjs color time ignored))) (define (set-ftime node ftime) (let ((name (dfs-name node)) (adjs (dfs-adjacencies node)) (color (dfs-color node)) (ignored (dfs-ignored node))) (really-make-dfs name adjs color ftime ignored))) ;;; ;;; DEPTH FIRST SEARCH: ;;; =================== ;;; ;;; (dfs dag) ---> sorted-dag ;;; (dfs dag pred auto-leafs? create-leaf) ---> sorted-dag ;;; ;;; where ;;; ;;; dag : '(#{:dfs} ...) ; representation of a given ;;; directed acyclic graph) ;;; pred : (pred adj-id node-id) ---> #t (if adj-identifier ;;; and node-identifier are equal) or #f ;;; ;;; auto-leafs? : #t (by default) or #f ;;; if auto-leafs? is set to #f then it is an error ;;; that an adjacency is unresolveable in the list of ;;; all node-names. if auto-leafs? is enabled then ;;; every adjacency which is unresolveable in the list ;;; of all node-names is assumed to point to a leaf. ;;; this leaf is then created automatically by ;;; executing the function create-leaf. ;;; ;;; create-leaf : (create-leaf unresolved-adjacency-identifier) ---> #{:dfs} ;;; create-leaf is a function which is called with the ;;; unresolved adjacency identifier. By default, this ;;; argument is function returning a leaf named with ;;; the unresolved adjacency identifier, with no ;;; adjacencies, and ignored-data set to #f. This ;;; leaf, created by create-leaf, doesn't really have ;;; to be a leaf; it can be a node as well. Maybe this ;;; introduces new cyclic dependency problems; not sure. ;;; ;;; sorted-dag : the sorted dag ;;; (define (dfs dag . maybe-args) (let-optionals maybe-args ((pred string=?) (auto-leafs? #t) (create-leaf (lambda (unresolved-adj) (make-dfs unresolved-adj '() #f)))) (let ((ftime