File: Mathlib/Data/QPF/Univariate/Basic.lean

full_name: QPF.abs_map
code: /-- Quotients of polynomial functors.

Roughly speaking, saying that `F` is a quotient of a polynomial functor means that for each `α`,
elements of `F α` are represented by pairs `⟨a, f⟩`, where `a` is the shape of the object and
`f` indexes the relevant elements of `α`, in a suitably natural manner.
-/
class QPF (F : Type u → Type u) extends Functor F where
  P : PFunctor.{u}
  abs : ∀ {α}, P α → F α
  repr : ∀ {α}, F α → P α
  abs_repr : ∀ {α} (x : F α), abs (repr x) = x
  abs_map : ∀ {α β} (f : α → β) (p : P α), abs (P.map f p) = f <$> abs p
goal: QPF.abs ((QPF.P F).map f p) = f <$> QPF.abs p

full_name: QPF.P
code: /-- Quotients of polynomial functors.

Roughly speaking, saying that `F` is a quotient of a polynomial functor means that for each `α`,
elements of `F α` are represented by pairs `⟨a, f⟩`, where `a` is the shape of the object and
`f` indexes the relevant elements of `α`, in a suitably natural manner.
-/
class QPF (F : Type u → Type u) extends Functor F where
  P : PFunctor.{u}
  abs : ∀ {α}, P α → F α
  repr : ∀ {α}, F α → P α
  abs_repr : ∀ {α} (x : F α), abs (repr x) = x
  abs_map : ∀ {α β} (f : α → β) (p : P α), abs (P.map f p) = f <$> abs p
goal: PFunctor.{u}

full_name: QPF.abs
code: /-- Quotients of polynomial functors.

Roughly speaking, saying that `F` is a quotient of a polynomial functor means that for each `α`,
elements of `F α` are represented by pairs `⟨a, f⟩`, where `a` is the shape of the object and
`f` indexes the relevant elements of `α`, in a suitably natural manner.
-/
class QPF (F : Type u → Type u) extends Functor F where
  P : PFunctor.{u}
  abs : ∀ {α}, P α → F α
  repr : ∀ {α}, F α → P α
  abs_repr : ∀ {α} (x : F α), abs (repr x) = x
  abs_map : ∀ {α β} (f : α → β) (p : P α), abs (P.map f p) = f <$> abs p
goal: ↑(QPF.P F) α → F α

full_name: QPF.repr
code: /-- Quotients of polynomial functors.

Roughly speaking, saying that `F` is a quotient of a polynomial functor means that for each `α`,
elements of `F α` are represented by pairs `⟨a, f⟩`, where `a` is the shape of the object and
`f` indexes the relevant elements of `α`, in a suitably natural manner.
-/
class QPF (F : Type u → Type u) extends Functor F where
  P : PFunctor.{u}
  abs : ∀ {α}, P α → F α
  repr : ∀ {α}, F α → P α
  abs_repr : ∀ {α} (x : F α), abs (repr x) = x
  abs_map : ∀ {α β} (f : α → β) (p : P α), abs (P.map f p) = f <$> abs p
goal: F α → ↑(QPF.P F) α

full_name: QPF
code: /-- Quotients of polynomial functors.

Roughly speaking, saying that `F` is a quotient of a polynomial functor means that for each `α`,
elements of `F α` are represented by pairs `⟨a, f⟩`, where `a` is the shape of the object and
`f` indexes the relevant elements of `α`, in a suitably natural manner.
-/
class QPF (F : Type u → Type u) extends Functor F where
  P : PFunctor.{u}
  abs : ∀ {α}, P α → F α
  repr : ∀ {α}, F α → P α
  abs_repr : ∀ {α} (x : F α), abs (repr x) = x
  abs_map : ∀ {α β} (f : α → β) (p : P α), abs (P.map f p) = f <$> abs p
goal: Type (u + 1)

full_name: QPF.abs_repr
code: /-- Quotients of polynomial functors.

