Built with doc-gen4, running Lean4. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓to navigate, Ctrl+🖱️to focus. On Mac, use Cmdinstead of Ctrl.
/-
Copyright (c) 2018 Mario Carneiro. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mario Carneiro

! This file was ported from Lean 3 source module logic.equiv.list
! leanprover-community/mathlib commit d11893b411025250c8e61ff2f12ccbd7ee35ab15
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathlib.Data.Finset.Sort
import Mathlib.Data.Vector.Basic
import Mathlib.Logic.Denumerable

/-!
# Equivalences involving `List`-like types

This file defines some additional constructive equivalences using `Encodable` and the pairing
function on `ℕ`.
-/


open Nat List

namespace Encodable

variable {
α: Type ?u.14774
α
:
Type _: Type (?u.12538+1)
Type _
} section List variable [
Encodable: Type ?u.356 → Type ?u.356
Encodable
α: Type ?u.9744
α
] /-- Explicit encoding function for `List α` -/ def
encodeList: List α
encodeList
:
List: Type ?u.18 → Type ?u.18
List
α: Type ?u.11
α
: Type
| [] =>
0: ?m.35
0
|
a: α
a
::
l: List α
l
=>
succ:
succ
(
pair:
pair
(
encode: {α : Type ?u.65} → [self : Encodable α] → α
encode
a: α
a
) (
encodeList: List α
encodeList
l: List α
l
)) #align encodable.encode_list
Encodable.encodeList: {α : Type u_1} → [inst : Encodable α] → List α
Encodable.encodeList
/-- Explicit decoding function for `List α` -/ def
decodeList: Option (List α)
decodeList
:
: Type
Option: Type ?u.361 → Type ?u.361
Option
(
List: Type ?u.362 → Type ?u.362
List
α: Type ?u.353
α
) |
0:
0
=>
some: {α : Type ?u.382} → αOption α
some
[]: List ?m.386
[]
|
succ:
succ
v:
v
=> match
unpair: ×
unpair
v:
v
,
unpair_right_le: ∀ (n : ), (unpair n).snd n
unpair_right_le
v:
v
with | (
v₁:
v₁
,
v₂:
v₂
),
h: (v₁, v₂).snd v
h
=> have :
v₂:
v₂
<
succ:
succ
v:
v
:=
lt_succ_of_le: ∀ {n m : }, n mn < succ m
lt_succ_of_le
h: (v₁, v₂).snd v
h
(· :: ·): αList αList α
(· :: ·)
<$>
decode: {α : Type ?u.510} → [self : Encodable α] → Option α
decode
(α :=
α: Type ?u.353
α
)
v₁:
v₁
<*>
decodeList: Option (List α)
decodeList
v₂:
v₂
#align encodable.decode_list
Encodable.decodeList: {α : Type u_1} → [inst : Encodable α] → Option (List α)
Encodable.decodeList
/-- If `α` is encodable, then so is `List α`. This uses the `pair` and `unpair` functions from `Data.Nat.Pairing`. -/ instance
_root_.List.encodable: {α : Type u_1} → [inst : Encodable α] → Encodable (List α)
_root_.List.encodable
:
Encodable: Type ?u.7044 → Type ?u.7044
Encodable
(
List: Type ?u.7045 → Type ?u.7045
List
α: Type ?u.7038
α
) := ⟨
encodeList: {α : Type ?u.7054} → [inst : Encodable α] → List α
encodeList
,
decodeList: {α : Type ?u.7082} → [inst : Encodable α] → Option (List α)
decodeList
, fun
l: ?m.7107
l
=>

Goals accomplished! 🐙
α: Type ?u.7038

inst✝: Encodable α

l: List α


α: Type ?u.7038

inst✝: Encodable α


nil
α: Type ?u.7038

inst✝: Encodable α

a: α

l: List α

IH: decodeList (encodeList l) = some l


cons
α: Type ?u.7038

inst✝: Encodable α

l: List α


α: Type ?u.7038

inst✝: Encodable α


nil
α: Type ?u.7038

inst✝: Encodable α

a: α

l: List α

IH: decodeList (encodeList l) = some l


cons
α: Type ?u.7038

inst✝: Encodable α

l: List α



Goals accomplished! 🐙
#align list.encodable
List.encodable: {α : Type u_1} → [inst : Encodable α] → Encodable (List α)
List.encodable
instance
_root_.List.countable: ∀ {α : Type ?u.9222} [inst : Countable α], Countable (List α)
_root_.List.countable
{
α: Type ?u.9222
α
:
Type _: Type (?u.9222+1)
Type _
} [
Countable: Sort ?u.9225 → Prop
Countable
α: Type ?u.9222
α
] :
Countable: Sort ?u.9228 → Prop
Countable
(
List: Type ?u.9229 → Type ?u.9229
List
α: Type ?u.9222
α
) :=

Goals accomplished! 🐙
α✝: Type ?u.9216

inst✝¹: Encodable α✝

α: Type ?u.9222

inst✝: Countable α


α✝: Type ?u.9216

inst✝¹: Encodable α✝

α: Type ?u.9222

inst✝: Countable α

this: Encodable α


α✝: Type ?u.9216

inst✝¹: Encodable α✝

α: Type ?u.9222

inst✝: Countable α



Goals accomplished! 🐙
#align list.countable
List.countable: ∀ {α : Type u_1} [inst : Countable α], Countable (List α)
List.countable
@[simp] theorem
encode_list_nil: encode [] = 0
encode_list_nil
:
encode: {α : Type ?u.9289} → [self : Encodable α] → α
encode
(@
nil: {α : Type ?u.9292} → List α
nil
α: Type ?u.9282
α
) =
0: ?m.9307
0
:=
rfl: ∀ {α : Sort ?u.9332} {a : α}, a = a
rfl
#align encodable.encode_list_nil
Encodable.encode_list_nil: ∀ {α : Type u_1} [inst : Encodable α], encode [] = 0
Encodable.encode_list_nil
@[simp] theorem
encode_list_cons: ∀ {α : Type u_1} [inst : Encodable α] (a : α) (l : List α), encode (a :: l) = succ (pair (encode a) (encode l))
encode_list_cons
(
a: α
a
:
α: Type ?u.9359
α
) (
l: List α
l
:
List: Type ?u.9367 → Type ?u.9367
List
α: Type ?u.9359
α
) :
encode: {α : Type ?u.9371} → [self : Encodable α] → α
encode
(
a: α
a
::
l: List α
l
) =
succ:
succ
(
pair:
pair
(
encode: {α : Type ?u.9389} → [self : Encodable α] → α
encode
a: α
a
) (
encode: {α : Type ?u.9413} → [self : Encodable α] → α
encode
l: List α
l
)) :=
rfl: ∀ {α : Sort ?u.9438} {a : α}, a = a
rfl
#align encodable.encode_list_cons
Encodable.encode_list_cons: ∀ {α : Type u_1} [inst : Encodable α] (a : α) (l : List α), encode (a :: l) = succ (pair (encode a) (encode l))
Encodable.encode_list_cons
@[simp] theorem
decode_list_zero: decode 0 = some []
decode_list_zero
:
decode: {α : Type ?u.9482} → [self : Encodable α] → Option α
decode
(α :=
List: Type ?u.9483 → Type ?u.9483
List
α: Type ?u.9475
α
)
0: ?m.9486
0
=
some: {α : Type ?u.9508} → αOption α
some
[]: List ?m.9511
[]
:= show
decodeList: {α : Type ?u.9547} → [inst : Encodable α] → Option (List α)
decodeList
0: ?m.9551
0
=
some: {α : Type ?u.9588} → αOption α
some
[]: List ?m.9591
[]
by
α: Type u_1

inst✝: Encodable α


α: Type u_1

inst✝: Encodable α


some [] = some []

Goals accomplished! 🐙
#align encodable.decode_list_zero
Encodable.decode_list_zero: ∀ {α : Type u_1} [inst : Encodable α], decode 0 = some []
Encodable.decode_list_zero
@[simp, nolint
unusedHavesSuffices: Std.Tactic.Lint.Linter
unusedHavesSuffices
] -- Porting note: false positive theorem
decode_list_succ: ∀ (v : ), decode (succ v) = Seq.seq ((fun x x_1 => x :: x_1) <$> decode (unpair v).fst) fun x => decode (unpair v).snd
decode_list_succ
(
v:
v
:
: Type
) :
decode: {α : Type ?u.9753} → [self : Encodable α] → Option α
decode
(α :=
List: Type ?u.9754 → Type ?u.9754
List
α: Type ?u.9744
α
) (
succ:
succ
v:
v
) =
(· :: ·): αList αList α
(· :: ·)
<$>
decode: {α : Type ?u.9813} → [self : Encodable α] → Option α
decode
(α :=
α: Type ?u.9744
α
)
v:
v
.
unpair: ×
unpair
.
1: {α : Type ?u.9820} → {β : Type ?u.9819} → α × βα
1
<*>
decode: {α : Type ?u.9837} → [self : Encodable α] → Option α
decode
(α :=
List: Type ?u.9838 → Type ?u.9838
List
α: Type ?u.9744
α
)
v:
v
.
unpair: ×
unpair
.
2: {α : Type ?u.9841} → {β : Type ?u.9840} → α × ββ
2
:= show
decodeList: {α : Type ?u.9877} → [inst : Encodable α] → Option (List α)
decodeList
(
succ:
succ
v:
v
) =
_: ?m.9916
_
by
α: Type u_1

inst✝: Encodable α

v, v₁, v₂:

e: unpair v = (v₁, v₂)


mk
decodeList (succ v) = Seq.seq ((fun x x_1 => x :: x_1) <$> decode (v₁, v₂).fst) fun x => decode (v₁, v₂).snd
α: Type u_1

inst✝: Encodable α

v:


decodeList (succ v) = Seq.seq ((fun x x_1 => x :: x_1) <$> decode (unpair v).fst) fun x => decode (unpair v).snd
α: Type u_1

inst✝: Encodable α

v, v₁, v₂:

e: unpair v = (v₁, v₂)


mk
(Seq.seq (Option.map (fun x x_1 => x :: x_1) (decode v₁)) fun x => decodeList v₂) = Seq.seq (Option.map (fun x x_1 => x :: x_1) (decode v₁)) fun x => decode v₂
α: Type u_1

inst✝: Encodable α

v, v₁, v₂:

e: unpair v = (v₁, v₂)


mk
(Seq.seq (Option.map (fun x x_1 => x :: x_1) (decode v₁)) fun x => decodeList v₂) = Seq.seq (Option.map (fun x x_1 => x :: x_1) (decode v₁)) fun x => decode v₂
α: Type u_1

inst✝: Encodable α

v:


decodeList (succ v) = Seq.seq ((fun x x_1 => x :: x_1) <$> decode (unpair v).fst) fun x => decode (unpair v).snd

