2024-08-02 16:46:20 -04:00
|
|
|
|
/-
|
|
|
|
|
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
|
|
|
|
|
-/
|
2024-08-06 08:10:47 -04:00
|
|
|
|
import HepLean.SpaceTime.LorentzTensor.IndexNotation.TensorIndex
|
2024-08-02 16:46:20 -04:00
|
|
|
|
/-!
|
|
|
|
|
|
|
|
|
|
# Strings of indices
|
|
|
|
|
|
|
|
|
|
A string of indices e.g. `ᵘ¹²ᵤ₄₃` is the structure we usually see
|
|
|
|
|
following a tensor symbol in index notation.
|
|
|
|
|
|
|
|
|
|
This file defines such an index string, and from it constructs a list of indices.
|
|
|
|
|
|
|
|
|
|
-/
|
|
|
|
|
|
|
|
|
|
open Lean
|
|
|
|
|
open String
|
|
|
|
|
|
|
|
|
|
namespace IndexNotation
|
|
|
|
|
|
|
|
|
|
variable (X : Type) [IndexNotation X] [Fintype X] [DecidableEq X]
|
|
|
|
|
|
|
|
|
|
/-!
|
|
|
|
|
|
|
|
|
|
## Lists of characters forming a string of indices.
|
|
|
|
|
|
|
|
|
|
-/
|
|
|
|
|
|
|
|
|
|
/-- A lemma used to show terminiation of recursive definitions which follow.
|
|
|
|
|
It says that the length of `List.dropWhile _ l.tail` is less then the length of
|
|
|
|
|
`l` when `l` is non-empty. -/
|
|
|
|
|
lemma dropWhile_isIndexSpecifier_length_lt (l : List Char) (hl : l ≠ []) :
|
|
|
|
|
(List.dropWhile (fun c => !isNotationChar X c) l.tail).length < l.length := by
|
|
|
|
|
let ld := l.tail.dropWhile (fun c => ¬ isNotationChar X c)
|
|
|
|
|
let lt := l.tail.takeWhile (fun c => ¬ isNotationChar X c)
|
|
|
|
|
simp only [gt_iff_lt]
|
|
|
|
|
have h2 : lt ++ ld = l.tail := by
|
|
|
|
|
exact List.takeWhile_append_dropWhile _ _
|
|
|
|
|
have h3 := congrArg List.length h2
|
|
|
|
|
rw [List.length_append] at h3
|
|
|
|
|
have h4 : l.length ≠ 0 := by
|
|
|
|
|
simp_all only [ne_eq, Bool.not_eq_true, Bool.decide_eq_false, List.takeWhile_append_dropWhile,
|
|
|
|
|
List.length_tail, List.length_eq_zero, not_false_eq_true]
|
|
|
|
|
have h5 : l.tail.length < l.length := by
|
|
|
|
|
rw [List.length_tail]
|
|
|
|
|
omega
|
|
|
|
|
have h6 : ld.length < l.length := by
|
|
|
|
|
omega
|
|
|
|
|
simpa [ld] using h6
|
|
|
|
|
|
|
|
|
|
/-- The proposition for a list of characters to be an index string. -/
|
|
|
|
|
def listCharIndexString (l : List Char) : Prop :=
|
|
|
|
|
if h : l = [] then True
|
|
|
|
|
else
|
|
|
|
|
let sfst := l.head h
|
|
|
|
|
if ¬ isNotationChar X sfst then False
|
|
|
|
|
else
|
|
|
|
|
let lt := l.tail.takeWhile (fun c => ¬ isNotationChar X c)
|
|
|
|
|
let ld := l.tail.dropWhile (fun c => ¬ isNotationChar X c)
|
|
|
|
|
if ¬ listCharIndexTail sfst lt then False
|
|
|
|
|
else listCharIndexString ld
|
|
|
|
|
termination_by l.length
|
|
|
|
|
decreasing_by
|
|
|
|
|
simpa [ld, InvImage] using dropWhile_isIndexSpecifier_length_lt X l h
|
|
|
|
|
|
|
|
|
|
/-- A bool version of `listCharIndexString` for computation. -/
|
|
|
|
|
def listCharIndexStringBool (l : List Char) : Bool :=
|
|
|
|
|
if h : l = [] then true
|
|
|
|
|
else
|
|
|
|
|
let sfst := l.head h
|
|
|
|
|
if ¬ isNotationChar X sfst then false
|
|
|
|
|
else
|
|
|
|
|
let lt := l.tail.takeWhile (fun c => ¬ isNotationChar X c)
|
|
|
|
|
let ld := l.tail.dropWhile (fun c => ¬ isNotationChar X c)
|
|
|
|
|
if ¬ listCharIndexTail sfst lt then false
|
|
|
|
|
else listCharIndexStringBool ld
|
|
|
|
|
termination_by l.length
|
|
|
|
|
decreasing_by
|
|
|
|
|
simpa [ld, InvImage] using dropWhile_isIndexSpecifier_length_lt X l h
|
|
|
|
|
|
|
|
|
|
lemma listCharIndexString_iff (l : List Char) : listCharIndexString X l
|
|
|
|
|
↔ (if h : l = [] then True else
|
|
|
|
|
let sfst := l.head h
|
|
|
|
|
if ¬ isNotationChar X sfst then False
|
|
|
|
|
else
|
|
|
|
|
let lt := l.tail.takeWhile (fun c => ¬ isNotationChar X c)
|
|
|
|
|
let ld := l.tail.dropWhile (fun c => ¬ isNotationChar X c)
|
|
|
|
|
if ¬ listCharIndexTail sfst lt then False
|
|
|
|
|
else listCharIndexString X ld) := by
|
|
|
|
|
rw [listCharIndexString]
|
|
|
|
|
|
|
|
|
|
lemma listCharIndexString_iff_bool (l : List Char) :
|
|
|
|
|
listCharIndexString X l ↔ listCharIndexStringBool X l = true := by
|
|
|
|
|
rw [listCharIndexString, listCharIndexStringBool]
|
|
|
|
|
by_cases h : l = []
|
|
|
|
|
simp [h]
|
|
|
|
|
simp [h]
|
|
|
|
|
intro _ _
|
|
|
|
|
exact listCharIndexString_iff_bool _
|
|
|
|
|
termination_by l.length
|
|
|
|
|
decreasing_by
|
|
|
|
|
simpa [InvImage] using dropWhile_isIndexSpecifier_length_lt X l h
|
|
|
|
|
|
|
|
|
|
instance : Decidable (listCharIndexString X l) :=
|
|
|
|
|
@decidable_of_decidable_of_iff _ _
|
|
|
|
|
((listCharIndexStringBool X l).decEq true)
|
|
|
|
|
(listCharIndexString_iff_bool X l).symm
|
|
|
|
|
|
|
|
|
|
/-!
|
|
|
|
|
|
|
|
|
|
## Returning the chars of first index from chars of string of indices.
|
|
|
|
|
|
|
|
|
|
In particular from a list of characters which form an index string,
|
|
|
|
|
to a list of characters which forms an index.
|
|
|
|
|
|
|
|
|
|
-/
|
|
|
|
|
|
|
|
|
|
/-- If a list of characters corresponds to an index string, then its head is an
|
|
|
|
|
index specifier. -/
|
|
|
|
|
lemma listCharIndexString_head_isIndexSpecifier (l : List Char) (h : listCharIndexString X l)
|
|
|
|
|
(hl : l ≠ []) : isNotationChar X (l.head hl) := by
|
|
|
|
|
by_contra
|
|
|
|
|
rw [listCharIndexString] at h
|
|
|
|
|
simp_all only [↓reduceDIte, Bool.false_eq_true, not_false_eq_true, ↓reduceIte]
|
|
|
|
|
|
|
|
|
|
/-- The tail of the first index in a list of characters corresponds to an index string
|
|
|
|
|
(junk on other lists). -/
|
|
|
|
|
def listCharIndexStringHeadIndexTail (l : List Char) : List Char :=
|
|
|
|
|
l.tail.takeWhile (fun c => ¬ isNotationChar X c)
|
|
|
|
|
|
|
|
|
|
/-- The tail of the first index in a list of characters corresponds to an index string
|
|
|
|
|
is the tail of a list of characters corresponding to an index specified by the head. -/
|
|
|
|
|
lemma listCharIndexStringHeadIndexTail_listCharIndexTail (l : List Char)
|
|
|
|
|
(h : listCharIndexString X l) (hl : l ≠ []) :
|
|
|
|
|
listCharIndexTail (l.head hl) (listCharIndexStringHeadIndexTail X l) := by
|
|
|
|
|
by_contra
|
|
|
|
|
have h1 := listCharIndexString_head_isIndexSpecifier X l h hl
|
|
|
|
|
rw [listCharIndexString] at h
|
|
|
|
|
simp_all only [not_true_eq_false, Bool.not_eq_true, Bool.decide_eq_false, ite_not, if_false_right,
|
|
|
|
|
ite_false, dite_false]
|
|
|
|
|
obtain ⟨left, _⟩ := h
|
|
|
|
|
rename_i x _
|
|
|
|
|
simp [listCharIndexStringHeadIndexTail] at x
|
|
|
|
|
simp_all only [Bool.false_eq_true]
|
|
|
|
|
|
|
|
|
|
/-- The first list of characters which form a index, from a list of characters
|
|
|
|
|
which form a string of indices. -/
|
|
|
|
|
def listCharIndexStringHeadIndex (l : List Char) : List Char :=
|
|
|
|
|
if h : l = [] then []
|
|
|
|
|
else l.head h :: listCharIndexStringHeadIndexTail X l
|
|
|
|
|
|
|
|
|
|
lemma listCharIndexStringHeadIndex_listCharIndex (l : List Char) (h : listCharIndexString X l) :
|
|
|
|
|
listCharIndex X (listCharIndexStringHeadIndex X l) := by
|
|
|
|
|
by_cases h1 : l = []
|
|
|
|
|
· subst h1
|
|
|
|
|
simp [listCharIndex, listCharIndexStringHeadIndex]
|
|
|
|
|
· simp [listCharIndexStringHeadIndex, listCharIndex, h1]
|
|
|
|
|
apply And.intro
|
|
|
|
|
exact listCharIndexString_head_isIndexSpecifier X l h h1
|
|
|
|
|
exact listCharIndexStringHeadIndexTail_listCharIndexTail X l h h1
|
|
|
|
|
|
|
|
|
|
/-!
|
|
|
|
|
|
|
|
|
|
## Dropping chars of first index from chars of string of indices.
|
|
|
|
|
|
|
|
|
|
-/
|
|
|
|
|
|
|
|
|
|
/-- The list of characters obtained by dropping the first block which
|
|
|
|
|
corresponds to an index. -/
|
|
|
|
|
def listCharIndexStringDropHeadIndex (l : List Char) : List Char :=
|
|
|
|
|
l.tail.dropWhile (fun c => ¬ isNotationChar X c)
|
|
|
|
|
|
|
|
|
|
lemma listCharIndexStringDropHeadIndex_listCharIndexString (l : List Char)
|
|
|
|
|
(h : listCharIndexString X l) :
|
|
|
|
|
listCharIndexString X (listCharIndexStringDropHeadIndex X l) := by
|
|
|
|
|
by_cases h1 : l = []
|
|
|
|
|
· subst h1
|
|
|
|
|
simp [listCharIndexStringDropHeadIndex, listCharIndexString]
|
|
|
|
|
· simp [listCharIndexStringDropHeadIndex, h1]
|
|
|
|
|
rw [listCharIndexString] at h
|
|
|
|
|
simp_all only [↓reduceDIte, Bool.not_eq_true, Bool.decide_eq_false, ite_not, if_false_right,
|
|
|
|
|
if_false_left, Bool.not_eq_false]
|
|
|
|
|
|
|
|
|
|
/-!
|
|
|
|
|
|
|
|
|
|
## Chars of all indices from char of string of indices
|
|
|
|
|
|
|
|
|
|
-/
|
|
|
|
|
|
|
|
|
|
/-- Given a list list of characters corresponding to an index string, the list
|
|
|
|
|
of lists of characters which correspond to an index and are non-zero corresponding
|
|
|
|
|
to that index string. -/
|
|
|
|
|
def listCharIndexStringTolistCharIndex (l : List Char) (h : listCharIndexString X l) :
|
|
|
|
|
List ({lI : List Char // listCharIndex X lI ∧ lI ≠ []}) :=
|
|
|
|
|
if hl : l = [] then [] else
|
|
|
|
|
⟨listCharIndexStringHeadIndex X l, by
|
|
|
|
|
apply And.intro (listCharIndexStringHeadIndex_listCharIndex X l h)
|
|
|
|
|
simp [listCharIndexStringHeadIndex]
|
|
|
|
|
exact hl⟩ ::
|
|
|
|
|
(listCharIndexStringTolistCharIndex (listCharIndexStringDropHeadIndex X l)
|
|
|
|
|
(listCharIndexStringDropHeadIndex_listCharIndexString X l h))
|
|
|
|
|
termination_by l.length
|
|
|
|
|
decreasing_by
|
|
|
|
|
rename_i h1
|
|
|
|
|
simpa [InvImage, listCharIndexStringDropHeadIndex] using
|
|
|
|
|
dropWhile_isIndexSpecifier_length_lt X l hl
|
|
|
|
|
|
|
|
|
|
/-!
|
|
|
|
|
|
|
|
|
|
## The definition of an index string
|
|
|
|
|
|
|
|
|
|
-/
|
|
|
|
|
|
|
|
|
|
/-- A string of indices to be associated with a tensor. For example, `ᵘ⁰ᵤ₂₆₀ᵘ³`. -/
|
|
|
|
|
def IndexString : Type := {s : String // listCharIndexStringBool X s.toList = true}
|
|
|
|
|
|
|
|
|
|
namespace IndexString
|
|
|
|
|
|
|
|
|
|
/-!
|
|
|
|
|
|
|
|
|
|
## Constructing a list of indices from an index string
|
|
|
|
|
|
|
|
|
|
-/
|
|
|
|
|
|
|
|
|
|
variable {X : Type} [IndexNotation X] [Fintype X] [DecidableEq X]
|
|
|
|
|
|
|
|
|
|
/-- The character list associated with a index string. -/
|
|
|
|
|
def toCharList (s : IndexString X) : List Char := s.val.toList
|
|
|
|
|
|
|
|
|
|
/-- The char list of an index string satisfies `listCharIndexString`. -/
|
|
|
|
|
lemma listCharIndexString (s : IndexString X) : listCharIndexString X s.toCharList := by
|
|
|
|
|
rw [listCharIndexString_iff_bool]
|
|
|
|
|
exact s.prop
|
|
|
|
|
|
|
|
|
|
/-- The indices associated to an index string. -/
|
|
|
|
|
def toIndexList (s : IndexString X) : IndexList X :=
|
2024-08-14 16:55:13 -04:00
|
|
|
|
{val := (listCharIndexStringTolistCharIndex X s.toCharList (listCharIndexString s)).map
|
|
|
|
|
fun x => Index.ofCharList x.1 x.2}
|
|
|
|
|
|
2024-08-15 10:16:42 -04:00
|
|
|
|
/-- The formation of an index list from a string `s` statisfying `listCharIndexStringBool`. -/
|
2024-08-14 16:55:13 -04:00
|
|
|
|
def toIndexList' (s : String) (hs : listCharIndexStringBool X s.toList = true) : IndexList X :=
|
|
|
|
|
toIndexList ⟨s, hs⟩
|
2024-08-02 16:46:20 -04:00
|
|
|
|
|
|
|
|
|
end IndexString
|
|
|
|
|
|
|
|
|
|
end IndexNotation
|
2024-08-06 08:10:47 -04:00
|
|
|
|
namespace TensorStructure
|
|
|
|
|
|
|
|
|
|
/-!
|
|
|
|
|
|
|
|
|
|
## Making a tensor index from an index string
|
|
|
|
|
|
|
|
|
|
-/
|
|
|
|
|
|
|
|
|
|
namespace TensorIndex
|
|
|
|
|
variable {R : Type} [CommSemiring R] (𝓣 : TensorStructure R)
|
|
|
|
|
variable {𝓣 : TensorStructure R} [IndexNotation 𝓣.Color] [Fintype 𝓣.Color] [DecidableEq 𝓣.Color]
|
|
|
|
|
variable {n m : ℕ} {cn : Fin n → 𝓣.Color} {cm : Fin m → 𝓣.Color}
|
|
|
|
|
|
2024-08-14 16:55:13 -04:00
|
|
|
|
open IndexNotation ColorIndexList IndexString
|
2024-08-06 08:10:47 -04:00
|
|
|
|
|
|
|
|
|
/-- The construction of a tensor index from a tensor and a string satisfing conditions which are
|
|
|
|
|
easy to check automatically. -/
|
|
|
|
|
noncomputable def fromIndexString (T : 𝓣.Tensor cn) (s : String)
|
|
|
|
|
(hs : listCharIndexStringBool 𝓣.toTensorColor.Color s.toList = true)
|
2024-08-14 16:55:13 -04:00
|
|
|
|
(hn : n = (toIndexList' s hs).length)
|
|
|
|
|
(hD : (toIndexList' s hs).withDual = (toIndexList' s hs).withUniqueDual)
|
|
|
|
|
(hC : IndexList.ColorCond (toIndexList' s hs))
|
|
|
|
|
(hd : TensorColor.ColorMap.DualMap (toIndexList' s hs).colorMap
|
2024-08-06 15:43:58 -04:00
|
|
|
|
(cn ∘ Fin.cast hn.symm)) : 𝓣.TensorIndex :=
|
2024-08-14 16:55:13 -04:00
|
|
|
|
TensorStructure.TensorIndex.mkDualMap T ⟨(toIndexList' s hs), hD, hC⟩ hn hd
|
2024-08-06 08:10:47 -04:00
|
|
|
|
|
|
|
|
|
end TensorIndex
|
|
|
|
|
|
|
|
|
|
end TensorStructure
|