Zulip Chat Archive

Stream: general

Topic: how to derive decidable_rel easily?


Eric Rodriguez (Mar 28 2022 at 11:33):

say that I have these definitions:

inductive sign_type
| zero | neg | pos

def le : sign_type  sign_type  Prop
| neg _     := true
| zero neg  := false
| zero zero := true
| zero pos  := true
| pos neg   := false
| pos zero  := false
| pos pos   := true

clearly, this is a decidable_rel. I don't particularly want to list out all 9 cases again though, to do of_true .../of_false .... is there some automatic way to generate decidable_rel for these sorts of declarations?

Yaël Dillies (Mar 28 2022 at 11:37):

Your MWE doesn't compile but does @[derive decidable] work?

Eric Wieser (Mar 28 2022 at 11:38):

open sign_type makes it work

Eric Rodriguez (Mar 28 2022 at 11:39):

oops, sorry

Eric Rodriguez (Mar 28 2022 at 11:39):

neither @[derive decidable] nor @[derive decidable_rel] work

Eric Wieser (Mar 28 2022 at 11:40):

What's the import for the decidable derive handler?

Yaël Dillies (Mar 28 2022 at 11:40):

Probably import tactic is enough

Eric Wieser (Mar 28 2022 at 11:43):

You might also want:

inductive le : sign_type  sign_type  Prop
| of_neg (a) : le neg a
| zero : le zero zero
| of_pos (a) : le a pos

Eric Wieser (Mar 28 2022 at 11:46):

Followed by

instance : decidable_rel le
| neg a := is_true (le.of_neg a)
| zero zero := is_true le.zero
| a pos := is_true (le.of_pos a)
| zero neg := is_false (λ h, by cases h)
| pos zero := is_false (λ h, by cases h)
| pos neg := is_false (λ h, by cases h)

Eric Wieser (Mar 28 2022 at 11:47):

Or

instance : decidable_rel le :=
λ a b, by cases a; cases b; {apply is_true, constructor} <|> {apply is_false, intro h, cases h}

Eric Wieser (Mar 28 2022 at 11:50):

That last proof works for both definitions of le

Eric Wieser (Mar 28 2022 at 11:59):

How does @[derive decidable_eq] work today? Which derive handler is it using? (edit: ah, docs#tactic.decidable_eq_derive_handler)

Eric Rodriguez (Mar 28 2022 at 13:46):

I ended up going with the inductive approach and λ a b, by cases a; cases b; exact is_false (by rintro ⟨⟩) <|> exact is_true (by constructor), but it would be nice if there was some other way to do this! I assume the metaprogramming thread is debugging this?

Damiano Testa (Mar 28 2022 at 14:38):

Honestly, I do not understand much of decidable, but I am always very fond of Johan's suggestion in one of the counterexamples. Is what below useful?

/--  The three element monoid. -/
@[derive [decidable_eq]]
inductive sign_type
| zero
| pos
| neg

namespace sign_type

instance inhabited : inhabited sign_type := zero

instance : has_zero sign_type := zero
instance : has_one sign_type := pos
notation `-1` := neg

/-- The order on `sign_type` is the one induced by the natural order on the image of `aux1`. -/
def aux1 : sign_type  
| -1 := 0
|  0 := 1
|  1 := 2

/-- A tactic to prove facts by cases. -/
meta def boom : tactic unit :=
`[repeat {rintro ⟨⟩}; dec_trivial]

lemma aux1_inj : function.injective aux1 :=
by boom

instance : linear_order sign_type :=
linear_order.lift aux1 $ aux1_inj

instance : decidable_rel (has_le.le : sign_type  sign_type  Prop) :=
by apply_instance

Damiano Testa (Mar 28 2022 at 14:48):

(Although I realize that the choice of -1 as notation for neg means that -1 : ℤ will not work, but - 1 : ℤ does! :upside_down: )

Eric Rodriguez (Mar 28 2022 at 14:54):

I just gave it a has_neg instance, that worked better I think! This is a neat idea, too

Damiano Testa (Mar 28 2022 at 14:57):

Slowly, this is crawling to become zmod 3...

Yaël Dillies (Mar 28 2022 at 14:58):

Probably closer to fin' 3

Damiano Testa (Mar 28 2022 at 15:02):

Sure, although, unless addition starts playing a role, it will be difficult to tell!

Eric Rodriguez (Mar 28 2022 at 15:11):

I mean, it is, it was just suggested in #12835 to make it a separate type

Eric Rodriguez (Mar 28 2022 at 15:12):

because sign : \a \to fin 3 is weird


Last updated: Dec 20 2023 at 11:08 UTC