/-
Copyright (c) 2018 Johan Commelin. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Johan Commelin, Reid Barton, Simon Hudon

! This file was ported from Lean 3 source module tactic.tfae
! leanprover-community/mathlib commit 3c11bd771ef17197a9e9fcd4a3fabfa2804d950c
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.Data.List.Tfae
import Mathbin.Tactic.Scc

/-!
# The Following Are Equivalent (TFAE)

This file provides the tactics `tfae_have` and `tfae_finish` for proving the pairwise equivalence of
propositions in a set using various implications between them.
-/

namespace Tactic

export List (TFAE)

namespace Tfae

inductive Arrow : Type
  | right : arrow
  | left_right : arrow
  | left : arrow
  deriving has_reflect, Inhabited
#align tactic.tfae.arrow Tactic.Tfae.Arrow

-- failed to format: unknown constant 'term.pseudo.antiquot'
unsafe
  def
    mk_implication
    : ∀ ( re : Arrow ) ( e₁ e₂ : expr ) , pexpr
    | arrow.right , e₁ , e₂ => ` `( $ ( e₁ ) → $ ( e₂ ) )
      | arrow.left_right , e₁ , e₂ => ` `( $ ( e₁ ) ↔ $ ( e₂ ) )
      | arrow.left , e₁ , e₂ => ` `( $ ( e₂ ) → $ ( e₁ ) )
#align tactic.tfae.mk_implication tactic.tfae.mk_implication

unsafe def mk_name : ∀ (re : Arrow) (i₁ i₂ : Nat), Name
  | arrow.right, i₁, i₂ => ("tfae_" ++ toString i₁ ++ "_to_" ++ toString i₂ : String)
  | arrow.left_right, i₁, i₂ => ("tfae_" ++ toString i₁ ++ "_iff_" ++ toString i₂ : String)
  | arrow.left, i₁, i₂ => ("tfae_" ++ toString i₂ ++ "_to_" ++ toString i₁ : String)
#align tactic.tfae.mk_name tactic.tfae.mk_name

end Tfae

namespace Interactive

/- ./././Mathport/Syntax/Translate/Tactic/Mathlib/Core.lean:38:34: unsupported: setup_tactic_parser -/
open Tactic.Tfae List

-- failed to format: unknown constant 'term.pseudo.antiquot'
unsafe
  def
    parse_list
    : expr → Option ( List expr )
    | q( [ ] ) => pure [ ] | q( $ ( e ) :: $ ( es ) ) => ( · :: · ) e <$> parse_list es | _ => none
#align tactic.interactive.parse_list tactic.interactive.parse_list

/-- In a goal of the form `tfae [a₀, a₁, a₂]`,
`tfae_have : i → j` creates the assertion `aᵢ → aⱼ`. The other possible
notations are `tfae_have : i ← j` and `tfae_have : i ↔ j`. The user can
also provide a label for the assertion, as with `have`: `tfae_have h : i ↔ j`.
-/
unsafe def tfae_have (h : parse <| optional ident <* tk ":") (i₁ : parse (with_desc "i" small_nat))
    (re :
      parse
        ((tk "→" <|> tk "->") *> return Arrow.right <|>
          (tk "↔" <|> tk "<->") *> return Arrow.left_right <|>
            (tk "←" <|> tk "<-") *> return Arrow.left))
    (i₂ : parse (with_desc "j" small_nat)) : tactic Unit := do
  let q(TFAE $(l)) ← target
  let l ← parse_list l
  let e₁ ← List.get? l (i₁ - 1) <|> fail f! "index {i₁ } is not between 1 and {l.length}"
  let e₂ ← List.get? l (i₂ - 1) <|> fail f! "index {i₂ } is not between 1 and {l.length}"
  let type ← to_expr (tfae.mk_implication re e₁ e₂)
  let h := h.getD (mk_name re i₁ i₂)
  tactic.assert h type
  return ()
#align tactic.interactive.tfae_have tactic.interactive.tfae_have

