Skip to content

Commit a619d25

Browse files
committed
feat: fun_prop tactic for proving Continuous, Differentiable, Measurable, ... (#10040)
New tactic `fun_prop` to prove FUNction PROPerties like continuity, differentiability, ...
1 parent 7ea8549 commit a619d25

23 files changed

+4364
-5
lines changed

Mathlib.lean

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3388,6 +3388,23 @@ import Mathlib.Tactic.FailIfNoProgress
33883388
import Mathlib.Tactic.FieldSimp
33893389
import Mathlib.Tactic.FinCases
33903390
import Mathlib.Tactic.Find
3391+
import Mathlib.Tactic.FunProp
3392+
import Mathlib.Tactic.FunProp.AEMesurable
3393+
import Mathlib.Tactic.FunProp.Attr
3394+
import Mathlib.Tactic.FunProp.ContDiff
3395+
import Mathlib.Tactic.FunProp.Continuous
3396+
import Mathlib.Tactic.FunProp.Core
3397+
import Mathlib.Tactic.FunProp.Decl
3398+
import Mathlib.Tactic.FunProp.Differentiable
3399+
import Mathlib.Tactic.FunProp.Elab
3400+
import Mathlib.Tactic.FunProp.FunctionData
3401+
import Mathlib.Tactic.FunProp.Measurable
3402+
import Mathlib.Tactic.FunProp.Mor
3403+
import Mathlib.Tactic.FunProp.RefinedDiscrTree
3404+
import Mathlib.Tactic.FunProp.StateList
3405+
import Mathlib.Tactic.FunProp.Theorems
3406+
import Mathlib.Tactic.FunProp.ToStd
3407+
import Mathlib.Tactic.FunProp.Types
33913408
import Mathlib.Tactic.GCongr
33923409
import Mathlib.Tactic.GCongr.Core
33933410
import Mathlib.Tactic.GCongr.ForwardAttr

Mathlib/Lean/Expr/Basic.lean

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -324,18 +324,21 @@ def modifyAppArgM [Functor M] [Pure M] (modifier : Expr → M Expr) : Expr → M
324324
| app f a => mkApp f <$> modifier a
325325
| e => pure e
326326

327-
def modifyAppArg (modifier : Expr → Expr) : Expr → Expr :=
328-
modifyAppArgM (M := Id) modifier
329-
330327
def modifyRevArg (modifier : Expr → Expr) : Nat → Expr → Expr
331-
| 0 => modifyAppArg modifier
332-
| (i+1) => modifyAppArg (modifyRevArg modifier i)
328+
| 0, (.app f x) => .app f (modifier x)
329+
| (i+1), (.app f x) => .app (modifyRevArg modifier i f) x
330+
| _, e => e
333331

334332
/-- Given `f a₀ a₁ ... aₙ₋₁`, runs `modifier` on the `i`th argument or
335333
returns the original expression if out of bounds. -/
336334
def modifyArg (modifier : Expr → Expr) (e : Expr) (i : Nat) (n := e.getAppNumArgs) : Expr :=
337335
modifyRevArg modifier (n - i - 1) e
338336

337+
/-- Given `f a₀ a₁ ... aₙ₋₁`, sets the argument on the `i`th argument to `x` or
338+
returns the original expression if out of bounds. -/
339+
def setArg (e : Expr) (i : Nat) (x : Expr) (n := e.getAppNumArgs) : Expr :=
340+
e.modifyArg (fun _ => x) i n
341+
339342
def getRevArg? : Expr → Nat → Option Expr
340343
| app _ a, 0 => a
341344
| app f _, i+1 => getRevArg! f i

Mathlib/Tactic.lean

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,23 @@ import Mathlib.Tactic.FailIfNoProgress
5151
import Mathlib.Tactic.FieldSimp
5252
import Mathlib.Tactic.FinCases
5353
import Mathlib.Tactic.Find
54+
import Mathlib.Tactic.FunProp
55+
import Mathlib.Tactic.FunProp.AEMesurable
56+
import Mathlib.Tactic.FunProp.Attr
57+
import Mathlib.Tactic.FunProp.ContDiff
58+
import Mathlib.Tactic.FunProp.Continuous
59+
import Mathlib.Tactic.FunProp.Core
60+
import Mathlib.Tactic.FunProp.Decl
61+
import Mathlib.Tactic.FunProp.Differentiable
62+
import Mathlib.Tactic.FunProp.Elab
63+
import Mathlib.Tactic.FunProp.FunctionData
64+
import Mathlib.Tactic.FunProp.Measurable
65+
import Mathlib.Tactic.FunProp.Mor
66+
import Mathlib.Tactic.FunProp.RefinedDiscrTree
67+
import Mathlib.Tactic.FunProp.StateList
68+
import Mathlib.Tactic.FunProp.Theorems
69+
import Mathlib.Tactic.FunProp.ToStd
70+
import Mathlib.Tactic.FunProp.Types
5471
import Mathlib.Tactic.GCongr
5572
import Mathlib.Tactic.GCongr.Core
5673
import Mathlib.Tactic.GCongr.ForwardAttr

Mathlib/Tactic/FunProp.lean

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import Mathlib.Tactic.FunProp.Attr
2+
import Mathlib.Tactic.FunProp.Core
3+
import Mathlib.Tactic.FunProp.Decl
4+
import Mathlib.Tactic.FunProp.Elab
5+
import Mathlib.Tactic.FunProp.FunctionData
6+
import Mathlib.Tactic.FunProp.Mor
7+
import Mathlib.Tactic.FunProp.RefinedDiscrTree
8+
import Mathlib.Tactic.FunProp.StateList
9+
import Mathlib.Tactic.FunProp.Theorems
10+
import Mathlib.Tactic.FunProp.ToStd
11+
import Mathlib.Tactic.FunProp.Types
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/-
2+
Copyright (c) 2024 Tomáš Skřivan All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Tomáš Skřivan
5+
-/
6+
import Mathlib.MeasureTheory.Measure.AEMeasurable
7+
import Mathlib.MeasureTheory.Constructions.Prod.Basic
8+
import Mathlib.MeasureTheory.Constructions.Pi
9+
import Mathlib.MeasureTheory.Measure.Haar.OfBasis
10+
11+
import Mathlib.Tactic.FunProp
12+
import Mathlib.Tactic.FunProp.Measurable
13+
14+
/-!
15+
## `fun_prop` minimal setup for AEMeasurable
16+
-/
17+
18+
19+
section missing
20+
21+
open MeasureTheory
22+
23+
variable {ι α β γ δ R : Type*} {m0 : MeasurableSpace α} [MeasurableSpace β] [MeasurableSpace γ]
24+
[MeasurableSpace δ] {f g : α → β} {μ ν : Measure α}
25+
26+
theorem AEMeasurable.comp_aemeasurable' {f : α → δ} {g : δ → β} (hg : AEMeasurable g (μ.map f))
27+
(hf : AEMeasurable f μ) : AEMeasurable (fun x => g (f x)) μ := comp_aemeasurable hg hf
28+
29+
end missing
30+
31+
open Mathlib
32+
33+
-- mark definition
34+
attribute [fun_prop]
35+
AEMeasurable
36+
37+
-- lambda rules
38+
attribute [fun_prop]
39+
aemeasurable_id'
40+
aemeasurable_const
41+
AEMeasurable.comp_aemeasurable'
42+
-- Measurable.comp_aemeasurable'
43+
-- AEMeasurable_apply -- is this somewhere?
44+
-- AEMeasurable_pi -- is this somewhere?
45+
46+
-- product
47+
attribute [fun_prop]
48+
AEMeasurable.prod_mk
49+
AEMeasurable.fst
50+
AEMeasurable.snd
51+
52+
-- algebra
53+
attribute [fun_prop]
54+
AEMeasurable.add
55+
AEMeasurable.sub
56+
AEMeasurable.mul
57+
AEMeasurable.neg
58+
AEMeasurable.div
59+
AEMeasurable.inv
60+
AEMeasurable.smul
61+
62+
-- transitions
63+
attribute [fun_prop]
64+
AEMeasurable.mono'
65+
Measurable.aemeasurable
66+
67+
68+
attribute [fun_prop]
69+
AEMeasurable.mono'
70+
Measurable.aemeasurable
71+
72+
73+
-- Notice that no theorems about measuability of log are used. It is infered from continuity.
74+
example : AEMeasurable (fun x => x * (Real.log x) ^ 2 - Real.exp x / x) :=
75+
by fun_prop
76+
77+
private noncomputable def S (a b c d : ℝ) : ℝ :=
78+
a / (a + b + d) + b / (a + b + c) +
79+
c / (b + c + d) + d / (a + c + d)
80+
81+
private noncomputable def T (t : ℝ) : ℝ := S 1 (1 - t) t (t * (1 - t))
82+
83+
example : AEMeasurable T := by
84+
unfold T S
85+
fun_prop

Mathlib/Tactic/FunProp/Attr.lean

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/-
2+
Copyright (c) 2024 Tomas Skrivan. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Tomas Skrivan
5+
-/
6+
import Lean
7+
8+
import Mathlib.Tactic.FunProp.Decl
9+
import Mathlib.Tactic.FunProp.Theorems
10+
11+
/-!
12+
## `funProp` attribute
13+
-/
14+
15+
16+
namespace Mathlib
17+
open Lean Meta
18+
19+
namespace Meta.FunProp
20+
21+
-- TODO: add support for specifying priority and discharger
22+
-- open Lean.Parser.Tactic
23+
-- syntax (name:=Attr.funProp) "funProp" (prio)? (discharger)? : attr
24+
25+
private def funPropHelpString : String :=
26+
"`funProp` tactic to prove function properties like `Continuous`, `Differentiable`, `IsLinearMap`"
27+
28+
/-- Initialization of `funProp` attribute -/
29+
initialize funPropAttr : Unit ←
30+
registerBuiltinAttribute {
31+
name := `fun_prop
32+
descr := funPropHelpString
33+
applicationTime := AttributeApplicationTime.afterCompilation
34+
add := fun declName _stx attrKind =>
35+
discard <| MetaM.run do
36+
let info ← getConstInfo declName
37+
38+
forallTelescope info.type fun _ b => do
39+
if b.isProp then
40+
addFunPropDecl declName none
41+
else
42+
addTheorem declName attrKind
43+
erase := fun _declName =>
44+
throwError "can't remove `funProp` attribute (not implemented yet)"
45+
}

0 commit comments

Comments
 (0)