diff options
| author | Hannes Schulze <haschu0103@outlook.de> | 2025-10-26 13:26:57 +0100 |
|---|---|---|
| committer | Hannes Schulze <haschu0103@outlook.de> | 2025-10-26 13:31:36 +0100 |
| commit | 091fd832586627fbf31375fb5487d5e6fa6f7053 (patch) | |
| tree | aac1679d86d15e2b9c89c2bd5efb7fd8b97980a0 /Nominal/Instances/Abstraction.lean | |
| parent | 10edba2c0365a6858a74da22042c98f9d5fa1acc (diff) | |
finish name abstraction proofs
Diffstat (limited to 'Nominal/Instances/Abstraction.lean')
| -rw-r--r-- | Nominal/Instances/Abstraction.lean | 79 |
1 files changed, 61 insertions, 18 deletions
diff --git a/Nominal/Instances/Abstraction.lean b/Nominal/Instances/Abstraction.lean index 660c2ab..bb654ed 100644 --- a/Nominal/Instances/Abstraction.lean +++ b/Nominal/Instances/Abstraction.lean @@ -133,15 +133,19 @@ lemma alpha_eq_iff_all {x y : NameAbstraction' 𝔸 X} : AlphaEq x y ↔ ∀ c, For ⟪a⟫ x = ⟪b⟫ y, we either have (a, x) = (b, y) or x is just (a b) y, requiring that a is not in the support of y. -/ lemma alpha_eq_iff_cases {x y : NameAbstraction' 𝔸 X} : AlphaEq x y ↔ (x.atom = y.atom ∧ x.body = y.body) ∨ (x.atom ≠ y.atom ∧ x.atom # y.body ∧ x.body = ⸨x.atom, y.atom⸩ • y.body) := by - by_cases h_eq : x.atom = y.atom - · constructor - · sorry - · sorry - · constructor - · rw [alpha_eq_iff_exists] - intro h; right - obtain ⟨c, ⟨hcx, ⟨hcy, hc⟩⟩⟩ := h - constructor + constructor + · rw [alpha_eq_iff_exists] + intro h + obtain ⟨c, ⟨hcx, ⟨hcy, hc⟩⟩⟩ := h + by_cases h_eq : x.atom = y.atom + · left; constructor + · exact h_eq + · calc + x.body = ⸨c, x.atom⸩ • ⸨c, x.atom⸩ • x.body := by rw [← mul_smul, FPerm.swap_mul_self, one_smul] + _ = ⸨c, x.atom⸩ • ⸨c, y.atom⸩ • y.body := by rw [hc] + _ = ⸨c, y.atom⸩ • ⸨c, y.atom⸩ • y.body := by rw [h_eq] + _ = y.body := by rw [← mul_smul, FPerm.swap_mul_self, one_smul] + · right; constructor · exact h_eq · simp at hcx simp at hcy @@ -160,24 +164,63 @@ lemma alpha_eq_iff_cases {x y : NameAbstraction' 𝔸 X} : AlphaEq x y ↔ (x.at _ = (⸨c, x.atom⸩ * ⸨c, y.atom⸩) • y.body := by rw [mul_smul, hc] _ = ⸨x.atom, y.atom⸩ • ⸨c, x.atom⸩ • y.body := by rw [← mul_smul, h_swap] _ = ⸨x.atom, y.atom⸩ • y.body := by rw [NominalSet.fresh_swap_fix 𝔸 hcy.right h_atom] - · rw [alpha_eq_iff_all] - intro h c ⟨hcx, hcy⟩ + · rw [alpha_eq_iff_all] + intro h c ⟨hcx, hcy⟩ + cases h with + | inl h => + rw [h.left, h.right] + | inr h => simp at hcx simp at hcy - simp only [h_eq, false_and, ne_eq, not_false_eq_true, true_and, false_or] at h have h_swap : ⸨c, x.atom⸩ * ⸨x.atom, y.atom⸩ = ⸨c, y.atom⸩ * ⸨c, x.atom⸩ := by ext a by_cases a = c <;> by_cases a = x.atom <;> by_cases a = y.atom - all_goals simp_all [FPerm.swap_apply_of_ne_of_ne, hcy.left, hcx.left, Ne.symm hcy.left, Ne.symm hcx.left, Ne.symm h_eq] - rw [h.right, ← mul_smul, h_swap, mul_smul, NominalSet.fresh_swap_fix 𝔸 hcy.right h.left] + all_goals simp_all [FPerm.swap_apply_of_ne_of_ne, hcy.left, hcx.left, Ne.symm hcy.left, Ne.symm hcx.left, Ne.symm h.left] + rw [h.right.right, ← mul_smul, h_swap, mul_smul, NominalSet.fresh_swap_fix 𝔸 hcy.right h.right.left] -private lemma alpha_eq_refl (x : NameAbstraction' 𝔸 X) : AlphaEq x x := by sorry +private lemma alpha_eq_refl (x : NameAbstraction' 𝔸 X) : AlphaEq x x := by + rw [alpha_eq_iff_cases]; left + trivial -private lemma alpha_eq_symm {x y : NameAbstraction' 𝔸 X} : AlphaEq x y → AlphaEq y x := by sorry +private lemma alpha_eq_symm {x y : NameAbstraction' 𝔸 X} : AlphaEq x y → AlphaEq y x := by + rw [alpha_eq_iff_cases, alpha_eq_iff_cases] + intro h + cases h with + | inl h => + left; exact ⟨h.left.symm, h.right.symm⟩ + | inr h => + right; constructor + · exact h.left.symm + · constructor + · have h : ⸨x.atom, y.atom⸩ • x.atom # x.body := by + rw [h.right.right] + exact NominalSet.fresh_equivariant 𝔸 _ _ _ h.right.left + simp at h; exact h + · rw [h.right.right, ← mul_smul, FPerm.swap_comm, FPerm.swap_mul_self, one_smul] -private lemma alpha_eq_trans {x y z : NameAbstraction' 𝔸 X} : AlphaEq x y → AlphaEq y z → AlphaEq x z := by sorry +private lemma alpha_eq_trans {x y z : NameAbstraction' 𝔸 X} : AlphaEq x y → AlphaEq y z → AlphaEq x z := by + intro hxy hyz + have h : AlphaEq x y ∧ AlphaEq y z := ⟨hxy, hyz⟩ + simp only [AlphaEq, AlphaEq, NominalSet.for_fresh_and] at h + apply NominalSet.for_fresh_imp + · exact h + · intro c ⟨hxy, hyz⟩ + rw [hxy, hyz] -lemma alpha_eq_equivariant : EquivariantRelation 𝔸 (AlphaEq : NameAbstraction' 𝔸 X → NameAbstraction' 𝔸 X → Prop) := by sorry +/-- Alpha-equivalence is an equivariant relation. -/ +lemma alpha_eq_equivariant : EquivariantRelation 𝔸 (AlphaEq : NameAbstraction' 𝔸 X → NameAbstraction' 𝔸 X → Prop) := by + intro x y π h + rw [alpha_eq_iff_exists] at * + obtain ⟨c, ⟨hcx, ⟨hcy, hc⟩⟩⟩ := h + use π • c + constructor + · apply NominalSet.fresh_equivariant; exact hcx + · constructor + · apply NominalSet.fresh_equivariant; exact hcy + · -- XXX: This is largely similar to alpha_eq_pred... + have h' : π • ⸨c, x.atom⸩ • x.body = π • ⸨c, y.atom⸩ • y.body := by congr + simp only [smul_smul, FPerm.mul_swap_eq_swap_mul] at h' + simpa [smul_smul] end NameAbstraction |
