Imports
/-
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
-/
module
public import Physlib.QFT.PerturbationTheory.WickContraction.BasicInvolution associated with a contraction
@[expose] public section
The involution of Fin n associated with a Wick contraction c : WickContraction n as follows.
If i : Fin n is contracted in c then it is taken to its dual, otherwise
it is taken to itself.
def toInvolution : {f : Fin n → Fin n // Function.Involutive f} :=
⟨fun i => if h : (c.getDual? i).isSome then (c.getDual? i).get h else i, 𝓕:FieldSpecificationn:ℕc:WickContraction n⊢ Function.Involutive fun i => if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i
𝓕:FieldSpecificationn:ℕc:WickContraction ni:Fin n⊢ (fun i => if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i)
((fun i => if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i) i) =
i
𝓕:FieldSpecificationn:ℕc:WickContraction ni:Fin nh:(c.getDual? i).isSome = true⊢ (fun i => if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i)
((fun i => if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i) i) =
i𝓕:FieldSpecificationn:ℕc:WickContraction ni:Fin nh:¬(c.getDual? i).isSome = true⊢ (fun i => if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i)
((fun i => if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i) i) =
i
𝓕:FieldSpecificationn:ℕc:WickContraction ni:Fin nh:(c.getDual? i).isSome = true⊢ (fun i => if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i)
((fun i => if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i) i) =
i All goals completed! 🐙
𝓕:FieldSpecificationn:ℕc:WickContraction ni:Fin nh:¬(c.getDual? i).isSome = true⊢ (fun i => if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i)
((fun i => if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i) i) =
i All goals completed! 🐙⟩
The Wick contraction formed by an involution f of Fin n by taking as the contracted
sets of the contraction the orbits of f of cardinality 2.
neg.right.right 𝓕:FieldSpecificationn:ℕc:WickContraction nf:{ f // Function.Involutive f }i:Fin nha:{i, ↑f i}.card = 2 ∧ ∃ i_1, {i_1, ↑f i_1} = {i, ↑f i}j:Fin nhb:{j, ↑f j}.card = 2 ∧ ∃ i, {i, ↑f i} = {j, ↑f j}h:¬i = jhi:¬i = ↑f j⊢ ¬j = ineg.right.right.I 𝓕:FieldSpecificationn:ℕc:WickContraction nf:{ f // Function.Involutive f }i:Fin nha:{i, ↑f i}.card = 2 ∧ ∃ i_1, {i_1, ↑f i_1} = {i, ↑f i}j:Fin nhb:{j, ↑f j}.card = 2 ∧ ∃ i, {i, ↑f i} = {j, ↑f j}h:¬i = jhi:¬i = ↑f j⊢ Function.Injective ↑f
exact fun a => h (id (Eq.symm a)) neg.right.right.I 𝓕:FieldSpecificationn:ℕc:WickContraction nf:{ f // Function.Involutive f }i:Fin nha:{i, ↑f i}.card = 2 ∧ ∃ i_1, {i_1, ↑f i_1} = {i, ↑f i}j:Fin nhb:{j, ↑f j}.card = 2 ∧ ∃ i, {i, ↑f i} = {j, ↑f j}h:¬i = jhi:¬i = ↑f j⊢ Function.Injective ↑f
exact Function.Involutive.injective f.2 All goals completed! 🐙⟩
@[simp]
lemma fromInvolution_getDual?_isSome (f : {f : Fin n → Fin n // Function.Involutive f})
(i : Fin n) : ((fromInvolution f).getDual? i).isSome ↔ f.1 i ≠ i := by n:ℕf:{ f // Function.Involutive f }i:Fin n⊢ ((fromInvolution f).getDual? i).isSome = true ↔ ↑f i ≠ i
rw [getDual?_isSome_iff n:ℕf:{ f // Function.Involutive f }i:Fin n⊢ (∃ a, i ∈ ↑a) ↔ ↑f i ≠ i n:ℕf:{ f // Function.Involutive f }i:Fin n⊢ (∃ a, i ∈ ↑a) ↔ ↑f i ≠ i] n:ℕf:{ f // Function.Involutive f }i:Fin n⊢ (∃ a, i ∈ ↑a) ↔ ↑f i ≠ i
apply Iff.intro mp n:ℕf:{ f // Function.Involutive f }i:Fin n⊢ (∃ a, i ∈ ↑a) → ↑f i ≠ impr n:ℕf:{ f // Function.Involutive f }i:Fin n⊢ ↑f i ≠ i → ∃ a, i ∈ ↑a
· mp n:ℕf:{ f // Function.Involutive f }i:Fin n⊢ (∃ a, i ∈ ↑a) → ↑f i ≠ i intro h mp n:ℕf:{ f // Function.Involutive f }i:Fin nh:∃ a, i ∈ ↑a⊢ ↑f i ≠ i
obtain ⟨a, ha⟩ := h mp n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha:i ∈ ↑a⊢ ↑f i ≠ i
have ha2 := a.2 mp n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha:i ∈ ↑aha2:↑a ∈ ↑(fromInvolution f)⊢ ↑f i ≠ i
simp only [fromInvolution, Finset.mem_filter, Finset.mem_univ, true_and] at ha2 mp n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha:i ∈ ↑aha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑a⊢ ↑f i ≠ i
obtain ⟨j, h⟩ := ha2.2 mp n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha:i ∈ ↑aha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nh:{j, ↑f j} = ↑a⊢ ↑f i ≠ i
rw [← h mp n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nha:i ∈ {j, ↑f j}h:{j, ↑f j} = ↑a⊢ ↑f i ≠ i mp n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nha:i ∈ {j, ↑f j}h:{j, ↑f j} = ↑a⊢ ↑f i ≠ i] at hamp n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nha:i ∈ {j, ↑f j}h:{j, ↑f j} = ↑a⊢ ↑f i ≠ i
have hj : f.1 j ≠ j := by n:ℕf:{ f // Function.Involutive f }i:Fin n⊢ ((fromInvolution f).getDual? i).isSome = true ↔ ↑f i ≠ i mp n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nha:i ∈ {j, ↑f j}h:{j, ↑f j} = ↑ahj:↑f j ≠ j⊢ ↑f i ≠ i
intro hn n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nha:i ∈ {j, ↑f j}h:{j, ↑f j} = ↑ahn:↑f j = j⊢ Falsemp n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nha:i ∈ {j, ↑f j}h:{j, ↑f j} = ↑ahj:↑f j ≠ j⊢ ↑f i ≠ i
rw [hn n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nha:i ∈ {j, ↑f j}h:{j, j} = ↑ahn:↑f j = j⊢ False n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nha:i ∈ {j, ↑f j}h:{j, j} = ↑ahn:↑f j = j⊢ Falsemp n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nha:i ∈ {j, ↑f j}h:{j, ↑f j} = ↑ahj:↑f j ≠ j⊢ ↑f i ≠ i] at h n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nha:i ∈ {j, ↑f j}h:{j, j} = ↑ahn:↑f j = j⊢ Falsemp n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nha:i ∈ {j, ↑f j}h:{j, ↑f j} = ↑ahj:↑f j ≠ j⊢ ↑f i ≠ i
simp [← h] at ha2mp n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nha:i ∈ {j, ↑f j}h:{j, ↑f j} = ↑ahj:↑f j ≠ j⊢ ↑f i ≠ imp n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nha:i ∈ {j, ↑f j}h:{j, ↑f j} = ↑ahj:↑f j ≠ j⊢ ↑f i ≠ i
simp only [Finset.mem_insert, Finset.mem_singleton] at ha mp n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nh:{j, ↑f j} = ↑ahj:↑f j ≠ jha:i = j ∨ i = ↑f j⊢ ↑f i ≠ i
rcases ha with rfl | rfl mp.inl n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑ah:{i, ↑f i} = ↑ahj:↑f i ≠ i⊢ ↑f i ≠ imp.inr n:ℕf:{ f // Function.Involutive f }a:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nh:{j, ↑f j} = ↑ahj:↑f j ≠ j⊢ ↑f (↑f j) ≠ ↑f j
· mp.inl n:ℕf:{ f // Function.Involutive f }i:Fin na:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑ah:{i, ↑f i} = ↑ahj:↑f i ≠ i⊢ ↑f i ≠ i exact hj All goals completed! 🐙
· mp.inr n:ℕf:{ f // Function.Involutive f }a:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nh:{j, ↑f j} = ↑ahj:↑f j ≠ j⊢ ↑f (↑f j) ≠ ↑f j rw [f.2 mp.inr n:ℕf:{ f // Function.Involutive f }a:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nh:{j, ↑f j} = ↑ahj:↑f j ≠ j⊢ j ≠ ↑f j mp.inr n:ℕf:{ f // Function.Involutive f }a:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nh:{j, ↑f j} = ↑ahj:↑f j ≠ j⊢ j ≠ ↑f j]mp.inr n:ℕf:{ f // Function.Involutive f }a:↥↑(fromInvolution f)ha2:(↑a).card = 2 ∧ ∃ i, {i, ↑f i} = ↑aj:Fin nh:{j, ↑f j} = ↑ahj:↑f j ≠ j⊢ j ≠ ↑f j
exact hj.symm All goals completed! 🐙
· mpr n:ℕf:{ f // Function.Involutive f }i:Fin n⊢ ↑f i ≠ i → ∃ a, i ∈ ↑a intro hi mpr n:ℕf:{ f // Function.Involutive f }i:Fin nhi:↑f i ≠ i⊢ ∃ a, i ∈ ↑a
use ⟨{i, f.1 i}, by n:ℕf:{ f // Function.Involutive f }i:Fin nhi:↑f i ≠ i⊢ {i, ↑f i} ∈ ↑(fromInvolution f)
simp only [fromInvolution, Finset.mem_filter, Finset.mem_univ, exists_apply_eq_apply,
and_true, true_and] n:ℕf:{ f // Function.Involutive f }i:Fin nhi:↑f i ≠ i⊢ {i, ↑f i}.card = 2
exact Finset.card_pair hi.symm All goals completed! 🐙⟩
simp All goals completed! 🐙
lemma fromInvolution_getDual?_eq_some (f : {f : Fin n → Fin n // Function.Involutive f}) (i : Fin n)
(h : ((fromInvolution f).getDual? i).isSome) :
((fromInvolution f).getDual? i) = some (f.1 i) := by n:ℕf:{ f // Function.Involutive f }i:Fin nh:((fromInvolution f).getDual? i).isSome = true⊢ (fromInvolution f).getDual? i = some (↑f i)
rw [getDual?_eq_some_iff_mem n:ℕf:{ f // Function.Involutive f }i:Fin nh:((fromInvolution f).getDual? i).isSome = true⊢ {i, ↑f i} ∈ ↑(fromInvolution f) n:ℕf:{ f // Function.Involutive f }i:Fin nh:((fromInvolution f).getDual? i).isSome = true⊢ {i, ↑f i} ∈ ↑(fromInvolution f)] n:ℕf:{ f // Function.Involutive f }i:Fin nh:((fromInvolution f).getDual? i).isSome = true⊢ {i, ↑f i} ∈ ↑(fromInvolution f)
simp only [fromInvolution, Finset.mem_filter, Finset.mem_univ, exists_apply_eq_apply, and_true,
true_and] n:ℕf:{ f // Function.Involutive f }i:Fin nh:((fromInvolution f).getDual? i).isSome = true⊢ {i, ↑f i}.card = 2
exact Finset.card_pair (Ne.symm ((fromInvolution_getDual?_isSome f i).mp h)) All goals completed! 🐙@[simp]
lemma fromInvolution_getDual?_get (f : {f : Fin n → Fin n // Function.Involutive f}) (i : Fin n)
(h : ((fromInvolution f).getDual? i).isSome) :
((fromInvolution f).getDual? i).get h = (f.1 i) :=
Option.get_of_mem h (fromInvolution_getDual?_eq_some f i h)lemma toInvolution_fromInvolution : fromInvolution c.toInvolution = c := by n:ℕc:WickContraction n⊢ fromInvolution c.toInvolution = c
apply Subtype.ext n:ℕc:WickContraction n⊢ ↑(fromInvolution c.toInvolution) = ↑c
simp only [fromInvolution, toInvolution] n:ℕc:WickContraction n⊢ {x | x.card = 2 ∧ ∃ i, {i, if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i} = x} = ↑c
ext a n:ℕc:WickContraction na:Finset (Fin n)⊢ a ∈ {x | x.card = 2 ∧ ∃ i, {i, if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i} = x} ↔ a ∈ ↑c
simp only [Finset.mem_filter, Finset.mem_univ, true_and] n:ℕc:WickContraction na:Finset (Fin n)⊢ (a.card = 2 ∧ ∃ i, {i, if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i} = a) ↔ a ∈ ↑c
apply Iff.intro mp n:ℕc:WickContraction na:Finset (Fin n)⊢ (a.card = 2 ∧ ∃ i, {i, if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i} = a) → a ∈ ↑cmpr n:ℕc:WickContraction na:Finset (Fin n)⊢ a ∈ ↑c → a.card = 2 ∧ ∃ i, {i, if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i} = a
· mp n:ℕc:WickContraction na:Finset (Fin n)⊢ (a.card = 2 ∧ ∃ i, {i, if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i} = a) → a ∈ ↑c intro h mp n:ℕc:WickContraction na:Finset (Fin n)h:a.card = 2 ∧ ∃ i, {i, if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i} = a⊢ a ∈ ↑c
obtain ⟨i, hi⟩ := h.2 mp n:ℕc:WickContraction na:Finset (Fin n)h:a.card = 2 ∧ ∃ i, {i, if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i} = ai:Fin nhi:{i, if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i} = a⊢ a ∈ ↑c
split at hi mp.isTrue n:ℕc:WickContraction na:Finset (Fin n)h:a.card = 2 ∧ ∃ i, {i, if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i} = ai:Fin nh✝:(c.getDual? i).isSome = truehi:{i, (c.getDual? i).get h✝} = a⊢ a ∈ ↑cmp.isFalse n:ℕc:WickContraction na:Finset (Fin n)h:a.card = 2 ∧ ∃ i, {i, if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i} = ai:Fin nh✝:¬(c.getDual? i).isSome = truehi:{i, i} = a⊢ a ∈ ↑c
· mp.isTrue n:ℕc:WickContraction na:Finset (Fin n)h:a.card = 2 ∧ ∃ i, {i, if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i} = ai:Fin nh✝:(c.getDual? i).isSome = truehi:{i, (c.getDual? i).get h✝} = a⊢ a ∈ ↑c subst hi mp.isTrue n:ℕc:WickContraction ni:Fin nh✝:(c.getDual? i).isSome = trueh:{i, (c.getDual? i).get h✝}.card = 2 ∧
∃ i_1, {i_1, if h : (c.getDual? i_1).isSome = true then (c.getDual? i_1).get h else i_1} = {i, (c.getDual? i).get h✝}⊢ {i, (c.getDual? i).get h✝} ∈ ↑c
simp All goals completed! 🐙
· mp.isFalse n:ℕc:WickContraction na:Finset (Fin n)h:a.card = 2 ∧ ∃ i, {i, if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i} = ai:Fin nh✝:¬(c.getDual? i).isSome = truehi:{i, i} = a⊢ a ∈ ↑c subst hi mp.isFalse n:ℕc:WickContraction ni:Fin nh✝:¬(c.getDual? i).isSome = trueh:{i, i}.card = 2 ∧ ∃ i_1, {i_1, if h : (c.getDual? i_1).isSome = true then (c.getDual? i_1).get h else i_1} = {i, i}⊢ {i, i} ∈ ↑c
simp [Finset.insert_eq_of_mem] at h All goals completed! 🐙
· mpr n:ℕc:WickContraction na:Finset (Fin n)⊢ a ∈ ↑c → a.card = 2 ∧ ∃ i, {i, if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i} = a intro ha mpr n:ℕc:WickContraction na:Finset (Fin n)ha:a ∈ ↑c⊢ a.card = 2 ∧ ∃ i, {i, if h : (c.getDual? i).isSome = true then (c.getDual? i).get h else i} = a
refine ⟨c.2.1 a ha, c.fstFieldOfContract ⟨a, ha⟩, ?_⟩ mpr n:ℕc:WickContraction na:Finset (Fin n)ha:a ∈ ↑c⊢ {c.fstFieldOfContract ⟨a, ha⟩,
if h : (c.getDual? (c.fstFieldOfContract ⟨a, ha⟩)).isSome = true then
(c.getDual? (c.fstFieldOfContract ⟨a, ha⟩)).get h
else c.fstFieldOfContract ⟨a, ha⟩} =
a
simp only [fstFieldOfContract_getDual?, Option.isSome_some, ↓reduceDIte, Option.get_some] mpr n:ℕc:WickContraction na:Finset (Fin n)ha:a ∈ ↑c⊢ {c.fstFieldOfContract ⟨a, ha⟩, c.sndFieldOfContract ⟨a, ha⟩} = a
exact (finset_eq_fstFieldOfContract_sndFieldOfContract c ⟨a, ha⟩).symm All goals completed! 🐙lemma fromInvolution_toInvolution (f : {f : Fin n → Fin n // Function.Involutive f}) :
(fromInvolution f).toInvolution = f := by n:ℕf:{ f // Function.Involutive f }⊢ (fromInvolution f).toInvolution = f
apply Subtype.ext n:ℕf:{ f // Function.Involutive f }⊢ ↑(fromInvolution f).toInvolution = ↑f
funext i n:ℕf:{ f // Function.Involutive f }i:Fin n⊢ ↑(fromInvolution f).toInvolution i = ↑f i
simp only [toInvolution] n:ℕf:{ f // Function.Involutive f }i:Fin n⊢ (if h : ((fromInvolution f).getDual? i).isSome = true then ((fromInvolution f).getDual? i).get h else i) = ↑f i
split isTrue n:ℕf:{ f // Function.Involutive f }i:Fin nh✝:((fromInvolution f).getDual? i).isSome = true⊢ ((fromInvolution f).getDual? i).get h✝ = ↑f iisFalse n:ℕf:{ f // Function.Involutive f }i:Fin nh✝:¬((fromInvolution f).getDual? i).isSome = true⊢ i = ↑f i
· isTrue n:ℕf:{ f // Function.Involutive f }i:Fin nh✝:((fromInvolution f).getDual? i).isSome = true⊢ ((fromInvolution f).getDual? i).get h✝ = ↑f i simp All goals completed! 🐙
· isFalse n:ℕf:{ f // Function.Involutive f }i:Fin nh✝:¬((fromInvolution f).getDual? i).isSome = true⊢ i = ↑f i rename_i h isFalse n:ℕf:{ f // Function.Involutive f }i:Fin nh:¬((fromInvolution f).getDual? i).isSome = true⊢ i = ↑f i
simp only [fromInvolution_getDual?_isSome, ne_eq, Decidable.not_not] at h isFalse n:ℕf:{ f // Function.Involutive f }i:Fin nh:↑f i = i⊢ i = ↑f i
exact h.symm All goals completed! 🐙
The equivalence between Wick contractions for n and involutions of Fin n.
The involution of Fin n associated with a Wick contraction c : WickContraction n as follows.
If i : Fin n is contracted in c then it is taken to its dual, otherwise
it is taken to itself.
def equivInvolution : WickContraction n ≃ {f : Fin n → Fin n // Function.Involutive f} where
toFun := toInvolution
invFun := fromInvolution
left_inv := toInvolution_fromInvolution
right_inv := fromInvolution_toInvolution