Zulip Chat Archive

Stream: mathlib4

Topic: Tournament has a Hamiltonian Path


Jafar Tanoukhi (Sep 09 2025 at 16:33):

I am working on a PR related to the issue #26771, and I am not sure how to proceed from here. I can't seem to figure out what lemmas or direction I must take to prove this theorem.

variable (V : Type*) (G : Digraph V) [DecidableEq V] [Fintype V] [Nonempty V]

theorem tournament_isTraceable (hG : G.IsTournament) :
    (a b : V),  (p : G.Walk a b), p.IsHamiltonian := by
  sorry

Here are my definitions of Walk and Hamiltonian for a Digraph :

universe u

namespace Digraph

variable {V : Type u}
variable (G : Digraph V)

inductive Walk : V  V  Type u
  | nil {u : V} : Walk u u
  | cons {u v w : V} (h : G.Adj u v) (p : Walk v w) : Walk u w
  deriving DecidableEq

namespace Walk

def support {u v : V} : G.Walk u v  List V
  | nil => [u]
  | cons _ p => u :: p.support

end Walk
namespace Walk

variable {V : Type u} [DecidableEq V] (G : Digraph V) (u v : V)

def IsHamiltonian (p : G.Walk u v) : Prop :=  a, p.support.count a = 1

end Walk

You can also find my definitions for Orientation and Tournament under this PR #28871

Jafar Tanoukhi (Sep 09 2025 at 16:38):

Though I can very easily prove this theorem with a piece of paper, the classical way, which is what's most frustrating to me.

Jafar Tanoukhi (Sep 09 2025 at 16:56):

Also here's an MWE :

import Mathlib.Order.CompleteBooleanAlgebra
import Mathlib.Data.Fintype.Pi
import Mathlib.Combinatorics.Digraph.Basic
import Mathlib.Combinatorics.Digraph.Orientation

universe u

namespace Digraph

variable {V : Type u}
variable (G : Digraph V)

inductive Walk : V  V  Type u
  | nil {u : V} : Walk u u
  | cons {u v w : V} (h : G.Adj u v) (p : Walk v w) : Walk u w
  deriving DecidableEq

namespace Walk

def support {u v : V} : G.Walk u v  List V
  | nil => [u]
  | cons _ p => u :: p.support

end Walk

end Digraph

namespace Digraph

namespace Walk

variable {V : Type u} [DecidableEq V] (G : Digraph V) (u v : V)

def IsHamiltonian (p : G.Walk u v) : Prop :=  a, p.support.count a = 1

end Walk

end Digraph

variable (V : Type*) (G : Digraph V)

namespace Digraph

structure IsTournament : Prop where
  loopless w : ¬ G.Adj w w
  one_edge w v : w  v  (G.Adj w v  ¬ G.Adj v w)

variable [DecidableEq V] [Fintype V] [Nonempty V]

  theorem tournament_isTraceable (hG : G.IsTournament) :
    (a b : V),  (p : G.Walk a b), p.IsHamiltonian := by
  sorry

  end Digraph

Aaron Liu (Sep 09 2025 at 17:07):

oh I remember this theorem

Aaron Liu (Sep 09 2025 at 17:09):

I did this as an exercise before

Aaron Liu (Sep 09 2025 at 17:10):

using docs#Fintype.induction_empty_option

Aaron Liu (Sep 09 2025 at 17:10):

and lots of list lemmas

Aaron Liu (Sep 09 2025 at 17:12):

Jafar Tanoukhi said:

Though I can very easily prove this theorem with a piece of paper, the classical way, which is what's most frustrating to me.

What's your paper proof? Is it the same one I know?

Jafar Tanoukhi (Sep 09 2025 at 17:26):

Aaron Liu said:

What's your paper proof? Is it the same one I know?

Induction on the number of vertices for a tournament
For 1 vertex, the Hamiltonian path is the vertex itself
For n + 1 vertices, we start with the Hamiltonian path that exists for n (we can assume this because of induction)
let's say this hamiltonian path is H : v1, v2, v3... vn and let's say the extra vertex is V

Three cases occur :
case 1: V is adjacent to v1 -> hence the hamiltonian path for n + 1 vertices would be V, v1, v2 ...vn
case 2: vn is adjacent to V -> hence the hamiltonian path for n + 1 vertices would be v1, v2...vn, V
case 3: if neither case 1 nor case 2 is true, then there will be some v in H such that vi -> V and V -> vi+1, hence the hamiltonian path for n + 1 vertices would be v1, v2,...,vi, V, vi+1,...,vn

This is it in a nutshell.

Jafar Tanoukhi (Sep 09 2025 at 18:56):

Aaron Liu said:

using docs#Fintype.induction_empty_option

I tried with this, but I was not able to figure out how exactly I'm supposed to use this.