Roughly speaking, saying that `F` is a quotient of a polynomial functor means that for each `α`,
elements of `F α` are represented by pairs `⟨a, f⟩`, where `a` is the shape of the object and
`f` indexes the relevant elements of `α`, in a suitably natural manner.
-/
class QPF (F : Type u → Type u) extends Functor F where
  P : PFunctor.{u}
  abs : ∀ {α}, P α → F α
  repr : ∀ {α}, F α → P α
  abs_repr : ∀ {α} (x : F α), abs (repr x) = x
  abs_map : ∀ {α β} (f : α → β) (p : P α), abs (P.map f p) = f <$> abs p
goal: QPF.abs (QPF.repr x) = x

full_name: QPF.id_map
code: theorem id_map {α : Type _} (x : F α) : id <$> x = x 
goal: id <$> x = x

full_name: QPF.comp_map
code: theorem comp_map {α β γ : Type _} (f : α → β) (g : β → γ) (x : F α) :
    (g ∘ f) <$> x = g <$> f <$> x 
goal: (g ∘ f) <$> x = g <$> f <$> x

full_name: QPF.lawfulFunctor
code: theorem lawfulFunctor
    (h : ∀ α β : Type u, @Functor.mapConst F _ α _ = Functor.map ∘ Function.const β) :
    LawfulFunctor F 
goal: LawfulFunctor F

full_name: QPF.liftp_iff
code: theorem liftp_iff {α : Type u} (p : α → Prop) (x : F α) :
    Liftp p x ↔ ∃ a f, x = abs ⟨a, f⟩ ∧ ∀ i, p (f i) 
goal: Functor.Liftp p x ↔ ∃ a f, x = QPF.abs ⟨a, f⟩ ∧ ∀ (i : (QPF.P F).B a), p (f i)

full_name: QPF.liftp_iff'
code: theorem liftp_iff' {α : Type u} (p : α → Prop) (x : F α) :
    Liftp p x ↔ ∃ u : q.P α, abs u = x ∧ ∀ i, p (u.snd i) 
goal: Functor.Liftp p x ↔ ∃ u, QPF.abs u = x ∧ ∀ (i : (QPF.P F).B u.fst), p (u.snd i)

full_name: QPF.liftr_iff
code: theorem liftr_iff {α : Type u} (r : α → α → Prop) (x y : F α) :
    Liftr r x y ↔ ∃ a f₀ f₁, x = abs ⟨a, f₀⟩ ∧ y = abs ⟨a, f₁⟩ ∧ ∀ i, r (f₀ i) (f₁ i) 
goal: Functor.Liftr r x y ↔ ∃ a f₀ f₁, x = QPF.abs ⟨a, f₀⟩ ∧ y = QPF.abs ⟨a, f₁⟩ ∧ ∀ (i : (QPF.P F).B a), r (f₀ i) (f₁ i)

full_name: QPF.recF
code: /-- does recursion on `q.P.W` using `g : F α → α` rather than `g : P α → α` -/
def recF {α : Type _} (g : F α → α) : q.P.W → α
  
goal: (QPF.P F).W → α

full_name: QPF.recF_eq
code: theorem recF_eq {α : Type _} (g : F α → α) (x : q.P.W) :
    recF g x = g (abs (q.P.map (recF g) x.dest)) 
goal: QPF.recF g x = g (QPF.abs ((QPF.P F).map (QPF.recF g) x.dest))

full_name: QPF.recF_eq'
code: theorem recF_eq' {α : Type _} (g : F α → α) (a : q.P.A) (f : q.P.B a → q.P.W) :
    recF g ⟨a, f⟩ = g (abs (q.P.map (recF g) ⟨a, f⟩)) 
goal: QPF.recF g (WType.mk a f) = g (QPF.abs ((QPF.P F).map (QPF.recF g) ⟨a, f⟩))

