module public import Langlib.Classes.RecursivelyEnumerable.Definition public import Langlib.Automata.Turing.Equivalence.GrammarToTM.MembershipTest public import Langlib.Utilities.ClosurePredicates public import Mathlib.CategoryTheory.Category.Basic public import Mathlib.Computability.Partrec import Langlib.Automata.Turing.DSL.CodeToTMDirect import Langlib.Automata.Turing.DSL.SearchProcToTM0 import Langlib.Automata.Turing.Equivalence.GrammarToTM.MembershipComputability import Langlib.Automata.Turing.Equivalence.TMToGrammar import Langlib.Grammars.Unrestricted.FiniteNonterminals import Langlib.Utilities.PrimrecHelpers import Mathlib.Algebra.Order.Floor.Extended import Mathlib.Algebra.Order.Floor.Semifield import Mathlib.Algebra.Order.Interval.Basic import Mathlib.Analysis.Complex.UpperHalfPlane.Basic import Mathlib.Analysis.SpecialFunctions.Bernstein import Mathlib.Analysis.SpecialFunctions.Gamma.Basic import Mathlib.Analysis.SpecialFunctions.Trigonometric.DerivHyp import Mathlib.Combinatorics.Enumerative.DyckWord import Mathlib.Combinatorics.SimpleGraph.Triangle.Removal import Mathlib.Data.NNRat.Floor import Mathlib.Data.Nat.Factorial.DoubleFactorial import Mathlib.Geometry.Euclidean.Altitude import Mathlib.NumberTheory.Height.Basic import Mathlib.NumberTheory.LucasLehmer import Mathlib.NumberTheory.SelbergSieve import Mathlib.Tactic.NormNum.BigOperators import Mathlib.Tactic.NormNum.Irrational import Mathlib.Tactic.NormNum.IsCoprime import Mathlib.Tactic.NormNum.IsSquare import Mathlib.Tactic.NormNum.LegendreSymbol import Mathlib.Tactic.NormNum.ModEq import Mathlib.Tactic.NormNum.NatFactorial import Mathlib.Tactic.NormNum.NatFib import Mathlib.Tactic.NormNum.NatLog import Mathlib.Tactic.NormNum.NatSqrt import Mathlib.Tactic.NormNum.Ordinal import Mathlib.Tactic.NormNum.Parity import Mathlib.Tactic.NormNum.Prime import Mathlib.Tactic.NormNum.RealSqrt import Mathlib.Topology.Sheaves.Init @[expose] public section /-! # RE Closure Under Inverse Homomorphism This file proves that recursively enumerable languages over finite alphabets are closed under inverse string homomorphism. The key result is `RE_of_inverseHomomorphism_RE`: for a fixed finite-alphabet homomorphism `h : α → List β`, the preprocessing map `w ↦ w.flatMap h` is primitive recursive, so a grammar-membership search for `L` can be reused as a search for the preimage `{w | w.flatMap h ∈ L}`. ## Main declarations - `primrec_flatMap_finite` - `reInverseHomomorphismTest` - `reInverseHomomorphismTest_computable₂` - `RE_of_inverseHomomorphism_RE` - `RE_closedUnderInverseHomomorphism` -/ open Turing /-- Search test for the inverse homomorphic image of a grammar language. -/ @[expose] public def reInverseHomomorphismTest {α β : Type} [DecidableEq β] (g : grammar β) [DecidableEq g.nt] (h : α → List β) (seq : List (ℕ × ℕ)) (w : List α) : Bool := grammarTest g seq (w.flatMap h) /-- The inverse-homomorphism grammar search test is computable. -/ public theorem reInverseHomomorphismTest_computable₂ {α β : Type} [DecidableEq β] [Primcodable α] [Primcodable β] [Finite α] (g : grammar β) [DecidableEq g.nt] [Primcodable g.nt] (h : α → List β) : Computable₂ (reInverseHomomorphismTest g h) := by apply Computable₂.mk unfold reInverseHomomorphismTest exact (grammarTest_computable₂ g).comp Computable.fst ((primrec_flatMap_finite h).to_comp.comp Computable.snd) /-- RE languages over finite alphabets are closed under inverse string homomorphism. -/ public theorem RE_of_inverseHomomorphism_RE {α β : Type} [Fintype α] [Fintype β] (L : Language β) (h : α → List β) : is_RE L → is_RE { w : List α | w.flatMap h ∈ L } := by intro hL haveI : DecidableEq α := Classical.decEq _ haveI : DecidableEq β := Classical.decEq _ obtain ⟨g, hg⟩ := hL obtain ⟨g', _hfin, hlang⟩ := grammar_equivalent_finiteNT g haveI : Fintype g'.nt := Fintype.ofFinite _ haveI : DecidableEq g'.nt := Classical.decEq _ haveI : Primcodable α := Primcodable.ofEquiv (Fin (Fintype.card α)) (Fintype.truncEquivFin α).out haveI : Primcodable β := Primcodable.ofEquiv (Fin (Fintype.card β)) (Fintype.truncEquivFin β).out haveI : Primcodable g'.nt := Primcodable.ofEquiv (Fin (Fintype.card g'.nt)) (Fintype.truncEquivFin g'.nt).out let test := reInverseHomomorphismTest g' h have hcomp : Computable₂ test := reInverseHomomorphismTest_computable₂ g' h obtain ⟨c, hc⟩ := search_is_partrec test hcomp have htm : is_TM ({ w : List α | w.flatMap h ∈ L } : Language α) := code_implies_isTM_direct ({ w : List α | w.flatMap h ∈ L } : Language α) c (fun w => by constructor · intro hw rw [← hc] have hw' : w.flatMap h ∈ grammar_language g' := by rw [← hlang, hg] exact hw obtain ⟨seq, hseq⟩ := grammarTest_complete g' (w.flatMap h) hw' exact ⟨seq, by simpa [test, reInverseHomomorphismTest] using hseq⟩ · intro hdom rw [← hc] at hdom obtain ⟨seq, hseq⟩ := hdom have hw' : w.flatMap h ∈ grammar_language g' := grammarTest_sound g' seq (w.flatMap h) (by simpa [test, reInverseHomomorphismTest] using hseq) rw [← hg, hlang] exact hw') exact tm_recognizable_implies_re ({ w : List α | w.flatMap h ∈ L } : Language α) htm /-- The class of RE languages is closed under inverse string homomorphism. -/ public theorem RE_closedUnderInverseHomomorphism : ClosedUnderInverseHomomorphism is_RE := by intro α β _ _ L h hL exact RE_of_inverseHomomorphism_RE L h hL