Topological sorting
Authors: François Bobot
Topics: Graph Algorithms
Tools: Why3
see also the index (by topic, by tool, by reference, by year)
Topological sorting
Author: François Bobot (CEA)
theory Graph use export int.Int use set.Fset as S use map.Map as M (* the graph is defined by a set of vertices and a set of edges *) type vertex type graph function vertices graph: S.fset vertex function edges graph: S.fset (vertex , vertex) axiom edges_use_vertices: forall g:graph. forall x y:vertex. S.mem (x,y) (edges g) -> (S.mem x (vertices g) /\ S.mem y (vertices g)) function preds graph vertex: S.fset vertex
direct predecessors
axiom preds_def: forall g:graph. forall v:vertex. forall u:vertex. S.mem (u,v) (edges g) <-> S.mem u (preds g v) function succs graph vertex: S.fset vertex axiom succs_def: forall g:graph. forall v:vertex. forall u:vertex. S.mem (u,v) (edges g) <-> S.mem v (succs g u)
direct successors
type msort = M.map vertex int predicate sort (g: graph) (m:msort) = forall v:vertex. forall u:vertex. S.mem (u,v) (edges g) -> (M.get m u) < (M.get m v) end module ImpmapNoDom use map.Map use map.Const type key type t 'a = abstract { mutable contents: map key 'a } val function create (x: 'a): t 'a ensures { result.contents = const x } val function ([]) (m: t 'a) (k: key): 'a ensures { result = m.contents[k] } val ghost function ([<-]) (m: t 'a) (k: key) (v: 'a): t 'a ensures { result.contents = m.contents[k <- v] } val ([]<-) (m: t 'a) (k: key) (v: 'a): unit writes { m } ensures { m = (old m)[k <- v] } end module Static
static topological sorting by depth-first search
use ref.Ref use Graph use set.Fset as Fset clone set.SetImp as S with type elt = vertex clone set.SetApp as SA with type elt = vertex clone ImpmapNoDom with type key = vertex val ghost function defined_sort (m: t int): Fset.fset vertex ensures { forall v: vertex [Fset.mem v result]. Fset.mem v result <-> 0 <= m[v] } val get_preds (g: graph) (v: vertex): S.set ensures { result.S.to_fset = preds g v } val get_vertices (g: graph): S.set ensures { result.S.to_fset = vertices g } predicate partial_sort (g: graph) (m: t int) = forall v:vertex. forall u:vertex. Fset.mem (u,v) (edges g) -> 0 <= m[v] -> 0 <= m[u] < m[v] exception Cycle_found predicate inv (g: graph) (m: t int) (next: int) = Fset.subset (defined_sort m) (vertices g) && 0 <= next && partial_sort g m && forall v:vertex. Fset.mem v (defined_sort m) -> m[v] < next let rec dfs (g: graph) (v: vertex) (seen: SA.set) (values: t int) (next: ref int): unit requires { inv g values !next } requires { Fset.mem v (vertices g) } requires { Fset.subset seen.SA.to_fset (vertices g) } variant { Fset.cardinal (vertices g) - SA.cardinal seen } ensures { Fset.subset (defined_sort (old values)) (defined_sort values) } ensures { 0 <= values[v] <= !next} ensures { inv g values !next } ensures { forall x:vertex. SA.mem x seen -> old values[x] = values[x] } raises { Cycle_found -> true } = if SA.mem v seen then raise Cycle_found; if values[v] < 0 then begin let p = get_preds g v in let seen = SA.add v seen in while not (S.is_empty p) do invariant { inv g values !next } invariant { Fset.subset (Fset.diff (preds g v) p.S.to_fset) (defined_sort values) } invariant { Fset.subset (defined_sort (old values)) (defined_sort values) } invariant { Fset.subset p.S.to_fset (preds g v) } invariant { forall x:vertex. SA.mem x seen -> values[x] = old values[x] } variant { S.cardinal p } let u = S.choose_and_remove p in dfs g u seen values next done; values[v] <- !next; next := !next + 1 end let topo_order (g:graph): t int raises { Cycle_found -> true } ensures { sort g result.contents } = let next = ref 0 in let values = create (-1) in let p = get_vertices g in while not (S.is_empty p) do invariant { inv g values !next } invariant { Fset.subset p.S.to_fset (vertices g) } invariant { Fset.subset (Fset.diff (vertices g) p.S.to_fset) (defined_sort values) } variant { S.cardinal p } let u = S.choose_and_remove p in dfs g u (SA.empty ()) values next done; values end module Online_graph use export Graph val function add_edge (g: graph) (u v: vertex): graph ensures { forall x. preds result x = if x = v then S.add u (preds g v) else preds g x } ensures { forall x. succs result x = if x = u then S.add v (succs g u) else succs g x } end module Online_Basic
A New Approach to Incremental Topological Ordering Michael A. Bender, Jeremy T. Fineman, Seth Gilbert
use ref.Ref use Online_graph use set.Fset clone set.SetImp as S with type elt = vertex clone set.SetApp as SA with type elt = vertex clone import ImpmapNoDom as M with type key = vertex val get_succs (g: graph) (v: vertex): S.set ensures { result.S.to_fset = succs g v } exception Cycle_found type t = { mutable graph : graph; mutable values: M.t int; } predicate inv (g:t) = sort g.graph g.values.contents let create (g: graph): t requires { forall x: vertex. Fset.is_empty (preds g x) } ensures { result.graph = g } ensures { inv result } = { graph = g; values = create 0 } let rec dfs (g: t) (v: vertex) (seen: SA.set) (min_depth: int): unit requires { inv g } requires { Fset.mem v (vertices g.graph) } requires { Fset.subset seen.SA.to_fset (vertices g.graph) } raises { Cycle_found -> true } variant { Fset.cardinal (vertices g.graph) - SA.cardinal seen } ensures { min_depth <= g.values[v] } ensures { inv g } ensures { forall x:vertex. SA.mem x seen -> g.values[x] = old g.values[x] } ensures { forall x:vertex. old g.values[x] <= g.values[x] } = if SA.mem v seen then raise Cycle_found; if g.values[v] < min_depth then begin let p = get_succs g.graph v in let seen = SA.add v seen in while not (S.is_empty p) do invariant { inv g } invariant { forall s:vertex. Fset.mem s (succs g.graph v) -> not (S.mem s p) -> min_depth < g.values[s] } invariant { S.subset p.S.to_fset (succs g.graph v) } invariant { forall x:vertex. SA.mem x seen -> g.values[x] = old g.values[x] } invariant { forall x:vertex. old g.values[x] <= g.values[x] } variant { S.cardinal p } let u = S.choose_and_remove p in dfs g u seen (min_depth + 1) done; g.values[v] <- min_depth; end let add_edge (g: t) (x y: vertex): unit requires { inv g } requires { Fset.mem x (vertices g.graph) } requires { Fset.mem y (vertices g.graph) } ensures { inv g } ensures { g.graph = add_edge (old g.graph) x y } raises { Cycle_found -> true } = let seen = SA.empty () in let seen = SA.add x seen in dfs g y seen (g.values[x] + 1); g.graph <- add_edge g.graph x y end
download ZIP archive
Why3 Proof Results for Project "topological_sorting"
Theory "topological_sorting.Static": fully verified
Obligations | Alt-Ergo 2.3.0 | CVC4 1.5 | ||||
VC for dfs | --- | --- | ||||
split_goal_right | ||||||
exceptional postcondition | --- | 0.01 | ||||
loop invariant init | --- | 0.02 | ||||
loop invariant init | --- | 0.05 | ||||
loop invariant init | --- | 0.02 | ||||
loop invariant init | --- | 0.03 | ||||
loop invariant init | --- | 0.02 | ||||
precondition | --- | 0.02 | ||||
variant decrease | --- | 0.04 | ||||
precondition | --- | 0.02 | ||||
precondition | --- | 0.16 | ||||
precondition | --- | 0.06 | ||||
loop variant decrease | --- | 0.06 | ||||
loop invariant preservation | --- | 0.02 | ||||
loop invariant preservation | --- | 0.34 | ||||
loop invariant preservation | --- | 0.03 | ||||
loop invariant preservation | --- | 0.04 | ||||
loop invariant preservation | --- | 0.04 | ||||
exceptional postcondition | --- | 0.02 | ||||
postcondition | --- | 0.23 | ||||
postcondition | --- | 0.05 | ||||
postcondition | --- | --- | ||||
split_vc | ||||||
postcondition | 2.75 | --- | ||||
postcondition | --- | 0.07 | ||||
postcondition | --- | 0.04 | ||||
postcondition | --- | 0.07 | ||||
postcondition | --- | --- | ||||
inline_goal | ||||||
postcondition | --- | --- | ||||
split_goal_right | ||||||
VC for dfs | --- | 0.02 | ||||
VC for dfs | --- | 0.04 | ||||
VC for dfs | --- | --- | ||||
inline_goal | ||||||
VC for dfs | --- | 0.07 | ||||
VC for dfs | --- | 0.04 | ||||
postcondition | --- | 0.02 | ||||
VC for topo_order | --- | --- | ||||
split_goal_right | ||||||
loop invariant init | --- | --- | ||||
inline_goal | ||||||
loop invariant init | --- | --- | ||||
split_goal_right | ||||||
VC for topo_order | --- | 0.04 | ||||
VC for topo_order | --- | 0.02 | ||||
VC for topo_order | --- | 0.04 | ||||
VC for topo_order | --- | 0.03 | ||||
loop invariant init | --- | 0.02 | ||||
loop invariant init | --- | 0.03 | ||||
precondition | --- | 0.02 | ||||
precondition | --- | 0.02 | ||||
precondition | --- | 0.04 | ||||
precondition | --- | 0.04 | ||||
loop variant decrease | --- | 0.05 | ||||
loop invariant preservation | --- | 0.02 | ||||
loop invariant preservation | --- | 0.04 | ||||
loop invariant preservation | --- | 0.22 | ||||
exceptional postcondition | --- | 0.01 | ||||
postcondition | --- | 0.08 |
Theory "topological_sorting.Online_Basic": fully verified
Obligations | Alt-Ergo 2.1.0 | CVC4 1.5 | ||
VC for create | --- | --- | ||
split_goal_right | ||||
postcondition | --- | 0.01 | ||
postcondition | --- | 0.05 | ||
VC for dfs | --- | --- | ||
split_goal_right | ||||
exceptional postcondition | --- | 0.01 | ||
loop invariant init | --- | 0.02 | ||
loop invariant init | --- | 0.03 | ||
loop invariant init | --- | 0.02 | ||
loop invariant init | --- | 0.01 | ||
loop invariant init | --- | 0.02 | ||
precondition | --- | 0.02 | ||
variant decrease | --- | --- | ||
split_goal_right | ||||
VC for dfs | --- | 0.04 | ||
VC for dfs | --- | 0.04 | ||
precondition | --- | 0.02 | ||
precondition | --- | 0.12 | ||
precondition | --- | 0.06 | ||
loop variant decrease | --- | 0.06 | ||
loop invariant preservation | --- | 0.02 | ||
loop invariant preservation | --- | 0.08 | ||
loop invariant preservation | --- | 0.04 | ||
loop invariant preservation | --- | 0.05 | ||
loop invariant preservation | --- | 0.05 | ||
exceptional postcondition | --- | 0.01 | ||
postcondition | --- | 0.02 | ||
postcondition | 0.05 | --- | ||
postcondition | --- | 0.07 | ||
postcondition | --- | 0.05 | ||
postcondition | --- | 0.04 | ||
postcondition | --- | 0.02 | ||
postcondition | --- | 0.01 | ||
postcondition | --- | 0.01 | ||
VC for add_edge | --- | --- | ||
split_goal_right | ||||
precondition | --- | 0.02 | ||
precondition | --- | 0.02 | ||
precondition | --- | 0.05 | ||
postcondition | --- | 0.19 | ||
postcondition | --- | 0.03 | ||
exceptional postcondition | --- | 0.01 |