Goals accomplished! 🐙
#align encodable.decode_list_succ
Encodable.decode_list_succ: ∀ {α : Type u_1} [inst : Encodable α] (v : ), decode (succ v) = Seq.seq ((fun x x_1 => x :: x_1) <$> decode (unpair v).fst) fun x => decode (unpair v).snd
Encodable.decode_list_succ
theorem
length_le_encode: ∀ {α : Type u_1} [inst : Encodable α] (l : List α), length l encode l
length_le_encode
: ∀
l: List α
l
:
List: Type ?u.12545 → Type ?u.12545
List
α: Type ?u.12538
α
,
length: {α : Type ?u.12549} → List α
length
l: List α
l
encode: {α : Type ?u.12553} → [self : Encodable α] → α
encode
l: List α
l
| [] =>
Nat.zero_le: ∀ (n : ), 0 n
Nat.zero_le
_:
_
| _ ::
l: List α
l
=>
succ_le_succ: ∀ {n m : }, n msucc n succ m
succ_le_succ
<| (
length_le_encode: ∀ (l : List α), length l encode l
length_le_encode
l: List α
l
).
trans: ∀ {α : Type ?u.12637} [inst : Preorder α] {a b c : α}, a bb ca c
trans
(
right_le_pair: ∀ (a b : ), b pair a b
right_le_pair
_:
_
_:
_
) #align encodable.length_le_encode
Encodable.length_le_encode: ∀ {α : Type u_1} [inst : Encodable α] (l : List α), length l encode l
Encodable.length_le_encode
end List section Finset variable [
Encodable: Type ?u.13761 → Type ?u.13761
Encodable
α: Type ?u.13210
α
] private def
enle: {α : Type u_1} → [inst : Encodable α] → ααProp
enle
:
α: Type ?u.12884
α
α: Type ?u.12884
α
Prop: Type
Prop
:=
encode: {α : Type ?u.12903} → [self : Encodable α] → α
encode
⁻¹'o
(· ≤ ·): Prop
(· ≤ ·)
private theorem
enle.isLinearOrder: ∀ {α : Type u_1} [inst : Encodable α], IsLinearOrder α Encodable.enle
enle.isLinearOrder
:
IsLinearOrder: (α : Type ?u.12969) → (ααProp) → Prop
IsLinearOrder
α: Type ?u.12963
α
enle: {α : Type ?u.12970} → [inst : Encodable α] → ααProp
enle
:= (
RelEmbedding.preimage: {α : Type ?u.13004} → {β : Type ?u.13003} → (f : α β) → (s : ββProp) → f ⁻¹'o s ↪r s
RelEmbedding.preimage
encode: {α : Type ?u.13017} → [self : Encodable α] → α
encode
,
encode_injective: ∀ {α : Type ?u.13058} [inst : Encodable α], Function.Injective encode
encode_injective
(· ≤ ·): Prop
(· ≤ ·)
).
isLinearOrder: ∀ {α : Type ?u.13125} {β : Type ?u.13126} {r : ααProp} {s : ββProp}, r ↪r s∀ [inst : IsLinearOrder β s], IsLinearOrder α r
isLinearOrder
private def
decidable_enle: (a b : α) → Decidable (Encodable.enle a b)
decidable_enle
(
a: α
a
b: α
b
:
α: Type ?u.13210
α
) :
Decidable: PropType
Decidable
(
enle: {α : Type ?u.13220} → [inst : Encodable α] → ααProp
enle
a: α
a
b: α
b
) :=

Goals accomplished! 🐙
α: Type ?u.13210

inst✝: Encodable α

a, b: α


Decidable (Encodable.enle a b)
α: Type ?u.13210

inst✝: Encodable α

a, b: α


Decidable ((fun x x_1 => x x_1) (encode a) (encode b))
α: Type ?u.13210

inst✝: Encodable α

a, b: α


Decidable (Encodable.enle a b)

Goals accomplished! 🐙
attribute [local instance]
enle.isLinearOrder: ∀ {α : Type u_1} [inst : Encodable α], IsLinearOrder α Encodable.enle
enle.isLinearOrder
decidable_enle: {α : Type u_1} → [inst : Encodable α] → (a b : α) → Decidable (Encodable.enle a b)
decidable_enle
/-- Explicit encoding function for `Multiset α` -/ def
encodeMultiset: {α : Type u_1} → [inst : Encodable α] → Multiset α
encodeMultiset
(
s: Multiset α
s
:
Multiset: Type ?u.13342 → Type ?u.13342
Multiset
α: Type ?u.13336
α
) :
: Type
:=
encode: {α : Type ?u.13347} → [self : Encodable α] → α
encode
(
s: Multiset α
s
.
sort: {α : Type ?u.13368} → (r : ααProp) → [inst : DecidableRel r] → [inst : IsTrans α r] → [inst : IsAntisymm α r] → [inst : IsTotal α r] → Multiset αList α
sort
enle: {α : Type ?u.13379} → [inst : Encodable α] → ααProp
enle
) #align encodable.encode_multiset
Encodable.encodeMultiset: {α : Type u_1} → [inst : Encodable α] → Multiset α
Encodable.encodeMultiset
/-- Explicit decoding function for `Multiset α` -/ def
decodeMultiset: Option (Multiset α)
decodeMultiset
(
n:
n
:
: Type
) :
Option: Type ?u.13766 → Type ?u.13766
Option
(
Multiset: Type ?u.13767 → Type ?u.13767
Multiset
α: Type ?u.13758
α
) := (
(↑): List αMultiset α
(↑)
:
List: Type ?u.13797 → Type ?u.13797
List
α: Type ?u.13758
α
Multiset: Type ?u.13799 → Type ?u.13799
Multiset
α: Type ?u.13758
α
) <$>
decode: {α : Type ?u.13909} → [self : Encodable α] → Option α
decode
(α :=
List: Type ?u.13910 → Type ?u.13910
List
α: Type ?u.13758
α
)
n:
n
#align encodable.decode_multiset
Encodable.decodeMultiset: {α : Type u_1} → [inst : Encodable α] → Option (Multiset α)
Encodable.decodeMultiset
/-- If `α` is encodable, then so is `Multiset α`. -/ instance
_root_.Multiset.encodable: Encodable (Multiset α)
_root_.Multiset.encodable
:
Encodable: Type ?u.13992 → Type ?u.13992
Encodable
(
Multiset: Type ?u.13993 → Type ?u.13993
Multiset
α: Type ?u.13986
α
) := ⟨
encodeMultiset: {α : Type ?u.14002} → [inst : Encodable α] → Multiset α
encodeMultiset
,
decodeMultiset: {α : Type ?u.14031} → [inst : Encodable α] → Option (Multiset α)
decodeMultiset
, fun
s: ?m.14057
s
=>

Goals accomplished! 🐙
α: Type ?u.13986

inst✝: Encodable α

s: Multiset α



Goals accomplished! 🐙
#align multiset.encodable
Multiset.encodable: {α : Type u_1} → [inst : Encodable α] → Encodable (Multiset α)
Multiset.encodable
/-- If `α` is countable, then so is `Multiset α`. -/ instance
_root_.Multiset.countable: ∀ {α : Type u_1} [inst : Countable α], Countable (Multiset α)
_root_.Multiset.countable
{
α: Type ?u.14780
α
:
Type _: Type (?u.14780+1)
Type _
} [
Countable: Sort ?u.14783 → Prop
Countable
α: Type ?u.14780
α
] :
Countable: Sort ?u.14786 → Prop
Countable
(
Multiset: Type ?u.14787 → Type ?u.14787
Multiset
α: Type ?u.14780
α
) :=
Quotient.countable: ∀ {α : Sort ?u.14791} [inst : Countable α] {r : ααProp}, Countable (Quot r)
Quotient.countable
#align multiset.countable
Multiset.countable: ∀ {α : Type u_1} [inst : Countable α], Countable (Multiset α)
Multiset.countable
end Finset /-- A listable type with decidable equality is encodable. -/ def
encodableOfList: [inst : DecidableEq α] → (l : List α) → (∀ (x : α), x l) → Encodable α
encodableOfList
[
DecidableEq: Sort ?u.14845 → Sort (max1?u.14845)
DecidableEq
α: Type ?u.14842
α
] (
l: List α
l
:
List: Type ?u.14854 → Type ?u.14854
List
α: Type ?u.14842
α
) (
H: ∀ (x : α), x l
H
: ∀
x: ?m.14858
x
,
x: ?m.14858
x
l: List α
l
) :
Encodable: Type ?u.14893 → Type ?u.14893
Encodable
α: Type ?u.14842
α
:= ⟨fun
a: ?m.14909
a
=>
indexOf: {α : Type ?u.14911} → [inst : BEq α] → αList α
indexOf
a: ?m.14909
a
l: List α
l
,
l: List α
l
.
get?: {α : Type ?u.14973} → List αOption α
get?
, fun
_: ?m.14983
_
=>
indexOf_get?: ∀ {α : Type ?u.14985} [inst : DecidableEq α] {a : α} {l : List α}, a lget? l (indexOf a l) = some a
indexOf_get?
(
H: ∀ (x : α), x l
H
_: α
_
)⟩ #align encodable.encodable_of_list
Encodable.encodableOfList: {α : Type u_1} → [inst : DecidableEq α] → (l : List α) → (∀ (x : α), x l) → Encodable α
Encodable.encodableOfList
/-- A finite type is encodable. Because the encoding is not unique, we wrap it in `Trunc` to preserve computability. -/ def
_root_.Fintype.truncEncodable: (α : Type u_1) → [inst : DecidableEq α] → [inst : Fintype α] → Trunc (Encodable α)
_root_.Fintype.truncEncodable
(
α: Type ?u.15217
α
:
Type _: Type (?u.15217+1)
Type _
) [
DecidableEq: Sort ?u.15220 → Sort (max1?u.15220)
DecidableEq
α: Type ?u.15217
α
] [
Fintype: Type ?u.15229 → Type ?u.15229
Fintype
α: Type ?u.15217
α
] :
Trunc: Sort ?u.15232 → Sort ?u.15232
Trunc
(
Encodable: Type ?u.15233 → Type ?u.15233
Encodable
α: Type ?u.15217
α
) := @
Quot.recOnSubsingleton': {α : Sort ?u.15246} → {r : ααProp} → {motive : Quot rSort ?u.15245} → [h : ∀ (a : α), Subsingleton (motive (Quot.mk r a))] → (q : Quot r) → ((a : α) → motive (Quot.mk r a)) → motive q
Quot.recOnSubsingleton'
_: Sort ?u.15246
_
_: ?m.15247?m.15247Prop
_
(fun
s: Multiset α
s
:
Multiset: Type ?u.15250 → Type ?u.15250
Multiset
α: Type ?u.15217
α
=> (∀
x: α
x
:
α: Type ?u.15217
α
,
x: α
x
s: Multiset α
s
) →
Trunc: Sort ?u.15290 → Sort ?u.15290
Trunc
(
Encodable: Type ?u.15291 → Type ?u.15291
Encodable
α: Type ?u.15217
α
)) _
Finset.univ: {α : Type ?u.15301} → [inst : Fintype α] → Finset α
Finset.univ
.
1: {α : Type ?u.15328} → Finset αMultiset α
1
(fun
l: ?m.15336
l
H: ?m.15339
H
=>
Trunc.mk: {α : Sort ?u.15343} → αTrunc α
Trunc.mk
<|
encodableOfList: {α : Type ?u.15346} → [inst : DecidableEq α] → (l : List α) → (∀ (x : α), x l) → Encodable α
encodableOfList
l: ?m.15336
l
H: ?m.15339
H
)
Finset.mem_univ: ∀ {α : Type ?u.15550} [inst : Fintype α] (x : α), x Finset.univ
Finset.mem_univ
#align fintype.trunc_encodable
Fintype.truncEncodable: (α : Type u_1) → [inst : DecidableEq α] → [inst : Fintype α] → Trunc (Encodable α)
Fintype.truncEncodable
/-- A noncomputable way to arbitrarily choose an ordering on a finite type. It is not made into a global instance, since it involves an arbitrary choice. This can be locally made into an instance with `local attribute [instance] Fintype.toEncodable`. -/ noncomputable def
_root_.Fintype.toEncodable: (α : Type u_1) → [inst : Fintype α] → Encodable α
_root_.Fintype.toEncodable
(
α: Type ?u.15748
α
:
Type _: Type (?u.15748+1)
Type _
) [
Fintype: Type ?u.15751 → Type ?u.15751
Fintype
α: Type ?u.15748
α
] :
Encodable: Type ?u.15754 → Type ?u.15754
Encodable
α: Type ?u.15748
α
:=

