Zulip Chat Archive

Stream: new members

Topic: Need help with using Fin n in a proof


Aatman Supkar (Apr 15 2025 at 22:44):

import Mathlib.Combinatorics.SimpleGraph.Basic
import Mathlib.Analysis.RCLike.Basic

universe u

open List

/-- We define an interval to just be a pair of points. If start > finish, we just have an empty interval. Meant to be treated as closed intervals. -/
structure Interval (α : Type u) [LinearOrder α] where
  start : α
  finish : α

/-- Boxes need to be 'axis-parallel', and can thus be defined as a list of intervals. -/
abbrev Box (α : Type u) [LinearOrder α] n := List.Vector (Interval α) n

/-- Given two intervals of the same type, returns their intersection. -/
@[simp]
def IntervalIntersection {α : Type u} [LinearOrder α] (i j : (Interval α)) : Interval α:=
  {start := max i.start j.start, finish := min i.finish j.finish}

/-- Given two boxes of the same type, returns their intersection. -/
@[simp]
def BoxIntersection {α : Type u} [LinearOrder α] {n : } (b1 b2 : Box α n) : Box α n :=
  List.Vector.ofFn (fun i  IntervalIntersection (b1.get i) (b2.get i))

/-- Hypothesis that characterises when a given interval is non-empty. -/
@[simp]
def nonempty_interval {α : Type u} [LinearOrder α] (i : Interval α) : Prop :=
  i.start  i.finish

@[simp]
def nonempty_box {n : } {α : Type u} [LinearOrder α] (b : Box α n) : Prop :=
   i : Fin n, nonempty_interval (b.get i)

/-- Each vertex `v ∈ G` is mapped to a non-empty box of dimension `n` via `Map`. Two distinct vertices `u,v ∈ G` intersect if and only if their corresponding boxes `Map u, Map v` intersect. The resulting box representation is said to be of dimension `n`. -/
structure BoxRepresentation (α : Type u) [LinearOrder α] (m : ) {n : } (G : SimpleGraph (Fin n)) where
  Map : Fin n  Box α m
  h1 (i : Fin n): nonempty_box (Map i)
  h2 :  u v : Fin n, (u = v)  (nonempty_box (BoxIntersection (Map u) (Map v))  G.Adj u v)

/-- The boxicity of a graph `G` is the smallest number of dimensions `n` needed for a box representation of dimension `n` to exist. -/
@[simp]
noncomputable def GraphBoxicity {n : } (G : SimpleGraph (Fin n)) :  :=
  sInf {m |  f : Fin n  Box  m,  R : BoxRepresentation  m G, R.Map = f}

/-- A discrete version of boxicity using `Fin n`. Is supposed to be the same as boxicity. -/
@[simp]
noncomputable def GraphBoxicity' {n : } (G : SimpleGraph (Fin n)) :  :=
  sInf {m |  f : Fin n  Box (Fin n) m,  R : BoxRepresentation (Fin n) m G, R.Map = f}

/-- Determining when the intersection of two non-empty intervals are supposed to be non-empty. -/
theorem interval_int_nonempty_iff_ineq {α : Type u} [LinearOrder α] (I J : Interval α):
  (nonempty_interval I)  (nonempty_interval J)  (nonempty_interval (IntervalIntersection I J)  I.start  J.finish  J.start  I.finish) := by
  intro h1 h2
  apply Iff.intro
  simp_all only [nonempty_interval, IntervalIntersection]
  by_cases ha : I.start  J.finish <;> by_cases hb : J.start  I.finish <;> intro hc <;> simp_all
  simp_all only [nonempty_interval, IntervalIntersection]
  by_cases ha : I.start  J.finish <;> by_cases hb : J.start  I.finish <;> intro hc <;> simp_all

-- def fin_succ {n : ℕ} (i : ℕ) (h : i < n) : ℕ (i < n + 1 : Prop) :=
--   let successor := i + 1
--   ⟨successor, Nat.add_lt_of_lt_sub (h)⟩

