/- Copyright (c) 2026 Langlib Contributors. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -/ import Mathlib import Langlib.Utilities.Homomorphism import Langlib.Utilities.LanguageOperations /-! # Abstract Closure Predicates for Language Classes This file defines predicates capturing common closure properties of language classes. A language class `P : Language α → Prop` is *closed* under an operation if applying the operation to languages in `P` yields another language in `P`. For same-alphabet operations (union, intersection, complement, concatenation, Kleene star, reversal, intersection/quotient with regular), closedness is expressed as a property of `P : Language α → Prop`. For cross-alphabet operations (string homomorphism, ε-free homomorphism), closedness is expressed as a property of an alphabet-indexed predicate `isP : ∀ {α : Type*}, Language α → Prop`. ## Main definitions - `ClosedUnderUnion` - `ClosedUnderIntersection` - `ClosedUnderComplement` - `ClosedUnderConcatenation` - `ClosedUnderKleeneStar` - `ClosedUnderReverse` - `ClosedUnderIntersectionWithRegular` - `ClosedUnderRightQuotient` - `ClosedUnderRightQuotientWithRegular` - `ClosedUnderHomomorphism` - `ClosedUnderEpsFreeHomomorphism` - `ClosedUnderInverseHomomorphism` - `ClosedUnderSubstitution` -/ variable {α : Type*} /-- A language class is closed under union. -/ def ClosedUnderUnion (P : Language α → Prop) : Prop := ∀ L₁ L₂ : Language α, P L₁ → P L₂ → P (L₁ + L₂) /-- A language class is closed under intersection. -/ def ClosedUnderIntersection (P : Language α → Prop) : Prop := ∀ L₁ L₂ : Language α, P L₁ → P L₂ → P (L₁ ⊓ L₂) /-- A language class is closed under complement. -/ def ClosedUnderComplement (P : Language α → Prop) : Prop := ∀ L : Language α, P L → P Lᶜ /-- A language class is closed under concatenation. -/ def ClosedUnderConcatenation (P : Language α → Prop) : Prop := ∀ L₁ L₂ : Language α, P L₁ → P L₂ → P (L₁ * L₂) /-- A language class is closed under Kleene star. -/ def ClosedUnderKleeneStar (P : Language α → Prop) : Prop := ∀ L : Language α, P L → P (KStar.kstar L) /-- A language class is closed under language reversal. -/ def ClosedUnderReverse (P : Language α → Prop) : Prop := ∀ L : Language α, P L → P L.reverse /-- A language class is closed under intersection with regular languages. -/ def ClosedUnderIntersectionWithRegular (P : Language α → Prop) : Prop := ∀ L : Language α, P L → ∀ R : Language α, R.IsRegular → P (L ⊓ R) /-- A language class is closed under right quotient (with any language from the same class). -/ def ClosedUnderRightQuotient (P : Language α → Prop) : Prop := ∀ L₁ L₂ : Language α, P L₁ → P L₂ → P (Language.rightQuotient L₁ L₂) /-- A language class is closed under right quotient with regular languages. -/ def ClosedUnderRightQuotientWithRegular (P : Language α → Prop) : Prop := ∀ L : Language α, P L → ∀ R : Language α, R.IsRegular → P (Language.rightQuotient L R) /-- An alphabet-indexed language class is closed under string homomorphism. Here `isP` is a predicate on languages that is uniform across alphabets. Note: `Language.homomorphicImage` works in universe `Type`, so `isP` ranges over `Type`. -/ def ClosedUnderHomomorphism (isP : ∀ {α : Type}, Language α → Prop) : Prop := ∀ {α β : Type} [Fintype α] [Fintype β] (L : Language α) (h : α → List β), isP L → isP (L.homomorphicImage h) /-- An alphabet-indexed language class is closed under ε-free string homomorphism. -/ def ClosedUnderEpsFreeHomomorphism (isP : ∀ {α : Type}, Language α → Prop) : Prop := ∀ {α β : Type} [Fintype α] [Fintype β] (L : Language α) (h : α → List β), IsEpsFreeHomomorphism h → isP L → isP (L.homomorphicImage h) /-- An alphabet-indexed language class is closed under inverse string homomorphism. The inverse homomorphic image of `L : Language β` under `h : α → List β` is `{ w : List α | w.flatMap h ∈ L }`. -/ def ClosedUnderInverseHomomorphism (isP : ∀ {α : Type}, Language α → Prop) : Prop := ∀ {α β : Type} [Fintype α] (L : Language β) (h : α → List β), isP L → isP { w : List α | w.flatMap h ∈ L } /-- An alphabet-indexed language class is closed under substitution. The source alphabet is assumed finite so the predicate matches the regular-language substitution theorem formalized in this library. -/ def ClosedUnderSubstitution (isP : ∀ {α : Type}, Language α → Prop) : Prop := ∀ {α β : Type} [Fintype α] (L : Language α) (f : α → Language β), isP L → (∀ a, isP (f a)) → isP (L.subst f)