Decidability of Relation.ReflTransGen on a finite carrier #
Generic substrate: given a relation r : α → α → Prop whose successors lie
in some finite list s : List α, derive Decidable (Relation.ReflTransGen r a b)
via path compression.
Construction #
A Path r a chain b is a list of intermediates [c₁, …, cₖ] with
r a c₁ ∧ r c₁ c₂ ∧ … ∧ r cₖ b. The empty chain [] witnesses a direct
edge r a b. Then:
ReflTransGen r a bis equivalent toa = bor the existence of somePath r a chain b(ReflTransGen.eq_or_path).- Any
Pathreduces to one whose intermediates are pairwise distinct and contain neitheranorb(Path.compress). - A compressed
Pathhas length< s.lengthbyList.Subperm. - Hence reachability is decidable via bounded BFS at fuel
s.length.
Naming #
Path is named to match Quiver.Path / SimpleGraph.Walk-style naming.
It is distinct from List.Chain' (which is a relation between
consecutive list elements without fixed endpoints).
Provenance #
Lifted from Core/Inheritance/Basic.lean where it was first proved for
Hudson's Word Grammar IsA relation. Generalised to be reusable across
Network.IsA, CausalGraph.IsAncestor,
SDRT.availableViaChain.
A chain of intermediate nodes [c₁, c₂, …, cₖ] witnesses
a → c₁ → c₂ → … → cₖ → b via r-steps. The empty chain [] witnesses
a direct edge r a b.
Distinct from List.Chain': Path r a chain b pins the source a and
target b; List.Chain' r l does not.
Equations
- Relation.ReflTransGen.Path r a [] x✝ = r a x✝
- Relation.ReflTransGen.Path r a (x_2 :: xs) x✝ = (r a x_2 ∧ Relation.ReflTransGen.Path r x_2 xs x✝)
Instances For
A path realises ReflTransGen.
Compression (right-truncation): if b appears in the chain, take
the prefix ending at its first occurrence.
Helper: if a chain Path r x chain b contains y, the suffix from
y's first occurrence is itself a chain Path r y _ b.
Compression (skip-to-self): if a appears in the chain, take the
suffix from its reappearance.
Compression (interior duplication): if some node appears twice in the chain, splice out the cycle.
Strong-induction helper for Path.compress. The explicit length parameter
threads chain-length through Nat.strongRecOn. Public so external callers
that already have a Nat-bound on the chain in hand can avoid Path.compress's
implicit chain.length evaluation; in practice all uses go through compress.
Chain compression: any path reduces to one with no repeats whose
intermediates are disjoint from {a, b}.
All intermediates of a path satisfy any predicate that holds of
r-successors. Stated abstractly so it specialises to both List and
Finset universes.
List specialisation of Path.intermediates_satisfy with P := (· ∈ s).
List specialisation of Path.endpoint_satisfies with P := (· ∈ s).
Length bound: a Nodup path with b not in the chain is bounded by the
size of any successor-closed list.
Decidability of Relation.ReflTransGen on a finite carrier, given an
explicit step function and a successor-bound list s.
Equations
- Relation.ReflTransGen.decidable_of_finite_step step s step_eq step_in_s a b = decidable_of_iff (a = b ∨ b ∈ Relation.ReflTransGen.stepBFS✝ step a s.length) ⋯
Instances For
Decidability of Relation.ReflTransGen on a finite carrier, derived
from a [DecidableRel r] instance and a successor-bound list. A convenience
wrapper around decidable_of_finite_step for callers that have r decidable
but no natural step function.
Equations
- Relation.ReflTransGen.decidable_of_finite s succ_in_s a b = Relation.ReflTransGen.decidable_of_finite_step (fun (a : α) => List.filter (fun (b : α) => decide (r a b)) s) s ⋯ ⋯ a b
Instances For
The List-based API above suits callers whose universe is naturally a
List α (e.g., Network.nodeUniverse derived from links via .dedup).
The Finset variants below suit callers whose universe is a Finset α
(e.g., CausalGraph.parents : V → Finset V with [Fintype V]). The
shared mathematical content (Path, compression, length_lt_of_nodup)
applies to both — only the BFS engine and the headline iff differ.
Finset length-bound variant. Goes through List.toFinset (computable
since List.dedup is computable) and Finset.card_le_card.
Decidability of Relation.ReflTransGen on a Finset-bounded carrier,
given an explicit Finset-valued step function.
Equations
- Relation.ReflTransGen.decidable_of_finset_step step s step_eq step_in_s a b = decidable_of_iff (a = b ∨ b ∈ Relation.ReflTransGen.finsetBFS✝ step a s.card) ⋯
Instances For
Decidability of Relation.ReflTransGen on a [Fintype] carrier —
the convenience headline most callers want. Takes no explicit universe;
uses Finset.univ as the bound.
Equations
- Relation.ReflTransGen.decidable_of_fintype_step step step_eq a b = Relation.ReflTransGen.decidable_of_finset_step step Finset.univ step_eq ⋯ a b
Instances For
Decidability of Relation.ReflTransGen on a [Fintype] carrier
given only a [DecidableRel r] instance. The convenience parallel to
mathlib's SimpleGraph.Reachable.decidable.
Equations
- Relation.ReflTransGen.decidable_of_fintype a b = Relation.ReflTransGen.decidable_of_fintype_step (fun (a : α) => {b : α | decide (r a b) = true}) ⋯ a b
Instances For
TransGen r a b decomposes as a Path (one or more edges).
Decidability of Relation.TransGen on a Finset-bounded carrier.
Equations
- Relation.ReflTransGen.decidable_TransGen_of_finset_step step s step_eq step_in_s a b = decidable_of_iff (b ∈ Relation.ReflTransGen.finsetBFS✝ step a s.card) ⋯
Instances For
Decidability of Relation.TransGen on a [Fintype] carrier.
Equations
- Relation.ReflTransGen.decidable_TransGen_of_fintype_step step step_eq a b = Relation.ReflTransGen.decidable_TransGen_of_finset_step step Finset.univ step_eq ⋯ a b
Instances For
Decidability of Relation.TransGen on a [Fintype] carrier given
[DecidableRel r].
Equations
- Relation.ReflTransGen.decidable_TransGen_of_fintype a b = Relation.ReflTransGen.decidable_TransGen_of_fintype_step (fun (a : α) => {b : α | decide (r a b) = true}) ⋯ a b