From 8fdf459876b999dbe184196f9abd330a3c24d560 Mon Sep 17 00:00:00 2001 From: Hannes Schulze Date: Thu, 4 Dec 2025 17:14:46 +0100 Subject: implement derivable equality --- Algebra/Derivations.lean | 136 +++++++++++++++++++++++++++++++++++++++++++ Algebra/Terms.lean | 23 ++++++++ Nominal/Instances/Basic.lean | 15 +++++ Nominal/Permutations.lean | 17 ++++++ 4 files changed, 191 insertions(+) diff --git a/Algebra/Derivations.lean b/Algebra/Derivations.lean index e69de29..6f81e9a 100644 --- a/Algebra/Derivations.lean +++ b/Algebra/Derivations.lean @@ -0,0 +1,136 @@ +import Mathlib +import Algebra.Terms + +namespace Algebra + +section Theories + +variable (𝔸 : Type) [Infinite 𝔸] [Countable 𝔸] [DecidableEq 𝔸] +variable (sig : Signature) + +structure Equation where + vars : Type + [vars_nominal : NominalSet 𝔸 vars] + [vars_orbitFinite : OrbitFinite 𝔸 vars] + left : Term 𝔸 sig vars + right : Term 𝔸 sig vars + +namespace Equation + +instance (eq : Equation 𝔸 sig) : NominalSet 𝔸 eq.vars := + eq.vars_nominal + +instance (eq : Equation 𝔸 sig) : OrbitFinite 𝔸 eq.vars := + eq.vars_orbitFinite + +def HasDepth + {𝔸 : Type} [Infinite 𝔸] [Countable 𝔸] [DecidableEq 𝔸] {sig : Signature} + (eq : Equation 𝔸 sig) (n : β„•) : Prop := + eq.left.HasDepth n ∧ eq.right.HasDepth n + +end Equation + +def EquationAtDepth (n : β„•) := + { eq : Equation 𝔸 sig // eq.HasDepth n } + +def UniformEquation := + { eq : Equation 𝔸 sig // βˆƒ n, eq.HasDepth n } + +structure Theory where + sig : Signature + axioms : Set (UniformEquation 𝔸 sig) + +end Theories + +variable {𝔸 : Type} [Infinite 𝔸] [Countable 𝔸] [DecidableEq 𝔸] +variable {sig : Signature} + +section Helpers + +def EquationAtDepth.left {n : β„•} (eq : EquationAtDepth 𝔸 sig n) : TermAtDepth 𝔸 sig eq.val.vars n := + ⟨eq.val.left, eq.prop.left⟩ + +def EquationAtDepth.right {n : β„•} (eq : EquationAtDepth 𝔸 sig n) : TermAtDepth 𝔸 sig eq.val.vars n := + ⟨eq.val.right, eq.prop.right⟩ + +def EquationAtDepth.mk + (X : Type) [NominalSet 𝔸 X] [OrbitFinite 𝔸 X] {n : β„•} (t u : TermAtDepth 𝔸 sig X n) : + EquationAtDepth 𝔸 sig n := + ⟨⟨X, t.val, u.val⟩, ⟨t.prop, u.prop⟩⟩ + +def EquationAtDepth.toUniform {n : β„•} (eq : EquationAtDepth 𝔸 sig n) : UniformEquation 𝔸 sig := + ⟨eq.val, ⟨n, eq.prop⟩⟩ + +notation:50 X " ⊒ " lhs " ≣ " rhs => EquationAtDepth.mk X lhs rhs + +end Helpers + +section DerivableEquations + +inductive Derivable (T : Theory 𝔸) : {m : β„•} β†’ (eq : EquationAtDepth 𝔸 T.sig m) β†’ Prop + | refl {X : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X] {x : X} : + Derivable T (X ⊒ .var x ≣ .var x) + | symm {X : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X] + {m : β„•} {t u : TermAtDepth 𝔸 T.sig X m} : + Derivable T (X ⊒ u ≣ t) β†’ + Derivable T (X ⊒ t ≣ u) + | trans {X : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X] + {m : β„•} {t u v : TermAtDepth 𝔸 T.sig X m} : + Derivable T (X ⊒ t ≣ v) β†’ + Derivable T (X ⊒ v ≣ u) β†’ + Derivable T (X ⊒ t ≣ u) + | cong_pure {X : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X] + {f : T.sig.pure} {m : β„•} {ts us : T.sig.pureArgs f β†’ TermAtDepth 𝔸 T.sig X m} : + (βˆ€ x, Derivable T (X ⊒ ts x ≣ us x)) β†’ + Derivable T (X ⊒ .pure f ts ≣ .pure f us) + | cong_free {X : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X] + {a : 𝔸} {f : T.sig.free} {m : β„•} {ts us : T.sig.freeArgs f β†’ TermAtDepth 𝔸 T.sig X m} : + (βˆ€ x, Derivable T (X ⊒ ts x ≣ us x)) β†’ + Derivable T (X ⊒ .free a f ts ≣ .free a f us) + | cong_bound {X : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X] + {a : 𝔸} {f : T.sig.bound} {m : β„•} {ts us : T.sig.boundArgs f β†’ TermAtDepth 𝔸 T.sig X m} : + (βˆ€ x, Derivable T (X ⊒ ts x ≣ us x)) β†’ + Derivable T (X ⊒ .bound a f ts ≣ .bound a f us) + | ax' {X Y : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X] [NominalSet 𝔸 Y] [OrbitFinite 𝔸 Y] + {m : β„•} {r s : TermAtDepth 𝔸 T.sig Y m} + {l : β„•} {Οƒ : UniformSubstitution 𝔸 T.sig Y X l} {Ο„ : FPerm 𝔸} : + ((Y ⊒ r ≣ s).toUniform ∈ T.axioms) β†’ + (βˆ€ (y : Y) (Ο€ : FPerm 𝔸), Derivable T (X ⊒ Οƒ (Ο€ β€’ y) ≣ Ο€ β€’ (Οƒ y))) β†’ + Derivable T (X ⊒ Οƒ.apply (Ο„ β€’ r) ≣ Οƒ.apply (Ο„ β€’ s)) + | perm {X : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X] + {a b : 𝔸} {f : T.sig.bound} {m : β„•} {ts us : T.sig.boundArgs f β†’ TermAtDepth 𝔸 T.sig X m} : + a β‰  b β†’ + (βˆ€ x, a # us x) β†’ + (βˆ€ x, Derivable T (X ⊒ ts x ≣ βΈ¨a, bβΈ© β€’ us x)) β†’ + Derivable T (X ⊒ .bound a f ts ≣ .bound b f us) + +variable {X Y : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X] [NominalSet 𝔸 Y] [OrbitFinite 𝔸 Y] + +def UniformSubstitution.DerivablyEquivariant + (T : Theory 𝔸) {l : β„•} (Οƒ : UniformSubstitution 𝔸 T.sig X Y l) : Prop := + (βˆ€ (x : X) (Ο€ : FPerm 𝔸), Derivable T (Y ⊒ Οƒ (Ο€ β€’ x) ≣ Ο€ β€’ Οƒ x)) + +/-- Restated ax' rule using DerivablyEquivariant in the premiss. -/ +lemma Derivable.ax + {T : Theory 𝔸} + {m : β„•} {r s : TermAtDepth 𝔸 T.sig Y m} + {l : β„•} {Οƒ : UniformSubstitution 𝔸 T.sig Y X l} {Ο„ : FPerm 𝔸} : + ((Y ⊒ r ≣ s).toUniform ∈ T.axioms) β†’ + Οƒ.DerivablyEquivariant T β†’ + Derivable T (X ⊒ Οƒ.apply (Ο„ β€’ r) ≣ Οƒ.apply (Ο„ β€’ s)) := + .ax' + +lemma Derivable.equivariant_substitution + (T : Theory 𝔸) + {l : β„•} (Οƒ : UniformSubstitution 𝔸 T.sig Y X l) (hequi : Οƒ.DerivablyEquivariant T) + {m : β„•} (t : TermAtDepth 𝔸 T.sig Y m) {Ο€ : FPerm 𝔸} : + Derivable T (X ⊒ Οƒ.apply (Ο€ β€’ t) ≣ Ο€ β€’ (Οƒ.apply t)) := by + induction' t using TermAtDepth.induction <;> expose_names + Β· sorry + Β· sorry + Β· sorry + Β· sorry + +end DerivableEquations + +end Algebra diff --git a/Algebra/Terms.lean b/Algebra/Terms.lean index aa853a8..997dca4 100644 --- a/Algebra/Terms.lean +++ b/Algebra/Terms.lean @@ -87,6 +87,29 @@ def TermAtDepth.bound {n : β„•} (a : 𝔸) (f : sig.bound) (args : sig.boundArgs TermAtDepth 𝔸 sig X (n + sig.boundDepth f) := ⟨.bound a f (Subtype.val ∘ args), by constructor; intro arg; exact (args arg).prop⟩ +theorem TermAtDepth.induction + {motive : {n : β„•} β†’ TermAtDepth 𝔸 sig X n β†’ Prop} + (var : βˆ€ (x : X), motive (.var x)) + (pure : βˆ€ {n : β„•} (f : sig.pure) (args : sig.pureArgs f β†’ TermAtDepth 𝔸 sig X n), + (βˆ€ x, motive (args x)) β†’ motive (.pure f args)) + (free : βˆ€ {n : β„•} (a : 𝔸) (f : sig.free) (args : sig.freeArgs f β†’ TermAtDepth 𝔸 sig X n), + (βˆ€ x, motive (args x)) β†’ motive (.free a f args)) + (bound : βˆ€ {n : β„•} (a : 𝔸) (f : sig.bound) (args : sig.boundArgs f β†’ TermAtDepth 𝔸 sig X n), + (βˆ€ x, motive (args x)) β†’ motive (.bound a f args)) + : βˆ€ {n : β„•} (t : TermAtDepth 𝔸 sig X n), motive t := by + intro n ⟨t, ht⟩ + induction' t generalizing n <;> cases ht <;> expose_names + Β· exact var x + Β· let args' : sig.pureArgs f β†’ TermAtDepth 𝔸 sig X k := fun x => ⟨args x, h x⟩ + have args_ih' : βˆ€ x, motive (args' x) := fun x => args_ih x (h x) + exact pure f args' args_ih' + Β· let args' : sig.freeArgs f β†’ TermAtDepth 𝔸 sig X k := fun x => ⟨args x, h x⟩ + have args_ih' : βˆ€ x, motive (args' x) := fun x => args_ih x (h x) + exact free a f args' args_ih' + Β· let args' : sig.boundArgs f β†’ TermAtDepth 𝔸 sig X k := fun x => ⟨args x, h x⟩ + have args_ih' : βˆ€ x, motive (args' x) := fun x => args_ih x (h x) + exact bound a f args' args_ih' + end ConvenienceConstructors section Substitution diff --git a/Nominal/Instances/Basic.lean b/Nominal/Instances/Basic.lean index dcca75b..64b6425 100644 --- a/Nominal/Instances/Basic.lean +++ b/Nominal/Instances/Basic.lean @@ -70,6 +70,21 @@ def NominalSet.mkDiscrete (X : Type) : NominalSet.Discrete 𝔸 X where Β· intro Ο€ hΟ€; simp only [PermSet.fix', Set.mem_setOf_eq]; rfl Β· exact Set.finite_empty +instance {X : Type} [NominalSet.Discrete 𝔸 X] [Finite X] : OrbitFinite 𝔸 X where + fin_orbits := Finite.of_equiv X + { toFun x := Quotient.mk _ x + invFun x := x.out + left_inv x := by + suffices βˆ€ (x y : X), MulAction.orbitRel (FPerm 𝔸) X x y β†’ x = y by + apply this + rw [← Quotient.eq] + apply Quotient.out_eq + intro x y βŸ¨Ο€, hΟ€βŸ© + simp only [NominalSet.Discrete.is_discrete] at hΟ€ + exact hΟ€.symm + right_inv x := by simp + } + @[simp] lemma NominalSet.Discrete.supp {X : Type} [NominalSet.Discrete 𝔸 X] {x : X} : supp 𝔸 x = βˆ… := by rw [← Set.subset_empty_iff] apply Set.sInter_subset_of_mem diff --git a/Nominal/Permutations.lean b/Nominal/Permutations.lean index 79a5042..0a4974a 100644 --- a/Nominal/Permutations.lean +++ b/Nominal/Permutations.lean @@ -187,12 +187,29 @@ class PermSet (𝔸 : Type) [Infinite 𝔸] [Countable 𝔸] [DecidableEq 𝔸] variable (𝔸 : Type) [Infinite 𝔸] [Countable 𝔸] [DecidableEq 𝔸] +/-- An (FPerm 𝔸)-set is orbit-finite if there are only finitely many different orbits. -/ +class OrbitFinite (X : Type) [PermSet 𝔸 X] where + fin_orbits : Finite (Quotient (MulAction.orbitRel (FPerm 𝔸) X)) + /-- The set of atoms itself forms an (FPerm 𝔸)-Set. -/ instance : PermSet 𝔸 𝔸 where smul Ο€ a := Ο€ a one_smul := by intro; rfl mul_smul := by intro _ _ _; rfl +instance : OrbitFinite 𝔸 𝔸 where + fin_orbits := Finite.of_equiv Unit + { toFun _ := Quotient.mk _ (inferInstanceAs (Nonempty 𝔸)).some + invFun _ := () + right_inv := by + let chosen := (inferInstanceAs (Nonempty 𝔸)).some + apply Quotient.ind; intro a + rw [Quotient.eq] + show chosen ∈ MulAction.orbit (FPerm 𝔸) a + use βΈ¨chosen, aβΈ© + exact FPerm.swap_apply_right chosen a + } + /-- The set of finite permutations forms an (FPerm 𝔸)-Set. -/ instance : PermSet 𝔸 (FPerm 𝔸) where smul Ο€ Ο„ := Ο€ * Ο„ -- cgit v1.3.1