PhysLean/HepLean/PerturbationTheory/FieldSpecification/CrAnSection.lean
Joseph Tooby-Smith b5c987180a
refactor: Some properties of field specifications (#285)
* refactor: Fix field struct defn.

* rename: FieldStruct to FieldSpecification

* feat: Add examples of field specifications

* docs: Slight improvement of module docs
2025-01-21 06:11:47 +00:00

395 lines
16 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2025 Joseph Tooby-Smith. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Joseph Tooby-Smith
-/
import HepLean.PerturbationTheory.FieldSpecification.CreateAnnihilate
/-!
# Creation and annihlation sections
This module defines creation and annihilation sections, which represent different ways to associate
fields with creation or annihilation operators.
## Main definitions
- `CrAnSection φs` : Represents sections in `𝓕.CrAnStates` over a list of states `φs`.
Given fields `φ₁...φₙ`, this captures all possible ways to assign each field as either a creation
or annihilation operator.
- `head`, `tail` : Access the first element and remaining elements of a section
- `cons` : Constructs a new section by prepending a creation/annihilation state
- Various equivalences:
* `nilEquiv` : Empty sections
* `singletonEquiv` : Sections over single elements
* `consEquiv` : Separates head and tail
* `appendEquiv` : Splits sections at a given point
All sections form finite types and support operations like taking/dropping elements and
concatenation while preserving the relationship between states and their operator assignments.
-/
namespace FieldSpecification
variable {𝓕 : FieldSpecification}
/-- The sections in `𝓕.CrAnStates` over a list `φs : List 𝓕.States`.
In terms of physics, given some fields `φ₁...φₙ`, the different ways one can associate
each field as a `creation` or an `annilation` operator. E.g. the number of terms
`φ₁⁰φ₂¹...φₙ⁰` `φ₁¹φ₂¹...φₙ⁰` etc. If some fields are exclusively creation or annhilation
operators at this point (e.g. ansymptotic states) this is accounted for. -/
def CrAnSection (φs : List 𝓕.States) : Type :=
{ψs : List 𝓕.CrAnStates //
List.map 𝓕.crAnStatesToStates ψs = φs}
-- Π i, 𝓕.statesToCreateAnnihilateType (φs.get i)
namespace CrAnSection
open FieldStatistic
variable {𝓕 : FieldSpecification} {φs : List 𝓕.States}
@[simp]
lemma length_eq (ψs : CrAnSection φs) : ψs.1.length = φs.length := by
simpa using congrArg List.length ψs.2
/-- The tail of a section for `φs`. -/
def tail : {φs : List 𝓕.States} → (ψs : CrAnSection φs) → CrAnSection φs.tail
| [], ⟨[], h⟩ => ⟨[], h⟩
| φ :: φs, ⟨[], h⟩ => False.elim (by simp at h)
| φ :: φs, ⟨ψ :: ψs, h⟩ => ⟨ψs, by rw [List.map_cons, List.cons.injEq] at h; exact h.2⟩
lemma head_state_eq {φ : 𝓕.States} : (ψs : CrAnSection (φ :: φs)) →
(ψs.1.head (by simp [← List.length_pos_iff_ne_nil])).1 = φ
| ⟨[], h⟩ => False.elim (by simp at h)
| ⟨ψ :: ψs, h⟩ => by
simp only [List.map_cons, List.cons.injEq] at h
exact h.1
lemma statistics_eq_state_statistics (ψs : CrAnSection φs) :
(𝓕 |>ₛ ψs.1) = 𝓕 |>ₛ φs := by
erw [FieldStatistic.ofList_eq_prod, FieldStatistic.ofList_eq_prod, crAnStatistics]
rw [← List.map_comp_map, Function.comp_apply, ψs.2]
lemma take_statistics_eq_take_state_statistics (ψs : CrAnSection φs) n :
(𝓕 |>ₛ (ψs.1.take n)) = 𝓕 |>ₛ (φs.take n) := by
erw [FieldStatistic.ofList_eq_prod, FieldStatistic.ofList_eq_prod, crAnStatistics]
simp only [instCommGroup, List.map_take]
rw [← List.map_comp_map, Function.comp_apply, ψs.2]
/-- The head of a section for `φ :: φs` as an element in `𝓕.statesToCreateAnnihilateType φ`. -/
def head : {φ : 𝓕.States} → (ψs : CrAnSection (φ :: φs)) →
𝓕.statesToCrAnType φ
| φ, ⟨[], h⟩ => False.elim (by simp at h)
| φ, ⟨ψ :: ψs, h⟩ => 𝓕.statesToCreateAnnihilateTypeCongr (by
simpa using head_state_eq ⟨ψ :: ψs, h⟩) ψ.2
lemma eq_head_cons_tail {φ : 𝓕.States} {ψs : CrAnSection (φ :: φs)} :
ψs.1 = ⟨φ, head ψs⟩ :: ψs.tail.1 := by
match ψs with
| ⟨[], h⟩ => exact False.elim (by simp at h)
| ⟨ψ :: ψs, h⟩ =>
have h2 := head_state_eq ⟨ψ :: ψs, h⟩
simp only [List.head_cons] at h2
subst h2
rfl
/-- The creation of a section from for `φ : φs` from a section for `φs` and a
element of `𝓕.statesToCreateAnnihilateType φ`. -/
def cons {φ : 𝓕.States} (ψ : 𝓕.statesToCrAnType φ) (ψs : CrAnSection φs) :
CrAnSection (φ :: φs) := ⟨⟨φ, ψ⟩ :: ψs.1, by
simp [List.map_cons, ψs.2]⟩
/-- For the empty list of states there is only one `CrAnSection`. Corresponding to the
empty list of `CrAnStates`. -/
def nilEquiv : CrAnSection (𝓕 := 𝓕) [] ≃ Unit where
toFun _ := ()
invFun _ := ⟨[], rfl⟩
left_inv ψs := Subtype.ext <| by
have h2 := ψs.2
simp only [List.map_eq_nil_iff] at h2
simp [h2]
right_inv _ := by
simp
/-- The creation and annihlation sections for a singleton list is given by
a choice of `𝓕.statesToCreateAnnihilateType φ`. If `φ` is a asymptotic state
there is no choice here, else there are two choices. -/
def singletonEquiv {φ : 𝓕.States} : CrAnSection [φ] ≃
𝓕.statesToCrAnType φ where
toFun ψs := ψs.head
invFun ψ := ⟨[⟨φ, ψ⟩], by simp⟩
left_inv ψs := by
apply Subtype.ext
simp only
have h1 := eq_head_cons_tail (ψs := ψs)
rw [h1]
have h2 := ψs.tail.2
simp only [List.tail_cons, List.map_eq_nil_iff] at h2
simp [h2]
right_inv ψ := by
simp only [head]
rfl
/-- An equivalence seperating the head of a creation and annhilation section
from the tail. -/
def consEquiv {φ : 𝓕.States} {φs : List 𝓕.States} : CrAnSection (φ :: φs) ≃
𝓕.statesToCrAnType φ × CrAnSection φs where
toFun ψs := ⟨ψs.head, ψs.tail⟩
invFun ψψs :=
match ψψs with
| (ψ, ψs) => cons ψ ψs
left_inv ψs := by
apply Subtype.ext
exact Eq.symm eq_head_cons_tail
right_inv ψψs := by
match ψψs with
| (ψ, ψs) => rfl
/-- The instance of a finite type on `CrAnSection`s defined recursively through
`consEquiv`. -/
instance fintype : (φs : List 𝓕.States) → Fintype (CrAnSection φs)
| [] => Fintype.ofEquiv _ nilEquiv.symm
| _ :: φs =>
haveI : Fintype (CrAnSection φs) := fintype φs
Fintype.ofEquiv _ consEquiv.symm
@[simp]
lemma sum_nil (f : CrAnSection (𝓕 := 𝓕) [] → M) [AddCommMonoid M] :
∑ (s : CrAnSection []), f s = f ⟨[], rfl⟩ := by
rw [← nilEquiv.symm.sum_comp]
simp only [Finset.univ_unique, PUnit.default_eq_unit, Finset.sum_singleton]
rfl
lemma sum_cons (f : CrAnSection (φ :: φs) → M) [AddCommMonoid M] :
∑ (s : CrAnSection (φ :: φs)), f s = ∑ (a : 𝓕.statesToCrAnType φ),
∑ (s : CrAnSection φs), f (cons a s) := by
rw [← consEquiv.symm.sum_comp, Fintype.sum_prod_type]
rfl
lemma sum_over_length {s : CrAnSection φs} (f : Fin s.1.length → M)
[AddCommMonoid M] : ∑ (n : Fin s.1.length), f n =
∑ (n : Fin φs.length), f (Fin.cast (length_eq s).symm n) := by
rw [← (finCongr (length_eq s)).sum_comp]
rfl
/-- The equivalence between `CrAnSection φs` and
`CrAnSection φs'` induced by an equality `φs = φs'`. -/
def congr : {φs φs' : List 𝓕.States} → (h : φs = φs') →
CrAnSection φs ≃ CrAnSection φs'
| _, _, rfl => Equiv.refl _
@[simp]
lemma congr_fst {φs φs' : List 𝓕.States} (h : φs = φs') (ψs : CrAnSection φs) :
(congr h ψs).1 = ψs.1 := by
cases h
rfl
@[simp]
lemma congr_symm {φs φs' : List 𝓕.States} (h : φs = φs') :
(congr h).symm = congr h.symm := by
cases h
rfl
@[simp]
lemma congr_trans_apply {φs φs' φs'' : List 𝓕.States} (h1 : φs = φs') (h2 : φs' = φs'')
(ψs : CrAnSection φs) :
(congr h2 (congr h1 ψs)) = congr (by rw [h1, h2]) ψs := by
subst h1 h2
rfl
/-- Returns the first `n` elements of a section and its underlying list. -/
def take (n : ) (ψs : CrAnSection φs) : CrAnSection (φs.take n) :=
⟨ψs.1.take n, by simp [ψs.2]⟩
@[simp]
lemma take_congr {φs φs' : List 𝓕.States} (h : φs = φs') (n : )
(ψs : CrAnSection φs) :
(take n (congr h ψs)) = congr (by rw [h]) (take n ψs) := by
subst h
rfl
/-- Removes the first `n` elements of a section and its underlying list. -/
def drop (n : ) (ψs : CrAnSection φs) : CrAnSection (φs.drop n) :=
⟨ψs.1.drop n, by simp [ψs.2]⟩
@[simp]
lemma drop_congr {φs φs' : List 𝓕.States} (h : φs = φs') (n : )
(ψs : CrAnSection φs) :
(drop n (congr h ψs)) = congr (by rw [h]) (drop n ψs) := by
subst h
rfl
/-- Appends two sections and their underlying lists. -/
def append {φs φs' : List 𝓕.States} (ψs : CrAnSection φs)
(ψs' : CrAnSection φs') : CrAnSection (φs ++ φs') :=
⟨ψs.1 ++ ψs'.1, by simp [ψs.2, ψs'.2]⟩
lemma append_assoc {φs φs' φs'' : List 𝓕.States} (ψs : CrAnSection φs)
(ψs' : CrAnSection φs') (ψs'' : CrAnSection φs'') :
append ψs (append ψs' ψs'') = congr (by simp) (append (append ψs ψs') ψs'') := by
apply Subtype.ext
simp [append]
lemma append_assoc' {φs φs' φs'' : List 𝓕.States} (ψs : CrAnSection φs)
(ψs' : CrAnSection φs') (ψs'' : CrAnSection φs'') :
(append (append ψs ψs') ψs'') = congr (by simp) (append ψs (append ψs' ψs'')) := by
apply Subtype.ext
simp [append]
lemma singletonEquiv_append_eq_cons {φs : List 𝓕.States} {φ : 𝓕.States}
(ψs : CrAnSection φs) (ψ : 𝓕.statesToCrAnType φ) :
append (singletonEquiv.symm ψ) ψs = cons ψ ψs := by
apply Subtype.ext
simp [append, cons, singletonEquiv]
@[simp]
lemma take_append_drop {n : } (ψs : CrAnSection φs) :
append (take n ψs) (drop n ψs) = congr (List.take_append_drop n φs).symm ψs := by
apply Subtype.ext
simp [take, drop, append]
lemma congr_append {φs1 φs1' φs2 φs2' : List 𝓕.States} (h1 : φs1 = φs1') (h2 : φs2 = φs2')
(ψs1 : CrAnSection φs1) (ψs2 : CrAnSection φs2) :
(append (congr h1 ψs1) (congr h2 ψs2)) = congr (by rw [h1, h2]) (append ψs1 ψs2) := by
subst h1 h2
rfl
@[simp]
lemma congr_fst_append {φs1 φs1' φs2 : List 𝓕.States} (h1 : φs1 = φs1')
(ψs1 : CrAnSection φs1) (ψs2 : CrAnSection φs2) :
(append (congr h1 ψs1) (ψs2)) = congr (by rw [h1]) (append ψs1 ψs2) := by
subst h1
rfl
@[simp]
lemma congr_snd_append {φs1 φs2 φs2' : List 𝓕.States} (h2 : φs2 = φs2')
(ψs1 : CrAnSection φs1) (ψs2 : CrAnSection φs2) :
(append ψs1 (congr h2 ψs2)) = congr (by rw [h2]) (append ψs1 ψs2) := by
subst h2
rfl
@[simp]
lemma take_left {φs φs' : List 𝓕.States} (ψs : CrAnSection φs)
(ψs' : CrAnSection φs') :
take φs.length (ψs.append ψs') = congr (by simp) ψs := by
apply Subtype.ext
simp [take, append]
@[simp]
lemma drop_left {φs φs' : List 𝓕.States} (ψs : CrAnSection φs)
(ψs' : CrAnSection φs') :
drop φs.length (ψs.append ψs') = congr (by simp) ψs' := by
apply Subtype.ext
simp [drop, append]
/-- The equivalence between `CrAnSection (φs ++ φs')` and
`CrAnSection φs × CrAnSection φs` formed by `append`, `take`
and `drop` and their interrelationship. -/
def appendEquiv {φs φs' : List 𝓕.States} : CrAnSection (φs ++ φs') ≃
CrAnSection φs × CrAnSection φs' where
toFun ψs := (congr (List.take_left φs φs') (take φs.length ψs),
congr (List.drop_left φs φs') (drop φs.length ψs))
invFun ψsψs' := append ψsψs'.1 ψsψs'.2
left_inv ψs := by
apply Subtype.ext
simp
right_inv ψsψs' := by
match ψsψs' with
| (ψs, ψs') =>
simp only [take_left, drop_left, Prod.mk.injEq]
refine And.intro (Subtype.ext ?_) (Subtype.ext ?_)
· simp
· simp
@[simp]
lemma _root_.List.map_eraseIdx {α β : Type} (f : α → β) : (l : List α) → (n : ) →
List.map f (l.eraseIdx n) = (List.map f l).eraseIdx n
| [], _ => rfl
| a :: l, 0 => rfl
| a :: l, n+1 => by
simp only [List.eraseIdx, List.map_cons, List.cons.injEq, true_and]
exact List.map_eraseIdx f l n
/-- Erasing an element from a section and it's underlying list. -/
def eraseIdx (n : ) (ψs : CrAnSection φs) : CrAnSection (φs.eraseIdx n) :=
⟨ψs.1.eraseIdx n, by simp [ψs.2]⟩
/-- The equivalence formed by extracting an element from a section. -/
def eraseIdxEquiv (n : ) (φs : List 𝓕.States) (hn : n < φs.length) :
CrAnSection φs ≃ 𝓕.statesToCrAnType φs[n] ×
CrAnSection (φs.eraseIdx n) :=
(congr (by simp only [List.take_concat_get', List.take_append_drop])).trans <|
appendEquiv.trans <|
(Equiv.prodCongr (appendEquiv.trans (Equiv.prodComm _ _)) (Equiv.refl _)).trans <|
(Equiv.prodAssoc _ _ _).trans <|
Equiv.prodCongr singletonEquiv <|
appendEquiv.symm.trans <|
congr (List.eraseIdx_eq_take_drop_succ φs n).symm
@[simp]
lemma eraseIdxEquiv_apply_snd {n : } (ψs : CrAnSection φs) (hn : n < φs.length) :
(eraseIdxEquiv n φs hn ψs).snd = eraseIdx n ψs := by
apply Subtype.ext
simp only [eraseIdxEquiv, appendEquiv, take, List.take_concat_get', List.length_take, drop,
append, Equiv.trans_apply, Equiv.coe_fn_mk, congr_fst, Equiv.prodCongr_apply, Equiv.coe_trans,
Equiv.coe_prodComm, Equiv.coe_refl, Prod.map_apply, Function.comp_apply, Prod.swap_prod_mk,
id_eq, Equiv.prodAssoc_apply, Equiv.coe_fn_symm_mk, eraseIdx]
rw [Nat.min_eq_left (Nat.le_of_succ_le hn), Nat.min_eq_left hn, List.take_take]
simp only [Nat.succ_eq_add_one, le_add_iff_nonneg_right, zero_le, inf_of_le_left]
exact Eq.symm (List.eraseIdx_eq_take_drop_succ ψs.1 n)
lemma eraseIdxEquiv_symm_eq_take_cons_drop {n : } (φs : List 𝓕.States) (hn : n < φs.length)
(a : 𝓕.statesToCrAnType φs[n]) (s : CrAnSection (φs.eraseIdx n)) :
(eraseIdxEquiv n φs hn).symm ⟨a, s⟩ =
congr (by
rw [HepLean.List.take_eraseIdx_same, HepLean.List.drop_eraseIdx_succ]
conv_rhs => rw [← List.take_append_drop n φs]) (append (take n s) (cons a (drop n s))) := by
simp only [eraseIdxEquiv, appendEquiv, Equiv.symm_trans_apply, congr_symm, Equiv.prodCongr_symm,
Equiv.refl_symm, Equiv.prodCongr_apply, Prod.map_apply, Equiv.symm_symm, Equiv.coe_fn_mk,
take_congr, congr_trans_apply, drop_congr, Equiv.prodAssoc_symm_apply, Equiv.coe_refl,
Equiv.prodComm_symm, Equiv.prodComm_apply, Prod.swap_prod_mk, Equiv.coe_fn_symm_mk,
congr_fst_append, id_eq, congr_snd_append]
rw [append_assoc', singletonEquiv_append_eq_cons]
simp only [List.singleton_append, congr_trans_apply]
apply Subtype.ext
simp only [congr_fst]
have hn : (List.take n φs).length = n := by
rw [@List.length_take]
simp only [inf_eq_left]
exact Nat.le_of_succ_le hn
rw [hn]
@[simp]
lemma eraseIdxEquiv_symm_getElem {n : } (φs : List 𝓕.States) (hn : n < φs.length)
(a : 𝓕.statesToCrAnType φs[n]) (s : CrAnSection (φs.eraseIdx n)) :
getElem ((eraseIdxEquiv n φs hn).symm ⟨a,s⟩).1 n
(by rw [length_eq]; exact hn) = ⟨φs[n], a⟩ := by
rw [eraseIdxEquiv_symm_eq_take_cons_drop]
simp only [append, take, cons, drop, congr_fst]
rw [List.getElem_append]
simp only [List.length_take, length_eq, lt_inf_iff, lt_self_iff_false, false_and, ↓reduceDIte]
have h0 : n ⊓ (φs.eraseIdx n).length = n := by
simp only [inf_eq_left]
rw [← HepLean.List.eraseIdx_length _ ⟨n, hn⟩] at hn
exact Nat.le_of_lt_succ hn
simp [h0]
@[simp]
lemma eraseIdxEquiv_symm_eraseIdx {n : } (φs : List 𝓕.States) (hn : n < φs.length)
(a : 𝓕.statesToCrAnType φs[n]) (s : CrAnSection (φs.eraseIdx n)) :
((eraseIdxEquiv n φs hn).symm ⟨a, s⟩).1.eraseIdx n = s.1 := by
change (((eraseIdxEquiv n φs hn).symm ⟨a, s⟩).eraseIdx n).1 = _
rw [← eraseIdxEquiv_apply_snd _ hn]
simp
lemma sum_eraseIdxEquiv (n : ) (φs : List 𝓕.States) (hn : n < φs.length)
(f : CrAnSection φs → M) [AddCommMonoid M] : ∑ (s : CrAnSection φs), f s =
∑ (a : 𝓕.statesToCrAnType φs[n]), ∑ (s : CrAnSection (φs.eraseIdx n)),
f ((eraseIdxEquiv n φs hn).symm ⟨a, s⟩) := by
rw [← (eraseIdxEquiv n φs hn).symm.sum_comp]
rw [Fintype.sum_prod_type]
end CrAnSection
end FieldSpecification