Skip to content

Commit ab21c23

Browse files
committed
move tests to Test
1 parent 969f657 commit ab21c23

8 files changed

Lines changed: 445 additions & 375 deletions

File tree

‎RandomDo.lean‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public import RandomDo.Monad.Notation
99
public import RandomDo.Probability.AlgTrace
1010
public import RandomDo.Probability.Examples
1111
public import RandomDo.Probability.Extend
12-
public import RandomDo.Probability.ExtendExamples
12+
public import RandomDo.Probability.MeasurePreserving
1313
public import RandomDo.Probability.Record
1414
public import RandomDo.Probability.Tactic
1515
public import RandomDo.Probability.Thompson

‎RandomDo/Probability/AlgTrace.lean‎

Lines changed: 0 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -512,151 +512,3 @@ elab_rules : tactic
512512
end RDo.Tactic
513513

514514
end
515-
516-
@[expose] public section
517-
518-
open MeasureTheory ProbabilityTheory Finset Learning RDo
519-
520-
noncomputable section
521-
522-
/-! ## An example: an algorithm whose policy is an `rdo` program
523-
524-
A toy sequential algorithm, to show the pipeline end to end: write the policy as an `rdo` program,
525-
get its trace from `rdo_trace`, package it as an `AlgTrace`, and then read the algorithm's internal
526-
draws off any algorithm-environment sequence.
527-
528-
To do the same for `thompson` one needs the measurable equivalence between `Iic n → 𝓐 × 𝓨` and
529-
`Vector (𝓐 × 𝓨) (n + 1)` that turns it into a policy — `Vector.v_equiv` in
530-
`RandomDo.Tactic.Examples`, still a `sorry` there (and stated one element short). Everything after
531-
that point is what follows below.
532-
-/
533-
534-
namespace RDo.Example
535-
536-
variable {K : ℕ} (hK : 0 < K)
537-
538-
/-- The action, read off the history and the noise: depending on the sign of the noise, either
539-
switch to arm `0` or repeat the last action. -/
540-
def readout (n : ℕ) (p : (Iic n → Fin K × ℝ) × ℝ) : Fin K :=
541-
if 0 < p.2 then ⟨0, hK⟩ else (p.1 ⟨n, by simp⟩).1
542-
543-
@[fun_prop]
544-
lemma measurable_readout (n : ℕ) : Measurable (readout hK n) := by
545-
unfold readout
546-
exact Measurable.ite (measurableSet_lt measurable_const measurable_snd) measurable_const
547-
(measurable_fst.comp ((measurable_pi_apply _).comp measurable_fst))
548-
549-
/-- The policy: perturb the last reward by Gaussian noise, then read the action off it. -/
550-
def policy (n : ℕ) (h : Iic n → Fin K × ℝ) : Measure (Fin K) := rdo
551-
let z ← gaussianReal (h ⟨n, by simp⟩).2 1
552-
return readout hK n (h, z)
553-
554-
instance (n : ℕ) : IsMarkov (policy hK n) := by unfold policy; is_markov
555-
556-
/-- The noise the policy draws at step `n`, as a kernel: the one coordinate of its trace. -/
557-
def noise (n : ℕ) : Kernel (Iic n → Fin K × ℝ) ℝ :=
558-
markovKernel (fun h ↦ gaussianReal (h ⟨n, by simp⟩).2 1)
559-
(IsMarkov.gaussianReal (by fun_prop) measurable_const)
560-
561-
instance (n : ℕ) : IsMarkovKernel (noise (K := K) n) := by unfold noise; infer_instance
562-
563-
lemma hasTrace_policy (n : ℕ) : HasTrace (policy hK n) (noise n) (readout hK n) := by
564-
rdo_trace (policy hK n) with h
565-
exact h
566-
567-
/-- The algorithm. -/
568-
def alg : Algorithm (Fin K) ℝ where
569-
policy n := markovKernel (policy hK n) inferInstance
570-
p0 := Measure.dirac ⟨0, hK⟩
571-
572-
/-- Its trace: one Gaussian draw per step. -/
573-
def trace : AlgTrace (alg hK) ℝ where
574-
K := noise
575-
out := readout hK
576-
hasTrace n := hasTrace_policy hK n
577-
K0 := gaussianReal 0 1
578-
out0 := fun _ ↦ ⟨0, hK⟩
579-
measurable_out0 := measurable_const
580-
map_out0 := by rw [Measure.map_const]; simp [alg]
581-
582-
/-- **The payoff.** Given any algorithm-environment sequence for this algorithm, one may assume the
583-
space also carries the noise `Z` the policy draws at each step: it has the conditional law `noise n`
584-
given the history, and the action is `readout` of the history and it. The trajectory keeps the same
585-
law, so anything proved there about the actions and feedbacks holds of the original sequence. -/
586-
theorem exists_noise (env : Environment (Fin K) ℝ) {Ω₀ : Type*} [MeasurableSpace Ω₀]
587-
{P : Measure Ω₀} [IsProbabilityMeasure P] {A : ℕ → Ω₀ → Fin K} {Y : ℕ → Ω₀ → ℝ}
588-
(h : IsAlgEnvSeq A Y (alg hK) env P) :
589-
∃ (Ω' : Type) (_ : MeasurableSpace Ω') (P' : Measure Ω') (_ : IsProbabilityMeasure P')
590-
(A' : ℕ → Ω' → Fin K) (Y' : ℕ → Ω' → ℝ) (Z : ℕ → Ω' → ℝ),
591-
IsAlgEnvSeq A' Y' (alg hK) env P'
592-
∧ P'.map (trajectory A' Y') = P.map (trajectory A Y)
593-
∧ (∀ n, HasCondDistrib (Z (n + 1)) (history A' Y' n) (noise n) P')
594-
∧ (∀ n, A' (n + 1) =ᵐ[P'] fun ω ↦ readout hK n (history A' Y' n ω, Z (n + 1) ω)) := by
595-
obtain ⟨Ω', mΩ', P', hP', A', Y', Z, hseq, hlaw, -, hZ, -, hA⟩ :=
596-
(trace hK).exists_isAlgEnvSeq_trace h
597-
exact ⟨Ω', mΩ', P', hP', A', Y', Z, hseq, hlaw, hZ, hA⟩
598-
599-
/-- **The tactic at work.** `alg_env_trace` replaces the context and the goal by ones on a space
600-
that also carries the noise `Z` the policy draws. The obligation that the statement only depends
601-
on the law of the trajectory is discharged by `transfer` through the trajectory space, so only the
602-
traced goal is left. Any hypothesis mentioning the space travels with the goal, so nothing is
603-
silently lost. -/
604-
example (env : Environment (Fin K) ℝ) {Ω₀ : Type} [MeasurableSpace Ω₀] {P : Measure Ω₀}
605-
[IsProbabilityMeasure P] {A : ℕ → Ω₀ → Fin K} {Y : ℕ → Ω₀ → ℝ}
606-
(h : IsAlgEnvSeq A Y (alg hK) env P) :
607-
P.map (A 0) = Measure.dirac ⟨0, hK⟩ := by
608-
alg_env_trace (trace hK) with Ω P A Y Z hseq hZ₀ hZ hA₀ hA
609-
-- `Z`, `hZ₀`, `hZ` and `hA` are the algorithm's draws and their laws, now available.
610-
exact hseq.hasLaw_action_zero.map_eq
611-
612-
/-- A statement `transfer` has no lemma for leaves the obligation, which is then proved by hand,
613-
here trivially. -/
614-
example (env : Environment (Fin K) ℝ) {Ω₀ : Type} [MeasurableSpace Ω₀] {P : Measure Ω₀}
615-
[IsProbabilityMeasure P] {A : ℕ → Ω₀ → Fin K} {Y : ℕ → Ω₀ → ℝ}
616-
(h : IsAlgEnvSeq A Y (alg hK) env P) :
617-
IsProbabilityMeasure P := by
618-
alg_env_trace (trace hK)
619-
case traced => infer_instance
620-
case transfer =>
621-
intro Ω₁ _ P₁ _ A₁ Y₁ Ω₂ _ P₂ _ A₂ Y₂ h₁ h₂ hlaw h₀
622-
infer_instance
623-
624-
/-- **`extend_space` alongside an algorithm-environment sequence.** After the extension, `Ω`, `P`,
625-
`A` and `Y` live on a larger space that also carries a Gaussian `U` independent of the whole
626-
trajectory, and `h` has been transported by `IsAlgEnvSeq.comp_measurePreserving`. The statement
627-
does not mention the original space, so the `transfer` obligation is trivial and `extend_space`
628-
closes it. The measurability of the sequence is put in the context first, so that the
629-
independence statement `hind` covers `A` and `Y`. -/
630-
example (env : Environment (Fin K) ℝ) {Ω₀ : Type} [MeasurableSpace Ω₀] {P : Measure Ω₀}
631-
[IsProbabilityMeasure P] {A : ℕ → Ω₀ → Fin K} {Y : ℕ → Ω₀ → ℝ}
632-
(h : IsAlgEnvSeq A Y (alg hK) env P) :
633-
∃ (Ω' : Type) (_ : MeasurableSpace Ω') (P' : Measure Ω') (_ : IsProbabilityMeasure P')
634-
(A' : ℕ → Ω' → Fin K) (Y' : ℕ → Ω' → ℝ) (U : Ω' → ℝ),
635-
IsAlgEnvSeq A' Y' (alg hK) env P' ∧ HasLaw U (gaussianReal 0 1) P'
636-
∧ IndepFun (trajectory A' Y') U P' := by
637-
have hA := h.measurable_action
638-
have hY := h.measurable_feedback
639-
extend_space! (gaussianReal 0 1) using P with U hU hind
640-
have hAY : IndepFun (trajectory A Y) U P :=
641-
hind.comp (φ := fun (p : (ℕ → Fin K) × (ℕ → ℝ)) (n : ℕ) ↦ (p.1 n, p.2 n)) (by fun_prop)
642-
measurable_id
643-
exact ⟨Ω₀, inferInstance, P, inferInstance, A, Y, U, h, hU, hAY⟩
644-
645-
/-- **The explicit form, `extend_space_map`.** The goal mentions the space through `P` and `A 0`;
646-
`transfer` moves it to the new space, with the measurability of the sequence taken from `h`. In
647-
the extended goal, `transfer hf at h` pulls the sequence back. -/
648-
example (env : Environment (Fin K) ℝ) {Ω₀ : Type} [MeasurableSpace Ω₀] {P : Measure Ω₀}
649-
[IsProbabilityMeasure P] {A : ℕ → Ω₀ → Fin K} {Y : ℕ → Ω₀ → ℝ}
650-
(h : IsAlgEnvSeq A Y (alg hK) env P) :
651-
P.map (A 0) = Measure.dirac ⟨0, hK⟩ := by
652-
have hA := h.measurable_action
653-
have hY := h.measurable_feedback
654-
extend_space_map (gaussianReal 0 1) with Ω' P' f hf U hU hind
655-
transfer hf at h
656-
exact h.hasLaw_action_zero.map_eq
657-
658-
end RDo.Example
659-
660-
end
661-
662-
end

‎RandomDo/Probability/Extend.lean‎

Lines changed: 4 additions & 182 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,7 @@ Authors: Rémy Degenne
55
-/
66
module
77

8-
public import RandomDo.Probability.Transfer
9-
public import Mathlib.MeasureTheory.Integral.Bochner.Basic
10-
public import Mathlib.MeasureTheory.Measure.Real
11-
public import Mathlib.Probability.HasCondDistrib
12-
public import Mathlib.Probability.Independence.Basic
8+
public import RandomDo.Probability.MeasurePreserving
139
public import Mathlib.Probability.Kernel.Composition.MeasureCompProd
1410
public meta import Lean.Elab.Tactic.Basic
1511

@@ -55,11 +51,9 @@ statement by statement. Here the projection `f` is measure preserving, which is
5551
## Main results
5652
5753
* `RDo.wlog_extend`, `RDo.wlog_extend_kernel`: the principles behind the tactic.
58-
* `MeasureTheory.MeasurePreserving.map_fun_comp`, `hasLaw_fun_comp_iff`, `indepFun_fun_comp_iff`,
59-
`hasCondDistrib_fun_comp_iff`: pulling statements back along a measure-preserving map.
60-
* The `@[transfer]` lemmas `MeasurePreserving.transfer_*` and the `@[transfer_forward]` lemmas
61-
`*.comp_measurePreserving`, `*.preimage_measurePreserving`: the same facts in the forms the
62-
`transfer` tactic uses.
54+
* `RDo.indepFun_fst_snd_prod`, `RDo.hasCondDistrib_snd_fst_compProd`: the product extension.
55+
56+
The lemmas the `transfer` tactic rewrites with are in `RandomDo.Probability.MeasurePreserving`.
6357
-/
6458

6559
@[expose] public section
@@ -68,178 +62,6 @@ open MeasureTheory ProbabilityTheory
6862

6963
noncomputable section
7064

71-
/-! ### Pulling statements back along a measure-preserving map -/
72-
73-
namespace MeasureTheory.MeasurePreserving
74-
75-
variable {Ω Ω' 𝓧 𝓨 : Type*} {mΩ : MeasurableSpace Ω} {mΩ' : MeasurableSpace Ω'}
76-
{m𝓧 : MeasurableSpace 𝓧} {m𝓨 : MeasurableSpace 𝓨} {P : Measure Ω} {P' : Measure Ω'}
77-
{f : Ω' → Ω} {X : Ω → 𝓧} {Y : Ω → 𝓨}
78-
79-
/-- The law of `X ∘ f` under `P'` is the law of `X` under `P`. -/
80-
lemma map_fun_comp (hf : MeasurePreserving f P' P) (hX : AEMeasurable X P) :
81-
P'.map (fun ω ↦ X (f ω)) = P.map X := by
82-
rw [← hf.map_eq] at hX ⊢
83-
exact (AEMeasurable.map_map_of_aemeasurable hX hf.measurable.aemeasurable).symm
84-
85-
lemma hasLaw_fun_comp_iff (hf : MeasurePreserving f P' P) (hX : Measurable X) {ν : Measure 𝓧} :
86-
HasLaw (fun ω ↦ X (f ω)) ν P' ↔ HasLaw X ν P where
87-
mp h := ⟨hX.aemeasurable, by rw [← hf.map_fun_comp hX.aemeasurable]; exact h.map_eq⟩
88-
mpr h := h.comp hf.hasLaw
89-
90-
lemma indepFun_fun_comp_iff (hf : MeasurePreserving f P' P) (hX : Measurable X)
91-
(hY : Measurable Y) :
92-
IndepFun (fun ω ↦ X (f ω)) (fun ω ↦ Y (f ω)) P' ↔ IndepFun X Y P := by
93-
simp only [indepFun_iff_measure_inter_preimage_eq_mul]
94-
refine forall₄_congr fun s t hs ht ↦ ?_
95-
change P' (f ⁻¹' (X ⁻¹' s) ∩ f ⁻¹' (Y ⁻¹' t))
96-
= P' (f ⁻¹' (X ⁻¹' s)) * P' (f ⁻¹' (Y ⁻¹' t)) ↔ _
97-
rw [← Set.preimage_inter, hf.measure_preimage ((hX hs).inter (hY ht)).nullMeasurableSet,
98-
hf.measure_preimage (hX hs).nullMeasurableSet, hf.measure_preimage (hY ht).nullMeasurableSet]
99-
100-
lemma hasCondDistrib_fun_comp_iff (hf : MeasurePreserving f P' P) (hX : Measurable X)
101-
(hY : Measurable Y) {κ : Kernel 𝓧 𝓨} :
102-
HasCondDistrib (fun ω ↦ Y (f ω)) (fun ω ↦ X (f ω)) κ P' ↔ HasCondDistrib Y X κ P := by
103-
unfold HasCondDistrib
104-
rw [hf.map_fun_comp hX.aemeasurable]
105-
exact hf.hasLaw_fun_comp_iff (hX.prodMk hY)
106-
107-
/-! ### The `@[transfer]` lemmas: from the old space to the new one
108-
109-
The same facts, stated with the old space on the left and `hf` as the first explicit argument,
110-
which is what the `transfer` tactic rewrites with. -/
111-
112-
@[transfer]
113-
lemma transfer_map (hf : MeasurePreserving f P' P) (hX : AEMeasurable X P) :
114-
P.map X = P'.map (fun ω ↦ X (f ω)) :=
115-
(hf.map_fun_comp hX).symm
116-
117-
@[transfer]
118-
lemma transfer_measure (hf : MeasurePreserving f P' P) {s : Set Ω} (hs : NullMeasurableSet s P) :
119-
P s = P' (f ⁻¹' s) :=
120-
(hf.measure_preimage hs).symm
121-
122-
@[transfer]
123-
lemma transfer_real (hf : MeasurePreserving f P' P) {s : Set Ω} (hs : NullMeasurableSet s P) :
124-
P.real s = P'.real (f ⁻¹' s) := by
125-
simp only [measureReal_def, hf.measure_preimage hs]
126-
127-
@[transfer]
128-
lemma transfer_hasLaw (hf : MeasurePreserving f P' P) (hX : Measurable X) {ν : Measure 𝓧} :
129-
HasLaw X ν P ↔ HasLaw (fun ω ↦ X (f ω)) ν P' :=
130-
(hf.hasLaw_fun_comp_iff hX).symm
131-
132-
@[transfer]
133-
lemma transfer_indepFun (hf : MeasurePreserving f P' P) (hX : Measurable X) (hY : Measurable Y) :
134-
IndepFun X Y P ↔ IndepFun (fun ω ↦ X (f ω)) (fun ω ↦ Y (f ω)) P' :=
135-
(hf.indepFun_fun_comp_iff hX hY).symm
136-
137-
@[transfer]
138-
lemma transfer_hasCondDistrib (hf : MeasurePreserving f P' P) (hX : Measurable X)
139-
(hY : Measurable Y) {κ : Kernel 𝓧 𝓨} :
140-
HasCondDistrib Y X κ P ↔ HasCondDistrib (fun ω ↦ Y (f ω)) (fun ω ↦ X (f ω)) κ P' :=
141-
(hf.hasCondDistrib_fun_comp_iff hX hY).symm
142-
143-
@[transfer]
144-
lemma transfer_integral {G : Type*} [NormedAddCommGroup G] [NormedSpace ℝ G]
145-
(hf : MeasurePreserving f P' P) {g : Ω → G} (hg : AEStronglyMeasurable g P) :
146-
∫ ω, g ω ∂P = ∫ ω, g (f ω) ∂P' := by
147-
rw [← hf.map_eq] at hg ⊢
148-
exact integral_map hf.measurable.aemeasurable hg
149-
150-
@[transfer]
151-
lemma transfer_lintegral (hf : MeasurePreserving f P' P) {g : Ω → ENNReal}
152-
(hg : AEMeasurable g P) :
153-
∫⁻ ω, g ω ∂P = ∫⁻ ω, g (f ω) ∂P' := by
154-
rw [← hf.map_eq] at hg ⊢
155-
exact lintegral_map' hg hf.measurable.aemeasurable
156-
157-
@[transfer]
158-
lemma transfer_ae (hf : MeasurePreserving f P' P) {p : Ω → Prop}
159-
(hp : NullMeasurableSet {ω | p ω} P) :
160-
(∀ᵐ ω ∂P, p ω) ↔ ∀ᵐ ω ∂P', p (f ω) := by
161-
rw [ae_iff, ae_iff, ← hf.measure_preimage (s := {ω | ¬ p ω}) hp.compl, Set.preimage_ofPred_eq]
162-
163-
@[transfer]
164-
lemma transfer_ae_eq (hf : MeasurePreserving f P' P) {X Y : Ω → 𝓧}
165-
(h : NullMeasurableSet {ω | X ω = Y ω} P) :
166-
X =ᵐ[P] Y ↔ (fun ω ↦ X (f ω)) =ᵐ[P'] fun ω ↦ Y (f ω) :=
167-
hf.transfer_ae h
168-
169-
@[transfer]
170-
lemma transfer_integrable {G : Type*} [NormedAddCommGroup G] (hf : MeasurePreserving f P' P)
171-
{g : Ω → G} (hg : AEStronglyMeasurable g P) :
172-
Integrable g P ↔ Integrable (fun ω ↦ g (f ω)) P' :=
173-
(hf.integrable_comp hg).symm
174-
175-
end MeasureTheory.MeasurePreserving
176-
177-
/-! ### Forward transport of hypotheses
178-
179-
A hypothesis about the old space gives one about the new space. These are the
180-
`@[transfer_forward]` lemmas: the hypothesis first, then `hf`, then side conditions. -/
181-
182-
section Forward
183-
184-
variable {Ω Ω' 𝓧 𝓨 : Type*} {mΩ : MeasurableSpace Ω} {mΩ' : MeasurableSpace Ω'}
185-
{m𝓧 : MeasurableSpace 𝓧} {m𝓨 : MeasurableSpace 𝓨} {P : Measure Ω} {P' : Measure Ω'}
186-
{f : Ω' → Ω} {X : Ω → 𝓧} {Y : Ω → 𝓨}
187-
188-
@[transfer_forward]
189-
lemma Measurable.comp_measurePreserving (hX : Measurable X) (hf : MeasurePreserving f P' P) :
190-
Measurable fun ω ↦ X (f ω) :=
191-
hX.comp hf.measurable
192-
193-
@[transfer_forward]
194-
lemma AEMeasurable.comp_measurePreserving (hX : AEMeasurable X P)
195-
(hf : MeasurePreserving f P' P) :
196-
AEMeasurable (fun ω ↦ X (f ω)) P' :=
197-
hX.comp_quasiMeasurePreserving hf.quasiMeasurePreserving
198-
199-
attribute [transfer_forward] MeasureTheory.AEStronglyMeasurable.comp_measurePreserving
200-
201-
@[transfer_forward]
202-
lemma MeasurableSet.preimage_measurePreserving {s : Set Ω} (hs : MeasurableSet s)
203-
(hf : MeasurePreserving f P' P) :
204-
MeasurableSet (f ⁻¹' s) :=
205-
hf.measurable hs
206-
207-
@[transfer_forward]
208-
lemma MeasureTheory.NullMeasurableSet.preimage_measurePreserving {s : Set Ω}
209-
(hs : NullMeasurableSet s P) (hf : MeasurePreserving f P' P) :
210-
NullMeasurableSet (f ⁻¹' s) P' :=
211-
hs.preimage hf.quasiMeasurePreserving
212-
213-
@[transfer_forward]
214-
lemma ProbabilityTheory.HasLaw.comp_measurePreserving {ν : Measure 𝓧} (hX : HasLaw X ν P)
215-
(hf : MeasurePreserving f P' P) :
216-
HasLaw (fun ω ↦ X (f ω)) ν P' :=
217-
hX.comp hf.hasLaw
218-
219-
/-- A conditional law pulls back along a measure-preserving map. -/
220-
@[transfer_forward]
221-
lemma ProbabilityTheory.HasCondDistrib.comp_measurePreserving {κ : Kernel 𝓧 𝓨}
222-
(h : HasCondDistrib Y X κ P) (hf : MeasurePreserving f P' P) :
223-
HasCondDistrib (fun ω ↦ Y (f ω)) (fun ω ↦ X (f ω)) κ P' := by
224-
have hX := h.aemeasurable_fst
225-
unfold HasCondDistrib at h ⊢
226-
rw [hf.map_fun_comp hX]
227-
exact h.comp hf.hasLaw
228-
229-
@[transfer_forward]
230-
lemma ProbabilityTheory.IndepFun.comp_measurePreserving (h : IndepFun X Y P)
231-
(hf : MeasurePreserving f P' P) (hX : Measurable X) (hY : Measurable Y) :
232-
IndepFun (fun ω ↦ X (f ω)) (fun ω ↦ Y (f ω)) P' :=
233-
(hf.indepFun_fun_comp_iff hX hY).2 h
234-
235-
@[transfer_forward]
236-
lemma MeasureTheory.Integrable.comp_measurePreserving {G : Type*} [NormedAddCommGroup G]
237-
{g : Ω → G} (hg : Integrable g P) (hf : MeasurePreserving f P' P) :
238-
Integrable (fun ω ↦ g (f ω)) P' :=
239-
(hf.integrable_comp hg.aestronglyMeasurable).2 hg
240-
241-
end Forward
242-
24365
namespace RDo
24466

24567
/-! ### The product extension -/

0 commit comments

Comments
 (0)