Zulip Chat Archive
Stream: general
Topic: Order diamond
Yaël Dillies (Sep 16 2021 at 18:59):
I don't know what to do to solve this.
import order.bounds
lemma monotone_fst' {α β : Type*} [preorder α] [preorder β] : monotone (@prod.fst α β) := sorry
lemma monotone_snd' {α β : Type*} [preorder α] [preorder β] : monotone (@prod.snd α β) := sorry
lemma mem_upper_bounds_image {α β : Type*} [preorder α] [preorder β] {f : α → β} (Hf : monotone f)
{a : α} {s : set α} (Ha : a ∈ upper_bounds s) :
f a ∈ upper_bounds (f '' s) := sorry
example {α β : Type*} [preorder α] [preorder β] {f : α → β} (Hf : monotone f) : true :=
begin
have := @mem_upper_bounds_image _ _ (@prod.preorder α β _ _) _ _ monotone_fst', -- works
have := @mem_upper_bounds_image _ _ _ _ _ monotone_fst', --fails
have := mem_upper_bounds_image monotone_fst', --fails
end
Yaël Dillies (Sep 16 2021 at 19:01):
The problem seems to stem from (Hf : monotone f)
taking in @preorder.to_has_le α
and preorder.to_has_le β
and not just any has_le
.
Yaël Dillies (Sep 16 2021 at 19:02):
Note this is all already in mathlib, and somehow I've broken it in the past 6 commits I made to #7987 :sad:
Reid Barton (Sep 16 2021 at 19:07):
What do you mean by "works" and "fails"?
Surely, the last two can't infer α
or β
.
Yaël Dillies (Sep 16 2021 at 19:09):
Yeah but they should be left as metavariables. If you provide them using other arguments, that still doesn't work
Reid Barton (Sep 16 2021 at 19:10):
Well in the Lean playground, they all "work" then.
Yaël Dillies (Sep 16 2021 at 19:11):
Hmm...
Yaël Dillies (Sep 16 2021 at 19:12):
Well a non minimal really non working example is the branch locally_finite
in order.bounds
, if somebody could have a look.
Yakov Pechersky (Sep 17 2021 at 00:41):
prod orders are broken, lt and le don't agree.
Yury G. Kudryashov (Sep 17 2021 at 01:28):
@Yakov Pechersky Could you please point me to the pair of instances that create a diamond?
Yakov Pechersky (Sep 17 2021 at 01:30):
src#prod.has_lt, src#prod.has_le
Yury G. Kudryashov (Sep 17 2021 at 01:31):
What's wrong with these two instances? We never require lt_iff_le_not_le
to be a definitional equality.
Yury G. Kudryashov (Sep 17 2021 at 01:32):
Probably some other instance up in the chain uses the default (<)
instead of lt := (<)
.
Yury G. Kudryashov (Sep 17 2021 at 01:33):
Indeed, docs#prod.preorder is bad.
Yakov Pechersky (Sep 17 2021 at 01:33):
Specifically in src#prod.ordered_smul, I couldn't generalize it properly.
Yury G. Kudryashov (Sep 17 2021 at 01:33):
I'll try to fix it now.
Yakov Pechersky (Sep 17 2021 at 01:33):
Yes, what I meant is that. I just sent the actually conflicting definitions.
Yury G. Kudryashov (Sep 17 2021 at 01:34):
I'll fix prod.preorder
, then the diamond should disappear.
Yury G. Kudryashov (Sep 17 2021 at 01:40):
OMG, prod.has_lt
is not equivalent to le_and_not_le
for a preorder
.
Yury G. Kudryashov (Sep 17 2021 at 01:40):
We'll need to fix it in the core.
Yury G. Kudryashov (Sep 17 2021 at 01:40):
(or move prod.has_lt
to mathlib
)
Mario Carneiro (Sep 17 2021 at 01:43):
I don't think prod.has_lt
should be an instance at all
Mario Carneiro (Sep 17 2021 at 01:43):
there should be a type alias for the total order
Mario Carneiro (Sep 17 2021 at 01:44):
or use prod.lex
instead of <
Yury G. Kudryashov (Sep 17 2021 at 01:50):
I'm going to delete the old instance from core.
Yury G. Kudryashov (Sep 17 2021 at 01:53):
Yury G. Kudryashov (Sep 17 2021 at 01:54):
We already have a type alias docs#lex for the lexicographical order.
Yakov Pechersky (Sep 17 2021 at 01:56):
Right, this is the issue I hit earlier. You're taking on the core change that I avoided :-) thank you
Yury G. Kudryashov (Sep 17 2021 at 01:59):
BTW, do we use the right definition for lex.has_le
in case of a preorder? It looks like the map λ x, (x, a)
is not monotone with our definition.
Yury G. Kudryashov (Sep 17 2021 at 01:59):
Because we don't have eq_or_lt_of_le
.
Yury G. Kudryashov (Sep 17 2021 at 02:03):
I think that we should use (a, b) ≤ (c, d) ↔ a ≤ c ∧ (c ≤ a → b ≤ d)
(or don't claim to support preorders).
Yury G. Kudryashov (Sep 17 2021 at 02:04):
@Scott Morrison @Minchao Wu According to the header, you're the authors of order.lexicographic
.
Scott Morrison (Sep 17 2021 at 02:07):
We'll need another statement that still says (a, b) ≤ (c, d) ↔ a < c \or (a = c ∧ b ≤ d)
with [partial_order]
.
Yury G. Kudryashov (Sep 17 2021 at 02:07):
Yes, sure. We need a partial order on α
and a preorder on β
for this statement.
Yury G. Kudryashov (Sep 17 2021 at 02:08):
There should be an iff
with lex
as well if we want to reuse the fact that it's well-founded.
Yaël Dillies (Sep 17 2021 at 06:26):
Oh duh, I didn't notice prod.has_lt
existed.
Eric Wieser (Sep 17 2021 at 06:27):
Yaël Dillies (Sep 17 2021 at 06:27):
Thansk for correcting this! What's puzzling me is that all this was working before and I somehow broke it. Maybe it was just fragile.
Yakov Pechersky (Sep 17 2021 at 11:12):
As you can see with src#prod.ordered_smul, if you're at a complex enough structure, then it takes only one "canonical" path through the TCs. But generalizing, it has more options to branch. That's probably what's going on in your generalization branch.
Yaël Dillies (Sep 22 2021 at 11:45):
Okay, I've made an actual MWE. This is the most minimizing I've ever done.
import tactic.interactive_expr
instance (α β : Type*) [has_le α] [has_le β] : has_le (α × β) :=
⟨λ p q, p.1 ≤ q.1 ∧ p.2 ≤ q.2⟩
instance (α β : Type*) [preorder α] [preorder β] : preorder (α × β) :=
{ le_refl := sorry,
le_trans := sorry,
.. prod.has_le α β }
variables {α β : Type*}
def monotone [has_le α] [has_le β] (f : α → β) : Prop := ∀ ⦃a b⦄, a ≤ b → f a ≤ f b
variables [preorder α] [preorder β]
lemma monotone_fst : monotone (@prod.fst α β) :=
sorry
infix ` '' `:80 := set.image
def upper_bounds (s : set α) : set α := {x | ∀ ⦃a⦄, a ∈ s → a ≤ x}
lemma monotone.mem_upper_bounds_image {f : α → β} (hf : monotone f) {a : α} {s : set α}
(ha : a ∈ upper_bounds s) :
f a ∈ upper_bounds (f '' s) :=
sorry
lemma mwe_works {s : set (α × β)} {a : α × β} (ha : a ∈ upper_bounds s) :
a.1 ∈ upper_bounds (prod.fst '' s) :=
begin
exact monotone.mem_upper_bounds_image monotone_fst ha, -- works
end
lemma mwe_fails {s : set (α × β)} {a : α × β} (ha : a ∈ upper_bounds s) :
a.1 ∈ upper_bounds (prod.fst '' s) :=
begin
exact monotone_fst.mem_upper_bounds_image ha, -- fails
end
Yaël Dillies (Sep 22 2021 at 11:46):
I think this is clearly(?) an elaboration issue.
Yaël Dillies (Sep 22 2021 at 11:47):
If I replace the definition of monotone
by def monotone [preorder α] [has_le β] (f : α → β) : Prop := ∀ ⦃a b⦄, a ≤ b → f a ≤ f b
, then mwe_fails
works.
Eric Wieser (Sep 22 2021 at 11:51):
This is because dot notation has different elaboration rules I guess
Yaël Dillies (Sep 22 2021 at 11:54):
I guess it does :frown:
Lean fails to unify @prod.has_le α β
with @preorder.to_has_le α β _
Yaël Dillies (Sep 22 2021 at 12:00):
In current mathlib, this works because monotone
assumes [preorder α] [preorder β]
. What should I do? Remove the affected dot notation? Stick to preorder
in the definition? Get someone to fix that elaboration issue?
Eric Wieser (Sep 22 2021 at 12:03):
Does putting a type annotation on monotone_fst
before the dot notation help?
Yaël Dillies (Sep 22 2021 at 12:15):
Indeed this works:
lemma mwe_fails {s : set (α × β)} {a : α × β} (ha : a ∈ upper_bounds s) :
a.1 ∈ upper_bounds (prod.fst '' s) :=
(monotone_fst : monotone (@prod.fst α β)).mem_upper_bounds_image ha
Reid Barton (Sep 22 2021 at 12:18):
(I put α
and β
in the same universe to make the errors a bit shorter.)
So here's something I don't understand. In a message like
Additional information:
/test.lean:40:8: context: switched to simple application elaboration procedure because failed to use expected type to elaborate it, error message
type mismatch at application
@monotone.mem_upper_bounds_image.{?l_1} ?m_2 ?m_3 ?m_4 ?m_5 ?m_6 (@monotone_fst.{?l_7} ?m_8 ?m_9 ?m_10 ?m_11)
term
@monotone_fst.{?l_1} ?m_2 ?m_3 ?m_4 ?m_5
has type
@monotone.{?l_1} (prod.{?l_1 ?l_1} ?m_2 ?m_3) ?m_2
(@prod.has_le.{?l_1 ?l_1} ?m_2 ?m_3 (@preorder.to_has_le.{?l_1} ?m_2 ?m_4) (@preorder.to_has_le.{?l_1} ?m_3 ?m_5))
(@preorder.to_has_le.{?l_1} ?m_2 ?m_4)
(@prod.fst.{?l_1 ?l_1} ?m_2 ?m_3)
but is expected to have type
@monotone.{?l_1} ?m_2 ?m_3 (@preorder.to_has_le.{?l_1} ?m_2 ?m_4) (@preorder.to_has_le.{?l_1} ?m_3 ?m_5) ?m_6
are the ?m_2
and ?m_3
that appear in the actual and expected types the same metavariables in both, or are they independent?
Reid Barton (Sep 22 2021 at 12:20):
Ah I guess they are numbered independently, since in the first line monotone_fst
is applied to things like ?m_8
and ?m_9
Reid Barton (Sep 22 2021 at 12:30):
I guess the story must be something like: We need to type check monotone_fst
first, in order to even find out what definition monotone_fst.mem_upper_bounds_image
refers to. At this point, we have no idea how the value monotone_fst
will get used so we can't infer anything about its type arguments. So if we try to do instance search now, we can't make any progress. So we end up with monotone_fst
applied to a slew of metavariables. But at least we know its type is of the form monotone _
.
Then, we know the dot notation is referring to monotone.mem_upper_bounds_image
. But monotone.mem_upper_bounds_image monotone_fst
can only type check after we do another instance search and find that we mean prod.has_le
. Apparently Lean doesn't do an instance search at this point.
Reid Barton (Sep 22 2021 at 12:33):
I think the reason it works with preorder
in monotone
but not has_le
is that in the latter case, there's a potentially non-defeq instance issue. Of course if you actually look at the definition of prod.preorder
you'll see that to_has_le
of it is the same as prod.has_le
, but you have to look at the instances to see this. If you only talk about preorder
everywhere then this issue doesn't come up.
Yaël Dillies (Oct 02 2021 at 07:22):
For reference, what I did here in the end is to require preorder
everywhere and it works fine.
Last updated: Dec 20 2023 at 11:08 UTC