/-- Graph boxicity equals its discrete variant on all graphs. -/
theorem graphBoxicity_eq_graphBoxicity' {n : } (G : SimpleGraph (Fin n)) [DecidableRel G.Adj] :
    GraphBoxicity G = GraphBoxicity' G := by
  unfold GraphBoxicity GraphBoxicity'
  let S1 : Set  := {m |  f : Fin n  Box  m,  R : BoxRepresentation  m G, R.Map = f}
  let S2 : Set  := {m |  f : Fin n  Box (Fin n) m,  R : BoxRepresentation (Fin n) m G, R.Map = f}
  have h1 : S2  S1 := by
    intro m h
    simp [S2] at h
    let f, R, h' := h
    simp [S1]
    let g1 (i : Interval (Fin n)) : Interval  :=
      {start := (i.start), finish := (i.finish)}
    have h1a :  i : Interval (Fin n), nonempty_interval (g1 i)  nonempty_interval i := by
      simp only [nonempty_interval, Nat.cast_le, Fin.val_fin_le, implies_true]
    let g2 (b : Box (Fin n) m) : Box  m :=
        List.Vector.ofFn (fun i  g1 ((b.get i) : Interval (Fin n)))
    have h1b :  b : Box (Fin n) m, nonempty_box b  nonempty_box (g2 b) := by
      intro b
      simp only [nonempty_box, nonempty_interval, Vector.get_ofFn, Nat.cast_le, Fin.val_fin_le, g2]
    have h1c (b1 b2 : Box (Fin n) m) : BoxIntersection (g2 b1) (g2 b2) = g2 (BoxIntersection b1 b2) := by
      simp only [BoxIntersection, IntervalIntersection, Vector.get_ofFn, Fin.coe_sup, Nat.cast_max,
        Fin.coe_inf, Nat.cast_min, g2, g1]
    have h1d :  u v : Fin n, (u = v)  (nonempty_box (BoxIntersection (g2 (f u)) (g2 (f v)))  G.Adj u v) := by
      intro u
      intro v
      cases Decidable.em (u = v)
      apply Or.inl
      assumption
      apply Or.inr
      rw [h1c,  h1b]
      have h1d1 := R.h2 u v
      cases h1d1 with
      | inl => contradiction
      | inr hw => rwa[ h']
    have h1e (i : Fin n) : nonempty_box (g2 (f i)) := by
      intro i1
      have h1e1 := R.h1
      simp_all [h', g2]
    exact g2  f, ⟨⟨g2  f, h1e, h1d, rfl⟩⟩
  have h2 : S1  S2 := by
    intro m h
    simp [S1] at h
    let f, R, h' := h
    simp [S2]
    have interval_dim_list (i : Fin n) := List.Vector.ofFn (fun j  (f i).get j)
    have discretise_real (x : ) (j : Fin m): Fin n := sorry
    have discretise_interval (i : Fin n) (j: Fin m) : Interval (Fin n) :=
      discretise_real ((f i).get j).start j , discretise_real ((f i).get j).finish j
    have discretise_box (i : Fin n): Box (Fin n) m:=
      List.Vector.ofFn (fun j  discretise_interval i j)
    have h2a :  (i : Fin n) (j : Fin m), nonempty_interval ((f i).get j)  nonempty_interval (discretise_interval i j) := by sorry
    have h2aa (i : Fin n) : nonempty_box ((f i))  nonempty_box (discretise_box i) := by sorry
    have h2b :  (i j : Fin n), nonempty_box (BoxIntersection (f i) (f j))  nonempty_box (BoxIntersection (discretise_box i) (discretise_box j)) := by sorry
    have h2c :  (i j : Fin n), (i = j)  (nonempty_box (BoxIntersection (discretise_box i) (discretise_box j))  G.Adj i j) := by
      intro i j
      cases Decidable.em (i = j)
      apply Or.inl
      assumption
      apply Or.inr
      have h2c1 := R.h2 i j
      cases h2c1 with
      | inl => contradiction
      | inr hw =>
        aesop
    have h2d :  i : Fin n, nonempty_box (discretise_box i) := by
      sorry
    exact discretise_box, discretise_box, h2d, h2c, rfl
  have h3 : S1 = S2 := by
    apply Set.Subset.antisymm
    assumption
    assumption
  exact congrArg sInf h3

I'm trying to figure out this last proof, but I don't know how to begin defining discretise_real.

Proof idea: Given a box representation of a graph G with n vertices, over the reals, map each box's kth interval as follows:
Make a list of all the kth intervals across all the boxes. Now assign to each interval's start or end point x the number of start points that come before x in the list above. I need this to be Fin n as well, and not just a natural. This assignment preserves all intersection properties, and should thus be able to map any real presentation to a Fin n one.

The issue with trying to define the above is:
a) If I try to create the integer iteratively using List.foldl, I need the type of the integer to be preserved in the foldl's input function, so I define it to be Fin n to start with. I'm not sure how to synthesise a proof that upon each addition, the integer still doesn't cross n-1.
b) I tried List.foldl with a (Nat, h : Prop) pair instead, but turns out you can't create such a pair for some reason?

Help with the rest of the proof would also be appreciated, but what matters to me most right now is being able to define discretise_real correctly. I am not sure if the comments in the code explain the setup sufficiently, so please let me know anything I should elaborate on.

Matt Diamond (Apr 16 2025 at 01:42):

on a side note, docs#Interval and docs#NonemptyInterval exist in Mathlib (though NonemptyInterval is a Type, not a Prop)

Matt Diamond (Apr 16 2025 at 02:28):

btw it might help if you included a definition of discretise_real even if the code doesn't work, just to help people understand what you're aiming at... you can definitely create (Nat, Prop) pairs (that's what Fin is, in a sense)

Aatman Supkar (Apr 16 2025 at 07:21):

Ah, apologies. In my head I did write it here, when I actually did not.

Aatman Supkar said:

Proof idea: Given a box representation of a graph G with n vertices, over the reals, map each box's kth interval as follows:
Make a list of all the kth intervals across all the boxes. Now assign to each interval's start or end point x the number of start points that come before x in the list above.

This assignment is precisely what I wish for discretise_real to be.

Matt Diamond said:

you can definitely create (Nat, Prop) pairs (that's what Fin is, in a sense)

Apologies, I meant something like (Nat, proof of given Nat being less than some integer) pairs. Even if I do that, proving that the natural is strictly less than n is slightly tricky. It needs me to figure out how to use the fact that since x itself will not be one of the indices greater than x, not all intervals contribute a start point.

At this point I'm also facing issues with understanding how I'm supposed to partition my work into the right blocks to tackle one at a time. Like, if I don't know exactly what I want to provide in the upcoming step which I haven't even worked out, what should my current step be achieving? I'm slightly lost here.


Last updated: May 02 2025 at 03:31 UTC