Goals accomplished! 🐙
α✝: Type ?u.15745

α: Type ?u.15748

inst✝: Fintype α


α✝: Type ?u.15745

α: Type ?u.15748

inst✝: Fintype α



Goals accomplished! 🐙
#align fintype.to_encodable
Fintype.toEncodable: (α : Type u_1) → [inst : Fintype α] → Encodable α
Fintype.toEncodable
/-- If `α` is encodable, then so is `Vector α n`. -/ instance
_root_.Vector.encodable: [inst : Encodable α] → {n : } → Encodable (Vector α n)
_root_.Vector.encodable
[
Encodable: Type ?u.15974 → Type ?u.15974
Encodable
α: Type ?u.15971
α
] {
n:
n
} :
Encodable: Type ?u.15980 → Type ?u.15980
Encodable
(
Vector: Type ?u.15981 → Type ?u.15981
Vector
α: Type ?u.15971
α
n: ?m.15977
n
) :=
Subtype.encodable: {α : Type ?u.15985} → {P : αProp} → [encA : Encodable α] → [decP : DecidablePred P] → Encodable { a // P a }
Subtype.encodable
#align vector.encodable
Vector.encodable: {α : Type u_1} → [inst : Encodable α] → {n : } → Encodable (Vector α n)
Vector.encodable
/-- If `α` is countable, then so is `Vector α n`. -/ instance
_root_.Vector.countable: ∀ [inst : Countable α] {n : }, Countable (Vector α n)
_root_.Vector.countable
[
Countable: Sort ?u.16307 → Prop
Countable
α: Type ?u.16304
α
] {
n:
n
} :
Countable: Sort ?u.16313 → Prop
Countable
(
Vector: Type ?u.16314 → Type ?u.16314
Vector
α: Type ?u.16304
α
n: ?m.16310
n
) :=
Subtype.countable: ∀ {α : Sort ?u.16318} [inst : Countable α] {p : αProp}, Countable { x // p x }
Subtype.countable
#align vector.countable
Vector.countable: ∀ {α : Type u_1} [inst : Countable α] {n : }, Countable (Vector α n)
Vector.countable
/-- If `α` is encodable, then so is `Fin n → α`. -/ instance
finArrow: {α : Type u_1} → [inst : Encodable α] → {n : } → Encodable (Fin nα)
finArrow
[
Encodable: Type ?u.16380 → Type ?u.16380
Encodable
α: Type ?u.16377
α
] {
n:
n
} :
Encodable: Type ?u.16386 → Type ?u.16386
Encodable
(
Fin: Type
Fin
n: ?m.16383
n
α: Type ?u.16377
α
) :=
ofEquiv: {β : Type ?u.16395} → (α : Type ?u.16394) → [inst : Encodable α] → β αEncodable β
ofEquiv
_: Type ?u.16394
_
(
Equiv.vectorEquivFin: (α : Type ?u.16421) → (n : ) → Vector α n (Fin nα)
Equiv.vectorEquivFin
_: Type ?u.16421
_
_:
_
).
symm: {α : Sort ?u.16425} → {β : Sort ?u.16424} → α ββ α
symm
#align encodable.fin_arrow
Encodable.finArrow: {α : Type u_1} → [inst : Encodable α] → {n : } → Encodable (Fin nα)
Encodable.finArrow
instance
finPi: (n : ) → (π : Fin nType u_1) → [inst : (i : Fin n) → Encodable (π i)] → Encodable ((i : Fin n) → π i)
finPi
(
n:
n
) (
π: Fin nType ?u.16515
π
:
Fin: Type
Fin
n: ?m.16510
n
Type _: Type (?u.16515+1)
Type _
) [∀
i: ?m.16519
i
,
Encodable: Type ?u.16522 → Type ?u.16522
Encodable
(
π: Fin nType ?u.16515
π
i: ?m.16519
i
)] :
Encodable: Type ?u.16526 → Type ?u.16526
Encodable
(∀
i: ?m.16528
i
,
π: Fin nType ?u.16515
π
i: ?m.16528
i
) :=
ofEquiv: {β : Type ?u.16538} → (α : Type ?u.16537) → [inst : Encodable α] → β αEncodable β
ofEquiv
_: Type ?u.16537
_
(
Equiv.piEquivSubtypeSigma: (ι : Type ?u.16568) → (π : ιType ?u.16567) → ((i : ι) → π i) { f // ∀ (i : ι), (f i).fst = i }
Equiv.piEquivSubtypeSigma
(
Fin: Type
Fin
n:
n
)
π: Fin nType ?u.16526
π
) #align encodable.fin_pi
Encodable.finPi: (n : ) → (π : Fin nType u_1) → [inst : (i : Fin n) → Encodable (π i)] → Encodable ((i : Fin n) → π i)
Encodable.finPi
/-- If `α` is encodable, then so is `Finset α`. -/ instance
_root_.Finset.encodable: {α : Type u_1} → [inst : Encodable α] → Encodable (Finset α)
_root_.Finset.encodable
[
Encodable: Type ?u.16946 → Type ?u.16946
Encodable
α: Type ?u.16943
α
] :
Encodable: Type ?u.16949 → Type ?u.16949
Encodable
(
Finset: Type ?u.16950 → Type ?u.16950
Finset
α: Type ?u.16943
α
) := haveI :=
decidableEqOfEncodable: (α : Type ?u.16955) → [inst : Encodable α] → DecidableEq α
decidableEqOfEncodable
α: Type ?u.16943
α
ofEquiv: {β : Type ?u.16967} → (α : Type ?u.16966) → [inst : Encodable α] → β αEncodable β
ofEquiv
{
s: Multiset α
s
:
Multiset: Type ?u.16972 → Type ?u.16972
Multiset
α: Type ?u.16943
α
//
s: Multiset α
s
.
Nodup: {α : Type ?u.16974} → Multiset αProp
Nodup
} ⟨fun
a: Multiset α
a
, b⟩ => ⟨
a: Multiset α
a
, b⟩, fun
a: Multiset α
a
, b⟩ => ⟨
a: Multiset α
a
, b⟩, fun ⟨_, _⟩ =>
rfl: ∀ {α : Sort ?u.17257} {a : α}, a = a
rfl
, fun ⟨_, _⟩ =>
rfl: ∀ {α : Sort ?u.17403} {a : α}, a = a
rfl
#align finset.encodable
Finset.encodable: {α : Type u_1} → [inst : Encodable α] → Encodable (Finset α)
Finset.encodable
/-- If `α` is countable, then so is `Finset α`. -/ instance
_root_.Finset.countable: ∀ {α : Type u_1} [inst : Countable α], Countable (Finset α)
_root_.Finset.countable
[
Countable: Sort ?u.17831 → Prop
Countable
α: Type ?u.17828
α
] :
Countable: Sort ?u.17834 → Prop
Countable
(
Finset: Type ?u.17835 → Type ?u.17835
Finset
α: Type ?u.17828
α
) :=
Finset.val_injective: ∀ {α : Type ?u.17838}, Function.Injective Finset.val
Finset.val_injective
.
countable: ∀ {α : Sort ?u.17841} {β : Sort ?u.17840} [inst : Countable β] {f : αβ}, Function.Injective fCountable α
countable
#align finset.countable
Finset.countable: ∀ {α : Type u_1} [inst : Countable α], Countable (Finset α)
Finset.countable
-- TODO: Unify with `fintypePi` and find a better name /-- When `α` is finite and `β` is encodable, `α → β` is encodable too. Because the encoding is not unique, we wrap it in `Trunc` to preserve computability. -/ def
fintypeArrow: (α : Type u_1) → (β : Type u_2) → [inst : DecidableEq α] → [inst : Fintype α] → [inst : Encodable β] → Trunc (Encodable (αβ))
fintypeArrow
(
α: Type ?u.17910
α
:
Type _: Type (?u.17910+1)
Type _
) (
β: Type ?u.17913
β
:
Type _: Type (?u.17913+1)
Type _
) [
DecidableEq: Sort ?u.17916 → Sort (max1?u.17916)
DecidableEq
α: Type ?u.17910
α
] [
Fintype: Type ?u.17925 → Type ?u.17925
Fintype
α: Type ?u.17910
α
] [
Encodable: Type ?u.17928 → Type ?u.17928
Encodable
β: Type ?u.17913
β
] :
Trunc: Sort ?u.17931 → Sort ?u.17931
Trunc
(
Encodable: Type ?u.17932 → Type ?u.17932
Encodable
(
α: Type ?u.17910
α
β: Type ?u.17913
β
)) := (
Fintype.truncEquivFin: (α : Type ?u.17951) → [inst : DecidableEq α] → [inst : Fintype α] → Trunc (α Fin (Fintype.card α))
Fintype.truncEquivFin
α: Type ?u.17910
α
).
map: {α : Sort ?u.17992} → {β : Sort ?u.17991} → (αβ) → Trunc αTrunc β
map
fun
f: ?m.18001
f
=>
Encodable.ofEquiv: {β : Type ?u.18004} → (α : Type ?u.18003) → [inst : Encodable α] → β αEncodable β
Encodable.ofEquiv
(
Fin: Type
Fin
(
Fintype.card: (α : Type ?u.18009) → [inst : Fintype α] →
Fintype.card
α: Type ?u.17910
α
) →
β: Type ?u.17913
β
) <|
Equiv.arrowCongr: {α₁ : Sort ?u.18017} → {β₁ : Sort ?u.18016} → {α₂ : Sort ?u.18015} → {β₂ : Sort ?u.18014} → α₁ α₂β₁ β₂(α₁β₁) (α₂β₂)
Equiv.arrowCongr
f: ?m.18001
f
(
Equiv.refl: (α : Sort ?u.18028) → α α
Equiv.refl
_: Sort ?u.18028
_
) #align encodable.fintype_arrow
Encodable.fintypeArrow: (α : Type u_1) → (β : Type u_2) → [inst : DecidableEq α] → [inst : Fintype α] → [inst : Encodable β] → Trunc (Encodable (αβ))
Encodable.fintypeArrow
/-- When `α` is finite and all `π a` are encodable, `Π a, π a` is encodable too. Because the encoding is not unique, we wrap it in `Trunc` to preserve computability. -/ def
fintypePi: (α : Type ?u.18192) → (π : αType ?u.18197) → [inst : DecidableEq α] → [inst : Fintype α] → [inst : (a : α) → Encodable (π a)] → Trunc (Encodable ((a : α) → π a))
fintypePi
(
α: Type ?u.18192
α
:
Type _: Type (?u.18192+1)
Type _
) (
π: αType ?u.18197
π
:
α: Type ?u.18192
α
Type _: Type (?u.18197+1)
Type _
) [
DecidableEq: Sort ?u.18200 → Sort (max1?u.18200)
DecidableEq
α: Type ?u.18192
α
] [
Fintype: Type ?u.18209 → Type ?u.18209
Fintype
α: Type ?u.18192
α
] [∀
a: ?m.18213
a
,
Encodable: Type ?u.18216 → Type ?u.18216
Encodable
(
π: αType ?u.18197
π
a: ?m.18213
a
)] :
Trunc: Sort ?u.18220 → Sort ?u.18220
Trunc
(
Encodable: Type ?u.18221 → Type ?u.18221
Encodable
(∀
a: ?m.18223
a
,
π: αType ?u.18197
π
a: ?m.18223
a
)) := (
Fintype.truncEncodable: (α : Type ?u.18242) → [inst : DecidableEq α] → [inst : Fintype α] → Trunc (Encodable α)
Fintype.truncEncodable
α: Type ?u.18192
α
).
bind: {α : Sort ?u.18283} → {β : Sort ?u.18282} → Trunc α(αTrunc β) → Trunc β
bind
fun
a: ?m.18294
a
=> (@
fintypeArrow: (α : Type ?u.18297) → (β : Type ?u.18296) → [inst : DecidableEq α] → [inst : Fintype α] → [inst : Encodable β] → Trunc (Encodable (αβ))
fintypeArrow
α: Type ?u.18192
α
a: ?m.18302
a
,
π: αType ?u.18197
π
a: ?m.18302
a
) _ _ (@
Sigma.encodable: {α : Type ?u.18309} → {γ : αType ?u.18308} → [inst : Encodable α] → [inst : (a : α) → Encodable (γ a)] → Encodable (Sigma γ)
Sigma.encodable
_: Type ?u.18309
_
_: ?m.18310Type ?u.18308
_
a: ?m.18294
a
_)).
bind: {α : Sort ?u.18369} → {β : Sort ?u.18368} → Trunc α(αTrunc β) → Trunc β
bind
fun
f: ?m.18380
f
=>
Trunc.mk: {α : Sort ?u.18382} → αTrunc α
Trunc.mk
<| @
Encodable.ofEquiv: {β : Type ?u.18385} → (α : Type ?u.18384) → [inst : Encodable α] → β αEncodable β
Encodable.ofEquiv
_: Type ?u.18385
_
_: Type ?u.18384
_
(@
Subtype.encodable: {α : Type ?u.18390} → {P : αProp} → [encA : Encodable α] → [decP : DecidablePred P] → Encodable { a // P a }
Subtype.encodable
_: Type ?u.18390
_
_: ?m.18391Prop
_
f: ?m.18380
f
_) (
Equiv.piEquivSubtypeSigma: (ι : Type ?u.18792) → (π : ιType ?u.18791) → ((i : ι) → π i) { f // ∀ (i : ι), (f i).fst = i }
Equiv.piEquivSubtypeSigma
α: Type ?u.18192
α
π: αType ?u.18197
π
) #align encodable.fintype_pi
Encodable.fintypePi: (α : Type u_1) → (π : αType u_2) → [inst : DecidableEq α] → [inst : Fintype α] → [inst : (a : α) → Encodable (π a)] → Trunc (Encodable ((a : α) → π a))
Encodable.fintypePi
/-- The elements of a `Fintype` as a sorted list. -/ def
sortedUniv: (α : Type ?u.19406) → [inst : Fintype α] → [inst : Encodable α] → List α
sortedUniv
(
α: ?m.19403
α
) [
Fintype: Type ?u.19406 → Type ?u.19406
Fintype
α: ?m.19403
α
] [
Encodable: Type ?u.19409 → Type ?u.19409
Encodable
α: ?m.19403
α
] :
List: Type ?u.19412 → Type ?u.19412
List
α: ?m.19403
α
:=
Finset.univ: {α : Type ?u.19417} → [inst : Fintype α] → Finset α
Finset.univ
.
sort: {α : Type ?u.19444} → (r : ααProp) → [inst : DecidableRel r] → [inst : IsTrans α r] → [inst : IsAntisymm α r] → [inst : IsTotal α r] → Finset αList α
sort
(
Encodable.encode': (α : Type ?u.19464) → [inst : Encodable α] → α
Encodable.encode'
α: Type ?u.19406
α
⁻¹'o
(· ≤ ·): Prop
(· ≤ ·)
) #align encodable.sorted_univ
Encodable.sortedUniv: (α : Type u_1) → [inst : Fintype α] → [inst : Encodable α] → List α
Encodable.sortedUniv
@[simp] theorem
mem_sortedUniv: ∀ {α : Type u_1} [inst : Fintype α] [inst_1 : Encodable α] (x : α), x sortedUniv α
mem_sortedUniv
{
α: Type u_1
α
} [
Fintype: Type ?u.27413 → Type ?u.27413
Fintype
α: ?m.27410
α
] [
Encodable: Type ?u.27416 → Type ?u.27416
Encodable
α: ?m.27410
α
] (
x: α
x
:
α: ?m.27410
α
) :
x: α
x
sortedUniv: (α : Type ?u.27438) → [inst : Fintype α] → [inst : Encodable α] → List α
sortedUniv
α: ?m.27410
α
:= (
Finset.mem_sort: ∀ {α : Type ?u.27469} (r : ααProp) [inst : DecidableRel r] [inst_1 : IsTrans α r] [inst_2 : IsAntisymm α r] [inst_3 : IsTotal α r] {s : Finset α} {a : α}, a Finset.sort r s a s
Finset.mem_sort
_: ?m.27470?m.27470Prop
_
).
2: ∀ {a b : Prop}, (a b) → ba
2
(
Finset.mem_univ: ∀ {α : Type ?u.27792} [inst : Fintype α] (x : α), x Finset.univ
Finset.mem_univ
_: ?m.27793
_
) #align encodable.mem_sorted_univ
Encodable.mem_sortedUniv: ∀ {α : Type u_1} [inst : Fintype α] [inst_1 : Encodable α] (x : α), x sortedUniv α
Encodable.mem_sortedUniv
@[simp] theorem
length_sortedUniv: ∀ (α : Type u_1) [inst : Fintype α] [inst_1 : Encodable α], length (sortedUniv α) = Fintype.card α
length_sortedUniv
(
α: Type u_1
α
) [
Fintype: Type ?u.28047 → Type ?u.28047
Fintype
α: ?m.28044
α
] [
Encodable: Type ?u.28050 → Type ?u.28050
Encodable
α: ?m.28044
α
] : (
sortedUniv: (α : Type ?u.28054) → [inst : Fintype α] → [inst : Encodable α] → List α
sortedUniv
α: ?m.28044
α
).
length: {α : Type ?u.28066} → List α
length
=
Fintype.card: (α : Type ?u.28071) → [inst : Fintype α] →
Fintype.card
α: ?m.28044
α
:=
Finset.length_sort: ∀ {α : Type ?u.28078} (r : ααProp) [inst : DecidableRel r] [inst_1 : IsTrans α r] [inst_2 : IsAntisymm α r] [inst_3 : IsTotal α r] {s : Finset α}, length (Finset.sort r s) = Finset.card s
Finset.length_sort
_: ?m.28079?m.28079Prop
_
#align encodable.length_sorted_univ
Encodable.length_sortedUniv: ∀ (α : Type u_1) [inst : Fintype α] [inst_1 : Encodable α], length (sortedUniv α) = Fintype.card α
Encodable.length_sortedUniv
@[simp] theorem
sortedUniv_nodup: ∀ (α : Type u_1) [inst : Fintype α] [inst_1 : Encodable α], Nodup (sortedUniv α)
sortedUniv_nodup
(
α: ?m.28596
α
) [
Fintype: Type ?u.28599 → Type ?u.28599
Fintype
α: ?m.28596
α
] [
Encodable: Type ?u.28602 → Type ?u.28602
Encodable
α: ?m.28596
α
] : (
sortedUniv: (α : Type ?u.28605) → [inst : Fintype α] → [inst : Encodable α] → List α
sortedUniv
α: ?m.28596
α
).
Nodup: {α : Type ?u.28617} → List αProp
Nodup
:=
Finset.sort_nodup: ∀ {α : Type ?u.28629} (r : ααProp) [inst : DecidableRel r] [inst_1 : IsTrans α r] [inst_2 : IsAntisymm α r] [inst_3 : IsTotal α r] (s : Finset α), Nodup (Finset.sort r s)
Finset.sort_nodup
_: ?m.28630?m.28630Prop
_
_: Finset ?m.28630
_
#align encodable.sorted_univ_nodup
Encodable.sortedUniv_nodup: ∀ (α : Type u_1) [inst : Fintype α] [inst_1 : Encodable α], Nodup (sortedUniv α)
Encodable.sortedUniv_nodup
@[simp] theorem
sortedUniv_toFinset: ∀ (α : Type u_1) [inst : Fintype α] [inst_1 : Encodable α] [inst_2 : DecidableEq α], toFinset (sortedUniv α) = Finset.univ
sortedUniv_toFinset
(
α: ?m.29148
α
) [
Fintype: Type ?u.29151 → Type ?u.29151
Fintype
α: ?m.29148
α
] [
Encodable: Type ?u.29154 → Type ?u.29154
Encodable
α: ?m.29148
α
] [
DecidableEq: Sort ?u.29157 → Sort (max1?u.29157)
DecidableEq
α: ?m.29148
α
] : (
sortedUniv: (α : Type ?u.29167) → [inst : Fintype α] → [inst : Encodable α] → List α
sortedUniv
α: ?m.29148
α
).
toFinset: {α : Type ?u.29179} → [inst : DecidableEq α] → List αFinset α
toFinset
=
Finset.univ: {α : Type ?u.29226} → [inst : Fintype α] → Finset α
Finset.univ
:=
Finset.sort_toFinset: ∀ {α : Type ?u.29312} (r : ααProp) [inst : DecidableRel r] [inst_1 : IsTrans α r] [inst_2 : IsAntisymm α r] [inst_3 : IsTotal α r] [inst_4 : DecidableEq α] (s : Finset α), toFinset (Finset.sort r s) = s
Finset.sort_toFinset
_: ?m.29313?m.29313Prop
_
_: Finset ?m.29313
_
#align encodable.sorted_univ_to_finset
Encodable.sortedUniv_toFinset: ∀ (α : Type u_1) [inst : Fintype α] [inst_1 : Encodable α] [inst_2 : DecidableEq α], toFinset (sortedUniv α) = Finset.univ
Encodable.sortedUniv_toFinset
/-- An encodable `Fintype` is equivalent to the same size `Fin`. -/ def
fintypeEquivFin: {α : Type ?u.29969} → [inst : Fintype α] → [inst_1 : Encodable α] → α Fin (Fintype.card α)
fintypeEquivFin
{
α: Type ?u.29969
α
} [
Fintype: Type ?u.29969 → Type ?u.29969
Fintype
α: ?m.29966
α
] [
Encodable: Type ?u.29972 → Type ?u.29972
Encodable
α: ?m.29966
α
] :
α: ?m.29966
α
Fin: Type
Fin
(
Fintype.card: (α : Type ?u.29977) → [inst : Fintype α] →
Fintype.card
α: ?m.29966
α
) := haveI :
DecidableEq: Sort ?u.29988 → Sort (max1?u.29988)
DecidableEq
α: Type ?u.29969
α
:=
Encodable.decidableEqOfEncodable: (α : Type ?u.29989) → [inst : Encodable α] → DecidableEq α
Encodable.decidableEqOfEncodable
_: Type ?u.29989
_
-- Porting note: used the `trans` tactic ((
sortedUniv_nodup: ∀ (α : Type ?u.30025) [inst : Fintype α] [inst_1 : Encodable α], Nodup (sortedUniv α)
sortedUniv_nodup
α: Type ?u.29969
α
).
getEquivOfForallMemList: {α : Type ?u.30034} → [inst : DecidableEq α] → (l : List α) → Nodup l(∀ (x : α), x l) → Fin (length l) α
getEquivOfForallMemList
_: List ?m.30043
_
mem_sortedUniv: ∀ {α : Type ?u.30049} [inst : Fintype α] [inst_1 : Encodable α] (x : α), x sortedUniv α
mem_sortedUniv
).
symm: {α : Sort ?u.30150} → {β : Sort ?u.30149} → α ββ α
symm
.
trans: {α : Sort ?u.30157} → {β : Sort ?u.30156} → {γ : Sort ?u.30155} → α ββ γα γ
trans
<|
Equiv.cast: {α β : Sort ?u.30168} → α = βα β
Equiv.cast
(
congr_arg: ∀ {α : Sort ?u.30174} {β : Sort ?u.30173} {a₁ a₂ : α} (f : αβ), a₁ = a₂f a₁ = f a₂
congr_arg
_: ?m.30175?m.30176
_
(
length_sortedUniv: ∀ (α : Type ?u.30185) [inst : Fintype α] [inst_1 : Encodable α], length (sortedUniv α) = Fintype.card α
length_sortedUniv
α: Type ?u.29969
α
)) #align encodable.fintype_equiv_fin
Encodable.fintypeEquivFin: {α : Type u_1} → [inst : Fintype α] → [inst_1 : Encodable α] → α Fin (Fintype.card α)
Encodable.fintypeEquivFin
/-- If `α` and `β` are encodable and `α` is a fintype, then `α → β` is encodable as well. -/ instance
fintypeArrowOfEncodable: {α : Type ?u.30242} → {β : Type ?u.30245} → [inst : Encodable α] → [inst : Fintype α] → [inst : Encodable β] → Encodable (αβ)
fintypeArrowOfEncodable
{
α: Type ?u.30242
α
β: Type ?u.30245
β
:
Type _: Type (?u.30245+1)
Type _
} [
Encodable: Type ?u.30248 → Type ?u.30248
Encodable
α: Type ?u.30242
α
] [
Fintype: Type ?u.30251 → Type ?u.30251
Fintype
α: Type ?u.30242
α
] [
Encodable: Type ?u.30254 → Type ?u.30254
Encodable
β: Type ?u.30245
β
] :
Encodable: Type ?u.30257 → Type ?u.30257
Encodable
(
α: Type ?u.30242
α
β: Type ?u.30245
β
) :=
ofEquiv: {β : Type ?u.30269} → (α : Type ?u.30268) → [inst : Encodable α] → β αEncodable β
ofEquiv
(
Fin: Type
Fin
(
Fintype.card: (α : Type ?u.30274) → [inst : Fintype α] →
Fintype.card
α: Type ?u.30242
α
) →
β: Type ?u.30245
β
) <|
Equiv.arrowCongr: {α₁ : Sort ?u.30286} → {β₁ : Sort ?u.30285} → {α₂ : Sort ?u.30284} → {β₂ : Sort ?u.30283} → α₁ α₂β₁ β₂(α₁β₁) (α₂β₂)
Equiv.arrowCongr
fintypeEquivFin: {α : Type ?u.30295} → [inst : Fintype α] → [inst_1 : Encodable α] → α Fin (Fintype.card α)
fintypeEquivFin
(
Equiv.refl: (α : Sort ?u.30356) → α α
Equiv.refl
_: Sort ?u.30356
_
) #align encodable.fintype_arrow_of_encodable
Encodable.fintypeArrowOfEncodable: {α : Type u_1} → {β : Type u_2} → [inst : Encodable α] → [inst : Fintype α] → [inst : Encodable β] → Encodable (αβ)
Encodable.fintypeArrowOfEncodable
end Encodable namespace Denumerable variable {
α: Type ?u.30488
α
:
Type _: Type (?u.38622+1)
Type _
} {
β: Type ?u.56216
β
:
Type _: Type (?u.43348+1)
Type _
} [
Denumerable: Type ?u.62387 → Type ?u.62387
Denumerable
α: Type ?u.55740
α
] [
Denumerable: Type ?u.43767 → Type ?u.43767
Denumerable
β: Type ?u.30491
β
] open Encodable section List @[nolint
unusedHavesSuffices: Std.Tactic.Lint.Linter
unusedHavesSuffices
] -- Porting note: false positive theorem
denumerable_list_aux: ∀ (n : ), a, a decodeList n encodeList a = n
denumerable_list_aux
: ∀
n:
n
:
: Type
, ∃
a: ?m.30518
a
∈ @
decodeList: {α : Type ?u.30525} → [inst : Encodable α] → Option (List α)
decodeList
α: Type ?u.30500
α
_
n:
n
,
encodeList: {α : Type ?u.30550} → [inst : Encodable α] → List α
encodeList
a: ?m.30518
a
=
n:
n
|
0:
0
=>

Goals accomplished! 🐙
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β


a, a decodeList 0 encodeList a = 0
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β


a, a decodeList 0 encodeList a = 0
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β


a, a some [] encodeList a = 0
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β


a, a some [] encodeList a = 0
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β


a, a some [] encodeList a = 0
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β


a, a decodeList 0 encodeList a = 0

Goals accomplished! 🐙
|
succ:
succ
v:
v
=>

Goals accomplished! 🐙
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v:


α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)


mk
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v:


α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)

h: (unpair v).snd v


mk
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v:


α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)

h: (unpair v).snd v


mk
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)

