diff --git a/utils-tests.rkt b/utils-tests.rkt index eec26d4..593ada8 100644 --- a/utils-tests.rkt +++ b/utils-tests.rkt @@ -68,7 +68,11 @@ [dbl (λ (x) (let ([x-str (symbol->string x)]) (string->symbol (string-append x-str x-str))))] [new-gr1 (update-vertices/unweighted gr1 dbl)] - [new-gr2 (update-vertices/unweighted gr2 dbl)]) + [new-gr2 (update-vertices/unweighted gr2 dbl)] + [new-gr1-ug (update-graph gr1 #:v-func dbl)] + [new-gr2-ug (update-graph gr2 #:v-func dbl)] + [gr3 (weighted-graph/directed '((10 a b) (11 b c)))] + [new-gr3 (update-graph gr3 #:v-func dbl #:e-func (λ (x) (* 2 x)))]) (check-false (has-vertex? new-gr1 'a)) (check-true (has-vertex? new-gr1 'aa)) (check-false (has-vertex? new-gr1 'b)) @@ -81,4 +85,25 @@ (check-true (has-edge? new-gr2 'aa 'bb)) (check-true (has-edge? new-gr2 'bb 'aa)) (check-true (has-edge? new-gr2 'bb 'cc)) - (check-true (has-edge? new-gr2 'cc 'bb)))) + (check-true (has-edge? new-gr2 'cc 'bb)) + + (check-false (has-vertex? new-gr1-ug 'a)) + (check-true (has-vertex? new-gr1-ug 'aa)) + (check-false (has-vertex? new-gr1-ug 'b)) + (check-true (has-vertex? new-gr1-ug 'bb)) + (check-false (has-vertex? new-gr1-ug 'c)) + (check-true (has-vertex? new-gr1-ug 'cc)) + (check-true (has-edge? new-gr1-ug 'aa 'bb)) + (check-true (has-edge? new-gr1-ug 'bb 'cc)) + + (check-true (has-edge? new-gr2-ug 'aa 'bb)) + (check-true (has-edge? new-gr2-ug 'bb 'aa)) + (check-true (has-edge? new-gr2-ug 'bb 'cc)) + (check-true (has-edge? new-gr2-ug 'cc 'bb)) + + (check-true (has-edge? new-gr3 'aa 'bb)) + (check-false (has-edge? new-gr3 'bb 'aa)) + (check-true (has-edge? new-gr3 'bb 'cc)) + (check-false (has-edge? new-gr3 'cc 'bb)) + (check-equal? (edge-weight new-gr3 'aa 'bb) 20) + (check-equal? (edge-weight new-gr3 'bb 'cc) 22))) diff --git a/utils.rkt b/utils.rkt index 003a454..90ea98b 100644 --- a/utils.rkt +++ b/utils.rkt @@ -19,7 +19,11 @@ [unstringify-pairs (-> (listof (general-pair/c string? any/c)) (listof (general-pair/c symbol? any/c)))] [read-org-variable-mapping (-> string? variable-mapping?)] - [update-vertices/unweighted (-> graph? (-> any/c any/c) graph?)]) + [update-vertices/unweighted (-> graph? (-> any/c any/c) graph?)] + [update-graph (->* (graph?) + (#:v-func (-> any/c any/c) + #:e-func (-> any/c any/c)) + graph?)]) ;; Contracts (contract-out [variable-mapping? contract?] [string-variable-mapping? contract?] @@ -228,3 +232,20 @@ (for/list ([e (in-edges gr)]) (match-let ([(list u v) e]) (list (func u) (func v)))))) + +;;; Given a graph, apply a transformation v-func to every vertex label +;;; and, if the graph is a weighted graph, the transformation e-func +;;; to every edge label. Both transformations default to identity +;;; functions. If gr is an weighted graph, the result is a weighted +;;; graph. If gr is an unweighted graph, the result is an unweighted +;;; graph. +(define (update-graph gr #:v-func [v-func identity] #:e-func [e-func identity]) + (let ([edges (for/list ([e (in-edges gr)]) + (match-let ([(list u v) e]) + (if (unweighted-graph? gr) + (list (v-func u) (v-func v)) + (list (e-func (edge-weight gr u v)) + (v-func u) (v-func v)))))]) + (if (unweighted-graph? gr) + (unweighted-graph/directed edges) + (weighted-graph/directed edges))))