diff --git a/LMLTutorial/Pages/DefiningAlgorithm.lean b/LMLTutorial/Pages/DefiningAlgorithm.lean index 86745598..5fb570ed 100644 --- a/LMLTutorial/Pages/DefiningAlgorithm.lean +++ b/LMLTutorial/Pages/DefiningAlgorithm.lean @@ -61,14 +61,14 @@ The `policy` field contains for each time `n` a kernel from that history togethe 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`. +That kernel is called `Algorithm.policyZero`. 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 and of the current observation. +If the algorithms actions are not random, we can use the `Algorithm.deterministic` 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} +{docstring Algorithm.deterministic} We can see here that we did not need to prove that the kernels are `IsMarkovKernel`. Lean knows that deterministic kernels are Markov. @@ -79,19 +79,21 @@ The `Environment` structure is the mirror of the `Algorithm` structure, with a k `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`. +The distribution of the first observation is `obs 0` applied to the empty history; it is called `Environment.obsZero`. +The distribution of the first feedback given the first observation and action is `feedback 0` applied to the empty history; it is called `Environment.feedbackZero`. -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. +In many applications neither the observation nor the feedback depends on the prior history: the observation at time `n` has a fixed law, and the feedback depends only on the current observation and action. +We provide an `Environment.oblivious` definition that builds an environment for those cases from a sequence of observation laws and a sequence of feedback kernels. -{docstring obliviousEnv} +{docstring Environment.oblivious} -`(ฮฝ n).prodMkLeft _` is the kernel `ฮฝ n` seen as a `Kernel ((Hist Unit ๐“ ๐“จ n ร— Unit) ร— ๐“) ๐“จ` by ignoring the history and the observation. +If furthermore those sequences do not change with time, we can use the `Environment.stationary` definition to build the environment. -If furthermore the feedback kernel does not change with time, we can use the `stationaryEnv` definition to build the environment. +{docstring Environment.stationary} -{docstring stationaryEnv} +When there is no observation (`๐“ž = Unit`), the feedback depends only on the last action. `Environment.banditSeq` builds such an environment from a sequence of kernels `ฮฝ : โ„• โ†’ Kernel ๐“ ๐“จ`, and `Environment.bandit` from a single kernel `ฮฝ : Kernel ๐“ ๐“จ` used at every time. + +{docstring Environment.bandit} # Sequences of actions and feedback, probability space @@ -120,14 +122,14 @@ We now illustrate the use of `Algorithm`, `Environment`, and `IsAlgEnvSeq` by de In a stochastic bandit, an algorithm chooses at each time an action from a finite set (here `Fin K`, the type of natural numbers less than `K`) and receives a reward drawn from a distribution that depends only on the action, not on the prior history. -The environment is thus simply `stationaryEnv ฮฝ` for some kernel `ฮฝ : Kernel (Fin K) โ„`. +The environment is thus simply `Environment.bandit ฮฝ` for some kernel `ฮฝ : Kernel (Fin K) โ„`. ## Algorithm The UCB algorithm chooses at time `n` the action that maximizes the sum of the empirical mean reward and an exploration bonus. It starts by choosing each action once and then chooses $`\arg\max_a (\hat{\mu}_{n,a} + \sqrt{\frac{2c \log (n + 1)}{N_{n,a}}})`, in which $`\hat{\mu}_{n,a}` is the empirical mean reward of action `a` before time `n` (`empMean'` in the code), $`N_{n,a}` is the number of times action `a` has been chosen before time `n` (`pullCount'` in the code), and `c` is a parameter of the algorithm. -To define the algorithm, we first define the exploration bonus and the next action function, and then we use `detAlgorithm` to build the algorithm. +To define the algorithm, we first define the exploration bonus and the next action function, and then we use `Algorithm.deterministic` to build the algorithm. We also need to prove that the next action function is measurable, which is done by the `measurable_nextArm` lemma. Note that we are careful to use a measurable version of the argmax function, `argmax`. @@ -139,7 +141,7 @@ Note that we are careful to use a measurable version of the argmax function, `ar {docstring Bandits.ucbAlgorithm} -The last line builds the algorithm using `detAlgorithm` and the function `UCB.nextArm`. +The last line builds the algorithm using `Algorithm.deterministic` and the function `UCB.nextArm`. Its measurability is proved by the `fun_prop` tactic, which proves measurability of functions by using lemmas tagged with `@[fun_prop]`. The first action of the algorithm is `UCB.nextArm K c 0` applied to the empty history, which is 0 as an element of `Fin K`. diff --git a/LeanMachineLearning.lean b/LeanMachineLearning.lean index ef058a9c..992ca486 100644 --- a/LeanMachineLearning.lean +++ b/LeanMachineLearning.lean @@ -54,6 +54,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.Algorithms.Markov public import LeanMachineLearning.SequentialLearning.Algorithms.RandomSampling.Basic public import LeanMachineLearning.SequentialLearning.Algorithms.RandomSampling.Tendsto public import LeanMachineLearning.SequentialLearning.Algorithms.RoundRobin diff --git a/LeanMachineLearning/Online/Bandit/Algorithms/ETC.lean b/LeanMachineLearning/Online/Bandit/Algorithms/ETC.lean index 12c60a34..6a28cc8f 100644 --- a/LeanMachineLearning/Online/Bandit/Algorithms/ETC.lean +++ b/LeanMachineLearning/Online/Bandit/Algorithms/ETC.lean @@ -48,7 +48,7 @@ variable (K) in to `ETC.nextArm`. -/ noncomputable def etcAlgorithm [NeZero K] (m : โ„•) : Algorithm Unit (Fin K) โ„ := - detAlgorithm (fun n p โ†ฆ ETC.nextArm K m n p.1) (by fun_prop) + Algorithm.deterministic (fun n p โ†ฆ ETC.nextArm K m n p.1) (by fun_prop) end AlgorithmDefinition @@ -61,21 +61,22 @@ variable [NeZero K] {m : โ„•} {ฮฝ : Kernel (Fin K) โ„} [IsMarkovKernel ฮฝ] /-- Before round `K * m`, the ETC algorithm behaves like the Round-Robin algorithm. -/ lemma isAlgEnvSeqUntil_roundRobinAlgorithm - (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (stationaryEnv ฮฝ) P) : - IsAlgEnvSeqUntil O A R (roundRobinAlgorithm K) (stationaryEnv ฮฝ) P (K * m) := by + (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (Environment.bandit ฮฝ) P) : + IsAlgEnvSeqUntil O A R (roundRobinAlgorithm K) (Environment.bandit ฮฝ) P (K * m) := by refine h.isAlgEnvSeqUntil_of_policy_eq fun n hn โ†ฆ ?_ - simp only [roundRobinAlgorithm, detAlgorithm_policy, etcAlgorithm] + simp only [roundRobinAlgorithm, Algorithm.deterministic_policy, etcAlgorithm] congr 1 with p simp [ETC.nextArm, hn] section AlgorithmBehavior -lemma arm_ae_eq_nextArm (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (stationaryEnv ฮฝ) P) (n : โ„•) : +lemma arm_ae_eq_nextArm (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (Environment.bandit ฮฝ) P) + (n : โ„•) : A n =แต[P] fun ฯ‰ โ†ฆ nextArm K m n (history O A R n ฯ‰) := - h.action_detAlgorithm_ae_eq n + h.action_deterministic_ae_eq n /-- For `n < K * m`, the arm pulled at time `n` is the arm `n % K`. -/ -lemma arm_of_lt (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (stationaryEnv ฮฝ) P) +lemma arm_of_lt (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (Environment.bandit ฮฝ) P) {n : โ„•} (hn : n < K * m) : A n =แต[P] fun _ โ†ฆ RoundRobin.nextAction K n := RoundRobin.action_ae_eq n ((isAlgEnvSeqUntil_roundRobinAlgorithm h).mono hn) @@ -83,13 +84,13 @@ lemma arm_of_lt (h : IsAlgEnvSeq O A R (etcAlgorithm K 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 - (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (stationaryEnv ฮฝ) P) : + (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (Environment.bandit ฮฝ) P) : A (K * m) =แต[P] fun ฯ‰ โ†ฆ argmax (empMean' (K * m) (history O A R (K * m) ฯ‰)) := by filter_upwards [arm_ae_eq_nextArm 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 O A R (etcAlgorithm K m) (stationaryEnv ฮฝ) P) +lemma arm_add_one_of_ge (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (Environment.bandit ฮฝ) P) {n : โ„•} (hn : K * m โ‰ค n) : A (n + 1) =แต[P] fun ฯ‰ โ†ฆ A n ฯ‰ := by filter_upwards [arm_ae_eq_nextArm h (n + 1)] with ฯ‰ hn_eq @@ -97,7 +98,7 @@ lemma arm_add_one_of_ge (h : IsAlgEnvSeq O A R (etcAlgorithm K 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 O A R (etcAlgorithm K m) (stationaryEnv ฮฝ) P) +lemma arm_of_ge (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (Environment.bandit ฮฝ) 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 @@ -108,11 +109,12 @@ lemma arm_of_ge (h : IsAlgEnvSeq O A R (etcAlgorithm K 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 O A R (etcAlgorithm K m) (stationaryEnv ฮฝ) P) (a : Fin K) : +lemma pullCount_mul (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (Environment.bandit ฮฝ) 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 O A R (etcAlgorithm K m) (stationaryEnv ฮฝ) P) +lemma pullCount_add_one_of_ge (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (Environment.bandit ฮฝ) 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 1 ฯ‰ := by @@ -122,7 +124,7 @@ lemma pullCount_add_one_of_ge (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (station /-- 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 O A R (etcAlgorithm K m) (stationaryEnv ฮฝ) P) +lemma pullCount_of_ge (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (Environment.bandit ฮฝ) P) (a : Fin K) {n : โ„•} (hn : K * m โ‰ค n) : pullCount A a n =แต[P] fun ฯ‰ โ†ฆ m + (n - K * m) * {ฯ‰' | A (K * m) ฯ‰' = a}.indicator 1 ฯ‰ := by @@ -142,7 +144,7 @@ lemma pullCount_of_ge (h : IsAlgEnvSeq O A R (etcAlgorithm K 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 - (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (stationaryEnv ฮฝ) P) (a : Fin K) (hm : m โ‰  0) : + (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (Environment.bandit ฮฝ) P) (a : Fin K) (hm : m โ‰  0) : โˆ€แต ฯ‰ โˆ‚P, A (K * m) ฯ‰ = a โ†’ sumRewards A R (bestArm ฮฝ) (K * m) ฯ‰ โ‰ค sumRewards A R a (K * m) ฯ‰ := by filter_upwards [arm_mul h, pullCount_mul h a, pullCount_mul h (bestArm ฮฝ)] diff --git a/LeanMachineLearning/Online/Bandit/Algorithms/Regret/ETC.lean b/LeanMachineLearning/Online/Bandit/Algorithms/Regret/ETC.lean index cfc3f1ee..c5a40cfc 100644 --- a/LeanMachineLearning/Online/Bandit/Algorithms/Regret/ETC.lean +++ b/LeanMachineLearning/Online/Bandit/Algorithms/Regret/ETC.lean @@ -26,7 +26,7 @@ variable {K : โ„•} [NeZero K] {m : โ„•} {ฮฝ : Kernel (Fin K) โ„} [IsMarkovKerne {ฯƒ2 : โ„โ‰ฅ0} lemma probReal_sumRewards_le_sumRewards_le - (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (stationaryEnv ฮฝ) P) + (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (Environment.bandit ฮฝ) 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 @@ -42,7 +42,7 @@ lemma probReal_sumRewards_le_sumRewards_le /-- The probability that at time `K * m` the ETC algorithm chooses arm `a` is at most `exp(- m * ฮ”_a^2 / (4 * ฯƒ2))`. -/ -lemma prob_arm_mul_eq_le (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (stationaryEnv ฮฝ) P) +lemma prob_arm_mul_eq_le (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (Environment.bandit ฮฝ) 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 @@ -57,7 +57,7 @@ lemma prob_arm_mul_eq_le (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (stationaryEn exact h_le.trans (probReal_sumRewards_le_sumRewards_le h hฮฝ a) /-- Bound on the expectation of the number of pulls of each arm by the ETC algorithm. -/ -lemma expectation_pullCount_le (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (stationaryEnv ฮฝ) P) +lemma expectation_pullCount_le (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (Environment.bandit ฮฝ) 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 ฯ‰ : โ„)] @@ -85,7 +85,7 @@ lemma expectation_pullCount_le (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (statio ยท exact (measurableSet_singleton _).preimage (by fun_prop) /-- Regret bound for the ETC algorithm. -/ -theorem regret_le (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (stationaryEnv ฮฝ) P) +theorem regret_le (h : IsAlgEnvSeq O A R (etcAlgorithm K m) (Environment.bandit ฮฝ) 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/UCB.lean b/LeanMachineLearning/Online/Bandit/Algorithms/Regret/UCB.lean index 7d106788..275e3dba 100644 --- a/LeanMachineLearning/Online/Bandit/Algorithms/Regret/UCB.lean +++ b/LeanMachineLearning/Online/Bandit/Algorithms/Regret/UCB.lean @@ -75,7 +75,7 @@ lemma pullCount_le_of_ucbIndex_le (hc : 0 โ‰ค c) {b : Fin K} /-- The probability that the UCB index of arm `a` is below its mean is at most `1 / (n + 1) ^ (c - 1)`. -/ lemma prob_ucbIndex_le {alg : Algorithm Unit (Fin K) โ„} - (h : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P) + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) P) (hฮฝ : โˆ€ a, HasSubgaussianMGF (fun x โ†ฆ x - (ฮฝ a)[id]) ฯƒ2 (ฮฝ a)) (hฯƒ2 : ฯƒ2 โ‰  0) (hc : 0 โ‰ค c) (a : Fin K) (n : โ„•) : P {ฯ‰ | 0 < pullCount A a n ฯ‰ โˆง empMean A R a n ฯ‰ + ucbWidth A (c * ฯƒ2) a n ฯ‰ โ‰ค (ฮฝ a)[id]} โ‰ค @@ -102,7 +102,7 @@ lemma prob_ucbIndex_le {alg : Algorithm Unit (Fin K) โ„} /-- The probability that the lower confidence bound of arm `a` is above its mean is at most `1 / (n + 1) ^ (c - 1)`. -/ lemma prob_lcbIndex_ge {alg : Algorithm Unit (Fin K) โ„} - (h : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P) + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) P) (hฮฝ : โˆ€ a, HasSubgaussianMGF (fun x โ†ฆ x - (ฮฝ a)[id]) ฯƒ2 (ฮฝ a)) (hฯƒ2 : ฯƒ2 โ‰  0) (hc : 0 โ‰ค c) (a : Fin K) (n : โ„•) : P {ฯ‰ | 0 < pullCount A a n ฯ‰ โˆง @@ -170,7 +170,7 @@ lemma pullCount_le_add_three (a : Fin K) (n C : โ„•) (ฯ‰ : ฮฉ) : rw [Finset.sum_add_distrib, Finset.sum_add_distrib] lemma pullCount_le_add_three_ae - (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (stationaryEnv ฮฝ) P) + (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (Environment.bandit ฮฝ) P) (a : Fin K) (n C : โ„•) (hC : C โ‰  0) : โˆ€แต ฯ‰ โˆ‚P, pullCount A a n ฯ‰ โ‰ค C + 1 + @@ -195,7 +195,7 @@ lemma pullCount_le_add_three_ae at which it already has more than `C` pulls and the means of the best arm and of `a` lie in their confidence intervals. -/ lemma sum_indicator_good_event_eq_zero - (h : IsAlgEnvSeq O A R (ucbAlgorithm K (c * ฯƒ2)) (stationaryEnv ฮฝ) P) + (h : IsAlgEnvSeq O A R (ucbAlgorithm K (c * ฯƒ2)) (Environment.bandit ฮฝ) 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, @@ -228,7 +228,8 @@ lemma sum_indicator_good_event_eq_zero simp_rw [โ† mul_assoc] gcongr -lemma pullCount_ae_le_add_two (h : IsAlgEnvSeq O A R (ucbAlgorithm K (c * ฯƒ2)) (stationaryEnv ฮฝ) P) +lemma pullCount_ae_le_add_two + (h : IsAlgEnvSeq O A R (ucbAlgorithm K (c * ฯƒ2)) (Environment.bandit ฮฝ) 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, @@ -296,7 +297,7 @@ lemma constSum_le {c : โ„} (hc : 2 < c) (n : โ„•) : constSum c n โ‰ค 1 + 1 / (c /-- Bound on the expectation of the number of pulls of each arm by the UCB algorithm. -/ lemma expectation_pullCount_le' - (h : IsAlgEnvSeq O A R (ucbAlgorithm K (c * ฯƒ2)) (stationaryEnv ฮฝ) P) + (h : IsAlgEnvSeq O A R (ucbAlgorithm K (c * ฯƒ2)) (Environment.bandit ฮฝ) 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 โ‰ค @@ -381,7 +382,8 @@ lemma expectation_pullCount_le' positivity /-- Bound on the expectation of the number of pulls of each arm by the UCB algorithm. -/ -lemma expectation_pullCount_le (h : IsAlgEnvSeq O A R (ucbAlgorithm K (c * ฯƒ2)) (stationaryEnv ฮฝ) P) +lemma expectation_pullCount_le + (h : IsAlgEnvSeq O A R (ucbAlgorithm K (c * ฯƒ2)) (Environment.bandit ฮฝ) 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 ฯ‰ : โ„)] โ‰ค @@ -403,7 +405,7 @@ lemma expectation_pullCount_le (h : IsAlgEnvSeq O A R (ucbAlgorithm K (c * ฯƒ2)) ring /-- Regret bound for the UCB algorithm. -/ -lemma regret_le (h : IsAlgEnvSeq O A R (ucbAlgorithm K (c * ฯƒ2)) (stationaryEnv ฮฝ) P) +lemma regret_le (h : IsAlgEnvSeq O A R (ucbAlgorithm K (c * ฯƒ2)) (Environment.bandit ฮฝ) P) (hฮฝ : โˆ€ a, HasSubgaussianMGF (fun x โ†ฆ x - (ฮฝ a)[id]) ฯƒ2 (ฮฝ a)) (hฯƒ2 : ฯƒ2 โ‰  0) (hc : 0 < c) (n : โ„•) : P[regret ฮฝ A n] โ‰ค @@ -417,7 +419,7 @@ lemma regret_le (h : IsAlgEnvSeq O A R (ucbAlgorithm K (c * ฯƒ2)) (stationaryEnv ยท field /-- Regret bound for the UCB algorithm with an explicit constant, for `c > 2`. -/ -lemma regret_le_of_gt_two (h : IsAlgEnvSeq O A R (ucbAlgorithm K (c * ฯƒ2)) (stationaryEnv ฮฝ) P) +lemma regret_le_of_gt_two (h : IsAlgEnvSeq O A R (ucbAlgorithm K (c * ฯƒ2)) (Environment.bandit ฮฝ) P) (hฮฝ : โˆ€ a, HasSubgaussianMGF (fun x โ†ฆ x - (ฮฝ a)[id]) ฯƒ2 (ฮฝ a)) (hฯƒ2 : ฯƒ2 โ‰  0) (hc : 2 < c) (n : โ„•) : P[regret ฮฝ A n] โ‰ค @@ -431,26 +433,26 @@ lemma regret_le_of_gt_two (h : IsAlgEnvSeq O A R (ucbAlgorithm K (c * ฯƒ2)) (sta /-- Regret bound for the UCB algorithm with exploration constant `c`, for `ฯƒ2`-subgaussian rewards. -/ -lemma regret_le' (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (stationaryEnv ฮฝ) P) +lemma regret_le' (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (Environment.bandit ฮฝ) P) (hฮฝ : โˆ€ a, HasSubgaussianMGF (fun x โ†ฆ x - (ฮฝ a)[id]) ฯƒ2 (ฮฝ a)) (hฯƒ2 : ฯƒ2 โ‰  0) (hc : 0 < c) (n : โ„•) : P[regret ฮฝ A n] โ‰ค โˆ‘ a, (8 * c * log (n + 1) / gap ฮฝ a + gap ฮฝ a * (2 + 2 * constSum (c / ฯƒ2) n)) := by have hฯƒ2' : (0 : โ„) < ฯƒ2 := NNReal.coe_pos.mpr (pos_iff_ne_zero.mpr hฯƒ2) - have h' : IsAlgEnvSeq O A R (ucbAlgorithm K (c / ฯƒ2 * ฯƒ2)) (stationaryEnv ฮฝ) P := by + have h' : IsAlgEnvSeq O A R (ucbAlgorithm K (c / ฯƒ2 * ฯƒ2)) (Environment.bandit ฮฝ) P := by rwa [div_mul_cancelโ‚€ _ hฯƒ2'.ne'] refine (regret_le h' hฮฝ hฯƒ2 (div_pos hc hฯƒ2') n).trans_eq ?_ rw [show (8 : โ„) * (c / ฯƒ2) * ฯƒ2 = 8 * c by rw [mul_assoc, div_mul_cancelโ‚€ _ hฯƒ2'.ne']] /-- Regret bound for the UCB algorithm with exploration constant `c > 2 * ฯƒ2`, for `ฯƒ2`-subgaussian rewards, with an explicit constant. -/ -theorem regret_le_of_gt_two' (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (stationaryEnv ฮฝ) P) +theorem regret_le_of_gt_two' (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (Environment.bandit ฮฝ) P) (hฮฝ : โˆ€ a, HasSubgaussianMGF (fun x โ†ฆ x - (ฮฝ a)[id]) ฯƒ2 (ฮฝ a)) (hฯƒ2 : ฯƒ2 โ‰  0) (hc : 2 * ฯƒ2 < c) (n : โ„•) : P[regret ฮฝ A n] โ‰ค โˆ‘ a, (8 * c * log (n + 1) / gap ฮฝ a + gap ฮฝ a * (4 + 2 * ฯƒ2 / (c - 2 * ฯƒ2))) := by have hฯƒ2' : (0 : โ„) < ฯƒ2 := NNReal.coe_pos.mpr (pos_iff_ne_zero.mpr hฯƒ2) - have h' : IsAlgEnvSeq O A R (ucbAlgorithm K (c / ฯƒ2 * ฯƒ2)) (stationaryEnv ฮฝ) P := by + have h' : IsAlgEnvSeq O A R (ucbAlgorithm K (c / ฯƒ2 * ฯƒ2)) (Environment.bandit ฮฝ) P := by rwa [div_mul_cancelโ‚€ _ hฯƒ2'.ne'] have hc' : 2 < c / ฯƒ2 := by rwa [lt_div_iffโ‚€ hฯƒ2'] refine (regret_le_of_gt_two h' hฮฝ hฯƒ2 hc' n).trans_eq ?_ diff --git a/LeanMachineLearning/Online/Bandit/Algorithms/TS.lean b/LeanMachineLearning/Online/Bandit/Algorithms/TS.lean index aa380f73..12a46b0f 100644 --- a/LeanMachineLearning/Online/Bandit/Algorithms/TS.lean +++ b/LeanMachineLearning/Online/Bandit/Algorithms/TS.lean @@ -20,7 +20,7 @@ probability of being optimal under the posterior over environments given the his * `tsAlgorithm Q ฮบ`: a Thompson sampling algorithm with actions in `Fin K` (for `K โ‰  0`), given a prior distribution over parameters `Q : Measure ๐“”` and a Markov kernel `ฮบ : Kernel (๐“” ร— Fin K) โ„`. This kernel defines how a parameter `e : ๐“”` gives rise to - a stationary environment: `stationaryEnv (ฮบ.sectR e) : Environment (Fin K) โ„`. + a stationary environment: `Environment.bandit (ฮบ.sectR e) : Environment (Fin K) โ„`. ## Main results @@ -60,7 +60,7 @@ instance [NeZero K] {Q : Measure ๐“”} [IsProbabilityMeasure Q] {ฮบ : Kernel ( /-- 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 - stationary environment `stationaryEnv (ฮบ.sectR e)` that corresponds to a parameter `e : ๐“”`. + stationary environment `Environment.bandit (ฮบ.sectR e)` that corresponds to a parameter `e : ๐“”`. At every time `n`, the Thompson sampling policy uses the posterior over the parameters given the history up to time `n` to derive the probability of each action being optimal. The action for time @@ -81,9 +81,9 @@ 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 : - (tsAlgorithm Q ฮบ).p0 () = Q.map (bestAction ฮบ id) := by - rw [Algorithm.p0_apply] +lemma TS.policyZero_tsAlgorithm : + (tsAlgorithm Q ฮบ).policyZero () = Q.map (bestAction ฮบ id) := by + rw [Algorithm.policyZero_apply] dsimp only [tsAlgorithm] rw [TS.policy, Kernel.prodMkRight_apply, Kernel.map_apply _ (by fun_prop), IT.bayesTrajMeasurePosterior_zero, Kernel.const_apply] diff --git a/LeanMachineLearning/Online/Bandit/Algorithms/UCB.lean b/LeanMachineLearning/Online/Bandit/Algorithms/UCB.lean index 832b152f..38ca7461 100644 --- a/LeanMachineLearning/Online/Bandit/Algorithms/UCB.lean +++ b/LeanMachineLearning/Online/Bandit/Algorithms/UCB.lean @@ -54,7 +54,7 @@ variable (K) in /-- The UCB algorithm. -/ noncomputable def ucbAlgorithm [NeZero K] (c : โ„) : Algorithm Unit (Fin K) โ„ := - detAlgorithm (fun n p โ†ฆ UCB.nextArm K c n p.1) (by fun_prop) + Algorithm.deterministic (fun n p โ†ฆ UCB.nextArm K c n p.1) (by fun_prop) end Algorithm namespace UCB @@ -67,10 +67,10 @@ variable [NeZero K] {c : โ„} {ฮฝ : Kernel (Fin K) โ„} [IsMarkovKernel ฮฝ] /-- Before round `K`, the UCB algorithm behaves like the Round-Robin algorithm. -/ lemma isAlgEnvSeqUntil_roundRobinAlgorithm - (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (stationaryEnv ฮฝ) P) : - IsAlgEnvSeqUntil O A R (roundRobinAlgorithm K) (stationaryEnv ฮฝ) P K := by + (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (Environment.bandit ฮฝ) P) : + IsAlgEnvSeqUntil O A R (roundRobinAlgorithm K) (Environment.bandit ฮฝ) P K := by refine h.isAlgEnvSeqUntil_of_policy_eq fun n hn โ†ฆ ?_ - simp only [roundRobinAlgorithm, detAlgorithm_policy, ucbAlgorithm] + simp only [roundRobinAlgorithm, Algorithm.deterministic_policy, ucbAlgorithm] congr 1 with p simp [UCB.nextArm, hn] @@ -93,16 +93,17 @@ lemma ucbWidth_eq_ucbWidth' (c : โ„) (a : Fin K) (n : โ„•) (ฯ‰ : ฮฉ) : 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 O A R (ucbAlgorithm K c) (stationaryEnv ฮฝ) P) : +lemma arm_zero (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (Environment.bandit ฮฝ) P) : A 0 =แต[P] fun _ โ†ฆ 0 := RoundRobin.action_zero ((isAlgEnvSeqUntil_roundRobinAlgorithm h).mono (Nat.pos_of_neZero K)) -lemma arm_ae_eq_nextArm (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (stationaryEnv ฮฝ) P) (n : โ„•) : +lemma arm_ae_eq_nextArm (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (Environment.bandit ฮฝ) P) + (n : โ„•) : A n =แต[P] fun ฯ‰ โ†ฆ nextArm K c n (history O A R n ฯ‰) := - h.action_detAlgorithm_ae_eq n + h.action_deterministic_ae_eq n lemma ucbIndex_le_ucbIndex_arm - (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (stationaryEnv ฮฝ) P) (a : Fin K) (hn : K โ‰ค n) : + (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (Environment.bandit ฮฝ) P) (a : Fin K) (hn : K โ‰ค n) : โˆ€แต ฯ‰ โˆ‚P, empMean A R a n ฯ‰ + ucbWidth A c a n ฯ‰ โ‰ค empMean A R (A n ฯ‰) n ฯ‰ + ucbWidth A c (A n ฯ‰) n ฯ‰ := by filter_upwards [arm_ae_eq_nextArm h n] with ฯ‰ h_arm @@ -112,7 +113,7 @@ lemma ucbIndex_le_ucbIndex_arm exact isMaxOn_argmax (fun a โ†ฆ empMean' n (history O A R n ฯ‰) a + ucbWidth' c n (history O A R n ฯ‰) a) _ -lemma forall_arm_eq_mod_of_lt (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (stationaryEnv ฮฝ) P) : +lemma forall_arm_eq_mod_of_lt (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (Environment.bandit ฮฝ) P) : โˆ€แต ฯ‰ โˆ‚P, โˆ€ n < K, A n ฯ‰ = RoundRobin.nextAction K n := by simp_rw [ae_all_iff] intro n hn @@ -121,7 +122,7 @@ lemma forall_arm_eq_mod_of_lt (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (station simp only [nextArm, hn, โ†“reduceIte] lemma forall_ucbIndex_le_ucbIndex_arm - (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (stationaryEnv ฮฝ) P) (a : Fin K) : + (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (Environment.bandit ฮฝ) P) (a : Fin K) : โˆ€แต ฯ‰ โˆ‚P, โˆ€ n, K โ‰ค n โ†’ empMean A R a n ฯ‰ + ucbWidth A c a n ฯ‰ โ‰ค empMean A R (A n ฯ‰) n ฯ‰ + ucbWidth A c (A n ฯ‰) n ฯ‰ := by @@ -129,12 +130,12 @@ lemma forall_ucbIndex_le_ucbIndex_arm exact fun _ โ†ฆ ucbIndex_le_ucbIndex_arm h a lemma time_gt_of_pullCount_gt_one - (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (stationaryEnv ฮฝ) P) (a : Fin K) : + (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (Environment.bandit ฮฝ) 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 O A R (ucbAlgorithm K c) (stationaryEnv ฮฝ) P) (a : Fin K) : + (h : IsAlgEnvSeq O A R (ucbAlgorithm K c) (Environment.bandit ฮฝ) 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 diff --git a/LeanMachineLearning/Online/Bandit/ArrayProbSpace.lean b/LeanMachineLearning/Online/Bandit/ArrayProbSpace.lean index 3bbfc3a6..55061bff 100644 --- a/LeanMachineLearning/Online/Bandit/ArrayProbSpace.lean +++ b/LeanMachineLearning/Online/Bandit/ArrayProbSpace.lean @@ -225,7 +225,7 @@ lemma algFunction_map (alg : Algorithm Unit ๐“ ๐“ก) (n : โ„•) (h : Hist Unit /-- The initial action is the image of a uniform random variable by `algFunction alg 0 default`. -/ lemma algFunction_zero_map (alg : Algorithm Unit ๐“ ๐“ก) : - volume.map (algFunction alg 0 default) = alg.p0 () := + volume.map (algFunction alg 0 default) = alg.policyZero () := algFunction_map alg 0 default @[fun_prop] @@ -755,7 +755,7 @@ lemma hasCondDistrib_reward (alg : Algorithm Unit ๐“ ๐“ก) (ฮฝ : Kernel ๐“ (n : โ„•) : HasCondDistrib (reward alg n) (fun ฯ‰ โ†ฆ ((history (noObs _) (action alg) (reward alg) n ฯ‰, noObs _ n ฯ‰), action alg n ฯ‰)) - ((stationaryEnv ฮฝ).feedback n) (arrayMeasure ฮฝ) := by + ((Environment.bandit ฮฝ).feedback n) (arrayMeasure ฮฝ) := by let e : (Hist Unit ๐“ ๐“ก n ร— ๐“) โ‰ƒแต ((Hist Unit ๐“ ๐“ก n ร— Unit) ร— ๐“) := { toFun := fun p โ†ฆ ((p.1, ()), p.2) invFun := fun p โ†ฆ (p.1.1, p.2) @@ -763,13 +763,14 @@ lemma hasCondDistrib_reward (alg : Algorithm Unit ๐“ ๐“ก) (ฮฝ : Kernel ๐“ 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] + rw [feedback_bandit] 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 ๐“ ๐“ก) (ฮฝ : Kernel ๐“ ๐“ก) [IsMarkovKernel ฮฝ] : - IsAlgEnvSeq (noObs _) (action alg) (reward alg) alg (stationaryEnv ฮฝ) (arrayMeasure ฮฝ) where + IsAlgEnvSeq (noObs _) (action alg) (reward alg) alg (Environment.bandit ฮฝ) + (arrayMeasure ฮฝ) where hasCondDistrib_obs n := hasCondDistrib_unit (measurable_history (fun _ โ†ฆ measurable_const) (measurable_action alg) (measurable_reward alg) n).aemeasurable _ _ @@ -777,8 +778,9 @@ lemma isAlgEnvSeq_arrayMeasure (alg : Algorithm Unit ๐“ ๐“ก) (ฮฝ : Kernel hasCondDistrib_feedback := hasCondDistrib_reward alg ฮฝ lemma hasLaw_action_zero (alg : Algorithm Unit ๐“ ๐“ก) (ฮฝ : Kernel ๐“ ๐“ก) [IsMarkovKernel ฮฝ] : - HasLaw (action alg 0) (alg.p0 ()) (arrayMeasure ฮฝ) := by - have h : HasCondDistrib (action alg 0) (fun _ : probSpace ๐“ ๐“ก โ†ฆ ()) alg.p0 (arrayMeasure ฮฝ) := + HasLaw (action alg 0) (alg.policyZero ()) (arrayMeasure ฮฝ) := by + have h : HasCondDistrib (action alg 0) (fun _ : probSpace ๐“ ๐“ก โ†ฆ ()) alg.policyZero + (arrayMeasure ฮฝ) := (isAlgEnvSeq_arrayMeasure alg ฮฝ).hasCondDistrib_action_zero exact h.hasLaw_of_const' @@ -786,7 +788,7 @@ lemma hasCondDistrib_reward_zero (alg : Algorithm Unit ๐“ ๐“ก) (ฮฝ : Kernel [IsMarkovKernel ฮฝ] : HasCondDistrib (reward alg 0) (action alg 0) ฮฝ (arrayMeasure ฮฝ) := by have h := (isAlgEnvSeq_arrayMeasure alg ฮฝ).hasCondDistrib_feedback_zero - rw [ฮฝ0_stationaryEnv] at h + rw [feedbackZero_bandit] at h simpa using hasCondDistrib_prodMk_left_unique_iff.mp h end Laws diff --git a/LeanMachineLearning/Online/Bandit/BayesRegret.lean b/LeanMachineLearning/Online/Bandit/BayesRegret.lean index 00210b41..c1a95147 100644 --- a/LeanMachineLearning/Online/Bandit/BayesRegret.lean +++ b/LeanMachineLearning/Online/Bandit/BayesRegret.lean @@ -17,7 +17,7 @@ measurable space `ฮฉ`. These definitions are useful when `IsBayesAlgEnvSeq Q ฮบ Recall that `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 ฯ‰))`) +underlying environment that depends on `E` and `ฮบ` (`Environment.bandit (ฮบ.sectR (E ฯ‰))`) ## Main definitions diff --git a/LeanMachineLearning/Online/Bandit/RewardByCountMeasure.lean b/LeanMachineLearning/Online/Bandit/RewardByCountMeasure.lean index fe804ee9..29e24b5a 100644 --- a/LeanMachineLearning/Online/Bandit/RewardByCountMeasure.lean +++ b/LeanMachineLearning/Online/Bandit/RewardByCountMeasure.lean @@ -22,7 +22,7 @@ namespace Bandits variable {๐“ ฮฉ : Type*} {m๐“ : MeasurableSpace ๐“} {mฮฉ : MeasurableSpace ฮฉ} [DecidableEq ๐“] {O : โ„• โ†’ ฮฉ โ†’ Unit} {A : โ„• โ†’ ฮฉ โ†’ ๐“} {R : โ„• โ†’ ฮฉ โ†’ โ„} {P : Measure ฮฉ} [IsProbabilityMeasure P] {alg : Algorithm Unit ๐“ โ„} {ฮฝ : Kernel ๐“ โ„} [IsMarkovKernel ฮฝ] - {h_inter : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P} + {h_inter : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) P} local notation "๐”“" => P.prod (streamMeasure ฮฝ) @@ -35,11 +35,11 @@ notation "๐“›[" Y " | " X " โ† " x "; " ฮผ "]" => Measure.map Y (ฮผ[|X โปยน' omit [DecidableEq ๐“] in lemma condDistrib_reward'' [Countable ๐“] - (h : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P) (n : โ„•) : + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 - have h_ra' : ๐“›[R n | A n; P] =แต[P.map (A n)] ฮฝ := h.condDistrib_feedback_stationaryEnv n + have h_ra' : ๐“›[R n | A n; P] =แต[P.map (A n)] ฮฝ := h.condDistrib_feedback_bandit n have h_law : (๐”“).map (fun ฯ‰ โ†ฆ A n ฯ‰.1) = P.map (A n) := by change ((๐”“).map (A n โˆ˜ Prod.fst)) = _ rw [โ† Measure.map_map (by fun_prop) (by fun_prop), โ† Measure.fst, Measure.fst_prod] @@ -56,7 +56,7 @@ variable [StandardBorelSpace ๐“] omit [DecidableEq ๐“] in lemma reward_cond_action [Countable ๐“] - (h : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P) (a : ๐“) (n : โ„•) + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 @@ -74,7 +74,7 @@ lemma reward_cond_action [Countable ๐“] variable [Nonempty ๐“] lemma condIndepFun_reward_stepsUntil_action' [StandardBorelSpace ฮฉ] - (h : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P) (a : ๐“) (m n : โ„•) : + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 @@ -83,12 +83,12 @@ lemma condIndepFun_reward_stepsUntil_action' [StandardBorelSpace ฮฉ] have hR := h.measurable_feedback 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 + IsAlgEnvSeq.condIndepFun_feedback_history_action_action_bandit h n refine h_indep.of_measurable_right (hX := hA n) ?_ exact measurable_comap_indicator_stepsUntil_eq O R a m n lemma condIndepFun_reward_stepsUntil_action [StandardBorelSpace ฮฉ] [Countable ๐“] - (h : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P) + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 @@ -99,7 +99,7 @@ lemma condIndepFun_reward_stepsUntil_action [StandardBorelSpace ฮฉ] [Countable (condIndepFun_reward_stepsUntil_action' h a m n) lemma reward_cond_stepsUntil [StandardBorelSpace ฮฉ] [Countable ๐“] - (h : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P) (a : ๐“) (m n : โ„•) + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 @@ -145,7 +145,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 O A R alg (stationaryEnv ฮฝ) P) (a : ๐“) (m : โ„•) (hm : m โ‰  0) : + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 @@ -178,7 +178,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 O A R alg (stationaryEnv ฮฝ) P) (a : ๐“) (m : โ„•) (hm : m โ‰  0) : + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 @@ -198,7 +198,7 @@ lemma hasLaw_rewardByCount [StandardBorelSpace ฮฉ] [Countable ๐“] _ = ฮฝ a := by simp lemma identDistrib_rewardByCount [StandardBorelSpace ฮฉ] [Countable ๐“] - (h : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P) (a : ๐“) (n m : โ„•) + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) P) (a : ๐“) (n m : โ„•) (hn : n โ‰  0) (hm : m โ‰  0) : IdentDistrib (rewardByCount A R a n) (rewardByCount A R a m) ๐”“ ๐”“ where aemeasurable_fst := @@ -208,7 +208,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 O A R alg (stationaryEnv ฮฝ) P) (a : ๐“) (n : โ„•) (hn : n โ‰  0) : + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 @@ -216,7 +216,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 O A R alg (stationaryEnv ฮฝ) P) (a : ๐“) (n m : โ„•) (hn : n โ‰  0) : + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 @@ -282,24 +282,25 @@ 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 O A R alg (stationaryEnv ฮฝ) P) +lemma indepFun_history_reward_cond (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) P) (n : โ„•) (b : ๐“) (k : โ„•) : (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 (O := O) (R' := R)] - exact h.indepFun_history_action_feedback_cond_stationaryEnv n + exact h.indepFun_history_action_feedback_cond_bandit 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 O A R alg (stationaryEnv ฮฝ) P) (t : โ„•) (b : ๐“) (k : โ„•) +lemma hasLaw_reward_cond (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 (O := O) (R' := R)] at hP โŠข - exact h.hasLaw_feedback_cond_stationaryEnv t (measurableSet_snd_eq_and_pullCount'_eq t b k) + exact h.hasLaw_feedback_cond_bandit t (measurableSet_snd_eq_and_pullCount'_eq t b k) (fun u hu โ†ฆ hu.1) hP -lemma hasLaw_reward_cond_prod (h : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P) (t : โ„•) (b : ๐“) +lemma hasLaw_reward_cond_prod (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 ฮฝ)) := @@ -310,7 +311,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 O A R alg (stationaryEnv ฮฝ) P) +lemma indepFun_update_rewardByCountUntil_reward (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 ฮฝ)] @@ -343,7 +344,8 @@ lemma indepFun_update_rewardByCountUntil_reward (h : IsAlgEnvSeq O A R alg (stat 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 O A R alg (stationaryEnv ฮฝ) P) +lemma identDistrib_rewardByCountUntil_add_one_cond + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 ฮฝ)) @@ -399,7 +401,7 @@ lemma identDistrib_rewardByCountUntil_add_one_cond (h : IsAlgEnvSeq O A R alg (s (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 O A R alg (stationaryEnv ฮฝ) P) +lemma identDistrib_rewardByCountUntil_add_one (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) P) (t : โ„•) : IdentDistrib (rewardByCountUntil A R (t + 1)) (rewardByCountUntil A R t) ๐”“ ๐”“ := by have hA := h.measurable_action @@ -424,7 +426,7 @@ lemma identDistrib_rewardByCountUntil_add_one (h : IsAlgEnvSeq O A R alg (statio 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 O A R alg (stationaryEnv ฮฝ) P) (t : โ„•) : +lemma hasLaw_rewardByCountUntil (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) P) (t : โ„•) : HasLaw (rewardByCountUntil A R t) (Measure.infinitePi fun p : ๐“ ร— โ„• โ†ฆ ฮฝ p.1) ๐”“ := by induction t with | zero => exact hasLaw_rewardByCountUntil_zero P @@ -432,7 +434,7 @@ lemma hasLaw_rewardByCountUntil (h : IsAlgEnvSeq O 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 O A R alg (stationaryEnv ฮฝ) P) : +lemma hasLaw_rewardByCount_infinitePi (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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) ฯ‰ := @@ -444,14 +446,14 @@ lemma hasLaw_rewardByCount_infinitePi (h : IsAlgEnvSeq O 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 O A R alg (stationaryEnv ฮฝ) P) +lemma hasLaw_rewardByCount_add_one (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 O A R alg (stationaryEnv ฮฝ) P) : +lemma iIndepFun_rewardByCount_add_one (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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) @@ -460,7 +462,7 @@ lemma iIndepFun_rewardByCount_add_one (h : IsAlgEnvSeq O 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 O A R alg (stationaryEnv ฮฝ) P) : +lemma iIndepFun_rewardByCount (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 @@ -474,14 +476,14 @@ lemma iIndepFun_rewardByCount (h : IsAlgEnvSeq O 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 O A R alg (stationaryEnv ฮฝ) P) +lemma iIndepFun_rewardByCount_add_one_action (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 O A R alg (stationaryEnv ฮฝ) P) +lemma indepFun_rewardByCount (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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/Online/Bandit/SumRewards.lean b/LeanMachineLearning/Online/Bandit/SumRewards.lean index 0263c221..1e9221dd 100644 --- a/LeanMachineLearning/Online/Bandit/SumRewards.lean +++ b/LeanMachineLearning/Online/Bandit/SumRewards.lean @@ -157,8 +157,8 @@ lemma pullCount_eq_comp : -- todo: write those lemmas with IdentDistrib instead of equality of maps lemma _root_.Learning.IsAlgEnvSeq.law_sumRewards_unique [MeasurableSingletonClass ๐“] - (h1 : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P) - (h2 : IsAlgEnvSeq Oโ‚‚ Aโ‚‚ Rโ‚‚ alg (stationaryEnv ฮฝ) P') : + (h1 : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) P) + (h2 : IsAlgEnvSeq Oโ‚‚ Aโ‚‚ Rโ‚‚ alg (Environment.bandit ฮฝ) 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 @@ -175,8 +175,8 @@ lemma _root_.Learning.IsAlgEnvSeq.law_sumRewards_unique [MeasurableSingletonClas ยท fun_prop lemma _root_.Learning.IsAlgEnvSeq.law_pullCount_sumRewards_unique' [MeasurableSingletonClass ๐“] - (h1 : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P) - (h2 : IsAlgEnvSeq Oโ‚‚ Aโ‚‚ Rโ‚‚ alg (stationaryEnv ฮฝ) P') : + (h1 : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) P) + (h2 : IsAlgEnvSeq Oโ‚‚ Aโ‚‚ Rโ‚‚ alg (Environment.bandit ฮฝ) 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 @@ -222,15 +222,15 @@ lemma _root_.Learning.IsAlgEnvSeq.law_pullCount_sumRewards_unique' [MeasurableSi ยท fun_prop lemma _root_.Learning.IsAlgEnvSeq.law_pullCount_sumRewards_unique [MeasurableSingletonClass ๐“] - (h1 : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P) - (h2 : IsAlgEnvSeq Oโ‚‚ Aโ‚‚ Rโ‚‚ alg (stationaryEnv ฮฝ) P') : + (h1 : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) P) + (h2 : IsAlgEnvSeq Oโ‚‚ Aโ‚‚ Rโ‚‚ alg (Environment.bandit ฮฝ) 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 O A R alg (stationaryEnv ฮฝ) P) - (h2 : IsAlgEnvSeq Oโ‚‚ Aโ‚‚ Rโ‚‚ alg (stationaryEnv ฮฝ) P') : + (h1 : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) P) + (h2 : IsAlgEnvSeq Oโ‚‚ Aโ‚‚ Rโ‚‚ alg (Environment.bandit ฮฝ) 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 (ฯ„ : โ„• โ†’ Round Unit ๐“ โ„) (n : โ„•) (a : ๐“) : โ„• ร— โ„ := @@ -263,7 +263,7 @@ variable [Nonempty ๐“] -- this is what we will use for UCB lemma prob_pullCount_prod_sumRewards_mem_le [Countable ๐“] [MeasurableSingletonClass ๐“] - (h : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P) + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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), @@ -289,7 +289,7 @@ property `p` holds for the number of pulls and the sum of rewards of action `a` least one pull, is at most `n` times a uniform bound on the probability of that property for the sums of `k โˆˆ [1, n]` i.i.d. rewards. -/ lemma prob_pullCount_pos_and_le [Countable ๐“] [MeasurableSingletonClass ๐“] - (h : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P) (a : ๐“) (n : โ„•) + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) P) (a : ๐“) (n : โ„•) {p : โ„• โ†’ โ„ โ†’ Prop} (hp : Measurable fun q : โ„• ร— โ„ โ†ฆ p q.1 q.2) {B : โ„โ‰ฅ0โˆž} (hB : โˆ€ k, k โ‰  0 โ†’ streamMeasure ฮฝ {ฯ‰ | p k (โˆ‘ i โˆˆ range k, ฯ‰ i a)} โ‰ค B) : P {ฯ‰ | 0 < pullCount A a n ฯ‰ โˆง p (pullCount A a n ฯ‰) (sumRewards A R a n ฯ‰)} โ‰ค n * B := by @@ -313,7 +313,7 @@ lemma prob_pullCount_pos_and_le [Countable ๐“] [MeasurableSingletonClass ๐“] _ = n * B := by simp lemma prob_pullCount_mem_and_sumRewards_mem_le [Countable ๐“] [MeasurableSingletonClass ๐“] - (h : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P) + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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), @@ -332,7 +332,7 @@ lemma prob_pullCount_mem_and_sumRewards_mem_le [Countable ๐“] [MeasurableSingl simp [hk.2.1] lemma prob_sumRewards_mem_le [Countable ๐“] [MeasurableSingletonClass ๐“] - (h : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P) + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 @@ -343,7 +343,7 @@ lemma prob_sumRewards_mem_le [Countable ๐“] [MeasurableSingletonClass ๐“] rfl lemma prob_pullCount_eq_and_sumRewards_mem_le [Countable ๐“] [MeasurableSingletonClass ๐“] - (h : IsAlgEnvSeq O A R alg (stationaryEnv ฮฝ) P) + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 @@ -352,7 +352,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 O A R alg (stationaryEnv ฮฝ) P) (a : ๐“) (m : โ„•) {B : Set โ„} + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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} := @@ -369,7 +369,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 O A R alg (stationaryEnv ฮฝ) P) + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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 ฯ‰} โ‰ค @@ -468,7 +468,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 O A R alg (stationaryEnv ฮฝ) P) {ฮด : โ„} (hฮด : 0 < ฮด) : + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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]} @@ -502,7 +502,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 O A R alg (stationaryEnv ฮฝ) P) {ฮด : โ„} (hฮด : 0 < ฮด) : + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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) * ฮด) := @@ -537,7 +537,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 O A R alg (stationaryEnv ฮฝ) P) {ฮด : โ„} (hฮด : 0 < ฮด) : + (h : IsAlgEnvSeq O A R alg (Environment.bandit ฮฝ) 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]} โ‰ค diff --git a/LeanMachineLearning/SequentialLearning/Algorithm.lean b/LeanMachineLearning/SequentialLearning/Algorithm.lean index 3185a206..20159435 100644 --- a/LeanMachineLearning/SequentialLearning/Algorithm.lean +++ b/LeanMachineLearning/SequentialLearning/Algorithm.lean @@ -151,47 +151,48 @@ lemma measurable_environment_iff (f : ฮฉ โ†’ Environment ๐“ž ๐“ ๐“จ) : /-- Distribution of the first observation: the observation kernel at time `0` applied to the empty history. -/ -def Environment.obs0 (env : Environment ๐“ž ๐“ ๐“จ) : Measure ๐“ž := +def Environment.obsZero (env : Environment ๐“ž ๐“ ๐“จ) : Measure ๐“ž := env.obs 0 default deriving IsProbabilityMeasure -lemma Environment.obs0_def (env : Environment ๐“ž ๐“ ๐“จ) : env.obs0 = env.obs 0 default := rfl +lemma Environment.obsZero_def (env : Environment ๐“ž ๐“ ๐“จ) : env.obsZero = env.obs 0 default := rfl lemma Environment.obs_zero (env : Environment ๐“ž ๐“ ๐“จ) (h : Hist ๐“ž ๐“ ๐“จ 0) : - env.obs 0 h = env.obs0 := by + env.obs 0 h = env.obsZero := 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 ๐“ž ๐“ := +noncomputable def Algorithm.policyZero (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.policyZero_def (alg : Algorithm ๐“ž ๐“ ๐“จ) : + alg.policyZero = (alg.policy 0).sectR default := rfl -lemma Algorithm.p0_apply (alg : Algorithm ๐“ž ๐“ ๐“จ) (o : ๐“ž) : - alg.p0 o = alg.policy 0 (default, o) := rfl +lemma Algorithm.policyZero_apply (alg : Algorithm ๐“ž ๐“ ๐“จ) (o : ๐“ž) : + alg.policyZero 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 + alg.policy 0 (h, o) = alg.policyZero o := by rw [Unique.eq_default h] rfl /-- 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 (๐“ž ร— ๐“) ๐“จ := +noncomputable def Environment.feedbackZero (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).comap (fun p โ†ฆ ((default, p.1), p.2)) (by fun_prop) := rfl +lemma Environment.feedbackZero_def (env : Environment ๐“ž ๐“ ๐“จ) : + env.feedbackZero = (env.feedback 0).comap (fun p โ†ฆ ((default, p.1), p.2)) (by fun_prop) := rfl -lemma Environment.ฮฝ0_apply (env : Environment ๐“ž ๐“ ๐“จ) (o : ๐“ž) (a : ๐“) : - env.ฮฝ0 (o, a) = env.feedback 0 ((default, o), a) := rfl +lemma Environment.feedbackZero_apply (env : Environment ๐“ž ๐“ ๐“จ) (o : ๐“ž) (a : ๐“) : + env.feedbackZero (o, a) = env.feedback 0 ((default, o), a) := rfl lemma Environment.feedback_zero (env : Environment ๐“ž ๐“ ๐“จ) (h : Hist ๐“ž ๐“ ๐“จ 0) (o : ๐“ž) (a : ๐“) : - env.feedback 0 ((h, o), a) = env.ฮฝ0 (o, a) := by + env.feedback 0 ((h, o), a) = env.feedbackZero (o, a) := by rw [Unique.eq_default h] rfl @@ -211,7 +212,7 @@ lemma fst_stepKernel (alg : Algorithm ๐“ž ๐“ ๐“จ) (env : Environment ๐“ž rw [stepKernel, Kernel.fst_compProd] lemma stepKernel_zero (alg : Algorithm ๐“ž ๐“ ๐“จ) (env : Environment ๐“ž ๐“ ๐“จ) (h : Hist ๐“ž ๐“ ๐“จ 0) : - stepKernel alg env 0 h = env.obs0 โŠ—โ‚˜ (alg.p0 โŠ—โ‚– env.ฮฝ0) := by + stepKernel alg env 0 h = env.obsZero โŠ—โ‚˜ (alg.policyZero โŠ—โ‚– env.feedbackZero) := by rw [Unique.eq_default h, stepKernel, Kernel.compProd_apply_eq_compProd_sectR] congr 1 ext o s hs @@ -475,30 +476,30 @@ lemma hasLaw_history_zero (O : โ„• โ†’ ฮฉ โ†’ ๐“ž) (A : โ„• โ†’ ฮฉ โ†’ ๐“) (Y map_eq := by rw [history_zero, Measure.map_const, measure_univ, one_smul] lemma IsAlgEnvSeqUntil.hasLaw_obs_zero (h : IsAlgEnvSeqUntil O A Y alg env P N) (hN : 0 < N) : - HasLaw (O 0) env.obs0 P := by + HasLaw (O 0) env.obsZero P := by have h0 := h.hasCondDistrib_obs 0 hN rw [history_zero] at h0 exact h0.hasLaw_of_const' lemma IsAlgEnvSeq.hasLaw_obs_zero (h : IsAlgEnvSeq O A Y alg env P) : - HasLaw (O 0) env.obs0 P := + HasLaw (O 0) env.obsZero 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 (A 0) (O 0) alg.policyZero 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 := + HasCondDistrib (A 0) (O 0) alg.policyZero P := (h.isAlgEnvSeqUntil 1).hasCondDistrib_action_zero zero_lt_one omit [IsProbabilityMeasure P] in lemma IsAlgEnvSeqUntil.hasCondDistrib_feedback_zero (h : IsAlgEnvSeqUntil O A Y alg env P N) (hN : 0 < N) : - HasCondDistrib (Y 0) (fun ฯ‰ โ†ฆ (O 0 ฯ‰, A 0 ฯ‰)) env.ฮฝ0 P := by + HasCondDistrib (Y 0) (fun ฯ‰ โ†ฆ (O 0 ฯ‰, A 0 ฯ‰)) env.feedbackZero P := by have h0 := h.hasCondDistrib_feedback 0 hN rw [history_zero] at h0 exact h0.of_measurableEmbedding_comp_right @@ -506,18 +507,18 @@ lemma IsAlgEnvSeqUntil.hasCondDistrib_feedback_zero (h : IsAlgEnvSeqUntil O A Y omit [IsProbabilityMeasure P] in lemma IsAlgEnvSeq.hasCondDistrib_feedback_zero (h : IsAlgEnvSeq O A Y alg env P) : - HasCondDistrib (Y 0) (fun ฯ‰ โ†ฆ (O 0 ฯ‰, A 0 ฯ‰)) env.ฮฝ0 P := + HasCondDistrib (Y 0) (fun ฯ‰ โ†ฆ (O 0 ฯ‰, A 0 ฯ‰)) env.feedbackZero P := (h.isAlgEnvSeqUntil 1).hasCondDistrib_feedback_zero zero_lt_one 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 + HasLaw (step O A Y 0) (env.obsZero โŠ—โ‚˜ (alg.policyZero โŠ—โ‚– env.feedbackZero)) 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 O A Y alg env P) : - HasLaw (step O A Y 0) (env.obs0 โŠ—โ‚˜ (alg.p0 โŠ—โ‚– env.ฮฝ0)) P := + HasLaw (step O A Y 0) (env.obsZero โŠ—โ‚˜ (alg.policyZero โŠ—โ‚– env.feedbackZero)) P := (h.isAlgEnvSeqUntil 1).hasLaw_step_zero zero_lt_one end Zero @@ -539,11 +540,11 @@ 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 `(O 0, A 0) = p`, the first feedback has law `env.ฮฝ0 p`. -/ +/-- Conditionally on the event `(O 0, A 0) = p`, the first feedback has law `env.feedbackZero 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}] := + HasLaw (Y 0) (env.feedbackZero p) P[|(fun ฯ‰ โ†ฆ (O 0 ฯ‰, A 0 ฯ‰)) โปยน' {p}] := h.hasCondDistrib_feedback_zero.hasLaw_cond (h.measurable_feedback 0) (measurableSet_singleton p) (fun a ha โ†ฆ by rw [Set.mem_singleton_iff.1 ha]) hP @@ -747,16 +748,22 @@ the algorithm only sees the past rounds. Since `Unit` carries a unique probabili 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 probability measure on `Unit` is `Measure.dirac ()`. -/ +lemma Measure.eq_dirac_unit (ฮผ : Measure Unit) [IsProbabilityMeasure ฮผ] : + ฮผ = Measure.dirac () := by + ext s hs + 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] + /-- 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 + ext a : 1 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] + exact Measure.eq_dirac_unit (ฮบ a) /-- A random variable with values in `Unit` admits any Markov kernel as conditional distribution. -/ diff --git a/LeanMachineLearning/SequentialLearning/AlgorithmDensity.lean b/LeanMachineLearning/SequentialLearning/AlgorithmDensity.lean index 53dd65a8..0175947c 100644 --- a/LeanMachineLearning/SequentialLearning/AlgorithmDensity.lean +++ b/LeanMachineLearning/SequentialLearning/AlgorithmDensity.lean @@ -58,8 +58,8 @@ structure AbsolutelyContinuous (alg algโ‚€ : Algorithm ๐“ž ๐“ ๐“จ) : Prop wh @[inherit_doc AbsolutelyContinuous] scoped notation:50 alg " โ‰ชโ‚ " algโ‚€ => AbsolutelyContinuous alg algโ‚€ -lemma AbsolutelyContinuous.p0 {alg algโ‚€ : Algorithm ๐“ž ๐“ ๐“จ} (h : alg โ‰ชโ‚ algโ‚€) (o : ๐“ž) : - alg.p0 o โ‰ช algโ‚€.p0 o := +lemma AbsolutelyContinuous.policyZero {alg algโ‚€ : Algorithm ๐“ž ๐“ ๐“จ} (h : alg โ‰ชโ‚ algโ‚€) (o : ๐“ž) : + alg.policyZero o โ‰ช algโ‚€.policyZero o := h.policy 0 (default, o) /-- If the algorithm `alg` is absolutely continuous with respect to the algorithm `algโ‚€` and they diff --git a/LeanMachineLearning/SequentialLearning/Algorithms/Markov.lean b/LeanMachineLearning/SequentialLearning/Algorithms/Markov.lean new file mode 100644 index 00000000..3a612140 --- /dev/null +++ b/LeanMachineLearning/SequentialLearning/Algorithms/Markov.lean @@ -0,0 +1,270 @@ +/- +Copyright (c) 2025 Rรฉmy Degenne. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Rรฉmy Degenne, Paulo Rauber +-/ +module + +public import LeanMachineLearning.ForMathlib.Probability.Kernel.Composition.MapComap +public import LeanMachineLearning.SequentialLearning.Algorithm + +/-! +# Algorithms that depend only on the time and the observation + +In general, an algorithm `alg : Algorithm ๐“ž ๐“ ๐“จ` has a policy +`alg.policy n : Kernel (Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) ๐“`, which depends on the history before time `n` and on +the observation at time `n`. In some cases, the policy depends only on the time and on the +observation. We say that `alg` is a *Markov algorithm* if there exists a sequence of Markov kernels +`ฮบ : โ„• โ†’ Kernel ๐“ž ๐“` such that `alg.policy n = (ฮบ n).prodMkLeft (Hist ๐“ž ๐“ ๐“จ n)` for all `n`. + +## Main definitions + +* `Algorithm.IsMarkov alg`: the policy of `alg` at time `n` depends only on `n` and on the current + observation, not on the history. +* `Algorithm.policyCondObs alg n`: the kernel representing the conditional distribution of the + action at time `n` given the observation at time `n` in a Markov algorithm `alg`. +* `Algorithm.markov ฮบ`: the algorithm whose action at time `n` is drawn from the Markov kernel + `ฮบ n` applied to the observation at time `n`. + +## Main statements + +* `Algorithm.IsMarkov.hasCondDistrib_action`: in a run of a Markov algorithm, the conditional + distribution of the action at time `n` given the observation at time `n` is + `alg.policyCondObs n`. +* `Algorithm.IsMarkov.condIndepFun_action_history`: in a run of a Markov algorithm, the action at + time `n` is conditionally independent of the history before time `n` given the observation at + time `n`. + +-/ + +@[expose] public section + +open MeasureTheory ProbabilityTheory Filter Real Finset + +open scoped ENNReal NNReal + +namespace Learning + +variable {๐“ž ๐“ ๐“จ : Type*} {m๐“ž : MeasurableSpace ๐“ž} {m๐“ : MeasurableSpace ๐“} + {m๐“จ : MeasurableSpace ๐“จ} + +/-- The policy of the algorithm at time `n` depends only on `n` and on the current observation, +not on the history. -/ +class Algorithm.IsMarkov (alg : Algorithm ๐“ž ๐“ ๐“จ) : Prop where + exists_policy_eq_prodMkLeft : โˆƒ ฮบ : โ„• โ†’ Kernel ๐“ž ๐“, (โˆ€ n, IsMarkovKernel (ฮบ n)) โˆง + โˆ€ n, alg.policy n = (ฮบ n).prodMkLeft (Hist ๐“ž ๐“ ๐“จ n) + +namespace Algorithm + +/-- The kernel representing the conditional distribution of the action at time `n` given the +observation at time `n` in a Markov algorithm. -/ +noncomputable +def policyCondObs (alg : Algorithm ๐“ž ๐“ ๐“จ) [h_markov : alg.IsMarkov] (n : โ„•) : Kernel ๐“ž ๐“ := + h_markov.exists_policy_eq_prodMkLeft.choose n + +instance (alg : Algorithm ๐“ž ๐“ ๐“จ) [alg.IsMarkov] (n : โ„•) : IsMarkovKernel (alg.policyCondObs n) := + IsMarkov.exists_policy_eq_prodMkLeft.choose_spec.1 n + +lemma policy_eq_prodMkLeft_policyCondObs (alg : Algorithm ๐“ž ๐“ ๐“จ) [alg.IsMarkov] (n : โ„•) : + alg.policy n = (alg.policyCondObs n).prodMkLeft (Hist ๐“ž ๐“ ๐“จ n) := + IsMarkov.exists_policy_eq_prodMkLeft.choose_spec.2 n + +lemma policy_apply_eq_policyCondObs (alg : Algorithm ๐“ž ๐“ ๐“จ) [alg.IsMarkov] (n : โ„•) + (h : Hist ๐“ž ๐“ ๐“จ n) (o : ๐“ž) : + alg.policy n (h, o) = alg.policyCondObs n o := by + rw [policy_eq_prodMkLeft_policyCondObs, Kernel.prodMkLeft_apply] + +lemma policyZero_eq_policyCondObs (alg : Algorithm ๐“ž ๐“ ๐“จ) [alg.IsMarkov] : + alg.policyZero = alg.policyCondObs 0 := by + ext o : 1 + rw [policyZero_apply, policy_apply_eq_policyCondObs] + +/-- The kernel `alg.policyCondObs n` is determined by the policy at time `n`. The assumption +`Nonempty ๐“จ` ensures that there are histories of every length. -/ +lemma policyCondObs_eq_of_policy_eq [Nonempty ๐“จ] (alg : Algorithm ๐“ž ๐“ ๐“จ) [alg.IsMarkov] {n : โ„•} + {ฮบ : Kernel ๐“ž ๐“} (h : alg.policy n = ฮบ.prodMkLeft (Hist ๐“ž ๐“ ๐“จ n)) : + alg.policyCondObs n = ฮบ := by + rcases isEmpty_or_nonempty ๐“ž with h๐“ž | h๐“ž + ยท ext o : 1 + exact h๐“ž.elim o + have : Nonempty ๐“ := Measure.nonempty_of_neZero (alg.policyCondObs n (Classical.arbitrary ๐“ž)) + rw [policy_eq_prodMkLeft_policyCondObs, Kernel.prodMkLeft_inj] at h + exact h + +namespace IsMarkov + +variable {ฮฉ : Type*} {mฮฉ : MeasurableSpace ฮฉ} + {alg : Algorithm ๐“ž ๐“ ๐“จ} {env : Environment ๐“ž ๐“ ๐“จ} {P : Measure ฮฉ} [IsFiniteMeasure P] + {O : โ„• โ†’ ฮฉ โ†’ ๐“ž} {A : โ„• โ†’ ฮฉ โ†’ ๐“} {Y : โ„• โ†’ ฮฉ โ†’ ๐“จ} {n N : โ„•} + +lemma hasCondDistrib_action_history_obs [alg.IsMarkov] (h : IsAlgEnvSeq O A Y alg env P) (n : โ„•) : + HasCondDistrib (A n) (fun ฯ‰ โ†ฆ (history O A Y n ฯ‰, O n ฯ‰)) + ((alg.policyCondObs n).prodMkLeft (Hist ๐“ž ๐“ ๐“จ n)) P := by + rw [โ† alg.policy_eq_prodMkLeft_policyCondObs] + exact h.hasCondDistrib_action n + +lemma hasCondDistrib_action_history_obs_of_isAlgEnvSeqUntil [alg.IsMarkov] + (h : IsAlgEnvSeqUntil O A Y alg env P N) (hn : n < N) : + HasCondDistrib (A n) (fun ฯ‰ โ†ฆ (history O A Y n ฯ‰, O n ฯ‰)) + ((alg.policyCondObs n).prodMkLeft (Hist ๐“ž ๐“ ๐“จ n)) P := by + rw [โ† alg.policy_eq_prodMkLeft_policyCondObs] + exact h.hasCondDistrib_action n hn + +/-- The conditional distribution of the action at time `n` given the observation at time `n` is +`alg.policyCondObs n`. -/ +lemma hasCondDistrib_action [alg.IsMarkov] (h : IsAlgEnvSeq O A Y alg env P) (n : โ„•) : + HasCondDistrib (A n) (O n) (alg.policyCondObs n) P := + (hasCondDistrib_action_history_obs h n).comp_right + +/-- The conditional distribution of the action at time `n < N` given the observation at time `n` +is `alg.policyCondObs n`. -/ +lemma hasCondDistrib_action_of_isAlgEnvSeqUntil [alg.IsMarkov] + (h : IsAlgEnvSeqUntil O A Y alg env P N) (hn : n < N) : + HasCondDistrib (A n) (O n) (alg.policyCondObs n) P := + (hasCondDistrib_action_history_obs_of_isAlgEnvSeqUntil h hn).comp_right + +/-- The law of the action at time `n` is the law of the observation at time `n` composed with +`alg.policyCondObs n`. -/ +lemma hasLaw_action_comp [alg.IsMarkov] (h : IsAlgEnvSeq O A Y alg env P) (n : โ„•) : + HasLaw (A n) (alg.policyCondObs n โˆ˜โ‚˜ (P.map (O n))) P := + (hasCondDistrib_action h n).hasLaw_comp + +/-- Conditionally on an event determined by the history before time `n` and the observation at +time `n`, on which that observation is equal to `b`, the action at time `n` has law +`alg.policyCondObs n b`. -/ +lemma hasLaw_action_cond [alg.IsMarkov] (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 ฯ‰)) โปยน' s) โ‰  0) : + HasLaw (A n) (alg.policyCondObs n b) P[|(fun ฯ‰ โ†ฆ (history O A Y n ฯ‰, O n ฯ‰)) โปยน' s] := by + refine (hasCondDistrib_action_history_obs h n).hasLaw_cond (h.measurable_action _) hs + (fun u hu โ†ฆ ?_) hP + rw [Kernel.prodMkLeft_apply, hsb u hu] + +/-- Conditionally on an event determined by the history before time `n` and the observation at +time `n`, on which that observation is constant, the action at time `n` is independent of the +history before time `n` and of the observation at time `n`. -/ +lemma indepFun_history_obs_action_cond [alg.IsMarkov] (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 ฯ‰)) + โŸ‚แตข[P[|(fun ฯ‰ โ†ฆ (history O A Y n ฯ‰, O n ฯ‰)) โปยน' s]] A n := by + have hO := h.measurable_obs + have hA := h.measurable_action + have hY := h.measurable_feedback + refine (hasCondDistrib_action_history_obs h n).indepFun_cond (by fun_prop) hs + (ฮท := alg.policyCondObs n b) fun u hu โ†ฆ ?_ + rw [Kernel.prodMkLeft_apply, hsb u hu] + +variable [StandardBorelSpace ๐“ž] [Nonempty ๐“ž] [StandardBorelSpace ๐“] [Nonempty ๐“] + [StandardBorelSpace ๐“จ] [Nonempty ๐“จ] + +/-- The action at time `n` is conditionally independent of the history before time `n`, given the +observation at time `n`. -/ +lemma condIndepFun_action_history [StandardBorelSpace ฮฉ] [alg.IsMarkov] + (h : IsAlgEnvSeq O A Y alg env P) (n : โ„•) : + A n โŸ‚แตข[O n, h.measurable_obs n; P] history O A Y 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 (ฮท := alg.policyCondObs n) + (by fun_prop) (by fun_prop) (by fun_prop) ?_ + exact HasCondDistrib.condDistrib_eq (hasCondDistrib_action_history_obs h n) + +/-- The action at time `n` is conditionally independent of the history before time `n` and the +observation at time `n`, given the observation at time `n`. -/ +lemma condIndepFun_action_history_obs [StandardBorelSpace ฮฉ] [alg.IsMarkov] + (h : IsAlgEnvSeq O A Y alg env P) (n : โ„•) : + A n โŸ‚แตข[O n, h.measurable_obs n; 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 + exact (condIndepFun_action_history h n).prod_right (by fun_prop) (by fun_prop) (by fun_prop) + +end IsMarkov + +section Markov + +variable {ฮบ : โ„• โ†’ Kernel ๐“ž ๐“} [โˆ€ n, IsMarkovKernel (ฮบ n)] + +/-- The algorithm whose action at time `n` is drawn from `ฮบ n` applied to the observation at +time `n`, whatever the history. -/ +def markov (ฮบ : โ„• โ†’ Kernel ๐“ž ๐“) [โˆ€ n, IsMarkovKernel (ฮบ n)] : Algorithm ๐“ž ๐“ ๐“จ where + policy n := (ฮบ n).prodMkLeft (Hist ๐“ž ๐“ ๐“จ n) + +@[simp] +lemma policy_markov (n : โ„•) : + (markov ฮบ : Algorithm ๐“ž ๐“ ๐“จ).policy n = (ฮบ n).prodMkLeft (Hist ๐“ž ๐“ ๐“จ n) := rfl + +@[simp] +lemma policyZero_markov : (markov ฮบ : Algorithm ๐“ž ๐“ ๐“จ).policyZero = ฮบ 0 := by + ext o : 1 + rw [policyZero_apply, policy_markov, Kernel.prodMkLeft_apply] + +instance : (markov ฮบ : Algorithm ๐“ž ๐“ ๐“จ).IsMarkov where + exists_policy_eq_prodMkLeft := โŸจฮบ, inferInstance, fun _ โ†ฆ rflโŸฉ + +@[simp] +lemma policyCondObs_markov [Nonempty ๐“จ] (n : โ„•) : + (markov ฮบ : Algorithm ๐“ž ๐“ ๐“จ).policyCondObs n = ฮบ n := + policyCondObs_eq_of_policy_eq _ rfl + +end Markov + +end Algorithm + +namespace IsAlgEnvSeq + +variable {ฮฉ : Type*} {mฮฉ : MeasurableSpace ฮฉ} + {ฮบ : โ„• โ†’ Kernel ๐“ž ๐“} [โˆ€ n, IsMarkovKernel (ฮบ n)] {env : Environment ๐“ž ๐“ ๐“จ} + {P : Measure ฮฉ} [IsFiniteMeasure P] + {O : โ„• โ†’ ฮฉ โ†’ ๐“ž} {A : โ„• โ†’ ฮฉ โ†’ ๐“} {Y : โ„• โ†’ ฮฉ โ†’ ๐“จ} + +lemma hasCondDistrib_action_history_obs_markov + (h : IsAlgEnvSeq O A Y (Algorithm.markov ฮบ) env P) (n : โ„•) : + HasCondDistrib (A n) (fun ฯ‰ โ†ฆ (history O A Y n ฯ‰, O n ฯ‰)) ((ฮบ n).prodMkLeft (Hist ๐“ž ๐“ ๐“จ n)) P := + h.hasCondDistrib_action n + +/-- The conditional distribution of the action at time `n` given the observation at time `n` +is `ฮบ n`. -/ +lemma hasCondDistrib_action_markov (h : IsAlgEnvSeq O A Y (Algorithm.markov ฮบ) env P) (n : โ„•) : + HasCondDistrib (A n) (O n) (ฮบ n) P := + (hasCondDistrib_action_history_obs_markov h n).comp_right + +/-- The conditional distribution of the action at time `n` given the observation at time `n` +is `ฮบ n`. -/ +lemma condDistrib_action_markov [StandardBorelSpace ๐“] [Nonempty ๐“] + (h : IsAlgEnvSeq O A Y (Algorithm.markov ฮบ) env P) (n : โ„•) : + condDistrib (A n) (O n) P =แต[P.map (O n)] ฮบ n := + (hasCondDistrib_action_markov h n).condDistrib_eq + +/-- Conditionally on an event determined by the history before time `n` and the observation at +time `n`, on which that observation is equal to `b`, the action at time `n` has law `ฮบ n b`. -/ +lemma hasLaw_action_cond_markov (h : IsAlgEnvSeq O A Y (Algorithm.markov ฮบ) 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 ฯ‰)) โปยน' s) โ‰  0) : + HasLaw (A n) (ฮบ n b) P[|(fun ฯ‰ โ†ฆ (history O A Y n ฯ‰, O n ฯ‰)) โปยน' s] := by + refine (hasCondDistrib_action_history_obs_markov h n).hasLaw_cond (h.measurable_action _) hs + (fun u hu โ†ฆ ?_) hP + rw [Kernel.prodMkLeft_apply, hsb u hu] + +/-- Conditionally on an event determined by the history before time `n` and the observation at +time `n`, on which that observation is constant, the action at time `n` is independent of the +history before time `n` and of the observation at time `n`. -/ +lemma indepFun_history_obs_action_cond_markov + (h : IsAlgEnvSeq O A Y (Algorithm.markov ฮบ) 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 ฯ‰)) + โŸ‚แตข[P[|(fun ฯ‰ โ†ฆ (history O A Y n ฯ‰, O n ฯ‰)) โปยน' s]] A n := + Algorithm.IsMarkov.indepFun_history_obs_action_cond h n hs hsb + +/-- The action at time `n` is conditionally independent of the history before time `n`, given the +observation at time `n`. -/ +lemma condIndepFun_action_history_markov [StandardBorelSpace ฮฉ] + [StandardBorelSpace ๐“ž] [Nonempty ๐“ž] [StandardBorelSpace ๐“] [Nonempty ๐“] + [StandardBorelSpace ๐“จ] [Nonempty ๐“จ] + (h : IsAlgEnvSeq O A Y (Algorithm.markov ฮบ) env P) (n : โ„•) : + A n โŸ‚แตข[O n, h.measurable_obs n; P] history O A Y n := + Algorithm.IsMarkov.condIndepFun_action_history h n + +end IsAlgEnvSeq + +end Learning diff --git a/LeanMachineLearning/SequentialLearning/Algorithms/RandomSampling/Basic.lean b/LeanMachineLearning/SequentialLearning/Algorithms/RandomSampling/Basic.lean index 7ade0abe..26b287bf 100644 --- a/LeanMachineLearning/SequentialLearning/Algorithms/RandomSampling/Basic.lean +++ b/LeanMachineLearning/SequentialLearning/Algorithms/RandomSampling/Basic.lean @@ -5,7 +5,7 @@ Authors: Gaรซtan Serrรฉ -/ module -public import LeanMachineLearning.SequentialLearning.Algorithm +public import LeanMachineLearning.SequentialLearning.Algorithms.Markov import LeanMachineLearning.ForMathlib.Probability.Independence.IndepFun @@ -17,7 +17,7 @@ measure at each iteration. ## Main definitions -* `randomSampling`: The random sampling algorithm that samples from a fixed distribution at +* `Algorithm.const`: The random sampling algorithm that samples from a fixed distribution at each iteration. ## Main statements @@ -43,28 +43,41 @@ open Set in /-- The _Random Sampling_ algorithm, which samples from a fixed probability measure at each iteration. -/ @[simps] -noncomputable def randomSampling (ฮผ : Measure ๐“) [IsProbabilityMeasure ฮผ] : +noncomputable def Algorithm.const (ฮผ : Measure ๐“) [IsProbabilityMeasure ฮผ] : Algorithm ๐“ž ๐“ ๐“จ where policy _ := Kernel.const _ ฮผ -namespace randomSampling +/-- The random sampling algorithm is the Markov algorithm with the constant kernel `ฮผ` at every +time. -/ +lemma Algorithm.const_eq_markov : + (Algorithm.const ฮผ : Algorithm ๐“ž ๐“ ๐“จ) = Algorithm.markov (fun _ โ†ฆ Kernel.const ๐“ž ฮผ) := rfl + +instance : (Algorithm.const ฮผ : Algorithm ๐“ž ๐“ ๐“จ).IsMarkov := + inferInstanceAs (Algorithm.markov (fun _ โ†ฆ Kernel.const ๐“ž ฮผ) : Algorithm ๐“ž ๐“ ๐“จ).IsMarkov + +@[simp] +lemma policyCondObs_const [Nonempty ๐“จ] (n : โ„•) : + (Algorithm.const ฮผ : Algorithm ๐“ž ๐“ ๐“จ).policyCondObs n = Kernel.const ๐“ž ฮผ := + Algorithm.policyCondObs_eq_of_policy_eq _ rfl + +namespace Algorithm.const variable {O : โ„• โ†’ ฮฉ โ†’ ๐“ž} {A : โ„• โ†’ ฮฉ โ†’ ๐“} {Y : โ„• โ†’ ฮฉ โ†’ ๐“จ} {env : Environment ๐“ž ๐“ ๐“จ} -/-- Each action follows the distribution ฮผ. -/ -lemma hasLaw_action (h : IsAlgEnvSeq O A Y (randomSampling ฮผ) env P) (n : โ„•) : +/-- Each action of the random sampling algorithm follows the distribution ฮผ. -/ +lemma hasLaw_action (h : IsAlgEnvSeq O A Y (Algorithm.const ฮผ) env P) (n : โ„•) : HasLaw (A n) ฮผ P := (h.hasCondDistrib_action n).hasLaw_of_const -/-- Actions are mutually independent. -/ -lemma iIndep_action (h : IsAlgEnvSeq O A Y (randomSampling ฮผ) env P) : +/-- Actions of the random sampling algorithm are mutually independent. -/ +lemma iIndep_action (h : IsAlgEnvSeq O A Y (Algorithm.const ฮผ) 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 have map_eq := (h.hasCondDistrib_action (n + 1)).map_eq - simp only [randomSampling_policy, Measure.compProd_const] at map_eq + simp only [Algorithm.const_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 (p : Hist ๐“ž ๐“ ๐“จ (n + 1) ร— ๐“ž) (i : Iic n) โ†ฆ @@ -74,6 +87,6 @@ lemma iIndep_action (h : IsAlgEnvSeq O A Y (randomSampling ฮผ) env P) : ยท exact ((h.measurable_history (n + 1)).prodMk (h.measurable_obs (n + 1))).aemeasurable ยท exact (h.measurable_action (n + 1)).aemeasurable -end randomSampling +end Algorithm.const end Learning diff --git a/LeanMachineLearning/SequentialLearning/Algorithms/RandomSampling/Tendsto.lean b/LeanMachineLearning/SequentialLearning/Algorithms/RandomSampling/Tendsto.lean index 91829c5e..b82d306c 100644 --- a/LeanMachineLearning/SequentialLearning/Algorithms/RandomSampling/Tendsto.lean +++ b/LeanMachineLearning/SequentialLearning/Algorithms/RandomSampling/Tendsto.lean @@ -17,8 +17,8 @@ import LeanMachineLearning.ForMathlib.Topology.Instances.ENNReal.Lemmas /-! # Random Sampling convergence lemmas -This file contains several convergence lemmas for the `randomSampling` algorithm along with an -`evalEnv` environment, that evaluates the actions using a measurable function. +This file contains several convergence lemmas for the `Algorithm.const` algorithm along with an +`Environment.eval` environment, that evaluates the actions using a measurable function. ## Main statements @@ -38,7 +38,7 @@ open Learning MeasureTheory ProbabilityTheory Filter Finset ENNReal open scoped Topology -namespace Learning.randomSampling +namespace Learning.Algorithm.const variable {๐“ ๐“จ ฮฉ : Type*} {m๐“ : MeasurableSpace ๐“} {m๐“จ : MeasurableSpace ๐“จ} {mฮฉ : MeasurableSpace ฮฉ} {ฮผ : Measure ๐“} [IsProbabilityMeasure ฮผ] {P : Measure ฮฉ} @@ -51,18 +51,18 @@ section rewards variable [StandardBorelSpace ๐“จ] [Nonempty ๐“จ] /-- Each reward follows the distribution ฮผ.map f. -/ -lemma hasLaw_feeback (h : IsAlgEnvSeq O A Y (randomSampling ฮผ) (evalEnv f hf) P) (n : โ„•) : +lemma hasLaw_feeback (h : IsAlgEnvSeq O A Y (Algorithm.const ฮผ) (Environment.eval f hf) P) (n : โ„•) : HasLaw (Y n) (ฮผ.map f) P := by - refine HasLaw.congr ?_ (feedback_evalEnv_ae_eq_eval_action h n) + refine HasLaw.congr ?_ (feedback_eval_ae_eq_eval_action h n) have hA := h.measurable_action n refine โŸจby fun_prop, ?_โŸฉ rw [โ† Measure.map_map hf hA, (hasLaw_action h n).map_eq] /-- Rewards are mutually independent. -/ -lemma iIndep_feedback (h : IsAlgEnvSeq O A Y (randomSampling ฮผ) (evalEnv f hf) P) : +lemma iIndep_feedback (h : IsAlgEnvSeq O A Y (Algorithm.const ฮผ) (Environment.eval f hf) P) : iIndepFun Y P := have (n : โ„•) : f โˆ˜ A n =แต[P] Y n := - (feedback_evalEnv_ae_eq_eval_action h n).symm + (feedback_eval_ae_eq_eval_action h n).symm iIndepFun.congr this <| (iIndep_action h).comp _ (fun _ โ†ฆ hf) end rewards @@ -71,17 +71,17 @@ variable [PseudoMetricSpace ๐“] [SecondCountableTopology ๐“] [OpensMeasurabl [ฮผ.IsOpenPosMeasure] /-- The minimum distance from sampled actions to any point tends to zero. -/ -theorem action_tendsto_any (h : IsAlgEnvSeq O A Y (randomSampling ฮผ) (evalEnv f hf) P) (a : ๐“) - {ฮต : โ„} (hฮต : 0 < ฮต) : +theorem action_tendsto_any (h : IsAlgEnvSeq O A Y (Algorithm.const ฮผ) (Environment.eval 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 (๐“ž := Unit) (๐“จ := ๐“จ) ฮผ + set const_alg := Algorithm.const (๐“ž := 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 refine iIndepSet.meas_biInter ?_ _ rw [iIndepSet_iff_meas_biInter fun i โ†ฆ ?_] ยท intro s - have iIndep_actions := randomSampling.iIndep_action h + have iIndep_actions := Algorithm.const.iIndep_action h rw [iIndepFun_iff_measure_inter_preimage_eq_mul] at iIndep_actions have meas_dist : โˆ€ i โˆˆ s, MeasurableSet {x | ฮต โ‰ค dist x a} := by intro i hs @@ -94,7 +94,7 @@ theorem action_tendsto_any (h : IsAlgEnvSeq O A Y (randomSampling ฮผ) (evalEnv f have prod_law (n : โ„•) : โˆ j โˆˆ Iic n, P {x | ฮต โ‰ค dist (A j x) a} = โˆ j โˆˆ Iic n, ฮผ {x | ฮต โ‰ค dist x a} := by refine prod_congr rfl fun j hj โ†ฆ ?_ - have hlaw (n : โ„•) : HasLaw (A n) ฮผ P := randomSampling.hasLaw_action h n + have hlaw (n : โ„•) : HasLaw (A n) ฮผ P := Algorithm.const.hasLaw_action h n rw [โ† (hlaw j).map_eq, P.map_apply] ยท simp ยท exact h.measurable_action j @@ -118,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 O A Y (randomSampling ฮผ) (evalEnv f hfc.measurable) P) + (h : IsAlgEnvSeq O A Y (Algorithm.const ฮผ) (Environment.eval 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 @@ -140,20 +140,21 @@ 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 O A Y (randomSampling ฮผ) (evalEnv f hfc.measurable) P) +lemma feedback_tendsto_any + (h : IsAlgEnvSeq O A Y (Algorithm.const ฮผ) (Environment.eval 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 refine measure_congr ?_ let g : ((Iic n) โ†’ ๐“จ) โ†’ โ„ := fun r โ†ฆ (fun i โ†ฆ dist (r i) (f a)).min - filter_upwards [feedback_evalEnv_ae_eq_eval_action_comp h g] with ฯ‰ hฯ‰ + filter_upwards [feedback_eval_ae_eq_eval_action_comp h g] with ฯ‰ hฯ‰ simp only [eq_iff_iff] simp [g, hฯ‰] variable {R : โ„• โ†’ ฮฉ โ†’ โ„} {f : ๐“ โ†’ โ„} (hfc : Continuous f) {a : ๐“} /-- The minimum image action converges to the function's global minimum. -/ -lemma tendsto_minโ‚€ (h : IsAlgEnvSeq O A R (randomSampling ฮผ) (evalEnv f hfc.measurable) P) +lemma tendsto_minโ‚€ (h : IsAlgEnvSeq O A R (Algorithm.const ฮผ) (Environment.eval 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] @@ -174,15 +175,15 @@ lemma tendsto_minโ‚€ (h : IsAlgEnvSeq O A R (randomSampling ฮผ) (evalEnv f hfc.m grind /-- The minimum reward converges to the function's global minimum. -/ -lemma tendsto_min (h : IsAlgEnvSeq O A R (randomSampling ฮผ) (evalEnv f hfc.measurable) P) +lemma tendsto_min (h : IsAlgEnvSeq O A R (Algorithm.const ฮผ) (Environment.eval 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 - filter_upwards [feedback_evalEnv_ae_eq_eval_action_comp h Function.min] with ฯ‰ hฯ‰ + filter_upwards [feedback_eval_ae_eq_eval_action_comp h Function.min] with ฯ‰ hฯ‰ rw [โ† hฯ‰] /-- The maximum image action converges to the function's global maximum. -/ -lemma tendsto_maxโ‚€ (h : IsAlgEnvSeq O A R (randomSampling ฮผ) (evalEnv f hfc.measurable) P) +lemma tendsto_maxโ‚€ (h : IsAlgEnvSeq O A R (Algorithm.const ฮผ) (Environment.eval 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] @@ -204,11 +205,11 @@ lemma tendsto_maxโ‚€ (h : IsAlgEnvSeq O A R (randomSampling ฮผ) (evalEnv f hfc.m grind /-- The maximum reward converges to the function's global maximum. -/ -lemma tendsto_max (h : IsAlgEnvSeq O A R (randomSampling ฮผ) (evalEnv f hfc.measurable) P) +lemma tendsto_max (h : IsAlgEnvSeq O A R (Algorithm.const ฮผ) (Environment.eval 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 - filter_upwards [feedback_evalEnv_ae_eq_eval_action_comp h Function.max] with ฯ‰ hฯ‰ + filter_upwards [feedback_eval_ae_eq_eval_action_comp h Function.max] with ฯ‰ hฯ‰ rw [โ† hฯ‰] -end Learning.randomSampling +end Learning.Algorithm.const diff --git a/LeanMachineLearning/SequentialLearning/Algorithms/RoundRobin.lean b/LeanMachineLearning/SequentialLearning/Algorithms/RoundRobin.lean index 3f377515..f73d6dde 100644 --- a/LeanMachineLearning/SequentialLearning/Algorithms/RoundRobin.lean +++ b/LeanMachineLearning/SequentialLearning/Algorithms/RoundRobin.lean @@ -84,7 +84,7 @@ variable (K) in /-- The Round-Robin algorithm: deterministic algorithm that chooses action `n % K` at time `n`. -/ noncomputable def roundRobinAlgorithm [NeZero K] : Algorithm ๐“ž (Fin K) ๐“จ := - detAlgorithm (fun n _ โ†ฆ RoundRobin.nextAction K n) (by fun_prop) + Algorithm.deterministic (fun n _ โ†ฆ RoundRobin.nextAction K n) (by fun_prop) end AlgorithmDefinition @@ -97,12 +97,12 @@ variable [NeZero K] {ฮฝ : Kernel (Fin K) ๐“จ} [IsMarkovKernel ฮฝ] /-- The action chosen at time `n` is the action `n % K`. -/ lemma action_ae_eq (n : โ„•) - (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm K) (stationaryEnv ฮฝ) P (n + 1)) : + (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm K) (Environment.bandit ฮฝ) P (n + 1)) : A n =แต[P] fun _ โ†ฆ nextAction K n := - h.action_detAlgorithm_ae_eq n.lt_succ_self + h.action_deterministic_ae_eq n.lt_succ_self lemma action_zero - (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm K) (stationaryEnv ฮฝ) P 1) : + (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm K) (Environment.bandit ฮฝ) P 1) : A 0 =แต[P] fun _ โ†ฆ 0 := by filter_upwards [action_ae_eq 0 h] with ฯ‰ hฯ‰ rw [hฯ‰] @@ -110,7 +110,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 O A Y (roundRobinAlgorithm K) (stationaryEnv ฮฝ) P (K * m)) + (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm K) (Environment.bandit ฮฝ) P (K * m)) (a : Fin K) : pullCount A a (K * m) =แต[P] fun _ โ†ฆ m := by rw [Filter.EventuallyEq] @@ -126,14 +126,14 @@ lemma pullCount_mul (m : โ„•) _ = m := sum_mod_range_mul (Nat.pos_of_neZero K) m a lemma pullCount_eq_one - (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm K) (stationaryEnv ฮฝ) P K) (a : Fin K) : + (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm K) (Environment.bandit ฮฝ) 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) (ฮฝ := ฮฝ) (O := O) (Y := Y) ?_ a simpa lemma time_gt_of_pullCount_gt_one - (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm K) (stationaryEnv ฮฝ) P K) (a : Fin K) : + (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm K) (Environment.bandit ฮฝ) 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 @@ -141,7 +141,7 @@ lemma time_gt_of_pullCount_gt_one exact hn.not_ge (pullCount_mono _ h_lt _) lemma pullCount_pos_of_time_ge - (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm K) (stationaryEnv ฮฝ) P K) : + (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm K) (Environment.bandit ฮฝ) 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 @@ -151,7 +151,7 @@ lemma pullCount_pos_of_time_ge exact pullCount_mono _ hn _ lemma pullCount_pos_of_pullCount_gt_one - (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm K) (stationaryEnv ฮฝ) P K) (a : Fin K) : + (h : IsAlgEnvSeqUntil O A Y (roundRobinAlgorithm K) (Environment.bandit ฮฝ) 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 7c6f3c4d..b636cf58 100644 --- a/LeanMachineLearning/SequentialLearning/Algorithms/Uniform.lean +++ b/LeanMachineLearning/SequentialLearning/Algorithms/Uniform.lean @@ -38,7 +38,10 @@ variable {๐“ž ๐“ ๐“จ : Type*} {m๐“ž : MeasurableSpace ๐“ž} {m๐“ : Measur /-- The Uniform algorithm: actions are chosen uniformly at random. -/ noncomputable def uniformAlgorithm [Finite ๐“] [Nonempty ๐“] : Algorithm ๐“ž ๐“ ๐“จ := - randomSampling (uniformOn Set.univ) + Algorithm.const (uniformOn Set.univ) + +instance [Finite ๐“] [Nonempty ๐“] : (uniformAlgorithm : Algorithm ๐“ž ๐“ ๐“จ).IsMarkov := + inferInstanceAs (Algorithm.const (uniformOn Set.univ) : Algorithm ๐“ž ๐“ ๐“จ).IsMarkov lemma absolutelyContinuous_uniformAlgorithm [Finite ๐“] [Nonempty ๐“] {alg : Algorithm ๐“ž ๐“ ๐“จ} : alg โ‰ชโ‚ uniformAlgorithm where diff --git a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean index dd29a648..e177abbd 100644 --- a/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean +++ b/LeanMachineLearning/SequentialLearning/BayesStationaryEnv.lean @@ -14,7 +14,7 @@ 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)`. Concretely, `bayesStationaryEnv Q ฮบ : Environment ๐“” ๐“ ๐“จ` announces +`Environment.bandit (ฮบ.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. @@ -27,7 +27,7 @@ an `alg : Algorithm Unit ๐“ ๐“จ`, an algorithm that does not use the observat 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 (fun _ โ†ฆ ())`. Equivalently, `A` and `Y` are generated by `alg` - interacting with the stationary environment `stationaryEnv (ฮบ.sectR (E ฯ‰))`. + interacting with the stationary environment `Environment.bandit (ฮบ.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 ๐“” ๐“ ๐“จ)` on a space that carries `E`, `A`, and `Y` such that @@ -43,12 +43,13 @@ an `alg : Algorithm Unit ๐“ ๐“จ`, an algorithm that does not use the observat * `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 + `IsAlgEnvSeq O' A' Y' alg (Environment.bandit (ฮบ.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 + measure that carries an `IsAlgEnvSeq` structure under the environment + `Environment.bandit (ฮบ.sectR e)` and the same algorithm. This allows transferring results from + the `IsAlgEnvSeq` structure to the `IsBayesAlgEnvSeq` structure. -/ @@ -93,10 +94,10 @@ lemma feedback_bayesStationaryEnv (n : โ„•) : (bayesStationaryEnv Q ฮบ).feedback n = ฮบ.comap (fun p โ†ฆ (p.1.2, p.2)) (by fun_prop) := rfl @[simp] -lemma obs0_bayesStationaryEnv : (bayesStationaryEnv Q ฮบ).obs0 = Q := rfl +lemma obsZero_bayesStationaryEnv : (bayesStationaryEnv Q ฮบ).obsZero = Q := rfl @[simp] -lemma ฮฝ0_bayesStationaryEnv : (bayesStationaryEnv Q ฮบ).ฮฝ0 = ฮบ := rfl +lemma feedbackZero_bayesStationaryEnv : (bayesStationaryEnv Q ฮบ).feedbackZero = ฮบ := rfl end BayesEnv @@ -114,7 +115,7 @@ lemma measurable_announceHist (n : โ„•) : 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 ฯ‰))`). +(`Environment.bandit (ฮบ.sectR (E ฯ‰))`). This is `IsAlgEnvSeq` for the announcing environment `bayesStationaryEnv Q ฮบ` and the algorithm `alg.comapObs (fun _ โ†ฆ ())` that ignores the announced parameter: the observation at every round @@ -183,16 +184,16 @@ lemma hasCondDistrib_feedback' (h : IsBayesAlgEnvSeq Q ฮบ alg E A Y P) (n : โ„•) (h.hasCondDistrib_feedback n).comp_right lemma hasLaw_action_zero (h : IsBayesAlgEnvSeq Q ฮบ alg E A Y P) : - HasLaw (A 0) (alg.p0 ()) P := by + HasLaw (A 0) (alg.policyZero ()) 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.policyZero ()`. -/ 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.policyZero ())) P := hasCondDistrib_prodMk_right_unique_iff.mp (h.hasCondDistrib_action 0) /-- The posterior over the parameter given the empty history is the prior. -/ @@ -254,7 +255,7 @@ lemma hasLaw_IT_hist (h : IsBayesAlgEnvSeq Q ฮบ alg E A Y P) (n : โ„•) : rw [โ† Kernel.map_apply _ (IT.measurable_hist n), he]โŸฉ lemma ae_IsAlgEnvSeq (h : IsBayesAlgEnvSeq Q ฮบ alg E A Y P) : - โˆ€แต e โˆ‚Q, IsAlgEnvSeq IT.obs IT.action IT.feedback alg (stationaryEnv (ฮบ.sectR e)) + โˆ€แต e โˆ‚Q, IsAlgEnvSeq IT.obs IT.action IT.feedback alg (Environment.bandit (ฮบ.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), diff --git a/LeanMachineLearning/SequentialLearning/Comap.lean b/LeanMachineLearning/SequentialLearning/Comap.lean index 78392f5a..bda9378f 100644 --- a/LeanMachineLearning/SequentialLearning/Comap.lean +++ b/LeanMachineLearning/SequentialLearning/Comap.lean @@ -136,12 +136,13 @@ lemma Algorithm.policy_comap (alg : Algorithm ๐“ž ๐“ ๐“จ) (alg.comap F hF).policy n = (alg.policy n).comap (F n) (hF n) := rfl @[simp] -lemma Algorithm.p0_comap (alg : Algorithm ๐“ž ๐“ ๐“จ) +lemma Algorithm.policyZero_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 + (alg.comap F hF).policyZero + = alg.policyZero.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] + rw [policyZero_apply, policy_comap, Kernel.comap_apply, alg.policy_zero, Kernel.comap_apply] @[simp] lemma Algorithm.comap_id (alg : Algorithm ๐“ž ๐“ ๐“จ) : @@ -172,10 +173,10 @@ lemma Algorithm.policy_comapObs (alg : Algorithm ๐“ž ๐“ ๐“จ) (hf : Measurabl = (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 +lemma Algorithm.policyZero_comapObs (alg : Algorithm ๐“ž ๐“ ๐“จ) (hf : Measurable f) : + (alg.comapObs f hf).policyZero = alg.policyZero.comap f hf := by ext o : 1 - rw [p0_apply, policy_comapObs, Kernel.comap_apply, alg.policy_zero, Kernel.comap_apply] + rw [policyZero_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 @@ -205,10 +206,10 @@ lemma Algorithm.policy_comapFeedback (alg : Algorithm ๐“ž ๐“ ๐“จ) (hg : Meas = (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 +lemma Algorithm.policyZero_comapFeedback (alg : Algorithm ๐“ž ๐“ ๐“จ) (hg : Measurable g) : + (alg.comapFeedback g hg).policyZero = alg.policyZero := by ext o : 1 - rw [p0_apply, policy_comapFeedback, Kernel.comap_apply, alg.policy_zero, p0_apply] + rw [policyZero_apply, policy_comapFeedback, Kernel.comap_apply, alg.policy_zero, policyZero_apply] @[simp] lemma Algorithm.comapFeedback_id (alg : Algorithm ๐“ž ๐“ ๐“จ) : @@ -255,17 +256,18 @@ lemma Environment.feedback_comap (env : Environment ๐“ž ๐“ ๐“จ) (hF : โˆ€ 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)) +lemma Environment.obsZero_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] + (env.comap F hF f hf).obsZero = env.obsZero := by + rw [Environment.obsZero_def, obs_comap, Kernel.comap_apply, env.obs_zero] @[simp] -lemma Environment.ฮฝ0_comap (env : Environment ๐“ž ๐“ ๐“จ) (hF : โˆ€ n, Measurable (F n)) +lemma Environment.feedbackZero_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 + (env.comap F hF f hf).feedbackZero + = env.feedbackZero.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, + rw [Environment.feedbackZero_apply, feedback_comap, Kernel.comap_apply, env.feedback_zero, Kernel.comap_apply] @[simp] @@ -299,15 +301,16 @@ lemma Environment.feedback_comapAction (env : Environment ๐“ž ๐“ ๐“จ) (hf : (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] +lemma Environment.obsZero_comapAction (env : Environment ๐“ž ๐“ ๐“จ) (hf : Measurable f) : + (env.comapAction f hf).obsZero = env.obsZero := by + rw [Environment.obsZero_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 +lemma Environment.feedbackZero_comapAction (env : Environment ๐“ž ๐“ ๐“จ) (hf : Measurable f) : + (env.comapAction f hf).feedbackZero + = env.feedbackZero.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, + rw [Environment.feedbackZero_apply, feedback_comapAction, Kernel.comap_apply, env.feedback_zero, Kernel.comap_apply] @[simp] @@ -341,11 +344,11 @@ lemma Algorithm.policy_congr (alg : Algorithm ๐“ž ๐“ ๐“จ) (e๐“ž : ๐“ž โ‰ƒ (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๐“ : ๐“ โ‰ƒแต ๐“') +lemma Algorithm.policyZero_congr (alg : Algorithm ๐“ž ๐“ ๐“จ) (e๐“ž : ๐“ž โ‰ƒแต ๐“ž') (e๐“ : ๐“ โ‰ƒแต ๐“') (e๐“จ : ๐“จ โ‰ƒแต ๐“จ') : - (alg.congr e๐“ž e๐“ e๐“จ).p0 = (alg.p0.map e๐“).comap e๐“ž.symm e๐“ž.symm.measurable := by + (alg.congr e๐“ž e๐“ e๐“จ).policyZero = (alg.policyZero.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, + rw [policyZero_apply, policy_congr, Kernel.comap_apply, Kernel.map_apply _ e๐“.measurable, alg.policy_zero, Kernel.comap_apply, Kernel.map_apply _ e๐“.measurable] @[simp] @@ -402,19 +405,19 @@ lemma Environment.feedback_congr (env : Environment ๐“ž ๐“ ๐“จ) (e๐“ž : (by fun_prop) := rfl @[simp] -lemma Environment.obs0_congr (env : Environment ๐“ž ๐“ ๐“จ) (e๐“ž : ๐“ž โ‰ƒแต ๐“ž') (e๐“ : ๐“ โ‰ƒแต ๐“') +lemma Environment.obsZero_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.congr e๐“ž e๐“ e๐“จ).obsZero = env.obsZero.map e๐“ž := by + rw [Environment.obsZero_def, obs_congr, Kernel.comap_apply, Kernel.map_apply _ e๐“ž.measurable, env.obs_zero] @[simp] -lemma Environment.ฮฝ0_congr (env : Environment ๐“ž ๐“ ๐“จ) (e๐“ž : ๐“ž โ‰ƒแต ๐“ž') (e๐“ : ๐“ โ‰ƒแต ๐“') +lemma Environment.feedbackZero_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 + (env.congr e๐“ž e๐“ e๐“จ).feedbackZero + = (env.feedbackZero.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, + rw [Environment.feedbackZero_apply, feedback_congr, Kernel.comap_apply, Kernel.map_apply _ e๐“จ.measurable, env.feedback_zero, Kernel.comap_apply, Kernel.map_apply _ e๐“จ.measurable] diff --git a/LeanMachineLearning/SequentialLearning/Deterministic.lean b/LeanMachineLearning/SequentialLearning/Deterministic.lean index 66784d36..ab7824b0 100644 --- a/LeanMachineLearning/SequentialLearning/Deterministic.lean +++ b/LeanMachineLearning/SequentialLearning/Deterministic.lean @@ -17,28 +17,33 @@ kernel. Similarly, a deterministic environment gives feedback in a deterministic ## Main definitions -We introduce two typeclasses `IsDeterministicAlg` and `IsDeterministicEnv` to express that -an algorithm or an environment is deterministic. We also give definitions for the initial action +We introduce two typeclasses `Algorithm.IsDeterministic` and +`Environment.HasDeterministicFeedback` to express that an algorithm is deterministic or that an +environment gives deterministic feedback. We also give definitions for the initial action and the next action of a deterministic algorithm, and for the feedback functions of a deterministic environment. Finally, we give a construction of a deterministic algorithm and environment from 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` 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, 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 +* `Algorithm.IsDeterministic alg`: a typeclass expressing that the algorithm `alg` is + deterministic. +* `Environment.HasDeterministicFeedback env`: a typeclass expressing that the feedback of the + environment `env` is deterministic. +* `Algorithm.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` and of the observation at step `n`. +* `Algorithm.actionZero alg`: the initial action of a deterministic algorithm `alg`, as a function + of the first observation. This is `alg.nextAction 0` applied to the empty history. +* `Environment.feedbackFun env n`: the function that gives the feedback of a deterministic + environment `env` at step `n`, as a function of the history, the current observation and the + current action. +* `Environment.feedbackFunZero env`: the function that gives the initial feedback of a + deterministic environment `env`. This is `env.feedbackFun 0` applied to the empty history. + +* `Algorithm.deterministic 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 `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`). +* `Environment.detFeedback obs f hf`: an environment with observation kernels `obs`, that gives + deterministic feedback according to the measurable function `f` (with proof of measurability + `hf`). -/ @@ -55,178 +60,186 @@ variable {๐“ž ๐“ ๐“จ : Type*} {m๐“ž : MeasurableSpace ๐“ž} {m๐“ : Measur /-- An algorithm is deterministic if its actions are determined by measurable functions of the history and of the current observation (and not possibly random kernels). -/ -class IsDeterministicAlg (alg : Algorithm ๐“ž ๐“ ๐“จ) : Prop where +class Algorithm.IsDeterministic (alg : Algorithm ๐“ž ๐“ ๐“จ) : Prop where exists_nextAction n : โˆƒ (nextAction : (Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) โ†’ ๐“) (h_meas : Measurable nextAction), alg.policy n = Kernel.deterministic nextAction h_meas +namespace Algorithm + /-- 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 : โ„•) : +def nextAction (alg : Algorithm ๐“ž ๐“ ๐“จ) [h_det : alg.IsDeterministic] (n : โ„•) : (Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) โ†’ ๐“ := (h_det.exists_nextAction n).choose /-- The initial action of a deterministic algorithm, as a function of the first observation. -/ noncomputable -def actionZero (alg : Algorithm ๐“ž ๐“ ๐“จ) [IsDeterministicAlg alg] : ๐“ž โ†’ ๐“ := - fun o โ†ฆ nextAction alg 0 (default, o) +def actionZero (alg : Algorithm ๐“ž ๐“ ๐“จ) [alg.IsDeterministic] : ๐“ž โ†’ ๐“ := + fun o โ†ฆ alg.nextAction 0 (default, o) @[fun_prop] -lemma measurable_nextAction (alg : Algorithm ๐“ž ๐“ ๐“จ) [IsDeterministicAlg alg] (n : โ„•) : - Measurable (nextAction alg n) := - (IsDeterministicAlg.exists_nextAction n).choose_spec.choose +lemma measurable_nextAction (alg : Algorithm ๐“ž ๐“ ๐“จ) [alg.IsDeterministic] (n : โ„•) : + Measurable (alg.nextAction n) := + (IsDeterministic.exists_nextAction n).choose_spec.choose @[fun_prop] -lemma measurable_actionZero (alg : Algorithm ๐“ž ๐“ ๐“จ) [IsDeterministicAlg alg] : - Measurable (actionZero alg) := - (measurable_nextAction alg 0).comp (measurable_const.prodMk measurable_id) +lemma measurable_actionZero (alg : Algorithm ๐“ž ๐“ ๐“จ) [alg.IsDeterministic] : + Measurable alg.actionZero := + (alg.measurable_nextAction 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 policy_eq_deterministic (alg : Algorithm ๐“ž ๐“ ๐“จ) [h_det : alg.IsDeterministic] (n : โ„•) : + alg.policy n = Kernel.deterministic (alg.nextAction n) (alg.measurable_nextAction n) := + (IsDeterministic.exists_nextAction n).choose_spec.choose_spec -lemma nextAction_zero (alg : Algorithm ๐“ž ๐“ ๐“จ) [IsDeterministicAlg alg] (h : Hist ๐“ž ๐“ ๐“จ 0) +lemma nextAction_zero (alg : Algorithm ๐“ž ๐“ ๐“จ) [alg.IsDeterministic] (h : Hist ๐“ž ๐“ ๐“จ 0) (o : ๐“ž) : - nextAction alg 0 (h, o) = actionZero alg o := by + alg.nextAction 0 (h, o) = alg.actionZero o := by rw [Unique.eq_default h] rfl -lemma p0_eq_deterministic (alg : Algorithm ๐“ž ๐“ ๐“จ) [IsDeterministicAlg alg] : - alg.p0 = Kernel.deterministic (actionZero alg) (measurable_actionZero alg) := by +lemma policyZero_eq_deterministic (alg : Algorithm ๐“ž ๐“ ๐“จ) [alg.IsDeterministic] : + alg.policyZero = Kernel.deterministic alg.actionZero alg.measurable_actionZero := by ext o : 1 - rw [Algorithm.p0_apply, policy_eq_deterministic, Kernel.deterministic_apply, + rw [policyZero_apply, policy_eq_deterministic, Kernel.deterministic_apply, Kernel.deterministic_apply] rfl -namespace IsDeterministicAlg +end Algorithm + +namespace Algorithm.IsDeterministic variable {ฮฉ : Type*} {mฮฉ : MeasurableSpace ฮฉ} {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 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 + [h_det : alg.IsDeterministic] (h : IsAlgEnvSeqUntil O A Y alg env P N) (hn : n < N) : + A n =แต[P] fun ฯ‰ โ†ฆ alg.nextAction 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 + rw [alg.policy_eq_deterministic 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] +lemma action_zero_of_IsAlgEnvSeqUntil [MeasurableEq ๐“] [h_det : alg.IsDeterministic] (h : IsAlgEnvSeqUntil O A Y alg env P N) (hN : 0 < N) : - A 0 =แต[P] fun ฯ‰ โ†ฆ actionZero alg (O 0 ฯ‰) := by + A 0 =แต[P] fun ฯ‰ โ†ฆ alg.actionZero (O 0 ฯ‰) := by filter_upwards [action_ae_eq_of_IsAlgEnvSeqUntil h hN] with ฯ‰ hฯ‰ rw [hฯ‰, nextAction_zero] -lemma hasCondDistrib_action_zero_of_IsAlgEnvSeqUntil [h_det : IsDeterministicAlg alg] +lemma hasCondDistrib_action_zero_of_IsAlgEnvSeqUntil [h_det : alg.IsDeterministic] (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] + (Kernel.deterministic alg.actionZero alg.measurable_actionZero) P := by + rw [โ† policyZero_eq_deterministic] exact h.hasCondDistrib_action_zero hN -lemma hasCondDistrib_action_zero [h_det : IsDeterministicAlg alg] +lemma hasCondDistrib_action_zero [h_det : alg.IsDeterministic] (h : IsAlgEnvSeq O A Y alg env P) : HasCondDistrib (A 0) (O 0) - (Kernel.deterministic (actionZero alg) (measurable_actionZero alg)) P := + (Kernel.deterministic alg.actionZero alg.measurable_actionZero) P := hasCondDistrib_action_zero_of_IsAlgEnvSeqUntil (h.isAlgEnvSeqUntil 1) zero_lt_one -lemma action_ae_eq [MeasurableEq ๐“] [h_det : IsDeterministicAlg alg] +lemma action_ae_eq [MeasurableEq ๐“] [h_det : alg.IsDeterministic] (h : IsAlgEnvSeq O A Y alg env P) (n : โ„•) : - A n =แต[P] fun ฯ‰ โ†ฆ nextAction alg n (history O A Y n ฯ‰, O n ฯ‰) := + A n =แต[P] fun ฯ‰ โ†ฆ alg.nextAction 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] +lemma action_zero_ae_eq [MeasurableEq ๐“] [h_det : alg.IsDeterministic] (h : IsAlgEnvSeq O A Y alg env P) : - A 0 =แต[P] fun ฯ‰ โ†ฆ actionZero alg (O 0 ฯ‰) := + A 0 =แต[P] fun ฯ‰ โ†ฆ alg.actionZero (O 0 ฯ‰) := action_zero_of_IsAlgEnvSeqUntil (h.isAlgEnvSeqUntil 1) zero_lt_one -lemma action_ae_all_eq [MeasurableEq ๐“] [h_det : IsDeterministicAlg alg] +lemma action_ae_all_eq [MeasurableEq ๐“] [h_det : alg.IsDeterministic] (h : IsAlgEnvSeq O A Y alg env P) : - โˆ€แต ฯ‰ โˆ‚P, โˆ€ n, A n ฯ‰ = nextAction alg n (history O A Y n ฯ‰, O n ฯ‰) := + โˆ€แต ฯ‰ โˆ‚P, โˆ€ n, A n ฯ‰ = alg.nextAction n (history O A Y n ฯ‰, O n ฯ‰) := ae_all_iff.mpr (action_ae_eq h) -end IsDeterministicAlg +end Algorithm.IsDeterministic -/-- An environment is deterministic if its feedbacks are determined by measurable functions of -the history, the observation and the action (and not possibly random kernels). -/ -class IsDeterministicEnv (env : Environment ๐“ž ๐“ ๐“จ) : Prop where +/-- An environment has deterministic feedback if its feedbacks are determined by measurable +functions of the history, the observation and the action (and not possibly random kernels). -/ +class Environment.HasDeterministicFeedback (env : Environment ๐“ž ๐“ ๐“จ) : Prop where exists_f : โˆ€ n, โˆƒ (f : ((Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) ร— ๐“) โ†’ ๐“จ) (hf : Measurable f), env.feedback n = Kernel.deterministic f hf +namespace Environment + /-- The feedback function of a deterministic environment at step `n`. -/ noncomputable -def feedbackFun (env : Environment ๐“ž ๐“ ๐“จ) [h_det : IsDeterministicEnv env] (n : โ„•) : +def feedbackFun (env : Environment ๐“ž ๐“ ๐“จ) [h_det : env.HasDeterministicFeedback] (n : โ„•) : ((Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) ร— ๐“) โ†’ ๐“จ := (h_det.exists_f n).choose @[fun_prop] -lemma measurable_feedbackFun (env : Environment ๐“ž ๐“ ๐“จ) [IsDeterministicEnv env] (n : โ„•) : - Measurable (feedbackFun env n) := - (IsDeterministicEnv.exists_f n).choose_spec.choose +lemma measurable_feedbackFun (env : Environment ๐“ž ๐“ ๐“จ) [env.HasDeterministicFeedback] (n : โ„•) : + Measurable (env.feedbackFun n) := + (HasDeterministicFeedback.exists_f n).choose_spec.choose -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 +lemma feedback_eq_deterministic (env : Environment ๐“ž ๐“ ๐“จ) [env.HasDeterministicFeedback] (n : โ„•) : + env.feedback n = Kernel.deterministic (env.feedbackFun n) (env.measurable_feedbackFun n) := + (HasDeterministicFeedback.exists_f n).choose_spec.choose_spec /-- 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 p โ†ฆ feedbackFun env 0 ((default, p.1), p.2) +def feedbackFunZero (env : Environment ๐“ž ๐“ ๐“จ) [env.HasDeterministicFeedback] : ๐“ž ร— ๐“ โ†’ ๐“จ := + fun p โ†ฆ env.feedbackFun 0 ((default, p.1), p.2) @[fun_prop] -lemma measurable_feedbackFunZero (env : Environment ๐“ž ๐“ ๐“จ) [IsDeterministicEnv env] : - Measurable (feedbackFunZero env) := - (measurable_feedbackFun env 0).comp +lemma measurable_feedbackFunZero (env : Environment ๐“ž ๐“ ๐“จ) [env.HasDeterministicFeedback] : + Measurable env.feedbackFunZero := + (env.measurable_feedbackFun 0).comp ((measurable_const.prodMk measurable_fst).prodMk measurable_snd) -lemma feedbackFun_zero (env : Environment ๐“ž ๐“ ๐“จ) [IsDeterministicEnv env] (h : Hist ๐“ž ๐“ ๐“จ 0) +lemma feedbackFun_zero (env : Environment ๐“ž ๐“ ๐“จ) [env.HasDeterministicFeedback] (h : Hist ๐“ž ๐“ ๐“จ 0) (o : ๐“ž) (a : ๐“) : - feedbackFun env 0 ((h, o), a) = feedbackFunZero env (o, a) := by + env.feedbackFun 0 ((h, o), a) = env.feedbackFunZero (o, a) := by rw [Unique.eq_default h] rfl -lemma ฮฝ0_eq_deterministic (env : Environment ๐“ž ๐“ ๐“จ) [IsDeterministicEnv env] : - env.ฮฝ0 = Kernel.deterministic (feedbackFunZero env) (measurable_feedbackFunZero env) := by +lemma feedbackZero_eq_deterministic (env : Environment ๐“ž ๐“ ๐“จ) [env.HasDeterministicFeedback] : + env.feedbackZero = Kernel.deterministic env.feedbackFunZero env.measurable_feedbackFunZero := by ext p : 1 - rw [Environment.ฮฝ0_def, Kernel.comap_apply, feedback_eq_deterministic, Kernel.deterministic_apply, + rw [feedbackZero_def, Kernel.comap_apply, feedback_eq_deterministic, Kernel.deterministic_apply, Kernel.deterministic_apply] rfl -namespace IsDeterministicEnv +end Environment + +namespace Environment.HasDeterministicFeedback variable {ฮฉ : Type*} {mฮฉ : MeasurableSpace ฮฉ} {alg : Algorithm ๐“ž ๐“ ๐“จ} {env : Environment ๐“ž ๐“ ๐“จ} {P : Measure ฮฉ} [IsFiniteMeasure P] {O : โ„• โ†’ ฮฉ โ†’ ๐“ž} {A : โ„• โ†’ ฮฉ โ†’ ๐“} {Y : โ„• โ†’ ฮฉ โ†’ ๐“จ} -lemma hasCondDistrib_feedback [h_det : IsDeterministicEnv env] +lemma hasCondDistrib_feedback [h_det : env.HasDeterministicFeedback] (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 + (Kernel.deterministic (env.feedbackFun n) (env.measurable_feedbackFun n)) P := by rw [โ† feedback_eq_deterministic] exact h.hasCondDistrib_feedback n -lemma hasCondDistrib_feedback_zero [h_det : IsDeterministicEnv env] +lemma hasCondDistrib_feedback_zero [h_det : env.HasDeterministicFeedback] (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] + (Kernel.deterministic env.feedbackFunZero env.measurable_feedbackFunZero) P := by + rw [โ† feedbackZero_eq_deterministic] exact h.hasCondDistrib_feedback_zero -lemma feedback_ae_eq [MeasurableEq ๐“จ] [h_det : IsDeterministicEnv env] +lemma feedback_ae_eq [MeasurableEq ๐“จ] [h_det : env.HasDeterministicFeedback] (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 + Y n =แต[P] fun ฯ‰ โ†ฆ env.feedbackFun 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) (by fun_prop) (hasCondDistrib_feedback h n) -end IsDeterministicEnv +end Environment.HasDeterministicFeedback variable {nextA : (n : โ„•) โ†’ (Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) โ†’ ๐“} {h_next : โˆ€ n, Measurable (nextA n)} {env : Environment ๐“ž ๐“ ๐“จ} @@ -237,38 +250,38 @@ variable {nextA : (n : โ„•) โ†’ (Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) โ†’ ๐“} {h_nex The initial action is `fun o โ†ฆ nextA 0 (default, o)`. -/ @[simps] noncomputable -def detAlgorithm (nextA : (n : โ„•) โ†’ (Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) โ†’ ๐“) +def Algorithm.deterministic (nextA : (n : โ„•) โ†’ (Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) โ†’ ๐“) (h_next : โˆ€ n, Measurable (nextA n)) : Algorithm ๐“ž ๐“ ๐“จ where policy n := Kernel.deterministic (nextA n) (h_next n) -instance : IsDeterministicAlg (detAlgorithm nextA h_next) where +instance : (Algorithm.deterministic nextA h_next).IsDeterministic where exists_nextAction n := โŸจnextA n, h_next n, rflโŸฉ @[simp] -lemma p0_detAlgorithm : - (detAlgorithm nextA h_next).p0 +lemma policyZero_deterministic : + (Algorithm.deterministic nextA h_next).policyZero = 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, + rw [Algorithm.policyZero_apply, Algorithm.deterministic_policy, Kernel.deterministic_apply, Kernel.deterministic_apply] @[simp] -lemma nextAction_detAlgorithm [MeasurableSpace.SeparatesPoints ๐“] (n : โ„•) : - nextAction (detAlgorithm nextA h_next) n = nextA n := by - have h_eq := policy_eq_deterministic (detAlgorithm nextA h_next) n - simpa [detAlgorithm] using h_eq.symm +lemma nextAction_deterministic [MeasurableSpace.SeparatesPoints ๐“] (n : โ„•) : + (Algorithm.deterministic nextA h_next).nextAction n = nextA n := by + have h_eq := (Algorithm.deterministic nextA h_next).policy_eq_deterministic n + simpa [Algorithm.deterministic] using h_eq.symm @[simp] -lemma actionZero_detAlgorithm [MeasurableSpace.SeparatesPoints ๐“] : - actionZero (detAlgorithm nextA h_next) = fun o โ†ฆ nextA 0 (default, o) := by - unfold actionZero - rw [nextAction_detAlgorithm] +lemma actionZero_deterministic [MeasurableSpace.SeparatesPoints ๐“] : + (Algorithm.deterministic nextA h_next).actionZero = fun o โ†ฆ nextA 0 (default, o) := by + unfold Algorithm.actionZero + rw [nextAction_deterministic] /-- A deterministic environment, where the feedback is given by evaluating fixed measurable functions. -/ -noncomputable def detEnvironment (obs : (n : โ„•) โ†’ Kernel (Hist ๐“ž ๐“ ๐“จ n) ๐“ž) +noncomputable def Environment.detFeedback (obs : (n : โ„•) โ†’ Kernel (Hist ๐“ž ๐“ ๐“จ n) ๐“ž) [โˆ€ n, IsMarkovKernel (obs n)] (f : (n : โ„•) โ†’ ((Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) ร— ๐“) โ†’ ๐“จ) (hf : โˆ€ n, Measurable (f n)) : Environment ๐“ž ๐“ ๐“จ where @@ -276,25 +289,26 @@ noncomputable def detEnvironment (obs : (n : โ„•) โ†’ Kernel (Hist ๐“ž ๐“ feedback n := (Kernel.deterministic (f n) (hf n)) @[simp] -lemma obs_detEnvironment (n : โ„•) : (detEnvironment obs f hf).obs n = obs n := rfl +lemma obs_detFeedback (n : โ„•) : (Environment.detFeedback 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 +lemma feedback_detFeedback (n : โ„•) : + (Environment.detFeedback obs f hf).feedback n = Kernel.deterministic (f n) (hf n) := rfl -instance : IsDeterministicEnv (detEnvironment obs f hf) where +instance : (Environment.detFeedback obs f hf).HasDeterministicFeedback where exists_f n := โŸจf n, hf n, rflโŸฉ @[simp] -lemma feedbackFun_detEnvironment [MeasurableSpace.SeparatesPoints ๐“จ] (n : โ„•) : - feedbackFun (detEnvironment obs f hf) n = f n := by - simpa [detEnvironment] using (feedback_eq_deterministic (detEnvironment obs f hf) n).symm +lemma feedbackFun_detFeedback [MeasurableSpace.SeparatesPoints ๐“จ] (n : โ„•) : + (Environment.detFeedback obs f hf).feedbackFun n = f n := by + simpa [Environment.detFeedback] using + ((Environment.detFeedback obs f hf).feedback_eq_deterministic n).symm @[simp] -lemma feedbackFunZero_detEnvironment [MeasurableSpace.SeparatesPoints ๐“จ] : - feedbackFunZero (detEnvironment obs f hf) = fun p โ†ฆ f 0 ((default, p.1), p.2) := by - unfold feedbackFunZero - rw [feedbackFun_detEnvironment] +lemma feedbackFunZero_detFeedback [MeasurableSpace.SeparatesPoints ๐“จ] : + (Environment.detFeedback obs f hf).feedbackFunZero = fun p โ†ฆ f 0 ((default, p.1), p.2) := by + unfold Environment.feedbackFunZero + rw [feedbackFun_detFeedback] namespace IsAlgEnvSeq @@ -303,28 +317,28 @@ variable {ฮฉ : Type*} {mฮฉ : MeasurableSpace ฮฉ} {P : Measure ฮฉ} [IsProbabilityMeasure P] {O : โ„• โ†’ ฮฉ โ†’ ๐“ž} {A : โ„• โ†’ ฮฉ โ†’ ๐“} {Y : โ„• โ†’ ฮฉ โ†’ ๐“จ} -lemma hasCondDistrib_action_zero_detAlgorithm - (h : IsAlgEnvSeq O A Y (detAlgorithm nextA h_next) env P) : +lemma hasCondDistrib_action_zero_deterministic + (h : IsAlgEnvSeq O A Y (Algorithm.deterministic 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] + rw [โ† policyZero_deterministic] exact h.hasCondDistrib_action_zero -lemma action_detAlgorithm_ae_eq [MeasurableEq ๐“] - (h : IsAlgEnvSeq O A Y (detAlgorithm nextA h_next) env P) (n : โ„•) : +lemma action_deterministic_ae_eq [MeasurableEq ๐“] + (h : IsAlgEnvSeq O A Y (Algorithm.deterministic 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) + (Algorithm.IsDeterministic.action_ae_eq h n).trans (by simp) -lemma action_zero_detAlgorithm [MeasurableEq ๐“] - (h : IsAlgEnvSeq O A Y (detAlgorithm nextA h_next) env P) : +lemma action_zero_deterministic [MeasurableEq ๐“] + (h : IsAlgEnvSeq O A Y (Algorithm.deterministic nextA h_next) env P) : A 0 =แต[P] fun ฯ‰ โ†ฆ nextA 0 (default, O 0 ฯ‰) := - (IsDeterministicAlg.action_zero_ae_eq h).trans (by simp) + (Algorithm.IsDeterministic.action_zero_ae_eq h).trans (by simp) -lemma action_detAlgorithm_ae_all_eq [MeasurableEq ๐“] - (h : IsAlgEnvSeq O A Y (detAlgorithm nextA h_next) env P) : +lemma action_deterministic_ae_all_eq [MeasurableEq ๐“] + (h : IsAlgEnvSeq O A Y (Algorithm.deterministic 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) + ae_all_iff.mpr (action_deterministic_ae_eq h) end IsAlgEnvSeq @@ -335,23 +349,23 @@ variable {ฮฉ : Type*} {mฮฉ : MeasurableSpace ฮฉ} {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) : +lemma hasCondDistrib_action_zero_deterministic + (h : IsAlgEnvSeqUntil O A Y (Algorithm.deterministic 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] + rw [โ† policyZero_deterministic] exact h.hasCondDistrib_action_zero hN -lemma action_detAlgorithm_ae_eq [MeasurableEq ๐“] - (h : IsAlgEnvSeqUntil O A Y (detAlgorithm nextA h_next) env P N) (hn : n < N) : +lemma action_deterministic_ae_eq [MeasurableEq ๐“] + (h : IsAlgEnvSeqUntil O A Y (Algorithm.deterministic 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) + (Algorithm.IsDeterministic.action_ae_eq_of_IsAlgEnvSeqUntil h hn).trans (by simp) -lemma action_zero_detAlgorithm [MeasurableEq ๐“] - (h : IsAlgEnvSeqUntil O A Y (detAlgorithm nextA h_next) env P N) (hN : 0 < N) : +lemma action_zero_deterministic [MeasurableEq ๐“] + (h : IsAlgEnvSeqUntil O A Y (Algorithm.deterministic 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) + (Algorithm.IsDeterministic.action_zero_of_IsAlgEnvSeqUntil h hN).trans (by simp) end IsAlgEnvSeqUntil diff --git a/LeanMachineLearning/SequentialLearning/DivergenceDecomposition.lean b/LeanMachineLearning/SequentialLearning/DivergenceDecomposition.lean index 3cad44da..d80f6b19 100644 --- a/LeanMachineLearning/SequentialLearning/DivergenceDecomposition.lean +++ b/LeanMachineLearning/SequentialLearning/DivergenceDecomposition.lean @@ -158,22 +158,22 @@ variable {O : โ„• โ†’ ฮฉ โ†’ Unit} {O' : โ„• โ†’ ฮฉ' โ†’ Unit} {alg : Algorithm {ฮบ ฮบ' : Kernel ๐“ ๐“จ} [IsMarkovKernel ฮบ] [IsMarkovKernel ฮบ'] /-- Chain rule for histories of a single algorithm versus two stationary environments. -/ -lemma IsAlgEnvSeq.klDiv_map_history_compProd (h : IsAlgEnvSeq O A Y alg (stationaryEnv ฮบ) P) - (h' : IsAlgEnvSeq O' A' Y' alg (stationaryEnv ฮบ') P') (M : โ„•) : +lemma IsAlgEnvSeq.klDiv_map_history_compProd (h : IsAlgEnvSeq O A Y alg (Environment.bandit ฮบ) P) + (h' : IsAlgEnvSeq O' A' Y' alg (Environment.bandit ฮบ') 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, + rw [obs_bandit] at h_obs + rw [stepKernel_bandit, stepKernel_bandit, 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 O A Y alg (stationaryEnv ฮบ) P) - (h' : IsAlgEnvSeq O' A' Y' alg (stationaryEnv ฮบ') P') (M : โ„•) : + (h : IsAlgEnvSeq O A Y alg (Environment.bandit ฮบ) P) + (h' : IsAlgEnvSeq O' A' Y' alg (Environment.bandit ฮบ') 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'] @@ -182,8 +182,8 @@ lemma IsAlgEnvSeq.klDiv_map_history [MeasurableSpace.CountablyGenerated ๐“จ] 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 O A Y alg (stationaryEnv ฮบ) P) - (h' : IsAlgEnvSeq O' A' Y' alg (stationaryEnv ฮบ') P') : +lemma IsAlgEnvSeq.klDiv_map_trajectory_compProd (h : IsAlgEnvSeq O A Y alg (Environment.bandit ฮบ) P) + (h' : IsAlgEnvSeq O' A' Y' alg (Environment.bandit ฮบ') 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 @@ -192,8 +192,8 @@ lemma IsAlgEnvSeq.klDiv_map_trajectory_compProd (h : IsAlgEnvSeq O A Y alg (stat /-- Chain rule for trajectories of a single algorithm versus two stationary environments. -/ lemma IsAlgEnvSeq.klDiv_map_trajectory [MeasurableSpace.CountablyGenerated ๐“จ] - (h : IsAlgEnvSeq O A Y alg (stationaryEnv ฮบ) P) - (h' : IsAlgEnvSeq O' A' Y' alg (stationaryEnv ฮบ') P') : + (h : IsAlgEnvSeq O A Y alg (Environment.bandit ฮบ) P) + (h' : IsAlgEnvSeq O' A' Y' alg (Environment.bandit ฮบ') 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'] diff --git a/LeanMachineLearning/SequentialLearning/EvaluationEnv.lean b/LeanMachineLearning/SequentialLearning/EvaluationEnv.lean index fdae6c06..d60e522a 100644 --- a/LeanMachineLearning/SequentialLearning/EvaluationEnv.lean +++ b/LeanMachineLearning/SequentialLearning/EvaluationEnv.lean @@ -12,24 +12,26 @@ public import LeanMachineLearning.ForMathlib.Probability.Independence.CondDistri /-! # Function evaluation environments -We define two environments, `onlineEvalEnv` and `evalEnv`, where the feedback is given by evaluating -a measurable function at the chosen action. The first one allows the function to change at every -time step, while the second one uses a fixed function at every time step. +We define two environments, `Environment.evalSeq` and `Environment.eval`, where the feedback is +given by evaluating a measurable function at the chosen action. The first one allows the function +to change at every time step, while the second one uses a fixed function at every time step. ## Main definitions -* `onlineEvalEnv g hg`: A stationary environment where the feedback at time `n` is given by a +* `Environment.evalSeq g hg`: A stationary environment where the feedback at time `n` is given by a deterministic kernel that evaluates the measurable function `g n` at the chosen action. -* `evalEnv f hf`: A stationary environment where the feedback is given by a deterministic kernel - that evaluates a fixed measurable function `f` at the chosen action. +* `Environment.eval f hf`: A stationary environment where the feedback is given by a deterministic + kernel that evaluates a fixed measurable function `f` at the chosen action. -They both satisfy the typeclasses `IsObliviousEnv` and `IsDeterministicEnv`. +They both satisfy the typeclasses `Environment.IsOblivious` and +`Environment.HasDeterministicFeedback`, and `Environment.eval f hf` is also +`Environment.IsStationary`. ## Main statements -* `forall_feedback_onlineEvalEnv_ae_eq_eval_action`: For almost all `ฯ‰`, the feedback at time `n` is +* `forall_feedback_evalSeq_ae_eq_eval_action`: For almost all `ฯ‰`, the feedback at time `n` is equal to `g n` evaluated at the action taken at time `n`. -* `forall_feedback_evalEnv_ae_eq_eval_action`: For almost all `ฯ‰`, the feedback at time `n` is equal +* `forall_feedback_eval_ae_eq_eval_action`: For almost all `ฯ‰`, the feedback at time `n` is equal to `f` evaluated at the action taken at time `n`. -/ @@ -46,32 +48,33 @@ variable {๐“ ๐“จ : Type*} {m๐“ : MeasurableSpace ๐“} {m๐“จ : MeasurableS /-- The evaluation environment where the feedback is given by evaluating a fixed measurable function `f` at the chosen action. -/ -noncomputable def onlineEvalEnv (g : โ„• โ†’ ๐“ โ†’ ๐“จ) (hg : โˆ€ n, Measurable (g n)) := - obliviousEnv (fun n โ†ฆ Kernel.deterministic (g n) (hg n)) +noncomputable def Environment.evalSeq (g : โ„• โ†’ ๐“ โ†’ ๐“จ) (hg : โˆ€ n, Measurable (g n)) := + Environment.banditSeq (fun n โ†ฆ Kernel.deterministic (g n) (hg n)) -instance : IsObliviousEnv (onlineEvalEnv g hg) := - โŸจโŸจfun n โ†ฆ Kernel.deterministic (g n) (hg n), fun _ โ†ฆ inferInstance, fun _ โ†ฆ rflโŸฉโŸฉ +instance : (Environment.evalSeq g hg).IsOblivious := + inferInstanceAs (Environment.banditSeq fun n โ†ฆ Kernel.deterministic (g n) (hg n)).IsOblivious -instance : IsDeterministicEnv (onlineEvalEnv g hg) where +instance : (Environment.evalSeq g hg).HasDeterministicFeedback where exists_f n := โŸจfun p โ†ฆ g n p.2, by fun_prop, rflโŸฉ @[simp] -lemma feedbackCondAction_onlineEvalEnv (n : โ„•) : - feedbackCondAction (onlineEvalEnv g hg) n = Kernel.deterministic (g n) (hg n) := by - simp [onlineEvalEnv] +lemma feedbackCondObsAction_evalSeq (n : โ„•) : + (Environment.evalSeq g hg).feedbackCondObsAction n + = Kernel.deterministic (fun p โ†ฆ g n p.2) (by fun_prop) := by + simp [Environment.evalSeq] @[simp] -lemma feedbackFun_onlineEvalEnv [MeasurableSpace.SeparatesPoints ๐“จ] (n : โ„•) : - feedbackFun (onlineEvalEnv g hg) n = fun p โ†ฆ g n p.2 := by - have h_eq := feedback_eq_deterministic (onlineEvalEnv g hg) n - simpa only [onlineEvalEnv, feedback_obliviousEnv, Kernel.prodMkLeft_deterministic, +lemma feedbackFun_evalSeq [MeasurableSpace.SeparatesPoints ๐“จ] (n : โ„•) : + (Environment.evalSeq g hg).feedbackFun n = fun p โ†ฆ g n p.2 := by + have h_eq := (Environment.evalSeq g hg).feedback_eq_deterministic n + simpa only [Environment.evalSeq, feedback_banditSeq, Kernel.prodMkLeft_deterministic, Kernel.deterministic_inj] using h_eq.symm @[simp] -lemma feedbackFunZero_onlineEvalEnv [MeasurableSpace.SeparatesPoints ๐“จ] : - feedbackFunZero (onlineEvalEnv g hg) = fun p โ†ฆ g 0 p.2 := by - unfold feedbackFunZero - rw [feedbackFun_onlineEvalEnv] +lemma feedbackFunZero_evalSeq [MeasurableSpace.SeparatesPoints ๐“จ] : + (Environment.evalSeq g hg).feedbackFunZero = fun p โ†ฆ g 0 p.2 := by + unfold Environment.feedbackFunZero + rw [feedbackFun_evalSeq] section OnlineEvalEnv @@ -80,46 +83,55 @@ variable {ฮฉ : Type*} {mฮฉ : MeasurableSpace ฮฉ} {alg : Algorithm Unit ๐“ ๐“จ {P : Measure ฮฉ} [IsProbabilityMeasure P] {O : โ„• โ†’ ฮฉ โ†’ Unit} {A : โ„• โ†’ ฮฉ โ†’ ๐“} {Y : โ„• โ†’ ฮฉ โ†’ ๐“จ} -lemma hascondDistrib_feedback_onlineEvalEnv - (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 hasCondDistrib_feedback_evalSeq + (h : IsAlgEnvSeq O A Y alg (Environment.evalSeq g hg) P) (n : โ„•) : + HasCondDistrib (Y n) (A n) (Kernel.deterministic (g n) (hg n)) P := + h.hasCondDistrib_feedback_banditSeq n -lemma feedback_onlineEvalEnv_ae_eq_eval_action [StandardBorelSpace ๐“จ] [Nonempty ๐“จ] - (h : IsAlgEnvSeq O A Y alg (onlineEvalEnv g hg) P) (n : โ„•) : +lemma feedback_evalSeq_ae_eq_eval_action [StandardBorelSpace ๐“จ] [Nonempty ๐“จ] + (h : IsAlgEnvSeq O A Y alg (Environment.evalSeq 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 + (hasCondDistrib_feedback_evalSeq h n).condDistrib_eq -lemma forall_feedback_onlineEvalEnv_ae_eq_eval_action [StandardBorelSpace ๐“จ] [Nonempty ๐“จ] - (h : IsAlgEnvSeq O A Y alg (onlineEvalEnv g hg) P) : +lemma forall_feedback_evalSeq_ae_eq_eval_action [StandardBorelSpace ๐“จ] [Nonempty ๐“จ] + (h : IsAlgEnvSeq O A Y alg (Environment.evalSeq g hg) P) : โˆ€แต ฯ‰ โˆ‚P, โˆ€ n, Y n ฯ‰ = g n (A n ฯ‰) := by rw [ae_all_iff] intro n - exact feedback_onlineEvalEnv_ae_eq_eval_action h n + exact feedback_evalSeq_ae_eq_eval_action h n end OnlineEvalEnv /-- The evaluation environment where the feedback is given by evaluating a fixed measurable function `f` at the chosen action. -/ -noncomputable def evalEnv (f : ๐“ โ†’ ๐“จ) (hf : Measurable f) := onlineEvalEnv (fun _ โ†ฆ f) (fun _ โ†ฆ hf) +noncomputable def Environment.eval (f : ๐“ โ†’ ๐“จ) (hf : Measurable f) := + Environment.evalSeq (fun _ โ†ฆ f) (fun _ โ†ฆ hf) -instance : IsObliviousEnv (evalEnv f hf) := by unfold evalEnv; infer_instance +instance : (Environment.eval f hf).IsStationary where + exists_obs_eq_const := โŸจMeasure.dirac (), inferInstance, fun _ โ†ฆ rflโŸฉ + exists_feedback_eq_comap := + โŸจ(Kernel.deterministic f hf).prodMkLeft Unit, inferInstance, fun _ โ†ฆ rflโŸฉ -instance : IsDeterministicEnv (evalEnv f hf) := by unfold evalEnv; infer_instance +instance : (Environment.eval f hf).IsOblivious := by unfold Environment.eval; infer_instance + +instance : (Environment.eval f hf).HasDeterministicFeedback := by + unfold Environment.eval; infer_instance @[simp] -lemma feedbackCondAction_evalEnv (n : โ„•) : - feedbackCondAction (evalEnv f hf) n = Kernel.deterministic f hf := by simp [evalEnv] +lemma feedbackCondObsAction_eval (n : โ„•) : + (Environment.eval f hf).feedbackCondObsAction n + = Kernel.deterministic (fun p โ†ฆ f p.2) (by fun_prop) := by + simp [Environment.eval] @[simp] -lemma feedbackFunZero_evalEnv [MeasurableSpace.SeparatesPoints ๐“จ] : - feedbackFunZero (evalEnv f hf) = fun p โ†ฆ f p.2 := by simp [evalEnv] +lemma feedbackFunZero_eval [MeasurableSpace.SeparatesPoints ๐“จ] : + (Environment.eval f hf).feedbackFunZero = fun p โ†ฆ f p.2 := by simp [Environment.eval] @[simp] -lemma feedbackFun_evalEnv [MeasurableSpace.SeparatesPoints ๐“จ] (n : โ„•) : - feedbackFun (evalEnv f hf) n = fun p โ†ฆ f p.2 := by simp [evalEnv] +lemma feedbackFun_eval [MeasurableSpace.SeparatesPoints ๐“จ] (n : โ„•) : + (Environment.eval f hf).feedbackFun n = fun p โ†ฆ f p.2 := by simp [Environment.eval] section EvalEnv @@ -128,23 +140,23 @@ variable {ฮฉ : Type*} {mฮฉ : MeasurableSpace ฮฉ} {alg : Algorithm Unit ๐“ ๐“จ {P : Measure ฮฉ} [IsProbabilityMeasure P] {O : โ„• โ†’ ฮฉ โ†’ Unit} {A : โ„• โ†’ ฮฉ โ†’ ๐“} {Y : โ„• โ†’ ฮฉ โ†’ ๐“จ} -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 hasCondDistrib_feedback_eval (h : IsAlgEnvSeq O A Y alg (Environment.eval f hf) P) (n : โ„•) : + HasCondDistrib (Y n) (A n) (Kernel.deterministic f hf) P := + h.hasCondDistrib_feedback_banditSeq n -lemma feedback_evalEnv_ae_eq_eval_action [StandardBorelSpace ๐“จ] [Nonempty ๐“จ] - (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 feedback_eval_ae_eq_eval_action [StandardBorelSpace ๐“จ] [Nonempty ๐“จ] + (h : IsAlgEnvSeq O A Y alg (Environment.eval f hf) P) (n : โ„•) : + Y n =แต[P] f โˆ˜ A n := feedback_evalSeq_ae_eq_eval_action h n -lemma forall_feedback_evalEnv_ae_eq_eval_action [StandardBorelSpace ๐“จ] [Nonempty ๐“จ] - (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 +lemma forall_feedback_eval_ae_eq_eval_action [StandardBorelSpace ๐“จ] [Nonempty ๐“จ] + (h : IsAlgEnvSeq O A Y alg (Environment.eval f hf) P) : + โˆ€แต ฯ‰ โˆ‚P, โˆ€ n, Y n ฯ‰ = f (A n ฯ‰) := forall_feedback_evalSeq_ae_eq_eval_action h open Finset in -lemma feedback_evalEnv_ae_eq_eval_action_comp {ฮฒ : Type*} [StandardBorelSpace ๐“จ] [Nonempty ๐“จ] - (h : IsAlgEnvSeq O A Y alg (evalEnv f hf) P) {n : โ„•} (g : (Iic n โ†’ ๐“จ) โ†’ ฮฒ) : +lemma feedback_eval_ae_eq_eval_action_comp {ฮฒ : Type*} [StandardBorelSpace ๐“จ] [Nonempty ๐“จ] + (h : IsAlgEnvSeq O A Y alg (Environment.eval 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ฯ‰ + filter_upwards [forall_feedback_eval_ae_eq_eval_action h] with ฯ‰ hฯ‰ simp_rw [hฯ‰] end EvalEnv diff --git a/LeanMachineLearning/SequentialLearning/IonescuTulceaSpace.lean b/LeanMachineLearning/SequentialLearning/IonescuTulceaSpace.lean index 515c6874..9601a064 100644 --- a/LeanMachineLearning/SequentialLearning/IonescuTulceaSpace.lean +++ b/LeanMachineLearning/SequentialLearning/IonescuTulceaSpace.lean @@ -345,19 +345,20 @@ lemma isAlgEnvSeq_trajMeasure (alg : Algorithm ๐“ž ๐“ ๐“จ) (env : Environmen hasCondDistrib_feedback n := hasCondDistrib_feedback alg env n lemma hasLaw_step_zero (alg : Algorithm ๐“ž ๐“ ๐“จ) (env : Environment ๐“ž ๐“ ๐“จ) : - HasLaw (step 0) (env.obs0 โŠ—โ‚˜ (alg.p0 โŠ—โ‚– env.ฮฝ0)) (trajMeasure alg env) := + HasLaw (step 0) (env.obsZero โŠ—โ‚˜ (alg.policyZero โŠ—โ‚– env.feedbackZero)) (trajMeasure alg env) := (isAlgEnvSeq_trajMeasure alg env).hasLaw_step_zero lemma hasLaw_obs_zero (alg : Algorithm ๐“ž ๐“ ๐“จ) (env : Environment ๐“ž ๐“ ๐“จ) : - HasLaw (obs 0) env.obs0 (trajMeasure alg env) := + HasLaw (obs 0) env.obsZero (trajMeasure alg env) := (isAlgEnvSeq_trajMeasure alg env).hasLaw_obs_zero lemma hasCondDistrib_action_zero (alg : Algorithm ๐“ž ๐“ ๐“จ) (env : Environment ๐“ž ๐“ ๐“จ) : - HasCondDistrib (action 0) (obs 0) alg.p0 (trajMeasure alg env) := + HasCondDistrib (action 0) (obs 0) alg.policyZero (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) := + HasCondDistrib (feedback 0) (fun ฯ‰ โ†ฆ (obs 0 ฯ‰, action 0 ฯ‰)) env.feedbackZero + (trajMeasure alg env) := (isAlgEnvSeq_trajMeasure alg env).hasCondDistrib_feedback_zero end Laws diff --git a/LeanMachineLearning/SequentialLearning/Means.lean b/LeanMachineLearning/SequentialLearning/Means.lean index 6207a34f..62460fcb 100644 --- a/LeanMachineLearning/SequentialLearning/Means.lean +++ b/LeanMachineLearning/SequentialLearning/Means.lean @@ -65,22 +65,36 @@ noncomputable def Environment.means (env : Environment ๐“ž ๐“ ๐“จ) (O : โ„• @[simp] lemma means_zero (env : Environment ๐“ž ๐“ ๐“จ) (O : โ„• โ†’ ฮฉ โ†’ ๐“ž) (A : โ„• โ†’ ฮฉ โ†’ ๐“) (Y : โ„• โ†’ ฮฉ โ†’ ๐“จ) (k : ๐“) (ฯ‰ : ฮฉ) : - env.means O A Y k 0 ฯ‰ = (env.ฮฝ0 (O 0 ฯ‰, k))[id] := by + env.means O A Y k 0 ฯ‰ = (env.feedbackZero (O 0 ฯ‰, k))[id] := by simp [Environment.means, Environment.measure, Environment.feedback_zero] @[simp] -lemma means_of_isObliviousEnv [IsObliviousEnv env] (O : โ„• โ†’ ฮฉ โ†’ ๐“ž) (A : โ„• โ†’ ฮฉ โ†’ ๐“) +lemma means_of_isOblivious [env.IsOblivious] (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] + env.means O A Y k n ฯ‰ = (env.feedbackCondObsAction n (O n ฯ‰, k))[id] := by + simp [Environment.means, Environment.measure, env.feedback_eq_comap_feedbackCondObsAction, + Kernel.comap_apply] -lemma means_obliviousEnv (ฮฝ : โ„• โ†’ Kernel ๐“ ๐“จ) [โˆ€ n, IsMarkovKernel (ฮฝ n)] +lemma means_of_isStationary [env.IsStationary] (O : โ„• โ†’ ฮฉ โ†’ ๐“ž) (A : โ„• โ†’ ฮฉ โ†’ ๐“) + (Y : โ„• โ†’ ฮฉ โ†’ ๐“จ) (k : ๐“) (n : โ„•) (ฯ‰ : ฮฉ) : + env.means O A Y k n ฯ‰ = (env.feedbackZero (O n ฯ‰, k))[id] := by + rw [means_of_isOblivious, env.feedbackCondObsAction_eq_feedbackZero] + +lemma means_oblivious (ฮผ : โ„• โ†’ Measure ๐“ž) [โˆ€ n, IsProbabilityMeasure (ฮผ n)] + (ฮฝ : โ„• โ†’ Kernel (๐“ž ร— ๐“) ๐“จ) [โˆ€ n, IsMarkovKernel (ฮฝ n)] (k : ๐“) (n : โ„•) (ฯ‰ : ฮฉ) : + (Environment.oblivious ฮผ ฮฝ).means O A Y k n ฯ‰ = (ฮฝ n (O n ฯ‰, k))[id] := by simp + +lemma means_stationary (ฮผ : Measure ๐“ž) [IsProbabilityMeasure ฮผ] (ฮฝ : Kernel (๐“ž ร— ๐“) ๐“จ) + [IsMarkovKernel ฮฝ] (k : ๐“) (n : โ„•) (ฯ‰ : ฮฉ) : + (Environment.stationary ฮผ ฮฝ).means O A Y k n ฯ‰ = (ฮฝ (O n ฯ‰, k))[id] := by simp + +lemma means_banditSeq (ฮฝ : โ„• โ†’ Kernel ๐“ ๐“จ) [โˆ€ n, IsMarkovKernel (ฮฝ n)] {O : โ„• โ†’ ฮฉ โ†’ Unit} {A : โ„• โ†’ ฮฉ โ†’ ๐“} {Y : โ„• โ†’ ฮฉ โ†’ ๐“จ} (k : ๐“) (n : โ„•) (ฯ‰ : ฮฉ) : - (obliviousEnv ฮฝ).means O A Y k n ฯ‰ = (ฮฝ n k)[id] := by simp + (Environment.banditSeq ฮฝ).means O A Y k n ฯ‰ = (ฮฝ n k)[id] := by simp -lemma means_stationaryEnv (ฮฝ : Kernel ๐“ ๐“จ) [IsMarkovKernel ฮฝ] +lemma means_bandit (ฮฝ : Kernel ๐“ ๐“จ) [IsMarkovKernel ฮฝ] {O : โ„• โ†’ ฮฉ โ†’ Unit} {A : โ„• โ†’ ฮฉ โ†’ ๐“} {Y : โ„• โ†’ ฮฉ โ†’ ๐“จ} (k : ๐“) (n : โ„•) (ฯ‰ : ฮฉ) : - (stationaryEnv ฮฝ).means O A Y k n ฯ‰ = (ฮฝ k)[id] := by simp + (Environment.bandit ฮฝ).means O A Y k n ฯ‰ = (ฮฝ k)[id] := by simp @[fun_prop] lemma IsAlgEnvSeq.stronglyMeasurable_means [SecondCountableTopology ๐“จ] [OpensMeasurableSpace ๐“จ] diff --git a/LeanMachineLearning/SequentialLearning/README.md b/LeanMachineLearning/SequentialLearning/README.md new file mode 100644 index 00000000..eb0cecbf --- /dev/null +++ b/LeanMachineLearning/SequentialLearning/README.md @@ -0,0 +1,94 @@ +# Naming of algorithms and environments + +The file `Algorithm.lean` defines the `Algorithm` and `Environment` structures. +An algorithm has a sequence of Markov kernels (the policy) which reads a history and an observation and returns an action. +```lean +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)] +``` +An environment has two sequences of kernels: one for observations, which reads the history, and one for feedback, which reads the history, the current observation and the current action. +```lean +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)] +``` + +In many applications, some of those kernels are deterministic, or do not depend on some of their inputs. +We detail here the naming conventions for the various constructors, predicates and accessors that are used in the library. + +NOTE: some names described below are marked as MISSING because they are not yet implemented in the library. +They may never be implemented if we don't need them. +If you need one of them, treat the name here as a recommendation that you may want to use. + +Generic constructions live in the `Algorithm` and `Environment` namespaces. +Predicates live in the `Algorithm` and `Environment` namespaces: they are classes when they carry an accessor, and `Prop` definitions otherwise. +Accessors are namespaced so that dot notation works. + +All time zero accessors are `โ€ฆZero` definitions. Example: `Algorithm.policyZero`. + +## Algorithms + +The policy at round `n` can depend on `n`, on the history at `n` and the current observation. It can be deterministic or stochastic. + +Not stochastic: `Algorithm.IsDeterministic`, `Algorithm.deterministic` + +No observation: `Algorithm.IgnoresObs` (MISSING), `Algorithm.comapObs fun _ โ†ฆ ()` + +No history: `Algorithm.IsMarkov`, `Algorithm.markov` + +No history, no observation: `Algorithm.IsOpenLoop` (MISSING), `Algorithm.openLoop` (MISSING), `Algorithm.ofSeq` (MISSING) (det version) + +Not time-dependent, no history: `Algorithm.IsStationary` (MISSING), `Algorithm.stationary` (MISSING) + +No time, no history, no observation: `Algorithm.const` + +## Environments + +The observation at round `n` can depend on `n` and on the history at `n`, and can be deterministic or stochastic. + +The feedback at round `n` can depend on `n`, on the history at `n`, on the current observation and on the current action. +It can be deterministic or stochastic. + +In general, the dependence on history is the same for both kernels. + +All for obs, no action for feedback: `Environment.FeedbackIgnoresAction` (MISSING), `Environment.adversary` (MISSING). + +No history for obs and feedback: `Environment.IsOblivious`, `Environment.oblivious`. + +No time, no history for obs and feedback: `Environment.IsStationary`, `Environment.stationary`. + +No time, last round of history for obs, not history for feedback: `Environment.IsMarkov` (MISSING), `Environment.markov` (MISSING). + +Determinism: `Environment.HasDeterministicObs` (MISSING), `Environment.HasDeterministicFeedback`, `Environment.detFeedback` (any observation kernels, deterministic feedback). + +### Obs = Unit + +Only the feedback matters, so the constructors are named by the feedback's shape. +It can depend on time, history and action and be stochastic or deterministic. + +general: use `Environment` with Obs = Unit. + +No history: `Environment.banditSeq` and `Environment.bandit` (no time). + +No history, deterministic: `Environment.evalSeq` and `Environment.eval` (no time). + +No history, no action (only time): `Environment.indep` (MISSING) and `Environment.ofSeq` (MISSING) (deterministic). + +Nothing: `Environment.const` (MISSING) (stochastic). The deterministic version is probably not useful. + +## Examples + +Oblivious adversarial bandit environment: Obs = Unit, feedback depends on time and action, deterministic. Use `Environment.evalSeq`. + +Stochastic optimization: Obs = Unit, feedback depends on time and action, stochastic. Use `Environment.banditSeq`. diff --git a/LeanMachineLearning/SequentialLearning/StationaryEnv.lean b/LeanMachineLearning/SequentialLearning/StationaryEnv.lean index b652c7e5..dcd5571d 100644 --- a/LeanMachineLearning/SequentialLearning/StationaryEnv.lean +++ b/LeanMachineLearning/SequentialLearning/StationaryEnv.lean @@ -11,29 +11,41 @@ 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 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. +An oblivious environment is an environment in which the distributions of the observation and of +the feedback do not depend on the past history: at time `n`, the observation has law +`env.obsLaw n`, and the feedback depends only on the current observation and action, through the +Markov kernel `env.feedbackCondObsAction n`. +A stationary environment is an oblivious environment in which these laws do not depend on time +either: every observation has law `env.obsZero`, and the feedback is drawn from the Markov kernel +`env.feedbackZero` applied to the current observation and action. ## Main definitions -We define a `Prop`-valued typeclass `IsObliviousEnv` to express that an environment is oblivious, -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. -* `feedbackCondAction env n`: the kernel representing the conditional distribution of the feedback - given the action at time `n` in an oblivious environment `env`. +We define `Prop`-valued typeclasses `Environment.IsOblivious` and `Environment.IsStationary` to +express that an environment is oblivious or stationary, and we define constructors for oblivious +and stationary environments, with and without observations. + +Typeclasses and related definitions: +* `Environment.IsOblivious env`: the environment `env` is oblivious. +* `Environment.obsLaw env n`: the law of the observation at time `n` in an oblivious + environment `env`. +* `Environment.feedbackCondObsAction env n`: the kernel representing the conditional distribution + of the feedback given the observation and the action at time `n` in an oblivious + environment `env`. +* `Environment.IsStationary env`: the environment `env` is stationary. A stationary environment is + oblivious, and its laws are described by the time zero accessors `env.obsZero` and + `env.feedbackZero` (see `Environment.obs_eq_const_obsZero` and + `Environment.feedback_eq_comap_feedbackZero`). Constructors for oblivious environments: -* `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 ๐“ ๐“จ`. +* `Environment.oblivious ฮผ ฮฝ`: the oblivious environment in which the observation at time `n` has + law `ฮผ n` and the feedback at time `n` is drawn from the Markov kernel `ฮฝ n : Kernel (๐“ž ร— ๐“) ๐“จ` + applied to the observation and the action at time `n`. +* `Environment.stationary ฮผ ฮฝ`: the oblivious environment with constant sequences: the observations + have law `ฮผ` and the feedback is drawn from `ฮฝ` applied to the observation and the action. +* `Environment.banditSeq ฮฝ`, `Environment.bandit ฮฝ`: the versions without observations + (`๐“ž = Unit`), in which the feedback at time `n` is drawn from `ฮฝ n : Kernel ๐“ ๐“จ` + (respectively from `ฮฝ : Kernel ๐“ ๐“จ`) applied to the action at time `n`. -/ @@ -48,246 +60,593 @@ namespace Learning 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 nor on the current observation. -/ -class IsObliviousEnv (env : Environment ๐“ž ๐“ ๐“จ) : Prop where - exists_eq_prodMkLeft : โˆƒ ฮฝ : โ„• โ†’ Kernel ๐“ ๐“จ, (โˆ€ n, IsMarkovKernel (ฮฝ n)) โˆง - (โˆ€ n, env.feedback n = (ฮฝ n).prodMkLeft _) +/-- An environment is oblivious if the distributions of the next observation and feedback +don't depend on the past history: the observation at time `n` has a fixed law, and the feedback +at time `n` depends only on the observation and the action at time `n`. -/ +class Environment.IsOblivious (env : Environment ๐“ž ๐“ ๐“จ) : Prop where + exists_obs_eq_const : โˆƒ ฮผ : โ„• โ†’ Measure ๐“ž, (โˆ€ n, IsProbabilityMeasure (ฮผ n)) โˆง + โˆ€ n, env.obs n = Kernel.const _ (ฮผ n) + exists_feedback_eq_comap : โˆƒ ฮฝ : โ„• โ†’ Kernel (๐“ž ร— ๐“) ๐“จ, (โˆ€ n, IsMarkovKernel (ฮฝ n)) โˆง + โˆ€ n, env.feedback n = (ฮฝ n).comap (fun p โ†ฆ (p.1.2, p.2)) (by fun_prop) + +namespace Environment + +/-- The law of the observation at time `n` in an oblivious environment. -/ +noncomputable +def obsLaw (env : Environment ๐“ž ๐“ ๐“จ) [h_obl : env.IsOblivious] (n : โ„•) : Measure ๐“ž := + h_obl.exists_obs_eq_const.choose n + +instance (env : Environment ๐“ž ๐“ ๐“จ) [env.IsOblivious] (n : โ„•) : + IsProbabilityMeasure (env.obsLaw n) := + IsOblivious.exists_obs_eq_const.choose_spec.1 n + +lemma obs_eq_const_obsLaw (env : Environment ๐“ž ๐“ ๐“จ) [env.IsOblivious] (n : โ„•) : + env.obs n = Kernel.const _ (env.obsLaw n) := + IsOblivious.exists_obs_eq_const.choose_spec.2 n -/-- The kernel representing the conditional distribution of the feedback given the action -at time `n` in an oblivious environment. -/ +lemma obsZero_eq_obsLaw (env : Environment ๐“ž ๐“ ๐“จ) [env.IsOblivious] : + env.obsZero = env.obsLaw 0 := by + rw [Environment.obsZero_def, obs_eq_const_obsLaw, Kernel.const_apply] + +/-- The kernel representing the conditional distribution of the feedback given the observation and +the action at time `n` in an oblivious environment. -/ noncomputable -def feedbackCondAction (env : Environment ๐“ž ๐“ ๐“จ) [h_obl : IsObliviousEnv env] (n : โ„•) : - Kernel ๐“ ๐“จ := - h_obl.exists_eq_prodMkLeft.choose n +def feedbackCondObsAction (env : Environment ๐“ž ๐“ ๐“จ) [h_obl : env.IsOblivious] (n : โ„•) : + Kernel (๐“ž ร— ๐“) ๐“จ := + h_obl.exists_feedback_eq_comap.choose n -instance (env : Environment ๐“ž ๐“ ๐“จ) [IsObliviousEnv env] (n : โ„•) : - IsMarkovKernel (feedbackCondAction env n) := - IsObliviousEnv.exists_eq_prodMkLeft.choose_spec.1 n +instance (env : Environment ๐“ž ๐“ ๐“จ) [env.IsOblivious] (n : โ„•) : + IsMarkovKernel (env.feedbackCondObsAction n) := + IsOblivious.exists_feedback_eq_comap.choose_spec.1 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 feedback_eq_comap_feedbackCondObsAction (env : Environment ๐“ž ๐“ ๐“จ) [env.IsOblivious] + (n : โ„•) : + env.feedback n = (env.feedbackCondObsAction n).comap (fun p โ†ฆ (p.1.2, p.2)) (by fun_prop) := + IsOblivious.exists_feedback_eq_comap.choose_spec.2 n -lemma ฮฝ0_eq_feedbackCondAction (env : Environment ๐“ž ๐“ ๐“จ) [IsObliviousEnv env] : - env.ฮฝ0 = (feedbackCondAction env 0).prodMkLeft ๐“ž := by +lemma feedbackZero_eq_feedbackCondObsAction (env : Environment ๐“ž ๐“ ๐“จ) [env.IsOblivious] : + env.feedbackZero = env.feedbackCondObsAction 0 := by ext p : 1 - rw [Environment.ฮฝ0_def, Kernel.comap_apply, feedback_eq_feedbackCondAction, - Kernel.prodMkLeft_apply, Kernel.prodMkLeft_apply] + rw [Environment.feedbackZero_def, Kernel.comap_apply, feedback_eq_comap_feedbackCondObsAction, + Kernel.comap_apply] + +lemma obsLaw_eq_of_obs_eq_const [Nonempty ๐“] [Nonempty ๐“จ] + (env : Environment ๐“ž ๐“ ๐“จ) [env.IsOblivious] {n : โ„•} {ฮผ : Measure ๐“ž} [IsProbabilityMeasure ฮผ] + (h : env.obs n = Kernel.const _ ฮผ) : + env.obsLaw n = ฮผ := by + have : Nonempty ๐“ž := Measure.nonempty_of_neZero ฮผ + have h_eq := env.obs_eq_const_obsLaw n + rw [h, Kernel.ext_iff] at h_eq + simpa using (h_eq (Classical.arbitrary _)).symm + +lemma feedbackCondObsAction_eq_of_feedback_eq (env : Environment ๐“ž ๐“ ๐“จ) [env.IsOblivious] + {n : โ„•} {ฮฝ : Kernel (๐“ž ร— ๐“) ๐“จ} [hฮฝ : IsMarkovKernel ฮฝ] + (h : env.feedback n = ฮฝ.comap (fun p โ†ฆ (p.1.2, p.2)) (by fun_prop)) : + env.feedbackCondObsAction n = ฮฝ := by + rcases isEmpty_or_nonempty ๐“ž with h๐“ž | h๐“ž + ยท ext p : 1 + exact h๐“ž.elim p.1 + rcases isEmpty_or_nonempty ๐“ with h๐“ | h๐“ + ยท ext p : 1 + exact h๐“.elim p.2 + rcases isEmpty_or_nonempty ๐“จ with h๐“จ | h๐“จ + ยท refine absurd hฮฝ ?_ + rw [Subsingleton.eq_zero ฮฝ] + exact Kernel.not_isMarkovKernel_zero + have h_eq := env.feedback_eq_comap_feedbackCondObsAction n + rw [h, Kernel.ext_iff] at h_eq + ext p : 1 + obtain โŸจo, aโŸฉ := p + exact (h_eq ((Classical.arbitrary _, o), a)).symm + +end Environment -namespace IsObliviousEnv +namespace Environment.IsOblivious variable {ฮฉ : Type*} {mฮฉ : MeasurableSpace ฮฉ} - {alg : Algorithm ๐“ž ๐“ ๐“จ} {env : Environment ๐“ž ๐“ ๐“จ} {P : Measure ฮฉ} [IsFiniteMeasure P] + {alg : Algorithm ๐“ž ๐“ ๐“จ} {env : Environment ๐“ž ๐“ ๐“จ} {P : Measure ฮฉ} {O : โ„• โ†’ ฮฉ โ†’ ๐“ž} {A : โ„• โ†’ ฮฉ โ†’ ๐“} {Y : โ„• โ†’ ฮฉ โ†’ ๐“จ} {n N : โ„•} - {ฮฝ : โ„• โ†’ Kernel ๐“ ๐“จ} [โˆ€ n, IsMarkovKernel (ฮฝ n)] -lemma hasCondDistrib_feedback_history_action [IsObliviousEnv env] +/-- The observation at time `n` has law `env.obsLaw n`. -/ +lemma hasLaw_obs [IsProbabilityMeasure P] [env.IsOblivious] + (h : IsAlgEnvSeq O A Y alg env P) (n : โ„•) : + HasLaw (O n) (env.obsLaw n) P := by + have h' := h.hasCondDistrib_obs n + rw [env.obs_eq_const_obsLaw] at h' + exact h'.hasLaw_of_const + +variable [IsFiniteMeasure P] + +lemma hasCondDistrib_feedback_history_action [env.IsOblivious] (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] + ((env.feedbackCondObsAction n).comap (fun p โ†ฆ (p.1.2, p.2)) (by fun_prop) + : Kernel ((Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) ร— ๐“) ๐“จ) P := by + rw [โ† env.feedback_eq_comap_feedbackCondObsAction] exact h.hasCondDistrib_feedback n -lemma hasCondDistrib_feedback [IsObliviousEnv env] (h : IsAlgEnvSeq O A Y alg env P) (n : โ„•) : - HasCondDistrib (Y n) (A n) (feedbackCondAction env n) P := +/-- The conditional distribution of the feedback at time `n` given the observation and the action +at time `n` is `env.feedbackCondObsAction n`. -/ +lemma hasCondDistrib_feedback [env.IsOblivious] (h : IsAlgEnvSeq O A Y alg env P) (n : โ„•) : + HasCondDistrib (Y n) (fun ฯ‰ โ†ฆ (O n ฯ‰, A n ฯ‰)) (env.feedbackCondObsAction n) P := (hasCondDistrib_feedback_history_action h n).comp_right -/-- 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 O A Y alg env P) (n : โ„•) - {s : Set ((Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) ร— ๐“)} (hs : MeasurableSet s) {b : ๐“} (hsb : โˆ€ u โˆˆ s, u.2 = b) +/-- Conditionally on an event determined by the history before time `n`, the observation and the +action at time `n`, on which the observation-action pair is equal to `b`, the feedback at time `n` +has law `env.feedbackCondObsAction n b`. -/ +lemma hasLaw_feedback_cond [env.IsOblivious] (h : IsAlgEnvSeq O A Y alg env P) (n : โ„•) + {s : Set ((Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) ร— ๐“)} (hs : MeasurableSet s) {b : ๐“ž ร— ๐“} + (hsb : โˆ€ u โˆˆ s, (u.1.2, u.2) = b) (hP : P ((fun ฯ‰ โ†ฆ ((history O A Y n ฯ‰, O n ฯ‰), A n ฯ‰)) โปยน' s) โ‰  0) : - HasLaw (Y n) (feedbackCondAction env n b) + HasLaw (Y n) (env.feedbackCondObsAction n b) 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] + rw [Kernel.comap_apply, hsb u hu] -/-- 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 [IsObliviousEnv env] +/-- Conditionally on an event determined by the history before time `n`, the observation and the +action at time `n`, on which the observation-action pair is constant, the feedback at time `n` is +independent of the history before time `n`, the observation and the action at time `n`. -/ +lemma indepFun_history_action_feedback_cond [env.IsOblivious] (h : IsAlgEnvSeq O A Y alg env P) (n : โ„•) - {s : Set ((Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) ร— ๐“)} (hs : MeasurableSet s) {b : ๐“} (hsb : โˆ€ u โˆˆ s, u.2 = b) : + {s : Set ((Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) ร— ๐“)} (hs : MeasurableSet s) {b : ๐“ž ร— ๐“} + (hsb : โˆ€ u โˆˆ s, (u.1.2, 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 - (ฮท := feedbackCondAction env n b) fun u hu โ†ฆ ?_ - rw [Kernel.prodMkLeft_apply, hsb u hu] + (ฮท := env.feedbackCondObsAction n b) fun u hu โ†ฆ ?_ + rw [Kernel.comap_apply, hsb u hu] variable [StandardBorelSpace ๐“ž] [Nonempty ๐“ž] [StandardBorelSpace ๐“] [Nonempty ๐“] [StandardBorelSpace ๐“จ] [Nonempty ๐“จ] -/-- 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 O A Y alg env P) (n : โ„•) : - Y n โŸ‚แตข[A n, h.measurable_action _ ; P] (fun ฯ‰ โ†ฆ (history O A Y n ฯ‰, O n ฯ‰)) := by +/-- The feedback at time `n` is conditionally independent of the history before time `n`, given +the observation and the action at time `n`. -/ +lemma condIndepFun_feedback_history [StandardBorelSpace ฮฉ] + [env.IsOblivious] (h : IsAlgEnvSeq O A Y alg env P) (n : โ„•) : + Y n โŸ‚แตข[fun ฯ‰ โ†ฆ (O n ฯ‰, A n ฯ‰), (h.measurable_obs n).prodMk (h.measurable_action n); P] + history O A Y 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 - (ฮท := feedbackCondAction env n) - (by fun_prop) (by fun_prop) (by fun_prop) ?_ + (ฮท := env.feedbackCondObsAction n) (by fun_prop) (by fun_prop) (by fun_prop) ?_ refine HasCondDistrib.condDistrib_eq ?_ - rw [โ† feedback_eq_feedbackCondAction] - exact h.hasCondDistrib_feedback n - -lemma condIndepFun_feedback_history_action_action [StandardBorelSpace ฮฉ] - [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 h' := hasCondDistrib_feedback_history_action h n + have hฮบ : ((env.feedbackCondObsAction n).comap (fun p โ†ฆ (p.1.2, p.2)) (by fun_prop) + : Kernel ((Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) ร— ๐“) ๐“จ) + = ((env.feedbackCondObsAction n).prodMkLeft (Hist ๐“ž ๐“ ๐“จ n)).comap + (fun p โ†ฆ (p.1.1, (p.1.2, p.2))) (by fun_prop) := rfl + rw [hฮบ] at h' + exact h'.comp_right + +/-- The feedback at time `n` is conditionally independent of the history before time `n`, the +observation and the action at time `n`, given the observation and the action at time `n`. -/ +lemma condIndepFun_feedback_history_obs_action [StandardBorelSpace ฮฉ] + [env.IsOblivious] (h : IsAlgEnvSeq O A Y alg env P) (n : โ„•) : + Y n โŸ‚แตข[fun ฯ‰ โ†ฆ (O n ฯ‰, A n ฯ‰), (h.measurable_obs n).prodMk (h.measurable_action n); P] + (fun ฯ‰ โ†ฆ (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 h_indep.prod_right (by fun_prop) (by fun_prop) (by fun_prop) + exact (condIndepFun_feedback_history h n).prod_right (by fun_prop) (by fun_prop) (by fun_prop) + +end Environment.IsOblivious + +/-- An environment is stationary if it is oblivious and its laws do not depend on time: the +observations have a fixed law, and the feedback depends only on the current observation and action, +through a fixed Markov kernel. -/ +class Environment.IsStationary (env : Environment ๐“ž ๐“ ๐“จ) : Prop where + exists_obs_eq_const : โˆƒ ฮผ : Measure ๐“ž, IsProbabilityMeasure ฮผ โˆง โˆ€ n, env.obs n = Kernel.const _ ฮผ + exists_feedback_eq_comap : โˆƒ ฮฝ : Kernel (๐“ž ร— ๐“) ๐“จ, IsMarkovKernel ฮฝ โˆง + โˆ€ n, env.feedback n = ฮฝ.comap (fun p โ†ฆ (p.1.2, p.2)) (by fun_prop) + +namespace Environment + +/-- In a stationary environment, the observation at every time has law `env.obsZero`. -/ +lemma obs_eq_const_obsZero (env : Environment ๐“ž ๐“ ๐“จ) [h : env.IsStationary] (n : โ„•) : + env.obs n = Kernel.const _ env.obsZero := by + obtain โŸจฮผ, -, hฮผโŸฉ := h.exists_obs_eq_const + rw [hฮผ n, obsZero_def, hฮผ 0, Kernel.const_apply] + +/-- In a stationary environment, the feedback at every time is drawn from `env.feedbackZero` applied +to the current observation and action. -/ +lemma feedback_eq_comap_feedbackZero (env : Environment ๐“ž ๐“ ๐“จ) [h : env.IsStationary] (n : โ„•) : + env.feedback n = env.feedbackZero.comap (fun p โ†ฆ (p.1.2, p.2)) (by fun_prop) := by + obtain โŸจฮฝ, -, hฮฝโŸฉ := h.exists_feedback_eq_comap + have hฮฝ0 : env.feedbackZero = ฮฝ := by + ext p : 1 + rw [feedbackZero_def, Kernel.comap_apply, hฮฝ 0, Kernel.comap_apply] + rw [hฮฝ n, hฮฝ0] + +instance (env : Environment ๐“ž ๐“ ๐“จ) [env.IsStationary] : env.IsOblivious where + exists_obs_eq_const := โŸจfun _ โ†ฆ env.obsZero, fun _ โ†ฆ inferInstance, env.obs_eq_const_obsZeroโŸฉ + exists_feedback_eq_comap := + โŸจfun _ โ†ฆ env.feedbackZero, fun _ โ†ฆ inferInstance, env.feedback_eq_comap_feedbackZeroโŸฉ + +/-- In a stationary environment, the law of the observation at time `n` is `env.obsZero`. -/ +lemma obsLaw_eq_obsZero (env : Environment ๐“ž ๐“ ๐“จ) [env.IsStationary] [Nonempty ๐“] [Nonempty ๐“จ] + (n : โ„•) : + env.obsLaw n = env.obsZero := + env.obsLaw_eq_of_obs_eq_const (env.obs_eq_const_obsZero n) + +/-- In a stationary environment, the conditional distribution of the feedback given the observation +and the action at time `n` is `env.feedbackZero`. -/ +lemma feedbackCondObsAction_eq_feedbackZero (env : Environment ๐“ž ๐“ ๐“จ) [env.IsStationary] + (n : โ„•) : + env.feedbackCondObsAction n = env.feedbackZero := + env.feedbackCondObsAction_eq_of_feedback_eq (env.feedback_eq_comap_feedbackZero n) + +end Environment + +namespace Environment.IsStationary + +variable {ฮฉ : Type*} {mฮฉ : MeasurableSpace ฮฉ} + {alg : Algorithm ๐“ž ๐“ ๐“จ} {env : Environment ๐“ž ๐“ ๐“จ} {P : Measure ฮฉ} + {O : โ„• โ†’ ฮฉ โ†’ ๐“ž} {A : โ„• โ†’ ฮฉ โ†’ ๐“} {Y : โ„• โ†’ ฮฉ โ†’ ๐“จ} -end IsObliviousEnv +/-- The observation at time `n` has law `env.obsZero`. -/ +lemma hasLaw_obs [IsProbabilityMeasure P] [env.IsStationary] + (h : IsAlgEnvSeq O A Y alg env P) (n : โ„•) : + HasLaw (O n) env.obsZero P := by + have h' := h.hasCondDistrib_obs n + rw [env.obs_eq_const_obsZero] at h' + exact h'.hasLaw_of_const + +variable [IsFiniteMeasure P] + +lemma hasCondDistrib_feedback_history_action [env.IsStationary] + (h : IsAlgEnvSeq O A Y alg env P) (n : โ„•) : + HasCondDistrib (Y n) (fun ฯ‰ โ†ฆ ((history O A Y n ฯ‰, O n ฯ‰), A n ฯ‰)) + (env.feedbackZero.comap (fun p โ†ฆ (p.1.2, p.2)) (by fun_prop) + : Kernel ((Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) ร— ๐“) ๐“จ) P := by + rw [โ† env.feedback_eq_comap_feedbackZero] + exact h.hasCondDistrib_feedback n + +/-- The conditional distribution of the feedback at time `n` given the observation and the action +at time `n` is `env.feedbackZero`. -/ +lemma hasCondDistrib_feedback [env.IsStationary] (h : IsAlgEnvSeq O A Y alg env P) (n : โ„•) : + HasCondDistrib (Y n) (fun ฯ‰ โ†ฆ (O n ฯ‰, A n ฯ‰)) env.feedbackZero P := + (hasCondDistrib_feedback_history_action h n).comp_right -/-- 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] +/-- Conditionally on an event determined by the history before time `n`, the observation and the +action at time `n`, on which the observation-action pair is equal to `b`, the feedback at time `n` +has law `env.feedbackZero b`. -/ +lemma hasLaw_feedback_cond [env.IsStationary] (h : IsAlgEnvSeq O A Y alg env P) (n : โ„•) + {s : Set ((Hist ๐“ž ๐“ ๐“จ n ร— ๐“ž) ร— ๐“)} (hs : MeasurableSet s) {b : ๐“ž ร— ๐“} + (hsb : โˆ€ u โˆˆ s, (u.1.2, u.2) = b) + (hP : P ((fun ฯ‰ โ†ฆ ((history O A Y n ฯ‰, O n ฯ‰), A n ฯ‰)) โปยน' s) โ‰  0) : + HasLaw (Y n) (env.feedbackZero b) + P[|(fun ฯ‰ โ†ฆ ((history O A Y n ฯ‰, O n ฯ‰), A n ฯ‰)) โปยน' s] := by + rw [โ† env.feedbackCondObsAction_eq_feedbackZero n] + exact IsOblivious.hasLaw_feedback_cond h n hs hsb hP + +end Environment.IsStationary + +section Oblivious + +variable {ฮผ : โ„• โ†’ Measure ๐“ž} [โˆ€ n, IsProbabilityMeasure (ฮผ n)] + {ฮฝ : โ„• โ†’ Kernel (๐“ž ร— ๐“) ๐“จ} [โˆ€ n, IsMarkovKernel (ฮฝ n)] + +/-- The oblivious environment in which the observation at time `n` has law `ฮผ n` and the feedback +at time `n` is drawn from `ฮฝ n` applied to the observation and the action at time `n`, whatever the +past history. -/ noncomputable -def obliviousEnv (ฮฝ : โ„• โ†’ Kernel ๐“ ๐“จ) [โˆ€ n, IsMarkovKernel (ฮฝ n)] : Environment Unit ๐“ ๐“จ where - obs _ := Kernel.const _ (Measure.dirac ()) - feedback n := (ฮฝ n).prodMkLeft _ +def Environment.oblivious (ฮผ : โ„• โ†’ Measure ๐“ž) [โˆ€ n, IsProbabilityMeasure (ฮผ n)] + (ฮฝ : โ„• โ†’ Kernel (๐“ž ร— ๐“) ๐“จ) [โˆ€ n, IsMarkovKernel (ฮฝ n)] : Environment ๐“ž ๐“ ๐“จ where + obs n := Kernel.const _ (ฮผ n) + feedback n := (ฮฝ n).comap (fun p โ†ฆ (p.1.2, p.2)) (by fun_prop) + +@[simp] +lemma obs_oblivious (n : โ„•) : (Environment.oblivious ฮผ ฮฝ).obs n = Kernel.const _ (ฮผ n) := rfl -lemma feedback_obliviousEnv (ฮฝ : โ„• โ†’ Kernel ๐“ ๐“จ) [โˆ€ n, IsMarkovKernel (ฮฝ n)] (n : โ„•) : - (obliviousEnv ฮฝ).feedback n = (ฮฝ n).prodMkLeft _ := rfl +@[simp] +lemma feedback_oblivious (n : โ„•) : + (Environment.oblivious ฮผ ฮฝ).feedback n = (ฮฝ n).comap (fun p โ†ฆ (p.1.2, p.2)) (by fun_prop) := rfl @[simp] -lemma obs0_obliviousEnv (ฮฝ : โ„• โ†’ Kernel ๐“ ๐“จ) [โˆ€ n, IsMarkovKernel (ฮฝ n)] : - (obliviousEnv ฮฝ).obs0 = Measure.dirac () := rfl +lemma obsZero_oblivious : (Environment.oblivious ฮผ ฮฝ).obsZero = ฮผ 0 := rfl @[simp] -lemma ฮฝ0_obliviousEnv (ฮฝ : โ„• โ†’ Kernel ๐“ ๐“จ) [โˆ€ n, IsMarkovKernel (ฮฝ n)] : - (obliviousEnv ฮฝ).ฮฝ0 = (ฮฝ 0).prodMkLeft Unit := by +lemma feedbackZero_oblivious : (Environment.oblivious ฮผ ฮฝ).feedbackZero = ฮฝ 0 := by ext p : 1 - rw [Environment.ฮฝ0_def, Kernel.comap_apply, feedback_obliviousEnv, Kernel.prodMkLeft_apply, - Kernel.prodMkLeft_apply] + rw [Environment.feedbackZero_def, Kernel.comap_apply, feedback_oblivious, Kernel.comap_apply] -instance (ฮฝ : โ„• โ†’ Kernel ๐“ ๐“จ) [โˆ€ n, IsMarkovKernel (ฮฝ n)] : - IsObliviousEnv (obliviousEnv ฮฝ) where - exists_eq_prodMkLeft := โŸจฮฝ, inferInstance, fun _ โ†ฆ rflโŸฉ +lemma stepKernel_oblivious (alg : Algorithm ๐“ž ๐“ ๐“จ) (n : โ„•) : + stepKernel alg (Environment.oblivious ฮผ ฮฝ) n + = Kernel.const _ (ฮผ n) + โŠ—โ‚– (alg.policy n โŠ—โ‚– (ฮฝ n).comap (fun p โ†ฆ (p.1.2, p.2)) (by fun_prop)) := + rfl +instance : (Environment.oblivious ฮผ ฮฝ).IsOblivious where + exists_obs_eq_const := โŸจฮผ, inferInstance, fun _ โ†ฆ rflโŸฉ + exists_feedback_eq_comap := โŸจฮฝ, inferInstance, fun _ โ†ฆ rflโŸฉ + +/-- The law of the observations of `Environment.oblivious ฮผ ฮฝ` is `ฮผ`. The nonemptiness assumptions +ensure that there are histories of every length, so that the observation kernels determine `ฮผ`. -/ @[simp] -lemma feedbackCondAction_obliviousEnv (ฮฝ : โ„• โ†’ Kernel ๐“ ๐“จ) [hฮฝ : โˆ€ n, IsMarkovKernel (ฮฝ n)] - (n : โ„•) : - feedbackCondAction (obliviousEnv ฮฝ) n = ฮฝ n := by - rcases isEmpty_or_nonempty ๐“ with h๐“ | h๐“ - ยท ext a : 1 - exact h๐“.elim a - rcases isEmpty_or_nonempty ๐“จ with hR | hR - ยท refine absurd (hฮฝ 0) ?_ - simp only [Subsingleton.eq_zero ฮฝ, Pi.zero_apply] - exact Kernel.not_isMarkovKernel_zero - 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 +lemma obsLaw_oblivious [Nonempty ๐“] [Nonempty ๐“จ] (n : โ„•) : + (Environment.oblivious ฮผ ฮฝ).obsLaw n = ฮผ n := + Environment.obsLaw_eq_of_obs_eq_const _ rfl + +@[simp] +lemma feedbackCondObsAction_oblivious (n : โ„•) : + (Environment.oblivious ฮผ ฮฝ).feedbackCondObsAction n = ฮฝ n := + Environment.feedbackCondObsAction_eq_of_feedback_eq _ rfl -/-- A stationary environment without observations, in which the distribution of the next feedback -depends only on the last action. -/ +end Oblivious + +section Stationary + +variable {ฮผ : Measure ๐“ž} [IsProbabilityMeasure ฮผ] {ฮฝ : Kernel (๐“ž ร— ๐“) ๐“จ} [IsMarkovKernel ฮฝ] + +/-- The stationary environment in which the observations have law `ฮผ` and the feedback is drawn +from `ฮฝ` applied to the observation and the action, whatever the past history. -/ noncomputable -def stationaryEnv (ฮฝ : Kernel ๐“ ๐“จ) [IsMarkovKernel ฮฝ] : Environment Unit ๐“ ๐“จ := - obliviousEnv fun _ โ†ฆ ฮฝ +def Environment.stationary (ฮผ : Measure ๐“ž) [IsProbabilityMeasure ฮผ] (ฮฝ : Kernel (๐“ž ร— ๐“) ๐“จ) + [IsMarkovKernel ฮฝ] : Environment ๐“ž ๐“ ๐“จ := + Environment.oblivious (fun _ โ†ฆ ฮผ) (fun _ โ†ฆ ฮฝ) + +lemma Environment.stationary_def : + Environment.stationary ฮผ ฮฝ = Environment.oblivious (fun _ โ†ฆ ฮผ) (fun _ โ†ฆ ฮฝ) := rfl @[simp] -lemma obs_stationaryEnv (ฮฝ : Kernel ๐“ ๐“จ) [IsMarkovKernel ฮฝ] (n : โ„•) : - (stationaryEnv ฮฝ).obs n = Kernel.const _ (Measure.dirac ()) := rfl +lemma obs_stationary (n : โ„•) : (Environment.stationary ฮผ ฮฝ).obs n = Kernel.const _ ฮผ := rfl @[simp] -lemma feedback_stationaryEnv (ฮฝ : Kernel ๐“ ๐“จ) [IsMarkovKernel ฮฝ] (n : โ„•) : - (stationaryEnv ฮฝ).feedback n = ฮฝ.prodMkLeft _ := rfl +lemma feedback_stationary (n : โ„•) : + (Environment.stationary ฮผ ฮฝ).feedback n = ฮฝ.comap (fun p โ†ฆ (p.1.2, p.2)) (by fun_prop) := rfl -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 obsZero_stationary : (Environment.stationary ฮผ ฮฝ).obsZero = ฮผ := rfl + +@[simp] +lemma feedbackZero_stationary : (Environment.stationary ฮผ ฮฝ).feedbackZero = ฮฝ := + feedbackZero_oblivious + +lemma stepKernel_stationary (alg : Algorithm ๐“ž ๐“ ๐“จ) (n : โ„•) : + stepKernel alg (Environment.stationary ฮผ ฮฝ) n + = Kernel.const _ ฮผ โŠ—โ‚– (alg.policy n โŠ—โ‚– ฮฝ.comap (fun p โ†ฆ (p.1.2, p.2)) (by fun_prop)) := + rfl + +instance : (Environment.stationary ฮผ ฮฝ).IsStationary where + exists_obs_eq_const := โŸจฮผ, inferInstance, fun _ โ†ฆ rflโŸฉ + exists_feedback_eq_comap := โŸจฮฝ, inferInstance, fun _ โ†ฆ rflโŸฉ + +instance : (Environment.stationary ฮผ ฮฝ).IsOblivious := + inferInstanceAs (Environment.oblivious _ _).IsOblivious + +@[simp] +lemma obsLaw_stationary [Nonempty ๐“] [Nonempty ๐“จ] (n : โ„•) : + (Environment.stationary ฮผ ฮฝ).obsLaw n = ฮผ := + obsLaw_oblivious n + +@[simp] +lemma feedbackCondObsAction_stationary (n : โ„•) : + (Environment.stationary ฮผ ฮฝ).feedbackCondObsAction n = ฮฝ := + feedbackCondObsAction_oblivious n + +end Stationary + +section BanditSeq + +variable {ฮฝ : โ„• โ†’ Kernel ๐“ ๐“จ} [โˆ€ n, IsMarkovKernel (ฮฝ n)] + +/-- The oblivious environment without observations in which the feedback at time `n` is drawn from +`ฮฝ n` applied to the action at time `n`, whatever the past history. -/ +noncomputable +def Environment.banditSeq (ฮฝ : โ„• โ†’ Kernel ๐“ ๐“จ) [โˆ€ n, IsMarkovKernel (ฮฝ n)] : + Environment Unit ๐“ ๐“จ := + Environment.oblivious (fun _ โ†ฆ Measure.dirac ()) (fun n โ†ฆ (ฮฝ n).prodMkLeft Unit) + +lemma Environment.banditSeq_def : + Environment.banditSeq ฮฝ + = Environment.oblivious (fun _ โ†ฆ Measure.dirac ()) (fun n โ†ฆ (ฮฝ n).prodMkLeft Unit) := + rfl + +@[simp] +lemma obs_banditSeq (n : โ„•) : + (Environment.banditSeq ฮฝ).obs n = Kernel.const _ (Measure.dirac ()) := rfl + +@[simp] +lemma feedback_banditSeq (n : โ„•) : (Environment.banditSeq ฮฝ).feedback n = (ฮฝ n).prodMkLeft _ := rfl + +@[simp] +lemma obsZero_banditSeq : (Environment.banditSeq ฮฝ).obsZero = Measure.dirac () := rfl + +@[simp] +lemma feedbackZero_banditSeq : (Environment.banditSeq ฮฝ).feedbackZero = (ฮฝ 0).prodMkLeft Unit := + feedbackZero_oblivious + +instance : (Environment.banditSeq ฮฝ).IsOblivious := + inferInstanceAs (Environment.oblivious _ _).IsOblivious + +@[simp] +lemma obsLaw_banditSeq (n : โ„•) : (Environment.banditSeq ฮฝ).obsLaw n = Measure.dirac () := + Measure.eq_dirac_unit _ + +@[simp] +lemma feedbackCondObsAction_banditSeq (n : โ„•) : + (Environment.banditSeq ฮฝ).feedbackCondObsAction n = (ฮฝ n).prodMkLeft Unit := + feedbackCondObsAction_oblivious n + +end BanditSeq + +section Bandit + +variable {ฮฝ : Kernel ๐“ ๐“จ} [IsMarkovKernel ฮฝ] + +/-- The stationary environment without observations in which the feedback is drawn from `ฮฝ` +applied to the action, whatever the past history: a stochastic bandit. -/ +noncomputable +def Environment.bandit (ฮฝ : Kernel ๐“ ๐“จ) [IsMarkovKernel ฮฝ] : Environment Unit ๐“ ๐“จ := + Environment.stationary (Measure.dirac ()) (ฮฝ.prodMkLeft Unit) + +lemma Environment.bandit_def : + Environment.bandit ฮฝ = Environment.stationary (Measure.dirac ()) (ฮฝ.prodMkLeft Unit) := rfl + +lemma Environment.bandit_eq_banditSeq : Environment.bandit ฮฝ = Environment.banditSeq fun _ โ†ฆ ฮฝ := + rfl @[simp] -lemma obs0_stationaryEnv (ฮฝ : Kernel ๐“ ๐“จ) [IsMarkovKernel ฮฝ] : - (stationaryEnv ฮฝ).obs0 = Measure.dirac () := rfl +lemma obs_bandit (n : โ„•) : (Environment.bandit ฮฝ).obs n = Kernel.const _ (Measure.dirac ()) := rfl @[simp] -lemma ฮฝ0_stationaryEnv (ฮฝ : Kernel ๐“ ๐“จ) [IsMarkovKernel ฮฝ] : - (stationaryEnv ฮฝ).ฮฝ0 = ฮฝ.prodMkLeft Unit := - ฮฝ0_obliviousEnv _ +lemma feedback_bandit (n : โ„•) : (Environment.bandit ฮฝ).feedback n = ฮฝ.prodMkLeft _ := rfl -instance (ฮฝ : Kernel ๐“ ๐“จ) [IsMarkovKernel ฮฝ] : IsObliviousEnv (stationaryEnv ฮฝ) where - exists_eq_prodMkLeft := โŸจfun _ โ†ฆ ฮฝ, inferInstance, fun _ โ†ฆ rflโŸฉ +lemma stepKernel_bandit (alg : Algorithm Unit ๐“ ๐“จ) (n : โ„•) : + stepKernel alg (Environment.bandit ฮฝ) n + = Kernel.const _ (Measure.dirac ()) โŠ—โ‚– (alg.policy n โŠ—โ‚– ฮฝ.prodMkLeft _) := by + rw [stepKernel_def, obs_bandit, feedback_bandit] @[simp] -lemma feedbackCondAction_stationaryEnv (ฮฝ : Kernel ๐“ ๐“จ) [hฮฝ : IsMarkovKernel ฮฝ] (n : โ„•) : - feedbackCondAction (stationaryEnv ฮฝ) n = ฮฝ := feedbackCondAction_obliviousEnv _ _ +lemma obsZero_bandit : (Environment.bandit ฮฝ).obsZero = Measure.dirac () := rfl + +@[simp] +lemma feedbackZero_bandit : (Environment.bandit ฮฝ).feedbackZero = ฮฝ.prodMkLeft Unit := + feedbackZero_oblivious + +instance : (Environment.bandit ฮฝ).IsStationary := + inferInstanceAs (Environment.stationary _ _).IsStationary + +instance : (Environment.bandit ฮฝ).IsOblivious := + inferInstanceAs (Environment.oblivious _ _).IsOblivious + +@[simp] +lemma obsLaw_bandit (n : โ„•) : (Environment.bandit ฮฝ).obsLaw n = Measure.dirac () := + Measure.eq_dirac_unit _ + +@[simp] +lemma feedbackCondObsAction_bandit (n : โ„•) : + (Environment.bandit ฮฝ).feedbackCondObsAction n = ฮฝ.prodMkLeft Unit := + feedbackCondObsAction_oblivious n + +end Bandit + +namespace IsAlgEnvSeq + +section General + +variable {ฮฉ : Type*} {mฮฉ : MeasurableSpace ฮฉ} {alg : Algorithm ๐“ž ๐“ ๐“จ} + {P : Measure ฮฉ} [IsProbabilityMeasure P] + {O : โ„• โ†’ ฮฉ โ†’ ๐“ž} {A : โ„• โ†’ ฮฉ โ†’ ๐“} {Y : โ„• โ†’ ฮฉ โ†’ ๐“จ} + +/-- The observation at time `n` has law `ฮผ n`. -/ +lemma hasLaw_obs_oblivious {ฮผ : โ„• โ†’ Measure ๐“ž} [โˆ€ n, IsProbabilityMeasure (ฮผ n)] + {ฮฝ : โ„• โ†’ Kernel (๐“ž ร— ๐“) ๐“จ} [โˆ€ n, IsMarkovKernel (ฮฝ n)] + (h : IsAlgEnvSeq O A Y alg (Environment.oblivious ฮผ ฮฝ) P) (n : โ„•) : + HasLaw (O n) (ฮผ n) P := by + have h' := h.hasCondDistrib_obs n + rw [obs_oblivious] at h' + exact h'.hasLaw_of_const + +/-- The conditional distribution of the feedback at time `n` given the observation and the action +at time `n` is `ฮฝ n`. -/ +lemma hasCondDistrib_feedback_oblivious {ฮผ : โ„• โ†’ Measure ๐“ž} [โˆ€ n, IsProbabilityMeasure (ฮผ n)] + {ฮฝ : โ„• โ†’ Kernel (๐“ž ร— ๐“) ๐“จ} [โˆ€ n, IsMarkovKernel (ฮฝ n)] + (h : IsAlgEnvSeq O A Y alg (Environment.oblivious ฮผ ฮฝ) P) (n : โ„•) : + HasCondDistrib (Y n) (fun ฯ‰ โ†ฆ (O n ฯ‰, A n ฯ‰)) (ฮฝ n) P := by + have h' := h.hasCondDistrib_feedback n + rw [feedback_oblivious] at h' + exact h'.comp_right + +/-- The observation at time `n` has law `ฮผ`. -/ +lemma hasLaw_obs_stationary {ฮผ : Measure ๐“ž} [IsProbabilityMeasure ฮผ] + {ฮฝ : Kernel (๐“ž ร— ๐“) ๐“จ} [IsMarkovKernel ฮฝ] + (h : IsAlgEnvSeq O A Y alg (Environment.stationary ฮผ ฮฝ) P) (n : โ„•) : + HasLaw (O n) ฮผ P := + hasLaw_obs_oblivious h n + +/-- The conditional distribution of the feedback at time `n` given the observation and the action +at time `n` is `ฮฝ`. -/ +lemma hasCondDistrib_feedback_stationary {ฮผ : Measure ๐“ž} [IsProbabilityMeasure ฮผ] + {ฮฝ : Kernel (๐“ž ร— ๐“) ๐“จ} [IsMarkovKernel ฮฝ] + (h : IsAlgEnvSeq O A Y alg (Environment.stationary ฮผ ฮฝ) P) (n : โ„•) : + HasCondDistrib (Y n) (fun ฯ‰ โ†ฆ (O n ฯ‰, A n ฯ‰)) ฮฝ P := + hasCondDistrib_feedback_oblivious h n + +end General + +section Bandit variable {ฮฉ : Type*} {mฮฉ : MeasurableSpace ฮฉ} {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 O A Y alg (obliviousEnv ฮฝ) P) (n : โ„•) : +lemma hasCondDistrib_feedback_banditSeq {ฮฝ : โ„• โ†’ Kernel ๐“ ๐“จ} [โˆ€ n, IsMarkovKernel (ฮฝ n)] + (h : IsAlgEnvSeq O A Y alg (Environment.banditSeq ฮฝ) P) (n : โ„•) : HasCondDistrib (Y n) (A n) (ฮฝ n) P := by - simpa using IsObliviousEnv.hasCondDistrib_feedback h n + have h' : HasCondDistrib (Y n) (fun ฯ‰ โ†ฆ (O n ฯ‰, A n ฯ‰)) ((ฮฝ n).prodMkLeft Unit) P := + hasCondDistrib_feedback_oblivious h n + exact h'.comp_right /-- The conditional distribution of the feedback at time `n` given the action at time `n` is `ฮฝ`. -/ -lemma hasCondDistrib_feedback_stationaryEnv - (h : IsAlgEnvSeq O A Y alg (stationaryEnv ฮฝ) P) (n : โ„•) : +lemma hasCondDistrib_feedback_bandit + (h : IsAlgEnvSeq O A Y alg (Environment.bandit ฮฝ) P) (n : โ„•) : HasCondDistrib (Y n) (A n) ฮฝ P := - hasCondDistrib_feedback_obliviousEnv h n + hasCondDistrib_feedback_banditSeq 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 O A Y alg (stationaryEnv ฮฝ) P) (n : โ„•) : +lemma condDistrib_feedback_bandit [StandardBorelSpace ๐“จ] [Nonempty ๐“จ] + (h : IsAlgEnvSeq O A Y alg (Environment.bandit ฮฝ) P) (n : โ„•) : condDistrib (Y n) (A n) P =แต[P.map (A n)] ฮฝ := - (hasCondDistrib_feedback_stationaryEnv h n).condDistrib_eq + (hasCondDistrib_feedback_bandit h n).condDistrib_eq /-- 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 O A Y alg (stationaryEnv ฮฝ) P) (n : โ„•) +lemma hasLaw_feedback_cond_bandit (h : IsAlgEnvSeq O A Y alg (Environment.bandit ฮฝ) 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 + simpa using Environment.IsOblivious.hasLaw_feedback_cond h n hs (b := ((), b)) + (fun u hu โ†ฆ by simp [hsb u hu]) 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 O A Y alg (stationaryEnv ฮฝ) P) (n : โ„•) +lemma indepFun_history_action_feedback_cond_bandit + (h : IsAlgEnvSeq O A Y alg (Environment.bandit ฮฝ) 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 + Environment.IsOblivious.indepFun_history_action_feedback_cond h n hs (b := ((), b)) + fun u hu โ†ฆ by simp [hsb u hu] /-- The feedback at time `n` is conditionally independent of the history before time `n` given the action at time `n`. -/ -lemma condIndepFun_feedback_history_action [StandardBorelSpace ฮฉ] +lemma condIndepFun_feedback_history_action_bandit [StandardBorelSpace ฮฉ] [StandardBorelSpace ๐“] [Nonempty ๐“] [StandardBorelSpace ๐“จ] [Nonempty ๐“จ] - (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 + (h : IsAlgEnvSeq O A Y alg (Environment.bandit ฮฝ) 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 (ฮท := ฮฝ) + (by fun_prop) (by fun_prop) (by fun_prop) ?_ + refine HasCondDistrib.condDistrib_eq ?_ + have h' := h.hasCondDistrib_feedback n + rwa [feedback_bandit] at h' -lemma condIndepFun_feedback_history_action_action [StandardBorelSpace ฮฉ] +lemma condIndepFun_feedback_history_action_action_bandit [StandardBorelSpace ฮฉ] [StandardBorelSpace ๐“] [Nonempty ๐“] [StandardBorelSpace ๐“จ] [Nonempty ๐“จ] - (h : IsAlgEnvSeq O A Y alg (stationaryEnv ฮฝ) P) (n : โ„•) : + (h : IsAlgEnvSeq O A Y alg (Environment.bandit ฮฝ) 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 + (fun ฯ‰ โ†ฆ ((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 (condIndepFun_feedback_history_action_bandit h n).prod_right (by fun_prop) (by fun_prop) + (by fun_prop) + +end Bandit end IsAlgEnvSeq