Zulip Chat Archive
Stream: general
Topic: subtype.decidable_eq
Chris Hughes (Jan 04 2019 at 15:56):
subtype.decidable_eq
sometimes fails to reduce in the kernel. Not sure why this is, it doesn't use propext
or anything. The instance
foo
that I wrote in this code does work for some reason.
import group_theory.perm group_theory.coset open equiv example : (⟨1, rfl⟩ : {x : perm bool // x = 1}) = ⟨swap ff tt * swap ff tt, dec_trivial⟩ := dec_trivial example : (⟨1, rfl⟩ : {x : perm bool // x = 1}) = ⟨swap ff tt * swap ff tt, dec_trivial⟩ := subtype.eq dec_trivial @[instance, priority 1000] lemma foo {α : Type*} [decidable_eq α] {P : α → Prop} : decidable_eq (subtype P) := λ a b, decidable_of_iff (a.1 = b.1) (by cases a; cases b; simp) example : (⟨1, rfl⟩ : {x : perm bool // x = 1}) = ⟨swap ff tt * swap ff tt, dec_trivial⟩ := dec_trivial
Mario Carneiro (Jan 04 2019 at 17:15):
Here's a little test of the decidable instance:
run_cmd do let t := `((⟨1, rfl⟩ : {x : perm bool // x = 1}) = ⟨swap ff tt * swap ff tt, dec_trivial⟩), inst ← mk_instance `(decidable %%t), e ← whnf inst, -- should be is_true _ but it's not trace e, -- eq.rec (λ (w_property : 1 = 1), is_true _) _ _ [_,_,_,_,_,_,e] ← return $ expr.get_app_args e, -- get the major premise `(%%a = %%b) ← infer_type e, -- it is a proof of swap ff tt * swap ff tt = 1 is_def_eq a b -- and they are not defeq
Mario Carneiro (Jan 04 2019 at 17:17):
whnf
gets stuck here because it does not unfold proofs, like the major premise of the eq.rec
, and it can't ignore the proof because it's not equivalent to rfl
(because the things being equated are not defeq)
Mario Carneiro (Jan 04 2019 at 17:23):
You should not cast types in order to prove a decidable instance. I know it's tempting but you should always use decidable_of_iff
which does a case on the target rather than a cast
Mario Carneiro (Jan 04 2019 at 17:23):
Unfortunately, the blame here seems to lie in mk_dec_eq_instance
, which is bad since it powers @[derive decidable_eq]
which is used all over
Mario Carneiro (Jan 04 2019 at 17:24):
Here's subtype.decidable_eq
:
@[instance] protected def subtype.decidable_eq : Π {α : Type u} {p : α → Prop} [_inst_1 : decidable_eq α], decidable_eq {x // p x} := λ {α : Type u} {p : α → Prop} [_inst_1 : decidable_eq α], id (λ (_v : {x // p x}), subtype.cases_on _v (λ (val : α) (property : p val) (w : {x // p x}), subtype.cases_on w (λ (w_val : α) (w_property : p w_val), decidable.by_cases (λ (a : val = w_val), eq.rec (λ (w_property : p val), is_true _) a w_property) (λ (a : ¬val = w_val), is_false _))))
Note the eq.rec
in the true branch
Mario Carneiro (Jan 04 2019 at 17:25):
if it said is_true (eq.rec (λ (w_property : p val), _) a w_property)
there would be no problem
Mario Carneiro (Jan 04 2019 at 17:30):
the culprit is the subst
here -> https://github.com/leanprover/lean/blob/master/library/init/meta/mk_dec_eq_instance.lean#L76 . Unfortunately I'm not sure there is anything we can do about it from mathlib
Last updated: Dec 20 2023 at 11:08 UTC