Simproc deciding Matrix.IsIndecomposable #
Matrix.reduceIsIndecomposable rewrites M.IsIndecomposable to True or False for a closed
square matrix literal M indexed by Fin n. This requires a kernel-decidable equality for the
matrix entry type.
This is equivalent to determining whether the directed graph corresponding to M is strongly
connected.
Main definitions #
Matrix.reduceIsIndecomposable: the simproc decidingM.IsIndecomposable.SpansFrom: states that every vertex is visited following a list of edges starting from a root.isClosed: tests whether a set of vertices has no edges leaving it.packedAdj: a Boolean adjacency matrix stored as the bits of a natural number computed from a matrix literal bypackRows.decideStronglyConnected: searches the graph from and to vertex0, returning two spanning trees or a closed set of vertices.
Implementation notes #
This simproc simply runs two bfs on the graph from vertex 0 forwards and
backwards. If all vertices are reached in both passes, then the indecomposability is certified by
the two search trees. Otherwise, M is decomposable, witnessed by a set of rows whose entries
outside the set evaluate to 0.
There is an existing implementation of Tarjan's algorithm at Tactic.Order.Graph.findSCCs, but it
doesn't return a witness for the strongly connected components, and the algorithm is also an
overkill.
The Boolean adjacency matrix of a !![…] literal is packed into one natural number, with entry
(i, j) at bit i * n + j, and both certificates are checked against that number, since reading
the literal by position costs the kernel a walk per entry.
Reachability in a Boolean adjacency matrix #
The vertices reached from the set bits of s by following the edges es in order. An edge
counts only when it leaves a vertex already reached and is an edge of adj.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The edges es in order reach every vertex of adj starting from root.
Equations
- Mathlib.Tactic.Matrix.IsIndecomposable.SpansFrom adj es root = (Mathlib.Tactic.Matrix.IsIndecomposable.reached adj (1 <<< ↑root) es = 2 ^ n - 1)
Instances For
If adj has a spanning list of edges from root, then root reaches every vertex.
Closed sets of vertices in a Boolean adjacency matrix, and the packed version #
Whether no edge of adj leaves the set of vertices given by the set bits of s.
Equations
- Mathlib.Tactic.Matrix.IsIndecomposable.isClosed adj s = (List.finRange n).all fun (i : Fin n) => !s.testBit ↑i || (List.finRange n).all fun (j : Fin n) => s.testBit ↑j || !adj i j
Instances For
Entry (i, j) of the n × n Boolean adjacency matrix represented by bits.
Equations
- Mathlib.Tactic.Matrix.IsIndecomposable.packedAdj n bits i j = bits.testBit (↑i * n + ↑j)
Instances For
Whether no edge of the n × n Boolean adjacency matrix represented by bits leaves the set
of vertices given by the set bits of s. Each row of bits is read at once.
Equations
Instances For
Certificates for a matrix from its Boolean adjacency matrix #
If both adj and its reverse have spanning edge lists from root, then M is
indecomposable (strong connectivity of adj).
If adj has a nonempty proper subset of vertices that is closed, then M is decomposable.
The Boolean adjacency matrix of a matrix literal #
The nonzero entries of row, as the set bits of a natural number.
Equations
- Mathlib.Tactic.Matrix.IsIndecomposable.packRow row = List.foldr (fun (a : R) (acc : ℕ) => (if a = 0 then 0 else 1) ||| acc <<< 1) 0 row
Instances For
The Boolean adjacency matrix of rows interpreted as an n × n matrix, as the set bits of a
natural number with entry (i, j) at bit i * n + j.
Equations
- Mathlib.Tactic.Matrix.IsIndecomposable.packRows n rows = List.foldr (fun (row : List R) (acc : ℕ) => Mathlib.Tactic.Matrix.IsIndecomposable.packRow row &&& 2 ^ n - 1 ||| acc <<< n) 0 rows
Instances For
The outcome of searching a directed graph from and to vertex 0.
- connected (outTree inTree : Array (ℕ × ℕ)) : StrongConnectivityResult
The graph is strongly connected, with the spanning out-tree
outTreefrom0and in-treeinTreeto0. - disconnected (closedSet : Array Bool) : StrongConnectivityResult
The graph is not strongly connected. No edge leaves the nonempty proper set of vertices
closedSet.
Instances For
Search the directed graph with Boolean adjacency matrix adjMatrix from and to vertex 0.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The Boolean adjacency matrix of the matrix with rows lit evaluated by the kernel. Returns
none if the kernel cannot decide which entries are zero.
The kernel evaluates the packed number packRows n lit and then unpacks the boolean adjacency
matrix from the bits. This round trip evaluates every entry in one Kernel.whnf call instead
of needing a call per cell (about 2.5x the cost).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Prove that lit interpreted as an n × n matrix is indecomposable using the spanning
out-tree outTree from vertex 0 and the in-tree inTree to it in its graph.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Prove that lit interpreted as an n × n matrix is decomposable from a nonempty proper
set closedSet of vertices that no edge of its graph leaves.
Instances For
Core of the Matrix.reduceIsIndecomposable simproc.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Matrix.reduceIsIndecomposable decides M.IsIndecomposable for a closed matrix literal M
indexed by Fin n with n a numeral, whose entry type has an equality the kernel can decide.