import Langlib.Classes.ContextSensitive.Definition import Langlib.Classes.RecursivelyEnumerable.Closure.Union import Langlib.Utilities.ClosurePredicates /-! # Context-Sensitive Closure Under Union This file proves that the class of context-sensitive languages is closed under union. The proof reuses the union grammar construction from the RE closure proof and additionally shows that the construction preserves the context-sensitive (non-contracting) property. ## Main results - `union_grammar_context_sensitive` — the union grammar is context-sensitive when both inputs are context-sensitive. - `CS_of_CS_u_CS` — the class of context-sensitive languages is closed under union. -/ variable {T : Type} /- The union grammar preserves the context-sensitive (non-contracting) property. -/ lemma union_grammar_context_sensitive {g₁ g₂ : grammar T} (h₁ : grammar_context_sensitive g₁) (h₂ : grammar_context_sensitive g₂) : grammar_context_sensitive (union_grammar g₁ g₂) := by intro r hr; unfold union_grammar at hr; simp_all +decide [ List.mem_cons ] ; rcases hr with ( rfl | rfl | ⟨ a, ha, rfl ⟩ | ⟨ a, ha, rfl ⟩ ) <;> simp_all +decide [ lift_rule_ ]; · obtain ⟨ γ, hγ₁, hγ₂ ⟩ := h₁ a ha; unfold lift_string_ at *; aesop; · obtain ⟨ γ, hγ₁, hγ₂ ⟩ := h₂ a ha; simp_all +decide [ lift_string_ ] /-- The class of context-sensitive languages is closed under union. -/ theorem CS_of_CS_u_CS (L₁ : Language T) (L₂ : Language T) : is_CS L₁ ∧ is_CS L₂ → is_CS (L₁ + L₂) := by rintro ⟨⟨g₁, hcs₁, hL₁⟩, ⟨g₂, hcs₂, hL₂⟩⟩ refine ⟨union_grammar g₁ g₂, union_grammar_context_sensitive hcs₁ hcs₂, ?_⟩ ext w constructor · intro hw rw [Language.mem_add, ← hL₁, ← hL₂] exact in_L₁_or_L₂_of_in_union hw · intro hw cases hw with | inl h₁ => exact in_union_of_in_L₁ (hL₁ ▸ h₁) | inr h₂ => exact in_union_of_in_L₂ (hL₂ ▸ h₂) /-- The class of context-sensitive languages is closed under union. -/ theorem CS_closedUnderUnion : ClosedUnderUnion (α := T) is_CS := fun L₁ L₂ h₁ h₂ => CS_of_CS_u_CS L₁ L₂ ⟨h₁, h₂⟩