h: (v₁, v₂).snd v


mk
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)

h: (v₁, v₂).snd v


mk
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)

h: (v₁, v₂).snd v


mk
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v:


α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)

h: (v₁, v₂).snd v

a: List α

h₁: a decodeList v₂

h₂: encodeList a = v₂


mk.intro.intro
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v:


α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)

h: (v₁, v₂).snd v

a: List α

h₁: a decodeList v₂

h₂: encodeList a = v₂


mk.intro.intro
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)

h: (v₁, v₂).snd v

a: List α

h₁: decodeList v₂ = some a

h₂: encodeList a = v₂


mk.intro.intro
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)

h: (v₁, v₂).snd v

a: List α

h₁: decodeList v₂ = some a

h₂: encodeList a = v₂


mk.intro.intro
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)

h: (v₁, v₂).snd v

a: List α

h₁: decodeList v₂ = some a

h₂: encodeList a = v₂


mk.intro.intro
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v:


α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)

h: (v₁, v₂).snd v

a: List α

h₁: decodeList v₂ = some a

h₂: encodeList a = v₂


mk.intro.intro
ofNat α v₁ :: a decodeList (succ v) encodeList (ofNat α v₁ :: a) = succ v
α: Type u_1

β: Type ?u.30503

inst✝¹: Denumerable α

