why3doc index index
The graph is represented by a pair (vertices
, successor
)
vertices
: this constant is the set of graph vertices
successor
: this function gives for each vertex the set of vertices directly joinable from it
Notice that this proof uses paths.
module DfsWhitePathCompleteness use import int.Int use import list.List use import list.Append use import list.Mem as L use import list.Length use import list.HdTlNoOpt use import list.Reverse use import list.Elements as E use import array.Array use import ref.Ref use import init_graph.GraphListArraySucc predicate white_vertex (x: vertex) (v: set vertex) = not (mem x v) inductive wpath vertex (list vertex) vertex (set vertex) = | WPath_empty: forall x v. white_vertex x v -> wpath x Nil x v | WPath_cons: forall x y l z v. white_vertex x v -> edge x y -> wpath y l z v -> wpath x (Cons x l) z v predicate whiteaccess (roots b v: set vertex) = forall z. mem z b -> exists x l. mem x roots /\ wpath x l z v predicate nbtw (b v: set vertex) = forall x x'. edge x x' -> mem x b -> mem x' (union b v) lemma nbtw_wpath: forall v v'. nbtw (diff v' v) v' -> forall x l z. mem x (diff v' v) -> wpath x l z v -> mem z (diff v' v) lemma path_wpathempty: forall y l z. wpath y l z empty -> path y l z lemma nbtw_path: forall v. nbtw v v -> forall x l z. mem x v -> path x l z -> mem z v
type color = WHITE | GRAY | BLACK function non_white_set (array color): set vertex axiom set_non_white: forall col x. mem x (non_white_set col) <-> mem x vertices /\ col[x] <> WHITE let rec dfs1 x col (graph: array (list vertex)) (ghost v) = requires {Array.length graph = cardinal vertices /\ forall x. graph[x] = successors x} requires {mem x vertices} requires {col[x] = WHITE /\ Array.length col = cardinal vertices} requires {forall x. mem x !v <-> mem x vertices /\ col[x] <> WHITE} ensures {forall x. mem x !v <-> mem x vertices /\ col[x] <> WHITE} ensures {subset !(old v) !v } ensures {mem x !v} ensures {nbtw (diff !v !(old v)) !v && forall s. whiteaccess (add x empty) s !(old v) -> subset s (diff !v !(old v)) } ensures {forall x. mem x vertices -> col[x] = GRAY <-> (old col)[x] = GRAY} 'L0: let ghost v0 = !v in assert {not mem x v0}; let ghost col0 = Array.copy col in col[x] <- GRAY; v := add x !v; let sons = ref graph[x] in let ghost dejavu = ref Nil in while !sons <> Nil do invariant {subset (elements !sons) vertices} invariant {subset !v vertices} invariant {forall z. mem z vertices -> (col[z] = GRAY <-> col0[x<-GRAY][z] = GRAY) } invariant {forall z. mem z !v <-> mem z vertices /\ col[z] <> WHITE} invariant {subset (elements !dejavu) !v} invariant {subset v0 !v} invariant {nbtw (diff !v (add x v0)) !v} invariant {successors x = (reverse !dejavu) ++ !sons} let y = hd !sons in if col[y] = WHITE then dfs1 y col graph v; sons := tl !sons; dejavu := Cons y !dejavu; done; 'L1: let ghost v' = !v in assert {diff v' v0 == add x (diff v' (add x v0))}; col[x] <- BLACK let dfs_main graph = requires {Array.length graph = cardinal vertices} requires {forall x. graph[x] = successors x} ensures {let s = non_white_set result in nbtw s s so forall x l z. mem x vertices -> path x l z -> mem z s} let col = make (cardinal vertices) WHITE in let ghost v = ref empty in let ghost dejavu = ref Nil in for x = 0 to (cardinal vertices) - 1 do invariant {subset !v vertices} invariant {forall z. mem z !v <-> mem z vertices /\ col[z] <> WHITE} invariant {nbtw !v !v} invariant {subset (elements !dejavu) !v} invariant {forall y. mem y (elements !dejavu) <-> 0 <= y < x} if col[x] = WHITE then dfs1 x col graph v; dejavu := Cons x !dejavu; done; col
(* let rec dfs1 x col graph = col[x] <- GRAY; let sons = ref graph[x] in while !sons <> Nil do let y = hd !sons in if col[y] = WHITE then dfs1 y col; sons := tl !sons; done; col[x] <- BLACK let dfs_main graph = let col = make (cardinal vertices) WHITE in for x = 0 to (cardinal vertices) - 1 do if col[x] = WHITE then dfs1 x col; done; col *) end
Generated by why3doc 0.88.3