Documentation

Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion

Non-primitive corecursion for sequences #

Primitive corecursive definition of the form

def foo (x : X) := hd x :: foo (tlArg x)

(where hd and tlArg are arbitrary functions) can be encoded via the corecursor Seq.corec.

It is not enough, however, to define multiplication and powser operation for multiseries.

This file implements a more general form of corecursion in the spirit of [BPT15]. This is a bare minimum that needed for the tactic, it justifies a weaker class of corecursive definitions than [BPT15] does, and only works for Seq.

A function f : Seq α → Seq α is called friendly if for all n : ℕ the n-prefix of its result f s depends only on the n-prefix of its input s.

In this file we develop a theory that justifies corecursive definitions of the form

def foo (x : X) := hd x :: f (foo (tlArg x))

where f is friendly.

Main definitions #

Implementation details #

To prove that the definition of the form

def foo (x : X) := hd x :: f (foo (tlArg x))

is correct we prove that there exists a function satisfying this equation. For that we employ a Banach fixed point theorem. We treat Seq α as a metric space here with the metric d(s, t) := 2 ^ (-n) where n is the minimal index where s and t differ.

Then f is friendly iff it is 1-Lipschitz.

Metric space structure on Stream' α considering α as a discrete metric space.

Equations
Instances For

    Metric space structure on Seq α considering α as a discrete metric space.

    Equations
    Instances For
      @[simp]
      theorem Tactic.ComputeAsymptotics.Seq.dist_eq_two_inv_pow {α : Type u_1} {s t : Stream'.Seq α} (h : s t) :
      ∃ (n : ), dist s t = 2⁻¹ ^ n

      A function on sequences is called a "friend" if any n-prefix of its output depends only on the n-prefix of the input. Such functions can be used in the tail of (non-primitive) corecursive definitions.

      Equations
      Instances For

        A family of friendly operations on sequences indexed by a type γ.

        Instances
          theorem Tactic.ComputeAsymptotics.Seq.FriendlyOperationClass.comp {α : Type u_1} {γ : Type u_3} {γ' : Type u_4} (F : γStream'.Seq αStream'.Seq α) (g : γ'γ) [h : FriendlyOperationClass F] :
          FriendlyOperationClass fun (c : γ') => F (g c)
          theorem Tactic.ComputeAsymptotics.Seq.FriendlyOperation.ite {α : Type u_1} {op₁ op₂ : Stream'.Seq αStream'.Seq α} (h₁ : FriendlyOperation op₁) (h₂ : FriendlyOperation op₂) {P : Option αProp} [DecidablePred P] :
          FriendlyOperation fun (s : Stream'.Seq α) => if P s.head then op₁ s else op₂ s
          theorem Tactic.ComputeAsymptotics.Seq.FriendlyOperation.exists_fixed_point {α : Type u_1} {β : Type u_2} {γ : Type u_3} (F : βOption (α × γ × β)) (op : γStream'.Seq αStream'.Seq α) [h : FriendlyOperationClass op] :
          ∃ (f : βStream'.Seq α), ∀ (b : β), match F b with | none => f b = Stream'.Seq.nil | some (a, c, b') => f b = Stream'.Seq.cons a (op c (f b'))

          Main theorem of this file. It shows that there exists a funcion satisfying the corecursive definition of the form def foo (x : X) := hd x :: op (foo (tlArg x)) where f is friendly.

          noncomputable def Tactic.ComputeAsymptotics.Seq.gcorec {α : Type u_1} {β : Type u_2} {γ : Type u_3} (F : βOption (α × γ × β)) (op : γStream'.Seq αStream'.Seq α) [FriendlyOperationClass op] :
          βStream'.Seq α

          (General) non-primitive corecursor for Seq α that allows using a friendly operation in the tail of the corecursive definition.

          Equations
          Instances For
            theorem Tactic.ComputeAsymptotics.Seq.gcorec_nil {α : Type u_1} {β : Type u_2} {γ : Type u_3} {F : βOption (α × γ × β)} {op : γStream'.Seq αStream'.Seq α} [FriendlyOperationClass op] {b : β} (h : F b = none) :
            theorem Tactic.ComputeAsymptotics.Seq.gcorec_some {α : Type u_1} {β : Type u_2} {γ : Type u_3} {F : βOption (α × γ × β)} {op : γStream'.Seq αStream'.Seq α} [FriendlyOperationClass op] {b : β} {a : α} {c : γ} {b' : β} (h : F b = some (a, c, b')) :
            gcorec F op b = Stream'.Seq.cons a (op c (gcorec F op b'))