Langlib

Langlib.Automata.Turing.DSL.SearchProcedure

Search Procedures — The Core DSL #

This file defines SearchProc, the central abstraction of the DSL. A SearchProc captures the pattern:

"Enumerate candidates from a countable domain; test each one; halt when a witness is found."

This is the universal pattern for semi-decision procedures: to check w ∈ L, we enumerate a domain of "proofs/witnesses" and test each one. For grammars, the witnesses are derivation sequences; for other problems they might be computation traces, certificates, etc.

Architecture #

  ┌─────────────┐     ┌──────────────┐     ┌──────────┐
  │  Enum α     │────▶│  test : α →  │────▶│  halt if │
  │  (generator)│     │  List T →    │     │  true    │
  │             │     │  Bool        │     │          │
  └─────────────┘     └──────────────┘     └──────────┘

The SearchProc bundles:

  1. An Enum α (the generator / candidate enumerator)
  2. A test : α → List T → Bool (the decidable test)

It recognizes the language { w | ∃ a ∈ enum.range, test a w = true }.

Composability #

Search procedures compose via the Enum combinators:

The test function can be built from decidable predicates using standard Boolean combinators.

Compilation to TM0 #

The search-to-machine compilation lives in SearchProcToTM0.lean. if the enumeration and test are "TM-computable" (formalized via a computability predicate), then the search procedure compiles to a TM0 machine satisfying is_TM.

Main definitions #

structure SearchProc (T : Type u_1) :
Type (max u_1 (u_2 + 1))

A search procedure over alphabet T with witness type α.

A search procedure recognizes a language by systematically enumerating witnesses from a countable domain and testing each one against the input word. It accepts w if and only if some witness passes the test.

This is the core abstraction of the DSL. Every semi-decision procedure for a language can be expressed as a SearchProc (by Rice's theorem, the converse also holds for r.e. languages).

  • WitTy : Type u_2

    The type of witnesses / certificates

  • enum : Enum self.WitTy

    Enumeration of all candidate witnesses

  • test : self.WitTyList TBool

    The test: given a witness and an input word, does the witness certify membership?

Instances For
    def SearchProc.accepts {T : Type u_1} (sp : SearchProc T) (w : List T) :

    A search procedure accepts word w if some enumerated witness passes the test.

    Equations
    Instances For
      def SearchProc.language {T : Type u_1} (sp : SearchProc T) :

      The language recognized by a search procedure: the set of all accepted words.

      Equations
      Instances For
        theorem SearchProc.accepts_iff {T : Type u_1} (sp : SearchProc T) (w : List T) :
        sp.accepts w ∃ (n : ) (a : sp.WitTy), sp.enum n = some a sp.test a w = true

        A search procedure accepts w iff there exists n : ℕ such that the n-th enumerated witness passes the test.

        def SearchProc.step {T : Type u_1} (sp : SearchProc T) (w : List T) (n : ) :

        Equivalent "step-based" view: the procedure accepts w iff sp.step w n = true for some n, where step is the composed enumerate-and-test function.

        Equations
        Instances For
          theorem SearchProc.accepts_iff_step {T : Type u_1} (sp : SearchProc T) (w : List T) :
          sp.accepts w ∃ (n : ), sp.step w n = true

          Constructors #

          def SearchProc.ofEncodable {T : Type u_1} {α : Type u_2} [Encodable α] (test : αList TBool) :

          Build a search procedure from an Encodable witness type and a test. Automatically uses the Encodable instance to enumerate all witnesses.

          Equations
          Instances For
            theorem SearchProc.ofEncodable_language {T : Type u_1} {α : Type u_2} [Encodable α] (test : αList TBool) :
            (ofEncodable test).language = {w : List T | ∃ (a : α), test a w = true}
            def SearchProc.searchNat {T : Type u_1} (test : List TBool) :

            Build a search procedure that searches over all natural numbers.

            Equations
            Instances For
              theorem SearchProc.searchNat_language {T : Type u_1} (test : List TBool) :
              (searchNat test).language = {w : List T | ∃ (n : ), test n w = true}

              Composition #

              def SearchProc.refine {T : Type u_1} (sp : SearchProc T) (p : sp.WitTyList TBool) :

              Refine a search procedure with a stronger test.

              Equations
              Instances For
                theorem SearchProc.refine_language {T : Type u_1} (sp : SearchProc T) (p : sp.WitTyList TBool) (w : List T) :
                w (sp.refine p).languagew sp.language
                def SearchProc.mapWitness {T : Type u_1} {β : Type u_2} (sp : SearchProc T) (f : βsp.WitTy) (enum_β : Enum β) :

                Transform the witness type of a search procedure.

                Equations
                • sp.mapWitness f enum_β = { WitTy := β, enum := enum_β, test := fun (b : β) (w : List T) => sp.test (f b) w }
                Instances For
                  def SearchProc.existsPair {T : Type u_1} {α : Type u_2} {β : Type u_3} (enumA : Enum α) (enumB : Enum β) (test : αβList TBool) :

                  Existential search: search for a pair (a, b) where a comes from one enumeration and b from another.

                  Equations
                  Instances For
                    theorem SearchProc.existsPair_language {T : Type u_1} {α : Type u_2} {β : Type u_3} (enumA : Enum α) (enumB : Enum β) (test : αβList TBool) :
                    (existsPair enumA enumB test).language = {w : List T | aenumA.range, benumB.range, test a b w = true}