Zulip Chat Archive
Stream: general
Topic: Derive by hand
Yaël Dillies (Dec 16 2021 at 13:16):
@[derive decidable_eq]
gave up on me because one field of my structure is something like o ≠ none
where o : option W
and it didn't detect that didn't require [decidable_eq W]
. What's the way to do provide the instance myself the derive
way, but being smart?
import data.option.basic
variables {α W : Type*}
/-- `W`-weighted graphs on `α`. `weight a b = some b` represents an edge between `a, b : α` of
weight `b : W`. `weight a b = none` represents no edge between `a` and `b`. -/
@[ext] structure weighted_graph (α : Type*) (W : Type*) :=
(weight : α → α → option W)
/-- Two vertices of a weighted graph are adjacent if their weight is not `none`. -/
def weighted_graph.adj (G : weighted_graph α W) (a b : α) : Prop := G.weight a b ≠ none
/-- A dart is a directed edge, consisting of an ordered pair of adjacent vertices. -/
@[ext, derive decidable_eq] structure weighted_graph.dart (G : weighted_graph α W) :=
(fst snd : α)
(adj : G.adj fst snd)
#check @weighted_graph.dart.decidable_eq
-- Π {α : Type u_3} [a : decidable_eq α] {W : Type u_4} [a : decidable_eq W]
-- (G : weighted_graph α W), decidable_eq G.dart
-- Should be
-- Π {α : Type u_3} [a : decidable_eq α] {W : Type u_4} (G : weighted_graph α W),
-- decidable_eq G.dart
instance (G : weighted_graph α W) [decidable_eq α] : decidable_eq G.dart :=
begin
-- What do I do here?
end
Eric Wieser (Dec 16 2021 at 13:19):
Just locally teach lean decidable (o = none)
?
Eric Wieser (Dec 16 2021 at 13:20):
I think that caused annoying diamonds as a global instance, but that wouldn't matter if you only temporarily enable it
Yaël Dillies (Dec 16 2021 at 13:23):
Okay, but even if I add
instance (G : weighted_graph α W) : decidable_rel G.adj :=
λ a b, @not.decidable _ option.decidable_eq_none
local attribute [instance] option.decidable_eq_none
local attribute [-instance] option.decidable_eq
it yucks
Eric Wieser (Dec 16 2021 at 13:33):
To answer your original question, intros x y
is how to start
Eric Wieser (Dec 16 2021 at 13:34):
#print
on the "bad" instance should hopefully show what an implementation looks like
Eric Wieser (Dec 16 2021 at 13:35):
Probably you want to use decidable_of_iff dart.ext_iff
Yaël Dillies (Dec 16 2021 at 13:41):
Okay, I'm trying it. On the other hand, any chance we could fix derive
?
Yaël Dillies (Dec 16 2021 at 13:48):
instance [decidable_eq α] : decidable_eq G.dart := λ a b, decidable_of_iff _ (dart.ext_iff _ _).symm
works fine indeed.
Reid Barton (Dec 16 2021 at 14:34):
As you probably realized, it has nothing to do with decidability of G.adj fst snd
itself
Reid Barton (Dec 16 2021 at 14:35):
In general I think making derive
smarter is hard though.
In Haskell, deriving
can write down the generated definition without class constraints and then run type inference on it to learn what the correct constraints should be. That really doesn't work in Lean.
Last updated: Dec 20 2023 at 11:08 UTC