Zulip Chat Archive

Stream: general

Topic: encodable fintypes


Jeremy Avigad (Jan 16 2020 at 03:20):

Given [fintype α] and [encodable α], we should have α ≃ fin (card α). Does anyone see a nice way to prove that?

Yury G. Kudryashov (Jan 16 2020 at 03:42):

You probably want to_fun x = ⟨card {y : α | encode y < encode x}, _⟩. This function is injective, hence bijective. Then it should be possible to use nat.find to build an inverse.

Yury G. Kudryashov (Jan 16 2020 at 04:00):

Probably we can use fintype.bij_inv and fintype.injective_iff_surjective_of_equiv.

Yury G. Kudryashov (Jan 16 2020 at 04:31):

This works:

import data.fintype data.equiv.encodable tactic.wlog

open fintype encodable function

variables (α : Type*) [fintype α] [encodable α] [decidable_eq α]

theorem fintype.card_subtype_strict_mono [fintype α] {p q : α  Prop} [decidable_pred p]
  [decidable_pred q] (hpq : {x | p x}  {x | q x}) :
  card {x // p x} < card {x // q x} :=
begin
  rw [subtype_card, subtype_card],
  apply finset.card_lt_card,
  simp only [finset.coe_ssubset.symm, set.ssubset_def, set.subset_def,
    finset.mem_coe, finset.mem_filter, finset.mem_univ, true_and],
  exact hpq
end

def equiv_fin_card_of_encodable : α  fin (card α) :=
begin
  set f : α  fin (card α) :=
    λ x, card {y : α | encode y < encode x}, card_subtype_lt $ lt_irrefl $ encode x,
  suffices : bijective f,
    from f, bij_inv this, left_inverse_bij_inv this, right_inverse_bij_inv this,
  suffices : injective f,
  { rcases equiv_fin α with e,
    exact this, (injective_iff_surjective_of_equiv e).1 this },
  assume x y hxy,
  apply encode_injective,
  by_contradiction h,
  wlog H : encode x < encode y := lt_or_gt_of_ne h using [x y, y x],
  suffices : f x < f y,
    from ne_of_lt this hxy,
  refine fintype.card_subtype_strict_mono _ ⟨λ z hz, _,
    λ h, absurd (h H) $ by simp only [set.mem_set_of_eq, lt_irrefl, not_false_iff],
  simp only [set.mem_set_of_eq] at hz ,
  exact lt_trans hz H
end

Yury G. Kudryashov (Jan 16 2020 at 04:34):

(deleted)

Mario Carneiro (Jan 16 2020 at 07:01):

I think this is in mathlib

Mario Carneiro (Jan 16 2020 at 07:02):

fintype.equiv_fin

Jeremy Avigad (Jan 16 2020 at 12:21):

@Mario Carneiro: def equiv_fin (α) [fintype α] [decidable_eq α] : trunc (α ≃ fin (card α)). There's a trunc there.
@Yury G. Kudryashov: Thanks! Do you mind if I add it to the library? I need it to revise a PR.

Mario Carneiro (Jan 16 2020 at 12:29):

@Jeremy Avigad Use trunc.out to get rid of it

Mario Carneiro (Jan 16 2020 at 12:30):

It's not computable without the trunc, because there is no canonical ordering of the type

Jeremy Avigad (Jan 16 2020 at 12:34):

Is it an advantage that Yuri's version is computable?
(Also, for the record, Yuri, decidable_eq α follows from encodable α.)

Jeremy Avigad (Jan 16 2020 at 12:41):

Background: I need encodable (α → β) where α is an encodable fintype and β is encodable. Right now we only have that when α is fin.

Mario Carneiro (Jan 16 2020 at 12:41):

does it have to be computable?

Jeremy Avigad (Jan 16 2020 at 12:43):

You tell me. It is towards a proof that finitely branching W types are encodable, which can be used e.g. to show that syntactic definitions are encodable. My guess is that yes, we want that to be computable.

Mario Carneiro (Jan 16 2020 at 13:11):

Here's a nicer approach IMO: (The first lemma is a fragment of the proof of fintype.equiv_fin)

def list.equiv_fin {α} [decidable_eq α]
  {l : list α} (h :  x:α, x  l) (nd : l.nodup) : α  fin (l.length) :=
⟨λ a, ⟨_, list.index_of_lt_length.2 (h a),
 λ i, l.nth_le i.1 i.2,
 λ a, by simp,
 λ i, h, fin.eq_of_veq $ list.nodup_iff_nth_le_inj.1 nd _ _
   (list.index_of_lt_length.2 (list.nth_le_mem _ _ _)) h $ by simp

instance order.preimage.decidable {α β} (f : α  β) (s : β  β  Prop)
  [H : decidable_rel s] : decidable_rel (f ⁻¹'o s) := λ x y, H _ _

def encodable.encode' (α) [encodable α] : α  nat :=
encodable.encode, encodable.encode_injective

instance {α} [encodable α] : is_trans _ (encodable.encode' α ⁻¹'o ()) :=
(order_embedding.preimage _ _).is_trans
instance {α} [encodable α] : is_antisymm _ (encodable.encode' α ⁻¹'o ()) :=
(order_embedding.preimage _ _).is_antisymm
instance {α} [encodable α] : is_total _ (encodable.encode' α ⁻¹'o ()) :=
(order_embedding.preimage _ _).is_total

def sorted_univ (α) [fintype α] [encodable α] : list α :=
finset.univ.sort (encodable.encode' α ⁻¹'o ())

theorem mem_sorted_univ {α} [fintype α] [encodable α] (x : α) : x  sorted_univ α :=
(finset.mem_sort _).2 (finset.mem_univ _)

theorem length_sorted_univ {α} [fintype α] [encodable α] : (sorted_univ α).length = fintype.card α :=
finset.length_sort _

theorem sorted_univ_nodup {α} [fintype α] [encodable α] : (sorted_univ α).nodup :=
finset.sort_nodup _ _

def encodable_fintype.equiv_fin {α} [fintype α] [encodable α] [decidable_eq α] :
  α  fin (fintype.card α) :=
by rw  @length_sorted_univ α; exact
list.equiv_fin mem_sorted_univ sorted_univ_nodup

Jeremy Avigad (Jan 16 2020 at 15:17):

Looks good. I am leaving for Zurich in a couple of hours but I'll get this in while traveling. (And, to repeat, we can drop [decidable_eq α].)


Last updated: Dec 20 2023 at 11:08 UTC