full_name: QPF.Wequiv.trans
code: /-- two trees are equivalent if their F-abstractions are -/
inductive Wequiv : q.P.W → q.P.W → Prop
  | ind (a : q.P.A) (f f' : q.P.B a → q.P.W) : (∀ x, Wequiv (f x) (f' x)) → Wequiv ⟨a, f⟩ ⟨a, f'⟩
  | abs (a : q.P.A) (f : q.P.B a → q.P.W) (a' : q.P.A) (f' : q.P.B a' → q.P.W) :
      abs ⟨a, f⟩ = abs ⟨a', f'⟩ → Wequiv ⟨a, f⟩ ⟨a', f'⟩
  | trans (u v w : q.P.W) : Wequiv u v → Wequiv v w → Wequiv u w
goal: QPF.Wequiv u v → QPF.Wequiv v w → QPF.Wequiv u w

full_name: QPF.Wequiv.abs
code: /-- two trees are equivalent if their F-abstractions are -/
inductive Wequiv : q.P.W → q.P.W → Prop
  | ind (a : q.P.A) (f f' : q.P.B a → q.P.W) : (∀ x, Wequiv (f x) (f' x)) → Wequiv ⟨a, f⟩ ⟨a, f'⟩
  | abs (a : q.P.A) (f : q.P.B a → q.P.W) (a' : q.P.A) (f' : q.P.B a' → q.P.W) :
      abs ⟨a, f⟩ = abs ⟨a', f'⟩ → Wequiv ⟨a, f⟩ ⟨a', f'⟩
  | trans (u v w : q.P.W) : Wequiv u v → Wequiv v w → Wequiv u w
goal: QPF.abs ⟨a, f⟩ = QPF.abs ⟨a', f'⟩ → QPF.Wequiv (WType.mk a f) (WType.mk a' f')

full_name: QPF.Wequiv
code: /-- two trees are equivalent if their F-abstractions are -/
inductive Wequiv : q.P.W → q.P.W → Prop
  | ind (a : q.P.A) (f f' : q.P.B a → q.P.W) : (∀ x, Wequiv (f x) (f' x)) → Wequiv ⟨a, f⟩ ⟨a, f'⟩
  | abs (a : q.P.A) (f : q.P.B a → q.P.W) (a' : q.P.A) (f' : q.P.B a' → q.P.W) :
      abs ⟨a, f⟩ = abs ⟨a', f'⟩ → Wequiv ⟨a, f⟩ ⟨a', f'⟩
  | trans (u v w : q.P.W) : Wequiv u v → Wequiv v w → Wequiv u w
goal: (QPF.P F).W → (QPF.P F).W → Prop

full_name: QPF.Wequiv.ind
code: /-- two trees are equivalent if their F-abstractions are -/
inductive Wequiv : q.P.W → q.P.W → Prop
  | ind (a : q.P.A) (f f' : q.P.B a → q.P.W) : (∀ x, Wequiv (f x) (f' x)) → Wequiv ⟨a, f⟩ ⟨a, f'⟩
  | abs (a : q.P.A) (f : q.P.B a → q.P.W) (a' : q.P.A) (f' : q.P.B a' → q.P.W) :
      abs ⟨a, f⟩ = abs ⟨a', f'⟩ → Wequiv ⟨a, f⟩ ⟨a', f'⟩
  | trans (u v w : q.P.W) : Wequiv u v → Wequiv v w → Wequiv u w
goal: (∀ (x : (QPF.P F).B a), QPF.Wequiv (f x) (f' x)) → QPF.Wequiv (WType.mk a f) (WType.mk a f')

full_name: QPF.recF_eq_of_Wequiv
code: /-- `recF` is insensitive to the representation -/
theorem recF_eq_of_Wequiv {α : Type u} (u : F α → α) (x y : q.P.W) :
    Wequiv x y → recF u x = recF u y 
goal: QPF.Wequiv x y → QPF.recF u x = QPF.recF u y

full_name: QPF.Wequiv.abs'
code: theorem Wequiv.abs' (x y : q.P.W) (h : QPF.abs x.dest = QPF.abs y.dest) : Wequiv x y 
goal: QPF.Wequiv x y

full_name: QPF.Wequiv.refl
code: theorem Wequiv.refl (x : q.P.W) : Wequiv x x 
goal: QPF.Wequiv x x

full_name: QPF.Wequiv.symm
code: theorem Wequiv.symm (x y : q.P.W) : Wequiv x y → Wequiv y x 
goal: QPF.Wequiv x y → QPF.Wequiv y x

full_name: QPF.Wrepr
code: /-- maps every element of the W type to a canonical representative -/
def Wrepr : q.P.W → q.P.W 
goal: (QPF.P F).W → (QPF.P F).W

full_name: QPF.Wrepr_equiv
code: theorem Wrepr_equiv (x : q.P.W) : Wequiv (Wrepr x) x 
goal: QPF.Wequiv (QPF.Wrepr x) x

full_name: QPF.Wsetoid
code: /-- Define the fixed point as the quotient of trees under the equivalence relation `Wequiv`. -/
def Wsetoid : Setoid q.P.W 
goal: Setoid (QPF.P F).W

full_name: QPF.Fix
code: /-- inductive type defined as initial algebra of a Quotient of Polynomial Functor -/
-- Porting note(#5171): this linter isn't ported yet.
-- @[nolint has_nonempty_instance]
def Fix (F : Type u → Type u) [q : QPF F] 
goal: Type u

full_name: QPF.Fix.rec
code: /-- recursor of a type defined by a qpf -/
def Fix.rec {α : Type _} (g : F α → α) : Fix F → α 
goal: QPF.Fix F → α

full_name: QPF.fixToW
code: /-- access the underlying W-type of a fixpoint data type -/
def fixToW : Fix F → q.P.W 
goal: QPF.Fix F → (QPF.P F).W

full_name: QPF.Fix.mk
code: /-- constructor of a type defined by a qpf -/
def Fix.mk (x : F (Fix F)) : Fix F 
goal: QPF.Fix F

full_name: QPF.Fix.dest
code: /-- destructor of a type defined by a qpf -/
def Fix.dest : Fix F → F (Fix F) 
goal: QPF.Fix F → F (QPF.Fix F)

full_name: QPF.Fix.rec_eq
code: theorem Fix.rec_eq {α : Type _} (g : F α → α) (x : F (Fix F)) :
    Fix.rec g (Fix.mk x) = g (Fix.rec g <$> x) 
goal: QPF.Fix.rec g (QPF.Fix.mk x) = g (QPF.Fix.rec g <$> x)

full_name: QPF.Fix.ind_aux
code: theorem Fix.ind_aux (a : q.P.A) (f : q.P.B a → q.P.W) :
    Fix.mk (abs ⟨a, fun x => ⟦f x⟧⟩) = ⟦⟨a, f⟩⟧ 
goal: QPF.Fix.mk (QPF.abs ⟨a, fun x => ⟦f x⟧⟩) = ⟦WType.mk a f⟧

full_name: QPF.Fix.ind_rec
code: theorem Fix.ind_rec {α : Type u} (g₁ g₂ : Fix F → α)
    (h : ∀ x : F (Fix F), g₁ <$> x = g₂ <$> x → g₁ (Fix.mk x) = g₂ (Fix.mk x)) :
    ∀ x, g₁ x = g₂ x 
goal: g₁ x = g₂ x

full_name: QPF.Fix.rec_unique
code: theorem Fix.rec_unique {α : Type u} (g : F α → α) (h : Fix F → α)
    (hyp : ∀ x, h (Fix.mk x) = g (h <$> x)) : Fix.rec g = h 
goal: QPF.Fix.rec g = h

full_name: QPF.Fix.mk_dest
code: theorem Fix.mk_dest (x : Fix F) : Fix.mk (Fix.dest x) = x 
goal: QPF.Fix.mk x.dest = x

full_name: QPF.Fix.dest_mk
code: theorem Fix.dest_mk (x : F (Fix F)) : Fix.dest (Fix.mk x) = x 
goal: (QPF.Fix.mk x).dest = x

full_name: QPF.Fix.ind
code: theorem Fix.ind (p : Fix F → Prop) (h : ∀ x : F (Fix F), Liftp p x → p (Fix.mk x)) : ∀ x, p x 
goal: p x

full_name: QPF.corecF
code: /-- does recursion on `q.P.M` using `g : α → F α` rather than `g : α → P α` -/
def corecF {α : Type _} (g : α → F α) : α → q.P.M 
goal: α → (QPF.P F).M

full_name: QPF.corecF_eq
code: theorem corecF_eq {α : Type _} (g : α → F α) (x : α) :
    PFunctor.M.dest (corecF g x) = q.P.map (corecF g) (repr (g x)) 
goal: (QPF.corecF g x).dest = (QPF.P F).map (QPF.corecF g) (QPF.repr (g x))

full_name: QPF.IsPrecongr
code: /-- A pre-congruence on `q.P.M` *viewed as an F-coalgebra*. Not necessarily symmetric. -/
def IsPrecongr (r : q.P.M → q.P.M → Prop) : Prop 
goal: Prop

full_name: QPF.Mcongr
code: /-- The maximal congruence on `q.P.M`. -/
def Mcongr : q.P.M → q.P.M → Prop 
goal: (QPF.P F).M → (QPF.P F).M → Prop

full_name: QPF.Cofix
code: /-- coinductive type defined as the final coalgebra of a qpf -/
def Cofix (F : Type u → Type u) [q : QPF F] 
goal: Type u

full_name: QPF.instInhabitedCofixOfAP
code: instance [Inhabited q.P.A] : Inhabited (Cofix F) 
goal: Inhabited (QPF.Cofix F)

full_name: QPF.Cofix.corec
code: /-- corecursor for type defined by `Cofix` -/
def Cofix.corec {α : Type _} (g : α → F α) (x : α) : Cofix F 
goal: QPF.Cofix F

full_name: QPF.Cofix.dest
code: /-- destructor for type defined by `Cofix` -/
def Cofix.dest : Cofix F → F (Cofix F) 
goal: QPF.Cofix F → F (QPF.Cofix F)

full_name: QPF.Cofix.dest_corec
code: theorem Cofix.dest_corec {α : Type u} (g : α → F α) (x : α) :
    Cofix.dest (Cofix.corec g x) = Cofix.corec g <$> g x 
goal: (QPF.Cofix.corec g x).dest = QPF.Cofix.corec g <$> g x

full_name: _private.Mathlib.Data.QPF.Univariate.Basic.0.QPF.Cofix.bisim_aux
code: private theorem Cofix.bisim_aux (r : Cofix F → Cofix F → Prop) (h' : ∀ x, r x x)
    (h : ∀ x y, r x y → Quot.mk r <$> Cofix.dest x = Quot.mk r <$> Cofix.dest y) :
    ∀ x y, r x y → x = y 
goal: r x y → x = y

full_name: QPF.Cofix.bisim_rel
code: theorem Cofix.bisim_rel (r : Cofix F → Cofix F → Prop)
    (h : ∀ x y, r x y → Quot.mk r <$> Cofix.dest x = Quot.mk r <$> Cofix.dest y) :
    ∀ x y, r x y → x = y 
goal: r x y → x = y

full_name: QPF.Cofix.bisim
code: theorem Cofix.bisim (r : Cofix F → Cofix F → Prop)
    (h : ∀ x y, r x y → Liftr r (Cofix.dest x) (Cofix.dest y)) : ∀ x y, r x y → x = y 
goal: r x y → x = y

full_name: QPF.Cofix.bisim'
code: theorem Cofix.bisim' {α : Type*} (Q : α → Prop) (u v : α → Cofix F)
    (h : ∀ x, Q x → ∃ a f f', Cofix.dest (u x) = abs ⟨a, f⟩ ∧ Cofix.dest (v x) = abs ⟨a, f'⟩ ∧
      ∀ i, ∃ x', Q x' ∧ f i = u x' ∧ f' i = v x') :
    ∀ x, Q x → u x = v x 
goal: Q x → u x = v x

full_name: QPF.comp
code: /-- composition of qpfs gives another qpf -/
def comp : QPF (Functor.Comp F₂ F₁) 
goal: QPF (Functor.Comp F₂ F₁)

full_name: QPF.quotientQPF
code: /-- Given a qpf `F` and a well-behaved surjection `FG_abs` from `F α` to
functor `G α`, `G` is a qpf. We can consider `G` a quotient on `F` where
elements `x y : F α` are in the same equivalence class if
`FG_abs x = FG_abs y`. -/
def quotientQPF (FG_abs_repr : ∀ {α} (x : G α), FG_abs (FG_repr x) = x)
    (FG_abs_map : ∀ {α β} (f : α → β) (x : F α), FG_abs (f <$> x) = f <$> FG_abs x) : QPF G 
goal: QPF G

full_name: QPF.mem_supp
code: theorem mem_supp {α : Type u} (x : F α) (u : α) :
    u ∈ supp x ↔ ∀ a f, abs ⟨a, f⟩ = x → u ∈ f '' univ 
goal: u ∈ Functor.supp x ↔ ∀ (a : (QPF.P F).A) (f : (QPF.P F).B a → α), QPF.abs ⟨a, f⟩ = x → u ∈ f '' Set.univ

full_name: QPF.supp_eq
code: theorem supp_eq {α : Type u} (x : F α) :
    supp x = { u | ∀ a f, abs ⟨a, f⟩ = x → u ∈ f '' univ } 
goal: Functor.supp x = {u | ∀ (a : (QPF.P F).A) (f : (QPF.P F).B a → α), QPF.abs ⟨a, f⟩ = x → u ∈ f '' Set.univ}

full_name: QPF.has_good_supp_iff
code: theorem has_good_supp_iff {α : Type u} (x : F α) :
    (∀ p, Liftp p x ↔ ∀ u ∈ supp x, p u) ↔
      ∃ a f, abs ⟨a, f⟩ = x ∧ ∀ a' f', abs ⟨a', f'⟩ = x → f '' univ ⊆ f' '' univ 
goal: (∀ (p : α → Prop), Functor.Liftp p x ↔ ∀ u ∈ Functor.supp x, p u) ↔
  ∃ a f,
    QPF.abs ⟨a, f⟩ = x ∧
      ∀ (a' : (QPF.P F).A) (f' : (QPF.P F).B a' → α), QPF.abs ⟨a', f'⟩ = x → f '' Set.univ ⊆ f' '' Set.univ

full_name: QPF.IsUniform
code: /-- A qpf is said to be uniform if every polynomial functor
representing a single value all have the same range. -/
def IsUniform : Prop 
goal: Prop

full_name: QPF.LiftpPreservation
code: /-- does `abs` preserve `Liftp`? -/
def LiftpPreservation : Prop 
goal: Prop

full_name: QPF.SuppPreservation
code: /-- does `abs` preserve `supp`? -/
def SuppPreservation : Prop 
goal: Prop

full_name: QPF.supp_eq_of_isUniform
code: theorem supp_eq_of_isUniform (h : q.IsUniform) {α : Type u} (a : q.P.A) (f : q.P.B a → α) :
    supp (abs ⟨a, f⟩) = f '' univ 
goal: Functor.supp (QPF.abs ⟨a, f⟩) = f '' Set.univ

full_name: QPF.liftp_iff_of_isUniform
code: theorem liftp_iff_of_isUniform (h : q.IsUniform) {α : Type u} (x : F α) (p : α → Prop) :
    Liftp p x ↔ ∀ u ∈ supp x, p u 
goal: Functor.Liftp p x ↔ ∀ u ∈ Functor.supp x, p u

full_name: QPF.supp_map
code: theorem supp_map (h : q.IsUniform) {α β : Type u} (g : α → β) (x : F α) :
    supp (g <$> x) = g '' supp x 
goal: Functor.supp (g <$> x) = g '' Functor.supp x

full_name: QPF.suppPreservation_iff_uniform
code: theorem suppPreservation_iff_uniform : q.SuppPreservation ↔ q.IsUniform 
goal: QPF.SuppPreservation ↔ QPF.IsUniform

full_name: QPF.suppPreservation_iff_liftpPreservation
code: theorem suppPreservation_iff_liftpPreservation : q.SuppPreservation ↔ q.LiftpPreservation 
goal: QPF.SuppPreservation ↔ QPF.LiftpPreservation

full_name: QPF.liftpPreservation_iff_uniform
code: theorem liftpPreservation_iff_uniform : q.LiftpPreservation ↔ q.IsUniform 
goal: QPF.LiftpPreservation ↔ QPF.IsUniform