apply Fintype.induction_empty_option at V yielded 5 goals, as there are other hypotheses like of_equiv, h_empty, and h_option that are required. Not sure how to get ride of those.

Snir Broshi (Sep 09 2025 at 19:29):

It looks Digraph is missing a lot of API that's needed here.
For example, I think we'd need these:

def map {V V' : Type*} (f : V  V') (G : Digraph V) : Digraph V' where
  Adj := Relation.Map G.Adj f f

def comap {V V' : Type*} (f : V  V') (G : Digraph V') : Digraph V where
  Adj u v := G.Adj (f u) (f v)

then theorems about when the IsTournament property is preserved across maps/comaps.
To use the induction hypothesis in h_option you would then have to show that G.comap some is a tournament.

Snir Broshi (Sep 09 2025 at 20:14):

I think that for the proof itself, the solution is to define docs#SimpleGraph.Walk.getVert for digraphs, prove docs#SimpleGraph.Walk.adj_getVert_succ, then prove that the getVert of a hamiltonian walk is a bijection from V to Fin n. Then the proof can use that bijection with docs#Fin.Lt.isWellOrder to get the first vertex v : α in the path from the induction hypothesis such that G.Adj (some v) none. If there is no such v we're in case 1, otherwise case 2 or 3.

Aaron Liu (Sep 09 2025 at 20:20):

Jafar Tanoukhi said:

Aaron Liu said:

using docs#Fintype.induction_empty_option

I tried with this, but I was not able to figure out how exactly I'm supposed to use this.

apply Fintype.induction_empty_option at V yielded 5 goals, as there are other hypotheses like of_equiv, h_empty, and h_option that are required. Not sure how to get ride of those.

With induction tactic

Aaron Liu (Sep 09 2025 at 20:21):

actually I think it has a bug which makes this not work

Snir Broshi (Sep 09 2025 at 20:33):

Oh we don't even have homomorphisms for Digraph :cold_sweat:

namespace Digraph
variable {V V' : Type*} (G : Digraph V) (G' : Digraph V')
abbrev Hom :=
  RelHom G.Adj G'.Adj
abbrev Embedding :=
  RelEmbedding G.Adj G'.Adj
abbrev Iso :=
  RelIso G.Adj G'.Adj
@[inherit_doc] infixl:50 " →g " => Hom
@[inherit_doc] infixl:50 " ↪g " => Embedding
@[inherit_doc] infixl:50 " ≃g " => Iso
end Digraph

Define Walk.map:

def Walk.map {V V' : Type*} {G : Digraph V} {G' : Digraph V'} (f : G g G') {u v : V} : G.Walk u v  G'.Walk (f u) (f v)
  | nil => nil
  | cons h p => cons (f.map_rel' h) (p.map f)

Then we need docs#SimpleGraph.Embedding.comap or docs#SimpleGraph.Embedding.map for digraphs, and we're really close to solving the simple part of the proof:

theorem tournament_isTraceable (hG : G.IsTournament) :
     (a b : V),  (p : G.Walk a b), p.IsHamiltonian := by
  revert G
  expose_names
  revert inst inst_2
  apply Fintype.induction_empty_option (P := fun α _  [DecidableEq α]  [Nonempty α] 
     G, IsTournament α G   a b p, Walk.IsHamiltonian G a b p)
  · intro α β _ f  _ _ G ht
    classical
    have := Equiv.nonempty_congr f |>.mpr Nonempty _›
    have : G.comap f |>.IsTournament := sorry
    have a, b, p, h :=  (G.comap f) this
    use f a, f b
    -- TODO: `use p.map (SimpleGraph.Embedding.comap f G)`
    sorry
  · aesop
  · intro α _ h _ _ G ht
    by_cases he : Nonempty α; rotate_left
    · use none, none, Walk.nil
      intro a
      have : IsEmpty α := not_nonempty_iff.mp he
      rw [show a = none by exact Unique.uniq _ _]
      simp [Walk.support]
    sorry

Jafar Tanoukhi (Sep 20 2025 at 15:40):

Snir said:

Oh we don't even have homomorphisms for Digraph :cold_sweat:

It seems to give these warnings :
@Hom does not have a doc string
@Embedding does not have a doc string
@Iso does not have a doc string

does it require some import other than importing the Digraph definition?

Jafar Tanoukhi (Sep 20 2025 at 16:19):

I removed the @[inherit_doc], which made the warning go away. Not sure what this is about though.

Damiano Testa (Sep 20 2025 at 16:34):

I think that Hom, Embedding and Iso should have a docstring and then the inherit_doc should be restored (and will not complain).

Jafar Tanoukhi (Sep 20 2025 at 16:53):

What's a docstring ?

Ruben Van de Velde (Sep 20 2025 at 17:03):

/-- explain what the thing does -/

Jafar Tanoukhi (Sep 20 2025 at 17:05):

ohh, alright haha.


Last updated: Dec 20 2025 at 21:32 UTC