/-- Finds all implications and equivalences in the context
to prove a goal of the form `tfae [...]`.
-/
unsafe def tfae_finish : tactic Unit :=
  applyc `` tfae_nil <|>
    closure.with_new_closure fun cl => do
      impl_graph.mk_scc cl
      let q(TFAE $(l)) ← target
      let l ← parse_list l
      let (_, r, _) ← cl.root l.headI
      refine ``(tfae_of_forall $(r) _ _)
      let thm ← mk_const `` forall_mem_cons
      l fun e => do
          rewrite_target thm
          split
          let (_, r', p) ← cl e
          tactic.exact p
      applyc `` forall_mem_nil
      pure ()
#align tactic.interactive.tfae_finish tactic.interactive.tfae_finish

end Interactive

end Tactic

/-- The `tfae` tactic suite is a set of tactics that help with proving that certain
propositions are equivalent.
In `data/list/basic.lean` there is a section devoted to propositions of the
form
```lean
tfae [p1, p2, ..., pn]
```
where `p1`, `p2`, through, `pn` are terms of type `Prop`.
This proposition asserts that all the `pi` are pairwise equivalent.
There are results that allow to extract the equivalence
of two propositions `pi` and `pj`.

To prove a goal of the form `tfae [p1, p2, ..., pn]`, there are two
tactics.  The first tactic is `tfae_have`.  As an argument it takes an
expression of the form `i arrow j`, where `i` and `j` are two positive
natural numbers, and `arrow` is an arrow such as `→`, `->`, `←`, `<-`,
`↔`, or `<->`.  The tactic `tfae_have : i arrow j` sets up a subgoal in
which the user has to prove the equivalence (or implication) of `pi` and `pj`.

The remaining tactic, `tfae_finish`, is a finishing tactic. It
collects all implications and equivalences from the local context and
computes their transitive closure to close the
main goal.

`tfae_have` and `tfae_finish` can be used together in a proof as
follows:

```lean
example (a b c d : Prop) : tfae [a,b,c,d] :=
begin
  tfae_have : 3 → 1,
  { /- prove c → a -/ },
  tfae_have : 2 → 3,
  { /- prove b → c -/ },
  tfae_have : 2 ← 1,
  { /- prove a → b -/ },
  tfae_have : 4 ↔ 2,
  { /- prove d ↔ b -/ },
    -- a b c d : Prop,
    -- tfae_3_to_1 : c → a,
    -- tfae_2_to_3 : b → c,
    -- tfae_1_to_2 : a → b,
    -- tfae_4_iff_2 : d ↔ b
    -- ⊢ tfae [a, b, c, d]
  tfae_finish,
end
```
-/
add_tactic_doc
  { Name := "tfae"
    category := DocCategory.tactic
    declNames := [`tactic.interactive.tfae_have, `tactic.interactive.tfae_finish]
    tags := ["logic"]
    inheritDescriptionFrom := `tactic.interactive.tfae_finish }


inductive Vec (α : Type u) : Nat → Type u
  | nil  : Vec α 0
  | cons : α → {n : Nat} → Vec α n → Vec α (n+1)

def Vec.repeat (a : α) (n : Nat) : Vec α n :=
  match n with
  | 0   => nil
  | n+1 => cons a («repeat» a n)

instance [Inhabited α] : Inhabited (Vec α n) where
  default := Vec.repeat default n

def Vec.map (v : Vec α n) (f : α → β) : Vec β n :=
  match n, v with
  | _, nil       => nil
  | _, cons a as => cons (f a) (map as f)

def Vec.reverse (v : Vec α n) : Vec α n :=
  let rec loop {n m : Nat} : Vec α n → Vec α m → Vec α (n + m)
    | nil,       w => Nat.zero_add .. ▸ w
    | cons a as, w => Nat.add_assoc .. ▸ loop as (Nat.add_comm .. ▸ cons a w)
  loop v nil

@[simp] theorem map_id (v : Vec α n) : v.map id = v := by
  induction v with
  | nil => rfl
  | cons a as ih => simp [Vec.map, ih]

def foo [Add α] (v w : Vec α n) (f : α → α) (a : α) : α :=
  match n, v.map f, w.map f with
  | _, Vec.nil,       Vec.nil       => a
  | _, Vec.cons a .., Vec.cons b .. => a + b

theorem ex1 (a b : Nat) (as : Vec Nat n) : foo (Vec.cons a as) (Vec.cons b as) id 0 = a + b := by
  simp [foo]

#print ex1

def bla (b : Bool) (f g : α → β) (a : α) : β :=
  (match b with
   | true => f | false => g) a

theorem ex2 (h : b = false) : bla b (fun x => x + 1) id 10 = 10 := by
  simp [bla, h]

#print ex2


/-
Copyright (c) 2020 Simon Hudon. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Simon Hudon

! This file was ported from Lean 3 source module control.lawful_fix
! leanprover-community/mathlib commit f47581155c818e6361af4e4fda60d27d020c226b
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.Data.Stream.Init
import Mathbin.Tactic.Apply
import Mathbin.Control.Fix
import Mathbin.Order.OmegaCompletePartialOrder

/-!
# Lawful fixed point operators

> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
> Any changes to this file require a corresponding PR to mathlib4.

This module defines the laws required of a `has_fix` instance, using the theory of
omega complete partial orders (ωCPO). Proofs of the lawfulness of all `has_fix` instances in
`control.fix` are provided.

## Main definition

 * class `lawful_fix`
-/

universe u v

open Classical

variable {α : Type _} {β : α → Type _}

open OmegaCompletePartialOrder

#print LawfulFix /-
/-- Intuitively, a fixed point operator `fix` is lawful if it satisfies `fix f = f (fix f)` for all
`f`, but this is inconsistent / uninteresting in most cases due to the existence of "exotic"
functions `f`, such as the function that is defined iff its argument is not, familiar from the
halting problem. Instead, this requirement is limited to only functions that are `continuous` in the
sense of `ω`-complete partial orders, which excludes the example because it is not monotone
(making the input argument less defined can make `f` more defined). -/
class LawfulFix (α : Type _) [OmegaCompletePartialOrder α] extends Fix α where
  fix_eq : ∀ {f : α →o α}, Continuous f → Fix.fix f = f (Fix.fix f)
#align lawful_fix LawfulFix
-/

#print LawfulFix.fix_eq' /-
theorem LawfulFix.fix_eq' {α} [OmegaCompletePartialOrder α] [LawfulFix α] {f : α → α}
    (hf : Continuous' f) : Fix.fix f = f (Fix.fix f) :=
  LawfulFix.fix_eq (hf.to_bundled _)
#align lawful_fix.fix_eq' LawfulFix.fix_eq'
-/

namespace Part

open Part Nat Nat.Upto

namespace Fix

variable (f : (∀ a, Part <| β a) →o ∀ a, Part <| β a)

/- warning: part.fix.approx_mono' -> Part.Fix.approx_mono' is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} {β : α -> Type.{u2}} (f : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) {i : Nat}, LE.le.{max u1 u2} (forall (a : α), Part.{u2} (β a)) (Pi.hasLe.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => Preorder.toLE.{u2} (Part.{u2} (β i)) (PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (Part.Fix.approx.{u1, u2} α (fun (a : α) => β a) (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f) i) (Part.Fix.approx.{u1, u2} α (fun (a : α) => β a) (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f) (Nat.succ i))
but is expected to have type
  forall {α : Type.{u2}} {β : α -> Type.{u1}} (f : OrderHom.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i))))) {i : Nat}, LE.le.{max u2 u1} (forall (a : α), Part.{u1} (β a)) (Pi.hasLe.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => Preorder.toLE.{u1} (Part.{u1} (β i)) (PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i))))) (Part.Fix.approx.{u2, u1} α (fun (a : α) => β a) (OrderHom.toFun.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) f) i) (Part.Fix.approx.{u2, u1} α (fun (a : α) => β a) (OrderHom.toFun.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) f) (Nat.succ i))
Case conversion may be inaccurate. Consider using '#align part.fix.approx_mono' Part.Fix.approx_mono'ₓ'. -/
theorem approx_mono' {i : ℕ} : Fix.approx f i ≤ Fix.approx f (succ i) :=
  by
  induction i; dsimp [approx]; apply @bot_le _ _ _ (f ⊥)
  intro ; apply f.monotone; apply i_ih
#align part.fix.approx_mono' Part.Fix.approx_mono'

/- warning: part.fix.approx_mono -> Part.Fix.approx_mono is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} {β : α -> Type.{u2}} (f : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) {{i : Nat}} {{j : Nat}}, (LE.le.{0} Nat Nat.hasLe i j) -> (LE.le.{max u1 u2} (forall (a : α), Part.{u2} (β a)) (Pi.hasLe.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => Preorder.toLE.{u2} (Part.{u2} (β i)) (PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (Part.Fix.approx.{u1, u2} α (fun (a : α) => β a) (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f) i) (Part.Fix.approx.{u1, u2} α (fun (a : α) => β a) (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f) j))
but is expected to have type
  forall {α : Type.{u2}} {β : α -> Type.{u1}} (f : OrderHom.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i))))) {{i : Nat}} {{j : Nat}}, (LE.le.{0} Nat instLENat i j) -> (LE.le.{max u2 u1} (forall (a : α), Part.{u1} (β a)) (Pi.hasLe.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => Preorder.toLE.{u1} (Part.{u1} (β i)) (PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i))))) (Part.Fix.approx.{u2, u1} α (fun (a : α) => β a) (OrderHom.toFun.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) f) i) (Part.Fix.approx.{u2, u1} α (fun (a : α) => β a) (OrderHom.toFun.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) f) j))
Case conversion may be inaccurate. Consider using '#align part.fix.approx_mono Part.Fix.approx_monoₓ'. -/
theorem approx_mono ⦃i j : ℕ⦄ (hij : i ≤ j) : approx f i ≤ approx f j :=
  by
  induction' j with j ih;
  · cases hij
    exact le_rfl
  cases hij; · exact le_rfl
  exact le_trans (ih ‹_›) (approx_mono' f)
#align part.fix.approx_mono Part.Fix.approx_mono

/- warning: part.fix.mem_iff -> Part.Fix.mem_iff is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} {β : α -> Type.{u2}} (f : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (a : α) (b : β a), Iff (Membership.Mem.{u2, u2} (β a) (Part.{u2} (β a)) (Part.hasMem.{u2} (β a)) b (Part.fix.{u1, u2} α (fun (a : α) => β a) (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f) a)) (Exists.{1} Nat (fun (i : Nat) => Membership.Mem.{u2, u2} (β a) (Part.{u2} (β a)) (Part.hasMem.{u2} (β a)) b (Part.Fix.approx.{u1, u2} α (fun (a : α) => β a) (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f) i a)))
but is expected to have type
  forall {α : Type.{u1}} {β : α -> Type.{u2}} (f : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i))))) (a : α) (b : β a), Iff (Membership.mem.{u2, u2} (β a) (Part.{u2} (β a)) (Part.instMembershipPart.{u2} (β a)) b (Part.fix.{u1, u2} α (fun (a : α) => β a) (OrderHom.toFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) f) a)) (Exists.{1} Nat (fun (i : Nat) => Membership.mem.{u2, u2} (β a) (Part.{u2} (β a)) (Part.instMembershipPart.{u2} (β a)) b (Part.Fix.approx.{u1, u2} α (fun (a : α) => β a) (OrderHom.toFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) f) i a)))
Case conversion may be inaccurate. Consider using '#align part.fix.mem_iff Part.Fix.mem_iffₓ'. -/
theorem mem_iff (a : α) (b : β a) : b ∈ Part.fix f a ↔ ∃ i, b ∈ approx f i a :=
  by
  by_cases h₀ : ∃ i : ℕ, (approx f i a).Dom
  · simp only [Part.fix_def f h₀]
    constructor <;> intro hh
    exact ⟨_, hh⟩
    have h₁ := Nat.find_spec h₀
    rw [dom_iff_mem] at h₁
    cases' h₁ with y h₁
    replace h₁ := approx_mono' f _ _ h₁
    suffices : y = b
    subst this
    exact h₁
    cases' hh with i hh
    revert h₁
    generalize succ (Nat.find h₀) = j
    intro
    wlog case : i ≤ j
    · cases' le_total i j with H H <;> [skip, symm] <;> apply_assumption <;> assumption
    replace hh := approx_mono f case _ _ hh
    apply Part.mem_unique h₁ hh
  · simp only [fix_def' (⇑f) h₀, not_exists, false_iff_iff, not_mem_none]
    simp only [dom_iff_mem, not_exists] at h₀
    intro
    apply h₀
#align part.fix.mem_iff Part.Fix.mem_iff

/- warning: part.fix.approx_le_fix -> Part.Fix.approx_le_fix is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} {β : α -> Type.{u2}} (f : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (i : Nat), LE.le.{max u1 u2} (forall (a : α), Part.{u2} (β a)) (Pi.hasLe.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => Preorder.toLE.{u2} (Part.{u2} (β i)) (PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (Part.Fix.approx.{u1, u2} α (fun (a : α) => β a) (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f) i) (Part.fix.{u1, u2} α (fun (a : α) => β a) (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f))
but is expected to have type
  forall {α : Type.{u2}} {β : α -> Type.{u1}} (f : OrderHom.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i))))) (i : Nat), LE.le.{max u2 u1} (forall (a : α), Part.{u1} (β a)) (Pi.hasLe.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => Preorder.toLE.{u1} (Part.{u1} (β i)) (PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i))))) (Part.Fix.approx.{u2, u1} α (fun (a : α) => β a) (OrderHom.toFun.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) f) i) (Part.fix.{u2, u1} α (fun (a : α) => β a) (OrderHom.toFun.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) f))
Case conversion may be inaccurate. Consider using '#align part.fix.approx_le_fix Part.Fix.approx_le_fixₓ'. -/
theorem approx_le_fix (i : ℕ) : approx f i ≤ Part.fix f := fun a b hh =>
  by
  rw [mem_iff f]
  exact ⟨_, hh⟩
#align part.fix.approx_le_fix Part.Fix.approx_le_fix

/- warning: part.fix.exists_fix_le_approx -> Part.Fix.exists_fix_le_approx is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} {β : α -> Type.{u2}} (f : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (x : α), Exists.{1} Nat (fun (i : Nat) => LE.le.{u2} (Part.{u2} (β x)) (Preorder.toLE.{u2} (Part.{u2} (β x)) (PartialOrder.toPreorder.{u2} (Part.{u2} (β x)) (Part.partialOrder.{u2} (β x)))) (Part.fix.{u1, u2} α (fun (a : α) => β a) (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f) x) (Part.Fix.approx.{u1, u2} α β (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f) i x))
but is expected to have type
  forall {α : Type.{u1}} {β : α -> Type.{u2}} (f : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i))))) (x : α), Exists.{1} Nat (fun (i : Nat) => LE.le.{u2} (Part.{u2} (β x)) (Preorder.toLE.{u2} (Part.{u2} (β x)) (PartialOrder.toPreorder.{u2} (Part.{u2} (β x)) (Part.instPartialOrderPart.{u2} (β x)))) (Part.fix.{u1, u2} α (fun (a : α) => β a) (OrderHom.toFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) f) x) (Part.Fix.approx.{u1, u2} α (fun (a : α) => β a) (OrderHom.toFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) f) i x))
Case conversion may be inaccurate. Consider using '#align part.fix.exists_fix_le_approx Part.Fix.exists_fix_le_approxₓ'. -/
theorem exists_fix_le_approx (x : α) : ∃ i, Part.fix f x ≤ approx f i x :=
  by
  by_cases hh : ∃ i b, b ∈ approx f i x
  · rcases hh with ⟨i, b, hb⟩
    exists i
    intro b' h'
    have hb' := approx_le_fix f i _ _ hb
    obtain rfl := Part.mem_unique h' hb'
    exact hb
  · simp only [not_exists] at hh
    exists 0
    intro b' h'
    simp only [mem_iff f] at h'
    cases' h' with i h'
    cases hh _ _ h'
#align part.fix.exists_fix_le_approx Part.Fix.exists_fix_le_approx

include f

/- warning: part.fix.approx_chain -> Part.Fix.approxChain is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} {β : α -> Type.{u2}}, (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) -> (OmegaCompletePartialOrder.Chain.{max u1 u2} (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))))
but is expected to have type
  forall {α : Type.{u1}} {β : α -> Type.{u2}}, (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i))))) -> (OmegaCompletePartialOrder.Chain.{max u1 u2} (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))))
Case conversion may be inaccurate. Consider using '#align part.fix.approx_chain Part.Fix.approxChainₓ'. -/
/-- The series of approximations of `fix f` (see `approx`) as a `chain` -/
def approxChain : Chain (∀ a, Part <| β a) :=
  ⟨approx f, approx_mono f⟩
#align part.fix.approx_chain Part.Fix.approxChain

/- warning: part.fix.le_f_of_mem_approx -> Part.Fix.le_f_of_mem_approx is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} {β : α -> Type.{u2}} (f : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) {x : forall (a : α), Part.{u2} (β a)}, (Membership.Mem.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (OmegaCompletePartialOrder.Chain.{max u1 u2} (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (OmegaCompletePartialOrder.Chain.hasMem.{max u1 u2} (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) x (Part.Fix.approxChain.{u1, u2} α (fun (a : α) => β a) f)) -> (LE.le.{max u1 u2} (forall (a : α), Part.{u2} (β a)) (Pi.hasLe.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => Preorder.toLE.{u2} (Part.{u2} (β i)) (PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) x (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f x))
but is expected to have type
  forall {α : Type.{u1}} {β : α -> Type.{u2}} (f : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i))))) {x : forall (a : α), Part.{u2} (β a)}, (Membership.mem.{max u1 u2, max u2 u1} (forall (a : α), Part.{u2} (β a)) (OmegaCompletePartialOrder.Chain.{max u1 u2} (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i))))) (OmegaCompletePartialOrder.Chain.instMembershipChain.{max u1 u2} (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i))))) x (Part.Fix.approxChain.{u1, u2} α (fun (a : α) => β a) f)) -> (LE.le.{max u1 u2} (forall (a : α), Part.{u2} (β a)) (Pi.hasLe.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => Preorder.toLE.{u2} (Part.{u2} (β i)) (PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i))))) x (OrderHom.toFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) f x))
Case conversion may be inaccurate. Consider using '#align part.fix.le_f_of_mem_approx Part.Fix.le_f_of_mem_approxₓ'. -/
theorem le_f_of_mem_approx {x} : x ∈ approxChain f → x ≤ f x :=
  by
  simp only [(· ∈ ·), forall_exists_index]
  rintro i rfl
  apply approx_mono'
#align part.fix.le_f_of_mem_approx Part.Fix.le_f_of_mem_approx

/- warning: part.fix.approx_mem_approx_chain -> Part.Fix.approx_mem_approxChain is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} {β : α -> Type.{u2}} (f : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) {i : Nat}, Membership.Mem.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (OmegaCompletePartialOrder.Chain.{max u1 u2} (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (OmegaCompletePartialOrder.Chain.hasMem.{max u1 u2} (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (Part.Fix.approx.{u1, u2} α (fun (a : α) => β a) (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f) i) (Part.Fix.approxChain.{u1, u2} α (fun (a : α) => β a) f)
but is expected to have type
  forall {α : Type.{u2}} {β : α -> Type.{u1}} (f : OrderHom.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i))))) {i : Nat}, Membership.mem.{max u2 u1, max u1 u2} (forall (a : α), Part.{u1} (β a)) (OmegaCompletePartialOrder.Chain.{max u2 u1} (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i))))) (OmegaCompletePartialOrder.Chain.instMembershipChain.{max u2 u1} (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i))))) (Part.Fix.approx.{u2, u1} α (fun (a : α) => β a) (OrderHom.toFun.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) f) i) (Part.Fix.approxChain.{u2, u1} α (fun (a : α) => β a) f)
Case conversion may be inaccurate. Consider using '#align part.fix.approx_mem_approx_chain Part.Fix.approx_mem_approxChainₓ'. -/
theorem approx_mem_approxChain {i} : approx f i ∈ approxChain f :=
  Stream'.mem_of_nth_eq rfl
#align part.fix.approx_mem_approx_chain Part.Fix.approx_mem_approxChain

end Fix

open Fix

variable {α}

variable (f : (∀ a, Part <| β a) →o ∀ a, Part <| β a)

open OmegaCompletePartialOrder

open Part hiding ωSup

open Nat

open Nat.Upto OmegaCompletePartialOrder

/- warning: part.fix_eq_ωSup -> Part.fix_eq_ωSup is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} {β : α -> Type.{u2}} (f : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))), Eq.{max (succ u1) (succ u2)} (forall (x : α), Part.{u2} (β x)) (Part.fix.{u1, u2} α (fun (a : α) => β a) (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f)) (OmegaCompletePartialOrder.ωSup.{max u1 u2} (forall (x : α), Part.{u2} (β x)) (Pi.omegaCompletePartialOrder.{u1, u2} α (fun (x : α) => Part.{u2} (β x)) (fun (a : α) => Part.omegaCompletePartialOrder.{u2} (β a))) (Part.Fix.approxChain.{u1, u2} α (fun (x : α) => β x) f))
but is expected to have type
  forall {α : Type.{u2}} {β : α -> Type.{u1}} (f : OrderHom.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i))))), Eq.{max (succ u2) (succ u1)} (forall (x : α), Part.{u1} (β x)) (Part.fix.{u2, u1} α (fun (a : α) => β a) (OrderHom.toFun.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) f)) (OmegaCompletePartialOrder.ωSup.{max u1 u2} (forall (x : α), Part.{u1} (β x)) (Pi.instOmegaCompletePartialOrderForAll.{u2, u1} α (fun (x : α) => Part.{u1} (β x)) (fun (a : α) => Part.omegaCompletePartialOrder.{u1} (β a))) (Part.Fix.approxChain.{u2, u1} α (fun (x : α) => β x) f))
Case conversion may be inaccurate. Consider using '#align part.fix_eq_ωSup Part.fix_eq_ωSupₓ'. -/
theorem fix_eq_ωSup : Part.fix f = ωSup (approxChain f) :=
  by
  apply le_antisymm
  · intro x
    cases' exists_fix_le_approx f x with i hx
    trans approx f i.succ x
    · trans
      apply hx
      apply approx_mono' f
    apply le_ωSup_of_le i.succ
    dsimp [approx]
    rfl
  · apply ωSup_le _ _ _
    simp only [fix.approx_chain, OrderHom.coe_fun_mk]
    intro y x
    apply approx_le_fix f
#align part.fix_eq_ωSup Part.fix_eq_ωSup

/- warning: part.fix_le -> Part.fix_le is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} {β : α -> Type.{u2}} (f : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) {X : forall (a : α), Part.{u2} (β a)}, (LE.le.{max u1 u2} (forall (a : α), Part.{u2} (β a)) (Pi.hasLe.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => Preorder.toLE.{u2} (Part.{u2} (β i)) (PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f X) X) -> (LE.le.{max u1 u2} (forall (x : α), Part.{u2} (β x)) (Pi.hasLe.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => Preorder.toLE.{u2} (Part.{u2} (β i)) (PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (Part.fix.{u1, u2} α (fun (a : α) => β a) (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f)) X)
but is expected to have type
  forall {α : Type.{u1}} {β : α -> Type.{u2}} (f : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i))))) {X : forall (a : α), Part.{u2} (β a)}, (LE.le.{max u1 u2} (forall (a : α), Part.{u2} (β a)) (Pi.hasLe.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => Preorder.toLE.{u2} (Part.{u2} (β i)) (PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i))))) (OrderHom.toFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) f X) X) -> (LE.le.{max u1 u2} (forall (x : α), Part.{u2} (β x)) (Pi.hasLe.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => Preorder.toLE.{u2} (Part.{u2} (β i)) (PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i))))) (Part.fix.{u1, u2} α (fun (a : α) => β a) (OrderHom.toFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.instPartialOrderPart.{u2} (β i)))) f)) X)
Case conversion may be inaccurate. Consider using '#align part.fix_le Part.fix_leₓ'. -/
theorem fix_le {X : ∀ a, Part <| β a} (hX : f X ≤ X) : Part.fix f ≤ X :=
  by
  rw [fix_eq_ωSup f]
  apply ωSup_le _ _ _
  simp only [fix.approx_chain, OrderHom.coe_fun_mk]
  intro i
  induction i; dsimp [fix.approx]; apply bot_le
  trans f X; apply f.monotone i_ih
  apply hX
#align part.fix_le Part.fix_le

variable {f} (hc : Continuous f)

include hc

/- warning: part.fix_eq -> Part.fix_eq is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} {β : α -> Type.{u2}} {f : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))}, (OmegaCompletePartialOrder.Continuous.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.omegaCompletePartialOrder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (a : α) => Part.omegaCompletePartialOrder.{u2} (β a))) (Pi.omegaCompletePartialOrder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (a : α) => Part.omegaCompletePartialOrder.{u2} (β a))) f) -> (Eq.{max (succ u1) (succ u2)} (forall (x : α), Part.{u2} (β x)) (Part.fix.{u1, u2} α (fun (a : α) => β a) (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f)) (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f (Part.fix.{u1, u2} α (fun (a : α) => β a) (coeFn.{succ (max u1 u2), succ (max u1 u2)} (OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) (fun (_x : OrderHom.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) => (forall (a : α), Part.{u2} (β a)) -> (forall (a : α), Part.{u2} (β a))) (OrderHom.hasCoeToFun.{max u1 u2, max u1 u2} (forall (a : α), Part.{u2} (β a)) (forall (a : α), Part.{u2} (β a)) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i)))) (Pi.preorder.{u1, u2} α (fun (a : α) => Part.{u2} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u2} (Part.{u2} (β i)) (Part.partialOrder.{u2} (β i))))) f))))
but is expected to have type
  forall {α : Type.{u2}} {β : α -> Type.{u1}} {f : OrderHom.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i))))}, (OmegaCompletePartialOrder.Continuous.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.instOmegaCompletePartialOrderForAll.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (a : α) => Part.omegaCompletePartialOrder.{u1} (β a))) (Pi.instOmegaCompletePartialOrderForAll.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (a : α) => Part.omegaCompletePartialOrder.{u1} (β a))) f) -> (Eq.{max (succ u2) (succ u1)} (forall (x : α), Part.{u1} (β x)) (Part.fix.{u2, u1} α (fun (a : α) => β a) (OrderHom.toFun.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) f)) (OrderHom.toFun.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) f (Part.fix.{u2, u1} α (fun (a : α) => β a) (OrderHom.toFun.{max u2 u1, max u2 u1} (forall (a : α), Part.{u1} (β a)) (forall (a : α), Part.{u1} (β a)) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) (Pi.preorder.{u2, u1} α (fun (a : α) => Part.{u1} (β a)) (fun (i : α) => PartialOrder.toPreorder.{u1} (Part.{u1} (β i)) (Part.instPartialOrderPart.{u1} (β i)))) f))))
Case conversion may be inaccurate. Consider using '#align part.fix_eq Part.fix_eqₓ'. -/
theorem fix_eq : Part.fix f = f (Part.fix f) :=
  by
  rw [fix_eq_ωSup f, hc]
  apply le_antisymm
  · apply ωSup_le_ωSup_of_le _
    intro i
    exists i
    intro x
    -- intros x y hx,
    apply le_f_of_mem_approx _ ⟨i, rfl⟩
  · apply ωSup_le_ωSup_of_le _
    intro i
    exists i.succ
    rfl
#align part.fix_eq Part.fix_eq

end Part

namespace Part

/- warning: part.to_unit_mono -> Part.toUnitMono is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}}, (OrderHom.{u1, u1} (Part.{u1} α) (Part.{u1} α) (PartialOrder.toPreorder.{u1} (Part.{u1} α) (Part.partialOrder.{u1} α)) (PartialOrder.toPreorder.{u1} (Part.{u1} α) (Part.partialOrder.{u1} α))) -> (OrderHom.{u1, u1} (Unit -> (Part.{u1} α)) (Unit -> (Part.{u1} α)) (Pi.preorder.{0, u1} Unit (fun (ᾰ : Unit) => Part.{u1} α) (fun (i : Unit) => PartialOrder.toPreorder.{u1} (Part.{u1} α) (Part.partialOrder.{u1} α))) (Pi.preorder.{0, u1} Unit (fun (ᾰ : Unit) => Part.{u1} α) (fun (i : Unit) => PartialOrder.toPreorder.{u1} (Part.{u1} α) (Part.partialOrder.{u1} α))))
but is expected to have type
  forall {α : Type.{u1}}, (OrderHom.{u1, u1} (Part.{u1} α) (Part.{u1} α) (PartialOrder.toPreorder.{u1} (Part.{u1} α) (Part.instPartialOrderPart.{u1} α)) (PartialOrder.toPreorder.{u1} (Part.{u1} α) (Part.instPartialOrderPart.{u1} α))) -> (OrderHom.{u1, u1} (Unit -> (Part.{u1} α)) (Unit -> (Part.{u1} α)) (Pi.preorder.{0, u1} Unit (fun (ᾰ : Unit) => Part.{u1} α) (fun (i : Unit) => PartialOrder.toPreorder.{u1} (Part.{u1} α) (Part.instPartialOrderPart.{u1} α))) (Pi.preorder.{0, u1} Unit (fun (ᾰ : Unit) => Part.{u1} α) (fun (i : Unit) => PartialOrder.toPreorder.{u1} (Part.{u1} α) (Part.instPartialOrderPart.{u1} α))))
Case conversion may be inaccurate. Consider using '#align part.to_unit_mono Part.toUnitMonoₓ'. -/
/-- `to_unit` as a monotone function -/
@[simps]
def toUnitMono (f : Part α →o Part α) : (Unit → Part α) →o Unit → Part α
    where
  toFun x u := f (x u)
  monotone' x y (h : x ≤ y) u := f.Monotone <| h u
#align part.to_unit_mono Part.toUnitMono

/- warning: part.to_unit_cont -> Part.to_unit_cont is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} (f : OrderHom.{u1, u1} (Part.{u1} α) (Part.{u1} α) (PartialOrder.toPreorder.{u1} (Part.{u1} α) (Part.partialOrder.{u1} α)) (PartialOrder.toPreorder.{u1} (Part.{u1} α) (Part.partialOrder.{u1} α))), (OmegaCompletePartialOrder.Continuous.{u1, u1} (Part.{u1} α) (Part.{u1} α) (Part.omegaCompletePartialOrder.{u1} α) (Part.omegaCompletePartialOrder.{u1} α) f) -> (OmegaCompletePartialOrder.Continuous.{u1, u1} (Unit -> (Part.{u1} α)) (Unit -> (Part.{u1} α)) (Pi.omegaCompletePartialOrder.{0, u1} Unit (fun (ᾰ : Unit) => Part.{u1} α) (fun (a : Unit) => Part.omegaCompletePartialOrder.{u1} α)) (Pi.omegaCompletePartialOrder.{0, u1} Unit (fun (ᾰ : Unit) => Part.{u1} α) (fun (a : Unit) => Part.omegaCompletePartialOrder.{u1} α)) (Part.toUnitMono.{u1} α f))
but is expected to have type
  forall {α : Type.{u1}} (f : OrderHom.{u1, u1} (Part.{u1} α) (Part.{u1} α) (PartialOrder.toPreorder.{u1} (Part.{u1} α) (Part.instPartialOrderPart.{u1} α)) (PartialOrder.toPreorder.{u1} (Part.{u1} α) (Part.instPartialOrderPart.{u1} α))), (OmegaCompletePartialOrder.Continuous.{u1, u1} (Part.{u1} α) (Part.{u1} α) (Part.omegaCompletePartialOrder.{u1} α) (Part.omegaCompletePartialOrder.{u1} α) f) -> (OmegaCompletePartialOrder.Continuous.{u1, u1} (Unit -> (Part.{u1} α)) (Unit -> (Part.{u1} α)) (Pi.instOmegaCompletePartialOrderForAll.{0, u1} Unit (fun (ᾰ : Unit) => Part.{u1} α) (fun (a : Unit) => Part.omegaCompletePartialOrder.{u1} α)) (Pi.instOmegaCompletePartialOrderForAll.{0, u1} Unit (fun (ᾰ : Unit) => Part.{u1} α) (fun (a : Unit) => Part.omegaCompletePartialOrder.{u1} α)) (Part.toUnitMono.{u1} α f))
Case conversion may be inaccurate. Consider using '#align part.to_unit_cont Part.to_unit_contₓ'. -/
theorem to_unit_cont (f : Part α →o Part α) (hc : Continuous f) : Continuous (toUnitMono f)
  | c => by
    ext ⟨⟩ : 1
    dsimp [OmegaCompletePartialOrder.ωSup]
    erw [hc, chain.map_comp]; rfl
#align part.to_unit_cont Part.to_unit_cont

instance : LawfulFix (Part α) :=
  ⟨fun f hc => show Part.fix (toUnitMono f) () = _ by rw [Part.fix_eq (to_unit_cont f hc)] <;> rfl⟩

end Part

open Sigma

namespace Pi

instance {β} : LawfulFix (α → Part β) :=
  ⟨fun f => Part.fix_eq⟩

variable {γ : ∀ a : α, β a → Type _}

section Monotone

variable (α β γ)

#print Pi.monotoneCurry /-
/-- `sigma.curry` as a monotone function. -/
@[simps]
def monotoneCurry [∀ x y, Preorder <| γ x y] : (∀ x : Σa, β a, γ x.1 x.2) →o ∀ (a) (b : β a), γ a b
    where
  toFun := curry
  monotone' x y h a b := h ⟨a, b⟩
#align pi.monotone_curry Pi.monotoneCurry
-/

#print Pi.monotoneUncurry /-
/-- `sigma.uncurry` as a monotone function. -/
@[simps]
def monotoneUncurry [∀ x y, Preorder <| γ x y] :
    (∀ (a) (b : β a), γ a b) →o ∀ x : Σa, β a, γ x.1 x.2
    where
  toFun := uncurry
  monotone' x y h a := h a.1 a.2
#align pi.monotone_uncurry Pi.monotoneUncurry
-/

variable [∀ x y, OmegaCompletePartialOrder <| γ x y]

open OmegaCompletePartialOrder.Chain

/- warning: pi.continuous_curry -> Pi.continuous_curry is a dubious translation:
lean 3 declaration is
  forall (α : Type.{u1}) (β : α -> Type.{u2}) (γ : forall (a : α), (β a) -> Type.{u3}) [_inst_1 : forall (x : α) (y : β x), OmegaCompletePartialOrder.{u3} (γ x y)], OmegaCompletePartialOrder.Continuous.{max (max u1 u2) u3, max u1 u2 u3} (forall (x : Sigma.{u1, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (forall (a : α) (b : β a), γ a b) (Pi.omegaCompletePartialOrder.{max u1 u2, u3} (Sigma.{u1, u2} α (fun (a : α) => β a)) (fun (x : Sigma.{u1, u2} α (fun (a : α) => β a)) => γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (fun (a : Sigma.{u1, u2} α (fun (a : α) => β a)) => _inst_1 (Sigma.fst.{u1, u2} α (fun (a : α) => β a) a) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) a))) (Pi.omegaCompletePartialOrder.{u1, max u2 u3} α (fun (a : α) => forall (b : β a), γ a b) (fun (a : α) => Pi.omegaCompletePartialOrder.{u2, u3} (β a) (fun (b : β a) => γ a b) (fun (a_1 : β a) => _inst_1 a a_1))) (Pi.monotoneCurry.{u1, u2, u3} α β γ (fun (x : α) (y : β x) => PartialOrder.toPreorder.{u3} (γ x y) (OmegaCompletePartialOrder.toPartialOrder.{u3} (γ x y) (_inst_1 x y))))
but is expected to have type
  forall (α : Type.{u3}) (β : α -> Type.{u2}) (γ : forall (a : α), (β a) -> Type.{u1}) [_inst_1 : forall (x : α) (y : β x), OmegaCompletePartialOrder.{u1} (γ x y)], OmegaCompletePartialOrder.Continuous.{max (max u3 u2) u1, max (max u3 u2) u1} (forall (x : Sigma.{u3, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (forall (a : α) (b : β a), γ a b) (Pi.instOmegaCompletePartialOrderForAll.{max u3 u2, u1} (Sigma.{u3, u2} α (fun (a : α) => β a)) (fun (x : Sigma.{u3, u2} α (fun (a : α) => β a)) => γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (fun (a : Sigma.{u3, u2} α (fun (a : α) => β a)) => _inst_1 (Sigma.fst.{u3, u2} α (fun (a : α) => β a) a) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) a))) (Pi.instOmegaCompletePartialOrderForAll.{u3, max u2 u1} α (fun (a : α) => forall (b : β a), γ a b) (fun (a : α) => Pi.instOmegaCompletePartialOrderForAll.{u2, u1} (β a) (fun (b : β a) => γ a b) (fun (a_1 : β a) => _inst_1 a a_1))) (Pi.monotoneCurry.{u3, u2, u1} α β γ (fun (x : α) (y : β x) => PartialOrder.toPreorder.{u1} (γ x y) (OmegaCompletePartialOrder.toPartialOrder.{u1} (γ x y) (_inst_1 x y))))
Case conversion may be inaccurate. Consider using '#align pi.continuous_curry Pi.continuous_curryₓ'. -/
theorem continuous_curry : Continuous <| monotoneCurry α β γ := fun c =>
  by
  ext (x y)
  dsimp [curry, ωSup]
  rw [map_comp, map_comp]
  rfl
#align pi.continuous_curry Pi.continuous_curry

/- warning: pi.continuous_uncurry -> Pi.continuous_uncurry is a dubious translation:
lean 3 declaration is
  forall (α : Type.{u1}) (β : α -> Type.{u2}) (γ : forall (a : α), (β a) -> Type.{u3}) [_inst_1 : forall (x : α) (y : β x), OmegaCompletePartialOrder.{u3} (γ x y)], OmegaCompletePartialOrder.Continuous.{max u1 u2 u3, max (max u1 u2) u3} (forall (a : α) (b : β a), γ a b) (forall (x : Sigma.{u1, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (Pi.omegaCompletePartialOrder.{u1, max u2 u3} α (fun (a : α) => forall (b : β a), γ a b) (fun (a : α) => Pi.omegaCompletePartialOrder.{u2, u3} (β a) (fun (b : β a) => γ a b) (fun (a_1 : β a) => _inst_1 a a_1))) (Pi.omegaCompletePartialOrder.{max u1 u2, u3} (Sigma.{u1, u2} α (fun (a : α) => β a)) (fun (x : Sigma.{u1, u2} α (fun (a : α) => β a)) => γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (fun (a : Sigma.{u1, u2} α (fun (a : α) => β a)) => _inst_1 (Sigma.fst.{u1, u2} α (fun (a : α) => β a) a) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) a))) (Pi.monotoneUncurry.{u1, u2, u3} α β γ (fun (x : α) (y : β x) => PartialOrder.toPreorder.{u3} (γ x y) (OmegaCompletePartialOrder.toPartialOrder.{u3} (γ x y) (_inst_1 x y))))
but is expected to have type
  forall (α : Type.{u3}) (β : α -> Type.{u2}) (γ : forall (a : α), (β a) -> Type.{u1}) [_inst_1 : forall (x : α) (y : β x), OmegaCompletePartialOrder.{u1} (γ x y)], OmegaCompletePartialOrder.Continuous.{max (max u3 u2) u1, max (max u3 u2) u1} (forall (a : α) (b : β a), γ a b) (forall (x : Sigma.{u3, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (Pi.instOmegaCompletePartialOrderForAll.{u3, max u2 u1} α (fun (a : α) => forall (b : β a), γ a b) (fun (a : α) => Pi.instOmegaCompletePartialOrderForAll.{u2, u1} (β a) (fun (b : β a) => γ a b) (fun (a_1 : β a) => _inst_1 a a_1))) (Pi.instOmegaCompletePartialOrderForAll.{max u3 u2, u1} (Sigma.{u3, u2} α (fun (a : α) => β a)) (fun (x : Sigma.{u3, u2} α (fun (a : α) => β a)) => γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (fun (a : Sigma.{u3, u2} α (fun (a : α) => β a)) => _inst_1 (Sigma.fst.{u3, u2} α (fun (a : α) => β a) a) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) a))) (Pi.monotoneUncurry.{u3, u2, u1} α β γ (fun (x : α) (y : β x) => PartialOrder.toPreorder.{u1} (γ x y) (OmegaCompletePartialOrder.toPartialOrder.{u1} (γ x y) (_inst_1 x y))))
Case conversion may be inaccurate. Consider using '#align pi.continuous_uncurry Pi.continuous_uncurryₓ'. -/
theorem continuous_uncurry : Continuous <| monotoneUncurry α β γ := fun c =>
  by
  ext (x y)
  dsimp [uncurry, ωSup]
  rw [map_comp, map_comp]
  rfl
#align pi.continuous_uncurry Pi.continuous_uncurry

end Monotone

open Fix

instance [Fix <| ∀ x : Sigma β, γ x.1 x.2] : Fix (∀ (x) (y : β x), γ x y) :=
  ⟨fun f => curry (fix <| uncurry ∘ f ∘ curry)⟩

variable [∀ x y, OmegaCompletePartialOrder <| γ x y]

section Curry

variable {f : (∀ (x) (y : β x), γ x y) →o ∀ (x) (y : β x), γ x y}

variable (hc : Continuous f)

/- warning: pi.uncurry_curry_continuous -> Pi.uncurry_curry_continuous is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} {β : α -> Type.{u2}} {γ : forall (a : α), (β a) -> Type.{u3}} [_inst_1 : forall (x : α) (y : β x), OmegaCompletePartialOrder.{u3} (γ x y)] {f : OrderHom.{max u1 u2 u3, max u1 u2 u3} (forall (x : α) (y : β x), γ x y) (forall (x : α) (y : β x), γ x y) (Pi.preorder.{u1, max u2 u3} α (fun (x : α) => forall (y : β x), γ x y) (fun (i : α) => Pi.preorder.{u2, u3} (β i) (fun (y : β i) => γ i y) (fun (i_1 : β i) => PartialOrder.toPreorder.{u3} (γ i i_1) (OmegaCompletePartialOrder.toPartialOrder.{u3} (γ i i_1) (_inst_1 i i_1))))) (Pi.preorder.{u1, max u2 u3} α (fun (x : α) => forall (y : β x), γ x y) (fun (i : α) => Pi.preorder.{u2, u3} (β i) (fun (y : β i) => γ i y) (fun (i_1 : β i) => PartialOrder.toPreorder.{u3} (γ i i_1) (OmegaCompletePartialOrder.toPartialOrder.{u3} (γ i i_1) (_inst_1 i i_1)))))}, (OmegaCompletePartialOrder.Continuous.{max u1 u2 u3, max u1 u2 u3} (forall (x : α) (y : β x), γ x y) (forall (x : α) (y : β x), γ x y) (Pi.omegaCompletePartialOrder.{u1, max u2 u3} α (fun (x : α) => forall (y : β x), γ x y) (fun (a : α) => Pi.omegaCompletePartialOrder.{u2, u3} (β a) (fun (y : β a) => γ a y) (fun (a_1 : β a) => _inst_1 a a_1))) (Pi.omegaCompletePartialOrder.{u1, max u2 u3} α (fun (x : α) => forall (y : β x), γ x y) (fun (a : α) => Pi.omegaCompletePartialOrder.{u2, u3} (β a) (fun (y : β a) => γ a y) (fun (a_1 : β a) => _inst_1 a a_1))) f) -> (OmegaCompletePartialOrder.Continuous.{max (max u1 u2) u3, max (max u1 u2) u3} (forall (x : Sigma.{u1, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (forall (x : Sigma.{u1, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (Pi.omegaCompletePartialOrder.{max u1 u2, u3} (Sigma.{u1, u2} α (fun (a : α) => β a)) (fun (x : Sigma.{u1, u2} α (fun (a : α) => β a)) => γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (fun (a : Sigma.{u1, u2} α (fun (a : α) => β a)) => _inst_1 (Sigma.fst.{u1, u2} α (fun (a : α) => β a) a) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) a))) (Pi.omegaCompletePartialOrder.{max u1 u2, u3} (Sigma.{u1, u2} α (fun (a : α) => β a)) (fun (x : Sigma.{u1, u2} α (fun (a : α) => β a)) => γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (fun (a : Sigma.{u1, u2} α (fun (a : α) => β a)) => _inst_1 (Sigma.fst.{u1, u2} α (fun (a : α) => β a) a) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) a))) (OrderHom.comp.{max (max u1 u2) u3, max u1 u2 u3, max (max u1 u2) u3} (forall (x : Sigma.{u1, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (forall (a : α) (b : β a), γ a b) (forall (x : Sigma.{u1, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (PartialOrder.toPreorder.{max (max u1 u2) u3} (forall (x : Sigma.{u1, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (OmegaCompletePartialOrder.toPartialOrder.{max (max u1 u2) u3} (forall (x : Sigma.{u1, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (Pi.omegaCompletePartialOrder.{max u1 u2, u3} (Sigma.{u1, u2} α (fun (a : α) => β a)) (fun (x : Sigma.{u1, u2} α (fun (a : α) => β a)) => γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (fun (a : Sigma.{u1, u2} α (fun (a : α) => β a)) => _inst_1 (Sigma.fst.{u1, u2} α (fun (a : α) => β a) a) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) a))))) (Pi.preorder.{u1, max u2 u3} α (fun (a : α) => forall (b : β a), γ a b) (fun (i : α) => Pi.preorder.{u2, u3} (β i) (fun (b : β i) => γ i b) (fun (i_1 : β i) => (fun (x : α) (y : β x) => PartialOrder.toPreorder.{u3} (γ x y) (OmegaCompletePartialOrder.toPartialOrder.{u3} (γ x y) (_inst_1 x y))) i i_1))) (Pi.preorder.{max u1 u2, u3} (Sigma.{u1, u2} α (fun (a : α) => β a)) (fun (x : Sigma.{u1, u2} α (fun (a : α) => β a)) => γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (fun (i : Sigma.{u1, u2} α (fun (a : α) => β a)) => (fun (x : α) (y : β x) => PartialOrder.toPreorder.{u3} (γ x y) (OmegaCompletePartialOrder.toPartialOrder.{u3} (γ x y) (_inst_1 x y))) (Sigma.fst.{u1, u2} α (fun (a : α) => β a) i) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) i))) (Pi.monotoneUncurry.{u1, u2, u3} α β γ (fun (x : α) (y : β x) => PartialOrder.toPreorder.{u3} (γ x y) (OmegaCompletePartialOrder.toPartialOrder.{u3} (γ x y) (_inst_1 x y)))) (OrderHom.comp.{max (max u1 u2) u3, max u1 u2 u3, max u1 u2 u3} (forall (x : Sigma.{u1, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (forall (x : α) (y : β x), γ x y) (forall (x : α) (y : β x), γ x y) (PartialOrder.toPreorder.{max (max u1 u2) u3} (forall (x : Sigma.{u1, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (OmegaCompletePartialOrder.toPartialOrder.{max (max u1 u2) u3} (forall (x : Sigma.{u1, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (Pi.omegaCompletePartialOrder.{max u1 u2, u3} (Sigma.{u1, u2} α (fun (a : α) => β a)) (fun (x : Sigma.{u1, u2} α (fun (a : α) => β a)) => γ (Sigma.fst.{u1, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) x)) (fun (a : Sigma.{u1, u2} α (fun (a : α) => β a)) => _inst_1 (Sigma.fst.{u1, u2} α (fun (a : α) => β a) a) (Sigma.snd.{u1, u2} α (fun (a : α) => β a) a))))) (Pi.preorder.{u1, max u2 u3} α (fun (x : α) => forall (y : β x), γ x y) (fun (i : α) => Pi.preorder.{u2, u3} (β i) (fun (y : β i) => γ i y) (fun (i_1 : β i) => PartialOrder.toPreorder.{u3} (γ i i_1) (OmegaCompletePartialOrder.toPartialOrder.{u3} (γ i i_1) (_inst_1 i i_1))))) (Pi.preorder.{u1, max u2 u3} α (fun (x : α) => forall (y : β x), γ x y) (fun (i : α) => Pi.preorder.{u2, u3} (β i) (fun (y : β i) => γ i y) (fun (i_1 : β i) => PartialOrder.toPreorder.{u3} (γ i i_1) (OmegaCompletePartialOrder.toPartialOrder.{u3} (γ i i_1) (_inst_1 i i_1))))) f (Pi.monotoneCurry.{u1, u2, u3} α β γ (fun (x : α) (y : β x) => PartialOrder.toPreorder.{u3} (γ x y) (OmegaCompletePartialOrder.toPartialOrder.{u3} (γ x y) (_inst_1 x y)))))))
but is expected to have type
  forall {α : Type.{u3}} {β : α -> Type.{u2}} {γ : forall (a : α), (β a) -> Type.{u1}} [_inst_1 : forall (x : α) (y : β x), OmegaCompletePartialOrder.{u1} (γ x y)] {f : OrderHom.{max (max u3 u2) u1, max (max u3 u2) u1} (forall (x : α) (y : β x), γ x y) (forall (x : α) (y : β x), γ x y) (Pi.preorder.{u3, max u2 u1} α (fun (x : α) => forall (y : β x), γ x y) (fun (i : α) => Pi.preorder.{u2, u1} (β i) (fun (y : β i) => γ i y) (fun (i_1 : β i) => PartialOrder.toPreorder.{u1} (γ i i_1) (OmegaCompletePartialOrder.toPartialOrder.{u1} (γ i i_1) (_inst_1 i i_1))))) (Pi.preorder.{u3, max u2 u1} α (fun (x : α) => forall (y : β x), γ x y) (fun (i : α) => Pi.preorder.{u2, u1} (β i) (fun (y : β i) => γ i y) (fun (i_1 : β i) => PartialOrder.toPreorder.{u1} (γ i i_1) (OmegaCompletePartialOrder.toPartialOrder.{u1} (γ i i_1) (_inst_1 i i_1)))))}, (OmegaCompletePartialOrder.Continuous.{max (max u3 u2) u1, max (max u3 u2) u1} (forall (x : α) (y : β x), γ x y) (forall (x : α) (y : β x), γ x y) (Pi.instOmegaCompletePartialOrderForAll.{u3, max u2 u1} α (fun (x : α) => forall (y : β x), γ x y) (fun (a : α) => Pi.instOmegaCompletePartialOrderForAll.{u2, u1} (β a) (fun (y : β a) => γ a y) (fun (a_1 : β a) => _inst_1 a a_1))) (Pi.instOmegaCompletePartialOrderForAll.{u3, max u2 u1} α (fun (x : α) => forall (y : β x), γ x y) (fun (a : α) => Pi.instOmegaCompletePartialOrderForAll.{u2, u1} (β a) (fun (y : β a) => γ a y) (fun (a_1 : β a) => _inst_1 a a_1))) f) -> (OmegaCompletePartialOrder.Continuous.{max (max u3 u2) u1, max (max u3 u2) u1} (forall (x : Sigma.{u3, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (forall (x : Sigma.{u3, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (Pi.instOmegaCompletePartialOrderForAll.{max u3 u2, u1} (Sigma.{u3, u2} α (fun (a : α) => β a)) (fun (x : Sigma.{u3, u2} α (fun (a : α) => β a)) => γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (fun (a : Sigma.{u3, u2} α (fun (a : α) => β a)) => _inst_1 (Sigma.fst.{u3, u2} α (fun (a : α) => β a) a) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) a))) (Pi.instOmegaCompletePartialOrderForAll.{max u3 u2, u1} (Sigma.{u3, u2} α (fun (a : α) => β a)) (fun (x : Sigma.{u3, u2} α (fun (a : α) => β a)) => γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (fun (a : Sigma.{u3, u2} α (fun (a : α) => β a)) => _inst_1 (Sigma.fst.{u3, u2} α (fun (a : α) => β a) a) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) a))) (OrderHom.comp.{max (max u3 u2) u1, max (max u3 u2) u1, max (max u3 u2) u1} (forall (x : Sigma.{u3, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (forall (a : α) (b : β a), γ a b) (forall (x : Sigma.{u3, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (PartialOrder.toPreorder.{max (max u3 u2) u1} (forall (x : Sigma.{u3, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (OmegaCompletePartialOrder.toPartialOrder.{max (max u3 u2) u1} (forall (x : Sigma.{u3, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (Pi.instOmegaCompletePartialOrderForAll.{max u3 u2, u1} (Sigma.{u3, u2} α (fun (a : α) => β a)) (fun (x : Sigma.{u3, u2} α (fun (a : α) => β a)) => γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (fun (a : Sigma.{u3, u2} α (fun (a : α) => β a)) => _inst_1 (Sigma.fst.{u3, u2} α (fun (a : α) => β a) a) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) a))))) (Pi.preorder.{u3, max u2 u1} α (fun (a : α) => forall (b : β a), γ a b) (fun (i : α) => Pi.preorder.{u2, u1} (β i) (fun (b : β i) => γ i b) (fun (i_1 : β i) => PartialOrder.toPreorder.{u1} (γ i i_1) (OmegaCompletePartialOrder.toPartialOrder.{u1} (γ i i_1) (_inst_1 i i_1))))) (Pi.preorder.{max u3 u2, u1} (Sigma.{u3, u2} α (fun (a : α) => β a)) (fun (x : Sigma.{u3, u2} α (fun (a : α) => β a)) => γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (fun (i : Sigma.{u3, u2} α (fun (a : α) => β a)) => PartialOrder.toPreorder.{u1} (γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) i) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) i)) (OmegaCompletePartialOrder.toPartialOrder.{u1} (γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) i) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) i)) (_inst_1 (Sigma.fst.{u3, u2} α (fun (a : α) => β a) i) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) i))))) (Pi.monotoneUncurry.{u3, u2, u1} α β γ (fun (x : α) (y : β x) => PartialOrder.toPreorder.{u1} (γ x y) (OmegaCompletePartialOrder.toPartialOrder.{u1} (γ x y) (_inst_1 x y)))) (OrderHom.comp.{max (max u3 u2) u1, max (max u3 u2) u1, max (max u3 u2) u1} (forall (x : Sigma.{u3, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (forall (x : α) (y : β x), γ x y) (forall (x : α) (y : β x), γ x y) (PartialOrder.toPreorder.{max (max u3 u2) u1} (forall (x : Sigma.{u3, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (OmegaCompletePartialOrder.toPartialOrder.{max (max u3 u2) u1} (forall (x : Sigma.{u3, u2} α (fun (a : α) => β a)), γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (Pi.instOmegaCompletePartialOrderForAll.{max u3 u2, u1} (Sigma.{u3, u2} α (fun (a : α) => β a)) (fun (x : Sigma.{u3, u2} α (fun (a : α) => β a)) => γ (Sigma.fst.{u3, u2} α (fun (a : α) => β a) x) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) x)) (fun (a : Sigma.{u3, u2} α (fun (a : α) => β a)) => _inst_1 (Sigma.fst.{u3, u2} α (fun (a : α) => β a) a) (Sigma.snd.{u3, u2} α (fun (a : α) => β a) a))))) (Pi.preorder.{u3, max u2 u1} α (fun (x : α) => forall (y : β x), γ x y) (fun (i : α) => Pi.preorder.{u2, u1} (β i) (fun (y : β i) => γ i y) (fun (i_1 : β i) => PartialOrder.toPreorder.{u1} (γ i i_1) (OmegaCompletePartialOrder.toPartialOrder.{u1} (γ i i_1) (_inst_1 i i_1))))) (Pi.preorder.{u3, max u2 u1} α (fun (x : α) => forall (y : β x), γ x y) (fun (i : α) => Pi.preorder.{u2, u1} (β i) (fun (y : β i) => γ i y) (fun (i_1 : β i) => PartialOrder.toPreorder.{u1} (γ i i_1) (OmegaCompletePartialOrder.toPartialOrder.{u1} (γ i i_1) (_inst_1 i i_1))))) f (Pi.monotoneCurry.{u3, u2, u1} α β γ (fun (x : α) (y : β x) => PartialOrder.toPreorder.{u1} (γ x y) (OmegaCompletePartialOrder.toPartialOrder.{u1} (γ x y) (_inst_1 x y)))))))
Case conversion may be inaccurate. Consider using '#align pi.uncurry_curry_continuous Pi.uncurry_curry_continuousₓ'. -/
theorem uncurry_curry_continuous :
    Continuous <| (monotoneUncurry α β γ).comp <| f.comp <| monotoneCurry α β γ :=
  continuous_comp _ _ (continuous_comp _ _ (continuous_curry _ _ _) hc) (continuous_uncurry _ _ _)
#align pi.uncurry_curry_continuous Pi.uncurry_curry_continuous

end Curry

#print Pi.Pi.lawfulFix' /-
instance Pi.lawfulFix' [LawfulFix <| ∀ x : Sigma β, γ x.1 x.2] : LawfulFix (∀ x y, γ x y)
    where fix_eq f hc := by
    dsimp [fix]
    conv =>
      lhs
      erw [LawfulFix.fix_eq (uncurry_curry_continuous hc)]
    rfl
#align pi.pi.lawful_fix' Pi.Pi.lawfulFix'
-/

end Pi


/-
Copyright (c) 2020 Simon Hudon. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author(s): Simon Hudon
-/
import Mathlib.PrePort
import Mathlib.Lean3Lib.init.default
import Mathlib.data.bitvec.core
import Mathlib.data.fin
import Mathlib.tactic.norm_num
import Mathlib.tactic.monotonicity.default
import Mathlib.PostPort

namespace Mathlib

namespace bitvec

protected instance preorder (n : ℕ) : preorder (bitvec n) := preorder.lift bitvec.to_nat

/-- convert `fin` to `bitvec` -/
def of_fin {n : ℕ} (i : fin (bit0 1 ^ n)) : bitvec n := bitvec.of_nat n (subtype.val i)

theorem of_fin_val {n : ℕ} (i : fin (bit0 1 ^ n)) : bitvec.to_nat (of_fin i) = subtype.val i :=
  sorry

/-- convert `bitvec` to `fin` -/
def to_fin {n : ℕ} (i : bitvec n) : fin (bit0 1 ^ n) := fin.of_nat' (bitvec.to_nat i)

theorem add_lsb_eq_twice_add_one {x : ℕ} {b : Bool} : add_lsb x b = bit0 1 * x + cond b 1 0 := sorry

theorem to_nat_eq_foldr_reverse {n : ℕ} (v : bitvec n) :
    bitvec.to_nat v = list.foldr (flip add_lsb) 0 (list.reverse (vector.to_list v)) :=
  sorry

theorem to_nat_lt {n : ℕ} (v : bitvec n) : bitvec.to_nat v < bit0 1 ^ n := sorry

theorem add_lsb_div_two {x : ℕ} {b : Bool} : add_lsb x b / bit0 1 = x := sorry

theorem to_bool_add_lsb_mod_two {x : ℕ} {b : Bool} : to_bool (add_lsb x b % bit0 1 = 1) = b := sorry

theorem of_nat_to_nat {n : ℕ} (v : bitvec n) : bitvec.of_nat n (bitvec.to_nat v) = v := sorry

theorem to_fin_val {n : ℕ} (v : bitvec n) : ↑(to_fin v) = bitvec.to_nat v := sorry

theorem to_fin_le_to_fin_of_le {n : ℕ} {v₀ : bitvec n} {v₁ : bitvec n} (h : v₀ ≤ v₁) :
    to_fin v₀ ≤ to_fin v₁ :=
  (fun (this : ↑(to_fin v₀) ≤ ↑(to_fin v₁)) => this)
    (eq.mpr (id (Eq._oldrec (Eq.refl (↑(to_fin v₀) ≤ ↑(to_fin v₁))) (to_fin_val v₀)))
      (eq.mpr (id (Eq._oldrec (Eq.refl (bitvec.to_nat v₀ ≤ ↑(to_fin v₁))) (to_fin_val v₁))) h))

theorem of_fin_le_of_fin_of_le {n : ℕ} {i : fin (bit0 1 ^ n)} {j : fin (bit0 1 ^ n)} (h : i ≤ j) :
    of_fin i ≤ of_fin j :=
  sorry

theorem to_fin_of_fin {n : ℕ} (i : fin (bit0 1 ^ n)) : to_fin (of_fin i) = i := sorry

theorem of_fin_to_fin {n : ℕ} (v : bitvec n) : of_fin (to_fin v) = v :=
  id
    (eq.mpr (id (Eq._oldrec (Eq.refl (bitvec.of_nat n ↑(to_fin v) = v)) (to_fin_val v)))
      (eq.mpr (id (Eq._oldrec (Eq.refl (bitvec.of_nat n (bitvec.to_nat v) = v)) (of_nat_to_nat v)))
        (Eq.refl v)))

end Mathlib