diff options
| author | Hannes Schulze <contact@haschu.me> | 2026-04-15 16:18:07 +0200 |
|---|---|---|
| committer | Hannes Schulze <contact@haschu.me> | 2026-04-15 16:18:47 +0200 |
| commit | 2e5f7e22761bd30857bbe067862a8b256805ecd8 (patch) | |
| tree | c40311802db91f935bc0a1ea00fbc98b5ae4c141 /Nominal | |
| parent | 37f7c86a7591da1233cdf1d293bf851f43c65ba1 (diff) | |
fs constructions
Diffstat (limited to 'Nominal')
| -rw-r--r-- | Nominal/Instances/Basic.lean | 2 | ||||
| -rw-r--r-- | Nominal/Instances/Finsupp.lean | 312 | ||||
| -rw-r--r-- | Nominal/Permutations.lean | 12 | ||||
| -rw-r--r-- | Nominal/Support.lean | 10 |
4 files changed, 335 insertions, 1 deletions
diff --git a/Nominal/Instances/Basic.lean b/Nominal/Instances/Basic.lean index 7a88eeb..a7aec47 100644 --- a/Nominal/Instances/Basic.lean +++ b/Nominal/Instances/Basic.lean @@ -398,7 +398,7 @@ instance : PermSet 𝔸 S where exact MulAction.one_smul x.val mul_smul π τ x := by apply Subtype.ext - exact SemigroupAction.mul_smul π τ x.val + exact mul_smul π τ x.val @[simp] lemma smul_val (π : FPerm 𝔸) (x : S) : (π • x).val = π • x.val := rfl diff --git a/Nominal/Instances/Finsupp.lean b/Nominal/Instances/Finsupp.lean new file mode 100644 index 0000000..360c88a --- /dev/null +++ b/Nominal/Instances/Finsupp.lean @@ -0,0 +1,312 @@ +import Mathlib +import Nominal.Support +import Nominal.Equivariance +import Nominal.Category +import Nominal.Permutations +import Nominal.Instances.Basic + +/-! +# Constructing Finitely Supported Sets + +We can restrict arbitrary `(FPerm 𝔸)`-sets to finitely supported subsets, which are nominal sets. + +Examples of this include finitely supported sets (`FinsuppSet`) and finitely supported functions (`FinsuppFunction`). +-/ + +variable (𝔸 : Type) [Infinite 𝔸] [Countable 𝔸] [DecidableEq 𝔸] + +namespace PermSet + +/-! +## Finitely Supported Subsets + +We first define how every `PermSet` can be restricted to its finitely supported elements (`Finsupp`), which form a +nominal set. +-/ +section FSSubsets + +/-- Restrict a type to its finitely supported elements -/ +abbrev Finsupp (X : Type) [PermSet 𝔸 X] : Type := + { x : X // ∃ S, PermSet.HasSupport 𝔸 x S ∧ S.Finite } + +namespace Finsupp + +variable {X : Type} [PermSet 𝔸 X] + +instance : PermSet 𝔸 (Finsupp 𝔸 X) where + smul π x := ⟨π • x.val, by + obtain ⟨S, ⟨hS₁, hS₂⟩⟩ := x.prop + use π • S; constructor + · rw [← Rel.equivariant 𝔸 (HasSupport 𝔸)] + exact hS₁ + · exact Set.Finite.smul_set hS₂⟩ + one_smul x := by + apply Subtype.ext + exact MulAction.one_smul x.val + mul_smul π τ x := by + apply Subtype.ext + exact mul_smul π τ x.val + +@[simp] lemma smul_val (π : FPerm 𝔸) (x : Finsupp 𝔸 X) : (π • x).val = π • x.val := rfl + +instance instValEquivariant : Function.Equivariant 𝔸 (Subtype.val : Finsupp 𝔸 X → X) := by + constructor; simp + +instance : NominalSet 𝔸 (Finsupp 𝔸 X) where + fin_supp x := by + obtain ⟨S, ⟨hS₁, hS₂⟩⟩ := x.prop + use S; constructor + · intro π hπ + apply Subtype.ext + exact hS₁ hπ + · exact hS₂ + +end Finsupp + +end FSSubsets + +/-! +## Finitely Supported Sets + +Since the powerset of an (FPerm 𝔸)-set is an (FPerm 𝔸)-set, we can restrict ourselves to finitely supported sets to +construct a nominal set `FinsuppSet`. + +Furthermore, common binary operations such as union, intersection, and difference are equivariant functions. +-/ +section FSSets + +abbrev FinsuppSet (X : Type) [PermSet 𝔸 X] : Type := + Finsupp 𝔸 (Set X) + +namespace FinsuppSet + +variable (X Y : Type) [NominalSet 𝔸 X] [NominalSet 𝔸 Y] + +private def union' : (FinsuppSet 𝔸 X × FinsuppSet 𝔸 X) → Set X := + fun (S₁, S₂) ↦ S₁.val ∪ S₂.val + +instance : Function.Equivariant 𝔸 (union' 𝔸 X) := by + constructor; intro (S₁, S₂) π + simp only [union', PermSet.Finsupp.smul_val] + exact Eq.symm Set.smul_set_union + +def union : (FinsuppSet 𝔸 X × FinsuppSet 𝔸 X) → FinsuppSet 𝔸 X := + fun p ↦ ⟨union' 𝔸 X p, by + use NominalSet.supp 𝔸 p; constructor + · apply Function.Equivariant.preserve_support + apply NominalSet.supp_is_support + · apply NominalSet.supp_finite⟩ + +instance : Function.Equivariant 𝔸 (union 𝔸 X) := by + constructor; intro p π + apply Subtype.ext + simp only [union, Finsupp.smul_val] + apply Function.equivariant + +instance : Union (FinsuppSet 𝔸 X) := ⟨Function.curry (union 𝔸 X)⟩ + +@[simp] lemma union_val {S₁ S₂ : FinsuppSet 𝔸 X} : + (S₁ ∪ S₂).val = S₁.val ∪ S₂.val := rfl + +@[simp] lemma union_equivariant {S₁ S₂ : FinsuppSet 𝔸 X} {π : FPerm 𝔸} : + π • (S₁ ∪ S₂) = π • S₁ ∪ π • S₂ := by + show π • (union _ _ (S₁, S₂)) = union _ _ (π • (S₁, S₂)) + rw [← Function.equivariant] + +private def inter' : (FinsuppSet 𝔸 X × FinsuppSet 𝔸 X) → Set X := + fun (S₁, S₂) ↦ S₁.val ∩ S₂.val + +instance : Function.Equivariant 𝔸 (inter' 𝔸 X) := by + constructor; intro (S₁, S₂) π + simp only [inter', PermSet.Finsupp.smul_val] + exact Eq.symm Set.smul_set_inter + +def inter : (FinsuppSet 𝔸 X × FinsuppSet 𝔸 X) → FinsuppSet 𝔸 X := + fun p ↦ ⟨inter' 𝔸 X p, by + use NominalSet.supp 𝔸 p; constructor + · apply Function.Equivariant.preserve_support + apply NominalSet.supp_is_support + · apply NominalSet.supp_finite⟩ + +instance : Function.Equivariant 𝔸 (inter 𝔸 X) := by + constructor; intro p π + apply Subtype.ext + simp only [inter, Finsupp.smul_val] + apply Function.equivariant + +instance : Inter (FinsuppSet 𝔸 X) := ⟨Function.curry (inter 𝔸 X)⟩ + +@[simp] lemma inter_val {S₁ S₂ : FinsuppSet 𝔸 X} : + (S₁ ∩ S₂).val = S₁.val ∩ S₂.val := rfl + +@[simp] lemma inter_equivariant {S₁ S₂ : FinsuppSet 𝔸 X} {π : FPerm 𝔸} : + π • (S₁ ∩ S₂) = π • S₁ ∩ π • S₂ := by + show π • (inter _ _ (S₁, S₂)) = inter _ _ (π • (S₁, S₂)) + rw [← Function.equivariant] + +private def sdiff' : (FinsuppSet 𝔸 X × FinsuppSet 𝔸 X) → Set X := + fun (S₁, S₂) ↦ S₁.val \ S₂.val + +instance : Function.Equivariant 𝔸 (sdiff' 𝔸 X) := by + constructor; intro (S₁, S₂) π + simp only [sdiff', PermSet.Finsupp.smul_val] + exact Eq.symm Set.smul_set_sdiff + +def sdiff : (FinsuppSet 𝔸 X × FinsuppSet 𝔸 X) → FinsuppSet 𝔸 X := + fun p ↦ ⟨sdiff' 𝔸 X p, by + use NominalSet.supp 𝔸 p; constructor + · apply Function.Equivariant.preserve_support + apply NominalSet.supp_is_support + · apply NominalSet.supp_finite⟩ + +instance : Function.Equivariant 𝔸 (sdiff 𝔸 X) := by + constructor; intro p π + apply Subtype.ext + simp only [sdiff, Finsupp.smul_val] + apply Function.equivariant + +instance : SDiff (FinsuppSet 𝔸 X) := ⟨Function.curry (sdiff 𝔸 X)⟩ + +@[simp] lemma sdiff_val {S₁ S₂ : FinsuppSet 𝔸 X} : + (S₁ \ S₂).val = S₁.val \ S₂.val := rfl + +@[simp] lemma sdiff_equivariant {S₁ S₂ : FinsuppSet 𝔸 X} {π : FPerm 𝔸} : + π • (S₁ \ S₂) = π • S₁ \ π • S₂ := by + show π • (sdiff _ _ (S₁, S₂)) = sdiff _ _ (π • (S₁, S₂)) + rw [← Function.equivariant] + +end FinsuppSet + +end FSSets + +/-! +## Finitely Supported Functions + +Since functions between (FPerm 𝔸)-sets are an (FPerm 𝔸)-set, we can restrict ourselves to finitely supported functions +to construct a nominal set `FinsuppFunction`. + +Furthermore, there is an isomorphism between finietly supported functions (X →fs Y) and sets 𝒫fs (X × Y). +-/ +section FSFunctions + +abbrev FinsuppFunction (X Y : Type) [PermSet 𝔸 X] [PermSet 𝔸 Y] : Type := + Finsupp 𝔸 (X → Y) + +lemma FinsuppFunction.supp_image {X Y : Type} [NominalSet 𝔸 X] [NominalSet 𝔸 Y] (f : PermSet.FinsuppFunction 𝔸 X Y) : + ∀ x, PermSet.HasSupport 𝔸 (f.val x) (NominalSet.supp 𝔸 f ∪ NominalSet.supp 𝔸 x) := by + intro x π hπ + have hπ₁ : π ∈ PermSet.fix 𝔸 (NominalSet.supp 𝔸 f) := by + apply PermSet.fix_antitone_mem 𝔸 hπ; exact Set.subset_union_left + have hπ₂ : π ∈ PermSet.fix 𝔸 (NominalSet.supp 𝔸 x) := by + apply PermSet.fix_antitone_mem 𝔸 hπ; exact Set.subset_union_right + suffices (π • f).val (π • x) = f.val x by + simp at this + exact this + rw [show π • f = f from NominalSet.supp_is_support 𝔸 hπ₁] + rw [show π • x = x from NominalSet.supp_is_support 𝔸 hπ₂] + +variable (X Y : Type) [NominalSet 𝔸 X] [NominalSet 𝔸 Y] + +namespace Finsupp + +private def flatten' (f : X → PermSet.FinsuppSet 𝔸 Y) : Set (X × Y) := + {p : X × Y | p.snd ∈ (f p.fst).val} + +instance : Function.Equivariant 𝔸 (flatten' 𝔸 X Y) := by + constructor + intro f π; ext ⟨x, y⟩; constructor + · simp only [flatten', PermSet.smul_function, PermSet.Finsupp.smul_val, Set.mem_setOf_eq] + intro hy + have hy' : π⁻¹ • y ∈ π⁻¹ • π • (f (π⁻¹ • x)).val := by + rw [Set.smul_mem_smul_set_iff]; exact hy + rw [inv_smul_smul] at hy' + rw [show (x, y) = π • (π⁻¹ • x, π⁻¹ • y) by simp] + rw [Set.smul_mem_smul_set_iff] + exact hy' + · intro hxy + have hxy' : π⁻¹ • (x, y) ∈ π⁻¹ • π • flatten' 𝔸 X Y f := by + rw [Set.smul_mem_smul_set_iff]; exact hxy + simp only [inv_smul_smul, Prod.smul_mk, flatten', Set.mem_setOf_eq] at hxy' + simp only [flatten', PermSet.smul_function, PermSet.Finsupp.smul_val, Set.mem_setOf_eq] + have hy : π • π⁻¹ • y ∈ π • (f (π⁻¹ • x)).val := by + rw [Set.smul_mem_smul_set_iff]; exact hxy' + simp only [smul_inv_smul] at hy + exact hy + +def flatten (f : PermSet.FinsuppFunction 𝔸 X (PermSet.FinsuppSet 𝔸 Y)) : + PermSet.FinsuppSet 𝔸 (X × Y) := + ⟨flatten' 𝔸 X Y f.val, by + obtain ⟨S, ⟨hS₁, hS₂⟩⟩ := f.prop + use S; constructor + · apply Function.Equivariant.preserve_support + exact hS₁ + · exact hS₂⟩ + +instance : Function.Equivariant 𝔸 (flatten 𝔸 X Y) := by + constructor; intro p π + apply Subtype.ext + simp only [flatten, Finsupp.smul_val] + apply Function.equivariant + +private def unflatten' (S : PermSet.FinsuppSet 𝔸 (X × Y)) : X → (PermSet.FinsuppSet 𝔸 Y) := + fun x ↦ ⟨{y : Y | (x, y) ∈ S.val}, by + use NominalSet.supp 𝔸 S ∪ NominalSet.supp 𝔸 x; constructor + · intro π hπ + have hfixx : π⁻¹ • x = x := by + apply NominalSet.supp_is_support + rw [← PermSet.fix_inv] + exact PermSet.fix_antitone_mem 𝔸 hπ Set.subset_union_right + have hfixS : π⁻¹ • S = S := by + apply NominalSet.supp_is_support + rw [← PermSet.fix_inv] + exact PermSet.fix_antitone_mem 𝔸 hπ Set.subset_union_left + ext y; constructor + · intro hy + simp only [Set.mem_smul_set_iff_inv_smul_mem, Set.mem_setOf_eq] at hy + rw [← hfixx, ← hfixS, smul_val, Set.mem_inv_smul_set_iff, Prod.smul_mk, smul_inv_smul, smul_inv_smul] at hy + exact hy + · intro hy + simp only [Set.mem_smul_set_iff_inv_smul_mem, Set.mem_setOf_eq] + simp only [Set.mem_setOf_eq] at hy + have hy' : (π⁻¹ • x, π⁻¹ • y) ∈ π⁻¹ • S.val := Set.smul_mem_smul_set hy + rw [hfixx, ← smul_val, hfixS] at hy' + exact hy' + · simp only [Set.finite_union]; constructor + · exact NominalSet.supp_finite 𝔸 + · exact NominalSet.supp_finite 𝔸⟩ + +instance : Function.Equivariant 𝔸 (unflatten' 𝔸 X Y) := by + constructor + intro S π + ext x y + simp only [unflatten', smul_val, Set.mem_setOf_eq, smul_function] + simp only [Set.mem_smul_set_iff_inv_smul_mem, Set.mem_setOf_eq, Prod.smul_mk] + +def unflatten (S : PermSet.FinsuppSet 𝔸 (X × Y)) : PermSet.FinsuppFunction 𝔸 X (PermSet.FinsuppSet 𝔸 Y) := + ⟨unflatten' 𝔸 X Y S, by + obtain ⟨A, ⟨hS₁, hS₂⟩⟩ := S.prop + use A; constructor + · apply Function.Equivariant.preserve_support + rw [← Function.Equivariant.preserve_support_inj 𝔸 Subtype.val_injective] at hS₁ + exact hS₁ + · exact hS₂⟩ + +instance : Function.Equivariant 𝔸 (unflatten 𝔸 X Y) := by + constructor; intro p π + apply Subtype.ext + simp only [unflatten, Finsupp.smul_val] + apply Function.equivariant + +def flattenEquiv : + EquivariantEquiv 𝔸 + (PermSet.FinsuppFunction 𝔸 X (PermSet.FinsuppSet 𝔸 Y)) + (PermSet.FinsuppSet 𝔸 (X × Y)) where + toFun := flatten 𝔸 X Y + invFun := unflatten 𝔸 X Y + toFun_equivariant := inferInstance + +end Finsupp + +end FSFunctions + +end PermSet diff --git a/Nominal/Permutations.lean b/Nominal/Permutations.lean index f1115d3..6119df3 100644 --- a/Nominal/Permutations.lean +++ b/Nominal/Permutations.lean @@ -259,4 +259,16 @@ lemma PermSet.atom_set_swap_left {a b : 𝔸} {S : Set 𝔸} : a ∈ S ↔ b ∈ lemma PermSet.atom_set_swap_right {a b : 𝔸} {S : Set 𝔸} : b ∈ S ↔ a ∈ ⸨a, b⸩ • S := by rw [FPerm.swap_comm, atom_set_swap_left] +instance {X Y : Type} [SMul (FPerm 𝔸) X] [SMul (FPerm 𝔸) Y] : SMul (FPerm 𝔸) (X → Y) where + smul π f := fun x ↦ π • f (π⁻¹ • x) + +@[simp] lemma PermSet.smul_function {X Y : Type} [PermSet 𝔸 X] [PermSet 𝔸 Y] (π : FPerm 𝔸) + (f : X → Y) (x : X) : (π • f) x = π • f (π⁻¹ • x) := + rfl + +/-- Functions between (FPerm 𝔸)-sets form (FPerm 𝔸)-sets with (π • f) x = π • f (π⁻¹ • x). -/ +instance {X Y : Type} [PermSet 𝔸 X] [PermSet 𝔸 Y] : PermSet 𝔸 (X → Y) where + one_smul f := by ext x; simp + mul_smul π τ f := by ext x; simp [mul_smul] + end PermSet diff --git a/Nominal/Support.lean b/Nominal/Support.lean index fde20c7..bb2ec92 100644 --- a/Nominal/Support.lean +++ b/Nominal/Support.lean @@ -33,6 +33,11 @@ def fix (A : Set X) : Set (FPerm 𝔸) := def HasSupport (x : X) (S : Set 𝔸) : Prop := fix 𝔸 S ⊆ fix' 𝔸 x +lemma perm_fixes_iff_inv_fixes {X : Type} [PermSet 𝔸 X] (π : FPerm 𝔸) (x : X) : π • x = x ↔ π⁻¹ • x = x := by + constructor + · intro h; nth_rw 1 [← h]; simp + · intro h; nth_rw 1 [← h]; simp + /-- fix is antitone: If S ⊆ T, then fix S ⊇ fix T. -/ lemma fix_antitone {X : Type} [PermSet 𝔸 X] {S T : Set X} : S ⊆ T → PermSet.fix 𝔸 T ⊆ PermSet.fix 𝔸 S := by intro hsub π hπ x hx @@ -48,6 +53,11 @@ lemma fix_antitone_mem {X : Type} [PermSet 𝔸 X] {S T : Set X} {π : FPerm ð�” lemma fix_union {X : Type} [PermSet 𝔸 X] {S T : Set X} : PermSet.fix 𝔸 (S ∪ T) ⊆ PermSet.fix 𝔸 S ∩ PermSet.fix 𝔸 T := by apply Set.subset_inter <;> all_goals simp [fix_antitone] +lemma fix_inv {X : Type} [PermSet 𝔸 X] {S : Set X} {π : FPerm 𝔸} : π ∈ PermSet.fix 𝔸 S ↔ π⁻¹ ∈ PermSet.fix 𝔸 S := by + constructor + · intro h x hx; rw [← perm_fixes_iff_inv_fixes]; exact h x hx + · intro h x hx; rw [perm_fixes_iff_inv_fixes]; exact h x hx + /-- Alternative definition with fix 𝔸 S unfolded. -/ lemma support_iff {x : X} {S : Set 𝔸} : HasSupport 𝔸 x S ↔ ∀ (π : FPerm 𝔸), (∀ x ∈ S, π x = x) → π ∈ fix' 𝔸 x := by simp [HasSupport, fix, fix'] |
