import Mathlib import Nominal.Permutations import Nominal.Support /-! # Definitions and Properties for Equivariance We define equivariance for functions, sets, and binary relations. -/ variable (๐”ธ : Type) [Infinite ๐”ธ] [Countable ๐”ธ] [DecidableEq ๐”ธ] /-! ## Definitions Basic definitions for equivariance. -/ section Definition variable {X Y : Type} [PermSet ๐”ธ X] [PermSet ๐”ธ Y] /-- A function is equivariant if it is invariant to applying a permutation before or after the function. -/ class inductive Function.Equivariant (f : X โ†’ Y) : Prop | intro : (โˆ€ (x : X) (ฯ€ : FPerm ๐”ธ), f (ฯ€ โ€ข x) = ฯ€ โ€ข f x) โ†’ Equivariant f lemma Function.equivariant (f : X โ†’ Y) [Equivariant ๐”ธ f] : โˆ€ (x : X) (ฯ€ : FPerm ๐”ธ), f (ฯ€ โ€ข x) = ฯ€ โ€ข f x := by cases (inferInstance : Equivariant ๐”ธ f); assumption /-- A set is equivariant if it is closed under permutations. -/ class inductive Set.Equivariant (S : Set X) : Prop | intro : (โˆ€ (x : X) (ฯ€ : FPerm ๐”ธ), x โˆˆ S โ†’ ฯ€ โ€ข x โˆˆ S) โ†’ Equivariant S /-- For equivariant sets, we even have "if and only if". -/ lemma Set.equivariant (S : Set X) [Equivariant ๐”ธ S] : โˆ€ (x : X) (ฯ€ : FPerm ๐”ธ), x โˆˆ S โ†” ฯ€ โ€ข x โˆˆ S := by cases (inferInstance : Equivariant ๐”ธ S); rename_i h intro x ฯ€; constructor ยท intro hx; exact h x ฯ€ hx ยท intro hx apply (h (ฯ€ โ€ข x) ฯ€โปยน) at hx simp only [inv_smul_smul] at hx exact hx /-- A binary relation is equivariant if it is closed under permutations. -/ class inductive Rel.Equivariant (R : Rel X Y) : Prop | intro : (โˆ€ (x : X) (y : Y) (ฯ€ : FPerm ๐”ธ), R x y โ†’ R (ฯ€ โ€ข x) (ฯ€ โ€ข y)) โ†’ Equivariant R /-- For equivariant relations, we even have "if and only if". -/ lemma Rel.equivariant (R : Rel X Y) [Rel.Equivariant ๐”ธ R] : โˆ€ (x : X) (y : Y) (ฯ€ : FPerm ๐”ธ), R x y โ†” R (ฯ€ โ€ข x) (ฯ€ โ€ข y) := by cases (inferInstance : Equivariant ๐”ธ R); rename_i h intro x y ฯ€; constructor ยท intro hxy; exact h x y ฯ€ hxy ยท intro hxy apply (h (ฯ€ โ€ข x) (ฯ€ โ€ข y) ฯ€โปยน) at hxy simp only [inv_smul_smul] at hxy exact hxy end Definition /-! ## Trivial Instances Some trivial instances of equivariant functions, sets, and relations. -/ section Trivial variable {X Y Z : Type} [PermSet ๐”ธ X] [PermSet ๐”ธ Y] [PermSet ๐”ธ Z] /-- The identity function is equivariant. -/ instance Function.Equivariant.id : Function.Equivariant ๐”ธ (id : X โ†’ X) := by constructor simp /-- The composition of two equivariant functions is equivariant. -/ instance Function.Equivariant.comp {f : Y โ†’ Z} [Function.Equivariant ๐”ธ f] {g : X โ†’ Y} [Function.Equivariant ๐”ธ g] : Function.Equivariant ๐”ธ (f โˆ˜ g) := by constructor; intro x ฯ€ calc f (g (ฯ€ โ€ข x)) = f (ฯ€ โ€ข g x) := by rw [โ† Function.equivariant ๐”ธ g] _ = ฯ€ โ€ข (f (g x)) := by rw [โ† Function.equivariant ๐”ธ f] /-- If a function is equivariant, its inverse is also equivariant. -/ @[reducible] def Function.Equivariant.inv {f : X โ†’ Y} [Function.Equivariant ๐”ธ f] {inv : Y โ†’ X} (hleft : Function.LeftInverse inv f) (hright : Function.RightInverse inv f) : Function.Equivariant ๐”ธ inv := by constructor; intro y ฯ€ apply hleft.injective rw [Function.equivariant ๐”ธ f, hright, hright] /-- The subset relation is equivariant. -/ instance Set.Equivariant.subset : Rel.Equivariant ๐”ธ (Set.Subset : Set X โ†’ Set X โ†’ Prop) := by constructor; intro S T ฯ€ hST x hx rw [Set.mem_smul_set_iff_inv_smul_mem] at hx rw [Set.mem_smul_set_iff_inv_smul_mem] exact hST hx end Trivial /-! ## Support Propositions relating equivariance to support in (FPerm ๐”ธ)-sets. -/ section Support variable {X Y : Type} [PermSet ๐”ธ X] [PermSet ๐”ธ Y] namespace Function.Equivariant /-- Equivariant functions preserve supports. -/ lemma preserve_support {x : X} {f : X โ†’ Y} [Equivariant ๐”ธ f] {S : Set ๐”ธ} : PermSet.HasSupport ๐”ธ x S โ†’ PermSet.HasSupport ๐”ธ (f x) S := by intro hsupp ฯ€ hฯ€ calc ฯ€ โ€ข f x = f (ฯ€ โ€ข x) := by rw [โ† equivariant ๐”ธ f] _ = f x := by rw [hsupp hฯ€] /-- Equivariant injective functions exactly preserve supports. -/ lemma preserve_support_inj {x : X} {f : X โ†’ Y} [Equivariant ๐”ธ f] {S : Set ๐”ธ} : f.Injective โ†’ (PermSet.HasSupport ๐”ธ x S โ†” PermSet.HasSupport ๐”ธ (f x) S) := by intro hinj; constructor ยท exact preserve_support ๐”ธ ยท intro hsupp ฯ€ hฯ€ by_contra h have : ฯ€ โ€ข f x โ‰  f x := by rw [โ† equivariant ๐”ธ f]; intro hcontra; exact h (hinj hcontra) have : ฯ€ โ€ข f x = f x := hsupp hฯ€ contradiction end Function.Equivariant /-- HasSupport is an equivariant relation. -/ instance PermSet.instHasSupportEquivariant : Rel.Equivariant ๐”ธ (HasSupport ๐”ธ : X โ†’ Set ๐”ธ โ†’ Prop) := by constructor; intro x S ฯ€ hS ฯƒ hฯƒ have hfix : (ฯ€โปยน * ฯƒ * ฯ€) โˆˆ fix ๐”ธ S := by intro a ha calc (ฯ€โปยน * ฯƒ * ฯ€) โ€ข a = ฯ€โปยน โ€ข (ฯƒ โ€ข (ฯ€ โ€ข a)) := rfl _ = ฯ€โปยน โ€ข (ฯ€ โ€ข a) := by rw [hฯƒ (ฯ€ โ€ข a) (Set.smul_mem_smul_set ha)] _ = (ฯ€โปยน * ฯ€) โ€ข a := rfl _ = (1 : FPerm ๐”ธ) โ€ข a := by rw [@Group.inv_mul_cancel] _ = a := rfl calc ฯƒ โ€ข (ฯ€ โ€ข x) = (ฯƒ * ฯ€) โ€ข x := by apply smul_smul _ = (1 * ฯƒ * ฯ€) โ€ข x := rfl _ = (ฯ€ * ฯ€โปยน * ฯƒ * ฯ€) โ€ข x := by rw [@mul_inv_cancel] _ = ฯ€ โ€ข ((ฯ€โปยน * ฯƒ * ฯ€) โ€ข x) := by symm; apply smul_smul _ = ฯ€ โ€ข x := by rw [hS hfix] end Support /-! ## Nominal Sets Properties about equivariance relating to nominal sets. -/ section Nominal variable {X Y : Type} [NominalSet ๐”ธ X] [NominalSet ๐”ธ Y] namespace Function.Equivariant /-- If f is equivariant, then supp (f x) โІ supp x. -/ lemma supp_subset {x : X} {f : X โ†’ Y} [Equivariant ๐”ธ f] : NominalSet.supp ๐”ธ (f x) โІ NominalSet.supp ๐”ธ x := by apply NominalSet.support_subset_supp ยท exact preserve_support ๐”ธ (NominalSet.supp_is_support ๐”ธ) ยท exact NominalSet.supp_finite ๐”ธ /-- If f is equivariant and injective, then supp (f x) = supp x. -/ lemma supp_eq_if_inj {x : X} {f : X โ†’ Y} [Equivariant ๐”ธ f] : Function.Injective f โ†’ NominalSet.supp ๐”ธ (f x) = NominalSet.supp ๐”ธ x := by intro hinj simp [NominalSet.supp, preserve_support_inj ๐”ธ hinj] /-- If f is equivariant and a # x, then a # f x. -/ lemma preserve_fresh {a : ๐”ธ} {x : X} {f : X โ†’ Y} [Equivariant ๐”ธ f] : a # x โ†’ a # f x := by intro hx ha exact hx (supp_subset ๐”ธ ha) /-- If f is equivariant and injective, then a # x iff a # f x. -/ lemma preserve_fresh_inj {a : ๐”ธ} {x : X} {f : X โ†’ Y} [Equivariant ๐”ธ f] : Function.Injective f โ†’ (a # x โ†” a # f x) := by intro hinj rw [NominalSet.IsFresh, NominalSet.IsFresh, supp_eq_if_inj ๐”ธ hinj] end Function.Equivariant /-- If there is an equivariant surjection from a nominal set into an (FPerm ๐”ธ)-Set, then that set is nominal. -/ @[reducible] def NominalSet.ofEquivariantSurjective {X Y : Type} [NominalSet ๐”ธ X] [PermSet ๐”ธ Y] (f : X โ†’ Y) [Function.Equivariant ๐”ธ f] (hsurj : Function.Surjective f) : NominalSet ๐”ธ Y where fin_supp := by intro y obtain โŸจx, hxโŸฉ := hsurj y use (NominalSet.supp ๐”ธ x) constructor ยท rw [โ† hx] exact Function.Equivariant.preserve_support ๐”ธ (supp_is_support ๐”ธ) ยท exact supp_finite ๐”ธ /-- supp is an equivariant function. -/ instance NominalSet.instSuppEquivariant : Function.Equivariant ๐”ธ (supp ๐”ธ : X โ†’ Set ๐”ธ) := by constructor; intro x ฯ€ ext a; constructor ยท apply support_subset_supp ๐”ธ ยท rw [โ† Rel.equivariant ๐”ธ (PermSet.HasSupport ๐”ธ)] exact supp_is_support ๐”ธ ยท apply Set.Finite.smul_set exact supp_finite ๐”ธ ยท intro ha S hS have hsupp : PermSet.HasSupport ๐”ธ x (ฯ€โปยน โ€ข S) := by rw [show x = ฯ€โปยน โ€ข ฯ€ โ€ข x by exact eq_inv_smul_iff.mpr rfl] rw [โ† Rel.equivariant ๐”ธ (PermSet.HasSupport ๐”ธ)] exact hS.out.left rw [Set.mem_smul_set_iff_inv_smul_mem] at ha suffices ฯ€โปยน โ€ข a โˆˆ ฯ€โปยน โ€ข S by rw [Set.smul_mem_smul_set_iff] at this; assumption suffices supp ๐”ธ x โІ ฯ€โปยน โ€ข S by exact this ha apply support_subset_supp ๐”ธ ยท exact hsupp ยท apply Set.Finite.smul_set exact hS.out.right /-- Freshness is an equivariant relation. -/ instance NominalSet.instFreshEquivariant : Rel.Equivariant ๐”ธ (NominalSet.IsFresh : ๐”ธ โ†’ X โ†’ Prop) := by constructor; intro x y ฯ€ h rwa [IsFresh, Function.equivariant ๐”ธ (supp ๐”ธ), Set.smul_mem_smul_set_iff] end Nominal /-! ## Freshness For propositions of the form `ะ˜ a, a R x`, where `R` is an equivariant relation, we do not have to differentiate between "for any fresh a" and "for all fresh a". -/ section Freshness namespace Rel.Equivariant variable {X : Type} [NominalSet ๐”ธ X] {R: Rel ๐”ธ X} {x : X} -- We continue with a circular implication chain argument to show these equivalences. private lemma for_fresh_iffโ‚ : (ะ˜ a, R a x) โ†’ (โˆƒ a, a # x โˆง R a x) := by intro h apply Set.Finite.infinite_compl at h simp at h have hinf : ({a | R a x} \ NominalSet.supp ๐”ธ x).Infinite := Set.Infinite.diff h (NominalSet.supp_finite ๐”ธ) obtain โŸจa, haโŸฉ := hinf.nonempty simp only [Set.mem_diff, Set.mem_setOf_eq] at ha use a; exact ha.symm private lemma for_fresh_iffโ‚‚ [Rel.Equivariant ๐”ธ R] : (โˆƒ a, a # x โˆง R a x) โ†’ (โˆ€ a, a # x โ†’ R a x) := by intro h obtain โŸจa, โŸจhfresha, haโŸฉโŸฉ := h intro b hfreshb rw [Rel.equivariant ๐”ธ R b x โธจa, bโธฉ] rw [PermSet.atom_swap, Equiv.swap_apply_right, NominalSet.fresh_swap_fix ๐”ธ hfresha hfreshb] exact ha private lemma for_fresh_iffโ‚ƒ : (โˆ€ a, a # x โ†’ R a x) โ†’ (ะ˜ a, R a x) := by intro h have hsub : {a : ๐”ธ | R a x}แถœ โІ NominalSet.supp ๐”ธ x := by rw [Set.compl_subset_comm] intro a ha rw [Set.mem_compl_iff] at ha exact h a ha simp only [NominalSet.ForFresh] apply Set.Finite.subset (NominalSet.supp_finite ๐”ธ) hsub /-- The quantifier in `ะ˜ a, a R x` is equivalent to "for any fresh `a`". -/ lemma for_fresh_iff_exists [Rel.Equivariant ๐”ธ R] : ((ะ˜ a, R a x) โ†” (โˆƒ a, a # x โˆง R a x)) := by constructor ยท intro h apply for_fresh_iffโ‚ exact h ยท intro h apply for_fresh_iffโ‚ƒ apply for_fresh_iffโ‚‚ exact h /-- The quantifier in `ะ˜ a, a R x` is equivalent to "for all fresh `a`". -/ lemma for_fresh_iff_all [Rel.Equivariant ๐”ธ R] : ((ะ˜ a, R a x) โ†” (โˆ€ a, a # x โ†’ R a x)) := by constructor ยท intro h apply for_fresh_iffโ‚‚ apply for_fresh_iffโ‚ exact h ยท intro h apply for_fresh_iffโ‚ƒ exact h end Rel.Equivariant end Freshness /-! ## Bundled Functions In the following, we also define a bundled function type for equivariant functions. -/ section BundledFunction /-- A function carrying a proof of its equivariance. -/ structure EquivariantMap (X Y : Type) [PermSet ๐”ธ X] [PermSet ๐”ธ Y] where /-- The underlying function. -/ toFun : X โ†’ Y /-- Proof of equivariance. -/ equivariant : Function.Equivariant ๐”ธ toFun /-- We write `X โ†’โ‚‘ Y` or `X โ†’โ‚‘[๐”ธ] Y` for an equivariant map X โ†’ Y. -/ infixr:25 " โ†’โ‚‘ " => EquivariantMap _ /-- We write `X โ†’โ‚‘ Y` or `X โ†’โ‚‘[๐”ธ] Y` for an equivariant map X โ†’ Y. -/ notation:25 X " โ†’โ‚‘[" A "] " Y => EquivariantMap A X Y variable {X Y Z : Type} [PermSet ๐”ธ X] [PermSet ๐”ธ Y] [PermSet ๐”ธ Z] instance EquivariantMap.toFunEquivariant (f : X โ†’โ‚‘[๐”ธ] Y) : Function.Equivariant ๐”ธ f.toFun := f.equivariant instance : FunLike (X โ†’โ‚‘[๐”ธ] Y) X Y where coe := EquivariantMap.toFun coe_injective' f g h := by cases f; cases g; congr namespace EquivariantMap /-- The identity function. -/ def id : X โ†’โ‚‘[๐”ธ] X := โŸจ_root_.id, inferInstanceโŸฉ /-- Function composition. -/ def comp (f : Y โ†’โ‚‘[๐”ธ] Z) (g : X โ†’โ‚‘[๐”ธ] Y) : X โ†’โ‚‘[๐”ธ] Z := โŸจf.toFun โˆ˜ g.toFun, inferInstanceโŸฉ @[simp] lemma id_app (x : X) : id ๐”ธ x = x := rfl @[simp] lemma comp_app (f : Y โ†’โ‚‘[๐”ธ] Z) (g : X โ†’โ‚‘[๐”ธ] Y) (x : X) : comp ๐”ธ f g x = f (g x) := rfl @[simp] lemma toFun_eq_coe {f : X โ†’โ‚‘[๐”ธ] Y} : f.toFun = (f : X โ†’ Y) := rfl @[ext] lemma ext {f g : X โ†’โ‚‘[๐”ธ] Y} (h : โˆ€ a, f a = g a) : f = g := DFunLike.ext _ _ h end EquivariantMap end BundledFunction /-! ## Equivalences If two types are equivalent and the conversion function is also equivariant, we know some additional information about nominal set structures. -/ section Equivalence /-- An equivalence where the function is equivariant. -/ structure EquivariantEquiv (X Y : Type) [PermSet ๐”ธ X] [PermSet ๐”ธ Y] extends Equiv X Y where toFun_equivariant : Function.Equivariant ๐”ธ toFun invFun_equivariant : Function.Equivariant ๐”ธ invFun := Function.Equivariant.inv ๐”ธ left_inv right_inv def Equivariant.Equiv.symm {๐”ธ X Y : Type} [Infinite ๐”ธ] [Countable ๐”ธ] [DecidableEq ๐”ธ] [PermSet ๐”ธ X] [PermSet ๐”ธ Y] (equiv : EquivariantEquiv ๐”ธ X Y) : EquivariantEquiv ๐”ธ Y X := { toFun := equiv.invFun invFun := equiv.toFun toFun_equivariant := equiv.invFun_equivariant left_inv := equiv.right_inv right_inv := equiv.left_inv } instance EquivariantEquiv.toFunEquivariant {X Y : Type} [PermSet ๐”ธ X] [PermSet ๐”ธ Y] (equiv : EquivariantEquiv ๐”ธ X Y) : Function.Equivariant ๐”ธ equiv.toFun := equiv.toFun_equivariant instance EquivariantEquiv.invFunEquivariant {X Y : Type} [PermSet ๐”ธ X] [PermSet ๐”ธ Y] (equiv : EquivariantEquiv ๐”ธ X Y) : Function.Equivariant ๐”ธ equiv.invFun := equiv.invFun_equivariant /-- If an (FPerm ๐”ธ)-Set is equivalent to a nominal set, it is also a nominal set. -/ @[reducible] def NominalSet.ofEquivariantEquiv {X Y : Type} [PermSet ๐”ธ X] [NominalSet ๐”ธ Y] (equiv : EquivariantEquiv ๐”ธ X Y) : NominalSet ๐”ธ X := NominalSet.ofEquivariantSurjective ๐”ธ equiv.invFun equiv.symm.surjective /-- If two nominal sets are equivalent, the corresponding least supports are equal. -/ lemma EquivariantEquiv.supp_eq {X Y : Type} [NominalSet ๐”ธ X] [NominalSet ๐”ธ Y] (equiv : EquivariantEquiv ๐”ธ X Y) (x : X) : NominalSet.supp ๐”ธ x = NominalSet.supp ๐”ธ (equiv.toFun x) := by symm apply Function.Equivariant.supp_eq_if_inj exact equiv.injective end Equivalence