Encodable types #
This file defines encodable (constructively countable) types as a typeclass.
This is used to provide explicit encode/decode functions from and to ℕ, with the information that
those functions are inverses of each other.
The difference with Denumerable is that finite types are encodable. For infinite types,
Encodable and Denumerable agree.
Main declarations #
Encodable α: States that there exists an explicit encoding functionencode : α → ℕwith a partial inversedecode : ℕ → Option α.decode₂: Version ofdecodethat is equal tononeoutside of the range ofencode. Useful as we do not require this in the definition ofdecode.ULower α: Any encodable type has an equivalent type living in the lowest universe, namely a subtype ofℕ.ULower αfinds it.
Implementation notes #
The point of asking for an explicit partial inverse decode : ℕ → Option α to encode : α → ℕ is
to make the range of encode decidable even when the finiteness of α is not.
- encode : α → ℕ
Encoding from Type α to ℕ
Decoding from ℕ to Option α
- encodek : ∀ (a : α), Encodable.decode (Encodable.encode a) = some a
Invariant relationship between encoding and decoding
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.
Instances
An encodable type has decidable equality. Not set as an instance because this is usually not the best way to infer decidability.
Equations
- One or more equations did not get rendered due to their size.
Instances For
If α is encodable and there is an injection f : β → α, then β is encodable as well.
Equations
- One or more equations did not get rendered due to their size.
Instances For
If α is encodable and f : β → α is invertible, then β is encodable as well.
Equations
- Encodable.ofLeftInverse f finv linv = Encodable.ofLeftInjection f (some ∘ finv) (_ : ∀ (b : β), some (finv (f b)) = some b)
Instances For
Encodability is preserved by equivalence.
Equations
- Encodable.ofEquiv α e = Encodable.ofLeftInverse ↑e ↑e.symm (_ : Function.LeftInverse e.invFun e.toFun)
Instances For
Equations
- Nat.encodable = { encode := id, decode := some, encodek := Nat.encodable.proof_1 }
Equations
- IsEmpty.toEncodable = { encode := fun a => isEmptyElim a, decode := fun x => none, encodek := (_ : ∀ (a : α), (fun x => none) ((fun a => isEmptyElim a) a) = some a) }
Equations
- PUnit.encodable = { encode := fun x => 0, decode := fun n => Nat.casesOn n (some PUnit.unit) fun x => none, encodek := PUnit.encodable.proof_1 }
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.
Equations
- Encodable.decode₂ α n = Option.bind (Encodable.decode n) (Option.guard fun a => Encodable.encode a = n)
Instances For
The encoding function has decidable range.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A type with unique element is encodable. This is not an instance to avoid diamonds.
Equations
Instances For
Explicit encoding function for the sum of two encodable types.
Equations
- Encodable.encodeSum x = match x with | Sum.inl a => 2 * Encodable.encode a | Sum.inr b => 2 * Encodable.encode b + 1
Instances For
Explicit decoding function for the sum of two encodable types.
Equations
- Encodable.decodeSum n = match Nat.boddDiv2 n with | (false, m) => Option.map Sum.inl (Encodable.decode m) | (fst, m) => Option.map Sum.inr (Encodable.decode m)
Instances For
If α and β are encodable, then so is their sum.
Equations
- Sum.encodable = { encode := Encodable.encodeSum, decode := Encodable.decodeSum, encodek := (_ : ∀ (s : α ⊕ β), Encodable.decodeSum (Encodable.encodeSum s) = some s) }
Explicit encoding function for Sigma γ
Equations
- Encodable.encodeSigma x = match x with | { fst := a, snd := b } => Nat.pair (Encodable.encode a) (Encodable.encode b)
Instances For
Explicit decoding function for Sigma γ
Equations
- Encodable.decodeSigma n = match Nat.unpair n with | (n₁, n₂) => Option.bind (Encodable.decode n₁) fun a => Option.map (Sigma.mk a) (Encodable.decode n₂)
Instances For
Equations
- Sigma.encodable = { encode := Encodable.encodeSigma, decode := Encodable.decodeSigma, encodek := (_ : ∀ (x : Sigma γ), Encodable.decodeSigma (Encodable.encodeSigma x) = some x) }
If α and β are encodable, then so is their product.
Equations
- Encodable.Prod.encodable = Encodable.ofEquiv ((_ : α) × β) (Equiv.sigmaEquivProd α β).symm
Explicit encoding function for a decidable subtype of an encodable type
Equations
- Encodable.encodeSubtype x = match x with | { val := v, property := property } => Encodable.encode v
Instances For
Explicit decoding function for a decidable subtype of an encodable type
Equations
- Encodable.decodeSubtype v = Option.bind (Encodable.decode v) fun a => if h : P a then some { val := a, property := h } else none
Instances For
A decidable subtype of an encodable type is encodable.
Equations
- Subtype.encodable = { encode := Encodable.encodeSubtype, decode := Encodable.decodeSubtype, encodek := (_ : ∀ (x : { a // P a }), Encodable.decodeSubtype (Encodable.encodeSubtype x) = some x) }
Equations
- Fin.encodable n = Encodable.ofEquiv { i // i < n } Fin.equivSubtype
Equations
Equations
The lift of an encodable type is encodable
Equations
- ULift.encodable = Encodable.ofEquiv α Equiv.ulift
The lift of an encodable type is encodable.
Equations
- PLift.encodable = Encodable.ofEquiv α Equiv.plift
If β is encodable and there is an injection f : α → β, then α is encodable as well.
Equations
- Encodable.ofInj f hf = Encodable.ofLeftInjection f (Function.partialInv f) (_ : ∀ (x : α), Function.partialInv f (f x) = some x)
Instances For
If α is countable, then it has a (non-canonical) Encodable structure.
Equations
- Encodable.ofCountable α = Nonempty.some (_ : Nonempty (Encodable α))
Instances For
Equations
Equations
- instDecidableEqULower = id (Encodable.decidableEqOfEncodable ↑(Set.range Encodable.encode))
Equations
- ULower.instInhabitedULower = { default := ULower.down default }
Constructive choice function for a decidable subtype of an encodable type.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Constructive choice function for a decidable predicate over an encodable type.
Equations
- Encodable.choose h = ↑(Encodable.chooseX h)
Instances For
A constructive version of Classical.axiom_of_choice for Encodable types.
A constructive version of Classical.skolem for Encodable types.
The encode function, viewed as an embedding.
Equations
- Encodable.encode' α = { toFun := Encodable.encode, inj' := (_ : Function.Injective Encodable.encode) }
Instances For
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
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)).
Equations
- Directed.sequence f hf 0 = default
- Directed.sequence f hf (Nat.succ n) = let p := Directed.sequence f hf n; match Encodable.decode n with | none => Classical.choose (hf p p) | some a => Classical.choose (hf p a)
Instances For
Representative of an equivalence class. This is a computable version of Quot.out for a setoid
on an encodable type.
Equations
- Quotient.rep q = Encodable.choose (_ : ∃ a, Quotient.mk s a = q)
Instances For
The quotient of an encodable space by a decidable equivalence relation is encodable.
Equations
- One or more equations did not get rendered due to their size.