refactor: Index notation
This commit is contained in:
parent
a8474233ae
commit
33b83d850b
4 changed files with 1314 additions and 106 deletions
595
HepLean/SpaceTime/LorentzTensor/IndexNotation/Append.lean
Normal file
595
HepLean/SpaceTime/LorentzTensor/IndexNotation/Append.lean
Normal file
|
@ -0,0 +1,595 @@
|
|||
/-
|
||||
Copyright (c) 2024 Joseph Tooby-Smith. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Joseph Tooby-Smith
|
||||
-/
|
||||
import HepLean.SpaceTime.LorentzTensor.IndexNotation.DualIndex
|
||||
import HepLean.SpaceTime.LorentzTensor.Basic
|
||||
/-!
|
||||
|
||||
# Appending index lists and consquences thereof.
|
||||
|
||||
-/
|
||||
|
||||
namespace IndexNotation
|
||||
|
||||
|
||||
namespace IndexList
|
||||
|
||||
variable {X : Type} [IndexNotation X] [Fintype X] [DecidableEq X]
|
||||
variable (l l2 : IndexList X)
|
||||
|
||||
/-!
|
||||
|
||||
## Appending index lists.
|
||||
|
||||
-/
|
||||
|
||||
instance : HAppend (IndexList X) (IndexList X) (IndexList X) :=
|
||||
@instHAppendOfAppend (List (Index X)) List.instAppend
|
||||
|
||||
def appendEquiv {l l2 : IndexList X} : Fin l.length ⊕ Fin l2.length ≃ Fin (l ++ l2).length :=
|
||||
finSumFinEquiv.trans (Fin.castOrderIso (List.length_append _ _).symm).toEquiv
|
||||
|
||||
@[simp]
|
||||
lemma idMap_append_inl {l l2 : IndexList X} (i : Fin l.length) :
|
||||
(l ++ l2).idMap (appendEquiv (Sum.inl i)) = l.idMap i := by
|
||||
simp [appendEquiv, idMap]
|
||||
rw [List.getElem_append_left]
|
||||
|
||||
@[simp]
|
||||
lemma idMap_append_inr {l l2 : IndexList X} (i : Fin l2.length) :
|
||||
(l ++ l2).idMap (appendEquiv (Sum.inr i)) = l2.idMap i := by
|
||||
simp [appendEquiv, idMap]
|
||||
rw [List.getElem_append_right]
|
||||
simp
|
||||
omega
|
||||
omega
|
||||
|
||||
@[simp]
|
||||
lemma colorMap_append_inl {l l2 : IndexList X} (i : Fin l.length) :
|
||||
(l ++ l2).colorMap (appendEquiv (Sum.inl i)) = l.colorMap i := by
|
||||
simp [appendEquiv, colorMap]
|
||||
rw [List.getElem_append_left]
|
||||
|
||||
@[simp]
|
||||
lemma colorMap_append_inr {l l2 : IndexList X} (i : Fin l2.length) :
|
||||
(l ++ l2).colorMap (appendEquiv (Sum.inr i)) = l2.colorMap i := by
|
||||
simp [appendEquiv, colorMap]
|
||||
rw [List.getElem_append_right]
|
||||
simp
|
||||
omega
|
||||
omega
|
||||
|
||||
|
||||
/-!
|
||||
|
||||
## AreDualInSelf
|
||||
|
||||
-/
|
||||
|
||||
namespace AreDualInSelf
|
||||
|
||||
@[simp]
|
||||
lemma append_inl_inl : (l ++ l2).AreDualInSelf (appendEquiv (Sum.inl i)) (appendEquiv (Sum.inl j))
|
||||
↔ l.AreDualInSelf i j := by
|
||||
simp [AreDualInSelf]
|
||||
|
||||
@[simp]
|
||||
lemma append_inr_inr (l l2 : IndexList X) (i j : Fin l2.length) :
|
||||
(l ++ l2).AreDualInSelf (appendEquiv (Sum.inr i)) (appendEquiv (Sum.inr j))
|
||||
↔ l2.AreDualInSelf i j := by
|
||||
simp [AreDualInSelf]
|
||||
|
||||
@[simp]
|
||||
lemma append_inl_inr (l l2 : IndexList X) (i : Fin l.length) (j : Fin l2.length) :
|
||||
(l ++ l2).AreDualInSelf (appendEquiv (Sum.inl i)) (appendEquiv (Sum.inr j)) =
|
||||
l.AreDualInOther l2 i j := by
|
||||
simp [AreDualInSelf, AreDualInOther]
|
||||
|
||||
@[simp]
|
||||
lemma append_inr_inl (l l2 : IndexList X) (i : Fin l2.length) (j : Fin l.length) :
|
||||
(l ++ l2).AreDualInSelf (appendEquiv (Sum.inr i)) (appendEquiv (Sum.inl j)) =
|
||||
l2.AreDualInOther l i j := by
|
||||
simp [AreDualInSelf, AreDualInOther]
|
||||
|
||||
end AreDualInSelf
|
||||
|
||||
|
||||
/-!
|
||||
|
||||
## Member withDual append conditions
|
||||
|
||||
-/
|
||||
|
||||
@[simp]
|
||||
lemma inl_mem_withDual_append_iff (i : Fin l.length) :
|
||||
appendEquiv (Sum.inl i) ∈ (l ++ l2).withDual ↔ (i ∈ l.withDual ∨ i ∈ l.withDualInOther l2) := by
|
||||
simp only [mem_withDual_iff_exists, mem_withInDualOther_iff_exists]
|
||||
refine Iff.intro (fun h => ?_) (fun h => ?_)
|
||||
· obtain ⟨j, hj⟩ := h
|
||||
obtain ⟨k, hk⟩ := appendEquiv.surjective j
|
||||
subst hk
|
||||
match k with
|
||||
| Sum.inl k =>
|
||||
exact Or.inl ⟨k, by simpa using hj⟩
|
||||
| Sum.inr k =>
|
||||
exact Or.inr ⟨k, by simpa using hj⟩
|
||||
· cases' h with h h <;>
|
||||
obtain ⟨j, hj⟩ := h
|
||||
· use appendEquiv (Sum.inl j)
|
||||
simpa using hj
|
||||
· use appendEquiv (Sum.inr j)
|
||||
simpa using hj
|
||||
|
||||
@[simp]
|
||||
lemma inr_mem_withDual_append_iff (i : Fin l2.length) :
|
||||
appendEquiv (Sum.inr i) ∈ (l ++ l2).withDual
|
||||
↔ (i ∈ l2.withDual ∨ i ∈ l2.withDualInOther l) := by
|
||||
simp only [mem_withDual_iff_exists, mem_withInDualOther_iff_exists]
|
||||
refine Iff.intro (fun h => ?_) (fun h => ?_)
|
||||
· obtain ⟨j, hj⟩ := h
|
||||
obtain ⟨k, hk⟩ := appendEquiv.surjective j
|
||||
subst hk
|
||||
match k with
|
||||
| Sum.inl k =>
|
||||
exact Or.inr ⟨k, by simpa using hj⟩
|
||||
| Sum.inr k =>
|
||||
exact Or.inl ⟨k, by simpa using hj⟩
|
||||
· cases' h with h h <;>
|
||||
obtain ⟨j, hj⟩ := h
|
||||
· use appendEquiv (Sum.inr j)
|
||||
simpa using hj
|
||||
· use appendEquiv (Sum.inl j)
|
||||
simpa using hj
|
||||
|
||||
def appendInlWithDual (i : l.withDual) : (l ++ l2).withDual :=
|
||||
⟨appendEquiv (Sum.inl i), by simp⟩
|
||||
|
||||
|
||||
/-!
|
||||
|
||||
## getDual on appended lists
|
||||
|
||||
-/
|
||||
|
||||
@[simp]
|
||||
lemma getDual?_append_inl_withDual (i : l.withDual) :
|
||||
(l ++ l2).getDual? (appendEquiv (Sum.inl i)) = some (appendEquiv (Sum.inl (l.getDual! i))) := by
|
||||
rw [getDual?, Fin.find_eq_some_iff, AreDualInSelf.append_inl_inl]
|
||||
apply And.intro (l.areDualInSelf_getDual! i)
|
||||
intro j hj
|
||||
obtain ⟨k, hk⟩ := appendEquiv.surjective j
|
||||
subst hk
|
||||
match k with
|
||||
| Sum.inl k =>
|
||||
simp only [appendEquiv, Equiv.trans_apply, finSumFinEquiv_apply_left, RelIso.coe_fn_toEquiv,
|
||||
Fin.castOrderIso_apply, ge_iff_le]
|
||||
rw [Fin.le_def]
|
||||
have h2 := l.getDual?_eq_some_getDual! i
|
||||
rw [getDual?, Fin.find_eq_some_iff] at h2
|
||||
exact h2.2 k (by simpa using hj)
|
||||
| Sum.inr k =>
|
||||
simp only [appendEquiv, Equiv.trans_apply, finSumFinEquiv_apply_left, RelIso.coe_fn_toEquiv,
|
||||
Fin.castOrderIso_apply, finSumFinEquiv_apply_right, ge_iff_le]
|
||||
rw [Fin.le_def]
|
||||
simp only [Fin.coe_cast, Fin.coe_castAdd, Fin.coe_natAdd]
|
||||
omega
|
||||
|
||||
@[simp]
|
||||
lemma getDual_append_inl_withDual (i : l.withDual) :
|
||||
(l ++ l2).getDual ⟨appendEquiv (Sum.inl i), by simp⟩ =
|
||||
⟨appendEquiv (Sum.inl (l.getDual i)), by simp⟩ := by
|
||||
simp [getDual, getDual!]
|
||||
|
||||
@[simp]
|
||||
lemma getDual?_append_inl_not_withDual (i : Fin l.length) (hi : i ∉ l.withDual)
|
||||
(h : appendEquiv (Sum.inl i) ∈ (l ++ l2).withDual) :
|
||||
(l ++ l2).getDual? (appendEquiv (Sum.inl i)) = some
|
||||
(appendEquiv (Sum.inr (l.getDualInOther! l2 ⟨i, by simp_all⟩))) := by
|
||||
rw [getDual?, Fin.find_eq_some_iff, AreDualInSelf.append_inl_inr]
|
||||
apply And.intro (l.areDualInOther_getDualInOther! l2 ⟨i, by simp_all⟩)
|
||||
intro j hj
|
||||
obtain ⟨k, hk⟩ := appendEquiv.surjective j
|
||||
subst hk
|
||||
match k with
|
||||
| Sum.inl k =>
|
||||
rw [AreDualInSelf.append_inl_inl] at hj
|
||||
simp only [withDual, getDual?, Finset.mem_filter, Finset.mem_univ, true_and, Bool.not_eq_true,
|
||||
Option.not_isSome, Option.isNone_iff_eq_none, Fin.find_eq_none_iff] at hi
|
||||
exact False.elim (hi k hj)
|
||||
| Sum.inr k =>
|
||||
simp [appendEquiv]
|
||||
rw [Fin.le_def]
|
||||
have h1 := l.getDualInOther?_eq_some_getDualInOther! l2 ⟨i, by simp_all⟩
|
||||
rw [getDualInOther?, Fin.find_eq_some_iff] at h1
|
||||
simp only [Fin.coe_cast, Fin.coe_natAdd, add_le_add_iff_left, Fin.val_fin_le, ge_iff_le]
|
||||
refine h1.2 k (by simpa using hj)
|
||||
|
||||
@[simp]
|
||||
lemma getDual_append_inl_not_withDual (i : Fin l.length) (hi : i ∉ l.withDual)
|
||||
(h : appendEquiv (Sum.inl i) ∈ (l ++ l2).withDual) :
|
||||
(l ++ l2).getDual ⟨appendEquiv (Sum.inl i), h⟩ =
|
||||
⟨appendEquiv (Sum.inr (l.getDualInOther l2 ⟨i, by simp_all⟩)), by simp⟩ := by
|
||||
simp [getDual, getDual!, getDual?_append_inl_not_withDual l l2 i hi h]
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
lemma getDual?_append_inr_withDualInOther (i : l2.withDualInOther l) :
|
||||
(l ++ l2).getDual? (appendEquiv (Sum.inr i)) =
|
||||
some (appendEquiv (Sum.inl (l2.getDualInOther! l i))) := by
|
||||
rw [getDual?, Fin.find_eq_some_iff, AreDualInSelf.append_inr_inl]
|
||||
apply And.intro (l2.areDualInOther_getDualInOther! l ⟨i, by simp_all⟩)
|
||||
intro j hj
|
||||
obtain ⟨k, hk⟩ := appendEquiv.surjective j
|
||||
subst hk
|
||||
match k with
|
||||
| Sum.inl k =>
|
||||
simp only [appendEquiv, Equiv.trans_apply, finSumFinEquiv_apply_left, RelIso.coe_fn_toEquiv,
|
||||
Fin.castOrderIso_apply, ge_iff_le]
|
||||
rw [Fin.le_def]
|
||||
have h1 := l2.getDualInOther?_eq_some_getDualInOther! l ⟨i, by simp_all⟩
|
||||
rw [getDualInOther?, Fin.find_eq_some_iff] at h1
|
||||
simp only [Fin.coe_cast, Fin.coe_natAdd, add_le_add_iff_left, Fin.val_fin_le, ge_iff_le]
|
||||
refine h1.2 k (by simpa using hj)
|
||||
| Sum.inr k =>
|
||||
simp only [appendEquiv, Equiv.trans_apply, finSumFinEquiv_apply_left, RelIso.coe_fn_toEquiv,
|
||||
Fin.castOrderIso_apply, finSumFinEquiv_apply_right, ge_iff_le]
|
||||
rw [Fin.le_def]
|
||||
simp only [Fin.coe_cast, Fin.coe_castAdd, Fin.coe_natAdd]
|
||||
omega
|
||||
|
||||
@[simp]
|
||||
lemma getDual_append_inr_withDualInOther (i : l2.withDualInOther l) :
|
||||
(l ++ l2).getDual ⟨appendEquiv (Sum.inr i), by simp⟩ =
|
||||
⟨appendEquiv (Sum.inl (l2.getDualInOther l i)), by simp⟩ := by
|
||||
simp [getDual, getDual!]
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
lemma getDual?_append_inr_not_withDualInOther (i : Fin l2.length) (hi : i ∉ l2.withDualInOther l)
|
||||
(h : appendEquiv (Sum.inr i) ∈ (l ++ l2).withDual) :
|
||||
(l ++ l2).getDual? (appendEquiv (Sum.inr i)) = some
|
||||
(appendEquiv (Sum.inr (l2.getDual! ⟨i, by simp_all⟩))) := by
|
||||
rw [getDual?, Fin.find_eq_some_iff, AreDualInSelf.append_inr_inr]
|
||||
apply And.intro (l2.areDualInSelf_getDual! ⟨i, by simp_all⟩)
|
||||
intro j hj
|
||||
obtain ⟨k, hk⟩ := appendEquiv.surjective j
|
||||
subst hk
|
||||
match k with
|
||||
| Sum.inl k =>
|
||||
simp at hj
|
||||
refine False.elim (hi ?_)
|
||||
simp [withDualInOther, getDualInOther?, Fin.isSome_find_iff]
|
||||
exact ⟨k, hj⟩
|
||||
| Sum.inr k =>
|
||||
simp [appendEquiv]
|
||||
rw [Fin.le_def]
|
||||
simp
|
||||
have h2 := l2.getDual?_eq_some_getDual! ⟨i, by simp_all⟩
|
||||
rw [getDual?, Fin.find_eq_some_iff] at h2
|
||||
simp only [AreDualInSelf.append_inr_inr] at hj
|
||||
exact h2.2 k hj
|
||||
|
||||
@[simp]
|
||||
lemma getDual_append_inr_not_withDualInOther (i : Fin l2.length) (hi : i ∉ l2.withDualInOther l)
|
||||
(h : appendEquiv (Sum.inr i) ∈ (l ++ l2).withDual) :
|
||||
(l ++ l2).getDual ⟨appendEquiv (Sum.inr i), h⟩ =
|
||||
⟨appendEquiv (Sum.inr (l2.getDual ⟨i, by simp_all⟩)), by simp⟩ := by
|
||||
simp [getDual, getDual!, getDual?_append_inr_not_withDualInOther l l2 i hi h]
|
||||
|
||||
|
||||
@[simp]
|
||||
lemma getDual?_append_inl (i : Fin l.length) : (l ++ l2).getDual? (appendEquiv (Sum.inl i)) =
|
||||
Option.or (Option.map (appendEquiv ∘ Sum.inl) (l.getDual? i))
|
||||
(Option.map (appendEquiv ∘ Sum.inr) (l.getDualInOther? l2 i)) := by
|
||||
by_cases h : (appendEquiv (Sum.inl i)) ∈ (l ++ l2).withDual
|
||||
· by_cases hl : i ∈ l.withDual
|
||||
· rw [(l ++ l2).getDual?_eq_some_getDual! ⟨(appendEquiv (Sum.inl i)), h⟩]
|
||||
rw [l.getDual?_eq_some_getDual! ⟨i, hl⟩]
|
||||
rw [getDual!]
|
||||
simp only [Option.some_get, Option.map_some', Function.comp_apply, Option.or_some]
|
||||
exact getDual?_append_inl_withDual l l2 ⟨i, hl⟩
|
||||
· let h' := h
|
||||
rw [l.getDual?_eq_none_on_not_mem i hl]
|
||||
simp only [inl_mem_withDual_append_iff] at h
|
||||
simp_all only [false_or, Option.map_none', Option.none_or]
|
||||
rw [l.getDualInOther?_eq_some_getDualInOther! l2 ⟨i, h⟩]
|
||||
rw [getDual?_append_inl_not_withDual l l2 i hl h']
|
||||
rfl
|
||||
· rw [(l ++ l2).getDual?_eq_none_on_not_mem _ h]
|
||||
simp only [inl_mem_withDual_append_iff, not_or, not_exists] at h
|
||||
rw [l.getDual?_eq_none_on_not_mem _ h.1, l.getDualInOther?_eq_none_on_not_mem l2 _ h.2]
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
lemma getDual?_append_inr (i : Fin l2.length) :
|
||||
(l ++ l2).getDual? (appendEquiv (Sum.inr i)) =
|
||||
Option.or (Option.map (appendEquiv ∘ Sum.inl) (l2.getDualInOther? l i))
|
||||
(Option.map (appendEquiv ∘ Sum.inr) (l2.getDual? i)) := by
|
||||
by_cases h : (appendEquiv (Sum.inr i)) ∈ (l ++ l2).withDual
|
||||
· by_cases hl1 : i ∈ l2.withDualInOther l
|
||||
· rw [(l ++ l2).getDual?_eq_some_getDual! ⟨(appendEquiv (Sum.inr i)), h⟩]
|
||||
rw [l2.getDualInOther?_eq_some_getDualInOther! l ⟨i, hl1⟩]
|
||||
rw [getDual!]
|
||||
simp only [Option.some_get, Option.map_some', Function.comp_apply, Option.or_some]
|
||||
exact getDual?_append_inr_withDualInOther l l2 ⟨i, hl1⟩
|
||||
· have h' := h
|
||||
rw [l2.getDualInOther?_eq_none_on_not_mem l i hl1]
|
||||
simp only [inr_mem_withDual_append_iff, not_exists] at h hl1
|
||||
simp_all only [not_exists, exists_false, or_false,
|
||||
Option.map_none', Option.none_or]
|
||||
rw [l2.getDual?_eq_some_getDual! ⟨i, h⟩]
|
||||
simp only [Option.map_some', Function.comp_apply]
|
||||
exact getDual?_append_inr_not_withDualInOther l l2 i hl1 h'
|
||||
· rw [(l ++ l2).getDual?_eq_none_on_not_mem _ h]
|
||||
simp only [inr_mem_withDual_append_iff, not_or, not_exists] at h
|
||||
rw [l2.getDual?_eq_none_on_not_mem _ h.1, l2.getDualInOther?_eq_none_on_not_mem l _ h.2]
|
||||
rfl
|
||||
|
||||
|
||||
/-!
|
||||
|
||||
## withUniqueDualInOther append conditions
|
||||
|
||||
-/
|
||||
|
||||
lemma append_inl_not_mem_withDual_of_withDualInOther (i : Fin l.length)
|
||||
(h : appendEquiv (Sum.inl i) ∈ (l ++ l2).withUniqueDual) :
|
||||
i ∈ l.withDual ↔ ¬ i ∈ l.withDualInOther l2 := by
|
||||
apply Iff.intro
|
||||
· intro hs
|
||||
by_contra ho
|
||||
obtain ⟨j, hj⟩ := (l.mem_withDual_iff_exists).mp hs
|
||||
obtain ⟨k, hk⟩ := (l.mem_withInDualOther_iff_exists l2).mp ho
|
||||
have h1 : appendEquiv (Sum.inl j) = appendEquiv (Sum.inr k) := by
|
||||
refine (l ++ l2).eq_of_areDualInSelf_withUniqueDual ⟨appendEquiv (Sum.inl i), h⟩ ?_ ?_
|
||||
simpa using hj
|
||||
simpa using hk
|
||||
simp at h1
|
||||
· intro ho
|
||||
by_contra hs
|
||||
have h1 : appendEquiv (Sum.inl i) ∈ (l ++ l2).withDual := by
|
||||
exact (l ++ l2).mem_withDual_of_withUniqueDual ⟨appendEquiv (Sum.inl i), h⟩
|
||||
obtain ⟨j, hj⟩ := ((l ++ l2).mem_withDual_iff_exists).mp h1
|
||||
obtain ⟨k, hk⟩ := appendEquiv.surjective j
|
||||
subst hk
|
||||
match k with
|
||||
| Sum.inl k =>
|
||||
rw [mem_withDual_iff_exists] at hs
|
||||
simp_all
|
||||
| Sum.inr k =>
|
||||
rw [mem_withInDualOther_iff_exists] at ho
|
||||
simp_all
|
||||
|
||||
lemma append_inr_not_mem_withDual_of_withDualInOther (i : Fin l2.length)
|
||||
(h : appendEquiv (Sum.inr i) ∈ (l ++ l2).withUniqueDual) :
|
||||
i ∈ l2.withDual ↔ ¬ i ∈ l2.withDualInOther l := by
|
||||
apply Iff.intro
|
||||
· intro hs
|
||||
by_contra ho
|
||||
obtain ⟨j, hj⟩ := (l2.mem_withDual_iff_exists).mp hs
|
||||
obtain ⟨k, hk⟩ := (l2.mem_withInDualOther_iff_exists l).mp ho
|
||||
have h1 : appendEquiv (Sum.inr j) = appendEquiv (Sum.inl k) := by
|
||||
refine (l ++ l2).eq_of_areDualInSelf_withUniqueDual ⟨appendEquiv (Sum.inr i), h⟩ ?_ ?_
|
||||
simpa using hj
|
||||
simpa using hk
|
||||
simp at h1
|
||||
· intro ho
|
||||
by_contra hs
|
||||
have h1 : appendEquiv (Sum.inr i) ∈ (l ++ l2).withDual := by
|
||||
exact (l ++ l2).mem_withDual_of_withUniqueDual ⟨appendEquiv (Sum.inr i), h⟩
|
||||
obtain ⟨j, hj⟩ := ((l ++ l2).mem_withDual_iff_exists).mp h1
|
||||
obtain ⟨k, hk⟩ := appendEquiv.surjective j
|
||||
subst hk
|
||||
match k with
|
||||
| Sum.inl k =>
|
||||
rw [mem_withInDualOther_iff_exists] at ho
|
||||
simp_all
|
||||
| Sum.inr k =>
|
||||
rw [mem_withDual_iff_exists] at hs
|
||||
simp_all
|
||||
|
||||
|
||||
lemma append_inr_mem_withUniqueDual_of_append_inl (i : Fin l.length)
|
||||
(h : appendEquiv (Sum.inl i) ∈ (l ++ l2).withUniqueDual) :
|
||||
appendEquiv (Sum.inr i) ∈ (l2 ++ l).withUniqueDual := by
|
||||
have hinj : Function.Injective (Option.map (@appendEquiv _ _ l l2 ∘ Sum.inr)) := by
|
||||
apply Option.map_injective
|
||||
rw [@Equiv.comp_injective]
|
||||
exact Sum.inr_injective
|
||||
let h' := h
|
||||
simp [withUniqueDual] at h ⊢
|
||||
apply And.intro h.1
|
||||
intro j hj
|
||||
obtain ⟨k, hk⟩ := appendEquiv.surjective j
|
||||
subst hk
|
||||
match k with
|
||||
| Sum.inl k =>
|
||||
have h1 := h.2 (appendEquiv (Sum.inr k))
|
||||
simp at h1 hj
|
||||
have h2 := h1 hj
|
||||
by_cases hs : i ∈ l.withDual <;> rename_i hs
|
||||
· rw [l.getDual?_eq_some_getDual! ⟨i, hs⟩] at h2
|
||||
simp at h2
|
||||
· rw [l.getDual?_eq_none_on_not_mem i hs] at h2
|
||||
simp at h2
|
||||
rw [← Option.map_some', ← Option.map_some', Option.map_map] at h2
|
||||
rw [← hinj h2]
|
||||
rfl
|
||||
| Sum.inr k =>
|
||||
have h1 := h.2 (appendEquiv (Sum.inl k))
|
||||
simp at h1 hj
|
||||
have h2 := h1 hj
|
||||
by_cases hs : i ∈ l.withDual <;> rename_i hs
|
||||
· rw [l.getDual?_eq_some_getDual! ⟨i, hs⟩] at h2
|
||||
simp only [Option.map_some', Function.comp_apply, Option.or_some, Option.some.injEq,
|
||||
EmbeddingLike.apply_eq_iff_eq, Sum.inl.injEq] at h2
|
||||
have ho := (l.append_inl_not_mem_withDual_of_withDualInOther l2 i h').mp hs
|
||||
rw [l.getDualInOther?_eq_none_on_not_mem _ _ ho]
|
||||
simp only [Option.map_none', Option.none_or]
|
||||
rw [← Option.map_some', ← Option.map_some', Option.map_map, h2]
|
||||
simp [some_dual!_eq_gual?]
|
||||
· have ho := (l.append_inl_not_mem_withDual_of_withDualInOther l2 i h').mpr.mt hs
|
||||
simp at ho
|
||||
rw [l.getDualInOther?_eq_some_getDualInOther! l2 ⟨i, ho⟩] at h2 ⊢
|
||||
simp at h2
|
||||
simp
|
||||
rw [l.getDual?_eq_none_on_not_mem _ hs] at h2
|
||||
simp at h2
|
||||
|
||||
lemma withUniqueDual_iff_not_withUniqueDualInOther_of_inl_withUniqueDualInOther
|
||||
(i : Fin l.length) (h : appendEquiv (Sum.inl i) ∈ (l ++ l2).withUniqueDual) :
|
||||
i ∈ l.withUniqueDual ↔ ¬ i ∈ l.withUniqueDualInOther l2 := by
|
||||
have h' := h
|
||||
rw [withUniqueDual] at h
|
||||
simp only [Finset.mem_filter, Finset.mem_univ, inl_mem_withDual_append_iff,
|
||||
getDual?_append_inl, true_and] at h
|
||||
simp [withUniqueDual, withUniqueDualInOther]
|
||||
cases' h.1 with h1 h1
|
||||
· simp [h1]
|
||||
intro j hj
|
||||
have hj' := h.2 (appendEquiv (Sum.inl j))
|
||||
simp at hj'
|
||||
have hj'' := hj' hj
|
||||
rw [l.getDual?_eq_some_getDual! ⟨i, by rw [mem_withDual_iff_exists]; exact ⟨j, hj⟩⟩] at hj'' ⊢
|
||||
simpa using hj''
|
||||
· have hn := l.append_inl_not_mem_withDual_of_withDualInOther l2 i h'
|
||||
simp_all
|
||||
intro j hj
|
||||
have hj' := h (appendEquiv (Sum.inr j))
|
||||
simp at hj'
|
||||
have hj'' := hj' hj
|
||||
rw [l.getDual?_eq_none_on_not_mem _ hn] at hj''
|
||||
simp at hj''
|
||||
rw [l.getDualInOther?_eq_some_getDualInOther!
|
||||
l2 ⟨i, by rw [mem_withInDualOther_iff_exists]; exact ⟨j, hj⟩⟩] at hj'' ⊢
|
||||
simpa using hj''
|
||||
|
||||
lemma withUniqueDual_iff_not_withUniqueDualInOther_of_inr_withUniqueDualInOther
|
||||
(i : Fin l2.length) (h : appendEquiv (Sum.inr i) ∈ (l ++ l2).withUniqueDual) :
|
||||
i ∈ l2.withUniqueDual ↔ ¬ i ∈ l2.withUniqueDualInOther l := by
|
||||
have h' := h
|
||||
rw [withUniqueDual] at h
|
||||
simp only [Finset.mem_filter, Finset.mem_univ, inr_mem_withDual_append_iff, getDual?_append_inr,
|
||||
true_and] at h
|
||||
simp [withUniqueDual, withUniqueDualInOther]
|
||||
cases' h.1 with h1 h1
|
||||
· have hn := (l.append_inr_not_mem_withDual_of_withDualInOther l2 i h').mp h1
|
||||
simp [h1]
|
||||
intro j hj
|
||||
have hj' := h.2 (appendEquiv (Sum.inr j))
|
||||
simp at hj'
|
||||
have hj'' := hj' hj
|
||||
rw [l2.getDual?_eq_some_getDual! ⟨i, by rw [mem_withDual_iff_exists]; exact ⟨j, hj⟩⟩] at hj'' ⊢
|
||||
rw [l2.getDualInOther?_eq_none_on_not_mem _ _ hn] at hj''
|
||||
simpa using hj''
|
||||
· have hn := l.append_inr_not_mem_withDual_of_withDualInOther l2 i h'
|
||||
simp_all
|
||||
intro j hj
|
||||
have hj' := h (appendEquiv (Sum.inl j))
|
||||
simp at hj'
|
||||
have hj'' := hj' hj
|
||||
rw [l2.getDual?_eq_none_on_not_mem _ hn] at hj''
|
||||
simp at hj''
|
||||
rw [l2.getDualInOther?_eq_some_getDualInOther!
|
||||
l ⟨i, by rw [mem_withInDualOther_iff_exists]; exact ⟨j, hj⟩⟩] at hj'' ⊢
|
||||
simpa using hj''
|
||||
|
||||
lemma append_inl_mem_withUniqueDual_of_withUniqueDual (i : Fin l.length)
|
||||
(h : i ∈ l.withUniqueDual) (hn : i ∉ l.withDualInOther l2) :
|
||||
appendEquiv (Sum.inl i) ∈ (l ++ l2).withUniqueDual := by
|
||||
simp [withUniqueDual]
|
||||
apply And.intro (Or.inl (l.mem_withDual_of_withUniqueDual ⟨i, h⟩))
|
||||
intro j hj
|
||||
obtain ⟨k, hk⟩ := appendEquiv.surjective j
|
||||
subst hk
|
||||
match k with
|
||||
| Sum.inl k =>
|
||||
rw [l.getDual?_eq_some_getDual! ⟨i, l.mem_withDual_of_withUniqueDual ⟨i, h⟩⟩]
|
||||
simp
|
||||
rw [← l.eq_getDual_of_withUniqueDual_iff ⟨i, h⟩ k]
|
||||
simpa using hj
|
||||
| Sum.inr k =>
|
||||
simp at hj
|
||||
refine False.elim (hn ?_)
|
||||
exact (l.mem_withInDualOther_iff_exists _).mpr ⟨k, hj⟩
|
||||
|
||||
lemma append_inl_mem_of_withUniqueDualInOther (i : Fin l.length) (ho : i ∈ l.withUniqueDualInOther l2) :
|
||||
appendEquiv (Sum.inl i) ∈ (l ++ l2).withUniqueDual := by
|
||||
simp [withUniqueDual]
|
||||
apply And.intro (Or.inr (l.mem_withDualInOther_of_withUniqueDualInOther l2 ⟨i, ho⟩))
|
||||
intro j hj
|
||||
obtain ⟨k, hk⟩ := appendEquiv.surjective j
|
||||
subst hk
|
||||
have hs := l.not_mem_withDual_of_withUniqueDualInOther l2 ⟨i, ho⟩
|
||||
rw [l.getDual?_eq_none_on_not_mem _ hs]
|
||||
rw [l.getDualInOther?_eq_some_getDualInOther! l2
|
||||
⟨i, (l.mem_withDualInOther_of_withUniqueDualInOther l2 ⟨i, ho⟩)⟩]
|
||||
match k with
|
||||
| Sum.inl k =>
|
||||
refine False.elim (hs ?_)
|
||||
simp at hj
|
||||
exact (l.mem_withDual_iff_exists).mpr ⟨k, hj⟩
|
||||
| Sum.inr k =>
|
||||
simp at hj
|
||||
simp
|
||||
erw [← l.eq_getDualInOther_of_withUniqueDual_iff l2 ⟨i, ho⟩ k]
|
||||
simpa using hj
|
||||
|
||||
@[simp]
|
||||
lemma append_inl_mem_withUniqueDual_iff (i : Fin l.length) :
|
||||
appendEquiv (Sum.inl i) ∈ (l ++ l2).withUniqueDual ↔
|
||||
((i ∈ l.withUniqueDual ∧ i ∉ l.withDualInOther l2) ↔ ¬ i ∈ l.withUniqueDualInOther l2) := by
|
||||
apply Iff.intro
|
||||
· intro h
|
||||
apply Iff.intro
|
||||
· intro hs
|
||||
exact (l.withUniqueDual_iff_not_withUniqueDualInOther_of_inl_withUniqueDualInOther l2 i
|
||||
h).mp hs.1
|
||||
· intro ho
|
||||
have hs := ((l.withUniqueDual_iff_not_withUniqueDualInOther_of_inl_withUniqueDualInOther l2 i
|
||||
h).mpr ho)
|
||||
apply And.intro hs
|
||||
refine (l.append_inl_not_mem_withDual_of_withDualInOther l2 i h).mp ?_
|
||||
exact (l.mem_withDual_of_withUniqueDual ⟨i, hs⟩)
|
||||
· intro h
|
||||
by_cases ho : i ∈ l.withUniqueDualInOther l2
|
||||
· exact append_inl_mem_of_withUniqueDualInOther l l2 i ho
|
||||
· exact append_inl_mem_withUniqueDual_of_withUniqueDual l l2 i (h.mpr ho).1 (h.mpr ho).2
|
||||
|
||||
lemma append_inl_mem_withUniqueDual_of_append_inr (i : Fin l.length)
|
||||
(h : appendEquiv (Sum.inr i) ∈ (l2 ++ l).withUniqueDual) :
|
||||
appendEquiv (Sum.inl i) ∈ (l ++ l2).withUniqueDual := by
|
||||
simp
|
||||
apply Iff.intro
|
||||
· intro hs
|
||||
exact (l2.withUniqueDual_iff_not_withUniqueDualInOther_of_inr_withUniqueDualInOther
|
||||
l i h).mp hs.1
|
||||
· intro ho
|
||||
have hs := (l2.withUniqueDual_iff_not_withUniqueDualInOther_of_inr_withUniqueDualInOther
|
||||
l i h).mpr ho
|
||||
apply And.intro hs
|
||||
refine (l2.append_inr_not_mem_withDual_of_withDualInOther l i h).mp ?_
|
||||
exact (l.mem_withDual_of_withUniqueDual ⟨i, hs⟩)
|
||||
|
||||
lemma append_mem_withUniqueDual_symm (i : Fin l.length) :
|
||||
appendEquiv (Sum.inl i) ∈ (l ++ l2).withUniqueDual ↔
|
||||
appendEquiv (Sum.inr i) ∈ (l2 ++ l).withUniqueDual := by
|
||||
apply Iff.intro
|
||||
· intro h'
|
||||
exact append_inr_mem_withUniqueDual_of_append_inl l l2 i h'
|
||||
· intro h'
|
||||
exact append_inl_mem_withUniqueDual_of_append_inr l l2 i h'
|
||||
|
||||
@[simp]
|
||||
lemma append_inr_mem_withUniqueDual_iff (i : Fin l2.length) :
|
||||
appendEquiv (Sum.inr i) ∈ (l ++ l2).withUniqueDual ↔
|
||||
((i ∈ l2.withUniqueDual ∧ i ∉ l2.withDualInOther l) ↔ ¬ i ∈ l2.withUniqueDualInOther l) := by
|
||||
rw [← append_mem_withUniqueDual_symm]
|
||||
simp
|
||||
|
||||
|
||||
end IndexList
|
||||
|
||||
end IndexNotation
|
|
@ -191,10 +191,10 @@ def colorMap : Fin l.numIndices → X :=
|
|||
fun i => (l.get i).toColor
|
||||
|
||||
/-- The map of from `Fin s.numIndices` into the natural numbers associated to an index list. -/
|
||||
def idMap : Fin l.numIndices → Nat :=
|
||||
def idMap : Fin l.length → Nat :=
|
||||
fun i => (l.get i).id
|
||||
|
||||
lemma idMap_cast {l1 l2 : IndexList X} (h : l1 = l2) (i : Fin l1.numIndices) :
|
||||
lemma idMap_cast {l1 l2 : IndexList X} (h : l1 = l2) (i : Fin l1.length) :
|
||||
l1.idMap i = l2.idMap (Fin.cast (by rw [h]) i) := by
|
||||
subst h
|
||||
rfl
|
||||
|
@ -249,47 +249,6 @@ lemma fromFinMap_numIndices {n : ℕ} (f : Fin n → Index X) :
|
|||
simp [fromFinMap, numIndices]
|
||||
|
||||
|
||||
/-!
|
||||
|
||||
## Appending index lists.
|
||||
|
||||
-/
|
||||
instance : HAppend (IndexList X) (IndexList X) (IndexList X) :=
|
||||
@instHAppendOfAppend (List (Index X)) List.instAppend
|
||||
|
||||
def appendEquiv {l l2 : IndexList X} : Fin l.length ⊕ Fin l2.length ≃ Fin (l ++ l2).length :=
|
||||
finSumFinEquiv.trans (Fin.castOrderIso (List.length_append _ _).symm).toEquiv
|
||||
|
||||
@[simp]
|
||||
lemma idMap_append_inl {l l2 : IndexList X} (i : Fin l.length) :
|
||||
(l ++ l2).idMap (appendEquiv (Sum.inl i)) = l.idMap i := by
|
||||
simp [appendEquiv, idMap]
|
||||
rw [List.getElem_append_left]
|
||||
|
||||
@[simp]
|
||||
lemma idMap_append_inr {l l2 : IndexList X} (i : Fin l2.length) :
|
||||
(l ++ l2).idMap (appendEquiv (Sum.inr i)) = l2.idMap i := by
|
||||
simp [appendEquiv, idMap]
|
||||
rw [List.getElem_append_right]
|
||||
simp
|
||||
omega
|
||||
omega
|
||||
|
||||
@[simp]
|
||||
lemma colorMap_append_inl {l l2 : IndexList X} (i : Fin l.length) :
|
||||
(l ++ l2).colorMap (appendEquiv (Sum.inl i)) = l.colorMap i := by
|
||||
simp [appendEquiv, colorMap]
|
||||
rw [List.getElem_append_left]
|
||||
|
||||
@[simp]
|
||||
lemma colorMap_append_inr {l l2 : IndexList X} (i : Fin l2.length) :
|
||||
(l ++ l2).colorMap (appendEquiv (Sum.inr i)) = l2.colorMap i := by
|
||||
simp [appendEquiv, colorMap]
|
||||
rw [List.getElem_append_right]
|
||||
simp
|
||||
omega
|
||||
omega
|
||||
|
||||
end IndexList
|
||||
|
||||
end IndexNotation
|
||||
|
|
|
@ -32,11 +32,11 @@ def AreDualInSelf (i j : Fin l.length) : Prop :=
|
|||
instance (i j : Fin l.length) : Decidable (l.AreDualInSelf i j) :=
|
||||
instDecidableAnd
|
||||
|
||||
def AreDualInOther {l : IndexList X} {l2 : IndexList X} (i : Fin l.length) (j : Fin l2.length) :
|
||||
def AreDualInOther (i : Fin l.length) (j : Fin l2.length) :
|
||||
Prop := l.idMap i = l2.idMap j
|
||||
|
||||
instance {l : IndexList X} {l2 : IndexList X} (i : Fin l.length) (j : Fin l2.length) :
|
||||
Decidable (AreDualInOther i j) := (l.idMap i).decEq (l2.idMap j)
|
||||
Decidable (l.AreDualInOther l2 i j) := (l.idMap i).decEq (l2.idMap j)
|
||||
|
||||
|
||||
namespace AreDualInSelf
|
||||
|
@ -52,29 +52,6 @@ lemma symm (h : l.AreDualInSelf i j) : l.AreDualInSelf j i := by
|
|||
lemma self_false (i : Fin l.length) : ¬ l.AreDualInSelf i i := by
|
||||
simp [AreDualInSelf]
|
||||
|
||||
@[simp]
|
||||
lemma append_inl_inl : (l ++ l2).AreDualInSelf (appendEquiv (Sum.inl i)) (appendEquiv (Sum.inl j))
|
||||
↔ l.AreDualInSelf i j := by
|
||||
simp [AreDualInSelf]
|
||||
|
||||
@[simp]
|
||||
lemma append_inr_inr (l l2 : IndexList X) (i j : Fin l2.length) :
|
||||
(l ++ l2).AreDualInSelf (appendEquiv (Sum.inr i)) (appendEquiv (Sum.inr j))
|
||||
↔ l2.AreDualInSelf i j := by
|
||||
simp [AreDualInSelf]
|
||||
|
||||
@[simp]
|
||||
lemma append_inl_inr (l l2 : IndexList X) (i : Fin l.length) (j : Fin l2.length) :
|
||||
(l ++ l2).AreDualInSelf (appendEquiv (Sum.inl i)) (appendEquiv (Sum.inr j)) =
|
||||
AreDualInOther i j := by
|
||||
simp [AreDualInSelf, AreDualInOther]
|
||||
|
||||
@[simp]
|
||||
lemma append_inr_inl (l l2 : IndexList X) (i : Fin l2.length) (j : Fin l.length) :
|
||||
(l ++ l2).AreDualInSelf (appendEquiv (Sum.inr i)) (appendEquiv (Sum.inl j)) =
|
||||
AreDualInOther i j := by
|
||||
simp [AreDualInSelf, AreDualInOther]
|
||||
|
||||
end AreDualInSelf
|
||||
|
||||
namespace AreDualInOther
|
||||
|
@ -82,7 +59,7 @@ namespace AreDualInOther
|
|||
variable {l l2 : IndexList X} {i : Fin l.length} {j : Fin l2.length}
|
||||
|
||||
@[symm]
|
||||
lemma symm (h : AreDualInOther i j) : AreDualInOther j i := by
|
||||
lemma symm (h : l.AreDualInOther l2 i j) : l2.AreDualInOther l j i := by
|
||||
rw [AreDualInOther] at h ⊢
|
||||
exact h.symm
|
||||
|
||||
|
@ -90,13 +67,552 @@ end AreDualInOther
|
|||
|
||||
/-!
|
||||
|
||||
## The getDual? Function
|
||||
|
||||
-/
|
||||
|
||||
/-- Given an `i`, if a dual exists in the same list,
|
||||
outputs the first such dual, otherwise outputs `none`. -/
|
||||
def getDual? (i : Fin l.length) : Option (Fin l.length) :=
|
||||
Fin.find (fun j => l.AreDualInSelf i j)
|
||||
|
||||
/-- Given an `i`, if a dual exists in the other list,
|
||||
outputs the first such dual, otherwise outputs `none`. -/
|
||||
def getDualInOther? (i : Fin l.length) : Option (Fin l2.length) :=
|
||||
Fin.find (fun j => l.AreDualInOther l2 i j)
|
||||
|
||||
/-!
|
||||
|
||||
## With dual self.
|
||||
|
||||
-/
|
||||
|
||||
def withDual : Finset (Fin l.length) :=
|
||||
Finset.filter (fun i => (l.getDual? i).isSome) Finset.univ
|
||||
|
||||
lemma mem_withDual_iff_exists : i ∈ l.withDual ↔ ∃ j, l.AreDualInSelf i j := by
|
||||
simp [withDual, Finset.mem_filter, Finset.mem_univ, getDual?]
|
||||
rw [Fin.isSome_find_iff]
|
||||
|
||||
lemma getDual?_of_areDualInSelf (h : l.AreDualInSelf i j) :
|
||||
l.getDual? j = i ∨ l.getDual? i = j ∨ l.getDual? j = l.getDual? i := by
|
||||
have h3 : (l.getDual? i).isSome := by
|
||||
simpa [getDual?, Fin.isSome_find_iff] using ⟨j, h⟩
|
||||
obtain ⟨k, hk⟩ := Option.isSome_iff_exists.mp h3
|
||||
rw [hk]
|
||||
rw [getDual?, Fin.find_eq_some_iff] at hk
|
||||
by_cases hik : i < k
|
||||
· apply Or.inl
|
||||
rw [getDual?, Fin.find_eq_some_iff]
|
||||
apply And.intro h.symm
|
||||
intro k' hk'
|
||||
by_cases hik' : i = k'
|
||||
subst hik'
|
||||
rfl
|
||||
have hik'' : l.AreDualInSelf i k' := by
|
||||
simp [AreDualInSelf, hik']
|
||||
simp_all [AreDualInSelf]
|
||||
have hk'' := hk.2 k' hik''
|
||||
exact (lt_of_lt_of_le hik hk'').le
|
||||
· by_cases hjk : j ≤ k
|
||||
· apply Or.inr
|
||||
apply Or.inl
|
||||
have hj := hk.2 j h
|
||||
simp
|
||||
omega
|
||||
· apply Or.inr
|
||||
apply Or.inr
|
||||
rw [getDual?, Fin.find_eq_some_iff]
|
||||
apply And.intro
|
||||
· simp_all [AreDualInSelf]
|
||||
exact Fin.ne_of_gt hjk
|
||||
intro k' hk'
|
||||
by_cases hik' : i = k'
|
||||
subst hik'
|
||||
exact Lean.Omega.Fin.le_of_not_lt hik
|
||||
have hik'' : l.AreDualInSelf i k' := by
|
||||
simp [AreDualInSelf, hik']
|
||||
simp_all [AreDualInSelf]
|
||||
exact hk.2 k' hik''
|
||||
|
||||
|
||||
def getDual! (i : l.withDual) : Fin l.length :=
|
||||
(l.getDual? i).get (by simpa [withDual] using i.2)
|
||||
|
||||
lemma getDual?_eq_some_getDual! (i : l.withDual) : l.getDual? i = some (l.getDual! i) := by
|
||||
simp [getDual!]
|
||||
|
||||
lemma getDual?_eq_none_on_not_mem (i : Fin l.length) (h : i ∉ l.withDual) :
|
||||
l.getDual? i = none := by
|
||||
simpa [withDual, getDual?, Fin.find_eq_none_iff] using h
|
||||
|
||||
lemma some_dual!_eq_gual? (i : l.withDual) : some (l.getDual! i) = l.getDual? i := by
|
||||
rw [getDual?_eq_some_getDual!]
|
||||
|
||||
lemma areDualInSelf_getDual! (i : l.withDual) : l.AreDualInSelf i (l.getDual! i) := by
|
||||
have h := l.getDual?_eq_some_getDual! i
|
||||
rw [getDual?, Fin.find_eq_some_iff] at h
|
||||
exact h.1
|
||||
|
||||
@[simp]
|
||||
lemma getDual!_id (i : l.withDual) : l.idMap (l.getDual! i) = l.idMap i := by
|
||||
simpa using (l.areDualInSelf_getDual! i).2.symm
|
||||
|
||||
lemma getDual_mem_withDual (i : l.withDual) : l.getDual! i ∈ l.withDual := by
|
||||
simp only [withDual, Finset.mem_filter, Finset.mem_univ, true_and]
|
||||
rw [getDual?, Fin.isSome_find_iff]
|
||||
exact ⟨i, (l.areDualInSelf_getDual! i).symm⟩
|
||||
|
||||
def getDual (i : l.withDual) : l.withDual := ⟨l.getDual! i, l.getDual_mem_withDual i⟩
|
||||
|
||||
@[simp]
|
||||
lemma getDual_id (i : l.withDual) :
|
||||
l.idMap (l.getDual i) = l.idMap i := by
|
||||
simp [getDual]
|
||||
|
||||
/-!
|
||||
|
||||
## With dual other.
|
||||
|
||||
-/
|
||||
|
||||
def withDualInOther : Finset (Fin l.length) :=
|
||||
Finset.filter (fun i => (l.getDualInOther? l2 i).isSome) Finset.univ
|
||||
|
||||
lemma mem_withInDualOther_iff_exists :
|
||||
i ∈ l.withDualInOther l2 ↔ ∃ (j : Fin l2.length), l.AreDualInOther l2 i j := by
|
||||
simp [withDualInOther, Finset.mem_filter, Finset.mem_univ, getDualInOther?]
|
||||
rw [Fin.isSome_find_iff]
|
||||
|
||||
def getDualInOther! (i : l.withDualInOther l2) : Fin l2.length :=
|
||||
(l.getDualInOther? l2 i).get (by simpa [withDualInOther] using i.2)
|
||||
|
||||
|
||||
lemma getDualInOther?_eq_some_getDualInOther! (i : l.withDualInOther l2) :
|
||||
l.getDualInOther? l2 i = some (l.getDualInOther! l2 i) := by
|
||||
simp [getDualInOther!]
|
||||
|
||||
lemma getDualInOther?_eq_none_on_not_mem (i : Fin l.length) (h : i ∉ l.withDualInOther l2) :
|
||||
l.getDualInOther? l2 i = none := by
|
||||
simpa [getDualInOther?, Fin.find_eq_none_iff, mem_withInDualOther_iff_exists] using h
|
||||
|
||||
|
||||
lemma areDualInOther_getDualInOther! (i : l.withDualInOther l2) :
|
||||
l.AreDualInOther l2 i (l.getDualInOther! l2 i) := by
|
||||
have h := l.getDualInOther?_eq_some_getDualInOther! l2 i
|
||||
rw [getDualInOther?, Fin.find_eq_some_iff] at h
|
||||
exact h.1
|
||||
|
||||
@[simp]
|
||||
lemma getDualInOther!_id (i : l.withDualInOther l2) :
|
||||
l2.idMap (l.getDualInOther! l2 i) = l.idMap i := by
|
||||
simpa using (l.areDualInOther_getDualInOther! l2 i).symm
|
||||
|
||||
lemma getDualInOther_mem_withDualInOther (i : l.withDualInOther l2) :
|
||||
l.getDualInOther! l2 i ∈ l2.withDualInOther l :=
|
||||
(l2.mem_withInDualOther_iff_exists l).mpr ⟨i, (areDualInOther_getDualInOther! l l2 i).symm⟩
|
||||
|
||||
def getDualInOther (i : l.withDualInOther l2) : l2.withDualInOther l :=
|
||||
⟨l.getDualInOther! l2 i, l.getDualInOther_mem_withDualInOther l2 i⟩
|
||||
|
||||
@[simp]
|
||||
lemma getDualInOther_id (i : l.withDualInOther l2) :
|
||||
l2.idMap (l.getDualInOther l2 i) = l.idMap i := by
|
||||
simp [getDualInOther]
|
||||
|
||||
lemma getDualInOther_coe (i : l.withDualInOther l2) :
|
||||
(l.getDualInOther l2 i).1 = l.getDualInOther! l2 i := by
|
||||
rfl
|
||||
|
||||
|
||||
/-!
|
||||
|
||||
## Has single dual in self.
|
||||
|
||||
-/
|
||||
|
||||
|
||||
def withUniqueDual : Finset (Fin l.length) :=
|
||||
Finset.filter (fun i => i ∈ l.withDual ∧
|
||||
∀ j, l.AreDualInSelf i j → j = l.getDual? i) Finset.univ
|
||||
|
||||
lemma mem_withDual_of_withUniqueDual (i : l.withUniqueDual) :
|
||||
i.1 ∈ l.withDual := by
|
||||
have hi := i.2
|
||||
simp [withUniqueDual, Finset.mem_filter, Finset.mem_univ] at hi
|
||||
exact hi.1
|
||||
|
||||
def fromWithUnique (i : l.withUniqueDual) : l.withDual :=
|
||||
⟨i.1, l.mem_withDual_of_withUniqueDual i⟩
|
||||
|
||||
instance : Coe l.withUniqueDual l.withDual where
|
||||
coe i := ⟨i.1, l.mem_withDual_of_withUniqueDual i⟩
|
||||
|
||||
@[simp]
|
||||
lemma fromWithUnique_coe (i : l.withUniqueDual) : (l.fromWithUnique i).1 = i.1 := by
|
||||
rfl
|
||||
|
||||
lemma all_dual_eq_getDual_of_withUniqueDual (i : l.withUniqueDual) :
|
||||
∀ j, l.AreDualInSelf i j → j = l.getDual! i := by
|
||||
have hi := i.2
|
||||
simp [withUniqueDual] at hi
|
||||
intro j hj
|
||||
simpa [getDual!, fromWithUnique] using (Option.get_of_mem _ (hi.2 j hj ).symm).symm
|
||||
|
||||
lemma eq_of_areDualInSelf_withUniqueDual {j k : Fin l.length} (i : l.withUniqueDual)
|
||||
(hj : l.AreDualInSelf i j) (hk : l.AreDualInSelf i k) :
|
||||
j = k := by
|
||||
have hj' := all_dual_eq_getDual_of_withUniqueDual l i j hj
|
||||
have hk' := all_dual_eq_getDual_of_withUniqueDual l i k hk
|
||||
rw [hj', hk']
|
||||
|
||||
lemma eq_getDual_of_withUniqueDual_iff (i : l.withUniqueDual) (j : Fin l.length) :
|
||||
l.AreDualInSelf i j ↔ j = l.getDual! i := by
|
||||
apply Iff.intro
|
||||
intro h
|
||||
exact (l.all_dual_eq_getDual_of_withUniqueDual i) j h
|
||||
intro h
|
||||
subst h
|
||||
exact areDualInSelf_getDual! l i
|
||||
|
||||
@[simp]
|
||||
lemma getDual!_getDual_of_withUniqueDual (i : l.withUniqueDual) :
|
||||
l.getDual! (l.getDual i) = i := by
|
||||
by_contra hn
|
||||
have h' : l.AreDualInSelf i (l.getDual! (l.getDual i)) := by
|
||||
simp [AreDualInSelf, hn]
|
||||
simp_all [AreDualInSelf, getDual, fromWithUnique]
|
||||
exact fun a => hn (id (Eq.symm a))
|
||||
rw [eq_getDual_of_withUniqueDual_iff] at h'
|
||||
have hx := l.areDualInSelf_getDual! (l.getDual i)
|
||||
simp_all [getDual]
|
||||
|
||||
@[simp]
|
||||
lemma getDual_getDual_of_withUniqueDual (i : l.withUniqueDual) :
|
||||
l.getDual (l.getDual i) = l.fromWithUnique i :=
|
||||
SetCoe.ext (getDual!_getDual_of_withUniqueDual l i)
|
||||
|
||||
@[simp]
|
||||
lemma getDual?_getDual!_of_withUniqueDual (i : l.withUniqueDual) :
|
||||
l.getDual? (l.getDual! i) = some i := by
|
||||
change l.getDual? (l.getDual i) = some i
|
||||
rw [getDual?_eq_some_getDual!]
|
||||
simp
|
||||
|
||||
@[simp]
|
||||
lemma getDual?_getDual?_of_withUniqueDualInOther (i : l.withUniqueDual) :
|
||||
(l.getDual? i).bind l.getDual? = some i := by
|
||||
rw [getDual?_eq_some_getDual! l i]
|
||||
simp
|
||||
|
||||
|
||||
lemma getDual_of_withUniqueDual_mem (i : l.withUniqueDual) :
|
||||
l.getDual! i ∈ l.withUniqueDual := by
|
||||
simp [withUniqueDual]
|
||||
apply And.intro (getDual_mem_withDual l ⟨↑i, mem_withDual_of_withUniqueDual l i⟩)
|
||||
intro j hj
|
||||
have h1 : i = j := by
|
||||
by_contra hn
|
||||
have h' : l.AreDualInSelf i j := by
|
||||
simp [AreDualInSelf, hn]
|
||||
simp_all [AreDualInSelf, getDual, fromWithUnique]
|
||||
rw [eq_getDual_of_withUniqueDual_iff] at h'
|
||||
subst h'
|
||||
simp_all [getDual]
|
||||
subst h1
|
||||
rfl
|
||||
|
||||
def getDualEquiv : l.withUniqueDual ≃ l.withUniqueDual where
|
||||
toFun x := ⟨l.getDual x, l.getDual_of_withUniqueDual_mem x⟩
|
||||
invFun x := ⟨l.getDual x, l.getDual_of_withUniqueDual_mem x⟩
|
||||
left_inv x := SetCoe.ext (by
|
||||
simp only [Subtype.coe_eta, getDual_getDual_of_withUniqueDual]
|
||||
rfl)
|
||||
right_inv x := SetCoe.ext (by
|
||||
simp only [Subtype.coe_eta, getDual_getDual_of_withUniqueDual]
|
||||
rfl)
|
||||
|
||||
@[simp]
|
||||
lemma getDualEquiv_involutive : Function.Involutive l.getDualEquiv := by
|
||||
intro x
|
||||
simp [getDualEquiv, fromWithUnique]
|
||||
|
||||
|
||||
/-!
|
||||
|
||||
## Has single in other.
|
||||
|
||||
-/
|
||||
|
||||
def withUniqueDualInOther : Finset (Fin l.length) :=
|
||||
Finset.filter (fun i => i ∉ l.withDual ∧ i ∈ l.withDualInOther l2
|
||||
∧ (∀ j, l.AreDualInOther l2 i j → j = l.getDualInOther? l2 i)) Finset.univ
|
||||
|
||||
lemma not_mem_withDual_of_withUniqueDualInOther (i : l.withUniqueDualInOther l2) :
|
||||
i.1 ∉ l.withDual := by
|
||||
have hi := i.2
|
||||
simp only [withUniqueDualInOther, Finset.univ_eq_attach, Finset.mem_filter, Finset.mem_attach,
|
||||
true_and] at hi
|
||||
exact hi.2.1
|
||||
|
||||
lemma mem_withDualInOther_of_withUniqueDualInOther (i : l.withUniqueDualInOther l2) :
|
||||
i.1 ∈ l.withDualInOther l2 := by
|
||||
have hi := i.2
|
||||
simp only [withUniqueDualInOther, Finset.univ_eq_attach, Finset.mem_filter, Finset.mem_attach,
|
||||
true_and] at hi
|
||||
exact hi.2.2.1
|
||||
|
||||
def fromWithUniqueDualInOther (i : l.withUniqueDualInOther l2) : l.withDualInOther l2 :=
|
||||
⟨i.1, l.mem_withDualInOther_of_withUniqueDualInOther l2 i⟩
|
||||
|
||||
instance : Coe (l.withUniqueDualInOther l2) (l.withDualInOther l2) where
|
||||
coe i := ⟨i.1, l.mem_withDualInOther_of_withUniqueDualInOther l2 i⟩
|
||||
|
||||
lemma all_dual_eq_of_withUniqueDualInOther (i : l.withUniqueDualInOther l2) :
|
||||
∀ j, l.AreDualInOther l2 i j → j = l.getDualInOther! l2 i := by
|
||||
have hi := i.2
|
||||
simp only [withUniqueDualInOther, Finset.univ_eq_attach, Finset.mem_filter, Finset.mem_attach,
|
||||
true_and] at hi
|
||||
intro j hj
|
||||
refine (Option.get_of_mem _ (hi.2.2.2 j hj).symm).symm
|
||||
|
||||
lemma eq_getDualInOther_of_withUniqueDual_iff (i : l.withUniqueDualInOther l2) (j : Fin l2.length) :
|
||||
l.AreDualInOther l2 i j ↔ j = l.getDualInOther! l2 i := by
|
||||
apply Iff.intro
|
||||
intro h
|
||||
exact l.all_dual_eq_of_withUniqueDualInOther l2 i j h
|
||||
intro h
|
||||
subst h
|
||||
exact areDualInOther_getDualInOther! l l2 i
|
||||
|
||||
@[simp]
|
||||
lemma getDualInOther!_getDualInOther_of_withUniqueDualInOther (i : l.withUniqueDualInOther l2) :
|
||||
l2.getDualInOther! l (l.getDualInOther l2 i) = i := by
|
||||
by_contra hn
|
||||
refine (l.not_mem_withDual_of_withUniqueDualInOther l2 i)
|
||||
(l.mem_withDual_iff_exists.mpr ⟨(l2.getDualInOther! l (l.getDualInOther l2 i)), ?_⟩ )
|
||||
simp [AreDualInSelf, hn]
|
||||
exact (fun a => hn (id (Eq.symm a)))
|
||||
|
||||
@[simp]
|
||||
lemma getDualInOther_getDualInOther_of_withUniqueDualInOther (i : l.withUniqueDualInOther l2) :
|
||||
l2.getDualInOther l (l.getDualInOther l2 i) = i :=
|
||||
SetCoe.ext (getDualInOther!_getDualInOther_of_withUniqueDualInOther l l2 i)
|
||||
|
||||
@[simp]
|
||||
lemma getDualInOther?_getDualInOther!_of_withUniqueDualInOther (i : l.withUniqueDualInOther l2) :
|
||||
l2.getDualInOther? l (l.getDualInOther! l2 i) = some i := by
|
||||
change l2.getDualInOther? l (l.getDualInOther l2 i) = some i
|
||||
rw [getDualInOther?_eq_some_getDualInOther!]
|
||||
simp
|
||||
|
||||
lemma getDualInOther_of_withUniqueDualInOther_not_mem_of_withDual (i : l.withUniqueDualInOther l2) :
|
||||
(l.getDualInOther l2 i).1 ∉ l2.withDual := by
|
||||
rw [mem_withDual_iff_exists]
|
||||
simp
|
||||
intro j
|
||||
simp [AreDualInSelf]
|
||||
intro hj
|
||||
by_contra hn
|
||||
have hn' : l.AreDualInOther l2 i j := by
|
||||
simp [AreDualInOther, hn, hj]
|
||||
rw [eq_getDualInOther_of_withUniqueDual_iff] at hn'
|
||||
simp_all
|
||||
simp only [getDualInOther_coe, not_true_eq_false] at hj
|
||||
|
||||
lemma getDualInOther_of_withUniqueDualInOther_mem (i : l.withUniqueDualInOther l2) :
|
||||
(l.getDualInOther l2 i).1 ∈ l2.withUniqueDualInOther l := by
|
||||
simp only [withUniqueDualInOther, Finset.mem_filter, Finset.mem_univ, true_and]
|
||||
apply And.intro (l.getDualInOther_of_withUniqueDualInOther_not_mem_of_withDual l2 i)
|
||||
apply And.intro
|
||||
exact Finset.coe_mem
|
||||
(l.getDualInOther l2 ⟨↑i, mem_withDualInOther_of_withUniqueDualInOther l l2 i⟩)
|
||||
intro j hj
|
||||
by_contra hn
|
||||
have h' : l.AreDualInSelf i j := by
|
||||
simp [AreDualInSelf, hn]
|
||||
simp_all [AreDualInOther, getDual]
|
||||
simp [getDualInOther_coe] at hn
|
||||
exact fun a => hn (id (Eq.symm a))
|
||||
have hi := l.not_mem_withDual_of_withUniqueDualInOther l2 i
|
||||
rw [mem_withDual_iff_exists] at hi
|
||||
simp_all
|
||||
|
||||
def getDualInOtherEquiv : l.withUniqueDualInOther l2 ≃ l2.withUniqueDualInOther l where
|
||||
toFun x := ⟨l.getDualInOther l2 x, l.getDualInOther_of_withUniqueDualInOther_mem l2 x⟩
|
||||
invFun x := ⟨l2.getDualInOther l x, l2.getDualInOther_of_withUniqueDualInOther_mem l x⟩
|
||||
left_inv x := SetCoe.ext (by simp)
|
||||
right_inv x := SetCoe.ext (by simp)
|
||||
|
||||
/-!
|
||||
|
||||
## Equality of withUnqiueDual and withDual
|
||||
|
||||
-/
|
||||
|
||||
lemma withUnqiueDual_eq_withDual_iff_unique_forall :
|
||||
l.withUniqueDual = l.withDual ↔
|
||||
∀ (i : l.withDual) j, l.AreDualInSelf i j → j = l.getDual? i := by
|
||||
apply Iff.intro
|
||||
· intro h i j hj
|
||||
rw [@Finset.ext_iff] at h
|
||||
simp [withUniqueDual] at h
|
||||
exact h i i.2 j hj
|
||||
· intro h
|
||||
apply Finset.ext
|
||||
intro i
|
||||
apply Iff.intro
|
||||
· intro hi
|
||||
simp [withUniqueDual] at hi
|
||||
exact hi.1
|
||||
· intro hi
|
||||
simp [withUniqueDual]
|
||||
apply And.intro hi
|
||||
intro j hj
|
||||
exact h ⟨i, hi⟩ j hj
|
||||
|
||||
|
||||
lemma withUnqiueDual_eq_withDual_iff :
|
||||
l.withUniqueDual = l.withDual ↔
|
||||
∀ i, (l.getDual? i).bind l.getDual? = Option.guard (fun i => i ∈ l.withDual) i := by
|
||||
apply Iff.intro
|
||||
· intro h i
|
||||
by_cases hi : i ∈ l.withDual
|
||||
· have hii : i ∈ l.withUniqueDual := by
|
||||
simp_all only
|
||||
change (l.getDual? i).bind l.getDual? = _
|
||||
rw [getDual?_getDual?_of_withUniqueDualInOther l ⟨i, hii⟩]
|
||||
simp
|
||||
symm
|
||||
rw [Option.guard_eq_some]
|
||||
exact ⟨rfl, hi⟩
|
||||
· rw [getDual?_eq_none_on_not_mem l i hi]
|
||||
simp
|
||||
symm
|
||||
simpa only [Option.guard, ite_eq_right_iff, imp_false] using hi
|
||||
· intro h
|
||||
rw [withUnqiueDual_eq_withDual_iff_unique_forall]
|
||||
intro i j hj
|
||||
rcases l.getDual?_of_areDualInSelf hj with hi | hi | hi
|
||||
· have hj' := h j
|
||||
rw [hi] at hj'
|
||||
simp at hj'
|
||||
rw [hj']
|
||||
symm
|
||||
rw [Option.guard_eq_some]
|
||||
exact ⟨rfl, l.mem_withDual_iff_exists.mpr ⟨i, hj.symm⟩⟩
|
||||
· exact hi.symm
|
||||
· have hj' := h j
|
||||
rw [hi] at hj'
|
||||
rw [h i] at hj'
|
||||
have hi : Option.guard (fun i => i ∈ l.withDual) ↑i = some i := by
|
||||
apply Option.guard_eq_some.mpr
|
||||
simp
|
||||
rw [hi] at hj'
|
||||
simp at hj'
|
||||
have hj'' := Option.guard_eq_some.mp hj'.symm
|
||||
have hj''' := hj''.1
|
||||
rw [hj'''] at hj
|
||||
simp at hj
|
||||
|
||||
lemma withUnqiueDual_eq_withDual_iff_list_apply :
|
||||
l.withUniqueDual = l.withDual ↔
|
||||
(Fin.list l.length).map (fun i => (l.getDual? i).bind l.getDual?) =
|
||||
(Fin.list l.length).map (fun i => Option.guard (fun i => i ∈ l.withDual) i) := by
|
||||
rw [withUnqiueDual_eq_withDual_iff]
|
||||
apply Iff.intro
|
||||
intro h
|
||||
apply congrFun
|
||||
apply congrArg
|
||||
exact (Set.eqOn_univ (fun i => (l.getDual? i).bind l.getDual?) fun i =>
|
||||
Option.guard (fun i => i ∈ l.withDual) i).mp fun ⦃x⦄ _ => h x
|
||||
intro h
|
||||
intro i
|
||||
simp only [List.map_inj_left] at h
|
||||
have h1 {n : ℕ} (m : Fin n) : m ∈ Fin.list n := by
|
||||
have h1' : (Fin.list n)[m] = m := Fin.getElem_list _ _
|
||||
exact h1' ▸ List.getElem_mem _ _ _
|
||||
exact h i (h1 i)
|
||||
|
||||
def withUnqiueDualEqWithDualBool : Bool :=
|
||||
if (Fin.list l.length).map (fun i => (l.getDual? i).bind l.getDual?) =
|
||||
(Fin.list l.length).map (fun i => Option.guard (fun i => i ∈ l.withDual) i) then
|
||||
true
|
||||
else
|
||||
false
|
||||
|
||||
lemma withUnqiueDual_eq_withDual_iff_list_apply_bool :
|
||||
l.withUniqueDual = l.withDual ↔ l.withUnqiueDualEqWithDualBool := by
|
||||
rw [withUnqiueDual_eq_withDual_iff_list_apply]
|
||||
apply Iff.intro
|
||||
intro h
|
||||
simp [withUnqiueDualEqWithDualBool, h]
|
||||
intro h
|
||||
simpa [withUnqiueDualEqWithDualBool] using h
|
||||
|
||||
|
||||
|
||||
/-
|
||||
|
||||
def withoutDual : Finset (Fin l.length) :=
|
||||
Finset.filter (fun i => (l.getDual? i).isNone) Finset.univ
|
||||
|
||||
|
||||
def withoutDualOther : Finset (Fin l.length) :=
|
||||
Finset.filter (fun i => (l.getDualInOther? l2 i).isNone) Finset.univ
|
||||
|
||||
lemma withDual_disjoint_withoutDual : Disjoint l.withDual l.withoutDual := by
|
||||
rw [Finset.disjoint_iff_ne]
|
||||
intro a ha b hb
|
||||
by_contra hn
|
||||
subst hn
|
||||
simp_all only [withDual, Finset.mem_filter, Finset.mem_univ, true_and, withoutDual,
|
||||
Option.isNone_iff_eq_none, Option.isSome_none, Bool.false_eq_true]
|
||||
|
||||
lemma withDual_union_withoutDual : l.withDual ∪ l.withoutDual = Finset.univ := by
|
||||
rw [Finset.eq_univ_iff_forall]
|
||||
intro i
|
||||
by_cases h : (l.getDual? i).isSome
|
||||
· simp [withDual, Finset.mem_filter, Finset.mem_univ, h]
|
||||
· simp at h
|
||||
simp [withoutDual, Finset.mem_filter, Finset.mem_univ, h]
|
||||
|
||||
lemma withDualOther_disjoint_withoutDualOther :
|
||||
Disjoint (l.withDualOther l2) (l.withoutDualOther l2) := by
|
||||
rw [Finset.disjoint_iff_ne]
|
||||
intro a ha b hb
|
||||
by_contra hn
|
||||
subst hn
|
||||
simp_all only [withDualOther, Finset.mem_filter, Finset.mem_univ, true_and, withoutDualOther,
|
||||
Option.isNone_iff_eq_none, Option.isSome_none, Bool.false_eq_true]
|
||||
|
||||
lemma withDualOther_union_withoutDualOther :
|
||||
l.withDualOther l2 ∪ l.withoutDualOther l2 = Finset.univ := by
|
||||
rw [Finset.eq_univ_iff_forall]
|
||||
intro i
|
||||
by_cases h : (l.getDualInOther? l2 i).isSome
|
||||
· simp [withDualOther, Finset.mem_filter, Finset.mem_univ, h]
|
||||
· simp at h
|
||||
simp [withoutDualOther, Finset.mem_filter, Finset.mem_univ, h]
|
||||
|
||||
def dualEquiv : l.withDual ⊕ l.withoutDual ≃ Fin l.length :=
|
||||
(Equiv.Finset.union _ _ l.withDual_disjoint_withoutDual).trans <|
|
||||
Equiv.subtypeUnivEquiv (Finset.eq_univ_iff_forall.mp l.withDual_union_withoutDual)
|
||||
|
||||
def dualEquivOther : l.withDualOther l2 ⊕ l.withoutDualOther l2 ≃ Fin l.length :=
|
||||
(Equiv.Finset.union _ _ (l.withDualOther_disjoint_withoutDualOther l2)).trans
|
||||
(Equiv.subtypeUnivEquiv
|
||||
(Finset.eq_univ_iff_forall.mp (l.withDualOther_union_withoutDualOther l2)))
|
||||
|
||||
/-!
|
||||
|
||||
## Has a dual
|
||||
|
||||
-/
|
||||
|
||||
def HasDualInSelf (i : Fin l.length) : Prop := ∃ j, AreDualInSelf l i j
|
||||
def HasDualInSelf (i : Fin l.length) : Prop := (l.getDual? i).isSome
|
||||
|
||||
instance (i : Fin l.length) : Decidable (l.HasDualInSelf i) := Fintype.decidableExistsFintype
|
||||
instance (i : Fin l.length) : Decidable (l.HasDualInSelf i) := (l.getDual? i).isSome.decEq true
|
||||
|
||||
def HasDualInOther (i : Fin l.length) : Prop :=
|
||||
∃ (j : Fin l2.length), AreDualInOther i j
|
||||
|
@ -107,9 +623,16 @@ namespace HasDualInSelf
|
|||
|
||||
variable {l l2 : IndexList X} {i : Fin l.length}
|
||||
|
||||
lemma iff_exists : l.HasDualInSelf i ↔ ∃ j, l.AreDualInSelf i j :=
|
||||
Fin.isSome_find_iff
|
||||
|
||||
lemma iff_mem : l.HasDualInSelf i ↔ i ∈ l.withDual := by
|
||||
simp [withDual, Finset.mem_filter, Finset.mem_univ, HasDualInSelf]
|
||||
|
||||
@[simp]
|
||||
lemma append_inl : (l ++ l2).HasDualInSelf (appendEquiv (Sum.inl i)) ↔
|
||||
(l.HasDualInSelf i ∨ l.HasDualInOther l2 i) := by
|
||||
rw [iff_exists, iff_exists]
|
||||
apply Iff.intro
|
||||
· intro h
|
||||
obtain ⟨j, hj⟩ := h
|
||||
|
@ -144,6 +667,7 @@ lemma append_inl : (l ++ l2).HasDualInSelf (appendEquiv (Sum.inl i)) ↔
|
|||
@[simp]
|
||||
lemma append_inr {i : Fin l2.length} : (l ++ l2).HasDualInSelf (appendEquiv (Sum.inr i)) ↔
|
||||
(l2.HasDualInSelf i ∨ l2.HasDualInOther l i) := by
|
||||
rw [iff_exists, iff_exists]
|
||||
apply Iff.intro
|
||||
· intro h
|
||||
obtain ⟨j, hj⟩ := h
|
||||
|
@ -171,12 +695,6 @@ lemma append_inr {i : Fin l2.length} : (l ++ l2).HasDualInSelf (appendEquiv (Sum
|
|||
simp [AreDualInSelf]
|
||||
exact hj
|
||||
|
||||
def getFirst (h : l.HasDualInSelf i) : Fin l.length :=
|
||||
(Fin.find (l.AreDualInSelf i)).get (by simpa [Fin.isSome_find_iff] using h)
|
||||
|
||||
lemma some_getFirst_eq_find (h : l.HasDualInSelf i) :
|
||||
Fin.find (l.AreDualInSelf i) = some h.getFirst := by
|
||||
simp [getFirst]
|
||||
|
||||
lemma getFirst_hasDualInSelf (h : l.HasDualInSelf i) :
|
||||
l.HasDualInSelf h.getFirst := by
|
||||
|
@ -231,7 +749,6 @@ end HasDualInOther
|
|||
|
||||
namespace HasDualInSelf
|
||||
|
||||
|
||||
@[simp]
|
||||
lemma getFirst_append_inl_of_hasDualInSelf (h : (l ++ l2).HasDualInSelf (appendEquiv (Sum.inl i)))
|
||||
(hi : l.HasDualInSelf i) : h.getFirst = appendEquiv (Sum.inl hi.getFirst) := by
|
||||
|
@ -409,6 +926,37 @@ lemma get_get (h : l.HasSingDualInSelf i) : h.get_hasSingDualInSelf.get = i := b
|
|||
|
||||
/-!
|
||||
|
||||
### Bool condition
|
||||
|
||||
-/
|
||||
|
||||
def bool (l : IndexList X) (i : Fin l.length) : Bool :=
|
||||
if h : l.HasDualInSelf i then
|
||||
let l' := (Fin.list l.length).filterMap fun j => if l.AreDualInSelf j i ∧ j ≠ h.getFirst
|
||||
then some j else none
|
||||
List.isEmpty l'
|
||||
else false
|
||||
|
||||
lemma of_bool_true (h : bool l i) : l.HasSingDualInSelf i := by
|
||||
simp [bool] at h
|
||||
split at h <;> rename_i h1
|
||||
· rw [List.isEmpty_iff_eq_nil] at h
|
||||
rw [List.filterMap_eq_nil] at h
|
||||
simp at h
|
||||
apply And.intro h1
|
||||
intro h' j
|
||||
have h1 {n : ℕ} (m : Fin n) : m ∈ Fin.list n := by
|
||||
have h1' : (Fin.list n)[m] = m := by
|
||||
erw [Fin.getElem_list]
|
||||
rfl
|
||||
rw [← h1']
|
||||
apply List.getElem_mem
|
||||
intro h2
|
||||
exact h j (h1 j) h2.symm
|
||||
· exact False.elim h
|
||||
|
||||
/-!
|
||||
|
||||
### Relations regarding append for HasSingDualInSelf
|
||||
|
||||
-/
|
||||
|
@ -810,6 +1358,9 @@ end HasSingColorDualInSelf
|
|||
|
||||
def HasSingColorDualsInSelf : Prop := ∀ i, l.HasSingColorDualInSelf i ∨ ¬ l.HasDualInSelf i
|
||||
|
||||
def HasSingColorDualsInOther : Prop := ∀ i, l.HasSingColorDualInOther l2 i
|
||||
∨ ¬ l.HasDualInOther l2 i
|
||||
|
||||
namespace HasSingColorDualsInSelf
|
||||
|
||||
variable {l : IndexList 𝓒.Color}
|
||||
|
@ -829,12 +1380,12 @@ lemma _root_.IndexNotation.IndexList.HasNoDualsSelf.toHasSingColorDualsInSelf
|
|||
fun i => Or.inr (h i)
|
||||
|
||||
end HasSingColorDualsInSelf
|
||||
def HasSingColorDualsInOther : Prop := ∀ i, l.HasSingColorDualInOther l2 i ∨ ¬ l.HasDualInOther l2 i
|
||||
|
||||
|
||||
|
||||
end Color
|
||||
|
||||
|
||||
-/
|
||||
end IndexList
|
||||
|
||||
end IndexNotation
|
||||
|
|
|
@ -18,35 +18,106 @@ namespace IndexList
|
|||
variable {X : Type} [IndexNotation X] [Fintype X] [DecidableEq X]
|
||||
variable (l l2 : IndexList X)
|
||||
|
||||
def getDual? (i : Fin l.length) : Option (Fin l.length) :=
|
||||
Fin.find (fun j => i ≠ j ∧ l.idMap i = l.idMap j)
|
||||
|
||||
def getDual (i : Fin l.length) : Option (Fin l.length) :=
|
||||
if h : l.HasDualInSelf i then
|
||||
some h.getFirst
|
||||
else
|
||||
none
|
||||
def getDualInOther? (i : Fin l.length) : Option (Fin l2.length) :=
|
||||
Fin.find (fun j => l.idMap i = l2.idMap j)
|
||||
|
||||
lemma getDual_of_hasDualInSelf {i : Fin l.length} (h : l.HasDualInSelf i) :
|
||||
l.getDual i = some h.getFirst := by
|
||||
simp [getDual, h]
|
||||
/-!
|
||||
|
||||
lemma getDual_of_not_hasDualInSelf {i : Fin l.length} (h : ¬l.HasDualInSelf i) :
|
||||
l.getDual i = none := by
|
||||
simp [getDual, h]
|
||||
## Finite sets of duals
|
||||
|
||||
def getDualOther (i : Fin l.length) : Option (Fin l2.length) :=
|
||||
if h : l.HasDualInOther l2 i then
|
||||
some h.getFirst
|
||||
else
|
||||
none
|
||||
-/
|
||||
|
||||
lemma getDualOther_of_hasDualInOther {i : Fin l.length} (h : l.HasDualInOther l2 i) :
|
||||
l.getDualOther l2 i = some h.getFirst := by
|
||||
simp [getDualOther, h]
|
||||
def withDual : Finset (Fin l.length) :=
|
||||
Finset.filter (fun i => (l.getDual? i).isSome) Finset.univ
|
||||
|
||||
lemma getDualOther_of_not_hasDualInOther {i : Fin l.length} (h : ¬l.HasDualInOther l2 i) :
|
||||
l.getDualOther l2 i = none := by
|
||||
simp [getDualOther, h]
|
||||
def withoutDual : Finset (Fin l.length) :=
|
||||
Finset.filter (fun i => (l.getDual? i).isNone) Finset.univ
|
||||
|
||||
def withDualOther : Finset (Fin l.length) :=
|
||||
Finset.filter (fun i => (l.getDualInOther? l2 i).isSome) Finset.univ
|
||||
|
||||
def withoutDualOther : Finset (Fin l.length) :=
|
||||
Finset.filter (fun i => (l.getDualInOther? l2 i).isNone) Finset.univ
|
||||
|
||||
lemma withDual_disjoint_withoutDual : Disjoint l.withDual l.withoutDual := by
|
||||
rw [Finset.disjoint_iff_ne]
|
||||
intro a ha b hb
|
||||
by_contra hn
|
||||
subst hn
|
||||
simp_all only [withDual, Finset.mem_filter, Finset.mem_univ, true_and, withoutDual,
|
||||
Option.isNone_iff_eq_none, Option.isSome_none, Bool.false_eq_true]
|
||||
|
||||
lemma withDual_union_withoutDual : l.withDual ∪ l.withoutDual = Finset.univ := by
|
||||
rw [Finset.eq_univ_iff_forall]
|
||||
intro i
|
||||
by_cases h : (l.getDual? i).isSome
|
||||
· simp [withDual, Finset.mem_filter, Finset.mem_univ, h]
|
||||
· simp at h
|
||||
simp [withoutDual, Finset.mem_filter, Finset.mem_univ, h]
|
||||
|
||||
lemma withDualOther_disjoint_withoutDualOther :
|
||||
Disjoint (l.withDualOther l2) (l.withoutDualOther l2) := by
|
||||
rw [Finset.disjoint_iff_ne]
|
||||
intro a ha b hb
|
||||
by_contra hn
|
||||
subst hn
|
||||
simp_all only [withDualOther, Finset.mem_filter, Finset.mem_univ, true_and, withoutDualOther,
|
||||
Option.isNone_iff_eq_none, Option.isSome_none, Bool.false_eq_true]
|
||||
|
||||
lemma withDualOther_union_withoutDualOther :
|
||||
l.withDualOther l2 ∪ l.withoutDualOther l2 = Finset.univ := by
|
||||
rw [Finset.eq_univ_iff_forall]
|
||||
intro i
|
||||
by_cases h : (l.getDualInOther? l2 i).isSome
|
||||
· simp [withDualOther, Finset.mem_filter, Finset.mem_univ, h]
|
||||
· simp at h
|
||||
simp [withoutDualOther, Finset.mem_filter, Finset.mem_univ, h]
|
||||
|
||||
def dualEquiv : l.withDual ⊕ l.withoutDual ≃ Fin l.length :=
|
||||
(Equiv.Finset.union _ _ l.withDual_disjoint_withoutDual).trans <|
|
||||
Equiv.subtypeUnivEquiv (Finset.eq_univ_iff_forall.mp l.withDual_union_withoutDual)
|
||||
|
||||
def dualEquivOther : l.withDualOther l2 ⊕ l.withoutDualOther l2 ≃ Fin l.length :=
|
||||
(Equiv.Finset.union _ _ (l.withDualOther_disjoint_withoutDualOther l2)).trans
|
||||
(Equiv.subtypeUnivEquiv
|
||||
(Finset.eq_univ_iff_forall.mp (l.withDualOther_union_withoutDualOther l2)))
|
||||
|
||||
/-!
|
||||
|
||||
## Index lists where `getDual?` is invertiable.
|
||||
-/
|
||||
|
||||
def InverDual : Prop :=
|
||||
∀ i, (l.getDual? i).bind l.getDual? = some i
|
||||
|
||||
namespace InverDual
|
||||
|
||||
end InverDual
|
||||
|
||||
def InvertDualOther : Prop :=
|
||||
∀ i, (l.getDualInOther? l2 i).bind (l2.getDualInOther? l) = some i
|
||||
∧ ∀ i, (l2.getDualInOther? l i).bind (l.getDualInOther? l2) = some i
|
||||
|
||||
section Color
|
||||
|
||||
variable {𝓒 : TensorColor}
|
||||
variable [IndexNotation 𝓒.Color] [Fintype 𝓒.Color] [DecidableEq 𝓒.Color]
|
||||
variable (l l2 : IndexList 𝓒.Color)
|
||||
/-!
|
||||
|
||||
## Has single dual of correct color
|
||||
|
||||
-/
|
||||
|
||||
def IndexListColor (𝓒 : TensorColor) [IndexNotation 𝓒.Color] : Type := {l : IndexList X //
|
||||
∀ i, (l.getDual? i).bind l.getDual? = some i ∧
|
||||
Option.map (l.colorMap) ∘ l.getDual? = Option.map ()
|
||||
}
|
||||
|
||||
end color
|
||||
/-!
|
||||
|
||||
## Append relations
|
||||
|
@ -104,10 +175,42 @@ def HasSingDualsInOther : Prop :=
|
|||
|
||||
def HasNoDualsInSelf : Prop := l.getDual = fun _ => none
|
||||
|
||||
lemma hasSingDualsInSelf_append :
|
||||
(l ++ l2).HasSingDualsInSelf ↔
|
||||
l.HasSingDualsInSelf ∧ l2.HasSingDualsInSelf ∧ HasSingDualsInOther l1 l2 := by
|
||||
lemma hasSingDualsInSelf_append (h1 : l.HasNoDualsInSelf) (h2 : l2.HasNoDualsInSelf) :
|
||||
(l ++ l2).HasSingDualsInSelf ↔ HasSingDualsInOther l l2 := by
|
||||
apply Iff.intro
|
||||
· intro h
|
||||
simp [HasSingDualsInOther]
|
||||
apply And.intro
|
||||
· intro i
|
||||
have h3 := h (appendEquiv (Sum.inl i))
|
||||
simp at h3
|
||||
rw [h1] at h3
|
||||
simp at h3
|
||||
by_cases hn : l.HasDualInOther l2 i
|
||||
· rw [l.getDualOther_of_hasDualInOther l2 hn] at h3 ⊢
|
||||
simp only [Option.map_some', Function.comp_apply, Option.some_bind, getDual_append_inr] at h3
|
||||
rw [h2] at h3
|
||||
simpa using h3
|
||||
· rw [l.getDualOther_of_not_hasDualInOther l2 hn] at h3 ⊢
|
||||
simp at h3
|
||||
· intro i
|
||||
have h3 := h (appendEquiv (Sum.inr i))
|
||||
simp at h3
|
||||
rw [h2] at h3
|
||||
simp at h3
|
||||
by_cases hn : l2.HasDualInOther l i
|
||||
· rw [l2.getDualOther_of_hasDualInOther l hn] at h3 ⊢
|
||||
simp only [Option.map_some', Function.comp_apply, Option.some_bind, getDual_append_inl] at h3
|
||||
rw [h1] at h3
|
||||
simpa using h3
|
||||
· rw [l2.getDualOther_of_not_hasDualInOther l hn] at h3 ⊢
|
||||
simp at h3
|
||||
· intro h
|
||||
intro i
|
||||
obtain ⟨k, hk⟩ := appendEquiv.surjective i
|
||||
|
||||
sorry
|
||||
|
||||
end IndexList
|
||||
|
||||
end IndexNotation
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue