Zulip Chat Archive
Stream: lean4
Topic: matching `instBEqOfDecidableEq` and `List.instBEq`
Paige Thomas (Jun 29 2025 at 03:04):
I'm wondering if someone might know what I need to make these match, where the first has instBEqOfDecidableEq and the other has List.instBEq?
1 goal
PSS QSS : List (List Formula_)
s1 : Function.Injective (List.map not_)
s2 : List.map (List.map not_) (PSS ∪ QSS) = List.map (List.map not_) PSS ∪ List.map (List.map not_) QSS
⊢ List.map (List.map not_) (PSS ∪ QSS) = List.map (List.map not_) PSS ∪ List.map (List.map not_) QSS
Expected type
PSS QSS : List (List Formula_)
s1 : Function.Injective (List.map not_)
s2 : List.map (List.map not_) (PSS ∪ QSS) = List.map (List.map not_) PSS ∪ List.map (List.map not_) QSS
⊢ List.map (List.map not_) (PSS ∪ QSS) = List.map (List.map not_) PSS ∪ List.map (List.map not_) QSS
Messages (1)
ToCNF.lean:40:2
type mismatch
s2
has type
List.map (List.map not_)
(@Union.union (List (List Formula_)) (@List.instUnionOfBEq_batteries (List Formula_) instBEqOfDecidableEq) PSS
QSS) =
List.map (List.map not_) PSS ∪ List.map (List.map not_) QSS : Prop
but is expected to have type
List.map (List.map not_)
(@Union.union (List (List Formula_)) (@List.instUnionOfBEq_batteries (List Formula_) List.instBEq) PSS QSS) =
List.map (List.map not_) PSS ∪ List.map (List.map not_) QSS : Prop
Paige Thomas (Jun 29 2025 at 03:07):
This comes from:
lemma map_map_not_union
(PSS QSS : List (List Formula_)) :
map_map_not (PSS ∪ QSS) = (map_map_not PSS) ∪ (map_map_not QSS) :=
by
unfold map_map_not
have s1 : Function.Injective (List.map not_) :=
by
simp only [List.map_injective_iff]
unfold Function.Injective
intro P Q a1
simp only [not_.injEq] at a1
exact a1
obtain s2 := List.map_union (List.map not_) PSS QSS s1
exact s2
where List.map_union is:
lemma List.map_union
{α β : Type}
[DecidableEq α]
[DecidableEq β]
(f : α → β)
(l1 l2 : List α)
(h1 : Function.Injective f) :
List.map f (l1 ∪ l2) = (List.map f l1) ∪ (List.map f l2) :=
Paige Thomas (Jun 29 2025 at 03:09):
and
def map_map_not
(FSS : List (List Formula_)) :
List (List Formula_) :=
List.map (List.map not_) FSS
Kyle Miller (Jun 29 2025 at 03:16):
Could you give a #mwe?
Something I'd suggest trying is using mathlib's convert s2, which tries to deal with these sorts of differences. Mathlib also has subsingleton, which might be useful for discharging some of the remaining goals.
Paige Thomas (Jun 29 2025 at 03:19):
I guess I'm not sure what is going on enough to give a mwe?
Paige Thomas (Jun 29 2025 at 03:28):
For some reason this gives
typeclass instance problem is stuck, it is often due to metavariables
Union (List (List ?m.11303))Lean 4
on the web, but not in my VS code.
import Mathlib
inductive Formula_ : Type
| false_ : Formula_
| true_ : Formula_
| atom_ : String → Formula_
| not_ : Formula_ → Formula_
| and_ : Formula_ → Formula_ → Formula_
| or_ : Formula_ → Formula_ → Formula_
| imp_ : Formula_ → Formula_ → Formula_
| iff_ : Formula_ → Formula_ → Formula_
deriving Inhabited, DecidableEq, Hashable, Repr
compile_inductive% Formula_
theorem extracted_1
(PSS QSS : List (List Formula_))
(s1 : List.map (List.map not_) (PSS ∪ QSS) = List.map (List.map not_) PSS ∪ List.map (List.map not_) QSS) :
List.map (List.map not_) (PSS ∪ QSS) = List.map (List.map not_) PSS ∪ List.map (List.map not_) QSS := sorry
Kyle Miller (Jun 29 2025 at 03:28):
It might be called "MWE" but it doesn't need to be minimal or working. The point is to have something we can paste into an editor to help you diagnose the issue and find something that works.
Kyle Miller (Jun 29 2025 at 03:29):
It saves collective time too, since then people don't have to individually try to reproduce the issue locally.
Paige Thomas (Jun 29 2025 at 03:32):
This reproduces it:
import Mathlib
lemma List.map_union
{α β : Type}
[DecidableEq α]
[DecidableEq β]
(f : α → β)
(l1 l2 : List α)
(h1 : Function.Injective f) :
List.map f (l1 ∪ l2) = (List.map f l1) ∪ (List.map f l2) :=
by
induction l1
case nil =>
simp only [List.map_nil]
simp only [List.nil_union]
case cons hd tl ih =>
simp only [List.cons_union, List.map_cons]
rewrite [← ih]
unfold List.insert
have s1 : List.elem (f hd) (List.map f (tl ∪ l2)) = true ↔ List.elem hd (tl ∪ l2) = true :=
by
simp only [List.elem_eq_mem, decide_eq_true_eq]
apply List.mem_map_of_injective
exact h1
simp only [s1]
split_ifs
case pos c1 =>
rfl
case neg c1 =>
simp only [List.map_cons]
inductive Formula_ : Type
| false_ : Formula_
| true_ : Formula_
| atom_ : String → Formula_
| not_ : Formula_ → Formula_
| and_ : Formula_ → Formula_ → Formula_
| or_ : Formula_ → Formula_ → Formula_
| imp_ : Formula_ → Formula_ → Formula_
| iff_ : Formula_ → Formula_ → Formula_
deriving Inhabited, DecidableEq, Hashable, Repr
compile_inductive% Formula_
open Formula_
def map_map_not
(FSS : List (List Formula_)) :
List (List Formula_) :=
List.map (List.map not_) FSS
lemma map_map_not_union
(PSS QSS : List (List Formula_)) :
map_map_not (PSS ∪ QSS) = (map_map_not PSS) ∪ (map_map_not QSS) :=
by
unfold map_map_not
have s1 : Function.Injective (List.map not_) :=
by
simp only [List.map_injective_iff]
unfold Function.Injective
intro P Q a1
simp only [not_.injEq] at a1
exact a1
obtain s2 := List.map_union (List.map not_) PSS QSS s1
exact s2
Kyle Miller (Jun 29 2025 at 03:35):
Kyle Miller said:
Something I'd suggest trying is using mathlib's
convert s2
This works
Paige Thomas (Jun 29 2025 at 03:41):
Oh, oops, I didn't realize it was a finishing tactic. I had an exact after it. Thank you!
Ruben Van de Velde (Jun 29 2025 at 06:14):
It can be, but isn't always
Robin Arnez (Jun 29 2025 at 08:43):
Union on lists is defined using BEq, so use [BEq α] [LawfulBEq α] [BEq β] [LawfulBEq β] instead of the DecidableEq assumptions. Eventually, this might become unnecessary though if Decidable was redefined such as in lean4#8309
Paige Thomas (Jun 29 2025 at 17:32):
Oh, ok. Thank you.
Last updated: Dec 20 2025 at 21:32 UTC