inst✝: Denumerable β

v:



Goals accomplished! 🐙
#align denumerable.denumerable_list_aux
Denumerable.denumerable_list_aux: ∀ {α : Type u_1} [inst : Denumerable α] (n : ), a, a decodeList n encodeList a = n
Denumerable.denumerable_list_aux
/-- If `α` is denumerable, then so is `List α`. -/ instance
denumerableList: Denumerable (List α)
denumerableList
:
Denumerable: Type ?u.38634 → Type ?u.38634
Denumerable
(
List: Type ?u.38635 → Type ?u.38635
List
α: Type ?u.38622
α
) := ⟨
denumerable_list_aux: ∀ {α : Type ?u.38672} [inst : Denumerable α] (n : ), a, a decodeList n encodeList a = n
denumerable_list_aux
#align denumerable.denumerable_list
Denumerable.denumerableList: {α : Type u_1} → [inst : Denumerable α] → Denumerable (List α)
Denumerable.denumerableList
@[simp] theorem
list_ofNat_zero: ∀ {α : Type u_1} [inst : Denumerable α], ofNat (List α) 0 = []
list_ofNat_zero
:
ofNat: (α : Type ?u.38952) → [inst : Denumerable α] → α
ofNat
(
List: Type ?u.38953 → Type ?u.38953
List
α: Type ?u.38939
α
)
0: ?m.38956
0
=
[]: List ?m.38975
[]
:=

Goals accomplished! 🐙
α: Type u_1

β: Type ?u.38942

inst✝¹: Denumerable α

inst✝: Denumerable β


ofNat (List α) 0 = []
α: Type u_1

β: Type ?u.38942

inst✝¹: Denumerable α

inst✝: Denumerable β


ofNat (List α) 0 = []
α: Type u_1

β: Type ?u.38942

inst✝¹: Denumerable α

inst✝: Denumerable β


ofNat (List α) (encode []) = []
α: Type u_1

β: Type ?u.38942

inst✝¹: Denumerable α

inst✝: Denumerable β


ofNat (List α) 0 = []
α: Type u_1

β: Type ?u.38942

inst✝¹: Denumerable α

inst✝: Denumerable β


[] = []

Goals accomplished! 🐙
#align denumerable.list_of_nat_zero
Denumerable.list_ofNat_zero: ∀ {α : Type u_1} [inst : Denumerable α], ofNat (List α) 0 = []
Denumerable.list_ofNat_zero
@[simp, nolint
unusedHavesSuffices: Std.Tactic.Lint.Linter
unusedHavesSuffices
] -- Porting note: false positive theorem
list_ofNat_succ: ∀ {α : Type u_1} [inst : Denumerable α] (v : ), ofNat (List α) (succ v) = ofNat α (unpair v).fst :: ofNat (List α) (unpair v).snd
list_ofNat_succ
(
v:
v
:
: Type
) :
ofNat: (α : Type ?u.39098) → [inst : Denumerable α] → α
ofNat
(
List: Type ?u.39099 → Type ?u.39099
List
α: Type ?u.39083
α
) (
succ:
succ
v:
v
) =
ofNat: (α : Type ?u.39111) → [inst : Denumerable α] → α
ofNat
α: Type ?u.39083
α
v:
v
.
unpair: ×
unpair
.
1: {α : Type ?u.39115} → {β : Type ?u.39114} → α × βα
1
::
ofNat: (α : Type ?u.39120) → [inst : Denumerable α] → α
ofNat
(
List: Type ?u.39121 → Type ?u.39121
List
α: Type ?u.39083
α
)
v:
v
.
unpair: ×
unpair
.
2: {α : Type ?u.39125} → {β : Type ?u.39124} → α × ββ
2
:=
ofNat_of_decode: ∀ {α : Type ?u.39131} [inst : Denumerable α] {n : } {b : α}, decode n = some bofNat α n = b
ofNat_of_decode
<| show
decodeList: {α : Type ?u.39158} → [inst : Encodable α] → Option (List α)
decodeList
(
succ:
succ
v:
v
) =
_: ?m.39217
_
by
α: Type u_1

β: Type ?u.39086

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)


mk
decodeList (succ v) = some (ofNat α (v₁, v₂).fst :: ofNat (List α) (v₁, v₂).snd)
α: Type u_1

β: Type ?u.39086

inst✝¹: Denumerable α

inst✝: Denumerable β

v:


decodeList (succ v) = some (ofNat α (unpair v).fst :: ofNat (List α) (unpair v).snd)
α: Type u_1

β: Type ?u.39086

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)


mk
(Seq.seq (some fun x => ofNat α v₁ :: x) fun x => decodeList v₂) = some (ofNat α v₁ :: ofNat (List α) v₂)
α: Type u_1

β: Type ?u.39086

inst✝¹: Denumerable α

inst✝: Denumerable β

v:


decodeList (succ v) = some (ofNat α (unpair v).fst :: ofNat (List α) (unpair v).snd)
α: Type u_1

β: Type ?u.39086

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)


mk
(Seq.seq (some fun x => ofNat α v₁ :: x) fun x => decodeList v₂) = some (ofNat α v₁ :: ofNat (List α) v₂)
α: Type u_1

β: Type ?u.39086

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)


mk
(Seq.seq (some fun x => ofNat α v₁ :: x) fun x => decode v₂) = some (ofNat α v₁ :: ofNat (List α) v₂)
α: Type u_1

β: Type ?u.39086

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)


mk
(Seq.seq (some fun x => ofNat α v₁ :: x) fun x => decodeList v₂) = some (ofNat α v₁ :: ofNat (List α) v₂)
α: Type u_1

β: Type ?u.39086

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)


mk
(Seq.seq (some fun x => ofNat α v₁ :: x) fun x => some (ofNat (List α) v₂)) = some (ofNat α v₁ :: ofNat (List α) v₂)
α: Type u_1

β: Type ?u.39086

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)


mk
(Seq.seq (some fun x => ofNat α v₁ :: x) fun x => decodeList v₂) = some (ofNat α v₁ :: ofNat (List α) v₂)
α: Type u_1

β: Type ?u.39086

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)


mk
some (ofNat α v₁ :: ofNat (List α) v₂) = some (ofNat α v₁ :: ofNat (List α) v₂)
α: Type u_1

β: Type ?u.39086

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)


mk
(Seq.seq (some fun x => ofNat α v₁ :: x) fun x => decodeList v₂) = some (ofNat α v₁ :: ofNat (List α) v₂)
α: Type u_1

β: Type ?u.39086

inst✝¹: Denumerable α

inst✝: Denumerable β

v, v₁, v₂:

e: unpair v = (v₁, v₂)


mk
ofNat α v₁ :: ofNat (List α) v₂ = ofNat α v₁ :: ofNat (List α) v₂

Goals accomplished! 🐙
#align denumerable.list_of_nat_succ
Denumerable.list_ofNat_succ: ∀ {α : Type u_1} [inst : Denumerable α] (v : ), ofNat (List α) (succ v) = ofNat α (unpair v).fst :: ofNat (List α) (unpair v).snd
Denumerable.list_ofNat_succ
end List section Multiset /-- Outputs the list of differences of the input list, that is `lower [a₁, a₂, ...] n = [a₁ - n, a₂ - a₁, ...]` -/ def
lower: List List
lower
:
List: Type ?u.43358 → Type ?u.43358
List
: Type
: Type
List: Type ?u.43362 → Type ?u.43362
List
: Type
| [], _ =>
[]: List ?m.43388
[]
|
m:
m
:: l,
n:
n
=> (
m:
m
-
n:
n
) ::
lower: List List
lower
l
m:
m
#align denumerable.lower
Denumerable.lower: List List
Denumerable.lower
/-- Outputs the list of partial sums of the input list, that is `raise [a₁, a₂, ...] n = [n + a₁, n + a₁ + a₂, ...]` -/ def
raise: List List
raise
:
List: Type ?u.43771 → Type ?u.43771
List
: Type
: Type
List: Type ?u.43775 → Type ?u.43775
List
: Type
| [], _ =>
[]: List ?m.43801
[]
|
m:
m
:: l,
n:
n
=> (
m:
m
+
n:
n
) ::
raise: List List
raise
l (
m:
m
+
n:
n
) #align denumerable.raise
Denumerable.raise: List List
Denumerable.raise
theorem
lower_raise: ∀ (l : List ) (n : ), lower (raise l n) n = l
lower_raise
: ∀
l: ?m.44190
l
n: ?m.44193
n
,
lower: List List
lower
(
raise: List List
raise
l: ?m.44190
l
n: ?m.44193
n
)
n: ?m.44193
n
=
l: ?m.44190
l
| [],
n:
n
=>
rfl: ∀ {α : Sort ?u.44225} {a : α}, a = a
rfl
|
m:
m
:: l,
n:
n
=>

Goals accomplished! 🐙
α: Type ?u.44177

β: Type ?u.44180

inst✝¹: Denumerable α

inst✝: Denumerable β

m:

l: List

n:


lower (raise (m :: l) n) n = m :: l
α: Type ?u.44177

β: Type ?u.44180

inst✝¹: Denumerable α

inst✝: Denumerable β

m:

l: List

n:


lower (raise (m :: l) n) n = m :: l
α: Type ?u.44177

β: Type ?u.44180

inst✝¹: Denumerable α

inst✝: Denumerable β

m:

l: List

n:


lower ((m + n) :: raise l (m + n)) n = m :: l
α: Type ?u.44177

β: Type ?u.44180

inst✝¹: Denumerable α

inst✝: Denumerable β

m:

l: List

n:


lower (raise (m :: l) n) n = m :: l
α: Type ?u.44177

β: Type ?u.44180

inst✝¹: Denumerable α

inst✝: Denumerable β

m:

l: List

n:


(m + n - n) :: lower (raise l (m + n)) (m + n) = m :: l
α: Type ?u.44177

β: Type ?u.44180

inst✝¹: Denumerable α

inst✝: Denumerable β

m:

l: List

n:


lower (raise (m :: l) n) n = m :: l
α: Type ?u.44177

β: Type ?u.44180

inst✝¹: Denumerable α

inst✝: Denumerable β

m:

l: List

n:


m :: lower (raise l (m + n)) (m + n) = m :: l
α: Type ?u.44177

β: Type ?u.44180

inst✝¹: Denumerable α

inst✝: Denumerable β

m:

l: List

n:


lower (raise (m :: l) n) n = m :: l
α: Type ?u.44177

β: Type ?u.44180

inst✝¹: Denumerable α

inst✝: Denumerable β

m:

l: List

n:


m :: l = m :: l

Goals accomplished! 🐙
#align denumerable.lower_raise
Denumerable.lower_raise: ∀ (l : List ) (n : ), lower (raise l n) n = l
Denumerable.lower_raise
theorem
raise_lower: ∀ {l : List } {n : }, Sorted (fun x x_1 => x x_1) (n :: l)raise (lower l n) n = l
raise_lower
: ∀ {
l: ?m.45417
l
n: ?m.45420
n
},
List.Sorted: {α : Type ?u.45424} → (ααProp) → List αProp
List.Sorted
(· ≤ ·): Prop
(· ≤ ·)
(
n: ?m.45420
n
::
l: ?m.45417
l
) →
raise: List List
raise
(
lower: List List
lower
l: ?m.45417
l
n: ?m.45420
n
)
n: ?m.45420
n
=
l: ?m.45417
l
| [],
n:
n
, _ =>
rfl: ∀ {α : Sort ?u.45558} {a : α}, a = a
rfl
|
m:
m
:: l,
n:
n
,
h: Sorted (fun x x_1 => x x_1) (n :: m :: l)
h
=>

Goals accomplished! 🐙
α: Type ?u.45404

β: Type ?u.45407

inst✝¹: Denumerable α

inst✝: Denumerable β

m:

l: List

n:

h: Sorted (fun x x_1 => x x_1) (n :: m :: l)


raise (lower (m :: l) n) n = m :: l
α: Type ?u.45404

β: Type ?u.45407

inst✝¹: Denumerable α

inst✝: Denumerable β

m:

l: List

n:

h: Sorted (fun x x_1 => x x_1) (n :: m :: l)

this: n m


raise (lower (m :: l) n) n = m :: l
α: Type ?u.45404

β: Type ?u.45407

inst✝¹: Denumerable α

inst✝: Denumerable β

m:

l: List

n:

h: Sorted (fun x x_1 => x x_1) (n :: m :: l)


raise (lower (m :: l) n) n = m :: l

Goals accomplished! 🐙
#align denumerable.raise_lower
Denumerable.raise_lower: ∀ {l : List } {n : }, Sorted (fun x x_1 => x x_1) (n :: l)raise (lower l n) n = l
Denumerable.raise_lower
theorem
raise_chain: ∀ (l : List ) (n : ), Chain (fun x x_1 => x x_1) n (raise l n)
raise_chain
: ∀
l: ?m.46966
l
n: ?m.46969
n
,
List.Chain: {α : Type ?u.46972} → (ααProp) → αList αProp
List.Chain
(· ≤ ·): Prop
(· ≤ ·)
n: ?m.46969
n
(
raise: List List
raise
l: ?m.46966
l
n: ?m.46969
n
) | [], _ =>
List.Chain.nil: ∀ {α : Type ?u.47080} {R : ααProp} {a : α}, Chain R a []
List.Chain.nil
| _ :: _, _ =>
List.Chain.cons: ∀ {α : Type ?u.47131} {R : ααProp} {a b : α} {l : List α}, R a bChain R b lChain R a (b :: l)
List.Chain.cons
(
Nat.le_add_left: ∀ (n m : ), n m + n
Nat.le_add_left
_:
_
_:
_
) (
raise_chain: ∀ (l : List ) (n : ), Chain (fun x x_1 => x x_1) n (raise l n)
raise_chain
_
_:
_
) #align denumerable.raise_chain
Denumerable.raise_chain: ∀ (l : List ) (n : ), Chain (fun x x_1 => x x_1) n (raise l n)
Denumerable.raise_chain
/-- `raise l n` is an non-decreasing sequence. -/ theorem
raise_sorted: ∀ (l : List ) (n : ), Sorted (fun x x_1 => x x_1) (raise l n)
raise_sorted
: ∀
l: ?m.47319
l
n: ?m.47322
n
,
List.Sorted: {α : Type ?u.47325} → (ααProp) → List αProp
List.Sorted
(· ≤ ·): Prop
(· ≤ ·)
(
raise: List List
raise
l: ?m.47319
l
n: ?m.47322
n
) | [], _ =>
List.sorted_nil: ∀ {α : Type ?u.47435} {r : ααProp}, Sorted r []
List.sorted_nil
| _ :: _, _ =>
List.chain_iff_pairwise: ∀ {α : Type ?u.47484} {R : ααProp} [inst : IsTrans α R] {a : α} {l : List α}, Chain R a l List.Pairwise R (a :: l)
List.chain_iff_pairwise
.
1: ∀ {a b : Prop}, (a b) → ab
1
(
raise_chain: ∀ (l : List ) (n : ), Chain (fun x x_1 => x x_1) n (raise l n)
raise_chain
_
_:
_
) #align denumerable.raise_sorted
Denumerable.raise_sorted: ∀ (l : List ) (n : ), Sorted (fun x x_1 => x x_1) (raise l n)
Denumerable.raise_sorted
/-- If `α` is denumerable, then so is `Multiset α`. Warning: this is *not* the same encoding as used in `Multiset.encodable`. -/ instance
multiset: Denumerable (Multiset α)
multiset
:
Denumerable: Type ?u.47775 → Type ?u.47775
Denumerable
(
Multiset: Type ?u.47776 → Type ?u.47776
Multiset
α: Type ?u.47763
α
) :=
mk': {α : Type ?u.47778} → α Denumerable α
mk'
fun
s: Multiset α
s
:
Multiset: Type ?u.47794 → Type ?u.47794
Multiset
α: Type ?u.47763
α
=>
encode: {α : Type ?u.47797} → [self : Encodable α] → α
encode
<|
lower: List List
lower
((
s: Multiset α
s
.
map: {α : Type ?u.47829} → {β : Type ?u.47828} → (αβ) → Multiset αMultiset β
map
encode: {α : Type ?u.47836} → [self : Encodable α] → α
encode
).
sort: {α : Type ?u.47897} → (r : ααProp) → [inst : DecidableRel r] → [inst : IsTrans α r] → [inst : IsAntisymm α r] → [inst : IsTotal α r] → Multiset αList α
sort
(· ≤ ·): Prop
(· ≤ ·)
)
0: ?m.48206
0
, fun
n: ?m.48231
n
=>
Multiset.map: {α : Type ?u.48234} → {β : Type ?u.48233} → (αβ) → Multiset αMultiset β
Multiset.map
(
ofNat: (α : Type ?u.48237) → [inst : Denumerable α] → α
ofNat
α: Type ?u.47763
α
) (
raise: List List
raise
(
ofNat: (α : Type ?u.48244) → [inst : Denumerable α] → α
ofNat
(
List: Type ?u.48245 → Type ?u.48245
List
: Type
)
n: ?m.48231
n
)
0: ?m.48254
0
), fun
s: ?m.48362
s
=>

Goals accomplished! 🐙
α: Type ?u.47763

β: Type ?u.47766

inst✝¹: Denumerable α

inst✝: Denumerable β

s: Multiset α


(fun n => Multiset.map (ofNat α) ↑(raise (ofNat (List ) n) 0)) ((fun s => encode (lower (Multiset.sort (fun x x_1 => x x_1) (Multiset.map encode s)) 0)) s) = s
α: Type ?u.47763

β: Type ?u.47766

inst✝¹: Denumerable α

inst✝: Denumerable β

s: Multiset α

this: raise (lower (Multiset.sort (fun x x_1 => x x_1) (Multiset.map encode s)) 0) 0 = Multiset.sort (fun x x_1 => x x_1) (Multiset.map encode s)


(fun n => Multiset.map (ofNat α) ↑(raise (ofNat (List ) n) 0)) ((fun s => encode (lower (Multiset.sort (fun x x_1 => x x_1) (Multiset.map encode s)) 0)) s) = s
α: Type ?u.47763

β: Type ?u.47766

inst✝¹: Denumerable α

inst✝: Denumerable β

s: Multiset α


(fun n => Multiset.map (ofNat α) ↑(raise (ofNat (List ) n) 0)) ((fun s => encode (lower (Multiset.sort (fun x x_1 => x x_1) (Multiset.map encode s)) 0)) s) = s

Goals accomplished! 🐙
, fun
n: ?m.48368
n
=>

Goals accomplished! 🐙
α: Type ?u.47763

β: Type ?u.47766

inst✝¹: Denumerable α

inst✝: Denumerable β

n:


(fun s => encode (lower (Multiset.sort (fun x x_1 => x x_1) (Multiset.map encode s)) 0)) ((fun n => Multiset.map (ofNat α) ↑(raise (ofNat (List ) n) 0)) n) = n

Goals accomplished! 🐙
#align denumerable.multiset
Denumerable.multiset: {α : Type u_1} → [inst : Denumerable α] → Denumerable (Multiset α)
Denumerable.multiset
end Multiset section Finset /-- Outputs the list of differences minus one of the input list, that is `lower' [a₁, a₂, a₃, ...] n = [a₁ - n, a₂ - a₁ - 1, a₃ - a₂ - 1, ...]`. -/ def
lower': List List
lower'
:
List: Type ?u.55277 → Type ?u.55277
List
: Type
: Type
List: Type ?u.55281 → Type ?u.55281
List
: Type
| [], _ =>
[]: List ?m.55307
[]
|
m:
m
:: l,
n:
n
=> (
m:
m
-
n:
n
) ::
lower': List List
lower'
l (
m:
m
+
1: ?m.55385
1
) #align denumerable.lower'
Denumerable.lower': List List
Denumerable.lower'
/-- Outputs the list of partial sums plus one of the input list, that is `raise [a₁, a₂, a₃, ...] n = [n + a₁, n + a₁ + a₂ + 1, n + a₁ + a₂ + a₃ + 2, ...]`. Adding one each time ensures the elements are distinct. -/ def
raise': List List
raise'
:
List: Type ?u.55753 → Type ?u.55753
List
: Type
: Type
List: Type ?u.55757 → Type ?u.55757
List
: Type
| [], _ =>
[]: List ?m.55783
[]
|
m:
m
:: l,
n:
n
=> (
m:
m
+
n:
n
) ::
raise': List List
raise'
l (
m:
m
+
n:
n
+
1: ?m.55862
1
) #align denumerable.raise'
Denumerable.raise': List List
Denumerable.raise'
theorem
lower_raise': ∀ (l : List ) (n : ), lower' (raise' l n) n = l
lower_raise'
: ∀
l: ?m.56226
l
n: ?m.56229
n
,
lower': List List
lower'
(
raise': List List
raise'
l: ?m.56226
l
n: ?m.56229
n
)
n: ?m.56229
n
=
l: ?m.56226
l
| [],
n:
n
=>
rfl: ∀ {α : Sort ?u.56261} {a : α}, a = a
rfl
|
m:
m
:: l,
n:
n
=>

Goals accomplished! 🐙
α: Type ?u.56213

β: Type ?u.56216

inst✝¹: Denumerable α

inst✝: Denumerable β

m:

l: List

n:


lower' (raise' (m :: l) n) n = m :: l

Goals accomplished! 🐙
#align denumerable.lower_raise'
Denumerable.lower_raise': ∀ (l : List ) (n : ), lower' (raise' l n) n = l
Denumerable.lower_raise'
theorem
raise_lower': ∀ {l : List } {n : }, (∀ (m : ), m ln m) → Sorted (fun x x_1 => x < x_1) lraise' (lower' l n) n = l
raise_lower'
: ∀ {
l: ?m.58438
l
n: ?m.58441
n
}, (∀
m: ?m.58446
m
l: ?m.58438
l
,
n: ?m.58441
n
m: ?m.58446
m
) →
List.Sorted: {α : Type ?u.58545} → (ααProp) → List αProp
List.Sorted
(· < ·): Prop
(· < ·)
l: ?m.58438
l
raise': List List
raise'
(
lower': List List
lower'
l: ?m.58438
l
n: ?m.58441
n
)
n: ?m.58441
n
=
l: ?m.58438
l
| [],
n:
n
, _, _ =>
rfl: ∀ {α : Sort ?u.58733} {a : α}, a = a
rfl
|
m:
m
:: l,
n:
n
,
h₁: ∀ (m_1 : ), m_1 m :: ln m_1
h₁
,
h₂: Sorted (fun x x_1 => x < x_1) (m :: l)
h₂
=>

Goals accomplished! 🐙
α: Type ?u.58425

β: Type ?u.58428

inst✝¹: Denumerable α

inst✝: Denumerable β

m:

l: List

n:

h₁: ∀ (m_1 : ), m_1 m :: ln m_1

h₂: Sorted (fun x x_1 => x < x_1) (m :: l)


raise' (lower' (m :: l) n) n = m :: l
α: Type ?u.58425

β: Type ?u.58428

inst✝¹: Denumerable α

inst✝: Denumerable β

m:

l: List

n:

h₁: ∀ (m_1 : ), m_1 m :: ln m_1

h₂: Sorted (fun x x_1 => x < x_1) (m :: l)

this: n m


raise' (lower' (m :: l) n) n = m :: l
α: Type ?u.58425

β: Type ?u.58428

inst✝¹: Denumerable α

inst✝: Denumerable β

m:

l: List

n:

h₁: ∀ (m_1 : ), m_1 m :: ln m_1

h₂: Sorted (fun x x_1 => x < x_1) (m :: l)


raise' (lower' (m :: l) n) n = m :: l

