module public import Langlib.Classes.ContextSensitive.Decidability.Membership public import Langlib.Classes.ContextSensitive.Inclusion.Recursive @[expose] public section /-! # Strict Inclusion: CS ⊊ Recursive Context-sensitive languages form a *strict* subclass of the recursive languages. The proof is based on **diagonalization**. The uniform computable membership oracle for context-sensitive grammars (`memCode` / `contextSensitive_computableMembership`, in `Classes/ContextSensitive/Decidability/Membership.lean`) supplies a surjective enumeration `e : List T → Language T` of all context-sensitive languages and a total computable `mem : List T → List T → Bool` with `mem u v = true ↔ v ∈ e u`. Define `D = {v | v ∉ e v}`. Then `D` is recursive, since its characteristic predicate `v ↦ mem v v` is computable. And `D` is not context-sensitive: if `e u = D` for some `u`, instantiating the definition of `D` at `v = u` and substituting `e u = D` gives `u ∈ D ↔ u ∉ e u ↔ u ∉ D`, a contradiction; hence `D` is not in the range of `e`. Therefore `D` is recursive but not context-sensitive, so `CS ⊊ Recursive`. The argument requires `mem` to be total and computable, which holds for CS but not for Recursive (the recursive languages are not recursively enumerable), so it separates CS from Recursive but does not extend to separating Recursive from RE. -/ open Language variable {T : Type} /-- **Abstract diagonalization core (proven).** From a correct, computable membership oracle for a word-indexed enumeration covering all context-sensitive languages, the diagonal language is recursive but not context-sensitive, giving `CS ⊊ Recursive`. -/ public theorem diagonal_strict [DecidableEq T] [Fintype T] [Primcodable T] (e : List T → Language T) (mem : List T → List T → Bool) (hmem : ∀ u v, mem u v = true ↔ v ∈ e u) (hmem_comp : Computable (fun p : List T × List T => mem p.1 p.2)) (hsurj : ∀ L : Language T, is_CS L → ∃ u, e u = L) : (CS : Set (Language T)) ⊂ (Recursive : Set (Language T)) := by classical -- Diagonal decider: accept `v` iff `v ∉ e v`. set f : List T → Bool := fun v => cond (mem v v) false true with hf_def set D : Language T := {v | f v = true} with hD_def -- `f` is computable: feed `mem` the diagonal pair `(v, v)`. have h1 : Computable (fun v : List T => mem v v) := hmem_comp.comp (Computable.pair Computable.id Computable.id) have hf_comp : Computable f := Computable.cond h1 (Computable.const false) (Computable.const true) -- `D` is recursive. have hDrec : is_Recursive D := is_Recursive_of_computable_decide D f hf_comp (fun _ => Iff.rfl) -- `D` is not context-sensitive: a fixed-point contradiction. have hDnotCS : ¬ is_CS D := by rintro hCS obtain ⟨u, hu⟩ := hsurj D hCS have hfu : f u = cond (mem u u) false true := by rw [hf_def] have key : u ∈ D ↔ u ∉ e u := by rw [hD_def, Set.mem_setOf_eq, hfu, ← hmem u u] cases mem u u <;> simp rw [hu] at key exact iff_not_self key -- Assemble strict inclusion: ⊆ holds, and equality would put the non-CS recursive `D` in CS. refine ssubset_iff_subset_ne.mpr ⟨CS_subset_Recursive_class, ?_⟩ intro heq exact hDnotCS ((Set.ext_iff.mp heq D).mpr hDrec) /-- Decode a word into a coded grammar, indexing by the word's length (`List.length` is onto `ℕ` for a nonempty alphabet, so this is surjective onto coded grammars). A default empty grammar is used if the code is malformed. -/ noncomputable def decodeCode [Primcodable T] (u : List T) : Code T := (Encodable.decode (α := Code T) u.length).getD ([], 0) /-- The membership oracle: decode the index word into a coded grammar and run the bounded search. -/ noncomputable def memOracle [DecidableEq T] [Primcodable T] (u v : List T) : Bool := memCode (decodeCode u) v /-- The enumerated language at index word `u`. Correctness against `memOracle` is definitional. -/ noncomputable def enumLang [DecidableEq T] [Primcodable T] (u : List T) : Language T := {v | memOracle u v = true} /-- **Obligation 1 (uniform computability), now discharged.** The bounded derivation-sequence search oracle is computable jointly in the grammar-code word and the input word: `decodeCode` is `Encodable.decode ∘ encode` and `memCode` is the bounded search, primrec via the uniform `primrec_applyRuleSeq_uniform`. -/ public theorem memOracle_computable [DecidableEq T] [Fintype T] [Primcodable T] : Computable (fun p : List T × List T => memOracle p.1 p.2) := by have hdec : Primrec (fun u : List T => decodeCode u) := Primrec.option_getD.comp (Primrec.decode.comp Primrec.list_length) (Primrec.const ([], 0)) exact (memCode_primrec.comp (Primrec.pair (hdec.comp Primrec.fst) Primrec.snd)).to_comp /-- **Surjectivity of decoding.** Every coded grammar is `decodeCode u` for some index word `u` — because `List T` is denumerable for a nonempty alphabet, so `Encodable.encode` is onto. -/ private theorem decodeCode_surj [Primcodable T] [Nonempty T] (c : Code T) : ∃ u : List T, decodeCode u = c := by refine ⟨List.replicate (Encodable.encode c) (Classical.arbitrary T), ?_⟩ rw [decodeCode, List.length_replicate, Encodable.encodek, Option.getD_some] /-- **Obligation 2 (coverage).** Every context-sensitive language is `enumLang u` for some index word `u`. Assembled from `memCode_sound`/`memCode_complete` (membership correctness), `code_of_CS` (encoding), and `decodeCode_surj` (surjectivity). -/ public theorem enum_covers_CS [DecidableEq T] [Fintype T] [Primcodable T] [Nonempty T] : ∀ L : Language T, is_CS L → ∃ u, enumLang u = L := by intro L hL obtain ⟨c, hcs, hlang⟩ := code_of_CS hL subst hlang obtain ⟨u, hu⟩ := decodeCode_surj c refine ⟨u, ?_⟩ have h1 : enumLang u = {v | memCode c v = true} := by rw [enumLang]; ext w; rw [Set.mem_setOf_eq, Set.mem_setOf_eq, memOracle, hu] rw [h1] ext v exact ⟨fun hm => memCode_sound c v hm, fun hv => memCode_complete c v hcs hv⟩ /-- **Effective enumeration of context-sensitive languages**, assembled from the two obligations `memOracle_computable` and `enum_covers_CS` (the correctness clause is definitional, since `enumLang u` is *defined* as `{v | memOracle u v = true}`). -/ public theorem exists_cs_enumeration [DecidableEq T] [Fintype T] [Primcodable T] [Nonempty T] : ∃ (e : List T → Language T) (mem : List T → List T → Bool), (∀ u v, mem u v = true ↔ v ∈ e u) ∧ Computable (fun p : List T × List T => mem p.1 p.2) ∧ (∀ L : Language T, is_CS L → ∃ u, e u = L) := ⟨enumLang, memOracle, fun _ _ => Iff.rfl, memOracle_computable, enum_covers_CS⟩ /-- **Context-sensitive languages are a strict subclass of the recursive languages**, `CS ⊊ Recursive`. Assembled from the proven diagonalization core `diagonal_strict` and the enumeration obligation `exists_cs_enumeration`. (Nonemptiness of the alphabet is necessary: over an empty alphabet `CS = Recursive`.) -/ public theorem CS_strict_subclass_Recursive [DecidableEq T] [Fintype T] [Primcodable T] [Nonempty T] : (CS : Set (Language T)) ⊂ (Recursive : Set (Language T)) := by obtain ⟨e, mem, hmem, hmem_comp, hsurj⟩ := exists_cs_enumeration (T := T) exact diagonal_strict e mem hmem hmem_comp hsurj