dfs.scm: depth-first-search/sort algorithm, work in progress...\n to-rule-set.scm: calls dfs, work in progress...
This commit is contained in:
		
							parent
							
								
									afb60fbb74
								
							
						
					
					
						commit
						5b462916b1
					
				| 
						 | 
					@ -0,0 +1,100 @@
 | 
				
			||||||
 | 
					(define-enumerated-type color :color
 | 
				
			||||||
 | 
					  is-color?
 | 
				
			||||||
 | 
					  the-color
 | 
				
			||||||
 | 
					  color-name
 | 
				
			||||||
 | 
					  color-index
 | 
				
			||||||
 | 
					  (white grey black))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define-record-type :dfs
 | 
				
			||||||
 | 
					  (really-make-dfs node adjacencies color predec dtime ftime ignored-data)
 | 
				
			||||||
 | 
					  is-dfs?
 | 
				
			||||||
 | 
					  (node dfs-node)
 | 
				
			||||||
 | 
					  (adjacencies dfs-adjacencies)
 | 
				
			||||||
 | 
					  ;; color (white by default)
 | 
				
			||||||
 | 
					  (color dfs-color)
 | 
				
			||||||
 | 
					  ;; predecessor (is #f by default)
 | 
				
			||||||
 | 
					  (predec dfs-predec)
 | 
				
			||||||
 | 
					  ;; discovery-time
 | 
				
			||||||
 | 
					  (dtime dfs-dtime)
 | 
				
			||||||
 | 
					  ;; finishing-time
 | 
				
			||||||
 | 
					  (ftime dfs-ftime)
 | 
				
			||||||
 | 
					  ;; thie is for all node specific information 
 | 
				
			||||||
 | 
					  ;; and is ignore by the dfs algorithm
 | 
				
			||||||
 | 
					  ;; put in there what you like
 | 
				
			||||||
 | 
					  (ignored-data dfs-ignored-data))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (make-dfs node adjacencies ignored-data)
 | 
				
			||||||
 | 
					  (really-make-dfs node adjacencies (color white) 0 0 #f ignored-data))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (dfs->list dfs)
 | 
				
			||||||
 | 
					  (list (dfs-node dfs) (dfs-adjacencies dfs) (dfs-ignored-data dfs)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (dfs-timer ch)
 | 
				
			||||||
 | 
					  (spawn
 | 
				
			||||||
 | 
					    (lambda ()
 | 
				
			||||||
 | 
					      (let timer-loop ((current-time 0))
 | 
				
			||||||
 | 
						(cml-sync-ch/receive ch)
 | 
				
			||||||
 | 
						(cml-sync-ch/send ch current-time)
 | 
				
			||||||
 | 
						(timer-loop (+ current-time 1))))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (dfs-time ch)
 | 
				
			||||||
 | 
					  (cml-sync-ch/send ch 'get-time)
 | 
				
			||||||
 | 
					  (cml-sync-ch/receive ch))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (dfs-lookup-adjs dag adj)
 | 
				
			||||||
 | 
					  (let ((maybe-rc ))
 | 
				
			||||||
 | 
					    (if maybe-rc maybe-rc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (dfs-visit dag node time-ch)
 | 
				
			||||||
 | 
					  (set! (dfs-color node) (color grey))
 | 
				
			||||||
 | 
					  (set! (dfs-dtime node) (dfs-time time-ch))
 | 
				
			||||||
 | 
					  (for-each (lambda (adj)
 | 
				
			||||||
 | 
						      (cond 
 | 
				
			||||||
 | 
						       ((eq? (dfs-color adj) (color white))
 | 
				
			||||||
 | 
							(begin 
 | 
				
			||||||
 | 
							  (set! (dfs-predecessor adj) node)
 | 
				
			||||||
 | 
							  (dfs-visit adj time-ch)))
 | 
				
			||||||
 | 
						       ;; 
 | 
				
			||||||
 | 
						       ;; ((eq? (dfs-color adj) (color black))
 | 
				
			||||||
 | 
						       ;; "already been here")
 | 
				
			||||||
 | 
						       ;; 
 | 
				
			||||||
 | 
						       ((eq? (dfs-color adj) (color grey))
 | 
				
			||||||
 | 
							(error "dfs-visit: cycle detected!"))))
 | 
				
			||||||
 | 
						    ;; this should be the list of all adjacency-nodes
 | 
				
			||||||
 | 
						    ;; this is done by map over all adjacencies
 | 
				
			||||||
 | 
						    ;; lookup each adj in dag, check if its node-name is adj
 | 
				
			||||||
 | 
						    (map (lambda (adj) 
 | 
				
			||||||
 | 
							   (find (lambda (candidate) 
 | 
				
			||||||
 | 
								   (eq? (dfs-node candidate) adj))
 | 
				
			||||||
 | 
								 dag))
 | 
				
			||||||
 | 
							 (dfs-adjs node)))
 | 
				
			||||||
 | 
					  (set! (dfs-color node) (color black))
 | 
				
			||||||
 | 
					  (set! (dfs-ftime node) (dfs-time time-ch)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					;;; this is the depth first search algorithm
 | 
				
			||||||
 | 
					;;; dag is a list of nodes of record-type dfs 
 | 
				
			||||||
 | 
					(define (dfs dag)
 | 
				
			||||||
 | 
					  (let* ((time-ch (cml-sync-ch/make-channel))
 | 
				
			||||||
 | 
						 (start-timer (dfs-timer time-ch)))
 | 
				
			||||||
 | 
					    (if (not (null? dag))
 | 
				
			||||||
 | 
						(begin
 | 
				
			||||||
 | 
						  (let visit-each-node ((current-node (car dag))
 | 
				
			||||||
 | 
									(nodes-to-do (cdr dag)))
 | 
				
			||||||
 | 
						    (if (eq? (dfs-color current-node) (color white))
 | 
				
			||||||
 | 
							(dfs-visit dag current-node time-ch))
 | 
				
			||||||
 | 
						    (if (not (null? nodes-to-do))
 | 
				
			||||||
 | 
							(visit-each-node (car nodes-to-do) (cdr nodes-to-do))))
 | 
				
			||||||
 | 
						  ;; now sort field (dfs-ftime node) in descendent order
 | 
				
			||||||
 | 
						  ...
 | 
				
			||||||
 | 
						  ))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (dfs-sort-insert pred item queue)
 | 
				
			||||||
 | 
					  (cond 
 | 
				
			||||||
 | 
					   ((null? queue) (cons item))
 | 
				
			||||||
 | 
					   ((not (pred item (car queue))) (cons item queue))
 | 
				
			||||||
 | 
					   (else (dfs-sort-insert item (cdr queue)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (dfs-sort pred todo done)
 | 
				
			||||||
 | 
					  (if (null? todo)
 | 
				
			||||||
 | 
					      done
 | 
				
			||||||
 | 
					      (dfs-sort pred (cdr todo) (dfs-sort-insert pred (car todo) done))))
 | 
				
			||||||
							
								
								
									
										106
									
								
								to-rule-set.scm
								
								
								
								
							
							
						
						
									
										106
									
								
								to-rule-set.scm
								
								
								
								
							| 
						 | 
					@ -1,71 +1,45 @@
 | 
				
			||||||
(define-record-type :rc-set
 | 
					(define (rcs->dag rcs)
 | 
				
			||||||
  (make-rc-set rule-candidates fname-rule-table rule-set)
 | 
					  (map (lambda (rc)
 | 
				
			||||||
  is-rc-set?
 | 
						 (make-dfs (car rc) (cadr rc) (caddr rc) (cadddr rc)))
 | 
				
			||||||
  (rule-candidates rc-set-rule-candidates)
 | 
					       rcs))
 | 
				
			||||||
  (fname-rule-table rc-set-fname-rule-table)
 | 
					 | 
				
			||||||
  (rule-set rc-set-rule-set))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-enumerated-type color :color
 | 
					(define (dag->rcs dag)
 | 
				
			||||||
  is-color?
 | 
					  (map (lambda (node)
 | 
				
			||||||
  the-color
 | 
						 (let* ((ls (dfs->list node))
 | 
				
			||||||
  color-name
 | 
							(target (car ls))
 | 
				
			||||||
  color-index
 | 
							(prereqs (cadr ls))
 | 
				
			||||||
  (white grey black))
 | 
							(wants-build? (caddr ls))
 | 
				
			||||||
 | 
							(build-func (cdddr ls)))
 | 
				
			||||||
 | 
						   (list target prereqs wants-build? build-func)))
 | 
				
			||||||
 | 
					       dag))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-record-type :dfs-data
 | 
					(define (lookup-rc rcs rc)
 | 
				
			||||||
  (make-dfs-data rc color discovery-time finishing-time predecessor)
 | 
					  (let ((maybe-rc (find (lambda (current) 
 | 
				
			||||||
  is-dfs-data?
 | 
								  (eq? (car rc) (car current))) 
 | 
				
			||||||
  (rc dfs-data-rc)
 | 
								rcs)))
 | 
				
			||||||
  (color dfs-data-color)
 | 
					    (if maybe-rc maybe-rc (error "lookup-rc: rc not found."))))
 | 
				
			||||||
  (discovery-time dfs-data-discovery-time)
 | 
					 | 
				
			||||||
  (finishing-time dfs-data-finishing-time)
 | 
					 | 
				
			||||||
  (predecessor dfs-data-predecessor))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (dfs-timer ch)
 | 
					(define (rcs->rules rcs)
 | 
				
			||||||
  (spawn
 | 
					  (let ((sorted-rcs (dag->rcs (dfs (rcs->dag rcs)))))
 | 
				
			||||||
    (lambda ()
 | 
					    (map (lambda (rc) 
 | 
				
			||||||
      (let timer-loop ((current-time 0))
 | 
						   (let* ((target (car rc))
 | 
				
			||||||
	(cml-sync-ch/receive ch)
 | 
							  (prereqs (cadr rc))
 | 
				
			||||||
	(cml-sync-ch/send ch current-time)
 | 
							  (wants-build? (caddr rc))
 | 
				
			||||||
	(timer-loop (+ current-time 1))))))
 | 
							  (build-func (cdddr rc))
 | 
				
			||||||
 | 
							  (prereq-rcs (map (lambda (p) 
 | 
				
			||||||
 | 
									     (lookup-rc sorted-rcs p))
 | 
				
			||||||
 | 
									   prereqs))
 | 
				
			||||||
 | 
							  (rule (make-rule prereq-rcs wants-build? build-func)))
 | 
				
			||||||
 | 
						     (cons target rule)))
 | 
				
			||||||
 | 
						 rcs)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (dfs-time ch)
 | 
					(define (rules->rule-set rules)
 | 
				
			||||||
  (cml-sync-ch/send ch 'get-time)
 | 
					  (let for-each-rule ((current-rule (if (null? rules) '() (car rules)))
 | 
				
			||||||
  (cml-sync-ch/receive ch))
 | 
							      (rules-to-do (if (null? rules) '() (cdr rules)))
 | 
				
			||||||
 | 
							      (rule-set (make-empty-rule-set)))
 | 
				
			||||||
 | 
					    (if (not (null? rules-to-do))
 | 
				
			||||||
 | 
						(for-each-rule (car rules-to-do) 
 | 
				
			||||||
 | 
							       (cdr rules-to-do)
 | 
				
			||||||
 | 
							       (rule-set-add current-rule rule-set)))
 | 
				
			||||||
 | 
					    rule-set))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (dfs-lookup-prereq rc-set prereq)
 | 
					 | 
				
			||||||
  (let ((maybe-rc (assoc prereq (rc-set-rule-candidates rc-set))))
 | 
					 | 
				
			||||||
    (if maybe-rc (car 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(define (dfs-visit node time-ch)
 | 
					 | 
				
			||||||
  (set! (dfs-data-color node) (color grey))
 | 
					 | 
				
			||||||
  (set! (dfs-data-discovery-time node) (dfs-time time-ch))
 | 
					 | 
				
			||||||
  (for-each (lambda (prereq)
 | 
					 | 
				
			||||||
	      (if (eq? (dfs-data-color prereq) (color white))
 | 
					 | 
				
			||||||
		  (begin 
 | 
					 | 
				
			||||||
		    (set! (dfs-data-predecessor prereq) node)
 | 
					 | 
				
			||||||
		    (dfs-visit prereq time))))
 | 
					 | 
				
			||||||
	    ;; rule-candidates:
 | 
					 | 
				
			||||||
	    ;; ((target . (prereqs wants-build? build-func)) ...)
 | 
					 | 
				
			||||||
	    ;; lookup the node for prereq
 | 
					 | 
				
			||||||
	    (map dfs-lookup-prereq
 | 
					 | 
				
			||||||
		 (cadr (rc-set-rule-candidates (dfs-data-rc node))))
 | 
					 | 
				
			||||||
  (set! (dfs-data-color node) (color black))
 | 
					 | 
				
			||||||
  (set! (dfs-data-discovery-time node) (dfs-time time-ch))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;; this is the depth first search algorithm
 | 
					 | 
				
			||||||
(define (dfs rc-set)
 | 
					 | 
				
			||||||
  (let* ((rule-candidates (rc-set-rule-candidates rc-set))
 | 
					 | 
				
			||||||
	 (fname-rule-table (rc-set-fname-rule-table rc-set))
 | 
					 | 
				
			||||||
	 (rule-set (rc-set-rule-set rc-set))
 | 
					 | 
				
			||||||
	 (rc-dfs-data (map (lambda (rc) (make-dfs-data rc (color white) 0 0 #f))
 | 
					 | 
				
			||||||
			   rule-candidates))
 | 
					 | 
				
			||||||
	 (time 0))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    (
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    (if (not (null? rc-dfs-data))
 | 
					 | 
				
			||||||
	(let visit-each-rc ((current-rc (car rc-dfs-data))
 | 
					 | 
				
			||||||
			    (to-visit-rcs (cdr rc-dfs-data)))
 | 
					 | 
				
			||||||
	  (if (eq? (color-name (dfs-data-color dfs-data)) (color white))
 | 
					 | 
				
			||||||
	      (begin
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue