File: Mathlib/Logic/Encodable/Basic.lean

full_name: Encodable.decode
code: /-- Constructively countable type. Made from an explicit injection `encode : α → ℕ` and a partial
inverse `decode : ℕ → Option α`. Note that finite types *are* countable. See `Denumerable` if you
wish to enforce infiniteness. -/
class Encodable (α : Type*) where
  /-- Encoding from Type α to ℕ -/
  encode : α → ℕ
  -- Porting note: was `decode [] : ℕ → Option α`. This means that `decode` does not take the type
  --explicitly in Lean4
  /-- Decoding from ℕ to Option α-/
  decode : ℕ → Option α
  /-- Invariant relationship between encoding and decoding-/
  encodek : ∀ a, decode (encode a) = some a
goal: ℕ → Option α

full_name: Encodable
code: /-- Constructively countable type. Made from an explicit injection `encode : α → ℕ` and a partial
inverse `decode : ℕ → Option α`. Note that finite types *are* countable. See `Denumerable` if you
wish to enforce infiniteness. -/
class Encodable (α : Type*) where
  /-- Encoding from Type α to ℕ -/
  encode : α → ℕ
  -- Porting note: was `decode [] : ℕ → Option α`. This means that `decode` does not take the type
  --explicitly in Lean4
  /-- Decoding from ℕ to Option α-/
  decode : ℕ → Option α
  /-- Invariant relationship between encoding and decoding-/
  encodek : ∀ a, decode (encode a) = some a
goal: Type u_1

full_name: Encodable.encodek
code: /-- Constructively countable type. Made from an explicit injection `encode : α → ℕ` and a partial
inverse `decode : ℕ → Option α`. Note that finite types *are* countable. See `Denumerable` if you
wish to enforce infiniteness. -/
class Encodable (α : Type*) where
  /-- Encoding from Type α to ℕ -/
  encode : α → ℕ
  -- Porting note: was `decode [] : ℕ → Option α`. This means that `decode` does not take the type
  --explicitly in Lean4
  /-- Decoding from ℕ to Option α-/
  decode : ℕ → Option α
  /-- Invariant relationship between encoding and decoding-/
  encodek : ∀ a, decode (encode a) = some a
goal: Encodable.decode (Encodable.encode a) = some a

full_name: Encodable.encode
code: /-- Constructively countable type. Made from an explicit injection `encode : α → ℕ` and a partial
inverse `decode : ℕ → Option α`. Note that finite types *are* countable. See `Denumerable` if you
wish to enforce infiniteness. -/
class Encodable (α : Type*) where
  /-- Encoding from Type α to ℕ -/
  encode : α → ℕ
  -- Porting note: was `decode [] : ℕ → Option α`. This means that `decode` does not take the type
  --explicitly in Lean4
  /-- Decoding from ℕ to Option α-/
  decode : ℕ → Option α
  /-- Invariant relationship between encoding and decoding-/
  encodek : ∀ a, decode (encode a) = some a
goal: α → ℕ

full_name: Encodable.encode_injective
code: theorem encode_injective [Encodable α] : Function.Injective (@encode α _)
  
goal: Function.Injective Encodable.encode

full_name: Encodable.encode_inj
code: @[simp]
theorem encode_inj [Encodable α] {a b : α} : encode a = encode b ↔ a = b 
goal: Encodable.encode a = Encodable.encode b ↔ a = b

full_name: Encodable.countable
code: instance (priority := 400) countable [Encodable α] : Countable α 
goal: Countable α

full_name: Encodable.surjective_decode_iget
code: theorem surjective_decode_iget (α : Type*) [Encodable α] [Inhabited α] :
    Surjective fun n => ((Encodable.decode n).iget : α) 
goal: Function.Surjective fun n => (Encodable.decode n).iget

full_name: Encodable.decidableEqOfEncodable
code: /-- An encodable type has decidable equality. Not set as an instance because this is usually not the
best way to infer decidability. -/
def decidableEqOfEncodable (α) [Encodable α] : DecidableEq α
  
goal: DecidableEq α

full_name: Encodable.ofLeftInjection
code: /-- If `α` is encodable and there is an injection `f : β → α`, then `β` is encodable as well. -/
def ofLeftInjection [Encodable α] (f : β → α) (finv : α → Option β)
    (linv : ∀ b, finv (f b) = some b) : Encodable β 
goal: Encodable β

full_name: Encodable.ofLeftInverse
code: /-- If `α` is encodable and `f : β → α` is invertible, then `β` is encodable as well. -/
def ofLeftInverse [Encodable α] (f : β → α) (finv : α → β) (linv : ∀ b, finv (f b) = b) :
    Encodable β 
goal: Encodable β

full_name: Encodable.ofEquiv
code: /-- Encodability is preserved by equivalence. -/
def ofEquiv (α) [Encodable α] (e : β ≃ α) : Encodable β 
goal: Encodable β

full_name: Encodable.encode_ofEquiv
code: theorem encode_ofEquiv {α β} [Encodable α] (e : β ≃ α) (b : β) :
    @encode _ (ofEquiv _ e) b = encode (e b) 
goal: Encodable.encode b = Encodable.encode (e b)

full_name: Encodable.decode_ofEquiv
code: theorem decode_ofEquiv {α β} [Encodable α] (e : β ≃ α) (n : ℕ) :
    @decode _ (ofEquiv _ e) n = (decode n).map e.symm 
goal: Encodable.decode n = Option.map (⇑e.symm) (Encodable.decode n)

full_name: Nat.encodable
code: instance _root_.Nat.encodable : Encodable ℕ 
goal: Encodable ℕ

full_name: Encodable.encode_nat
code: @[simp]
theorem encode_nat (n : ℕ) : encode n = n 
goal: Encodable.encode n = n

full_name: Encodable.decode_nat
code: @[simp 1100]
theorem decode_nat (n : ℕ) : decode n = some n 
goal: Encodable.decode n = some n

full_name: IsEmpty.toEncodable
code: instance (priority := 100) _root_.IsEmpty.toEncodable [IsEmpty α] : Encodable α 
goal: Encodable α

full_name: PUnit.encodable
code: instance _root_.PUnit.encodable : Encodable PUnit 
goal: Encodable PUnit.{u_3 + 1}

full_name: Encodable.encode_star
code: @[simp]
theorem encode_star : encode PUnit.unit = 0 
goal: Encodable.encode PUnit.unit = 0

full_name: Encodable.decode_unit_zero
code: @[simp]
theorem decode_unit_zero : decode 0 = some PUnit.unit 
goal: Encodable.decode 0 = some PUnit.unit

full_name: Encodable.decode_unit_succ
code: @[simp]
theorem decode_unit_succ (n) : decode (succ n) = (none : Option PUnit) 
goal: Encodable.decode n.succ = none

full_name: Option.encodable
code: /-- If `α` is encodable, then so is `Option α`. -/
instance _root_.Option.encodable {α : Type*} [h : Encodable α] : Encodable (Option α) 
goal: Encodable (Option α)

full_name: Encodable.encode_none
code: @[simp]
theorem encode_none [Encodable α] : encode (@none α) = 0 
goal: Encodable.encode none = 0

full_name: Encodable.encode_some
code: @[simp]
theorem encode_some [Encodable α] (a : α) : encode (some a) = succ (encode a) 
goal: Encodable.encode (some a) = (Encodable.encode a).succ

full_name: Encodable.decode_option_zero
code: @[simp]
theorem decode_option_zero [Encodable α] : (decode 0 : Option (Option α))= some none 
goal: Encodable.decode 0 = some none

full_name: Encodable.decode_option_succ
code: @[simp]
theorem decode_option_succ [Encodable α] (n) :
    (decode (succ n) : Option (Option α)) = (decode n).map some 
goal: Encodable.decode n.succ = Option.map some (Encodable.decode n)

full_name: Encodable.decode₂
code: /-- Failsafe variant of `decode`. `decode₂ α n` returns the preimage of `n` under `encode` if it
exists, and returns `none` if it doesn't. This requirement could be imposed directly on `decode` but
is not to help make the definition easier to use. -/
def decode₂ (α) [Encodable α] (n : ℕ) : Option α 
goal: Option α

full_name: Encodable.mem_decode₂'
code: theorem mem_decode₂' [Encodable α] {n : ℕ} {a : α} :
    a ∈ decode₂ α n ↔ a ∈ decode n ∧ encode a = n 
goal: a ∈ Encodable.decode₂ α n ↔ a ∈ Encodable.decode n ∧ Encodable.encode a = n

full_name: Encodable.mem_decode₂
code: theorem mem_decode₂ [Encodable α] {n : ℕ} {a : α} : a ∈ decode₂ α n ↔ encode a = n 
goal: a ∈ Encodable.decode₂ α n ↔ Encodable.encode a = n

full_name: Encodable.decode₂_eq_some
code: theorem decode₂_eq_some [Encodable α] {n : ℕ} {a : α} : decode₂ α n = some a ↔ encode a = n 
goal: Encodable.decode₂ α n = some a ↔ Encodable.encode a = n

full_name: Encodable.decode₂_encode
code: @[simp]
theorem decode₂_encode [Encodable α] (a : α) : decode₂ α (encode a) = some a 
goal: Encodable.decode₂ α (Encodable.encode a) = some a

full_name: Encodable.decode₂_ne_none_iff
code: theorem decode₂_ne_none_iff [Encodable α] {n : ℕ} :
    decode₂ α n ≠ none ↔ n ∈ Set.range (encode : α → ℕ) 
goal: Encodable.decode₂ α n ≠ none ↔ n ∈ Set.range Encodable.encode

full_name: Encodable.decode₂_is_partial_inv
code: theorem decode₂_is_partial_inv [Encodable α] : IsPartialInv encode (decode₂ α) 
goal: Function.IsPartialInv Encodable.encode (Encodable.decode₂ α)

full_name: Encodable.decode₂_inj
code: theorem decode₂_inj [Encodable α] {n : ℕ} {a₁ a₂ : α} (h₁ : a₁ ∈ decode₂ α n)
    (h₂ : a₂ ∈ decode₂ α n) : a₁ = a₂ 
goal: a₁ = a₂

full_name: Encodable.encodek₂
code: theorem encodek₂ [Encodable α] (a : α) : decode₂ α (encode a) = some a 
goal: Encodable.decode₂ α (Encodable.encode a) = some a

full_name: Encodable.decidableRangeEncode
code: /-- The encoding function has decidable range. -/
def decidableRangeEncode (α : Type*) [Encodable α] : DecidablePred (· ∈ Set.range (@encode α _)) 
goal: DecidablePred fun x => x ∈ Set.range Encodable.encode

full_name: Encodable.equivRangeEncode
code: /-- An encodable type is equivalent to the range of its encoding function. -/
def equivRangeEncode (α : Type*) [Encodable α] : α ≃ Set.range (@encode α _) 
goal: α ≃ ↑(Set.range Encodable.encode)

full_name: Unique.encodable
code: /-- A type with unique element is encodable. This is not an instance to avoid diamonds. -/
def _root_.Unique.encodable [Unique α] : Encodable α 
goal: Encodable α

full_name: Encodable.encodeSum
code: /-- Explicit encoding function for the sum of two encodable types. -/
def encodeSum : α ⊕ β → ℕ
  
goal: α ⊕ β → ℕ

full_name: Encodable.decodeSum
code: /-- Explicit decoding function for the sum of two encodable types. -/
def decodeSum (n : ℕ) : Option (α ⊕ β) 
goal: Option (α ⊕ β)

full_name: Sum.encodable
code: /-- If `α` and `β` are encodable, then so is their sum. -/
instance _root_.Sum.encodable : Encodable (α ⊕ β) 
goal: Encodable (α ⊕ β)

full_name: Encodable.encode_inl
code: @[simp]
theorem encode_inl (a : α) : @encode (α ⊕ β) _ (Sum.inl a) = 2 * (encode a) 
goal: Encodable.encode (Sum.inl a) = 2 * Encodable.encode a

full_name: Encodable.encode_inr
code: @[simp]
theorem encode_inr (b : β) : @encode (α ⊕ β) _ (Sum.inr b) = 2 * (encode b) + 1 
goal: Encodable.encode (Sum.inr b) = 2 * Encodable.encode b + 1

full_name: Encodable.decode_sum_val
code: @[simp]
theorem decode_sum_val (n : ℕ) : (decode n : Option (α ⊕ β)) = decodeSum n 
goal: Encodable.decode n = Encodable.decodeSum n

full_name: Bool.encodable
code: instance _root_.Bool.encodable : Encodable Bool 
goal: Encodable Bool

full_name: Encodable.encode_true
code: @[simp]
theorem encode_true : encode true = 1 
goal: Encodable.encode true = 1

full_name: Encodable.encode_false
code: @[simp]
theorem encode_false : encode false = 0 
goal: Encodable.encode false = 0

full_name: Encodable.decode_zero
code: @[simp]
theorem decode_zero : (decode 0 : Option Bool) = some false 
goal: Encodable.decode 0 = some false

full_name: Encodable.decode_one
code: @[simp]
theorem decode_one : (decode 1 : Option Bool) = some true 
goal: Encodable.decode 1 = some true

full_name: Encodable.decode_ge_two
code: theorem decode_ge_two (n) (h : 2 ≤ n) : (decode n : Option Bool) = none 
goal: Encodable.decode n = none

full_name: Prop.encodable
code: noncomputable instance _root_.Prop.encodable : Encodable Prop 
goal: Encodable Prop

full_name: Encodable.encodeSigma
code: /-- Explicit encoding function for `Sigma γ` -/
def encodeSigma : Sigma γ → ℕ
  
goal: Sigma γ → ℕ

full_name: Encodable.decodeSigma
code: /-- Explicit decoding function for `Sigma γ` -/
def decodeSigma (n : ℕ) : Option (Sigma γ) 
goal: Option (Sigma γ)

full_name: Sigma.encodable
code: instance _root_.Sigma.encodable : Encodable (Sigma γ) 
goal: Encodable (Sigma γ)

full_name: Encodable.decode_sigma_val
code: @[simp]
theorem decode_sigma_val (n : ℕ) :
    (decode n : Option (Sigma γ)) =
      (decode n.unpair.1).bind fun a => (decode n.unpair.2).map <| Sigma.mk a 
goal: Encodable.decode n =
  (Encodable.decode (Nat.unpair n).1).bind fun a => Option.map (Sigma.mk a) (Encodable.decode (Nat.unpair n).2)

full_name: Encodable.encode_sigma_val
code: @[simp]
theorem encode_sigma_val (a b) : @encode (Sigma γ) _ ⟨a, b⟩ = pair (encode a) (encode b) 
goal: Encodable.encode ⟨a, b⟩ = Nat.pair (Encodable.encode a) (Encodable.encode b)

full_name: Encodable.Prod.encodable
code: /-- If `α` and `β` are encodable, then so is their product. -/
instance Prod.encodable : Encodable (α × β) 
goal: Encodable (α × β)

full_name: Encodable.decode_prod_val
code: @[simp]
theorem decode_prod_val (n : ℕ) :
    (@decode (α × β) _ n : Option (α × β))
      = (decode n.unpair.1).bind fun a => (decode n.unpair.2).map <| Prod.mk a 
goal: Encodable.decode n =
  (Encodable.decode (Nat.unpair n).1).bind fun a => Option.map (Prod.mk a) (Encodable.decode (Nat.unpair n).2)

full_name: Encodable.encode_prod_val
code: @[simp]
theorem encode_prod_val (a b) : @encode (α × β) _ (a, b) = pair (encode a) (encode b) 
goal: Encodable.encode (a, b) = Nat.pair (Encodable.encode a) (Encodable.encode b)

full_name: Encodable.encodeSubtype
code: /-- Explicit encoding function for a decidable subtype of an encodable type -/
def encodeSubtype : { a : α // P a } → ℕ
  
goal: { a // P a } → ℕ

full_name: Encodable.decodeSubtype
code: /-- Explicit decoding function for a decidable subtype of an encodable type -/
def decodeSubtype (v : ℕ) : Option { a : α // P a } 
goal: Option { a // P a }

full_name: Subtype.encodable
code: /-- A decidable subtype of an encodable type is encodable. -/
instance _root_.Subtype.encodable : Encodable { a : α // P a } 
goal: Encodable { a // P a }

full_name: Encodable.Subtype.encode_eq
code: theorem Subtype.encode_eq (a : Subtype P) : encode a = encode a.val 
goal: Encodable.encode a = Encodable.encode ↑a

full_name: Fin.encodable
code: instance _root_.Fin.encodable (n) : Encodable (Fin n) 
goal: Encodable (Fin n)

full_name: Int.encodable
code: instance _root_.Int.encodable : Encodable ℤ 
goal: Encodable ℤ

full_name: PNat.encodable
code: instance _root_.PNat.encodable : Encodable ℕ+ 
goal: Encodable ℕ+

full_name: ULift.encodable
code: /-- The lift of an encodable type is encodable -/
instance _root_.ULift.encodable [Encodable α] : Encodable (ULift α) 
goal: Encodable (ULift.{u_3, u_1} α)

full_name: PLift.encodable
code: /-- The lift of an encodable type is encodable. -/
instance _root_.PLift.encodable [Encodable α] : Encodable (PLift α) 
goal: Encodable (PLift α)

full_name: Encodable.ofInj
code: /-- If `β` is encodable and there is an injection `f : α → β`, then `α` is encodable as well. -/
noncomputable def ofInj [Encodable β] (f : α → β) (hf : Injective f) : Encodable α 
goal: Encodable α

full_name: Encodable.ofCountable
code: /-- If `α` is countable, then it has a (non-canonical) `Encodable` structure. -/
noncomputable def ofCountable (α : Type*) [Countable α] : Encodable α 
goal: Encodable α

full_name: Encodable.nonempty_encodable
code: @[simp]
theorem nonempty_encodable : Nonempty (Encodable α) ↔ Countable α 
goal: Nonempty (Encodable α) ↔ Countable α

full_name: nonempty_encodable
code: /-- See also `nonempty_fintype`, `nonempty_denumerable`. -/
theorem nonempty_encodable (α : Type*) [Countable α] : Nonempty (Encodable α) 
goal: Nonempty (Encodable α)

full_name: instCountablePNat
code: instance : Countable ℕ+ 
goal: Countable ℕ+

full_name: ULower
code: /-- `ULower α : Type` is an equivalent type in the lowest universe, given `Encodable α`. -/
def ULower (α : Type*) [Encodable α] : Type 
goal: Type

full_name: instDecidableEqULower
code: instance {α : Type*} [Encodable α] : DecidableEq (ULower α) 
goal: DecidableEq (ULower α)

full_name: instEncodableULower
code: instance {α : Type*} [Encodable α] : Encodable (ULower α) 
goal: Encodable (ULower α)

full_name: ULower.equiv
code: /-- The equivalence between the encodable type `α` and `ULower α : Type`. -/
def equiv : α ≃ ULower α 
goal: α ≃ ULower α

full_name: ULower.down
code: /-- Lowers an `a : α` into `ULower α`. -/
def down (a : α) : ULower α 
goal: ULower α

full_name: ULower.instInhabited
code: instance [Inhabited α] : Inhabited (ULower α) 
goal: Inhabited (ULower α)

full_name: ULower.up
code: /-- Lifts an `a : ULower α` into `α`. -/
def up (a : ULower α) : α 
goal: α

full_name: ULower.down_up
code: @[simp]
theorem down_up {a : ULower α} : down a.up = a 
goal: ULower.down a.up = a

full_name: ULower.up_down
code: @[simp]
theorem up_down {a : α} : (down a).up = a 
goal: (ULower.down a).up = a

full_name: ULower.up_eq_up
code: @[simp]
theorem up_eq_up {a b : ULower α} : a.up = b.up ↔ a = b 
goal: a.up = b.up ↔ a = b

full_name: ULower.down_eq_down
code: @[simp]
theorem down_eq_down {a b : α} : down a = down b ↔ a = b 
goal: ULower.down a = ULower.down b ↔ a = b

full_name: ULower.ext
code: @[ext]
protected theorem ext {a b : ULower α} : a.up = b.up → a = b 
goal: a.up = b.up → a = b

full_name: _private.Mathlib.Logic.Encodable.Basic.0.Encodable.good
code: private def good : Option α → Prop
  
goal: Option α → Prop

full_name: _private.Mathlib.Logic.Encodable.Basic.0.Encodable.decidable_good
code: private def decidable_good : DecidablePred (good p) 
goal: DecidablePred (Encodable.good p)

full_name: Encodable.chooseX
code: /-- Constructive choice function for a decidable subtype of an encodable type. -/
def chooseX (h : ∃ x, p x) : { a : α // p a } 
goal: { a // p a }

full_name: Encodable.choose
code: /-- Constructive choice function for a decidable predicate over an encodable type. -/
def choose (h : ∃ x, p x) : α 
goal: α

full_name: Encodable.choose_spec
code: theorem choose_spec (h : ∃ x, p x) : p (choose h) 
goal: p (Encodable.choose h)

full_name: Encodable.axiom_of_choice
code: /-- A constructive version of `Classical.axiom_of_choice` for `Encodable` types. -/
theorem axiom_of_choice {α : Type*} {β : α → Type*} {R : ∀ x, β x → Prop} [∀ a, Encodable (β a)]
    [∀ x y, Decidable (R x y)] (H : ∀ x, ∃ y, R x y) : ∃ f : ∀ a, β a, ∀ x, R x (f x) 
goal: ∃ f, ∀ (x : α), R x (f x)

full_name: Encodable.skolem
code: /-- A constructive version of `Classical.skolem` for `Encodable` types. -/
theorem skolem {α : Type*} {β : α → Type*} {P : ∀ x, β x → Prop} [∀ a, Encodable (β a)]
    [∀ x y, Decidable (P x y)] : (∀ x, ∃ y, P x y) ↔ ∃ f : ∀ a, β a, ∀ x, P x (f x) 
goal: (∀ (x : α), ∃ y, P x y) ↔ ∃ f, ∀ (x : α), P x (f x)

full_name: Encodable.encode'
code: /-- The `encode` function, viewed as an embedding. -/
def encode' (α) [Encodable α] : α ↪ ℕ 
goal: α ↪ ℕ

full_name: Encodable.instIsAntisymmPreimageNatCoeEmbeddingEncode'Le
code: instance {α} [Encodable α] : IsAntisymm _ (Encodable.encode' α ⁻¹'o (· ≤ ·)) 
goal: IsAntisymm α (⇑(Encodable.encode' α) ⁻¹'o fun x x_1 => x ≤ x_1)

full_name: Encodable.instIsTotalPreimageNatCoeEmbeddingEncode'Le
code: instance {α} [Encodable α] : IsTotal _ (Encodable.encode' α ⁻¹'o (· ≤ ·)) 
goal: IsTotal α (⇑(Encodable.encode' α) ⁻¹'o fun x x_1 => x ≤ x_1)

full_name: Directed.sequence
code: /-- Given a `Directed r` function `f : α → β` defined on an encodable inhabited type,
construct a noncomputable sequence such that `r (f (x n)) (f (x (n + 1)))`
and `r (f a) (f (x (encode a + 1))`. -/
protected noncomputable def sequence {r : β → β → Prop} (f : α → β) (hf : Directed r f) : ℕ → α
  
goal: ℕ → α

full_name: Directed.sequence_mono_nat
code: theorem sequence_mono_nat {r : β → β → Prop} {f : α → β} (hf : Directed r f) (n : ℕ) :
    r (f (hf.sequence f n)) (f (hf.sequence f (n + 1))) 
goal: r (f (Directed.sequence f hf n)) (f (Directed.sequence f hf (n + 1)))

full_name: Directed.rel_sequence
code: theorem rel_sequence {r : β → β → Prop} {f : α → β} (hf : Directed r f) (a : α) :
    r (f a) (f (hf.sequence f (encode a + 1))) 
goal: r (f a) (f (Directed.sequence f hf (Encodable.encode a + 1)))

full_name: Directed.sequence_mono
code: theorem sequence_mono : Monotone (f ∘ hf.sequence f) 
goal: Monotone (f ∘ Directed.sequence f hf)

full_name: Directed.le_sequence
code: theorem le_sequence (a : α) : f a ≤ f (hf.sequence f (encode a + 1)) 
goal: f a ≤ f (Directed.sequence f hf (Encodable.encode a + 1))

full_name: Directed.sequence_anti
code: theorem sequence_anti : Antitone (f ∘ hf.sequence f) 
goal: Antitone (f ∘ Directed.sequence f hf)

full_name: Directed.sequence_le
code: theorem sequence_le (a : α) : f (hf.sequence f (Encodable.encode a + 1)) ≤ f a 
goal: f (Directed.sequence f hf (Encodable.encode a + 1)) ≤ f a

full_name: Quotient.rep
code: /-- Representative of an equivalence class. This is a computable version of `Quot.out` for a setoid
on an encodable type. -/
def Quotient.rep (q : Quotient s) : α 
goal: α

full_name: Quotient.rep_spec
code: theorem Quotient.rep_spec (q : Quotient s) : ⟦q.rep⟧ = q 
goal: ⟦q.rep⟧ = q

full_name: encodableQuotient
code: /-- The quotient of an encodable space by a decidable equivalence relation is encodable. -/
def encodableQuotient : Encodable (Quotient s) 
goal: Encodable (Quotient s)