diff --git a/MyIA.AI.Notebooks/SymbolicAI/Lean/Lean-33-Distribution-Spaces.ipynb b/MyIA.AI.Notebooks/SymbolicAI/Lean/Lean-33-Distribution-Spaces.ipynb new file mode 100644 index 0000000000..eb98c50782 --- /dev/null +++ b/MyIA.AI.Notebooks/SymbolicAI/Lean/Lean-33-Distribution-Spaces.ipynb @@ -0,0 +1,1736 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a1b2c3d0", + "metadata": { + "papermill": { + "duration": 0.002414, + "end_time": "2026-09-14T07:32:53.401227+00:00", + "exception": false, + "start_time": "2026-09-14T07:32:53.398813+00:00", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "# Lean-33 : espaces de Schwartz — décroissance et régularité\n", + "\n", + "Compagnon **natif** du lake [`calibration_lean`](calibration_lean/) : le module\n", + "`Calibration.Distribution` y est **importé et exécuté** dans un kernel Lean 4 réel\n", + "(`lean4-wsl`). Chaque définition et chaque théorème est interrogé par `#check`,\n", + "`#print` ou `#print axioms` — les sorties de ce notebook sont des sorties du\n", + "compilateur Lean, pas de la prose à propos de Lean.\n", + "\n", + "Le lake `calibration_lean` porte des *cibles de calibration* pour le harnais de preuve\n", + "automatique (Epic #1452) : chaque théorème exerce un chemin différent du prouveur\n", + "(décision bornée, lemme ciblé à découvrir, erreur distante à diagnostiquer). Ce notebook\n", + "visite le module `Calibration.Distribution`, qui porte la capacité distinctive des\n", + "**espaces de Schwartz** : la *décroissance* de toutes les dérivées, mesurée par une\n", + "famille de *seminormes*.\n", + "\n", + "Prérequis : le kernel `lean4-wsl` (voir [Lean-1-Setup](Lean-1-Setup.ipynb) pour\n", + "l'installation). L'import du module suppose que le lake a été construit une fois\n", + "(`lake build Calibration.Distribution`).\n" + ] + }, + { + "cell_type": "markdown", + "id": "a1b2c3d1", + "metadata": { + "papermill": { + "duration": 0.001895, + "end_time": "2026-09-14T07:32:53.405089+00:00", + "exception": false, + "start_time": "2026-09-14T07:32:53.403194+00:00", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "## 1. Le contrat du module\n", + "\n", + "Une fonction de Schwartz est une fonction **lisse** dont **toutes les dérivées\n", + "décroissent plus vite que n'importe quelle puissance** de `‖x‖`. En Mathlib, cette\n", + "double exigence est portée par deux champs d'une seule structure :\n", + "\n", + "| Champ | Ce qu'il dit |\n", + "|---|---|\n", + "| `smooth'` | la **régularité** : `ContDiff ℝ ∞ toFun` |\n", + "| `decay'` | la **décroissance** : `∀ k n, ∃ C, ∀ x, ‖x‖^k * ‖iteratedFDeriv ℝ n toFun x‖ ≤ C` |\n", + "\n", + "Le module `Calibration.Distribution` **n'invente aucune définition** : il instancie\n", + "l'API `Mathlib.Analysis.Distribution.SchwartzSpace.Basic` réellement pinnée par le lake,\n", + "et il en expose les énoncés qui rendent le contrat manipulable.\n", + "\n", + "La cellule suivante est la **tête de session** : toutes les importations d'un notebook\n", + "Lean 4 vivent dans une seule cellule, placée en premier. On y interroge le type de la\n", + "structure et les signatures des théorèmes que le module ajoute.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "a1b2c3d2", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-14T07:32:53.410742Z", + "iopub.status.busy": "2026-09-14T07:32:53.410482Z", + "iopub.status.idle": "2026-09-14T07:33:07.449888Z", + "shell.execute_reply": "2026-09-14T07:33:07.448500Z" + }, + "papermill": { + "duration": 14.042887, + "end_time": "2026-09-14T07:33:07.450540+00:00", + "exception": false, + "start_time": "2026-09-14T07:32:53.407653+00:00", + "status": "completed" + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
-- Tete de session : toutes les importations viennent ici.
\n", + "
import Calibration.Distribution
\n", + "
\n", + "
open scoped SchwartzMap ContDiff
\n", + "
\n", + "
-- La structure de Mathlib telle que le module l'emploie :
\n", + "
SchwartzMap : (E : Type u_1) →\n", + " (F : Type u_2) →\n", + " [inst : NormedAddCommGroup E] →\n", + " [NormedSpace ℝ E] → [inst : NormedAddCommGroup F] → [NormedSpace ℝ F] → Type (max u_1 u_2)
\n", + "
SchwartzMap.seminorm.{u_2, u_5, u_6} (𝕜 : Type u_2) {E : Type u_5} {F : Type u_6} [NormedAddCommGroup E]\n", + " [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedField 𝕜] [NormedSpace 𝕜 F] [SMulCommClass ℝ 𝕜 F]\n", + " (k n : ℕ) : Seminorm 𝕜 𝓢(E, F)
\n", + "
\n", + "
-- Les theoremes que le module AJOUTE (namespace Calibration.Distribution) :
\n", + "
Calibration.Distribution.exists_decay_bound.{u_1, u_2} {E : Type u_1} {F : Type u_2} [NormedAddCommGroup E]\n", + " [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] (f : 𝓢(E, F)) (k n : ℕ) :\n", + " ∃ C, 0 < C ∧ ∀ (x : E), ‖x‖ ^ k * ‖iteratedFDeriv ℝ n (⇑f) x‖ ≤ C
\n", + "
Calibration.Distribution.seminorm_bounds_decay.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2}\n", + " {F : Type u_3} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\n", + " [SMulCommClass ℝ 𝕜 F] (f : 𝓢(E, F)) (k n : ℕ) (x : E) :\n", + " ‖x‖ ^ k * ‖iteratedFDeriv ℝ n (⇑f) x‖ ≤ (SchwartzMap.seminorm 𝕜 k n) f
\n", + "
Calibration.Distribution.seminorm_le_of_pointwise_bound.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2}\n", + " {F : Type u_3} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\n", + " [SMulCommClass ℝ 𝕜 F] (f : 𝓢(E, F)) (k n : ℕ) {M : ℝ} (hMp : 0 ≤ M)\n", + " (hM : ∀ (x : E), ‖x‖ ^ k * ‖iteratedFDeriv ℝ n (⇑f) x‖ ≤ M) : (SchwartzMap.seminorm 𝕜 k n) f ≤ M
\n", + "
Calibration.Distribution.norm_le_seminorm_div_pow.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2}\n", + " {F : Type u_3} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\n", + " [SMulCommClass ℝ 𝕜 F] (f : 𝓢(E, F)) (k : ℕ) {x : E} (hx : 0 < ‖x‖) : ‖f x‖ ≤ (SchwartzMap.seminorm 𝕜 k 0) f / ‖x‖ ^ k
\n", + "
\n", + "
--% env 0
\n", + "
\n", + "
\n", + " Raw input\n", + " {\"cmd\": \"-- Tete de session : toutes les importations viennent ici.\\nimport Calibration.Distribution\\n\\nopen scoped SchwartzMap ContDiff\\n\\n-- La structure de Mathlib telle que le module l'emploie :\\n#check @SchwartzMap\\n#check SchwartzMap.seminorm\\n\\n-- Les theoremes que le module AJOUTE (namespace Calibration.Distribution) :\\n#check Calibration.Distribution.exists_decay_bound\\n#check Calibration.Distribution.seminorm_bounds_decay\\n#check Calibration.Distribution.seminorm_le_of_pointwise_bound\\n#check Calibration.Distribution.norm_le_seminorm_div_pow\\n\"}\n", + "
\n", + "
\n", + " Raw output\n", + " {\"messages\":\r\n", + " [{\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 7, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 7, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"SchwartzMap : (E : Type u_1) →\\n (F : Type u_2) →\\n [inst : NormedAddCommGroup E] →\\n [NormedSpace ℝ E] → [inst : NormedAddCommGroup F] → [NormedSpace ℝ F] → Type (max u_1 u_2)\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 8, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 8, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"SchwartzMap.seminorm.{u_2, u_5, u_6} (𝕜 : Type u_2) {E : Type u_5} {F : Type u_6} [NormedAddCommGroup E]\\n [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedField 𝕜] [NormedSpace 𝕜 F] [SMulCommClass ℝ 𝕜 F]\\n (k n : ℕ) : Seminorm 𝕜 𝓢(E, F)\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 11, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 11, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"Calibration.Distribution.exists_decay_bound.{u_1, u_2} {E : Type u_1} {F : Type u_2} [NormedAddCommGroup E]\\n [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] (f : 𝓢(E, F)) (k n : ℕ) :\\n ∃ C, 0 < C ∧ ∀ (x : E), ‖x‖ ^ k * ‖iteratedFDeriv ℝ n (⇑f) x‖ ≤ C\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 12, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 12, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"Calibration.Distribution.seminorm_bounds_decay.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2}\\n {F : Type u_3} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\\n [SMulCommClass ℝ 𝕜 F] (f : 𝓢(E, F)) (k n : ℕ) (x : E) :\\n ‖x‖ ^ k * ‖iteratedFDeriv ℝ n (⇑f) x‖ ≤ (SchwartzMap.seminorm 𝕜 k n) f\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 13, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 13, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"Calibration.Distribution.seminorm_le_of_pointwise_bound.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2}\\n {F : Type u_3} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\\n [SMulCommClass ℝ 𝕜 F] (f : 𝓢(E, F)) (k n : ℕ) {M : ℝ} (hMp : 0 ≤ M)\\n (hM : ∀ (x : E), ‖x‖ ^ k * ‖iteratedFDeriv ℝ n (⇑f) x‖ ≤ M) : (SchwartzMap.seminorm 𝕜 k n) f ≤ M\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 14, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 14, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"Calibration.Distribution.norm_le_seminorm_div_pow.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2}\\n {F : Type u_3} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\\n [SMulCommClass ℝ 𝕜 F] (f : 𝓢(E, F)) (k : ℕ) {x : E} (hx : 0 < ‖x‖) : ‖f x‖ ≤ (SchwartzMap.seminorm 𝕜 k 0) f / ‖x‖ ^ k\"}],\r\n", + " \"env\": 0}\n", + "
\n", + " " + ], + "text/plain": [ + "-- Tete de session : toutes les importations viennent ici.\n", + "import Calibration.Distribution\n", + "\n", + "open scoped SchwartzMap ContDiff\n", + "\n", + "-- La structure de Mathlib telle que le module l'emploie :\n", + "#check @SchwartzMap\n", + "──────▶ SchwartzMap : (E : Type u_1) →\n", + " (F : Type u_2) →\n", + " [inst : NormedAddCommGroup E] →\n", + " [NormedSpace ℝ E] → [inst : NormedAddCommGroup F] → [NormedSpace ℝ F] → Type (max u_1 u_2)\n", + "#check SchwartzMap.seminorm\n", + "──────▶ SchwartzMap.seminorm.{u_2, u_5, u_6} (𝕜 : Type u_2) {E : Type u_5} {F : Type u_6} [NormedAddCommGroup E]\n", + " [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedField 𝕜] [NormedSpace 𝕜 F] [SMulCommClass ℝ 𝕜 F]\n", + " (k n : ℕ) : Seminorm 𝕜 𝓢(E, F)\n", + "\n", + "-- Les theoremes que le module AJOUTE (namespace Calibration.Distribution) :\n", + "#check Calibration.Distribution.exists_decay_bound\n", + "──────▶ Calibration.Distribution.exists_decay_bound.{u_1, u_2} {E : Type u_1} {F : Type u_2} [NormedAddCommGroup E]\n", + " [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] (f : 𝓢(E, F)) (k n : ℕ) :\n", + " ∃ C, 0 < C ∧ ∀ (x : E), ‖x‖ ^ k * ‖iteratedFDeriv ℝ n (⇑f) x‖ ≤ C\n", + "#check Calibration.Distribution.seminorm_bounds_decay\n", + "──────▶ Calibration.Distribution.seminorm_bounds_decay.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2}\n", + " {F : Type u_3} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\n", + " [SMulCommClass ℝ 𝕜 F] (f : 𝓢(E, F)) (k n : ℕ) (x : E) :\n", + " ‖x‖ ^ k * ‖iteratedFDeriv ℝ n (⇑f) x‖ ≤ (SchwartzMap.seminorm 𝕜 k n) f\n", + "#check Calibration.Distribution.seminorm_le_of_pointwise_bound\n", + "──────▶ Calibration.Distribution.seminorm_le_of_pointwise_bound.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2}\n", + " {F : Type u_3} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\n", + " [SMulCommClass ℝ 𝕜 F] (f : 𝓢(E, F)) (k n : ℕ) {M : ℝ} (hMp : 0 ≤ M)\n", + " (hM : ∀ (x : E), ‖x‖ ^ k * ‖iteratedFDeriv ℝ n (⇑f) x‖ ≤ M) : (SchwartzMap.seminorm 𝕜 k n) f ≤ M\n", + "#check Calibration.Distribution.norm_le_seminorm_div_pow\n", + "──────▶ Calibration.Distribution.norm_le_seminorm_div_pow.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2}\n", + " {F : Type u_3} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\n", + " [SMulCommClass ℝ 𝕜 F] (f : 𝓢(E, F)) (k : ℕ) {x : E} (hx : 0 < ‖x‖) : ‖f x‖ ≤ (SchwartzMap.seminorm 𝕜 k 0) f / ‖x‖ ^ k\n", + "\n", + "--% env 0\n", + "\n", + "Raw input:\n", + "{\"cmd\": \"-- Tete de session : toutes les importations viennent ici.\\nimport Calibration.Distribution\\n\\nopen scoped SchwartzMap ContDiff\\n\\n-- La structure de Mathlib telle que le module l'emploie :\\n#check @SchwartzMap\\n#check SchwartzMap.seminorm\\n\\n-- Les theoremes que le module AJOUTE (namespace Calibration.Distribution) :\\n#check Calibration.Distribution.exists_decay_bound\\n#check Calibration.Distribution.seminorm_bounds_decay\\n#check Calibration.Distribution.seminorm_le_of_pointwise_bound\\n#check Calibration.Distribution.norm_le_seminorm_div_pow\\n\"}\n", + "Raw output:\n", + "{\"messages\":\r\n", + " [{\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 7, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 7, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"SchwartzMap : (E : Type u_1) →\\n (F : Type u_2) →\\n [inst : NormedAddCommGroup E] →\\n [NormedSpace ℝ E] → [inst : NormedAddCommGroup F] → [NormedSpace ℝ F] → Type (max u_1 u_2)\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 8, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 8, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"SchwartzMap.seminorm.{u_2, u_5, u_6} (𝕜 : Type u_2) {E : Type u_5} {F : Type u_6} [NormedAddCommGroup E]\\n [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedField 𝕜] [NormedSpace 𝕜 F] [SMulCommClass ℝ 𝕜 F]\\n (k n : ℕ) : Seminorm 𝕜 𝓢(E, F)\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 11, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 11, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"Calibration.Distribution.exists_decay_bound.{u_1, u_2} {E : Type u_1} {F : Type u_2} [NormedAddCommGroup E]\\n [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] (f : 𝓢(E, F)) (k n : ℕ) :\\n ∃ C, 0 < C ∧ ∀ (x : E), ‖x‖ ^ k * ‖iteratedFDeriv ℝ n (⇑f) x‖ ≤ C\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 12, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 12, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"Calibration.Distribution.seminorm_bounds_decay.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2}\\n {F : Type u_3} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\\n [SMulCommClass ℝ 𝕜 F] (f : 𝓢(E, F)) (k n : ℕ) (x : E) :\\n ‖x‖ ^ k * ‖iteratedFDeriv ℝ n (⇑f) x‖ ≤ (SchwartzMap.seminorm 𝕜 k n) f\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 13, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 13, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"Calibration.Distribution.seminorm_le_of_pointwise_bound.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2}\\n {F : Type u_3} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\\n [SMulCommClass ℝ 𝕜 F] (f : 𝓢(E, F)) (k n : ℕ) {M : ℝ} (hMp : 0 ≤ M)\\n (hM : ∀ (x : E), ‖x‖ ^ k * ‖iteratedFDeriv ℝ n (⇑f) x‖ ≤ M) : (SchwartzMap.seminorm 𝕜 k n) f ≤ M\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 14, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 14, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"Calibration.Distribution.norm_le_seminorm_div_pow.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2}\\n {F : Type u_3} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\\n [SMulCommClass ℝ 𝕜 F] (f : 𝓢(E, F)) (k : ℕ) {x : E} (hx : 0 < ‖x‖) : ‖f x‖ ≤ (SchwartzMap.seminorm 𝕜 k 0) f / ‖x‖ ^ k\"}],\r\n", + " \"env\": 0}" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "-- Tete de session : toutes les importations viennent ici.\n", + "import Calibration.Distribution\n", + "\n", + "open scoped SchwartzMap ContDiff\n", + "\n", + "-- La structure de Mathlib telle que le module l'emploie :\n", + "#check @SchwartzMap\n", + "#check SchwartzMap.seminorm\n", + "\n", + "-- Les theoremes que le module AJOUTE (namespace Calibration.Distribution) :\n", + "#check Calibration.Distribution.exists_decay_bound\n", + "#check Calibration.Distribution.seminorm_bounds_decay\n", + "#check Calibration.Distribution.seminorm_le_of_pointwise_bound\n", + "#check Calibration.Distribution.norm_le_seminorm_div_pow\n" + ] + }, + { + "cell_type": "markdown", + "id": "a1b2c3d3", + "metadata": { + "papermill": { + "duration": 0.001975, + "end_time": "2026-09-14T07:33:07.454988+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:07.453013+00:00", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "### Lecture du résultat\n", + "\n", + "`#check @SchwartzMap` rend la **signature de la famille de types** : deux paramètres de\n", + "type `E` et `F`, puis les hypothèses d'instance qu'il faut avoir en portée pour que\n", + "`𝓢(E, F)` dénote un type — `NormedAddCommGroup` et `NormedSpace ℝ` de part et d'autre —\n", + "et le résultat `Type (max u_1 u_2)`. C'est la **forme du type**, pas son contenu : ni les\n", + "champs ni le constructeur n'apparaissent ici. C'est `#print SchwartzMap`, en section 2,\n", + "qui les demande au noyau.\n", + "\n", + "`#check SchwartzMap.seminorm` montre que la seminorme prend **deux indices** `(k, n)` :\n", + "`k` indexe l'ordre de décroissance (`‖x‖^k`) et `n` l'ordre de dérivation\n", + "(`iteratedFDeriv ℝ n`). Un seul objet mesure donc les deux moitiés du contrat.\n", + "\n", + "Les quatre `#check` suivants sont les énoncés **ajoutés par le module** : la décroissance\n", + "brute avec une constante strictement positive, la seminorme comme majorant, la seminorme\n", + "comme *plus petit* majorant, et la décroissance polynômiale effective qui se déduit de\n", + "la seminorme. Aucun n'est déclaré `sorry` — ce sont des théorèmes clos.\n" + ] + }, + { + "cell_type": "markdown", + "id": "a1b2c3d2b", + "metadata": { + "papermill": { + "duration": 0.001883, + "end_time": "2026-09-14T07:33:07.458818+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:07.456935+00:00", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "## 2. La structure, imprimée par le compilateur\n", + "\n", + "`#check` donne la *signature*. `#print` donne la *définition*. Pour une structure, `#print`\n", + "est le moyen le plus direct de lire le contrat : les champs et leurs types, tels que le\n", + "noyau Lean les connaît.\n", + "\n", + "C'est aussi la première chose qu'un prouveur — humain ou automatique — doit lire avant de\n", + "vouloir produire une fonction de Schwartz : *que me demande-t-on de fournir exactement ?*\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "a1b2c3d2c", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-14T07:33:07.464172Z", + "iopub.status.busy": "2026-09-14T07:33:07.464000Z", + "iopub.status.idle": "2026-09-14T07:33:07.650016Z", + "shell.execute_reply": "2026-09-14T07:33:07.649292Z" + }, + "papermill": { + "duration": 0.189864, + "end_time": "2026-09-14T07:33:07.650636+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:07.460772+00:00", + "status": "completed" + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
-- La structure telle que le noyau la connait : ses champs et leurs types.
\n", + "
structure SchwartzMap.{u_5, u_6} (E : Type u_5) (F : Type u_6) [NormedAddCommGroup E] [NormedSpace ℝ E]\n", + " [NormedAddCommGroup F] [NormedSpace ℝ F] : Type (max u_5 u_6)\n", + "number of parameters: 6\n", + "fields:\n", + " SchwartzMap.toFun : E → F\n", + " SchwartzMap.smooth' : ContDiff ℝ ∞ self.toFun\n", + " SchwartzMap.decay' : ∀ (k n : ℕ), ∃ C, ∀ (x : E), ‖x‖ ^ k * ‖iteratedFDeriv ℝ n self.toFun x‖ ≤ C\n", + "constructor:\n", + " SchwartzMap.mk.{u_5, u_6} {E : Type u_5} {F : Type u_6} [NormedAddCommGroup E] [NormedSpace ℝ E]\n", + " [NormedAddCommGroup F] [NormedSpace ℝ F] (toFun : E → F) (smooth' : ContDiff ℝ ∞ toFun)\n", + " (decay' : ∀ (k n : ℕ), ∃ C, ∀ (x : E), ‖x‖ ^ k * ‖iteratedFDeriv ℝ n toFun x‖ ≤ C) : 𝓢(E, F)
\n", + "
\n", + "
--% env 1
\n", + "
\n", + "
\n", + " Raw input\n", + " {\"cmd\": \"-- La structure telle que le noyau la connait : ses champs et leurs types.\\n#print SchwartzMap\\n\", \"env\": 0}\n", + "
\n", + "
\n", + " Raw output\n", + " {\"messages\":\r\n", + " [{\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 2, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 2, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"structure SchwartzMap.{u_5, u_6} (E : Type u_5) (F : Type u_6) [NormedAddCommGroup E] [NormedSpace ℝ E]\\n [NormedAddCommGroup F] [NormedSpace ℝ F] : Type (max u_5 u_6)\\nnumber of parameters: 6\\nfields:\\n SchwartzMap.toFun : E → F\\n SchwartzMap.smooth' : ContDiff ℝ ∞ self.toFun\\n SchwartzMap.decay' : ∀ (k n : ℕ), ∃ C, ∀ (x : E), ‖x‖ ^ k * ‖iteratedFDeriv ℝ n self.toFun x‖ ≤ C\\nconstructor:\\n SchwartzMap.mk.{u_5, u_6} {E : Type u_5} {F : Type u_6} [NormedAddCommGroup E] [NormedSpace ℝ E]\\n [NormedAddCommGroup F] [NormedSpace ℝ F] (toFun : E → F) (smooth' : ContDiff ℝ ∞ toFun)\\n (decay' : ∀ (k n : ℕ), ∃ C, ∀ (x : E), ‖x‖ ^ k * ‖iteratedFDeriv ℝ n toFun x‖ ≤ C) : 𝓢(E, F)\"}],\r\n", + " \"env\": 1}\n", + "
\n", + " " + ], + "text/plain": [ + "-- La structure telle que le noyau la connait : ses champs et leurs types.\n", + "#print SchwartzMap\n", + "──────▶ structure SchwartzMap.{u_5, u_6} (E : Type u_5) (F : Type u_6) [NormedAddCommGroup E] [NormedSpace ℝ E]\n", + " [NormedAddCommGroup F] [NormedSpace ℝ F] : Type (max u_5 u_6)\n", + "number of parameters: 6\n", + "fields:\n", + " SchwartzMap.toFun : E → F\n", + " SchwartzMap.smooth' : ContDiff ℝ ∞ self.toFun\n", + " SchwartzMap.decay' : ∀ (k n : ℕ), ∃ C, ∀ (x : E), ‖x‖ ^ k * ‖iteratedFDeriv ℝ n self.toFun x‖ ≤ C\n", + "constructor:\n", + " SchwartzMap.mk.{u_5, u_6} {E : Type u_5} {F : Type u_6} [NormedAddCommGroup E] [NormedSpace ℝ E]\n", + " [NormedAddCommGroup F] [NormedSpace ℝ F] (toFun : E → F) (smooth' : ContDiff ℝ ∞ toFun)\n", + " (decay' : ∀ (k n : ℕ), ∃ C, ∀ (x : E), ‖x‖ ^ k * ‖iteratedFDeriv ℝ n toFun x‖ ≤ C) : 𝓢(E, F)\n", + "\n", + "--% env 1\n", + "\n", + "Raw input:\n", + "{\"cmd\": \"-- La structure telle que le noyau la connait : ses champs et leurs types.\\n#print SchwartzMap\\n\", \"env\": 0}\n", + "Raw output:\n", + "{\"messages\":\r\n", + " [{\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 2, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 2, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"structure SchwartzMap.{u_5, u_6} (E : Type u_5) (F : Type u_6) [NormedAddCommGroup E] [NormedSpace ℝ E]\\n [NormedAddCommGroup F] [NormedSpace ℝ F] : Type (max u_5 u_6)\\nnumber of parameters: 6\\nfields:\\n SchwartzMap.toFun : E → F\\n SchwartzMap.smooth' : ContDiff ℝ ∞ self.toFun\\n SchwartzMap.decay' : ∀ (k n : ℕ), ∃ C, ∀ (x : E), ‖x‖ ^ k * ‖iteratedFDeriv ℝ n self.toFun x‖ ≤ C\\nconstructor:\\n SchwartzMap.mk.{u_5, u_6} {E : Type u_5} {F : Type u_6} [NormedAddCommGroup E] [NormedSpace ℝ E]\\n [NormedAddCommGroup F] [NormedSpace ℝ F] (toFun : E → F) (smooth' : ContDiff ℝ ∞ toFun)\\n (decay' : ∀ (k n : ℕ), ∃ C, ∀ (x : E), ‖x‖ ^ k * ‖iteratedFDeriv ℝ n toFun x‖ ≤ C) : 𝓢(E, F)\"}],\r\n", + " \"env\": 1}" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "-- La structure telle que le noyau la connait : ses champs et leurs types.\n", + "#print SchwartzMap\n" + ] + }, + { + "cell_type": "markdown", + "id": "a1b2c3d4", + "metadata": { + "papermill": { + "duration": 0.002205, + "end_time": "2026-09-14T07:33:07.655380+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:07.653175+00:00", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "### Lecture du résultat\n", + "\n", + "L'impression confirme les deux champs annoncés :\n", + "\n", + "* `smooth' : ContDiff ℝ ∞ toFun` — la **régularité** ;\n", + "* `decay' : ∀ (k n : ℕ), ∃ C, ∀ (x : E), ‖x‖ ^ k * ‖iteratedFDeriv ℝ n toFun x‖ ≤ C` —\n", + " la **décroissance**.\n", + "\n", + "Le point à retenir est la **quantification** : la constante `C` dépend de `k` et de `n`\n", + "mais **pas de `x`**. C'est ce « pas de `x` » qui fait toute la force de l'énoncé — la\n", + "même constante majore l'estimation sur tout l'espace, y compris là où `‖x‖` devient\n", + "arbitrairement grand. Un `C` qui dépendrait de `x` ne dirait rien.\n", + "\n", + "C'est précisément ce quantificateur que la famille de seminormes transforme en **nombre** :\n", + "`SchwartzMap.seminorm 𝕜 k n f` est la *meilleure* constante `C` possible pour le couple\n", + "`(k, n)`.\n" + ] + }, + { + "cell_type": "markdown", + "id": "a1b2c3d5", + "metadata": { + "papermill": { + "duration": 0.002248, + "end_time": "2026-09-14T07:33:07.659969+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:07.657721+00:00", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "## 3. Employer le module : deux corollaires rejoués en session\n", + "\n", + "Importer un module ne prouve pas qu'on l'a compris. La cellule suivante **emploie** les\n", + "théorèmes du module pour obtenir deux corollaires qui ne sont pas dans le module :\n", + "la décroissance polynômiale d'ordre `1`, et sa forme en `k = 0`.\n", + "\n", + "Les `example` ci-dessous n'ont pas de nom : Lean les vérifie et les jette. S'ils\n", + "élaborent, c'est que les énoncés du module s'appliquent **dans la session du notebook**,\n", + "sur les objets de Mathlib chargés par l'import — pas seulement dans le fichier du lake.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "a1b2c3d6", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-14T07:33:07.665698Z", + "iopub.status.busy": "2026-09-14T07:33:07.665533Z", + "iopub.status.idle": "2026-09-14T07:33:07.944188Z", + "shell.execute_reply": "2026-09-14T07:33:07.943365Z" + }, + "papermill": { + "duration": 0.282428, + "end_time": "2026-09-14T07:33:07.944774+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:07.662346+00:00", + "status": "completed" + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
-- Le theoreme du module, rejoue sur la droite reelle pour k = 1.
\n", + "
-- (Le corps scalaire `𝕜` est un argument implicite : on l'instancie par `ℝ`,
\n", + "
--  et `simpa` normalise `‖x‖^1` en `‖x‖`.)
\n", + "
example (f : 𝓢(ℝ, ℝ)) {x : ℝ} (hx : 0 < ‖x‖) :
\n", + "
    ‖f x‖ ≤ SchwartzMap.seminorm ℝ 1 0 f / ‖x‖ := by
\n", + "
  simpa using Calibration.Distribution.norm_le_seminorm_div_pow (𝕜 := ℝ) f 1 hx
\n", + "
\n", + "
-- ... et son cas k = 0, qui n'a meme plus besoin de l'hypothese ‖x‖ > 0 :
\n", + "
example (f : 𝓢(ℝ, ℝ)) (x : ℝ) :
\n", + "
    ‖f x‖ ≤ SchwartzMap.seminorm ℝ 0 0 f :=
\n", + "
  Calibration.Distribution.norm_le_seminorm_zero f x
\n", + "
\n", + "
-- Le contrat de regularite, lu comme un enonce public :
\n", + "
example (f : 𝓢(ℝ, ℝ)) : ContDiff ℝ ∞ (f : ℝ → ℝ) :=
\n", + "
  Calibration.Distribution.smooth_of_schwartz f
\n", + "
\n", + "
-- Un `example` n'affiche rien quand il elabore : c'est pourquoi la cellule a paru
\n", + "
-- muette. On rend donc visible ce qui vient d'etre applique, en demandant au
\n", + "
-- compilateur les signatures des deux enonces du module employes par les deux
\n", + "
-- derniers `example`, puis la borne de Mathlib sur laquelle repose le premier :
\n", + "
Calibration.Distribution.norm_le_seminorm_zero.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2}\n", + " {F : Type u_3} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\n", + " [SMulCommClass ℝ 𝕜 F] (f : 𝓢(E, F)) (x : E) : ‖f x‖ ≤ (SchwartzMap.seminorm 𝕜 0 0) f
\n", + "
Calibration.Distribution.smooth_of_schwartz.{u_1, u_2} {E : Type u_1} {F : Type u_2} [NormedAddCommGroup E]\n", + " [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] (f : 𝓢(E, F)) : ContDiff ℝ ∞ ⇑f
\n", + "
SchwartzMap.norm_pow_mul_le_seminorm.{u_2, u_5, u_6} (𝕜 : Type u_2) {E : Type u_5} {F : Type u_6} [NormedAddCommGroup E]\n", + " [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedField 𝕜] [NormedSpace 𝕜 F] [SMulCommClass ℝ 𝕜 F]\n", + " (f : 𝓢(E, F)) (k : ℕ) (x₀ : E) : ‖x₀‖ ^ k * ‖f x₀‖ ≤ (SchwartzMap.seminorm 𝕜 k 0) f
\n", + "
\n", + "
--% env 2
\n", + "
\n", + "
\n", + " Raw input\n", + " {\"cmd\": \"-- Le theoreme du module, rejoue sur la droite reelle pour k = 1.\\n-- (Le corps scalaire `\\ud835\\udd5c` est un argument implicite : on l'instancie par `\\u211d`,\\n-- et `simpa` normalise `\\u2016x\\u2016^1` en `\\u2016x\\u2016`.)\\nexample (f : \\ud835\\udce2(\\u211d, \\u211d)) {x : \\u211d} (hx : 0 < \\u2016x\\u2016) :\\n \\u2016f x\\u2016 \\u2264 SchwartzMap.seminorm \\u211d 1 0 f / \\u2016x\\u2016 := by\\n simpa using Calibration.Distribution.norm_le_seminorm_div_pow (\\ud835\\udd5c := \\u211d) f 1 hx\\n\\n-- ... et son cas k = 0, qui n'a meme plus besoin de l'hypothese \\u2016x\\u2016 > 0 :\\nexample (f : \\ud835\\udce2(\\u211d, \\u211d)) (x : \\u211d) :\\n \\u2016f x\\u2016 \\u2264 SchwartzMap.seminorm \\u211d 0 0 f :=\\n Calibration.Distribution.norm_le_seminorm_zero f x\\n\\n-- Le contrat de regularite, lu comme un enonce public :\\nexample (f : \\ud835\\udce2(\\u211d, \\u211d)) : ContDiff \\u211d \\u221e (f : \\u211d \\u2192 \\u211d) :=\\n Calibration.Distribution.smooth_of_schwartz f\\n\\n-- Un `example` n'affiche rien quand il elabore : c'est pourquoi la cellule a paru\\n-- muette. On rend donc visible ce qui vient d'etre applique, en demandant au\\n-- compilateur les signatures des deux enonces du module employes par les deux\\n-- derniers `example`, puis la borne de Mathlib sur laquelle repose le premier :\\n#check Calibration.Distribution.norm_le_seminorm_zero\\n#check Calibration.Distribution.smooth_of_schwartz\\n#check SchwartzMap.norm_pow_mul_le_seminorm\\n\", \"env\": 1}\n", + "
\n", + "
\n", + " Raw output\n", + " {\"messages\":\r\n", + " [{\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 21, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 21, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"Calibration.Distribution.norm_le_seminorm_zero.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2}\\n {F : Type u_3} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\\n [SMulCommClass ℝ 𝕜 F] (f : 𝓢(E, F)) (x : E) : ‖f x‖ ≤ (SchwartzMap.seminorm 𝕜 0 0) f\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 22, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 22, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"Calibration.Distribution.smooth_of_schwartz.{u_1, u_2} {E : Type u_1} {F : Type u_2} [NormedAddCommGroup E]\\n [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] (f : 𝓢(E, F)) : ContDiff ℝ ∞ ⇑f\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 23, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 23, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"SchwartzMap.norm_pow_mul_le_seminorm.{u_2, u_5, u_6} (𝕜 : Type u_2) {E : Type u_5} {F : Type u_6} [NormedAddCommGroup E]\\n [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedField 𝕜] [NormedSpace 𝕜 F] [SMulCommClass ℝ 𝕜 F]\\n (f : 𝓢(E, F)) (k : ℕ) (x₀ : E) : ‖x₀‖ ^ k * ‖f x₀‖ ≤ (SchwartzMap.seminorm 𝕜 k 0) f\"}],\r\n", + " \"env\": 2}\n", + "
\n", + " " + ], + "text/plain": [ + "-- Le theoreme du module, rejoue sur la droite reelle pour k = 1.\n", + "-- (Le corps scalaire `𝕜` est un argument implicite : on l'instancie par `ℝ`,\n", + "-- et `simpa` normalise `‖x‖^1` en `‖x‖`.)\n", + "example (f : 𝓢(ℝ, ℝ)) {x : ℝ} (hx : 0 < ‖x‖) :\n", + " ‖f x‖ ≤ SchwartzMap.seminorm ℝ 1 0 f / ‖x‖ := by\n", + " simpa using Calibration.Distribution.norm_le_seminorm_div_pow (𝕜 := ℝ) f 1 hx\n", + "\n", + "-- ... et son cas k = 0, qui n'a meme plus besoin de l'hypothese ‖x‖ > 0 :\n", + "example (f : 𝓢(ℝ, ℝ)) (x : ℝ) :\n", + " ‖f x‖ ≤ SchwartzMap.seminorm ℝ 0 0 f :=\n", + " Calibration.Distribution.norm_le_seminorm_zero f x\n", + "\n", + "-- Le contrat de regularite, lu comme un enonce public :\n", + "example (f : 𝓢(ℝ, ℝ)) : ContDiff ℝ ∞ (f : ℝ → ℝ) :=\n", + " Calibration.Distribution.smooth_of_schwartz f\n", + "\n", + "-- Un `example` n'affiche rien quand il elabore : c'est pourquoi la cellule a paru\n", + "-- muette. On rend donc visible ce qui vient d'etre applique, en demandant au\n", + "-- compilateur les signatures des deux enonces du module employes par les deux\n", + "-- derniers `example`, puis la borne de Mathlib sur laquelle repose le premier :\n", + "#check Calibration.Distribution.norm_le_seminorm_zero\n", + "──────▶ Calibration.Distribution.norm_le_seminorm_zero.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2}\n", + " {F : Type u_3} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\n", + " [SMulCommClass ℝ 𝕜 F] (f : 𝓢(E, F)) (x : E) : ‖f x‖ ≤ (SchwartzMap.seminorm 𝕜 0 0) f\n", + "#check Calibration.Distribution.smooth_of_schwartz\n", + "──────▶ Calibration.Distribution.smooth_of_schwartz.{u_1, u_2} {E : Type u_1} {F : Type u_2} [NormedAddCommGroup E]\n", + " [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] (f : 𝓢(E, F)) : ContDiff ℝ ∞ ⇑f\n", + "#check SchwartzMap.norm_pow_mul_le_seminorm\n", + "──────▶ SchwartzMap.norm_pow_mul_le_seminorm.{u_2, u_5, u_6} (𝕜 : Type u_2) {E : Type u_5} {F : Type u_6} [NormedAddCommGroup E]\n", + " [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedField 𝕜] [NormedSpace 𝕜 F] [SMulCommClass ℝ 𝕜 F]\n", + " (f : 𝓢(E, F)) (k : ℕ) (x₀ : E) : ‖x₀‖ ^ k * ‖f x₀‖ ≤ (SchwartzMap.seminorm 𝕜 k 0) f\n", + "\n", + "--% env 2\n", + "\n", + "Raw input:\n", + "{\"cmd\": \"-- Le theoreme du module, rejoue sur la droite reelle pour k = 1.\\n-- (Le corps scalaire `\\ud835\\udd5c` est un argument implicite : on l'instancie par `\\u211d`,\\n-- et `simpa` normalise `\\u2016x\\u2016^1` en `\\u2016x\\u2016`.)\\nexample (f : \\ud835\\udce2(\\u211d, \\u211d)) {x : \\u211d} (hx : 0 < \\u2016x\\u2016) :\\n \\u2016f x\\u2016 \\u2264 SchwartzMap.seminorm \\u211d 1 0 f / \\u2016x\\u2016 := by\\n simpa using Calibration.Distribution.norm_le_seminorm_div_pow (\\ud835\\udd5c := \\u211d) f 1 hx\\n\\n-- ... et son cas k = 0, qui n'a meme plus besoin de l'hypothese \\u2016x\\u2016 > 0 :\\nexample (f : \\ud835\\udce2(\\u211d, \\u211d)) (x : \\u211d) :\\n \\u2016f x\\u2016 \\u2264 SchwartzMap.seminorm \\u211d 0 0 f :=\\n Calibration.Distribution.norm_le_seminorm_zero f x\\n\\n-- Le contrat de regularite, lu comme un enonce public :\\nexample (f : \\ud835\\udce2(\\u211d, \\u211d)) : ContDiff \\u211d \\u221e (f : \\u211d \\u2192 \\u211d) :=\\n Calibration.Distribution.smooth_of_schwartz f\\n\\n-- Un `example` n'affiche rien quand il elabore : c'est pourquoi la cellule a paru\\n-- muette. On rend donc visible ce qui vient d'etre applique, en demandant au\\n-- compilateur les signatures des deux enonces du module employes par les deux\\n-- derniers `example`, puis la borne de Mathlib sur laquelle repose le premier :\\n#check Calibration.Distribution.norm_le_seminorm_zero\\n#check Calibration.Distribution.smooth_of_schwartz\\n#check SchwartzMap.norm_pow_mul_le_seminorm\\n\", \"env\": 1}\n", + "Raw output:\n", + "{\"messages\":\r\n", + " [{\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 21, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 21, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"Calibration.Distribution.norm_le_seminorm_zero.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2}\\n {F : Type u_3} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\\n [SMulCommClass ℝ 𝕜 F] (f : 𝓢(E, F)) (x : E) : ‖f x‖ ≤ (SchwartzMap.seminorm 𝕜 0 0) f\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 22, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 22, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"Calibration.Distribution.smooth_of_schwartz.{u_1, u_2} {E : Type u_1} {F : Type u_2} [NormedAddCommGroup E]\\n [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] (f : 𝓢(E, F)) : ContDiff ℝ ∞ ⇑f\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 23, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 23, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"SchwartzMap.norm_pow_mul_le_seminorm.{u_2, u_5, u_6} (𝕜 : Type u_2) {E : Type u_5} {F : Type u_6} [NormedAddCommGroup E]\\n [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedField 𝕜] [NormedSpace 𝕜 F] [SMulCommClass ℝ 𝕜 F]\\n (f : 𝓢(E, F)) (k : ℕ) (x₀ : E) : ‖x₀‖ ^ k * ‖f x₀‖ ≤ (SchwartzMap.seminorm 𝕜 k 0) f\"}],\r\n", + " \"env\": 2}" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "-- Le theoreme du module, rejoue sur la droite reelle pour k = 1.\n", + "-- (Le corps scalaire `𝕜` est un argument implicite : on l'instancie par `ℝ`,\n", + "-- et `simpa` normalise `‖x‖^1` en `‖x‖`.)\n", + "example (f : 𝓢(ℝ, ℝ)) {x : ℝ} (hx : 0 < ‖x‖) :\n", + " ‖f x‖ ≤ SchwartzMap.seminorm ℝ 1 0 f / ‖x‖ := by\n", + " simpa using Calibration.Distribution.norm_le_seminorm_div_pow (𝕜 := ℝ) f 1 hx\n", + "\n", + "-- ... et son cas k = 0, qui n'a meme plus besoin de l'hypothese ‖x‖ > 0 :\n", + "example (f : 𝓢(ℝ, ℝ)) (x : ℝ) :\n", + " ‖f x‖ ≤ SchwartzMap.seminorm ℝ 0 0 f :=\n", + " Calibration.Distribution.norm_le_seminorm_zero f x\n", + "\n", + "-- Le contrat de regularite, lu comme un enonce public :\n", + "example (f : 𝓢(ℝ, ℝ)) : ContDiff ℝ ∞ (f : ℝ → ℝ) :=\n", + " Calibration.Distribution.smooth_of_schwartz f\n", + "\n", + "-- Un `example` n'affiche rien quand il elabore : c'est pourquoi la cellule a paru\n", + "-- muette. On rend donc visible ce qui vient d'etre applique, en demandant au\n", + "-- compilateur les signatures des deux enonces du module employes par les deux\n", + "-- derniers `example`, puis la borne de Mathlib sur laquelle repose le premier :\n", + "#check Calibration.Distribution.norm_le_seminorm_zero\n", + "#check Calibration.Distribution.smooth_of_schwartz\n", + "#check SchwartzMap.norm_pow_mul_le_seminorm\n" + ] + }, + { + "cell_type": "markdown", + "id": "a1b2c3d7", + "metadata": { + "papermill": { + "duration": 0.002499, + "end_time": "2026-09-14T07:33:07.950205+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:07.947706+00:00", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "### Lecture du résultat\n", + "\n", + "Les trois `example` n'affichent **rien** : Lean est muet quand un `example` élabore, et\n", + "c'est justement le signe qu'ils passent — une erreur aurait rougi la case entière. Les\n", + "`#check` en fin de cellule compensent ce silence en faisant imprimer les signatures que\n", + "les `example` viennent d'appliquer.\n", + "\n", + "Ce qui vient d'être vérifié mérite d'être dit précisément : les trois `example` ne sont\n", + "pas des redites du module. Le premier **instancie** `norm_le_seminorm_div_pow` à `k = 1`\n", + "pour obtenir la décroissance `‖f x‖ ≤ C / ‖x‖` ; le deuxième applique\n", + "`norm_le_seminorm_zero`, le cas `k = 0`, qui se passe même de l'hypothèse `0 < ‖x‖` ; le\n", + "troisième **lit** `smooth_of_schwartz`, la régularité présentée comme un théorème public\n", + "sur la fonction sous-jacente. Les énoncés du module sont donc utilisables comme des\n", + "briques, ce qui est exactement ce qu'on attend d'un module pédagogique : il doit *servir*,\n", + "pas seulement exister.\n" + ] + }, + { + "cell_type": "markdown", + "id": "a1b2c3d8", + "metadata": { + "papermill": { + "duration": 0.002359, + "end_time": "2026-09-14T07:33:07.954935+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:07.952576+00:00", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "## 4. Ce que « plus vite que toute puissance » veut dire — numériquement\n", + "\n", + "Les sections précédentes sont formelles. Cette section est **numérique et illustrative** :\n", + "elle ne prouve rien, elle donne une intuition calculable de la quantification lue en\n", + "section 2. Le code ci-dessous n'emploie aucune tactic ni aucun objet de Schwartz — il\n", + "échantillonne des profils sur une grille finie.\n", + "\n", + "On mesure, pour une fonction `f` donnée, la quantité\n", + "\n", + "$$\\sup_{|x| \\le R} \\; |x|^k \\, |f(x)|$$\n", + "\n", + "pour `k` fixé et `R` croissant. Deux comportements sont possibles :\n", + "\n", + "* la quantité **plafonne** — alors la constante `C` de `decay'` existe pour ce `k` ;\n", + "* la quantité **croît sans borne** — alors aucune constante ne convient pour ce `k`.\n", + "\n", + "Le second cas est le plus instructif : il montre qu'une fonction peut *décroître* et\n", + "n'être *pas* de Schwartz pour autant.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a1b2c3d9", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-14T07:33:07.960872Z", + "iopub.status.busy": "2026-09-14T07:33:07.960713Z", + "iopub.status.idle": "2026-09-14T07:33:08.222069Z", + "shell.execute_reply": "2026-09-14T07:33:08.221270Z" + }, + "papermill": { + "duration": 0.265086, + "end_time": "2026-09-14T07:33:08.222570+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:07.957484+00:00", + "status": "completed" + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
-- Illustration DISCRETE (ce n'est pas une preuve Mathlib) : on echantillonne
\n", + "
-- le profil |x|^k * |f x| sur [-R, R] et on lit le maximum atteint.
\n", + "
-- `f x = 1 / (1 + x^2)` est lisse et decroit comme 1/x^2.
\n", + "
--
\n", + "
-- Note technique : `Float` n'instancie pas `HPow _ Nat` ; on definit donc
\n", + "
-- l'exponentiation entiere par recursion plutot que d'ecrire `x ^ k`.
\n", + "
\n", + "
def powF (x : Float) : Nat → Float
\n", + "
  | 0 => 1.0
\n", + "
  | n + 1 => x * powF x n
\n", + "
\n", + "
def supProfile (k : Nat) (R : Float) (N : Nat) : Float :=
\n", + "
  let step := 2.0 * R / Float.ofNat N
\n", + "
  (List.range N).foldl (fun acc i =>
\n", + "
    let x := -R + step * Float.ofNat i
\n", + "
    max acc (powF (Float.abs x) k * (1.0 / (1.0 + x * x)))) 0.0
\n", + "
\n", + "
-- k = 2 : le profil PLAFONNE quand R grandit -> la constante C_2 existe.
\n", + "
0.990099
\n", + "
0.999999
\n", + "
1.000000
\n", + "
\n", + "
-- k = 4 : le profil CROIT avec R -> aucune constante C_4 ne convient.
\n", + "
99.009901
\n", + "
999999.000001
\n", + "
999999999998.999878
\n", + "
\n", + "
--% env 3
\n", + "
\n", + "
\n", + " Raw input\n", + " {\"cmd\": \"-- Illustration DISCRETE (ce n'est pas une preuve Mathlib) : on echantillonne\\n-- le profil |x|^k * |f x| sur [-R, R] et on lit le maximum atteint.\\n-- `f x = 1 / (1 + x^2)` est lisse et decroit comme 1/x^2.\\n--\\n-- Note technique : `Float` n'instancie pas `HPow _ Nat` ; on definit donc\\n-- l'exponentiation entiere par recursion plutot que d'ecrire `x ^ k`.\\n\\ndef powF (x : Float) : Nat \\u2192 Float\\n | 0 => 1.0\\n | n + 1 => x * powF x n\\n\\ndef supProfile (k : Nat) (R : Float) (N : Nat) : Float :=\\n let step := 2.0 * R / Float.ofNat N\\n (List.range N).foldl (fun acc i =>\\n let x := -R + step * Float.ofNat i\\n max acc (powF (Float.abs x) k * (1.0 / (1.0 + x * x)))) 0.0\\n\\n-- k = 2 : le profil PLAFONNE quand R grandit -> la constante C_2 existe.\\n#eval supProfile 2 10.0 4000\\n#eval supProfile 2 1000.0 4000\\n#eval supProfile 2 1000000.0 4000\\n\\n-- k = 4 : le profil CROIT avec R -> aucune constante C_4 ne convient.\\n#eval supProfile 4 10.0 4000\\n#eval supProfile 4 1000.0 4000\\n#eval supProfile 4 1000000.0 4000\\n\", \"env\": 2}\n", + "
\n", + "
\n", + " Raw output\n", + " {\"messages\":\r\n", + " [{\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 19, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 19, \"column\": 5},\r\n", + " \"data\": \"0.990099\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 20, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 20, \"column\": 5},\r\n", + " \"data\": \"0.999999\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 21, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 21, \"column\": 5},\r\n", + " \"data\": \"1.000000\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 24, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 24, \"column\": 5},\r\n", + " \"data\": \"99.009901\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 25, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 25, \"column\": 5},\r\n", + " \"data\": \"999999.000001\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 26, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 26, \"column\": 5},\r\n", + " \"data\": \"999999999998.999878\"}],\r\n", + " \"env\": 3}\n", + "
\n", + " " + ], + "text/plain": [ + "-- Illustration DISCRETE (ce n'est pas une preuve Mathlib) : on echantillonne\n", + "-- le profil |x|^k * |f x| sur [-R, R] et on lit le maximum atteint.\n", + "-- `f x = 1 / (1 + x^2)` est lisse et decroit comme 1/x^2.\n", + "--\n", + "-- Note technique : `Float` n'instancie pas `HPow _ Nat` ; on definit donc\n", + "-- l'exponentiation entiere par recursion plutot que d'ecrire `x ^ k`.\n", + "\n", + "def powF (x : Float) : Nat → Float\n", + " | 0 => 1.0\n", + " | n + 1 => x * powF x n\n", + "\n", + "def supProfile (k : Nat) (R : Float) (N : Nat) : Float :=\n", + " let step := 2.0 * R / Float.ofNat N\n", + " (List.range N).foldl (fun acc i =>\n", + " let x := -R + step * Float.ofNat i\n", + " max acc (powF (Float.abs x) k * (1.0 / (1.0 + x * x)))) 0.0\n", + "\n", + "-- k = 2 : le profil PLAFONNE quand R grandit -> la constante C_2 existe.\n", + "#eval supProfile 2 10.0 4000\n", + "─────▶ 0.990099\n", + "#eval supProfile 2 1000.0 4000\n", + "─────▶ 0.999999\n", + "#eval supProfile 2 1000000.0 4000\n", + "─────▶ 1.000000\n", + "\n", + "-- k = 4 : le profil CROIT avec R -> aucune constante C_4 ne convient.\n", + "#eval supProfile 4 10.0 4000\n", + "─────▶ 99.009901\n", + "#eval supProfile 4 1000.0 4000\n", + "─────▶ 999999.000001\n", + "#eval supProfile 4 1000000.0 4000\n", + "─────▶ 999999999998.999878\n", + "\n", + "--% env 3\n", + "\n", + "Raw input:\n", + "{\"cmd\": \"-- Illustration DISCRETE (ce n'est pas une preuve Mathlib) : on echantillonne\\n-- le profil |x|^k * |f x| sur [-R, R] et on lit le maximum atteint.\\n-- `f x = 1 / (1 + x^2)` est lisse et decroit comme 1/x^2.\\n--\\n-- Note technique : `Float` n'instancie pas `HPow _ Nat` ; on definit donc\\n-- l'exponentiation entiere par recursion plutot que d'ecrire `x ^ k`.\\n\\ndef powF (x : Float) : Nat \\u2192 Float\\n | 0 => 1.0\\n | n + 1 => x * powF x n\\n\\ndef supProfile (k : Nat) (R : Float) (N : Nat) : Float :=\\n let step := 2.0 * R / Float.ofNat N\\n (List.range N).foldl (fun acc i =>\\n let x := -R + step * Float.ofNat i\\n max acc (powF (Float.abs x) k * (1.0 / (1.0 + x * x)))) 0.0\\n\\n-- k = 2 : le profil PLAFONNE quand R grandit -> la constante C_2 existe.\\n#eval supProfile 2 10.0 4000\\n#eval supProfile 2 1000.0 4000\\n#eval supProfile 2 1000000.0 4000\\n\\n-- k = 4 : le profil CROIT avec R -> aucune constante C_4 ne convient.\\n#eval supProfile 4 10.0 4000\\n#eval supProfile 4 1000.0 4000\\n#eval supProfile 4 1000000.0 4000\\n\", \"env\": 2}\n", + "Raw output:\n", + "{\"messages\":\r\n", + " [{\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 19, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 19, \"column\": 5},\r\n", + " \"data\": \"0.990099\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 20, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 20, \"column\": 5},\r\n", + " \"data\": \"0.999999\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 21, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 21, \"column\": 5},\r\n", + " \"data\": \"1.000000\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 24, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 24, \"column\": 5},\r\n", + " \"data\": \"99.009901\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 25, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 25, \"column\": 5},\r\n", + " \"data\": \"999999.000001\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 26, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 26, \"column\": 5},\r\n", + " \"data\": \"999999999998.999878\"}],\r\n", + " \"env\": 3}" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "-- Illustration DISCRETE (ce n'est pas une preuve Mathlib) : on echantillonne\n", + "-- le profil |x|^k * |f x| sur [-R, R] et on lit le maximum atteint.\n", + "-- `f x = 1 / (1 + x^2)` est lisse et decroit comme 1/x^2.\n", + "--\n", + "-- Note technique : `Float` n'instancie pas `HPow _ Nat` ; on definit donc\n", + "-- l'exponentiation entiere par recursion plutot que d'ecrire `x ^ k`.\n", + "\n", + "def powF (x : Float) : Nat → Float\n", + " | 0 => 1.0\n", + " | n + 1 => x * powF x n\n", + "\n", + "def supProfile (k : Nat) (R : Float) (N : Nat) : Float :=\n", + " let step := 2.0 * R / Float.ofNat N\n", + " (List.range N).foldl (fun acc i =>\n", + " let x := -R + step * Float.ofNat i\n", + " max acc (powF (Float.abs x) k * (1.0 / (1.0 + x * x)))) 0.0\n", + "\n", + "-- k = 2 : le profil PLAFONNE quand R grandit -> la constante C_2 existe.\n", + "#eval supProfile 2 10.0 4000\n", + "#eval supProfile 2 1000.0 4000\n", + "#eval supProfile 2 1000000.0 4000\n", + "\n", + "-- k = 4 : le profil CROIT avec R -> aucune constante C_4 ne convient.\n", + "#eval supProfile 4 10.0 4000\n", + "#eval supProfile 4 1000.0 4000\n", + "#eval supProfile 4 1000000.0 4000\n" + ] + }, + { + "cell_type": "markdown", + "id": "a1b2c3da", + "metadata": { + "papermill": { + "duration": 0.002553, + "end_time": "2026-09-14T07:33:08.227962+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:08.225409+00:00", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "### Lecture du résultat\n", + "\n", + "Les trois premières valeurs (k = 2) restent **essentiellement constantes** autour de `1.0`\n", + "quand `R` passe de `10` à `10^6` : le profil `x^2/(1+x^2)` tend vers `1`, il est donc\n", + "**borné**, et la constante `C_2` du champ `decay'` existe pour ce couple.\n", + "\n", + "Les trois suivantes (k = 4) **croissent** avec `R` : `x^4/(1+x^2)` tend vers l'infini. Il\n", + "n'existe donc **aucune** constante `C_4` majore le profil pour tout `x`.\n", + "\n", + "Conclusion honnête, et c'est le cœur pédagogique de cette section : `f(x) = 1/(1+x^2)`\n", + "est **lisse** et **décroît** — elle satisfait donc la moitié « régularité » et une partie\n", + "de la moitié « décroissance » — mais elle **n'est pas** une fonction de Schwartz, parce\n", + "qu'elle ne décroît pas plus vite que *toutes* les puissances : elle décroît comme `1/x^2`\n", + "et s'arrête là. C'est exactement la quantification du champ `decay'`, dont le `∀ k` est\n", + "sans échappatoire.\n", + "\n", + "Une réserve méthodologique : ces nombres viennent d'un échantillonnage sur une grille\n", + "finie. Ils **suggèrent** le comportement, ils ne l'établissent pas — le seul juge de\n", + "`decay'` reste une preuve. Un profil peut plafonner sur la grille sans être borné.\n" + ] + }, + { + "cell_type": "markdown", + "id": "a1b2c3db", + "metadata": { + "papermill": { + "duration": 0.002475, + "end_time": "2026-09-14T07:33:08.232926+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:08.230451+00:00", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "## 5. Axiomes des théorèmes publics\n", + "\n", + "Un théorème Lean peut être **clos** (`sorry`-free) et reposer néanmoins sur des axiomes\n", + "du noyau. La commande `#print axioms` liste exactement ceux qu'un théorème donné\n", + "consomme — c'est la vérification d'intégrité de preuve.\n", + "\n", + "Trois familles d'axiomes sont à surveiller :\n", + "\n", + "* `sorryAx` — un `sorry` **transitif**, que ce soit dans le théorème ou dans un lemme\n", + " qu'il appelle : il vide le théorème de son contenu ;\n", + "* `native_decide.*` — une réduction par le noyau natif **sans preuve** ;\n", + "* `Classical.choice`, `propext`, `Quot.sound` — les axiomes classiques de Lean, souvent\n", + " légitimes, mais qui doivent être **nommés** pour être vus.\n", + "\n", + "Le module `Calibration.Distribution` annonce « aucun `sorry` ». La cellule suivante le\n", + "vérifie sur ses théorèmes publics — et la seule autorité est le compilateur.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "a1b2c3dc", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-14T07:33:08.239167Z", + "iopub.status.busy": "2026-09-14T07:33:08.238998Z", + "iopub.status.idle": "2026-09-14T07:33:08.415041Z", + "shell.execute_reply": "2026-09-14T07:33:08.413705Z" + }, + "papermill": { + "duration": 0.180508, + "end_time": "2026-09-14T07:33:08.416032+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:08.235524+00:00", + "status": "completed" + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
-- Les axiomes reellement consommes par les theoremes publics du module :
\n", + "
'Calibration.Distribution.exists_decay_bound' depends on axioms: [propext, Classical.choice, Quot.sound]
\n", + "
'Calibration.Distribution.seminorm_bounds_decay' depends on axioms: [propext, Classical.choice, Quot.sound]
\n", + "
'Calibration.Distribution.norm_le_seminorm_div_pow' depends on axioms: [propext, Classical.choice, Quot.sound]
\n", + "
'Calibration.Distribution.exists_schwartzMap_of_compactSupport' depends on axioms: [propext,\n", + " Classical.choice,\n", + " Quot.sound]
\n", + "
\n", + "
--% env 4
\n", + "
\n", + "
\n", + " Raw input\n", + " {\"cmd\": \"-- Les axiomes reellement consommes par les theoremes publics du module :\\n#print axioms Calibration.Distribution.exists_decay_bound\\n#print axioms Calibration.Distribution.seminorm_bounds_decay\\n#print axioms Calibration.Distribution.norm_le_seminorm_div_pow\\n#print axioms Calibration.Distribution.exists_schwartzMap_of_compactSupport\\n\", \"env\": 3}\n", + "
\n", + "
\n", + " Raw output\n", + " {\"messages\":\r\n", + " [{\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 2, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 2, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"'Calibration.Distribution.exists_decay_bound' depends on axioms: [propext, Classical.choice, Quot.sound]\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 3, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 3, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"'Calibration.Distribution.seminorm_bounds_decay' depends on axioms: [propext, Classical.choice, Quot.sound]\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 4, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 4, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"'Calibration.Distribution.norm_le_seminorm_div_pow' depends on axioms: [propext, Classical.choice, Quot.sound]\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 5, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 5, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"'Calibration.Distribution.exists_schwartzMap_of_compactSupport' depends on axioms: [propext,\\n Classical.choice,\\n Quot.sound]\"}],\r\n", + " \"env\": 4}\n", + "
\n", + " " + ], + "text/plain": [ + "-- Les axiomes reellement consommes par les theoremes publics du module :\n", + "#print axioms Calibration.Distribution.exists_decay_bound\n", + "──────▶ 'Calibration.Distribution.exists_decay_bound' depends on axioms: [propext, Classical.choice, Quot.sound]\n", + "#print axioms Calibration.Distribution.seminorm_bounds_decay\n", + "──────▶ 'Calibration.Distribution.seminorm_bounds_decay' depends on axioms: [propext, Classical.choice, Quot.sound]\n", + "#print axioms Calibration.Distribution.norm_le_seminorm_div_pow\n", + "──────▶ 'Calibration.Distribution.norm_le_seminorm_div_pow' depends on axioms: [propext, Classical.choice, Quot.sound]\n", + "#print axioms Calibration.Distribution.exists_schwartzMap_of_compactSupport\n", + "──────▶ 'Calibration.Distribution.exists_schwartzMap_of_compactSupport' depends on axioms: [propext,\n", + " Classical.choice,\n", + " Quot.sound]\n", + "\n", + "--% env 4\n", + "\n", + "Raw input:\n", + "{\"cmd\": \"-- Les axiomes reellement consommes par les theoremes publics du module :\\n#print axioms Calibration.Distribution.exists_decay_bound\\n#print axioms Calibration.Distribution.seminorm_bounds_decay\\n#print axioms Calibration.Distribution.norm_le_seminorm_div_pow\\n#print axioms Calibration.Distribution.exists_schwartzMap_of_compactSupport\\n\", \"env\": 3}\n", + "Raw output:\n", + "{\"messages\":\r\n", + " [{\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 2, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 2, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"'Calibration.Distribution.exists_decay_bound' depends on axioms: [propext, Classical.choice, Quot.sound]\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 3, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 3, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"'Calibration.Distribution.seminorm_bounds_decay' depends on axioms: [propext, Classical.choice, Quot.sound]\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 4, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 4, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"'Calibration.Distribution.norm_le_seminorm_div_pow' depends on axioms: [propext, Classical.choice, Quot.sound]\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 5, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 5, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"'Calibration.Distribution.exists_schwartzMap_of_compactSupport' depends on axioms: [propext,\\n Classical.choice,\\n Quot.sound]\"}],\r\n", + " \"env\": 4}" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "-- Les axiomes reellement consommes par les theoremes publics du module :\n", + "#print axioms Calibration.Distribution.exists_decay_bound\n", + "#print axioms Calibration.Distribution.seminorm_bounds_decay\n", + "#print axioms Calibration.Distribution.norm_le_seminorm_div_pow\n", + "#print axioms Calibration.Distribution.exists_schwartzMap_of_compactSupport\n" + ] + }, + { + "cell_type": "markdown", + "id": "a1b2c3dd", + "metadata": { + "papermill": { + "duration": 0.00318, + "end_time": "2026-09-14T07:33:08.422248+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:08.419068+00:00", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "### Lecture du résultat\n", + "\n", + "Aucun des quatre théorèmes ne consomme `sorryAx` ni `native_decide.*` : ce sont des\n", + "preuves réelles, pas des preuves vidées. C'est la vérification d'intégrité que la règle de\n", + "revue Lean du dépôt exige (`count_code_sorry.py` compte les `sorry` du *code* ;\n", + "`#print axioms` compte ceux qui *subsistent transitivement*).\n", + "\n", + "Les axiomes qui **apparaissent** — `propext`, `Classical.choice`, `Quot.sound` — sont les\n", + "axiomes fondationnels de Lean 4. Ils entrent par les lemmes de Mathlib que le module\n", + "appelle : `sInf` (l'infimum qui *définit* la seminorme) et le choix classique sont\n", + "omniprésents dans l'analyse réelle. Ce n'est pas une dette du module : c'est le socle\n", + "standard sur lequel toute la bibliothèque d'analyse repose.\n" + ] + }, + { + "cell_type": "markdown", + "id": "a1b2c3de", + "metadata": { + "papermill": { + "duration": 0.003124, + "end_time": "2026-09-14T07:33:08.428316+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:08.425192+00:00", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "## 6. Exercices\n", + "\n", + "Trois exercices, dans l'ordre de difficulté croissante. Aucun ne contient d'erreur\n", + "volontaire : les cellules ci-dessous **s'exécutent toutes sans erreur** telles quelles.\n", + "Un énoncé à compléter est fourni en commentaire (`--`) ou sous forme d'un squelette qui\n", + "renvoie une valeur neutre, à remplacer.\n", + "\n", + "| # | Nature | Ce qui est travaillé |\n", + "|---|---|---|\n", + "| 1 | instanciation | `norm_le_seminorm_div_pow` à un indice `k` choisi |\n", + "| 2 | calcul | le profil de décroissance d'une gaussienne |\n", + "| 3 | preuve | l'homogénéité de la seminorme, en valeur absolue |\n" + ] + }, + { + "cell_type": "markdown", + "id": "a1b2c3df", + "metadata": { + "papermill": { + "duration": 0.002687, + "end_time": "2026-09-14T07:33:08.433747+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:08.431060+00:00", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "### Exercice 1 — instancier la décroissance polynômiale\n", + "\n", + "Le module fournit `norm_le_seminorm_div_pow`, valable pour tout indice `k`. Écrivez un\n", + "`example` qui en déduit, **sur la droite réelle et pour `k = 3`**, la décroissance\n", + "\n", + " `‖f x‖ ≤ seminorm ℝ 3 0 f / ‖x‖^3` dès que `0 < ‖x‖`.\n", + "\n", + "Indice : les arguments explicites de `norm_le_seminorm_div_pow` sont, dans l'ordre, la\n", + "fonction, l'indice `k`, puis — implicite — le point `x` et l'hypothèse `hx`. Le corps\n", + "scalaire `𝕜` est lui aussi implicite : l'instancier explicitement (`(𝕜 := ℝ)`) évite\n", + "une métavariable non résolue. Comme à la section 3, `simpa` normalise `‖x‖^k`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "a1b2c3e0", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-14T07:33:08.440190Z", + "iopub.status.busy": "2026-09-14T07:33:08.440021Z", + "iopub.status.idle": "2026-09-14T07:33:08.637265Z", + "shell.execute_reply": "2026-09-14T07:33:08.636483Z" + }, + "papermill": { + "duration": 0.201386, + "end_time": "2026-09-14T07:33:08.637840+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:08.436454+00:00", + "status": "completed" + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
-- TODO etudiant (exercice 1) : instancier le theoreme a k = 3.
\n", + "
-- Decommentez et completez la ligne ci-dessous.
\n", + "
--
\n", + "
-- example (f : 𝓢(ℝ, ℝ)) {x : ℝ} (hx : 0 < ‖x‖) :
\n", + "
--     ‖f x‖ ≤ SchwartzMap.seminorm ℝ 3 0 f / ‖x‖ ^ 3 := by
\n", + "
--   -- TODO etudiant : appliquer Calibration.Distribution.norm_le_seminorm_div_pow a k = 3
\n", + "
\n", + "
-- La cible de l'exercice, telle que Lean la lit : le compilateur accepte ce `Prop`
\n", + "
-- comme but bien forme. C'est exactement l'enonce du commentaire ci-dessus.
\n", + "
∀ (f : 𝓢(ℝ, ℝ)) {x : ℝ}, 0 < ‖x‖ → ‖f x‖ ≤ (SchwartzMap.seminorm ℝ 3 0) f / ‖x‖ ^ 3 : Prop
\n", + "
    ‖f x‖ ≤ SchwartzMap.seminorm ℝ 3 0 f / ‖x‖ ^ 3)
\n", + "
\n", + "
-- Cellule neutre : rien a faire ici, elle sert a garder la session verte.
\n", + "
example : True := trivial
\n", + "
\n", + "
--% env 5
\n", + "
\n", + "
\n", + " Raw input\n", + " {\"cmd\": \"-- TODO etudiant (exercice 1) : instancier le theoreme a k = 3.\\n-- Decommentez et completez la ligne ci-dessous.\\n--\\n-- example (f : \\ud835\\udce2(\\u211d, \\u211d)) {x : \\u211d} (hx : 0 < \\u2016x\\u2016) :\\n-- \\u2016f x\\u2016 \\u2264 SchwartzMap.seminorm \\u211d 3 0 f / \\u2016x\\u2016 ^ 3 := by\\n-- -- TODO etudiant : appliquer Calibration.Distribution.norm_le_seminorm_div_pow a k = 3\\n\\n-- La cible de l'exercice, telle que Lean la lit : le compilateur accepte ce `Prop`\\n-- comme but bien forme. C'est exactement l'enonce du commentaire ci-dessus.\\n#check (\\u2200 (f : \\ud835\\udce2(\\u211d, \\u211d)) {x : \\u211d}, 0 < \\u2016x\\u2016 \\u2192\\n \\u2016f x\\u2016 \\u2264 SchwartzMap.seminorm \\u211d 3 0 f / \\u2016x\\u2016 ^ 3)\\n\\n-- Cellule neutre : rien a faire ici, elle sert a garder la session verte.\\nexample : True := trivial\\n\", \"env\": 4}\n", + "
\n", + "
\n", + " Raw output\n", + " {\"messages\":\r\n", + " [{\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 10, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 10, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"∀ (f : 𝓢(ℝ, ℝ)) {x : ℝ}, 0 < ‖x‖ → ‖f x‖ ≤ (SchwartzMap.seminorm ℝ 3 0) f / ‖x‖ ^ 3 : Prop\"}],\r\n", + " \"env\": 5}\n", + "
\n", + " " + ], + "text/plain": [ + "-- TODO etudiant (exercice 1) : instancier le theoreme a k = 3.\n", + "-- Decommentez et completez la ligne ci-dessous.\n", + "--\n", + "-- example (f : 𝓢(ℝ, ℝ)) {x : ℝ} (hx : 0 < ‖x‖) :\n", + "-- ‖f x‖ ≤ SchwartzMap.seminorm ℝ 3 0 f / ‖x‖ ^ 3 := by\n", + "-- -- TODO etudiant : appliquer Calibration.Distribution.norm_le_seminorm_div_pow a k = 3\n", + "\n", + "-- La cible de l'exercice, telle que Lean la lit : le compilateur accepte ce `Prop`\n", + "-- comme but bien forme. C'est exactement l'enonce du commentaire ci-dessus.\n", + "#check (∀ (f : 𝓢(ℝ, ℝ)) {x : ℝ}, 0 < ‖x‖ →\n", + "──────▶ ∀ (f : 𝓢(ℝ, ℝ)) {x : ℝ}, 0 < ‖x‖ → ‖f x‖ ≤ (SchwartzMap.seminorm ℝ 3 0) f / ‖x‖ ^ 3 : Prop\n", + " ‖f x‖ ≤ SchwartzMap.seminorm ℝ 3 0 f / ‖x‖ ^ 3)\n", + "\n", + "-- Cellule neutre : rien a faire ici, elle sert a garder la session verte.\n", + "example : True := trivial\n", + "\n", + "--% env 5\n", + "\n", + "Raw input:\n", + "{\"cmd\": \"-- TODO etudiant (exercice 1) : instancier le theoreme a k = 3.\\n-- Decommentez et completez la ligne ci-dessous.\\n--\\n-- example (f : \\ud835\\udce2(\\u211d, \\u211d)) {x : \\u211d} (hx : 0 < \\u2016x\\u2016) :\\n-- \\u2016f x\\u2016 \\u2264 SchwartzMap.seminorm \\u211d 3 0 f / \\u2016x\\u2016 ^ 3 := by\\n-- -- TODO etudiant : appliquer Calibration.Distribution.norm_le_seminorm_div_pow a k = 3\\n\\n-- La cible de l'exercice, telle que Lean la lit : le compilateur accepte ce `Prop`\\n-- comme but bien forme. C'est exactement l'enonce du commentaire ci-dessus.\\n#check (\\u2200 (f : \\ud835\\udce2(\\u211d, \\u211d)) {x : \\u211d}, 0 < \\u2016x\\u2016 \\u2192\\n \\u2016f x\\u2016 \\u2264 SchwartzMap.seminorm \\u211d 3 0 f / \\u2016x\\u2016 ^ 3)\\n\\n-- Cellule neutre : rien a faire ici, elle sert a garder la session verte.\\nexample : True := trivial\\n\", \"env\": 4}\n", + "Raw output:\n", + "{\"messages\":\r\n", + " [{\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 10, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 10, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"∀ (f : 𝓢(ℝ, ℝ)) {x : ℝ}, 0 < ‖x‖ → ‖f x‖ ≤ (SchwartzMap.seminorm ℝ 3 0) f / ‖x‖ ^ 3 : Prop\"}],\r\n", + " \"env\": 5}" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "-- TODO etudiant (exercice 1) : instancier le theoreme a k = 3.\n", + "-- Decommentez et completez la ligne ci-dessous.\n", + "--\n", + "-- example (f : 𝓢(ℝ, ℝ)) {x : ℝ} (hx : 0 < ‖x‖) :\n", + "-- ‖f x‖ ≤ SchwartzMap.seminorm ℝ 3 0 f / ‖x‖ ^ 3 := by\n", + "-- -- TODO etudiant : appliquer Calibration.Distribution.norm_le_seminorm_div_pow a k = 3\n", + "\n", + "-- La cible de l'exercice, telle que Lean la lit : le compilateur accepte ce `Prop`\n", + "-- comme but bien forme. C'est exactement l'enonce du commentaire ci-dessus.\n", + "#check (∀ (f : 𝓢(ℝ, ℝ)) {x : ℝ}, 0 < ‖x‖ →\n", + " ‖f x‖ ≤ SchwartzMap.seminorm ℝ 3 0 f / ‖x‖ ^ 3)\n", + "\n", + "-- Cellule neutre : rien a faire ici, elle sert a garder la session verte.\n", + "example : True := trivial\n" + ] + }, + { + "cell_type": "markdown", + "id": "a1b2c3e1", + "metadata": { + "papermill": { + "duration": 0.003205, + "end_time": "2026-09-14T07:33:08.644323+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:08.641118+00:00", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "### Exercice 2 — le profil d'une gaussienne\n", + "\n", + "En section 4, `f(x) = 1/(1+x^2)` échoue à `k = 4`. Prenez maintenant une fonction qui\n", + "décroît **plus vite que toute puissance**, la gaussienne `x ↦ exp(-x^2)`, et complétez\n", + "`gaussProfile` pour qu'elle renvoie le maximum du profil `|x|^k * exp(-x^2)` sur\n", + "`[-R, R]`.\n", + "\n", + "Puis exécutez les deux `#eval` : pour `k = 2` comme pour `k = 8`, la valeur doit rester\n", + "**petite et finie** — c'est le comportement qui distingue une fonction de Schwartz de la\n", + "fonction rationnelle de la section 4. `Float.exp` est disponible dans le noyau.\n", + "\n", + "Indice : la structure de `gaussProfile` est identique à `supProfile` de la section 4 ;\n", + "seul le facteur `1/(1+x^2)` change.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "a1b2c3e2", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-14T07:33:08.651203Z", + "iopub.status.busy": "2026-09-14T07:33:08.651034Z", + "iopub.status.idle": "2026-09-14T07:33:08.837529Z", + "shell.execute_reply": "2026-09-14T07:33:08.836335Z" + }, + "papermill": { + "duration": 0.190873, + "end_time": "2026-09-14T07:33:08.838197+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:08.647324+00:00", + "status": "completed" + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
-- TODO etudiant (exercice 2) : completer le profil de la gaussienne.
\n", + "
-- `powF` (section 4) et `Float.exp` sont disponibles dans le noyau.
\n", + "
-- Le linter d'arguments non utilises est desactive le temps du stub : le
\n", + "
-- completer rendra `k`, `R` et `N` effectivement consommes.
\n", + "
set_option linter.unusedVariables false in
\n", + "
def gaussProfile (k : Nat) (R : Float) (N : Nat) : Float :=
\n", + "
  0.0  -- TODO etudiant : remplacer par le maximum du profil |x|^k * exp(-x^2)
\n", + "
       --                sur la grille de N points de [-R, R]
\n", + "
\n", + "
-- Attendu (exercice complete) : deux valeurs FINIES et petites,
\n", + "
-- qui ne croissent pas avec R.
\n", + "
0.000000
\n", + "
0.000000
\n", + "
\n", + "
--% env 6
\n", + "
\n", + "
\n", + " Raw input\n", + " {\"cmd\": \"-- TODO etudiant (exercice 2) : completer le profil de la gaussienne.\\n-- `powF` (section 4) et `Float.exp` sont disponibles dans le noyau.\\n-- Le linter d'arguments non utilises est desactive le temps du stub : le\\n-- completer rendra `k`, `R` et `N` effectivement consommes.\\nset_option linter.unusedVariables false in\\ndef gaussProfile (k : Nat) (R : Float) (N : Nat) : Float :=\\n 0.0 -- TODO etudiant : remplacer par le maximum du profil |x|^k * exp(-x^2)\\n -- sur la grille de N points de [-R, R]\\n\\n-- Attendu (exercice complete) : deux valeurs FINIES et petites,\\n-- qui ne croissent pas avec R.\\n#eval gaussProfile 2 10.0 4000\\n#eval gaussProfile 8 10.0 4000\\n\", \"env\": 5}\n", + "
\n", + "
\n", + " Raw output\n", + " {\"messages\":\r\n", + " [{\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 12, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 12, \"column\": 5},\r\n", + " \"data\": \"0.000000\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 13, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 13, \"column\": 5},\r\n", + " \"data\": \"0.000000\"}],\r\n", + " \"env\": 6}\n", + "
\n", + " " + ], + "text/plain": [ + "-- TODO etudiant (exercice 2) : completer le profil de la gaussienne.\n", + "-- `powF` (section 4) et `Float.exp` sont disponibles dans le noyau.\n", + "-- Le linter d'arguments non utilises est desactive le temps du stub : le\n", + "-- completer rendra `k`, `R` et `N` effectivement consommes.\n", + "set_option linter.unusedVariables false in\n", + "def gaussProfile (k : Nat) (R : Float) (N : Nat) : Float :=\n", + " 0.0 -- TODO etudiant : remplacer par le maximum du profil |x|^k * exp(-x^2)\n", + " -- sur la grille de N points de [-R, R]\n", + "\n", + "-- Attendu (exercice complete) : deux valeurs FINIES et petites,\n", + "-- qui ne croissent pas avec R.\n", + "#eval gaussProfile 2 10.0 4000\n", + "─────▶ 0.000000\n", + "#eval gaussProfile 8 10.0 4000\n", + "─────▶ 0.000000\n", + "\n", + "--% env 6\n", + "\n", + "Raw input:\n", + "{\"cmd\": \"-- TODO etudiant (exercice 2) : completer le profil de la gaussienne.\\n-- `powF` (section 4) et `Float.exp` sont disponibles dans le noyau.\\n-- Le linter d'arguments non utilises est desactive le temps du stub : le\\n-- completer rendra `k`, `R` et `N` effectivement consommes.\\nset_option linter.unusedVariables false in\\ndef gaussProfile (k : Nat) (R : Float) (N : Nat) : Float :=\\n 0.0 -- TODO etudiant : remplacer par le maximum du profil |x|^k * exp(-x^2)\\n -- sur la grille de N points de [-R, R]\\n\\n-- Attendu (exercice complete) : deux valeurs FINIES et petites,\\n-- qui ne croissent pas avec R.\\n#eval gaussProfile 2 10.0 4000\\n#eval gaussProfile 8 10.0 4000\\n\", \"env\": 5}\n", + "Raw output:\n", + "{\"messages\":\r\n", + " [{\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 12, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 12, \"column\": 5},\r\n", + " \"data\": \"0.000000\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 13, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 13, \"column\": 5},\r\n", + " \"data\": \"0.000000\"}],\r\n", + " \"env\": 6}" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "-- TODO etudiant (exercice 2) : completer le profil de la gaussienne.\n", + "-- `powF` (section 4) et `Float.exp` sont disponibles dans le noyau.\n", + "-- Le linter d'arguments non utilises est desactive le temps du stub : le\n", + "-- completer rendra `k`, `R` et `N` effectivement consommes.\n", + "set_option linter.unusedVariables false in\n", + "def gaussProfile (k : Nat) (R : Float) (N : Nat) : Float :=\n", + " 0.0 -- TODO etudiant : remplacer par le maximum du profil |x|^k * exp(-x^2)\n", + " -- sur la grille de N points de [-R, R]\n", + "\n", + "-- Attendu (exercice complete) : deux valeurs FINIES et petites,\n", + "-- qui ne croissent pas avec R.\n", + "#eval gaussProfile 2 10.0 4000\n", + "#eval gaussProfile 8 10.0 4000\n" + ] + }, + { + "cell_type": "markdown", + "id": "a1b2c3e3", + "metadata": { + "papermill": { + "duration": 0.003445, + "end_time": "2026-09-14T07:33:08.845272+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:08.841827+00:00", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "### Exercice 3 — l'homogénéité, en valeur absolue\n", + "\n", + "Le module énonce `seminorm_smul` : `seminorm 𝕜 k n (c • f) = ‖c‖ * seminorm 𝕜 k n f`.\n", + "Sur la droite réelle, `‖c‖ = |c|` pour `c : ℝ`. Écrivez un `example` qui en déduit la\n", + "forme en valeur absolue :\n", + "\n", + " `seminorm ℝ 0 0 (c • f) = |c| * seminorm ℝ 0 0 f`.\n", + "\n", + "Indice : le théorème du module s'écrit `Calibration.Distribution.seminorm_smul` (le nom\n", + "court est ambigu dans la session du notebook). Une seule étape `rw` suffit : appliquer\n", + "`seminorm_smul`, puis faire apparaître `|c|` depuis `‖c‖` — `Real.norm_eq_abs` fait ce pont.\n", + "\n", + "Note : contrairement aux deux premiers, cet énoncé est une **preuve** à écrire, pas un\n", + "appel à compléter. C'est l'exercice le plus proche du travail du prouveur automatique.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "a1b2c3e4", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-14T07:33:08.860403Z", + "iopub.status.busy": "2026-09-14T07:33:08.860187Z", + "iopub.status.idle": "2026-09-14T07:33:09.096710Z", + "shell.execute_reply": "2026-09-14T07:33:09.095714Z" + }, + "papermill": { + "duration": 0.242566, + "end_time": "2026-09-14T07:33:09.097425+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:08.854859+00:00", + "status": "completed" + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
-- TODO etudiant (exercice 3) : deriver la forme en valeur absolue.
\n", + "
-- Decommentez et completez.
\n", + "
--
\n", + "
-- example (f : 𝓢(ℝ, ℝ)) (c : ℝ) :
\n", + "
--     SchwartzMap.seminorm ℝ 0 0 (c • f) = |c| * SchwartzMap.seminorm ℝ 0 0 f := by
\n", + "
--   -- TODO etudiant : appliquer `seminorm_smul` puis `Real.norm_eq_abs`
\n", + "
\n", + "
-- La cible de l'exercice, telle que Lean la lit :
\n", + "
∀ (f : 𝓢(ℝ, ℝ)) (c : ℝ), (SchwartzMap.seminorm ℝ 0 0) (c • f) = |c| * (SchwartzMap.seminorm ℝ 0 0) f : Prop
\n", + "
    SchwartzMap.seminorm ℝ 0 0 (c • f) = |c| * SchwartzMap.seminorm ℝ 0 0 f)
\n", + "
\n", + "
-- Les deux lemmes que l'indice nomme, avec leurs signatures exactes :
\n", + "
Calibration.Distribution.seminorm_smul.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2} {F : Type u_3}\n", + " [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\n", + " [SMulCommClass ℝ 𝕜 F] (c : 𝕜) (f : 𝓢(E, F)) (k n : ℕ) :\n", + " (SchwartzMap.seminorm 𝕜 k n) (c • f) = ‖c‖ * (SchwartzMap.seminorm 𝕜 k n) f
\n", + "
Real.norm_eq_abs (r : ℝ) : ‖r‖ = |r|
\n", + "
\n", + "
-- Cellule neutre : rien a faire ici, elle sert a garder la session verte.
\n", + "
example : True := trivial
\n", + "
\n", + "
--% env 7
\n", + "
\n", + "
\n", + " Raw input\n", + " {\"cmd\": \"-- TODO etudiant (exercice 3) : deriver la forme en valeur absolue.\\n-- Decommentez et completez.\\n--\\n-- example (f : \\ud835\\udce2(\\u211d, \\u211d)) (c : \\u211d) :\\n-- SchwartzMap.seminorm \\u211d 0 0 (c \\u2022 f) = |c| * SchwartzMap.seminorm \\u211d 0 0 f := by\\n-- -- TODO etudiant : appliquer `seminorm_smul` puis `Real.norm_eq_abs`\\n\\n-- La cible de l'exercice, telle que Lean la lit :\\n#check (\\u2200 (f : \\ud835\\udce2(\\u211d, \\u211d)) (c : \\u211d),\\n SchwartzMap.seminorm \\u211d 0 0 (c \\u2022 f) = |c| * SchwartzMap.seminorm \\u211d 0 0 f)\\n\\n-- Les deux lemmes que l'indice nomme, avec leurs signatures exactes :\\n#check Calibration.Distribution.seminorm_smul\\n#check Real.norm_eq_abs\\n\\n-- Cellule neutre : rien a faire ici, elle sert a garder la session verte.\\nexample : True := trivial\\n\", \"env\": 6}\n", + "
\n", + "
\n", + " Raw output\n", + " {\"messages\":\r\n", + " [{\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 9, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 9, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"∀ (f : 𝓢(ℝ, ℝ)) (c : ℝ), (SchwartzMap.seminorm ℝ 0 0) (c • f) = |c| * (SchwartzMap.seminorm ℝ 0 0) f : Prop\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 13, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 13, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"Calibration.Distribution.seminorm_smul.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2} {F : Type u_3}\\n [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\\n [SMulCommClass ℝ 𝕜 F] (c : 𝕜) (f : 𝓢(E, F)) (k n : ℕ) :\\n (SchwartzMap.seminorm 𝕜 k n) (c • f) = ‖c‖ * (SchwartzMap.seminorm 𝕜 k n) f\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 14, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 14, \"column\": 6},\r\n", + " \"data\": \"Real.norm_eq_abs (r : ℝ) : ‖r‖ = |r|\"}],\r\n", + " \"env\": 7}\n", + "
\n", + " " + ], + "text/plain": [ + "-- TODO etudiant (exercice 3) : deriver la forme en valeur absolue.\n", + "-- Decommentez et completez.\n", + "--\n", + "-- example (f : 𝓢(ℝ, ℝ)) (c : ℝ) :\n", + "-- SchwartzMap.seminorm ℝ 0 0 (c • f) = |c| * SchwartzMap.seminorm ℝ 0 0 f := by\n", + "-- -- TODO etudiant : appliquer `seminorm_smul` puis `Real.norm_eq_abs`\n", + "\n", + "-- La cible de l'exercice, telle que Lean la lit :\n", + "#check (∀ (f : 𝓢(ℝ, ℝ)) (c : ℝ),\n", + "──────▶ ∀ (f : 𝓢(ℝ, ℝ)) (c : ℝ), (SchwartzMap.seminorm ℝ 0 0) (c • f) = |c| * (SchwartzMap.seminorm ℝ 0 0) f : Prop\n", + " SchwartzMap.seminorm ℝ 0 0 (c • f) = |c| * SchwartzMap.seminorm ℝ 0 0 f)\n", + "\n", + "-- Les deux lemmes que l'indice nomme, avec leurs signatures exactes :\n", + "#check Calibration.Distribution.seminorm_smul\n", + "──────▶ Calibration.Distribution.seminorm_smul.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2} {F : Type u_3}\n", + " [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\n", + " [SMulCommClass ℝ 𝕜 F] (c : 𝕜) (f : 𝓢(E, F)) (k n : ℕ) :\n", + " (SchwartzMap.seminorm 𝕜 k n) (c • f) = ‖c‖ * (SchwartzMap.seminorm 𝕜 k n) f\n", + "#check Real.norm_eq_abs\n", + "──────▶ Real.norm_eq_abs (r : ℝ) : ‖r‖ = |r|\n", + "\n", + "-- Cellule neutre : rien a faire ici, elle sert a garder la session verte.\n", + "example : True := trivial\n", + "\n", + "--% env 7\n", + "\n", + "Raw input:\n", + "{\"cmd\": \"-- TODO etudiant (exercice 3) : deriver la forme en valeur absolue.\\n-- Decommentez et completez.\\n--\\n-- example (f : \\ud835\\udce2(\\u211d, \\u211d)) (c : \\u211d) :\\n-- SchwartzMap.seminorm \\u211d 0 0 (c \\u2022 f) = |c| * SchwartzMap.seminorm \\u211d 0 0 f := by\\n-- -- TODO etudiant : appliquer `seminorm_smul` puis `Real.norm_eq_abs`\\n\\n-- La cible de l'exercice, telle que Lean la lit :\\n#check (\\u2200 (f : \\ud835\\udce2(\\u211d, \\u211d)) (c : \\u211d),\\n SchwartzMap.seminorm \\u211d 0 0 (c \\u2022 f) = |c| * SchwartzMap.seminorm \\u211d 0 0 f)\\n\\n-- Les deux lemmes que l'indice nomme, avec leurs signatures exactes :\\n#check Calibration.Distribution.seminorm_smul\\n#check Real.norm_eq_abs\\n\\n-- Cellule neutre : rien a faire ici, elle sert a garder la session verte.\\nexample : True := trivial\\n\", \"env\": 6}\n", + "Raw output:\n", + "{\"messages\":\r\n", + " [{\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 9, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 9, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"∀ (f : 𝓢(ℝ, ℝ)) (c : ℝ), (SchwartzMap.seminorm ℝ 0 0) (c • f) = |c| * (SchwartzMap.seminorm ℝ 0 0) f : Prop\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 13, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 13, \"column\": 6},\r\n", + " \"data\":\r\n", + " \"Calibration.Distribution.seminorm_smul.{u_1, u_2, u_3} {𝕜 : Type u_1} [NormedField 𝕜] {E : Type u_2} {F : Type u_3}\\n [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\\n [SMulCommClass ℝ 𝕜 F] (c : 𝕜) (f : 𝓢(E, F)) (k n : ℕ) :\\n (SchwartzMap.seminorm 𝕜 k n) (c • f) = ‖c‖ * (SchwartzMap.seminorm 𝕜 k n) f\"},\r\n", + " {\"severity\": \"info\",\r\n", + " \"pos\": {\"line\": 14, \"column\": 0},\r\n", + " \"endPos\": {\"line\": 14, \"column\": 6},\r\n", + " \"data\": \"Real.norm_eq_abs (r : ℝ) : ‖r‖ = |r|\"}],\r\n", + " \"env\": 7}" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "-- TODO etudiant (exercice 3) : deriver la forme en valeur absolue.\n", + "-- Decommentez et completez.\n", + "--\n", + "-- example (f : 𝓢(ℝ, ℝ)) (c : ℝ) :\n", + "-- SchwartzMap.seminorm ℝ 0 0 (c • f) = |c| * SchwartzMap.seminorm ℝ 0 0 f := by\n", + "-- -- TODO etudiant : appliquer `seminorm_smul` puis `Real.norm_eq_abs`\n", + "\n", + "-- La cible de l'exercice, telle que Lean la lit :\n", + "#check (∀ (f : 𝓢(ℝ, ℝ)) (c : ℝ),\n", + " SchwartzMap.seminorm ℝ 0 0 (c • f) = |c| * SchwartzMap.seminorm ℝ 0 0 f)\n", + "\n", + "-- Les deux lemmes que l'indice nomme, avec leurs signatures exactes :\n", + "#check Calibration.Distribution.seminorm_smul\n", + "#check Real.norm_eq_abs\n", + "\n", + "-- Cellule neutre : rien a faire ici, elle sert a garder la session verte.\n", + "example : True := trivial\n" + ] + }, + { + "cell_type": "markdown", + "id": "a1b2c3e5", + "metadata": { + "papermill": { + "duration": 0.004053, + "end_time": "2026-09-14T07:33:09.105860+00:00", + "exception": false, + "start_time": "2026-09-14T07:33:09.101807+00:00", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "## 7. Conclusion\n", + "\n", + "Ce notebook a parcouru le module `Calibration.Distribution` par ses énoncés, dans un\n", + "kernel Lean 4 réel.\n", + "\n", + "**Ce que le module apporte.** La capacité distinctive des espaces de Schwartz est une\n", + "*dualité* : régularité (`smooth'`) et décroissance (`decay'`), mesurées d'un seul geste\n", + "par la famille `SchwartzMap.seminorm 𝕜 k n` — `k` pour la décroissance, `n` pour l'ordre\n", + "de dérivation. Le module n'invente aucune définition : il rend manipulables les énoncés\n", + "que Mathlib fournit (le *majorant* `le_seminorm`, le *plus petit majorant*\n", + "`seminorm_le_bound`, l'homogénéité, la sous-additivité), et il en extrait un corollaire\n", + "qui est le vrai contenu intuitif de la définition — la **décroissance polynômiale\n", + "effective** `‖f x‖ ≤ C_k / ‖x‖^k`.\n", + "\n", + "**Ce que ce notebook n'est pas.** La section 4 est **numérique et illustrative** : un\n", + "échantillonnage sur grille finie ne prouve rien. Le seul juge du champ `decay'` reste une\n", + "preuve, et c'est ce que le module fournit.\n", + "\n", + "**Ce que la calibration vérifie.** Les théorèmes du module sont **clos** — `#print axioms`\n", + "de la section 5 ne montre ni `sorryAx` ni `native_decide.*`. Ce qui reste\n", + "(`propext`, `Classical.choice`, `Quot.sound`) est le socle fondationnel standard de\n", + "l'analyse réelle dans Lean 4.\n", + "\n", + "### Repères\n", + "\n", + "- Mathlib 4, `Mathlib.Analysis.Distribution.SchwartzSpace.Basic` (structure `SchwartzMap`,\n", + " `seminorm`, `le_seminorm`, `seminorm_le_bound`, `norm_pow_mul_le_seminorm`,\n", + " `HasCompactSupport.toSchwartzMap`)\n", + "- EPIC #1452 — harnais de preuve multi-agents : cibles de calibration\n", + "- EPIC #4980 — convention *sibling pair* FR/EN pour les lakes Lean\n", + "- Le module : [`calibration_lean/Calibration/Distribution.lean`](calibration_lean/Calibration/Distribution.lean)\n", + " (FR) et son jumeau [`Distribution_en.lean`](calibration_lean/Calibration/Distribution_en.lean) (EN)\n", + "- Compagnon du même lake : [Lean-24-Calibration-Native-Companion](Lean-24-Calibration-Native-Companion.ipynb)\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Lean 4 (WSL)", + "language": "lean4", + "name": "lean4-wsl" + }, + "language_info": { + "codemirror_mode": "lean4", + "file_extension": ".lean", + "mimetype": "text/x-lean4", + "name": "lean4" + }, + "papermill": { + "default_parameters": {}, + "duration": 24.495976, + "end_time": "2026-09-14T07:33:11.959204+00:00", + "environment_variables": {}, + "exception": null, + "input_path": "Lean-33-Distribution-Spaces.ipynb", + "output_path": "Lean-33-Distribution-Spaces.ipynb", + "parameters": {}, + "start_time": "2026-09-14T07:32:47.463228+00:00", + "version": "2.7.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/MyIA.AI.Notebooks/SymbolicAI/Lean/calibration_lean/Calibration/Distribution.lean b/MyIA.AI.Notebooks/SymbolicAI/Lean/calibration_lean/Calibration/Distribution.lean new file mode 100644 index 0000000000..a8dcc96c7f --- /dev/null +++ b/MyIA.AI.Notebooks/SymbolicAI/Lean/calibration_lean/Calibration/Distribution.lean @@ -0,0 +1,172 @@ +/- + Cible de calibration : espaces de Schwartz — décroissance et régularité + ======================================================================= + + L'espace de Schwartz est l'espace des fonctions lisses dont TOUTES les + dérivées décroissent plus vite que n'importe quelle puissance de `‖x‖`. Sa + capacité distinctive est double, et c'est cette dualité que ce module + enseigne : + + * la RÉGULARITÉ — la lissité `C^∞`, portée par le champ `smooth'` ; + * la DÉCROISSANCE — le champ `decay'`, qui majore uniformément + `‖x‖^k * ‖iteratedFDeriv ℝ n f x‖` par une constante. + + La famille de seminormes `SchwartzMap.seminorm 𝕜 k n` mesure les deux d'un + seul geste : `k` indexe la décroissance, `n` l'ordre de dérivation. C'est la + structure qui rend l'espace muni d'une topologie localement convexe, et + c'est ce que les théorèmes ci-dessous rendent manipulable. + + Le module instancie l'API Mathlib réellement pinnée par le lake + (`Mathlib.Analysis.Distribution.SchwartzSpace.Basic`) — aucune définition + n'est réinventée, aucune preuve n'est laissée en `sorry`. + + Chemins du harnais exercés : + - Cible S1 (exists_decay_bound) : P3 — le prouveur doit découvrir le lemme + nommé `SchwartzMap.decay` ; un `simp` nu ne le trouve pas. + - Cible S2 (seminorm_bounds_decay) : P3 — le lemme nommé + `SchwartzMap.le_seminorm`, à ne pas confondre avec sa réciproque. + - Cible S3 (seminorm_le_of_pointwise_bound) : P1 — le pont inverse + `SchwartzMap.seminorm_le_bound`, avec son hypothèse de positivité. + - Cible S4 (seminorm_smul) : P3 — l'homogénéité sort du lemme générique + `SeminormClass.map_smul_eq_mul`, pas de `simp`. + - Cible S5 (seminorm_add_le) : P1 — la sous-additivité via le champ + `Seminorm.add_le'`. + - Cible S6 (norm_le_seminorm_div_pow) : P2 — la décroissance polynômiale + RÉELLE se déduit de la seminorme ; requiert `le_div_iff₀` puis une + commutation `mul_comm` (preuve en deux temps, l'erreur est distante). + - Cible S7 (exists_schwartzMap_of_compactSupport) : P2 — l'énoncé de + clôture `HasCompactSupport.toSchwartzMap`, avec l'égalité de la fonction + sous-jacente. + + Difficulté visée : zone de Goldilocks (3-10 itérations du prouveur). +-/ +import Mathlib.Analysis.Distribution.SchwartzSpace.Basic +import Mathlib.Tactic + +open scoped SchwartzMap ContDiff Topology + +namespace Calibration.Distribution + +/-! ## 1. Le contrat : décroissance contrôlée par une constante -/ + +section Decay + +variable {E F : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + [NormedAddCommGroup F] [NormedSpace ℝ F] + +/-- **Décroissance brute (cible S1).** Pour toute fonction de Schwartz `f` et +tout couple d'indices `(k, n)`, il existe une constante strictement positive +`C` qui majore `‖x‖^k * ‖iteratedFDeriv ℝ n f x‖` pour tout `x`. + +C'est le champ `decay'` de la structure, raffiné par le lemme `decay` qui +garantit en plus `0 < C` (utile pour diviser). -/ +theorem exists_decay_bound (f : 𝓢(E, F)) (k n : ℕ) : + ∃ C : ℝ, 0 < C ∧ ∀ x : E, ‖x‖ ^ k * ‖iteratedFDeriv ℝ n f x‖ ≤ C := + f.decay k n + +/-- **Régularité (la première moitié du contrat).** Toute fonction de Schwartz +est lisse à l'ordre infini : c'est le champ `smooth'`, ici lu comme un énoncé +public sur la fonction sous-jacente. -/ +theorem smooth_of_schwartz (f : 𝓢(E, F)) : ContDiff ℝ ∞ (f : E → F) := + f.smooth' + +/-- **La décroissance entraîne l'annulation à l'infini.** C'est le sens +concret de « décroît plus vite que toute puissance » : `f` tend vers `0` +le long du filtre `cocompact`. -/ +theorem tendsto_zero_atInfty [ProperSpace E] (f : 𝓢(E, F)) : + Filter.Tendsto (f : E → F) (Filter.cocompact E) (𝓝 0) := + f.tendsto_cocompact + +end Decay + +/-! ## 2. Les seminormes : mesurer décroissance et régularité d'un seul geste + +`SchwartzMap.seminorm 𝕜 k n` est la meilleure constante de l'estimation +`‖x‖^k * ‖iteratedFDeriv ℝ n f x‖ ≤ C`. Le théorème `le_seminorm` dit qu'elle +la réalise (c'est un majorant), `seminorm_le_bound` qu'elle en est le plus +petit (toute constante qui marche la majore) : les deux moitiés de la +définition par infimum, prises par les deux bouts. -/ + +section Seminorm + +variable {𝕜 : Type*} [NormedField 𝕜] +variable {E F : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F] [SMulCommClass ℝ 𝕜 F] + +/-- **La seminorme réalise l'estimation (cible S2).** Pour tout point `x`, +l'estimation de Schwartz est majorée par la seminorme d'indices `(k, n)`. + +C'est la moitié « la seminorme est un majorant ». -/ +theorem seminorm_bounds_decay (f : 𝓢(E, F)) (k n : ℕ) (x : E) : + ‖x‖ ^ k * ‖iteratedFDeriv ℝ n f x‖ ≤ SchwartzMap.seminorm 𝕜 k n f := + SchwartzMap.le_seminorm 𝕜 k n f x + +/-- **La seminorme est le plus petit majorant (cible S3).** Réciproque du +théorème précédent : borner l'estimation en TOUT point par une constante `M` +borne la seminorme par `M`. L'hypothèse `hMp : 0 ≤ M` est indispensable (sans +elle, une constante strictement négative bornerait tout). -/ +theorem seminorm_le_of_pointwise_bound (f : 𝓢(E, F)) (k n : ℕ) {M : ℝ} + (hMp : 0 ≤ M) + (hM : ∀ x : E, ‖x‖ ^ k * ‖iteratedFDeriv ℝ n f x‖ ≤ M) : + SchwartzMap.seminorm 𝕜 k n f ≤ M := + SchwartzMap.seminorm_le_bound 𝕜 k n f hMp hM + +/-- **Homogénéité (cible S4).** Le scalaire sort multiplicativement, en norme, +de la seminorme. C'est l'axiome `SMul` de `Seminorm`, lu par le lemme +générique `SeminormClass.map_smul_eq_mul`. -/ +theorem seminorm_smul (c : 𝕜) (f : 𝓢(E, F)) (k n : ℕ) : + SchwartzMap.seminorm 𝕜 k n (c • f) = ‖c‖ * SchwartzMap.seminorm 𝕜 k n f := + map_smul_eq_mul (SchwartzMap.seminorm 𝕜 k n) c f + +/-- **Sous-additivité (cible S5).** Une seminorme n'est pas additive, elle est +sous-additive : l'inégalité triangulaire est un axiome de la structure, lu par +le champ `Seminorm.add_le'`. -/ +theorem seminorm_add_le (f g : 𝓢(E, F)) (k n : ℕ) : + SchwartzMap.seminorm 𝕜 k n (f + g) ≤ + SchwartzMap.seminorm 𝕜 k n f + SchwartzMap.seminorm 𝕜 k n g := + (SchwartzMap.seminorm 𝕜 k n).add_le' f g + +/-- **Décroissance polynômiale effective (cible S6).** La seminorme d'indices +`(k, 0)` — décroissance d'ordre `k`, aucune dérivée — fournit une décroissance +POLYNÔMIALE de la fonction elle-même : hors de l'origine, + + `‖f x‖ ≤ C_k / ‖x‖^k`. + +La preuve déplace `‖x‖^k` au dénominateur (`le_div_iff₀`, l'hypothèse +`0 < ‖x‖` est ce qui l'autorise), puis commute les deux facteurs pour +retomber sur `norm_pow_mul_le_seminorm`. -/ +theorem norm_le_seminorm_div_pow (f : 𝓢(E, F)) (k : ℕ) {x : E} (hx : 0 < ‖x‖) : + ‖f x‖ ≤ SchwartzMap.seminorm 𝕜 k 0 f / ‖x‖ ^ k := by + rw [le_div_iff₀ (pow_pos hx k)] + exact (mul_comm _ _).trans_le (SchwartzMap.norm_pow_mul_le_seminorm 𝕜 f k x) + +/-- **La seminorme `(0, 0)` majore la norme uniforme.** Cas particulier +`k = 0` du théorème précédent, sans hypothèse : partout, +`‖f x‖ ≤ seminorm 𝕜 0 0 f`. C'est la seminorme qui contrôle le sup de `f`. -/ +theorem norm_le_seminorm_zero (f : 𝓢(E, F)) (x : E) : + ‖f x‖ ≤ SchwartzMap.seminorm 𝕜 0 0 f := + SchwartzMap.norm_le_seminorm 𝕜 f x + +end Seminorm + +/-! ## 3. Clôture : le support compact fabrique des fonctions de Schwartz -/ + +section CompactSupport + +variable {E F : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + [NormedAddCommGroup F] [NormedSpace ℝ F] + +/-- **Une fonction lisse à support compact est de Schwartz (cible S7).** La +clôture de la classe est un fait du support compact : hors du support, la +fonction est nulle, donc la décroissance est gagnée sans hypothèse. + +La conclusion témoigne EN PLUS de la préservation de la fonction sous-jacente +— `toSchwartzMap` ne change pas la fonction, il l'habille du contrat. -/ +theorem exists_schwartzMap_of_compactSupport {f : E → F} + (hsupp : HasCompactSupport f) (hsmooth : ContDiff ℝ ∞ f) : + ∃ g : 𝓢(E, F), (g : E → F) = f := + ⟨hsupp.toSchwartzMap hsmooth, rfl⟩ + +end CompactSupport + +end Calibration.Distribution diff --git a/MyIA.AI.Notebooks/SymbolicAI/Lean/calibration_lean/Calibration/Distribution_en.lean b/MyIA.AI.Notebooks/SymbolicAI/Lean/calibration_lean/Calibration/Distribution_en.lean new file mode 100644 index 0000000000..653bc14099 --- /dev/null +++ b/MyIA.AI.Notebooks/SymbolicAI/Lean/calibration_lean/Calibration/Distribution_en.lean @@ -0,0 +1,176 @@ +/- + Calibration target: Schwartz spaces — decay and regularity + ========================================================== + + The Schwartz space is the space of smooth functions all of whose + derivatives decay faster than any power of `‖x‖`. Its distinctive + capability is twofold, and that duality is what this module teaches: + + * REGULARITY — `C^∞` smoothness, carried by the `smooth'` field; + * DECAY — the `decay'` field, which uniformly bounds + `‖x‖^k * ‖iteratedFDeriv ℝ n f x‖` by a constant. + + The family of seminorms `SchwartzMap.seminorm 𝕜 k n` measures both at once: + `k` indexes decay, `n` the order of differentiation. That structure is what + gives the space its locally convex topology, and it is what the theorems + below make manipulable. + + The module instantiates the Mathlib API actually pinned by the lake + (`Mathlib.Analysis.Distribution.SchwartzSpace.Basic`) — no definition is + reinvented, no proof is left as `sorry`. + + Harness paths exercised: + - Target S1 (exists_decay_bound): P3 — the prover must discover the named + lemma `SchwartzMap.decay`; a bare `simp` will not find it. + - Target S2 (seminorm_bounds_decay): P3 — the named lemma + `SchwartzMap.le_seminorm`, not to be confused with its converse. + - Target S3 (seminorm_le_of_pointwise_bound): P1 — the converse bridge + `SchwartzMap.seminorm_le_bound`, with its positivity hypothesis. + - Target S4 (seminorm_smul): P3 — homogeneity comes from the generic lemma + `SeminormClass.map_smul_eq_mul`, not from `simp`. + - Target S5 (seminorm_add_le): P1 — subadditivity via the + `Seminorm.add_le'` field. + - Target S6 (norm_le_seminorm_div_pow): P2 — the REAL polynomial decay is + derived from the seminorm; it requires `le_div_iff₀` and then a + `mul_comm` swap (a two-step proof, the error is distant). + - Target S7 (exists_schwartzMap_of_compactSupport): P2 — the closure + statement `HasCompactSupport.toSchwartzMap`, with the equality of the + underlying function. + + Target difficulty: Goldilocks zone (3-10 prover iterations). + + i18n convention #4980 (sibling pair): this file is the EN sibling of + `Calibration/Distribution.lean`; the two are never imported together. +-/ +import Mathlib.Analysis.Distribution.SchwartzSpace.Basic +import Mathlib.Tactic + +open scoped SchwartzMap ContDiff Topology + +namespace Calibration.Distribution + +/-! ## 1. The contract: decay bounded by a constant -/ + +section Decay + +variable {E F : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + [NormedAddCommGroup F] [NormedSpace ℝ F] + +/-- **Raw decay (target S1).** For every Schwartz function `f` and every pair +of indices `(k, n)` there is a strictly positive constant `C` bounding +`‖x‖^k * ‖iteratedFDeriv ℝ n f x‖` for all `x`. + +This is the `decay'` field of the structure, refined by the `decay` lemma +which additionally guarantees `0 < C` (needed to divide). -/ +theorem exists_decay_bound (f : 𝓢(E, F)) (k n : ℕ) : + ∃ C : ℝ, 0 < C ∧ ∀ x : E, ‖x‖ ^ k * ‖iteratedFDeriv ℝ n f x‖ ≤ C := + f.decay k n + +/-- **Regularity (the first half of the contract).** Every Schwartz function is +smooth to infinite order: this is the `smooth'` field, read here as a public +statement about the underlying function. -/ +theorem smooth_of_schwartz (f : 𝓢(E, F)) : ContDiff ℝ ∞ (f : E → F) := + f.smooth' + +/-- **Decay implies vanishing at infinity.** This is the concrete meaning of +"decays faster than any power": `f` tends to `0` along the `cocompact` +filter. -/ +theorem tendsto_zero_atInfty [ProperSpace E] (f : 𝓢(E, F)) : + Filter.Tendsto (f : E → F) (Filter.cocompact E) (𝓝 0) := + f.tendsto_cocompact + +end Decay + +/-! ## 2. The seminorms: measuring decay and regularity in one gesture + +`SchwartzMap.seminorm 𝕜 k n` is the best constant in the estimate +`‖x‖^k * ‖iteratedFDeriv ℝ n f x‖ ≤ C`. The theorem `le_seminorm` says it +realizes that estimate (it is an upper bound); `seminorm_le_bound` says it is +the least such constant (every working constant bounds it): the two halves of +the infimum definition, taken from both ends. -/ + +section Seminorm + +variable {𝕜 : Type*} [NormedField 𝕜] +variable {E F : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F] [SMulCommClass ℝ 𝕜 F] + +/-- **The seminorm realizes the estimate (target S2).** At every point `x`, the +Schwartz estimate is bounded by the seminorm of indices `(k, n)`. + +This is the "the seminorm is an upper bound" half. -/ +theorem seminorm_bounds_decay (f : 𝓢(E, F)) (k n : ℕ) (x : E) : + ‖x‖ ^ k * ‖iteratedFDeriv ℝ n f x‖ ≤ SchwartzMap.seminorm 𝕜 k n f := + SchwartzMap.le_seminorm 𝕜 k n f x + +/-- **The seminorm is the least upper bound (target S3).** Converse of the +previous theorem: bounding the estimate at EVERY point by a constant `M` +bounds the seminorm by `M`. The hypothesis `hMp : 0 ≤ M` is indispensable +(without it, a strictly negative constant would bound everything). -/ +theorem seminorm_le_of_pointwise_bound (f : 𝓢(E, F)) (k n : ℕ) {M : ℝ} + (hMp : 0 ≤ M) + (hM : ∀ x : E, ‖x‖ ^ k * ‖iteratedFDeriv ℝ n f x‖ ≤ M) : + SchwartzMap.seminorm 𝕜 k n f ≤ M := + SchwartzMap.seminorm_le_bound 𝕜 k n f hMp hM + +/-- **Homogeneity (target S4).** The scalar comes out multiplicatively, as a +norm, of the seminorm. This is the `SMul` axiom of `Seminorm`, read through +the generic lemma `SeminormClass.map_smul_eq_mul`. -/ +theorem seminorm_smul (c : 𝕜) (f : 𝓢(E, F)) (k n : ℕ) : + SchwartzMap.seminorm 𝕜 k n (c • f) = ‖c‖ * SchwartzMap.seminorm 𝕜 k n f := + map_smul_eq_mul (SchwartzMap.seminorm 𝕜 k n) c f + +/-- **Subadditivity (target S5).** A seminorm is not additive, it is +subadditive: the triangle inequality is an axiom of the structure, read +through the `Seminorm.add_le'` field. -/ +theorem seminorm_add_le (f g : 𝓢(E, F)) (k n : ℕ) : + SchwartzMap.seminorm 𝕜 k n (f + g) ≤ + SchwartzMap.seminorm 𝕜 k n f + SchwartzMap.seminorm 𝕜 k n g := + (SchwartzMap.seminorm 𝕜 k n).add_le' f g + +/-- **Effective polynomial decay (target S6).** The seminorm of indices +`(k, 0)` — decay of order `k`, no derivative — yields POLYNOMIAL decay of the +function itself: away from the origin, + + `‖f x‖ ≤ C_k / ‖x‖^k`. + +The proof moves `‖x‖^k` to the denominator (`le_div_iff₀`, whose hypothesis +`0 < ‖x‖` is what authorizes it), then commutes the two factors to land on +`norm_pow_mul_le_seminorm`. -/ +theorem norm_le_seminorm_div_pow (f : 𝓢(E, F)) (k : ℕ) {x : E} (hx : 0 < ‖x‖) : + ‖f x‖ ≤ SchwartzMap.seminorm 𝕜 k 0 f / ‖x‖ ^ k := by + rw [le_div_iff₀ (pow_pos hx k)] + exact (mul_comm _ _).trans_le (SchwartzMap.norm_pow_mul_le_seminorm 𝕜 f k x) + +/-- **The `(0, 0)` seminorm bounds the uniform norm.** The `k = 0` special +case of the previous theorem, without any hypothesis: everywhere, +`‖f x‖ ≤ seminorm 𝕜 0 0 f`. That seminorm is the one controlling the sup +of `f`. -/ +theorem norm_le_seminorm_zero (f : 𝓢(E, F)) (x : E) : + ‖f x‖ ≤ SchwartzMap.seminorm 𝕜 0 0 f := + SchwartzMap.norm_le_seminorm 𝕜 f x + +end Seminorm + +/-! ## 3. Closure: compact support manufactures Schwartz functions -/ + +section CompactSupport + +variable {E F : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + [NormedAddCommGroup F] [NormedSpace ℝ F] + +/-- **A smooth compactly supported function is Schwartz (target S7).** The +closure of the class is a fact about compact support: outside the support the +function is zero, so decay is obtained without any hypothesis. + +The conclusion additionally witnesses preservation of the underlying function +— `toSchwartzMap` does not change the function, it dresses it in the +contract. -/ +theorem exists_schwartzMap_of_compactSupport {f : E → F} + (hsupp : HasCompactSupport f) (hsmooth : ContDiff ℝ ∞ f) : + ∃ g : 𝓢(E, F), (g : E → F) = f := + ⟨hsupp.toSchwartzMap hsmooth, rfl⟩ + +end CompactSupport + +end Calibration.Distribution