Zulip Chat Archive
Stream: mathlib4
Topic: Importing a file changed `dite` if macro semantics
Yakov Pechersky (Oct 30 2022 at 01:28):
Consider:
import Mathlib.Init.Data.Nat.Lemmas
-- comment out to make `extend_apply` work and `extend_apply_noninj` break
def Function.Injective (f : α → β) : Prop := ∀ ⦃a₁ a₂⦄, f a₁ = f a₂ → a₁ = a₂
@[simp] theorem exists_apply_eq_apply' (f : α → β) (a' : α) : ∃ a, f a = f a' := ⟨a', rfl⟩
noncomputable section Extend
attribute [local instance] Classical.propDecidable
def extend (f : α → β) (g : α → γ) (e' : β → γ) : β → γ := fun b =>
if h : ∃ a, f a = b then g (Classical.choose h) else e' b
def extend' (f : α → β) (g : α → γ) (e' : β → γ) : β → γ := fun b =>
@dite γ (∃ a, f a = b) (Classical.propDecidable _) (fun h => g (Classical.choose h)) (fun _ => e' b)
theorem extend_def (f : α → β) (g : α → γ) (e' : β → γ) (b : β) [Decidable (∃ a, f a = b)] :
extend f g e' b = if h : ∃ a, f a = b then g (Classical.choose h) else e' b := by
unfold extend
congr
theorem extend'_def (f : α → β) (g : α → γ) (e' : β → γ) (b : β) [Decidable (∃ a, f a = b)] :
extend' f g e' b = if h : ∃ a, f a = b then g (Classical.choose h) else e' b := by
unfold extend'
congr
@[simp]
theorem extend_apply {f} (hf : Function.Injective f) (g : α → γ) (e' : β → γ) (a : α) :
extend f g e' (f a) = g a := by
simp only [extend_def, dif_pos, exists_apply_eq_apply']
exact congrArg g (hf $ Classical.choose_spec (exists_apply_eq_apply' f a))
@[simp]
theorem extend_apply_noninj (f : α → β) (g : α → γ) (e' : β → γ) (a : α) :
extend f g e' (f a) = g a := by
rw [extend_def, dif_pos (exists_apply_eq_apply' f a)]
@[simp]
theorem extend'_apply {f} (hf : Function.Injective f) (g : α → γ) (e' : β → γ) (a : α) :
extend' f g e' (f a) = g a := by
simp only [extend'_def, dif_pos, exists_apply_eq_apply']
exact congrArg g (hf $ Classical.choose_spec (exists_apply_eq_apply' f a))
Yakov Pechersky (Oct 30 2022 at 01:29):
I think this change in the if
macro also affects other porting attempts. Right now, the obvious definition of invFun
results in specializing the α
to Prop
for some reason. Making the definition explicitly go through @dite
avoids that
Yakov Pechersky (Oct 30 2022 at 01:32):
import Std.Logic -- comment out to make invFun work with Sort, Sort
@[reducible]
protected noncomputable def Classical.arbitrary (α) [h : Nonempty α] : α :=
Classical.choice h
noncomputable section Extend
attribute [local instance] Classical.propDecidable
noncomputable def invFun [Nonempty α] (f : α → β) : β → α :=
fun y => if h : (∃ x, f x = y) then (Classical.choose h) else Classical.arbitrary α
noncomputable def invFun' [Nonempty α] (f : α → β) : β → α :=
fun y => @dite α (∃ x, f x = y) (Classical.propDecidable _)
Classical.choose (fun _ => Classical.arbitrary _)
#check @invFun -- Prop, Sort
#check @invFun' -- Sort, Sort
Mario Carneiro (Oct 30 2022 at 04:24):
It appears to be the fault of exists_prop_decidable
:
-- Comment this out to make invFun work with Sort, Sort
instance exists_prop_decidable {p} (P : p → Prop)
[Decidable p] [∀ h, Decidable (P h)] : Decidable (∃ h, P h) :=
if h : p then
decidable_of_decidable_of_iff ⟨fun h2 => ⟨h, h2⟩, fun ⟨_, h2⟩ => h2⟩
else isFalse fun ⟨h', _⟩ => h h'
@[reducible]
protected noncomputable def Classical.arbitrary (α) [h : Nonempty α] : α :=
Classical.choice h
noncomputable section Extend
attribute [local instance] Classical.propDecidable
noncomputable def invFun [Nonempty α] (f : α → β) : β → α :=
fun y => if h : (∃ x, f x = y) then (Classical.choose h) else Classical.arbitrary α
noncomputable def invFun' [Nonempty α] (f : α → β) : β → α :=
fun y => @dite α (∃ x, f x = y) (Classical.propDecidable _)
Classical.choose (fun _ => Classical.arbitrary _)
#check @invFun -- Prop, Sort
#check @invFun' -- Sort, Sort
Mario Carneiro (Oct 30 2022 at 04:26):
and it makes some sense too: with that instance available invFun
will use it, and this unifies the universe metavar in {α : Sort _}
Mario Carneiro (Oct 30 2022 at 04:28):
I think this should be classed as a bug though, because definitions with a given (explicit) type are supposed to be fully elaborated using only their types
Yakov Pechersky (Oct 30 2022 at 04:45):
Yeah, I noticed that too here: https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Decidable.20of.20Exists.20changes.20.60if.60.20macro.20semantics
Last updated: Dec 20 2023 at 11:08 UTC