Dijkstra's algorithm
DefinitionEndpoint-weight sum along a vertex list#✓fully proved
Given a weight \(w(u, v) \in \mathbb{N}\) for each ordered pair of vertices, the weight of a list of vertices \(v_0, v_1, \dots, v_k\) is \(w(v_0, v_1) + w(v_1, v_2) + \dots + w(v_{k-1}, v_k)\). In particular the empty list and every one-vertex list have weight \(0\).
@[expose] public def pathWeight (weight : V → V → Nat) : List V → Nat
| [] | [_] => 0
| source :: target :: rest =>
weight source target + pathWeight weight (target :: rest)
Used by 17
DefinitionWalks of a given weight#✓fully proved
Let \(G\) be a directed graph given by adjacency lists, let \(w(u, v) \in \mathbb{N}\) be a weight for each ordered pair of vertices, let \(s\) and \(t\) be vertices and let \(d\) be a natural number. Then \(s\) reaches \(t\) with weight \(d\) when there is a nonempty list of vertices \(v_0, v_1, \dots, v_k\) with \(v_0 = s\), \(v_k = t\) and each \(v_{i+1}\) in the adjacency list of \(v_i\), such that \(w(v_0, v_1) + \dots + w(v_{k-1}, v_k) = d\).
@[expose] public def HasPathWeight (graph : DirectedAdjacency V) (weight : V → V → Nat)
(source target : V) (distance : Nat) : Prop :=
∃ path, path.IsChainFromTo graph.Edge source target ∧
pathWeight weight path = distance
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
@[expose] public def pathWeight (weight : V → V → Nat) : List V → Nat
| [] | [_] => 0
| source :: target :: rest =>
weight source target + pathWeight weight (target :: rest)
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:34
Uses 3 · Used by 15
TheoremReachability via weighted walks#✓fully proved
Let \(G\) be a directed graph given by adjacency lists and let \(w(u, v) \in \mathbb{N}\) be a weight for each ordered pair of vertices. For vertices \(s\) and \(t\), \(t\) is reachable from \(s\) in \(G\) if and only if there is a natural number \(d\) such that \(s\) reaches \(t\) with weight \(d\) with respect to \(w\).
public theorem reachable_iff_exists_hasPathWeight (graph : DirectedAdjacency V)
(weight : V → V → Nat) (source target : V) :
graph.Reachable source target ↔
∃ distance, HasPathWeight graph weight source target distance
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
@[expose] public def HasPathWeight (graph : DirectedAdjacency V) (weight : V → V → Nat)
(source target : V) (distance : Nat) : Prop :=
∃ path, path.IsChainFromTo graph.Edge source target ∧
pathWeight weight path = distance
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:40
Uses 7 · Used by 7
DefinitionAdjacency entry count#✓fully proved
For a directed graph \(G\) given by an out-neighbour list \(\mathrm{adj}(v)\) for each vertex \(v\), the adjacency entry count of \(G\) is the total length \(\sum_{v} |\mathrm{adj}(v)|\) of these lists over all vertices \(v\), so repeated entries and self-loops are counted with multiplicity.
@[expose] public def adjacencyEntryCount (graph : DirectedAdjacency V) : Nat :=
(graph.vertices.map fun vertex => (graph.adjacency vertex).length).sum
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
Uses 1 · Used by 5
StructureCost of dense Dijkstra#✓fully proved
A Dijkstra cost is a pair of natural numbers that counts two kinds of events separately: the number of vertex entries inspected during minimum selection, and the number of adjacency-list entries inspected during relaxation.
public structure DijkstraCost where
/-- Vertex entries inspected by minimum selection. -/
minScans : Nat
/-- Adjacency entries inspected by relaxation. -/
edgeRelaxations : Nat
deriving DecidableEq
Used by 24
DefinitionTotal Dijkstra cost#✓fully proved
The total of a Dijkstra cost record is its number of vertex entries inspected by minimum selection plus its number of adjacency entries inspected by relaxation.
@[expose] public def DijkstraCost.total (cost : DijkstraCost) : Nat :=
cost.minScans + cost.edgeRelaxations
public structure DijkstraCost where
/-- Vertex entries inspected by minimum selection. -/
minScans : Nat
/-- Adjacency entries inspected by relaxation. -/
edgeRelaxations : Nat
deriving DecidableEq
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:136
Uses 1 · Used by 7
StructureOutput of Dijkstra's algorithm#✓fully proved
For vertices \(0, \dots, n-1\), a Dijkstra result consists of a source vertex \(s\), a distance entry \(d(v)\) for each vertex \(v\) that is either a natural number or \(\infty\), and a predecessor entry \(p(v)\) for each vertex \(v\) that is either a vertex or undefined. The entries are stored as arrays of length \(n\); \(d(v)\) is meant as the computed distance from \(s\) to \(v\) and \(p(v)\) as the vertex before \(v\) on a shortest path from \(s\).
public structure DijkstraResult (n : Nat) where
/-- The starting vertex. -/
source : Fin n
/-- Final distance estimates, with `none` denoting infinity. -/
distance : Vector (Option Nat) n
/-- Shortest-path predecessor pointers. -/
predecessor : Vector (Option (Fin n)) n
Used by 26
DefinitionPath recovery from Dijkstra predecessors#✓fully proved
Let a Dijkstra result on \(n\) vertices have source \(s\) and predecessor entries \(p\). The path to a vertex \(t\) follows predecessors backwards: starting from \(u_0 = t\), as long as \(u_i \ne s\) it sets \(u_{i+1} = p(u_i)\). If \(u_k = s\) for some \(k \le n\), the result is the list \(u_k, u_{k-1}, \dots, u_0\) from \(s\) to \(t\). If some \(p(u_i)\) is undefined before \(s\) is reached, or \(s\) is not reached within \(n\) steps, there is no result.
public def DijkstraResult.pathTo? {n : Nat} (result : DijkstraResult n) (target : Fin n) :
Option (List (Fin n)) :=
let rec @[reducible] go (current : Fin n) : Nat → Option (List (Fin n))
| 0 => if current = result.source then some [result.source] else none
| fuel + 1 =>
if current = result.source then
some [result.source]
else
match result.predecessor.get current with
| none => none
| some previous => (go previous fuel).map fun path => path ++ [current]
go target n
public structure DijkstraResult (n : Nat) where
/-- The starting vertex. -/
source : Fin n
/-- Final distance estimates, with `none` denoting infinity. -/
distance : Vector (Option Nat) n
/-- Shortest-path predecessor pointers. -/
predecessor : Vector (Option (Fin n)) n
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:186
Uses 1 · Used by 4
DefinitionDense Dijkstra's algorithm#✓fully proved
Let \(G\) be a directed graph on the vertices \(0, \dots, n-1\) given by a fixed enumeration of its vertices and adjacency lists, let \(w(u, v) \in \mathbb{N}\) be a weight for each ordered pair of vertices, and let \(s\) be a source vertex. The algorithm starts with \(d(s) = 0\), \(d(v) = \infty\) for \(v \ne s\), no predecessors and no settled vertices, and runs \(n\) rounds. In each round it scans all vertices in the order of the enumeration of \(G\) and selects the first unsettled vertex \(u\) in that order whose value \(d(u)\) is minimal among unsettled vertices; if every vertex is settled the round does nothing. Otherwise it marks \(u\) settled and, for each entry \(v\) of the adjacency list of \(u\) in order, if \(v\) is unsettled, \(d(u)\) is finite and \(d(u) + w(u, v) < d(v)\), it sets \(d(v) := d(u) + w(u, v)\) and makes \(u\) the predecessor of \(v\). The result is \(s\) together with the final distances and predecessors. The cost charges one minimum-selection step for each vertex inspected during selection and one relaxation step for each adjacency entry inspected during relaxation.
Cslib.Algorithms.Lean.DirectedAdjacency.dijkstra · 80 lines
public def dijkstra {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source : Fin n) :
TimeM DijkstraCost (DijkstraResult n) :=
let State := Vector (Option Nat) n × Vector (Option (Fin n)) n ×
Vector Bool n × Vector (Option Nat) n × List (Fin n)
let update {α : Type} (values : Vector α n) (index : Fin n) (value : α) :
Vector α n :=
values.set index.val value index.isLt
let distanceLess (left right : Option Nat) : Bool :=
match left, right with
| some leftDistance, some rightDistance => leftDistance < rightDistance
| some _, none => true
| none, _ => false
let consider (state : State) (best : Option (Fin n))
(candidate : Fin n) : Option (Fin n) :=
if state.2.2.1.get candidate then
best
else
match best with
| none => some candidate
| some current =>
if distanceLess (state.1.get candidate) (state.1.get current) then
some candidate
else
best
let rec @[reducible] selectLoop (state : State) :
List (Fin n) → Option (Fin n) → TimeM DijkstraCost (Option (Fin n))
| [], best => pure best
| candidate :: rest, best => do
TimeM.tick { minScans := 1, edgeRelaxations := 0 }
selectLoop state rest (consider state best candidate)
let relaxOne (previous target : Fin n) (state : State) : State :=
if state.2.2.1.get target then
state
else
match state.1.get previous with
| none => state
| some previousDistance =>
let candidate := previousDistance + weight previous target
match state.1.get target with
| none =>
(update state.1 target (some candidate),
update state.2.1 target (some previous), state.2.2.1,
state.2.2.2.1, state.2.2.2.2)
| some targetDistance =>
if candidate < targetDistance then
(update state.1 target (some candidate),
update state.2.1 target (some previous), state.2.2.1,
state.2.2.2.1, state.2.2.2.2)
else
state
let rec @[reducible] relaxLoop (previous : Fin n) :
List (Fin n) → State → TimeM DijkstraCost State
| [], state => pure state
| target :: rest, state => do
TimeM.tick { minScans := 0, edgeRelaxations := 1 }
relaxLoop previous rest (relaxOne previous target state)
let rec @[reducible] runRounds : Nat → Nat → State → TimeM DijkstraCost State
| 0, _, state => pure state
| remaining + 1, nextRank, state => do
let selected ← selectLoop state graph.vertices none
match selected with
| none => runRounds remaining nextRank state
| some vertex =>
let state : State :=
(state.1, state.2.1, update state.2.2.1 vertex true,
update state.2.2.2.1 vertex (some nextRank),
state.2.2.2.2 ++ [vertex])
let state ← relaxLoop vertex (graph.adjacency vertex) state
runRounds remaining (nextRank + 1) state
let initial : State :=
(Vector.ofFn fun vertex => if vertex = source then some 0 else none,
Vector.ofFn fun _ => none, Vector.ofFn fun _ => false,
Vector.ofFn fun _ => none, [])
let run := runRounds n 0 initial
{ ret :=
{ source := source
distance := run.ret.1
predecessor := run.ret.2.1 }
time := run.time }
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
public structure DijkstraCost where
/-- Vertex entries inspected by minimum selection. -/
minScans : Nat
/-- Adjacency entries inspected by relaxation. -/
edgeRelaxations : Nat
deriving DecidableEq
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:136
public structure DijkstraResult (n : Nat) where
/-- The starting vertex. -/
source : Fin n
/-- Final distance estimates, with `none` denoting infinity. -/
distance : Vector (Option Nat) n
/-- Shortest-path predecessor pointers. -/
predecessor : Vector (Option (Fin n)) n
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:186
Uses 3 · Used by 22
TheoremDijkstra's finite distances are realized by walks#✓fully proved
Let \(G\) be a directed graph on the vertices \(0, \dots, n-1\), let \(w(u, v)\) be a natural-number weight for every ordered pair of vertices, and let \(s\) and \(t\) be vertices. If Dijkstra's algorithm on \(G\) with weights \(w\) from source \(s\) outputs a finite distance \(d\) for \(t\), then \(G\) has a walk \(s = v_0, v_1, \dots, v_k = t\), with an edge from each \(v_{i-1}\) to \(v_i\), of weight \(\sum_{i=1}^{k} w(v_{i-1}, v_i) = d\).
theorem dijkstra_distance_realized {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source target : Fin n) (distance : Nat)
(h : (dijkstra graph weight source).ret.distance.get target = some distance) :
HasPathWeight graph weight source target distance
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
public def dijkstra {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source : Fin n) :
TimeM DijkstraCost (DijkstraResult n) :=
let State := Vector (Option Nat) n × Vector (Option (Fin n)) n ×
Vector Bool n × Vector (Option Nat) n × List (Fin n)
let update {α : Type} (values : Vector α n) (index : Fin n) (value : α) :
Vector α n :=
values.set index.val value index.isLt
let distanceLess (left right : Option Nat) : Bool :=
match left, right with
| some leftDistance, some rightDistance => leftDistance < rightDistance
| some _, none => true
⋯
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:222
@[expose] public def HasPathWeight (graph : DirectedAdjacency V) (weight : V → V → Nat)
(source target : V) (distance : Nat) : Prop :=
∃ path, path.IsChainFromTo graph.Edge source target ∧
pathWeight weight path = distance
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:40
Uses 9 · Used by 4
TheoremDijkstra's finite distances are lower bounds on walk weights#✓fully proved
Let \(G\) be a directed graph on the vertices \(0, \dots, n-1\), let \(w(u, v)\) be a natural-number weight for every ordered pair of vertices, and let \(s\) and \(t\) be vertices. If Dijkstra's algorithm on \(G\) with weights \(w\) from source \(s\) outputs a finite distance \(d\) for \(t\), then \(d \le d'\) for every walk \(s = v_0, v_1, \dots, v_k = t\) in \(G\) (with an edge from each \(v_{i-1}\) to \(v_i\)) of weight \(d' = \sum_{i=1}^{k} w(v_{i-1}, v_i)\).
theorem dijkstra_distance_minimal {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source target : Fin n)
(distance otherDistance : Nat)
(h : (dijkstra graph weight source).ret.distance.get target = some distance)
(path : HasPathWeight graph weight source target otherDistance) :
distance ≤ otherDistance
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
public def dijkstra {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source : Fin n) :
TimeM DijkstraCost (DijkstraResult n) :=
let State := Vector (Option Nat) n × Vector (Option (Fin n)) n ×
Vector Bool n × Vector (Option Nat) n × List (Fin n)
let update {α : Type} (values : Vector α n) (index : Fin n) (value : α) :
Vector α n :=
values.set index.val value index.isLt
let distanceLess (left right : Option Nat) : Bool :=
match left, right with
| some leftDistance, some rightDistance => leftDistance < rightDistance
| some _, none => true
⋯
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:222
@[expose] public def HasPathWeight (graph : DirectedAdjacency V) (weight : V → V → Nat)
(source target : V) (distance : Nat) : Prop :=
∃ path, path.IsChainFromTo graph.Edge source target ∧
pathWeight weight path = distance
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:40
Uses 9 · Used by 2
TheoremDijkstra's distance is infinite exactly at unreachable vertices#✓fully proved
Let \(G\) be a directed graph on the vertices \(0, \dots, n-1\), let \(w(u, v)\) be a natural-number weight for every ordered pair of vertices, and let \(s\) and \(t\) be vertices. The distance to \(t\) output by Dijkstra's algorithm on \(G\) with weights \(w\) from source \(s\) is infinite if and only if \(t\) is not reachable from \(s\) in \(G\).
theorem dijkstra_distance_eq_none_iff {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source target : Fin n) :
(dijkstra graph weight source).ret.distance.get target = none ↔
¬graph.Reachable source target
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
public def dijkstra {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source : Fin n) :
TimeM DijkstraCost (DijkstraResult n) :=
let State := Vector (Option Nat) n × Vector (Option (Fin n)) n ×
Vector Bool n × Vector (Option Nat) n × List (Fin n)
let update {α : Type} (values : Vector α n) (index : Fin n) (value : α) :
Vector α n :=
values.set index.val value index.isLt
let distanceLess (left right : Option Nat) : Bool :=
match left, right with
| some leftDistance, some rightDistance => leftDistance < rightDistance
| some _, none => true
⋯
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:222
Uses 9 · Used by 2
TheoremDijkstra's predecessor pointers satisfy the distance equation#✓fully proved
Let \(G\) be a directed graph on the vertices \(0, \dots, n-1\), let \(w(u, v)\) be a natural-number weight for every ordered pair of vertices, and let \(s\), \(t\) and \(p\) be vertices. If Dijkstra's algorithm on \(G\) with weights \(w\) from source \(s\) outputs \(p\) as the predecessor of \(t\), then \(G\) has an edge from \(p\) to \(t\), the distances \(d(p)\) and \(d(t)\) output for \(p\) and \(t\) are both finite, and \(d(t) = d(p) + w(p, t)\).
theorem dijkstra_predecessor_spec {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source target previous : Fin n)
(h : (dijkstra graph weight source).ret.predecessor.get target = some previous) :
graph.Edge previous target ∧
∃ previousDistance targetDistance,
(dijkstra graph weight source).ret.distance.get previous = some previousDistance ∧
(dijkstra graph weight source).ret.distance.get target = some targetDistance ∧
targetDistance = previousDistance + weight previous target
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
public def dijkstra {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source : Fin n) :
TimeM DijkstraCost (DijkstraResult n) :=
let State := Vector (Option Nat) n × Vector (Option (Fin n)) n ×
Vector Bool n × Vector (Option Nat) n × List (Fin n)
let update {α : Type} (values : Vector α n) (index : Fin n) (value : α) :
Vector α n :=
values.set index.val value index.isLt
let distanceLess (left right : Option Nat) : Bool :=
match left, right with
| some leftDistance, some rightDistance => leftDistance < rightDistance
| some _, none => true
⋯
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:222
Uses 9 · Used by 1
TheoremDijkstra's path reconstruction fails exactly at infinite distance#✓fully proved
Let \(G\) be a directed graph on the vertices \(0, \dots, n-1\), let \(w(u, v)\) be a natural-number weight for every ordered pair of vertices, and let \(s\) and \(t\) be vertices. Reconstructing a path from \(s\) to \(t\) by following, for at most \(n\) steps, the predecessor pointers output by Dijkstra's algorithm on \(G\) with weights \(w\) from source \(s\) fails if and only if the distance output for \(t\) is infinite.
theorem dijkstra_pathTo?_eq_none_iff {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source target : Fin n) :
(dijkstra graph weight source).ret.pathTo? target = none ↔
(dijkstra graph weight source).ret.distance.get target = none
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
public def dijkstra {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source : Fin n) :
TimeM DijkstraCost (DijkstraResult n) :=
let State := Vector (Option Nat) n × Vector (Option (Fin n)) n ×
Vector Bool n × Vector (Option Nat) n × List (Fin n)
let update {α : Type} (values : Vector α n) (index : Fin n) (value : α) :
Vector α n :=
values.set index.val value index.isLt
let distanceLess (left right : Option Nat) : Bool :=
match left, right with
| some leftDistance, some rightDistance => leftDistance < rightDistance
| some _, none => true
⋯
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:222
Uses 10 · Used by 1
TheoremReconstructed Dijkstra paths are simple and have the output weight#✓fully proved
Let \(G\) be a directed graph on the vertices \(0, \dots, n-1\), let \(w(u, v)\) be a natural-number weight for every ordered pair of vertices, and let \(s\) and \(t\) be vertices. Suppose that following the predecessor pointers output by Dijkstra's algorithm on \(G\) with weights \(w\) from source \(s\) reconstructs a list of vertices \(P\) for \(t\). Then \(P\) is nonempty, say \(P = v_0, \dots, v_k\), with \(v_0 = s\) and \(v_k = t\); there is an edge from each \(v_{i-1}\) to \(v_i\); the \(v_i\) are pairwise distinct; and the distance \(d\) output for \(t\) is finite with \(d = \sum_{i=1}^{k} w(v_{i-1}, v_i)\).
theorem dijkstra_pathTo?_spec {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source target : Fin n) (path : List (Fin n))
(h : (dijkstra graph weight source).ret.pathTo? target = some path) :
∃ distance,
(dijkstra graph weight source).ret.distance.get target = some distance ∧
path.head? = some source ∧ path.getLast? = some target ∧
path.IsChain graph.Edge ∧ path.Nodup ∧ pathWeight weight path = distance
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
public def dijkstra {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source : Fin n) :
TimeM DijkstraCost (DijkstraResult n) :=
let State := Vector (Option Nat) n × Vector (Option (Fin n)) n ×
Vector Bool n × Vector (Option Nat) n × List (Fin n)
let update {α : Type} (values : Vector α n) (index : Fin n) (value : α) :
Vector α n :=
values.set index.val value index.isLt
let distanceLess (left right : Option Nat) : Bool :=
match left, right with
| some leftDistance, some rightDistance => leftDistance < rightDistance
| some _, none => true
⋯
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:222
@[expose] public def pathWeight (weight : V → V → Nat) : List V → Nat
| [] | [_] => 0
| source :: target :: rest =>
weight source target + pathWeight weight (target :: rest)
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:34
Uses 11 · Used by 1
TheoremRelaxation count of dense Dijkstra#✓fully proved
Let \(G\) be a directed graph on the vertices \(0, \dots, n-1\), let \(w(u, v)\) be a natural-number weight for every ordered pair of vertices, and let \(s\) be a vertex. The number of adjacency-list entries that Dijkstra's algorithm on \(G\) with weights \(w\) from source \(s\) inspects during relaxation equals the adjacency entry count of \(G\), the total length of all out-neighbour lists.
theorem dijkstra_edgeRelaxations {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source : Fin n) :
(dijkstra graph weight source).time.edgeRelaxations = adjacencyEntryCount graph
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
public def dijkstra {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source : Fin n) :
TimeM DijkstraCost (DijkstraResult n) :=
let State := Vector (Option Nat) n × Vector (Option (Fin n)) n ×
Vector Bool n × Vector (Option Nat) n × List (Fin n)
let update {α : Type} (values : Vector α n) (index : Fin n) (value : α) :
Vector α n :=
values.set index.val value index.isLt
let distanceLess (left right : Option Nat) : Bool :=
match left, right with
| some leftDistance, some rightDistance => leftDistance < rightDistance
| some _, none => true
⋯
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:222
@[expose] public def adjacencyEntryCount (graph : DirectedAdjacency V) : Nat :=
(graph.vertices.map fun vertex => (graph.adjacency vertex).length).sum
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:132
Uses 10 · Used by 1
TheoremMinimum-selection count of dense Dijkstra#✓fully proved
Let \(G\) be a directed graph on the vertices \(0, \dots, n-1\), let \(w(u, v)\) be a natural-number weight for every ordered pair of vertices, and let \(s\) be a vertex. Dijkstra's algorithm on \(G\) with weights \(w\) from source \(s\) inspects exactly \(n^2\) vertex entries during minimum selection.
theorem dijkstra_minScans {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source : Fin n) :
(dijkstra graph weight source).time.minScans = n * n
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
public def dijkstra {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source : Fin n) :
TimeM DijkstraCost (DijkstraResult n) :=
let State := Vector (Option Nat) n × Vector (Option (Fin n)) n ×
Vector Bool n × Vector (Option Nat) n × List (Fin n)
let update {α : Type} (values : Vector α n) (index : Fin n) (value : α) :
Vector α n :=
values.set index.val value index.isLt
let distanceLess (left right : Option Nat) : Bool :=
match left, right with
| some leftDistance, some rightDistance => leftDistance < rightDistance
| some _, none => true
⋯
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:222
Uses 4 · Used by 1
TheoremRunning time of dense Dijkstra#✓fully proved
Let \(G\) be a directed graph on the vertices \(0, \dots, n-1\) given by adjacency lists, let \(w(u, v) \in \mathbb{N}\) be a weight for each ordered pair of vertices, and let \(s\) be a vertex. For dense Dijkstra from \(s\), the number of vertex entries inspected by minimum selection plus the number of adjacency entries inspected by relaxation is exactly \(n^2 + m\), where \(m\) is the number of adjacency-list entries of \(G\), counting duplicates and self-loops.
theorem dijkstra_time {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source : Fin n) :
(dijkstra graph weight source).time.total = n * n + adjacencyEntryCount graph
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
public def dijkstra {n : Nat} (graph : DirectedAdjacency (Fin n))
(weight : Fin n → Fin n → Nat) (source : Fin n) :
TimeM DijkstraCost (DijkstraResult n) :=
let State := Vector (Option Nat) n × Vector (Option (Fin n)) n ×
Vector Bool n × Vector (Option Nat) n × List (Fin n)
let update {α : Type} (values : Vector α n) (index : Fin n) (value : α) :
Vector α n :=
values.set index.val value index.isLt
let distanceLess (left right : Option Nat) : Bool :=
match left, right with
| some leftDistance, some rightDistance => leftDistance < rightDistance
| some _, none => true
⋯
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:222
@[expose] public def adjacencyEntryCount (graph : DirectedAdjacency V) : Nat :=
(graph.vertices.map fun vertex => (graph.adjacency vertex).length).sum
CSLibExt/Algorithms/Lean/Graph/ShortestPath/Dijkstra.lean:132
Uses 8 · Used by 3
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.