Goals accomplished! 🐙
#align denumerable.raise_lower'
Denumerable.raise_lower': ∀ {l : List } {n : }, (∀ (m : ), m ln m) → Sorted (fun x x_1 => x < x_1) lraise' (lower' l n) n = l
Denumerable.raise_lower'
theorem
raise'_chain: ∀ (l : List ) {m n : }, m < nChain (fun x x_1 => x < x_1) m (raise' l n)
raise'_chain
: ∀ (
l: ?m.60490
l
) {
m: ?m.60493
m
n: ?m.60496
n
},
m: ?m.60493
m
<
n: ?m.60496
n
List.Chain: {α : Type ?u.60551} → (ααProp) → αList αProp
List.Chain
(· < ·): Prop
(· < ·)
m: ?m.60493
m
(
raise': List List
raise'
l: ?m.60490
l
n: ?m.60496
n
) | [], _, _, _ =>
List.Chain.nil: ∀ {α : Type ?u.60685} {R : ααProp} {a : α}, Chain R a []
List.Chain.nil
| _ :: _, _, _,
h: x✝¹ < x✝
h
=>
List.Chain.cons: ∀ {α : Type ?u.60758} {R : ααProp} {a b : α} {l : List α}, R a bChain R b lChain R a (b :: l)
List.Chain.cons
(
lt_of_lt_of_le: ∀ {α : Type ?u.60771} [inst : Preorder α] {a b c : α}, a < bb ca < c
lt_of_lt_of_le
h: x✝¹ < x✝
h
(
Nat.le_add_left: ∀ (n m : ), n m + n
Nat.le_add_left
_:
_
_:
_
)) (
raise'_chain: ∀ (l : List ) {m n : }, m < nChain (fun x x_1 => x < x_1) m (raise' l n)
raise'_chain
_ (
lt_succ_self: ∀ (n : ), n < succ n
lt_succ_self
_:
_
)) #align denumerable.raise'_chain
Denumerable.raise'_chain: ∀ (l : List ) {m n : }, m < nChain (fun x x_1 => x < x_1) m (raise' l n)
Denumerable.raise'_chain
/-- `raise' l n` is a strictly increasing sequence. -/ theorem
raise'_sorted: ∀ (l : List ) (n : ), Sorted (fun x x_1 => x < x_1) (raise' l n)
raise'_sorted
: ∀
l: ?m.61172
l
n: ?m.61175
n
,
List.Sorted: {α : Type ?u.61178} → (ααProp) → List αProp
List.Sorted
(· < ·): Prop
(· < ·)
(
raise': List List
raise'
l: ?m.61172
l
n: ?m.61175
n
) | [], _ =>
List.sorted_nil: ∀ {α : Type ?u.61285} {r : ααProp}, Sorted r []
List.sorted_nil
| _ :: _, _ =>
List.chain_iff_pairwise: ∀ {α : Type ?u.61334} {R : ααProp} [inst : IsTrans α R] {a : α} {l : List α}, Chain R a l List.Pairwise R (a :: l)
List.chain_iff_pairwise
.
1: ∀ {a b : Prop}, (a b) → ab
1
(
raise'_chain: ∀ (l : List ) {m n : }, m < nChain (fun x x_1 => x < x_1) m (raise' l n)
raise'_chain
_ (
lt_succ_self: ∀ (n : ), n < succ n
lt_succ_self
_:
_
)) #align denumerable.raise'_sorted
Denumerable.raise'_sorted: ∀ (l : List ) (n : ), Sorted (fun x x_1 => x < x_1) (raise' l n)
Denumerable.raise'_sorted
/-- Makes `raise' l n` into a finset. Elements are distinct thanks to `raise'_sorted`. -/ def
raise'Finset: List Finset
raise'Finset
(l :
List: Type ?u.61633 → Type ?u.61633
List
: Type
) (
n:
n
:
: Type
) :
Finset: Type ?u.61638 → Type ?u.61638
Finset
: Type
:= ⟨
raise': List List
raise'
l
n:
n
, (
raise'_sorted: ∀ (l : List ) (n : ), Sorted (fun x x_1 => x < x_1) (raise' l n)
raise'_sorted
_
_:
_
).
imp: ∀ {α : Type ?u.61755} {R S : ααProp}, (∀ {a b : α}, R a bS a b) → ∀ {l : List α}, List.Pairwise R lList.Pairwise S l
imp
(@
ne_of_lt: ∀ {α : Type ?u.61765} [inst : Preorder α] {a b : α}, a < ba b
ne_of_lt
_: Type ?u.61765
_
_)⟩ #align denumerable.raise'_finset
Denumerable.raise'Finset: List Finset
Denumerable.raise'Finset
/-- If `α` is denumerable, then so is `Finset α`. Warning: this is *not* the same encoding as used in `Finset.encodable`. -/ instance
finset: {α : Type u_1} → [inst : Denumerable α] → Denumerable (Finset α)
finset
:
Denumerable: Type ?u.62393 → Type ?u.62393
Denumerable
(
Finset: Type ?u.62394 → Type ?u.62394
Finset
α: Type ?u.62381
α
) :=
mk': {α : Type ?u.62396} → α Denumerable α
mk'
fun
s: Finset α
s
:
Finset: Type ?u.62412 → Type ?u.62412
Finset
α: Type ?u.62381
α
=>
encode: {α : Type ?u.62415} → [self : Encodable α] → α
encode
<|
lower': List List
lower'
((
s: Finset α
s
.
map: {α : Type ?u.62447} → {β : Type ?u.62446} → (α β) → Finset αFinset β
map
(
eqv: (α : Type ?u.62454) → [inst : Denumerable α] → α
eqv
α: Type ?u.62381
α
).
toEmbedding: {α : Sort ?u.62459} → {β : Sort ?u.62458} → α βα β
toEmbedding
).
sort: {α : Type ?u.62469} → (r : ααProp) → [inst : DecidableRel r] → [inst : IsTrans α r] → [inst : IsAntisymm α r] → [inst : IsTotal α r] → Finset αList α
sort
(· ≤ ·): Prop
(· ≤ ·)
)
0: ?m.62778
0
, fun
n: ?m.62802
n
=>
Finset.map: {α : Type ?u.62805} → {β : Type ?u.62804} → (α β) → Finset αFinset β
Finset.map
(
eqv: (α : Type ?u.62808) → [inst : Denumerable α] → α
eqv
α: Type ?u.62381
α
).
symm: {α : Sort ?u.62811} → {β : Sort ?u.62810} → α ββ α
symm
.
toEmbedding: {α : Sort ?u.62815} → {β : Sort ?u.62814} → α βα β
toEmbedding
(
raise'Finset: List Finset
raise'Finset
(
ofNat: (α : Type ?u.62827) → [inst : Denumerable α] → α
ofNat
(
List: Type ?u.62828 → Type ?u.62828
List
: Type
)
n: ?m.62802
n
)
0: ?m.62837
0
), fun
s: ?m.62842
s
=>
Finset.eq_of_veq: ∀ {α : Type ?u.62844} {s t : Finset α}, s.val = t.vals = t
Finset.eq_of_veq
<|

Goals accomplished! 🐙
α: Type ?u.62381

β: Type ?u.62384

inst✝¹: Denumerable α

inst✝: Denumerable β

s: Finset α


((fun n => Finset.map (Equiv.toEmbedding (eqv α).symm) (raise'Finset (ofNat (List ) n) 0)) ((fun s => encode (lower' (Finset.sort (fun x x_1 => x x_1) (Finset.map (Equiv.toEmbedding (eqv α)) s)) 0)) s)).val = s.val

Goals accomplished! 🐙
, fun
n: ?m.62857
n
=>

Goals accomplished! 🐙
α: Type ?u.62381

β: Type ?u.62384

inst✝¹: Denumerable α

inst✝: Denumerable β

n:


(fun s => encode (lower' (Finset.sort (fun x x_1 => x x_1) (Finset.map (Equiv.toEmbedding (eqv α)) s)) 0)) ((fun n => Finset.map (Equiv.toEmbedding (eqv α).symm) (raise'Finset (ofNat (List ) n) 0)) n) = n

Goals accomplished! 🐙
#align denumerable.finset
Denumerable.finset: {α : Type u_1} → [inst : Denumerable α] → Denumerable (Finset α)
Denumerable.finset
end Finset end Denumerable namespace Equiv /-- The type lists on unit is canonically equivalent to the natural numbers. -/ def
listUnitEquiv: List Unit
listUnitEquiv
:
List: Type ?u.67871 → Type ?u.67871
List
Unit: Type
Unit
: Type
where toFun :=
List.length: {α : Type ?u.67879} → List α
List.length
invFun
n: ?m.67886
n
:=
List.replicate: {α : Type ?u.67888} → αList α
List.replicate
n: ?m.67886
n
(): Unit
()
left_inv
u: ?m.67893
u
:=
List.length_injective: ∀ {α : Type ?u.67895} [inst : Subsingleton α], Function.Injective length
List.length_injective
(

Goals accomplished! 🐙

length ((fun n => replicate n ()) (length u)) = length u

Goals accomplished! 🐙
) right_inv
n: ?m.67954
n
:=
List.length_replicate: ∀ {α : Type ?u.67956} (n : ) (a : α), length (replicate n a) = n
List.length_replicate
n: ?m.67954
n
(): Unit
()
#align equiv.list_unit_equiv
Equiv.listUnitEquiv: List Unit
Equiv.listUnitEquiv
/-- `List ℕ` is equivalent to `ℕ`. -/ def
listNatEquivNat: List
listNatEquivNat
:
List: Type ?u.68120 → Type ?u.68120
List
: Type
: Type
:=
Denumerable.eqv: (α : Type ?u.68122) → [inst : Denumerable α] → α
Denumerable.eqv
_: Type ?u.68122
_
#align equiv.list_nat_equiv_nat
Equiv.listNatEquivNat: List
Equiv.listNatEquivNat
/-- If `α` is equivalent to `ℕ`, then `List α` is equivalent to `α`. -/ def
listEquivSelfOfEquivNat: {α : Type u_1} → α List α α
listEquivSelfOfEquivNat
{
α: Type ?u.68320
α
:
Type _: Type (?u.68320+1)
Type _
} (
e: α
e
:
α: Type ?u.68320
α
: Type
) :
List: Type ?u.68329 → Type ?u.68329
List
α: Type ?u.68320
α
α: Type ?u.68320
α
:= calc
List: Type ?u.68336 → Type ?u.68336
List
α: Type ?u.68320
α
List: Type ?u.68337 → Type ?u.68337
List
: Type
:=
listEquivOfEquiv: {α : Type ?u.68339} → {β : Type ?u.68338} → α βList α List β
listEquivOfEquiv
e: α
e
_: ?m✝
_
: Type
:=
listNatEquivNat: List
listNatEquivNat
_: ?m✝
_
α: Type ?u.68320
α
:=
e: α
e
.
symm: {α : Sort ?u.68419} → {β : Sort ?u.68418} → α ββ α
symm
#align equiv.list_equiv_self_of_equiv_nat
Equiv.listEquivSelfOfEquivNat: {α : Type u_1} → α List α α
Equiv.listEquivSelfOfEquivNat
end Equiv