Zulip Chat Archive

Stream: mathlib4

Topic: Weird behavior of fun_prop


Etienne Marion (Jul 07 2025 at 09:25):

Hi! Consider the following #mwe:

import Mathlib.MeasureTheory.Function.LpSeminorm.Defs

open MeasureTheory

variable {Ω ι : Type*} [Fintype ι] { : MeasurableSpace Ω} {μ : Measure Ω} {X : ι  Ω  }

example (hX :  i, MemLp (X i) 2 μ) : AEMeasurable (fun ω i  X i ω) μ := by
  fun_prop -- fails, ok

example (hX :  i, MemLp (X i) 2 μ) : AEMeasurable (fun ω i  X i ω) μ := by
  have :  i, AEMeasurable (X i) μ := fun i  (hX i).aestronglyMeasurable.aemeasurable
  fun_prop -- works, ok

example (hX :  i, MemLp (X i) 2 μ) : AEMeasurable (fun ω i  X i ω) μ := by
  have := fun i  (hX i).aestronglyMeasurable.aemeasurable
  fun_prop -- fails, why?

fun_prop works in the second case but not in the third, while if I'm not mistaken the contexts are exactly the same. Any idea of what is going on?

Aaron Liu (Jul 07 2025 at 10:15):

I thought they were the same too, but I guess not:

elab "t " i:ident : tactic =>
  Lean.Elab.Tactic.withMainContext do
    let hyp  Lean.Meta.getLocalDeclFromUserName i.getId
    Lean.logInfo hyp.type.ctorName

example (hX :  i, MemLp (X i) 2 μ) : AEMeasurable (fun ω i  X i ω) μ := by
  have :  i, AEMeasurable (X i) μ := fun i  (hX i).aestronglyMeasurable.aemeasurable
  t this -- forallE
  fun_prop -- works, ok

example (hX :  i, MemLp (X i) 2 μ) : AEMeasurable (fun ω i  X i ω) μ := by
  have := fun i  (hX i).aestronglyMeasurable.aemeasurable
  t this -- mvar
  fun_prop -- fails, why?

Kevin Buzzard (Jul 07 2025 at 10:38):

Oh interesting! Even with pp.all on, the two thiss look identical:

this :  (i : ι), @AEMeasurable.{u_1, 0} Ω Real Real.measurableSpace  (X i) μ
this :  (i : ι), @AEMeasurable.{u_1, 0} Ω Real Real.measurableSpace  (X i) μ

Aaron Liu (Jul 07 2025 at 10:39):

I even turned off pp.instantiateMVars and it still looked the same

Aaron Liu (Jul 07 2025 at 10:42):

So I guess fun_prop forgot an instantiateMVars somewhere?

Etienne Marion (Jul 07 2025 at 11:17):

If it's an easy fix, that'd be great.

example (hX :  i, MemLp (X i) 2 μ) : AEMeasurable (fun ω i  X i ω) μ := by
  have (i : ι) := (hX i).aestronglyMeasurable.aemeasurable
  fun_prop

also works.

Tomas Skrivan (Jul 08 2025 at 02:19):

example (hX :  i, MemLp (X i) 2 μ) : AEMeasurable (fun ω i  X i ω) μ := by
  fun_prop -- fails, ok

does not work because MemLp is not marked with fun_prop so it does not try to infer AEMeasurable from MemLp

This works

import Mathlib.MeasureTheory.Function.LpSeminorm.Defs
open MeasureTheory

variable {Ω ι : Type*} [Fintype ι] { : MeasurableSpace Ω} {μ : Measure Ω} {X : ι  Ω  }

attribute [fun_prop]
  MemLp
  MemLp.aestronglyMeasurable
  AEStronglyMeasurable.aemeasurable

example (hX :  i, MemLp (X i) 2 μ) : AEMeasurable (fun ω i  X i ω) μ := by
  fun_prop (maxTransitionDepth := 2)

Not sure if it actually make sense to have MemLp marked with fun_prop as it does not play well with composition. In general, fun_prop is not good/designed at proving integrability.

Tomas Skrivan (Jul 08 2025 at 02:24):

Aaron Liu said:

I thought they were the same too, but I guess not:

elab "t " i:ident : tactic =>
  Lean.Elab.Tactic.withMainContext do
    let hyp  Lean.Meta.getLocalDeclFromUserName i.getId
    Lean.logInfo hyp.type.ctorName

example (hX :  i, MemLp (X i) 2 μ) : AEMeasurable (fun ω i  X i ω) μ := by
  have :  i, AEMeasurable (X i) μ := fun i  (hX i).aestronglyMeasurable.aemeasurable
  t this -- forallE
  fun_prop -- works, ok

example (hX :  i, MemLp (X i) 2 μ) : AEMeasurable (fun ω i  X i ω) μ := by
  have := fun i  (hX i).aestronglyMeasurable.aemeasurable
  t this -- mvar
  fun_prop -- fails, why?

This indeed seems like a problem. There must be some minor but at the last stage as trace for fun_prop correctly finds the local hypothesis but fails to apply it.

fun_prop trace:

[Meta.Tactic.fun_prop] [❌️] AEMeasurable (fun ω i => X i ω) μ 
  [] [❌️] AEMeasurable (fun ω i => X i ω) μ 
    [] [❌️] applying: aemeasurable_pi_lambda 
      [] [❌️]  (a : ι), AEMeasurable (fun c => X a c) μ 
        [] [❌️] AEMeasurable (fun c => X a c) μ 
          [] candidate local theorems for X #[this :  (i : ι), AEMeasurable (X i) μ]
          [] [❌️] applying: this :  (i : ι), AEMeasurable (X i) μ 
            [] failed to unify this
                 (i : ι), AEMeasurable (X i) μ
                with
                AEMeasurable (fun c => X a c) μ
          ....

It looks like that it is missing an application of forallMetaTelescope to the local hypothesis before the unification.


Last updated: Dec 20 2025 at 21:32 UTC