From 29828caf3fa50cce54e45b3c5d33b97a40aa22c2 Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Fri, 28 Aug 2026 11:55:35 +0200 Subject: [PATCH 01/21] refactor: add O --- LMLTutorial/Pages/DefiningAlgorithm.lean | 46 +- .../ForMathlib/Probability/WithDensity.lean | 24 + .../Online/Bandit/Algorithms/ETC.lean | 50 +- .../Algorithms/Regret/BayesRegretTS.lean | 30 +- .../Online/Bandit/Algorithms/TS.lean | 50 +- .../Online/Bandit/Algorithms/UCB.lean | 77 +- .../Online/Bandit/ArrayProbSpace.lean | 207 +++--- LeanMachineLearning/Online/Bandit/Regret.lean | 9 +- .../Online/Bandit/RewardByCountMeasure.lean | 31 +- .../Online/Bandit/SumRewards.lean | 102 +-- .../SequentialLearning/ActionIndicator.lean | 13 +- .../SequentialLearning/Algorithm.lean | 677 +++++++++++++----- .../SequentialLearning/AlgorithmDensity.lean | 72 +- .../AlgorithmDensityBayes.lean | 24 +- .../Algorithms/RandomSampling/Basic.lean | 20 +- .../Algorithms/RandomSampling/Tendsto.lean | 23 +- .../Algorithms/RoundRobin.lean | 22 +- .../Algorithms/Uniform.lean | 8 +- .../BayesStationaryEnv.lean | 201 ++++-- .../SequentialLearning/Deterministic.lean | 270 ++++--- .../SequentialLearning/EvaluationEnv.lean | 29 +- .../FeedbackMartingale.lean | 103 +-- .../SequentialLearning/FiniteActions.lean | 80 ++- .../IonescuTulceaSpace.lean | 306 ++++---- .../SequentialLearning/Means.lean | 100 +-- .../SequentialLearning/StationaryEnv.lean | 129 ++-- .../SequentialLearning/SumRewards.lean | 60 +- 27 files changed, 1674 insertions(+), 1089 deletions(-) diff --git a/LMLTutorial/Pages/DefiningAlgorithm.lean b/LMLTutorial/Pages/DefiningAlgorithm.lean index 2286647b..5b406cec 100644 --- a/LMLTutorial/Pages/DefiningAlgorithm.lean +++ b/LMLTutorial/Pages/DefiningAlgorithm.lean @@ -33,22 +33,30 @@ We then illustrate them with the UCB bandit algorithm. # Algorithm and environment In LML, we prove theorems about the interaction of an algorithm with an environment. -An algorithm takes actions, to which the environment responds with feedback (e.g., rewards for the bandit case, the gradient of a function in optimization problems). -In general, both action and feedback can depend on the entire history up to the current time and can be randomized. +Each round of the interaction consists of three stages: the environment draws an observation (e.g., the context in a contextual bandit), the algorithm takes an action based on that observation, and the environment responds with feedback (e.g., rewards for the bandit case, the gradient of a function in optimization problems). +In general, observation, action and feedback can depend on the entire history up to the current time and can be randomized. +One round is recorded by the `Round` abbreviation and a history of `n` rounds by the `Hist` abbreviation. + +{docstring Round} + +{docstring Hist} + The `Algorithm` structure is defined as follows: {docstring Algorithm} -This structure refers to two types, the type of actions `𝓐` and the type of feedback `𝓨`. -Both are measurable spaces, since we consider stochastic algorithms and environments. -Before time `n`, there is a history of actions and feedbacks `Fin n β†’ 𝓐 Γ— 𝓨` (the `n` pairs of action and feedback at times `0, ..., n - 1`; the processes are 0-indexed). -The `policy` field contains for each time `n` a kernel from that history to the action space. -That is, it maps every possible history to a random action at time `n` (and that map is measurable). -The `h_policy` field records that the measure describing the action is a probability measure (and it is in square brackets to tell Lean to infer it automatically whenever possible). -At time `0` the history is empty: `Fin 0 β†’ 𝓐 Γ— 𝓨` has a unique element, and the distribution of the first action is `policy 0` applied to that element. -That distribution is called `Algorithm.p0`. +This structure refers to three types, the type of observations `π“ž`, the type of actions `𝓐` and the type of feedback `𝓨`. +All three are measurable spaces, since we consider stochastic algorithms and environments. +Before time `n`, there is a history of `n` complete rounds `Hist π“ž 𝓐 𝓨 n = Fin n β†’ π“ž Γ— 𝓐 Γ— 𝓨` (the observation-action-feedback triples at times `0, ..., n - 1`; the processes are 0-indexed). +The `policy` field contains for each time `n` a kernel from that history together with the observation at time `n` to the action space. +That is, it maps every possible history and current observation to a random action at time `n` (and that map is measurable). +The `isMarkovKernel_policy` field records that the measure describing the action is a probability measure (and it is in square brackets to tell Lean to infer it automatically whenever possible). +At time `0` the history is empty: `Hist π“ž 𝓐 𝓨 0` has a unique element, and the distribution of the first action given the first observation is `policy 0` applied to that element. +That kernel is called `Algorithm.p0`. + +Many settings have no observations at all: the algorithm sees only the past rounds. Those are described by taking `π“ž = Unit`, and we write `noObs Ξ©` for the corresponding (constant) observation process. -If the algorithms actions are not random, we can use the `detAlgorithm` definition to build an algorithm from the data of a measurable function for the action at each time, as a function of the history before that time. +If the algorithms actions are not random, we can use the `detAlgorithm` definition to build an algorithm from the data of a measurable function for the action at each time, as a function of the history before that time and of the current observation. The first action is the value of that function at time `0` on the empty history. {docstring detAlgorithm} @@ -56,19 +64,21 @@ The first action is the value of that function at time `0` on the empty history. We can see here that we did not need to prove that the kernels are `IsMarkovKernel`. Lean knows that deterministic kernels are Markov. -The `Environment` structure is the mirror of the `Algorithm` structure, with a kernel for the feedback instead of the actions. +The `Environment` structure is the mirror of the `Algorithm` structure, with a kernel for the observation and a kernel for the feedback instead of the actions. {docstring Environment} -`feedback n` gives the distribution of the feedback at time `n` given the history before `n` and the action at time `n`. -The distribution of the first feedback given the first action is `feedback 0` applied to the empty history; it is called `Environment.Ξ½0`. +`obs n` gives the distribution of the observation at time `n` given the history before `n`. +`feedback n` gives the distribution of the feedback at time `n` given the history before `n`, the observation and the action at time `n`. +The distribution of the first observation is `obs 0` applied to the empty history; it is called `Environment.obs0`. +The distribution of the first feedback given the first observation and action is `feedback 0` applied to the empty history; it is called `Environment.Ξ½0`. -In many applications the feedback depends only on the last action and not on the prior history. +In many applications there is no observation and the feedback depends only on the last action, not on the prior history. We provide an `obliviousEnv` definition that builds an environment for those cases. {docstring obliviousEnv} -`(Ξ½ n).prodMkLeft _` is the kernel `Ξ½ n` seen as a `Kernel ((Fin n β†’ 𝓐 Γ— 𝓨) Γ— 𝓐) 𝓨` by ignoring the history. +`(Ξ½ n).prodMkLeft _` is the kernel `Ξ½ n` seen as a `Kernel ((Hist Unit 𝓐 𝓨 n Γ— Unit) Γ— 𝓐) 𝓨` by ignoring the history and the observation. If furthermore the feedback kernel does not change with time, we can use the `stationaryEnv` definition to build the environment. @@ -82,7 +92,7 @@ This is done by the `IsAlgEnvSeq` structure. {docstring IsAlgEnvSeq} -This structure takes as input two sequences of random variables (two stochastic processes), `A` and `Y`, which represent the actions and feedback generated by the interaction of the algorithm with the environment. +This structure takes as input three sequences of random variables (three stochastic processes), `O`, `A` and `Y`, which represent the observations, actions and feedback generated by the interaction of the algorithm with the environment. It states that those sequences are measurable and that they have the correct conditional distributions given by the algorithm and environment. The measurable space `Ξ©` and the measure `P` are not imposed: they can be chosen as we want, as long as the conditions of `IsAlgEnvSeq` are satisfied. This definition requires `𝓐` and `𝓨` to be nonempty standard Borel spaces, because Mathlib's theory about conditional distributions requires those assumptions. @@ -149,7 +159,7 @@ The theorem gives an upper bound on the expected regret of UCB at time `n`. # Building vs analyzing algorithms -When building an algorithm, we describe it with functions from the history `(Fin n β†’ 𝓐 Γ— R)` to the action space `𝓐`. +When building an algorithm, we describe it with functions from the history and the current observation `(Hist π“ž 𝓐 R n Γ— π“ž)` to the action space `𝓐`. Thus, to construct UCB, we used the following empirical mean function. {docstring empMean'} diff --git a/LeanMachineLearning/ForMathlib/Probability/WithDensity.lean b/LeanMachineLearning/ForMathlib/Probability/WithDensity.lean index 8471c6ff..eef5d6b7 100644 --- a/LeanMachineLearning/ForMathlib/Probability/WithDensity.lean +++ b/LeanMachineLearning/ForMathlib/Probability/WithDensity.lean @@ -120,6 +120,30 @@ lemma compProd_withDensity_left {ΞΊ : Kernel Ξ± Ξ²} {Ξ· : Kernel (Ξ± Γ— Ξ²) Ξ³} _ = ((ΞΊ βŠ—β‚– Ξ·).withDensity (fun a bc ↦ f a bc.1)) a := by rw [← compProd_apply_eq_compProd_sectR, Kernel.withDensity_apply _ (by fun_prop)] +lemma sectR_withDensity {Ξ· : Kernel (Ξ± Γ— Ξ²) Ξ³} {g : Ξ± Γ— Ξ² β†’ Ξ³ β†’ ℝβ‰₯0∞} [IsSFiniteKernel Ξ·] + (hg : Measurable (Function.uncurry g)) (a : Ξ±) : + (Ξ·.withDensity g).sectR a = (Ξ·.sectR a).withDensity (fun b ↦ g (a, b)) := by + ext b s hs + rw [Kernel.sectR_apply, Kernel.withDensity_apply' _ hg, + Kernel.withDensity_apply' _ (by fun_prop), Kernel.sectR_apply] + +lemma compProd_withDensity_right {ΞΊ : Kernel Ξ± Ξ²} {Ξ· : Kernel (Ξ± Γ— Ξ²) Ξ³} {g : Ξ± Γ— Ξ² β†’ Ξ³ β†’ ℝβ‰₯0∞} + [IsSFiniteKernel ΞΊ] [IsSFiniteKernel Ξ·] [IsSFiniteKernel (Ξ·.withDensity g)] + (hg : Measurable (Function.uncurry g)) : + ΞΊ βŠ—β‚– (Ξ·.withDensity g) = (ΞΊ βŠ—β‚– Ξ·).withDensity (fun a bc ↦ g (a, bc.1) bc.2) := by + ext a : 1 + have h_sf : IsSFiniteKernel ((Ξ·.sectR a).withDensity (fun b ↦ g (a, b))) := by + rw [← sectR_withDensity hg] + infer_instance + calc (ΞΊ βŠ—β‚– (Ξ·.withDensity g)) a + = (ΞΊ a) βŠ—β‚˜ ((Ξ·.withDensity g).sectR a) := compProd_apply_eq_compProd_sectR .. + _ = (ΞΊ a) βŠ—β‚˜ ((Ξ·.sectR a).withDensity (fun b ↦ g (a, b))) := by rw [sectR_withDensity hg] + _ = ((ΞΊ a) βŠ—β‚˜ (Ξ·.sectR a)).withDensity (fun p ↦ g (a, p.1) p.2) := by + refine Measure.compProd_withDensity ?_ + fun_prop + _ = ((ΞΊ βŠ—β‚– Ξ·).withDensity (fun a bc ↦ g (a, bc.1) bc.2)) a := by + rw [← compProd_apply_eq_compProd_sectR, Kernel.withDensity_apply _ (by fun_prop)] + lemma withDensity_rnDeriv_eq' {ΞΊ Ξ· : Kernel Ξ± Ξ²} [MeasurableSpace.CountableOrCountablyGenerated Ξ± Ξ²] [IsFiniteKernel ΞΊ] [IsFiniteKernel Ξ·] (h : βˆ€ a, ΞΊ a β‰ͺ Ξ· a) : Ξ·.withDensity (ΞΊ.rnDeriv Ξ·) = ΞΊ := diff --git a/LeanMachineLearning/Online/Bandit/Algorithms/ETC.lean b/LeanMachineLearning/Online/Bandit/Algorithms/ETC.lean index 7b87e5f8..f6a53d31 100644 --- a/LeanMachineLearning/Online/Bandit/Algorithms/ETC.lean +++ b/LeanMachineLearning/Online/Bandit/Algorithms/ETC.lean @@ -29,12 +29,12 @@ For `n < K * m`, this is arm `n % K`. For `n = K * m`, this is the arm with the highest empirical mean after the exploration phase. For `n > K * m`, this is the same arm as at time `n - 1`. -/ noncomputable -def ETC.nextArm (hK : 0 < K) (m n : β„•) (h : Fin n β†’ Fin K Γ— ℝ) : Fin K := +def ETC.nextArm (hK : 0 < K) (m n : β„•) (h : Hist Unit (Fin K) ℝ n) : Fin K := have : Nonempty (Fin K) := Fin.pos_iff_nonempty.mp hK if hn : n < K * m then RoundRobin.nextAction hK n else if hn_eq : n = K * m then argmax (empMean' n h) - else (h ⟨n - 1, by omega⟩).1 + else (h ⟨n - 1, by omega⟩).action /-- The next arm pulled by ETC is chosen in a measurable way. -/ @[fun_prop] @@ -54,8 +54,8 @@ lemma ETC.measurable_nextArm (hK : 0 < K) (m n : β„•) : Measurable (nextArm hK m /-- The Explore-Then-Commit algorithm: deterministic algorithm that chooses the next arm according to `ETC.nextArm`. -/ noncomputable -def etcAlgorithm (hK : 0 < K) (m : β„•) : Algorithm (Fin K) ℝ := - detAlgorithm (ETC.nextArm hK m) (by fun_prop) +def etcAlgorithm (hK : 0 < K) (m : β„•) : Algorithm Unit (Fin K) ℝ := + detAlgorithm (fun n p ↦ ETC.nextArm hK m n p.1) (by fun_prop) end AlgorithmDefinition @@ -64,15 +64,17 @@ namespace ETC variable {hK : 0 < K} {m : β„•} {Ξ½ : Kernel (Fin K) ℝ} [IsMarkovKernel Ξ½] {Ξ© : Type*} {mΞ© : MeasurableSpace Ξ©} {P : Measure Ξ©} [IsProbabilityMeasure P] - {A : β„• β†’ Ξ© β†’ Fin K} {R : β„• β†’ Ξ© β†’ ℝ} + {O : β„• β†’ Ξ© β†’ Unit} {A : β„• β†’ Ξ© β†’ Fin K} {R : β„• β†’ Ξ© β†’ ℝ} {Οƒ2 : ℝβ‰₯0} /-- Before round `K * m`, the ETC algorithm behaves like the Round-Robin algorithm. -/ lemma isAlgEnvSeqUntil_roundRobinAlgorithm - (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) : - IsAlgEnvSeqUntil A R (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P (K * m) where + (h : IsAlgEnvSeq O A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) : + IsAlgEnvSeqUntil O A R (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P (K * m) where + measurable_obs := h.measurable_obs measurable_action := h.measurable_action measurable_feedback := h.measurable_feedback + hasCondDistrib_obs n _ := h.hasCondDistrib_obs n hasCondDistrib_action n hn := by convert h.hasCondDistrib_action n using 1 simp only [roundRobinAlgorithm, detAlgorithm_policy, etcAlgorithm] @@ -82,13 +84,13 @@ lemma isAlgEnvSeqUntil_roundRobinAlgorithm section AlgorithmBehavior -lemma arm_ae_eq_etcNextArm (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) (n : β„•) : - A n =ᡐ[P] fun Ο‰ ↦ nextArm hK m n (history A R n Ο‰) := by +lemma arm_ae_eq_etcNextArm (h : IsAlgEnvSeq O A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) (n : β„•) : + A n =ᡐ[P] fun Ο‰ ↦ nextArm hK m n (history O A R n Ο‰) := by have : Nonempty (Fin K) := Fin.pos_iff_nonempty.mp hK exact h.action_detAlgorithm_ae_eq n /-- For `n < K * m`, the arm pulled at time `n` is the arm `n % K`. -/ -lemma arm_of_lt (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) +lemma arm_of_lt (h : IsAlgEnvSeq O A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) {n : β„•} (hn : n < K * m) : A n =ᡐ[P] fun _ ↦ ⟨n % K, Nat.mod_lt _ hK⟩ := RoundRobin.action_ae_eq n ((isAlgEnvSeqUntil_roundRobinAlgorithm h).mono hn) @@ -96,13 +98,13 @@ lemma arm_of_lt (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) /-- The arm pulled at time `K * m` is the arm with the highest empirical mean after the exploration phase. -/ lemma arm_mul [Nonempty (Fin K)] - (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) : - A (K * m) =ᡐ[P] fun Ο‰ ↦ argmax (empMean' (K * m) (history A R (K * m) Ο‰)) := by + (h : IsAlgEnvSeq O A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) : + A (K * m) =ᡐ[P] fun Ο‰ ↦ argmax (empMean' (K * m) (history O A R (K * m) Ο‰)) := by filter_upwards [arm_ae_eq_etcNextArm h (K * m)] with Ο‰ hn_eq rw [hn_eq, nextArm, dite_eq_right (by simp), dite_eq_left rfl] /-- For `n β‰₯ K * m`, the arm pulled at time `n + 1` is the same as the arm pulled at time `n`. -/ -lemma arm_add_one_of_ge (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) +lemma arm_add_one_of_ge (h : IsAlgEnvSeq O A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) {n : β„•} (hn : K * m ≀ n) : A (n + 1) =ᡐ[P] fun Ο‰ ↦ A n Ο‰ := by filter_upwards [arm_ae_eq_etcNextArm h (n + 1)] with Ο‰ hn_eq @@ -110,7 +112,7 @@ lemma arm_add_one_of_ge (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv rfl /-- For `n β‰₯ K * m`, the arm pulled at time `n` is the same as the arm pulled at time `K * m`. -/ -lemma arm_of_ge (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) +lemma arm_of_ge (h : IsAlgEnvSeq O A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) {n : β„•} (hn : K * m ≀ n) : A n =ᡐ[P] A (K * m) := by have h_ae n : K * m ≀ n β†’ A (n + 1) =ᡐ[P] fun Ο‰ ↦ A n Ο‰ := arm_add_one_of_ge h @@ -121,11 +123,11 @@ lemma arm_of_ge (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) | succ n hmn h_ind => rw [h_ae n hmn, h_ind] /-- At time `K * m`, the number of pulls of each arm is equal to `m`. -/ -lemma pullCount_mul (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) (a : Fin K) : +lemma pullCount_mul (h : IsAlgEnvSeq O A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) (a : Fin K) : pullCount A a (K * m) =ᡐ[P] fun _ ↦ m := RoundRobin.pullCount_mul m (isAlgEnvSeqUntil_roundRobinAlgorithm h) a -lemma pullCount_add_one_of_ge (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) +lemma pullCount_add_one_of_ge (h : IsAlgEnvSeq O A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) (a : Fin K) {n : β„•} (hn : K * m ≀ n) : pullCount A a (n + 1) =ᡐ[P] fun Ο‰ ↦ pullCount A a n Ο‰ + {Ο‰' | A (K * m) Ο‰' = a}.indicator (fun _ ↦ 1) Ο‰ := by @@ -135,7 +137,7 @@ lemma pullCount_add_one_of_ge (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationa /-- For `n β‰₯ K * m`, the number of pulls of each arm `a` at time `n` is equal to `m` plus `n - K * m` if arm `a` is the best arm after the exploration phase. -/ -lemma pullCount_of_ge (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) +lemma pullCount_of_ge (h : IsAlgEnvSeq O A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) (a : Fin K) {n : β„•} (hn : K * m ≀ n) : pullCount A a n =ᡐ[P] fun Ο‰ ↦ m + (n - K * m) * {Ο‰' | A (K * m) Ο‰' = a}.indicator (fun _ ↦ 1) Ο‰ := by @@ -155,16 +157,16 @@ lemma pullCount_of_ge (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv Ξ½ /-- If at time `K * m` the algorithm chooses arm `a`, then the total reward obtained by pulling arm `a` is at least the total reward obtained by pulling the best arm. -/ lemma sumRewards_bestArm_le_of_arm_mul_eq [Nonempty (Fin K)] - (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) (a : Fin K) (hm : m β‰  0) : + (h : IsAlgEnvSeq O A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) (a : Fin K) (hm : m β‰  0) : βˆ€α΅ h βˆ‚P, A (K * m) h = a β†’ sumRewards A R (bestArm Ξ½) (K * m) h ≀ sumRewards A R a (K * m) h := by filter_upwards [arm_mul h, pullCount_mul h a, pullCount_mul h (bestArm Ξ½)] with h h_arm ha h_best h_eq - have h_max := isMaxOn_argmax (empMean' (K * m) (history A R (K * m) h)) (bestArm Ξ½) + have h_max := isMaxOn_argmax (empMean' (K * m) (history O A R (K * m) h)) (bestArm Ξ½) rw [← h_arm, h_eq] at h_max rw [sumRewards_eq_pullCount_mul_empMean, sumRewards_eq_pullCount_mul_empMean, ha, h_best] Β· gcongr - rwa [empMean_eq_empMean', empMean_eq_empMean'] + rwa [empMean_eq_empMean' (O := O), empMean_eq_empMean' (O := O)] Β· simp [ha, hm] Β· simp [h_best, hm] @@ -173,7 +175,7 @@ end AlgorithmBehavior section Regret lemma probReal_sumRewards_le_sumRewards_le [Nonempty (Fin K)] - (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) + (h : IsAlgEnvSeq O A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) (hΞ½ : βˆ€ a, HasSubgaussianMGF (fun x ↦ x - (Ξ½ a)[id]) Οƒ2 (Ξ½ a)) (a : Fin K) : P.real {Ο‰ | sumRewards A R (bestArm Ξ½) (K * m) Ο‰ ≀ sumRewards A R a (K * m) Ο‰} ≀ Real.exp (-↑m * gap Ξ½ a ^ 2 / (4 * Οƒ2)) := by @@ -190,7 +192,7 @@ lemma probReal_sumRewards_le_sumRewards_le [Nonempty (Fin K)] /-- The probability that at time `K * m` the ETC algorithm chooses arm `a` is at most `exp(- m * Ξ”_a^2 / 4)`. -/ lemma prob_arm_mul_eq_le [Nonempty (Fin K)] - (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) + (h : IsAlgEnvSeq O A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) (hΞ½ : βˆ€ a, HasSubgaussianMGF (fun x ↦ x - (Ξ½ a)[id]) Οƒ2 (Ξ½ a)) (a : Fin K) (hm : m β‰  0) : P.real {Ο‰ | A (K * m) Ο‰ = a} ≀ Real.exp (- (m : ℝ) * gap Ξ½ a ^ 2 / (4 * Οƒ2)) := by @@ -206,7 +208,7 @@ lemma prob_arm_mul_eq_le [Nonempty (Fin K)] /-- Bound on the expectation of the number of pulls of each arm by the ETC algorithm. -/ lemma expectation_pullCount_le [Nonempty (Fin K)] - (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) + (h : IsAlgEnvSeq O A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) (hΞ½ : βˆ€ a, HasSubgaussianMGF (fun x ↦ x - (Ξ½ a)[id]) Οƒ2 (Ξ½ a)) (a : Fin K) (hm : m β‰  0) {n : β„•} (hn : K * m ≀ n) : P[fun Ο‰ ↦ (pullCount A a n Ο‰ : ℝ)] @@ -235,7 +237,7 @@ lemma expectation_pullCount_le [Nonempty (Fin K)] /-- Regret bound for the ETC algorithm. -/ theorem regret_le [Nonempty (Fin K)] - (h : IsAlgEnvSeq A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) + (h : IsAlgEnvSeq O A R (etcAlgorithm hK m) (stationaryEnv Ξ½) P) (hΞ½ : βˆ€ a, HasSubgaussianMGF (fun x ↦ x - (Ξ½ a)[id]) Οƒ2 (Ξ½ a)) (hm : m β‰  0) (n : β„•) (hn : K * m ≀ n) : P[regret Ξ½ A n] ≀ diff --git a/LeanMachineLearning/Online/Bandit/Algorithms/Regret/BayesRegretTS.lean b/LeanMachineLearning/Online/Bandit/Algorithms/Regret/BayesRegretTS.lean index 8508a313..7b1f5c6c 100644 --- a/LeanMachineLearning/Online/Bandit/Algorithms/Regret/BayesRegretTS.lean +++ b/LeanMachineLearning/Online/Bandit/Algorithms/Regret/BayesRegretTS.lean @@ -93,19 +93,19 @@ lemma integrable_uncurry_ucb_comp [MeasurableSpace Ξ©] (hA : βˆ€ t, Measurable ( /-- Clipped upper confidence bound (history-based version). -/ noncomputable -def ucb' (n : β„•) (h : Fin n β†’ Fin K Γ— ℝ) (l u Οƒ2 Ξ΄ : ℝ) (a : Fin K) : ℝ := +def ucb' (n : β„•) (h : Hist Unit (Fin K) ℝ n) (l u Οƒ2 Ξ΄ : ℝ) (a : Fin K) : ℝ := if pullCount' n h a = 0 then u else max l (min u (empMean' n h a + √(2 * Οƒ2 * Real.log (1 / Ξ΄) / (pullCount' n h a)))) @[fun_prop] lemma measurable_uncurry_ucb' {n : β„•} : - Measurable (fun p : (Fin n β†’ Fin K Γ— ℝ) Γ— Fin K ↦ ucb' n p.1 l u Οƒ2 Ξ΄ p.2) := + Measurable (fun p : Hist Unit (Fin K) ℝ n Γ— Fin K ↦ ucb' n p.1 l u Οƒ2 Ξ΄ p.2) := Measurable.ite (by measurability) (by fun_prop) (by fun_prop) -lemma ucb_eq_ucb' {a : Fin K} {n : β„•} {Ο‰ : Ξ©} : - ucb A R l u Οƒ2 Ξ΄ a n Ο‰ = ucb' n (history A R n Ο‰) l u Οƒ2 Ξ΄ a := by - have hp : pullCount A a n Ο‰ = pullCount' n (history A R n Ο‰) a := pullCount_eq_pullCount' - have he : empMean A R a n Ο‰ = empMean' n (history A R n Ο‰) a := empMean_eq_empMean' +lemma ucb_eq_ucb' {O : β„• β†’ Ξ© β†’ Unit} {a : Fin K} {n : β„•} {Ο‰ : Ξ©} : + ucb A R l u Οƒ2 Ξ΄ a n Ο‰ = ucb' n (history O A R n Ο‰) l u Οƒ2 Ξ΄ a := by + have hp : pullCount A a n Ο‰ = pullCount' n (history O A R n Ο‰) a := pullCount_eq_pullCount' + have he : empMean A R a n Ο‰ = empMean' n (history O A R n Ο‰) a := empMean_eq_empMean' rw [ucb, ucb', hp, he] /-- Helper for `sum_ucb_sub_mean_le`. -/ @@ -203,8 +203,8 @@ variable {E : Ξ© β†’ 𝓔} variable {Q : Measure 𝓔} {ΞΊ : Kernel (𝓔 Γ— Fin K) ℝ} [IsMarkovKernel ΞΊ] variable {P : Measure Ξ©} [IsProbabilityMeasure P] -lemma integral_sum_range_actionMean_bestAction_sub_ucb_bestAction_le {alg : Algorithm (Fin K) ℝ} - (h : IsBayesAlgEnvSeq Q ΞΊ alg E A R P) +lemma integral_sum_range_actionMean_bestAction_sub_ucb_bestAction_le + {alg : Algorithm Unit (Fin K) ℝ} (h : IsBayesAlgEnvSeq Q ΞΊ alg E A R P) (hlu : l ≀ u) (hm : βˆ€ e a, (ΞΊ (e, a))[id] ∈ (Set.Icc l u)) (hΟƒ2 : 0 < Οƒ2) (hs : βˆ€ e a, HasSubgaussianMGF (fun x ↦ x - (ΞΊ (e, a))[id]) βŸ¨Οƒ2, hΟƒ2.le⟩ (ΞΊ (e, a))) (hΞ΄ : 0 < Ξ΄) (n : β„•) : @@ -251,7 +251,7 @@ lemma integral_sum_range_actionMean_bestAction_sub_ucb_bestAction_le {alg : Algo _ = _ := by ring -lemma integral_sum_range_ucb_action_sub_actionMean_action_le {alg : Algorithm (Fin K) ℝ} +lemma integral_sum_range_ucb_action_sub_actionMean_action_le {alg : Algorithm Unit (Fin K) ℝ} (h : IsBayesAlgEnvSeq Q ΞΊ alg E A R P) (hlu : l ≀ u) (hm : βˆ€ e a, (ΞΊ (e, a))[id] ∈ (Set.Icc l u)) (hΟƒ2 : 0 < Οƒ2) (hs : βˆ€ e a, HasSubgaussianMGF (fun x ↦ x - (ΞΊ (e, a))[id]) βŸ¨Οƒ2, hΟƒ2.le⟩ (ΞΊ (e, a))) @@ -321,18 +321,18 @@ lemma integral_ucb_action_eq_integral_ucb_bestAction (hK : 0 < K) have := h.measurable_action have := h.measurable_param have := h.measurable_feedback - let uc (ha : (Fin n β†’ Fin K Γ— ℝ) Γ— Fin K) := ucb' n ha.1 l u Οƒ2 Ξ΄ ha.2 + let uc (ha : Hist Unit (Fin K) ℝ n Γ— Fin K) := ucb' n ha.1 l u Οƒ2 Ξ΄ ha.2 calc - _ = P[fun Ο‰ ↦ uc (history A R n Ο‰, A n Ο‰)] := by - simp_rw [uc, ucb_eq_ucb'] - _ = ∫ ha, uc ha βˆ‚P.map (fun Ο‰ ↦ (history A R n Ο‰, A n Ο‰)) := by + _ = P[fun Ο‰ ↦ uc (history (noObs Ξ©) A R n Ο‰, A n Ο‰)] := by + simp_rw [uc, ucb_eq_ucb' (O := noObs Ξ©)] + _ = ∫ ha, uc ha βˆ‚P.map (fun Ο‰ ↦ (history (noObs Ξ©) A R n Ο‰, A n Ο‰)) := by rw [← integral_map (by fun_prop) (by fun_prop)] - _ = ∫ ha, uc ha βˆ‚P.map (fun Ο‰ ↦ (history A R n Ο‰, bestAction ΞΊ E Ο‰)) := by + _ = ∫ ha, uc ha βˆ‚P.map (fun Ο‰ ↦ (history (noObs Ξ©) A R n Ο‰, bestAction ΞΊ E Ο‰)) := by rw [← compProd_map_condDistrib (by fun_prop), ← compProd_map_condDistrib (by fun_prop), Measure.compProd_congr (hasCondDistrib_action hK h n).condDistrib_eq] _ = P[fun Ο‰ ↦ ucb A R l u Οƒ2 Ξ΄ (bestAction ΞΊ E Ο‰) n Ο‰] := by rw [integral_map (by fun_prop) (by fun_prop)] - simp_rw [uc, ucb_eq_ucb'] + simp_rw [uc, ucb_eq_ucb' (O := noObs Ξ©)] lemma integral_regret_eq_add (hK : 0 < K) (h : IsBayesAlgEnvSeq Q ΞΊ (tsAlgorithm hK Q ΞΊ) E A R P) (hm : βˆ€ e a, (ΞΊ (e, a))[id] ∈ (Set.Icc l u)) (n : β„•) : diff --git a/LeanMachineLearning/Online/Bandit/Algorithms/TS.lean b/LeanMachineLearning/Online/Bandit/Algorithms/TS.lean index d457ddbe..e4982c72 100644 --- a/LeanMachineLearning/Online/Bandit/Algorithms/TS.lean +++ b/LeanMachineLearning/Online/Bandit/Algorithms/TS.lean @@ -47,13 +47,18 @@ under the posterior over environments given the history so far. The posterior under a uniform algorithm is used to avoid a circular definition. -/ noncomputable def TS.policy (hK : 0 < K) (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— Fin K) ℝ) - [IsMarkovKernel ΞΊ] (n : β„•) : Kernel (Fin n β†’ (Fin K) Γ— ℝ) (Fin K) := + [IsMarkovKernel ΞΊ] (n : β„•) : Kernel (Hist Unit (Fin K) ℝ n Γ— Unit) (Fin K) := have : Nonempty (Fin K) := Fin.pos_iff_nonempty.mp hK - (IT.bayesTrajMeasurePosterior Q ΞΊ uniformAlgorithm n).map (bestAction ΞΊ id) + (((IT.bayesTrajMeasurePosterior Q ΞΊ uniformAlgorithm n).map + (bestAction ΞΊ id)).prodMkRight Unit) instance {hK : 0 < K} {Q : Measure 𝓔} [IsProbabilityMeasure Q] {ΞΊ : Kernel (𝓔 Γ— Fin K) ℝ} - [IsMarkovKernel ΞΊ] {n : β„•} : IsMarkovKernel (TS.policy hK Q ΞΊ n) := - Kernel.IsMarkovKernel.map _ (by fun_prop) + [IsMarkovKernel ΞΊ] {n : β„•} : IsMarkovKernel (TS.policy hK Q ΞΊ n) := by + have : Nonempty (Fin K) := Fin.pos_iff_nonempty.mp hK + have : IsMarkovKernel ((IT.bayesTrajMeasurePosterior Q ΞΊ uniformAlgorithm n).map + (bestAction ΞΊ id)) := Kernel.IsMarkovKernel.map _ (by fun_prop) + unfold TS.policy + infer_instance /-- The Thompson sampling algorithm with actions in `Fin K`, where `Q : Measure 𝓔` is a prior distribution over parameters, and `ΞΊ : Kernel (𝓔 Γ— Fin K) ℝ` is a Markov kernel that defines the @@ -64,7 +69,7 @@ instance {hK : 0 < K} {Q : Measure 𝓔} [IsProbabilityMeasure Q] {ΞΊ : Kernel ( `n` is sampled according to these probabilities. -/ noncomputable def tsAlgorithm (hK : 0 < K) (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— Fin K) ℝ) - [IsMarkovKernel ΞΊ] : Algorithm (Fin K) ℝ where + [IsMarkovKernel ΞΊ] : Algorithm Unit (Fin K) ℝ where policy := TS.policy hK Q ΞΊ end Algorithm @@ -79,36 +84,39 @@ variable {P : Measure Ξ©} [IsProbabilityMeasure P] /-- The first action of Thompson sampling is sampled according to its probability of being optimal under the prior over environments. -/ lemma TS.p0_tsAlgorithm (hK : 0 < K) : - (tsAlgorithm hK Q ΞΊ).p0 = Q.map (bestAction ΞΊ id) := by - rw [Algorithm.p0_def] - change TS.policy hK Q ΞΊ 0 default = _ - rw [TS.policy, Kernel.map_apply _ (by fun_prop), IT.bayesTrajMeasurePosterior_zero, - Kernel.const_apply] + (tsAlgorithm hK Q ΞΊ).p0 () = Q.map (bestAction ΞΊ id) := by + rw [Algorithm.p0_apply] + change TS.policy hK Q ΞΊ 0 (default, ()) = _ + rw [TS.policy, Kernel.prodMkRight_apply, Kernel.map_apply _ (by fun_prop), + IT.bayesTrajMeasurePosterior_zero, Kernel.const_apply] /-- If Thompson sampling has the correct prior over environments, then the conditional distribution of the next action given the history so far is equal to the conditional distribution of the best action given the history so far. -/ lemma TS.hasCondDistrib_action (hK : 0 < K) (h : IsBayesAlgEnvSeq Q ΞΊ (tsAlgorithm hK Q ΞΊ) E A R P) (n : β„•) : - HasCondDistrib (A n) (history A R n) - (condDistrib (bestAction ΞΊ E) (history A R n) P) P where - aemeasurable := ((measurable_history h.measurable_action h.measurable_feedback n).prodMk - (h.measurable_action n)).aemeasurable + HasCondDistrib (A n) (history (noObs Ξ©) A R n) + (condDistrib (bestAction ΞΊ E) (history (noObs Ξ©) A R n) P) P where + aemeasurable := ((measurable_history (fun _ ↦ measurable_const) h.measurable_action + h.measurable_feedback n).prodMk (h.measurable_action n)).aemeasurable map_eq := by have hm : Measurable (bestAction ΞΊ id) := by fun_prop - rw [(h.hasCondDistrib_action' n).map_eq] + have h' : HasCondDistrib (A n) (history (noObs Ξ©) A R n) + (((tsAlgorithm hK Q ΞΊ).policy n).sectL ()) P := + hasCondDistrib_prodMk_right_unique_iff.mp (h.hasCondDistrib_action' n) + rw [h'.map_eq] refine Measure.compProd_congr ?_ calc - _ =ᡐ[P.map (history A R n)] + _ =ᡐ[P.map (history (noObs Ξ©) A R n)] (IT.bayesTrajMeasurePosterior Q ΞΊ uniformAlgorithm n).map (bestAction ΞΊ id) := by rfl - _ =ᡐ[P.map (history A R n)] - (condDistrib E (history A R n) P).map (bestAction ΞΊ id) := by + _ =ᡐ[P.map (history (noObs Ξ©) A R n)] + (condDistrib E (history (noObs Ξ©) A R n) P).map (bestAction ΞΊ id) := by filter_upwards [(h.hasCondDistrib_env_history (IT.isBayesAlgEnvSeq_bayesTrajMeasure Q ΞΊ uniformAlgorithm) absolutelyContinuous_uniformAlgorithm n).condDistrib_eq] with _ hc simp_rw [Kernel.map_apply _ hm, IT.bayesTrajMeasurePosterior, hc] - _ =ᡐ[P.map (history A R n)] - condDistrib (bestAction ΞΊ E) (history A R n) P := - (condDistrib_comp (history A R n) h.measurable_param.aemeasurable hm).symm + _ =ᡐ[P.map (history (noObs Ξ©) A R n)] + condDistrib (bestAction ΞΊ E) (history (noObs Ξ©) A R n) P := + (condDistrib_comp (history (noObs Ξ©) A R n) h.measurable_param.aemeasurable hm).symm end Bandits diff --git a/LeanMachineLearning/Online/Bandit/Algorithms/UCB.lean b/LeanMachineLearning/Online/Bandit/Algorithms/UCB.lean index 94ada521..2fd9cde1 100644 --- a/LeanMachineLearning/Online/Bandit/Algorithms/UCB.lean +++ b/LeanMachineLearning/Online/Bandit/Algorithms/UCB.lean @@ -28,13 +28,13 @@ section Algorithm /-- The exploration bonus of the UCB algorithm, which corresponds to the width of a confidence interval. -/ -noncomputable def ucbWidth' (c : ℝ) (n : β„•) (h : Fin n β†’ Fin K Γ— ℝ) (a : Fin K) : ℝ := +noncomputable def ucbWidth' (c : ℝ) (n : β„•) (h : Hist Unit (Fin K) ℝ n) (a : Fin K) : ℝ := √(2 * c * log (n + 1) / pullCount' n h a) open Classical in /-- Arm pulled by the UCB algorithm at time `n`, as a function of the history before `n`. -/ noncomputable -def UCB.nextArm (hK : 0 < K) (c : ℝ) (n : β„•) (h : Fin n β†’ Fin K Γ— ℝ) : Fin K := +def UCB.nextArm (hK : 0 < K) (c : ℝ) (n : β„•) (h : Hist Unit (Fin K) ℝ n) : Fin K := have : Nonempty (Fin K) := Fin.pos_iff_nonempty.mp hK if n < K then RoundRobin.nextAction hK n else argmax (fun a ↦ empMean' n h a + ucbWidth' c n h a) @@ -48,8 +48,8 @@ lemma UCB.measurable_nextArm (hK : 0 < K) (c : ℝ) (n : β„•) : Measurable (next /-- The UCB algorithm. -/ noncomputable -def ucbAlgorithm (hK : 0 < K) (c : ℝ) : Algorithm (Fin K) ℝ := - detAlgorithm (UCB.nextArm hK c) (by fun_prop) +def ucbAlgorithm (hK : 0 < K) (c : ℝ) : Algorithm Unit (Fin K) ℝ := + detAlgorithm (fun n p ↦ UCB.nextArm hK c n p.1) (by fun_prop) end Algorithm namespace UCB @@ -57,15 +57,17 @@ namespace UCB variable {hK : 0 < K} {c : ℝ} {Ξ½ : Kernel (Fin K) ℝ} [IsMarkovKernel Ξ½] {Ξ© : Type*} {mΞ© : MeasurableSpace Ξ©} {P : Measure Ξ©} [IsProbabilityMeasure P] - {A : β„• β†’ Ξ© β†’ Fin K} {R : β„• β†’ Ξ© β†’ ℝ} + {O : β„• β†’ Ξ© β†’ Unit} {A : β„• β†’ Ξ© β†’ Fin K} {R : β„• β†’ Ξ© β†’ ℝ} {Οƒ2 : ℝβ‰₯0} {n : β„•} {Ο‰ : Ξ©} /-- Before round `K`, the UCB algorithm behaves like the Round-Robin algorithm. -/ lemma isAlgEnvSeqUntil_roundRobinAlgorithm - (h : IsAlgEnvSeq A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) : - IsAlgEnvSeqUntil A R (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P K where + (h : IsAlgEnvSeq O A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) : + IsAlgEnvSeqUntil O A R (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P K where + measurable_obs := h.measurable_obs measurable_action := h.measurable_action measurable_feedback := h.measurable_feedback + hasCondDistrib_obs n _ := h.hasCondDistrib_obs n hasCondDistrib_action n hn := by convert h.hasCondDistrib_action n using 1 simp only [roundRobinAlgorithm, detAlgorithm_policy, ucbAlgorithm] @@ -87,36 +89,35 @@ lemma measurable_ucbWidth (hA : βˆ€ n, Measurable (A n)) (c : ℝ) (a : Fin K) : fun_prop lemma ucbWidth_eq_ucbWidth' (c : ℝ) (a : Fin K) (n : β„•) (Ο‰ : Ξ©) : - ucbWidth A c a n Ο‰ = ucbWidth' c n (history A R n Ο‰) a := by - rw [ucbWidth, ucbWidth', pullCount_eq_pullCount' (A := A) (R' := R)] - rfl + ucbWidth A c a n Ο‰ = ucbWidth' c n (history O A R n Ο‰) a := by + rw [ucbWidth, ucbWidth', pullCount_eq_pullCount' (O := O) (A := A) (R' := R)] -lemma arm_zero (h : IsAlgEnvSeq A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) : +lemma arm_zero (h : IsAlgEnvSeq O A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) : A 0 =ᡐ[P] fun _ ↦ ⟨0, hK⟩ := RoundRobin.action_zero ((isAlgEnvSeqUntil_roundRobinAlgorithm h).mono hK) -lemma arm_ae_eq_ucbNextArm (h : IsAlgEnvSeq A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) (n : β„•) : - A n =ᡐ[P] fun Ο‰ ↦ nextArm hK c n (history A R n Ο‰) := by +lemma arm_ae_eq_ucbNextArm (h : IsAlgEnvSeq O A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) (n : β„•) : + A n =ᡐ[P] fun Ο‰ ↦ nextArm hK c n (history O A R n Ο‰) := by have : Nonempty (Fin K) := Fin.pos_iff_nonempty.mp hK exact h.action_detAlgorithm_ae_eq n -lemma arm_ae_all_eq (h : IsAlgEnvSeq A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) : - βˆ€α΅ h βˆ‚P, βˆ€ n, A n h = nextArm hK c n (history A R n h) := +lemma arm_ae_all_eq (h : IsAlgEnvSeq O A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) : + βˆ€α΅ h βˆ‚P, βˆ€ n, A n h = nextArm hK c n (history O A R n h) := ae_all_iff.mpr (arm_ae_eq_ucbNextArm h) lemma ucbIndex_le_ucbIndex_arm - (h : IsAlgEnvSeq A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) (a : Fin K) (hn : K ≀ n) : + (h : IsAlgEnvSeq O A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) (a : Fin K) (hn : K ≀ n) : βˆ€α΅ h βˆ‚P, empMean A R a n h + ucbWidth A c a n h ≀ empMean A R (A n h) n h + ucbWidth A c (A n h) n h := by filter_upwards [arm_ae_eq_ucbNextArm h n] with h h_arm have h_not_lt : Β¬ n < K := by grind simp only [nextArm, h_not_lt, ↓reduceIte] at h_arm have : Nonempty (Fin K) := Fin.pos_iff_nonempty.mp hK - simp_rw [h_arm, empMean_eq_empMean', ucbWidth_eq_ucbWidth' (A := A) (R := R)] - exact isMaxOn_argmax (fun a ↦ empMean' n (history A R n h) a - + ucbWidth' c n (history A R n h) a) _ + simp_rw [h_arm, empMean_eq_empMean' (O := O), ucbWidth_eq_ucbWidth' (O := O) (A := A) (R := R)] + exact isMaxOn_argmax (fun a ↦ empMean' n (history O A R n h) a + + ucbWidth' c n (history O A R n h) a) _ -lemma forall_arm_eq_mod_of_lt (h : IsAlgEnvSeq A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) : +lemma forall_arm_eq_mod_of_lt (h : IsAlgEnvSeq O A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) : βˆ€α΅ h βˆ‚P, βˆ€ n < K, A n h = ⟨n % K, Nat.mod_lt _ hK⟩ := by simp_rw [ae_all_iff] intro n hn @@ -125,7 +126,7 @@ lemma forall_arm_eq_mod_of_lt (h : IsAlgEnvSeq A R (ucbAlgorithm hK c) (stationa simp only [nextArm, hn, ↓reduceIte, RoundRobin.nextAction] lemma forall_ucbIndex_le_ucbIndex_arm - (h : IsAlgEnvSeq A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) (a : Fin K) : + (h : IsAlgEnvSeq O A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) (a : Fin K) : βˆ€α΅ h βˆ‚P, βˆ€ n, K ≀ n β†’ empMean A R a n h + ucbWidth A c a n h ≀ empMean A R (A n h) n h + ucbWidth A c (A n h) n h := by @@ -133,7 +134,7 @@ lemma forall_ucbIndex_le_ucbIndex_arm exact fun _ ↦ ucbIndex_le_ucbIndex_arm h a lemma forall_arm_prop - (h : IsAlgEnvSeq A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) : + (h : IsAlgEnvSeq O A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) : βˆ€α΅ h βˆ‚P, (βˆ€ n < K, A n h = ⟨n % K, Nat.mod_lt _ hK⟩) ∧ (βˆ€ n, K ≀ n β†’ βˆ€ a, empMean A R a n h + ucbWidth A c a n h ≀ @@ -148,12 +149,12 @@ lemma forall_arm_prop exact h_ae n hn lemma time_gt_of_pullCount_gt_one - (h : IsAlgEnvSeq A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) (a : Fin K) : + (h : IsAlgEnvSeq O A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) (a : Fin K) : βˆ€α΅ Ο‰ βˆ‚P, βˆ€ n, 1 < pullCount A a n Ο‰ β†’ K < n := RoundRobin.time_gt_of_pullCount_gt_one (isAlgEnvSeqUntil_roundRobinAlgorithm h) a lemma pullCount_pos_of_pullCount_gt_one - (h : IsAlgEnvSeq A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) (a : Fin K) : + (h : IsAlgEnvSeq O A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) (a : Fin K) : βˆ€α΅ Ο‰ βˆ‚P, βˆ€ n, 1 < pullCount A a n Ο‰ β†’ βˆ€ b : Fin K, 0 < pullCount A b n Ο‰ := RoundRobin.pullCount_pos_of_pullCount_gt_one (isAlgEnvSeqUntil_roundRobinAlgorithm h) a @@ -196,8 +197,8 @@ lemma pullCount_arm_le [Nonempty (Fin K)] (hc : 0 ≀ c) positivity -- todo: this is not about UCB but about any algorithm with subgaussian rewards. Move it? -lemma prob_ucbIndex_le [Nonempty (Fin K)] {alg : Algorithm (Fin K) ℝ} - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) +lemma prob_ucbIndex_le [Nonempty (Fin K)] {alg : Algorithm Unit (Fin K) ℝ} + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (hΞ½ : βˆ€ a, HasSubgaussianMGF (fun x ↦ x - (Ξ½ a)[id]) Οƒ2 (Ξ½ a)) (hΟƒ2 : Οƒ2 β‰  0) (hc : 0 ≀ c) (a : Fin K) (n : β„•) : P {h | 0 < pullCount A a n h ∧ empMean A R a n h + ucbWidth A (c * Οƒ2) a n h ≀ (Ξ½ a)[id]} ≀ @@ -239,8 +240,8 @@ lemma prob_ucbIndex_le [Nonempty (Fin K)] {alg : Algorithm (Fin K) ℝ} ENNReal.div_eq_inv_mul, ENNReal.mul_inv (by simp) (by simp), inv_inv] -- todo: this is not about UCB but about any algorithm with subgaussian rewards. Move it? -lemma prob_ucbIndex_ge [Nonempty (Fin K)] {alg : Algorithm (Fin K) ℝ} - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) +lemma prob_ucbIndex_ge [Nonempty (Fin K)] {alg : Algorithm Unit (Fin K) ℝ} + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (hΞ½ : βˆ€ a, HasSubgaussianMGF (fun x ↦ x - (Ξ½ a)[id]) Οƒ2 (Ξ½ a)) (hΟƒ2 : Οƒ2 β‰  0) (hc : 0 ≀ c) (a : Fin K) (n : β„•) : P {h | 0 < pullCount A a n h ∧ @@ -281,8 +282,8 @@ lemma prob_ucbIndex_ge [Nonempty (Fin K)] {alg : Algorithm (Fin K) ℝ} rw [ENNReal.rpow_sub _ _ (by simp) (by finiteness), ENNReal.rpow_one, div_eq_mul_inv, ENNReal.div_eq_inv_mul, ENNReal.mul_inv (by simp) (by simp), inv_inv] -lemma probReal_ucbIndex_le [Nonempty (Fin K)] {alg : Algorithm (Fin K) ℝ} - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) +lemma probReal_ucbIndex_le [Nonempty (Fin K)] {alg : Algorithm Unit (Fin K) ℝ} + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (hΞ½ : βˆ€ a, HasSubgaussianMGF (fun x ↦ x - (Ξ½ a)[id]) Οƒ2 (Ξ½ a)) (hΟƒ2 : Οƒ2 β‰  0) (hc : 0 ≀ c) (a : Fin K) (n : β„•) : P.real {h | 0 < pullCount A a n h ∧ empMean A R a n h + ucbWidth A (c * Οƒ2) a n h ≀ (Ξ½ a)[id]} ≀ @@ -294,8 +295,8 @@ lemma probReal_ucbIndex_le [Nonempty (Fin K)] {alg : Algorithm (Fin K) ℝ} rw [← ENNReal.toReal_rpow] norm_cast -lemma probReal_ucbIndex_ge [Nonempty (Fin K)] {alg : Algorithm (Fin K) ℝ} - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) +lemma probReal_ucbIndex_ge [Nonempty (Fin K)] {alg : Algorithm Unit (Fin K) ℝ} + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (hΞ½ : βˆ€ a, HasSubgaussianMGF (fun x ↦ x - (Ξ½ a)[id]) Οƒ2 (Ξ½ a)) (hΟƒ2 : Οƒ2 β‰  0) (hc : 0 ≀ c) (a : Fin K) (n : β„•) : P.real {h | 0 < pullCount A a n h ∧ @@ -351,7 +352,7 @@ lemma pullCount_le_add_three [Nonempty (Fin K)] (a : Fin K) (n C : β„•) (Ο‰ : Ξ© rw [Finset.sum_add_distrib, Finset.sum_add_distrib] lemma pullCount_le_add_three_ae [Nonempty (Fin K)] - (h : IsAlgEnvSeq A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) + (h : IsAlgEnvSeq O A R (ucbAlgorithm hK c) (stationaryEnv Ξ½) P) (a : Fin K) (n C : β„•) (hC : C β‰  0) : βˆ€α΅ Ο‰ βˆ‚P, pullCount A a n Ο‰ ≀ C + 1 + @@ -373,7 +374,7 @@ lemma pullCount_le_add_three_ae [Nonempty (Fin K)] Β· exact fun h_gt ↦ hΟ‰ _ (lt_of_le_of_lt (by grind) h_gt) _ lemma some_sum_eq_zero [Nonempty (Fin K)] - (h : IsAlgEnvSeq A R (ucbAlgorithm hK (c * Οƒ2)) (stationaryEnv Ξ½) P) + (h : IsAlgEnvSeq O A R (ucbAlgorithm hK (c * Οƒ2)) (stationaryEnv Ξ½) P) (hc : 0 ≀ c) (a : Fin K) (h_gap : 0 < gap Ξ½ a) (n C : β„•) (hC : C β‰  0) (hC' : 8 * c * Οƒ2 * log (n + 1) / gap Ξ½ a ^ 2 ≀ C) : βˆ€α΅ Ο‰ βˆ‚P, @@ -406,7 +407,7 @@ lemma some_sum_eq_zero [Nonempty (Fin K)] gcongr lemma pullCount_ae_le_add_two [Nonempty (Fin K)] - (h : IsAlgEnvSeq A R (ucbAlgorithm hK (c * Οƒ2)) (stationaryEnv Ξ½) P) + (h : IsAlgEnvSeq O A R (ucbAlgorithm hK (c * Οƒ2)) (stationaryEnv Ξ½) P) (hc : 0 ≀ c) (a : Fin K) (h_gap : 0 < gap Ξ½ a) (n C : β„•) (hC : C β‰  0) (hC' : 8 * c * Οƒ2 * log (n + 1) / gap Ξ½ a ^ 2 ≀ C) : βˆ€α΅ Ο‰ βˆ‚P, @@ -435,7 +436,7 @@ lemma constSum_lt_top (c : ℝ) (n : β„•) : constSum c n < ∞ := by /-- Bound on the expectation of the number of pulls of each arm by the UCB algorithm. -/ lemma expectation_pullCount_le' - (h : IsAlgEnvSeq A R (ucbAlgorithm hK (c * Οƒ2)) (stationaryEnv Ξ½) P) + (h : IsAlgEnvSeq O A R (ucbAlgorithm hK (c * Οƒ2)) (stationaryEnv Ξ½) P) (hΞ½ : βˆ€ a, HasSubgaussianMGF (fun x ↦ x - (Ξ½ a)[id]) Οƒ2 (Ξ½ a)) (hΟƒ2 : Οƒ2 β‰  0) (hc : 0 < c) (a : Fin K) (h_gap : 0 < gap Ξ½ a) (n : β„•) : ∫⁻ Ο‰, pullCount A a n Ο‰ βˆ‚P ≀ @@ -524,7 +525,7 @@ lemma expectation_pullCount_le' /-- Bound on the expectation of the number of pulls of each arm by the UCB algorithm. -/ lemma expectation_pullCount_le - (h : IsAlgEnvSeq A R (ucbAlgorithm hK (c * Οƒ2)) (stationaryEnv Ξ½) P) + (h : IsAlgEnvSeq O A R (ucbAlgorithm hK (c * Οƒ2)) (stationaryEnv Ξ½) P) (hΞ½ : βˆ€ a, HasSubgaussianMGF (fun x ↦ x - (Ξ½ a)[id]) Οƒ2 (Ξ½ a)) (hΟƒ2 : Οƒ2 β‰  0) (hc : 0 < c) (a : Fin K) (h_gap : 0 < gap Ξ½ a) (n : β„•) : P[fun Ο‰ ↦ (pullCount A a n Ο‰ : ℝ)] ≀ @@ -554,7 +555,7 @@ lemma expectation_pullCount_le ring /-- Regret bound for the UCB algorithm. -/ -theorem regret_le (h : IsAlgEnvSeq A R (ucbAlgorithm hK (c * Οƒ2)) (stationaryEnv Ξ½) P) +theorem regret_le (h : IsAlgEnvSeq O A R (ucbAlgorithm hK (c * Οƒ2)) (stationaryEnv Ξ½) P) (hΞ½ : βˆ€ a, HasSubgaussianMGF (fun x ↦ x - (Ξ½ a)[id]) Οƒ2 (Ξ½ a)) (hΟƒ2 : Οƒ2 β‰  0) (hc : 0 < c) (n : β„•) : P[regret Ξ½ A n] ≀ diff --git a/LeanMachineLearning/Online/Bandit/ArrayProbSpace.lean b/LeanMachineLearning/Online/Bandit/ArrayProbSpace.lean index b6aeef7b..24d2247d 100644 --- a/LeanMachineLearning/Online/Bandit/ArrayProbSpace.lean +++ b/LeanMachineLearning/Online/Bandit/ArrayProbSpace.lean @@ -149,23 +149,23 @@ variable [Nonempty 𝓐] [StandardBorelSpace 𝓐] /-- The next action is the image of the history and a uniform random variable by this function. -/ noncomputable -def algFunction (alg : Algorithm 𝓐 R) (n : β„•) : - (Fin n β†’ 𝓐 Γ— R) β†’ I β†’ 𝓐 := - (Kernel.exists_measurable_map_eq_unitInterval (alg.policy n)).choose +def algFunction (alg : Algorithm Unit 𝓐 R) (n : β„•) : + Hist Unit 𝓐 R n β†’ I β†’ 𝓐 := + (Kernel.exists_measurable_map_eq_unitInterval ((alg.policy n).sectL ())).choose -lemma algFunction_map (alg : Algorithm 𝓐 R) (n : β„•) (h : Fin n β†’ 𝓐 Γ— R) : - volume.map (algFunction alg n h) = alg.policy n h := - (Kernel.exists_measurable_map_eq_unitInterval (alg.policy n)).choose_spec.2 h +lemma algFunction_map (alg : Algorithm Unit 𝓐 R) (n : β„•) (h : Hist Unit 𝓐 R n) : + volume.map (algFunction alg n h) = alg.policy n (h, ()) := + (Kernel.exists_measurable_map_eq_unitInterval ((alg.policy n).sectL ())).choose_spec.2 h /-- The initial action is the image of a uniform random variable by `algFunction alg 0 default`. -/ -lemma algFunction_zero_map (alg : Algorithm 𝓐 R) : - volume.map (algFunction alg 0 default) = alg.p0 := +lemma algFunction_zero_map (alg : Algorithm Unit 𝓐 R) : + volume.map (algFunction alg 0 default) = alg.p0 () := algFunction_map alg 0 default @[fun_prop] -lemma measurable_algFunction (alg : Algorithm 𝓐 R) (n : β„•) : +lemma measurable_algFunction (alg : Algorithm Unit 𝓐 R) (n : β„•) : Measurable (Function.uncurry (algFunction alg n)) := - (Kernel.exists_measurable_map_eq_unitInterval (alg.policy n)).choose_spec.1 + (Kernel.exists_measurable_map_eq_unitInterval ((alg.policy n).sectL ())).choose_spec.1 end ProbabilitySpace @@ -175,28 +175,29 @@ section HistoryActionReward /-- History of actions and rewards before time `n` in the array model. -/ noncomputable -def hist [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) (Ο‰ : probSpace 𝓐 R) : (n : β„•) β†’ Fin n β†’ 𝓐 Γ— R +def hist [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 R) (Ο‰ : probSpace 𝓐 R) : + (n : β„•) β†’ Hist Unit 𝓐 R n | 0 => default | n + 1 => - let hn : Fin n β†’ 𝓐 Γ— R := hist alg Ο‰ n + let hn : Hist Unit 𝓐 R n := hist alg Ο‰ n let a : 𝓐 := algFunction alg n hn (Ο‰.1 n) - Fin.snoc hn (a, Ο‰.2 (pullCount' n hn a) a) + Fin.snoc hn ((), a, Ο‰.2 (pullCount' n hn a) a) @[simp] -lemma hist_zero [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) (Ο‰ : probSpace 𝓐 R) : +lemma hist_zero [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 R) (Ο‰ : probSpace 𝓐 R) : hist alg Ο‰ 0 = default := rfl -lemma hist_add_one [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) (Ο‰ : probSpace 𝓐 R) (n : β„•) : +lemma hist_add_one [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 R) (Ο‰ : probSpace 𝓐 R) (n : β„•) : hist alg Ο‰ (n + 1) = - Fin.snoc (hist alg Ο‰ n) (algFunction alg n (hist alg Ο‰ n) (Ο‰.1 n), + Fin.snoc (hist alg Ο‰ n) ((), algFunction alg n (hist alg Ο‰ n) (Ο‰.1 n), Ο‰.2 (pullCount' n (hist alg Ο‰ n) (algFunction alg n (hist alg Ο‰ n) (Ο‰.1 n))) (algFunction alg n (hist alg Ο‰ n) (Ο‰.1 n))) := rfl -lemma hist_add_one_eq_finSuccProd' [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) (Ο‰ : probSpace 𝓐 R) +lemma hist_add_one_eq_finSuccProd' [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 R) (Ο‰ : probSpace 𝓐 R) (n : β„•) : hist alg Ο‰ (n + 1) = - (MeasurableEquiv.finSuccProd (𝓐 Γ— R) n).symm - (hist alg Ο‰ n, (algFunction alg n (hist alg Ο‰ n) (Ο‰.1 n), + (MeasurableEquiv.finSuccProd (Round Unit 𝓐 R) n).symm + (hist alg Ο‰ n, ((), algFunction alg n (hist alg Ο‰ n) (Ο‰.1 n), Ο‰.2 (pullCount' n (hist alg Ο‰ n) (algFunction alg n (hist alg Ο‰ n) (Ο‰.1 n))) (algFunction alg n (hist alg Ο‰ n) (Ο‰.1 n)))) := by rw [MeasurableEquiv.finSuccProd_symm_apply] @@ -204,44 +205,44 @@ lemma hist_add_one_eq_finSuccProd' [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) ( /-- Action taken at time `n` in the array model. -/ noncomputable -def action [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) (n : β„•) (Ο‰ : probSpace 𝓐 R) : 𝓐 := +def action [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 R) (n : β„•) (Ο‰ : probSpace 𝓐 R) : 𝓐 := algFunction alg n (hist alg Ο‰ n) (Ο‰.1 n) -lemma action_eq [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) (n : β„•) : +lemma action_eq [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 R) (n : β„•) : action alg n = fun Ο‰ ↦ algFunction alg n (hist alg Ο‰ n) (Ο‰.1 n) := rfl -lemma action_zero [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) : +lemma action_zero [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 R) : action alg 0 = fun Ο‰ ↦ algFunction alg 0 default (Ο‰.1 0) := rfl /-- Reward received at time `n` in the array model. -/ noncomputable -def reward [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) (n : β„•) (Ο‰ : probSpace 𝓐 R) : R := - (hist alg Ο‰ (n + 1) (Fin.last n)).2 +def reward [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 R) (n : β„•) (Ο‰ : probSpace 𝓐 R) : R := + (hist alg Ο‰ (n + 1) (Fin.last n)).feedback -lemma reward_eq' [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) (n : β„•) (Ο‰ : probSpace 𝓐 R) : +lemma reward_eq' [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 R) (n : β„•) (Ο‰ : probSpace 𝓐 R) : reward alg n Ο‰ = Ο‰.2 (pullCount' n (hist alg Ο‰ n) (action alg n Ο‰)) (action alg n Ο‰) := by - change (hist alg Ο‰ (n + 1) (Fin.last n)).2 = _ + change (hist alg Ο‰ (n + 1) (Fin.last n)).feedback = _ rw [hist_add_one, Fin.snoc_last] rfl -lemma hist_succ [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) (Ο‰ : probSpace 𝓐 R) (n : β„•) : - hist alg Ο‰ (n + 1) = Fin.snoc (hist alg Ο‰ n) (action alg n Ο‰, reward alg n Ο‰) := by +lemma hist_succ [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 R) (Ο‰ : probSpace 𝓐 R) (n : β„•) : + hist alg Ο‰ (n + 1) = Fin.snoc (hist alg Ο‰ n) ((), action alg n Ο‰, reward alg n Ο‰) := by rw [hist_add_one, reward_eq'] rfl -lemma hist_succ_eq_finSuccProd [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) (Ο‰ : probSpace 𝓐 R) +lemma hist_succ_eq_finSuccProd [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 R) (Ο‰ : probSpace 𝓐 R) (n : β„•) : hist alg Ο‰ (n + 1) = - (MeasurableEquiv.finSuccProd (𝓐 Γ— R) n).symm - (hist alg Ο‰ n, (action alg n Ο‰, reward alg n Ο‰)) := by + (MeasurableEquiv.finSuccProd (Round Unit 𝓐 R) n).symm + (hist alg Ο‰ n, ((), action alg n Ο‰, reward alg n Ο‰)) := by rw [MeasurableEquiv.finSuccProd_symm_apply, hist_succ] -lemma hist_apply_last [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) (Ο‰ : probSpace 𝓐 R) (n : β„•) : - hist alg Ο‰ (n + 1) (Fin.last n) = (action alg n Ο‰, reward alg n Ο‰) := by +lemma hist_apply_last [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 R) (Ο‰ : probSpace 𝓐 R) (n : β„•) : + hist alg Ο‰ (n + 1) (Fin.last n) = ((), action alg n Ο‰, reward alg n Ο‰) := by rw [hist_succ, Fin.snoc_last] -lemma hist_eq [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) (Ο‰ : probSpace 𝓐 R) (n : β„•) : - hist alg Ο‰ n = fun i : Fin n ↦ (action alg i Ο‰, reward alg i Ο‰) := by +lemma hist_eq [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 R) (Ο‰ : probSpace 𝓐 R) (n : β„•) : + hist alg Ο‰ n = fun i : Fin n ↦ ((), action alg i Ο‰, reward alg i Ο‰) := by induction n with | zero => exact Subsingleton.elim _ _ | succ n hn => @@ -253,25 +254,26 @@ lemma hist_eq [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) (Ο‰ : probSpace 𝓐 R simp /-- The history in the array model is the history of the action and reward processes. -/ -lemma hist_eq_history [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) (Ο‰ : probSpace 𝓐 R) (n : β„•) : - hist alg Ο‰ n = history (action alg) (reward alg) n Ο‰ := hist_eq alg Ο‰ n +lemma hist_eq_history [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 R) (Ο‰ : probSpace 𝓐 R) (n : β„•) : + hist alg Ο‰ n = history (noObs _) (action alg) (reward alg) n Ο‰ := hist_eq alg Ο‰ n -lemma pullCount_action_eq [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) (a : 𝓐) (n : β„•) +lemma pullCount_action_eq [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 R) (a : 𝓐) (n : β„•) (Ο‰ : probSpace 𝓐 R) : pullCount (action alg) a n Ο‰ = pullCount' n (hist alg Ο‰ n) a := by - rw [pullCount_eq_pullCount' (R' := reward alg), hist_eq] + rw [pullCount_eq_pullCount' (O := noObs _) (R' := reward alg), hist_eq] + rfl -lemma pullCount_action_eq_comp [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) (a : 𝓐) (n : β„•) : +lemma pullCount_action_eq_comp [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 R) (a : 𝓐) (n : β„•) : pullCount (action alg) a n = (fun h ↦ pullCount' n h a) ∘ (hist alg Β· n) := by ext Ο‰ exact pullCount_action_eq alg a n Ο‰ -lemma reward_eq [DecidableEq 𝓐] (alg : Algorithm 𝓐 R) (n : β„•) : +lemma reward_eq [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 R) (n : β„•) : reward alg n = fun Ο‰ ↦ Ο‰.2 (pullCount (action alg) (action alg n Ο‰) n Ο‰) (action alg n Ο‰) := by ext Ο‰ rw [reward_eq', pullCount_action_eq] -lemma sumRewards_eq [DecidableEq 𝓐] (alg : Algorithm 𝓐 ℝ) (a : 𝓐) (n : β„•) (Ο‰ : probSpace 𝓐 ℝ) : +lemma sumRewards_eq [DecidableEq 𝓐] (alg : Algorithm Unit 𝓐 ℝ) (a : 𝓐) (n : β„•) (Ο‰ : probSpace 𝓐 ℝ) : sumRewards (action alg) (reward alg) a n Ο‰ = βˆ‘ i ∈ range (pullCount (action alg) a n Ο‰), Ο‰.2 i a := by induction n with @@ -283,11 +285,11 @@ lemma sumRewards_eq [DecidableEq 𝓐] (alg : Algorithm 𝓐 ℝ) (a : 𝓐) (n section Measurability -lemma measurable_action' [DecidableEq 𝓐] {alg : Algorithm 𝓐 R} +lemma measurable_action' [DecidableEq 𝓐] {alg : Algorithm Unit 𝓐 R} (n : β„•) (h : Measurable (hist alg Β· n)) : Measurable (fun x ↦ algFunction alg n (hist alg x n) (x.1 n)) := by fun_prop -lemma measurable_pullCount'_action [DecidableEq 𝓐] {alg : Algorithm 𝓐 R} +lemma measurable_pullCount'_action [DecidableEq 𝓐] {alg : Algorithm Unit 𝓐 R} (n : β„•) (h_hist : Measurable (hist alg Β· n)) : Measurable (fun x ↦ pullCount' n (hist alg x n) (algFunction alg n (hist alg x n) (x.1 n))) := by @@ -296,7 +298,7 @@ lemma measurable_pullCount'_action [DecidableEq 𝓐] {alg : Algorithm 𝓐 R} exact (measurable_uncurry_pullCount' (𝓐 := 𝓐) n).comp (h_hist.prodMk h_alg_meas) @[fun_prop] -lemma measurable_hist [DecidableEq 𝓐] [Countable 𝓐] (alg : Algorithm 𝓐 R) (n : β„•) : +lemma measurable_hist [DecidableEq 𝓐] [Countable 𝓐] (alg : Algorithm Unit 𝓐 R) (n : β„•) : Measurable (fun Ο‰ ↦ hist alg Ο‰ n) := by induction n with | zero => @@ -304,15 +306,15 @@ lemma measurable_hist [DecidableEq 𝓐] [Countable 𝓐] (alg : Algorithm 𝓐 exact measurable_const | succ n hn => have h_eq : (fun Ο‰ ↦ hist alg Ο‰ (n + 1)) = - (MeasurableEquiv.finSuccProd (𝓐 Γ— R) n).symm ∘ - (fun Ο‰ ↦ (hist alg Ο‰ n, (algFunction alg n (hist alg Ο‰ n) (Ο‰.1 n), + (MeasurableEquiv.finSuccProd (Round Unit 𝓐 R) n).symm ∘ + (fun Ο‰ ↦ (hist alg Ο‰ n, ((), algFunction alg n (hist alg Ο‰ n) (Ο‰.1 n), Ο‰.2 (pullCount' n (hist alg Ο‰ n) (algFunction alg n (hist alg Ο‰ n) (Ο‰.1 n))) (algFunction alg n (hist alg Ο‰ n) (Ο‰.1 n))))) := by ext Ο‰ : 1 exact hist_add_one_eq_finSuccProd' alg Ο‰ n rw [h_eq] refine (MeasurableEquiv.measurable _).comp (hn.prodMk ?_) - refine Measurable.prodMk (measurable_action' n hn) ?_ + refine Measurable.prodMk measurable_const (Measurable.prodMk (measurable_action' n hn) ?_) change Measurable ((fun (x : (β„• β†’ 𝓐 β†’ R) Γ— β„• Γ— 𝓐) ↦ x.1 x.2.1 x.2.2) ∘ (fun x ↦ (x.2, pullCount' n (hist alg x n) (algFunction alg n (hist alg x n) (x.1 n)), (algFunction alg n (hist alg x n) (x.1 n))))) @@ -322,15 +324,15 @@ lemma measurable_hist [DecidableEq 𝓐] [Countable 𝓐] (alg : Algorithm 𝓐 exact (measurable_pullCount'_action n hn).prodMk (measurable_action' n hn) @[fun_prop] -lemma measurable_action [DecidableEq 𝓐] [Countable 𝓐] (alg : Algorithm 𝓐 R) (n : β„•) : +lemma measurable_action [DecidableEq 𝓐] [Countable 𝓐] (alg : Algorithm Unit 𝓐 R) (n : β„•) : Measurable (action alg n) := by unfold action; fun_prop @[fun_prop] -lemma measurable_reward [DecidableEq 𝓐] [Countable 𝓐] (alg : Algorithm 𝓐 R) (n : β„•) : +lemma measurable_reward [DecidableEq 𝓐] [Countable 𝓐] (alg : Algorithm Unit 𝓐 R) (n : β„•) : Measurable (reward alg n) := by unfold reward; fun_prop @[fun_prop] -lemma measurable_pullCount_action [DecidableEq 𝓐] [Countable 𝓐] (alg : Algorithm 𝓐 R) +lemma measurable_pullCount_action [DecidableEq 𝓐] [Countable 𝓐] (alg : Algorithm Unit 𝓐 R) (n : β„•) : Measurable (fun Ο‰ ↦ pullCount (action alg) (action alg n Ο‰) n Ο‰) := by change Measurable ((fun p : (probSpace 𝓐 R) Γ— 𝓐 ↦ pullCount (action alg) p.2 n p.1) ∘ @@ -346,7 +348,7 @@ variable [DecidableEq 𝓐] section Congruence -- very useful to prove measurability -lemma hist_congr (alg : Algorithm 𝓐 R) (n : β„•) {Ο‰ Ο‰' : probSpace 𝓐 R} +lemma hist_congr (alg : Algorithm Unit 𝓐 R) (n : β„•) {Ο‰ Ο‰' : probSpace 𝓐 R} (hΟ‰1 : βˆ€ i < n, Ο‰.1 i = Ο‰'.1 i) (hΟ‰2 : βˆ€ i a, i < pullCount (action alg) a n Ο‰ β†’ Ο‰.2 i a = Ο‰'.2 i a) : hist alg Ο‰ n = hist alg Ο‰' n := by @@ -365,7 +367,7 @@ lemma hist_congr (alg : Algorithm 𝓐 R) (n : β„•) {Ο‰ Ο‰' : probSpace 𝓐 R} exact Nat.lt_succ_self _ rw [hist_succ, hist_succ, h_hist, h_action, h_reward] -lemma stepsUntil_congr_aux (alg : Algorithm 𝓐 R) +lemma stepsUntil_congr_aux (alg : Algorithm Unit 𝓐 R) (a : 𝓐) (m n : β„•) {Ο‰ Ο‰' : probSpace 𝓐 R} (hΟ‰1 : βˆ€ i, Ο‰.1 i = Ο‰'.1 i) (hΟ‰2_ne : βˆ€ i b, b β‰  a β†’ Ο‰.2 i b = Ο‰'.2 i b) (hΟ‰2_eq : βˆ€ i, i + 1 ≀ m β†’ Ο‰.2 i a = Ο‰'.2 i a) @@ -383,7 +385,7 @@ lemma stepsUntil_congr_aux (alg : Algorithm 𝓐 R) simp only [action, h_hist, hΟ‰1] Β· rw [← h_pc, pullCount_action_eq, pullCount_action_eq, h_hist] -lemma stepsUntil_congr (alg : Algorithm 𝓐 R) (a : 𝓐) (m n : β„•) {Ο‰ Ο‰' : probSpace 𝓐 R} +lemma stepsUntil_congr (alg : Algorithm Unit 𝓐 R) (a : 𝓐) (m n : β„•) {Ο‰ Ο‰' : probSpace 𝓐 R} (hΟ‰1 : βˆ€ i, Ο‰.1 i = Ο‰'.1 i) (hΟ‰2_ne : βˆ€ i b, b β‰  a β†’ Ο‰.2 i b = Ο‰'.2 i b) (hΟ‰2_eq : βˆ€ i, i + 1 ≀ m β†’ Ο‰.2 i a = Ο‰'.2 i a) : (action alg n Ο‰ = a ∧ pullCount (action alg) a n Ο‰ = m) ↔ @@ -391,7 +393,7 @@ lemma stepsUntil_congr (alg : Algorithm 𝓐 R) (a : 𝓐) (m n : β„•) {Ο‰ Ο‰' : ⟨stepsUntil_congr_aux alg a m n hΟ‰1 hΟ‰2_ne hΟ‰2_eq, stepsUntil_congr_aux alg a m n (by grind) (by grind) (by grind)⟩ -lemma stepsUntil_indicator_congr (alg : Algorithm 𝓐 R) (a : 𝓐) (m n : β„•) {Ο‰ Ο‰' : probSpace 𝓐 R} +lemma stepsUntil_indicator_congr (alg : Algorithm Unit 𝓐 R) (a : 𝓐) (m n : β„•) {Ο‰ Ο‰' : probSpace 𝓐 R} (hΟ‰1 : βˆ€ i, Ο‰.1 i = Ο‰'.1 i) (hΟ‰2_ne : βˆ€ i b, b β‰  a β†’ Ο‰.2 i b = Ο‰'.2 i b) (hΟ‰2_eq : βˆ€ i, i + 1 ≀ m β†’ Ο‰.2 i a = Ο‰'.2 i a) : {Ο‰ | action alg n Ο‰ = a ∧ pullCount (action alg) a n Ο‰ = m}.indicator (fun _ ↦ 1) Ο‰ = @@ -403,7 +405,7 @@ end Congruence section MeasurabilityAdvanced -lemma measurable_hist_comap [Countable 𝓐] (alg : Algorithm 𝓐 R) (n : β„•) : +lemma measurable_hist_comap [Countable 𝓐] (alg : Algorithm Unit 𝓐 R) (n : β„•) : Measurable[MeasurableSpace.comap (fun Ο‰ ↦ (fun (i : Fin n) ↦ Ο‰.1 i, Ο‰.2)) inferInstance] (hist alg Β· n) := by have h_eq : (hist alg Β· n) = @@ -428,13 +430,13 @@ variable [Nonempty R] /-- All random variables in the space, except for the rewards of action `a` that have not been observed before time `n` (those with index at least `pullCount (action alg) a n Ο‰`). -/ noncomputable -def truePast (alg : Algorithm 𝓐 R) (a : 𝓐) (n : β„•) (Ο‰ : probSpace 𝓐 R) : +def truePast (alg : Algorithm Unit 𝓐 R) (a : 𝓐) (n : β„•) (Ο‰ : probSpace 𝓐 R) : probSpace 𝓐 R := (Ο‰.1, fun i b ↦ if b = a then if pullCount (action alg) a n Ο‰ β‰  0 then Ο‰.2 (min i ((pullCount (action alg) a n Ο‰) - 1)) a else Nonempty.some inferInstance else Ο‰.2 i b) -lemma truePast_eq_of_pullCount_eq (alg : Algorithm 𝓐 R) +lemma truePast_eq_of_pullCount_eq (alg : Algorithm Unit 𝓐 R) (a : 𝓐) (n m : β„•) (Ο‰ : probSpace 𝓐 R) (h_pc : pullCount (action alg) a n Ο‰ = m) : truePast alg a n Ο‰ = (Ο‰.1, fun i b ↦ if b = a then if m β‰  0 then @@ -442,7 +444,7 @@ lemma truePast_eq_of_pullCount_eq (alg : Algorithm 𝓐 R) simp [truePast, h_pc] grind -lemma truePast_eq_of_pullCount_eq_of_ne_zero (alg : Algorithm 𝓐 R) +lemma truePast_eq_of_pullCount_eq_of_ne_zero (alg : Algorithm Unit 𝓐 R) (a : 𝓐) (n m : β„•) (Ο‰ : probSpace 𝓐 R) (h_pc : pullCount (action alg) a n Ο‰ = m) (hm : m β‰  0) : truePast alg a n Ο‰ = (Ο‰.1, fun i b ↦ if b = a then @@ -450,7 +452,7 @@ lemma truePast_eq_of_pullCount_eq_of_ne_zero (alg : Algorithm 𝓐 R) simp [truePast, h_pc, hm] grind -lemma measurable_hist_truePast [Countable 𝓐] (alg : Algorithm 𝓐 R) +lemma measurable_hist_truePast [Countable 𝓐] (alg : Algorithm Unit 𝓐 R) (a : 𝓐) (n : β„•) : Measurable[MeasurableSpace.comap (truePast alg a n) inferInstance] (hist alg Β· n) := by have h_eq : (hist alg Β· n) = (hist alg Β· n) ∘ (truePast alg a n) := by @@ -466,7 +468,7 @@ lemma measurable_hist_truePast [Countable 𝓐] (alg : Algorithm 𝓐 R) refine Measurable.comp ?_ (Measurable.of_comap_le le_rfl) fun_prop -lemma measurable_action_truePast [Countable 𝓐] (alg : Algorithm 𝓐 R) +lemma measurable_action_truePast [Countable 𝓐] (alg : Algorithm Unit 𝓐 R) (a : 𝓐) (n : β„•) : Measurable[MeasurableSpace.comap (truePast alg a n) inferInstance] (action alg n) := by change Measurable[MeasurableSpace.comap (truePast alg a n) inferInstance] @@ -477,13 +479,13 @@ lemma measurable_action_truePast [Countable 𝓐] (alg : Algorithm 𝓐 R) rw [this] exact Measurable.comp (by fun_prop) (Measurable.of_comap_le le_rfl) -lemma measurable_pullCount_truePast [Countable 𝓐] (alg : Algorithm 𝓐 R) (a : 𝓐) (n : β„•) : +lemma measurable_pullCount_truePast [Countable 𝓐] (alg : Algorithm Unit 𝓐 R) (a : 𝓐) (n : β„•) : Measurable[MeasurableSpace.comap (truePast alg a n) inferInstance] (pullCount (action alg) a n) := by rw [pullCount_action_eq_comp] exact (measurable_pullCount' n a).comp (measurable_hist_truePast alg a n) -lemma measurable_stepsUntil [Countable 𝓐] (alg : Algorithm 𝓐 R) (a : 𝓐) (m n : β„•) : +lemma measurable_stepsUntil [Countable 𝓐] (alg : Algorithm Unit 𝓐 R) (a : 𝓐) (m n : β„•) : Measurable[MeasurableSpace.comap (fun Ο‰ ↦ (Ο‰.1, fun k b ↦ if b = a then if m β‰  0 then Ο‰.2 (min k (m - 1)) b else Nonempty.some inferInstance else Ο‰.2 k b)) inferInstance] @@ -506,12 +508,12 @@ lemma measurable_stepsUntil [Countable 𝓐] (alg : Algorithm 𝓐 R) (a : 𝓐) ((measurableSet_singleton _).preimage (by fun_prop)) omit [Nonempty R] in -lemma measurable_pullCount_action_hist (alg : Algorithm 𝓐 R) (n : β„•) : +lemma measurable_pullCount_action_hist (alg : Algorithm Unit 𝓐 R) (n : β„•) : Measurable[MeasurableSpace.comap (fun Ο‰ ↦ (action alg n Ο‰, hist alg Ο‰ n)) inferInstance] (fun Ο‰ ↦ pullCount (action alg) (action alg n Ο‰) n Ο‰) := by simp_rw [pullCount_action_eq] change Measurable[MeasurableSpace.comap (fun Ο‰ ↦ (action alg n Ο‰, hist alg Ο‰ n)) inferInstance] - ((fun p : 𝓐 Γ— (Fin n β†’ 𝓐 Γ— R) ↦ pullCount' n p.2 p.1) ∘ + ((fun p : 𝓐 Γ— (Hist Unit 𝓐 R n) ↦ pullCount' n p.2 p.1) ∘ (fun Ο‰ ↦ (action alg n Ο‰, hist alg Ο‰ n))) exact measurable_comp_comap _ ((measurable_uncurry_pullCount' n).comp measurable_swap) @@ -598,7 +600,7 @@ lemma indepFun_fst_aux (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] (n : β„•) : variable [StandardBorelSpace R] [Nonempty R] -lemma indepFun_fst_hist [Countable 𝓐] (alg : Algorithm 𝓐 R) +lemma indepFun_fst_hist [Countable 𝓐] (alg : Algorithm Unit 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] (n : β„•) : IndepFun (fun Ο‰ ↦ Ο‰.1 n) (hist alg Β· n) (arrayMeasure Ξ½) := (indepFun_fst_aux Ξ½ n).of_measurable_right (measurable_hist_comap alg n) @@ -816,7 +818,7 @@ lemma indepFun_snd_apply_aux (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] (a : 𝓐) omit [StandardBorelSpace R] in -lemma indepFun_snd_apply_pullCount_action [Countable 𝓐] (alg : Algorithm 𝓐 R) +lemma indepFun_snd_apply_pullCount_action [Countable 𝓐] (alg : Algorithm Unit 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] (a : 𝓐) (m n : β„•) : (fun Ο‰ ↦ Ο‰.2 m a) βŸ‚α΅’[arrayMeasure Ξ½] ({Ο‰ | action alg n Ο‰ = a ∧ pullCount (action alg) a n Ο‰ = m}).indicator (fun _ ↦ 1) := @@ -831,7 +833,7 @@ lemma indepFun_cond_comp {𝓐 Ξ² Ξ³ Ξ΄ : Type*} {m𝓐 : MeasurableSpace 𝓐} simp_rw [h_preim] exact indepFun_cond_of_indepFun hXY hY (hZ (measurableSet_singleton z)) -lemma indepFun_snd_hist_cond [Countable 𝓐] (alg : Algorithm 𝓐 R) +lemma indepFun_snd_hist_cond [Countable 𝓐] (alg : Algorithm Unit 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] (a : 𝓐) (n m : β„•) : (fun Ο‰ ↦ Ο‰.2 m a) βŸ‚α΅’[(arrayMeasure Ξ½)[|(fun Ο‰ ↦ (action alg n Ο‰, pullCount (action alg) (action alg n Ο‰) n Ο‰)) ⁻¹' {(a, m)}]] @@ -882,10 +884,12 @@ section Laws variable [Countable 𝓐] [StandardBorelSpace R] [Nonempty R] -lemma hasCondDistrib_action' (alg : Algorithm 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] (n : β„•) : - HasCondDistrib (action alg n) (hist alg Β· n) (alg.policy n) (arrayMeasure Ξ½) := by +lemma hasCondDistrib_action' (alg : Algorithm Unit 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] + (n : β„•) : + HasCondDistrib (action alg n) (hist alg Β· n) ((alg.policy n).sectL ()) (arrayMeasure Ξ½) := by rw [action_eq] - have h_fun Ο‰ := algFunction_map alg n (hist alg Ο‰ n) + have h_fun Ο‰ : Measure.map (algFunction alg n (hist alg Ο‰ n)) β„™ + = ((alg.policy n).sectL ()) (hist alg Ο‰ n) := algFunction_map alg n (hist alg Ο‰ n) refine ⟨by fun_prop, ?_⟩ have h_indep : (arrayMeasure Ξ½).map (fun Ο‰ ↦ (Ο‰.1 n, hist alg Ο‰ n)) = (β„™).prod ((arrayMeasure Ξ½).map (hist alg Β· n)) := by @@ -940,7 +944,7 @@ lemma hasCondDistrib_action' (alg : Algorithm 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMa and the number of times that action has been pulled before time `n`, is equal to the kernel `Ξ½`. -/ lemma hasCondDistrib_reward_pullCount_action - (alg : Algorithm 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] (n : β„•) : + (alg : Algorithm Unit 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] (n : β„•) : HasCondDistrib (reward alg n) (fun Ο‰ ↦ (action alg n Ο‰, pullCount (action alg) (action alg n Ο‰) n Ο‰)) (Ξ½.prodMkRight _) (arrayMeasure Ξ½) := by @@ -990,7 +994,7 @@ lemma hasCondDistrib_reward_pullCount_action simp [ha] omit [StandardBorelSpace R] [Nonempty R] in -lemma reward_ae_eq_cond (alg : Algorithm 𝓐 R) (Ξ½ : Kernel 𝓐 R) (a : 𝓐) (n m : β„•) : +lemma reward_ae_eq_cond (alg : Algorithm Unit 𝓐 R) (Ξ½ : Kernel 𝓐 R) (a : 𝓐) (n m : β„•) : reward alg n =ᡐ[(arrayMeasure Ξ½)[|(fun Ο‰ ↦ (action alg n Ο‰, pullCount (action alg) (action alg n Ο‰) n Ο‰)) ⁻¹' {(a, m)}]] (fun Ο‰ ↦ Ο‰.2 m a) := by @@ -1004,14 +1008,14 @@ lemma reward_ae_eq_cond (alg : Algorithm 𝓐 R) (Ξ½ : Kernel 𝓐 R) (a : 𝓐) the action at time `n`, and the number of times that action has been pulled before time `n`, is equal to the kernel `Ξ½`. -/ lemma hasCondDistrib_reward_hist_action_pullCount - (alg : Algorithm 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] (n : β„•) : + (alg : Algorithm Unit 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] (n : β„•) : HasCondDistrib (reward alg n) (fun Ο‰ ↦ (hist alg Ο‰ n, action alg n Ο‰, pullCount (action alg) (action alg n Ο‰) n Ο‰)) ((Ξ½.prodMkRight _).prodMkLeft _) (arrayMeasure Ξ½) := by refine hasCondDistrib_of_condDistrib_eq (by fun_prop) (by fun_prop) ?_ refine condDistrib_prod_of_forall_condDistrib_cond (by fun_prop) (by fun_prop) (by fun_prop) _ ?_ intro (a, m) ham - have h_eq : ((Ξ½.prodMkRight _).prodMkLeft _).comap (fun Ο‰ : (Fin n β†’ 𝓐 Γ— R) ↦ (Ο‰, a, m)) + have h_eq : ((Ξ½.prodMkRight _).prodMkLeft _).comap (fun Ο‰ : Hist Unit 𝓐 R n ↦ (Ο‰, a, m)) (by fun_prop) = Kernel.const _ (Ξ½ a) := by ext; simp rw [h_eq, condDistrib_congr_left (reward_ae_eq_cond alg Ξ½ a n m)] @@ -1042,7 +1046,8 @@ lemma hasCondDistrib_reward_hist_action_pullCount /-- The reward at time `n` is conditionally independent of the history before time `n`, given the action at time `n` and the number of times that action has been pulled before time `n`. -/ -lemma condIndepFun_reward_hist (alg : Algorithm 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] (n : β„•) : +lemma condIndepFun_reward_hist (alg : Algorithm Unit 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] + (n : β„•) : (reward alg n) βŸ‚α΅’[(fun Ο‰ ↦ (action alg n Ο‰, pullCount (action alg) (action alg n Ο‰) n Ο‰)), Measurable.prodMk (by fun_prop) (measurable_pullCount_action alg n); arrayMeasure Ξ½] @@ -1054,7 +1059,8 @@ lemma condIndepFun_reward_hist (alg : Algorithm 𝓐 R) (Ξ½ : Kernel 𝓐 R) [Is /-- The conditional distribution of the reward at time `n`, given the history before time `n` and the action at time `n`, is equal to the kernel `Ξ½`. -/ -lemma hasCondDistrib_reward' (alg : Algorithm 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] (n : β„•) : +lemma hasCondDistrib_reward' (alg : Algorithm Unit 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] + (n : β„•) : HasCondDistrib (reward alg n) (fun Ο‰ ↦ (hist alg Ο‰ n, action alg n Ο‰)) (Ξ½.prodMkLeft _) (arrayMeasure Ξ½) := by let R' := reward alg n @@ -1078,7 +1084,7 @@ lemma hasCondDistrib_reward' (alg : Algorithm 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMa rwa [hasCondDistrib_prod_right_iff _ _ hf_meas] at this suffices HasCondDistrib R' (fun Ο‰ ↦ ((A Ο‰, P Ο‰), H Ο‰)) ((Ξ½.prodMkRight _).prodMkRight _) (arrayMeasure Ξ½) by - let e : ((𝓐 Γ— β„•) Γ— (Fin n β†’ 𝓐 Γ— R)) ≃ᡐ ((𝓐 Γ— (Fin n β†’ 𝓐 Γ— R)) Γ— β„•) := + let e : ((𝓐 Γ— β„•) Γ— (Hist Unit 𝓐 R n)) ≃ᡐ ((𝓐 Γ— (Hist Unit 𝓐 R n)) Γ— β„•) := { toFun := fun x ↦ ((x.1.1, x.2), x.1.2) invFun := fun x ↦ ((x.1.1, x.2), x.1.2) measurable_toFun := by simp only [Equiv.coe_fn_mk]; fun_prop @@ -1100,31 +1106,50 @@ lemma hasCondDistrib_reward' (alg : Algorithm 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMa Β· exact Kernel.measurableSet_eq _ _ exact hasCondDistrib_reward_pullCount_action alg Ξ½ n -lemma hasCondDistrib_action (alg : Algorithm 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] (n : β„•) : - HasCondDistrib (action alg n) (history (action alg) (reward alg) n) (alg.policy n) +lemma hasCondDistrib_action (alg : Algorithm Unit 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] + (n : β„•) : + HasCondDistrib (action alg n) + (fun Ο‰ ↦ (history (noObs _) (action alg) (reward alg) n Ο‰, noObs _ n Ο‰)) (alg.policy n) (arrayMeasure Ξ½) := by + refine hasCondDistrib_prodMk_right_unique_iff.mpr ?_ simpa only [hist_eq_history] using hasCondDistrib_action' alg Ξ½ n -lemma hasCondDistrib_reward (alg : Algorithm 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] +lemma hasCondDistrib_reward (alg : Algorithm Unit 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] (n : β„•) : HasCondDistrib (reward alg n) - (fun Ο‰ ↦ (history (action alg) (reward alg) n Ο‰, action alg n Ο‰)) + (fun Ο‰ ↦ ((history (noObs _) (action alg) (reward alg) n Ο‰, noObs _ n Ο‰), action alg n Ο‰)) ((stationaryEnv Ξ½).feedback n) (arrayMeasure Ξ½) := by - simpa only [hist_eq_history, feedback_stationaryEnv] using hasCondDistrib_reward' alg Ξ½ n - -lemma isAlgEnvSeq_arrayMeasure (alg : Algorithm 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] : - IsAlgEnvSeq (action alg) (reward alg) alg (stationaryEnv Ξ½) (arrayMeasure Ξ½) where + let e : (Hist Unit 𝓐 R n Γ— 𝓐) ≃ᡐ ((Hist Unit 𝓐 R n Γ— Unit) Γ— 𝓐) := + { toFun := fun p ↦ ((p.1, ()), p.2) + invFun := fun p ↦ (p.1.1, p.2) + left_inv := fun _ ↦ rfl + right_inv := fun _ ↦ rfl + measurable_toFun := by simp only [Equiv.coe_fn_mk]; fun_prop + measurable_invFun := by simp only [Equiv.symm_mk, Equiv.coe_fn_mk]; fun_prop } + rw [feedback_stationaryEnv] + have h := (hasCondDistrib_reward' alg Ξ½ n).measurableEquiv_comp_right e + simp only [hist_eq_history] at h + exact h + +lemma isAlgEnvSeq_arrayMeasure (alg : Algorithm Unit 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] : + IsAlgEnvSeq (noObs _) (action alg) (reward alg) alg (stationaryEnv Ξ½) (arrayMeasure Ξ½) where + hasCondDistrib_obs n := + hasCondDistrib_unit (measurable_history (fun _ ↦ measurable_const) + (measurable_action alg) (measurable_reward alg) n).aemeasurable _ _ hasCondDistrib_action := hasCondDistrib_action alg Ξ½ hasCondDistrib_feedback := hasCondDistrib_reward alg Ξ½ -lemma hasLaw_action_zero (alg : Algorithm 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] : - HasLaw (action alg 0) alg.p0 (arrayMeasure Ξ½) := - (isAlgEnvSeq_arrayMeasure alg Ξ½).hasLaw_action_zero +lemma hasLaw_action_zero (alg : Algorithm Unit 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] : + HasLaw (action alg 0) (alg.p0 ()) (arrayMeasure Ξ½) := by + have h : HasCondDistrib (action alg 0) (fun _ : probSpace 𝓐 R ↦ ()) alg.p0 (arrayMeasure Ξ½) := + (isAlgEnvSeq_arrayMeasure alg Ξ½).hasCondDistrib_action_zero + exact h.hasLaw_of_const' -lemma hasCondDistrib_reward_zero (alg : Algorithm 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] : +lemma hasCondDistrib_reward_zero (alg : Algorithm Unit 𝓐 R) (Ξ½ : Kernel 𝓐 R) [IsMarkovKernel Ξ½] : HasCondDistrib (reward alg 0) (action alg 0) Ξ½ (arrayMeasure Ξ½) := by have h := (isAlgEnvSeq_arrayMeasure alg Ξ½).hasCondDistrib_feedback_zero - rwa [Ξ½0_stationaryEnv] at h + rw [Ξ½0_stationaryEnv] at h + simpa using hasCondDistrib_prodMk_left_unique_iff.mp h end Laws diff --git a/LeanMachineLearning/Online/Bandit/Regret.lean b/LeanMachineLearning/Online/Bandit/Regret.lean index d5e4a96d..58c5683a 100644 --- a/LeanMachineLearning/Online/Bandit/Regret.lean +++ b/LeanMachineLearning/Online/Bandit/Regret.lean @@ -28,9 +28,10 @@ open scoped ENNReal NNReal namespace Bandits -variable {𝓐 Ξ© : Type*} [DecidableEq 𝓐] {m𝓐 : MeasurableSpace 𝓐} {mΞ© : MeasurableSpace Ξ©} +variable {π“ž 𝓐 Ξ© : Type*} [DecidableEq 𝓐] {mπ“ž : MeasurableSpace π“ž} {m𝓐 : MeasurableSpace 𝓐} + {mΞ© : MeasurableSpace Ξ©} {Ξ½ : Kernel 𝓐 ℝ} - {A : β„• β†’ Ξ© β†’ 𝓐} {R : β„• β†’ Ξ© β†’ ℝ} + {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {R : β„• β†’ Ξ© β†’ ℝ} {Ο‰ : Ξ©} {m n t : β„•} {a : 𝓐} /-- Gap of an action `a`: difference between the highest mean of the actions and the mean of `a`. -/ @@ -91,8 +92,8 @@ lemma integral_regret_eq_sum_gap_mul_integral_pullCount with positive gap. -/ lemma integral_regret_le_of_forall_integral_pullCount_le [StandardBorelSpace 𝓐] [Fintype 𝓐] {P : Measure Ξ©} [IsProbabilityMeasure P] - {alg : Algorithm 𝓐 ℝ} {env : Environment 𝓐 ℝ} {B : 𝓐 β†’ ℝ} - (h : IsAlgEnvSeq A R alg env P) + {alg : Algorithm π“ž 𝓐 ℝ} {env : Environment π“ž 𝓐 ℝ} {B : 𝓐 β†’ ℝ} + (h : IsAlgEnvSeq O A R alg env P) (h_le : βˆ€ a, gap Ξ½ a β‰  0 β†’ ∫ Ο‰, (pullCount A a n Ο‰ : ℝ) βˆ‚P ≀ B a) : P[regret Ξ½ A n] ≀ βˆ‘ a, gap Ξ½ a * B a := by have hA := h.measurable_action diff --git a/LeanMachineLearning/Online/Bandit/RewardByCountMeasure.lean b/LeanMachineLearning/Online/Bandit/RewardByCountMeasure.lean index f4f70bfb..d2590b51 100644 --- a/LeanMachineLearning/Online/Bandit/RewardByCountMeasure.lean +++ b/LeanMachineLearning/Online/Bandit/RewardByCountMeasure.lean @@ -18,9 +18,9 @@ open scoped ENNReal NNReal namespace Bandits variable {𝓐 Ξ© : Type*} {m𝓐 : MeasurableSpace 𝓐} {mΞ© : MeasurableSpace Ξ©} [DecidableEq 𝓐] - {A : β„• β†’ Ξ© β†’ 𝓐} {R : β„• β†’ Ξ© β†’ ℝ} {P : Measure Ξ©} [IsProbabilityMeasure P] - {alg : Algorithm 𝓐 ℝ} {Ξ½ : Kernel 𝓐 ℝ} [IsMarkovKernel Ξ½] - {h_inter : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P} + {O : β„• β†’ Ξ© β†’ Unit} {A : β„• β†’ Ξ© β†’ 𝓐} {R : β„• β†’ Ξ© β†’ ℝ} {P : Measure Ξ©} [IsProbabilityMeasure P] + {alg : Algorithm Unit 𝓐 ℝ} {Ξ½ : Kernel 𝓐 ℝ} [IsMarkovKernel Ξ½] + {h_inter : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P} local notation "𝔓" => P.prod (streamMeasure Ξ½) @@ -48,7 +48,7 @@ notation "𝓛[" Y " | " X " ← " x "; " ΞΌ "]" => Measure.map Y (ΞΌ[|X ⁻¹' omit [DecidableEq 𝓐] in lemma condDistrib_reward'' [Countable 𝓐] - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) (n : β„•) : + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (n : β„•) : 𝓛[fun Ο‰ ↦ R n Ο‰.1 | fun Ο‰ ↦ A n Ο‰.1; 𝔓] =ᡐ[(𝔓).map (fun Ο‰ ↦ A n Ο‰.1)] Ξ½ := by have hA := h.measurable_action have hR := h.measurable_feedback @@ -67,7 +67,7 @@ variable [StandardBorelSpace 𝓐] omit [DecidableEq 𝓐] in lemma reward_cond_action [Countable 𝓐] - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (n : β„•) + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (n : β„•) (hΞΌa : (𝔓).map (fun Ο‰ ↦ A n Ο‰.1) {a} β‰  0) : 𝓛[fun Ο‰ ↦ R n Ο‰.1 | fun Ο‰ ↦ A n Ο‰.1 ← a; 𝔓] = Ξ½ a := by have hA := h.measurable_action @@ -85,20 +85,21 @@ lemma reward_cond_action [Countable 𝓐] variable [Nonempty 𝓐] lemma condIndepFun_reward_stepsUntil_action' [StandardBorelSpace Ξ©] - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (m n : β„•) : + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (m n : β„•) : R n βŸ‚α΅’[A n, h.measurable_action n; P] {Ο‰ | stepsUntil A a m Ο‰ = ↑n}.indicator (fun _ ↦ 1) := by -- the indicator of `stepsUntil ... = n` is a function of `hist (n-1)` and `action n`. -- It thus suffices to use the independence of `reward n` and `hist (n-1)` conditionally -- on `action n`. have hA := h.measurable_action have hR := h.measurable_feedback - have h_indep : R n βŸ‚α΅’[A n, hA n; P] fun Ο‰ ↦ (history A R n Ο‰, A n Ο‰) := + have h_indep : R n βŸ‚α΅’[A n, hA n; P] + fun Ο‰ ↦ ((history O A R n Ο‰, O n Ο‰), A n Ο‰) := IsAlgEnvSeq.condIndepFun_feedback_history_action_action h n refine h_indep.of_measurable_right (hX := hA n) ?_ - exact measurable_comap_indicator_stepsUntil_eq R a m n + exact measurable_comap_indicator_stepsUntil_eq O R a m n lemma condIndepFun_reward_stepsUntil_action [StandardBorelSpace Ξ©] [Countable 𝓐] - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (m n : β„•) : CondIndepFun (m𝓐.comap (fun Ο‰ ↦ A n Ο‰.1)) ((h.measurable_action n).comp measurable_fst).comap_le (fun Ο‰ ↦ R n Ο‰.1) ({Ο‰ | stepsUntil A a m Ο‰.1 = ↑n}.indicator (fun _ ↦ 1)) 𝔓 := by @@ -109,7 +110,7 @@ lemma condIndepFun_reward_stepsUntil_action [StandardBorelSpace Ξ©] [Countable (condIndepFun_reward_stepsUntil_action' h a m n) lemma reward_cond_stepsUntil [StandardBorelSpace Ξ©] [Countable 𝓐] - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (m n : β„•) + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (m n : β„•) (hm : m β‰  0) (hΞΌn : 𝔓 ((fun Ο‰ ↦ stepsUntil A a m Ο‰.1) ⁻¹' {↑n}) β‰  0) : 𝓛[fun Ο‰ ↦ R n Ο‰.1 | fun Ο‰ ↦ stepsUntil A a m Ο‰.1 ← ↑n; 𝔓] = Ξ½ a := by have hA := h.measurable_action @@ -155,7 +156,7 @@ lemma reward_cond_stepsUntil [StandardBorelSpace Ξ©] [Countable 𝓐] /-- The conditional distribution of the reward received at the `m`-th pull of action `a` given the time at which number of pulls is `m` is the constant kernel with value `Ξ½ a`. -/ lemma condDistrib_rewardByCount_stepsUntil [StandardBorelSpace Ξ©] [Countable 𝓐] - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (m : β„•) (hm : m β‰  0) : + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (m : β„•) (hm : m β‰  0) : condDistrib (rewardByCount A R a m) (fun Ο‰ ↦ stepsUntil A a m Ο‰.1) 𝔓 =ᡐ[(𝔓).map (fun Ο‰ ↦ stepsUntil A a m Ο‰.1)] Kernel.const _ (Ξ½ a) := by have hA := h.measurable_action @@ -188,7 +189,7 @@ lemma condDistrib_rewardByCount_stepsUntil [StandardBorelSpace Ξ©] [Countable /-- The reward received at the `m`-th pull of action `a` has law `Ξ½ a`. -/ lemma hasLaw_rewardByCount [StandardBorelSpace Ξ©] [Countable 𝓐] - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (m : β„•) (hm : m β‰  0) : + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (m : β„•) (hm : m β‰  0) : HasLaw (rewardByCount A R a m) (Ξ½ a) 𝔓 where aemeasurable := (measurable_rewardByCount h.measurable_action h.measurable_feedback a m).aemeasurable @@ -211,7 +212,7 @@ lemma hasLaw_rewardByCount [StandardBorelSpace Ξ©] [Countable 𝓐] simp lemma identDistrib_rewardByCount [StandardBorelSpace Ξ©] [Countable 𝓐] - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (n m : β„•) + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (n m : β„•) (hn : n β‰  0) (hm : m β‰  0) : IdentDistrib (rewardByCount A R a n) (rewardByCount A R a m) 𝔓 𝔓 where aemeasurable_fst := @@ -221,7 +222,7 @@ lemma identDistrib_rewardByCount [StandardBorelSpace Ξ©] [Countable 𝓐] map_eq := by rw [(hasLaw_rewardByCount h a n hn).map_eq, (hasLaw_rewardByCount h a m hm).map_eq] lemma identDistrib_rewardByCount_id [StandardBorelSpace Ξ©] [Countable 𝓐] - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (n : β„•) (hn : n β‰  0) : + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (n : β„•) (hn : n β‰  0) : IdentDistrib (rewardByCount A R a n) id 𝔓 (Ξ½ a) where aemeasurable_fst := (measurable_rewardByCount h.measurable_action h.measurable_feedback a n).aemeasurable @@ -229,7 +230,7 @@ lemma identDistrib_rewardByCount_id [StandardBorelSpace Ξ©] [Countable 𝓐] map_eq := by rw [(hasLaw_rewardByCount h a n hn).map_eq, Measure.map_id] lemma identDistrib_rewardByCount_eval [StandardBorelSpace Ξ©] [Countable 𝓐] - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (n m : β„•) (hn : n β‰  0) : + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (n m : β„•) (hn : n β‰  0) : IdentDistrib (rewardByCount A R a n) (fun Ο‰ ↦ Ο‰ m a) 𝔓 (streamMeasure Ξ½) := (identDistrib_rewardByCount_id h a n hn).trans (identDistrib_eval_eval_id_streamMeasure Ξ½ m a).symm diff --git a/LeanMachineLearning/Online/Bandit/SumRewards.lean b/LeanMachineLearning/Online/Bandit/SumRewards.lean index 4d9fc081..764de6ee 100644 --- a/LeanMachineLearning/Online/Bandit/SumRewards.lean +++ b/LeanMachineLearning/Online/Bandit/SumRewards.lean @@ -24,7 +24,7 @@ namespace ArrayModel variable {𝓐 : Type*} {m𝓐 : MeasurableSpace 𝓐} [DecidableEq 𝓐] [Countable 𝓐] [StandardBorelSpace 𝓐] [Nonempty 𝓐] - {alg : Algorithm 𝓐 ℝ} {Ξ½ : Kernel 𝓐 ℝ} [IsMarkovKernel Ξ½] + {alg : Algorithm Unit 𝓐 ℝ} {Ξ½ : Kernel 𝓐 ℝ} [IsMarkovKernel Ξ½] local notation "A" => action alg local notation "R" => reward alg @@ -134,36 +134,39 @@ end ArrayModel variable {𝓐 Ξ© Ξ©' : Type*} [DecidableEq 𝓐] {m𝓐 : MeasurableSpace 𝓐} {mΞ© : MeasurableSpace Ξ©} {mΞ©' : MeasurableSpace Ξ©'} {P : Measure Ξ©} [IsProbabilityMeasure P] {P' : Measure Ξ©'} [IsProbabilityMeasure P'] - {alg : Algorithm 𝓐 ℝ} {Ξ½ : Kernel 𝓐 ℝ} [IsMarkovKernel Ξ½] - {A : β„• β†’ Ξ© β†’ 𝓐} {R : β„• β†’ Ξ© β†’ ℝ} {Aβ‚‚ : β„• β†’ Ξ©' β†’ 𝓐} {Rβ‚‚ : β„• β†’ Ξ©' β†’ ℝ} + {alg : Algorithm Unit 𝓐 ℝ} {Ξ½ : Kernel 𝓐 ℝ} [IsMarkovKernel Ξ½] + {O : β„• β†’ Ξ© β†’ Unit} {A : β„• β†’ Ξ© β†’ 𝓐} {R : β„• β†’ Ξ© β†’ ℝ} + {Oβ‚‚ : β„• β†’ Ξ©' β†’ Unit} {Aβ‚‚ : β„• β†’ Ξ©' β†’ 𝓐} {Rβ‚‚ : β„• β†’ Ξ©' β†’ ℝ} {Ο‰ : Ξ©} {m n t : β„•} {a : 𝓐} lemma sumRewards_eq_comp : sumRewards A R a n = - (fun p ↦ βˆ‘ i ∈ range n, if (p i).1 = a then (p i).2 else 0) ∘ (trajectory A R) := by + (fun p : β„• β†’ Round Unit 𝓐 ℝ ↦ + βˆ‘ i ∈ range n, if (p i).action = a then (p i).feedback else 0) ∘ (trajectory O A R) := by ext simp [sumRewards, trajectory] grind lemma pullCount_eq_comp : pullCount A a n = - (fun p ↦ βˆ‘ i ∈ range n, if (p i).1 = a then 1 else 0) ∘ (trajectory A R) := by + (fun p : β„• β†’ Round Unit 𝓐 ℝ ↦ βˆ‘ i ∈ range n, if (p i).action = a then 1 else 0) ∘ + (trajectory O A R) := by ext simp [pullCount, trajectory] rfl -- todo: write those lemmas with IdentDistrib instead of equality of maps lemma _root_.Learning.IsAlgEnvSeq.law_sumRewards_unique [MeasurableSingletonClass 𝓐] - (h1 : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) - (h2 : IsAlgEnvSeq Aβ‚‚ Rβ‚‚ alg (stationaryEnv Ξ½) P') : + (h1 : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) + (h2 : IsAlgEnvSeq Oβ‚‚ Aβ‚‚ Rβ‚‚ alg (stationaryEnv Ξ½) P') : P.map (sumRewards A R a n) = P'.map (sumRewards Aβ‚‚ Rβ‚‚ a n) := by have hA := h1.measurable_action have hR := h1.measurable_feedback have hA2 := h2.measurable_action have hR2 := h2.measurable_feedback have h_unique := isAlgEnvSeq_unique h1 h2 - rw [sumRewards_eq_comp, sumRewards_eq_comp, ← Measure.map_map, h_unique, Measure.map_map, - ← sumRewards_eq_comp] + rw [sumRewards_eq_comp (O := O), sumRewards_eq_comp (O := Oβ‚‚), ← Measure.map_map, h_unique, + Measure.map_map, ← sumRewards_eq_comp (O := Oβ‚‚)] Β· refine measurable_sum _ fun i hi ↦ Measurable.ite ?_ (by fun_prop) (by fun_prop) exact (measurableSet_singleton _).preimage (by fun_prop) Β· fun_prop @@ -172,12 +175,14 @@ lemma _root_.Learning.IsAlgEnvSeq.law_sumRewards_unique [MeasurableSingletonClas Β· fun_prop lemma _root_.Learning.IsAlgEnvSeq.law_pullCount_sumRewards_unique' [MeasurableSingletonClass 𝓐] - (h1 : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) - (h2 : IsAlgEnvSeq Aβ‚‚ Rβ‚‚ alg (stationaryEnv Ξ½) P') : + (h1 : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) + (h2 : IsAlgEnvSeq Oβ‚‚ Aβ‚‚ Rβ‚‚ alg (stationaryEnv Ξ½) P') : IdentDistrib (fun Ο‰ a ↦ (pullCount A a n Ο‰, sumRewards A R a n Ο‰)) (fun Ο‰ a ↦ (pullCount Aβ‚‚ a n Ο‰, sumRewards Aβ‚‚ Rβ‚‚ a n Ο‰)) P P' := by + have hO := h1.measurable_obs have hA := h1.measurable_action have hR := h1.measurable_feedback + have hO2 := h2.measurable_obs have hA2 := h2.measurable_action have hR2 := h2.measurable_feedback constructor @@ -188,8 +193,9 @@ lemma _root_.Learning.IsAlgEnvSeq.law_pullCount_sumRewards_unique' [MeasurableSi rw [measurable_pi_iff] exact fun a ↦ Measurable.prod (by fun_prop) (measurable_sumRewards hA2 hR2 _ _) have h_unique := isAlgEnvSeq_unique h1 h2 - let f := fun (p : β„• β†’ 𝓐 Γ— ℝ ) (a : 𝓐) ↦ (βˆ‘ i ∈ range n, if (p i).1 = a then 1 else 0, - βˆ‘ i ∈ range n, if (p i).1 = a then (p i).2 else 0) + let f := fun (p : β„• β†’ Round Unit 𝓐 ℝ) (a : 𝓐) ↦ + (βˆ‘ i ∈ range n, if (p i).action = a then 1 else 0, + βˆ‘ i ∈ range n, if (p i).action = a then (p i).feedback else 0) have hf : Measurable f := by rw [measurable_pi_iff] intro a @@ -201,44 +207,42 @@ lemma _root_.Learning.IsAlgEnvSeq.law_pullCount_sumRewards_unique' [MeasurableSi refine measurable_sum _ fun i hi ↦ Measurable.ite ?_ (by fun_prop) (by fun_prop) exact (measurableSet_singleton _).preimage (by fun_prop) have h_eq_comp : (fun Ο‰ a ↦ (pullCount A a n Ο‰, sumRewards A R a n Ο‰)) - = f ∘ (trajectory A R) := by + = f ∘ (trajectory O A R) := by ext Ο‰ a : 2 - rw [pullCount_eq_comp (R := R), sumRewards_eq_comp] + rw [pullCount_eq_comp (O := O) (R := R), sumRewards_eq_comp (O := O)] grind have h_eq_comp2 : (fun Ο‰ a ↦ (pullCount Aβ‚‚ a n Ο‰, sumRewards Aβ‚‚ Rβ‚‚ a n Ο‰)) - = f ∘ (trajectory Aβ‚‚ Rβ‚‚) := by + = f ∘ (trajectory Oβ‚‚ Aβ‚‚ Rβ‚‚) := by ext Ο‰ a : 2 - rw [pullCount_eq_comp (R := Rβ‚‚), sumRewards_eq_comp] + rw [pullCount_eq_comp (O := Oβ‚‚) (R := Rβ‚‚), sumRewards_eq_comp (O := Oβ‚‚)] grind rw [h_eq_comp, h_eq_comp2, ← Measure.map_map hf, h_unique, Measure.map_map hf, ← h_eq_comp2] - Β· rw [measurable_pi_iff] - exact fun n ↦ Measurable.prodMk (hA2 n) (hR2 n) - Β· rw [measurable_pi_iff] - exact fun n ↦ Measurable.prodMk (hA n) (hR n) + Β· fun_prop + Β· fun_prop lemma _root_.Learning.IsAlgEnvSeq.law_pullCount_sumRewards_unique [MeasurableSingletonClass 𝓐] - (h1 : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) - (h2 : IsAlgEnvSeq Aβ‚‚ Rβ‚‚ alg (stationaryEnv Ξ½) P') : + (h1 : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) + (h2 : IsAlgEnvSeq Oβ‚‚ Aβ‚‚ Rβ‚‚ alg (stationaryEnv Ξ½) P') : P.map (fun Ο‰ ↦ (pullCount A a n Ο‰, sumRewards A R a n Ο‰)) = P'.map (fun Ο‰ ↦ (pullCount Aβ‚‚ a n Ο‰, sumRewards Aβ‚‚ Rβ‚‚ a n Ο‰)) := ((h1.law_pullCount_sumRewards_unique' h2 (n := n)).comp (u := fun f ↦ f a) (by fun_prop)).map_eq lemma _root_.Learning.IsAlgEnvSeq.identDistrib_pullCount_sumRewards [MeasurableSingletonClass 𝓐] - (h1 : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) - (h2 : IsAlgEnvSeq Aβ‚‚ Rβ‚‚ alg (stationaryEnv Ξ½) P') : + (h1 : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) + (h2 : IsAlgEnvSeq Oβ‚‚ Aβ‚‚ Rβ‚‚ alg (stationaryEnv Ξ½) P') : IdentDistrib (fun Ο‰ n a ↦ (pullCount A a n Ο‰, sumRewards A R a n Ο‰)) (fun Ο‰' n a ↦ (pullCount Aβ‚‚ a n Ο‰', sumRewards Aβ‚‚ Rβ‚‚ a n Ο‰')) P P' := by - let f (Ο„ : β„• β†’ 𝓐 Γ— ℝ) (n : β„•) (a : 𝓐) : β„• Γ— ℝ := - (βˆ‘ i ∈ range n, if (Ο„ i).1 = a then 1 else 0, - βˆ‘ i ∈ range n, if (Ο„ i).1 = a then (Ο„ i).2 else 0) + let f (Ο„ : β„• β†’ Round Unit 𝓐 ℝ) (n : β„•) (a : 𝓐) : β„• Γ— ℝ := + (βˆ‘ i ∈ range n, if (Ο„ i).action = a then 1 else 0, + βˆ‘ i ∈ range n, if (Ο„ i).action = a then (Ο„ i).feedback else 0) have hc1 : (fun Ο‰ n a ↦ (pullCount A a n Ο‰, sumRewards A R a n Ο‰)) = - f ∘ (trajectory A R) := by + f ∘ (trajectory O A R) := by ext Ο‰ n a : 3 simp_rw [Function.comp, f, pullCount, card_filter, sumRewards, trajectory] rfl have hc2 : (fun Ο‰' n a ↦ (pullCount Aβ‚‚ a n Ο‰', sumRewards Aβ‚‚ Rβ‚‚ a n Ο‰')) = - f ∘ (trajectory Aβ‚‚ Rβ‚‚) := by + f ∘ (trajectory Oβ‚‚ Aβ‚‚ Rβ‚‚) := by ext Ο‰' n a : 3 simp_rw [Function.comp, f, pullCount, card_filter, sumRewards, trajectory] rfl @@ -259,7 +263,7 @@ variable [Nonempty 𝓐] -- this is what we will use for UCB lemma prob_pullCount_prod_sumRewards_mem_le [Countable 𝓐] [MeasurableSingletonClass 𝓐] - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) {s : Set (β„• Γ— ℝ)} [DecidablePred (Β· ∈ Prod.fst '' s)] (hs : MeasurableSet s) : P {Ο‰ | (pullCount A a n Ο‰, sumRewards A R a n Ο‰) ∈ s} ≀ βˆ‘ k ∈ (range (n + 1)).filter (Β· ∈ Prod.fst '' s), @@ -281,7 +285,7 @@ lemma prob_pullCount_prod_sumRewards_mem_le [Countable 𝓐] [MeasurableSingleto ArrayModel.prob_pullCount_prod_sumRewards_mem_le a n hs lemma prob_pullCount_mem_and_sumRewards_mem_le [Countable 𝓐] [MeasurableSingletonClass 𝓐] - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) {s : Set β„•} [DecidablePred (Β· ∈ s)] (hs : MeasurableSet s) {B : Set ℝ} (hB : MeasurableSet B) : P {Ο‰ | pullCount A a n Ο‰ ∈ s ∧ sumRewards A R a n Ο‰ ∈ B} ≀ βˆ‘ k ∈ (range (n + 1)).filter (Β· ∈ s), @@ -300,7 +304,7 @@ lemma prob_pullCount_mem_and_sumRewards_mem_le [Countable 𝓐] [MeasurableSingl simp [hk.2.1] lemma prob_sumRewards_mem_le [Countable 𝓐] [MeasurableSingletonClass 𝓐] - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) {B : Set ℝ} (hB : MeasurableSet B) : P (sumRewards A R a n ⁻¹' B) ≀ βˆ‘ k ∈ range (n + 1), streamMeasure Ξ½ {Ο‰ | βˆ‘ i ∈ range k, Ο‰ i a ∈ B} := by @@ -311,7 +315,7 @@ lemma prob_sumRewards_mem_le [Countable 𝓐] [MeasurableSingletonClass 𝓐] rfl lemma prob_pullCount_eq_and_sumRewards_mem_le [Countable 𝓐] [MeasurableSingletonClass 𝓐] - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) {m : β„•} (hm : m ≀ n) {B : Set ℝ} (hB : MeasurableSet B) : P {Ο‰ | pullCount A a n Ο‰ = m ∧ sumRewards A R a n Ο‰ ∈ B} ≀ streamMeasure Ξ½ {Ο‰ | βˆ‘ i ∈ range m, Ο‰ i a ∈ B} := by @@ -320,7 +324,7 @@ lemma prob_pullCount_eq_and_sumRewards_mem_le [Countable 𝓐] [MeasurableSingle simpa [hm'] using h_le lemma prob_exists_pullCount_eq_and_sumRewards_mem_le [Countable 𝓐] [MeasurableSingletonClass 𝓐] - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (m : β„•) {B : Set ℝ} + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (m : β„•) {B : Set ℝ} (hB : MeasurableSet B) : P {Ο‰ | βˆƒ n, pullCount A a n Ο‰ = m ∧ sumRewards A R a n Ο‰ ∈ B} ≀ streamMeasure Ξ½ {Ο‰ | βˆ‘ i ∈ range m, Ο‰ i a ∈ B} := @@ -337,7 +341,7 @@ lemma prob_exists_pullCount_eq_and_sumRewards_mem_le [Countable 𝓐] [Measurabl _ ≀ _ := ArrayModel.prob_exists_pullCount_eq_and_sumRewards_mem_le a m hB lemma probReal_sumRewards_le_sumRewards_le [Fintype 𝓐] [MeasurableSingletonClass 𝓐] - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (n m₁ mβ‚‚ : β„•) : P.real {Ο‰ | pullCount A (bestArm Ξ½) n Ο‰ = m₁ ∧ pullCount A a n Ο‰ = mβ‚‚ ∧ sumRewards A R (bestArm Ξ½) n Ο‰ ≀ sumRewards A R a n Ο‰} ≀ @@ -436,7 +440,7 @@ end StreamMeasure lemma prob_sumRewards_sub_pullCount_mul_ge_le [Countable 𝓐] [MeasurableSingletonClass 𝓐] {Οƒ2 : ℝβ‰₯0} (hΟƒ2 : 0 < Οƒ2) (ha : HasSubgaussianMGF (fun x ↦ x - (Ξ½ a)[id]) Οƒ2 (Ξ½ a)) - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) {Ξ΄ : ℝ} (hΞ΄ : 0 < Ξ΄) : + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) {Ξ΄ : ℝ} (hΞ΄ : 0 < Ξ΄) : P {Ο‰ | βˆƒ t < n, pullCount A a t Ο‰ β‰  0 ∧ √(2 * pullCount A a t Ο‰ * Οƒ2 * Real.log (1 / Ξ΄)) ≀ sumRewards A R a t Ο‰ - pullCount A a t Ο‰ * (Ξ½ a)[id]} ≀ ENNReal.ofReal ((n - 1) * Ξ΄) := let B (m : β„•) := {x : ℝ | √(2 * m * Οƒ2 * Real.log (1 / Ξ΄)) ≀ x - m * (Ξ½ a)[id]} @@ -470,7 +474,7 @@ lemma prob_sumRewards_sub_pullCount_mul_ge_le [Countable 𝓐] [MeasurableSingle lemma prob_sumRewards_sub_pullCount_mul_le_le [Countable 𝓐] [MeasurableSingletonClass 𝓐] {Οƒ2 : ℝβ‰₯0} (hΟƒ2 : 0 < Οƒ2) (ha : HasSubgaussianMGF (fun x ↦ x - (Ξ½ a)[id]) Οƒ2 (Ξ½ a)) - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) {Ξ΄ : ℝ} (hΞ΄ : 0 < Ξ΄) : + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) {Ξ΄ : ℝ} (hΞ΄ : 0 < Ξ΄) : P {Ο‰ | βˆƒ t < n, pullCount A a t Ο‰ β‰  0 ∧ sumRewards A R a t Ο‰ - pullCount A a t Ο‰ * (Ξ½ a)[id] ≀ -√(2 * pullCount A a t Ο‰ * Οƒ2 * Real.log (1 / Ξ΄))} ≀ ENNReal.ofReal ((n - 1) * Ξ΄) := @@ -505,7 +509,7 @@ lemma prob_sumRewards_sub_pullCount_mul_le_le [Countable 𝓐] [MeasurableSingle lemma prob_sumRewards_sub_pullCount_mul_ge_le_of_Fintype [Fintype 𝓐] [MeasurableSingletonClass 𝓐] {Οƒ2 : ℝβ‰₯0} (hΟƒ2 : 0 < Οƒ2) (hΞ½ : βˆ€ a, HasSubgaussianMGF (fun x ↦ x - (Ξ½ a)[id]) Οƒ2 (Ξ½ a)) - (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) {Ξ΄ : ℝ} (hΞ΄ : 0 < Ξ΄) : + (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) {Ξ΄ : ℝ} (hΞ΄ : 0 < Ξ΄) : P {Ο‰ | βˆƒ a, βˆƒ t < n, pullCount A a t Ο‰ β‰  0 ∧ √(2 * pullCount A a t Ο‰ * Οƒ2 * Real.log (1 / Ξ΄)) ≀ sumRewards A R a t Ο‰ - pullCount A a t Ο‰ * (Ξ½ a)[id]} ≀ @@ -672,7 +676,7 @@ namespace Learning.IsBayesAlgEnvSeq variable {𝓔 Ξ© : Type*} [MeasurableSpace 𝓔] [MeasurableSpace Ξ©] variable {K : β„•} [Nonempty (Fin K)] variable {Q : Measure 𝓔} {ΞΊ : Kernel (𝓔 Γ— Fin K) ℝ} [IsMarkovKernel ΞΊ] -variable {alg : Algorithm (Fin K) ℝ} +variable {alg : Algorithm Unit (Fin K) ℝ} variable {E : Ξ© β†’ 𝓔} {A : β„• β†’ Ξ© β†’ (Fin K)} {R : β„• β†’ Ξ© β†’ ℝ} variable {P : Measure Ξ©} [IsProbabilityMeasure P] @@ -699,19 +703,20 @@ lemma prob_empMean_sub_actionMean_ge_le (h : IsBayesAlgEnvSeq Q ΞΊ alg E A R P) have := h.measurable_param have := h.measurable_action have := h.measurable_feedback - let S := {(e, Ο„) | βˆƒ a, βˆƒ t < n, pullCount IT.action a t Ο„ β‰  0 ∧ + let S : Set (𝓔 Γ— (β„• β†’ Round Unit (Fin K) ℝ)) := + {(e, Ο„) | βˆƒ a, βˆƒ t < n, pullCount IT.action a t Ο„ β‰  0 ∧ √(2 * pullCount IT.action a t Ο„ * Οƒ2 * Real.log (1 / Ξ΄)) ≀ sumRewards IT.action IT.feedback a t Ο„ - pullCount IT.action a t Ο„ * actionMean ΞΊ id a e} calc - _ ≀ (P.map (fun Ο‰ ↦ (E Ο‰, trajectory A R Ο‰))) S := by + _ ≀ (P.map (fun Ο‰ ↦ (E Ο‰, trajectory (noObs Ξ©) A R Ο‰))) S := by rw [Measure.map_apply (by fun_prop) (by measurability)] apply measure_mono intro Ο‰ ⟨t, ht, a, hpc, hle⟩ rw [empMean] at hle exact ⟨a, t, ht, hpc, sqrt_two_mul_le_sub hpc hle⟩ - _ = (P.map E βŠ—β‚˜ condDistrib (trajectory A R) E P) S := by + _ = (P.map E βŠ—β‚˜ condDistrib (trajectory (noObs Ξ©) A R) E P) S := by rw [← compProd_map_condDistrib (by fun_prop)] - _ = ∫⁻ e, condDistrib (trajectory A R) E P e (Prod.mk e ⁻¹' S) βˆ‚(P.map E) := + _ = ∫⁻ e, condDistrib (trajectory (noObs Ξ©) A R) E P e (Prod.mk e ⁻¹' S) βˆ‚(P.map E) := Measure.compProd_apply (by measurability) _ ≀ ∫⁻ e, ENNReal.ofReal (Fintype.card (Fin K) * (n - 1) * Ξ΄) βˆ‚(P.map E) := by apply lintegral_mono_ae @@ -738,20 +743,21 @@ lemma prob_empMean_bestAction_sub_actionMean_le_le (h : IsBayesAlgEnvSeq Q ΞΊ al have := h.measurable_param have := h.measurable_action have := h.measurable_feedback - let S := {(e, Ο„) | βˆƒ t < n, pullCount IT.action (bestAction ΞΊ id e) t Ο„ β‰  0 ∧ + let S : Set (𝓔 Γ— (β„• β†’ Round Unit (Fin K) ℝ)) := + {(e, Ο„) | βˆƒ t < n, pullCount IT.action (bestAction ΞΊ id e) t Ο„ β‰  0 ∧ sumRewards IT.action IT.feedback (bestAction ΞΊ id e) t Ο„ - pullCount IT.action (bestAction ΞΊ id e) t Ο„ * actionMean ΞΊ id (bestAction ΞΊ id e) e ≀ -√(2 * pullCount IT.action (bestAction ΞΊ id e) t Ο„ * Οƒ2 * Real.log (1 / Ξ΄))} calc - _ ≀ (P.map (fun Ο‰ ↦ (E Ο‰, trajectory A R Ο‰))) S := by + _ ≀ (P.map (fun Ο‰ ↦ (E Ο‰, trajectory (noObs Ξ©) A R Ο‰))) S := by rw [Measure.map_apply (by fun_prop) (by measurability)] apply measure_mono intro Ο‰ ⟨t, ht, hpc, hle⟩ rw [empMean] at hle exact ⟨t, ht, hpc, sub_le_neg_sqrt_two_mul hpc hle⟩ - _ = (P.map E βŠ—β‚˜ condDistrib (trajectory A R) E P) S := by + _ = (P.map E βŠ—β‚˜ condDistrib (trajectory (noObs Ξ©) A R) E P) S := by rw [← compProd_map_condDistrib (by fun_prop)] - _ = ∫⁻ e, condDistrib (trajectory A R) E P e (Prod.mk e ⁻¹' S) βˆ‚(P.map E) := + _ = ∫⁻ e, condDistrib (trajectory (noObs Ξ©) A R) E P e (Prod.mk e ⁻¹' S) βˆ‚(P.map E) := Measure.compProd_apply (by measurability) _ ≀ ∫⁻ e, ENNReal.ofReal ((n - 1) * Ξ΄) βˆ‚(P.map E) := by apply lintegral_mono_ae diff --git a/LeanMachineLearning/SequentialLearning/ActionIndicator.lean b/LeanMachineLearning/SequentialLearning/ActionIndicator.lean index 6c17a2d6..5b5debc8 100644 --- a/LeanMachineLearning/SequentialLearning/ActionIndicator.lean +++ b/LeanMachineLearning/SequentialLearning/ActionIndicator.lean @@ -33,8 +33,9 @@ open MeasureTheory ProbabilityTheory Filter Finset namespace Learning -variable {Ξ© 𝓐 𝓨 : Type*} {mΞ© : MeasurableSpace Ξ©} {m𝓐 : MeasurableSpace 𝓐} {m𝓨 : MeasurableSpace 𝓨} - [MeasurableSingletonClass 𝓐] {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {P : Measure Ξ©} +variable {Ξ© π“ž 𝓐 𝓨 : Type*} {mΞ© : MeasurableSpace Ξ©} {mπ“ž : MeasurableSpace π“ž} + {m𝓐 : MeasurableSpace 𝓐} {m𝓨 : MeasurableSpace 𝓨} + [MeasurableSingletonClass 𝓐] {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {P : Measure Ξ©} /-- The `{0,1}`-valued assignment indicator of action `k`: `actionIndicator A k n Ο‰ = πŸ™{A n Ο‰ = k}`. -/ @@ -93,16 +94,16 @@ lemma integrable_actionIndicator (P : Measure Ξ©) [IsFiniteMeasure P] /-- The action indicator is adapted to the history filtration: whether action `k` was chosen at `n` is known at time `n`. -/ -lemma IsAlgEnvSeq.adapted_actionIndicator {alg : Algorithm 𝓐 𝓨} {env : Environment 𝓐 𝓨} - [IsFiniteMeasure P] (h : IsAlgEnvSeq A Y alg env P) (k : 𝓐) : +lemma IsAlgEnvSeq.adapted_actionIndicator {alg : Algorithm π“ž 𝓐 𝓨} {env : Environment π“ž 𝓐 𝓨} + [IsFiniteMeasure P] (h : IsAlgEnvSeq O A Y alg env P) (k : 𝓐) : Adapted h.filtration (actionIndicator A k) := fun _ ↦ Measurable.indicator measurable_const (h.adapted_action _ (measurableSet_singleton k)) /-- The action indicator is adapted to the history+action filtration: whether action `k` was chosen at `n` is known once we know the action at `n`. -/ lemma IsAlgEnvSeq.adapted_actionIndicator_filtrationAction - {alg : Algorithm 𝓐 𝓨} {env : Environment 𝓐 𝓨} - [IsFiniteMeasure P] (h : IsAlgEnvSeq A Y alg env P) (k : 𝓐) : + {alg : Algorithm π“ž 𝓐 𝓨} {env : Environment π“ž 𝓐 𝓨} + [IsFiniteMeasure P] (h : IsAlgEnvSeq O A Y alg env P) (k : 𝓐) : Adapted h.filtrationAction (actionIndicator A k) := fun _ ↦ Measurable.indicator measurable_const (h.adapted_action_filtrationAction _ (measurableSet_singleton k)) diff --git a/LeanMachineLearning/SequentialLearning/Algorithm.lean b/LeanMachineLearning/SequentialLearning/Algorithm.lean index d5104eff..e317d6d0 100644 --- a/LeanMachineLearning/SequentialLearning/Algorithm.lean +++ b/LeanMachineLearning/SequentialLearning/Algorithm.lean @@ -12,27 +12,34 @@ public import LeanMachineLearning.ForMathlib.Probability.Kernel.IonescuTulcea.Tr # Algorithms and environments We define structures for stochastic, sequential algorithms and environments, and the notion of an -algorithm-environment sequence, which is a sequence of actions and feedbacks generated by -an algorithm interacting with an environment. - -At time `n`, the algorithm has observed the `n` action-feedback pairs at times `0, ..., n - 1`. -That history is an element of `Fin n β†’ 𝓐 Γ— 𝓨`. The algorithm then chooses an action `A n` -according to its policy, and the environment returns a feedback `Y n` given the history and `A n`. -In particular, the first action is chosen according to the policy at time `0`, applied to the -empty history (the unique element of `Fin 0 β†’ 𝓐 Γ— 𝓨`). +algorithm-environment sequence, which is a sequence of observations, actions and feedbacks generated +by an algorithm interacting with an environment. + +A round of interaction consists of an observation in `π“ž`, an action in `𝓐` and a feedback in `𝓨`, +in that order: it is an element of `Round π“ž 𝓐 𝓨 = π“ž Γ— 𝓐 Γ— 𝓨`. +At time `n`, the algorithm has seen the `n` complete rounds at times `0, ..., n - 1`. +That history is an element of `Hist π“ž 𝓐 𝓨 n = Fin n β†’ Round π“ž 𝓐 𝓨`. The environment then draws +an observation `O n` given the history, the algorithm chooses an action `A n` according to its +policy applied to the history and `O n`, and the environment returns a feedback `Y n` given the +history, `O n` and `A n`. +In particular, the first observation is drawn according to the observation kernel at time `0`, +applied to the empty history (the unique element of `Hist π“ž 𝓐 𝓨 0`). ## Main definitions -* `Algorithm 𝓐 𝓨`: a stochastic, sequential algorithm. -* `Environment 𝓐 𝓨`: a stochastic environment. -* `history A Y n`: the history before time `n`, a random variable with values in `Fin n β†’ 𝓐 Γ— 𝓨`. -* `IsAlgEnvSeq A 𝓨 alg env P`: an algorithm-environment sequence. That is, a sequence of - actions `A` and feedback `Y` that have the correct conditional distributions to be generated by - an algorithm `alg` interacting with an environment `env`, defined on a probability space `(Ξ©, P)`. -* `IsAlgEnvSeqUntil A Y alg env P N`: `A` and `Y` form an algorithm-environment sequence for the - times `n < N`. -* `prod_left alg`: an `Algorithm 𝓐 (𝓧 Γ— 𝓨)` obtained from an algorithm `alg : Algorithm 𝓐 𝓨` by - ignoring the `𝓧` component of each observation. +* `Round π“ž 𝓐 𝓨`: one round of interaction, an observation-action-feedback triple. +* `Hist π“ž 𝓐 𝓨 n`: a history of `n` complete rounds. +* `Algorithm π“ž 𝓐 𝓨`: a stochastic, sequential algorithm. +* `Environment π“ž 𝓐 𝓨`: a stochastic environment. +* `history O A Y n`: the history before time `n`, a random variable with values in `Hist π“ž 𝓐 𝓨 n`. +* `IsAlgEnvSeq O A Y alg env P`: an algorithm-environment sequence. That is, a sequence of + observations `O`, actions `A` and feedbacks `Y` that have the correct conditional distributions + to be generated by an algorithm `alg` interacting with an environment `env`, defined on a + probability space `(Ξ©, P)`. +* `IsAlgEnvSeqUntil O A Y alg env P N`: `O`, `A` and `Y` form an algorithm-environment sequence for + the times `n < N`. +* `prodLeft alg`: an `Algorithm π“ž 𝓐 (𝓧 Γ— 𝓨)` obtained from an algorithm `alg : Algorithm π“ž 𝓐 𝓨` by + ignoring the `𝓧` component of each feedback. -/ @@ -42,149 +49,239 @@ open MeasureTheory ProbabilityTheory Filter Real Finset open scoped ENNReal NNReal +-- TODO: this belongs to Mathlib. +instance Prod.instUnique {Ξ± Ξ² : Type*} [Unique Ξ±] [Unique Ξ²] : Unique (Ξ± Γ— Ξ²) where + default := (default, default) + uniq p := by simp [Prod.ext_iff, Unique.eq_default] + namespace Learning -variable {𝓐 𝓨 Ξ© : Type*} {m𝓐 : MeasurableSpace 𝓐} {m𝓨 : MeasurableSpace 𝓨} {mΞ© : MeasurableSpace Ξ©} +variable {π“ž 𝓐 𝓨 Ξ© : Type*} {mπ“ž : MeasurableSpace π“ž} {m𝓐 : MeasurableSpace 𝓐} + {m𝓨 : MeasurableSpace 𝓨} {mΞ© : MeasurableSpace Ξ©} -/-- A stochastic, sequential algorithm. -/ -structure Algorithm (𝓐 𝓨 : Type*) [MeasurableSpace 𝓐] [MeasurableSpace 𝓨] where - /-- Policy or sampling rule: distribution of the action at time `n` given the history of the - `n` previous action-feedback pairs. -/ - policy : (n : β„•) β†’ Kernel (Fin n β†’ 𝓐 Γ— 𝓨) 𝓐 - /-- The policy is a Markov kernel. -/ - [h_policy : βˆ€ n, IsMarkovKernel (policy n)] +/-- One round of interaction: an observation, then an action, then a feedback. -/ +abbrev Round (π“ž 𝓐 𝓨 : Type*) := π“ž Γ— 𝓐 Γ— 𝓨 + +/-- The observation of a round. -/ +def Round.obs (r : Round π“ž 𝓐 𝓨) : π“ž := r.1 +/-- The action of a round. -/ +def Round.action (r : Round π“ž 𝓐 𝓨) : 𝓐 := r.2.1 +/-- The feedback of a round. -/ +def Round.feedback (r : Round π“ž 𝓐 𝓨) : 𝓨 := r.2.2 + +namespace Round + +@[simp] lemma obs_mk (o : π“ž) (a : 𝓐) (y : 𝓨) : Round.obs (o, a, y) = o := rfl +@[simp] lemma action_mk (o : π“ž) (a : 𝓐) (y : 𝓨) : Round.action (o, a, y) = a := rfl +@[simp] lemma feedback_mk (o : π“ž) (a : 𝓐) (y : 𝓨) : Round.feedback (o, a, y) = y := rfl + +@[simp] +lemma mk_obs_action_feedback (r : Round π“ž 𝓐 𝓨) : (r.obs, r.action, r.feedback) = r := rfl + +lemma obs_eq_fst (r : Round π“ž 𝓐 𝓨) : r.obs = r.1 := rfl +lemma action_eq_snd_fst (r : Round π“ž 𝓐 𝓨) : r.action = r.2.1 := rfl +lemma feedback_eq_snd_snd (r : Round π“ž 𝓐 𝓨) : r.feedback = r.2.2 := rfl + +@[fun_prop] +lemma measurable_obs : Measurable (Round.obs (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨)) := measurable_fst + +@[fun_prop] +lemma measurable_action : Measurable (Round.action (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨)) := + measurable_snd.fst + +@[fun_prop] +lemma measurable_feedback : Measurable (Round.feedback (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨)) := + measurable_snd.snd -instance (alg : Algorithm 𝓐 𝓨) (n : β„•) : IsMarkovKernel (alg.policy n) := alg.h_policy n +end Round -/-- Distribution of the first action: the policy at time `0` applied to the empty history. -/ -def Algorithm.p0 (alg : Algorithm 𝓐 𝓨) : Measure 𝓐 := - alg.policy 0 default +/-- History of `n` complete rounds; `n = 0` is the empty history. -/ +abbrev Hist (π“ž 𝓐 𝓨 : Type*) (n : β„•) := Fin n β†’ Round π“ž 𝓐 𝓨 + +/-- A stochastic, sequential algorithm. +At each round, it sees an observation in `π“ž`, then takes an action in `𝓐`, and finally receives +feedback in `𝓨`. The action is a random function of the past rounds and the current observation. -/ +structure Algorithm (π“ž 𝓐 𝓨 : Type*) [MeasurableSpace π“ž] [MeasurableSpace 𝓐] [MeasurableSpace 𝓨] + where + /-- Law of the action of round `n` given the past rounds and the current observation. -/ + policy : (n : β„•) β†’ Kernel (Hist π“ž 𝓐 𝓨 n Γ— π“ž) 𝓐 + /-- The policy is a Markov kernel. -/ + [isMarkovKernel_policy : βˆ€ n, IsMarkovKernel (policy n)] + +instance (alg : Algorithm π“ž 𝓐 𝓨) (n : β„•) : IsMarkovKernel (alg.policy n) := + alg.isMarkovKernel_policy n + +/-- A stochastic environment. +At each round, an observation is drawn prior to the algorithm taking an action. Then the environment +provides feedback based on the observation and the action. -/ +structure Environment (π“ž 𝓐 𝓨 : Type*) [MeasurableSpace π“ž] [MeasurableSpace 𝓐] [MeasurableSpace 𝓨] + where + /-- Law of the observation of round `n` given the past rounds. -/ + obs : (n : β„•) β†’ Kernel (Hist π“ž 𝓐 𝓨 n) π“ž + /-- Law of the feedback of round `n` given the past rounds, the observation and the action. -/ + feedback : (n : β„•) β†’ Kernel ((Hist π“ž 𝓐 𝓨 n Γ— π“ž) Γ— 𝓐) 𝓨 + /-- The observation kernel is a Markov kernel. -/ + [isMarkovKernel_obs : βˆ€ n, IsMarkovKernel (obs n)] + /-- The feedback kernel is a Markov kernel. -/ + [isMarkovKernel_feedback : βˆ€ n, IsMarkovKernel (feedback n)] + +instance (env : Environment π“ž 𝓐 𝓨) (n : β„•) : IsMarkovKernel (env.obs n) := env.isMarkovKernel_obs n +instance (env : Environment π“ž 𝓐 𝓨) (n : β„•) : IsMarkovKernel (env.feedback n) := + env.isMarkovKernel_feedback n + +/-- Distribution of the first observation: the observation kernel at time `0` applied to the empty +history. -/ +def Environment.obs0 (env : Environment π“ž 𝓐 𝓨) : Measure π“ž := + env.obs 0 default deriving IsProbabilityMeasure -lemma Algorithm.p0_def (alg : Algorithm 𝓐 𝓨) : alg.p0 = alg.policy 0 default := rfl +lemma Environment.obs0_def (env : Environment π“ž 𝓐 𝓨) : env.obs0 = env.obs 0 default := rfl + +lemma Environment.obs_zero (env : Environment π“ž 𝓐 𝓨) (h : Hist π“ž 𝓐 𝓨 0) : + env.obs 0 h = env.obs0 := by + rw [Unique.eq_default h] + rfl + +/-- Distribution of the first action given the first observation: the policy at time `0` applied to +the empty history. -/ +noncomputable def Algorithm.p0 (alg : Algorithm π“ž 𝓐 𝓨) : Kernel π“ž 𝓐 := + (alg.policy 0).sectR default +deriving IsMarkovKernel + +lemma Algorithm.p0_def (alg : Algorithm π“ž 𝓐 𝓨) : alg.p0 = (alg.policy 0).sectR default := rfl -lemma Algorithm.policy_zero (alg : Algorithm 𝓐 𝓨) (h : Fin 0 β†’ 𝓐 Γ— 𝓨) : - alg.policy 0 h = alg.p0 := by +lemma Algorithm.p0_apply (alg : Algorithm π“ž 𝓐 𝓨) (o : π“ž) : + alg.p0 o = alg.policy 0 (default, o) := rfl + +lemma Algorithm.policy_zero (alg : Algorithm π“ž 𝓐 𝓨) (h : Hist π“ž 𝓐 𝓨 0) (o : π“ž) : + alg.policy 0 (h, o) = alg.p0 o := by rw [Unique.eq_default h] rfl -/-- An algorithm with observations in `𝓧 Γ— 𝓨` obtained from an algorithm with observations in `𝓨` -by ignoring the `𝓧` component of each observation. -/ +/-- An algorithm with feedback in `𝓧 Γ— 𝓨` obtained from an algorithm with feedback in `𝓨` +by ignoring the `𝓧` component of each feedback. -/ @[simps] -def Algorithm.prodLeft (𝓧 : Type*) [MeasurableSpace 𝓧] (alg : Algorithm 𝓐 𝓨) : - Algorithm 𝓐 (𝓧 Γ— 𝓨) where - policy n := (alg.policy n).comap (fun h i ↦ ((h i).1, (h i).2.2)) (by fun_prop) +def Algorithm.prodLeft (𝓧 : Type*) [MeasurableSpace 𝓧] (alg : Algorithm π“ž 𝓐 𝓨) : + Algorithm π“ž 𝓐 (𝓧 Γ— 𝓨) where + policy n := (alg.policy n).comap + (fun p ↦ (fun i ↦ ((p.1 i).obs, (p.1 i).action, (p.1 i).feedback.2), p.2)) (by fun_prop) @[simp] -lemma Algorithm.prodLeft_p0 (𝓧 : Type*) [MeasurableSpace 𝓧] (alg : Algorithm 𝓐 𝓨) : +lemma Algorithm.prodLeft_p0 (𝓧 : Type*) [MeasurableSpace 𝓧] (alg : Algorithm π“ž 𝓐 𝓨) : (alg.prodLeft 𝓧).p0 = alg.p0 := by - rw [p0_def, prodLeft_policy, Kernel.comap_apply, policy_zero] - -/-- A stochastic environment. -/ -structure Environment (𝓐 𝓨 : Type*) [MeasurableSpace 𝓐] [MeasurableSpace 𝓨] where - /-- Distribution of the feedback at time `n` as function of the history of the `n` previous - action-feedback pairs and of the action at time `n`. -/ - feedback : (n : β„•) β†’ Kernel ((Fin n β†’ 𝓐 Γ— 𝓨) Γ— 𝓐) 𝓨 - /-- The feedback kernels are Markov kernels. -/ - [h_feedback : βˆ€ n, IsMarkovKernel (feedback n)] - -instance (env : Environment 𝓐 𝓨) (n : β„•) : IsMarkovKernel (env.feedback n) := env.h_feedback n - -/-- Distribution of the first feedback given the first action: the feedback kernel at time `0` -applied to the empty history. -/ -noncomputable def Environment.Ξ½0 (env : Environment 𝓐 𝓨) : Kernel 𝓐 𝓨 := - (env.feedback 0).sectR default + ext o : 1 + rw [p0_apply, prodLeft_policy, Kernel.comap_apply, policy_zero, p0_apply] + +/-- Distribution of the first feedback given the first observation and action: the feedback kernel +at time `0` applied to the empty history. -/ +noncomputable def Environment.Ξ½0 (env : Environment π“ž 𝓐 𝓨) : Kernel (π“ž Γ— 𝓐) 𝓨 := + (env.feedback 0).comap (fun p ↦ ((default, p.1), p.2)) (by fun_prop) deriving IsMarkovKernel -lemma Environment.Ξ½0_def (env : Environment 𝓐 𝓨) : env.Ξ½0 = (env.feedback 0).sectR default := rfl +lemma Environment.Ξ½0_def (env : Environment π“ž 𝓐 𝓨) : + env.Ξ½0 = (env.feedback 0).comap (fun p ↦ ((default, p.1), p.2)) (by fun_prop) := rfl -lemma Environment.Ξ½0_apply (env : Environment 𝓐 𝓨) (a : 𝓐) : - env.Ξ½0 a = env.feedback 0 (default, a) := rfl +lemma Environment.Ξ½0_apply (env : Environment π“ž 𝓐 𝓨) (o : π“ž) (a : 𝓐) : + env.Ξ½0 (o, a) = env.feedback 0 ((default, o), a) := rfl -lemma Environment.feedback_zero (env : Environment 𝓐 𝓨) (h : Fin 0 β†’ 𝓐 Γ— 𝓨) (a : 𝓐) : - env.feedback 0 (h, a) = env.Ξ½0 a := by +lemma Environment.feedback_zero (env : Environment π“ž 𝓐 𝓨) (h : Hist π“ž 𝓐 𝓨 0) (o : π“ž) (a : 𝓐) : + env.feedback 0 ((h, o), a) = env.Ξ½0 (o, a) := by rw [Unique.eq_default h] rfl -/-- Kernel describing the distribution of the action-feedback pair at time `n` given the history -before `n`. -/ +/-- Kernel describing the distribution of the round at time `n` given the history before `n`. -/ noncomputable -def stepKernel (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) (n : β„•) : - Kernel (Fin n β†’ 𝓐 Γ— 𝓨) (𝓐 Γ— 𝓨) := - alg.policy n βŠ—β‚– env.feedback n +def stepKernel (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (n : β„•) : + Kernel (Hist π“ž 𝓐 𝓨 n) (Round π“ž 𝓐 𝓨) := + env.obs n βŠ—β‚– (alg.policy n βŠ—β‚– env.feedback n) deriving IsMarkovKernel -lemma stepKernel_def (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) (n : β„•) : - stepKernel alg env n = alg.policy n βŠ—β‚– env.feedback n := rfl +lemma stepKernel_def (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (n : β„•) : + stepKernel alg env n = env.obs n βŠ—β‚– (alg.policy n βŠ—β‚– env.feedback n) := rfl @[simp] -lemma fst_stepKernel (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) (n : β„•) : - (stepKernel alg env n).fst = alg.policy n := by +lemma fst_stepKernel (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (n : β„•) : + (stepKernel alg env n).fst = env.obs n := by rw [stepKernel, Kernel.fst_compProd] -lemma stepKernel_zero (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) (h : Fin 0 β†’ 𝓐 Γ— 𝓨) : - stepKernel alg env 0 h = alg.p0 βŠ—β‚˜ env.Ξ½0 := by +lemma stepKernel_zero (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (h : Hist π“ž 𝓐 𝓨 0) : + stepKernel alg env 0 h = env.obs0 βŠ—β‚˜ (alg.p0 βŠ—β‚– env.Ξ½0) := by rw [Unique.eq_default h, stepKernel, Kernel.compProd_apply_eq_compProd_sectR] + congr 1 + ext o s hs + rw [Kernel.sectR_apply, Kernel.compProd_apply hs, Kernel.compProd_apply hs] rfl section IsAlgEnvSeq -variable {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {alg : Algorithm 𝓐 𝓨} {env : Environment 𝓐 𝓨} +variable {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} + {alg : Algorithm π“ž 𝓐 𝓨} {env : Environment π“ž 𝓐 𝓨} {P : Measure Ξ©} [IsFiniteMeasure P] {N : β„•} -/-- Step of the algorithm-environment sequence: the action-feedback pair at time `n`. -/ -def step (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) (n : β„•) (Ο‰ : Ξ©) : 𝓐 Γ— 𝓨 := - (A n Ο‰, Y n Ο‰) +/-- Step of the algorithm-environment sequence: the round at time `n`. -/ +def step (O : β„• β†’ Ξ© β†’ π“ž) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) (n : β„•) (Ο‰ : Ξ©) : Round π“ž 𝓐 𝓨 := + (O n Ο‰, A n Ο‰, Y n Ο‰) + +@[simp] lemma obs_step (n : β„•) (Ο‰ : Ξ©) : (step O A Y n Ο‰).obs = O n Ο‰ := rfl +@[simp] lemma action_step (n : β„•) (Ο‰ : Ξ©) : (step O A Y n Ο‰).action = A n Ο‰ := rfl +@[simp] lemma feedback_step (n : β„•) (Ο‰ : Ξ©) : (step O A Y n Ο‰).feedback = Y n Ο‰ := rfl @[fun_prop] -lemma measurable_step (n : β„•) (hA : Measurable (A n)) (hY : Measurable (Y n)) : - Measurable (step A Y n) := by +lemma measurable_step (n : β„•) (hO : Measurable (O n)) (hA : Measurable (A n)) + (hY : Measurable (Y n)) : + Measurable (step O A Y n) := by unfold step fun_prop -/-- A random variable that gives the sequence of action-feedback pairs. -/ -def trajectory (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) (Ο‰ : Ξ©) : β„• β†’ 𝓐 Γ— 𝓨 := fun n ↦ (A n Ο‰, Y n Ο‰) +/-- A random variable that gives the sequence of rounds. -/ +def trajectory (O : β„• β†’ Ξ© β†’ π“ž) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) (Ο‰ : Ξ©) : β„• β†’ Round π“ž 𝓐 𝓨 := + fun n ↦ (O n Ο‰, A n Ο‰, Y n Ο‰) @[fun_prop] -lemma measurable_trajectory {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} (hA : βˆ€ n, Measurable (A n)) - (hR : βˆ€ n, Measurable (Y n)) : Measurable (trajectory A Y) := by +lemma measurable_trajectory {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} + (hO : βˆ€ n, Measurable (O n)) (hA : βˆ€ n, Measurable (A n)) + (hR : βˆ€ n, Measurable (Y n)) : Measurable (trajectory O A Y) := by unfold trajectory fun_prop -/-- History of the algorithm-environment sequence before time `n`: the action-feedback pairs at +/-- History of the algorithm-environment sequence before time `n`: the rounds at times `0, ..., n - 1`. -/ -def history (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) (n : β„•) (Ο‰ : Ξ©) : Fin n β†’ 𝓐 Γ— 𝓨 := - fun i ↦ (A i Ο‰, Y i Ο‰) +def history (O : β„• β†’ Ξ© β†’ π“ž) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) (n : β„•) (Ο‰ : Ξ©) : Hist π“ž 𝓐 𝓨 n := + fun i ↦ (O i Ο‰, A i Ο‰, Y i Ο‰) -lemma history_apply (n : β„•) (Ο‰ : Ξ©) (i : Fin n) : history A Y n Ο‰ i = (A i Ο‰, Y i Ο‰) := rfl +lemma history_apply (n : β„•) (Ο‰ : Ξ©) (i : Fin n) : + history O A Y n Ο‰ i = (O i Ο‰, A i Ο‰, Y i Ο‰) := rfl @[simp] -lemma history_zero : history A Y 0 = fun _ ↦ (default : Fin 0 β†’ 𝓐 Γ— 𝓨) := Unique.eq_default _ +lemma history_zero : history O A Y 0 = fun _ ↦ (default : Hist π“ž 𝓐 𝓨 0) := Unique.eq_default _ @[fun_prop] -lemma measurable_history (hA : βˆ€ n, Measurable (A n)) +lemma measurable_history (hO : βˆ€ n, Measurable (O n)) (hA : βˆ€ n, Measurable (A n)) (hY : βˆ€ n, Measurable (Y n)) (n : β„•) : - Measurable (history A Y n) := by + Measurable (history O A Y n) := by unfold history fun_prop lemma eval_comp_history (n : β„•) : - (fun x ↦ x (Fin.last n)) ∘ (history A Y (n + 1)) = step A Y n := rfl + (fun x ↦ x (Fin.last n)) ∘ (history O A Y (n + 1)) = step O A Y n := rfl + +lemma obs_eval_comp_history (n : β„•) : + (fun x ↦ (x (Fin.last n)).obs) ∘ (history O A Y (n + 1)) = O n := rfl -lemma fst_eval_comp_history (n : β„•) : - (fun x ↦ (x (Fin.last n)).1) ∘ (history A Y (n + 1)) = A n := rfl +lemma action_eval_comp_history (n : β„•) : + (fun x ↦ (x (Fin.last n)).action) ∘ (history O A Y (n + 1)) = A n := rfl -lemma snd_eval_comp_history (n : β„•) : - (fun x ↦ (x (Fin.last n)).2) ∘ (history A Y (n + 1)) = Y n := rfl +lemma feedback_eval_comp_history (n : β„•) : + (fun x ↦ (x (Fin.last n)).feedback) ∘ (history O A Y (n + 1)) = Y n := rfl /-- The history before time `m` is a restriction of the history before time `n β‰₯ m`. -/ lemma history_eq_comp_history {m n : β„•} (hmn : m ≀ n) : - history A Y m = (fun h (i : Fin m) ↦ h (Fin.castLE hmn i)) ∘ history A Y n := rfl + history O A Y m = (fun h (i : Fin m) ↦ h (Fin.castLE hmn i)) ∘ history O A Y n := rfl lemma history_succ (n : β„•) : - history A Y (n + 1) = - (MeasurableEquiv.finSuccProd (𝓐 Γ— 𝓨) n).symm ∘ - (fun Ο‰ ↦ (history A Y n Ο‰, step A Y n Ο‰)) := by + history O A Y (n + 1) = + (MeasurableEquiv.finSuccProd (Round π“ž 𝓐 𝓨) n).symm ∘ + (fun Ο‰ ↦ (history O A Y n Ο‰, step O A Y n Ο‰)) := by funext Ο‰ simp only [Function.comp_apply, MeasurableEquiv.finSuccProd_symm_apply] funext i @@ -192,166 +289,211 @@ lemma history_succ (n : β„•) : Β· simp [history, step] Β· simp [history] -/-- An algorithm-environment sequence: a sequence of actions and feedbacks generated +/-- An algorithm-environment sequence: a sequence of observations, actions and feedbacks generated by an algorithm interacting with an environment. -/ structure IsAlgEnvSeq - (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) + (O : β„• β†’ Ξ© β†’ π“ž) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) + (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (P : Measure Ξ©) [IsFiniteMeasure P] : Prop where + /-- The observation sequence is measurable. -/ + measurable_obs n : Measurable (O n) := by fun_prop /-- The action sequence is measurable. -/ measurable_action n : Measurable (A n) := by fun_prop /-- The feedback sequence is measurable. -/ measurable_feedback n : Measurable (Y n) := by fun_prop - /-- The action at time `n` has the correct conditional distribution given the history. -/ + /-- The observation at time `n` has the correct conditional distribution given the history. -/ + hasCondDistrib_obs n : + HasCondDistrib (O n) (history O A Y n) (env.obs n) P + /-- The action at time `n` has the correct conditional distribution given the history and the + observation at time `n`. -/ hasCondDistrib_action n : - HasCondDistrib (A n) (history A Y n) (alg.policy n) P - /-- The feedback at time `n` has the correct conditional distribution given the history and - the action at time `n`. -/ + HasCondDistrib (A n) (fun Ο‰ ↦ (history O A Y n Ο‰, O n Ο‰)) (alg.policy n) P + /-- The feedback at time `n` has the correct conditional distribution given the history, the + observation and the action at time `n`. -/ hasCondDistrib_feedback n : - HasCondDistrib (Y n) (fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) (env.feedback n) P + HasCondDistrib (Y n) (fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) (env.feedback n) P -/-- An algorithm-environment sequence until time `N`: a sequence of actions and feedbacks such that -the actions and feedbacks at times `n < N` are generated by an algorithm interacting with -an environment. In particular, the law of `history A Y N` is determined. -/ +/-- An algorithm-environment sequence until time `N`: a sequence of observations, actions and +feedbacks such that the rounds at times `n < N` are generated by an algorithm interacting with +an environment. In particular, the law of `history O A Y N` is determined. -/ structure IsAlgEnvSeqUntil - (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) + (O : β„• β†’ Ξ© β†’ π“ž) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) + (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (P : Measure Ξ©) [IsFiniteMeasure P] (N : β„•) : Prop where + /-- The observation sequence is measurable. -/ + measurable_obs n : Measurable (O n) := by fun_prop /-- The action sequence is measurable. -/ measurable_action n : Measurable (A n) := by fun_prop /-- The feedback sequence is measurable. -/ measurable_feedback n : Measurable (Y n) := by fun_prop - /-- The action at time `n < N` has the correct conditional distribution given the history. -/ + /-- The observation at time `n < N` has the correct conditional distribution given the history. -/ + hasCondDistrib_obs n (hn : n < N) : + HasCondDistrib (O n) (history O A Y n) (env.obs n) P + /-- The action at time `n < N` has the correct conditional distribution given the history and the + observation at time `n`. -/ hasCondDistrib_action n (hn : n < N) : - HasCondDistrib (A n) (history A Y n) (alg.policy n) P - /-- The feedback at time `n < N` has the correct conditional distribution given the history and - the action at time `n`. -/ + HasCondDistrib (A n) (fun Ο‰ ↦ (history O A Y n Ο‰, O n Ο‰)) (alg.policy n) P + /-- The feedback at time `n < N` has the correct conditional distribution given the history, the + observation and the action at time `n`. -/ hasCondDistrib_feedback n (hn : n < N) : - HasCondDistrib (Y n) (fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) (env.feedback n) P + HasCondDistrib (Y n) (fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) (env.feedback n) P -lemma IsAlgEnvSeqUntil.mono (h : IsAlgEnvSeqUntil A Y alg env P N) {N' : β„•} (hN : N' ≀ N) : - IsAlgEnvSeqUntil A Y alg env P N' where +lemma IsAlgEnvSeqUntil.mono (h : IsAlgEnvSeqUntil O A Y alg env P N) {N' : β„•} (hN : N' ≀ N) : + IsAlgEnvSeqUntil O A Y alg env P N' where + measurable_obs := h.measurable_obs measurable_action := h.measurable_action measurable_feedback := h.measurable_feedback + hasCondDistrib_obs n hn := h.hasCondDistrib_obs n (hn.trans_le hN) hasCondDistrib_action n hn := h.hasCondDistrib_action n (hn.trans_le hN) hasCondDistrib_feedback n hn := h.hasCondDistrib_feedback n (hn.trans_le hN) -lemma IsAlgEnvSeq.isAlgEnvSeqUntil (h : IsAlgEnvSeq A Y alg env P) (N : β„•) : - IsAlgEnvSeqUntil A Y alg env P N where +lemma IsAlgEnvSeq.isAlgEnvSeqUntil (h : IsAlgEnvSeq O A Y alg env P) (N : β„•) : + IsAlgEnvSeqUntil O A Y alg env P N where + measurable_obs := h.measurable_obs measurable_action := h.measurable_action measurable_feedback := h.measurable_feedback + hasCondDistrib_obs n _ := h.hasCondDistrib_obs n hasCondDistrib_action n _ := h.hasCondDistrib_action n hasCondDistrib_feedback n _ := h.hasCondDistrib_feedback n lemma isAlgEnvSeq_iff_forall_isAlgEnvSeqUntil : - IsAlgEnvSeq A Y alg env P ↔ βˆ€ N, IsAlgEnvSeqUntil A Y alg env P N where + IsAlgEnvSeq O A Y alg env P ↔ βˆ€ N, IsAlgEnvSeqUntil O A Y alg env P N where mp h N := h.isAlgEnvSeqUntil N mpr h := { + measurable_obs := (h 0).measurable_obs measurable_action := (h 0).measurable_action measurable_feedback := (h 0).measurable_feedback + hasCondDistrib_obs n := (h (n + 1)).hasCondDistrib_obs n n.lt_succ_self hasCondDistrib_action n := (h (n + 1)).hasCondDistrib_action n n.lt_succ_self hasCondDistrib_feedback n := (h (n + 1)).hasCondDistrib_feedback n n.lt_succ_self } @[fun_prop] -lemma IsAlgEnvSeq.measurable_step (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : - Measurable (step A Y n) := by +lemma IsAlgEnvSeq.measurable_step (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + Measurable (step O A Y n) := by + have hO := h.measurable_obs have hA := h.measurable_action have hY := h.measurable_feedback fun_prop @[fun_prop] -lemma IsAlgEnvSeq.measurable_history (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : - Measurable (history A Y n) := by +lemma IsAlgEnvSeq.measurable_history (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + Measurable (history O A Y n) := by + have hO := h.measurable_obs have hA := h.measurable_action have hY := h.measurable_feedback fun_prop @[fun_prop] -lemma IsAlgEnvSeq.measurable_trajectory (h : IsAlgEnvSeq A Y alg env P) : - Measurable (trajectory A Y) := - Learning.measurable_trajectory h.measurable_action h.measurable_feedback +lemma IsAlgEnvSeq.measurable_trajectory (h : IsAlgEnvSeq O A Y alg env P) : + Measurable (trajectory O A Y) := + Learning.measurable_trajectory h.measurable_obs h.measurable_action h.measurable_feedback @[fun_prop] -lemma IsAlgEnvSeqUntil.measurable_step (h : IsAlgEnvSeqUntil A Y alg env P N) (n : β„•) : - Measurable (step A Y n) := by +lemma IsAlgEnvSeqUntil.measurable_step (h : IsAlgEnvSeqUntil O A Y alg env P N) (n : β„•) : + Measurable (step O A Y n) := by + have hO := h.measurable_obs have hA := h.measurable_action have hY := h.measurable_feedback fun_prop @[fun_prop] -lemma IsAlgEnvSeqUntil.measurable_history (h : IsAlgEnvSeqUntil A Y alg env P N) (n : β„•) : - Measurable (history A Y n) := by +lemma IsAlgEnvSeqUntil.measurable_history (h : IsAlgEnvSeqUntil O A Y alg env P N) (n : β„•) : + Measurable (history O A Y n) := by + have hO := h.measurable_obs have hA := h.measurable_action have hY := h.measurable_feedback fun_prop -lemma IsAlgEnvSeq.hasCondDistrib_step (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : - HasCondDistrib (step A Y n) (history A Y n) (stepKernel alg env n) P := - HasCondDistrib.prod (h.hasCondDistrib_action n) (h.hasCondDistrib_feedback n) +lemma IsAlgEnvSeq.hasCondDistrib_step (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + HasCondDistrib (step O A Y n) (history O A Y n) (stepKernel alg env n) P := + (h.hasCondDistrib_obs n).prod + ((h.hasCondDistrib_action n).prod (h.hasCondDistrib_feedback n)) -lemma IsAlgEnvSeqUntil.hasCondDistrib_step (h : IsAlgEnvSeqUntil A Y alg env P N) +lemma IsAlgEnvSeqUntil.hasCondDistrib_step (h : IsAlgEnvSeqUntil O A Y alg env P N) (n : β„•) (hn : n < N) : - HasCondDistrib (step A Y n) (history A Y n) (stepKernel alg env n) P := - HasCondDistrib.prod (h.hasCondDistrib_action n hn) (h.hasCondDistrib_feedback n hn) + HasCondDistrib (step O A Y n) (history O A Y n) (stepKernel alg env n) P := + (h.hasCondDistrib_obs n hn).prod + ((h.hasCondDistrib_action n hn).prod (h.hasCondDistrib_feedback n hn)) section Zero /-! ### Laws at time `0` -At time `0` the history is the unique element of `Fin 0 β†’ 𝓐 Γ— 𝓨`: conditioning on it is the same +At time `0` the history is the unique element of `Hist π“ž 𝓐 𝓨 0`: conditioning on it is the same as not conditioning. Note that those results need `P` to be a probability measure. -/ variable [IsProbabilityMeasure P] omit [IsFiniteMeasure P] in /-- The history before time `0` is a constant. -/ -lemma hasLaw_history_zero (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) : - HasLaw (history A Y 0) (Measure.dirac default) P where +lemma hasLaw_history_zero (O : β„• β†’ Ξ© β†’ π“ž) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) : + HasLaw (history O A Y 0) (Measure.dirac default) P where aemeasurable := by rw [history_zero]; exact aemeasurable_const map_eq := by rw [history_zero, Measure.map_const, measure_univ, one_smul] -lemma IsAlgEnvSeqUntil.hasLaw_action_zero (h : IsAlgEnvSeqUntil A Y alg env P N) (hN : 0 < N) : - HasLaw (A 0) alg.p0 P := by - have h0 := h.hasCondDistrib_action 0 hN +lemma IsAlgEnvSeqUntil.hasLaw_obs_zero (h : IsAlgEnvSeqUntil O A Y alg env P N) (hN : 0 < N) : + HasLaw (O 0) env.obs0 P := by + have h0 := h.hasCondDistrib_obs 0 hN rw [history_zero] at h0 exact h0.hasLaw_of_const' -lemma IsAlgEnvSeq.hasLaw_action_zero (h : IsAlgEnvSeq A Y alg env P) : - HasLaw (A 0) alg.p0 P := - (h.isAlgEnvSeqUntil 1).hasLaw_action_zero zero_lt_one +lemma IsAlgEnvSeq.hasLaw_obs_zero (h : IsAlgEnvSeq O A Y alg env P) : + HasLaw (O 0) env.obs0 P := + (h.isAlgEnvSeqUntil 1).hasLaw_obs_zero zero_lt_one + +omit [IsProbabilityMeasure P] in +lemma IsAlgEnvSeqUntil.hasCondDistrib_action_zero (h : IsAlgEnvSeqUntil O A Y alg env P N) + (hN : 0 < N) : + HasCondDistrib (A 0) (O 0) alg.p0 P := + hasCondDistrib_prodMk_left_unique_iff.mp (h.hasCondDistrib_action 0 hN) + +omit [IsProbabilityMeasure P] in +lemma IsAlgEnvSeq.hasCondDistrib_action_zero (h : IsAlgEnvSeq O A Y alg env P) : + HasCondDistrib (A 0) (O 0) alg.p0 P := + (h.isAlgEnvSeqUntil 1).hasCondDistrib_action_zero zero_lt_one omit [IsProbabilityMeasure P] in -lemma IsAlgEnvSeqUntil.hasCondDistrib_feedback_zero (h : IsAlgEnvSeqUntil A Y alg env P N) +lemma IsAlgEnvSeqUntil.hasCondDistrib_feedback_zero (h : IsAlgEnvSeqUntil O A Y alg env P N) (hN : 0 < N) : - HasCondDistrib (Y 0) (A 0) env.Ξ½0 P := - hasCondDistrib_prodMk_left_unique_iff.mp (h.hasCondDistrib_feedback 0 hN) + HasCondDistrib (Y 0) (fun Ο‰ ↦ (O 0 Ο‰, A 0 Ο‰)) env.Ξ½0 P := by + have h0 := h.hasCondDistrib_feedback 0 hN + rw [history_zero] at h0 + exact h0.of_measurableEmbedding_comp_right + ((measurableEmbedding_prodMk_left (default : Hist π“ž 𝓐 𝓨 0)).prodMap .id) omit [IsProbabilityMeasure P] in -lemma IsAlgEnvSeq.hasCondDistrib_feedback_zero (h : IsAlgEnvSeq A Y alg env P) : - HasCondDistrib (Y 0) (A 0) env.Ξ½0 P := +lemma IsAlgEnvSeq.hasCondDistrib_feedback_zero (h : IsAlgEnvSeq O A Y alg env P) : + HasCondDistrib (Y 0) (fun Ο‰ ↦ (O 0 Ο‰, A 0 Ο‰)) env.Ξ½0 P := (h.isAlgEnvSeqUntil 1).hasCondDistrib_feedback_zero zero_lt_one -lemma IsAlgEnvSeqUntil.hasLaw_step_zero (h : IsAlgEnvSeqUntil A Y alg env P N) (hN : 0 < N) : - HasLaw (step A Y 0) (alg.p0 βŠ—β‚˜ env.Ξ½0) P := by +lemma IsAlgEnvSeqUntil.hasLaw_step_zero (h : IsAlgEnvSeqUntil O A Y alg env P N) (hN : 0 < N) : + HasLaw (step O A Y 0) (env.obs0 βŠ—β‚˜ (alg.p0 βŠ—β‚– env.Ξ½0)) P := by have h0 := h.hasCondDistrib_step 0 hN rw [history_zero] at h0 rw [← stepKernel_zero alg env default] exact h0.hasLaw_of_const' -lemma IsAlgEnvSeq.hasLaw_step_zero (h : IsAlgEnvSeq A Y alg env P) : - HasLaw (step A Y 0) (alg.p0 βŠ—β‚˜ env.Ξ½0) P := +lemma IsAlgEnvSeq.hasLaw_step_zero (h : IsAlgEnvSeq O A Y alg env P) : + HasLaw (step O A Y 0) (env.obs0 βŠ—β‚˜ (alg.p0 βŠ—β‚– env.Ξ½0)) P := (h.isAlgEnvSeqUntil 1).hasLaw_step_zero zero_lt_one end Zero -lemma IsAlgEnvSeq.hasLaw_action_comp (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : - HasLaw (A n) (alg.policy n βˆ˜β‚˜ (P.map (history A Y n))) P := +lemma IsAlgEnvSeq.hasLaw_obs_comp (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + HasLaw (O n) (env.obs n βˆ˜β‚˜ (P.map (history O A Y n))) P := + HasCondDistrib.hasLaw_comp (h.hasCondDistrib_obs n) + +lemma IsAlgEnvSeq.hasLaw_action_comp (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + HasLaw (A n) (alg.policy n βˆ˜β‚˜ (P.map fun Ο‰ ↦ (history O A Y n Ο‰, O n Ο‰))) P := HasCondDistrib.hasLaw_comp (h.hasCondDistrib_action n) -lemma IsAlgEnvSeq.hasLaw_feedback_comp (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : - HasLaw (Y n) ((env.feedback n) βˆ˜β‚˜ (P.map fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰))) P := +lemma IsAlgEnvSeq.hasLaw_feedback_comp (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + HasLaw (Y n) + ((env.feedback n) βˆ˜β‚˜ (P.map fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰))) P := HasCondDistrib.hasLaw_comp (h.hasCondDistrib_feedback n) -lemma IsAlgEnvSeq.hasLaw_step_comp (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : - HasLaw (step A Y n) (stepKernel alg env n βˆ˜β‚˜ (P.map (history A Y n))) P := +lemma IsAlgEnvSeq.hasLaw_step_comp (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + HasLaw (step O A Y n) (stepKernel alg env n βˆ˜β‚˜ (P.map (history O A Y n))) P := HasCondDistrib.hasLaw_comp (h.hasCondDistrib_step n) section Filtration @@ -359,102 +501,181 @@ section Filtration namespace IsAlgEnvSeq /-- Filtration generated by the history up to time `n` (included): `h.filtration n` is the -Οƒ-algebra generated by `history A Y (n + 1)`, that is by the action-feedback pairs at times -`0, ..., n`. -/ -def filtration (h : IsAlgEnvSeq A Y alg env P) : +Οƒ-algebra generated by `history O A Y (n + 1)`, that is by the rounds at times `0, ..., n`. -/ +def filtration (h : IsAlgEnvSeq O A Y alg env P) : Filtration β„• mΞ© where - seq n := MeasurableSpace.comap (history A Y (n + 1)) inferInstance + seq n := MeasurableSpace.comap (history O A Y (n + 1)) inferInstance mono' i j hij := by simp only rw [← measurable_iff_comap_le, history_eq_comp_history (Nat.succ_le_succ hij)] exact measurable_comp_comap _ (by fun_prop) le' i := by rw [← measurable_iff_comap_le] - exact Learning.measurable_history h.measurable_action h.measurable_feedback _ + exact Learning.measurable_history h.measurable_obs h.measurable_action h.measurable_feedback _ -lemma filtration_eq_comap (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : - h.filtration n = MeasurableSpace.comap (history A Y (n + 1)) inferInstance := rfl +lemma filtration_eq_comap (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + h.filtration n = MeasurableSpace.comap (history O A Y (n + 1)) inferInstance := rfl -lemma measurable_history_succ_filtration (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : - Measurable[h.filtration n] (history A Y (n + 1)) := +lemma measurable_history_succ_filtration (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + Measurable[h.filtration n] (history O A Y (n + 1)) := measurable_iff_comap_le.mpr le_rfl -lemma adapted_history (h : IsAlgEnvSeq A Y alg env P) : - Adapted h.filtration (history A Y) := by +lemma adapted_history (h : IsAlgEnvSeq O A Y alg env P) : + Adapted h.filtration (history O A Y) := by intro n rw [history_eq_comp_history n.le_succ] exact measurable_comp_comap _ (by fun_prop) -lemma adapted_step (h : IsAlgEnvSeq A Y alg env P) : - Adapted h.filtration (step A Y) := by +lemma adapted_step (h : IsAlgEnvSeq O A Y alg env P) : + Adapted h.filtration (step O A Y) := by intro n rw [← eval_comp_history] exact measurable_comp_comap _ (by fun_prop) -lemma adapted_action (h : IsAlgEnvSeq A Y alg env P) : +lemma adapted_obs (h : IsAlgEnvSeq O A Y alg env P) : + Adapted h.filtration O := by + intro n + rw [← obs_eval_comp_history (O := O) (A := A) (Y := Y) n] + exact measurable_comp_comap _ (by fun_prop) + +lemma adapted_action (h : IsAlgEnvSeq O A Y alg env P) : Adapted h.filtration A := by intro n - rw [← fst_eval_comp_history (A := A) (Y := Y) n] + rw [← action_eval_comp_history (O := O) (A := A) (Y := Y) n] exact measurable_comp_comap _ (by fun_prop) -lemma adapted_feedback (h : IsAlgEnvSeq A Y alg env P) : +lemma adapted_feedback (h : IsAlgEnvSeq O A Y alg env P) : Adapted h.filtration Y := by intro n - rw [← snd_eval_comp_history (A := A) (Y := Y) n] + rw [← feedback_eval_comp_history (O := O) (A := A) (Y := Y) n] exact measurable_comp_comap _ (by fun_prop) -/-- Filtration generated by the history before time `n` together with the action at time `n`. -/ -def filtrationAction (h : IsAlgEnvSeq A Y alg env P) : +/-- Filtration generated by the history before time `n` together with the observation at +time `n`. -/ +def filtrationObs (h : IsAlgEnvSeq O A Y alg env P) : + Filtration β„• mΞ© where + seq n := MeasurableSpace.comap (fun Ο‰ ↦ (history O A Y n Ο‰, O n Ο‰)) inferInstance + mono' n m hnm := by + simp only + rw [← measurable_iff_comap_le] + rcases eq_or_lt_of_le hnm with rfl | hlt + Β· exact measurable_iff_comap_le.mpr le_rfl + have : (fun Ο‰ ↦ (history O A Y n Ο‰, O n Ο‰)) = + (fun p : Hist π“ž 𝓐 𝓨 m Γ— π“ž ↦ + (fun i : Fin n ↦ p.1 (Fin.castLE hnm i), (p.1 ⟨n, hlt⟩).obs)) ∘ + (fun Ο‰ ↦ (history O A Y m Ο‰, O m Ο‰)) := rfl + rw [this] + exact measurable_comp_comap _ (by fun_prop) + le' n := by + rw [← measurable_iff_comap_le] + exact (Learning.measurable_history h.measurable_obs h.measurable_action + h.measurable_feedback n).prodMk (h.measurable_obs n) + +lemma filtrationObs_eq_comap (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + h.filtrationObs n = + MeasurableSpace.comap (fun Ο‰ ↦ (history O A Y n Ο‰, O n Ο‰)) inferInstance := rfl + +/-- Filtration generated by the history before time `n` together with the observation and the +action at time `n`. -/ +def filtrationAction (h : IsAlgEnvSeq O A Y alg env P) : Filtration β„• mΞ© where - seq n := MeasurableSpace.comap (fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) inferInstance + seq n := MeasurableSpace.comap (fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) inferInstance mono' n m hnm := by simp only rw [← measurable_iff_comap_le] rcases eq_or_lt_of_le hnm with rfl | hlt Β· exact measurable_iff_comap_le.mpr le_rfl - have : (fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) = - (fun p : (Fin m β†’ 𝓐 Γ— 𝓨) Γ— 𝓐 ↦ - (fun i : Fin n ↦ p.1 (Fin.castLE hnm i), (p.1 ⟨n, hlt⟩).1)) ∘ - (fun Ο‰ ↦ (history A Y m Ο‰, A m Ο‰)) := rfl + have : (fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) = + (fun p : (Hist π“ž 𝓐 𝓨 m Γ— π“ž) Γ— 𝓐 ↦ + ((fun i : Fin n ↦ p.1.1 (Fin.castLE hnm i), (p.1.1 ⟨n, hlt⟩).obs), + (p.1.1 ⟨n, hlt⟩).action)) ∘ + (fun Ο‰ ↦ ((history O A Y m Ο‰, O m Ο‰), A m Ο‰)) := rfl rw [this] exact measurable_comp_comap _ (by fun_prop) le' n := by rw [← measurable_iff_comap_le] - exact (Learning.measurable_history h.measurable_action h.measurable_feedback n).prodMk - (h.measurable_action n) + exact ((Learning.measurable_history h.measurable_obs h.measurable_action + h.measurable_feedback n).prodMk (h.measurable_obs n)).prodMk (h.measurable_action n) -lemma filtrationAction_eq_comap (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : +lemma filtrationAction_eq_comap (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : h.filtrationAction n = - MeasurableSpace.comap (fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) inferInstance := rfl + MeasurableSpace.comap (fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) inferInstance := rfl -lemma filtrationAction_zero_eq_comap (h : IsAlgEnvSeq A Y alg env P) : - h.filtrationAction 0 = MeasurableSpace.comap (A 0) inferInstance := by - rw [filtrationAction_eq_comap, history_zero] +lemma filtrationObs_zero_eq_comap (h : IsAlgEnvSeq O A Y alg env P) : + h.filtrationObs 0 = MeasurableSpace.comap (O 0) inferInstance := by + rw [filtrationObs_eq_comap, history_zero] refine le_antisymm ?_ ?_ Β· rw [← measurable_iff_comap_le] exact measurable_const.prodMk (measurable_iff_comap_le.mpr le_rfl) Β· rw [← measurable_iff_comap_le] exact measurable_snd.comp (measurable_iff_comap_le.mpr le_rfl) +lemma filtrationAction_zero_eq_comap (h : IsAlgEnvSeq O A Y alg env P) : + h.filtrationAction 0 = + MeasurableSpace.comap (fun Ο‰ ↦ (O 0 Ο‰, A 0 Ο‰)) inferInstance := by + rw [filtrationAction_eq_comap, history_zero] + refine le_antisymm ?_ ?_ + Β· rw [← measurable_iff_comap_le] + exact ((measurable_const.prodMk + (measurable_fst.comp (measurable_iff_comap_le.mpr le_rfl)))).prodMk + (measurable_snd.comp (measurable_iff_comap_le.mpr le_rfl)) + Β· rw [← measurable_iff_comap_le] + exact ((measurable_snd.comp measurable_fst).comp + (measurable_iff_comap_le.mpr le_rfl)).prodMk + (measurable_snd.comp (measurable_iff_comap_le.mpr le_rfl)) + @[fun_prop] -lemma measurable_history_filtrationAction (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : - Measurable[h.filtrationAction n] (history A Y n) := +lemma measurable_history_filtrationObs (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + Measurable[h.filtrationObs n] (history O A Y n) := measurable_fst.comp (measurable_iff_comap_le.mpr le_rfl) -lemma filtration_le_filtrationAction_succ (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : +@[fun_prop] +lemma measurable_history_filtrationAction (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + Measurable[h.filtrationAction n] (history O A Y n) := + (measurable_fst.comp measurable_fst).comp (measurable_iff_comap_le.mpr le_rfl) + +lemma filtrationObs_le_filtrationAction (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + h.filtrationObs n ≀ h.filtrationAction n := by + rw [filtrationObs_eq_comap, filtrationAction_eq_comap, ← measurable_iff_comap_le] + exact measurable_fst.comp (measurable_iff_comap_le.mpr le_rfl) + +lemma filtration_le_filtrationObs_succ (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + h.filtration n ≀ h.filtrationObs (n + 1) := + measurable_iff_comap_le.mp (h.measurable_history_filtrationObs (n + 1)) + +lemma filtration_le_filtrationAction_succ (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : h.filtration n ≀ h.filtrationAction (n + 1) := measurable_iff_comap_le.mp (h.measurable_history_filtrationAction (n + 1)) -lemma filtrationAction_le_filtration (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : +lemma filtrationAction_le_filtration (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : h.filtrationAction n ≀ h.filtration n := by rw [filtrationAction_eq_comap, ← measurable_iff_comap_le] - exact (h.adapted_history n).prodMk (h.adapted_action n) + exact ((h.adapted_history n).prodMk (h.adapted_obs n)).prodMk (h.adapted_action n) + +lemma filtrationObs_le_filtration (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + h.filtrationObs n ≀ h.filtration n := + (h.filtrationObs_le_filtrationAction n).trans (h.filtrationAction_le_filtration n) -lemma adapted_action_filtrationAction (h : IsAlgEnvSeq A Y alg env P) : +lemma adapted_obs_filtrationObs (h : IsAlgEnvSeq O A Y alg env P) : + Adapted h.filtrationObs O := fun _ ↦ + measurable_snd.comp (measurable_iff_comap_le.mpr le_rfl) + +lemma adapted_obs_filtrationAction (h : IsAlgEnvSeq O A Y alg env P) : + Adapted h.filtrationAction O := fun _ ↦ + (measurable_snd.comp measurable_fst).comp (measurable_iff_comap_le.mpr le_rfl) + +lemma adapted_action_filtrationAction (h : IsAlgEnvSeq O A Y alg env P) : Adapted h.filtrationAction A := fun _ ↦ measurable_snd.comp (measurable_iff_comap_le.mpr le_rfl) -lemma measurable_feedback_filtrationAction_of_lt (h : IsAlgEnvSeq A Y alg env P) +lemma measurable_feedback_filtrationObs_of_lt (h : IsAlgEnvSeq O A Y alg env P) + {m n : β„•} (hmn : m < n) : + Measurable[h.filtrationObs n] (Y m) := by + obtain ⟨j, rfl⟩ : βˆƒ j, n = j + 1 := ⟨n - 1, by lia⟩ + exact (h.adapted_feedback.measurable_le (by lia)).mono + (filtration_le_filtrationObs_succ h j) le_rfl + +lemma measurable_feedback_filtrationAction_of_lt (h : IsAlgEnvSeq O A Y alg env P) {m n : β„•} (hmn : m < n) : Measurable[h.filtrationAction n] (Y m) := by obtain ⟨j, rfl⟩ : βˆƒ j, n = j + 1 := ⟨n - 1, by lia⟩ @@ -467,4 +688,66 @@ end Filtration end IsAlgEnvSeq +section NoObservation + +/-! ### Environments without observations + +An environment with `π“ž = Unit` provides no information to the algorithm before it takes its action: +the algorithm only sees the past rounds. Since `Unit` carries a unique probability measure, the +observation kernels of such an environment are all equal to `Kernel.const _ (Measure.dirac ())`, +and the observation process of an algorithm-environment sequence is `noObs`. -/ + +/-- Every Markov kernel with codomain `Unit` is the constant kernel at `Measure.dirac ()`. -/ +lemma Kernel.eq_const_dirac_unit {Ξ± : Type*} {mΞ± : MeasurableSpace Ξ±} (ΞΊ : Kernel Ξ± Unit) + [IsMarkovKernel ΞΊ] : + ΞΊ = Kernel.const Ξ± (Measure.dirac ()) := by + ext a s hs + rw [Kernel.const_apply] + rcases Set.eq_empty_or_nonempty s with rfl | ⟨u, hu⟩ + Β· simp + Β· have hs_univ : s = Set.univ := Set.eq_univ_of_forall fun x ↦ by rwa [Subsingleton.elim x u] + simp [hs_univ] + +/-- A random variable with values in `Unit` admits any Markov kernel as conditional +distribution. -/ +lemma hasCondDistrib_unit {Ξ± : Type*} {mΞ± : MeasurableSpace Ξ±} {P : Measure Ξ©} + [IsProbabilityMeasure P] {X : Ξ© β†’ Ξ±} (hX : AEMeasurable X P) (U : Ξ© β†’ Unit) + (ΞΊ : Kernel Ξ± Unit) [IsMarkovKernel ΞΊ] : + HasCondDistrib U X ΞΊ P := by + have hU : U = fun _ ↦ () := funext fun _ ↦ rfl + subst hU + refine HasLaw.mk (hX.prodMk aemeasurable_const) ?_ + rw [Kernel.eq_const_dirac_unit ΞΊ, Measure.compProd_const, Measure.prod_dirac, + AEMeasurable.map_map_of_aemeasurable (by fun_prop) hX] + rfl + +/-- Any function with values in `Unit` is measurable. -/ +lemma measurable_unit {Ξ± : Type*} {mΞ± : MeasurableSpace Ξ±} (f : Ξ± β†’ Unit) : Measurable f := by + have hf : f = fun _ ↦ () := funext fun _ ↦ rfl + rw [hf] + exact measurable_const + +/-- The observation process of an algorithm-environment sequence without observations. -/ +def noObs (Ξ© : Type*) : β„• β†’ Ξ© β†’ Unit := fun _ _ ↦ () + +@[simp] lemma noObs_apply (n : β„•) (Ο‰ : Ξ©) : noObs Ξ© n Ο‰ = () := rfl + +@[fun_prop] +lemma measurable_noObs (n : β„•) : Measurable (noObs Ξ© n) := measurable_const + +/-- The observation kernels of an environment without observations. -/ +noncomputable def unitObs (𝓐 𝓨 : Type*) [MeasurableSpace 𝓐] [MeasurableSpace 𝓨] (n : β„•) : + Kernel (Hist Unit 𝓐 𝓨 n) Unit := + Kernel.const _ (Measure.dirac ()) +deriving IsMarkovKernel + +lemma unitObs_def (n : β„•) : + unitObs 𝓐 𝓨 n = Kernel.const _ (Measure.dirac ()) := rfl + +@[simp] +lemma unitObs_apply (n : β„•) (h : Hist Unit 𝓐 𝓨 n) : + unitObs 𝓐 𝓨 n h = Measure.dirac () := rfl + +end NoObservation + end Learning diff --git a/LeanMachineLearning/SequentialLearning/AlgorithmDensity.lean b/LeanMachineLearning/SequentialLearning/AlgorithmDensity.lean index de6d7c96..4ea64b4e 100644 --- a/LeanMachineLearning/SequentialLearning/AlgorithmDensity.lean +++ b/LeanMachineLearning/SequentialLearning/AlgorithmDensity.lean @@ -46,39 +46,41 @@ open scoped ENNReal namespace Learning -variable {𝓐 𝓨 : Type*} [MeasurableSpace 𝓐] [MeasurableSpace 𝓨] +variable {π“ž 𝓐 𝓨 : Type*} [MeasurableSpace π“ž] [MeasurableSpace 𝓐] [MeasurableSpace 𝓨] namespace Algorithm /-- For every time and history, the distribution over actions according to `alg` is absolutely continuous with respect to the distribution over actions according to `algβ‚€`. -/ -structure AbsolutelyContinuous (alg algβ‚€ : Algorithm 𝓐 𝓨) : Prop where +structure AbsolutelyContinuous (alg algβ‚€ : Algorithm π“ž 𝓐 𝓨) : Prop where policy n h : alg.policy n h β‰ͺ algβ‚€.policy n h @[inherit_doc AbsolutelyContinuous] scoped notation:50 alg " β‰ͺₐ " algβ‚€ => AbsolutelyContinuous alg algβ‚€ -lemma AbsolutelyContinuous.p0 {alg algβ‚€ : Algorithm 𝓐 𝓨} (h : alg β‰ͺₐ algβ‚€) : alg.p0 β‰ͺ algβ‚€.p0 := - h.policy 0 default +lemma AbsolutelyContinuous.p0 {alg algβ‚€ : Algorithm π“ž 𝓐 𝓨} (h : alg β‰ͺₐ algβ‚€) (o : π“ž) : + alg.p0 o β‰ͺ algβ‚€.p0 o := + h.policy 0 (default, o) /-- If the algorithm `alg` is absolutely continuous with respect to the algorithm `algβ‚€` and they are both interacting with the same environment, then the law of the history before time `n` under `alg` is the law of the history before time `n` under `algβ‚€` with density `alg.density algβ‚€ n`. -/ noncomputable -def density [MeasurableSpace.CountablyGenerated 𝓐] (alg algβ‚€ : Algorithm 𝓐 𝓨) : - (n : β„•) β†’ (Fin n β†’ 𝓐 Γ— 𝓨) β†’ ℝβ‰₯0∞ +def density [MeasurableSpace.CountablyGenerated 𝓐] (alg algβ‚€ : Algorithm π“ž 𝓐 𝓨) : + (n : β„•) β†’ Hist π“ž 𝓐 𝓨 n β†’ ℝβ‰₯0∞ | 0, _ => 1 | n + 1, h => - let p := MeasurableEquiv.finSuccProd (𝓐 Γ— 𝓨) n h - alg.density algβ‚€ n p.1 * (alg.policy n).rnDeriv (algβ‚€.policy n) p.1 p.2.1 + let p := MeasurableEquiv.finSuccProd (Round π“ž 𝓐 𝓨) n h + alg.density algβ‚€ n p.1 * (alg.policy n).rnDeriv (algβ‚€.policy n) (p.1, p.2.obs) p.2.action @[simp] -lemma density_zero [MeasurableSpace.CountablyGenerated 𝓐] (alg algβ‚€ : Algorithm 𝓐 𝓨) - (h : Fin 0 β†’ 𝓐 Γ— 𝓨) : +lemma density_zero [MeasurableSpace.CountablyGenerated 𝓐] (alg algβ‚€ : Algorithm π“ž 𝓐 𝓨) + (h : Hist π“ž 𝓐 𝓨 0) : alg.density algβ‚€ 0 h = 1 := rfl @[fun_prop] -lemma measurable_density [MeasurableSpace.CountablyGenerated 𝓐] (alg algβ‚€ : Algorithm 𝓐 𝓨) (n : β„•) : +lemma measurable_density [MeasurableSpace.CountablyGenerated 𝓐] + (alg algβ‚€ : Algorithm π“ž 𝓐 𝓨) (n : β„•) : Measurable (alg.density algβ‚€ n) := by induction n with | zero => simp_rw [density]; fun_prop @@ -91,21 +93,21 @@ open scoped Algorithm namespace IsAlgEnvSeq variable {Ξ© : Type*} [MeasurableSpace Ξ©] -variable {alg : Algorithm 𝓐 𝓨} {env : Environment 𝓐 𝓨} -variable {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} +variable {alg : Algorithm π“ž 𝓐 𝓨} {env : Environment π“ž 𝓐 𝓨} +variable {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} variable {P : Measure Ξ©} [IsProbabilityMeasure P] variable {Ξ©β‚€ : Type*} [MeasurableSpace Ξ©β‚€] -variable {algβ‚€ : Algorithm 𝓐 𝓨} -variable {Aβ‚€ : β„• β†’ Ξ©β‚€ β†’ 𝓐} {Yβ‚€ : β„• β†’ Ξ©β‚€ β†’ 𝓨} +variable {algβ‚€ : Algorithm π“ž 𝓐 𝓨} +variable {Oβ‚€ : β„• β†’ Ξ©β‚€ β†’ π“ž} {Aβ‚€ : β„• β†’ Ξ©β‚€ β†’ 𝓐} {Yβ‚€ : β„• β†’ Ξ©β‚€ β†’ 𝓨} variable {Pβ‚€ : Measure Ξ©β‚€} [IsProbabilityMeasure Pβ‚€] -lemma absolutelyContinuous_map_history (h : IsAlgEnvSeq A Y alg env P) - (hβ‚€ : IsAlgEnvSeq Aβ‚€ Yβ‚€ algβ‚€ env Pβ‚€) (hc : alg β‰ͺₐ algβ‚€) (n : β„•) : - P.map (history A Y n) β‰ͺ Pβ‚€.map (history Aβ‚€ Yβ‚€ n) := by +lemma absolutelyContinuous_map_history (h : IsAlgEnvSeq O A Y alg env P) + (hβ‚€ : IsAlgEnvSeq Oβ‚€ Aβ‚€ Yβ‚€ algβ‚€ env Pβ‚€) (hc : alg β‰ͺₐ algβ‚€) (n : β„•) : + P.map (history O A Y n) β‰ͺ Pβ‚€.map (history Oβ‚€ Aβ‚€ Yβ‚€ n) := by induction n with | zero => - rw [(hasLaw_history_zero A Y).map_eq, (hasLaw_history_zero Aβ‚€ Yβ‚€).map_eq] + rw [(hasLaw_history_zero O A Y).map_eq, (hasLaw_history_zero Oβ‚€ Aβ‚€ Yβ‚€).map_eq] | succ n ih => simp_rw [history_succ] rw [← Measure.map_map (by fun_prop), ← Measure.map_map (by fun_prop)] @@ -115,24 +117,40 @@ lemma absolutelyContinuous_map_history (h : IsAlgEnvSeq A Y alg env P) apply Measure.AbsolutelyContinuous.map _ (by fun_prop) rw [(h.hasCondDistrib_step n).map_eq, (hβ‚€.hasCondDistrib_step n).map_eq] apply Measure.AbsolutelyContinuous.compProd ih - filter_upwards with h' using Measure.AbsolutelyContinuous.compProd_left_apply (hc.policy n h') _ + filter_upwards with h' + rw [stepKernel_def, stepKernel_def, Kernel.compProd_apply_eq_compProd_sectR, + Kernel.compProd_apply_eq_compProd_sectR] + refine Measure.AbsolutelyContinuous.compProd_right ?_ + filter_upwards with o + simp only [Kernel.sectR_apply] + exact Measure.AbsolutelyContinuous.compProd_left_apply (hc.policy n (h', o)) _ variable [MeasurableSpace.CountablyGenerated 𝓐] -lemma hasLaw_history_withDensity (h : IsAlgEnvSeq A Y alg env P) - (hβ‚€ : IsAlgEnvSeq Aβ‚€ Yβ‚€ algβ‚€ env Pβ‚€) (hc : alg β‰ͺₐ algβ‚€) (n : β„•) : HasLaw (history A Y n) - ((Pβ‚€.map (history Aβ‚€ Yβ‚€ n)).withDensity (alg.density algβ‚€ n)) P where +lemma hasLaw_history_withDensity (h : IsAlgEnvSeq O A Y alg env P) + (hβ‚€ : IsAlgEnvSeq Oβ‚€ Aβ‚€ Yβ‚€ algβ‚€ env Pβ‚€) (hc : alg β‰ͺₐ algβ‚€) (n : β„•) : HasLaw (history O A Y n) + ((Pβ‚€.map (history Oβ‚€ Aβ‚€ Yβ‚€ n)).withDensity (alg.density algβ‚€ n)) P where aemeasurable := (h.measurable_history n).aemeasurable map_eq := by induction n with | zero => - rw [(hasLaw_history_zero A Y).map_eq, (hasLaw_history_zero Aβ‚€ Yβ‚€).map_eq, + rw [(hasLaw_history_zero O A Y).map_eq, (hasLaw_history_zero Oβ‚€ Aβ‚€ Yβ‚€).map_eq, show alg.density algβ‚€ 0 = 1 from rfl, withDensity_one] | succ n ih => - let ρ h' (ar : 𝓐 Γ— 𝓨) := Kernel.rnDeriv (alg.policy n) (algβ‚€.policy n) h' ar.1 + let ρ h' (r : Round π“ž 𝓐 𝓨) := + Kernel.rnDeriv (alg.policy n) (algβ‚€.policy n) (h', r.obs) r.action have hs : stepKernel alg env n = (stepKernel algβ‚€ env n).withDensity ρ := by - rw [stepKernel, ← Kernel.withDensity_rnDeriv_eq' (hc.policy n)] - exact Kernel.compProd_withDensity_left (Kernel.measurable_rnDeriv _ _) + have h_inner : alg.policy n βŠ—β‚– env.feedback n + = (algβ‚€.policy n βŠ—β‚– env.feedback n).withDensity + (fun p ar ↦ Kernel.rnDeriv (alg.policy n) (algβ‚€.policy n) p ar.1) := by + conv_lhs => rw [← Kernel.withDensity_rnDeriv_eq' (hc.policy n)] + exact Kernel.compProd_withDensity_left (Kernel.measurable_rnDeriv _ _) + have h_sf : IsSFiniteKernel ((algβ‚€.policy n βŠ—β‚– env.feedback n).withDensity + (fun p ar ↦ Kernel.rnDeriv (alg.policy n) (algβ‚€.policy n) p ar.1)) := by + rw [← h_inner] + infer_instance + rw [stepKernel_def alg env n, h_inner, Kernel.compProd_withDensity_right (by fun_prop)] + rfl have : IsMarkovKernel ((stepKernel algβ‚€ env n).withDensity ρ) := by rw [← hs] infer_instance diff --git a/LeanMachineLearning/SequentialLearning/AlgorithmDensityBayes.lean b/LeanMachineLearning/SequentialLearning/AlgorithmDensityBayes.lean index ad4b00c4..41235288 100644 --- a/LeanMachineLearning/SequentialLearning/AlgorithmDensityBayes.lean +++ b/LeanMachineLearning/SequentialLearning/AlgorithmDensityBayes.lean @@ -48,18 +48,18 @@ variable {ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨} [IsMarkovKernel ΞΊ] variable {Ξ© : Type*} [MeasurableSpace Ξ©] variable {E : Ξ© β†’ 𝓔} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} -variable {alg : Algorithm 𝓐 𝓨} +variable {alg : Algorithm Unit 𝓐 𝓨} variable {P : Measure Ξ©} [IsProbabilityMeasure P] variable {Ξ©β‚€ : Type*} [MeasurableSpace Ξ©β‚€] variable {Eβ‚€ : Ξ©β‚€ β†’ 𝓔} {Aβ‚€ : β„• β†’ Ξ©β‚€ β†’ 𝓐} {Yβ‚€ : β„• β†’ Ξ©β‚€ β†’ 𝓨} -variable {algβ‚€ : Algorithm 𝓐 𝓨} +variable {algβ‚€ : Algorithm Unit 𝓐 𝓨} variable {Pβ‚€ : Measure Ξ©β‚€} [IsProbabilityMeasure Pβ‚€] lemma condDistrib_history_eq_condDistrib_hist_withDensity (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (hβ‚€ : IsBayesAlgEnvSeq Q ΞΊ algβ‚€ Eβ‚€ Aβ‚€ Yβ‚€ Pβ‚€) (hc : alg β‰ͺₐ algβ‚€) (n : β„•) : - condDistrib (history A Y n) E P =ᡐ[Q] - ((condDistrib (history Aβ‚€ Yβ‚€ n) Eβ‚€ Pβ‚€).withDensity + condDistrib (history (noObs Ξ©) A Y n) E P =ᡐ[Q] + ((condDistrib (history (noObs Ξ©β‚€) Aβ‚€ Yβ‚€ n) Eβ‚€ Pβ‚€).withDensity (fun _ ↦ alg.density algβ‚€ n)) := by filter_upwards [h.ae_IsAlgEnvSeq, hβ‚€.ae_IsAlgEnvSeq, h.hasLaw_IT_hist n, hβ‚€.hasLaw_IT_hist n] with _ hae haeβ‚€ he heβ‚€ @@ -68,10 +68,13 @@ lemma condDistrib_history_eq_condDistrib_hist_withDensity (h : IsBayesAlgEnvSeq lemma hasLaw_history_withDensity (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (hβ‚€ : IsBayesAlgEnvSeq Q ΞΊ algβ‚€ Eβ‚€ Aβ‚€ Yβ‚€ Pβ‚€) (hc : alg β‰ͺₐ algβ‚€) (n : β„•) : - HasLaw (history A Y n) - ((Pβ‚€.map (history Aβ‚€ Yβ‚€ n)).withDensity (alg.density algβ‚€ n)) P where - aemeasurable := (measurable_history h.measurable_action h.measurable_feedback n).aemeasurable + HasLaw (history (noObs Ξ©) A Y n) + ((Pβ‚€.map (history (noObs Ξ©β‚€) Aβ‚€ Yβ‚€ n)).withDensity (alg.density algβ‚€ n)) P where + aemeasurable := (measurable_history (fun _ ↦ measurable_const) h.measurable_action + h.measurable_feedback n).aemeasurable map_eq := by + have hO : βˆ€ n, Measurable (noObs Ξ© n) := fun _ ↦ measurable_const + have hOβ‚€ : βˆ€ n, Measurable (noObs Ξ©β‚€ n) := fun _ ↦ measurable_const have hA := h.measurable_action have hY := h.measurable_feedback have hAβ‚€ := hβ‚€.measurable_action @@ -88,10 +91,13 @@ variable [IsProbabilityMeasure Q] lemma hasCondDistrib_env_history (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (hβ‚€ : IsBayesAlgEnvSeq Q ΞΊ algβ‚€ Eβ‚€ Aβ‚€ Yβ‚€ Pβ‚€) (hc : alg β‰ͺₐ algβ‚€) (n : β„•) : - HasCondDistrib E (history A Y n) (condDistrib Eβ‚€ (history Aβ‚€ Yβ‚€ n) Pβ‚€) P where - aemeasurable := ((measurable_history h.measurable_action + HasCondDistrib E (history (noObs Ξ©) A Y n) + (condDistrib Eβ‚€ (history (noObs Ξ©β‚€) Aβ‚€ Yβ‚€ n) Pβ‚€) P where + aemeasurable := ((measurable_history (fun _ ↦ measurable_const) h.measurable_action h.measurable_feedback n).prodMk h.measurable_param).aemeasurable map_eq := by + have hO : βˆ€ n, Measurable (noObs Ξ© n) := fun _ ↦ measurable_const + have hOβ‚€ : βˆ€ n, Measurable (noObs Ξ©β‚€ n) := fun _ ↦ measurable_const have hA := h.measurable_action have hY := h.measurable_feedback have hAβ‚€ := hβ‚€.measurable_action diff --git a/LeanMachineLearning/SequentialLearning/Algorithms/RandomSampling/Basic.lean b/LeanMachineLearning/SequentialLearning/Algorithms/RandomSampling/Basic.lean index ebaa27d9..7ade0abe 100644 --- a/LeanMachineLearning/SequentialLearning/Algorithms/RandomSampling/Basic.lean +++ b/LeanMachineLearning/SequentialLearning/Algorithms/RandomSampling/Basic.lean @@ -34,7 +34,8 @@ open scoped Topology namespace Learning -variable {𝓐 𝓨 Ξ© : Type*} {m𝓐 : MeasurableSpace 𝓐} {m𝓨 : MeasurableSpace 𝓨} +variable {π“ž 𝓐 𝓨 Ξ© : Type*} {mπ“ž : MeasurableSpace π“ž} {m𝓐 : MeasurableSpace 𝓐} + {m𝓨 : MeasurableSpace 𝓨} {mΞ© : MeasurableSpace Ξ©} {ΞΌ : Measure 𝓐} [IsProbabilityMeasure ΞΌ] {P : Measure Ξ©} [IsProbabilityMeasure P] @@ -42,21 +43,23 @@ open Set in /-- The _Random Sampling_ algorithm, which samples from a fixed probability measure at each iteration. -/ @[simps] -noncomputable def randomSampling (ΞΌ : Measure 𝓐) [IsProbabilityMeasure ΞΌ] : Algorithm 𝓐 𝓨 where +noncomputable def randomSampling (ΞΌ : Measure 𝓐) [IsProbabilityMeasure ΞΌ] : + Algorithm π“ž 𝓐 𝓨 where policy _ := Kernel.const _ ΞΌ namespace randomSampling -variable {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {env : Environment 𝓐 𝓨} +variable {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {env : Environment π“ž 𝓐 𝓨} /-- Each action follows the distribution ΞΌ. -/ -lemma hasLaw_action (h : IsAlgEnvSeq A Y (randomSampling ΞΌ) env P) (n : β„•) : +lemma hasLaw_action (h : IsAlgEnvSeq O A Y (randomSampling ΞΌ) env P) (n : β„•) : HasLaw (A n) ΞΌ P := (h.hasCondDistrib_action n).hasLaw_of_const /-- Actions are mutually independent. -/ -lemma iIndep_action (h : IsAlgEnvSeq A Y (randomSampling ΞΌ) env P) : +lemma iIndep_action (h : IsAlgEnvSeq O A Y (randomSampling ΞΌ) env P) : iIndepFun A P := by + have hO := h.measurable_obs have hA := h.measurable_action rw [iIndepFun_nat_iff_forall_indepFun (by fun_prop)] intro n @@ -64,10 +67,11 @@ lemma iIndep_action (h : IsAlgEnvSeq A Y (randomSampling ΞΌ) env P) : simp only [randomSampling_policy, Measure.compProd_const] at map_eq have law_eq : P.map (A (n + 1)) = ΞΌ := (hasLaw_action h (n + 1)).map_eq rw [← law_eq, ← indepFun_iff_map_prod_eq_prod_map_map] at map_eq - Β· change A (n + 1) βŸ‚α΅’[P] (fun (f : Fin (n + 1) β†’ 𝓐 Γ— 𝓨) (i : Iic n) ↦ - (f ⟨i.1, Nat.lt_succ_of_le (mem_Iic.mp i.2)⟩).1) ∘ (history A Y (n + 1)) + Β· change A (n + 1) βŸ‚α΅’[P] (fun (p : Hist π“ž 𝓐 𝓨 (n + 1) Γ— π“ž) (i : Iic n) ↦ + (p.1 ⟨i.1, Nat.lt_succ_of_le (mem_Iic.mp i.2)⟩).action) ∘ + (fun Ο‰ ↦ (history O A Y (n + 1) Ο‰, O (n + 1) Ο‰)) refine map_eq.symm.comp measurable_id (by fun_prop) - Β· exact (h.measurable_history (n + 1)).aemeasurable + Β· exact ((h.measurable_history (n + 1)).prodMk (h.measurable_obs (n + 1))).aemeasurable Β· exact (h.measurable_action (n + 1)).aemeasurable end randomSampling diff --git a/LeanMachineLearning/SequentialLearning/Algorithms/RandomSampling/Tendsto.lean b/LeanMachineLearning/SequentialLearning/Algorithms/RandomSampling/Tendsto.lean index c23e291e..65778126 100644 --- a/LeanMachineLearning/SequentialLearning/Algorithms/RandomSampling/Tendsto.lean +++ b/LeanMachineLearning/SequentialLearning/Algorithms/RandomSampling/Tendsto.lean @@ -42,7 +42,8 @@ namespace Learning.randomSampling variable {𝓐 𝓨 Ξ© : Type*} {m𝓐 : MeasurableSpace 𝓐} {m𝓨 : MeasurableSpace 𝓨} {mΞ© : MeasurableSpace Ξ©} {ΞΌ : Measure 𝓐} [IsProbabilityMeasure ΞΌ] {P : Measure Ξ©} - [IsProbabilityMeasure P] {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {env : Environment 𝓐 𝓨} + [IsProbabilityMeasure P] {O : β„• β†’ Ξ© β†’ Unit} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} + {env : Environment Unit 𝓐 𝓨} {f : 𝓐 β†’ 𝓨} {hf : Measurable f} section rewards @@ -50,7 +51,7 @@ section rewards variable [StandardBorelSpace 𝓨] [Nonempty 𝓨] /-- Each reward follows the distribution ΞΌ.map f. -/ -lemma hasLaw_feeback (h : IsAlgEnvSeq A Y (randomSampling ΞΌ) (evalEnv f hf) P) (n : β„•) : +lemma hasLaw_feeback (h : IsAlgEnvSeq O A Y (randomSampling ΞΌ) (evalEnv f hf) P) (n : β„•) : HasLaw (Y n) (ΞΌ.map f) P := by refine HasLaw.congr ?_ (feedback_evalEnv_ae_eq_eval_action h n) have hA := h.measurable_action n @@ -58,7 +59,7 @@ lemma hasLaw_feeback (h : IsAlgEnvSeq A Y (randomSampling ΞΌ) (evalEnv f hf) P) rw [← Measure.map_map hf hA, (hasLaw_action h n).map_eq] /-- Rewards are mutually independent. -/ -lemma iIndep_feedback (h : IsAlgEnvSeq A Y (randomSampling ΞΌ) (evalEnv f hf) P) : +lemma iIndep_feedback (h : IsAlgEnvSeq O A Y (randomSampling ΞΌ) (evalEnv f hf) P) : iIndepFun Y P := have (n : β„•) : f ∘ A n =ᡐ[P] Y n := (feedback_evalEnv_ae_eq_eval_action h n).symm @@ -70,10 +71,10 @@ variable [PseudoMetricSpace 𝓐] [SecondCountableTopology 𝓐] [OpensMeasurabl [ΞΌ.IsOpenPosMeasure] /-- The minimum distance from sampled actions to any point tends to zero. -/ -theorem action_tendsto_any (h : IsAlgEnvSeq A Y (randomSampling ΞΌ) (evalEnv f hf) P) (a : 𝓐) +theorem action_tendsto_any (h : IsAlgEnvSeq O A Y (randomSampling ΞΌ) (evalEnv f hf) P) (a : 𝓐) {Ξ΅ : ℝ} (hΞ΅ : 0 < Ξ΅) : Tendsto (fun i => P {x | Ξ΅ ≀ (fun (j : Iic i) ↦ dist (A j.1 x) a).min}) atTop (𝓝 0) := by - set randomSampling_alg := randomSampling (𝓨 := 𝓨) ΞΌ + set randomSampling_alg := randomSampling (π“ž := Unit) (𝓨 := 𝓨) ΞΌ refine tendsto_zero_of_le (g := fun n ↦ P (β‹‚ i ∈ Iic n, {x | Ξ΅ ≀ dist (A i x) a})) ?_ ?_ Β· have inter_prod (n : β„•) : P (β‹‚ j ∈ Iic n, {x | Ξ΅ ≀ dist (A j x) a}) = ∏ j ∈ Iic n, P {x | Ξ΅ ≀ dist (A j x) a} := by @@ -117,7 +118,7 @@ variable [PseudoMetricSpace 𝓨] [BorelSpace 𝓨] (hfc : Continuous f) /-- The minimum distance from image of actions to any function value tends to zero. -/ lemma image_action_tendsto_any - (h : IsAlgEnvSeq A Y (randomSampling ΞΌ) (evalEnv f hfc.measurable) P) + (h : IsAlgEnvSeq O A Y (randomSampling ΞΌ) (evalEnv f hfc.measurable) P) (a : 𝓐) {Ξ΅ : ℝ} (hΞ΅ : 0 < Ξ΅) : Tendsto (fun i => P {x | Ξ΅ ≀ (fun (j : Iic i) ↦ dist (f (A j.1 x)) (f a)).min}) atTop (𝓝 0) := by @@ -139,7 +140,7 @@ lemma image_action_tendsto_any variable [StandardBorelSpace 𝓨] [Nonempty 𝓨] /-- The minimum distance from rewards to any function value tends to zero. -/ -lemma feedback_tendsto_any (h : IsAlgEnvSeq A Y (randomSampling ΞΌ) (evalEnv f hfc.measurable) P) +lemma feedback_tendsto_any (h : IsAlgEnvSeq O A Y (randomSampling ΞΌ) (evalEnv f hfc.measurable) P) (a : 𝓐) {Ξ΅ : ℝ} (hΞ΅ : 0 < Ξ΅) : Tendsto (fun i => P {x | Ξ΅ ≀ (fun (j : Iic i) ↦ dist (Y j.1 x) (f a)).min}) atTop (𝓝 0) := by convert image_action_tendsto_any hfc h a hΞ΅ using 2 with n @@ -154,7 +155,7 @@ lemma feedback_tendsto_any (h : IsAlgEnvSeq A Y (randomSampling ΞΌ) (evalEnv f h variable {R : β„• β†’ Ξ© β†’ ℝ} {f : 𝓐 β†’ ℝ} (hfc : Continuous f) {a : 𝓐} /-- The minimum image action converges to the function's global minimum. -/ -lemma tendsto_minβ‚€ (h : IsAlgEnvSeq A R (randomSampling ΞΌ) (evalEnv f hfc.measurable) P) +lemma tendsto_minβ‚€ (h : IsAlgEnvSeq O A R (randomSampling ΞΌ) (evalEnv f hfc.measurable) P) (hf_min : βˆ€ x, f a ≀ f x) : TendstoInMeasure P (fun n Ο‰ ↦ (fun (i : Iic n) ↦ f (A i.1 Ο‰)).min) atTop (fun _ ↦ f a) := by rw [tendstoInMeasure_iff_dist] @@ -175,7 +176,7 @@ lemma tendsto_minβ‚€ (h : IsAlgEnvSeq A R (randomSampling ΞΌ) (evalEnv f hfc.mea grind /-- The minimum reward converges to the function's global minimum. -/ -lemma tendsto_min (h : IsAlgEnvSeq A R (randomSampling ΞΌ) (evalEnv f hfc.measurable) P) +lemma tendsto_min (h : IsAlgEnvSeq O A R (randomSampling ΞΌ) (evalEnv f hfc.measurable) P) (hf_min : βˆ€ x, f a ≀ f x) : TendstoInMeasure P (fun n Ο‰ ↦ (fun (i : Iic n) ↦ R i.1 Ο‰).min) atTop (fun _ ↦ f a) := by refine TendstoInMeasure.congr_left (fun n ↦ ?_) <| tendsto_minβ‚€ hfc h hf_min @@ -183,7 +184,7 @@ lemma tendsto_min (h : IsAlgEnvSeq A R (randomSampling ΞΌ) (evalEnv f hfc.measur rw [← hΟ‰] /-- The maximum image action converges to the function's global maximum. -/ -lemma tendsto_maxβ‚€ (h : IsAlgEnvSeq A R (randomSampling ΞΌ) (evalEnv f hfc.measurable) P) +lemma tendsto_maxβ‚€ (h : IsAlgEnvSeq O A R (randomSampling ΞΌ) (evalEnv f hfc.measurable) P) (hf_max : βˆ€ x, f x ≀ f a) : TendstoInMeasure P (fun n Ο‰ ↦ (fun (i : Iic n) ↦ f (A i.1 Ο‰)).max) atTop (fun _ ↦ f a) := by rw [tendstoInMeasure_iff_dist] @@ -205,7 +206,7 @@ lemma tendsto_maxβ‚€ (h : IsAlgEnvSeq A R (randomSampling ΞΌ) (evalEnv f hfc.mea grind /-- The maximum reward converges to the function's global maximum. -/ -lemma tendsto_max (h : IsAlgEnvSeq A R (randomSampling ΞΌ) (evalEnv f hfc.measurable) P) +lemma tendsto_max (h : IsAlgEnvSeq O A R (randomSampling ΞΌ) (evalEnv f hfc.measurable) P) (hf_max : βˆ€ x, f x ≀ f a) : TendstoInMeasure P (fun n Ο‰ ↦ (fun (i : Iic n) ↦ R i.1 Ο‰).max) atTop (fun _ ↦ f a) := by refine TendstoInMeasure.congr_left (fun n ↦ ?_) <| tendsto_maxβ‚€ hfc h hf_max diff --git a/LeanMachineLearning/SequentialLearning/Algorithms/RoundRobin.lean b/LeanMachineLearning/SequentialLearning/Algorithms/RoundRobin.lean index c3ddd464..6f021c9e 100644 --- a/LeanMachineLearning/SequentialLearning/Algorithms/RoundRobin.lean +++ b/LeanMachineLearning/SequentialLearning/Algorithms/RoundRobin.lean @@ -70,7 +70,7 @@ end Aux namespace Learning -variable {𝓨 : Type*} {m𝓨 : MeasurableSpace 𝓨} {K : β„•} +variable {π“ž 𝓨 : Type*} {mπ“ž : MeasurableSpace π“ž} {m𝓨 : MeasurableSpace 𝓨} {K : β„•} section AlgorithmDefinition @@ -80,7 +80,7 @@ def RoundRobin.nextAction (hK : 0 < K) (n : β„•) : Fin K := ⟨n % K, Nat.mod_lt /-- The Round-Robin algorithm: deterministic algorithm that chooses action `n % K` at time `n`. -/ noncomputable -def roundRobinAlgorithm (hK : 0 < K) : Algorithm (Fin K) 𝓨 := +def roundRobinAlgorithm (hK : 0 < K) : Algorithm π“ž (Fin K) 𝓨 := detAlgorithm (fun n _ ↦ RoundRobin.nextAction hK n) (by fun_prop) end AlgorithmDefinition @@ -90,17 +90,17 @@ namespace RoundRobin variable {hK : 0 < K} {Ξ½ : Kernel (Fin K) 𝓨} [IsMarkovKernel Ξ½] {Ξ© : Type*} {mΞ© : MeasurableSpace Ξ©} {P : Measure Ξ©} [IsProbabilityMeasure P] - {A : β„• β†’ Ξ© β†’ Fin K} {Y : β„• β†’ Ξ© β†’ 𝓨} + {O : β„• β†’ Ξ© β†’ Unit} {A : β„• β†’ Ξ© β†’ Fin K} {Y : β„• β†’ Ξ© β†’ 𝓨} /-- The action chosen at time `n` is the action `n % K`. -/ lemma action_ae_eq (n : β„•) - (h : IsAlgEnvSeqUntil A Y (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P (n + 1)) : + (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P (n + 1)) : A n =ᡐ[P] fun _ ↦ ⟨n % K, Nat.mod_lt _ hK⟩ := by have : Nonempty (Fin K) := Fin.pos_iff_nonempty.mp hK exact h.action_detAlgorithm_ae_eq n.lt_succ_self lemma action_zero - (h : IsAlgEnvSeqUntil A Y (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P 1) : + (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P 1) : A 0 =ᡐ[P] fun _ ↦ ⟨0, hK⟩ := by filter_upwards [action_ae_eq 0 h] with Ο‰ hΟ‰ rw [hΟ‰] @@ -108,7 +108,7 @@ lemma action_zero /-- At time `K * m`, the number of times each action is chosen is equal to `m`. -/ lemma pullCount_mul (m : β„•) - (h : IsAlgEnvSeqUntil A Y (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P (K * m)) + (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P (K * m)) (a : Fin K) : pullCount A a (K * m) =ᡐ[P] fun _ ↦ m := by rw [Filter.EventuallyEq] @@ -124,14 +124,14 @@ lemma pullCount_mul (m : β„•) _ = m := sum_mod_range_mul hK m a lemma pullCount_eq_one - (h : IsAlgEnvSeqUntil A Y (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P K) (a : Fin K) : + (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P K) (a : Fin K) : pullCount A a K =ᡐ[P] fun _ ↦ 1 := by suffices pullCount A a (K * 1) =ᡐ[P] fun _ ↦ 1 by simpa using this - refine pullCount_mul 1 (P := P) (Ξ½ := Ξ½) (Y := Y) (hK := hK) ?_ a + refine pullCount_mul 1 (P := P) (Ξ½ := Ξ½) (O := O) (Y := Y) (hK := hK) ?_ a simpa lemma time_gt_of_pullCount_gt_one - (h : IsAlgEnvSeqUntil A Y (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P K) (a : Fin K) : + (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P K) (a : Fin K) : βˆ€α΅ Ο‰ βˆ‚P, βˆ€ n, 1 < pullCount A a n Ο‰ β†’ K < n := by filter_upwards [pullCount_eq_one h a] with h h_eq n hn rw [← h_eq] at hn @@ -139,7 +139,7 @@ lemma time_gt_of_pullCount_gt_one exact hn.not_ge (pullCount_mono _ h_lt _) lemma pullCount_pos_of_time_ge - (h : IsAlgEnvSeqUntil A Y (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P K) : + (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P K) : βˆ€α΅ Ο‰ βˆ‚P, βˆ€ n, K ≀ n β†’ βˆ€ b : Fin K, 0 < pullCount A b n Ο‰ := by have h_ae a := pullCount_eq_one h a simp_rw [Filter.EventuallyEq, ← ae_all_iff] at h_ae @@ -149,7 +149,7 @@ lemma pullCount_pos_of_time_ge exact pullCount_mono _ hn _ lemma pullCount_pos_of_pullCount_gt_one - (h : IsAlgEnvSeqUntil A Y (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P K) (a : Fin K) : + (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm hK) (stationaryEnv Ξ½) P K) (a : Fin K) : βˆ€α΅ Ο‰ βˆ‚P, βˆ€ n, 1 < pullCount A a n Ο‰ β†’ βˆ€ b : Fin K, 0 < pullCount A b n Ο‰ := by filter_upwards [time_gt_of_pullCount_gt_one h a, pullCount_pos_of_time_ge h] with Ο‰ h1 h2 n h_gt a exact h2 n (h1 n h_gt).le a diff --git a/LeanMachineLearning/SequentialLearning/Algorithms/Uniform.lean b/LeanMachineLearning/SequentialLearning/Algorithms/Uniform.lean index a2efb83b..7c6f3c4d 100644 --- a/LeanMachineLearning/SequentialLearning/Algorithms/Uniform.lean +++ b/LeanMachineLearning/SequentialLearning/Algorithms/Uniform.lean @@ -32,13 +32,15 @@ open scoped Algorithm namespace Learning -variable {𝓐 𝓨 : Type*} {m𝓐 : MeasurableSpace 𝓐} {m𝓨 : MeasurableSpace 𝓨} +variable {π“ž 𝓐 𝓨 : Type*} {mπ“ž : MeasurableSpace π“ž} {m𝓐 : MeasurableSpace 𝓐} + {m𝓨 : MeasurableSpace 𝓨} /-- The Uniform algorithm: actions are chosen uniformly at random. -/ noncomputable -def uniformAlgorithm [Finite 𝓐] [Nonempty 𝓐] : Algorithm 𝓐 𝓨 := randomSampling (uniformOn Set.univ) +def uniformAlgorithm [Finite 𝓐] [Nonempty 𝓐] : Algorithm π“ž 𝓐 𝓨 := + randomSampling (uniformOn Set.univ) -lemma absolutelyContinuous_uniformAlgorithm [Finite 𝓐] [Nonempty 𝓐] {alg : Algorithm 𝓐 𝓨} : +lemma absolutelyContinuous_uniformAlgorithm [Finite 𝓐] [Nonempty 𝓐] {alg : Algorithm π“ž 𝓐 𝓨} : alg β‰ͺₐ uniformAlgorithm where policy n h := Measure.absolutelyContinuous_of_measure_singleton_ne_zero (by simp [uniformAlgorithm, uniformOn, ← pos_iff_ne_zero, cond_pos_of_inter_ne_zero]) diff --git a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean index 97b40c6a..9d209727 100644 --- a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean +++ b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean @@ -12,19 +12,22 @@ public import LeanMachineLearning.SequentialLearning.StationaryEnv # Bayesian stationary environments This file defines the structure `IsBayesAlgEnvSeq` and provides its basic properties. +The underlying environments are stationary environments, which have no observations: the +observation type is `Unit` and the observation process is `noObs`. ## Main definitions * `IsBayesAlgEnvSeq Q ΞΊ alg E A Y P`: states that there is a measure `P : Measure Ξ©` such that the parameter `E : Ξ© β†’ 𝓔` has law `Q` and that the sequences of actions `A : β„• β†’ Ξ© β†’ 𝓐` - and feedbacks `Y : β„• β†’ Ξ© β†’ 𝓨` are generated by the algorithm `alg : Algorithm 𝓐 𝓨` interacting - with an underlying environment that depends on `E` and `ΞΊ` (`stationaryEnv (ΞΊ.sectR (E Ο‰))`). + and feedbacks `Y : β„• β†’ Ξ© β†’ 𝓨` are generated by the algorithm `alg : Algorithm Unit 𝓐 𝓨` + interacting with an underlying environment that depends on `E` and `ΞΊ` + (`stationaryEnv (ΞΊ.sectR (E Ο‰))`). * `bayesTrajMeasure Q ΞΊ alg`: for any choice of probability measure `Q : Measure 𝓔`, Markov kernel - `ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨`, and algorithm `alg : Algorithm 𝓐 𝓨`, provides a probability measure - `P : Measure (β„• β†’ 𝓐 Γ— 𝓔 Γ— 𝓨)` on a space that carries `E`, `A`, and `Y` such that + `ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨`, and algorithm `alg : Algorithm Unit 𝓐 𝓨`, provides a probability measure + `P : Measure (β„• β†’ Round Unit 𝓐 (𝓔 Γ— 𝓨))` on a space that carries `E`, `A`, and `Y` such that `IsBayesAlgEnvSeq Q ΞΊ alg E A Y P`. -* `bayesTrajMeasurePosterior Q ΞΊ alg n`: a `Kernel (Fin n β†’ 𝓐 Γ— 𝓨) 𝓔` that represents the - posterior over `E` given the history before time `n` (the `n` first action-feedback pairs) under +* `bayesTrajMeasurePosterior Q ΞΊ alg n`: a `Kernel (Hist Unit 𝓐 𝓨 n) 𝓔` that represents the + posterior over `E` given the history before time `n` (the `n` first rounds) under the prior `Q` and the algorithm `alg`, assuming that the kernel `ΞΊ` specifies how `E` gives rise to the underlying (stationary) environment. See also `LeanMachineLearning/SequentialLearning/AlgorithmDensityBayes.lean`. @@ -32,9 +35,9 @@ This file defines the structure `IsBayesAlgEnvSeq` and provides its basic proper ## Main results * `ae_IsAlgEnvSeq h`: if `h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P`, for `Q`-almost every `e : 𝓔`, - `IsAlgEnvSeq A' Y' alg (stationaryEnv (ΞΊ.sectR e)) (condDistrib (trajectory A Y) E P e)` for some - sequence of actions `A' : β„• β†’ (β„• β†’ 𝓐 Γ— 𝓨) β†’ 𝓐` and sequence of feedbacks - `Y' : β„• β†’ (β„• β†’ 𝓐 Γ— 𝓨) β†’ 𝓨`. Intuitively, if the observable trajectory is generated by an + `IsAlgEnvSeq O' A' Y' alg (stationaryEnv (ΞΊ.sectR e)) (condDistrib (trajectory _ A Y) E P e)` for + some sequence of actions `A' : β„• β†’ (β„• β†’ Round Unit 𝓐 𝓨) β†’ 𝓐` and sequence of feedbacks + `Y' : β„• β†’ (β„• β†’ Round Unit 𝓐 𝓨) β†’ 𝓨`. Intuitively, if the observable trajectory is generated by an underlying parameter `e : 𝓔`, the measure that carries the `IsBayesAlgEnvSeq` structure reveals a measure that carries an `IsAlgEnvSeq` structure under the environment `stationaryEnv (ΞΊ.sectR e)` and the same algorithm. This allows transferring results from the `IsAlgEnvSeq` structure to the @@ -54,10 +57,11 @@ variable [MeasurableSpace 𝓔] [MeasurableSpace 𝓐] [MeasurableSpace 𝓨] [M /-- `IsBayesAlgEnvSeq Q ΞΊ alg E A Y P` states that there is a measure `P : Measure Ξ©` such that the parameter `E : Ξ© β†’ 𝓔` has law `Q` and that the sequences of actions `A : β„• β†’ Ξ© β†’ 𝓐` - and feedbacks `Y : β„• β†’ Ξ© β†’ 𝓨` are generated by the algorithm `alg : Algorithm 𝓐 𝓨` interacting - with an underlying environment that depends on `E` and `ΞΊ` (`stationaryEnv (ΞΊ.sectR (E Ο‰))`). -/ + and feedbacks `Y : β„• β†’ Ξ© β†’ 𝓨` are generated by the algorithm `alg : Algorithm Unit 𝓐 𝓨` + interacting with an underlying environment that depends on `E` and `ΞΊ` + (`stationaryEnv (ΞΊ.sectR (E Ο‰))`). -/ structure IsBayesAlgEnvSeq - (Q : Measure 𝓔) (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) (alg : Algorithm 𝓐 𝓨) + (Q : Measure 𝓔) (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) (alg : Algorithm Unit 𝓐 𝓨) (E : Ξ© β†’ 𝓔) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) (P : Measure Ξ©) [IsFiniteMeasure P] : Prop where measurable_param : Measurable E := by fun_prop @@ -67,20 +71,22 @@ structure IsBayesAlgEnvSeq /-- The action at time `n` has the correct conditional distribution given the parameter and the history: it depends only on the history. -/ hasCondDistrib_action n : - HasCondDistrib (A n) (fun Ο‰ ↦ (E Ο‰, history A Y n Ο‰)) ((alg.policy n).prodMkLeft _) P + HasCondDistrib (A n) (fun Ο‰ ↦ (E Ο‰, (history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰))) + ((alg.policy n).prodMkLeft _) P /-- The feedback at time `n` has the correct conditional distribution given the history, the parameter and the action at time `n`: it depends only on the parameter and the action. -/ hasCondDistrib_feedback n : - HasCondDistrib (Y n) (fun Ο‰ ↦ (history A Y n Ο‰, E Ο‰, A n Ο‰)) (ΞΊ.prodMkLeft _) P + HasCondDistrib (Y n) (fun Ο‰ ↦ ((history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰), E Ο‰, A n Ο‰)) + (ΞΊ.prodMkLeft _) P namespace IsBayesAlgEnvSeq -variable {Q : Measure 𝓔} {ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨} {alg : Algorithm 𝓐 𝓨} +variable {Q : Measure 𝓔} {ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨} {alg : Algorithm Unit 𝓐 𝓨} variable {E : Ξ© β†’ 𝓔} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} variable {P : Measure Ξ©} [IsFiniteMeasure P] lemma hasCondDistrib_action' (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : - HasCondDistrib (A n) (history A Y n) (alg.policy n) P := + HasCondDistrib (A n) (fun Ο‰ ↦ (history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰)) (alg.policy n) P := (h.hasCondDistrib_action n).comp_right lemma hasCondDistrib_feedback' [IsFiniteKernel ΞΊ] (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : @@ -88,14 +94,16 @@ lemma hasCondDistrib_feedback' [IsFiniteKernel ΞΊ] (h : IsBayesAlgEnvSeq Q ΞΊ al (h.hasCondDistrib_feedback n).comp_right lemma hasLaw_action_zero [IsProbabilityMeasure P] (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : - HasLaw (A 0) alg.p0 P := by - have h0 := h.hasCondDistrib_action' 0 - rw [history_zero] at h0 + HasLaw (A 0) (alg.p0 ()) P := by + have h0 : HasCondDistrib (A 0) + (fun _ : Ξ© ↦ ((default : Hist Unit 𝓐 𝓨 0), ())) (alg.policy 0) P := by + have h1 := h.hasCondDistrib_action' 0 + rwa [history_zero] at h1 exact h0.hasLaw_of_const' -/-- The first action is independent of the parameter `E`, and has law `alg.p0`. -/ +/-- The first action is independent of the parameter `E`, and has law `alg.p0 ()`. -/ lemma hasCondDistrib_action_zero (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : - HasCondDistrib (A 0) E (Kernel.const _ alg.p0) P := + HasCondDistrib (A 0) E (Kernel.const _ (alg.p0 ())) P := hasCondDistrib_prodMk_right_unique_iff.mp (h.hasCondDistrib_action 0) variable [StandardBorelSpace 𝓐] [Nonempty 𝓐] [StandardBorelSpace 𝓨] [Nonempty 𝓨] @@ -104,130 +112,163 @@ omit [StandardBorelSpace 𝓐] [Nonempty 𝓐] [StandardBorelSpace 𝓨] [Nonemp /-- The posterior over the parameter given the empty history is the prior. -/ lemma condDistrib_param_history_zero [StandardBorelSpace 𝓔] [Nonempty 𝓔] [IsProbabilityMeasure P] [IsFiniteMeasure Q] (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : - condDistrib E (history A Y 0) P = Kernel.const _ Q := by + condDistrib E (history (noObs Ξ©) A Y 0) P = Kernel.const _ Q := by ext x : 1 rw [Unique.eq_default x, history_zero] - have hc : HasCondDistrib E (fun _ : Ξ© ↦ (default : Fin 0 β†’ 𝓐 Γ— 𝓨)) (Kernel.const _ Q) P := + have hc : HasCondDistrib E (fun _ : Ξ© ↦ (default : Hist Unit 𝓐 𝓨 0)) (Kernel.const _ Q) P := h.hasLaw_env.hasCondDistrib_const have h_ae := hc.condDistrib_eq rw [Measure.map_const, measure_univ, one_smul, Filter.EventuallyEq, ae_dirac_iff Subsingleton.measurableSet] at h_ae exact h_ae +lemma hasCondDistrib_IT_obs [IsProbabilityMeasure P] (_h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) + (n : β„•) : + βˆ€α΅ e βˆ‚Q, HasCondDistrib (IT.obs n) (IT.hist n) (unitObs 𝓐 𝓨 n) + (condDistrib (trajectory (noObs Ξ©) A Y) E P e) := + ae_of_all _ fun _ ↦ hasCondDistrib_unit (IT.measurable_hist n).aemeasurable _ _ + lemma hasCondDistrib_IT_action (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : - βˆ€α΅ e βˆ‚Q, HasCondDistrib (IT.action n) (IT.hist n) (alg.policy n) - (condDistrib (trajectory A Y) E P e) := by + βˆ€α΅ e βˆ‚Q, HasCondDistrib (IT.action n) (fun Ο„ ↦ (IT.hist n Ο„, IT.obs n Ο„)) (alg.policy n) + (condDistrib (trajectory (noObs Ξ©) A Y) E P e) := by rw [← h.hasLaw_env.map_eq] filter_upwards [(h.hasCondDistrib_action n).hasCondDistrib_sectR - (IT.measurable_hist n) (IT.measurable_action n) - (measurable_trajectory h.measurable_action h.measurable_feedback).aemeasurable] with _ he + ((IT.measurable_hist n).prodMk (IT.measurable_obs n)) (IT.measurable_action n) + (measurable_trajectory (O := noObs Ξ©) (fun _ ↦ measurable_const) h.measurable_action + h.measurable_feedback).aemeasurable] with _ he rwa [Kernel.sectR_prodMkLeft] at he lemma hasCondDistrib_IT_feedback [IsFiniteKernel ΞΊ] (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : - βˆ€α΅ e βˆ‚Q, HasCondDistrib (IT.feedback n) (fun Ο„ ↦ (IT.hist n Ο„, IT.action n Ο„)) - ((ΞΊ.sectR e).prodMkLeft _) (condDistrib (trajectory A Y) E P e) := by + βˆ€α΅ e βˆ‚Q, HasCondDistrib (IT.feedback n) + (fun Ο„ ↦ ((IT.hist n Ο„, IT.obs n Ο„), IT.action n Ο„)) + ((ΞΊ.sectR e).prodMkLeft _) (condDistrib (trajectory (noObs Ξ©) A Y) E P e) := by rw [← h.hasLaw_env.map_eq] - have hc : HasCondDistrib (Y n) (fun Ο‰ ↦ (E Ο‰, history A Y n Ο‰, A n Ο‰)) - (ΞΊ.comap (fun (e, _, a) ↦ (e, a)) (by fun_prop)) P := + have hc : HasCondDistrib (Y n) + (fun Ο‰ ↦ (E Ο‰, ((history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰), A n Ο‰))) + (ΞΊ.comap (fun p : 𝓔 Γ— ((Hist Unit 𝓐 𝓨 n Γ— Unit) Γ— 𝓐) ↦ (p.1, p.2.2)) (by fun_prop)) P := (h.hasCondDistrib_feedback n).measurableEquiv_comp_right (MeasurableEquiv.prodAssoc.symm.trans ((MeasurableEquiv.prodCongr .prodComm (.refl _)).trans .prodAssoc)) - exact hc.hasCondDistrib_sectR ((IT.measurable_hist n).prodMk (IT.measurable_action n)) + exact hc.hasCondDistrib_sectR + (((IT.measurable_hist n).prodMk (IT.measurable_obs n)).prodMk (IT.measurable_action n)) (IT.measurable_feedback n) - (measurable_trajectory h.measurable_action h.measurable_feedback).aemeasurable + (measurable_trajectory (O := noObs Ξ©) (fun _ ↦ measurable_const) h.measurable_action + h.measurable_feedback).aemeasurable lemma hasLaw_IT_hist (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : - βˆ€α΅ e βˆ‚Q, HasLaw (IT.hist n) (condDistrib (history A Y n) E P e) - (condDistrib (trajectory A Y) E P e) := by - rw [← h.hasLaw_env.map_eq, show history A Y n = IT.hist n ∘ trajectory A Y from rfl] + βˆ€α΅ e βˆ‚Q, HasLaw (IT.hist n) (condDistrib (history (noObs Ξ©) A Y n) E P e) + (condDistrib (trajectory (noObs Ξ©) A Y) E P e) := by + rw [← h.hasLaw_env.map_eq, show history (noObs Ξ©) A Y n + = IT.hist (π“ž := Unit) (𝓐 := 𝓐) (𝓨 := 𝓨) n ∘ trajectory (noObs Ξ©) A Y from rfl] filter_upwards [condDistrib_comp E - (measurable_trajectory h.measurable_action h.measurable_feedback).aemeasurable - (IT.measurable_hist n)] with _ he + (measurable_trajectory (O := noObs Ξ©) (fun _ ↦ measurable_const) h.measurable_action + h.measurable_feedback).aemeasurable + (IT.measurable_hist (π“ž := Unit) (𝓐 := 𝓐) (𝓨 := 𝓨) n)] with _ he exact ⟨(IT.measurable_hist n).aemeasurable, by rw [← Kernel.map_apply _ (IT.measurable_hist n), he]⟩ -lemma ae_IsAlgEnvSeq [IsMarkovKernel ΞΊ] (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : - βˆ€α΅ e βˆ‚Q, IsAlgEnvSeq IT.action IT.feedback alg (stationaryEnv (ΞΊ.sectR e)) - (condDistrib (trajectory A Y) E P e) := by - filter_upwards [ae_all_iff.2 (hasCondDistrib_IT_action h), - ae_all_iff.2 (hasCondDistrib_IT_feedback h)] with _ hA hR - exact ⟨IT.measurable_action, IT.measurable_feedback, hA, hR⟩ +lemma ae_IsAlgEnvSeq [IsProbabilityMeasure P] [IsMarkovKernel ΞΊ] + (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : + βˆ€α΅ e βˆ‚Q, IsAlgEnvSeq IT.obs IT.action IT.feedback alg (stationaryEnv (ΞΊ.sectR e)) + (condDistrib (trajectory (noObs Ξ©) A Y) E P e) := by + filter_upwards [ae_all_iff.2 (hasCondDistrib_IT_obs h), + ae_all_iff.2 (hasCondDistrib_IT_action h), + ae_all_iff.2 (hasCondDistrib_IT_feedback h)] with _ hO hA hR + exact ⟨IT.measurable_obs, IT.measurable_action, IT.measurable_feedback, hO, hA, hR⟩ end IsBayesAlgEnvSeq section IsAlgEnvSeq -/-- An environment with observations in `𝓔 Γ— 𝓨`. The first element `e` of an observation is -sampled from `Q` at time `0` and then remains constant: at time `n + 1` it is read from the first -observation in the history. The second element of an observation is sampled from `ΞΊ (e, a)`, where +/-- An environment without observations whose feedback lies in `𝓔 Γ— 𝓨`. The first element `e` of a +feedback is sampled from `Q` at time `0` and then remains constant: at time `n + 1` it is read from +the first round in the history. The second element of a feedback is sampled from `ΞΊ (e, a)`, where `a` is the corresponding action. -/ noncomputable def bayesStationaryEnv (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) - [IsMarkovKernel ΞΊ] : Environment 𝓐 (𝓔 Γ— 𝓨) where + [IsMarkovKernel ΞΊ] : Environment Unit 𝓐 (𝓔 Γ— 𝓨) where + obs n := unitObs 𝓐 (𝓔 Γ— 𝓨) n feedback | 0 => ((Kernel.const _ Q) βŠ—β‚– ΞΊ.swapLeft).prodMkLeft _ | n + 1 => - let g : (Fin (n + 1) β†’ 𝓐 Γ— 𝓔 Γ— 𝓨) Γ— 𝓐 β†’ 𝓔 Γ— 𝓐 := fun (h, a) ↦ ((h 0).2.1, a) + let g : (Hist Unit 𝓐 (𝓔 Γ— 𝓨) (n + 1) Γ— Unit) Γ— 𝓐 β†’ 𝓔 Γ— 𝓐 := + fun p ↦ ((p.1.1 0).feedback.1, p.2) (Kernel.deterministic (Prod.fst ∘ g) (by fun_prop)) Γ—β‚– (ΞΊ.comap g (by fun_prop)) - h_feedback n := by cases n <;> infer_instance + isMarkovKernel_feedback n := by cases n <;> infer_instance variable {Q : Measure 𝓔} [IsProbabilityMeasure Q] {ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨} [IsMarkovKernel ΞΊ] +@[simp] +lemma bayesStationaryEnv_obs (n : β„•) : + (bayesStationaryEnv Q ΞΊ).obs n = unitObs 𝓐 (𝓔 Γ— 𝓨) n := rfl + lemma bayesStationaryEnv_feedback_zero : (bayesStationaryEnv Q ΞΊ).feedback 0 = ((Kernel.const _ Q) βŠ—β‚– ΞΊ.swapLeft).prodMkLeft _ := rfl lemma bayesStationaryEnv_feedback_succ (n : β„•) : (bayesStationaryEnv Q ΞΊ).feedback (n + 1) = - (Kernel.deterministic (Prod.fst ∘ (fun (p : (Fin (n + 1) β†’ 𝓐 Γ— 𝓔 Γ— 𝓨) Γ— 𝓐) ↦ - ((p.1 0).2.1, p.2))) (by fun_prop)) Γ—β‚– - (ΞΊ.comap (fun p ↦ ((p.1 0).2.1, p.2)) (by fun_prop)) := rfl + (Kernel.deterministic (Prod.fst ∘ (fun p : (Hist Unit 𝓐 (𝓔 Γ— 𝓨) (n + 1) Γ— Unit) Γ— 𝓐 ↦ + ((p.1.1 0).feedback.1, p.2))) (by fun_prop)) Γ—β‚– + (ΞΊ.comap (fun p ↦ ((p.1.1 0).feedback.1, p.2)) (by fun_prop)) := rfl @[simp] -lemma Ξ½0_bayesStationaryEnv : (bayesStationaryEnv Q ΞΊ).Ξ½0 = (Kernel.const _ Q) βŠ—β‚– ΞΊ.swapLeft := by - rw [Environment.Ξ½0_def, bayesStationaryEnv_feedback_zero, Kernel.sectR_prodMkLeft] +lemma Ξ½0_bayesStationaryEnv : + (bayesStationaryEnv Q ΞΊ).Ξ½0 = ((Kernel.const _ Q) βŠ—β‚– ΞΊ.swapLeft).prodMkLeft Unit := rfl -variable {alg : Algorithm 𝓐 𝓨} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓔 Γ— 𝓨} +variable {alg : Algorithm Unit 𝓐 𝓨} {O : β„• β†’ Ξ© β†’ Unit} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓔 Γ— 𝓨} variable {P : Measure Ξ©} [IsProbabilityMeasure P] lemma IsAlgEnvSeq.isBayesAlgEnvSeq - (h : IsAlgEnvSeq A Y (alg.prodLeft 𝓔) (bayesStationaryEnv Q ΞΊ) P) : + (h : IsAlgEnvSeq O A Y (alg.prodLeft 𝓔) (bayesStationaryEnv Q ΞΊ) P) : IsBayesAlgEnvSeq Q ΞΊ alg (fun Ο‰ ↦ (Y 0 Ο‰).1) A (fun n Ο‰ ↦ (Y n Ο‰).2) P where measurable_param := (h.measurable_feedback 0).fst measurable_action := h.measurable_action measurable_feedback n := (h.measurable_feedback n).snd hasLaw_env := by - apply HasCondDistrib.hasLaw_of_const - simpa [Kernel.fst_compProd] using h.hasCondDistrib_feedback_zero.fst + have hc : HasCondDistrib (Y 0) (A 0) ((Kernel.const _ Q) βŠ—β‚– ΞΊ.swapLeft) P := + hasCondDistrib_prodMk_left_unique_iff.mp h.hasCondDistrib_feedback_zero + have hc' : HasCondDistrib (fun Ο‰ ↦ (Y 0 Ο‰).1) (A 0) (Kernel.const 𝓐 Q) P := by + simpa [Kernel.fst_compProd] using hc.fst + exact hc'.hasLaw_of_const hasCondDistrib_action n := by cases n with | zero => -- At time `0` the history is empty: `E` is the parameter component of `Y 0`, which is -- independent of `A 0`. + have hc0 : HasCondDistrib (Y 0) (A 0) ((Kernel.const _ Q) βŠ—β‚– ΞΊ.swapLeft) P := + hasCondDistrib_prodMk_left_unique_iff.mp h.hasCondDistrib_feedback_zero have hc : HasCondDistrib (fun Ο‰ ↦ (Y 0 Ο‰).1) (A 0) (Kernel.const _ Q) P := by - simpa [Kernel.fst_compProd] using h.hasCondDistrib_feedback_zero.fst - have hc' : HasCondDistrib (A 0) (fun Ο‰ ↦ (Y 0 Ο‰).1) (Kernel.const _ alg.p0) P := by - simpa [h.hasLaw_action_zero.map_eq] using hc.const_map_of_const + simpa [Kernel.fst_compProd] using hc0.fst + have h_law : HasLaw (A 0) (alg.p0 ()) P := by + have h0 : HasCondDistrib (A 0) (fun _ : Ξ© ↦ ()) + ((alg.prodLeft 𝓔).p0) P := h.hasCondDistrib_action_zero + simpa using h0.hasLaw_of_const' + have hc' : HasCondDistrib (A 0) (fun Ο‰ ↦ (Y 0 Ο‰).1) (Kernel.const _ (alg.p0 ())) P := by + simpa [h_law.map_eq] using hc.const_map_of_const exact hasCondDistrib_prodMk_right_unique_iff.mpr hc' | succ n => - let f : (Fin (n + 1) β†’ 𝓐 Γ— 𝓔 Γ— 𝓨) β†’ 𝓔 Γ— (Fin (n + 1) β†’ 𝓐 Γ— 𝓨) := - fun h ↦ ((h 0).2.1, fun i ↦ ((h i).1, (h i).2.2)) - have hc : HasCondDistrib (A (n + 1)) (history A Y (n + 1)) - (((alg.policy (n + 1)).comap Prod.snd (by fun_prop)).comap f (by fun_prop)) P := + let f : (Hist Unit 𝓐 (𝓔 Γ— 𝓨) (n + 1) Γ— Unit) β†’ 𝓔 Γ— (Hist Unit 𝓐 𝓨 (n + 1) Γ— Unit) := + fun p ↦ ((p.1 0).feedback.1, + (fun i ↦ ((p.1 i).obs, (p.1 i).action, (p.1 i).feedback.2), p.2)) + have hc : HasCondDistrib (A (n + 1)) (fun Ο‰ ↦ (history O A Y (n + 1) Ο‰, O (n + 1) Ο‰)) + (((alg.policy (n + 1)).prodMkLeft 𝓔).comap f (by fun_prop)) P := h.hasCondDistrib_action (n + 1) exact hc.comp_right (f := f) hasCondDistrib_feedback n := by cases n with | zero => - have hc : HasCondDistrib (Y 0) (A 0) ((Kernel.const _ Q) βŠ—β‚– ΞΊ.swapLeft) P := by - simpa using h.hasCondDistrib_feedback_zero + have hc : HasCondDistrib (Y 0) (A 0) ((Kernel.const _ Q) βŠ—β‚– ΞΊ.swapLeft) P := + hasCondDistrib_prodMk_left_unique_iff.mp h.hasCondDistrib_feedback_zero exact hasCondDistrib_prodMk_left_unique_iff.mpr (hc.of_compProd.measurableEquiv_comp_right MeasurableEquiv.prodComm) | succ n => - let f : (Fin (n + 1) β†’ 𝓐 Γ— 𝓔 Γ— 𝓨) Γ— 𝓐 β†’ (Fin (n + 1) β†’ 𝓐 Γ— 𝓨) Γ— 𝓔 Γ— 𝓐 := - fun p ↦ ((fun i ↦ ((p.1 i).1, (p.1 i).2.2)), (p.1 0).2.1, p.2) + let f : ((Hist Unit 𝓐 (𝓔 Γ— 𝓨) (n + 1) Γ— Unit) Γ— 𝓐) β†’ + ((Hist Unit 𝓐 𝓨 (n + 1) Γ— Unit) Γ— 𝓔 Γ— 𝓐) := + fun p ↦ ((fun i ↦ ((p.1.1 i).obs, (p.1.1 i).action, (p.1.1 i).feedback.2), p.1.2), + (p.1.1 0).feedback.1, p.2) have hc : HasCondDistrib (fun Ο‰ ↦ (Y (n + 1) Ο‰).2) - (fun Ο‰ ↦ (history A Y (n + 1) Ο‰, A (n + 1) Ο‰)) - ((Kernel.prodMkLeft (Fin (n + 1) β†’ 𝓐 Γ— 𝓨) ΞΊ).comap f (by fun_prop)) P := by + (fun Ο‰ ↦ ((history O A Y (n + 1) Ο‰, O (n + 1) Ο‰), A (n + 1) Ο‰)) + ((Kernel.prodMkLeft (Hist Unit 𝓐 𝓨 (n + 1) Γ— Unit) ΞΊ).comap f (by fun_prop)) P := by simpa [bayesStationaryEnv_feedback_succ, Kernel.prodMkLeft, ← Kernel.comap_comp_right, Function.comp_def] using (h.hasCondDistrib_feedback (n + 1)).snd exact hc.comp_right @@ -240,29 +281,31 @@ namespace IT `IsBayesAlgEnvSeq Q ΞΊ alg E A Y P`. -/ noncomputable def bayesTrajMeasure (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) - [IsMarkovKernel ΞΊ] (alg : Algorithm 𝓐 𝓨) : Measure (β„• β†’ 𝓐 Γ— 𝓔 Γ— 𝓨) := + [IsMarkovKernel ΞΊ] (alg : Algorithm Unit 𝓐 𝓨) : Measure (β„• β†’ Round Unit 𝓐 (𝓔 Γ— 𝓨)) := trajMeasure (alg.prodLeft 𝓔) (bayesStationaryEnv Q ΞΊ) deriving IsProbabilityMeasure lemma isBayesAlgEnvSeq_bayesTrajMeasure (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) [IsMarkovKernel ΞΊ] - (alg : Algorithm 𝓐 𝓨) : - IsBayesAlgEnvSeq Q ΞΊ alg (fun Ο‰ ↦ (Ο‰ 0).2.1) action (fun n Ο‰ ↦ (Ο‰ n).2.2) - (bayesTrajMeasure Q ΞΊ alg) := (isAlgEnvSeq_trajMeasure _ _).isBayesAlgEnvSeq + (alg : Algorithm Unit 𝓐 𝓨) : + IsBayesAlgEnvSeq Q ΞΊ alg (fun Ο‰ ↦ (Ο‰ 0).feedback.1) action + (fun n Ο‰ ↦ (Ο‰ n).feedback.2) (bayesTrajMeasure Q ΞΊ alg) := + (isAlgEnvSeq_trajMeasure _ _).isBayesAlgEnvSeq /-- A kernel that represents the posterior over `E` given the history before time `n`. -/ noncomputable def bayesTrajMeasurePosterior [StandardBorelSpace 𝓔] [Nonempty 𝓔] (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) [IsMarkovKernel ΞΊ] - (alg : Algorithm 𝓐 𝓨) (n : β„•) : Kernel (Fin n β†’ 𝓐 Γ— 𝓨) 𝓔 := - condDistrib (fun Ο‰ ↦ (Ο‰ 0).2.1) (history action (fun n Ο‰ ↦ (Ο‰ n).2.2) n) + (alg : Algorithm Unit 𝓐 𝓨) (n : β„•) : Kernel (Hist Unit 𝓐 𝓨 n) 𝓔 := + condDistrib (fun Ο‰ ↦ (Ο‰ 0).feedback.1) + (history (noObs _) action (fun n Ο‰ ↦ (Ο‰ n).feedback.2) n) (bayesTrajMeasure Q ΞΊ alg) deriving IsMarkovKernel /-- The posterior given the empty history is the prior. -/ lemma bayesTrajMeasurePosterior_zero [StandardBorelSpace 𝓔] [Nonempty 𝓔] (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) [IsMarkovKernel ΞΊ] - (alg : Algorithm 𝓐 𝓨) : + (alg : Algorithm Unit 𝓐 𝓨) : bayesTrajMeasurePosterior Q ΞΊ alg 0 = Kernel.const _ Q := (isBayesAlgEnvSeq_bayesTrajMeasure Q ΞΊ alg).condDistrib_param_history_zero diff --git a/LeanMachineLearning/SequentialLearning/Deterministic.lean b/LeanMachineLearning/SequentialLearning/Deterministic.lean index 913659ce..66784d36 100644 --- a/LeanMachineLearning/SequentialLearning/Deterministic.lean +++ b/LeanMachineLearning/SequentialLearning/Deterministic.lean @@ -12,8 +12,8 @@ public import LeanMachineLearning.SequentialLearning.Algorithm # Deterministic algorithms and environments A deterministic algorithm chooses its action in a deterministic way. That is, that action is given -by a measurable function of the history instead of a general Markov kernel. -Similarly, a deterministic environment gives feedback in a deterministic way. +by a measurable function of the history and of the current observation instead of a general Markov +kernel. Similarly, a deterministic environment gives feedback in a deterministic way. ## Main definitions @@ -26,19 +26,19 @@ measurable functions. * `IsDeterministicAlg alg`: a typeclass expressing that the algorithm `alg` is deterministic. * `IsDeterministicEnv env`: a typeclass expressing that the environment `env` is deterministic. * `nextAction alg n`: the function that gives the action of a deterministic algorithm `alg` - at step `n`, as a function of the history before `n`. -* `actionZero alg`: the initial action of a deterministic algorithm `alg`. This is - `nextAction alg 0` applied to the empty history. + at step `n`, as a function of the history before `n` and of the observation at step `n`. +* `actionZero alg`: the initial action of a deterministic algorithm `alg`, as a function of the + first observation. This is `nextAction alg 0` applied to the empty history. * `feedbackFun env n`: the function that gives the feedback of a deterministic environment `env` - at step `n`, as a function of the history and the current action. + at step `n`, as a function of the history, the current observation and the current action. * `feedbackFunZero env`: the function that gives the initial feedback of a deterministic environment `env`. This is `feedbackFun env 0` applied to the empty history. * `detAlgorithm nextA h_next`: a deterministic algorithm that chooses its action according to the measurable function `nextA` (with proof of measurability `h_next`). - The initial action is `nextA 0 default`. -* `detEnvironment f hf`: a deterministic environment that gives feedback according to the - measurable function `f` (with proof of measurability `hf`). + The initial action is `fun o ↦ nextA 0 (default, o)`. +* `detEnvironment obs f hf`: a deterministic environment with observation kernels `obs`, that gives + feedback according to the measurable function `f` (with proof of measurability `hf`). -/ @@ -50,159 +50,177 @@ open scoped ENNReal NNReal namespace Learning -variable {𝓐 𝓨 : Type*} {m𝓐 : MeasurableSpace 𝓐} {m𝓨 : MeasurableSpace 𝓨} +variable {π“ž 𝓐 𝓨 : Type*} {mπ“ž : MeasurableSpace π“ž} {m𝓐 : MeasurableSpace 𝓐} + {m𝓨 : MeasurableSpace 𝓨} /-- An algorithm is deterministic if its actions are determined by measurable functions of the -history (and not possibly random kernels). -/ -class IsDeterministicAlg (alg : Algorithm 𝓐 𝓨) : Prop where - exists_nextAction n : βˆƒ (nextAction : (Fin n β†’ 𝓐 Γ— 𝓨) β†’ 𝓐) (h_meas : Measurable nextAction), +history and of the current observation (and not possibly random kernels). -/ +class IsDeterministicAlg (alg : Algorithm π“ž 𝓐 𝓨) : Prop where + exists_nextAction n : βˆƒ (nextAction : (Hist π“ž 𝓐 𝓨 n Γ— π“ž) β†’ 𝓐) (h_meas : Measurable nextAction), alg.policy n = Kernel.deterministic nextAction h_meas -/-- The action of a deterministic algorithm at step `n`, as a function of the history before `n`. -/ +/-- The action of a deterministic algorithm at step `n`, as a function of the history before `n` +and of the observation at step `n`. -/ noncomputable -def nextAction (alg : Algorithm 𝓐 𝓨) [h_det : IsDeterministicAlg alg] (n : β„•) : - (Fin n β†’ 𝓐 Γ— 𝓨) β†’ 𝓐 := +def nextAction (alg : Algorithm π“ž 𝓐 𝓨) [h_det : IsDeterministicAlg alg] (n : β„•) : + (Hist π“ž 𝓐 𝓨 n Γ— π“ž) β†’ 𝓐 := (h_det.exists_nextAction n).choose -/-- The initial action of a deterministic algorithm. -/ +/-- The initial action of a deterministic algorithm, as a function of the first observation. -/ noncomputable -def actionZero (alg : Algorithm 𝓐 𝓨) [IsDeterministicAlg alg] : 𝓐 := - nextAction alg 0 default +def actionZero (alg : Algorithm π“ž 𝓐 𝓨) [IsDeterministicAlg alg] : π“ž β†’ 𝓐 := + fun o ↦ nextAction alg 0 (default, o) @[fun_prop] -lemma measurable_nextAction (alg : Algorithm 𝓐 𝓨) [IsDeterministicAlg alg] (n : β„•) : +lemma measurable_nextAction (alg : Algorithm π“ž 𝓐 𝓨) [IsDeterministicAlg alg] (n : β„•) : Measurable (nextAction alg n) := (IsDeterministicAlg.exists_nextAction n).choose_spec.choose -lemma policy_eq_deterministic (alg : Algorithm 𝓐 𝓨) [h_det : IsDeterministicAlg alg] (n : β„•) : +@[fun_prop] +lemma measurable_actionZero (alg : Algorithm π“ž 𝓐 𝓨) [IsDeterministicAlg alg] : + Measurable (actionZero alg) := + (measurable_nextAction alg 0).comp (measurable_const.prodMk measurable_id) + +lemma policy_eq_deterministic (alg : Algorithm π“ž 𝓐 𝓨) [h_det : IsDeterministicAlg alg] (n : β„•) : alg.policy n = Kernel.deterministic (nextAction alg n) (measurable_nextAction alg n) := (IsDeterministicAlg.exists_nextAction n).choose_spec.choose_spec -lemma nextAction_zero (alg : Algorithm 𝓐 𝓨) [IsDeterministicAlg alg] (h : Fin 0 β†’ 𝓐 Γ— 𝓨) : - nextAction alg 0 h = actionZero alg := by +lemma nextAction_zero (alg : Algorithm π“ž 𝓐 𝓨) [IsDeterministicAlg alg] (h : Hist π“ž 𝓐 𝓨 0) + (o : π“ž) : + nextAction alg 0 (h, o) = actionZero alg o := by rw [Unique.eq_default h] rfl -lemma p0_eq_dirac (alg : Algorithm 𝓐 𝓨) [IsDeterministicAlg alg] : - alg.p0 = Measure.dirac (actionZero alg) := by - rw [Algorithm.p0_def, policy_eq_deterministic, Kernel.deterministic_apply] +lemma p0_eq_deterministic (alg : Algorithm π“ž 𝓐 𝓨) [IsDeterministicAlg alg] : + alg.p0 = Kernel.deterministic (actionZero alg) (measurable_actionZero alg) := by + ext o : 1 + rw [Algorithm.p0_apply, policy_eq_deterministic, Kernel.deterministic_apply, + Kernel.deterministic_apply] rfl namespace IsDeterministicAlg variable {Ξ© : Type*} {mΞ© : MeasurableSpace Ξ©} - {alg : Algorithm 𝓐 𝓨} {env : Environment 𝓐 𝓨} {P : Measure Ξ©} [IsFiniteMeasure P] - {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {n N : β„•} + {alg : Algorithm π“ž 𝓐 𝓨} {env : Environment π“ž 𝓐 𝓨} {P : Measure Ξ©} [IsFiniteMeasure P] + {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {n N : β„•} lemma action_ae_eq_of_IsAlgEnvSeqUntil [MeasurableEq 𝓐] - [h_det : IsDeterministicAlg alg] (h : IsAlgEnvSeqUntil A Y alg env P N) (hn : n < N) : - A n =ᡐ[P] fun Ο‰ ↦ nextAction alg n (history A Y n Ο‰) := by + [h_det : IsDeterministicAlg alg] (h : IsAlgEnvSeqUntil O A Y alg env P N) (hn : n < N) : + A n =ᡐ[P] fun Ο‰ ↦ nextAction alg n (history O A Y n Ο‰, O n Ο‰) := by have h_eq := (h.hasCondDistrib_action n hn) rw [policy_eq_deterministic alg n] at h_eq + have hO := h.measurable_obs + have hA := h.measurable_action + have hY := h.measurable_feedback exact ae_eq_of_hasCondDistrib_deterministic (measurable_nextAction _ _) (by fun_prop) (by fun_prop) h_eq lemma action_zero_of_IsAlgEnvSeqUntil [MeasurableEq 𝓐] [h_det : IsDeterministicAlg alg] - (h : IsAlgEnvSeqUntil A Y alg env P N) (hN : 0 < N) : - A 0 =ᡐ[P] fun _ ↦ actionZero alg := by + (h : IsAlgEnvSeqUntil O A Y alg env P N) (hN : 0 < N) : + A 0 =ᡐ[P] fun Ο‰ ↦ actionZero alg (O 0 Ο‰) := by filter_upwards [action_ae_eq_of_IsAlgEnvSeqUntil h hN] with Ο‰ hΟ‰ rw [hΟ‰, nextAction_zero] -lemma hasLaw_action_zero_of_IsAlgEnvSeqUntil [IsProbabilityMeasure P] - [h_det : IsDeterministicAlg alg] (h : IsAlgEnvSeqUntil A Y alg env P N) (hN : 0 < N) : - HasLaw (A 0) (Measure.dirac (actionZero alg)) P where - aemeasurable := have hA := h.measurable_action; by fun_prop - map_eq := (h.hasLaw_action_zero hN).map_eq.trans (p0_eq_dirac alg) +lemma hasCondDistrib_action_zero_of_IsAlgEnvSeqUntil [h_det : IsDeterministicAlg alg] + (h : IsAlgEnvSeqUntil O A Y alg env P N) (hN : 0 < N) : + HasCondDistrib (A 0) (O 0) + (Kernel.deterministic (actionZero alg) (measurable_actionZero alg)) P := by + rw [← p0_eq_deterministic] + exact h.hasCondDistrib_action_zero hN -lemma hasLaw_action_zero [IsProbabilityMeasure P] [h_det : IsDeterministicAlg alg] - (h : IsAlgEnvSeq A Y alg env P) : - HasLaw (A 0) (Measure.dirac (actionZero alg)) P := - hasLaw_action_zero_of_IsAlgEnvSeqUntil (h.isAlgEnvSeqUntil 1) zero_lt_one +lemma hasCondDistrib_action_zero [h_det : IsDeterministicAlg alg] + (h : IsAlgEnvSeq O A Y alg env P) : + HasCondDistrib (A 0) (O 0) + (Kernel.deterministic (actionZero alg) (measurable_actionZero alg)) P := + hasCondDistrib_action_zero_of_IsAlgEnvSeqUntil (h.isAlgEnvSeqUntil 1) zero_lt_one lemma action_ae_eq [MeasurableEq 𝓐] [h_det : IsDeterministicAlg alg] - (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : - A n =ᡐ[P] fun Ο‰ ↦ nextAction alg n (history A Y n Ο‰) := + (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + A n =ᡐ[P] fun Ο‰ ↦ nextAction alg n (history O A Y n Ο‰, O n Ο‰) := action_ae_eq_of_IsAlgEnvSeqUntil (h.isAlgEnvSeqUntil (n + 1)) n.lt_succ_self lemma action_zero_ae_eq [MeasurableEq 𝓐] [h_det : IsDeterministicAlg alg] - (h : IsAlgEnvSeq A Y alg env P) : - A 0 =ᡐ[P] fun _ ↦ actionZero alg := + (h : IsAlgEnvSeq O A Y alg env P) : + A 0 =ᡐ[P] fun Ο‰ ↦ actionZero alg (O 0 Ο‰) := action_zero_of_IsAlgEnvSeqUntil (h.isAlgEnvSeqUntil 1) zero_lt_one lemma action_ae_all_eq [MeasurableEq 𝓐] [h_det : IsDeterministicAlg alg] - (h : IsAlgEnvSeq A Y alg env P) : - βˆ€α΅ Ο‰ βˆ‚P, βˆ€ n, A n Ο‰ = nextAction alg n (history A Y n Ο‰) := + (h : IsAlgEnvSeq O A Y alg env P) : + βˆ€α΅ Ο‰ βˆ‚P, βˆ€ n, A n Ο‰ = nextAction alg n (history O A Y n Ο‰, O n Ο‰) := ae_all_iff.mpr (action_ae_eq h) end IsDeterministicAlg /-- An environment is deterministic if its feedbacks are determined by measurable functions of -the history and the action (and not possibly random kernels). -/ -class IsDeterministicEnv (env : Environment 𝓐 𝓨) : Prop where - exists_f : βˆ€ n, βˆƒ (f : ((Fin n β†’ 𝓐 Γ— 𝓨) Γ— 𝓐) β†’ 𝓨) (hf : Measurable f), +the history, the observation and the action (and not possibly random kernels). -/ +class IsDeterministicEnv (env : Environment π“ž 𝓐 𝓨) : Prop where + exists_f : βˆ€ n, βˆƒ (f : ((Hist π“ž 𝓐 𝓨 n Γ— π“ž) Γ— 𝓐) β†’ 𝓨) (hf : Measurable f), env.feedback n = Kernel.deterministic f hf /-- The feedback function of a deterministic environment at step `n`. -/ noncomputable -def feedbackFun (env : Environment 𝓐 𝓨) [h_det : IsDeterministicEnv env] (n : β„•) : - ((Fin n β†’ 𝓐 Γ— 𝓨) Γ— 𝓐) β†’ 𝓨 := +def feedbackFun (env : Environment π“ž 𝓐 𝓨) [h_det : IsDeterministicEnv env] (n : β„•) : + ((Hist π“ž 𝓐 𝓨 n Γ— π“ž) Γ— 𝓐) β†’ 𝓨 := (h_det.exists_f n).choose @[fun_prop] -lemma measurable_feedbackFun (env : Environment 𝓐 𝓨) [IsDeterministicEnv env] (n : β„•) : +lemma measurable_feedbackFun (env : Environment π“ž 𝓐 𝓨) [IsDeterministicEnv env] (n : β„•) : Measurable (feedbackFun env n) := (IsDeterministicEnv.exists_f n).choose_spec.choose -lemma feedback_eq_deterministic (env : Environment 𝓐 𝓨) [IsDeterministicEnv env] (n : β„•) : +lemma feedback_eq_deterministic (env : Environment π“ž 𝓐 𝓨) [IsDeterministicEnv env] (n : β„•) : env.feedback n = Kernel.deterministic (feedbackFun env n) (measurable_feedbackFun env n) := (IsDeterministicEnv.exists_f n).choose_spec.choose_spec -/-- The initial feedback function of a deterministic environment. -/ +/-- The initial feedback function of a deterministic environment, as a function of the first +observation and the first action. -/ noncomputable -def feedbackFunZero (env : Environment 𝓐 𝓨) [IsDeterministicEnv env] : 𝓐 β†’ 𝓨 := - fun a ↦ feedbackFun env 0 (default, a) +def feedbackFunZero (env : Environment π“ž 𝓐 𝓨) [IsDeterministicEnv env] : π“ž Γ— 𝓐 β†’ 𝓨 := + fun p ↦ feedbackFun env 0 ((default, p.1), p.2) @[fun_prop] -lemma measurable_feedbackFunZero (env : Environment 𝓐 𝓨) [IsDeterministicEnv env] : +lemma measurable_feedbackFunZero (env : Environment π“ž 𝓐 𝓨) [IsDeterministicEnv env] : Measurable (feedbackFunZero env) := - (measurable_feedbackFun env 0).comp (measurable_const.prodMk measurable_id) + (measurable_feedbackFun env 0).comp + ((measurable_const.prodMk measurable_fst).prodMk measurable_snd) -lemma feedbackFun_zero (env : Environment 𝓐 𝓨) [IsDeterministicEnv env] (h : Fin 0 β†’ 𝓐 Γ— 𝓨) - (a : 𝓐) : - feedbackFun env 0 (h, a) = feedbackFunZero env a := by +lemma feedbackFun_zero (env : Environment π“ž 𝓐 𝓨) [IsDeterministicEnv env] (h : Hist π“ž 𝓐 𝓨 0) + (o : π“ž) (a : 𝓐) : + feedbackFun env 0 ((h, o), a) = feedbackFunZero env (o, a) := by rw [Unique.eq_default h] rfl -lemma Ξ½0_eq_deterministic (env : Environment 𝓐 𝓨) [IsDeterministicEnv env] : +lemma Ξ½0_eq_deterministic (env : Environment π“ž 𝓐 𝓨) [IsDeterministicEnv env] : env.Ξ½0 = Kernel.deterministic (feedbackFunZero env) (measurable_feedbackFunZero env) := by - ext a : 1 - rw [Environment.Ξ½0_apply, feedback_eq_deterministic, Kernel.deterministic_apply, + ext p : 1 + rw [Environment.Ξ½0_def, Kernel.comap_apply, feedback_eq_deterministic, Kernel.deterministic_apply, Kernel.deterministic_apply] rfl namespace IsDeterministicEnv variable {Ξ© : Type*} {mΞ© : MeasurableSpace Ξ©} - {alg : Algorithm 𝓐 𝓨} {env : Environment 𝓐 𝓨} {P : Measure Ξ©} [IsFiniteMeasure P] - {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} + {alg : Algorithm π“ž 𝓐 𝓨} {env : Environment π“ž 𝓐 𝓨} {P : Measure Ξ©} [IsFiniteMeasure P] + {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} lemma hasCondDistrib_feedback [h_det : IsDeterministicEnv env] - (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : - HasCondDistrib (Y n) (fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) + (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + HasCondDistrib (Y n) (fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) (Kernel.deterministic (feedbackFun env n) (measurable_feedbackFun env n)) P := by rw [← feedback_eq_deterministic] exact h.hasCondDistrib_feedback n lemma hasCondDistrib_feedback_zero [h_det : IsDeterministicEnv env] - (h : IsAlgEnvSeq A Y alg env P) : - HasCondDistrib (Y 0) (A 0) + (h : IsAlgEnvSeq O A Y alg env P) : + HasCondDistrib (Y 0) (fun Ο‰ ↦ (O 0 Ο‰, A 0 Ο‰)) (Kernel.deterministic (feedbackFunZero env) (measurable_feedbackFunZero env)) P := by rw [← Ξ½0_eq_deterministic] exact h.hasCondDistrib_feedback_zero lemma feedback_ae_eq [MeasurableEq 𝓨] [h_det : IsDeterministicEnv env] - (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : - Y n =ᡐ[P] fun Ο‰ ↦ feedbackFun env n (history A Y n Ο‰, A n Ο‰) := by + (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + Y n =ᡐ[P] fun Ο‰ ↦ feedbackFun env n ((history O A Y n Ο‰, O n Ο‰), A n Ο‰) := by + have hO := h.measurable_obs have hA := h.measurable_action have hY := h.measurable_feedback exact ae_eq_of_hasCondDistrib_deterministic (measurable_feedbackFun _ _) (by fun_prop) @@ -210,25 +228,31 @@ lemma feedback_ae_eq [MeasurableEq 𝓨] [h_det : IsDeterministicEnv env] end IsDeterministicEnv -variable {nextA : (n : β„•) β†’ (Fin n β†’ 𝓐 Γ— 𝓨) β†’ 𝓐} {h_next : βˆ€ n, Measurable (nextA n)} - {env : Environment 𝓐 𝓨} - {f : (n : β„•) β†’ ((Fin n β†’ 𝓐 Γ— 𝓨) Γ— 𝓐) β†’ 𝓨} {hf : βˆ€ n, Measurable (f n)} +variable {nextA : (n : β„•) β†’ (Hist π“ž 𝓐 𝓨 n Γ— π“ž) β†’ 𝓐} {h_next : βˆ€ n, Measurable (nextA n)} + {env : Environment π“ž 𝓐 𝓨} + {obs : (n : β„•) β†’ Kernel (Hist π“ž 𝓐 𝓨 n) π“ž} [βˆ€ n, IsMarkovKernel (obs n)] + {f : (n : β„•) β†’ ((Hist π“ž 𝓐 𝓨 n Γ— π“ž) Γ— 𝓐) β†’ 𝓨} {hf : βˆ€ n, Measurable (f n)} /-- A deterministic algorithm, which chooses the action given by the function `nextA`. -The initial action is `nextA 0 default`. -/ +The initial action is `fun o ↦ nextA 0 (default, o)`. -/ @[simps] noncomputable -def detAlgorithm (nextA : (n : β„•) β†’ (Fin n β†’ 𝓐 Γ— 𝓨) β†’ 𝓐) +def detAlgorithm (nextA : (n : β„•) β†’ (Hist π“ž 𝓐 𝓨 n Γ— π“ž) β†’ 𝓐) (h_next : βˆ€ n, Measurable (nextA n)) : - Algorithm 𝓐 𝓨 where + Algorithm π“ž 𝓐 𝓨 where policy n := Kernel.deterministic (nextA n) (h_next n) instance : IsDeterministicAlg (detAlgorithm nextA h_next) where exists_nextAction n := ⟨nextA n, h_next n, rfl⟩ @[simp] -lemma p0_detAlgorithm : (detAlgorithm nextA h_next).p0 = Measure.dirac (nextA 0 default) := by - rw [Algorithm.p0_def, detAlgorithm_policy, Kernel.deterministic_apply] +lemma p0_detAlgorithm : + (detAlgorithm nextA h_next).p0 + = Kernel.deterministic (fun o ↦ nextA 0 (default, o)) + ((h_next 0).comp (measurable_const.prodMk measurable_id)) := by + ext o : 1 + rw [Algorithm.p0_apply, detAlgorithm_policy, Kernel.deterministic_apply, + Kernel.deterministic_apply] @[simp] lemma nextAction_detAlgorithm [MeasurableSpace.SeparatesPoints 𝓐] (n : β„•) : @@ -238,54 +262,68 @@ lemma nextAction_detAlgorithm [MeasurableSpace.SeparatesPoints 𝓐] (n : β„•) : @[simp] lemma actionZero_detAlgorithm [MeasurableSpace.SeparatesPoints 𝓐] : - actionZero (detAlgorithm nextA h_next) = nextA 0 default := by - rw [actionZero, nextAction_detAlgorithm] + actionZero (detAlgorithm nextA h_next) = fun o ↦ nextA 0 (default, o) := by + unfold actionZero + rw [nextAction_detAlgorithm] /-- A deterministic environment, where the feedback is given by evaluating fixed measurable functions. -/ -noncomputable def detEnvironment - (f : (n : β„•) β†’ ((Fin n β†’ 𝓐 Γ— 𝓨) Γ— 𝓐) β†’ 𝓨) (hf : βˆ€ n, Measurable (f n)) : - Environment 𝓐 𝓨 where +noncomputable def detEnvironment (obs : (n : β„•) β†’ Kernel (Hist π“ž 𝓐 𝓨 n) π“ž) + [βˆ€ n, IsMarkovKernel (obs n)] + (f : (n : β„•) β†’ ((Hist π“ž 𝓐 𝓨 n Γ— π“ž) Γ— 𝓐) β†’ 𝓨) (hf : βˆ€ n, Measurable (f n)) : + Environment π“ž 𝓐 𝓨 where + obs := obs feedback n := (Kernel.deterministic (f n) (hf n)) -instance : IsDeterministicEnv (detEnvironment f hf) where +@[simp] +lemma obs_detEnvironment (n : β„•) : (detEnvironment obs f hf).obs n = obs n := rfl + +@[simp] +lemma feedback_detEnvironment (n : β„•) : + (detEnvironment obs f hf).feedback n = Kernel.deterministic (f n) (hf n) := rfl + +instance : IsDeterministicEnv (detEnvironment obs f hf) where exists_f n := ⟨f n, hf n, rfl⟩ @[simp] lemma feedbackFun_detEnvironment [MeasurableSpace.SeparatesPoints 𝓨] (n : β„•) : - feedbackFun (detEnvironment f hf) n = f n := by - simpa [detEnvironment] using (feedback_eq_deterministic (detEnvironment f hf) n).symm + feedbackFun (detEnvironment obs f hf) n = f n := by + simpa [detEnvironment] using (feedback_eq_deterministic (detEnvironment obs f hf) n).symm @[simp] lemma feedbackFunZero_detEnvironment [MeasurableSpace.SeparatesPoints 𝓨] : - feedbackFunZero (detEnvironment f hf) = fun a ↦ f 0 (default, a) := by + feedbackFunZero (detEnvironment obs f hf) = fun p ↦ f 0 ((default, p.1), p.2) := by unfold feedbackFunZero rw [feedbackFun_detEnvironment] namespace IsAlgEnvSeq variable {Ξ© : Type*} {mΞ© : MeasurableSpace Ξ©} - {alg : Algorithm 𝓐 𝓨} {Ξ½ : Kernel 𝓐 𝓨} [IsMarkovKernel Ξ½] - {P : Measure Ξ©} [IsProbabilityMeasure P] {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} - -lemma hasLaw_action_zero_detAlgorithm [MeasurableEq 𝓐] - (h : IsAlgEnvSeq A Y (detAlgorithm nextA h_next) env P) : - HasLaw (A 0) (Measure.dirac (nextA 0 default)) P := by - simpa using IsDeterministicAlg.hasLaw_action_zero h + {alg : Algorithm π“ž 𝓐 𝓨} {Ξ½ : Kernel (π“ž Γ— 𝓐) 𝓨} [IsMarkovKernel Ξ½] + {P : Measure Ξ©} [IsProbabilityMeasure P] + {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} + +lemma hasCondDistrib_action_zero_detAlgorithm + (h : IsAlgEnvSeq O A Y (detAlgorithm nextA h_next) env P) : + HasCondDistrib (A 0) (O 0) + (Kernel.deterministic (fun o ↦ nextA 0 (default, o)) + ((h_next 0).comp (measurable_const.prodMk measurable_id))) P := by + rw [← p0_detAlgorithm] + exact h.hasCondDistrib_action_zero lemma action_detAlgorithm_ae_eq [MeasurableEq 𝓐] - (h : IsAlgEnvSeq A Y (detAlgorithm nextA h_next) env P) (n : β„•) : - A n =ᡐ[P] fun Ο‰ ↦ nextA n (history A Y n Ο‰) := + (h : IsAlgEnvSeq O A Y (detAlgorithm nextA h_next) env P) (n : β„•) : + A n =ᡐ[P] fun Ο‰ ↦ nextA n (history O A Y n Ο‰, O n Ο‰) := (IsDeterministicAlg.action_ae_eq h n).trans (by simp) lemma action_zero_detAlgorithm [MeasurableEq 𝓐] - (h : IsAlgEnvSeq A Y (detAlgorithm nextA h_next) env P) : - A 0 =ᡐ[P] fun _ ↦ nextA 0 default := + (h : IsAlgEnvSeq O A Y (detAlgorithm nextA h_next) env P) : + A 0 =ᡐ[P] fun Ο‰ ↦ nextA 0 (default, O 0 Ο‰) := (IsDeterministicAlg.action_zero_ae_eq h).trans (by simp) lemma action_detAlgorithm_ae_all_eq [MeasurableEq 𝓐] - (h : IsAlgEnvSeq A Y (detAlgorithm nextA h_next) env P) : - βˆ€α΅ Ο‰ βˆ‚P, βˆ€ n, A n Ο‰ = nextA n (history A Y n Ο‰) := + (h : IsAlgEnvSeq O A Y (detAlgorithm nextA h_next) env P) : + βˆ€α΅ Ο‰ βˆ‚P, βˆ€ n, A n Ο‰ = nextA n (history O A Y n Ο‰, O n Ο‰) := ae_all_iff.mpr (action_detAlgorithm_ae_eq h) end IsAlgEnvSeq @@ -293,22 +331,26 @@ end IsAlgEnvSeq namespace IsAlgEnvSeqUntil variable {Ξ© : Type*} {mΞ© : MeasurableSpace Ξ©} - {alg : Algorithm 𝓐 𝓨} {Ξ½ : Kernel 𝓐 𝓨} [IsMarkovKernel Ξ½] - {P : Measure Ξ©} [IsProbabilityMeasure P] {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {N n : β„•} - -lemma hasLaw_action_zero_detAlgorithm [MeasurableEq 𝓐] - (h : IsAlgEnvSeqUntil A Y (detAlgorithm nextA h_next) env P N) (hN : 0 < N) : - HasLaw (A 0) (Measure.dirac (nextA 0 default)) P := by - simpa using IsDeterministicAlg.hasLaw_action_zero_of_IsAlgEnvSeqUntil h hN + {alg : Algorithm π“ž 𝓐 𝓨} {Ξ½ : Kernel (π“ž Γ— 𝓐) 𝓨} [IsMarkovKernel Ξ½] + {P : Measure Ξ©} [IsProbabilityMeasure P] + {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {N n : β„•} + +lemma hasCondDistrib_action_zero_detAlgorithm + (h : IsAlgEnvSeqUntil O A Y (detAlgorithm nextA h_next) env P N) (hN : 0 < N) : + HasCondDistrib (A 0) (O 0) + (Kernel.deterministic (fun o ↦ nextA 0 (default, o)) + ((h_next 0).comp (measurable_const.prodMk measurable_id))) P := by + rw [← p0_detAlgorithm] + exact h.hasCondDistrib_action_zero hN lemma action_detAlgorithm_ae_eq [MeasurableEq 𝓐] - (h : IsAlgEnvSeqUntil A Y (detAlgorithm nextA h_next) env P N) (hn : n < N) : - A n =ᡐ[P] fun Ο‰ ↦ nextA n (history A Y n Ο‰) := + (h : IsAlgEnvSeqUntil O A Y (detAlgorithm nextA h_next) env P N) (hn : n < N) : + A n =ᡐ[P] fun Ο‰ ↦ nextA n (history O A Y n Ο‰, O n Ο‰) := (IsDeterministicAlg.action_ae_eq_of_IsAlgEnvSeqUntil h hn).trans (by simp) lemma action_zero_detAlgorithm [MeasurableEq 𝓐] - (h : IsAlgEnvSeqUntil A Y (detAlgorithm nextA h_next) env P N) (hN : 0 < N) : - A 0 =ᡐ[P] fun _ ↦ nextA 0 default := + (h : IsAlgEnvSeqUntil O A Y (detAlgorithm nextA h_next) env P N) (hN : 0 < N) : + A 0 =ᡐ[P] fun Ο‰ ↦ nextA 0 (default, O 0 Ο‰) := (IsDeterministicAlg.action_zero_of_IsAlgEnvSeqUntil h hN).trans (by simp) end IsAlgEnvSeqUntil diff --git a/LeanMachineLearning/SequentialLearning/EvaluationEnv.lean b/LeanMachineLearning/SequentialLearning/EvaluationEnv.lean index 9aac0774..fdae6c06 100644 --- a/LeanMachineLearning/SequentialLearning/EvaluationEnv.lean +++ b/LeanMachineLearning/SequentialLearning/EvaluationEnv.lean @@ -69,30 +69,31 @@ lemma feedbackFun_onlineEvalEnv [MeasurableSpace.SeparatesPoints 𝓨] (n : β„•) @[simp] lemma feedbackFunZero_onlineEvalEnv [MeasurableSpace.SeparatesPoints 𝓨] : - feedbackFunZero (onlineEvalEnv g hg) = g 0 := by + feedbackFunZero (onlineEvalEnv g hg) = fun p ↦ g 0 p.2 := by unfold feedbackFunZero rw [feedbackFun_onlineEvalEnv] section OnlineEvalEnv -variable {Ξ© : Type*} {mΞ© : MeasurableSpace Ξ©} {alg : Algorithm 𝓐 𝓨} +variable {Ξ© : Type*} {mΞ© : MeasurableSpace Ξ©} {alg : Algorithm Unit 𝓐 𝓨} {g : β„• β†’ 𝓐 β†’ 𝓨} {hg : βˆ€ n, Measurable (g n)} - {P : Measure Ξ©} [IsProbabilityMeasure P] {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} + {P : Measure Ξ©} [IsProbabilityMeasure P] + {O : β„• β†’ Ξ© β†’ Unit} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} lemma hascondDistrib_feedback_onlineEvalEnv - (h : IsAlgEnvSeq A Y alg (onlineEvalEnv g hg) P) (n : β„•) : + (h : IsAlgEnvSeq O A Y alg (onlineEvalEnv g hg) P) (n : β„•) : HasCondDistrib (Y n) (A n) (Kernel.deterministic (g n) (hg n)) P := by simpa using IsObliviousEnv.hasCondDistrib_feedback h n lemma feedback_onlineEvalEnv_ae_eq_eval_action [StandardBorelSpace 𝓨] [Nonempty 𝓨] - (h : IsAlgEnvSeq A Y alg (onlineEvalEnv g hg) P) (n : β„•) : + (h : IsAlgEnvSeq O A Y alg (onlineEvalEnv g hg) P) (n : β„•) : Y n =ᡐ[P] g n ∘ A n := ae_eq_of_condDistrib_eq_deterministic (hg n) (h.measurable_action n).aemeasurable (h.measurable_feedback n).aemeasurable (hascondDistrib_feedback_onlineEvalEnv h n).condDistrib_eq lemma forall_feedback_onlineEvalEnv_ae_eq_eval_action [StandardBorelSpace 𝓨] [Nonempty 𝓨] - (h : IsAlgEnvSeq A Y alg (onlineEvalEnv g hg) P) : + (h : IsAlgEnvSeq O A Y alg (onlineEvalEnv g hg) P) : βˆ€α΅ Ο‰ βˆ‚P, βˆ€ n, Y n Ο‰ = g n (A n Ο‰) := by rw [ae_all_iff] intro n @@ -114,7 +115,7 @@ lemma feedbackCondAction_evalEnv (n : β„•) : @[simp] lemma feedbackFunZero_evalEnv [MeasurableSpace.SeparatesPoints 𝓨] : - feedbackFunZero (evalEnv f hf) = f := by simp [evalEnv] + feedbackFunZero (evalEnv f hf) = fun p ↦ f p.2 := by simp [evalEnv] @[simp] lemma feedbackFun_evalEnv [MeasurableSpace.SeparatesPoints 𝓨] (n : β„•) : @@ -122,24 +123,26 @@ lemma feedbackFun_evalEnv [MeasurableSpace.SeparatesPoints 𝓨] (n : β„•) : section EvalEnv -variable {Ξ© : Type*} {mΞ© : MeasurableSpace Ξ©} {alg : Algorithm 𝓐 𝓨} {f : 𝓐 β†’ 𝓨} {hf : Measurable f} - {P : Measure Ξ©} [IsProbabilityMeasure P] {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} +variable {Ξ© : Type*} {mΞ© : MeasurableSpace Ξ©} {alg : Algorithm Unit 𝓐 𝓨} + {f : 𝓐 β†’ 𝓨} {hf : Measurable f} + {P : Measure Ξ©} [IsProbabilityMeasure P] + {O : β„• β†’ Ξ© β†’ Unit} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} -lemma hascondDistrib_feedback_evalEnv (h : IsAlgEnvSeq A Y alg (evalEnv f hf) P) (n : β„•) : +lemma hascondDistrib_feedback_evalEnv (h : IsAlgEnvSeq O A Y alg (evalEnv f hf) P) (n : β„•) : HasCondDistrib (Y n) (A n) (Kernel.deterministic f hf) P := by simpa using IsObliviousEnv.hasCondDistrib_feedback h n lemma feedback_evalEnv_ae_eq_eval_action [StandardBorelSpace 𝓨] [Nonempty 𝓨] - (h : IsAlgEnvSeq A Y alg (evalEnv f hf) P) (n : β„•) : + (h : IsAlgEnvSeq O A Y alg (evalEnv f hf) P) (n : β„•) : Y n =ᡐ[P] f ∘ A n := feedback_onlineEvalEnv_ae_eq_eval_action h n lemma forall_feedback_evalEnv_ae_eq_eval_action [StandardBorelSpace 𝓨] [Nonempty 𝓨] - (h : IsAlgEnvSeq A Y alg (evalEnv f hf) P) : + (h : IsAlgEnvSeq O A Y alg (evalEnv f hf) P) : βˆ€α΅ Ο‰ βˆ‚P, βˆ€ n, Y n Ο‰ = f (A n Ο‰) := forall_feedback_onlineEvalEnv_ae_eq_eval_action h open Finset in lemma feedback_evalEnv_ae_eq_eval_action_comp {Ξ² : Type*} [StandardBorelSpace 𝓨] [Nonempty 𝓨] - (h : IsAlgEnvSeq A Y alg (evalEnv f hf) P) {n : β„•} (g : (Iic n β†’ 𝓨) β†’ Ξ²) : + (h : IsAlgEnvSeq O A Y alg (evalEnv f hf) P) {n : β„•} (g : (Iic n β†’ 𝓨) β†’ Ξ²) : βˆ€α΅ Ο‰ βˆ‚P, g (fun i ↦ Y i Ο‰) = g (fun i ↦ f (A i Ο‰)) := by filter_upwards [forall_feedback_evalEnv_ae_eq_eval_action h] with Ο‰ hΟ‰ simp_rw [hΟ‰] diff --git a/LeanMachineLearning/SequentialLearning/FeedbackMartingale.lean b/LeanMachineLearning/SequentialLearning/FeedbackMartingale.lean index 34aedb10..df1f7815 100644 --- a/LeanMachineLearning/SequentialLearning/FeedbackMartingale.lean +++ b/LeanMachineLearning/SequentialLearning/FeedbackMartingale.lean @@ -21,128 +21,132 @@ open scoped ENNReal namespace Learning -variable {Ξ© 𝓐 𝓨 : Type*} {mΞ© : MeasurableSpace Ξ©} {m𝓐 : MeasurableSpace 𝓐} {m𝓨 : MeasurableSpace 𝓨} +variable {Ξ© π“ž 𝓐 𝓨 : Type*} {mΞ© : MeasurableSpace Ξ©} {mπ“ž : MeasurableSpace π“ž} + {m𝓐 : MeasurableSpace 𝓐} {m𝓨 : MeasurableSpace 𝓨} [NormedAddCommGroup 𝓨] [NormedSpace ℝ 𝓨] {P : Measure Ξ©} [IsFiniteMeasure P] - {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {alg : Algorithm 𝓐 𝓨} {env : Environment 𝓐 𝓨} + {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} + {alg : Algorithm π“ž 𝓐 𝓨} {env : Environment π“ž 𝓐 𝓨} /-- The sum of noise terms for action `k`. This is the martingale part of `sumRewards A Y k` for the filtration `IsAlgEnvSeq.filtrationAction`. -/ noncomputable -def noiseSum (env : Environment 𝓐 𝓨) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) (k : 𝓐) (n : β„•) (Ο‰ : Ξ©) : 𝓨 := - βˆ‘ m ∈ range n, {Ο‰ | A m Ο‰ = k}.indicator (fun Ο‰ ↦ Y m Ο‰ - env.means A Y (A m Ο‰) m Ο‰) Ο‰ +def noiseSum (env : Environment π“ž 𝓐 𝓨) (O : β„• β†’ Ξ© β†’ π“ž) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) + (k : 𝓐) (n : β„•) (Ο‰ : Ξ©) : 𝓨 := + βˆ‘ m ∈ range n, {Ο‰ | A m Ο‰ = k}.indicator (fun Ο‰ ↦ Y m Ο‰ - env.means O A Y (A m Ο‰) m Ο‰) Ο‰ /-- The sum of mean terms for action `k`. This is the predictable part of `sumRewards A Y k` for the filtration `IsAlgEnvSeq.filtrationAction`. -/ noncomputable -def meanSum (env : Environment 𝓐 𝓨) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) (k : 𝓐) (n : β„•) (Ο‰ : Ξ©) : 𝓨 := - βˆ‘ m ∈ range n, {Ο‰ | A m Ο‰ = k}.indicator (fun Ο‰ ↦ env.means A Y (A m Ο‰) m Ο‰) Ο‰ +def meanSum (env : Environment π“ž 𝓐 𝓨) (O : β„• β†’ Ξ© β†’ π“ž) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) + (k : 𝓐) (n : β„•) (Ο‰ : Ξ©) : 𝓨 := + βˆ‘ m ∈ range n, {Ο‰ | A m Ο‰ = k}.indicator (fun Ο‰ ↦ env.means O A Y (A m Ο‰) m Ο‰) Ο‰ lemma noiseSum_add_meanSum' (k : 𝓐) (n : β„•) (Ο‰ : Ξ©) : - noiseSum env A Y k n Ο‰ + meanSum env A Y k n Ο‰ = + noiseSum env O A Y k n Ο‰ + meanSum env O A Y k n Ο‰ = βˆ‘ m ∈ range n, {Ο‰ | A m Ο‰ = k}.indicator (Y m) Ο‰ := by simp only [noiseSum, meanSum, ← sum_add_distrib] congr with m by_cases h : A m Ο‰ = k <;> simp [h] lemma noiseSum_add_meanSum [DecidableEq 𝓐] (k : 𝓐) (n : β„•) (Ο‰ : Ξ©) : - noiseSum env A Y k n Ο‰ + meanSum env A Y k n Ο‰ = sumRewards A Y k n Ο‰ := by + noiseSum env O A Y k n Ο‰ + meanSum env O A Y k n Ο‰ = sumRewards A Y k n Ο‰ := by unfold sumRewards rw [noiseSum_add_meanSum' k n Ο‰] congr with m by_cases h : A m Ο‰ = k <;> simp [h] @[simp] -lemma noiseSum_zero (k : 𝓐) : noiseSum env A Y k 0 = fun _ ↦ 0 := by unfold noiseSum; simp +lemma noiseSum_zero (k : 𝓐) : noiseSum env O A Y k 0 = fun _ ↦ 0 := by unfold noiseSum; simp @[simp] -lemma meanSum_zero (k : 𝓐) : meanSum env A Y k 0 = fun _ ↦ 0 := by unfold meanSum; simp +lemma meanSum_zero (k : 𝓐) : meanSum env O A Y k 0 = fun _ ↦ 0 := by unfold meanSum; simp lemma noiseSum_succ (k : 𝓐) (n : β„•) : - noiseSum env A Y k (n + 1) = noiseSum env A Y k n + - {Ο‰ | A n Ο‰ = k}.indicator (fun Ο‰ ↦ Y n Ο‰ - env.means A Y (A n Ο‰) n Ο‰) := by + noiseSum env O A Y k (n + 1) = noiseSum env O A Y k n + + {Ο‰ | A n Ο‰ = k}.indicator (fun Ο‰ ↦ Y n Ο‰ - env.means O A Y (A n Ο‰) n Ο‰) := by ext Ο‰ simp [noiseSum, Finset.sum_range_succ] lemma noiseSum_succ_sub (k : 𝓐) (n : β„•) (Ο‰ : Ξ©) : - noiseSum env A Y k (n + 1) Ο‰ - noiseSum env A Y k n Ο‰ - = {Ο‰ | A n Ο‰ = k}.indicator (fun Ο‰ ↦ Y n Ο‰ - env.means A Y (A n Ο‰) n Ο‰) Ο‰ := by + noiseSum env O A Y k (n + 1) Ο‰ - noiseSum env O A Y k n Ο‰ + = {Ο‰ | A n Ο‰ = k}.indicator (fun Ο‰ ↦ Y n Ο‰ - env.means O A Y (A n Ο‰) n Ο‰) Ο‰ := by simp [noiseSum_succ] lemma meanSum_succ (k : 𝓐) (n : β„•) : - meanSum env A Y k (n + 1) = meanSum env A Y k n + - {Ο‰ | A n Ο‰ = k}.indicator (fun Ο‰ ↦ env.means A Y (A n Ο‰) n Ο‰) := by + meanSum env O A Y k (n + 1) = meanSum env O A Y k n + + {Ο‰ | A n Ο‰ = k}.indicator (fun Ο‰ ↦ env.means O A Y (A n Ο‰) n Ο‰) := by ext Ο‰ simp [meanSum, Finset.sum_range_succ] lemma meanSum_succ_sub (k : 𝓐) (n : β„•) (Ο‰ : Ξ©) : - meanSum env A Y k (n + 1) Ο‰ - meanSum env A Y k n Ο‰ - = {Ο‰ | A n Ο‰ = k}.indicator (fun Ο‰ ↦ env.means A Y (A n Ο‰) n Ο‰) Ο‰ := by + meanSum env O A Y k (n + 1) Ο‰ - meanSum env O A Y k n Ο‰ + = {Ο‰ | A n Ο‰ = k}.indicator (fun Ο‰ ↦ env.means O A Y (A n Ο‰) n Ο‰) Ο‰ := by simp [meanSum_succ] variable [MeasurableSingletonClass 𝓐] [SecondCountableTopology 𝓨] @[fun_prop] lemma IsAlgEnvSeq.integrable_noiseSum_increment [OpensMeasurableSpace 𝓨] - {m : β„•} (h : IsAlgEnvSeq A Y alg env P) (hint : Integrable (Y m) P) (k : 𝓐) : + {m : β„•} (h : IsAlgEnvSeq O A Y alg env P) (hint : Integrable (Y m) P) (k : 𝓐) : Integrable (fun Ο‰ ↦ {Ο‰ | A m Ο‰ = k}.indicator - (fun Ο‰ ↦ Y m Ο‰ - env.means A Y (A m Ο‰) m Ο‰) Ο‰) P := by + (fun Ο‰ ↦ Y m Ο‰ - env.means O A Y (A m Ο‰) m Ο‰) Ο‰) P := by exact (hint.sub (h.integrable_means_action hint)).indicator (h.measurable_action _ (measurableSet_singleton k)) @[fun_prop] lemma IsAlgEnvSeq.integrable_meanSum_increment [OpensMeasurableSpace 𝓨] - {m : β„•} (h : IsAlgEnvSeq A Y alg env P) (hint : Integrable (Y m) P) (k : 𝓐) : - Integrable (fun Ο‰ ↦ {Ο‰ | A m Ο‰ = k}.indicator (fun Ο‰ ↦ env.means A Y (A m Ο‰) m Ο‰) Ο‰) P := by + {m : β„•} (h : IsAlgEnvSeq O A Y alg env P) (hint : Integrable (Y m) P) (k : 𝓐) : + Integrable (fun Ο‰ ↦ {Ο‰ | A m Ο‰ = k}.indicator (fun Ο‰ ↦ env.means O A Y (A m Ο‰) m Ο‰) Ο‰) P := by exact (h.integrable_means_action hint).indicator (h.measurable_action _ (measurableSet_singleton k)) @[fun_prop] lemma IsAlgEnvSeq.integrable_noiseSum [OpensMeasurableSpace 𝓨] - (h : IsAlgEnvSeq A Y alg env P) (hint : βˆ€ n, Integrable (Y n) P) (k : 𝓐) (n : β„•) : - Integrable (noiseSum env A Y k n) P := + (h : IsAlgEnvSeq O A Y alg env P) (hint : βˆ€ n, Integrable (Y n) P) (k : 𝓐) (n : β„•) : + Integrable (noiseSum env O A Y k n) P := integrable_finsetSum _ fun m _ ↦ h.integrable_noiseSum_increment (hint m) k @[fun_prop] lemma IsAlgEnvSeq.integrable_meanSum [OpensMeasurableSpace 𝓨] - (h : IsAlgEnvSeq A Y alg env P) (hint : βˆ€ n, Integrable (Y n) P) (k : 𝓐) (n : β„•) : - Integrable (meanSum env A Y k n) P := + (h : IsAlgEnvSeq O A Y alg env P) (hint : βˆ€ n, Integrable (Y n) P) (k : 𝓐) (n : β„•) : + Integrable (meanSum env O A Y k n) P := integrable_finsetSum _ fun m _ ↦ h.integrable_meanSum_increment (hint m) k lemma IsAlgEnvSeq.memLp_noiseSum_increment [BorelSpace 𝓨] - {m : β„•} (k : 𝓐) (h : IsAlgEnvSeq A Y alg env P) {p : ℝβ‰₯0∞} (hp1 : 1 ≀ p) (hp_top : p β‰  ∞) + {m : β„•} (k : 𝓐) (h : IsAlgEnvSeq O A Y alg env P) {p : ℝβ‰₯0∞} (hp1 : 1 ≀ p) (hp_top : p β‰  ∞) (hY : MemLp (Y m) p P) : - MemLp ({Ο‰ | A m Ο‰ = k}.indicator (fun Ο‰ ↦ Y m Ο‰ - env.means A Y (A m Ο‰) m Ο‰)) p P := by + MemLp ({Ο‰ | A m Ο‰ = k}.indicator (fun Ο‰ ↦ Y m Ο‰ - env.means O A Y (A m Ο‰) m Ο‰)) p P := by refine (hY.sub ?_).indicator (h.measurable_action _ (measurableSet_singleton k)) exact h.memLp_means_action hp1 hp_top hY lemma IsAlgEnvSeq.memLp_meanSum_increment [BorelSpace 𝓨] - {m : β„•} (k : 𝓐) (h : IsAlgEnvSeq A Y alg env P) {p : ℝβ‰₯0∞} (hp1 : 1 ≀ p) (hp_top : p β‰  ∞) + {m : β„•} (k : 𝓐) (h : IsAlgEnvSeq O A Y alg env P) {p : ℝβ‰₯0∞} (hp1 : 1 ≀ p) (hp_top : p β‰  ∞) (hY : MemLp (Y m) p P) : - MemLp ({Ο‰ | A m Ο‰ = k}.indicator (fun Ο‰ ↦ env.means A Y (A m Ο‰) m Ο‰)) p P := by + MemLp ({Ο‰ | A m Ο‰ = k}.indicator (fun Ο‰ ↦ env.means O A Y (A m Ο‰) m Ο‰)) p P := by exact (h.memLp_means_action hp1 hp_top hY).indicator (h.measurable_action _ (measurableSet_singleton k)) lemma IsAlgEnvSeq.memLp_noiseSum [BorelSpace 𝓨] - (h : IsAlgEnvSeq A Y alg env P) {p : ℝβ‰₯0∞} (hp1 : 1 ≀ p) (hp_top : p β‰  ∞) + (h : IsAlgEnvSeq O A Y alg env P) {p : ℝβ‰₯0∞} (hp1 : 1 ≀ p) (hp_top : p β‰  ∞) (hY : βˆ€ n, MemLp (Y n) p P) (k : 𝓐) (n : β„•) : - MemLp (noiseSum env A Y k n) p P := + MemLp (noiseSum env O A Y k n) p P := memLp_finsetSum _ fun m _ ↦ memLp_noiseSum_increment k h hp1 hp_top (hY m) lemma IsAlgEnvSeq.memLp_meanSum [BorelSpace 𝓨] - (h : IsAlgEnvSeq A Y alg env P) {p : ℝβ‰₯0∞} (hp1 : 1 ≀ p) (hp_top : p β‰  ∞) + (h : IsAlgEnvSeq O A Y alg env P) {p : ℝβ‰₯0∞} (hp1 : 1 ≀ p) (hp_top : p β‰  ∞) (hY : βˆ€ n, MemLp (Y n) p P) (k : 𝓐) (n : β„•) : - MemLp (meanSum env A Y k n) p P := + MemLp (meanSum env O A Y k n) p P := memLp_finsetSum _ fun m _ ↦ memLp_meanSum_increment k h hp1 hp_top (hY m) section Martingale variable [BorelSpace 𝓨] -lemma IsAlgEnvSeq.adapted_noiseSum (h : IsAlgEnvSeq A Y alg env P) (k : 𝓐) : - Adapted h.filtrationAction (noiseSum env A Y k) := by +lemma IsAlgEnvSeq.adapted_noiseSum (h : IsAlgEnvSeq O A Y alg env P) (k : 𝓐) : + Adapted h.filtrationAction (noiseSum env O A Y k) := by refine fun n ↦ Finset.measurable_fun_sum _ fun m hm ↦ ?_ have hAm : Measurable[h.filtrationAction n] (A m) := h.adapted_action_filtrationAction.measurable_le (by grind) @@ -151,12 +155,12 @@ lemma IsAlgEnvSeq.adapted_noiseSum (h : IsAlgEnvSeq A Y alg env P) (k : 𝓐) : refine (hYm.sub ?_).indicator (hAm (measurableSet_singleton k)) exact h.adapted_means_filtrationAction.measurable_le (by grind) -lemma IsAlgEnvSeq.stronglyAdapted_noiseSum (h : IsAlgEnvSeq A Y alg env P) (k : 𝓐) : - StronglyAdapted h.filtrationAction (noiseSum env A Y k) := +lemma IsAlgEnvSeq.stronglyAdapted_noiseSum (h : IsAlgEnvSeq O A Y alg env P) (k : 𝓐) : + StronglyAdapted h.filtrationAction (noiseSum env O A Y k) := (adapted_noiseSum h k).stronglyAdapted -lemma IsAlgEnvSeq.isStronglyPredictable_meanSum (h : IsAlgEnvSeq A Y alg env P) (k : 𝓐) : - IsStronglyPredictable h.filtrationAction (meanSum env A Y k) := by +lemma IsAlgEnvSeq.isStronglyPredictable_meanSum (h : IsAlgEnvSeq O A Y alg env P) (k : 𝓐) : + IsStronglyPredictable h.filtrationAction (meanSum env O A Y k) := by refine .of_measurable_add_one ?_ fun n ↦ ?_ Β· simp only [meanSum_zero] fun_prop @@ -167,12 +171,13 @@ lemma IsAlgEnvSeq.isStronglyPredictable_meanSum (h : IsAlgEnvSeq A Y alg env P) exact (h.stronglyAdapted_means_filtrationAction m).mono (h.filtrationAction.mono (by grind)) lemma IsAlgEnvSeq.condExp_noiseSum_increment [CompleteSpace 𝓨] - (h : IsAlgEnvSeq A Y alg env P) (k : 𝓐) (i : β„•) (hint : Integrable (Y i) P) : - P[{Ο‰ | A i Ο‰ = k}.indicator (fun Ο‰ ↦ Y i Ο‰ - env.means A Y (A i Ο‰) i Ο‰) | h.filtrationAction i] - =ᡐ[P] 0 := by + (h : IsAlgEnvSeq O A Y alg env P) (k : 𝓐) (i : β„•) (hint : Integrable (Y i) P) : + P[{Ο‰ | A i Ο‰ = k}.indicator (fun Ο‰ ↦ Y i Ο‰ - env.means O A Y (A i Ο‰) i Ο‰) + | h.filtrationAction i] =ᡐ[P] 0 := by let c : Ξ© β†’ ℝ := actionIndicator A k i - let g : Ξ© β†’ 𝓨 := fun Ο‰ ↦ Y i Ο‰ - env.means A Y (A i Ο‰) i Ο‰ - have h_smul : c β€’ g = {Ο‰ | A i Ο‰ = k}.indicator (fun Ο‰ ↦ Y i Ο‰ - env.means A Y (A i Ο‰) i Ο‰) := by + let g : Ξ© β†’ 𝓨 := fun Ο‰ ↦ Y i Ο‰ - env.means O A Y (A i Ο‰) i Ο‰ + have h_smul : c β€’ g + = {Ο‰ | A i Ο‰ = k}.indicator (fun Ο‰ ↦ Y i Ο‰ - env.means O A Y (A i Ο‰) i Ο‰) := by ext Ο‰ by_cases hΟ‰ : A i Ο‰ = k <;> simp [c, g, actionIndicator, hΟ‰] have hAG : Measurable[h.filtrationAction i] (A i) := h.adapted_action_filtrationAction i @@ -199,15 +204,15 @@ lemma IsAlgEnvSeq.condExp_noiseSum_increment [CompleteSpace 𝓨] Β· simp [c, actionIndicator, hak] lemma IsAlgEnvSeq.martingale_noiseSum [CompleteSpace 𝓨] - (h : IsAlgEnvSeq A Y alg env P) (hint : βˆ€ n, Integrable (Y n) P) (k : 𝓐) : - Martingale (noiseSum env A Y k) h.filtrationAction P := by - have hInt : βˆ€ n, Integrable (noiseSum env A Y k n) P := h.integrable_noiseSum (hint) k + (h : IsAlgEnvSeq O A Y alg env P) (hint : βˆ€ n, Integrable (Y n) P) (k : 𝓐) : + Martingale (noiseSum env O A Y k) h.filtrationAction P := by + have hInt : βˆ€ n, Integrable (noiseSum env O A Y k n) P := h.integrable_noiseSum (hint) k refine martingale_nat (h.stronglyAdapted_noiseSum k) hInt fun i ↦ ?_ rw [noiseSum_succ] symm have hadd := condExp_add (hInt i) (integrable_noiseSum_increment h (hint i) k) (h.filtrationAction i) - have hself : P[noiseSum env A Y k i | h.filtrationAction i] = noiseSum env A Y k i := + have hself : P[noiseSum env O A Y k i | h.filtrationAction i] = noiseSum env O A Y k i := condExp_of_stronglyMeasurable (h.filtrationAction.le i) (h.stronglyAdapted_noiseSum k i) (hInt i) have hincr := condExp_noiseSum_increment h k i (hint i) diff --git a/LeanMachineLearning/SequentialLearning/FiniteActions.lean b/LeanMachineLearning/SequentialLearning/FiniteActions.lean index bf7e15a2..2215780b 100644 --- a/LeanMachineLearning/SequentialLearning/FiniteActions.lean +++ b/LeanMachineLearning/SequentialLearning/FiniteActions.lean @@ -28,11 +28,12 @@ open MeasureTheory Finset Learning namespace Learning -variable {𝓐 R Ξ© : Type*} {m𝓐 : MeasurableSpace 𝓐} {mR : MeasurableSpace R} {mΞ© : MeasurableSpace Ξ©} +variable {π“ž 𝓐 R Ξ© : Type*} {mπ“ž : MeasurableSpace π“ž} {m𝓐 : MeasurableSpace 𝓐} + {mR : MeasurableSpace R} {mΞ© : MeasurableSpace Ξ©} [DecidableEq 𝓐] - {alg : Algorithm 𝓐 R} {env : Environment 𝓐 R} + {alg : Algorithm π“ž 𝓐 R} {env : Environment π“ž 𝓐 R} {P : Measure Ξ©} [IsProbabilityMeasure P] - {A : β„• β†’ Ξ© β†’ 𝓐} {R' : β„• β†’ Ξ© β†’ R} + {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {R' : β„• β†’ Ξ© β†’ R} {a : 𝓐} {m n t : β„•} {Ο‰ : Ξ©} section PullCount @@ -45,7 +46,7 @@ def pullCount (A : β„• β†’ Ξ© β†’ 𝓐) (a : 𝓐) (t : β„•) (Ο‰ : Ξ©) : β„• := /-- Number of pulls of arm `a` in the history before time `n`. This is the number of entries in `h` in which the arm is `a`. -/ noncomputable -def pullCount' (n : β„•) (h : Fin n β†’ 𝓐 Γ— R) (a : 𝓐) := #{s | (h s).1 = a} +def pullCount' (n : β„•) (h : Hist π“ž 𝓐 R n) (a : 𝓐) := #{s | (h s).action = a} @[simp] lemma pullCount_zero (a : 𝓐) : pullCount A a 0 = 0 := by ext; simp [pullCount] @@ -84,23 +85,23 @@ lemma pullCount_add_one : lemma pullCount_eq_sum (a : 𝓐) (t : β„•) (Ο‰ : Ξ©) : pullCount A a t Ο‰ = βˆ‘ s ∈ range t, if A s Ο‰ = a then 1 else 0 := by simp [pullCount] -lemma pullCount'_eq_sum (n : β„•) (h : Fin n β†’ 𝓐 Γ— R) (a : 𝓐) : - pullCount' n h a = βˆ‘ s : Fin n, if (h s).1 = a then 1 else 0 := by simp [pullCount'] +lemma pullCount'_eq_sum (n : β„•) (h : Hist π“ž 𝓐 R n) (a : 𝓐) : + pullCount' n h a = βˆ‘ s : Fin n, if (h s).action = a then 1 else 0 := by simp [pullCount'] lemma pullCount_eq_pullCount' {n : β„•} {Ο‰ : Ξ©} : - pullCount A a n Ο‰ = pullCount' n (fun i ↦ (A i Ο‰, R' i Ο‰)) a := by + pullCount A a n Ο‰ = pullCount' n (history O A R' n Ο‰) a := by rw [pullCount_eq_sum, pullCount'_eq_sum] exact (Fin.sum_univ_eq_sum_range (fun i ↦ if A i Ο‰ = a then 1 else 0) n).symm /-- `pullCount A a n` is a function of the history before time `n`. -/ lemma pullCount_eq_comp_history (a : 𝓐) (n : β„•) : - pullCount A a n = (fun h : Fin n β†’ 𝓐 Γ— R ↦ pullCount' n h a) ∘ history A R' n := by + pullCount A a n = (fun h : Hist π“ž 𝓐 R n ↦ pullCount' n h a) ∘ history O A R' n := by ext Ο‰ exact pullCount_eq_pullCount' lemma pullCount'_mono {n m : β„•} (hnm : n ≀ m) : - pullCount' n (fun i ↦ (A i Ο‰, R' i Ο‰)) a ≀ pullCount' m (fun i ↦ (A i Ο‰, R' i Ο‰)) a := by - rw [← pullCount_eq_pullCount', ← pullCount_eq_pullCount'] + pullCount' n (history O A R' n Ο‰) a ≀ pullCount' m (history O A R' m Ο‰) a := by + rw [← pullCount_eq_pullCount' (O := O), ← pullCount_eq_pullCount' (O := O)] exact pullCount_mono a hnm _ lemma pullCount_le (a : 𝓐) (t : β„•) (Ο‰ : Ξ©) : pullCount A a t Ο‰ ≀ t := @@ -201,38 +202,39 @@ lemma measurable_uncurry_pullCount_comp [Countable 𝓐] [MeasurableSingletonCla @[fun_prop] lemma measurable_pullCount' [MeasurableSingletonClass 𝓐] (n : β„•) (a : 𝓐) : - Measurable (fun h : Fin n β†’ 𝓐 Γ— R ↦ pullCount' n h a) := by + Measurable (fun h : Hist π“ž 𝓐 R n ↦ pullCount' n h a) := by simp_rw [pullCount'_eq_sum] - have h_meas s : Measurable (fun (h : Fin n β†’ 𝓐 Γ— R) ↦ if (h s).1 = a then 1 else 0) := by + have h_meas s : Measurable (fun (h : Hist π“ž 𝓐 R n) ↦ if (h s).action = a then 1 else 0) := by refine Measurable.ite ?_ (by fun_prop) (by fun_prop) exact (measurableSet_singleton _).preimage (by fun_prop) fun_prop @[fun_prop] lemma measurable_uncurry_pullCount' [MeasurableEq 𝓐] (n : β„•) : - Measurable (fun p : (Fin n β†’ 𝓐 Γ— R) Γ— 𝓐 ↦ pullCount' n p.1 p.2) := by + Measurable (fun p : Hist π“ž 𝓐 R n Γ— 𝓐 ↦ pullCount' n p.1 p.2) := by simp_rw [pullCount'_eq_sum] - have h_meas s : Measurable (fun h : (Fin n β†’ 𝓐 Γ— R) Γ— 𝓐 ↦ if (h.1 s).1 = h.2 then 1 else 0) := by + have h_meas s : Measurable + (fun h : Hist π“ž 𝓐 R n Γ— 𝓐 ↦ if (h.1 s).action = h.2 then 1 else 0) := by refine Measurable.ite ?_ (by fun_prop) (by fun_prop) exact measurableSet_eq_fun (by fun_prop) (by fun_prop) fun_prop lemma adapted_pullCount_add_one [MeasurableSingletonClass 𝓐] - (h : IsAlgEnvSeq A R' alg env P) (a : 𝓐) : + (h : IsAlgEnvSeq O A R' alg env P) (a : 𝓐) : Adapted h.filtration (fun n ↦ pullCount A a (n + 1)) := by intro n change Measurable[h.filtration n] (pullCount A a (n + 1)) - rw [measurable_iff_comap_le, h.filtration_eq_comap, pullCount_eq_comp_history (R' := R'), + rw [measurable_iff_comap_le, h.filtration_eq_comap, pullCount_eq_comp_history (O := O) (R' := R'), ← measurable_iff_comap_le] exact measurable_comp_comap _ (measurable_pullCount' (n + 1) a) lemma stronglyAdapted_pullCount_add_one [MeasurableSingletonClass 𝓐] - (h : IsAlgEnvSeq A R' alg env P) (a : 𝓐) : + (h : IsAlgEnvSeq O A R' alg env P) (a : 𝓐) : StronglyAdapted h.filtration (fun n ↦ pullCount A a (n + 1)) := (adapted_pullCount_add_one h a).stronglyAdapted lemma isStronglyPredictable_pullCount [MeasurableSingletonClass 𝓐] - (h : IsAlgEnvSeq A R' alg env P) (a : 𝓐) : + (h : IsAlgEnvSeq O A R' alg env P) (a : 𝓐) : IsStronglyPredictable h.filtration (pullCount A a) := by rw [IsStronglyPredictable.iff_measurable_add_one] refine ⟨?_, stronglyAdapted_pullCount_add_one h a⟩ @@ -505,7 +507,7 @@ lemma stepsUntil_eq_congr {Ο‰' : Ξ©} (h_eq : βˆ€ i ≀ n, A i Ο‰ = A i Ο‰') : section Measurability lemma isStoppingTime_stepsUntil [MeasurableSingletonClass 𝓐] - (h : IsAlgEnvSeq A R' alg env P) (a : 𝓐) (hm : m β‰  0) : + (h : IsAlgEnvSeq O A R' alg env P) (a : 𝓐) (hm : m β‰  0) : IsStoppingTime h.filtration (stepsUntil A a m) := by rw [stepsUntil_eq_leastGE _ hm] refine StronglyAdapted.isStoppingTime_leastGE _ fun n ↦ ?_ @@ -554,9 +556,9 @@ lemma measurable_stepsUntil' [MeasurableSingletonClass 𝓐] (measurable_stepsUntil hA a m).comp measurable_fst lemma measurable_comap_indicator_stepsUntil_eq [MeasurableSingletonClass 𝓐] - (R' : β„• β†’ Ξ© β†’ R) (a : 𝓐) (m n : β„•) : + (O : β„• β†’ Ξ© β†’ π“ž) (R' : β„• β†’ Ξ© β†’ R) (a : 𝓐) (m n : β„•) : Measurable[MeasurableSpace.comap - (fun Ο‰ : Ξ© ↦ (history A R' n Ο‰, A n Ο‰)) inferInstance] + (fun Ο‰ : Ξ© ↦ ((history O A R' n Ο‰, O n Ο‰), A n Ο‰)) inferInstance] ({Ο‰ | stepsUntil A a m Ο‰ = ↑n}.indicator fun _ ↦ 1) := by by_cases hm : m = 0 Β· simp only [hm] @@ -582,38 +584,42 @@ lemma measurable_comap_indicator_stepsUntil_eq [MeasurableSingletonClass 𝓐] refine ((measurableSet_singleton _).preimage ?_).inter ((measurableSet_singleton _).preimage ?_) Β· rw [measurable_iff_comap_le, Prod.instMeasurableSpace, MeasurableSpace.comap_prodMk] exact le_sup_of_le_right le_rfl - Β· rw [measurable_iff_comap_le, Prod.instMeasurableSpace, MeasurableSpace.comap_prodMk] - refine le_sup_of_le_left ?_ - rw [← measurable_iff_comap_le, pullCount_eq_comp_history (R' := R')] - exact measurable_comp_comap _ (measurable_pullCount' n a) + Β· have h_comp : pullCount A a n + = (fun p : (Hist π“ž 𝓐 R n Γ— π“ž) Γ— 𝓐 ↦ pullCount' n p.1.1 a) ∘ + (fun Ο‰ ↦ ((history O A R' n Ο‰, O n Ο‰), A n Ο‰)) := by + rw [pullCount_eq_comp_history (O := O) (R' := R')] + rfl + rw [h_comp] + exact measurable_comp_comap _ (by fun_prop) lemma measurable_indicator_stepsUntil_eq [MeasurableSingletonClass 𝓐] - (h : IsAlgEnvSeq A R' alg env P) (a : 𝓐) (m n : β„•) : + (h : IsAlgEnvSeq O A R' alg env P) (a : 𝓐) (m n : β„•) : Measurable ({Ο‰ : Ξ© | stepsUntil A a m Ο‰ = ↑n}.indicator fun _ ↦ 1) := by - refine (measurable_comap_indicator_stepsUntil_eq (mR := mR) R' a m n).mono ?_ le_rfl + refine (measurable_comap_indicator_stepsUntil_eq (mπ“ž := mπ“ž) (mR := mR) O R' a m n).mono ?_ le_rfl refine Measurable.comap_le ?_ + have hO := h.measurable_obs have hA := h.measurable_action have hR' := h.measurable_feedback fun_prop lemma measurableSet_stepsUntil_eq [MeasurableSingletonClass 𝓐] - (R' : β„• β†’ Ξ© β†’ R) (a : 𝓐) (m n : β„•) : - MeasurableSet[MeasurableSpace.comap (fun Ο‰ : Ξ© ↦ (history A R' n Ο‰, A n Ο‰)) - inferInstance] + (O : β„• β†’ Ξ© β†’ π“ž) (R' : β„• β†’ Ξ© β†’ R) (a : 𝓐) (m n : β„•) : + MeasurableSet[MeasurableSpace.comap + (fun Ο‰ : Ξ© ↦ ((history O A R' n Ο‰, O n Ο‰), A n Ο‰)) inferInstance] {Ο‰ : Ξ© | stepsUntil A a m Ο‰ = ↑n} := by let mProd := MeasurableSpace.comap - (fun Ο‰ : Ξ© ↦ (history A R' n Ο‰, A n Ο‰)) inferInstance + (fun Ο‰ : Ξ© ↦ ((history O A R' n Ο‰, O n Ο‰), A n Ο‰)) inferInstance suffices Measurable[mProd] ({Ο‰ | stepsUntil A a m Ο‰ = ↑n}.indicator fun x ↦ 1) by rwa [measurable_indicator_const_iff] at this - exact measurable_comap_indicator_stepsUntil_eq R' a m n + exact measurable_comap_indicator_stepsUntil_eq O R' a m n /-- `stepsUntil a m` is a stopping time with respect to the filtration `filtrationAction`. -/ lemma isStoppingTime_stepsUntil_filtrationAction [MeasurableSingletonClass 𝓐] - (h : IsAlgEnvSeq A R' alg env P) (a : 𝓐) (m : β„•) : + (h : IsAlgEnvSeq O A R' alg env P) (a : 𝓐) (m : β„•) : IsStoppingTime h.filtrationAction (stepsUntil A a m) := by refine isStoppingTime_of_measurableSet_eq fun n ↦ ?_ rw [h.filtrationAction_eq_comap n] - exact measurableSet_stepsUntil_eq R' a m n + exact measurableSet_stepsUntil_eq O R' a m n end Measurability @@ -728,11 +734,11 @@ lemma sum_comp_pullCount [Fintype 𝓐] [AddCommMonoid R] (f : β„• β†’ R) (t : Β· simp [sum_range_succ] Β· simp -lemma sum_pullCount' [Fintype 𝓐] (n : β„•) (h : Fin n β†’ 𝓐 Γ— ℝ) : βˆ‘ a, pullCount' n h a = n := by +lemma sum_pullCount' [Fintype 𝓐] (n : β„•) (h : Hist π“ž 𝓐 ℝ n) : βˆ‘ a, pullCount' n h a = n := by simp_rw [pullCount'_eq_sum] rw [Finset.sum_comm] - have hcol (s : Fin n) : βˆ‘ a, (if (h s).1 = a then (1 : β„•) else 0) = 1 := by - simp [Finset.sum_ite_eq univ (h s).1 (fun _ ↦ (1 : β„•))] + have hcol (s : Fin n) : βˆ‘ a, (if (h s).action = a then (1 : β„•) else 0) = 1 := by + simp [Finset.sum_ite_eq univ (h s).action (fun _ ↦ (1 : β„•))] simp [hcol] end Learning diff --git a/LeanMachineLearning/SequentialLearning/IonescuTulceaSpace.lean b/LeanMachineLearning/SequentialLearning/IonescuTulceaSpace.lean index 411429af..ac65d247 100644 --- a/LeanMachineLearning/SequentialLearning/IonescuTulceaSpace.lean +++ b/LeanMachineLearning/SequentialLearning/IonescuTulceaSpace.lean @@ -17,11 +17,11 @@ The main ingredient of the construction is the Ionescu-Tulcea theorem. ## Main statements -* `isAlgEnvSeq_unique`: the law of the sequence of actions and observations generated by an +* `isAlgEnvSeq_unique`: the law of the sequence of rounds generated by an algorithm-environment pair is unique: it does not depend on the probability space used. - If `A₁`, `R₁` and `Aβ‚‚`, `Rβ‚‚` are two algorithm-environment sequences generated by the same - algorithm-environment pair on probability spaces `(Ξ©, P)` and `(Ξ©', P')`, then - `P.map (fun Ο‰ n ↦ (A₁ n Ο‰, R₁ n Ο‰)) = P'.map (fun Ο‰ n ↦ (Aβ‚‚ n Ο‰, Rβ‚‚ n Ο‰))`. + If `O₁`, `A₁`, `R₁` and `Oβ‚‚`, `Aβ‚‚`, `Rβ‚‚` are two algorithm-environment sequences generated by the + same algorithm-environment pair on probability spaces `(Ξ©, P)` and `(Ξ©', P')`, then + `P.map (trajectory O₁ A₁ R₁) = P'.map (trajectory Oβ‚‚ Aβ‚‚ Rβ‚‚)`. -/ @@ -33,151 +33,171 @@ open scoped ENNReal NNReal namespace Learning -variable {𝓐 𝓨 Ξ© : Type*} {m𝓐 : MeasurableSpace 𝓐} {m𝓨 : MeasurableSpace 𝓨} {mΞ© : MeasurableSpace Ξ©} +variable {π“ž 𝓐 𝓨 Ξ© : Type*} {mπ“ž : MeasurableSpace π“ž} {m𝓐 : MeasurableSpace 𝓐} + {m𝓨 : MeasurableSpace 𝓨} {mΞ© : MeasurableSpace Ξ©} -/-- Measure on the sequence of actions and observations generated by the algorithm/environment. -/ +/-- Measure on the sequence of rounds generated by the algorithm/environment. -/ noncomputable -def trajMeasure (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) : - Measure (β„• β†’ 𝓐 Γ— 𝓨) := +def trajMeasure (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) : + Measure (β„• β†’ Round π“ž 𝓐 𝓨) := Kernel.trajMeasureFin (stepKernel alg env) deriving IsProbabilityMeasure namespace IT -/-- Action and feedback at step `n`. -/ -def step (n : β„•) (h : β„• β†’ 𝓐 Γ— 𝓨) : 𝓐 Γ— 𝓨 := h n +/-- The round at step `n`. -/ +def step (n : β„•) (h : β„• β†’ Round π“ž 𝓐 𝓨) : Round π“ž 𝓐 𝓨 := h n + +/-- `obs n` is the observation at time `n`. This is a random variable on the measurable space +`β„• β†’ Round π“ž 𝓐 𝓨`. -/ +def obs (n : β„•) (h : β„• β†’ Round π“ž 𝓐 𝓨) : π“ž := (h n).obs /-- `action n` is the action pulled at time `n`. This is a random variable on the measurable space -`β„• β†’ 𝓐 Γ— 𝓨`. -/ -def action (n : β„•) (h : β„• β†’ 𝓐 Γ— 𝓨) : 𝓐 := (h n).1 +`β„• β†’ Round π“ž 𝓐 𝓨`. -/ +def action (n : β„•) (h : β„• β†’ Round π“ž 𝓐 𝓨) : 𝓐 := (h n).action /-- `feedback n` is the feedback at time `n`. This is a random variable on the measurable space -`β„• β†’ 𝓐 Γ— 𝓨`. -/ -def feedback (n : β„•) (h : β„• β†’ 𝓐 Γ— 𝓨) : 𝓨 := (h n).2 +`β„• β†’ Round π“ž 𝓐 𝓨`. -/ +def feedback (n : β„•) (h : β„• β†’ Round π“ž 𝓐 𝓨) : 𝓨 := (h n).feedback -/-- `hist n` is the history before time `n`: the action-feedback pairs at times `0, ..., n - 1`. -This is a random variable on the measurable space `β„• β†’ 𝓐 Γ— 𝓨`. -/ -def hist (n : β„•) (h : β„• β†’ 𝓐 Γ— 𝓨) : Fin n β†’ 𝓐 Γ— 𝓨 := fun i ↦ h i +/-- `hist n` is the history before time `n`: the rounds at times `0, ..., n - 1`. +This is a random variable on the measurable space `β„• β†’ Round π“ž 𝓐 𝓨`. -/ +def hist (n : β„•) (h : β„• β†’ Round π“ž 𝓐 𝓨) : Hist π“ž 𝓐 𝓨 n := fun i ↦ h i -lemma fst_comp_step (n : β„•) : Prod.fst ∘ step (𝓐 := 𝓐) (𝓨 := 𝓨) n = action n := rfl +lemma fst_comp_step (n : β„•) : Prod.fst ∘ step (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨) n = obs n := rfl -lemma history_action_feedback (n : β„•) : - history (action (𝓐 := 𝓐) (𝓨 := 𝓨)) feedback n = hist n := rfl +lemma history_obs_action_feedback (n : β„•) : + history (obs (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨)) action feedback n = hist n := rfl @[simp] -lemma hist_zero : hist (𝓐 := 𝓐) (𝓨 := 𝓨) 0 = fun _ ↦ default := Unique.eq_default _ +lemma hist_zero : hist (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨) 0 = fun _ ↦ default := Unique.eq_default _ @[fun_prop] -lemma measurable_step (n : β„•) : Measurable (step n (𝓐 := 𝓐) (𝓨 := 𝓨)) := by +lemma measurable_step (n : β„•) : Measurable (step n (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨)) := by unfold step; fun_prop @[fun_prop] -lemma measurable_step_prod : Measurable (fun p : β„• Γ— (β„• β†’ 𝓐 Γ— 𝓨) ↦ step p.1 p.2) := +lemma measurable_step_prod : Measurable (fun p : β„• Γ— (β„• β†’ Round π“ž 𝓐 𝓨) ↦ step p.1 p.2) := + measurable_from_prod_countable_right fun n ↦ (by simp only; fun_prop) + +@[fun_prop] +lemma measurable_obs (n : β„•) : Measurable (obs n (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨)) := by + unfold obs; fun_prop + +@[fun_prop] +lemma measurable_obs_prod : Measurable (fun p : β„• Γ— (β„• β†’ Round π“ž 𝓐 𝓨) ↦ obs p.1 p.2) := measurable_from_prod_countable_right fun n ↦ (by simp only; fun_prop) @[fun_prop] -lemma measurable_action (n : β„•) : Measurable (action n (𝓐 := 𝓐) (𝓨 := 𝓨)) := by +lemma measurable_action (n : β„•) : Measurable (action n (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨)) := by unfold action; fun_prop @[fun_prop] -lemma measurable_action_prod : Measurable (fun p : β„• Γ— (β„• β†’ 𝓐 Γ— 𝓨) ↦ action p.1 p.2) := +lemma measurable_action_prod : Measurable (fun p : β„• Γ— (β„• β†’ Round π“ž 𝓐 𝓨) ↦ action p.1 p.2) := measurable_from_prod_countable_right fun n ↦ (by simp only; fun_prop) @[fun_prop] -lemma measurable_feedback (n : β„•) : Measurable (feedback n (𝓐 := 𝓐) (𝓨 := 𝓨)) := by +lemma measurable_feedback (n : β„•) : Measurable (feedback n (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨)) := by unfold feedback; fun_prop @[fun_prop] -lemma measurable_feedback_prod : Measurable (fun p : β„• Γ— (β„• β†’ 𝓐 Γ— 𝓨) ↦ feedback p.1 p.2) := +lemma measurable_feedback_prod : Measurable (fun p : β„• Γ— (β„• β†’ Round π“ž 𝓐 𝓨) ↦ feedback p.1 p.2) := measurable_from_prod_countable_right fun n ↦ (by simp only; fun_prop) @[fun_prop] -lemma measurable_hist (n : β„•) : Measurable (hist n (𝓐 := 𝓐) (𝓨 := 𝓨)) := by unfold hist; fun_prop +lemma measurable_hist (n : β„•) : Measurable (hist n (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨)) := by + unfold hist; fun_prop lemma hist_succ_eq_comp_frestrictLe (n : β„•) : - hist (𝓐 := 𝓐) (𝓨 := 𝓨) (n + 1) = - (MeasurableEquiv.finSuccPiIic (fun _ ↦ 𝓐 Γ— 𝓨) n).symm ∘ Preorder.frestrictLe n := rfl + hist (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨) (n + 1) = + (MeasurableEquiv.finSuccPiIic (fun _ ↦ Round π“ž 𝓐 𝓨) n).symm ∘ Preorder.frestrictLe n := rfl lemma frestrictLe_eq_comp_hist (n : β„•) : - Preorder.frestrictLe («π» := fun _ ↦ 𝓐 Γ— 𝓨) n = - (MeasurableEquiv.finSuccPiIic (fun _ ↦ 𝓐 Γ— 𝓨) n) ∘ hist (n + 1) := rfl + Preorder.frestrictLe («π» := fun _ ↦ Round π“ž 𝓐 𝓨) n = + (MeasurableEquiv.finSuccPiIic (fun _ ↦ Round π“ž 𝓐 𝓨) n) ∘ hist (n + 1) := rfl lemma step_eq_eval_comp_hist (n : β„•) : - step (𝓐 := 𝓐) (𝓨 := 𝓨) n = (fun x ↦ x (Fin.last n)) ∘ (hist (n + 1)) := rfl + step (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨) n = (fun x ↦ x (Fin.last n)) ∘ (hist (n + 1)) := rfl + +lemma obs_eq_eval_comp_hist (n : β„•) : + obs (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨) n = (fun x ↦ (x (Fin.last n)).obs) ∘ (hist (n + 1)) := rfl lemma action_eq_eval_comp_hist (n : β„•) : - action (𝓐 := 𝓐) (𝓨 := 𝓨) n = (fun x ↦ (x (Fin.last n)).1) ∘ (hist (n + 1)) := rfl + action (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨) n = (fun x ↦ (x (Fin.last n)).action) ∘ (hist (n + 1)) := rfl lemma feedback_eq_eval_comp_hist (n : β„•) : - feedback (𝓐 := 𝓐) (𝓨 := 𝓨) n = (fun x ↦ (x (Fin.last n)).2) ∘ (hist (n + 1)) := rfl + feedback (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨) n = + (fun x ↦ (x (Fin.last n)).feedback) ∘ (hist (n + 1)) := rfl /-- The history before time `m` is a restriction of the history before time `n β‰₯ m`. -/ lemma hist_eq_comp_hist {m n : β„•} (hmn : m ≀ n) : - hist (𝓐 := 𝓐) (𝓨 := 𝓨) m = (fun h (i : Fin m) ↦ h (Fin.castLE hmn i)) ∘ hist n := rfl + hist (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨) m = (fun h (i : Fin m) ↦ h (Fin.castLE hmn i)) ∘ hist n := rfl end IT section ModelEquivalence variable {Ξ© Ξ©' : Type*} {mΞ© : MeasurableSpace Ξ©} {mΞ©' : MeasurableSpace Ξ©'} - {alg : Algorithm 𝓐 𝓨} {env : Environment 𝓐 𝓨} + {alg : Algorithm π“ž 𝓐 𝓨} {env : Environment π“ž 𝓐 𝓨} {P : Measure Ξ©} [IsProbabilityMeasure P] {P' : Measure Ξ©'} [IsProbabilityMeasure P'] - {A₁ : β„• β†’ Ξ© β†’ 𝓐} {R₁ : β„• β†’ Ξ© β†’ 𝓨} {Aβ‚‚ : β„• β†’ Ξ©' β†’ 𝓐} {Rβ‚‚ : β„• β†’ Ξ©' β†’ 𝓨} {N : β„•} + {O₁ : β„• β†’ Ξ© β†’ π“ž} {A₁ : β„• β†’ Ξ© β†’ 𝓐} {R₁ : β„• β†’ Ξ© β†’ 𝓨} + {Oβ‚‚ : β„• β†’ Ξ©' β†’ π“ž} {Aβ‚‚ : β„• β†’ Ξ©' β†’ 𝓐} {Rβ‚‚ : β„• β†’ Ξ©' β†’ 𝓨} {N : β„•} -lemma IsAlgEnvSeq.map_trajectory (h : IsAlgEnvSeq A₁ R₁ alg env P) : - P.map (trajectory A₁ R₁) = trajMeasure alg env := - (Kernel.hasLaw_trajMeasureFin (X := fun _ ↦ 𝓐 Γ— 𝓨) (Y := step A₁ R₁) (P := P) +lemma IsAlgEnvSeq.map_trajectory (h : IsAlgEnvSeq O₁ A₁ R₁ alg env P) : + P.map (trajectory O₁ A₁ R₁) = trajMeasure alg env := + (Kernel.hasLaw_trajMeasureFin (X := fun _ ↦ Round π“ž 𝓐 𝓨) (Y := step O₁ A₁ R₁) (P := P) (ΞΊ' := stepKernel alg env) h.measurable_step h.hasCondDistrib_step).map_eq -lemma IsAlgEnvSeq.hasLaw_trajectory (h : IsAlgEnvSeq A₁ R₁ alg env P) : - HasLaw (trajectory A₁ R₁) (trajMeasure alg env) P where +lemma IsAlgEnvSeq.hasLaw_trajectory (h : IsAlgEnvSeq O₁ A₁ R₁ alg env P) : + HasLaw (trajectory O₁ A₁ R₁) (trajMeasure alg env) P where aemeasurable := h.measurable_trajectory.aemeasurable map_eq := h.map_trajectory -lemma IsAlgEnvSeqUntil.map_history (h : IsAlgEnvSeqUntil A₁ R₁ alg env P N) : - P.map (history A₁ R₁ N) = (trajMeasure alg env).map (IT.hist N) := - Kernel.eq_trajMeasureFin_map (X := fun _ ↦ 𝓐 Γ— 𝓨) (Y := step A₁ R₁) (P := P) (N := N) +lemma IsAlgEnvSeqUntil.map_history (h : IsAlgEnvSeqUntil O₁ A₁ R₁ alg env P N) : + P.map (history O₁ A₁ R₁ N) = (trajMeasure alg env).map (IT.hist N) := + Kernel.eq_trajMeasureFin_map (X := fun _ ↦ Round π“ž 𝓐 𝓨) (Y := step O₁ A₁ R₁) (P := P) (N := N) (ΞΊ' := stepKernel alg env) h.measurable_step h.hasCondDistrib_step -lemma IsAlgEnvSeq.map_history (h : IsAlgEnvSeq A₁ R₁ alg env P) (n : β„•) : - P.map (history A₁ R₁ n) = (trajMeasure alg env).map (IT.hist n) := +lemma IsAlgEnvSeq.map_history (h : IsAlgEnvSeq O₁ A₁ R₁ alg env P) (n : β„•) : + P.map (history O₁ A₁ R₁ n) = (trajMeasure alg env).map (IT.hist n) := (h.isAlgEnvSeqUntil n).map_history -/-- The law of the sequence of actions and observations generated by an algorithm-environment pair +/-- The law of the sequence of rounds generated by an algorithm-environment pair is unique: it does not depend on the probability space used. -/ -lemma isAlgEnvSeq_unique (h1 : IsAlgEnvSeq A₁ R₁ alg env P) - (h2 : IsAlgEnvSeq Aβ‚‚ Rβ‚‚ alg env P') : - P.map (trajectory A₁ R₁) = P'.map (trajectory Aβ‚‚ Rβ‚‚) := by +lemma isAlgEnvSeq_unique (h1 : IsAlgEnvSeq O₁ A₁ R₁ alg env P) + (h2 : IsAlgEnvSeq Oβ‚‚ Aβ‚‚ Rβ‚‚ alg env P') : + P.map (trajectory O₁ A₁ R₁) = P'.map (trajectory Oβ‚‚ Aβ‚‚ Rβ‚‚) := by rw [h1.map_trajectory, h2.map_trajectory] -/-- The law of the sequence of actions and observations generated by an algorithm-environment pair +/-- The law of the sequence of rounds generated by an algorithm-environment pair is unique: it does not depend on the probability space used. -/ -theorem IsAlgEnvSeq.identDistrib_trajectory (h1 : IsAlgEnvSeq A₁ R₁ alg env P) - (h2 : IsAlgEnvSeq Aβ‚‚ Rβ‚‚ alg env P') : - IdentDistrib (trajectory A₁ R₁) (trajectory Aβ‚‚ Rβ‚‚) P P' where +theorem IsAlgEnvSeq.identDistrib_trajectory (h1 : IsAlgEnvSeq O₁ A₁ R₁ alg env P) + (h2 : IsAlgEnvSeq Oβ‚‚ Aβ‚‚ Rβ‚‚ alg env P') : + IdentDistrib (trajectory O₁ A₁ R₁) (trajectory Oβ‚‚ Aβ‚‚ Rβ‚‚) P P' where aemeasurable_fst := h1.measurable_trajectory.aemeasurable aemeasurable_snd := h2.measurable_trajectory.aemeasurable map_eq := isAlgEnvSeq_unique h1 h2 /-- The law of the history before time `N` is determined by the algorithm-environment pair, provided that the sequence is an algorithm-environment sequence until time `N`. -/ -lemma isAlgEnvSeqUntil_unique (h1 : IsAlgEnvSeqUntil A₁ R₁ alg env P N) - (h2 : IsAlgEnvSeqUntil Aβ‚‚ Rβ‚‚ alg env P' N) : - P.map (history A₁ R₁ N) = P'.map (history Aβ‚‚ Rβ‚‚ N) := by +lemma isAlgEnvSeqUntil_unique (h1 : IsAlgEnvSeqUntil O₁ A₁ R₁ alg env P N) + (h2 : IsAlgEnvSeqUntil Oβ‚‚ Aβ‚‚ Rβ‚‚ alg env P' N) : + P.map (history O₁ A₁ R₁ N) = P'.map (history Oβ‚‚ Aβ‚‚ Rβ‚‚ N) := by rw [h1.map_history, h2.map_history] end ModelEquivalence namespace IT -/-- Filtration of the algorithm Seq: `IT.filtration 𝓐 𝓨 n` is the Οƒ-algebra generated by the -action-feedback pairs at times `0, ..., n`, that is by `hist (n + 1)`. -/ -protected def filtration (𝓐 𝓨 : Type*) [MeasurableSpace 𝓐] [MeasurableSpace 𝓨] : - Filtration β„• (inferInstance : MeasurableSpace (β„• β†’ 𝓐 Γ— 𝓨)) := - MeasureTheory.Filtration.piLE (X := fun _ ↦ 𝓐 Γ— 𝓨) +/-- Filtration of the algorithm Seq: `IT.filtration π“ž 𝓐 𝓨 n` is the Οƒ-algebra generated by the +rounds at times `0, ..., n`, that is by `hist (n + 1)`. -/ +protected def filtration (π“ž 𝓐 𝓨 : Type*) [MeasurableSpace π“ž] [MeasurableSpace 𝓐] + [MeasurableSpace 𝓨] : + Filtration β„• (inferInstance : MeasurableSpace (β„• β†’ Round π“ž 𝓐 𝓨)) := + MeasureTheory.Filtration.piLE (X := fun _ ↦ Round π“ž 𝓐 𝓨) lemma filtration_eq_comap (n : β„•) : - IT.filtration 𝓐 𝓨 n = MeasurableSpace.comap (hist (n + 1)) inferInstance := by + IT.filtration π“ž 𝓐 𝓨 n = MeasurableSpace.comap (hist (n + 1)) inferInstance := by simp only [IT.filtration, Filtration.piLE_eq_comap_frestrictLe] refine le_antisymm ?_ ?_ Β· rw [← measurable_iff_comap_le, frestrictLe_eq_comp_hist] @@ -185,46 +205,54 @@ lemma filtration_eq_comap (n : β„•) : Β· rw [← measurable_iff_comap_le, hist_succ_eq_comp_frestrictLe] exact measurable_comp_comap _ (by fun_prop) -lemma adapted_step : Adapted (IT.filtration 𝓐 𝓨) (step (𝓐 := 𝓐) (𝓨 := 𝓨)) := by +lemma adapted_step : Adapted (IT.filtration π“ž 𝓐 𝓨) (step (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨)) := by intro n rw [filtration_eq_comap, step_eq_eval_comp_hist] exact measurable_comp_comap _ (by fun_prop) +lemma adapted_obs : Adapted (IT.filtration π“ž 𝓐 𝓨) obs := by + intro n + rw [filtration_eq_comap, obs_eq_eval_comp_hist] + exact measurable_comp_comap _ (by fun_prop) + lemma measurable_hist_succ_filtration (n : β„•) : - Measurable[IT.filtration 𝓐 𝓨 n] (hist (n + 1)) := by + Measurable[IT.filtration π“ž 𝓐 𝓨 n] (hist (n + 1)) := by rw [filtration_eq_comap] exact measurable_iff_comap_le.mpr le_rfl -lemma adapted_hist : Adapted (IT.filtration 𝓐 𝓨) hist := by +lemma adapted_hist : Adapted (IT.filtration π“ž 𝓐 𝓨) hist := by intro n rw [filtration_eq_comap, hist_eq_comp_hist n.le_succ] exact measurable_comp_comap _ (by fun_prop) -lemma adapted_action : Adapted (IT.filtration 𝓐 𝓨) action := by +lemma adapted_action : Adapted (IT.filtration π“ž 𝓐 𝓨) action := by intro n rw [filtration_eq_comap, action_eq_eval_comp_hist] exact measurable_comp_comap _ (by fun_prop) -lemma adapted_feedback : Adapted (IT.filtration 𝓐 𝓨) feedback := by +lemma adapted_feedback : Adapted (IT.filtration π“ž 𝓐 𝓨) feedback := by intro n rw [filtration_eq_comap, feedback_eq_eval_comp_hist] exact measurable_comp_comap _ (by fun_prop) section FiltrationAction -/-- Filtration generated by the history before time `n` together with the action at time `n`. -/ -def filtrationAction (𝓐 𝓨 : Type*) [MeasurableSpace 𝓐] [MeasurableSpace 𝓨] : - Filtration β„• (inferInstance : MeasurableSpace (β„• β†’ 𝓐 Γ— 𝓨)) where - seq n := MeasurableSpace.comap (fun Ο‰ ↦ (hist n Ο‰, action n Ο‰)) inferInstance +/-- Filtration generated by the history before time `n` together with the observation and the +action at time `n`. -/ +def filtrationAction (π“ž 𝓐 𝓨 : Type*) [MeasurableSpace π“ž] [MeasurableSpace 𝓐] + [MeasurableSpace 𝓨] : + Filtration β„• (inferInstance : MeasurableSpace (β„• β†’ Round π“ž 𝓐 𝓨)) where + seq n := MeasurableSpace.comap (fun Ο‰ ↦ ((hist n Ο‰, obs n Ο‰), action n Ο‰)) inferInstance mono' n m hnm := by simp only rw [← measurable_iff_comap_le] rcases eq_or_lt_of_le hnm with rfl | hlt Β· exact measurable_iff_comap_le.mpr le_rfl - have : (fun Ο‰ ↦ (hist (𝓐 := 𝓐) (𝓨 := 𝓨) n Ο‰, action n Ο‰)) = - (fun p : (Fin m β†’ 𝓐 Γ— 𝓨) Γ— 𝓐 ↦ - (fun i : Fin n ↦ p.1 (Fin.castLE hnm i), (p.1 ⟨n, hlt⟩).1)) ∘ - (fun Ο‰ ↦ (hist m Ο‰, action m Ο‰)) := rfl + have : (fun Ο‰ ↦ ((hist (π“ž := π“ž) (𝓐 := 𝓐) (𝓨 := 𝓨) n Ο‰, obs n Ο‰), action n Ο‰)) = + (fun p : (Hist π“ž 𝓐 𝓨 m Γ— π“ž) Γ— 𝓐 ↦ + ((fun i : Fin n ↦ p.1.1 (Fin.castLE hnm i), (p.1.1 ⟨n, hlt⟩).obs), + (p.1.1 ⟨n, hlt⟩).action)) ∘ + (fun Ο‰ ↦ ((hist m Ο‰, obs m Ο‰), action m Ο‰)) := rfl rw [this] exact measurable_comp_comap _ (by fun_prop) le' n := by @@ -232,107 +260,135 @@ def filtrationAction (𝓐 𝓨 : Type*) [MeasurableSpace 𝓐] [MeasurableSpace fun_prop lemma filtrationAction_eq_comap (n : β„•) : - filtrationAction 𝓐 𝓨 n = - MeasurableSpace.comap (fun Ο‰ ↦ (hist n Ο‰, action n Ο‰)) inferInstance := rfl + filtrationAction π“ž 𝓐 𝓨 n = + MeasurableSpace.comap (fun Ο‰ ↦ ((hist n Ο‰, obs n Ο‰), action n Ο‰)) inferInstance := rfl lemma filtrationAction_zero_eq_comap : - filtrationAction 𝓐 𝓨 0 = MeasurableSpace.comap (action 0) inferInstance := by + filtrationAction π“ž 𝓐 𝓨 0 = + MeasurableSpace.comap (fun Ο‰ ↦ (obs 0 Ο‰, action 0 Ο‰)) inferInstance := by rw [filtrationAction_eq_comap, hist_zero] refine le_antisymm ?_ ?_ Β· rw [← measurable_iff_comap_le] - exact measurable_const.prodMk (measurable_iff_comap_le.mpr le_rfl) + exact (measurable_const.prodMk + (measurable_fst.comp (measurable_iff_comap_le.mpr le_rfl))).prodMk + (measurable_snd.comp (measurable_iff_comap_le.mpr le_rfl)) Β· rw [← measurable_iff_comap_le] - exact measurable_snd.comp (measurable_iff_comap_le.mpr le_rfl) + exact ((measurable_snd.comp measurable_fst).comp + (measurable_iff_comap_le.mpr le_rfl)).prodMk + (measurable_snd.comp (measurable_iff_comap_le.mpr le_rfl)) lemma measurable_hist_filtrationAction (n : β„•) : - Measurable[filtrationAction 𝓐 𝓨 n] (hist n) := - measurable_fst.comp (measurable_iff_comap_le.mpr le_rfl) + Measurable[filtrationAction π“ž 𝓐 𝓨 n] (hist n) := + (measurable_fst.comp measurable_fst).comp (measurable_iff_comap_le.mpr le_rfl) lemma filtration_le_filtrationAction_add_one (n : β„•) : - IT.filtration 𝓐 𝓨 n ≀ filtrationAction 𝓐 𝓨 (n + 1) := by + IT.filtration π“ž 𝓐 𝓨 n ≀ filtrationAction π“ž 𝓐 𝓨 (n + 1) := by rw [filtration_eq_comap] exact measurable_iff_comap_le.mp (measurable_hist_filtrationAction (n + 1)) lemma filtration_le_filtrationAction {m n : β„•} (h : n < m) : - IT.filtration 𝓐 𝓨 n ≀ filtrationAction 𝓐 𝓨 m := by + IT.filtration π“ž 𝓐 𝓨 n ≀ filtrationAction π“ž 𝓐 𝓨 m := by have h' : n + 1 ≀ m := by grind - exact (filtration_le_filtrationAction_add_one n).trans ((filtrationAction 𝓐 𝓨).mono h') + exact (filtration_le_filtrationAction_add_one n).trans ((filtrationAction π“ž 𝓐 𝓨).mono h') lemma filtrationAction_le_filtration_self (n : β„•) : - filtrationAction 𝓐 𝓨 n ≀ IT.filtration 𝓐 𝓨 n := by + filtrationAction π“ž 𝓐 𝓨 n ≀ IT.filtration π“ž 𝓐 𝓨 n := by rw [filtrationAction_eq_comap, ← measurable_iff_comap_le] - exact (adapted_hist n).prodMk (adapted_action n) + exact ((adapted_hist n).prodMk (adapted_obs n)).prodMk (adapted_action n) lemma filtrationAction_le_filtration {m n : β„•} (h : m ≀ n) : - filtrationAction 𝓐 𝓨 m ≀ IT.filtration 𝓐 𝓨 n := - (filtrationAction_le_filtration_self m).trans ((IT.filtration 𝓐 𝓨).mono h) + filtrationAction π“ž 𝓐 𝓨 m ≀ IT.filtration π“ž 𝓐 𝓨 n := + (filtrationAction_le_filtration_self m).trans ((IT.filtration π“ž 𝓐 𝓨).mono h) + +lemma measurable_obs_filtrationAction (n : β„•) : + Measurable[filtrationAction π“ž 𝓐 𝓨 n] (obs n) := + (measurable_snd.comp measurable_fst).comp (measurable_iff_comap_le.mpr le_rfl) lemma measurable_action_filtrationAction (n : β„•) : - Measurable[filtrationAction 𝓐 𝓨 n] (action n) := + Measurable[filtrationAction π“ž 𝓐 𝓨 n] (action n) := measurable_snd.comp (measurable_iff_comap_le.mpr le_rfl) end FiltrationAction section Laws -lemma hasCondDistrib_step (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) (n : β„•) : +lemma hasCondDistrib_step (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (n : β„•) : HasCondDistrib (step n) (hist n) (stepKernel alg env n) (trajMeasure alg env) := Kernel.hasCondDistrib_trajMeasureFin n -lemma hasCondDistrib_action (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) (n : β„•) : - HasCondDistrib (action n) (hist n) (alg.policy n) (trajMeasure alg env) := by +lemma hasCondDistrib_obs (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (n : β„•) : + HasCondDistrib (obs n) (hist n) (env.obs n) (trajMeasure alg env) := by rw [← fst_comp_step, ← fst_stepKernel, Kernel.fst_eq] exact HasCondDistrib.comp_left (hasCondDistrib_step alg env n) measurable_fst -lemma hasCondDistrib_feedback (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) (n : β„•) : - HasCondDistrib (feedback n) (fun Ο‰ ↦ (hist n Ο‰, action n Ο‰)) (env.feedback n) +/-- The action and the feedback at time `n`, given the history and the observation at time `n`. -/ +lemma hasCondDistrib_action_feedback (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (n : β„•) : + HasCondDistrib (fun Ο‰ ↦ (action n Ο‰, feedback n Ο‰)) (fun Ο‰ ↦ (hist n Ο‰, obs n Ο‰)) + (alg.policy n βŠ—β‚– env.feedback n) (trajMeasure alg env) := + HasCondDistrib.of_compProd (hasCondDistrib_step alg env n) + +lemma hasCondDistrib_action (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (n : β„•) : + HasCondDistrib (action n) (fun Ο‰ ↦ (hist n Ο‰, obs n Ο‰)) (alg.policy n) (trajMeasure alg env) := by - have h_step := hasCondDistrib_step alg env n - have h_action := hasCondDistrib_action alg env n - refine ⟨by fun_prop, ?_⟩ - rw [h_action.map_eq, ← Measure.compProd_assoc, ← stepKernel, ← h_step.map_eq, - Measure.map_map (by fun_prop) (by fun_prop)] - rfl - -lemma isAlgEnvSeq_trajMeasure (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) : - IsAlgEnvSeq action feedback alg env (trajMeasure alg env) where + have h := (hasCondDistrib_action_feedback alg env n).fst + rwa [Kernel.fst_compProd] at h + +lemma hasCondDistrib_feedback (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (n : β„•) : + HasCondDistrib (feedback n) (fun Ο‰ ↦ ((hist n Ο‰, obs n Ο‰), action n Ο‰)) (env.feedback n) + (trajMeasure alg env) := + HasCondDistrib.of_compProd (hasCondDistrib_action_feedback alg env n) + +lemma isAlgEnvSeq_trajMeasure (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) : + IsAlgEnvSeq obs action feedback alg env (trajMeasure alg env) where + hasCondDistrib_obs n := hasCondDistrib_obs alg env n hasCondDistrib_action n := hasCondDistrib_action alg env n hasCondDistrib_feedback n := hasCondDistrib_feedback alg env n -lemma hasLaw_step_zero (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) : - HasLaw (step 0) (alg.p0 βŠ—β‚˜ env.Ξ½0) (trajMeasure alg env) := +lemma hasLaw_step_zero (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) : + HasLaw (step 0) (env.obs0 βŠ—β‚˜ (alg.p0 βŠ—β‚– env.Ξ½0)) (trajMeasure alg env) := (isAlgEnvSeq_trajMeasure alg env).hasLaw_step_zero -lemma hasLaw_action_zero (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) : - HasLaw (action 0) alg.p0 (trajMeasure alg env) := - (isAlgEnvSeq_trajMeasure alg env).hasLaw_action_zero +lemma hasLaw_obs_zero (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) : + HasLaw (obs 0) env.obs0 (trajMeasure alg env) := + (isAlgEnvSeq_trajMeasure alg env).hasLaw_obs_zero -lemma hasCondDistrib_feedback_zero (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) : - HasCondDistrib (feedback 0) (action 0) env.Ξ½0 (trajMeasure alg env) := +lemma hasCondDistrib_action_zero (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) : + HasCondDistrib (action 0) (obs 0) alg.p0 (trajMeasure alg env) := + (isAlgEnvSeq_trajMeasure alg env).hasCondDistrib_action_zero + +lemma hasCondDistrib_feedback_zero (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) : + HasCondDistrib (feedback 0) (fun Ο‰ ↦ (obs 0 Ο‰, action 0 Ο‰)) env.Ξ½0 (trajMeasure alg env) := (isAlgEnvSeq_trajMeasure alg env).hasCondDistrib_feedback_zero lemma condDistrib_feedback_zero [StandardBorelSpace 𝓨] [Nonempty 𝓨] - (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) : - condDistrib (feedback 0) (action 0) (trajMeasure alg env) - =ᡐ[(trajMeasure alg env).map (action 0)] env.Ξ½0 := + (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) : + condDistrib (feedback 0) (fun Ο‰ ↦ (obs 0 Ο‰, action 0 Ο‰)) (trajMeasure alg env) + =ᡐ[(trajMeasure alg env).map (fun Ο‰ ↦ (obs 0 Ο‰, action 0 Ο‰))] env.Ξ½0 := (hasCondDistrib_feedback_zero alg env).condDistrib_eq -lemma condDistrib_step [StandardBorelSpace 𝓐] [Nonempty 𝓐] [StandardBorelSpace 𝓨] [Nonempty 𝓨] - (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) (n : β„•) : +lemma condDistrib_step [StandardBorelSpace π“ž] [Nonempty π“ž] + [StandardBorelSpace 𝓐] [Nonempty 𝓐] [StandardBorelSpace 𝓨] [Nonempty 𝓨] + (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (n : β„•) : condDistrib (step n) (hist n) (trajMeasure alg env) =ᡐ[(trajMeasure alg env).map (hist n)] stepKernel alg env n := (hasCondDistrib_step alg env n).condDistrib_eq +lemma condDistrib_obs [StandardBorelSpace π“ž] [Nonempty π“ž] + (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (n : β„•) : + condDistrib (obs n) (hist n) (trajMeasure alg env) + =ᡐ[(trajMeasure alg env).map (hist n)] env.obs n := + (hasCondDistrib_obs alg env n).condDistrib_eq + lemma condDistrib_action [StandardBorelSpace 𝓐] [Nonempty 𝓐] - (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) (n : β„•) : - condDistrib (action n) (hist n) (trajMeasure alg env) - =ᡐ[(trajMeasure alg env).map (hist n)] alg.policy n := + (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (n : β„•) : + condDistrib (action n) (fun Ο‰ ↦ (hist n Ο‰, obs n Ο‰)) (trajMeasure alg env) + =ᡐ[(trajMeasure alg env).map (fun Ο‰ ↦ (hist n Ο‰, obs n Ο‰))] alg.policy n := (hasCondDistrib_action alg env n).condDistrib_eq lemma condDistrib_feedback [StandardBorelSpace 𝓨] [Nonempty 𝓨] - (alg : Algorithm 𝓐 𝓨) (env : Environment 𝓐 𝓨) (n : β„•) : - condDistrib (feedback n) (fun Ο‰ ↦ (hist n Ο‰, action n Ο‰)) (trajMeasure alg env) - =ᡐ[(trajMeasure alg env).map (fun Ο‰ ↦ (hist n Ο‰, action n Ο‰))] env.feedback n := + (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (n : β„•) : + condDistrib (feedback n) (fun Ο‰ ↦ ((hist n Ο‰, obs n Ο‰), action n Ο‰)) (trajMeasure alg env) + =ᡐ[(trajMeasure alg env).map (fun Ο‰ ↦ ((hist n Ο‰, obs n Ο‰), action n Ο‰))] env.feedback n := (hasCondDistrib_feedback alg env n).condDistrib_eq end Laws diff --git a/LeanMachineLearning/SequentialLearning/Means.lean b/LeanMachineLearning/SequentialLearning/Means.lean index f583c1f5..6207a34f 100644 --- a/LeanMachineLearning/SequentialLearning/Means.lean +++ b/LeanMachineLearning/SequentialLearning/Means.lean @@ -45,102 +45,106 @@ end ProbabilityTheory namespace Learning -variable {Ξ© 𝓐 𝓨 : Type*} {mΞ© : MeasurableSpace Ξ©} {m𝓐 : MeasurableSpace 𝓐} {m𝓨 : MeasurableSpace 𝓨} +variable {Ξ© π“ž 𝓐 𝓨 : Type*} {mΞ© : MeasurableSpace Ξ©} {mπ“ž : MeasurableSpace π“ž} + {m𝓐 : MeasurableSpace 𝓐} {m𝓨 : MeasurableSpace 𝓨} [NormedAddCommGroup 𝓨] [NormedSpace ℝ 𝓨] - {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {P : Measure Ξ©} [IsFiniteMeasure P] - {alg : Algorithm 𝓐 𝓨} {env : Environment 𝓐 𝓨} + {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {P : Measure Ξ©} [IsFiniteMeasure P] + {alg : Algorithm π“ž 𝓐 𝓨} {env : Environment π“ž 𝓐 𝓨} /-- The kernel that gives the measure of the feedback distribution as a function of the action chosen at time `n`. -/ -noncomputable def Environment.measure (env : Environment 𝓐 𝓨) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) - (n : β„•) (Ο‰ : Ξ©) : Kernel 𝓐 𝓨 := - (env.feedback n).sectR (history A Y n Ο‰) +noncomputable def Environment.measure (env : Environment π“ž 𝓐 𝓨) (O : β„• β†’ Ξ© β†’ π“ž) (A : β„• β†’ Ξ© β†’ 𝓐) + (Y : β„• β†’ Ξ© β†’ 𝓨) (n : β„•) (Ο‰ : Ξ©) : Kernel 𝓐 𝓨 := + (env.feedback n).sectR (history O A Y n Ο‰, O n Ο‰) /-- The means of the feedback distribution as a function of the action chosen at time `n`. -/ -noncomputable def Environment.means (env : Environment 𝓐 𝓨) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) - (k : 𝓐) (n : β„•) (Ο‰ : Ξ©) : 𝓨 := - (env.measure A Y n Ο‰ k)[id] +noncomputable def Environment.means (env : Environment π“ž 𝓐 𝓨) (O : β„• β†’ Ξ© β†’ π“ž) (A : β„• β†’ Ξ© β†’ 𝓐) + (Y : β„• β†’ Ξ© β†’ 𝓨) (k : 𝓐) (n : β„•) (Ο‰ : Ξ©) : 𝓨 := + (env.measure O A Y n Ο‰ k)[id] @[simp] -lemma means_zero (env : Environment 𝓐 𝓨) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) +lemma means_zero (env : Environment π“ž 𝓐 𝓨) (O : β„• β†’ Ξ© β†’ π“ž) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) (k : 𝓐) (Ο‰ : Ξ©) : - env.means A Y k 0 Ο‰ = (env.Ξ½0 k)[id] := by + env.means O A Y k 0 Ο‰ = (env.Ξ½0 (O 0 Ο‰, k))[id] := by simp [Environment.means, Environment.measure, Environment.feedback_zero] @[simp] -lemma means_of_isObliviousEnv [IsObliviousEnv env] (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) - (k : 𝓐) (n : β„•) (Ο‰ : Ξ©) : - env.means A Y k n Ο‰ = (feedbackCondAction env n k)[id] := by +lemma means_of_isObliviousEnv [IsObliviousEnv env] (O : β„• β†’ Ξ© β†’ π“ž) (A : β„• β†’ Ξ© β†’ 𝓐) + (Y : β„• β†’ Ξ© β†’ 𝓨) (k : 𝓐) (n : β„•) (Ο‰ : Ξ©) : + env.means O A Y k n Ο‰ = (feedbackCondAction env n k)[id] := by simp [Environment.means, Environment.measure, feedback_eq_feedbackCondAction] lemma means_obliviousEnv (Ξ½ : β„• β†’ Kernel 𝓐 𝓨) [βˆ€ n, IsMarkovKernel (Ξ½ n)] - (k : 𝓐) (n : β„•) (Ο‰ : Ξ©) : - (obliviousEnv Ξ½).means A Y k n Ο‰ = (Ξ½ n k)[id] := by simp + {O : β„• β†’ Ξ© β†’ Unit} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} (k : 𝓐) (n : β„•) (Ο‰ : Ξ©) : + (obliviousEnv Ξ½).means O A Y k n Ο‰ = (Ξ½ n k)[id] := by simp -lemma means_stationaryEnv (Ξ½ : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ½] (k : 𝓐) (n : β„•) (Ο‰ : Ξ©) : - (stationaryEnv Ξ½).means A Y k n Ο‰ = (Ξ½ k)[id] := by simp +lemma means_stationaryEnv (Ξ½ : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ½] + {O : β„• β†’ Ξ© β†’ Unit} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} (k : 𝓐) (n : β„•) (Ο‰ : Ξ©) : + (stationaryEnv Ξ½).means O A Y k n Ο‰ = (Ξ½ k)[id] := by simp @[fun_prop] lemma IsAlgEnvSeq.stronglyMeasurable_means [SecondCountableTopology 𝓨] [OpensMeasurableSpace 𝓨] - (h : IsAlgEnvSeq A Y alg env P) (k : 𝓐) (n : β„•) : - StronglyMeasurable (env.means A Y k n) := by + (h : IsAlgEnvSeq O A Y alg env P) (k : 𝓐) (n : β„•) : + StronglyMeasurable (env.means O A Y k n) := by unfold Environment.means - have h_eq Ο‰ : env.measure A Y n Ο‰ k = - (env.feedback n βˆ˜β‚– Kernel.deterministic (fun Ο‰ ↦ (history A Y n Ο‰, k)) - ((h.measurable_history n).prodMk (by fun_prop))) Ο‰ := by + have hO := h.measurable_obs + have h_eq Ο‰ : env.measure O A Y n Ο‰ k = + (env.feedback n βˆ˜β‚– Kernel.deterministic (fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), k)) + (((h.measurable_history n).prodMk (h.measurable_obs n)).prodMk (by fun_prop))) Ο‰ := by simp [Environment.measure, Kernel.comp_deterministic_eq_comap] simp_rw [h_eq] fun_prop @[fun_prop] lemma IsAlgEnvSeq.measurable_means [SecondCountableTopology 𝓨] [BorelSpace 𝓨] - (h : IsAlgEnvSeq A Y alg env P) (k : 𝓐) (n : β„•) : - Measurable (env.means A Y k n) := + (h : IsAlgEnvSeq O A Y alg env P) (k : 𝓐) (n : β„•) : + Measurable (env.means O A Y k n) := (h.stronglyMeasurable_means k n).measurable lemma IsAlgEnvSeq.adapted_means_filtrationAction [SecondCountableTopology 𝓨] [BorelSpace 𝓨] - (h : IsAlgEnvSeq A Y alg env P) : - Adapted h.filtrationAction (fun n Ο‰ ↦ env.means A Y (A n Ο‰) n Ο‰) := by + (h : IsAlgEnvSeq O A Y alg env P) : + Adapted h.filtrationAction (fun n Ο‰ ↦ env.means O A Y (A n Ο‰) n Ο‰) := by intro n simp only [Environment.means, Environment.measure, Kernel.sectR_apply, id_eq] change Measurable[h.filtrationAction n] - ((fun Ο‰ ↦ ∫ x, x βˆ‚(env.feedback n Ο‰)) ∘ (fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰))) + ((fun Ο‰ ↦ ∫ x, x βˆ‚(env.feedback n Ο‰)) ∘ (fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰))) rw [IsAlgEnvSeq.filtrationAction_eq_comap] exact measurable_comp_comap _ stronglyMeasurable_id.integral_kernel.measurable lemma IsAlgEnvSeq.stronglyAdapted_means_filtrationAction [SecondCountableTopology 𝓨] [BorelSpace 𝓨] - (h : IsAlgEnvSeq A Y alg env P) : - StronglyAdapted h.filtrationAction (fun n Ο‰ ↦ env.means A Y (A n Ο‰) n Ο‰) := + (h : IsAlgEnvSeq O A Y alg env P) : + StronglyAdapted h.filtrationAction (fun n Ο‰ ↦ env.means O A Y (A n Ο‰) n Ο‰) := (h.adapted_means_filtrationAction).stronglyAdapted lemma IsAlgEnvSeq.adapted_means [SecondCountableTopology 𝓨] [BorelSpace 𝓨] - (h : IsAlgEnvSeq A Y alg env P) : - Adapted h.filtration (fun n Ο‰ ↦ env.means A Y (A n Ο‰) n Ο‰) := + (h : IsAlgEnvSeq O A Y alg env P) : + Adapted h.filtration (fun n Ο‰ ↦ env.means O A Y (A n Ο‰) n Ο‰) := fun n ↦ (h.adapted_means_filtrationAction n).mono (h.filtrationAction_le_filtration n) le_rfl omit [NormedSpace ℝ 𝓨] in lemma IsAlgEnvSeq.condExp_feedback_comp {𝓩 : Type*} [NormedAddCommGroup 𝓩] [NormedSpace ℝ 𝓩] [CompleteSpace 𝓩] [StandardBorelSpace 𝓨] - (h : IsAlgEnvSeq A Y alg env P) (n : β„•) + (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) {g : 𝓨 β†’ 𝓩} (hg : StronglyMeasurable g) (hint : Integrable (fun Ο‰ ↦ g (Y n Ο‰)) P) : P[fun Ο‰ ↦ g (Y n Ο‰) | h.filtrationAction n] =ᡐ[P] - fun Ο‰ ↦ (env.feedback n (history A Y n Ο‰, A n Ο‰))[g] := by - have hX : Measurable (fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) := - (h.measurable_history n).prodMk (h.measurable_action n) + fun Ο‰ ↦ (env.feedback n ((history O A Y n Ο‰, O n Ο‰), A n Ο‰))[g] := by + have hX : Measurable (fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) := + ((h.measurable_history n).prodMk (h.measurable_obs n)).prodMk (h.measurable_action n) rw [h.filtrationAction_eq_comap n] exact (h.hasCondDistrib_feedback n).condExp_comp_eq hX hg hint lemma IsAlgEnvSeq.condExp_feedback [BorelSpace 𝓨] [SecondCountableTopology 𝓨] [CompleteSpace 𝓨] - (h : IsAlgEnvSeq A Y alg env P) (n : β„•) + (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) (hint : Integrable (Y n) P) : - P[Y n | h.filtrationAction n] =ᡐ[P] fun Ο‰ ↦ env.means A Y (A n Ο‰) n Ο‰ := + P[Y n | h.filtrationAction n] =ᡐ[P] fun Ο‰ ↦ env.means O A Y (A n Ο‰) n Ο‰ := condExp_feedback_comp h n stronglyMeasurable_id hint lemma IsAlgEnvSeq.memLp_means_action [SecondCountableTopology 𝓨] [BorelSpace 𝓨] - (h : IsAlgEnvSeq A Y alg env P) {n : β„•} {p : ℝβ‰₯0∞} (hp1 : 1 ≀ p) (hp_top : p β‰  ∞) + (h : IsAlgEnvSeq O A Y alg env P) {n : β„•} {p : ℝβ‰₯0∞} (hp1 : 1 ≀ p) (hp_top : p β‰  ∞) (hint : MemLp (Y n) p P) : - MemLp (fun Ο‰ ↦ env.means A Y (A n Ο‰) n Ο‰) p P := by + MemLp (fun Ο‰ ↦ env.means O A Y (A n Ο‰) n Ο‰) p P := by have hp0 : p β‰  0 := by positivity + have hO := h.measurable_obs have hA := h.measurable_action have h_hist := h.measurable_history have hint' : MemLp id p (P.map (Y n)) := by @@ -149,9 +153,9 @@ lemma IsAlgEnvSeq.memLp_means_action [SecondCountableTopology 𝓨] [BorelSpace simp only [id_eq] rw [(h.hasLaw_feedback_comp n).map_eq, Measure.memLp_comp_iff hp0 hp_top (by fun_prop)] at hint' have hint'' := hint'.2.comp_aemeasurable (by fun_prop) - have h_eq Ο‰ : (env.feedback n) (history A Y n Ο‰, A n Ο‰) = + have h_eq Ο‰ : (env.feedback n) ((history O A Y n Ο‰, O n Ο‰), A n Ο‰) = (env.feedback n βˆ˜β‚– - Kernel.deterministic (fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) (by fun_prop)) Ο‰ := by + Kernel.deterministic (fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) (by fun_prop)) Ο‰ := by simp [Kernel.comp_deterministic_eq_comap] rw [← integrable_norm_rpow_iff _ hp0 hp_top] swap @@ -165,13 +169,15 @@ lemma IsAlgEnvSeq.memLp_means_action [SecondCountableTopology 𝓨] [BorelSpace simp_rw [Kernel.sectR_apply, h_eq] exact StronglyMeasurable.integral_kernel (by fun_prop) Β· simp only [Real.norm_eq_abs, Function.comp_apply, Kernel.sectR_apply] - filter_upwards [ae_of_ae_map ((h_hist n).prodMk (hA n)).aemeasurable hint'.1] with Ο‰ hΟ‰ + filter_upwards [ae_of_ae_map (((h_hist n).prodMk (hO n)).prodMk (hA n)).aemeasurable hint'.1] + with Ο‰ hΟ‰ rw [abs_of_nonneg (by positivity)] exact norm_integral_rpow_le_integral_norm_rpow hp1 hp_top hΟ‰ lemma IsAlgEnvSeq.integrable_means_action [SecondCountableTopology 𝓨] [OpensMeasurableSpace 𝓨] - (h : IsAlgEnvSeq A Y alg env P) {n : β„•} (hint : Integrable (Y n) P) : - Integrable (fun Ο‰ ↦ env.means A Y (A n Ο‰) n Ο‰) P := by + (h : IsAlgEnvSeq O A Y alg env P) {n : β„•} (hint : Integrable (Y n) P) : + Integrable (fun Ο‰ ↦ env.means O A Y (A n Ο‰) n Ο‰) P := by + have hO := h.measurable_obs have hA := h.measurable_action have h_hist := h.measurable_history have hint' : Integrable id (P.map (Y n)) := by @@ -183,9 +189,9 @@ lemma IsAlgEnvSeq.integrable_means_action [SecondCountableTopology 𝓨] [OpensM simp only [id_eq] at hint'' refine Integrable.mono' hint'' ?_ ?_ Β· refine StronglyMeasurable.aestronglyMeasurable ?_ - have h_eq Ο‰ : (env.feedback n) (history A Y n Ο‰, A n Ο‰) = + have h_eq Ο‰ : (env.feedback n) ((history O A Y n Ο‰, O n Ο‰), A n Ο‰) = (env.feedback n βˆ˜β‚– - Kernel.deterministic (fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) (by fun_prop)) Ο‰ := by + Kernel.deterministic (fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) (by fun_prop)) Ο‰ := by simp [Kernel.comp_deterministic_eq_comap] simp_rw [Kernel.sectR_apply, h_eq] exact StronglyMeasurable.integral_kernel (by fun_prop) diff --git a/LeanMachineLearning/SequentialLearning/StationaryEnv.lean b/LeanMachineLearning/SequentialLearning/StationaryEnv.lean index 9a36413a..8f38b188 100644 --- a/LeanMachineLearning/SequentialLearning/StationaryEnv.lean +++ b/LeanMachineLearning/SequentialLearning/StationaryEnv.lean @@ -12,14 +12,15 @@ public import LeanMachineLearning.SequentialLearning.Algorithm # Oblivious and stationary environments An oblivious environment is an environment in which the distribution of the next feedback depends -only on the last action (and not on the past history). +only on the last action (and not on the past history nor on the current observation). If the kernel that gives the distribution of the next feedback given the last action is the same at every time step, then we say that the environment is stationary. ## Main definitions We define a `Prop`-valued typeclass `IsObliviousEnv` to express that an environment is oblivious, -and we define two constructors for oblivious environments. +and we define two constructors for oblivious environments. Those constructors build environments +without observations, that is with observation type `Unit`. Typeclass and related definitions: * `IsObliviousEnv env`: the environment `env` is oblivious. @@ -27,12 +28,12 @@ Typeclass and related definitions: given the action at time `n` in an oblivious environment `env`. Constructors for oblivious environments: -* `obliviousEnv Ξ½`: an oblivious environment, in which the distribution of the next feedback depends - only on the last action, but in a possibly time-dependent manner, and is given by a sequence of - Markov kernels `Ξ½ : β„• β†’ Kernel 𝓐 𝓨`. -* `stationaryEnv Ξ½`: a stationary environment, in which the distribution of the next feedback - depends only on the last action (and not on the past history), and is given by a Markov kernel - `Ξ½ : Kernel 𝓐 𝓨`. +* `obliviousEnv Ξ½`: an oblivious environment without observations, in which the distribution of the + next feedback depends only on the last action, but in a possibly time-dependent manner, and is + given by a sequence of Markov kernels `Ξ½ : β„• β†’ Kernel 𝓐 𝓨`. +* `stationaryEnv Ξ½`: a stationary environment without observations, in which the distribution of + the next feedback depends only on the last action (and not on the past history), and is given by + a Markov kernel `Ξ½ : Kernel 𝓐 𝓨`. -/ @@ -44,57 +45,63 @@ open scoped ENNReal NNReal namespace Learning -variable {𝓐 𝓨 : Type*} {m𝓐 : MeasurableSpace 𝓐} {m𝓨 : MeasurableSpace 𝓨} +variable {π“ž 𝓐 𝓨 : Type*} {mπ“ž : MeasurableSpace π“ž} {m𝓐 : MeasurableSpace 𝓐} + {m𝓨 : MeasurableSpace 𝓨} /-- An environment is oblivious if the distribution of the next feedback depends only on -the last action and not on the past history. -/ -class IsObliviousEnv (env : Environment 𝓐 𝓨) : Prop where +the last action and not on the past history nor on the current observation. -/ +class IsObliviousEnv (env : Environment π“ž 𝓐 𝓨) : Prop where exists_eq_prodMkLeft : βˆƒ Ξ½ : β„• β†’ Kernel 𝓐 𝓨, (βˆ€ n, IsMarkovKernel (Ξ½ n)) ∧ (βˆ€ n, env.feedback n = (Ξ½ n).prodMkLeft _) /-- The kernel representing the conditional distribution of the feedback given the action at time `n` in an oblivious environment. -/ noncomputable -def feedbackCondAction (env : Environment 𝓐 𝓨) [h_obl : IsObliviousEnv env] (n : β„•) : Kernel 𝓐 𝓨 := +def feedbackCondAction (env : Environment π“ž 𝓐 𝓨) [h_obl : IsObliviousEnv env] (n : β„•) : + Kernel 𝓐 𝓨 := h_obl.exists_eq_prodMkLeft.choose n -instance (env : Environment 𝓐 𝓨) [IsObliviousEnv env] (n : β„•) : +instance (env : Environment π“ž 𝓐 𝓨) [IsObliviousEnv env] (n : β„•) : IsMarkovKernel (feedbackCondAction env n) := IsObliviousEnv.exists_eq_prodMkLeft.choose_spec.1 n -lemma feedback_eq_feedbackCondAction (env : Environment 𝓐 𝓨) [IsObliviousEnv env] (n : β„•) : +lemma feedback_eq_feedbackCondAction (env : Environment π“ž 𝓐 𝓨) [IsObliviousEnv env] (n : β„•) : env.feedback n = (feedbackCondAction env n).prodMkLeft _ := IsObliviousEnv.exists_eq_prodMkLeft.choose_spec.2 n -lemma Ξ½0_eq_feedbackCondAction (env : Environment 𝓐 𝓨) [IsObliviousEnv env] : - env.Ξ½0 = feedbackCondAction env 0 := by - rw [Environment.Ξ½0_def, feedback_eq_feedbackCondAction, Kernel.sectR_prodMkLeft] +lemma Ξ½0_eq_feedbackCondAction (env : Environment π“ž 𝓐 𝓨) [IsObliviousEnv env] : + env.Ξ½0 = (feedbackCondAction env 0).prodMkLeft π“ž := by + ext p : 1 + rw [Environment.Ξ½0_def, Kernel.comap_apply, feedback_eq_feedbackCondAction, + Kernel.prodMkLeft_apply, Kernel.prodMkLeft_apply] namespace IsObliviousEnv variable {Ξ© : Type*} {mΞ© : MeasurableSpace Ξ©} - {alg : Algorithm 𝓐 𝓨} {env : Environment 𝓐 𝓨} {P : Measure Ξ©} [IsFiniteMeasure P] - {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {n N : β„•} + {alg : Algorithm π“ž 𝓐 𝓨} {env : Environment π“ž 𝓐 𝓨} {P : Measure Ξ©} [IsFiniteMeasure P] + {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {n N : β„•} {Ξ½ : β„• β†’ Kernel 𝓐 𝓨} [βˆ€ n, IsMarkovKernel (Ξ½ n)] lemma hasCondDistrib_feedback_history_action [IsObliviousEnv env] - (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : - HasCondDistrib (Y n) (fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) + (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + HasCondDistrib (Y n) (fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) ((feedbackCondAction env n).prodMkLeft _) P := by rw [← feedback_eq_feedbackCondAction] exact h.hasCondDistrib_feedback n -lemma hasCondDistrib_feedback [IsObliviousEnv env] (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : +lemma hasCondDistrib_feedback [IsObliviousEnv env] (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : HasCondDistrib (Y n) (A n) (feedbackCondAction env n) P := (hasCondDistrib_feedback_history_action h n).comp_right -variable [StandardBorelSpace 𝓐] [Nonempty 𝓐] [StandardBorelSpace 𝓨] [Nonempty 𝓨] +variable [StandardBorelSpace π“ž] [Nonempty π“ž] [StandardBorelSpace 𝓐] [Nonempty 𝓐] + [StandardBorelSpace 𝓨] [Nonempty 𝓨] -/-- The feedback at time `n` is conditionally independent of the history before time `n` -given the action at time `n`. -/ +/-- The feedback at time `n` is conditionally independent of the history before time `n` and of +the observation at time `n`, given the action at time `n`. -/ lemma condIndepFun_feedback_history_action [StandardBorelSpace Ξ©] - [IsObliviousEnv env] (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : - Y n βŸ‚α΅’[A n, h.measurable_action _ ; P] history A Y n := by + [IsObliviousEnv env] (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + Y n βŸ‚α΅’[A n, h.measurable_action _ ; P] (fun Ο‰ ↦ (history O A Y n Ο‰, O n Ο‰)) := by + have hO := h.measurable_obs have hA := h.measurable_action have hY := h.measurable_feedback refine condIndepFun_of_exists_condDistrib_prod_ae_eq_prodMkLeft @@ -105,29 +112,38 @@ lemma condIndepFun_feedback_history_action [StandardBorelSpace Ξ©] exact h.hasCondDistrib_feedback n lemma condIndepFun_feedback_history_action_action [StandardBorelSpace Ξ©] - [IsObliviousEnv env] (h : IsAlgEnvSeq A Y alg env P) (n : β„•) : - Y n βŸ‚α΅’[A n, h.measurable_action n; P] (fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) := by - have h_indep : Y n βŸ‚α΅’[A n, h.measurable_action n; P] history A Y n := - condIndepFun_feedback_history_action h n + [IsObliviousEnv env] (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : + Y n βŸ‚α΅’[A n, h.measurable_action n; P] (fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) := by + have h_indep : Y n βŸ‚α΅’[A n, h.measurable_action n; P] + (fun Ο‰ ↦ (history O A Y n Ο‰, O n Ο‰)) := condIndepFun_feedback_history_action h n + have hO := h.measurable_obs have hA := h.measurable_action have hY := h.measurable_feedback exact h_indep.prod_right (by fun_prop) (by fun_prop) (by fun_prop) end IsObliviousEnv -/-- An oblivious environment, in which the distribution of the next feedback depends only on -the last action, but in a possibly time-dependent manner. -/ +/-- An oblivious environment without observations, in which the distribution of the next feedback +depends only on the last action, but in a possibly time-dependent manner. -/ @[simps] -def obliviousEnv (Ξ½ : β„• β†’ Kernel 𝓐 𝓨) [βˆ€ n, IsMarkovKernel (Ξ½ n)] : Environment 𝓐 𝓨 where +noncomputable +def obliviousEnv (Ξ½ : β„• β†’ Kernel 𝓐 𝓨) [βˆ€ n, IsMarkovKernel (Ξ½ n)] : Environment Unit 𝓐 𝓨 where + obs n := unitObs 𝓐 𝓨 n feedback n := (Ξ½ n).prodMkLeft _ lemma feedback_obliviousEnv (Ξ½ : β„• β†’ Kernel 𝓐 𝓨) [βˆ€ n, IsMarkovKernel (Ξ½ n)] (n : β„•) : (obliviousEnv Ξ½).feedback n = (Ξ½ n).prodMkLeft _ := rfl +@[simp] +lemma obs0_obliviousEnv (Ξ½ : β„• β†’ Kernel 𝓐 𝓨) [βˆ€ n, IsMarkovKernel (Ξ½ n)] : + (obliviousEnv Ξ½).obs0 = Measure.dirac () := rfl + @[simp] lemma Ξ½0_obliviousEnv (Ξ½ : β„• β†’ Kernel 𝓐 𝓨) [βˆ€ n, IsMarkovKernel (Ξ½ n)] : - (obliviousEnv Ξ½).Ξ½0 = Ξ½ 0 := by - rw [Environment.Ξ½0_def, feedback_obliviousEnv, Kernel.sectR_prodMkLeft] + (obliviousEnv Ξ½).Ξ½0 = (Ξ½ 0).prodMkLeft Unit := by + ext p : 1 + rw [Environment.Ξ½0_def, Kernel.comap_apply, feedback_obliviousEnv, Kernel.prodMkLeft_apply, + Kernel.prodMkLeft_apply] instance (Ξ½ : β„• β†’ Kernel 𝓐 𝓨) [βˆ€ n, IsMarkovKernel (Ξ½ n)] : IsObliviousEnv (obliviousEnv Ξ½) where @@ -144,21 +160,32 @@ lemma feedbackCondAction_obliviousEnv (Ξ½ : β„• β†’ Kernel 𝓐 𝓨) [hΞ½ : βˆ€ Β· refine absurd (hΞ½ 0) ?_ simp only [Subsingleton.eq_zero Ξ½, Pi.zero_apply] exact Kernel.not_isMarkovKernel_zero - have : Nonempty (Fin n β†’ 𝓐 Γ— 𝓨) := ⟨fun _ ↦ (h𝓐.some, hR.some)⟩ + have : Nonempty (Hist Unit 𝓐 𝓨 n Γ— Unit) := ⟨(fun _ ↦ ((), h𝓐.some, hR.some), ())⟩ have h_eq := feedback_eq_feedbackCondAction (obliviousEnv Ξ½) n rw [feedback_obliviousEnv, Kernel.prodMkLeft_inj] at h_eq exact h_eq.symm -/-- A stationary environment, in which the distribution of the next feedback depends only on the -last action. -/ -def stationaryEnv (Ξ½ : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ½] : Environment 𝓐 𝓨 := obliviousEnv fun _ ↦ Ξ½ +/-- A stationary environment without observations, in which the distribution of the next feedback +depends only on the last action. -/ +noncomputable +def stationaryEnv (Ξ½ : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ½] : Environment Unit 𝓐 𝓨 := + obliviousEnv fun _ ↦ Ξ½ + +@[simp] +lemma obs_stationaryEnv (Ξ½ : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ½] (n : β„•) : + (stationaryEnv Ξ½).obs n = unitObs 𝓐 𝓨 n := rfl @[simp] lemma feedback_stationaryEnv (Ξ½ : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ½] (n : β„•) : (stationaryEnv Ξ½).feedback n = Ξ½.prodMkLeft _ := rfl @[simp] -lemma Ξ½0_stationaryEnv (Ξ½ : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ½] : (stationaryEnv Ξ½).Ξ½0 = Ξ½ := +lemma obs0_stationaryEnv (Ξ½ : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ½] : + (stationaryEnv Ξ½).obs0 = Measure.dirac () := rfl + +@[simp] +lemma Ξ½0_stationaryEnv (Ξ½ : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ½] : + (stationaryEnv Ξ½).Ξ½0 = Ξ½.prodMkLeft Unit := Ξ½0_obliviousEnv _ instance (Ξ½ : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ½] : IsObliviousEnv (stationaryEnv Ξ½) where @@ -169,27 +196,28 @@ lemma feedbackCondAction_stationaryEnv (Ξ½ : Kernel 𝓐 𝓨) [hΞ½ : IsMarkovKe feedbackCondAction (stationaryEnv Ξ½) n = Ξ½ := feedbackCondAction_obliviousEnv _ _ variable {Ξ© : Type*} {mΞ© : MeasurableSpace Ξ©} - {alg : Algorithm 𝓐 𝓨} {Ξ½ : Kernel 𝓐 𝓨} [IsMarkovKernel Ξ½] - {P : Measure Ξ©} [IsProbabilityMeasure P] {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} + {alg : Algorithm Unit 𝓐 𝓨} {Ξ½ : Kernel 𝓐 𝓨} [IsMarkovKernel Ξ½] + {P : Measure Ξ©} [IsProbabilityMeasure P] + {O : β„• β†’ Ξ© β†’ Unit} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} namespace IsAlgEnvSeq /-- The conditional distribution of the feedback at time `n` given the action at time `n` is `Ξ½ n`. -/ lemma hasCondDistrib_feedback_obliviousEnv {Ξ½ : β„• β†’ Kernel 𝓐 𝓨} [βˆ€ n, IsMarkovKernel (Ξ½ n)] - (h : IsAlgEnvSeq A Y alg (obliviousEnv Ξ½) P) (n : β„•) : + (h : IsAlgEnvSeq O A Y alg (obliviousEnv Ξ½) P) (n : β„•) : HasCondDistrib (Y n) (A n) (Ξ½ n) P := by simpa using IsObliviousEnv.hasCondDistrib_feedback h n /-- The conditional distribution of the feedback at time `n` given the action at time `n` is `Ξ½`. -/ lemma hasCondDistrib_feedback_stationaryEnv - (h : IsAlgEnvSeq A Y alg (stationaryEnv Ξ½) P) (n : β„•) : + (h : IsAlgEnvSeq O A Y alg (stationaryEnv Ξ½) P) (n : β„•) : HasCondDistrib (Y n) (A n) Ξ½ P := hasCondDistrib_feedback_obliviousEnv h n /-- The conditional distribution of the feedback at time `n` given the action at time `n` is `Ξ½`. -/ lemma condDistrib_feedback_stationaryEnv [StandardBorelSpace 𝓨] [Nonempty 𝓨] - (h : IsAlgEnvSeq A Y alg (stationaryEnv Ξ½) P) (n : β„•) : + (h : IsAlgEnvSeq O A Y alg (stationaryEnv Ξ½) P) (n : β„•) : condDistrib (Y n) (A n) P =ᡐ[P.map (A n)] Ξ½ := (hasCondDistrib_feedback_stationaryEnv h n).condDistrib_eq @@ -197,14 +225,15 @@ lemma condDistrib_feedback_stationaryEnv [StandardBorelSpace 𝓨] [Nonempty given the action at time `n`. -/ lemma condIndepFun_feedback_history_action [StandardBorelSpace Ξ©] [StandardBorelSpace 𝓐] [Nonempty 𝓐] [StandardBorelSpace 𝓨] [Nonempty 𝓨] - (h : IsAlgEnvSeq A Y alg (stationaryEnv Ξ½) P) (n : β„•) : - Y n βŸ‚α΅’[A n, h.measurable_action _ ; P] history A Y n := + (h : IsAlgEnvSeq O A Y alg (stationaryEnv Ξ½) P) (n : β„•) : + Y n βŸ‚α΅’[A n, h.measurable_action _ ; P] (fun Ο‰ ↦ (history O A Y n Ο‰, O n Ο‰)) := IsObliviousEnv.condIndepFun_feedback_history_action h n lemma condIndepFun_feedback_history_action_action [StandardBorelSpace Ξ©] [StandardBorelSpace 𝓐] [Nonempty 𝓐] [StandardBorelSpace 𝓨] [Nonempty 𝓨] - (h : IsAlgEnvSeq A Y alg (stationaryEnv Ξ½) P) (n : β„•) : - Y n βŸ‚α΅’[A n, h.measurable_action n; P] (fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) := + (h : IsAlgEnvSeq O A Y alg (stationaryEnv Ξ½) P) (n : β„•) : + Y n βŸ‚α΅’[A n, h.measurable_action n; P] + (fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) := IsObliviousEnv.condIndepFun_feedback_history_action_action h n end IsAlgEnvSeq diff --git a/LeanMachineLearning/SequentialLearning/SumRewards.lean b/LeanMachineLearning/SequentialLearning/SumRewards.lean index b02ad3d3..820cd4ef 100644 --- a/LeanMachineLearning/SequentialLearning/SumRewards.lean +++ b/LeanMachineLearning/SequentialLearning/SumRewards.lean @@ -17,10 +17,11 @@ open MeasureTheory Finset Learning namespace Learning -variable {𝓐 𝓨 Ξ© : Type*} {m𝓐 : MeasurableSpace 𝓐} {m𝓨 : MeasurableSpace 𝓨} {mΞ© : MeasurableSpace Ξ©} +variable {π“ž 𝓐 𝓨 Ξ© : Type*} {mπ“ž : MeasurableSpace π“ž} {m𝓐 : MeasurableSpace 𝓐} + {m𝓨 : MeasurableSpace 𝓨} {mΞ© : MeasurableSpace Ξ©} [DecidableEq 𝓐] [AddCommGroup 𝓨] {P : Measure Ξ©} [IsProbabilityMeasure P] - {A : β„• β†’ Ξ© β†’ 𝓐} {R : β„• β†’ Ξ© β†’ 𝓨} + {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {R : β„• β†’ Ξ© β†’ 𝓨} {a : 𝓐} {m n t : β„•} {Ο‰ : Ξ©} /-- Sum of rewards obtained when pulling action `a` up to time `t` (exclusive). -/ @@ -29,8 +30,8 @@ noncomputable def sumRewards (A : β„• β†’ Ξ© β†’ 𝓐) (R : β„• β†’ Ξ© β†’ 𝓨) /-- Sum of rewards of arm `a` in the history before time `n`. -/ noncomputable -def sumRewards' (n : β„•) (h : Fin n β†’ 𝓐 Γ— 𝓨) (a : 𝓐) := - βˆ‘ s, if (h s).1 = a then (h s).2 else 0 +def sumRewards' (n : β„•) (h : Hist π“ž 𝓐 𝓨 n) (a : 𝓐) := + βˆ‘ s, if (h s).action = a then (h s).feedback else 0 /-- Empirical mean reward obtained when pulling action `a` up to time `t` (exclusive). -/ noncomputable @@ -39,7 +40,7 @@ def empMean (A : β„• β†’ Ξ© β†’ 𝓐) (R : β„• β†’ Ξ© β†’ ℝ) (a : 𝓐) (t : /-- Empirical mean of arm `a` in the history before time `n`. -/ noncomputable -def empMean' (n : β„•) (h : Fin n β†’ 𝓐 Γ— ℝ) (a : 𝓐) := +def empMean' (n : β„•) (h : Hist π“ž 𝓐 ℝ n) (a : 𝓐) := sumRewards' n h a / pullCount' n h a @[simp] @@ -86,23 +87,23 @@ lemma sum_rewardByCount_eq_sumRewards {R : β„• β†’ Ξ© β†’ 𝓨} (a : 𝓐) (t : rwa [pullCount_eq_pullCount_of_action_ne hta, sum_range_succ, ite_eq_right hta, add_zero] lemma sumRewards_eq_sumRewards' {R : β„• β†’ Ξ© β†’ 𝓨} {n : β„•} {Ο‰ : Ξ©} : - sumRewards A R a n Ο‰ = sumRewards' n (fun i ↦ (A i Ο‰, R i Ο‰)) a := + sumRewards A R a n Ο‰ = sumRewards' n (history O A R n Ο‰) a := (Fin.sum_univ_eq_sum_range (fun i ↦ if A i Ο‰ = a then R i Ο‰ else 0) n).symm /-- `sumRewards A R a n` is a function of the history before time `n`. -/ lemma sumRewards_eq_comp_history {R : β„• β†’ Ξ© β†’ 𝓨} (a : 𝓐) (n : β„•) : - sumRewards A R a n = (fun h : Fin n β†’ 𝓐 Γ— 𝓨 ↦ sumRewards' n h a) ∘ history A R n := by + sumRewards A R a n = (fun h : Hist π“ž 𝓐 𝓨 n ↦ sumRewards' n h a) ∘ history O A R n := by ext Ο‰ exact sumRewards_eq_sumRewards' lemma empMean_eq_empMean' {R : β„• β†’ Ξ© β†’ ℝ} {n : β„•} {Ο‰ : Ξ©} : - empMean A R a n Ο‰ = empMean' n (fun i ↦ (A i Ο‰, R i Ο‰)) a := by + empMean A R a n Ο‰ = empMean' n (history O A R n Ο‰) a := by unfold empMean empMean' - rw [sumRewards_eq_sumRewards', pullCount_eq_pullCount'] + rw [sumRewards_eq_sumRewards' (O := O), pullCount_eq_pullCount' (O := O)] /-- `empMean A R a n` is a function of the history before time `n`. -/ lemma empMean_eq_comp_history {R : β„• β†’ Ξ© β†’ ℝ} (a : 𝓐) (n : β„•) : - empMean A R a n = (fun h : Fin n β†’ 𝓐 Γ— ℝ ↦ empMean' n h a) ∘ history A R n := by + empMean A R a n = (fun h : Hist π“ž 𝓐 ℝ n ↦ empMean' n h a) ∘ history O A R n := by ext Ο‰ exact empMean_eq_empMean' @@ -158,37 +159,38 @@ lemma measurable_uncurry_empMean_comp [Countable 𝓐] [MeasurableSingletonClass @[fun_prop] lemma measurable_sumRewards' [MeasurableSingletonClass 𝓐] [MeasurableAddβ‚‚ 𝓨] (n : β„•) (a : 𝓐) : - Measurable (sumRewards' (𝓨 := 𝓨) n Β· a) := by + Measurable (sumRewards' (π“ž := π“ž) (𝓨 := 𝓨) n Β· a) := by simp_rw [sumRewards'] - have h_meas s : Measurable (fun (h : Fin n β†’ 𝓐 Γ— 𝓨) ↦ if (h s).1 = a then (h s).2 else 0) := by + have h_meas s : Measurable + (fun (h : Hist π“ž 𝓐 𝓨 n) ↦ if (h s).action = a then (h s).feedback else 0) := by refine Measurable.ite ?_ (by fun_prop) (by fun_prop) exact (measurableSet_singleton _).preimage (by fun_prop) fun_prop @[fun_prop] lemma measurable_uncurry_sumRewards' [MeasurableEq 𝓐] [MeasurableAddβ‚‚ 𝓨] (n : β„•) : - Measurable (fun p : (Fin n β†’ 𝓐 Γ— 𝓨) Γ— 𝓐 ↦ sumRewards' n p.1 p.2) := by + Measurable (fun p : Hist π“ž 𝓐 𝓨 n Γ— 𝓐 ↦ sumRewards' n p.1 p.2) := by simp_rw [sumRewards'] - have h_meas s : Measurable (fun p : (Fin n β†’ 𝓐 Γ— 𝓨) Γ— 𝓐 ↦ - if (p.1 s).1 = p.2 then (p.1 s).2 else 0) := by + have h_meas s : Measurable (fun p : Hist π“ž 𝓐 𝓨 n Γ— 𝓐 ↦ + if (p.1 s).action = p.2 then (p.1 s).feedback else 0) := by refine Measurable.ite ?_ (by fun_prop) (by fun_prop) exact measurableSet_eq_fun (by fun_prop) (by fun_prop) fun_prop @[fun_prop] lemma measurable_empMean' [MeasurableSingletonClass 𝓐] (n : β„•) (a : 𝓐) : - Measurable (empMean' n Β· a) := by unfold empMean'; fun_prop + Measurable (empMean' (π“ž := π“ž) n Β· a) := by unfold empMean'; fun_prop @[fun_prop] lemma measurable_uncurry_empMean' [MeasurableEq 𝓐] (n : β„•) : - Measurable (fun p : (Fin n β†’ 𝓐 Γ— ℝ) Γ— 𝓐 ↦ empMean' n p.1 p.2) := by unfold empMean'; fun_prop + Measurable (fun p : Hist π“ž 𝓐 ℝ n Γ— 𝓐 ↦ empMean' n p.1 p.2) := by unfold empMean'; fun_prop variable [MeasurableSingletonClass 𝓐] lemma IsAlgEnvSeq.isStronglyPredictable_sumRewards {𝓨 : Type*} {_ : MeasurableSpace 𝓨} [NormedAddCommGroup 𝓨] [OpensMeasurableSpace 𝓨] [SecondCountableTopology 𝓨] - {R : β„• β†’ Ξ© β†’ 𝓨} {alg : Algorithm 𝓐 𝓨} {env : Environment 𝓐 𝓨} - (h : IsAlgEnvSeq A R alg env P) (a : 𝓐) : + {R : β„• β†’ Ξ© β†’ 𝓨} {alg : Algorithm π“ž 𝓐 𝓨} {env : Environment π“ž 𝓐 𝓨} + (h : IsAlgEnvSeq O A R alg env P) (a : 𝓐) : IsStronglyPredictable h.filtration (sumRewards A R a) := by rw [IsStronglyPredictable.iff_measurable_add_one] constructor @@ -206,8 +208,8 @@ lemma IsAlgEnvSeq.isStronglyPredictable_sumRewards {𝓨 : Type*} {_ : Measurabl lemma IsAlgEnvSeq.stronglyAdapted_sumRewards_add_one {𝓨 : Type*} {_ : MeasurableSpace 𝓨} [NormedAddCommGroup 𝓨] [OpensMeasurableSpace 𝓨] [SecondCountableTopology 𝓨] - {R : β„• β†’ Ξ© β†’ 𝓨} {alg : Algorithm 𝓐 𝓨} {env : Environment 𝓐 𝓨} - (h : IsAlgEnvSeq A R alg env P) (a : 𝓐) : + {R : β„• β†’ Ξ© β†’ 𝓨} {alg : Algorithm π“ž 𝓐 𝓨} {env : Environment π“ž 𝓐 𝓨} + (h : IsAlgEnvSeq O A R alg env P) (a : 𝓐) : StronglyAdapted h.filtration (fun n ↦ sumRewards A R a (n + 1)) := by have h_predictable := h.isStronglyPredictable_sumRewards a rw [IsStronglyPredictable.iff_measurable_add_one] at h_predictable @@ -216,14 +218,14 @@ lemma IsAlgEnvSeq.stronglyAdapted_sumRewards_add_one {𝓨 : Type*} {_ : Measura -- TODO: give a direct proof, without a topology lemma IsAlgEnvSeq.adapted_sumRewards_add_one {𝓨 : Type*} {_ : MeasurableSpace 𝓨} [NormedAddCommGroup 𝓨] [BorelSpace 𝓨] [SecondCountableTopology 𝓨] - {R : β„• β†’ Ξ© β†’ 𝓨} {alg : Algorithm 𝓐 𝓨} {env : Environment 𝓐 𝓨} - (h : IsAlgEnvSeq A R alg env P) (a : 𝓐) : + {R : β„• β†’ Ξ© β†’ 𝓨} {alg : Algorithm π“ž 𝓐 𝓨} {env : Environment π“ž 𝓐 𝓨} + (h : IsAlgEnvSeq O A R alg env P) (a : 𝓐) : Adapted h.filtration (fun n ↦ sumRewards A R a (n + 1)) := (h.stronglyAdapted_sumRewards_add_one a).adapted lemma IsAlgEnvSeq.isStronglyPredictable_empMean {R' : β„• β†’ Ξ© β†’ ℝ} - {alg : Algorithm 𝓐 ℝ} {env : Environment 𝓐 ℝ} - (h : IsAlgEnvSeq A R' alg env P) (a : 𝓐) : + {alg : Algorithm π“ž 𝓐 ℝ} {env : Environment π“ž 𝓐 ℝ} + (h : IsAlgEnvSeq O A R' alg env P) (a : 𝓐) : IsStronglyPredictable h.filtration (empMean A R' a) := by unfold empMean refine StronglyMeasurable.div ?_ ?_ @@ -232,16 +234,16 @@ lemma IsAlgEnvSeq.isStronglyPredictable_empMean {R' : β„• β†’ Ξ© β†’ ℝ} fun_prop lemma IsAlgEnvSeq.stronglyAdapted_empMean_add_one - {R' : β„• β†’ Ξ© β†’ ℝ} {alg : Algorithm 𝓐 ℝ} {env : Environment 𝓐 ℝ} - (h : IsAlgEnvSeq A R' alg env P) (a : 𝓐) : + {R' : β„• β†’ Ξ© β†’ ℝ} {alg : Algorithm π“ž 𝓐 ℝ} {env : Environment π“ž 𝓐 ℝ} + (h : IsAlgEnvSeq O A R' alg env P) (a : 𝓐) : StronglyAdapted h.filtration (fun n ↦ empMean A R' a (n + 1)) := by have h_predictable := h.isStronglyPredictable_empMean a rw [IsStronglyPredictable.iff_measurable_add_one] at h_predictable exact h_predictable.2 lemma IsAlgEnvSeq.adapted_empMean_add_one {R' : β„• β†’ Ξ© β†’ ℝ} - {alg : Algorithm 𝓐 ℝ} {env : Environment 𝓐 ℝ} - (h : IsAlgEnvSeq A R' alg env P) (a : 𝓐) : + {alg : Algorithm π“ž 𝓐 ℝ} {env : Environment π“ž 𝓐 ℝ} + (h : IsAlgEnvSeq O A R' alg env P) (a : 𝓐) : Adapted h.filtration (fun n ↦ empMean A R' a (n + 1)) := (h.stronglyAdapted_empMean_add_one a).adapted From 7a7a8fe71da5618eaf131bf142a1a268b2c055c6 Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Fri, 28 Aug 2026 13:00:01 +0200 Subject: [PATCH 02/21] refactor Bayesian stuff --- LeanMachineLearning.lean | 1 + .../Probability/HasCondDistrib.lean | 22 ++ .../Algorithms/Regret/BayesRegretTS.lean | 2 +- .../Online/Bandit/SumRewards.lean | 2 +- .../SequentialLearning/Algorithm.lean | 46 ++- .../AlgorithmDensityBayes.lean | 3 +- .../SequentialLearning/Announce.lean | 337 ++++++++++++++++ .../BayesStationaryEnv.lean | 362 +++++++++++------- 8 files changed, 615 insertions(+), 160 deletions(-) create mode 100644 LeanMachineLearning/SequentialLearning/Announce.lean diff --git a/LeanMachineLearning.lean b/LeanMachineLearning.lean index 070ce824..4a508bf3 100644 --- a/LeanMachineLearning.lean +++ b/LeanMachineLearning.lean @@ -35,6 +35,7 @@ public import LeanMachineLearning.SequentialLearning.ActionIndicator public import LeanMachineLearning.SequentialLearning.Algorithm public import LeanMachineLearning.SequentialLearning.AlgorithmDensity public import LeanMachineLearning.SequentialLearning.AlgorithmDensityBayes +public import LeanMachineLearning.SequentialLearning.Announce public import LeanMachineLearning.SequentialLearning.Algorithms.RandomSampling.Basic public import LeanMachineLearning.SequentialLearning.Algorithms.RandomSampling.Tendsto public import LeanMachineLearning.SequentialLearning.Algorithms.RoundRobin diff --git a/LeanMachineLearning/ForMathlib/Probability/HasCondDistrib.lean b/LeanMachineLearning/ForMathlib/Probability/HasCondDistrib.lean index a933a6d9..c259e17e 100644 --- a/LeanMachineLearning/ForMathlib/Probability/HasCondDistrib.lean +++ b/LeanMachineLearning/ForMathlib/Probability/HasCondDistrib.lean @@ -130,6 +130,17 @@ lemma HasLaw.prod_of_hasCondDistrib {P : Measure Ξ²} HasLaw (fun Ο‰ ↦ (X Ο‰, Y Ο‰)) (P βŠ—β‚˜ ΞΊ) ΞΌ := ⟨by fun_prop, by rw [h2.map_eq, h1.map_eq]⟩ +/-- `HasCondDistrib` only depends on the almost everywhere equivalence classes of the two random +variables. -/ +lemma HasCondDistrib.congr {X' : Ξ± β†’ Ξ²} {Y' : Ξ± β†’ Ξ©} (h : HasCondDistrib Y X ΞΊ ΞΌ) + (hX : X' =ᡐ[ΞΌ] X) (hY : Y' =ᡐ[ΞΌ] Y) : + HasCondDistrib Y' X' ΞΊ ΞΌ := by + have h_pair : (fun a ↦ (X' a, Y' a)) =ᡐ[ΞΌ] fun a ↦ (X a, Y a) := by + filter_upwards [hX, hY] with a h1 h2 + rw [h1, h2] + exact ⟨h.aemeasurable.congr h_pair.symm, by rw [Measure.map_congr h_pair, + Measure.map_congr hX, h.map_eq]⟩ + lemma HasCondDistrib.hasLaw_comp [SFinite ΞΌ] [IsSFiniteKernel ΞΊ] (h : HasCondDistrib Y X ΞΊ ΞΌ) : HasLaw Y (ΞΊ βˆ˜β‚˜ (ΞΌ.map X)) ΞΌ := by refine ⟨by fun_prop, ?_⟩ @@ -145,6 +156,17 @@ lemma HasCondDistrib.prod {Z : Ξ± β†’ Ξ©'} {Ξ· : Kernel (Ξ² Γ— Ξ©) Ξ©'} AEMeasurable.map_map_of_aemeasurable (by fun_prop) (by fun_prop)] rfl +/-- A random variable that is almost surely a measurable function of `X` has the corresponding +deterministic conditional distribution given `X`. -/ +lemma hasCondDistrib_deterministic [SFinite ΞΌ] {f : Ξ² β†’ Ξ©} (hf : Measurable f) + (hX : AEMeasurable X ΞΌ) (hY : Y =ᡐ[ΞΌ] f ∘ X) : + HasCondDistrib Y X (Kernel.deterministic f hf) ΞΌ := by + have h : HasCondDistrib (f ∘ X) X (Kernel.deterministic f hf) ΞΌ := by + refine ⟨hX.prodMk (hf.comp_aemeasurable hX), ?_⟩ + rw [Measure.compProd_deterministic, AEMeasurable.map_map_of_aemeasurable (by fun_prop) hX] + rfl + exact HasCondDistrib.congr h .rfl hY + lemma ae_eq_of_hasCondDistrib_deterministic [MeasurableEq Ξ©] [SFinite ΞΌ] {f : Ξ² β†’ Ξ©} (hf : Measurable f) (hX : AEMeasurable X ΞΌ) (hY : AEMeasurable Y ΞΌ) (h : HasCondDistrib Y X (Kernel.deterministic f hf) ΞΌ) : diff --git a/LeanMachineLearning/Online/Bandit/Algorithms/Regret/BayesRegretTS.lean b/LeanMachineLearning/Online/Bandit/Algorithms/Regret/BayesRegretTS.lean index 7b1f5c6c..a9e39543 100644 --- a/LeanMachineLearning/Online/Bandit/Algorithms/Regret/BayesRegretTS.lean +++ b/LeanMachineLearning/Online/Bandit/Algorithms/Regret/BayesRegretTS.lean @@ -200,7 +200,7 @@ variable [Nonempty (Fin K)] variable [MeasurableSpace Ξ©] variable {𝓔 : Type*} [MeasurableSpace 𝓔] variable {E : Ξ© β†’ 𝓔} -variable {Q : Measure 𝓔} {ΞΊ : Kernel (𝓔 Γ— Fin K) ℝ} [IsMarkovKernel ΞΊ] +variable {Q : Measure 𝓔} [IsProbabilityMeasure Q] {ΞΊ : Kernel (𝓔 Γ— Fin K) ℝ} [IsMarkovKernel ΞΊ] variable {P : Measure Ξ©} [IsProbabilityMeasure P] lemma integral_sum_range_actionMean_bestAction_sub_ucb_bestAction_le diff --git a/LeanMachineLearning/Online/Bandit/SumRewards.lean b/LeanMachineLearning/Online/Bandit/SumRewards.lean index 764de6ee..1719cfd0 100644 --- a/LeanMachineLearning/Online/Bandit/SumRewards.lean +++ b/LeanMachineLearning/Online/Bandit/SumRewards.lean @@ -675,7 +675,7 @@ namespace Learning.IsBayesAlgEnvSeq variable {𝓔 Ξ© : Type*} [MeasurableSpace 𝓔] [MeasurableSpace Ξ©] variable {K : β„•} [Nonempty (Fin K)] -variable {Q : Measure 𝓔} {ΞΊ : Kernel (𝓔 Γ— Fin K) ℝ} [IsMarkovKernel ΞΊ] +variable {Q : Measure 𝓔} [IsProbabilityMeasure Q] {ΞΊ : Kernel (𝓔 Γ— Fin K) ℝ} [IsMarkovKernel ΞΊ] variable {alg : Algorithm Unit (Fin K) ℝ} variable {E : Ξ© β†’ 𝓔} {A : β„• β†’ Ξ© β†’ (Fin K)} {R : β„• β†’ Ξ© β†’ ℝ} variable {P : Measure Ξ©} [IsProbabilityMeasure P] diff --git a/LeanMachineLearning/SequentialLearning/Algorithm.lean b/LeanMachineLearning/SequentialLearning/Algorithm.lean index e317d6d0..87417109 100644 --- a/LeanMachineLearning/SequentialLearning/Algorithm.lean +++ b/LeanMachineLearning/SequentialLearning/Algorithm.lean @@ -38,8 +38,6 @@ applied to the empty history (the unique element of `Hist π“ž 𝓐 𝓨 0`). probability space `(Ξ©, P)`. * `IsAlgEnvSeqUntil O A Y alg env P N`: `O`, `A` and `Y` form an algorithm-environment sequence for the times `n < N`. -* `prodLeft alg`: an `Algorithm π“ž 𝓐 (𝓧 Γ— 𝓨)` obtained from an algorithm `alg : Algorithm π“ž 𝓐 𝓨` by - ignoring the `𝓧` component of each feedback. -/ @@ -158,20 +156,6 @@ lemma Algorithm.policy_zero (alg : Algorithm π“ž 𝓐 𝓨) (h : Hist π“ž 𝓐 rw [Unique.eq_default h] rfl -/-- An algorithm with feedback in `𝓧 Γ— 𝓨` obtained from an algorithm with feedback in `𝓨` -by ignoring the `𝓧` component of each feedback. -/ -@[simps] -def Algorithm.prodLeft (𝓧 : Type*) [MeasurableSpace 𝓧] (alg : Algorithm π“ž 𝓐 𝓨) : - Algorithm π“ž 𝓐 (𝓧 Γ— 𝓨) where - policy n := (alg.policy n).comap - (fun p ↦ (fun i ↦ ((p.1 i).obs, (p.1 i).action, (p.1 i).feedback.2), p.2)) (by fun_prop) - -@[simp] -lemma Algorithm.prodLeft_p0 (𝓧 : Type*) [MeasurableSpace 𝓧] (alg : Algorithm π“ž 𝓐 𝓨) : - (alg.prodLeft 𝓧).p0 = alg.p0 := by - ext o : 1 - rw [p0_apply, prodLeft_policy, Kernel.comap_apply, policy_zero, p0_apply] - /-- Distribution of the first feedback given the first observation and action: the feedback kernel at time `0` applied to the empty history. -/ noncomputable def Environment.Ξ½0 (env : Environment π“ž 𝓐 𝓨) : Kernel (π“ž Γ— 𝓐) 𝓨 := @@ -262,6 +246,16 @@ lemma measurable_history (hO : βˆ€ n, Measurable (O n)) (hA : βˆ€ n, Measurable unfold history fun_prop +lemma history_congr {O' : β„• β†’ Ξ© β†’ π“ž} {A' : β„• β†’ Ξ© β†’ 𝓐} {Y' : β„• β†’ Ξ© β†’ 𝓨} {P : Measure Ξ©} + (hO : βˆ€ n, O' n =ᡐ[P] O n) (hA : βˆ€ n, A' n =ᡐ[P] A n) (hY : βˆ€ n, Y' n =ᡐ[P] Y n) (n : β„•) : + history O' A' Y' n =ᡐ[P] history O A Y n := by + have h : βˆ€α΅ Ο‰ βˆ‚P, βˆ€ i : Fin n, (O' i Ο‰ = O i Ο‰ ∧ A' i Ο‰ = A i Ο‰) ∧ Y' i Ο‰ = Y i Ο‰ := by + rw [ae_all_iff] + exact fun i ↦ ((hO i).and (hA i)).and (hY i) + filter_upwards [h] with Ο‰ hΟ‰ + funext i + rw [history_apply, history_apply, (hΟ‰ i).1.1, (hΟ‰ i).1.2, (hΟ‰ i).2] + lemma eval_comp_history (n : β„•) : (fun x ↦ x (Fin.last n)) ∘ (history O A Y (n + 1)) = step O A Y n := rfl @@ -356,6 +350,26 @@ lemma IsAlgEnvSeq.isAlgEnvSeqUntil (h : IsAlgEnvSeq O A Y alg env P) (N : β„•) : hasCondDistrib_action n _ := h.hasCondDistrib_action n hasCondDistrib_feedback n _ := h.hasCondDistrib_feedback n +/-- `IsAlgEnvSeq` only depends on the almost everywhere equivalence classes of the processes. -/ +lemma IsAlgEnvSeq.congr {O' : β„• β†’ Ξ© β†’ π“ž} {A' : β„• β†’ Ξ© β†’ 𝓐} {Y' : β„• β†’ Ξ© β†’ 𝓨} + (h : IsAlgEnvSeq O A Y alg env P) + (hO' : βˆ€ n, Measurable (O' n)) (hA' : βˆ€ n, Measurable (A' n)) (hY' : βˆ€ n, Measurable (Y' n)) + (hO : βˆ€ n, O' n =ᡐ[P] O n) (hA : βˆ€ n, A' n =ᡐ[P] A n) (hY : βˆ€ n, Y' n =ᡐ[P] Y n) : + IsAlgEnvSeq O' A' Y' alg env P where + measurable_obs := hO' + measurable_action := hA' + measurable_feedback := hY' + hasCondDistrib_obs n := + HasCondDistrib.congr (h.hasCondDistrib_obs n) (history_congr hO hA hY n) (hO n) + hasCondDistrib_action n := by + refine HasCondDistrib.congr (h.hasCondDistrib_action n) ?_ (hA n) + filter_upwards [history_congr hO hA hY n, hO n] with Ο‰ h1 h2 + rw [h1, h2] + hasCondDistrib_feedback n := by + refine HasCondDistrib.congr (h.hasCondDistrib_feedback n) ?_ (hY n) + filter_upwards [history_congr hO hA hY n, hO n, hA n] with Ο‰ h1 h2 h3 + rw [h1, h2, h3] + lemma isAlgEnvSeq_iff_forall_isAlgEnvSeqUntil : IsAlgEnvSeq O A Y alg env P ↔ βˆ€ N, IsAlgEnvSeqUntil O A Y alg env P N where mp h N := h.isAlgEnvSeqUntil N diff --git a/LeanMachineLearning/SequentialLearning/AlgorithmDensityBayes.lean b/LeanMachineLearning/SequentialLearning/AlgorithmDensityBayes.lean index 41235288..e345f31f 100644 --- a/LeanMachineLearning/SequentialLearning/AlgorithmDensityBayes.lean +++ b/LeanMachineLearning/SequentialLearning/AlgorithmDensityBayes.lean @@ -43,7 +43,7 @@ namespace IsBayesAlgEnvSeq variable {𝓐 𝓨 : Type*} [MeasurableSpace 𝓐] [MeasurableSpace 𝓨] variable {𝓔 : Type*} [MeasurableSpace 𝓔] variable [StandardBorelSpace 𝓐] [Nonempty 𝓐] [StandardBorelSpace 𝓨] [Nonempty 𝓨] -variable {Q : Measure 𝓔} +variable {Q : Measure 𝓔} [IsProbabilityMeasure Q] variable {ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨} [IsMarkovKernel ΞΊ] variable {Ξ© : Type*} [MeasurableSpace Ξ©] @@ -87,7 +87,6 @@ lemma hasLaw_history_withDensity (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) ← hβ‚€.hasLaw_env.map_eq, condDistrib_comp_map hEβ‚€.aemeasurable (by fun_prop)] variable [StandardBorelSpace 𝓔] [Nonempty 𝓔] -variable [IsProbabilityMeasure Q] lemma hasCondDistrib_env_history (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (hβ‚€ : IsBayesAlgEnvSeq Q ΞΊ algβ‚€ Eβ‚€ Aβ‚€ Yβ‚€ Pβ‚€) (hc : alg β‰ͺₐ algβ‚€) (n : β„•) : diff --git a/LeanMachineLearning/SequentialLearning/Announce.lean b/LeanMachineLearning/SequentialLearning/Announce.lean new file mode 100644 index 00000000..8c346371 --- /dev/null +++ b/LeanMachineLearning/SequentialLearning/Announce.lean @@ -0,0 +1,337 @@ +/- +Copyright (c) 2026 RΓ©my Degenne. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: RΓ©my Degenne +-/ +module + +public import LeanMachineLearning.SequentialLearning.IonescuTulceaSpace + +/-! +# Announced variables + +A hidden variable of one of the two players (memory or sampled index of the algorithm, parameter of +the environment) is modelled by making it part of that player's move, while the other player is +transported so as to ignore it: + +* the algorithm announces a variable of type `𝓩`: it is an `Algorithm π“ž (𝓩 Γ— 𝓐) 𝓨` that runs + against `env.comapAction Prod.snd`, for an `env : Environment π“ž 𝓐 𝓨`; +* the environment announces a variable of type `𝓔`: it is an `Environment (𝓔 Γ— π“ž) 𝓐 𝓨` that runs + against `alg.comapObs Prod.snd`, for an `alg : Algorithm π“ž 𝓐 𝓨`. + +In both cases the announced variable is an honest random variable of the run, and the player that +ignores it satisfies the conditional distribution properties of a run of the un-announced +interaction: this is the content of `IsAlgEnvSeq.hasCondDistrib_action_comapObs` (the algorithm +does not use the announced variable) and of `IsAlgEnvSeq.hasCondDistrib_obs_comapAction` and +`IsAlgEnvSeq.hasCondDistrib_feedback_comapAction` (the environment does not use it). +The law of the observable trajectory is the image of the law of the full trajectory under the map +that forgets the announced variable. + +## Main definitions + +* `Round.map fo fa fy`, `Hist.map fo fa fy`, `Traj.map fo fa fy`: round-wise transport of a round, + a history and a trajectory along maps of the observation, the action and the feedback, with the + special cases `mapObs`, `mapAction` and `mapFeedback` that transport a single component. +* `Algorithm.comapObs alg f`: the algorithm that sees `f o` when the observation is `o`, both in + the current round and in the past rounds. +* `Algorithm.comapFeedback alg g`: the algorithm that sees `g y` when the feedback of a past round + is `y`. +* `Environment.comapAction env f`: the environment that reads `f a` when the algorithm plays `a`, + both in the current round and in the past rounds. + +## Main statements + +* `IsAlgEnvSeq.hasCondDistrib_action_comapObs`, `IsAlgEnvSeq.hasCondDistrib_action_comapFeedback`: + in a run of `alg.comapObs f` (resp. `alg.comapFeedback g`) against any environment, the + conditional distribution of the action given the transported history and the transported + observation is `alg.policy n`. +* `IsAlgEnvSeq.hasCondDistrib_obs_comapAction`, `IsAlgEnvSeq.hasCondDistrib_feedback_comapAction`: + in a run against `env.comapAction f`, the observations and feedbacks have the conditional + distributions of a run of `env` on the transported actions. +* `IsAlgEnvSeq.map_trajectory_comapObs`, `IsAlgEnvSeq.map_trajectory_comapFeedback`, + `IsAlgEnvSeq.map_trajectory_comapAction`: the law of the trajectory that a player sees is the + image of `trajMeasure` under the forgetful map. + +-/ + +@[expose] public section + +open MeasureTheory ProbabilityTheory + +namespace Learning + +variable {π“ž π“ž' 𝓐 𝓐' 𝓨 𝓨' Ξ© : Type*} + {mπ“ž : MeasurableSpace π“ž} {mπ“ž' : MeasurableSpace π“ž'} + {m𝓐 : MeasurableSpace 𝓐} {m𝓐' : MeasurableSpace 𝓐'} + {m𝓨 : MeasurableSpace 𝓨} {m𝓨' : MeasurableSpace 𝓨'} + {mΞ© : MeasurableSpace Ξ©} + {fo : π“ž β†’ π“ž'} {fa : 𝓐 β†’ 𝓐'} {fy : 𝓨 β†’ 𝓨'} + +section Map + +/-- Transport a round along maps of the observation, the action and the feedback. -/ +def Round.map (fo : π“ž β†’ π“ž') (fa : 𝓐 β†’ 𝓐') (fy : 𝓨 β†’ 𝓨') (r : Round π“ž 𝓐 𝓨) : Round π“ž' 𝓐' 𝓨' := + (fo r.obs, fa r.action, fy r.feedback) + +/-- Transport a history round-wise. -/ +def Hist.map (fo : π“ž β†’ π“ž') (fa : 𝓐 β†’ 𝓐') (fy : 𝓨 β†’ 𝓨') {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) : + Hist π“ž' 𝓐' 𝓨' n := + fun i ↦ Round.map fo fa fy (h i) + +/-- Transport a trajectory round-wise. -/ +def Traj.map (fo : π“ž β†’ π“ž') (fa : 𝓐 β†’ 𝓐') (fy : 𝓨 β†’ 𝓨') (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : + β„• β†’ Round π“ž' 𝓐' 𝓨' := + fun n ↦ Round.map fo fa fy (Ο„ n) + +@[simp] lemma Round.obs_map (r : Round π“ž 𝓐 𝓨) : (Round.map fo fa fy r).obs = fo r.obs := rfl +@[simp] lemma Round.action_map (r : Round π“ž 𝓐 𝓨) : + (Round.map fo fa fy r).action = fa r.action := rfl +@[simp] lemma Round.feedback_map (r : Round π“ž 𝓐 𝓨) : + (Round.map fo fa fy r).feedback = fy r.feedback := rfl + +@[simp] lemma Hist.map_apply {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) (i : Fin n) : + Hist.map fo fa fy h i = Round.map fo fa fy (h i) := rfl + +@[simp] lemma Traj.map_apply (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) (n : β„•) : + Traj.map fo fa fy Ο„ n = Round.map fo fa fy (Ο„ n) := rfl + +@[fun_prop] +lemma Round.measurable_map (hfo : Measurable fo) (hfa : Measurable fa) (hfy : Measurable fy) : + Measurable (Round.map fo fa fy) := by + unfold Round.map + fun_prop + +@[fun_prop] +lemma Hist.measurable_map (hfo : Measurable fo) (hfa : Measurable fa) (hfy : Measurable fy) + (n : β„•) : + Measurable (Hist.map fo fa fy (n := n)) := by + unfold Hist.map + fun_prop + +@[fun_prop] +lemma Traj.measurable_map (hfo : Measurable fo) (hfa : Measurable fa) (hfy : Measurable fy) : + Measurable (Traj.map fo fa fy) := by + unfold Traj.map + fun_prop + +/-- Transport the observations of a round. -/ +abbrev Round.mapObs (f : π“ž β†’ π“ž') (r : Round π“ž 𝓐 𝓨) : Round π“ž' 𝓐 𝓨 := Round.map f id id r + +/-- Transport the observations of a history. -/ +abbrev Hist.mapObs (f : π“ž β†’ π“ž') {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) : Hist π“ž' 𝓐 𝓨 n := + Hist.map f id id h + +/-- Transport the observations of a trajectory. -/ +abbrev Traj.mapObs (f : π“ž β†’ π“ž') (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : β„• β†’ Round π“ž' 𝓐 𝓨 := Traj.map f id id Ο„ + +/-- Transport the actions of a round. -/ +abbrev Round.mapAction (f : 𝓐 β†’ 𝓐') (r : Round π“ž 𝓐 𝓨) : Round π“ž 𝓐' 𝓨 := Round.map id f id r + +/-- Transport the actions of a history. -/ +abbrev Hist.mapAction (f : 𝓐 β†’ 𝓐') {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) : Hist π“ž 𝓐' 𝓨 n := + Hist.map id f id h + +/-- Transport the actions of a trajectory. -/ +abbrev Traj.mapAction (f : 𝓐 β†’ 𝓐') (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : β„• β†’ Round π“ž 𝓐' 𝓨 := + Traj.map id f id Ο„ + +/-- Transport the feedback of a round. -/ +abbrev Round.mapFeedback (f : 𝓨 β†’ 𝓨') (r : Round π“ž 𝓐 𝓨) : Round π“ž 𝓐 𝓨' := Round.map id id f r + +/-- Transport the feedback of a history. -/ +abbrev Hist.mapFeedback (f : 𝓨 β†’ 𝓨') {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) : Hist π“ž 𝓐 𝓨' n := + Hist.map id id f h + +/-- Transport the feedback of a trajectory. -/ +abbrev Traj.mapFeedback (f : 𝓨 β†’ 𝓨') (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : β„• β†’ Round π“ž 𝓐 𝓨' := + Traj.map id id f Ο„ + +variable {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} + +lemma history_map (n : β„•) : + history (fun n Ο‰ ↦ fo (O n Ο‰)) (fun n Ο‰ ↦ fa (A n Ο‰)) (fun n Ο‰ ↦ fy (Y n Ο‰)) n + = Hist.map fo fa fy ∘ history O A Y n := rfl + +lemma trajectory_map : + trajectory (fun n Ο‰ ↦ fo (O n Ο‰)) (fun n Ο‰ ↦ fa (A n Ο‰)) (fun n Ο‰ ↦ fy (Y n Ο‰)) + = Traj.map fo fa fy ∘ trajectory O A Y := rfl + +end Map + +section Comap + +/-- The algorithm that sees `f o` when the observation is `o`, both in the current round and in the +past rounds. -/ +def Algorithm.comapObs (alg : Algorithm π“ž 𝓐 𝓨) (f : π“ž' β†’ π“ž) + (hf : Measurable f := by fun_prop) : Algorithm π“ž' 𝓐 𝓨 where + policy n := (alg.policy n).comap (fun p ↦ (Hist.mapObs f p.1, f p.2)) (by fun_prop) + +@[simp] +lemma Algorithm.policy_comapObs (alg : Algorithm π“ž 𝓐 𝓨) (f : π“ž' β†’ π“ž) (hf : Measurable f) (n : β„•) : + (alg.comapObs f hf).policy n + = (alg.policy n).comap (fun p ↦ (Hist.mapObs f p.1, f p.2)) (by fun_prop) := rfl + +@[simp] +lemma Algorithm.p0_comapObs (alg : Algorithm π“ž 𝓐 𝓨) (f : π“ž' β†’ π“ž) (hf : Measurable f) : + (alg.comapObs f hf).p0 = alg.p0.comap f hf := by + ext o : 1 + rw [p0_apply, policy_comapObs, Kernel.comap_apply, alg.policy_zero, Kernel.comap_apply] + +/-- The algorithm that sees `g y` when the feedback of a past round is `y`. Together with +`Algorithm.comapObs`, this describes an algorithm that only sees a summary of each past round: +bandit feedback extracted from a loss vector, or an algorithm that ignores a variable that the +environment announces in the feedback. -/ +def Algorithm.comapFeedback (alg : Algorithm π“ž 𝓐 𝓨) (g : 𝓨' β†’ 𝓨) + (hg : Measurable g := by fun_prop) : Algorithm π“ž 𝓐 𝓨' where + policy n := (alg.policy n).comap (fun p ↦ (Hist.mapFeedback g p.1, p.2)) (by fun_prop) + +@[simp] +lemma Algorithm.policy_comapFeedback (alg : Algorithm π“ž 𝓐 𝓨) (g : 𝓨' β†’ 𝓨) (hg : Measurable g) + (n : β„•) : + (alg.comapFeedback g hg).policy n + = (alg.policy n).comap (fun p ↦ (Hist.mapFeedback g p.1, p.2)) (by fun_prop) := rfl + +@[simp] +lemma Algorithm.p0_comapFeedback (alg : Algorithm π“ž 𝓐 𝓨) (g : 𝓨' β†’ 𝓨) (hg : Measurable g) : + (alg.comapFeedback g hg).p0 = alg.p0 := by + ext o : 1 + rw [p0_apply, policy_comapFeedback, Kernel.comap_apply, alg.policy_zero, p0_apply] + +/-- The environment that reads `f a` when the algorithm plays `a`, both in the current round and in +the past rounds. -/ +def Environment.comapAction (env : Environment π“ž 𝓐 𝓨) (f : 𝓐' β†’ 𝓐) + (hf : Measurable f := by fun_prop) : Environment π“ž 𝓐' 𝓨 where + obs n := (env.obs n).comap (Hist.mapAction f) (by fun_prop) + feedback n := (env.feedback n).comap + (fun p ↦ ((Hist.mapAction f p.1.1, p.1.2), f p.2)) (by fun_prop) + +@[simp] +lemma Environment.obs_comapAction (env : Environment π“ž 𝓐 𝓨) (f : 𝓐' β†’ 𝓐) (hf : Measurable f) + (n : β„•) : + (env.comapAction f hf).obs n = (env.obs n).comap (Hist.mapAction f) (by fun_prop) := rfl + +@[simp] +lemma Environment.feedback_comapAction (env : Environment π“ž 𝓐 𝓨) (f : 𝓐' β†’ 𝓐) (hf : Measurable f) + (n : β„•) : + (env.comapAction f hf).feedback n = (env.feedback n).comap + (fun p ↦ ((Hist.mapAction f p.1.1, p.1.2), f p.2)) (by fun_prop) := rfl + +@[simp] +lemma Environment.obs0_comapAction (env : Environment π“ž 𝓐 𝓨) (f : 𝓐' β†’ 𝓐) (hf : Measurable f) : + (env.comapAction f hf).obs0 = env.obs0 := by + rw [Environment.obs0_def, obs_comapAction, Kernel.comap_apply, env.obs_zero] + +@[simp] +lemma Environment.Ξ½0_comapAction (env : Environment π“ž 𝓐 𝓨) (f : 𝓐' β†’ 𝓐) (hf : Measurable f) : + (env.comapAction f hf).Ξ½0 = env.Ξ½0.comap (fun p ↦ (p.1, f p.2)) (by fun_prop) := by + ext p : 1 + rw [Environment.Ξ½0_apply, feedback_comapAction, Kernel.comap_apply, env.feedback_zero, + Kernel.comap_apply] + +end Comap + +section Runs + +variable {alg : Algorithm π“ž 𝓐 𝓨} {P : Measure Ξ©} [IsFiniteMeasure P] + {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} + +namespace IsAlgEnvSeq + +section ComapObs + +variable {env : Environment π“ž' 𝓐 𝓨} {f : π“ž' β†’ π“ž} {hf : Measurable f} {O : β„• β†’ Ξ© β†’ π“ž'} + +/-- The algorithm does not use the part of the observation that it ignores: the conditional +distribution of its action given the transported history and observation is its own policy. -/ +lemma hasCondDistrib_action_comapObs (h : IsAlgEnvSeq O A Y (alg.comapObs f hf) env P) (n : β„•) : + HasCondDistrib (A n) + (fun Ο‰ ↦ (history (fun n Ο‰ ↦ f (O n Ο‰)) A Y n Ο‰, f (O n Ο‰))) (alg.policy n) P := + HasCondDistrib.comp_right (f := fun p : Hist π“ž' 𝓐 𝓨 n Γ— π“ž' ↦ (Hist.mapObs f p.1, f p.2)) + (hf := by fun_prop) (h.hasCondDistrib_action n) + +/-- The law of the trajectory that the algorithm sees is the image of the law of the full +trajectory under the map that forgets the part of the observations that the algorithm ignores. -/ +lemma map_trajectory_comapObs [IsProbabilityMeasure P] + (h : IsAlgEnvSeq O A Y (alg.comapObs f hf) env P) : + P.map (trajectory (fun n Ο‰ ↦ f (O n Ο‰)) A Y) + = (trajMeasure (alg.comapObs f hf) env).map (Traj.mapObs f) := by + calc P.map (trajectory (fun n Ο‰ ↦ f (O n Ο‰)) A Y) + _ = P.map (Traj.mapObs f ∘ trajectory O A Y) := rfl + _ = (P.map (trajectory O A Y)).map (Traj.mapObs f) := + (Measure.map_map (by fun_prop) h.measurable_trajectory).symm + _ = (trajMeasure (alg.comapObs f hf) env).map (Traj.mapObs f) := by rw [h.map_trajectory] + +end ComapObs + +section ComapFeedback + +variable {env : Environment π“ž 𝓐 𝓨'} {g : 𝓨' β†’ 𝓨} {hg : Measurable g} {O : β„• β†’ Ξ© β†’ π“ž} + {Y' : β„• β†’ Ξ© β†’ 𝓨'} + +/-- The algorithm does not use the part of the past feedbacks that it ignores: the conditional +distribution of its action given the transported history and the observation is its own policy. -/ +lemma hasCondDistrib_action_comapFeedback + (h : IsAlgEnvSeq O A Y' (alg.comapFeedback g hg) env P) (n : β„•) : + HasCondDistrib (A n) + (fun Ο‰ ↦ (history O A (fun n Ο‰ ↦ g (Y' n Ο‰)) n Ο‰, O n Ο‰)) (alg.policy n) P := + HasCondDistrib.comp_right (f := fun p : Hist π“ž 𝓐 𝓨' n Γ— π“ž ↦ (Hist.mapFeedback g p.1, p.2)) + (hf := by fun_prop) (h.hasCondDistrib_action n) + +/-- The law of the trajectory that the algorithm sees is the image of the law of the full +trajectory under the map that forgets the part of the feedbacks that the algorithm ignores. -/ +lemma map_trajectory_comapFeedback [IsProbabilityMeasure P] + (h : IsAlgEnvSeq O A Y' (alg.comapFeedback g hg) env P) : + P.map (trajectory O A (fun n Ο‰ ↦ g (Y' n Ο‰))) + = (trajMeasure (alg.comapFeedback g hg) env).map (Traj.mapFeedback g) := by + calc P.map (trajectory O A (fun n Ο‰ ↦ g (Y' n Ο‰))) + _ = P.map (Traj.mapFeedback g ∘ trajectory O A Y') := rfl + _ = (P.map (trajectory O A Y')).map (Traj.mapFeedback g) := + (Measure.map_map (by fun_prop) h.measurable_trajectory).symm + _ = (trajMeasure (alg.comapFeedback g hg) env).map (Traj.mapFeedback g) := by + rw [h.map_trajectory] + +end ComapFeedback + +section ComapAction + +variable {env : Environment π“ž 𝓐 𝓨} {f : 𝓐' β†’ 𝓐} {hf : Measurable f} {O : β„• β†’ Ξ© β†’ π“ž} + {A' : β„• β†’ Ξ© β†’ 𝓐'} + +/-- The environment does not use the part of the action that it ignores: the conditional +distribution of the observation given the transported history is its own observation kernel. -/ +lemma hasCondDistrib_obs_comapAction {alg : Algorithm π“ž 𝓐' 𝓨} + (h : IsAlgEnvSeq O A' Y alg (env.comapAction f hf) P) (n : β„•) : + HasCondDistrib (O n) (history O (fun n Ο‰ ↦ f (A' n Ο‰)) Y n) (env.obs n) P := + HasCondDistrib.comp_right (f := Hist.mapAction (π“ž := π“ž) (𝓨 := 𝓨) f (n := n)) + (hf := by fun_prop) (h.hasCondDistrib_obs n) + +/-- The environment does not use the part of the action that it ignores: the conditional +distribution of the feedback given the transported history, the observation and the transported +action is its own feedback kernel. -/ +lemma hasCondDistrib_feedback_comapAction {alg : Algorithm π“ž 𝓐' 𝓨} + (h : IsAlgEnvSeq O A' Y alg (env.comapAction f hf) P) (n : β„•) : + HasCondDistrib (Y n) + (fun Ο‰ ↦ ((history O (fun n Ο‰ ↦ f (A' n Ο‰)) Y n Ο‰, O n Ο‰), f (A' n Ο‰))) (env.feedback n) P := + HasCondDistrib.comp_right + (f := fun p : (Hist π“ž 𝓐' 𝓨 n Γ— π“ž) Γ— 𝓐' ↦ ((Hist.mapAction f p.1.1, p.1.2), f p.2)) + (hf := by fun_prop) (h.hasCondDistrib_feedback n) + +/-- The law of the trajectory that the environment sees is the image of the law of the full +trajectory under the map that forgets the part of the actions that the environment ignores. -/ +lemma map_trajectory_comapAction [IsProbabilityMeasure P] {alg : Algorithm π“ž 𝓐' 𝓨} + (h : IsAlgEnvSeq O A' Y alg (env.comapAction f hf) P) : + P.map (trajectory O (fun n Ο‰ ↦ f (A' n Ο‰)) Y) + = (trajMeasure alg (env.comapAction f hf)).map (Traj.mapAction f) := by + calc P.map (trajectory O (fun n Ο‰ ↦ f (A' n Ο‰)) Y) + _ = P.map (Traj.mapAction f ∘ trajectory O A' Y) := rfl + _ = (P.map (trajectory O A' Y)).map (Traj.mapAction f) := + (Measure.map_map (by fun_prop) h.measurable_trajectory).symm + _ = (trajMeasure alg (env.comapAction f hf)).map (Traj.mapAction f) := by rw [h.map_trajectory] + +end ComapAction + +end IsAlgEnvSeq + +end Runs + +end Learning diff --git a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean index 9d209727..972b8b06 100644 --- a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean +++ b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean @@ -5,26 +5,36 @@ Authors: Paulo Rauber, RΓ©my Degenne -/ module -public import LeanMachineLearning.SequentialLearning.IonescuTulceaSpace +public import LeanMachineLearning.SequentialLearning.Announce public import LeanMachineLearning.SequentialLearning.StationaryEnv /-! # Bayesian stationary environments -This file defines the structure `IsBayesAlgEnvSeq` and provides its basic properties. -The underlying environments are stationary environments, which have no observations: the -observation type is `Unit` and the observation process is `noObs`. +A Bayesian stationary environment is an environment that draws a parameter `e : 𝓔` from a prior +`Q` before the first round and then behaves like the stationary environment +`stationaryEnv (ΞΊ.sectR e)`. Following the "announced variables" mechanism of +`LeanMachineLearning/SequentialLearning/Announce.lean`, the parameter is not hidden: it is part of +the environment's move, and the algorithm is the one that ignores it. Concretely, +`bayesEnv Q ΞΊ : Environment (𝓔 Γ— Unit) 𝓐 𝓨` announces `e` in every observation and runs against +`alg.comapObs Prod.snd`, for an `alg : Algorithm Unit 𝓐 𝓨`. + +The predicate `IsBayesAlgEnvSeq` is not a new notion of run: it is `IsAlgEnvSeq` for that pair, +for the observation process that announces the parameter `E` at every round. ## Main definitions -* `IsBayesAlgEnvSeq Q ΞΊ alg E A Y P`: states that there is a measure `P : Measure Ξ©` such - that the parameter `E : Ξ© β†’ 𝓔` has law `Q` and that the sequences of actions `A : β„• β†’ Ξ© β†’ 𝓐` - and feedbacks `Y : β„• β†’ Ξ© β†’ 𝓨` are generated by the algorithm `alg : Algorithm Unit 𝓐 𝓨` - interacting with an underlying environment that depends on `E` and `ΞΊ` - (`stationaryEnv (ΞΊ.sectR (E Ο‰))`). +* `bayesEnv Q ΞΊ`: the environment that draws a parameter from `Q` before the first round, announces + it in the first component of every observation, and returns feedback `ΞΊ (e, a)` when the + parameter is `e` and the action is `a`. +* `IsBayesAlgEnvSeq Q ΞΊ alg E A Y P`: states that the parameter `E : Ξ© β†’ 𝓔` has law `Q` and that + the sequences of actions `A : β„• β†’ Ξ© β†’ 𝓐` and feedbacks `Y : β„• β†’ Ξ© β†’ 𝓨` are generated by the + algorithm `alg : Algorithm Unit 𝓐 𝓨` interacting with `bayesEnv Q ΞΊ`, which it sees through + `Algorithm.comapObs Prod.snd`. Equivalently, `A` and `Y` are generated by `alg` interacting with + the stationary environment `stationaryEnv (ΞΊ.sectR (E Ο‰))`. * `bayesTrajMeasure Q ΞΊ alg`: for any choice of probability measure `Q : Measure 𝓔`, Markov kernel `ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨`, and algorithm `alg : Algorithm Unit 𝓐 𝓨`, provides a probability measure - `P : Measure (β„• β†’ Round Unit 𝓐 (𝓔 Γ— 𝓨))` on a space that carries `E`, `A`, and `Y` such that + `P : Measure (β„• β†’ Round (𝓔 Γ— Unit) 𝓐 𝓨)` on a space that carries `E`, `A`, and `Y` such that `IsBayesAlgEnvSeq Q ΞΊ alg E A Y P`. * `bayesTrajMeasurePosterior Q ΞΊ alg n`: a `Kernel (Hist Unit 𝓐 𝓨 n) 𝓔` that represents the posterior over `E` given the history before time `n` (the `n` first rounds) under @@ -34,6 +44,8 @@ observation type is `Unit` and the observation process is `noObs`. ## Main results +* `IsAlgEnvSeq.isBayesAlgEnvSeq`: a run of `alg.comapObs Prod.snd` against `bayesEnv Q ΞΊ` is a + Bayesian algorithm-environment sequence for the announced parameter. * `ae_IsAlgEnvSeq h`: if `h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P`, for `Q`-almost every `e : 𝓔`, `IsAlgEnvSeq O' A' Y' alg (stationaryEnv (ΞΊ.sectR e)) (condDistrib (trajectory _ A Y) E P e)` for some sequence of actions `A' : β„• β†’ (β„• β†’ Round Unit 𝓐 𝓨) β†’ 𝓐` and sequence of feedbacks @@ -55,45 +67,179 @@ namespace Learning variable {𝓔 𝓐 𝓨 Ξ© : Type*} variable [MeasurableSpace 𝓔] [MeasurableSpace 𝓐] [MeasurableSpace 𝓨] [MeasurableSpace Ξ©] +section BayesEnv + +/-- The environment that draws a parameter `e : 𝓔` from `Q` before the first round, announces it in +the first component of every observation, and returns a feedback drawn from `ΞΊ (e, a)` when the +action is `a`. The algorithm is meant to ignore the announced parameter, that is, to run through +`Algorithm.comapObs Prod.snd`. -/ +noncomputable +def bayesEnv (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) [IsMarkovKernel ΞΊ] : + Environment (𝓔 Γ— Unit) 𝓐 𝓨 where + obs + | 0 => Kernel.const _ (Q.prod (Measure.dirac ())) + | _ + 1 => Kernel.deterministic (fun h ↦ (h 0).obs) (by fun_prop) + feedback _ := ΞΊ.comap (fun p ↦ (p.1.2.1, p.2)) (by fun_prop) + isMarkovKernel_obs n := by cases n <;> infer_instance + +variable {Q : Measure 𝓔} [IsProbabilityMeasure Q] {ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨} [IsMarkovKernel ΞΊ] + +@[simp] +lemma obs_bayesEnv_zero : + (bayesEnv Q ΞΊ).obs 0 = Kernel.const _ (Q.prod (Measure.dirac ())) := rfl + +@[simp] +lemma obs_bayesEnv_succ (n : β„•) : + (bayesEnv Q ΞΊ).obs (n + 1) + = Kernel.deterministic (fun h : Hist (𝓔 Γ— Unit) 𝓐 𝓨 (n + 1) ↦ (h 0).obs) (by fun_prop) := rfl + +@[simp] +lemma feedback_bayesEnv (n : β„•) : + (bayesEnv Q ΞΊ).feedback n = ΞΊ.comap (fun p ↦ (p.1.2.1, p.2)) (by fun_prop) := rfl + +@[simp] +lemma obs0_bayesEnv : (bayesEnv Q ΞΊ).obs0 = Q.prod (Measure.dirac ()) := rfl + +@[simp] +lemma Ξ½0_bayesEnv : (bayesEnv Q ΞΊ).Ξ½0 = ΞΊ.comap (fun p ↦ (p.1.1, p.2)) (by fun_prop) := rfl + +end BayesEnv + +/-- Insert an announced parameter `e` into every round of an observable history. -/ +def announceHist (e : 𝓔) {n : β„•} (h : Hist Unit 𝓐 𝓨 n) : Hist (𝓔 Γ— Unit) 𝓐 𝓨 n := + fun i ↦ ((e, ()), (h i).action, (h i).feedback) + +@[fun_prop] +lemma measurable_announceHist (n : β„•) : + Measurable (fun p : 𝓔 Γ— Hist Unit 𝓐 𝓨 n ↦ announceHist p.1 p.2) := by + unfold announceHist + fun_prop + /-- `IsBayesAlgEnvSeq Q ΞΊ alg E A Y P` states that there is a measure `P : Measure Ξ©` such - that the parameter `E : Ξ© β†’ 𝓔` has law `Q` and that the sequences of actions `A : β„• β†’ Ξ© β†’ 𝓐` - and feedbacks `Y : β„• β†’ Ξ© β†’ 𝓨` are generated by the algorithm `alg : Algorithm Unit 𝓐 𝓨` - interacting with an underlying environment that depends on `E` and `ΞΊ` - (`stationaryEnv (ΞΊ.sectR (E Ο‰))`). -/ -structure IsBayesAlgEnvSeq - (Q : Measure 𝓔) (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) (alg : Algorithm Unit 𝓐 𝓨) +that the parameter `E : Ξ© β†’ 𝓔` has law `Q` and that the sequences of actions `A : β„• β†’ Ξ© β†’ 𝓐` +and feedbacks `Y : β„• β†’ Ξ© β†’ 𝓨` are generated by the algorithm `alg : Algorithm Unit 𝓐 𝓨` +interacting with an underlying environment that depends on `E` and `ΞΊ` +(`stationaryEnv (ΞΊ.sectR (E Ο‰))`). + +This is `IsAlgEnvSeq` for the announcing environment `bayesEnv Q ΞΊ` and the algorithm +`alg.comapObs Prod.snd` that ignores the announced parameter: the observation at every round is +`(E Ο‰, ())`. -/ +def IsBayesAlgEnvSeq (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) + [IsMarkovKernel ΞΊ] (alg : Algorithm Unit 𝓐 𝓨) (E : Ξ© β†’ 𝓔) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) - (P : Measure Ξ©) [IsFiniteMeasure P] : Prop where - measurable_param : Measurable E := by fun_prop - measurable_action n : Measurable (A n) := by fun_prop - measurable_feedback n : Measurable (Y n) := by fun_prop - hasLaw_env : HasLaw E Q P - /-- The action at time `n` has the correct conditional distribution given the parameter and the - history: it depends only on the history. -/ - hasCondDistrib_action n : - HasCondDistrib (A n) (fun Ο‰ ↦ (E Ο‰, (history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰))) - ((alg.policy n).prodMkLeft _) P - /-- The feedback at time `n` has the correct conditional distribution given the history, the - parameter and the action at time `n`: it depends only on the parameter and the action. -/ - hasCondDistrib_feedback n : - HasCondDistrib (Y n) (fun Ο‰ ↦ ((history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰), E Ο‰, A n Ο‰)) - (ΞΊ.prodMkLeft _) P + (P : Measure Ξ©) [IsProbabilityMeasure P] : Prop := + IsAlgEnvSeq (fun _ Ο‰ ↦ (E Ο‰, ())) A Y (alg.comapObs Prod.snd) (bayesEnv Q ΞΊ) P namespace IsBayesAlgEnvSeq -variable {Q : Measure 𝓔} {ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨} {alg : Algorithm Unit 𝓐 𝓨} +variable {Q : Measure 𝓔} [IsProbabilityMeasure Q] {ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨} [IsMarkovKernel ΞΊ] +variable {alg : Algorithm Unit 𝓐 𝓨} variable {E : Ξ© β†’ 𝓔} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} -variable {P : Measure Ξ©} [IsFiniteMeasure P] +variable {P : Measure Ξ©} [IsProbabilityMeasure P] + +/-- Constructor for `IsBayesAlgEnvSeq` from the law of the parameter and the conditional +distributions of the actions and of the feedbacks given the parameter and the observable history. +Together with `IsBayesAlgEnvSeq.hasLaw_env`, `IsBayesAlgEnvSeq.hasCondDistrib_action` and +`IsBayesAlgEnvSeq.hasCondDistrib_feedback`, this shows that being an `IsAlgEnvSeq` for the +announcing environment is equivalent to those conditions. -/ +lemma mk (hasLaw_env : HasLaw E Q P) + (hasCondDistrib_action : βˆ€ n, + HasCondDistrib (A n) (fun Ο‰ ↦ (E Ο‰, (history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰))) + ((alg.policy n).prodMkLeft _) P) + (hasCondDistrib_feedback : βˆ€ n, + HasCondDistrib (Y n) (fun Ο‰ ↦ ((history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰), (E Ο‰, A n Ο‰))) + (ΞΊ.prodMkLeft _) P) + (measurable_param : Measurable E := by fun_prop) + (measurable_action : βˆ€ n, Measurable (A n) := by fun_prop) + (measurable_feedback : βˆ€ n, Measurable (Y n) := by fun_prop) : + IsBayesAlgEnvSeq Q ΞΊ alg E A Y P := by + have hO : βˆ€ _ : β„•, Measurable (fun Ο‰ ↦ ((E Ο‰, ()) : 𝓔 Γ— Unit)) := + fun _ ↦ measurable_param.prodMk measurable_const + refine IsAlgEnvSeq.mk hO measurable_action measurable_feedback ?_ ?_ ?_ + Β· intro n + cases n with + | zero => + rw [history_zero, obs_bayesEnv_zero] + refine HasLaw.hasCondDistrib_const ⟨(hO 0).aemeasurable, ?_⟩ + rw [Kernel.const_apply, Measure.prod_dirac, ← hasLaw_env.map_eq, + AEMeasurable.map_map_of_aemeasurable (by fun_prop) hasLaw_env.aemeasurable] + rfl + | succ n => + rw [obs_bayesEnv_succ] + exact hasCondDistrib_deterministic _ + (measurable_history hO measurable_action measurable_feedback (n + 1)).aemeasurable + (ae_of_all _ fun _ ↦ rfl) + Β· intro n + exact HasCondDistrib.comp_right + (f := fun q : 𝓔 Γ— (Hist Unit 𝓐 𝓨 n Γ— Unit) ↦ (announceHist q.1 q.2.1, (q.1, q.2.2))) + (hf := by fun_prop) + (Z := fun Ο‰ ↦ (E Ο‰, (history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰))) + (hasCondDistrib_action n) + Β· intro n + exact HasCondDistrib.comp_right + (f := fun q : (Hist Unit 𝓐 𝓨 n Γ— Unit) Γ— (𝓔 Γ— 𝓐) ↦ + ((announceHist q.2.1 q.1.1, (q.2.1, q.1.2)), q.2.2)) + (hf := by fun_prop) + (Z := fun Ο‰ ↦ ((history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰), (E Ο‰, A n Ο‰))) + (hasCondDistrib_feedback n) + +/-- A Bayesian algorithm-environment sequence is an algorithm-environment sequence for the +announcing environment `bayesEnv Q ΞΊ`. -/ +lemma isAlgEnvSeq (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : + IsAlgEnvSeq (fun _ Ο‰ ↦ (E Ο‰, ())) A Y (alg.comapObs Prod.snd) (bayesEnv Q ΞΊ) P := h + +lemma measurable_param (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : Measurable E := + (h.isAlgEnvSeq.measurable_obs 0).fst + +lemma measurable_action (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : Measurable (A n) := + h.isAlgEnvSeq.measurable_action n + +lemma measurable_feedback (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : Measurable (Y n) := + h.isAlgEnvSeq.measurable_feedback n + +/-- The parameter has law `Q`. -/ +lemma hasLaw_env (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : HasLaw E Q P := by + have h0 := h.isAlgEnvSeq.hasCondDistrib_obs 0 + rw [history_zero] at h0 + have h1 : HasLaw (fun Ο‰ ↦ (E Ο‰, ())) (Q.prod (Measure.dirac ())) P := h0.hasLaw_of_const' + refine ⟨h.measurable_param.aemeasurable, ?_⟩ + have h2 : E = Prod.fst ∘ (fun Ο‰ ↦ (E Ο‰, ())) := rfl + rw [h2, ← Measure.map_map measurable_fst + (h.measurable_param.prodMk (measurable_const : Measurable fun _ : Ξ© ↦ ())), h1.map_eq] + exact Measure.fst_prod + +/-- The action at time `n` has the correct conditional distribution given the parameter and the +history: it depends only on the history. -/ +lemma hasCondDistrib_action (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : + HasCondDistrib (A n) (fun Ο‰ ↦ (E Ο‰, (history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰))) + ((alg.policy n).prodMkLeft _) P := + HasCondDistrib.comp_right + (f := fun p : Hist (𝓔 Γ— Unit) 𝓐 𝓨 n Γ— (𝓔 Γ— Unit) ↦ (p.2.1, (Hist.mapObs Prod.snd p.1, p.2.2))) + (hf := by fun_prop) + (Z := fun Ο‰ ↦ (history (fun _ Ο‰ ↦ (E Ο‰, ())) A Y n Ο‰, (E Ο‰, ()))) + (h.isAlgEnvSeq.hasCondDistrib_action n) + +/-- The feedback at time `n` has the correct conditional distribution given the history, the +parameter and the action at time `n`: it depends only on the parameter and the action. -/ +lemma hasCondDistrib_feedback (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : + HasCondDistrib (Y n) (fun Ο‰ ↦ ((history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰), (E Ο‰, A n Ο‰))) + (ΞΊ.prodMkLeft _) P := + HasCondDistrib.comp_right + (f := fun p : (Hist (𝓔 Γ— Unit) 𝓐 𝓨 n Γ— (𝓔 Γ— Unit)) Γ— 𝓐 ↦ + ((Hist.mapObs Prod.snd p.1.1, p.1.2.2), (p.1.2.1, p.2))) + (hf := by fun_prop) + (Z := fun Ο‰ ↦ ((history (fun _ Ο‰ ↦ (E Ο‰, ())) A Y n Ο‰, (E Ο‰, ())), A n Ο‰)) + (h.isAlgEnvSeq.hasCondDistrib_feedback n) lemma hasCondDistrib_action' (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : HasCondDistrib (A n) (fun Ο‰ ↦ (history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰)) (alg.policy n) P := (h.hasCondDistrib_action n).comp_right -lemma hasCondDistrib_feedback' [IsFiniteKernel ΞΊ] (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : +lemma hasCondDistrib_feedback' (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : HasCondDistrib (Y n) (fun Ο‰ ↦ (E Ο‰, A n Ο‰)) ΞΊ P := (h.hasCondDistrib_feedback n).comp_right -lemma hasLaw_action_zero [IsProbabilityMeasure P] (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : +lemma hasLaw_action_zero (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : HasLaw (A 0) (alg.p0 ()) P := by have h0 : HasCondDistrib (A 0) (fun _ : Ξ© ↦ ((default : Hist Unit 𝓐 𝓨 0), ())) (alg.policy 0) P := by @@ -110,8 +256,8 @@ variable [StandardBorelSpace 𝓐] [Nonempty 𝓐] [StandardBorelSpace 𝓨] [No omit [StandardBorelSpace 𝓐] [Nonempty 𝓐] [StandardBorelSpace 𝓨] [Nonempty 𝓨] in /-- The posterior over the parameter given the empty history is the prior. -/ -lemma condDistrib_param_history_zero [StandardBorelSpace 𝓔] [Nonempty 𝓔] [IsProbabilityMeasure P] - [IsFiniteMeasure Q] (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : +lemma condDistrib_param_history_zero [StandardBorelSpace 𝓔] [Nonempty 𝓔] + (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : condDistrib E (history (noObs Ξ©) A Y 0) P = Kernel.const _ Q := by ext x : 1 rw [Unique.eq_default x, history_zero] @@ -122,8 +268,7 @@ lemma condDistrib_param_history_zero [StandardBorelSpace 𝓔] [Nonempty 𝓔] [ ae_dirac_iff Subsingleton.measurableSet] at h_ae exact h_ae -lemma hasCondDistrib_IT_obs [IsProbabilityMeasure P] (_h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) - (n : β„•) : +lemma hasCondDistrib_IT_obs (_h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : βˆ€α΅ e βˆ‚Q, HasCondDistrib (IT.obs n) (IT.hist n) (unitObs 𝓐 𝓨 n) (condDistrib (trajectory (noObs Ξ©) A Y) E P e) := ae_of_all _ fun _ ↦ hasCondDistrib_unit (IT.measurable_hist n).aemeasurable _ _ @@ -138,8 +283,7 @@ lemma hasCondDistrib_IT_action (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) h.measurable_feedback).aemeasurable] with _ he rwa [Kernel.sectR_prodMkLeft] at he -lemma hasCondDistrib_IT_feedback [IsFiniteKernel ΞΊ] (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) - (n : β„•) : +lemma hasCondDistrib_IT_feedback (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : βˆ€α΅ e βˆ‚Q, HasCondDistrib (IT.feedback n) (fun Ο„ ↦ ((IT.hist n Ο„, IT.obs n Ο„), IT.action n Ο„)) ((ΞΊ.sectR e).prodMkLeft _) (condDistrib (trajectory (noObs Ξ©) A Y) E P e) := by @@ -167,8 +311,7 @@ lemma hasLaw_IT_hist (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : exact ⟨(IT.measurable_hist n).aemeasurable, by rw [← Kernel.map_apply _ (IT.measurable_hist n), he]⟩ -lemma ae_IsAlgEnvSeq [IsProbabilityMeasure P] [IsMarkovKernel ΞΊ] - (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : +lemma ae_IsAlgEnvSeq (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : βˆ€α΅ e βˆ‚Q, IsAlgEnvSeq IT.obs IT.action IT.feedback alg (stationaryEnv (ΞΊ.sectR e)) (condDistrib (trajectory (noObs Ξ©) A Y) E P e) := by filter_upwards [ae_all_iff.2 (hasCondDistrib_IT_obs h), @@ -180,98 +323,33 @@ end IsBayesAlgEnvSeq section IsAlgEnvSeq -/-- An environment without observations whose feedback lies in `𝓔 Γ— 𝓨`. The first element `e` of a -feedback is sampled from `Q` at time `0` and then remains constant: at time `n + 1` it is read from -the first round in the history. The second element of a feedback is sampled from `ΞΊ (e, a)`, where -`a` is the corresponding action. -/ -noncomputable -def bayesStationaryEnv (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) - [IsMarkovKernel ΞΊ] : Environment Unit 𝓐 (𝓔 Γ— 𝓨) where - obs n := unitObs 𝓐 (𝓔 Γ— 𝓨) n - feedback - | 0 => ((Kernel.const _ Q) βŠ—β‚– ΞΊ.swapLeft).prodMkLeft _ - | n + 1 => - let g : (Hist Unit 𝓐 (𝓔 Γ— 𝓨) (n + 1) Γ— Unit) Γ— 𝓐 β†’ 𝓔 Γ— 𝓐 := - fun p ↦ ((p.1.1 0).feedback.1, p.2) - (Kernel.deterministic (Prod.fst ∘ g) (by fun_prop)) Γ—β‚– (ΞΊ.comap g (by fun_prop)) - isMarkovKernel_feedback n := by cases n <;> infer_instance - variable {Q : Measure 𝓔} [IsProbabilityMeasure Q] {ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨} [IsMarkovKernel ΞΊ] - -@[simp] -lemma bayesStationaryEnv_obs (n : β„•) : - (bayesStationaryEnv Q ΞΊ).obs n = unitObs 𝓐 (𝓔 Γ— 𝓨) n := rfl - -lemma bayesStationaryEnv_feedback_zero : - (bayesStationaryEnv Q ΞΊ).feedback 0 = ((Kernel.const _ Q) βŠ—β‚– ΞΊ.swapLeft).prodMkLeft _ := rfl - -lemma bayesStationaryEnv_feedback_succ (n : β„•) : - (bayesStationaryEnv Q ΞΊ).feedback (n + 1) = - (Kernel.deterministic (Prod.fst ∘ (fun p : (Hist Unit 𝓐 (𝓔 Γ— 𝓨) (n + 1) Γ— Unit) Γ— 𝓐 ↦ - ((p.1.1 0).feedback.1, p.2))) (by fun_prop)) Γ—β‚– - (ΞΊ.comap (fun p ↦ ((p.1.1 0).feedback.1, p.2)) (by fun_prop)) := rfl - -@[simp] -lemma Ξ½0_bayesStationaryEnv : - (bayesStationaryEnv Q ΞΊ).Ξ½0 = ((Kernel.const _ Q) βŠ—β‚– ΞΊ.swapLeft).prodMkLeft Unit := rfl - -variable {alg : Algorithm Unit 𝓐 𝓨} {O : β„• β†’ Ξ© β†’ Unit} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓔 Γ— 𝓨} +variable {alg : Algorithm Unit 𝓐 𝓨} {O : β„• β†’ Ξ© β†’ 𝓔 Γ— Unit} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} variable {P : Measure Ξ©} [IsProbabilityMeasure P] -lemma IsAlgEnvSeq.isBayesAlgEnvSeq - (h : IsAlgEnvSeq O A Y (alg.prodLeft 𝓔) (bayesStationaryEnv Q ΞΊ) P) : - IsBayesAlgEnvSeq Q ΞΊ alg (fun Ο‰ ↦ (Y 0 Ο‰).1) A (fun n Ο‰ ↦ (Y n Ο‰).2) P where - measurable_param := (h.measurable_feedback 0).fst - measurable_action := h.measurable_action - measurable_feedback n := (h.measurable_feedback n).snd - hasLaw_env := by - have hc : HasCondDistrib (Y 0) (A 0) ((Kernel.const _ Q) βŠ—β‚– ΞΊ.swapLeft) P := - hasCondDistrib_prodMk_left_unique_iff.mp h.hasCondDistrib_feedback_zero - have hc' : HasCondDistrib (fun Ο‰ ↦ (Y 0 Ο‰).1) (A 0) (Kernel.const 𝓐 Q) P := by - simpa [Kernel.fst_compProd] using hc.fst - exact hc'.hasLaw_of_const - hasCondDistrib_action n := by - cases n with - | zero => - -- At time `0` the history is empty: `E` is the parameter component of `Y 0`, which is - -- independent of `A 0`. - have hc0 : HasCondDistrib (Y 0) (A 0) ((Kernel.const _ Q) βŠ—β‚– ΞΊ.swapLeft) P := - hasCondDistrib_prodMk_left_unique_iff.mp h.hasCondDistrib_feedback_zero - have hc : HasCondDistrib (fun Ο‰ ↦ (Y 0 Ο‰).1) (A 0) (Kernel.const _ Q) P := by - simpa [Kernel.fst_compProd] using hc0.fst - have h_law : HasLaw (A 0) (alg.p0 ()) P := by - have h0 : HasCondDistrib (A 0) (fun _ : Ξ© ↦ ()) - ((alg.prodLeft 𝓔).p0) P := h.hasCondDistrib_action_zero - simpa using h0.hasLaw_of_const' - have hc' : HasCondDistrib (A 0) (fun Ο‰ ↦ (Y 0 Ο‰).1) (Kernel.const _ (alg.p0 ())) P := by - simpa [h_law.map_eq] using hc.const_map_of_const - exact hasCondDistrib_prodMk_right_unique_iff.mpr hc' - | succ n => - let f : (Hist Unit 𝓐 (𝓔 Γ— 𝓨) (n + 1) Γ— Unit) β†’ 𝓔 Γ— (Hist Unit 𝓐 𝓨 (n + 1) Γ— Unit) := - fun p ↦ ((p.1 0).feedback.1, - (fun i ↦ ((p.1 i).obs, (p.1 i).action, (p.1 i).feedback.2), p.2)) - have hc : HasCondDistrib (A (n + 1)) (fun Ο‰ ↦ (history O A Y (n + 1) Ο‰, O (n + 1) Ο‰)) - (((alg.policy (n + 1)).prodMkLeft 𝓔).comap f (by fun_prop)) P := - h.hasCondDistrib_action (n + 1) - exact hc.comp_right (f := f) - hasCondDistrib_feedback n := by - cases n with - | zero => - have hc : HasCondDistrib (Y 0) (A 0) ((Kernel.const _ Q) βŠ—β‚– ΞΊ.swapLeft) P := - hasCondDistrib_prodMk_left_unique_iff.mp h.hasCondDistrib_feedback_zero - exact hasCondDistrib_prodMk_left_unique_iff.mpr - (hc.of_compProd.measurableEquiv_comp_right MeasurableEquiv.prodComm) - | succ n => - let f : ((Hist Unit 𝓐 (𝓔 Γ— 𝓨) (n + 1) Γ— Unit) Γ— 𝓐) β†’ - ((Hist Unit 𝓐 𝓨 (n + 1) Γ— Unit) Γ— 𝓔 Γ— 𝓐) := - fun p ↦ ((fun i ↦ ((p.1.1 i).obs, (p.1.1 i).action, (p.1.1 i).feedback.2), p.1.2), - (p.1.1 0).feedback.1, p.2) - have hc : HasCondDistrib (fun Ο‰ ↦ (Y (n + 1) Ο‰).2) - (fun Ο‰ ↦ ((history O A Y (n + 1) Ο‰, O (n + 1) Ο‰), A (n + 1) Ο‰)) - ((Kernel.prodMkLeft (Hist Unit 𝓐 𝓨 (n + 1) Γ— Unit) ΞΊ).comap f (by fun_prop)) P := by - simpa [bayesStationaryEnv_feedback_succ, Kernel.prodMkLeft, ← Kernel.comap_comp_right, - Function.comp_def] using (h.hasCondDistrib_feedback (n + 1)).snd - exact hc.comp_right +/-- Under `bayesEnv Q ΞΊ`, the announced parameter is almost surely the same at every round. -/ +lemma IsAlgEnvSeq.ae_obs_eq_obs_zero [StandardBorelSpace 𝓔] + (h : IsAlgEnvSeq O A Y (alg.comapObs Prod.snd) (bayesEnv Q ΞΊ) P) (n : β„•) : + (fun Ο‰ ↦ ((O 0 Ο‰).1, ())) =ᡐ[P] O n := by + cases n with + | zero => exact ae_of_all _ fun _ ↦ rfl + | succ n => + have h1 := h.hasCondDistrib_obs (n + 1) + rw [obs_bayesEnv_succ] at h1 + have h2 := ae_eq_of_hasCondDistrib_deterministic (by fun_prop) + (h.measurable_history (n + 1)).aemeasurable (h.measurable_obs (n + 1)).aemeasurable h1 + filter_upwards [h2] with Ο‰ hΟ‰ + rw [hΟ‰] + simp [history_apply] + +/-- A run of `alg.comapObs Prod.snd` against the announcing environment `bayesEnv Q ΞΊ` is a +Bayesian algorithm-environment sequence for the announced parameter. -/ +lemma IsAlgEnvSeq.isBayesAlgEnvSeq [StandardBorelSpace 𝓔] + (h : IsAlgEnvSeq O A Y (alg.comapObs Prod.snd) (bayesEnv Q ΞΊ) P) : + IsBayesAlgEnvSeq Q ΞΊ alg (fun Ο‰ ↦ (O 0 Ο‰).1) A Y P := + h.congr (fun _ ↦ (h.measurable_obs 0).fst.prodMk measurable_const) + h.measurable_action h.measurable_feedback h.ae_obs_eq_obs_zero + (fun _ ↦ .rfl) (fun _ ↦ .rfl) end IsAlgEnvSeq @@ -281,15 +359,21 @@ namespace IT `IsBayesAlgEnvSeq Q ΞΊ alg E A Y P`. -/ noncomputable def bayesTrajMeasure (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) - [IsMarkovKernel ΞΊ] (alg : Algorithm Unit 𝓐 𝓨) : Measure (β„• β†’ Round Unit 𝓐 (𝓔 Γ— 𝓨)) := - trajMeasure (alg.prodLeft 𝓔) (bayesStationaryEnv Q ΞΊ) + [IsMarkovKernel ΞΊ] (alg : Algorithm Unit 𝓐 𝓨) : Measure (β„• β†’ Round (𝓔 Γ— Unit) 𝓐 𝓨) := + trajMeasure (alg.comapObs Prod.snd) (bayesEnv Q ΞΊ) deriving IsProbabilityMeasure -lemma isBayesAlgEnvSeq_bayesTrajMeasure +/-- The parameter announced by `bayesEnv Q ΞΊ`, read on the trajectory space. -/ +def param (Ο„ : β„• β†’ Round (𝓔 Γ— Unit) 𝓐 𝓨) : 𝓔 := (IT.obs 0 Ο„).1 + +@[fun_prop] +lemma measurable_param : Measurable (param (𝓔 := 𝓔) (𝓐 := 𝓐) (𝓨 := 𝓨)) := by + unfold param; fun_prop + +lemma isBayesAlgEnvSeq_bayesTrajMeasure [StandardBorelSpace 𝓔] (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) [IsMarkovKernel ΞΊ] (alg : Algorithm Unit 𝓐 𝓨) : - IsBayesAlgEnvSeq Q ΞΊ alg (fun Ο‰ ↦ (Ο‰ 0).feedback.1) action - (fun n Ο‰ ↦ (Ο‰ n).feedback.2) (bayesTrajMeasure Q ΞΊ alg) := + IsBayesAlgEnvSeq Q ΞΊ alg param action feedback (bayesTrajMeasure Q ΞΊ alg) := (isAlgEnvSeq_trajMeasure _ _).isBayesAlgEnvSeq /-- A kernel that represents the posterior over `E` given the history before time `n`. -/ @@ -297,9 +381,7 @@ noncomputable def bayesTrajMeasurePosterior [StandardBorelSpace 𝓔] [Nonempty 𝓔] (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) [IsMarkovKernel ΞΊ] (alg : Algorithm Unit 𝓐 𝓨) (n : β„•) : Kernel (Hist Unit 𝓐 𝓨 n) 𝓔 := - condDistrib (fun Ο‰ ↦ (Ο‰ 0).feedback.1) - (history (noObs _) action (fun n Ο‰ ↦ (Ο‰ n).feedback.2) n) - (bayesTrajMeasure Q ΞΊ alg) + condDistrib param (history (noObs _) action feedback n) (bayesTrajMeasure Q ΞΊ alg) deriving IsMarkovKernel /-- The posterior given the empty history is the prior. -/ From ff5aa2ee86dcf8064d354950fbc434255587eb73 Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Fri, 28 Aug 2026 13:07:54 +0200 Subject: [PATCH 03/21] rename: bayesEnv -> bayesStationaryEnv --- .../BayesStationaryEnv.lean | 70 ++++++++++--------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean index 972b8b06..d2b3a7d4 100644 --- a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean +++ b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean @@ -16,22 +16,22 @@ A Bayesian stationary environment is an environment that draws a parameter `e : `stationaryEnv (ΞΊ.sectR e)`. Following the "announced variables" mechanism of `LeanMachineLearning/SequentialLearning/Announce.lean`, the parameter is not hidden: it is part of the environment's move, and the algorithm is the one that ignores it. Concretely, -`bayesEnv Q ΞΊ : Environment (𝓔 Γ— Unit) 𝓐 𝓨` announces `e` in every observation and runs against -`alg.comapObs Prod.snd`, for an `alg : Algorithm Unit 𝓐 𝓨`. +`bayesStationaryEnv Q ΞΊ : Environment (𝓔 Γ— Unit) 𝓐 𝓨` announces `e` in every observation and runs +against `alg.comapObs Prod.snd`, for an `alg : Algorithm Unit 𝓐 𝓨`. The predicate `IsBayesAlgEnvSeq` is not a new notion of run: it is `IsAlgEnvSeq` for that pair, for the observation process that announces the parameter `E` at every round. ## Main definitions -* `bayesEnv Q ΞΊ`: the environment that draws a parameter from `Q` before the first round, announces - it in the first component of every observation, and returns feedback `ΞΊ (e, a)` when the - parameter is `e` and the action is `a`. +* `bayesStationaryEnv Q ΞΊ`: the environment that draws a parameter from `Q` before the first + round, announces it in the first component of every observation, and returns feedback `ΞΊ (e, a)` + when the parameter is `e` and the action is `a`. * `IsBayesAlgEnvSeq Q ΞΊ alg E A Y P`: states that the parameter `E : Ξ© β†’ 𝓔` has law `Q` and that the sequences of actions `A : β„• β†’ Ξ© β†’ 𝓐` and feedbacks `Y : β„• β†’ Ξ© β†’ 𝓨` are generated by the - algorithm `alg : Algorithm Unit 𝓐 𝓨` interacting with `bayesEnv Q ΞΊ`, which it sees through - `Algorithm.comapObs Prod.snd`. Equivalently, `A` and `Y` are generated by `alg` interacting with - the stationary environment `stationaryEnv (ΞΊ.sectR (E Ο‰))`. + algorithm `alg : Algorithm Unit 𝓐 𝓨` interacting with `bayesStationaryEnv Q ΞΊ`, which it sees + through `Algorithm.comapObs Prod.snd`. Equivalently, `A` and `Y` are generated by `alg` + interacting with the stationary environment `stationaryEnv (ΞΊ.sectR (E Ο‰))`. * `bayesTrajMeasure Q ΞΊ alg`: for any choice of probability measure `Q : Measure 𝓔`, Markov kernel `ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨`, and algorithm `alg : Algorithm Unit 𝓐 𝓨`, provides a probability measure `P : Measure (β„• β†’ Round (𝓔 Γ— Unit) 𝓐 𝓨)` on a space that carries `E`, `A`, and `Y` such that @@ -44,8 +44,8 @@ for the observation process that announces the parameter `E` at every round. ## Main results -* `IsAlgEnvSeq.isBayesAlgEnvSeq`: a run of `alg.comapObs Prod.snd` against `bayesEnv Q ΞΊ` is a - Bayesian algorithm-environment sequence for the announced parameter. +* `IsAlgEnvSeq.isBayesAlgEnvSeq`: a run of `alg.comapObs Prod.snd` against `bayesStationaryEnv Q ΞΊ` + is a Bayesian algorithm-environment sequence for the announced parameter. * `ae_IsAlgEnvSeq h`: if `h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P`, for `Q`-almost every `e : 𝓔`, `IsAlgEnvSeq O' A' Y' alg (stationaryEnv (ΞΊ.sectR e)) (condDistrib (trajectory _ A Y) E P e)` for some sequence of actions `A' : β„• β†’ (β„• β†’ Round Unit 𝓐 𝓨) β†’ 𝓐` and sequence of feedbacks @@ -74,8 +74,8 @@ the first component of every observation, and returns a feedback drawn from `ΞΊ action is `a`. The algorithm is meant to ignore the announced parameter, that is, to run through `Algorithm.comapObs Prod.snd`. -/ noncomputable -def bayesEnv (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) [IsMarkovKernel ΞΊ] : - Environment (𝓔 Γ— Unit) 𝓐 𝓨 where +def bayesStationaryEnv (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) + [IsMarkovKernel ΞΊ] : Environment (𝓔 Γ— Unit) 𝓐 𝓨 where obs | 0 => Kernel.const _ (Q.prod (Measure.dirac ())) | _ + 1 => Kernel.deterministic (fun h ↦ (h 0).obs) (by fun_prop) @@ -85,23 +85,24 @@ def bayesEnv (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— variable {Q : Measure 𝓔} [IsProbabilityMeasure Q] {ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨} [IsMarkovKernel ΞΊ] @[simp] -lemma obs_bayesEnv_zero : - (bayesEnv Q ΞΊ).obs 0 = Kernel.const _ (Q.prod (Measure.dirac ())) := rfl +lemma obs_bayesStationaryEnv_zero : + (bayesStationaryEnv Q ΞΊ).obs 0 = Kernel.const _ (Q.prod (Measure.dirac ())) := rfl @[simp] -lemma obs_bayesEnv_succ (n : β„•) : - (bayesEnv Q ΞΊ).obs (n + 1) +lemma obs_bayesStationaryEnv_succ (n : β„•) : + (bayesStationaryEnv Q ΞΊ).obs (n + 1) = Kernel.deterministic (fun h : Hist (𝓔 Γ— Unit) 𝓐 𝓨 (n + 1) ↦ (h 0).obs) (by fun_prop) := rfl @[simp] -lemma feedback_bayesEnv (n : β„•) : - (bayesEnv Q ΞΊ).feedback n = ΞΊ.comap (fun p ↦ (p.1.2.1, p.2)) (by fun_prop) := rfl +lemma feedback_bayesStationaryEnv (n : β„•) : + (bayesStationaryEnv Q ΞΊ).feedback n = ΞΊ.comap (fun p ↦ (p.1.2.1, p.2)) (by fun_prop) := rfl @[simp] -lemma obs0_bayesEnv : (bayesEnv Q ΞΊ).obs0 = Q.prod (Measure.dirac ()) := rfl +lemma obs0_bayesStationaryEnv : (bayesStationaryEnv Q ΞΊ).obs0 = Q.prod (Measure.dirac ()) := rfl @[simp] -lemma Ξ½0_bayesEnv : (bayesEnv Q ΞΊ).Ξ½0 = ΞΊ.comap (fun p ↦ (p.1.1, p.2)) (by fun_prop) := rfl +lemma Ξ½0_bayesStationaryEnv : + (bayesStationaryEnv Q ΞΊ).Ξ½0 = ΞΊ.comap (fun p ↦ (p.1.1, p.2)) (by fun_prop) := rfl end BayesEnv @@ -121,14 +122,14 @@ and feedbacks `Y : β„• β†’ Ξ© β†’ 𝓨` are generated by the algorithm `alg : Al interacting with an underlying environment that depends on `E` and `ΞΊ` (`stationaryEnv (ΞΊ.sectR (E Ο‰))`). -This is `IsAlgEnvSeq` for the announcing environment `bayesEnv Q ΞΊ` and the algorithm +This is `IsAlgEnvSeq` for the announcing environment `bayesStationaryEnv Q ΞΊ` and the algorithm `alg.comapObs Prod.snd` that ignores the announced parameter: the observation at every round is `(E Ο‰, ())`. -/ def IsBayesAlgEnvSeq (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) [IsMarkovKernel ΞΊ] (alg : Algorithm Unit 𝓐 𝓨) (E : Ξ© β†’ 𝓔) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) (P : Measure Ξ©) [IsProbabilityMeasure P] : Prop := - IsAlgEnvSeq (fun _ Ο‰ ↦ (E Ο‰, ())) A Y (alg.comapObs Prod.snd) (bayesEnv Q ΞΊ) P + IsAlgEnvSeq (fun _ Ο‰ ↦ (E Ο‰, ())) A Y (alg.comapObs Prod.snd) (bayesStationaryEnv Q ΞΊ) P namespace IsBayesAlgEnvSeq @@ -159,13 +160,13 @@ lemma mk (hasLaw_env : HasLaw E Q P) Β· intro n cases n with | zero => - rw [history_zero, obs_bayesEnv_zero] + rw [history_zero, obs_bayesStationaryEnv_zero] refine HasLaw.hasCondDistrib_const ⟨(hO 0).aemeasurable, ?_⟩ rw [Kernel.const_apply, Measure.prod_dirac, ← hasLaw_env.map_eq, AEMeasurable.map_map_of_aemeasurable (by fun_prop) hasLaw_env.aemeasurable] rfl | succ n => - rw [obs_bayesEnv_succ] + rw [obs_bayesStationaryEnv_succ] exact hasCondDistrib_deterministic _ (measurable_history hO measurable_action measurable_feedback (n + 1)).aemeasurable (ae_of_all _ fun _ ↦ rfl) @@ -184,9 +185,9 @@ lemma mk (hasLaw_env : HasLaw E Q P) (hasCondDistrib_feedback n) /-- A Bayesian algorithm-environment sequence is an algorithm-environment sequence for the -announcing environment `bayesEnv Q ΞΊ`. -/ +announcing environment `bayesStationaryEnv Q ΞΊ`. -/ lemma isAlgEnvSeq (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : - IsAlgEnvSeq (fun _ Ο‰ ↦ (E Ο‰, ())) A Y (alg.comapObs Prod.snd) (bayesEnv Q ΞΊ) P := h + IsAlgEnvSeq (fun _ Ο‰ ↦ (E Ο‰, ())) A Y (alg.comapObs Prod.snd) (bayesStationaryEnv Q ΞΊ) P := h lemma measurable_param (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : Measurable E := (h.isAlgEnvSeq.measurable_obs 0).fst @@ -327,25 +328,26 @@ variable {Q : Measure 𝓔} [IsProbabilityMeasure Q] {ΞΊ : Kernel (𝓔 Γ— 𝓐) variable {alg : Algorithm Unit 𝓐 𝓨} {O : β„• β†’ Ξ© β†’ 𝓔 Γ— Unit} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} variable {P : Measure Ξ©} [IsProbabilityMeasure P] -/-- Under `bayesEnv Q ΞΊ`, the announced parameter is almost surely the same at every round. -/ +/-- Under `bayesStationaryEnv Q ΞΊ`, the announced parameter is almost surely the same at every +round. -/ lemma IsAlgEnvSeq.ae_obs_eq_obs_zero [StandardBorelSpace 𝓔] - (h : IsAlgEnvSeq O A Y (alg.comapObs Prod.snd) (bayesEnv Q ΞΊ) P) (n : β„•) : + (h : IsAlgEnvSeq O A Y (alg.comapObs Prod.snd) (bayesStationaryEnv Q ΞΊ) P) (n : β„•) : (fun Ο‰ ↦ ((O 0 Ο‰).1, ())) =ᡐ[P] O n := by cases n with | zero => exact ae_of_all _ fun _ ↦ rfl | succ n => have h1 := h.hasCondDistrib_obs (n + 1) - rw [obs_bayesEnv_succ] at h1 + rw [obs_bayesStationaryEnv_succ] at h1 have h2 := ae_eq_of_hasCondDistrib_deterministic (by fun_prop) (h.measurable_history (n + 1)).aemeasurable (h.measurable_obs (n + 1)).aemeasurable h1 filter_upwards [h2] with Ο‰ hΟ‰ rw [hΟ‰] simp [history_apply] -/-- A run of `alg.comapObs Prod.snd` against the announcing environment `bayesEnv Q ΞΊ` is a -Bayesian algorithm-environment sequence for the announced parameter. -/ +/-- A run of `alg.comapObs Prod.snd` against the announcing environment `bayesStationaryEnv Q ΞΊ` +is a Bayesian algorithm-environment sequence for the announced parameter. -/ lemma IsAlgEnvSeq.isBayesAlgEnvSeq [StandardBorelSpace 𝓔] - (h : IsAlgEnvSeq O A Y (alg.comapObs Prod.snd) (bayesEnv Q ΞΊ) P) : + (h : IsAlgEnvSeq O A Y (alg.comapObs Prod.snd) (bayesStationaryEnv Q ΞΊ) P) : IsBayesAlgEnvSeq Q ΞΊ alg (fun Ο‰ ↦ (O 0 Ο‰).1) A Y P := h.congr (fun _ ↦ (h.measurable_obs 0).fst.prodMk measurable_const) h.measurable_action h.measurable_feedback h.ae_obs_eq_obs_zero @@ -360,10 +362,10 @@ namespace IT noncomputable def bayesTrajMeasure (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) [IsMarkovKernel ΞΊ] (alg : Algorithm Unit 𝓐 𝓨) : Measure (β„• β†’ Round (𝓔 Γ— Unit) 𝓐 𝓨) := - trajMeasure (alg.comapObs Prod.snd) (bayesEnv Q ΞΊ) + trajMeasure (alg.comapObs Prod.snd) (bayesStationaryEnv Q ΞΊ) deriving IsProbabilityMeasure -/-- The parameter announced by `bayesEnv Q ΞΊ`, read on the trajectory space. -/ +/-- The parameter announced by `bayesStationaryEnv Q ΞΊ`, read on the trajectory space. -/ def param (Ο„ : β„• β†’ Round (𝓔 Γ— Unit) 𝓐 𝓨) : 𝓔 := (IT.obs 0 Ο„).1 @[fun_prop] From 2f033db761cd423769e517584b37bae2bfb0676a Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Fri, 28 Aug 2026 13:15:59 +0200 Subject: [PATCH 04/21] remove Unit --- .../BayesStationaryEnv.lean | 132 ++++++++---------- 1 file changed, 57 insertions(+), 75 deletions(-) diff --git a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean index d2b3a7d4..48e5cf48 100644 --- a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean +++ b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean @@ -16,8 +16,8 @@ A Bayesian stationary environment is an environment that draws a parameter `e : `stationaryEnv (ΞΊ.sectR e)`. Following the "announced variables" mechanism of `LeanMachineLearning/SequentialLearning/Announce.lean`, the parameter is not hidden: it is part of the environment's move, and the algorithm is the one that ignores it. Concretely, -`bayesStationaryEnv Q ΞΊ : Environment (𝓔 Γ— Unit) 𝓐 𝓨` announces `e` in every observation and runs -against `alg.comapObs Prod.snd`, for an `alg : Algorithm Unit 𝓐 𝓨`. +`bayesStationaryEnv Q ΞΊ : Environment 𝓔 𝓐 𝓨` announces `e` as the observation of every round and +runs against `alg.comapObs (fun _ ↦ ())`, for an `alg : Algorithm Unit 𝓐 𝓨`. The predicate `IsBayesAlgEnvSeq` is not a new notion of run: it is `IsAlgEnvSeq` for that pair, for the observation process that announces the parameter `E` at every round. @@ -25,16 +25,16 @@ for the observation process that announces the parameter `E` at every round. ## Main definitions * `bayesStationaryEnv Q ΞΊ`: the environment that draws a parameter from `Q` before the first - round, announces it in the first component of every observation, and returns feedback `ΞΊ (e, a)` - when the parameter is `e` and the action is `a`. + round, announces it as the observation of every round, and returns feedback `ΞΊ (e, a)` when the + parameter is `e` and the action is `a`. * `IsBayesAlgEnvSeq Q ΞΊ alg E A Y P`: states that the parameter `E : Ξ© β†’ 𝓔` has law `Q` and that the sequences of actions `A : β„• β†’ Ξ© β†’ 𝓐` and feedbacks `Y : β„• β†’ Ξ© β†’ 𝓨` are generated by the algorithm `alg : Algorithm Unit 𝓐 𝓨` interacting with `bayesStationaryEnv Q ΞΊ`, which it sees - through `Algorithm.comapObs Prod.snd`. Equivalently, `A` and `Y` are generated by `alg` + through `Algorithm.comapObs (fun _ ↦ ())`. Equivalently, `A` and `Y` are generated by `alg` interacting with the stationary environment `stationaryEnv (ΞΊ.sectR (E Ο‰))`. * `bayesTrajMeasure Q ΞΊ alg`: for any choice of probability measure `Q : Measure 𝓔`, Markov kernel `ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨`, and algorithm `alg : Algorithm Unit 𝓐 𝓨`, provides a probability measure - `P : Measure (β„• β†’ Round (𝓔 Γ— Unit) 𝓐 𝓨)` on a space that carries `E`, `A`, and `Y` such that + `P : Measure (β„• β†’ Round 𝓔 𝓐 𝓨)` on a space that carries `E`, `A`, and `Y` such that `IsBayesAlgEnvSeq Q ΞΊ alg E A Y P`. * `bayesTrajMeasurePosterior Q ΞΊ alg n`: a `Kernel (Hist Unit 𝓐 𝓨 n) 𝓔` that represents the posterior over `E` given the history before time `n` (the `n` first rounds) under @@ -44,8 +44,8 @@ for the observation process that announces the parameter `E` at every round. ## Main results -* `IsAlgEnvSeq.isBayesAlgEnvSeq`: a run of `alg.comapObs Prod.snd` against `bayesStationaryEnv Q ΞΊ` - is a Bayesian algorithm-environment sequence for the announced parameter. +* `IsAlgEnvSeq.isBayesAlgEnvSeq`: a run of `alg.comapObs (fun _ ↦ ())` against + `bayesStationaryEnv Q ΞΊ` is a Bayesian algorithm-environment sequence for the announced parameter. * `ae_IsAlgEnvSeq h`: if `h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P`, for `Q`-almost every `e : 𝓔`, `IsAlgEnvSeq O' A' Y' alg (stationaryEnv (ΞΊ.sectR e)) (condDistrib (trajectory _ A Y) E P e)` for some sequence of actions `A' : β„• β†’ (β„• β†’ Round Unit 𝓐 𝓨) β†’ 𝓐` and sequence of feedbacks @@ -69,46 +69,44 @@ variable [MeasurableSpace 𝓔] [MeasurableSpace 𝓐] [MeasurableSpace 𝓨] [M section BayesEnv -/-- The environment that draws a parameter `e : 𝓔` from `Q` before the first round, announces it in -the first component of every observation, and returns a feedback drawn from `ΞΊ (e, a)` when the -action is `a`. The algorithm is meant to ignore the announced parameter, that is, to run through -`Algorithm.comapObs Prod.snd`. -/ +/-- The environment that draws a parameter `e : 𝓔` from `Q` before the first round, announces it as +the observation of every round, and returns a feedback drawn from `ΞΊ (e, a)` when the action is +`a`. The algorithm is meant to ignore the announced parameter, that is, to run through +`Algorithm.comapObs (fun _ ↦ ())`. -/ noncomputable def bayesStationaryEnv (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) - [IsMarkovKernel ΞΊ] : Environment (𝓔 Γ— Unit) 𝓐 𝓨 where + [IsMarkovKernel ΞΊ] : Environment 𝓔 𝓐 𝓨 where obs - | 0 => Kernel.const _ (Q.prod (Measure.dirac ())) + | 0 => Kernel.const _ Q | _ + 1 => Kernel.deterministic (fun h ↦ (h 0).obs) (by fun_prop) - feedback _ := ΞΊ.comap (fun p ↦ (p.1.2.1, p.2)) (by fun_prop) + feedback _ := ΞΊ.comap (fun p ↦ (p.1.2, p.2)) (by fun_prop) isMarkovKernel_obs n := by cases n <;> infer_instance variable {Q : Measure 𝓔} [IsProbabilityMeasure Q] {ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨} [IsMarkovKernel ΞΊ] @[simp] -lemma obs_bayesStationaryEnv_zero : - (bayesStationaryEnv Q ΞΊ).obs 0 = Kernel.const _ (Q.prod (Measure.dirac ())) := rfl +lemma obs_bayesStationaryEnv_zero : (bayesStationaryEnv Q ΞΊ).obs 0 = Kernel.const _ Q := rfl @[simp] lemma obs_bayesStationaryEnv_succ (n : β„•) : (bayesStationaryEnv Q ΞΊ).obs (n + 1) - = Kernel.deterministic (fun h : Hist (𝓔 Γ— Unit) 𝓐 𝓨 (n + 1) ↦ (h 0).obs) (by fun_prop) := rfl + = Kernel.deterministic (fun h : Hist 𝓔 𝓐 𝓨 (n + 1) ↦ (h 0).obs) (by fun_prop) := rfl @[simp] lemma feedback_bayesStationaryEnv (n : β„•) : - (bayesStationaryEnv Q ΞΊ).feedback n = ΞΊ.comap (fun p ↦ (p.1.2.1, p.2)) (by fun_prop) := rfl + (bayesStationaryEnv Q ΞΊ).feedback n = ΞΊ.comap (fun p ↦ (p.1.2, p.2)) (by fun_prop) := rfl @[simp] -lemma obs0_bayesStationaryEnv : (bayesStationaryEnv Q ΞΊ).obs0 = Q.prod (Measure.dirac ()) := rfl +lemma obs0_bayesStationaryEnv : (bayesStationaryEnv Q ΞΊ).obs0 = Q := rfl @[simp] -lemma Ξ½0_bayesStationaryEnv : - (bayesStationaryEnv Q ΞΊ).Ξ½0 = ΞΊ.comap (fun p ↦ (p.1.1, p.2)) (by fun_prop) := rfl +lemma Ξ½0_bayesStationaryEnv : (bayesStationaryEnv Q ΞΊ).Ξ½0 = ΞΊ := rfl end BayesEnv -/-- Insert an announced parameter `e` into every round of an observable history. -/ -def announceHist (e : 𝓔) {n : β„•} (h : Hist Unit 𝓐 𝓨 n) : Hist (𝓔 Γ— Unit) 𝓐 𝓨 n := - fun i ↦ ((e, ()), (h i).action, (h i).feedback) +/-- Insert an announced parameter `e` as the observation of every round of an observable history. -/ +def announceHist (e : 𝓔) {n : β„•} (h : Hist Unit 𝓐 𝓨 n) : Hist 𝓔 𝓐 𝓨 n := + fun i ↦ (e, (h i).action, (h i).feedback) @[fun_prop] lemma measurable_announceHist (n : β„•) : @@ -123,13 +121,13 @@ interacting with an underlying environment that depends on `E` and `ΞΊ` (`stationaryEnv (ΞΊ.sectR (E Ο‰))`). This is `IsAlgEnvSeq` for the announcing environment `bayesStationaryEnv Q ΞΊ` and the algorithm -`alg.comapObs Prod.snd` that ignores the announced parameter: the observation at every round is -`(E Ο‰, ())`. -/ +`alg.comapObs (fun _ ↦ ())` that ignores the announced parameter: the observation at every round +is `E Ο‰`. -/ def IsBayesAlgEnvSeq (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) [IsMarkovKernel ΞΊ] (alg : Algorithm Unit 𝓐 𝓨) (E : Ξ© β†’ 𝓔) (A : β„• β†’ Ξ© β†’ 𝓐) (Y : β„• β†’ Ξ© β†’ 𝓨) (P : Measure Ξ©) [IsProbabilityMeasure P] : Prop := - IsAlgEnvSeq (fun _ Ο‰ ↦ (E Ο‰, ())) A Y (alg.comapObs Prod.snd) (bayesStationaryEnv Q ΞΊ) P + IsAlgEnvSeq (fun _ ↦ E) A Y (alg.comapObs (fun _ : 𝓔 ↦ ())) (bayesStationaryEnv Q ΞΊ) P namespace IsBayesAlgEnvSeq @@ -154,32 +152,27 @@ lemma mk (hasLaw_env : HasLaw E Q P) (measurable_action : βˆ€ n, Measurable (A n) := by fun_prop) (measurable_feedback : βˆ€ n, Measurable (Y n) := by fun_prop) : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P := by - have hO : βˆ€ _ : β„•, Measurable (fun Ο‰ ↦ ((E Ο‰, ()) : 𝓔 Γ— Unit)) := - fun _ ↦ measurable_param.prodMk measurable_const - refine IsAlgEnvSeq.mk hO measurable_action measurable_feedback ?_ ?_ ?_ + refine IsAlgEnvSeq.mk (fun _ ↦ measurable_param) measurable_action measurable_feedback ?_ ?_ ?_ Β· intro n cases n with | zero => rw [history_zero, obs_bayesStationaryEnv_zero] - refine HasLaw.hasCondDistrib_const ⟨(hO 0).aemeasurable, ?_⟩ - rw [Kernel.const_apply, Measure.prod_dirac, ← hasLaw_env.map_eq, - AEMeasurable.map_map_of_aemeasurable (by fun_prop) hasLaw_env.aemeasurable] - rfl + exact hasLaw_env.hasCondDistrib_const | succ n => rw [obs_bayesStationaryEnv_succ] exact hasCondDistrib_deterministic _ - (measurable_history hO measurable_action measurable_feedback (n + 1)).aemeasurable - (ae_of_all _ fun _ ↦ rfl) + (measurable_history (fun _ ↦ measurable_param) measurable_action measurable_feedback + (n + 1)).aemeasurable (ae_of_all _ fun _ ↦ rfl) Β· intro n exact HasCondDistrib.comp_right - (f := fun q : 𝓔 Γ— (Hist Unit 𝓐 𝓨 n Γ— Unit) ↦ (announceHist q.1 q.2.1, (q.1, q.2.2))) + (f := fun q : 𝓔 Γ— (Hist Unit 𝓐 𝓨 n Γ— Unit) ↦ (announceHist q.1 q.2.1, q.1)) (hf := by fun_prop) (Z := fun Ο‰ ↦ (E Ο‰, (history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰))) (hasCondDistrib_action n) Β· intro n exact HasCondDistrib.comp_right (f := fun q : (Hist Unit 𝓐 𝓨 n Γ— Unit) Γ— (𝓔 Γ— 𝓐) ↦ - ((announceHist q.2.1 q.1.1, (q.2.1, q.1.2)), q.2.2)) + ((announceHist q.2.1 q.1.1, q.2.1), q.2.2)) (hf := by fun_prop) (Z := fun Ο‰ ↦ ((history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰), (E Ο‰, A n Ο‰))) (hasCondDistrib_feedback n) @@ -187,10 +180,10 @@ lemma mk (hasLaw_env : HasLaw E Q P) /-- A Bayesian algorithm-environment sequence is an algorithm-environment sequence for the announcing environment `bayesStationaryEnv Q ΞΊ`. -/ lemma isAlgEnvSeq (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : - IsAlgEnvSeq (fun _ Ο‰ ↦ (E Ο‰, ())) A Y (alg.comapObs Prod.snd) (bayesStationaryEnv Q ΞΊ) P := h + IsAlgEnvSeq (fun _ ↦ E) A Y (alg.comapObs (fun _ : 𝓔 ↦ ())) (bayesStationaryEnv Q ΞΊ) P := h lemma measurable_param (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : Measurable E := - (h.isAlgEnvSeq.measurable_obs 0).fst + h.isAlgEnvSeq.measurable_obs 0 lemma measurable_action (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : Measurable (A n) := h.isAlgEnvSeq.measurable_action n @@ -202,12 +195,7 @@ lemma measurable_feedback (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : Me lemma hasLaw_env (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : HasLaw E Q P := by have h0 := h.isAlgEnvSeq.hasCondDistrib_obs 0 rw [history_zero] at h0 - have h1 : HasLaw (fun Ο‰ ↦ (E Ο‰, ())) (Q.prod (Measure.dirac ())) P := h0.hasLaw_of_const' - refine ⟨h.measurable_param.aemeasurable, ?_⟩ - have h2 : E = Prod.fst ∘ (fun Ο‰ ↦ (E Ο‰, ())) := rfl - rw [h2, ← Measure.map_map measurable_fst - (h.measurable_param.prodMk (measurable_const : Measurable fun _ : Ξ© ↦ ())), h1.map_eq] - exact Measure.fst_prod + exact h0.hasLaw_of_const' /-- The action at time `n` has the correct conditional distribution given the parameter and the history: it depends only on the history. -/ @@ -215,9 +203,9 @@ lemma hasCondDistrib_action (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : HasCondDistrib (A n) (fun Ο‰ ↦ (E Ο‰, (history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰))) ((alg.policy n).prodMkLeft _) P := HasCondDistrib.comp_right - (f := fun p : Hist (𝓔 Γ— Unit) 𝓐 𝓨 n Γ— (𝓔 Γ— Unit) ↦ (p.2.1, (Hist.mapObs Prod.snd p.1, p.2.2))) + (f := fun p : Hist 𝓔 𝓐 𝓨 n Γ— 𝓔 ↦ (p.2, (Hist.mapObs (fun _ ↦ ()) p.1, ()))) (hf := by fun_prop) - (Z := fun Ο‰ ↦ (history (fun _ Ο‰ ↦ (E Ο‰, ())) A Y n Ο‰, (E Ο‰, ()))) + (Z := fun Ο‰ ↦ (history (fun _ ↦ E) A Y n Ο‰, E Ο‰)) (h.isAlgEnvSeq.hasCondDistrib_action n) /-- The feedback at time `n` has the correct conditional distribution given the history, the @@ -226,10 +214,10 @@ lemma hasCondDistrib_feedback (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) HasCondDistrib (Y n) (fun Ο‰ ↦ ((history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰), (E Ο‰, A n Ο‰))) (ΞΊ.prodMkLeft _) P := HasCondDistrib.comp_right - (f := fun p : (Hist (𝓔 Γ— Unit) 𝓐 𝓨 n Γ— (𝓔 Γ— Unit)) Γ— 𝓐 ↦ - ((Hist.mapObs Prod.snd p.1.1, p.1.2.2), (p.1.2.1, p.2))) + (f := fun p : (Hist 𝓔 𝓐 𝓨 n Γ— 𝓔) Γ— 𝓐 ↦ + ((Hist.mapObs (fun _ ↦ ()) p.1.1, ()), (p.1.2, p.2))) (hf := by fun_prop) - (Z := fun Ο‰ ↦ ((history (fun _ Ο‰ ↦ (E Ο‰, ())) A Y n Ο‰, (E Ο‰, ())), A n Ο‰)) + (Z := fun Ο‰ ↦ ((history (fun _ ↦ E) A Y n Ο‰, E Ο‰), A n Ο‰)) (h.isAlgEnvSeq.hasCondDistrib_feedback n) lemma hasCondDistrib_action' (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : @@ -325,16 +313,16 @@ end IsBayesAlgEnvSeq section IsAlgEnvSeq variable {Q : Measure 𝓔} [IsProbabilityMeasure Q] {ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨} [IsMarkovKernel ΞΊ] -variable {alg : Algorithm Unit 𝓐 𝓨} {O : β„• β†’ Ξ© β†’ 𝓔 Γ— Unit} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} +variable {alg : Algorithm Unit 𝓐 𝓨} {O : β„• β†’ Ξ© β†’ 𝓔} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} variable {P : Measure Ξ©} [IsProbabilityMeasure P] /-- Under `bayesStationaryEnv Q ΞΊ`, the announced parameter is almost surely the same at every round. -/ lemma IsAlgEnvSeq.ae_obs_eq_obs_zero [StandardBorelSpace 𝓔] - (h : IsAlgEnvSeq O A Y (alg.comapObs Prod.snd) (bayesStationaryEnv Q ΞΊ) P) (n : β„•) : - (fun Ο‰ ↦ ((O 0 Ο‰).1, ())) =ᡐ[P] O n := by + (h : IsAlgEnvSeq O A Y (alg.comapObs (fun _ : 𝓔 ↦ ())) (bayesStationaryEnv Q ΞΊ) P) (n : β„•) : + O 0 =ᡐ[P] O n := by cases n with - | zero => exact ae_of_all _ fun _ ↦ rfl + | zero => rfl | succ n => have h1 := h.hasCondDistrib_obs (n + 1) rw [obs_bayesStationaryEnv_succ] at h1 @@ -344,38 +332,32 @@ lemma IsAlgEnvSeq.ae_obs_eq_obs_zero [StandardBorelSpace 𝓔] rw [hΟ‰] simp [history_apply] -/-- A run of `alg.comapObs Prod.snd` against the announcing environment `bayesStationaryEnv Q ΞΊ` -is a Bayesian algorithm-environment sequence for the announced parameter. -/ +/-- A run of `alg.comapObs (fun _ ↦ ())` against the announcing environment +`bayesStationaryEnv Q ΞΊ` is a Bayesian algorithm-environment sequence for the announced +parameter. -/ lemma IsAlgEnvSeq.isBayesAlgEnvSeq [StandardBorelSpace 𝓔] - (h : IsAlgEnvSeq O A Y (alg.comapObs Prod.snd) (bayesStationaryEnv Q ΞΊ) P) : - IsBayesAlgEnvSeq Q ΞΊ alg (fun Ο‰ ↦ (O 0 Ο‰).1) A Y P := - h.congr (fun _ ↦ (h.measurable_obs 0).fst.prodMk measurable_const) - h.measurable_action h.measurable_feedback h.ae_obs_eq_obs_zero - (fun _ ↦ .rfl) (fun _ ↦ .rfl) + (h : IsAlgEnvSeq O A Y (alg.comapObs (fun _ : 𝓔 ↦ ())) (bayesStationaryEnv Q ΞΊ) P) : + IsBayesAlgEnvSeq Q ΞΊ alg (O 0) A Y P := + h.congr (fun _ ↦ h.measurable_obs 0) h.measurable_action h.measurable_feedback + h.ae_obs_eq_obs_zero (fun _ ↦ .rfl) (fun _ ↦ .rfl) end IsAlgEnvSeq namespace IT /-- A measure `P` on a measurable space that carries random variables `E`, `A`, and `Y` such that -`IsBayesAlgEnvSeq Q ΞΊ alg E A Y P`. -/ +`IsBayesAlgEnvSeq Q ΞΊ alg E A Y P`. The parameter is the observation of the first round, +`IT.obs 0`. -/ noncomputable def bayesTrajMeasure (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) - [IsMarkovKernel ΞΊ] (alg : Algorithm Unit 𝓐 𝓨) : Measure (β„• β†’ Round (𝓔 Γ— Unit) 𝓐 𝓨) := - trajMeasure (alg.comapObs Prod.snd) (bayesStationaryEnv Q ΞΊ) + [IsMarkovKernel ΞΊ] (alg : Algorithm Unit 𝓐 𝓨) : Measure (β„• β†’ Round 𝓔 𝓐 𝓨) := + trajMeasure (alg.comapObs (fun _ : 𝓔 ↦ ())) (bayesStationaryEnv Q ΞΊ) deriving IsProbabilityMeasure -/-- The parameter announced by `bayesStationaryEnv Q ΞΊ`, read on the trajectory space. -/ -def param (Ο„ : β„• β†’ Round (𝓔 Γ— Unit) 𝓐 𝓨) : 𝓔 := (IT.obs 0 Ο„).1 - -@[fun_prop] -lemma measurable_param : Measurable (param (𝓔 := 𝓔) (𝓐 := 𝓐) (𝓨 := 𝓨)) := by - unfold param; fun_prop - lemma isBayesAlgEnvSeq_bayesTrajMeasure [StandardBorelSpace 𝓔] (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) [IsMarkovKernel ΞΊ] (alg : Algorithm Unit 𝓐 𝓨) : - IsBayesAlgEnvSeq Q ΞΊ alg param action feedback (bayesTrajMeasure Q ΞΊ alg) := + IsBayesAlgEnvSeq Q ΞΊ alg (obs 0) action feedback (bayesTrajMeasure Q ΞΊ alg) := (isAlgEnvSeq_trajMeasure _ _).isBayesAlgEnvSeq /-- A kernel that represents the posterior over `E` given the history before time `n`. -/ @@ -383,7 +365,7 @@ noncomputable def bayesTrajMeasurePosterior [StandardBorelSpace 𝓔] [Nonempty 𝓔] (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨) [IsMarkovKernel ΞΊ] (alg : Algorithm Unit 𝓐 𝓨) (n : β„•) : Kernel (Hist Unit 𝓐 𝓨 n) 𝓔 := - condDistrib param (history (noObs _) action feedback n) (bayesTrajMeasure Q ΞΊ alg) + condDistrib (obs 0) (history (noObs _) action feedback n) (bayesTrajMeasure Q ΞΊ alg) deriving IsMarkovKernel /-- The posterior given the empty history is the prior. -/ From a77a1f7d40b53dc22f5b5d1a7aae3548120d3d00 Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Fri, 28 Aug 2026 13:23:20 +0200 Subject: [PATCH 05/21] lake exe mk_all --- LeanMachineLearning.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LeanMachineLearning.lean b/LeanMachineLearning.lean index 4a508bf3..a3913a94 100644 --- a/LeanMachineLearning.lean +++ b/LeanMachineLearning.lean @@ -35,11 +35,11 @@ public import LeanMachineLearning.SequentialLearning.ActionIndicator public import LeanMachineLearning.SequentialLearning.Algorithm public import LeanMachineLearning.SequentialLearning.AlgorithmDensity public import LeanMachineLearning.SequentialLearning.AlgorithmDensityBayes -public import LeanMachineLearning.SequentialLearning.Announce public import LeanMachineLearning.SequentialLearning.Algorithms.RandomSampling.Basic public import LeanMachineLearning.SequentialLearning.Algorithms.RandomSampling.Tendsto public import LeanMachineLearning.SequentialLearning.Algorithms.RoundRobin public import LeanMachineLearning.SequentialLearning.Algorithms.Uniform +public import LeanMachineLearning.SequentialLearning.Announce public import LeanMachineLearning.SequentialLearning.BayesStationaryEnv public import LeanMachineLearning.SequentialLearning.Deterministic public import LeanMachineLearning.SequentialLearning.EvaluationEnv From b63bb028ceecd512de8fbaa6b1ca9300174b5c63 Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Fri, 28 Aug 2026 14:17:23 +0200 Subject: [PATCH 06/21] aux lemmas --- LeanMachineLearning.lean | 1 + .../MeasurableSpace/Embedding.lean | 12 ++++ .../MeasureTheory/MeasurableSpace/Option.lean | 58 +++++++++++++++ .../Kernel/Composition/MeasureCompProd.lean | 21 ++++++ .../SequentialLearning/Announce.lean | 71 +++++++++++++++++++ 5 files changed, 163 insertions(+) create mode 100644 LeanMachineLearning/ForMathlib/MeasureTheory/MeasurableSpace/Option.lean diff --git a/LeanMachineLearning.lean b/LeanMachineLearning.lean index a3913a94..796a0a4d 100644 --- a/LeanMachineLearning.lean +++ b/LeanMachineLearning.lean @@ -2,6 +2,7 @@ module -- shake: keep-all --deprecated_module: ignore public import LeanMachineLearning.ForMathlib.MeasureTheory.Measurable public import LeanMachineLearning.ForMathlib.MeasureTheory.MeasurableSpace.Embedding +public import LeanMachineLearning.ForMathlib.MeasureTheory.MeasurableSpace.Option public import LeanMachineLearning.ForMathlib.MeasureTheory.Measure.AbsolutelyContinuous public import LeanMachineLearning.ForMathlib.MeasureTheory.Order.Lattice public import LeanMachineLearning.ForMathlib.MeasureTheory.Order.MeasurableArg diff --git a/LeanMachineLearning/ForMathlib/MeasureTheory/MeasurableSpace/Embedding.lean b/LeanMachineLearning/ForMathlib/MeasureTheory/MeasurableSpace/Embedding.lean index 47e61a4b..859212b0 100644 --- a/LeanMachineLearning/ForMathlib/MeasureTheory/MeasurableSpace/Embedding.lean +++ b/LeanMachineLearning/ForMathlib/MeasureTheory/MeasurableSpace/Embedding.lean @@ -26,6 +26,18 @@ learning algorithms (elements of `Fin n β†’ 𝓐 Γ— 𝓨` or `Iic n β†’ 𝓐 Γ— open Finset Preorder +/-- `Prod.mk x` is a measurable embedding as soon as `{x}` is measurable. This generalises +`measurableEmbedding_prodMk_left`, which assumes `MeasurableSingletonClass`. -/ +lemma measurableEmbedding_prodMk_left_of_measurableSet {Ξ± Ξ² : Type*} [MeasurableSpace Ξ±] + [MeasurableSpace Ξ²] {x : Ξ±} (hx : MeasurableSet {x}) : + MeasurableEmbedding (Prod.mk x : Ξ² β†’ Ξ± Γ— Ξ²) where + injective _ _ h := (Prod.ext_iff.mp h).2 + measurable := by fun_prop + measurableSet_image' s hs := by + convert! hx.prod hs + ext p + simp [Prod.ext_iff, eq_comm, and_left_comm] + lemma coe_default_Iic_zero : ((default : Iic 0) : β„•) = 0 := rfl namespace MeasurableEquiv diff --git a/LeanMachineLearning/ForMathlib/MeasureTheory/MeasurableSpace/Option.lean b/LeanMachineLearning/ForMathlib/MeasureTheory/MeasurableSpace/Option.lean new file mode 100644 index 00000000..0c0dd77c --- /dev/null +++ b/LeanMachineLearning/ForMathlib/MeasureTheory/MeasurableSpace/Option.lean @@ -0,0 +1,58 @@ +/- +Copyright (c) 2026 RΓ©my Degenne. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: RΓ©my Degenne +-/ +module + +public import Mathlib.MeasureTheory.MeasurableSpace.Constructions +public import Mathlib.MeasureTheory.MeasurableSpace.Embedding + +/-! +# The measurable space structure on `Option Ξ±` + +`Option Ξ±` is the disjoint union of `Ξ±` and the singleton `{none}`: a set of `Option Ξ±` is +measurable if and only if its preimage under `Option.some` is measurable. Equivalently, a function +out of `Option Ξ±` is measurable if and only if its restriction to `Ξ±` is. +-/ + +@[expose] public section + +/-- The measurable space structure on `Option Ξ±`, in which a set is measurable if and only if its +preimage under `Option.some` is measurable. This makes `Option Ξ±` the disjoint union of `Ξ±` and the +measurable atom `{none}`. -/ +instance Option.instMeasurableSpace {Ξ± : Type*} [MeasurableSpace Ξ±] : + MeasurableSpace (Option Ξ±) where + MeasurableSet' s := MeasurableSet (Option.some ⁻¹' s) + measurableSet_empty := by simp + measurableSet_compl s hs := by + rw [Set.preimage_compl] + exact hs.compl + measurableSet_iUnion f hf := by + rw [Set.preimage_iUnion] + exact MeasurableSet.iUnion hf + +variable {Ξ± Ξ² : Type*} [MeasurableSpace Ξ±] [MeasurableSpace Ξ²] + +lemma measurableSet_option_iff {s : Set (Option Ξ±)} : + MeasurableSet s ↔ MeasurableSet (Option.some ⁻¹' s) := Iff.rfl + +/-- A function out of `Option Ξ±` is measurable if and only if its restriction along `Option.some` +is measurable: no condition is imposed at `none`. -/ +lemma measurable_option_iff {f : Option Ξ± β†’ Ξ²} : Measurable f ↔ Measurable (f ∘ Option.some) := + Iff.rfl + +@[fun_prop] +lemma measurable_some : Measurable (Option.some : Ξ± β†’ Option Ξ±) := fun _ hs ↦ hs + +lemma measurableEmbedding_some : MeasurableEmbedding (Option.some : Ξ± β†’ Option Ξ±) where + injective := Option.some_injective Ξ± + measurable := measurable_some + measurableSet_image' s hs := by + rw [measurableSet_option_iff, Set.preimage_image_eq _ (Option.some_injective Ξ±)] + exact hs + +@[simp] +lemma measurableSet_singleton_none : MeasurableSet ({none} : Set (Option Ξ±)) := by + rw [measurableSet_option_iff, Set.preimage_singleton_eq_empty.2 (by simp)] + exact MeasurableSet.empty diff --git a/LeanMachineLearning/ForMathlib/Probability/Kernel/Composition/MeasureCompProd.lean b/LeanMachineLearning/ForMathlib/Probability/Kernel/Composition/MeasureCompProd.lean index e2f2aec7..34a14d3f 100644 --- a/LeanMachineLearning/ForMathlib/Probability/Kernel/Composition/MeasureCompProd.lean +++ b/LeanMachineLearning/ForMathlib/Probability/Kernel/Composition/MeasureCompProd.lean @@ -5,6 +5,7 @@ Authors: Paulo Rauber -/ module +public import Mathlib.Probability.Kernel.Composition.MeasureComp public import Mathlib.Probability.Kernel.Composition.MeasureCompProd /-! # Lemmas about measure composition-product @@ -32,3 +33,23 @@ lemma AbsolutelyContinuous.compProd_left_apply {Ξ³ : Type*} {mΞ³ : MeasurableSpa end AbsolutelyContinuous end MeasureTheory.Measure + +namespace ProbabilityTheory.Kernel + +variable {Ξ± Ξ² Ξ³ : Type*} {mΞ± : MeasurableSpace Ξ±} {mΞ² : MeasurableSpace Ξ²} {mΞ³ : MeasurableSpace Ξ³} + +/-- Recording a measurable function of a draw: mapping a kernel to the graph of `f` is the +composition-product of that kernel with the deterministic kernel given by `f`. This is how an +algorithm announces a variable that it then uses deterministically. -/ +lemma map_graph (ΞΊ : Kernel Ξ± Ξ²) [IsSFiniteKernel ΞΊ] {f : Ξ² β†’ Ξ³} (hf : Measurable f) : + ΞΊ.map (fun b ↦ (b, f b)) + = ΞΊ βŠ—β‚– Kernel.deterministic (fun p : Ξ± Γ— Ξ² ↦ f p.2) (by fun_prop) := by + ext a : 1 + have h_sectR : (Kernel.deterministic (fun p : Ξ± Γ— Ξ² ↦ f p.2) (by fun_prop)).sectR a + = Kernel.deterministic f hf := by + ext b : 1 + rw [Kernel.sectR_apply, Kernel.deterministic_apply, Kernel.deterministic_apply] + rw [Kernel.map_apply _ (by fun_prop), Kernel.compProd_apply_eq_compProd_sectR, h_sectR, + MeasureTheory.Measure.compProd_deterministic] + +end ProbabilityTheory.Kernel diff --git a/LeanMachineLearning/SequentialLearning/Announce.lean b/LeanMachineLearning/SequentialLearning/Announce.lean index 8c346371..06bf35c3 100644 --- a/LeanMachineLearning/SequentialLearning/Announce.lean +++ b/LeanMachineLearning/SequentialLearning/Announce.lean @@ -38,6 +38,8 @@ that forgets the announced variable. is `y`. * `Environment.comapAction env f`: the environment that reads `f a` when the algorithm plays `a`, both in the current round and in the past rounds. +* `Algorithm.IgnoresAnnounced algZ alg`: the announcing algorithm `algZ` does not read the variables + it announced in the past rounds, and the law of the action it plays is `alg.policy n`. ## Main statements @@ -51,6 +53,14 @@ that forgets the announced variable. * `IsAlgEnvSeq.map_trajectory_comapObs`, `IsAlgEnvSeq.map_trajectory_comapFeedback`, `IsAlgEnvSeq.map_trajectory_comapAction`: the law of the trajectory that a player sees is the image of `trajMeasure` under the forgetful map. +* `IsAlgEnvSeq.hasCondDistrib_announced`: in a run of an announcing algorithm, the announced + variable of round `n` has the first marginal of the policy for conditional distribution. It is an + honest random variable of the run, not a variable integrated out inside the policy kernel. +* `IsAlgEnvSeq.isAlgEnvSeq_of_ignoresAnnounced`: **projection of a run**. If the announcing + algorithm does not read its own past announcements, the observable part of a run of it against + `env.comapAction Prod.snd` is a run of the behavioral algorithm against `env`. This is the case of + the projection theorem in which the announced variable is redrawn from the observable history at + every round; it needs no disintegration. -/ @@ -228,6 +238,28 @@ lemma Environment.Ξ½0_comapAction (env : Environment π“ž 𝓐 𝓨) (f : 𝓐' rw [Environment.Ξ½0_apply, feedback_comapAction, Kernel.comap_apply, env.feedback_zero, Kernel.comap_apply] +/-- An announcing algorithm `algZ : Algorithm π“ž (𝓩 Γ— 𝓐) 𝓨` *ignores its own announcements*, with +behavioral algorithm `alg`, if the law of the action it plays given the past rounds and the current +observation does not depend on the variables announced in the past rounds, and is `alg.policy n`. + +Announcing algorithms that redraw their announced variable from the observable history at every +round satisfy this; algorithms that reuse a variable drawn once (a mixture component, a random +permutation) do not, and their projection needs a disintegration argument. -/ +def Algorithm.IgnoresAnnounced {𝓩 : Type*} [MeasurableSpace 𝓩] + (algZ : Algorithm π“ž (𝓩 Γ— 𝓐) 𝓨) (alg : Algorithm π“ž 𝓐 𝓨) : Prop := + βˆ€ n, (algZ.policy n).snd + = (alg.policy n).comap (fun p ↦ (Hist.mapAction Prod.snd p.1, p.2)) (by fun_prop) + +lemma Algorithm.IgnoresAnnounced.comapObs {𝓩 : Type*} [MeasurableSpace 𝓩] + {algZ : Algorithm π“ž (𝓩 Γ— 𝓐) 𝓨} {alg : Algorithm π“ž 𝓐 𝓨} (h : algZ.IgnoresAnnounced alg) + (f : π“ž' β†’ π“ž) (hf : Measurable f) : + (algZ.comapObs f hf).IgnoresAnnounced (alg.comapObs f hf) := by + intro n + have h_snd : ((algZ.comapObs f hf).policy n).snd + = ((algZ.policy n).snd).comap (fun p ↦ (Hist.mapObs f p.1, f p.2)) (by fun_prop) := rfl + rw [h_snd, h n] + rfl + end Comap section Runs @@ -330,6 +362,45 @@ lemma map_trajectory_comapAction [IsProbabilityMeasure P] {alg : Algorithm π“ž end ComapAction +section Announcing + +variable {𝓩 : Type*} {m𝓩 : MeasurableSpace 𝓩} {env : Environment π“ž 𝓐 𝓨} + {algZ : Algorithm π“ž (𝓩 Γ— 𝓐) 𝓨} {O : β„• β†’ Ξ© β†’ π“ž} {B : β„• β†’ Ξ© β†’ 𝓩 Γ— 𝓐} + +/-- The announced variable of round `n`, given the past rounds and the current observation, has the +first marginal of the policy for conditional distribution. It is an honest random variable of the +run, not a variable integrated out inside the policy kernel. -/ +lemma hasCondDistrib_announced {env' : Environment π“ž (𝓩 Γ— 𝓐) 𝓨} + (h : IsAlgEnvSeq O B Y algZ env' P) (n : β„•) : + HasCondDistrib (fun Ο‰ ↦ (B n Ο‰).1) (fun Ο‰ ↦ (history O B Y n Ο‰, O n Ο‰)) + (algZ.policy n).fst P := + (h.hasCondDistrib_action n).fst + +/-- **Projection of a run of an announcing algorithm.** If `algZ` announces a variable in `𝓩` and +does not read its own past announcements, then the observable part of a run of `algZ` against +`env.comapAction Prod.snd` is a run of the behavioral algorithm `alg` against `env`. The announced +variables are honest random variables of that run. + +This is the special case of the projection theorem in which the announced variable is redrawn from +the observable history at every round; it needs no disintegration. -/ +lemma isAlgEnvSeq_of_ignoresAnnounced {alg : Algorithm π“ž 𝓐 𝓨} + (h : IsAlgEnvSeq O B Y algZ (env.comapAction Prod.snd) P) + (h_alg : algZ.IgnoresAnnounced alg) : + IsAlgEnvSeq O (fun n Ο‰ ↦ (B n Ο‰).2) Y alg env P where + measurable_obs := h.measurable_obs + measurable_action n := (h.measurable_action n).snd + measurable_feedback := h.measurable_feedback + hasCondDistrib_obs n := h.hasCondDistrib_obs_comapAction n + hasCondDistrib_feedback n := h.hasCondDistrib_feedback_comapAction n + hasCondDistrib_action n := by + have h1 := (h.hasCondDistrib_action n).snd + rw [h_alg n] at h1 + exact HasCondDistrib.comp_right + (f := fun p : Hist π“ž (𝓩 Γ— 𝓐) 𝓨 n Γ— π“ž ↦ (Hist.mapAction Prod.snd p.1, p.2)) + (hf := by fun_prop) (Z := fun Ο‰ ↦ (history O B Y n Ο‰, O n Ο‰)) h1 + +end Announcing + end IsAlgEnvSeq end Runs From d0edf18500ebbeafa5270f6721c7f0b8924a1a70 Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Mon, 31 Aug 2026 13:44:50 +0200 Subject: [PATCH 07/21] split file, add generic comap --- LeanMachineLearning.lean | 1 + .../SequentialLearning/Algorithm.lean | 2 + .../SequentialLearning/Announce.lean | 304 +--------- .../BayesStationaryEnv.lean | 1 + .../SequentialLearning/Comap.lean | 570 ++++++++++++++++++ 5 files changed, 583 insertions(+), 295 deletions(-) create mode 100644 LeanMachineLearning/SequentialLearning/Comap.lean diff --git a/LeanMachineLearning.lean b/LeanMachineLearning.lean index 796a0a4d..3491eb85 100644 --- a/LeanMachineLearning.lean +++ b/LeanMachineLearning.lean @@ -42,6 +42,7 @@ public import LeanMachineLearning.SequentialLearning.Algorithms.RoundRobin public import LeanMachineLearning.SequentialLearning.Algorithms.Uniform public import LeanMachineLearning.SequentialLearning.Announce public import LeanMachineLearning.SequentialLearning.BayesStationaryEnv +public import LeanMachineLearning.SequentialLearning.Comap public import LeanMachineLearning.SequentialLearning.Deterministic public import LeanMachineLearning.SequentialLearning.EvaluationEnv public import LeanMachineLearning.SequentialLearning.FeedbackMartingale diff --git a/LeanMachineLearning/SequentialLearning/Algorithm.lean b/LeanMachineLearning/SequentialLearning/Algorithm.lean index 87417109..4003b19d 100644 --- a/LeanMachineLearning/SequentialLearning/Algorithm.lean +++ b/LeanMachineLearning/SequentialLearning/Algorithm.lean @@ -99,6 +99,7 @@ abbrev Hist (π“ž 𝓐 𝓨 : Type*) (n : β„•) := Fin n β†’ Round π“ž 𝓐 𝓨 /-- A stochastic, sequential algorithm. At each round, it sees an observation in `π“ž`, then takes an action in `𝓐`, and finally receives feedback in `𝓨`. The action is a random function of the past rounds and the current observation. -/ +@[ext] structure Algorithm (π“ž 𝓐 𝓨 : Type*) [MeasurableSpace π“ž] [MeasurableSpace 𝓐] [MeasurableSpace 𝓨] where /-- Law of the action of round `n` given the past rounds and the current observation. -/ @@ -112,6 +113,7 @@ instance (alg : Algorithm π“ž 𝓐 𝓨) (n : β„•) : IsMarkovKernel (alg.policy /-- A stochastic environment. At each round, an observation is drawn prior to the algorithm taking an action. Then the environment provides feedback based on the observation and the action. -/ +@[ext] structure Environment (π“ž 𝓐 𝓨 : Type*) [MeasurableSpace π“ž] [MeasurableSpace 𝓐] [MeasurableSpace 𝓨] where /-- Law of the observation of round `n` given the past rounds. -/ diff --git a/LeanMachineLearning/SequentialLearning/Announce.lean b/LeanMachineLearning/SequentialLearning/Announce.lean index 06bf35c3..3892a478 100644 --- a/LeanMachineLearning/SequentialLearning/Announce.lean +++ b/LeanMachineLearning/SequentialLearning/Announce.lean @@ -5,11 +5,13 @@ Authors: RΓ©my Degenne -/ module -public import LeanMachineLearning.SequentialLearning.IonescuTulceaSpace +public import LeanMachineLearning.SequentialLearning.Comap /-! # Announced variables +TODO + A hidden variable of one of the two players (memory or sampled index of the algorithm, parameter of the environment) is modelled by making it part of that player's move, while the other player is transported so as to ignore it: @@ -29,27 +31,11 @@ that forgets the announced variable. ## Main definitions -* `Round.map fo fa fy`, `Hist.map fo fa fy`, `Traj.map fo fa fy`: round-wise transport of a round, - a history and a trajectory along maps of the observation, the action and the feedback, with the - special cases `mapObs`, `mapAction` and `mapFeedback` that transport a single component. -* `Algorithm.comapObs alg f`: the algorithm that sees `f o` when the observation is `o`, both in - the current round and in the past rounds. -* `Algorithm.comapFeedback alg g`: the algorithm that sees `g y` when the feedback of a past round - is `y`. -* `Environment.comapAction env f`: the environment that reads `f a` when the algorithm plays `a`, - both in the current round and in the past rounds. * `Algorithm.IgnoresAnnounced algZ alg`: the announcing algorithm `algZ` does not read the variables it announced in the past rounds, and the law of the action it plays is `alg.policy n`. ## Main statements -* `IsAlgEnvSeq.hasCondDistrib_action_comapObs`, `IsAlgEnvSeq.hasCondDistrib_action_comapFeedback`: - in a run of `alg.comapObs f` (resp. `alg.comapFeedback g`) against any environment, the - conditional distribution of the action given the transported history and the transported - observation is `alg.policy n`. -* `IsAlgEnvSeq.hasCondDistrib_obs_comapAction`, `IsAlgEnvSeq.hasCondDistrib_feedback_comapAction`: - in a run against `env.comapAction f`, the observations and feedbacks have the conditional - distributions of a run of `env` on the transported actions. * `IsAlgEnvSeq.map_trajectory_comapObs`, `IsAlgEnvSeq.map_trajectory_comapFeedback`, `IsAlgEnvSeq.map_trajectory_comapAction`: the law of the trajectory that a player sees is the image of `trajMeasure` under the forgetful map. @@ -58,9 +44,7 @@ that forgets the announced variable. honest random variable of the run, not a variable integrated out inside the policy kernel. * `IsAlgEnvSeq.isAlgEnvSeq_of_ignoresAnnounced`: **projection of a run**. If the announcing algorithm does not read its own past announcements, the observable part of a run of it against - `env.comapAction Prod.snd` is a run of the behavioral algorithm against `env`. This is the case of - the projection theorem in which the announced variable is redrawn from the observable history at - every round; it needs no disintegration. + `env.comapAction Prod.snd` is a run of the behavioral algorithm against `env`. -/ @@ -70,173 +54,8 @@ open MeasureTheory ProbabilityTheory namespace Learning -variable {π“ž π“ž' 𝓐 𝓐' 𝓨 𝓨' Ξ© : Type*} - {mπ“ž : MeasurableSpace π“ž} {mπ“ž' : MeasurableSpace π“ž'} - {m𝓐 : MeasurableSpace 𝓐} {m𝓐' : MeasurableSpace 𝓐'} - {m𝓨 : MeasurableSpace 𝓨} {m𝓨' : MeasurableSpace 𝓨'} - {mΞ© : MeasurableSpace Ξ©} - {fo : π“ž β†’ π“ž'} {fa : 𝓐 β†’ 𝓐'} {fy : 𝓨 β†’ 𝓨'} - -section Map - -/-- Transport a round along maps of the observation, the action and the feedback. -/ -def Round.map (fo : π“ž β†’ π“ž') (fa : 𝓐 β†’ 𝓐') (fy : 𝓨 β†’ 𝓨') (r : Round π“ž 𝓐 𝓨) : Round π“ž' 𝓐' 𝓨' := - (fo r.obs, fa r.action, fy r.feedback) - -/-- Transport a history round-wise. -/ -def Hist.map (fo : π“ž β†’ π“ž') (fa : 𝓐 β†’ 𝓐') (fy : 𝓨 β†’ 𝓨') {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) : - Hist π“ž' 𝓐' 𝓨' n := - fun i ↦ Round.map fo fa fy (h i) - -/-- Transport a trajectory round-wise. -/ -def Traj.map (fo : π“ž β†’ π“ž') (fa : 𝓐 β†’ 𝓐') (fy : 𝓨 β†’ 𝓨') (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : - β„• β†’ Round π“ž' 𝓐' 𝓨' := - fun n ↦ Round.map fo fa fy (Ο„ n) - -@[simp] lemma Round.obs_map (r : Round π“ž 𝓐 𝓨) : (Round.map fo fa fy r).obs = fo r.obs := rfl -@[simp] lemma Round.action_map (r : Round π“ž 𝓐 𝓨) : - (Round.map fo fa fy r).action = fa r.action := rfl -@[simp] lemma Round.feedback_map (r : Round π“ž 𝓐 𝓨) : - (Round.map fo fa fy r).feedback = fy r.feedback := rfl - -@[simp] lemma Hist.map_apply {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) (i : Fin n) : - Hist.map fo fa fy h i = Round.map fo fa fy (h i) := rfl - -@[simp] lemma Traj.map_apply (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) (n : β„•) : - Traj.map fo fa fy Ο„ n = Round.map fo fa fy (Ο„ n) := rfl - -@[fun_prop] -lemma Round.measurable_map (hfo : Measurable fo) (hfa : Measurable fa) (hfy : Measurable fy) : - Measurable (Round.map fo fa fy) := by - unfold Round.map - fun_prop - -@[fun_prop] -lemma Hist.measurable_map (hfo : Measurable fo) (hfa : Measurable fa) (hfy : Measurable fy) - (n : β„•) : - Measurable (Hist.map fo fa fy (n := n)) := by - unfold Hist.map - fun_prop - -@[fun_prop] -lemma Traj.measurable_map (hfo : Measurable fo) (hfa : Measurable fa) (hfy : Measurable fy) : - Measurable (Traj.map fo fa fy) := by - unfold Traj.map - fun_prop - -/-- Transport the observations of a round. -/ -abbrev Round.mapObs (f : π“ž β†’ π“ž') (r : Round π“ž 𝓐 𝓨) : Round π“ž' 𝓐 𝓨 := Round.map f id id r - -/-- Transport the observations of a history. -/ -abbrev Hist.mapObs (f : π“ž β†’ π“ž') {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) : Hist π“ž' 𝓐 𝓨 n := - Hist.map f id id h - -/-- Transport the observations of a trajectory. -/ -abbrev Traj.mapObs (f : π“ž β†’ π“ž') (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : β„• β†’ Round π“ž' 𝓐 𝓨 := Traj.map f id id Ο„ - -/-- Transport the actions of a round. -/ -abbrev Round.mapAction (f : 𝓐 β†’ 𝓐') (r : Round π“ž 𝓐 𝓨) : Round π“ž 𝓐' 𝓨 := Round.map id f id r - -/-- Transport the actions of a history. -/ -abbrev Hist.mapAction (f : 𝓐 β†’ 𝓐') {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) : Hist π“ž 𝓐' 𝓨 n := - Hist.map id f id h - -/-- Transport the actions of a trajectory. -/ -abbrev Traj.mapAction (f : 𝓐 β†’ 𝓐') (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : β„• β†’ Round π“ž 𝓐' 𝓨 := - Traj.map id f id Ο„ - -/-- Transport the feedback of a round. -/ -abbrev Round.mapFeedback (f : 𝓨 β†’ 𝓨') (r : Round π“ž 𝓐 𝓨) : Round π“ž 𝓐 𝓨' := Round.map id id f r - -/-- Transport the feedback of a history. -/ -abbrev Hist.mapFeedback (f : 𝓨 β†’ 𝓨') {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) : Hist π“ž 𝓐 𝓨' n := - Hist.map id id f h - -/-- Transport the feedback of a trajectory. -/ -abbrev Traj.mapFeedback (f : 𝓨 β†’ 𝓨') (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : β„• β†’ Round π“ž 𝓐 𝓨' := - Traj.map id id f Ο„ - -variable {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} - -lemma history_map (n : β„•) : - history (fun n Ο‰ ↦ fo (O n Ο‰)) (fun n Ο‰ ↦ fa (A n Ο‰)) (fun n Ο‰ ↦ fy (Y n Ο‰)) n - = Hist.map fo fa fy ∘ history O A Y n := rfl - -lemma trajectory_map : - trajectory (fun n Ο‰ ↦ fo (O n Ο‰)) (fun n Ο‰ ↦ fa (A n Ο‰)) (fun n Ο‰ ↦ fy (Y n Ο‰)) - = Traj.map fo fa fy ∘ trajectory O A Y := rfl - -end Map - -section Comap - -/-- The algorithm that sees `f o` when the observation is `o`, both in the current round and in the -past rounds. -/ -def Algorithm.comapObs (alg : Algorithm π“ž 𝓐 𝓨) (f : π“ž' β†’ π“ž) - (hf : Measurable f := by fun_prop) : Algorithm π“ž' 𝓐 𝓨 where - policy n := (alg.policy n).comap (fun p ↦ (Hist.mapObs f p.1, f p.2)) (by fun_prop) - -@[simp] -lemma Algorithm.policy_comapObs (alg : Algorithm π“ž 𝓐 𝓨) (f : π“ž' β†’ π“ž) (hf : Measurable f) (n : β„•) : - (alg.comapObs f hf).policy n - = (alg.policy n).comap (fun p ↦ (Hist.mapObs f p.1, f p.2)) (by fun_prop) := rfl - -@[simp] -lemma Algorithm.p0_comapObs (alg : Algorithm π“ž 𝓐 𝓨) (f : π“ž' β†’ π“ž) (hf : Measurable f) : - (alg.comapObs f hf).p0 = alg.p0.comap f hf := by - ext o : 1 - rw [p0_apply, policy_comapObs, Kernel.comap_apply, alg.policy_zero, Kernel.comap_apply] - -/-- The algorithm that sees `g y` when the feedback of a past round is `y`. Together with -`Algorithm.comapObs`, this describes an algorithm that only sees a summary of each past round: -bandit feedback extracted from a loss vector, or an algorithm that ignores a variable that the -environment announces in the feedback. -/ -def Algorithm.comapFeedback (alg : Algorithm π“ž 𝓐 𝓨) (g : 𝓨' β†’ 𝓨) - (hg : Measurable g := by fun_prop) : Algorithm π“ž 𝓐 𝓨' where - policy n := (alg.policy n).comap (fun p ↦ (Hist.mapFeedback g p.1, p.2)) (by fun_prop) - -@[simp] -lemma Algorithm.policy_comapFeedback (alg : Algorithm π“ž 𝓐 𝓨) (g : 𝓨' β†’ 𝓨) (hg : Measurable g) - (n : β„•) : - (alg.comapFeedback g hg).policy n - = (alg.policy n).comap (fun p ↦ (Hist.mapFeedback g p.1, p.2)) (by fun_prop) := rfl - -@[simp] -lemma Algorithm.p0_comapFeedback (alg : Algorithm π“ž 𝓐 𝓨) (g : 𝓨' β†’ 𝓨) (hg : Measurable g) : - (alg.comapFeedback g hg).p0 = alg.p0 := by - ext o : 1 - rw [p0_apply, policy_comapFeedback, Kernel.comap_apply, alg.policy_zero, p0_apply] - -/-- The environment that reads `f a` when the algorithm plays `a`, both in the current round and in -the past rounds. -/ -def Environment.comapAction (env : Environment π“ž 𝓐 𝓨) (f : 𝓐' β†’ 𝓐) - (hf : Measurable f := by fun_prop) : Environment π“ž 𝓐' 𝓨 where - obs n := (env.obs n).comap (Hist.mapAction f) (by fun_prop) - feedback n := (env.feedback n).comap - (fun p ↦ ((Hist.mapAction f p.1.1, p.1.2), f p.2)) (by fun_prop) - -@[simp] -lemma Environment.obs_comapAction (env : Environment π“ž 𝓐 𝓨) (f : 𝓐' β†’ 𝓐) (hf : Measurable f) - (n : β„•) : - (env.comapAction f hf).obs n = (env.obs n).comap (Hist.mapAction f) (by fun_prop) := rfl - -@[simp] -lemma Environment.feedback_comapAction (env : Environment π“ž 𝓐 𝓨) (f : 𝓐' β†’ 𝓐) (hf : Measurable f) - (n : β„•) : - (env.comapAction f hf).feedback n = (env.feedback n).comap - (fun p ↦ ((Hist.mapAction f p.1.1, p.1.2), f p.2)) (by fun_prop) := rfl - -@[simp] -lemma Environment.obs0_comapAction (env : Environment π“ž 𝓐 𝓨) (f : 𝓐' β†’ 𝓐) (hf : Measurable f) : - (env.comapAction f hf).obs0 = env.obs0 := by - rw [Environment.obs0_def, obs_comapAction, Kernel.comap_apply, env.obs_zero] - -@[simp] -lemma Environment.Ξ½0_comapAction (env : Environment π“ž 𝓐 𝓨) (f : 𝓐' β†’ 𝓐) (hf : Measurable f) : - (env.comapAction f hf).Ξ½0 = env.Ξ½0.comap (fun p ↦ (p.1, f p.2)) (by fun_prop) := by - ext p : 1 - rw [Environment.Ξ½0_apply, feedback_comapAction, Kernel.comap_apply, env.feedback_zero, - Kernel.comap_apply] +variable {π“ž π“ž' 𝓐 𝓨 Ξ© : Type*} {mπ“ž : MeasurableSpace π“ž} {mπ“ž' : MeasurableSpace π“ž'} + {m𝓐 : MeasurableSpace 𝓐} {m𝓨 : MeasurableSpace 𝓨} {mΞ© : MeasurableSpace Ξ©} /-- An announcing algorithm `algZ : Algorithm π“ž (𝓩 Γ— 𝓐) 𝓨` *ignores its own announcements*, with behavioral algorithm `alg`, if the law of the action it plays given the past rounds and the current @@ -260,112 +79,11 @@ lemma Algorithm.IgnoresAnnounced.comapObs {𝓩 : Type*} [MeasurableSpace 𝓩] rw [h_snd, h n] rfl -end Comap - -section Runs - -variable {alg : Algorithm π“ž 𝓐 𝓨} {P : Measure Ξ©} [IsFiniteMeasure P] - {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} - namespace IsAlgEnvSeq -section ComapObs - -variable {env : Environment π“ž' 𝓐 𝓨} {f : π“ž' β†’ π“ž} {hf : Measurable f} {O : β„• β†’ Ξ© β†’ π“ž'} - -/-- The algorithm does not use the part of the observation that it ignores: the conditional -distribution of its action given the transported history and observation is its own policy. -/ -lemma hasCondDistrib_action_comapObs (h : IsAlgEnvSeq O A Y (alg.comapObs f hf) env P) (n : β„•) : - HasCondDistrib (A n) - (fun Ο‰ ↦ (history (fun n Ο‰ ↦ f (O n Ο‰)) A Y n Ο‰, f (O n Ο‰))) (alg.policy n) P := - HasCondDistrib.comp_right (f := fun p : Hist π“ž' 𝓐 𝓨 n Γ— π“ž' ↦ (Hist.mapObs f p.1, f p.2)) - (hf := by fun_prop) (h.hasCondDistrib_action n) - -/-- The law of the trajectory that the algorithm sees is the image of the law of the full -trajectory under the map that forgets the part of the observations that the algorithm ignores. -/ -lemma map_trajectory_comapObs [IsProbabilityMeasure P] - (h : IsAlgEnvSeq O A Y (alg.comapObs f hf) env P) : - P.map (trajectory (fun n Ο‰ ↦ f (O n Ο‰)) A Y) - = (trajMeasure (alg.comapObs f hf) env).map (Traj.mapObs f) := by - calc P.map (trajectory (fun n Ο‰ ↦ f (O n Ο‰)) A Y) - _ = P.map (Traj.mapObs f ∘ trajectory O A Y) := rfl - _ = (P.map (trajectory O A Y)).map (Traj.mapObs f) := - (Measure.map_map (by fun_prop) h.measurable_trajectory).symm - _ = (trajMeasure (alg.comapObs f hf) env).map (Traj.mapObs f) := by rw [h.map_trajectory] - -end ComapObs - -section ComapFeedback - -variable {env : Environment π“ž 𝓐 𝓨'} {g : 𝓨' β†’ 𝓨} {hg : Measurable g} {O : β„• β†’ Ξ© β†’ π“ž} - {Y' : β„• β†’ Ξ© β†’ 𝓨'} - -/-- The algorithm does not use the part of the past feedbacks that it ignores: the conditional -distribution of its action given the transported history and the observation is its own policy. -/ -lemma hasCondDistrib_action_comapFeedback - (h : IsAlgEnvSeq O A Y' (alg.comapFeedback g hg) env P) (n : β„•) : - HasCondDistrib (A n) - (fun Ο‰ ↦ (history O A (fun n Ο‰ ↦ g (Y' n Ο‰)) n Ο‰, O n Ο‰)) (alg.policy n) P := - HasCondDistrib.comp_right (f := fun p : Hist π“ž 𝓐 𝓨' n Γ— π“ž ↦ (Hist.mapFeedback g p.1, p.2)) - (hf := by fun_prop) (h.hasCondDistrib_action n) - -/-- The law of the trajectory that the algorithm sees is the image of the law of the full -trajectory under the map that forgets the part of the feedbacks that the algorithm ignores. -/ -lemma map_trajectory_comapFeedback [IsProbabilityMeasure P] - (h : IsAlgEnvSeq O A Y' (alg.comapFeedback g hg) env P) : - P.map (trajectory O A (fun n Ο‰ ↦ g (Y' n Ο‰))) - = (trajMeasure (alg.comapFeedback g hg) env).map (Traj.mapFeedback g) := by - calc P.map (trajectory O A (fun n Ο‰ ↦ g (Y' n Ο‰))) - _ = P.map (Traj.mapFeedback g ∘ trajectory O A Y') := rfl - _ = (P.map (trajectory O A Y')).map (Traj.mapFeedback g) := - (Measure.map_map (by fun_prop) h.measurable_trajectory).symm - _ = (trajMeasure (alg.comapFeedback g hg) env).map (Traj.mapFeedback g) := by - rw [h.map_trajectory] - -end ComapFeedback - -section ComapAction - -variable {env : Environment π“ž 𝓐 𝓨} {f : 𝓐' β†’ 𝓐} {hf : Measurable f} {O : β„• β†’ Ξ© β†’ π“ž} - {A' : β„• β†’ Ξ© β†’ 𝓐'} - -/-- The environment does not use the part of the action that it ignores: the conditional -distribution of the observation given the transported history is its own observation kernel. -/ -lemma hasCondDistrib_obs_comapAction {alg : Algorithm π“ž 𝓐' 𝓨} - (h : IsAlgEnvSeq O A' Y alg (env.comapAction f hf) P) (n : β„•) : - HasCondDistrib (O n) (history O (fun n Ο‰ ↦ f (A' n Ο‰)) Y n) (env.obs n) P := - HasCondDistrib.comp_right (f := Hist.mapAction (π“ž := π“ž) (𝓨 := 𝓨) f (n := n)) - (hf := by fun_prop) (h.hasCondDistrib_obs n) - -/-- The environment does not use the part of the action that it ignores: the conditional -distribution of the feedback given the transported history, the observation and the transported -action is its own feedback kernel. -/ -lemma hasCondDistrib_feedback_comapAction {alg : Algorithm π“ž 𝓐' 𝓨} - (h : IsAlgEnvSeq O A' Y alg (env.comapAction f hf) P) (n : β„•) : - HasCondDistrib (Y n) - (fun Ο‰ ↦ ((history O (fun n Ο‰ ↦ f (A' n Ο‰)) Y n Ο‰, O n Ο‰), f (A' n Ο‰))) (env.feedback n) P := - HasCondDistrib.comp_right - (f := fun p : (Hist π“ž 𝓐' 𝓨 n Γ— π“ž) Γ— 𝓐' ↦ ((Hist.mapAction f p.1.1, p.1.2), f p.2)) - (hf := by fun_prop) (h.hasCondDistrib_feedback n) - -/-- The law of the trajectory that the environment sees is the image of the law of the full -trajectory under the map that forgets the part of the actions that the environment ignores. -/ -lemma map_trajectory_comapAction [IsProbabilityMeasure P] {alg : Algorithm π“ž 𝓐' 𝓨} - (h : IsAlgEnvSeq O A' Y alg (env.comapAction f hf) P) : - P.map (trajectory O (fun n Ο‰ ↦ f (A' n Ο‰)) Y) - = (trajMeasure alg (env.comapAction f hf)).map (Traj.mapAction f) := by - calc P.map (trajectory O (fun n Ο‰ ↦ f (A' n Ο‰)) Y) - _ = P.map (Traj.mapAction f ∘ trajectory O A' Y) := rfl - _ = (P.map (trajectory O A' Y)).map (Traj.mapAction f) := - (Measure.map_map (by fun_prop) h.measurable_trajectory).symm - _ = (trajMeasure alg (env.comapAction f hf)).map (Traj.mapAction f) := by rw [h.map_trajectory] - -end ComapAction - -section Announcing - -variable {𝓩 : Type*} {m𝓩 : MeasurableSpace 𝓩} {env : Environment π“ž 𝓐 𝓨} - {algZ : Algorithm π“ž (𝓩 Γ— 𝓐) 𝓨} {O : β„• β†’ Ξ© β†’ π“ž} {B : β„• β†’ Ξ© β†’ 𝓩 Γ— 𝓐} +variable {𝓩 : Type*} {m𝓩 : MeasurableSpace 𝓩} {alg : Algorithm π“ž 𝓐 𝓨} {env : Environment π“ž 𝓐 𝓨} + {algZ : Algorithm π“ž (𝓩 Γ— 𝓐) 𝓨} {P : Measure Ξ©} [IsFiniteMeasure P] + {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {B : β„• β†’ Ξ© β†’ 𝓩 Γ— 𝓐} /-- The announced variable of round `n`, given the past rounds and the current observation, has the first marginal of the policy for conditional distribution. It is an honest random variable of the @@ -399,10 +117,6 @@ lemma isAlgEnvSeq_of_ignoresAnnounced {alg : Algorithm π“ž 𝓐 𝓨} (f := fun p : Hist π“ž (𝓩 Γ— 𝓐) 𝓨 n Γ— π“ž ↦ (Hist.mapAction Prod.snd p.1, p.2)) (hf := by fun_prop) (Z := fun Ο‰ ↦ (history O B Y n Ο‰, O n Ο‰)) h1 -end Announcing - end IsAlgEnvSeq -end Runs - end Learning diff --git a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean index 48e5cf48..8510d66e 100644 --- a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean +++ b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean @@ -6,6 +6,7 @@ Authors: Paulo Rauber, RΓ©my Degenne module public import LeanMachineLearning.SequentialLearning.Announce +public import LeanMachineLearning.SequentialLearning.IonescuTulceaSpace public import LeanMachineLearning.SequentialLearning.StationaryEnv /-! diff --git a/LeanMachineLearning/SequentialLearning/Comap.lean b/LeanMachineLearning/SequentialLearning/Comap.lean new file mode 100644 index 00000000..59d3f692 --- /dev/null +++ b/LeanMachineLearning/SequentialLearning/Comap.lean @@ -0,0 +1,570 @@ +/- +Copyright (c) 2026 RΓ©my Degenne. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: RΓ©my Degenne +-/ +module + +public import LeanMachineLearning.SequentialLearning.Algorithm + +/-! +# Transport of algorithms and environments + +## Main definitions + +* `Round.map fo fa fy`, `Hist.map fo fa fy`, `Traj.map fo fa fy`: round-wise transport of a round, + a history and a trajectory along maps of the observation, the action and the feedback, with the + special cases `mapObs`, `mapAction` and `mapFeedback` that transport a single component. +* `Algorithm.comap alg F hF`: the algorithm that transforms the pair (past rounds, current + observation) by the measurable map `F n` at round `n` before applying the policy of `alg`. +* `Algorithm.comapObs alg f`: the algorithm that sees `f o` when the observation is `o`, both in + the current round and in the past rounds. +* `Algorithm.comapFeedback alg g`: the algorithm that sees `g y` when the feedback of a past round + is `y`. +* `Environment.comap env F hF f hf`: the environment that reads the summary `F n` of the past + rounds and reads `f a` when the algorithm plays `a` in the current round. +* `Environment.comapAction env f`: the environment that reads `f a` when the algorithm plays `a`, + both in the current round and in the past rounds. +* `Algorithm.congr alg eπ“ž e𝓐 e𝓨`, `Environment.congr env eπ“ž e𝓐 e𝓨`: relabelling of the + observations, the actions and the feedbacks of a player along measurable equivalences. + +## Main statements + +* `IsAlgEnvSeq.hasCondDistrib_action_comapObs`, `IsAlgEnvSeq.hasCondDistrib_action_comapFeedback`: + in a run of `alg.comapObs f` (resp. `alg.comapFeedback g`) against any environment, the + conditional distribution of the action given the transported history and the transported + observation is `alg.policy n`. +* `IsAlgEnvSeq.hasCondDistrib_obs_comapAction`, `IsAlgEnvSeq.hasCondDistrib_feedback_comapAction`: + in a run against `env.comapAction f`, the observations and feedbacks have the conditional + distributions of a run of `env` on the transported actions. + +-/ + +@[expose] public section + +open MeasureTheory ProbabilityTheory + +namespace Learning + +variable {π“ž π“ž' π“ž'' 𝓐 𝓐' 𝓐'' 𝓨 𝓨' 𝓨'' Ξ© : Type*} + {mπ“ž : MeasurableSpace π“ž} {mπ“ž' : MeasurableSpace π“ž'} {mπ“ž'' : MeasurableSpace π“ž''} + {m𝓐 : MeasurableSpace 𝓐} {m𝓐' : MeasurableSpace 𝓐'} {m𝓐'' : MeasurableSpace 𝓐''} + {m𝓨 : MeasurableSpace 𝓨} {m𝓨' : MeasurableSpace 𝓨'} {m𝓨'' : MeasurableSpace 𝓨''} + {mΞ© : MeasurableSpace Ξ©} + {fo : π“ž β†’ π“ž'} {fa : 𝓐 β†’ 𝓐'} {fy : 𝓨 β†’ 𝓨'} + {go : π“ž' β†’ π“ž''} {ga : 𝓐' β†’ 𝓐''} {gy : 𝓨' β†’ 𝓨''} + +section Map + +/-- Transport a round along maps of the observation, the action and the feedback. -/ +def Round.map (fo : π“ž β†’ π“ž') (fa : 𝓐 β†’ 𝓐') (fy : 𝓨 β†’ 𝓨') (r : Round π“ž 𝓐 𝓨) : Round π“ž' 𝓐' 𝓨' := + (fo r.obs, fa r.action, fy r.feedback) + +/-- Transport a history round-wise. -/ +def Hist.map (fo : π“ž β†’ π“ž') (fa : 𝓐 β†’ 𝓐') (fy : 𝓨 β†’ 𝓨') {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) : + Hist π“ž' 𝓐' 𝓨' n := + fun i ↦ Round.map fo fa fy (h i) + +/-- Transport a trajectory round-wise. -/ +def Traj.map (fo : π“ž β†’ π“ž') (fa : 𝓐 β†’ 𝓐') (fy : 𝓨 β†’ 𝓨') (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : + β„• β†’ Round π“ž' 𝓐' 𝓨' := + fun n ↦ Round.map fo fa fy (Ο„ n) + +@[simp] lemma Round.obs_map (r : Round π“ž 𝓐 𝓨) : (Round.map fo fa fy r).obs = fo r.obs := rfl +@[simp] lemma Round.action_map (r : Round π“ž 𝓐 𝓨) : + (Round.map fo fa fy r).action = fa r.action := rfl +@[simp] lemma Round.feedback_map (r : Round π“ž 𝓐 𝓨) : + (Round.map fo fa fy r).feedback = fy r.feedback := rfl + +@[simp] lemma Hist.map_apply {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) (i : Fin n) : + Hist.map fo fa fy h i = Round.map fo fa fy (h i) := rfl + +@[simp] lemma Traj.map_apply (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) (n : β„•) : + Traj.map fo fa fy Ο„ n = Round.map fo fa fy (Ο„ n) := rfl + +@[simp] lemma Round.map_id : Round.map (id : π“ž β†’ π“ž) (id : 𝓐 β†’ 𝓐) (id : 𝓨 β†’ 𝓨) = id := rfl + +@[simp] lemma Hist.map_id {n : β„•} : + Hist.map (id : π“ž β†’ π“ž) (id : 𝓐 β†’ 𝓐) (id : 𝓨 β†’ 𝓨) (n := n) = id := rfl + +@[simp] lemma Traj.map_id : Traj.map (id : π“ž β†’ π“ž) (id : 𝓐 β†’ 𝓐) (id : 𝓨 β†’ 𝓨) = id := rfl + +lemma Round.map_comp (r : Round π“ž 𝓐 𝓨) : + Round.map go ga gy (Round.map fo fa fy r) = Round.map (go ∘ fo) (ga ∘ fa) (gy ∘ fy) r := rfl + +lemma Hist.map_comp {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) : + Hist.map go ga gy (Hist.map fo fa fy h) = Hist.map (go ∘ fo) (ga ∘ fa) (gy ∘ fy) h := rfl + +lemma Traj.map_comp (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : + Traj.map go ga gy (Traj.map fo fa fy Ο„) = Traj.map (go ∘ fo) (ga ∘ fa) (gy ∘ fy) Ο„ := rfl + +@[fun_prop] +lemma Round.measurable_map (hfo : Measurable fo) (hfa : Measurable fa) (hfy : Measurable fy) : + Measurable (Round.map fo fa fy) := by + unfold Round.map + fun_prop + +@[fun_prop] +lemma Hist.measurable_map (hfo : Measurable fo) (hfa : Measurable fa) (hfy : Measurable fy) + (n : β„•) : + Measurable (Hist.map fo fa fy (n := n)) := by + unfold Hist.map + fun_prop + +@[fun_prop] +lemma Traj.measurable_map (hfo : Measurable fo) (hfa : Measurable fa) (hfy : Measurable fy) : + Measurable (Traj.map fo fa fy) := by + unfold Traj.map + fun_prop + +/-- Transport the observations of a round. -/ +abbrev Round.mapObs (f : π“ž β†’ π“ž') (r : Round π“ž 𝓐 𝓨) : Round π“ž' 𝓐 𝓨 := Round.map f id id r + +/-- Transport the observations of a history. -/ +abbrev Hist.mapObs (f : π“ž β†’ π“ž') {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) : Hist π“ž' 𝓐 𝓨 n := + Hist.map f id id h + +/-- Transport the observations of a trajectory. -/ +abbrev Traj.mapObs (f : π“ž β†’ π“ž') (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : β„• β†’ Round π“ž' 𝓐 𝓨 := Traj.map f id id Ο„ + +/-- Transport the actions of a round. -/ +abbrev Round.mapAction (f : 𝓐 β†’ 𝓐') (r : Round π“ž 𝓐 𝓨) : Round π“ž 𝓐' 𝓨 := Round.map id f id r + +/-- Transport the actions of a history. -/ +abbrev Hist.mapAction (f : 𝓐 β†’ 𝓐') {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) : Hist π“ž 𝓐' 𝓨 n := + Hist.map id f id h + +/-- Transport the actions of a trajectory. -/ +abbrev Traj.mapAction (f : 𝓐 β†’ 𝓐') (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : β„• β†’ Round π“ž 𝓐' 𝓨 := + Traj.map id f id Ο„ + +/-- Transport the feedback of a round. -/ +abbrev Round.mapFeedback (f : 𝓨 β†’ 𝓨') (r : Round π“ž 𝓐 𝓨) : Round π“ž 𝓐 𝓨' := Round.map id id f r + +/-- Transport the feedback of a history. -/ +abbrev Hist.mapFeedback (f : 𝓨 β†’ 𝓨') {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) : Hist π“ž 𝓐 𝓨' n := + Hist.map id id f h + +/-- Transport the feedback of a trajectory. -/ +abbrev Traj.mapFeedback (f : 𝓨 β†’ 𝓨') (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : β„• β†’ Round π“ž 𝓐 𝓨' := + Traj.map id id f Ο„ + +variable {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} + +lemma history_map (n : β„•) : + history (fun n Ο‰ ↦ fo (O n Ο‰)) (fun n Ο‰ ↦ fa (A n Ο‰)) (fun n Ο‰ ↦ fy (Y n Ο‰)) n + = Hist.map fo fa fy ∘ history O A Y n := rfl + +lemma trajectory_map : + trajectory (fun n Ο‰ ↦ fo (O n Ο‰)) (fun n Ο‰ ↦ fa (A n Ο‰)) (fun n Ο‰ ↦ fy (Y n Ο‰)) + = Traj.map fo fa fy ∘ trajectory O A Y := rfl + +end Map + +section Comap + +/-- The algorithm with observations in `π“ž'` and feedbacks in `𝓨'` obtained from +`alg : Algorithm π“ž 𝓐 𝓨` by transforming the pair (past rounds, current observation) by `F n` at +each round `n` before applying the policy of `alg`. + +This is the primitive transport operation on algorithms: `Algorithm.comapObs` and +`Algorithm.comapFeedback` are the special cases in which `F n` is a round-wise map of the +observation and of the feedback. -/ +def Algorithm.comap (alg : Algorithm π“ž 𝓐 𝓨) + (F : (n : β„•) β†’ Hist π“ž' 𝓐 𝓨' n Γ— π“ž' β†’ Hist π“ž 𝓐 𝓨 n Γ— π“ž) (hF : βˆ€ n, Measurable (F n)) : + Algorithm π“ž' 𝓐 𝓨' where + policy n := (alg.policy n).comap (F n) (hF n) + +@[simp] +lemma Algorithm.policy_comap (alg : Algorithm π“ž 𝓐 𝓨) + {F : (n : β„•) β†’ Hist π“ž' 𝓐 𝓨' n Γ— π“ž' β†’ Hist π“ž 𝓐 𝓨 n Γ— π“ž} (hF : βˆ€ n, Measurable (F n)) (n : β„•) : + (alg.comap F hF).policy n = (alg.policy n).comap (F n) (hF n) := rfl + +@[simp] +lemma Algorithm.p0_comap (alg : Algorithm π“ž 𝓐 𝓨) + {F : (n : β„•) β†’ Hist π“ž' 𝓐 𝓨' n Γ— π“ž' β†’ Hist π“ž 𝓐 𝓨 n Γ— π“ž} (hF : βˆ€ n, Measurable (F n)) : + (alg.comap F hF).p0 + = alg.p0.comap (fun o ↦ (F 0 (default, o)).2) (((hF 0).comp measurable_prodMk_left).snd) := by + ext o : 1 + rw [p0_apply, policy_comap, Kernel.comap_apply, alg.policy_zero, Kernel.comap_apply] + +@[simp] +lemma Algorithm.comap_id (alg : Algorithm π“ž 𝓐 𝓨) : + alg.comap (fun _ ↦ id) (fun _ ↦ measurable_id) = alg := rfl + +lemma Algorithm.comap_comap (alg : Algorithm π“ž 𝓐 𝓨) + {F : (n : β„•) β†’ Hist π“ž' 𝓐 𝓨' n Γ— π“ž' β†’ Hist π“ž 𝓐 𝓨 n Γ— π“ž} (hF : βˆ€ n, Measurable (F n)) + {G : (n : β„•) β†’ Hist π“ž'' 𝓐 𝓨'' n Γ— π“ž'' β†’ Hist π“ž' 𝓐 𝓨' n Γ— π“ž'} (hG : βˆ€ n, Measurable (G n)) : + (alg.comap F hF).comap G hG = + alg.comap (fun n ↦ F n ∘ G n) fun n ↦ (hF n).comp (hG n) := rfl + +section ComapObs + +variable {f : π“ž' β†’ π“ž} + +/-- The algorithm that sees `f o` when the observation is `o`, both in the current round and in the +past rounds. -/ +def Algorithm.comapObs (alg : Algorithm π“ž 𝓐 𝓨) (f : π“ž' β†’ π“ž) + (hf : Measurable f := by fun_prop) : Algorithm π“ž' 𝓐 𝓨 := + alg.comap (fun _ p ↦ (Hist.mapObs f p.1, f p.2)) fun _ ↦ by fun_prop + +lemma Algorithm.comapObs_def (alg : Algorithm π“ž 𝓐 𝓨) (hf : Measurable f) : + alg.comapObs f hf = alg.comap (fun _ p ↦ (Hist.mapObs f p.1, f p.2)) fun _ ↦ by fun_prop := rfl + +@[simp] +lemma Algorithm.policy_comapObs (alg : Algorithm π“ž 𝓐 𝓨) (hf : Measurable f) (n : β„•) : + (alg.comapObs f hf).policy n + = (alg.policy n).comap (fun p ↦ (Hist.mapObs f p.1, f p.2)) (by fun_prop) := rfl + +@[simp] +lemma Algorithm.p0_comapObs (alg : Algorithm π“ž 𝓐 𝓨) (hf : Measurable f) : + (alg.comapObs f hf).p0 = alg.p0.comap f hf := by + ext o : 1 + rw [p0_apply, policy_comapObs, Kernel.comap_apply, alg.policy_zero, Kernel.comap_apply] + +@[simp] +lemma Algorithm.comapObs_id (alg : Algorithm π“ž 𝓐 𝓨) : alg.comapObs id measurable_id = alg := rfl + +lemma Algorithm.comapObs_comapObs (alg : Algorithm π“ž 𝓐 𝓨) (hf : Measurable f) + {g : π“ž'' β†’ π“ž'} (hg : Measurable g) : + (alg.comapObs f hf).comapObs g hg = alg.comapObs (f ∘ g) (hf.comp hg) := rfl + +end ComapObs + +section ComapFeedback + +variable {g : 𝓨' β†’ 𝓨} + +/-- The algorithm that sees `g y` when the feedback of a past round is `y`. -/ +def Algorithm.comapFeedback (alg : Algorithm π“ž 𝓐 𝓨) (g : 𝓨' β†’ 𝓨) + (hg : Measurable g := by fun_prop) : Algorithm π“ž 𝓐 𝓨' := + alg.comap (fun _ p ↦ (Hist.mapFeedback g p.1, p.2)) fun _ ↦ by fun_prop + +lemma Algorithm.comapFeedback_def (alg : Algorithm π“ž 𝓐 𝓨) (hg : Measurable g) : + alg.comapFeedback g hg + = alg.comap (fun _ p ↦ (Hist.mapFeedback g p.1, p.2)) fun _ ↦ by fun_prop := rfl + +@[simp] +lemma Algorithm.policy_comapFeedback (alg : Algorithm π“ž 𝓐 𝓨) (hg : Measurable g) (n : β„•) : + (alg.comapFeedback g hg).policy n + = (alg.policy n).comap (fun p ↦ (Hist.mapFeedback g p.1, p.2)) (by fun_prop) := rfl + +@[simp] +lemma Algorithm.p0_comapFeedback (alg : Algorithm π“ž 𝓐 𝓨) (hg : Measurable g) : + (alg.comapFeedback g hg).p0 = alg.p0 := by + ext o : 1 + rw [p0_apply, policy_comapFeedback, Kernel.comap_apply, alg.policy_zero, p0_apply] + +@[simp] +lemma Algorithm.comapFeedback_id (alg : Algorithm π“ž 𝓐 𝓨) : + alg.comapFeedback id measurable_id = alg := rfl + +lemma Algorithm.comapFeedback_comapFeedback (alg : Algorithm π“ž 𝓐 𝓨) + {g : 𝓨' β†’ 𝓨} (hg : Measurable g) {g' : 𝓨'' β†’ 𝓨'} (hg' : Measurable g') : + (alg.comapFeedback g hg).comapFeedback g' hg' = alg.comapFeedback (g ∘ g') (hg.comp hg') := rfl + +end ComapFeedback + +/-- Transporting the observations and the feedbacks of an algorithm are independent operations. -/ +lemma Algorithm.comapObs_comapFeedback_comm (alg : Algorithm π“ž 𝓐 𝓨) + {f : π“ž' β†’ π“ž} (hf : Measurable f) {g : 𝓨' β†’ 𝓨} (hg : Measurable g) : + (alg.comapFeedback g hg).comapObs f hf = (alg.comapObs f hf).comapFeedback g hg := rfl + +section ComapAction + +variable {F : (n : β„•) β†’ Hist π“ž 𝓐' 𝓨 n β†’ Hist π“ž 𝓐 𝓨 n} {f : 𝓐' β†’ 𝓐} + +/-- The environment that reads the summary `F n` of the past rounds and reads `f a` when the +algorithm plays `a` in the current round. + +This is the primitive transport operation on environments, dual to `Algorithm.comap`: +`Environment.comapAction` is the special case in which `F n` is the round-wise map of the actions. +Only the action can change type, since the observations and the feedbacks are outputs of the +environment; `F n` can nonetheless forget or summarize the past rounds, as an environment that +reads only the last round does. -/ +def Environment.comap (env : Environment π“ž 𝓐 𝓨) + (F : (n : β„•) β†’ Hist π“ž 𝓐' 𝓨 n β†’ Hist π“ž 𝓐 𝓨 n) (hF : βˆ€ n, Measurable (F n)) + (f : 𝓐' β†’ 𝓐) (hf : Measurable f) : Environment π“ž 𝓐' 𝓨 where + obs n := (env.obs n).comap (F n) (hF n) + feedback n := (env.feedback n).comap (fun p ↦ ((F n p.1.1, p.1.2), f p.2)) (by fun_prop) + +@[simp] +lemma Environment.obs_comap (env : Environment π“ž 𝓐 𝓨) + (hF : βˆ€ n, Measurable (F n)) (hf : Measurable f) (n : β„•) : + (env.comap F hF f hf).obs n = (env.obs n).comap (F n) (hF n) := rfl + +@[simp] +lemma Environment.feedback_comap (env : Environment π“ž 𝓐 𝓨) (hF : βˆ€ n, Measurable (F n)) + (hf : Measurable f) (n : β„•) : + (env.comap F hF f hf).feedback n + = (env.feedback n).comap (fun p ↦ ((F n p.1.1, p.1.2), f p.2)) (by fun_prop) := rfl + +@[simp] +lemma Environment.obs0_comap (env : Environment π“ž 𝓐 𝓨) (hF : βˆ€ n, Measurable (F n)) + (hf : Measurable f) : + (env.comap F hF f hf).obs0 = env.obs0 := by + rw [Environment.obs0_def, obs_comap, Kernel.comap_apply, env.obs_zero] + +@[simp] +lemma Environment.Ξ½0_comap (env : Environment π“ž 𝓐 𝓨) (hF : βˆ€ n, Measurable (F n)) + (hf : Measurable f) : + (env.comap F hF f hf).Ξ½0 = env.Ξ½0.comap (fun p ↦ (p.1, f p.2)) (by fun_prop) := by + ext p : 1 + rw [Environment.Ξ½0_apply, feedback_comap, Kernel.comap_apply, env.feedback_zero, + Kernel.comap_apply] + +@[simp] +lemma Environment.comap_id (env : Environment π“ž 𝓐 𝓨) : + env.comap (fun _ ↦ id) (fun _ ↦ measurable_id) id measurable_id = env := rfl + +lemma Environment.comap_comp (env : Environment π“ž 𝓐 𝓨) (hF : βˆ€ n, Measurable (F n)) + (hf : Measurable f) + {G : (n : β„•) β†’ Hist π“ž 𝓐'' 𝓨 n β†’ Hist π“ž 𝓐' 𝓨 n} (hG : βˆ€ n, Measurable (G n)) + {g : 𝓐'' β†’ 𝓐'} (hg : Measurable g) : + (env.comap F hF f hf).comap G hG g hg + = env.comap (fun n ↦ F n ∘ G n) (fun n ↦ (hF n).comp (hG n)) (f ∘ g) (hf.comp hg) := rfl + +/-- The environment that reads `f a` when the algorithm plays `a`, both in the current round and in +the past rounds. -/ +def Environment.comapAction (env : Environment π“ž 𝓐 𝓨) (f : 𝓐' β†’ 𝓐) + (hf : Measurable f := by fun_prop) : Environment π“ž 𝓐' 𝓨 := + env.comap (fun _ ↦ Hist.mapAction f) (fun _ ↦ by fun_prop) f hf + +lemma Environment.comapAction_def (env : Environment π“ž 𝓐 𝓨) (f : 𝓐' β†’ 𝓐) (hf : Measurable f) : + env.comapAction f hf = env.comap (fun _ ↦ Hist.mapAction f) (fun _ ↦ by fun_prop) f hf := rfl + +@[simp] +lemma Environment.obs_comapAction (env : Environment π“ž 𝓐 𝓨) (hf : Measurable f) + (n : β„•) : + (env.comapAction f hf).obs n = (env.obs n).comap (Hist.mapAction f) (by fun_prop) := rfl + +@[simp] +lemma Environment.feedback_comapAction (env : Environment π“ž 𝓐 𝓨) (hf : Measurable f) (n : β„•) : + (env.comapAction f hf).feedback n = (env.feedback n).comap + (fun p ↦ ((Hist.mapAction f p.1.1, p.1.2), f p.2)) (by fun_prop) := rfl + +@[simp] +lemma Environment.obs0_comapAction (env : Environment π“ž 𝓐 𝓨) (hf : Measurable f) : + (env.comapAction f hf).obs0 = env.obs0 := by + rw [Environment.obs0_def, obs_comapAction, Kernel.comap_apply, env.obs_zero] + +@[simp] +lemma Environment.Ξ½0_comapAction (env : Environment π“ž 𝓐 𝓨) (hf : Measurable f) : + (env.comapAction f hf).Ξ½0 = env.Ξ½0.comap (fun p ↦ (p.1, f p.2)) (by fun_prop) := by + ext p : 1 + rw [Environment.Ξ½0_apply, feedback_comapAction, Kernel.comap_apply, env.feedback_zero, + Kernel.comap_apply] + +@[simp] +lemma Environment.comapAction_id (env : Environment π“ž 𝓐 𝓨) : + env.comapAction id measurable_id = env := rfl + +lemma Environment.comapAction_comp (env : Environment π“ž 𝓐 𝓨) (hf : Measurable f) + (g : 𝓐'' β†’ 𝓐') (hg : Measurable g) : + (env.comapAction f hf).comapAction g hg = env.comapAction (f ∘ g) (hf.comp hg) := rfl + +end ComapAction + +end Comap + +section Congr + +/-- Relabelling of the observations, the actions and the feedbacks of an algorithm along measurable +equivalences. + +This is the covariant transport that a player does admit: the algorithm reads its own past actions, +so post-composing its policy with a map of the actions only defines an algorithm on the target +types when that map can be inverted on the history. -/ +noncomputable def Algorithm.congr (alg : Algorithm π“ž 𝓐 𝓨) (eπ“ž : π“ž ≃ᡐ π“ž') (e𝓐 : 𝓐 ≃ᡐ 𝓐') + (e𝓨 : 𝓨 ≃ᡐ 𝓨') : Algorithm π“ž' 𝓐' 𝓨' where + policy n := ((alg.policy n).map e𝓐).comap + (fun p ↦ (Hist.map eπ“ž.symm e𝓐.symm e𝓨.symm p.1, eπ“ž.symm p.2)) (by fun_prop) + isMarkovKernel_policy n := by + have : IsMarkovKernel ((alg.policy n).map e𝓐) := Kernel.IsMarkovKernel.map _ e𝓐.measurable + infer_instance + +@[simp] +lemma Algorithm.policy_congr (alg : Algorithm π“ž 𝓐 𝓨) (eπ“ž : π“ž ≃ᡐ π“ž') (e𝓐 : 𝓐 ≃ᡐ 𝓐') + (e𝓨 : 𝓨 ≃ᡐ 𝓨') (n : β„•) : + (alg.congr eπ“ž e𝓐 e𝓨).policy n = ((alg.policy n).map e𝓐).comap + (fun p ↦ (Hist.map eπ“ž.symm e𝓐.symm e𝓨.symm p.1, eπ“ž.symm p.2)) (by fun_prop) := rfl + +@[simp] +lemma Algorithm.p0_congr (alg : Algorithm π“ž 𝓐 𝓨) (eπ“ž : π“ž ≃ᡐ π“ž') (e𝓐 : 𝓐 ≃ᡐ 𝓐') + (e𝓨 : 𝓨 ≃ᡐ 𝓨') : + (alg.congr eπ“ž e𝓐 e𝓨).p0 = (alg.p0.map e𝓐).comap eπ“ž.symm eπ“ž.symm.measurable := by + ext o : 1 + rw [p0_apply, policy_congr, Kernel.comap_apply, Kernel.map_apply _ e𝓐.measurable, + alg.policy_zero, Kernel.comap_apply, Kernel.map_apply _ e𝓐.measurable] + +@[simp] +lemma Algorithm.congr_refl (alg : Algorithm π“ž 𝓐 𝓨) : + alg.congr (.refl π“ž) (.refl 𝓐) (.refl 𝓨) = alg := by + ext n : 2 + simp [MeasurableEquiv.symm_refl, MeasurableEquiv.coe_refl] + +lemma Algorithm.congr_congr (alg : Algorithm π“ž 𝓐 𝓨) (eπ“ž : π“ž ≃ᡐ π“ž') (e𝓐 : 𝓐 ≃ᡐ 𝓐') + (e𝓨 : 𝓨 ≃ᡐ 𝓨') (fπ“ž : π“ž' ≃ᡐ π“ž'') (f𝓐 : 𝓐' ≃ᡐ 𝓐'') (f𝓨 : 𝓨' ≃ᡐ 𝓨'') : + (alg.congr eπ“ž e𝓐 e𝓨).congr fπ“ž f𝓐 f𝓨 + = alg.congr (eπ“ž.trans fπ“ž) (e𝓐.trans f𝓐) (e𝓨.trans f𝓨) := by + ext n : 2 + ext p : 1 + rw [policy_congr, Kernel.comap_apply, Kernel.map_apply _ f𝓐.measurable, policy_congr, + Kernel.comap_apply, Kernel.map_apply _ e𝓐.measurable, + Measure.map_map f𝓐.measurable e𝓐.measurable, policy_congr, Kernel.comap_apply, + Kernel.map_apply _ (e𝓐.trans f𝓐).measurable] + rfl + +@[simp] +lemma Algorithm.congr_symm (alg : Algorithm π“ž 𝓐 𝓨) (eπ“ž : π“ž ≃ᡐ π“ž') (e𝓐 : 𝓐 ≃ᡐ 𝓐') + (e𝓨 : 𝓨 ≃ᡐ 𝓨') : + (alg.congr eπ“ž e𝓐 e𝓨).congr eπ“ž.symm e𝓐.symm e𝓨.symm = alg := by + rw [congr_congr, MeasurableEquiv.self_trans_symm, MeasurableEquiv.self_trans_symm, + MeasurableEquiv.self_trans_symm, congr_refl] + +/-- Relabelling of the observations, the actions and the feedbacks of an environment along +measurable equivalences. See `Algorithm.congr`. -/ +noncomputable def Environment.congr (env : Environment π“ž 𝓐 𝓨) (eπ“ž : π“ž ≃ᡐ π“ž') (e𝓐 : 𝓐 ≃ᡐ 𝓐') + (e𝓨 : 𝓨 ≃ᡐ 𝓨') : Environment π“ž' 𝓐' 𝓨' where + obs n := ((env.obs n).map eπ“ž).comap (Hist.map eπ“ž.symm e𝓐.symm e𝓨.symm) (by fun_prop) + feedback n := ((env.feedback n).map e𝓨).comap + (fun p ↦ ((Hist.map eπ“ž.symm e𝓐.symm e𝓨.symm p.1.1, eπ“ž.symm p.1.2), e𝓐.symm p.2)) (by fun_prop) + isMarkovKernel_obs n := by + have : IsMarkovKernel ((env.obs n).map eπ“ž) := Kernel.IsMarkovKernel.map _ eπ“ž.measurable + infer_instance + isMarkovKernel_feedback n := by + have : IsMarkovKernel ((env.feedback n).map e𝓨) := Kernel.IsMarkovKernel.map _ e𝓨.measurable + infer_instance + +@[simp] +lemma Environment.obs_congr (env : Environment π“ž 𝓐 𝓨) (eπ“ž : π“ž ≃ᡐ π“ž') (e𝓐 : 𝓐 ≃ᡐ 𝓐') + (e𝓨 : 𝓨 ≃ᡐ 𝓨') (n : β„•) : + (env.congr eπ“ž e𝓐 e𝓨).obs n + = ((env.obs n).map eπ“ž).comap (Hist.map eπ“ž.symm e𝓐.symm e𝓨.symm) (by fun_prop) := rfl + +@[simp] +lemma Environment.feedback_congr (env : Environment π“ž 𝓐 𝓨) (eπ“ž : π“ž ≃ᡐ π“ž') (e𝓐 : 𝓐 ≃ᡐ 𝓐') + (e𝓨 : 𝓨 ≃ᡐ 𝓨') (n : β„•) : + (env.congr eπ“ž e𝓐 e𝓨).feedback n = ((env.feedback n).map e𝓨).comap + (fun p ↦ ((Hist.map eπ“ž.symm e𝓐.symm e𝓨.symm p.1.1, eπ“ž.symm p.1.2), e𝓐.symm p.2)) + (by fun_prop) := rfl + +@[simp] +lemma Environment.obs0_congr (env : Environment π“ž 𝓐 𝓨) (eπ“ž : π“ž ≃ᡐ π“ž') (e𝓐 : 𝓐 ≃ᡐ 𝓐') + (e𝓨 : 𝓨 ≃ᡐ 𝓨') : + (env.congr eπ“ž e𝓐 e𝓨).obs0 = env.obs0.map eπ“ž := by + rw [Environment.obs0_def, obs_congr, Kernel.comap_apply, Kernel.map_apply _ eπ“ž.measurable, + env.obs_zero] + +@[simp] +lemma Environment.Ξ½0_congr (env : Environment π“ž 𝓐 𝓨) (eπ“ž : π“ž ≃ᡐ π“ž') (e𝓐 : 𝓐 ≃ᡐ 𝓐') + (e𝓨 : 𝓨 ≃ᡐ 𝓨') : + (env.congr eπ“ž e𝓐 e𝓨).Ξ½0 + = (env.Ξ½0.map e𝓨).comap (fun p ↦ (eπ“ž.symm p.1, e𝓐.symm p.2)) (by fun_prop) := by + ext p : 1 + rw [Environment.Ξ½0_apply, feedback_congr, Kernel.comap_apply, + Kernel.map_apply _ e𝓨.measurable, env.feedback_zero, Kernel.comap_apply, + Kernel.map_apply _ e𝓨.measurable] + +@[simp] +lemma Environment.congr_refl (env : Environment π“ž 𝓐 𝓨) : + env.congr (.refl π“ž) (.refl 𝓐) (.refl 𝓨) = env := by + ext n : 2 + Β· simp [MeasurableEquiv.symm_refl, MeasurableEquiv.coe_refl] + Β· simp [MeasurableEquiv.symm_refl, MeasurableEquiv.coe_refl] + +lemma Environment.congr_congr (env : Environment π“ž 𝓐 𝓨) (eπ“ž : π“ž ≃ᡐ π“ž') (e𝓐 : 𝓐 ≃ᡐ 𝓐') + (e𝓨 : 𝓨 ≃ᡐ 𝓨') (fπ“ž : π“ž' ≃ᡐ π“ž'') (f𝓐 : 𝓐' ≃ᡐ 𝓐'') (f𝓨 : 𝓨' ≃ᡐ 𝓨'') : + (env.congr eπ“ž e𝓐 e𝓨).congr fπ“ž f𝓐 f𝓨 + = env.congr (eπ“ž.trans fπ“ž) (e𝓐.trans f𝓐) (e𝓨.trans f𝓨) := by + ext n : 2 + Β· ext p : 1 + rw [obs_congr, Kernel.comap_apply, Kernel.map_apply _ fπ“ž.measurable, obs_congr, + Kernel.comap_apply, Kernel.map_apply _ eπ“ž.measurable, + Measure.map_map fπ“ž.measurable eπ“ž.measurable, obs_congr, Kernel.comap_apply, + Kernel.map_apply _ (eπ“ž.trans fπ“ž).measurable] + rfl + Β· ext p : 1 + rw [feedback_congr, Kernel.comap_apply, Kernel.map_apply _ f𝓨.measurable, feedback_congr, + Kernel.comap_apply, Kernel.map_apply _ e𝓨.measurable, + Measure.map_map f𝓨.measurable e𝓨.measurable, feedback_congr, Kernel.comap_apply, + Kernel.map_apply _ (e𝓨.trans f𝓨).measurable] + rfl + +@[simp] +lemma Environment.congr_symm (env : Environment π“ž 𝓐 𝓨) (eπ“ž : π“ž ≃ᡐ π“ž') (e𝓐 : 𝓐 ≃ᡐ 𝓐') + (e𝓨 : 𝓨 ≃ᡐ 𝓨') : + (env.congr eπ“ž e𝓐 e𝓨).congr eπ“ž.symm e𝓐.symm e𝓨.symm = env := by + rw [congr_congr, MeasurableEquiv.self_trans_symm, MeasurableEquiv.self_trans_symm, + MeasurableEquiv.self_trans_symm, congr_refl] + +end Congr + +section Runs + +variable {alg : Algorithm π“ž 𝓐 𝓨} {P : Measure Ξ©} [IsFiniteMeasure P] + {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} + +namespace IsAlgEnvSeq + +section ComapObs + +variable {env : Environment π“ž' 𝓐 𝓨} {f : π“ž' β†’ π“ž} {hf : Measurable f} {O : β„• β†’ Ξ© β†’ π“ž'} + +/-- The algorithm does not use the part of the observation that it ignores: the conditional +distribution of its action given the transported history and observation is its own policy. -/ +lemma hasCondDistrib_action_comapObs (h : IsAlgEnvSeq O A Y (alg.comapObs f hf) env P) (n : β„•) : + HasCondDistrib (A n) + (fun Ο‰ ↦ (history (fun n Ο‰ ↦ f (O n Ο‰)) A Y n Ο‰, f (O n Ο‰))) (alg.policy n) P := + HasCondDistrib.comp_right (f := fun p : Hist π“ž' 𝓐 𝓨 n Γ— π“ž' ↦ (Hist.mapObs f p.1, f p.2)) + (hf := by fun_prop) (h.hasCondDistrib_action n) + +end ComapObs + +section ComapFeedback + +variable {env : Environment π“ž 𝓐 𝓨'} {g : 𝓨' β†’ 𝓨} {hg : Measurable g} {O : β„• β†’ Ξ© β†’ π“ž} + {Y' : β„• β†’ Ξ© β†’ 𝓨'} + +/-- The algorithm does not use the part of the past feedbacks that it ignores: the conditional +distribution of its action given the transported history and the observation is its own policy. -/ +lemma hasCondDistrib_action_comapFeedback + (h : IsAlgEnvSeq O A Y' (alg.comapFeedback g hg) env P) (n : β„•) : + HasCondDistrib (A n) + (fun Ο‰ ↦ (history O A (fun n Ο‰ ↦ g (Y' n Ο‰)) n Ο‰, O n Ο‰)) (alg.policy n) P := + HasCondDistrib.comp_right (f := fun p : Hist π“ž 𝓐 𝓨' n Γ— π“ž ↦ (Hist.mapFeedback g p.1, p.2)) + (hf := by fun_prop) (h.hasCondDistrib_action n) + +end ComapFeedback + +section ComapAction + +variable {env : Environment π“ž 𝓐 𝓨} {f : 𝓐' β†’ 𝓐} {hf : Measurable f} {O : β„• β†’ Ξ© β†’ π“ž} + {A' : β„• β†’ Ξ© β†’ 𝓐'} + +/-- The environment does not use the part of the action that it ignores: the conditional +distribution of the observation given the transported history is its own observation kernel. -/ +lemma hasCondDistrib_obs_comapAction {alg : Algorithm π“ž 𝓐' 𝓨} + (h : IsAlgEnvSeq O A' Y alg (env.comapAction f hf) P) (n : β„•) : + HasCondDistrib (O n) (history O (fun n Ο‰ ↦ f (A' n Ο‰)) Y n) (env.obs n) P := + HasCondDistrib.comp_right (f := Hist.mapAction (π“ž := π“ž) (𝓨 := 𝓨) f (n := n)) + (hf := by fun_prop) (h.hasCondDistrib_obs n) + +/-- The environment does not use the part of the action that it ignores: the conditional +distribution of the feedback given the transported history, the observation and the transported +action is its own feedback kernel. -/ +lemma hasCondDistrib_feedback_comapAction {alg : Algorithm π“ž 𝓐' 𝓨} + (h : IsAlgEnvSeq O A' Y alg (env.comapAction f hf) P) (n : β„•) : + HasCondDistrib (Y n) + (fun Ο‰ ↦ ((history O (fun n Ο‰ ↦ f (A' n Ο‰)) Y n Ο‰, O n Ο‰), f (A' n Ο‰))) (env.feedback n) P := + HasCondDistrib.comp_right + (f := fun p : (Hist π“ž 𝓐' 𝓨 n Γ— π“ž) Γ— 𝓐' ↦ ((Hist.mapAction f p.1.1, p.1.2), f p.2)) + (hf := by fun_prop) (h.hasCondDistrib_feedback n) + +end ComapAction + +end IsAlgEnvSeq + +end Runs + +end Learning From f2d747273912a08dff128648935dde0e9ec825a9 Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Sat, 5 Sep 2026 13:54:20 +0200 Subject: [PATCH 08/21] delete Announce --- LeanMachineLearning.lean | 1 - .../SequentialLearning/Announce.lean | 122 ------------------ .../BayesStationaryEnv.lean | 13 +- 3 files changed, 4 insertions(+), 132 deletions(-) delete mode 100644 LeanMachineLearning/SequentialLearning/Announce.lean diff --git a/LeanMachineLearning.lean b/LeanMachineLearning.lean index 3491eb85..4ab3a584 100644 --- a/LeanMachineLearning.lean +++ b/LeanMachineLearning.lean @@ -40,7 +40,6 @@ public import LeanMachineLearning.SequentialLearning.Algorithms.RandomSampling.B public import LeanMachineLearning.SequentialLearning.Algorithms.RandomSampling.Tendsto public import LeanMachineLearning.SequentialLearning.Algorithms.RoundRobin public import LeanMachineLearning.SequentialLearning.Algorithms.Uniform -public import LeanMachineLearning.SequentialLearning.Announce public import LeanMachineLearning.SequentialLearning.BayesStationaryEnv public import LeanMachineLearning.SequentialLearning.Comap public import LeanMachineLearning.SequentialLearning.Deterministic diff --git a/LeanMachineLearning/SequentialLearning/Announce.lean b/LeanMachineLearning/SequentialLearning/Announce.lean deleted file mode 100644 index 3892a478..00000000 --- a/LeanMachineLearning/SequentialLearning/Announce.lean +++ /dev/null @@ -1,122 +0,0 @@ -/- -Copyright (c) 2026 RΓ©my Degenne. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: RΓ©my Degenne --/ -module - -public import LeanMachineLearning.SequentialLearning.Comap - -/-! -# Announced variables - -TODO - -A hidden variable of one of the two players (memory or sampled index of the algorithm, parameter of -the environment) is modelled by making it part of that player's move, while the other player is -transported so as to ignore it: - -* the algorithm announces a variable of type `𝓩`: it is an `Algorithm π“ž (𝓩 Γ— 𝓐) 𝓨` that runs - against `env.comapAction Prod.snd`, for an `env : Environment π“ž 𝓐 𝓨`; -* the environment announces a variable of type `𝓔`: it is an `Environment (𝓔 Γ— π“ž) 𝓐 𝓨` that runs - against `alg.comapObs Prod.snd`, for an `alg : Algorithm π“ž 𝓐 𝓨`. - -In both cases the announced variable is an honest random variable of the run, and the player that -ignores it satisfies the conditional distribution properties of a run of the un-announced -interaction: this is the content of `IsAlgEnvSeq.hasCondDistrib_action_comapObs` (the algorithm -does not use the announced variable) and of `IsAlgEnvSeq.hasCondDistrib_obs_comapAction` and -`IsAlgEnvSeq.hasCondDistrib_feedback_comapAction` (the environment does not use it). -The law of the observable trajectory is the image of the law of the full trajectory under the map -that forgets the announced variable. - -## Main definitions - -* `Algorithm.IgnoresAnnounced algZ alg`: the announcing algorithm `algZ` does not read the variables - it announced in the past rounds, and the law of the action it plays is `alg.policy n`. - -## Main statements - -* `IsAlgEnvSeq.map_trajectory_comapObs`, `IsAlgEnvSeq.map_trajectory_comapFeedback`, - `IsAlgEnvSeq.map_trajectory_comapAction`: the law of the trajectory that a player sees is the - image of `trajMeasure` under the forgetful map. -* `IsAlgEnvSeq.hasCondDistrib_announced`: in a run of an announcing algorithm, the announced - variable of round `n` has the first marginal of the policy for conditional distribution. It is an - honest random variable of the run, not a variable integrated out inside the policy kernel. -* `IsAlgEnvSeq.isAlgEnvSeq_of_ignoresAnnounced`: **projection of a run**. If the announcing - algorithm does not read its own past announcements, the observable part of a run of it against - `env.comapAction Prod.snd` is a run of the behavioral algorithm against `env`. - --/ - -@[expose] public section - -open MeasureTheory ProbabilityTheory - -namespace Learning - -variable {π“ž π“ž' 𝓐 𝓨 Ξ© : Type*} {mπ“ž : MeasurableSpace π“ž} {mπ“ž' : MeasurableSpace π“ž'} - {m𝓐 : MeasurableSpace 𝓐} {m𝓨 : MeasurableSpace 𝓨} {mΞ© : MeasurableSpace Ξ©} - -/-- An announcing algorithm `algZ : Algorithm π“ž (𝓩 Γ— 𝓐) 𝓨` *ignores its own announcements*, with -behavioral algorithm `alg`, if the law of the action it plays given the past rounds and the current -observation does not depend on the variables announced in the past rounds, and is `alg.policy n`. - -Announcing algorithms that redraw their announced variable from the observable history at every -round satisfy this; algorithms that reuse a variable drawn once (a mixture component, a random -permutation) do not, and their projection needs a disintegration argument. -/ -def Algorithm.IgnoresAnnounced {𝓩 : Type*} [MeasurableSpace 𝓩] - (algZ : Algorithm π“ž (𝓩 Γ— 𝓐) 𝓨) (alg : Algorithm π“ž 𝓐 𝓨) : Prop := - βˆ€ n, (algZ.policy n).snd - = (alg.policy n).comap (fun p ↦ (Hist.mapAction Prod.snd p.1, p.2)) (by fun_prop) - -lemma Algorithm.IgnoresAnnounced.comapObs {𝓩 : Type*} [MeasurableSpace 𝓩] - {algZ : Algorithm π“ž (𝓩 Γ— 𝓐) 𝓨} {alg : Algorithm π“ž 𝓐 𝓨} (h : algZ.IgnoresAnnounced alg) - (f : π“ž' β†’ π“ž) (hf : Measurable f) : - (algZ.comapObs f hf).IgnoresAnnounced (alg.comapObs f hf) := by - intro n - have h_snd : ((algZ.comapObs f hf).policy n).snd - = ((algZ.policy n).snd).comap (fun p ↦ (Hist.mapObs f p.1, f p.2)) (by fun_prop) := rfl - rw [h_snd, h n] - rfl - -namespace IsAlgEnvSeq - -variable {𝓩 : Type*} {m𝓩 : MeasurableSpace 𝓩} {alg : Algorithm π“ž 𝓐 𝓨} {env : Environment π“ž 𝓐 𝓨} - {algZ : Algorithm π“ž (𝓩 Γ— 𝓐) 𝓨} {P : Measure Ξ©} [IsFiniteMeasure P] - {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {B : β„• β†’ Ξ© β†’ 𝓩 Γ— 𝓐} - -/-- The announced variable of round `n`, given the past rounds and the current observation, has the -first marginal of the policy for conditional distribution. It is an honest random variable of the -run, not a variable integrated out inside the policy kernel. -/ -lemma hasCondDistrib_announced {env' : Environment π“ž (𝓩 Γ— 𝓐) 𝓨} - (h : IsAlgEnvSeq O B Y algZ env' P) (n : β„•) : - HasCondDistrib (fun Ο‰ ↦ (B n Ο‰).1) (fun Ο‰ ↦ (history O B Y n Ο‰, O n Ο‰)) - (algZ.policy n).fst P := - (h.hasCondDistrib_action n).fst - -/-- **Projection of a run of an announcing algorithm.** If `algZ` announces a variable in `𝓩` and -does not read its own past announcements, then the observable part of a run of `algZ` against -`env.comapAction Prod.snd` is a run of the behavioral algorithm `alg` against `env`. The announced -variables are honest random variables of that run. - -This is the special case of the projection theorem in which the announced variable is redrawn from -the observable history at every round; it needs no disintegration. -/ -lemma isAlgEnvSeq_of_ignoresAnnounced {alg : Algorithm π“ž 𝓐 𝓨} - (h : IsAlgEnvSeq O B Y algZ (env.comapAction Prod.snd) P) - (h_alg : algZ.IgnoresAnnounced alg) : - IsAlgEnvSeq O (fun n Ο‰ ↦ (B n Ο‰).2) Y alg env P where - measurable_obs := h.measurable_obs - measurable_action n := (h.measurable_action n).snd - measurable_feedback := h.measurable_feedback - hasCondDistrib_obs n := h.hasCondDistrib_obs_comapAction n - hasCondDistrib_feedback n := h.hasCondDistrib_feedback_comapAction n - hasCondDistrib_action n := by - have h1 := (h.hasCondDistrib_action n).snd - rw [h_alg n] at h1 - exact HasCondDistrib.comp_right - (f := fun p : Hist π“ž (𝓩 Γ— 𝓐) 𝓨 n Γ— π“ž ↦ (Hist.mapAction Prod.snd p.1, p.2)) - (hf := by fun_prop) (Z := fun Ο‰ ↦ (history O B Y n Ο‰, O n Ο‰)) h1 - -end IsAlgEnvSeq - -end Learning diff --git a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean index 8510d66e..319f3cf8 100644 --- a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean +++ b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean @@ -5,7 +5,7 @@ Authors: Paulo Rauber, RΓ©my Degenne -/ module -public import LeanMachineLearning.SequentialLearning.Announce +public import LeanMachineLearning.SequentialLearning.Comap public import LeanMachineLearning.SequentialLearning.IonescuTulceaSpace public import LeanMachineLearning.SequentialLearning.StationaryEnv @@ -14,14 +14,9 @@ public import LeanMachineLearning.SequentialLearning.StationaryEnv A Bayesian stationary environment is an environment that draws a parameter `e : 𝓔` from a prior `Q` before the first round and then behaves like the stationary environment -`stationaryEnv (ΞΊ.sectR e)`. Following the "announced variables" mechanism of -`LeanMachineLearning/SequentialLearning/Announce.lean`, the parameter is not hidden: it is part of -the environment's move, and the algorithm is the one that ignores it. Concretely, -`bayesStationaryEnv Q ΞΊ : Environment 𝓔 𝓐 𝓨` announces `e` as the observation of every round and -runs against `alg.comapObs (fun _ ↦ ())`, for an `alg : Algorithm Unit 𝓐 𝓨`. - -The predicate `IsBayesAlgEnvSeq` is not a new notion of run: it is `IsAlgEnvSeq` for that pair, -for the observation process that announces the parameter `E` at every round. +`stationaryEnv (ΞΊ.sectR e)`. Concretely, `bayesStationaryEnv Q ΞΊ : Environment 𝓔 𝓐 𝓨` announces +an observation `e` at every round and runs against `alg.comapObs (fun _ ↦ ())`, for +an `alg : Algorithm Unit 𝓐 𝓨`, an algorithm that does not use the observation. ## Main definitions From 6958179134fff3f9f9d157befad617a745443d6e Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Sat, 5 Sep 2026 13:59:49 +0200 Subject: [PATCH 09/21] delete unused lemma --- .../Kernel/Composition/MeasureCompProd.lean | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/LeanMachineLearning/ForMathlib/Probability/Kernel/Composition/MeasureCompProd.lean b/LeanMachineLearning/ForMathlib/Probability/Kernel/Composition/MeasureCompProd.lean index 34a14d3f..ca018b7f 100644 --- a/LeanMachineLearning/ForMathlib/Probability/Kernel/Composition/MeasureCompProd.lean +++ b/LeanMachineLearning/ForMathlib/Probability/Kernel/Composition/MeasureCompProd.lean @@ -33,23 +33,3 @@ lemma AbsolutelyContinuous.compProd_left_apply {Ξ³ : Type*} {mΞ³ : MeasurableSpa end AbsolutelyContinuous end MeasureTheory.Measure - -namespace ProbabilityTheory.Kernel - -variable {Ξ± Ξ² Ξ³ : Type*} {mΞ± : MeasurableSpace Ξ±} {mΞ² : MeasurableSpace Ξ²} {mΞ³ : MeasurableSpace Ξ³} - -/-- Recording a measurable function of a draw: mapping a kernel to the graph of `f` is the -composition-product of that kernel with the deterministic kernel given by `f`. This is how an -algorithm announces a variable that it then uses deterministically. -/ -lemma map_graph (ΞΊ : Kernel Ξ± Ξ²) [IsSFiniteKernel ΞΊ] {f : Ξ² β†’ Ξ³} (hf : Measurable f) : - ΞΊ.map (fun b ↦ (b, f b)) - = ΞΊ βŠ—β‚– Kernel.deterministic (fun p : Ξ± Γ— Ξ² ↦ f p.2) (by fun_prop) := by - ext a : 1 - have h_sectR : (Kernel.deterministic (fun p : Ξ± Γ— Ξ² ↦ f p.2) (by fun_prop)).sectR a - = Kernel.deterministic f hf := by - ext b : 1 - rw [Kernel.sectR_apply, Kernel.deterministic_apply, Kernel.deterministic_apply] - rw [Kernel.map_apply _ (by fun_prop), Kernel.compProd_apply_eq_compProd_sectR, h_sectR, - MeasureTheory.Measure.compProd_deterministic] - -end ProbabilityTheory.Kernel From cf3614c01e38f1b06d5ec104d127a5d347c5ea67 Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Sat, 5 Sep 2026 14:00:36 +0200 Subject: [PATCH 10/21] remove import --- .../Probability/Kernel/Composition/MeasureCompProd.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/LeanMachineLearning/ForMathlib/Probability/Kernel/Composition/MeasureCompProd.lean b/LeanMachineLearning/ForMathlib/Probability/Kernel/Composition/MeasureCompProd.lean index ca018b7f..e2f2aec7 100644 --- a/LeanMachineLearning/ForMathlib/Probability/Kernel/Composition/MeasureCompProd.lean +++ b/LeanMachineLearning/ForMathlib/Probability/Kernel/Composition/MeasureCompProd.lean @@ -5,7 +5,6 @@ Authors: Paulo Rauber -/ module -public import Mathlib.Probability.Kernel.Composition.MeasureComp public import Mathlib.Probability.Kernel.Composition.MeasureCompProd /-! # Lemmas about measure composition-product From d889bd09a348a18627249e4bfc9472fc98aab6be Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Sat, 5 Sep 2026 14:22:26 +0200 Subject: [PATCH 11/21] better aux lemma --- .../Probability/HasCondDistrib.lean | 24 +++++++++++-------- .../BayesStationaryEnv.lean | 4 ++-- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/LeanMachineLearning/ForMathlib/Probability/HasCondDistrib.lean b/LeanMachineLearning/ForMathlib/Probability/HasCondDistrib.lean index 785f8bd5..3735fd55 100644 --- a/LeanMachineLearning/ForMathlib/Probability/HasCondDistrib.lean +++ b/LeanMachineLearning/ForMathlib/Probability/HasCondDistrib.lean @@ -171,16 +171,12 @@ lemma HasCondDistrib.prod {Z : Ξ± β†’ Ξ©'} {Ξ· : Kernel (Ξ² Γ— Ξ©) Ξ©'} AEMeasurable.map_map_of_aemeasurable (by fun_prop) (by fun_prop)] rfl -/-- A random variable that is almost surely a measurable function of `X` has the corresponding -deterministic conditional distribution given `X`. -/ -lemma hasCondDistrib_deterministic [SFinite ΞΌ] {f : Ξ² β†’ Ξ©} (hf : Measurable f) - (hX : AEMeasurable X ΞΌ) (hY : Y =ᡐ[ΞΌ] f ∘ X) : - HasCondDistrib Y X (Kernel.deterministic f hf) ΞΌ := by - have h : HasCondDistrib (f ∘ X) X (Kernel.deterministic f hf) ΞΌ := by - refine ⟨hX.prodMk (hf.comp_aemeasurable hX), ?_⟩ - rw [Measure.compProd_deterministic, AEMeasurable.map_map_of_aemeasurable (by fun_prop) hX] - rfl - exact HasCondDistrib.congr h .rfl hY +lemma hasCondDistrib_comp_self [SFinite ΞΌ] {f : Ξ² β†’ Ξ©} (hf : Measurable f) + (hX : AEMeasurable X ΞΌ) : + HasCondDistrib (f ∘ X) X (Kernel.deterministic f hf) ΞΌ := by + refine ⟨hX.prodMk (hf.comp_aemeasurable hX), ?_⟩ + rw [Measure.compProd_deterministic, AEMeasurable.map_map_of_aemeasurable (by fun_prop) hX] + rfl lemma ae_eq_of_hasCondDistrib_deterministic [MeasurableEq Ξ©] [SFinite ΞΌ] {f : Ξ² β†’ Ξ©} (hf : Measurable f) (hX : AEMeasurable X ΞΌ) @@ -191,6 +187,14 @@ lemma ae_eq_of_hasCondDistrib_deterministic [MeasurableEq Ξ©] [SFinite ΞΌ] {f : AEMeasurable.map_map_of_aemeasurable (by fun_prop) (by fun_prop)] rfl +lemma hasCondDistrib_deterministic_iff [MeasurableEq Ξ©] [SFinite ΞΌ] {f : Ξ² β†’ Ξ©} + (hf : Measurable f) (hX : AEMeasurable X ΞΌ) (hY : AEMeasurable Y ΞΌ) : + HasCondDistrib Y X (Kernel.deterministic f hf) ΞΌ ↔ Y =ᡐ[ΞΌ] f ∘ X := by + refine ⟨ae_eq_of_hasCondDistrib_deterministic hf hX hY, fun h ↦ ?_⟩ + refine HasCondDistrib.congr ?_ ?_ h (X := X) + Β· exact hasCondDistrib_comp_self hf hX + Β· rfl + section Const section CompRight diff --git a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean index 319f3cf8..6377f40c 100644 --- a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean +++ b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean @@ -156,9 +156,9 @@ lemma mk (hasLaw_env : HasLaw E Q P) exact hasLaw_env.hasCondDistrib_const | succ n => rw [obs_bayesStationaryEnv_succ] - exact hasCondDistrib_deterministic _ + exact hasCondDistrib_comp_self (f := fun h : Hist 𝓔 𝓐 𝓨 (n + 1) ↦ (h 0).obs) _ (measurable_history (fun _ ↦ measurable_param) measurable_action measurable_feedback - (n + 1)).aemeasurable (ae_of_all _ fun _ ↦ rfl) + (n + 1)).aemeasurable Β· intro n exact HasCondDistrib.comp_right (f := fun q : 𝓔 Γ— (Hist Unit 𝓐 𝓨 n Γ— Unit) ↦ (announceHist q.1 q.2.1, q.1)) From 0109d3b6af9c894e127ea0a5b95424e8c8e8ec1a Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Sat, 5 Sep 2026 14:24:11 +0200 Subject: [PATCH 12/21] space --- LeanMachineLearning/ForMathlib/Probability/HasCondDistrib.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/LeanMachineLearning/ForMathlib/Probability/HasCondDistrib.lean b/LeanMachineLearning/ForMathlib/Probability/HasCondDistrib.lean index 3735fd55..27e431cf 100644 --- a/LeanMachineLearning/ForMathlib/Probability/HasCondDistrib.lean +++ b/LeanMachineLearning/ForMathlib/Probability/HasCondDistrib.lean @@ -319,5 +319,4 @@ lemma HasCondDistrib.hasCondDistrib_sectR [IsFiniteMeasure ΞΌ] [StandardBorelSpa rw [Kernel.map_apply _ hf] at ha filter_upwards [hc, ha] with b hcb hab using hcb.trans hab - end ProbabilityTheory From dc4cb70edadbf72e5f645244d0ddf47233eab1df Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Sat, 5 Sep 2026 14:43:03 +0200 Subject: [PATCH 13/21] delete a def --- .../SequentialLearning/Algorithm.lean | 19 ------------------- .../BayesStationaryEnv.lean | 2 +- .../SequentialLearning/StationaryEnv.lean | 4 ++-- 3 files changed, 3 insertions(+), 22 deletions(-) diff --git a/LeanMachineLearning/SequentialLearning/Algorithm.lean b/LeanMachineLearning/SequentialLearning/Algorithm.lean index 4003b19d..30b2cdfb 100644 --- a/LeanMachineLearning/SequentialLearning/Algorithm.lean +++ b/LeanMachineLearning/SequentialLearning/Algorithm.lean @@ -737,12 +737,6 @@ lemma hasCondDistrib_unit {Ξ± : Type*} {mΞ± : MeasurableSpace Ξ±} {P : Measure AEMeasurable.map_map_of_aemeasurable (by fun_prop) hX] rfl -/-- Any function with values in `Unit` is measurable. -/ -lemma measurable_unit {Ξ± : Type*} {mΞ± : MeasurableSpace Ξ±} (f : Ξ± β†’ Unit) : Measurable f := by - have hf : f = fun _ ↦ () := funext fun _ ↦ rfl - rw [hf] - exact measurable_const - /-- The observation process of an algorithm-environment sequence without observations. -/ def noObs (Ξ© : Type*) : β„• β†’ Ξ© β†’ Unit := fun _ _ ↦ () @@ -751,19 +745,6 @@ def noObs (Ξ© : Type*) : β„• β†’ Ξ© β†’ Unit := fun _ _ ↦ () @[fun_prop] lemma measurable_noObs (n : β„•) : Measurable (noObs Ξ© n) := measurable_const -/-- The observation kernels of an environment without observations. -/ -noncomputable def unitObs (𝓐 𝓨 : Type*) [MeasurableSpace 𝓐] [MeasurableSpace 𝓨] (n : β„•) : - Kernel (Hist Unit 𝓐 𝓨 n) Unit := - Kernel.const _ (Measure.dirac ()) -deriving IsMarkovKernel - -lemma unitObs_def (n : β„•) : - unitObs 𝓐 𝓨 n = Kernel.const _ (Measure.dirac ()) := rfl - -@[simp] -lemma unitObs_apply (n : β„•) (h : Hist Unit 𝓐 𝓨 n) : - unitObs 𝓐 𝓨 n h = Measure.dirac () := rfl - end NoObservation end Learning diff --git a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean index 6377f40c..0a33b448 100644 --- a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean +++ b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean @@ -254,7 +254,7 @@ lemma condDistrib_param_history_zero [StandardBorelSpace 𝓔] [Nonempty 𝓔] exact h_ae lemma hasCondDistrib_IT_obs (_h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : - βˆ€α΅ e βˆ‚Q, HasCondDistrib (IT.obs n) (IT.hist n) (unitObs 𝓐 𝓨 n) + βˆ€α΅ e βˆ‚Q, HasCondDistrib (IT.obs n) (IT.hist n) (Kernel.const _ (Measure.dirac ())) (condDistrib (trajectory (noObs Ξ©) A Y) E P e) := ae_of_all _ fun _ ↦ hasCondDistrib_unit (IT.measurable_hist n).aemeasurable _ _ diff --git a/LeanMachineLearning/SequentialLearning/StationaryEnv.lean b/LeanMachineLearning/SequentialLearning/StationaryEnv.lean index 8f38b188..2fa3c8ec 100644 --- a/LeanMachineLearning/SequentialLearning/StationaryEnv.lean +++ b/LeanMachineLearning/SequentialLearning/StationaryEnv.lean @@ -128,7 +128,7 @@ depends only on the last action, but in a possibly time-dependent manner. -/ @[simps] noncomputable def obliviousEnv (Ξ½ : β„• β†’ Kernel 𝓐 𝓨) [βˆ€ n, IsMarkovKernel (Ξ½ n)] : Environment Unit 𝓐 𝓨 where - obs n := unitObs 𝓐 𝓨 n + obs _ := Kernel.const _ (Measure.dirac ()) feedback n := (Ξ½ n).prodMkLeft _ lemma feedback_obliviousEnv (Ξ½ : β„• β†’ Kernel 𝓐 𝓨) [βˆ€ n, IsMarkovKernel (Ξ½ n)] (n : β„•) : @@ -173,7 +173,7 @@ def stationaryEnv (Ξ½ : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ½] : Environment Unit @[simp] lemma obs_stationaryEnv (Ξ½ : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ½] (n : β„•) : - (stationaryEnv Ξ½).obs n = unitObs 𝓐 𝓨 n := rfl + (stationaryEnv Ξ½).obs n = Kernel.const _ (Measure.dirac ()) := rfl @[simp] lemma feedback_stationaryEnv (Ξ½ : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ½] (n : β„•) : From bbc6700ad69024f957ff810a284fcba9233f3f66 Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Sat, 5 Sep 2026 14:46:36 +0200 Subject: [PATCH 14/21] minor --- .../SequentialLearning/BayesStationaryEnv.lean | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean index 0a33b448..b1b1c34a 100644 --- a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean +++ b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean @@ -237,9 +237,6 @@ lemma hasCondDistrib_action_zero (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : HasCondDistrib (A 0) E (Kernel.const _ (alg.p0 ())) P := hasCondDistrib_prodMk_right_unique_iff.mp (h.hasCondDistrib_action 0) -variable [StandardBorelSpace 𝓐] [Nonempty 𝓐] [StandardBorelSpace 𝓨] [Nonempty 𝓨] - -omit [StandardBorelSpace 𝓐] [Nonempty 𝓐] [StandardBorelSpace 𝓨] [Nonempty 𝓨] in /-- The posterior over the parameter given the empty history is the prior. -/ lemma condDistrib_param_history_zero [StandardBorelSpace 𝓔] [Nonempty 𝓔] (h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) : @@ -253,6 +250,8 @@ lemma condDistrib_param_history_zero [StandardBorelSpace 𝓔] [Nonempty 𝓔] ae_dirac_iff Subsingleton.measurableSet] at h_ae exact h_ae +variable [StandardBorelSpace 𝓐] [Nonempty 𝓐] [StandardBorelSpace 𝓨] [Nonempty 𝓨] + lemma hasCondDistrib_IT_obs (_h : IsBayesAlgEnvSeq Q ΞΊ alg E A Y P) (n : β„•) : βˆ€α΅ e βˆ‚Q, HasCondDistrib (IT.obs n) (IT.hist n) (Kernel.const _ (Measure.dirac ())) (condDistrib (trajectory (noObs Ξ©) A Y) E P e) := From 2faa07bda92a63b52d967cc3dc0623e194e1ae1b Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Sat, 5 Sep 2026 14:49:46 +0200 Subject: [PATCH 15/21] delete unused constructor --- .../BayesStationaryEnv.lean | 46 +------------------ 1 file changed, 2 insertions(+), 44 deletions(-) diff --git a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean index b1b1c34a..779a6a71 100644 --- a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean +++ b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean @@ -128,50 +128,8 @@ def IsBayesAlgEnvSeq (Q : Measure 𝓔) [IsProbabilityMeasure Q] (ΞΊ : Kernel ( namespace IsBayesAlgEnvSeq variable {Q : Measure 𝓔} [IsProbabilityMeasure Q] {ΞΊ : Kernel (𝓔 Γ— 𝓐) 𝓨} [IsMarkovKernel ΞΊ] -variable {alg : Algorithm Unit 𝓐 𝓨} -variable {E : Ξ© β†’ 𝓔} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} -variable {P : Measure Ξ©} [IsProbabilityMeasure P] - -/-- Constructor for `IsBayesAlgEnvSeq` from the law of the parameter and the conditional -distributions of the actions and of the feedbacks given the parameter and the observable history. -Together with `IsBayesAlgEnvSeq.hasLaw_env`, `IsBayesAlgEnvSeq.hasCondDistrib_action` and -`IsBayesAlgEnvSeq.hasCondDistrib_feedback`, this shows that being an `IsAlgEnvSeq` for the -announcing environment is equivalent to those conditions. -/ -lemma mk (hasLaw_env : HasLaw E Q P) - (hasCondDistrib_action : βˆ€ n, - HasCondDistrib (A n) (fun Ο‰ ↦ (E Ο‰, (history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰))) - ((alg.policy n).prodMkLeft _) P) - (hasCondDistrib_feedback : βˆ€ n, - HasCondDistrib (Y n) (fun Ο‰ ↦ ((history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰), (E Ο‰, A n Ο‰))) - (ΞΊ.prodMkLeft _) P) - (measurable_param : Measurable E := by fun_prop) - (measurable_action : βˆ€ n, Measurable (A n) := by fun_prop) - (measurable_feedback : βˆ€ n, Measurable (Y n) := by fun_prop) : - IsBayesAlgEnvSeq Q ΞΊ alg E A Y P := by - refine IsAlgEnvSeq.mk (fun _ ↦ measurable_param) measurable_action measurable_feedback ?_ ?_ ?_ - Β· intro n - cases n with - | zero => - rw [history_zero, obs_bayesStationaryEnv_zero] - exact hasLaw_env.hasCondDistrib_const - | succ n => - rw [obs_bayesStationaryEnv_succ] - exact hasCondDistrib_comp_self (f := fun h : Hist 𝓔 𝓐 𝓨 (n + 1) ↦ (h 0).obs) _ - (measurable_history (fun _ ↦ measurable_param) measurable_action measurable_feedback - (n + 1)).aemeasurable - Β· intro n - exact HasCondDistrib.comp_right - (f := fun q : 𝓔 Γ— (Hist Unit 𝓐 𝓨 n Γ— Unit) ↦ (announceHist q.1 q.2.1, q.1)) - (hf := by fun_prop) - (Z := fun Ο‰ ↦ (E Ο‰, (history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰))) - (hasCondDistrib_action n) - Β· intro n - exact HasCondDistrib.comp_right - (f := fun q : (Hist Unit 𝓐 𝓨 n Γ— Unit) Γ— (𝓔 Γ— 𝓐) ↦ - ((announceHist q.2.1 q.1.1, q.2.1), q.2.2)) - (hf := by fun_prop) - (Z := fun Ο‰ ↦ ((history (noObs Ξ©) A Y n Ο‰, noObs Ξ© n Ο‰), (E Ο‰, A n Ο‰))) - (hasCondDistrib_feedback n) + {alg : Algorithm Unit 𝓐 𝓨} {P : Measure Ξ©} [IsProbabilityMeasure P] + {E : Ξ© β†’ 𝓔} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} /-- A Bayesian algorithm-environment sequence is an algorithm-environment sequence for the announcing environment `bayesStationaryEnv Q ΞΊ`. -/ From f01201569d1347e45ee01f4572f4b3dece00c899 Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Sat, 5 Sep 2026 14:54:52 +0200 Subject: [PATCH 16/21] delete unused defs --- .../SequentialLearning/Comap.lean | 51 ++----------------- 1 file changed, 3 insertions(+), 48 deletions(-) diff --git a/LeanMachineLearning/SequentialLearning/Comap.lean b/LeanMachineLearning/SequentialLearning/Comap.lean index 59d3f692..347f11f1 100644 --- a/LeanMachineLearning/SequentialLearning/Comap.lean +++ b/LeanMachineLearning/SequentialLearning/Comap.lean @@ -51,8 +51,7 @@ variable {π“ž π“ž' π“ž'' 𝓐 𝓐' 𝓐'' 𝓨 𝓨' 𝓨'' Ξ© : Type*} {m𝓐 : MeasurableSpace 𝓐} {m𝓐' : MeasurableSpace 𝓐'} {m𝓐'' : MeasurableSpace 𝓐''} {m𝓨 : MeasurableSpace 𝓨} {m𝓨' : MeasurableSpace 𝓨'} {m𝓨'' : MeasurableSpace 𝓨''} {mΞ© : MeasurableSpace Ξ©} - {fo : π“ž β†’ π“ž'} {fa : 𝓐 β†’ 𝓐'} {fy : 𝓨 β†’ 𝓨'} - {go : π“ž' β†’ π“ž''} {ga : 𝓐' β†’ 𝓐''} {gy : 𝓨' β†’ 𝓨''} + {fo : π“ž β†’ π“ž'} {fa : 𝓐 β†’ 𝓐'} {fy : 𝓨 β†’ 𝓨'} {go : π“ž' β†’ π“ž''} {ga : 𝓐' β†’ 𝓐''} {gy : 𝓨' β†’ 𝓨''} section Map @@ -65,11 +64,6 @@ def Hist.map (fo : π“ž β†’ π“ž') (fa : 𝓐 β†’ 𝓐') (fy : 𝓨 β†’ 𝓨') { Hist π“ž' 𝓐' 𝓨' n := fun i ↦ Round.map fo fa fy (h i) -/-- Transport a trajectory round-wise. -/ -def Traj.map (fo : π“ž β†’ π“ž') (fa : 𝓐 β†’ 𝓐') (fy : 𝓨 β†’ 𝓨') (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : - β„• β†’ Round π“ž' 𝓐' 𝓨' := - fun n ↦ Round.map fo fa fy (Ο„ n) - @[simp] lemma Round.obs_map (r : Round π“ž 𝓐 𝓨) : (Round.map fo fa fy r).obs = fo r.obs := rfl @[simp] lemma Round.action_map (r : Round π“ž 𝓐 𝓨) : (Round.map fo fa fy r).action = fa r.action := rfl @@ -79,43 +73,25 @@ def Traj.map (fo : π“ž β†’ π“ž') (fa : 𝓐 β†’ 𝓐') (fy : 𝓨 β†’ 𝓨') ( @[simp] lemma Hist.map_apply {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) (i : Fin n) : Hist.map fo fa fy h i = Round.map fo fa fy (h i) := rfl -@[simp] lemma Traj.map_apply (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) (n : β„•) : - Traj.map fo fa fy Ο„ n = Round.map fo fa fy (Ο„ n) := rfl - @[simp] lemma Round.map_id : Round.map (id : π“ž β†’ π“ž) (id : 𝓐 β†’ 𝓐) (id : 𝓨 β†’ 𝓨) = id := rfl @[simp] lemma Hist.map_id {n : β„•} : Hist.map (id : π“ž β†’ π“ž) (id : 𝓐 β†’ 𝓐) (id : 𝓨 β†’ 𝓨) (n := n) = id := rfl -@[simp] lemma Traj.map_id : Traj.map (id : π“ž β†’ π“ž) (id : 𝓐 β†’ 𝓐) (id : 𝓨 β†’ 𝓨) = id := rfl - lemma Round.map_comp (r : Round π“ž 𝓐 𝓨) : Round.map go ga gy (Round.map fo fa fy r) = Round.map (go ∘ fo) (ga ∘ fa) (gy ∘ fy) r := rfl lemma Hist.map_comp {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) : Hist.map go ga gy (Hist.map fo fa fy h) = Hist.map (go ∘ fo) (ga ∘ fa) (gy ∘ fy) h := rfl -lemma Traj.map_comp (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : - Traj.map go ga gy (Traj.map fo fa fy Ο„) = Traj.map (go ∘ fo) (ga ∘ fa) (gy ∘ fy) Ο„ := rfl - @[fun_prop] lemma Round.measurable_map (hfo : Measurable fo) (hfa : Measurable fa) (hfy : Measurable fy) : - Measurable (Round.map fo fa fy) := by - unfold Round.map - fun_prop + Measurable (Round.map fo fa fy) := by unfold Round.map; fun_prop @[fun_prop] lemma Hist.measurable_map (hfo : Measurable fo) (hfa : Measurable fa) (hfy : Measurable fy) (n : β„•) : - Measurable (Hist.map fo fa fy (n := n)) := by - unfold Hist.map - fun_prop - -@[fun_prop] -lemma Traj.measurable_map (hfo : Measurable fo) (hfa : Measurable fa) (hfy : Measurable fy) : - Measurable (Traj.map fo fa fy) := by - unfold Traj.map - fun_prop + Measurable (Hist.map fo fa fy (n := n)) := by unfold Hist.map; fun_prop /-- Transport the observations of a round. -/ abbrev Round.mapObs (f : π“ž β†’ π“ž') (r : Round π“ž 𝓐 𝓨) : Round π“ž' 𝓐 𝓨 := Round.map f id id r @@ -124,9 +100,6 @@ abbrev Round.mapObs (f : π“ž β†’ π“ž') (r : Round π“ž 𝓐 𝓨) : Round π“ž abbrev Hist.mapObs (f : π“ž β†’ π“ž') {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) : Hist π“ž' 𝓐 𝓨 n := Hist.map f id id h -/-- Transport the observations of a trajectory. -/ -abbrev Traj.mapObs (f : π“ž β†’ π“ž') (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : β„• β†’ Round π“ž' 𝓐 𝓨 := Traj.map f id id Ο„ - /-- Transport the actions of a round. -/ abbrev Round.mapAction (f : 𝓐 β†’ 𝓐') (r : Round π“ž 𝓐 𝓨) : Round π“ž 𝓐' 𝓨 := Round.map id f id r @@ -134,10 +107,6 @@ abbrev Round.mapAction (f : 𝓐 β†’ 𝓐') (r : Round π“ž 𝓐 𝓨) : Round abbrev Hist.mapAction (f : 𝓐 β†’ 𝓐') {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) : Hist π“ž 𝓐' 𝓨 n := Hist.map id f id h -/-- Transport the actions of a trajectory. -/ -abbrev Traj.mapAction (f : 𝓐 β†’ 𝓐') (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : β„• β†’ Round π“ž 𝓐' 𝓨 := - Traj.map id f id Ο„ - /-- Transport the feedback of a round. -/ abbrev Round.mapFeedback (f : 𝓨 β†’ 𝓨') (r : Round π“ž 𝓐 𝓨) : Round π“ž 𝓐 𝓨' := Round.map id id f r @@ -145,20 +114,6 @@ abbrev Round.mapFeedback (f : 𝓨 β†’ 𝓨') (r : Round π“ž 𝓐 𝓨) : Round abbrev Hist.mapFeedback (f : 𝓨 β†’ 𝓨') {n : β„•} (h : Hist π“ž 𝓐 𝓨 n) : Hist π“ž 𝓐 𝓨' n := Hist.map id id f h -/-- Transport the feedback of a trajectory. -/ -abbrev Traj.mapFeedback (f : 𝓨 β†’ 𝓨') (Ο„ : β„• β†’ Round π“ž 𝓐 𝓨) : β„• β†’ Round π“ž 𝓐 𝓨' := - Traj.map id id f Ο„ - -variable {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} - -lemma history_map (n : β„•) : - history (fun n Ο‰ ↦ fo (O n Ο‰)) (fun n Ο‰ ↦ fa (A n Ο‰)) (fun n Ο‰ ↦ fy (Y n Ο‰)) n - = Hist.map fo fa fy ∘ history O A Y n := rfl - -lemma trajectory_map : - trajectory (fun n Ο‰ ↦ fo (O n Ο‰)) (fun n Ο‰ ↦ fa (A n Ο‰)) (fun n Ο‰ ↦ fy (Y n Ο‰)) - = Traj.map fo fa fy ∘ trajectory O A Y := rfl - end Map section Comap From 9b4138bbdacd4f7ccdb25d587d8e0cb087fcbd46 Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Sat, 5 Sep 2026 14:58:00 +0200 Subject: [PATCH 17/21] docstrings --- LeanMachineLearning/SequentialLearning/Comap.lean | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/LeanMachineLearning/SequentialLearning/Comap.lean b/LeanMachineLearning/SequentialLearning/Comap.lean index 347f11f1..78392f5a 100644 --- a/LeanMachineLearning/SequentialLearning/Comap.lean +++ b/LeanMachineLearning/SequentialLearning/Comap.lean @@ -12,8 +12,8 @@ public import LeanMachineLearning.SequentialLearning.Algorithm ## Main definitions -* `Round.map fo fa fy`, `Hist.map fo fa fy`, `Traj.map fo fa fy`: round-wise transport of a round, - a history and a trajectory along maps of the observation, the action and the feedback, with the +* `Round.map fo fa fy`, `Hist.map fo fa fy`: round-wise transport of a round and a history + along maps of the observation, the action and the feedback, with the special cases `mapObs`, `mapAction` and `mapFeedback` that transport a single component. * `Algorithm.comap alg F hF`: the algorithm that transforms the pair (past rounds, current observation) by the measurable map `F n` at round `n` before applying the policy of `alg`. @@ -325,11 +325,7 @@ end Comap section Congr /-- Relabelling of the observations, the actions and the feedbacks of an algorithm along measurable -equivalences. - -This is the covariant transport that a player does admit: the algorithm reads its own past actions, -so post-composing its policy with a map of the actions only defines an algorithm on the target -types when that map can be inverted on the history. -/ +equivalences. -/ noncomputable def Algorithm.congr (alg : Algorithm π“ž 𝓐 𝓨) (eπ“ž : π“ž ≃ᡐ π“ž') (e𝓐 : 𝓐 ≃ᡐ 𝓐') (e𝓨 : 𝓨 ≃ᡐ 𝓨') : Algorithm π“ž' 𝓐' 𝓨' where policy n := ((alg.policy n).map e𝓐).comap @@ -378,9 +374,10 @@ lemma Algorithm.congr_symm (alg : Algorithm π“ž 𝓐 𝓨) (eπ“ž : π“ž ≃ᡐ MeasurableEquiv.self_trans_symm, congr_refl] /-- Relabelling of the observations, the actions and the feedbacks of an environment along -measurable equivalences. See `Algorithm.congr`. -/ +measurable equivalences. See also `Algorithm.congr`. -/ noncomputable def Environment.congr (env : Environment π“ž 𝓐 𝓨) (eπ“ž : π“ž ≃ᡐ π“ž') (e𝓐 : 𝓐 ≃ᡐ 𝓐') - (e𝓨 : 𝓨 ≃ᡐ 𝓨') : Environment π“ž' 𝓐' 𝓨' where + (e𝓨 : 𝓨 ≃ᡐ 𝓨') : + Environment π“ž' 𝓐' 𝓨' where obs n := ((env.obs n).map eπ“ž).comap (Hist.map eπ“ž.symm e𝓐.symm e𝓨.symm) (by fun_prop) feedback n := ((env.feedback n).map e𝓨).comap (fun p ↦ ((Hist.map eπ“ž.symm e𝓐.symm e𝓨.symm p.1.1, eπ“ž.symm p.1.2), e𝓐.symm p.2)) (by fun_prop) From b9addef6baad01365c9ead162099287a63eace52 Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Tue, 8 Sep 2026 12:56:21 +0200 Subject: [PATCH 18/21] fix --- .../Online/Bandit/RewardByCountMeasure.lean | 46 ++++++++++--------- .../SequentialLearning/Algorithm.lean | 11 +++-- .../SequentialLearning/FiniteActions.lean | 13 +++--- .../SequentialLearning/StationaryEnv.lean | 35 +++++++------- 4 files changed, 56 insertions(+), 49 deletions(-) diff --git a/LeanMachineLearning/Online/Bandit/RewardByCountMeasure.lean b/LeanMachineLearning/Online/Bandit/RewardByCountMeasure.lean index 0980ea8e..902d6c53 100644 --- a/LeanMachineLearning/Online/Bandit/RewardByCountMeasure.lean +++ b/LeanMachineLearning/Online/Bandit/RewardByCountMeasure.lean @@ -285,24 +285,24 @@ lemma indepFun_update_rewardByCountUntil_eval [Countable 𝓐] (hA : βˆ€ n, Meas /-- Conditionally on the event that the action at time `n` is `b` and that `b` was pulled `k` times before, the reward at time `n` is independent of the history before time `n` and of the action at time `n`. -/ -lemma indepFun_history_reward_cond (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) +lemma indepFun_history_reward_cond (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (n : β„•) (b : 𝓐) (k : β„•) : - (fun x ↦ (history A R n x, A n x)) + (fun x ↦ ((history O A R n x, O n x), A n x)) βŸ‚α΅’[P[|{x | A n x = b ∧ pullCount A b n x = k}]] R n := by - rw [setOf_action_eq_and_pullCount_eq_eq_preimage (R' := R)] + rw [setOf_action_eq_and_pullCount_eq_eq_preimage (O := O) (R' := R)] exact h.indepFun_history_action_feedback_cond_stationaryEnv n (measurableSet_snd_eq_and_pullCount'_eq n b k) fun u hu ↦ hu.1 /-- Conditionally on the event that the action at time `t` is `b` and that `b` was pulled `k` times before, the reward at time `t` has law `Ξ½ b`. -/ -lemma hasLaw_reward_cond (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) (t : β„•) (b : 𝓐) (k : β„•) +lemma hasLaw_reward_cond (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (t : β„•) (b : 𝓐) (k : β„•) (hP : P {x | A t x = b ∧ pullCount A b t x = k} β‰  0) : HasLaw (R t) (Ξ½ b) (P[|{x | A t x = b ∧ pullCount A b t x = k}]) := by - rw [setOf_action_eq_and_pullCount_eq_eq_preimage (R' := R)] at hP ⊒ + rw [setOf_action_eq_and_pullCount_eq_eq_preimage (O := O) (R' := R)] at hP ⊒ exact h.hasLaw_feedback_cond_stationaryEnv t (measurableSet_snd_eq_and_pullCount'_eq t b k) (fun u hu ↦ hu.1) hP -lemma hasLaw_reward_cond_prod (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) (t : β„•) (b : 𝓐) +lemma hasLaw_reward_cond_prod (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (t : β„•) (b : 𝓐) (k : β„•) (hP : P {x | A t x = b ∧ pullCount A b t x = k} β‰  0) : HasLaw (fun Ο‰ ↦ R t Ο‰.1) (Ξ½ b) ((P[|{x | A t x = b ∧ pullCount A b t x = k}]).prod (streamMeasure Ξ½)) := @@ -313,7 +313,7 @@ variable [Countable 𝓐] /-- Conditionally on the event that the action at time `t` is `b` and that `b` was pulled `k` times before, the array `rewardByCountUntil A R t` with the entry `(b, k)` erased is independent of the reward at time `t`. -/ -lemma indepFun_update_rewardByCountUntil_reward (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) +lemma indepFun_update_rewardByCountUntil_reward (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (t : β„•) (b : 𝓐) (k : β„•) : (fun Ο‰ ↦ Function.update (rewardByCountUntil A R t Ο‰) (b, k) 0) βŸ‚α΅’[(P[|{x | A t x = b ∧ pullCount A b t x = k}]).prod (streamMeasure Ξ½)] @@ -331,20 +331,22 @@ lemma indepFun_update_rewardByCountUntil_reward (h : IsAlgEnvSeq A R alg (statio refine Measurable.comp measurable_update_left ?_ refine measurable_rewardByCountUntil_of t (fun i hi ↦ ?_) (fun i hi ↦ ?_) ?_ Β· exact measurable_comp_comap - (fun Ο‰ : Ξ© Γ— (β„• β†’ 𝓐 β†’ ℝ) ↦ ((history A R t Ο‰.1, A t Ο‰.1), Ο‰.2)) - (g := fun v : ((Fin t β†’ 𝓐 Γ— ℝ) Γ— 𝓐) Γ— (β„• β†’ 𝓐 β†’ ℝ) ↦ (v.1.1 ⟨i, hi⟩).1) (by fun_prop) + (fun Ο‰ : Ξ© Γ— (β„• β†’ 𝓐 β†’ ℝ) ↦ (((history O A R t Ο‰.1, O t Ο‰.1), A t Ο‰.1), Ο‰.2)) + (g := fun v : ((Hist Unit 𝓐 ℝ t Γ— Unit) Γ— 𝓐) Γ— (β„• β†’ 𝓐 β†’ ℝ) ↦ (v.1.1.1 ⟨i, hi⟩).action) + (by fun_prop) Β· exact measurable_comp_comap - (fun Ο‰ : Ξ© Γ— (β„• β†’ 𝓐 β†’ ℝ) ↦ ((history A R t Ο‰.1, A t Ο‰.1), Ο‰.2)) - (g := fun v : ((Fin t β†’ 𝓐 Γ— ℝ) Γ— 𝓐) Γ— (β„• β†’ 𝓐 β†’ ℝ) ↦ (v.1.1 ⟨i, hi⟩).2) (by fun_prop) + (fun Ο‰ : Ξ© Γ— (β„• β†’ 𝓐 β†’ ℝ) ↦ (((history O A R t Ο‰.1, O t Ο‰.1), A t Ο‰.1), Ο‰.2)) + (g := fun v : ((Hist Unit 𝓐 ℝ t Γ— Unit) Γ— 𝓐) Γ— (β„• β†’ 𝓐 β†’ ℝ) ↦ (v.1.1.1 ⟨i, hi⟩).feedback) + (by fun_prop) Β· exact measurable_comp_comap - (fun Ο‰ : Ξ© Γ— (β„• β†’ 𝓐 β†’ ℝ) ↦ ((history A R t Ο‰.1, A t Ο‰.1), Ο‰.2)) - (g := fun v : ((Fin t β†’ 𝓐 Γ— ℝ) Γ— 𝓐) Γ— (β„• β†’ 𝓐 β†’ ℝ) ↦ v.2) measurable_snd + (fun Ο‰ : Ξ© Γ— (β„• β†’ 𝓐 β†’ ℝ) ↦ (((history O A R t Ο‰.1, O t Ο‰.1), A t Ο‰.1), Ο‰.2)) + (g := fun v : ((Hist Unit 𝓐 ℝ t Γ— Unit) Γ— 𝓐) Γ— (β„• β†’ 𝓐 β†’ ℝ) ↦ v.2) measurable_snd /-- Conditionally on the event that the action at time `t` is `b` and that `b` was pulled `k` times before, the arrays `rewardByCountUntil A R (t + 1)` and `rewardByCountUntil A R t` have the same law: they differ only in the entry `(b, k)`, which is `R t` in the first and an auxiliary reward in the second, and both are independent of the rest of the array with law `Ξ½ b`. -/ -lemma identDistrib_rewardByCountUntil_add_one_cond (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) +lemma identDistrib_rewardByCountUntil_add_one_cond (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (t : β„•) (b : 𝓐) (k : β„•) : IdentDistrib (rewardByCountUntil A R (t + 1)) (rewardByCountUntil A R t) ((P[|{x | A t x = b ∧ pullCount A b t x = k}]).prod (streamMeasure Ξ½)) @@ -400,7 +402,7 @@ lemma identDistrib_rewardByCountUntil_add_one_cond (h : IsAlgEnvSeq A R alg (sta (IdentDistrib.of_ae_eq (measurable_rewardByCountUntil hA hR _).aemeasurable h2).symm /-- The law of `rewardByCountUntil A R t` under `𝔓` does not depend on `t`. -/ -lemma identDistrib_rewardByCountUntil_add_one (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) +lemma identDistrib_rewardByCountUntil_add_one (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (t : β„•) : IdentDistrib (rewardByCountUntil A R (t + 1)) (rewardByCountUntil A R t) 𝔓 𝔓 := by have hA := h.measurable_action @@ -425,7 +427,7 @@ lemma identDistrib_rewardByCountUntil_add_one (h : IsAlgEnvSeq A R alg (stationa exact identDistrib_rewardByCountUntil_add_one_cond h t p.1 p.2 /-- The law of `rewardByCountUntil A R t` under `𝔓` is `⨂ (a, m), Ξ½ a`, for all `t`. -/ -lemma hasLaw_rewardByCountUntil (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) (t : β„•) : +lemma hasLaw_rewardByCountUntil (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (t : β„•) : HasLaw (rewardByCountUntil A R t) (Measure.infinitePi fun p : 𝓐 Γ— β„• ↦ Ξ½ p.1) 𝔓 := by induction t with | zero => exact hasLaw_rewardByCountUntil_zero P @@ -433,7 +435,7 @@ lemma hasLaw_rewardByCountUntil (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) ( /-- The array of rewards by count `(a, m) ↦ rewardByCount A R a (m + 1)` has law `⨂ (a, m), Ξ½ a`: its entries are independent, and the entry `(a, m)` has law `Ξ½ a`. -/ -lemma hasLaw_rewardByCount_infinitePi (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) : +lemma hasLaw_rewardByCount_infinitePi (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) : HasLaw (fun Ο‰ (p : 𝓐 Γ— β„•) ↦ rewardByCount A R p.1 (p.2 + 1) Ο‰) (Measure.infinitePi fun p : 𝓐 Γ— β„• ↦ Ξ½ p.1) 𝔓 := by have hY : Measurable fun Ο‰ (p : 𝓐 Γ— β„•) ↦ rewardByCount A R p.1 (p.2 + 1) Ο‰ := @@ -445,14 +447,14 @@ lemma hasLaw_rewardByCount_infinitePi (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½ (hasLaw_rewardByCountUntil h) eventually_rewardByCountUntil_eq /-- The reward received at the `(m + 1)`-th pull of action `a` has law `Ξ½ a`. -/ -lemma hasLaw_rewardByCount_add_one (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) +lemma hasLaw_rewardByCount_add_one (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (a : 𝓐) (m : β„•) : HasLaw (rewardByCount A R a (m + 1)) (Ξ½ a) 𝔓 := (hasLaw_eval_infinitePi (fun p : 𝓐 Γ— β„• ↦ Ξ½ p.1) (a, m)).comp (hasLaw_rewardByCount_infinitePi h) /-- The rewards by count `rewardByCount A R a (m + 1)` are independent over all actions `a` and all counts `m`. -/ -lemma iIndepFun_rewardByCount_add_one (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) : +lemma iIndepFun_rewardByCount_add_one (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) : iIndepFun (fun (p : 𝓐 Γ— β„•) Ο‰ ↦ rewardByCount A R p.1 (p.2 + 1) Ο‰) 𝔓 := (iIndepFun_iff_hasLaw_Pi_infinitePi (X := fun (p : 𝓐 Γ— β„•) Ο‰ ↦ rewardByCount A R p.1 (p.2 + 1) Ο‰) (ΞΌ := fun p : 𝓐 Γ— β„• ↦ Ξ½ p.1) @@ -461,7 +463,7 @@ lemma iIndepFun_rewardByCount_add_one (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½ /-- The rewards by count `rewardByCount A R a m` for `m β‰  0` are independent over all actions `a` and all counts `m`. -/ -lemma iIndepFun_rewardByCount (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) : +lemma iIndepFun_rewardByCount (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) : iIndepFun (fun (p : {p : 𝓐 Γ— β„• // p.2 β‰  0}) Ο‰ ↦ rewardByCount A R p.1.1 p.1.2 Ο‰) 𝔓 := by have h_eq : (fun (p : {p : 𝓐 Γ— β„• // p.2 β‰  0}) Ο‰ ↦ rewardByCount A R p.1.1 p.1.2 Ο‰) = fun p Ο‰ ↦ rewardByCount A R p.1.1 (p.1.2 - 1 + 1) Ο‰ := by @@ -475,14 +477,14 @@ lemma iIndepFun_rewardByCount (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) : /-- For each action `a`, the rewards by count `(rewardByCount A R a (m + 1))_m` are independent (and by `hasLaw_rewardByCount_add_one` identically distributed with law `Ξ½ a`). -/ -lemma iIndepFun_rewardByCount_add_one_action (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) +lemma iIndepFun_rewardByCount_add_one_action (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) (a : 𝓐) : iIndepFun (fun m Ο‰ ↦ rewardByCount A R a (m + 1) Ο‰) 𝔓 := (iIndepFun_rewardByCount_add_one h).precomp (g := fun m ↦ (a, m)) fun _ _ hmn ↦ (Prod.mk.inj hmn).2 /-- Two distinct rewards by count are independent. -/ -lemma indepFun_rewardByCount (h : IsAlgEnvSeq A R alg (stationaryEnv Ξ½) P) +lemma indepFun_rewardByCount (h : IsAlgEnvSeq O A R alg (stationaryEnv Ξ½) P) {a b : 𝓐} {m n : β„•} (hm : m β‰  0) (hn : n β‰  0) (hne : (a, m) β‰  (b, n)) : rewardByCount A R a m βŸ‚α΅’[𝔓] rewardByCount A R b n := (iIndepFun_rewardByCount h).indepFun (i := ⟨(a, m), hm⟩) (j := ⟨(b, n), hn⟩) diff --git a/LeanMachineLearning/SequentialLearning/Algorithm.lean b/LeanMachineLearning/SequentialLearning/Algorithm.lean index 22888fa7..c711163c 100644 --- a/LeanMachineLearning/SequentialLearning/Algorithm.lean +++ b/LeanMachineLearning/SequentialLearning/Algorithm.lean @@ -507,12 +507,13 @@ lemma IsAlgEnvSeq.hasLaw_step_comp (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) : HasLaw (step O A Y n) (stepKernel alg env n βˆ˜β‚˜ (P.map (history O A Y n))) P := HasCondDistrib.hasLaw_comp (h.hasCondDistrib_step n) -/-- Conditionally on the event `A 0 = b`, the first feedback has law `env.Ξ½0 b`. -/ -lemma IsAlgEnvSeq.hasLaw_feedback_zero_cond [MeasurableSingletonClass 𝓐] - (h : IsAlgEnvSeq A Y alg env P) {b : 𝓐} (hP : P (A 0 ⁻¹' {b}) β‰  0) : - HasLaw (Y 0) (env.Ξ½0 b) P[|A 0 ⁻¹' {b}] := +/-- Conditionally on the event `(O 0, A 0) = p`, the first feedback has law `env.Ξ½0 p`. -/ +lemma IsAlgEnvSeq.hasLaw_feedback_zero_cond [MeasurableSingletonClass π“ž] + [MeasurableSingletonClass 𝓐] (h : IsAlgEnvSeq O A Y alg env P) {p : π“ž Γ— 𝓐} + (hP : P ((fun Ο‰ ↦ (O 0 Ο‰, A 0 Ο‰)) ⁻¹' {p}) β‰  0) : + HasLaw (Y 0) (env.Ξ½0 p) P[|(fun Ο‰ ↦ (O 0 Ο‰, A 0 Ο‰)) ⁻¹' {p}] := h.hasCondDistrib_feedback_zero.hasLaw_cond (h.measurable_feedback 0) - (measurableSet_singleton b) (fun a ha ↦ by rw [Set.mem_singleton_iff.1 ha]) hP + (measurableSet_singleton p) (fun a ha ↦ by rw [Set.mem_singleton_iff.1 ha]) hP section Filtration diff --git a/LeanMachineLearning/SequentialLearning/FiniteActions.lean b/LeanMachineLearning/SequentialLearning/FiniteActions.lean index 7c739e6a..b0ca865b 100644 --- a/LeanMachineLearning/SequentialLearning/FiniteActions.lean +++ b/LeanMachineLearning/SequentialLearning/FiniteActions.lean @@ -249,19 +249,20 @@ lemma measurableSet_action_eq_and_pullCount_eq [MeasurableSingletonClass 𝓐] lemma measurableSet_snd_eq_and_pullCount'_eq [MeasurableSingletonClass 𝓐] (n : β„•) (b : 𝓐) (k : β„•) : - MeasurableSet {u : (Fin n β†’ 𝓐 Γ— R) Γ— 𝓐 | u.2 = b ∧ pullCount' n u.1 b = k} := + MeasurableSet {u : (Hist π“ž 𝓐 R n Γ— π“ž) Γ— 𝓐 | u.2 = b ∧ pullCount' n u.1.1 b = k} := ((measurableSet_singleton _).preimage measurable_snd).inter - ((measurableSet_singleton _).preimage ((measurable_pullCount' n b).comp measurable_fst)) + ((measurableSet_singleton _).preimage + ((measurable_pullCount' n b).comp (measurable_fst.comp measurable_fst))) /-- The event that the action at time `n` is `b` and that `b` was pulled `k` times before is -a preimage by `(history A R' n, A n)`. -/ +a preimage by `((history O A R' n, O n), A n)`. -/ lemma setOf_action_eq_and_pullCount_eq_eq_preimage (n : β„•) (b : 𝓐) (k : β„•) : {x | A n x = b ∧ pullCount A b n x = k} - = (fun x ↦ (history A R' n x, A n x)) ⁻¹' {u | u.2 = b ∧ pullCount' n u.1 b = k} := by + = (fun x ↦ ((history O A R' n x, O n x), A n x)) + ⁻¹' {u | u.2 = b ∧ pullCount' n u.1.1 b = k} := by ext x simp only [Set.mem_ofPred_eq, Set.mem_preimage] - rw [pullCount_eq_pullCount' (R' := R')] - rfl + rw [pullCount_eq_pullCount' (O := O) (R' := R')] lemma integrable_pullCount [MeasurableSingletonClass 𝓐] (hA : βˆ€ n, Measurable (A n)) (a : 𝓐) (n : β„•) : diff --git a/LeanMachineLearning/SequentialLearning/StationaryEnv.lean b/LeanMachineLearning/SequentialLearning/StationaryEnv.lean index 61da5670..3acb5363 100644 --- a/LeanMachineLearning/SequentialLearning/StationaryEnv.lean +++ b/LeanMachineLearning/SequentialLearning/StationaryEnv.lean @@ -96,11 +96,11 @@ lemma hasCondDistrib_feedback [IsObliviousEnv env] (h : IsAlgEnvSeq O A Y alg en /-- Conditionally on an event determined by the history before time `n` and the action at time `n`, on which that action is equal to `b`, the feedback at time `n` has law `feedbackCondAction env n b`. -/ -lemma hasLaw_feedback_cond [IsObliviousEnv env] (h : IsAlgEnvSeq A Y alg env P) (n : β„•) - {s : Set ((Fin n β†’ 𝓐 Γ— 𝓨) Γ— 𝓐)} (hs : MeasurableSet s) {b : 𝓐} (hsb : βˆ€ u ∈ s, u.2 = b) - (hP : P ((fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) ⁻¹' s) β‰  0) : +lemma hasLaw_feedback_cond [IsObliviousEnv env] (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) + {s : Set ((Hist π“ž 𝓐 𝓨 n Γ— π“ž) Γ— 𝓐)} (hs : MeasurableSet s) {b : 𝓐} (hsb : βˆ€ u ∈ s, u.2 = b) + (hP : P ((fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) ⁻¹' s) β‰  0) : HasLaw (Y n) (feedbackCondAction env n b) - P[|(fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) ⁻¹' s] := by + P[|(fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) ⁻¹' s] := by refine (hasCondDistrib_feedback_history_action h n).hasLaw_cond (h.measurable_feedback _) hs (fun u hu ↦ ?_) hP rw [Kernel.prodMkLeft_apply, hsb u hu] @@ -109,10 +109,11 @@ lemma hasLaw_feedback_cond [IsObliviousEnv env] (h : IsAlgEnvSeq A Y alg env P) `n`, on which that action is constant, the feedback at time `n` is independent of the history before time `n` and of the action at time `n`. -/ lemma indepFun_history_action_feedback_cond [IsObliviousEnv env] - (h : IsAlgEnvSeq A Y alg env P) (n : β„•) - {s : Set ((Fin n β†’ 𝓐 Γ— 𝓨) Γ— 𝓐)} (hs : MeasurableSet s) {b : 𝓐} (hsb : βˆ€ u ∈ s, u.2 = b) : - (fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) - βŸ‚α΅’[P[|(fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) ⁻¹' s]] Y n := by + (h : IsAlgEnvSeq O A Y alg env P) (n : β„•) + {s : Set ((Hist π“ž 𝓐 𝓨 n Γ— π“ž) Γ— 𝓐)} (hs : MeasurableSet s) {b : 𝓐} (hsb : βˆ€ u ∈ s, u.2 = b) : + (fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) + βŸ‚α΅’[P[|(fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) ⁻¹' s]] Y n := by + have hO := h.measurable_obs have hA := h.measurable_action have hY := h.measurable_feedback refine (hasCondDistrib_feedback_history_action h n).indepFun_cond (by fun_prop) hs @@ -249,20 +250,22 @@ lemma condDistrib_feedback_stationaryEnv [StandardBorelSpace 𝓨] [Nonempty /-- Conditionally on an event determined by the history before time `n` and the action at time `n`, on which that action is equal to `b`, the feedback at time `n` has law `Ξ½ b`. -/ -lemma hasLaw_feedback_cond_stationaryEnv (h : IsAlgEnvSeq A Y alg (stationaryEnv Ξ½) P) (n : β„•) - {s : Set ((Fin n β†’ 𝓐 Γ— 𝓨) Γ— 𝓐)} (hs : MeasurableSet s) {b : 𝓐} (hsb : βˆ€ u ∈ s, u.2 = b) - (hP : P ((fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) ⁻¹' s) β‰  0) : - HasLaw (Y n) (Ξ½ b) P[|(fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) ⁻¹' s] := by +lemma hasLaw_feedback_cond_stationaryEnv (h : IsAlgEnvSeq O A Y alg (stationaryEnv Ξ½) P) (n : β„•) + {s : Set ((Hist Unit 𝓐 𝓨 n Γ— Unit) Γ— 𝓐)} (hs : MeasurableSet s) {b : 𝓐} + (hsb : βˆ€ u ∈ s, u.2 = b) + (hP : P ((fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) ⁻¹' s) β‰  0) : + HasLaw (Y n) (Ξ½ b) P[|(fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) ⁻¹' s] := by simpa using IsObliviousEnv.hasLaw_feedback_cond h n hs hsb hP /-- Conditionally on an event determined by the history before time `n` and the action at time `n`, on which that action is constant, the feedback at time `n` is independent of the history before time `n` and of the action at time `n`. -/ lemma indepFun_history_action_feedback_cond_stationaryEnv - (h : IsAlgEnvSeq A Y alg (stationaryEnv Ξ½) P) (n : β„•) - {s : Set ((Fin n β†’ 𝓐 Γ— 𝓨) Γ— 𝓐)} (hs : MeasurableSet s) {b : 𝓐} (hsb : βˆ€ u ∈ s, u.2 = b) : - (fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) - βŸ‚α΅’[P[|(fun Ο‰ ↦ (history A Y n Ο‰, A n Ο‰)) ⁻¹' s]] Y n := + (h : IsAlgEnvSeq O A Y alg (stationaryEnv Ξ½) P) (n : β„•) + {s : Set ((Hist Unit 𝓐 𝓨 n Γ— Unit) Γ— 𝓐)} (hs : MeasurableSet s) {b : 𝓐} + (hsb : βˆ€ u ∈ s, u.2 = b) : + (fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) + βŸ‚α΅’[P[|(fun Ο‰ ↦ ((history O A Y n Ο‰, O n Ο‰), A n Ο‰)) ⁻¹' s]] Y n := IsObliviousEnv.indepFun_history_action_feedback_cond h n hs hsb /-- The feedback at time `n` is conditionally independent of the history before time `n` From 97a661292dbb55f1d94158460468a73e48410674 Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Thu, 10 Sep 2026 11:21:47 +0200 Subject: [PATCH 19/21] merge --- .../DivergenceDecomposition.lean | 137 ++++++++++-------- .../SequentialLearning/StationaryEnv.lean | 8 +- 2 files changed, 84 insertions(+), 61 deletions(-) diff --git a/LeanMachineLearning/SequentialLearning/DivergenceDecomposition.lean b/LeanMachineLearning/SequentialLearning/DivergenceDecomposition.lean index 4cb2be59..a45faebd 100644 --- a/LeanMachineLearning/SequentialLearning/DivergenceDecomposition.lean +++ b/LeanMachineLearning/SequentialLearning/DivergenceDecomposition.lean @@ -15,19 +15,19 @@ public import LeanMachineLearning.SequentialLearning.StationaryEnv # The divergence decomposition Let `alg`, `alg'` be algorithms, `env`, `env'` be environments, and consider two -algorithm-environment sequences `(X, Y)` and `(X', Y')` of `alg` against `env` and of `alg'` +algorithm-environment sequences `(O, A, Y)` and `(O', A', Y')` of `alg` against `env` and of `alg'` against `env'`, on arbitrary probability spaces `(Ξ©, P)` and `(Ξ©', P')`. The Kullback-Leibler divergence between the laws of the histories of the first `M` rounds is the sum, over the rounds `t < M`, of the conditional divergences of the step at round `t` given the first `t` rounds. Note that both arguments of the conditional term use the law of the *first* history, so that term measures only how the two step kernels differ. -The same identity holds for the whole trajectory `trajectory X Y : Ξ© β†’ (β„• β†’ 𝓐 Γ— 𝓨)`, with a series -in place of the finite sum. +The same identity holds for the whole trajectory `trajectory O A Y : Ξ© β†’ (β„• β†’ Round π“ž 𝓐 𝓨)`, with +a series in place of the finite sum. For a single algorithm run against two stationary environments with reward kernels `ΞΊ` and -`ΞΊ'`, the two step kernels share the policy and differ only in the reward kernel, so the -conditional divergence of a step is the conditional divergence of the reward given the played -action. +`ΞΊ'`, the two step kernels share the observation kernel and the policy and differ only in the +reward kernel, so the conditional divergence of a step is the conditional divergence of the reward +given the played action. This is the *divergence decomposition* of bandit lower bounds. ## Main statements @@ -49,17 +49,18 @@ open scoped ENNReal RealInnerProductSpace ENat namespace Learning -variable {𝓐 𝓨 : Type*} {m𝓐 : MeasurableSpace 𝓐} {m𝓨 : MeasurableSpace 𝓨} +variable {π“ž 𝓐 𝓨 : Type*} {mπ“ž : MeasurableSpace π“ž} {m𝓐 : MeasurableSpace 𝓐} + {m𝓨 : MeasurableSpace 𝓨} {Ξ© Ξ©' : Type*} {mΞ© : MeasurableSpace Ξ©} {mΞ©' : MeasurableSpace Ξ©'} {P : Measure Ξ©} {P' : Measure Ξ©'} [IsProbabilityMeasure P] [IsProbabilityMeasure P'] - {X : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} {X' : β„• β†’ Ξ©' β†’ 𝓐} {Y' : β„• β†’ Ξ©' β†’ 𝓨} - {alg alg' : Algorithm 𝓐 𝓨} {env env' : Environment 𝓐 𝓨} - {ΞΊ ΞΊ' : Kernel 𝓐 𝓨} [IsMarkovKernel ΞΊ] [IsMarkovKernel ΞΊ'] + {O : β„• β†’ Ξ© β†’ π“ž} {A : β„• β†’ Ξ© β†’ 𝓐} {Y : β„• β†’ Ξ© β†’ 𝓨} + {O' : β„• β†’ Ξ©' β†’ π“ž} {A' : β„• β†’ Ξ©' β†’ 𝓐} {Y' : β„• β†’ Ξ©' β†’ 𝓨} + {alg alg' : Algorithm π“ž 𝓐 𝓨} {env env' : Environment π“ž 𝓐 𝓨} section -variable {Ξ± Ξ² Ξ³ : Type*} {mΞ± : MeasurableSpace Ξ±} {mΞ² : MeasurableSpace Ξ²} - {mΞ³ : MeasurableSpace Ξ³} {ΞΌ : Measure Ξ±} [IsFiniteMeasure ΞΌ] +variable {Ξ± Ξ² Ξ³ Ξ΄ : Type*} {mΞ± : MeasurableSpace Ξ±} {mΞ² : MeasurableSpace Ξ²} + {mΞ³ : MeasurableSpace Ξ³} {mΞ΄ : MeasurableSpace Ξ΄} {ΞΌ : Measure Ξ±} [IsFiniteMeasure ΞΌ] /-- The divergence of one step of a policy/reward decomposition, in composition-product form: the policy `Ο€` is shared and the reward kernels `ΞΊ`, `Ξ·` (which ignore the history) differ, so @@ -74,21 +75,38 @@ lemma klDiv_compProd_compProd_prodMkLeft_eq_klDiv_comp_compProd (ΞΌ : Measure Ξ± Measure.compProd_assoc, ← Measure.snd_compProd, Measure.snd] exact klDiv_compProd_comap _ _ _ measurable_snd +/-- The divergence of one step of an observation/policy/reward decomposition, in +composition-product form: the observation kernel `o` and the policy `Ο€` are shared and the reward +kernels `ΞΊ`, `Ξ·` (which ignore the history and the observation) differ, so the divergence is the +conditional divergence of the reward kernels given the played action, whose law is +`Ο€ βˆ˜β‚˜ (ΞΌ βŠ—β‚˜ o)`. -/ +lemma klDiv_compProd_compProd_compProd_prodMkLeft_eq_klDiv_comp_compProd (ΞΌ : Measure Ξ±) + [IsFiniteMeasure ΞΌ] (o : Kernel Ξ± Ξ²) [IsMarkovKernel o] (Ο€ : Kernel (Ξ± Γ— Ξ²) Ξ³) + [IsMarkovKernel Ο€] (ΞΊ Ξ· : Kernel Ξ³ Ξ΄) [IsFiniteKernel ΞΊ] [IsFiniteKernel Ξ·] : + klDiv (ΞΌ βŠ—β‚˜ (o βŠ—β‚– (Ο€ βŠ—β‚– ΞΊ.prodMkLeft (Ξ± Γ— Ξ²)))) + (ΞΌ βŠ—β‚˜ (o βŠ—β‚– (Ο€ βŠ—β‚– Ξ·.prodMkLeft (Ξ± Γ— Ξ²)))) = + klDiv ((Ο€ βˆ˜β‚˜ (ΞΌ βŠ—β‚˜ o)) βŠ—β‚˜ ΞΊ) ((Ο€ βˆ˜β‚˜ (ΞΌ βŠ—β‚˜ o)) βŠ—β‚˜ Ξ·) := by + rw [← klDiv_map_measurableEquiv _ _ MeasurableEquiv.prodAssoc.symm, Measure.compProd_assoc, + Measure.compProd_assoc] + exact klDiv_compProd_compProd_prodMkLeft_eq_klDiv_comp_compProd _ _ _ _ + end /-- **Chain rule for histories.** For two algorithms `alg`, `alg'` run against two environments `env`, `env'`, the divergence between the laws of the histories of the first `M` rounds is the sum over the rounds `t < M` of the conditional divergences of the step at round `t` given the first `t` rounds. -/ -lemma IsAlgEnvSeq.klDiv_map_history_stepKernel (h : IsAlgEnvSeq X Y alg env P) - (h' : IsAlgEnvSeq X' Y' alg' env' P') (M : β„•) : - klDiv (P.map (history X Y M)) (P'.map (history X' Y' M)) = +lemma IsAlgEnvSeq.klDiv_map_history_stepKernel (h : IsAlgEnvSeq O A Y alg env P) + (h' : IsAlgEnvSeq O' A' Y' alg' env' P') (M : β„•) : + klDiv (P.map (history O A Y M)) (P'.map (history O' A' Y' M)) = βˆ‘ t ∈ range M, - klDiv (P.map (history X Y t) βŠ—β‚˜ stepKernel alg env t) - (P.map (history X Y t) βŠ—β‚˜ stepKernel alg' env' t) := by - have hX := h.measurable_action + klDiv (P.map (history O A Y t) βŠ—β‚˜ stepKernel alg env t) + (P.map (history O A Y t) βŠ—β‚˜ stepKernel alg' env' t) := by + have hO := h.measurable_obs + have hA := h.measurable_action have hY := h.measurable_feedback - have hX' := h'.measurable_action + have hO' := h'.measurable_obs + have hA' := h'.measurable_action have hY' := h'.measurable_feedback induction M with | zero => simp @@ -100,21 +118,22 @@ lemma IsAlgEnvSeq.klDiv_map_history_stepKernel (h : IsAlgEnvSeq X Y alg env P) /-- The divergence between the laws of two trajectories is the supremum over `n` of the divergences between the laws of the histories up to time `n`. -/ -lemma klDiv_map_trajectory_eq_iSup (hX : βˆ€ n, Measurable (X n)) (hY : βˆ€ n, Measurable (Y n)) - (hX' : βˆ€ n, Measurable (X' n)) (hY' : βˆ€ n, Measurable (Y' n)) : - klDiv (P.map (trajectory X Y)) (P'.map (trajectory X' Y')) = - ⨆ n, klDiv (P.map (history X Y n)) (P'.map (history X' Y' n)) := by - have hg : βˆ€ n, Measurable fun f : β„• β†’ 𝓐 Γ— 𝓨 ↦ fun i : Fin n ↦ f i.1 := fun n ↦ +lemma klDiv_map_trajectory_eq_iSup (hO : βˆ€ n, Measurable (O n)) (hA : βˆ€ n, Measurable (A n)) + (hY : βˆ€ n, Measurable (Y n)) (hO' : βˆ€ n, Measurable (O' n)) (hA' : βˆ€ n, Measurable (A' n)) + (hY' : βˆ€ n, Measurable (Y' n)) : + klDiv (P.map (trajectory O A Y)) (P'.map (trajectory O' A' Y')) = + ⨆ n, klDiv (P.map (history O A Y n)) (P'.map (history O' A' Y' n)) := by + have hg : βˆ€ n, Measurable fun f : β„• β†’ Round π“ž 𝓐 𝓨 ↦ fun i : Fin n ↦ f i.1 := fun n ↦ measurable_pi_lambda _ fun i ↦ measurable_pi_apply i.1 rw [klDiv_eq_iSup_map hg ?_ MeasurableSpace.iSup_comap_restrictFin] Β· refine iSup_congr fun n ↦ ?_ - rw [Measure.map_map (hg n) (measurable_trajectory hX hY), - Measure.map_map (hg n) (measurable_trajectory hX' hY')] + rw [Measure.map_map (hg n) (measurable_trajectory hO hA hY), + Measure.map_map (hg n) (measurable_trajectory hO' hA' hY')] rfl Β· intro n m hnm - have : (fun f : β„• β†’ 𝓐 Γ— 𝓨 ↦ fun i : Fin n ↦ f i.1) = - (fun h : Fin m β†’ 𝓐 Γ— 𝓨 ↦ fun i : Fin n ↦ h (Fin.castLE hnm i)) ∘ - fun f : β„• β†’ 𝓐 Γ— 𝓨 ↦ fun i : Fin m ↦ f i.1 := rfl + have : (fun f : β„• β†’ Round π“ž 𝓐 𝓨 ↦ fun i : Fin n ↦ f i.1) = + (fun h : Fin m β†’ Round π“ž 𝓐 𝓨 ↦ fun i : Fin n ↦ h (Fin.castLE hnm i)) ∘ + fun f : β„• β†’ Round π“ž 𝓐 𝓨 ↦ fun i : Fin m ↦ f i.1 := rfl beta_reduce rw [this, ← MeasurableSpace.comap_comp] exact MeasurableSpace.comap_mono (measurable_pi_lambda _ fun i ↦ @@ -124,57 +143,59 @@ lemma klDiv_map_trajectory_eq_iSup (hX : βˆ€ n, Measurable (X n)) (hY : βˆ€ n, M two environments `env` and `env'`, the divergence between the laws of the trajectories is the series over the rounds `t` of the conditional divergences of the step at round `t` given the first `t` rounds. -/ -lemma IsAlgEnvSeq.klDiv_map_trajectory_stepKernel (h : IsAlgEnvSeq X Y alg env P) - (h' : IsAlgEnvSeq X' Y' alg' env' P') : - klDiv (P.map (trajectory X Y)) (P'.map (trajectory X' Y')) = - βˆ‘' t : β„•, klDiv (P.map (history X Y t) βŠ—β‚˜ stepKernel alg env t) - (P.map (history X Y t) βŠ—β‚˜ stepKernel alg' env' t) := by - have hX := h.measurable_action - have hY := h.measurable_feedback - have hX' := h'.measurable_action - have hY' := h'.measurable_feedback - rw [klDiv_map_trajectory_eq_iSup hX hY hX' hY', ENNReal.tsum_eq_iSup_nat] +lemma IsAlgEnvSeq.klDiv_map_trajectory_stepKernel (h : IsAlgEnvSeq O A Y alg env P) + (h' : IsAlgEnvSeq O' A' Y' alg' env' P') : + klDiv (P.map (trajectory O A Y)) (P'.map (trajectory O' A' Y')) = + βˆ‘' t : β„•, klDiv (P.map (history O A Y t) βŠ—β‚˜ stepKernel alg env t) + (P.map (history O A Y t) βŠ—β‚˜ stepKernel alg' env' t) := by + rw [klDiv_map_trajectory_eq_iSup h.measurable_obs h.measurable_action h.measurable_feedback + h'.measurable_obs h'.measurable_action h'.measurable_feedback, ENNReal.tsum_eq_iSup_nat] exact iSup_congr fun n ↦ h.klDiv_map_history_stepKernel h' n section StationaryEnv +variable {O : β„• β†’ Ξ© β†’ Unit} {O' : β„• β†’ Ξ©' β†’ Unit} {alg : Algorithm Unit 𝓐 𝓨} + {ΞΊ ΞΊ' : Kernel 𝓐 𝓨} [IsMarkovKernel ΞΊ] [IsMarkovKernel ΞΊ'] + /-- Chain rule for histories of a single algorithm versus two stationary environments. -/ -lemma IsAlgEnvSeq.klDiv_map_history_compProd (h : IsAlgEnvSeq X Y alg (stationaryEnv ΞΊ) P) - (h' : IsAlgEnvSeq X' Y' alg (stationaryEnv ΞΊ') P') (M : β„•) : - klDiv (P.map (history X Y M)) (P'.map (history X' Y' M)) = - βˆ‘ t ∈ range M, klDiv (P.map (X t) βŠ—β‚˜ ΞΊ) (P.map (X t) βŠ—β‚˜ ΞΊ') := by +lemma IsAlgEnvSeq.klDiv_map_history_compProd (h : IsAlgEnvSeq O A Y alg (stationaryEnv ΞΊ) P) + (h' : IsAlgEnvSeq O' A' Y' alg (stationaryEnv ΞΊ') P') (M : β„•) : + klDiv (P.map (history O A Y M)) (P'.map (history O' A' Y' M)) = + βˆ‘ t ∈ range M, klDiv (P.map (A t) βŠ—β‚˜ ΞΊ) (P.map (A t) βŠ—β‚˜ ΞΊ') := by rw [h.klDiv_map_history_stepKernel h'] refine sum_congr rfl fun t _ ↦ ?_ + have h_obs := (h.hasCondDistrib_obs t).map_eq + rw [obs_stationaryEnv] at h_obs rw [stepKernel_stationaryEnv, stepKernel_stationaryEnv, - klDiv_compProd_compProd_prodMkLeft_eq_klDiv_comp_compProd, + klDiv_compProd_compProd_compProd_prodMkLeft_eq_klDiv_comp_compProd, ← h_obs, ← (h.hasCondDistrib_action t).hasLaw_comp.map_eq] /-- Chain rule for histories of a single algorithm versus two stationary environments. -/ lemma IsAlgEnvSeq.klDiv_map_history [MeasurableSpace.CountablyGenerated 𝓨] - (h : IsAlgEnvSeq X Y alg (stationaryEnv ΞΊ) P) - (h' : IsAlgEnvSeq X' Y' alg (stationaryEnv ΞΊ') P') (M : β„•) : - klDiv (P.map (history X Y M)) (P'.map (history X' Y' M)) = - βˆ‘ t ∈ range M, ∫⁻ Ο‰, klDiv (ΞΊ (X t Ο‰)) (ΞΊ' (X t Ο‰)) βˆ‚P := by + (h : IsAlgEnvSeq O A Y alg (stationaryEnv ΞΊ) P) + (h' : IsAlgEnvSeq O' A' Y' alg (stationaryEnv ΞΊ') P') (M : β„•) : + klDiv (P.map (history O A Y M)) (P'.map (history O' A' Y' M)) = + βˆ‘ t ∈ range M, ∫⁻ Ο‰, klDiv (ΞΊ (A t Ο‰)) (ΞΊ' (A t Ο‰)) βˆ‚P := by rw [h.klDiv_map_history_compProd h'] refine sum_congr rfl fun t _ ↦ ?_ rw [klDiv_compProd_right_eq_lintegral, lintegral_map (measurable_klDiv_kernel ΞΊ ΞΊ') (h.measurable_action t)] /-- Chain rule for trajectories of a single algorithm versus two stationary environments. -/ -lemma IsAlgEnvSeq.klDiv_map_trajectory_compProd (h : IsAlgEnvSeq X Y alg (stationaryEnv ΞΊ) P) - (h' : IsAlgEnvSeq X' Y' alg (stationaryEnv ΞΊ') P') : - klDiv (P.map (trajectory X Y)) (P'.map (trajectory X' Y')) = - βˆ‘' t : β„•, klDiv (P.map (X t) βŠ—β‚˜ ΞΊ) (P.map (X t) βŠ—β‚˜ ΞΊ') := by - rw [klDiv_map_trajectory_eq_iSup h.measurable_action h.measurable_feedback - h'.measurable_action h'.measurable_feedback, ENNReal.tsum_eq_iSup_nat] +lemma IsAlgEnvSeq.klDiv_map_trajectory_compProd (h : IsAlgEnvSeq O A Y alg (stationaryEnv ΞΊ) P) + (h' : IsAlgEnvSeq O' A' Y' alg (stationaryEnv ΞΊ') P') : + klDiv (P.map (trajectory O A Y)) (P'.map (trajectory O' A' Y')) = + βˆ‘' t : β„•, klDiv (P.map (A t) βŠ—β‚˜ ΞΊ) (P.map (A t) βŠ—β‚˜ ΞΊ') := by + rw [klDiv_map_trajectory_eq_iSup h.measurable_obs h.measurable_action h.measurable_feedback + h'.measurable_obs h'.measurable_action h'.measurable_feedback, ENNReal.tsum_eq_iSup_nat] exact iSup_congr fun n ↦ h.klDiv_map_history_compProd h' n /-- Chain rule for trajectories of a single algorithm versus two stationary environments. -/ lemma IsAlgEnvSeq.klDiv_map_trajectory [MeasurableSpace.CountablyGenerated 𝓨] - (h : IsAlgEnvSeq X Y alg (stationaryEnv ΞΊ) P) - (h' : IsAlgEnvSeq X' Y' alg (stationaryEnv ΞΊ') P') : - klDiv (P.map (trajectory X Y)) (P'.map (trajectory X' Y')) = - βˆ‘' t : β„•, ∫⁻ Ο‰, klDiv (ΞΊ (X t Ο‰)) (ΞΊ' (X t Ο‰)) βˆ‚P := by + (h : IsAlgEnvSeq O A Y alg (stationaryEnv ΞΊ) P) + (h' : IsAlgEnvSeq O' A' Y' alg (stationaryEnv ΞΊ') P') : + klDiv (P.map (trajectory O A Y)) (P'.map (trajectory O' A' Y')) = + βˆ‘' t : β„•, ∫⁻ Ο‰, klDiv (ΞΊ (A t Ο‰)) (ΞΊ' (A t Ο‰)) βˆ‚P := by rw [h.klDiv_map_trajectory_compProd h'] refine tsum_congr fun t ↦ ?_ rw [klDiv_compProd_right_eq_lintegral, diff --git a/LeanMachineLearning/SequentialLearning/StationaryEnv.lean b/LeanMachineLearning/SequentialLearning/StationaryEnv.lean index 55d9f673..b652c7e5 100644 --- a/LeanMachineLearning/SequentialLearning/StationaryEnv.lean +++ b/LeanMachineLearning/SequentialLearning/StationaryEnv.lean @@ -206,9 +206,11 @@ lemma obs_stationaryEnv (Ξ½ : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ½] (n : β„•) : lemma feedback_stationaryEnv (Ξ½ : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ½] (n : β„•) : (stationaryEnv Ξ½).feedback n = Ξ½.prodMkLeft _ := rfl -lemma stepKernel_stationaryEnv (alg : Algorithm 𝓐 𝓨) (Ξ· : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ·] (n : β„•) : - stepKernel alg (stationaryEnv Ξ·) n = alg.policy n βŠ—β‚– Ξ·.prodMkLeft _ := by - rw [stepKernel, feedback_stationaryEnv] +lemma stepKernel_stationaryEnv (alg : Algorithm Unit 𝓐 𝓨) (Ξ· : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ·] + (n : β„•) : + stepKernel alg (stationaryEnv Ξ·) n + = Kernel.const _ (Measure.dirac ()) βŠ—β‚– (alg.policy n βŠ—β‚– Ξ·.prodMkLeft _) := by + rw [stepKernel_def, obs_stationaryEnv, feedback_stationaryEnv] @[simp] lemma obs0_stationaryEnv (Ξ½ : Kernel 𝓐 𝓨) [IsMarkovKernel Ξ½] : From 8e1b2d23f0ae5127048aa8a791cc58dfdb5a25d1 Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Thu, 10 Sep 2026 13:11:00 +0200 Subject: [PATCH 20/21] review: delete dead code --- .../IonescuTulceaSpace.lean | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/LeanMachineLearning/SequentialLearning/IonescuTulceaSpace.lean b/LeanMachineLearning/SequentialLearning/IonescuTulceaSpace.lean index ac65d247..515c6874 100644 --- a/LeanMachineLearning/SequentialLearning/IonescuTulceaSpace.lean +++ b/LeanMachineLearning/SequentialLearning/IonescuTulceaSpace.lean @@ -360,37 +360,6 @@ lemma hasCondDistrib_feedback_zero (alg : Algorithm π“ž 𝓐 𝓨) (env : Envir HasCondDistrib (feedback 0) (fun Ο‰ ↦ (obs 0 Ο‰, action 0 Ο‰)) env.Ξ½0 (trajMeasure alg env) := (isAlgEnvSeq_trajMeasure alg env).hasCondDistrib_feedback_zero -lemma condDistrib_feedback_zero [StandardBorelSpace 𝓨] [Nonempty 𝓨] - (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) : - condDistrib (feedback 0) (fun Ο‰ ↦ (obs 0 Ο‰, action 0 Ο‰)) (trajMeasure alg env) - =ᡐ[(trajMeasure alg env).map (fun Ο‰ ↦ (obs 0 Ο‰, action 0 Ο‰))] env.Ξ½0 := - (hasCondDistrib_feedback_zero alg env).condDistrib_eq - -lemma condDistrib_step [StandardBorelSpace π“ž] [Nonempty π“ž] - [StandardBorelSpace 𝓐] [Nonempty 𝓐] [StandardBorelSpace 𝓨] [Nonempty 𝓨] - (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (n : β„•) : - condDistrib (step n) (hist n) (trajMeasure alg env) - =ᡐ[(trajMeasure alg env).map (hist n)] stepKernel alg env n := - (hasCondDistrib_step alg env n).condDistrib_eq - -lemma condDistrib_obs [StandardBorelSpace π“ž] [Nonempty π“ž] - (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (n : β„•) : - condDistrib (obs n) (hist n) (trajMeasure alg env) - =ᡐ[(trajMeasure alg env).map (hist n)] env.obs n := - (hasCondDistrib_obs alg env n).condDistrib_eq - -lemma condDistrib_action [StandardBorelSpace 𝓐] [Nonempty 𝓐] - (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (n : β„•) : - condDistrib (action n) (fun Ο‰ ↦ (hist n Ο‰, obs n Ο‰)) (trajMeasure alg env) - =ᡐ[(trajMeasure alg env).map (fun Ο‰ ↦ (hist n Ο‰, obs n Ο‰))] alg.policy n := - (hasCondDistrib_action alg env n).condDistrib_eq - -lemma condDistrib_feedback [StandardBorelSpace 𝓨] [Nonempty 𝓨] - (alg : Algorithm π“ž 𝓐 𝓨) (env : Environment π“ž 𝓐 𝓨) (n : β„•) : - condDistrib (feedback n) (fun Ο‰ ↦ ((hist n Ο‰, obs n Ο‰), action n Ο‰)) (trajMeasure alg env) - =ᡐ[(trajMeasure alg env).map (fun Ο‰ ↦ ((hist n Ο‰, obs n Ο‰), action n Ο‰))] env.feedback n := - (hasCondDistrib_feedback alg env n).condDistrib_eq - end Laws end IT From 26f16d8b9001a237adf8534b8e794f89840935d5 Mon Sep 17 00:00:00 2001 From: Remy Degenne Date: Thu, 10 Sep 2026 16:01:07 +0200 Subject: [PATCH 21/21] remove unused file --- LeanMachineLearning.lean | 1 - .../MeasureTheory/MeasurableSpace/Option.lean | 58 ------------------- 2 files changed, 59 deletions(-) delete mode 100644 LeanMachineLearning/ForMathlib/MeasureTheory/MeasurableSpace/Option.lean diff --git a/LeanMachineLearning.lean b/LeanMachineLearning.lean index 58bb16f3..6516f85c 100644 --- a/LeanMachineLearning.lean +++ b/LeanMachineLearning.lean @@ -8,7 +8,6 @@ public import LeanMachineLearning.ForMathlib.InformationTheory.KullbackLeibler.M public import LeanMachineLearning.ForMathlib.InformationTheory.KullbackLeibler.Restrict public import LeanMachineLearning.ForMathlib.MeasureTheory.Measurable public import LeanMachineLearning.ForMathlib.MeasureTheory.MeasurableSpace.Embedding -public import LeanMachineLearning.ForMathlib.MeasureTheory.MeasurableSpace.Option public import LeanMachineLearning.ForMathlib.MeasureTheory.Measure.AbsolutelyContinuous public import LeanMachineLearning.ForMathlib.MeasureTheory.Order.Lattice public import LeanMachineLearning.ForMathlib.MeasureTheory.Order.MeasurableArg diff --git a/LeanMachineLearning/ForMathlib/MeasureTheory/MeasurableSpace/Option.lean b/LeanMachineLearning/ForMathlib/MeasureTheory/MeasurableSpace/Option.lean deleted file mode 100644 index 0c0dd77c..00000000 --- a/LeanMachineLearning/ForMathlib/MeasureTheory/MeasurableSpace/Option.lean +++ /dev/null @@ -1,58 +0,0 @@ -/- -Copyright (c) 2026 RΓ©my Degenne. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: RΓ©my Degenne --/ -module - -public import Mathlib.MeasureTheory.MeasurableSpace.Constructions -public import Mathlib.MeasureTheory.MeasurableSpace.Embedding - -/-! -# The measurable space structure on `Option Ξ±` - -`Option Ξ±` is the disjoint union of `Ξ±` and the singleton `{none}`: a set of `Option Ξ±` is -measurable if and only if its preimage under `Option.some` is measurable. Equivalently, a function -out of `Option Ξ±` is measurable if and only if its restriction to `Ξ±` is. --/ - -@[expose] public section - -/-- The measurable space structure on `Option Ξ±`, in which a set is measurable if and only if its -preimage under `Option.some` is measurable. This makes `Option Ξ±` the disjoint union of `Ξ±` and the -measurable atom `{none}`. -/ -instance Option.instMeasurableSpace {Ξ± : Type*} [MeasurableSpace Ξ±] : - MeasurableSpace (Option Ξ±) where - MeasurableSet' s := MeasurableSet (Option.some ⁻¹' s) - measurableSet_empty := by simp - measurableSet_compl s hs := by - rw [Set.preimage_compl] - exact hs.compl - measurableSet_iUnion f hf := by - rw [Set.preimage_iUnion] - exact MeasurableSet.iUnion hf - -variable {Ξ± Ξ² : Type*} [MeasurableSpace Ξ±] [MeasurableSpace Ξ²] - -lemma measurableSet_option_iff {s : Set (Option Ξ±)} : - MeasurableSet s ↔ MeasurableSet (Option.some ⁻¹' s) := Iff.rfl - -/-- A function out of `Option Ξ±` is measurable if and only if its restriction along `Option.some` -is measurable: no condition is imposed at `none`. -/ -lemma measurable_option_iff {f : Option Ξ± β†’ Ξ²} : Measurable f ↔ Measurable (f ∘ Option.some) := - Iff.rfl - -@[fun_prop] -lemma measurable_some : Measurable (Option.some : Ξ± β†’ Option Ξ±) := fun _ hs ↦ hs - -lemma measurableEmbedding_some : MeasurableEmbedding (Option.some : Ξ± β†’ Option Ξ±) where - injective := Option.some_injective Ξ± - measurable := measurable_some - measurableSet_image' s hs := by - rw [measurableSet_option_iff, Set.preimage_image_eq _ (Option.some_injective Ξ±)] - exact hs - -@[simp] -lemma measurableSet_singleton_none : MeasurableSet ({none} : Set (Option Ξ±)) := by - rw [measurableSet_option_iff, Set.preimage_singleton_eq_empty.2 (by simp)] - exact MeasurableSet.empty