Zulip Chat Archive
Stream: mathlib4
Topic: Decidable whether there is cycle in directed graph?
aron (Sep 29 2025 at 10:17):
Hi :wave: I've been playing with Lean for a while now although I have mostly not touched anything in Mathlib. Most of the stuff in there is quite intimidating to me, probably because I am not a mathematician :sweat_smile:
The project I'm working on entails something that is effectively a directed graph, on which I want to be able to check whether it contains cycles. I can model the prop for "there are no cycles starting from this point" using an inductive. But actually writing a function that returns a Decidable for it is turning out to be really really hard. I'm wondering if there is anything already in Mathlib that could help me?
I posted my original question here #new members > How to decide no loops in list of references but the key parts of it are:
inductive LeafOrRef
| leaf : LeafOrRef
| ref : Nat → LeafOrRef
deriving DecidableEq, BEq
/-- Proves that `i` is not contained in `lor` or any of the items it points to.
This prop also contains proofs for any refs we find along the way, so it indeed
proves not only that `i` isn't contained along the paths, but there are no
loops anywhere along the path. -/
inductive NoLoop (list : List LeafOrRef) : (i : Nat) → (lor : LeafOrRef) → Prop
| leaf : NoLoop list i .leaf
| ref {prf : j < list.length} :
i ≠ j →
NoLoop list i list[j] → -- doesn't contain the ref that this thing is about
NoLoop list j list[j] → -- also doesn't contain the current ref, recursively
NoLoop list i (.ref j)
/-- How to implement this -/
def NoLoop.decide list i lor : Decidable (NoLoop list i lor) := by
sorry
aron (Sep 29 2025 at 10:23):
I've also tried with the opposite approach, hoping it would be easier:
inductive Walk (list : List LeafOrRef) : (origin : Nat) → (dest : Nat) → Prop
| direct {prf} :
list[origin]'prf = .ref dest → -- if `origin` and `dest` are the same then the thing directly references itself
Walk list origin dest
| indirect :
(walk₁ : Walk list a b) →
(walk₂ : Walk list b c) →
Walk list a c
but although this does make some things easier, I haven't had any more luck implementing a function that returns Decidable (Walk ctx origin dest) than I've had with NoLoop
Tomaz Mascarenhas (Sep 30 2025 at 00:34):
(deleted)
Last updated: Dec 20 2025 at 21:32 UTC