Theory Code_Setup
theory Code_Setup
imports
"HOL-Library.IArray"
"HOL-Data_Structures.Array_Braun"
"HOL-Data_Structures.RBT_Map"
"../MDP_fin"
"../Value_Iteration"
"./lib/DiffArray_ST"
begin
context MDP_nat_disc begin
lemma L_zero:
assumes "⋀s. s ≥ states ⟹ apply_bfun v s = 0" "s ≥ states"
shows "L d v s = 0"
using assms
proof (induction s rule: less_induct)
case (less x)
moreover have "r (x, a) = 0" if "a ∈ A x" for a
by (simp add: less.prems reward_zero_outside)
moreover have "measure_pmf.expectation (K (x, a)) v = 0" for a
using K_closed_compl assms less
by (blast intro: integral_eq_zero_AE AE_pmfI)
ultimately show ?case
by (auto simp: A_ne A_fin L_eq_L⇩a reward_zero_outside)
qed
lemma ℒ⇩b_zero:
assumes "⋀s. s ≥ states ⟹ apply_bfun v s = 0" "s ≥ states"
shows "ℒ⇩b v s = 0"
using assms
proof (induction s rule: less_induct)
case (less x)
have "r (x, a) = 0" if "a ∈ A x" for a
by (simp add: less.prems reward_zero_outside)
moreover have "measure_pmf.expectation (K (x, a)) v = 0" for a
using K_closed_compl assms less
by (blast intro: integral_eq_zero_AE AE_pmfI)
ultimately show ?case
by (auto simp: A_ne A_fin ℒ⇩b_eq_L⇩a_max')
qed
end
lemma max_geI: "finite A ⟹ A ≠ {} ⟹ (∃a∈A. x ≤ a) ⟹ (x ≤ Max A)" for x A
by (simp add: Max_ge_iff)
section ‹Least argmax›
fun "least_arg_max_max_ne" where
"least_arg_max_max_ne f (x#xs) =
(fold (λy (am, m). let fy = f y in
if m < fy then (y, fy) else (am, m)) xs (x, f x))" |
"least_arg_max_max_ne a [] = undefined"
fun "least_arg_max_ne" where
"least_arg_max_ne f (x#xs) = fst (least_arg_max_max_ne f (x#xs))" |
"least_arg_max_ne a [] = undefined"
lemmas
least_arg_max_ne.simps[simp del]
least_arg_max_max_ne.simps[simp del]
lemma least_arg_max_max_ne_Cons: "least_arg_max_max_ne f (x#y#xs) =
(if f x < f y then least_arg_max_max_ne f (y#xs) else least_arg_max_max_ne f (x#xs))"
by (auto simp: least_arg_max_max_ne.simps)
lemma least_arg_max_max_ne_Cons1: "f x < f y ⟹ least_arg_max_max_ne f (x#y#xs) = least_arg_max_max_ne f (y#xs)"
by (auto simp: least_arg_max_max_ne.simps)
lemma least_arg_max_max_ne_Cons2: "¬ f x < f y ⟹ least_arg_max_max_ne f (x#y#xs) = least_arg_max_max_ne f (x#xs)"
by (auto simp: least_arg_max_max_ne.simps)
lemma Max_insert_absorb: "finite X ⟹ (∃y ∈ X. x ≤ y) ⟹ Max (Set.insert x X) = (if X = {} then x else Max X)"
by (simp add: Max_ge_iff)
lemma Max_insert_absorb': "finite X ⟹ y∈X ⟹ x ≤ y ⟹ Max (Set.insert x X) = (if X = {} then x else Max X)"
using Max_insert_absorb
by blast
lemma fold_max_eq_arg_max:
assumes "sorted (x#xs)"
shows "least_arg_max_max_ne f (x#xs) = (least_arg_max f (List.member (x#xs)), Max (f ` set (x#xs)))"
using assms
proof (induction xs arbitrary: x)
case Nil
then show ?case
by (auto simp: List.member_def least_arg_max_def least_arg_max_max_ne.simps is_arg_max_def intro!: Least_equality[symmetric])
next
case (Cons a xs)
then show ?case
proof (cases "is_arg_max f (List.member (x#a#xs)) x")
case True
have 1: "least_arg_max f (List.member (x#a#xs)) = x"
using True Cons
unfolding least_arg_max_def
by (fastforce intro!: Least_equality simp: in_set_member[symmetric])
have 2: "Max (f ` set (x#a#xs)) = f x"
using True unfolding is_arg_max_def
by (subst Max_eq_iff) (auto simp add: not_less in_set_member member_rec(1))
show ?thesis
unfolding 1 2
using True
by (induction xs) (auto simp: least_arg_max_max_ne.simps simp: is_arg_max_linorder member_rec)+
next
case False
have "is_arg_max f (List.member (x#a#xs)) = is_arg_max f (List.member (a#xs))"
using False by (fastforce simp: least_arg_max_max_ne.simps is_arg_max_linorder member_rec)
hence 1: "least_arg_max f (List.member (x#a#xs)) = least_arg_max f (List.member (a#xs))"
using Cons False unfolding least_arg_max_def by auto
have "f a ≤ f x ⟹ is_arg_max f (List.member (x#xs)) = is_arg_max f (List.member xs)"
using False by (fastforce simp: is_arg_max_linorder member_rec)
hence 4: "f a ≤ f x ⟹ least_arg_max f (List.member (x#xs)) = least_arg_max f (List.member xs)"
using Cons False unfolding least_arg_max_def by auto
have "f a ≤ f x ⟹ is_arg_max f (List.member (a#xs)) = is_arg_max f (List.member xs)"
using False by (fastforce simp: is_arg_max_linorder member_rec(1))
hence 3: "f a ≤ f x ⟹ least_arg_max f (List.member (a#xs)) = least_arg_max f (List.member xs)"
using Cons False unfolding least_arg_max_def by auto
have 2: "Max (f`set (x#a#xs)) = Max (f`set (a#xs))"
using False
by (fastforce simp: nle_le in_set_member is_arg_max_linorder Max_ge_iff simp: member_rec intro!: max_absorb2 )
have 5: "Max (f`set (a#xs)) = Max (f`set (xs)) ∧ Max (f`set (x#xs)) = Max (f`set (xs))" if "f a ≤ f x"
using False that
by (cases "xs = []") (auto simp: nle_le is_arg_max_linorder in_set_member[symmetric] intro: order.trans intro!:max_absorb2)
show ?thesis
unfolding least_arg_max_max_ne_Cons 1 2 using Cons 5 3 4 by auto
qed
qed
lemma least_arg_max_ne_correct:
assumes "sorted (x#xs)"
shows "least_arg_max_ne (f :: _ ⇒ 'b ::linorder) (x#xs) = least_arg_max f (List.member (x#xs))"
using assms
by (auto simp: fold_max_eq_arg_max least_arg_max_ne.simps)
lemma least_arg_max_ne_cong:
assumes "⋀x. x ∈ set xs ⟹ g x = f x"
shows "least_arg_max_max_ne f xs = least_arg_max_max_ne g xs"
proof (cases xs)
case Nil
then show ?thesis
by (metis least_arg_max_max_ne.elims list.discI)
next
case (Cons a list)
then show ?thesis
using assms
by (auto simp: least_arg_max_max_ne.simps intro!: List.fold_cong)
qed
lemma least_arg_max_max_ne_app:
assumes "⋀y. y ∈ set (x#xs) ⟹ f' (g y) = (f y)"
shows "(case (least_arg_max_max_ne f (x#xs)) of (a, m) ⇒ (g a, m)) = least_arg_max_max_ne f' (map g (x#xs))"
using assms
proof (induction xs arbitrary: x)
case Nil
then show ?case
by (auto simp: least_arg_max_max_ne.simps)
next
case (Cons a xs)
thus ?case
by (cases "f x < f a") (auto simp: least_arg_max_max_ne_Cons1 least_arg_max_max_ne_Cons2)
qed
lemma least_arg_max_max_ne_app':
assumes "⋀y. y ∈ set xs ⟹ f' (g y) = (f y)" "xs ≠ []"
shows "(case (least_arg_max_max_ne f xs) of (a, m) ⇒ (g a, m)) = least_arg_max_max_ne f' (map g xs)"
using assms
by (cases xs) (auto intro!: least_arg_max_max_ne_app[simplified])
lemma fold_max_eq_arg_max': "xs ≠ [] ⟹ sorted xs ⟹ least_arg_max_max_ne f xs = (least_arg_max f (List.member xs), Max (f ` set xs))"
using fold_max_eq_arg_max by (metis list.exhaust)
lemma least_arg_max_cong: "(⋀x. P x ⟹ f x = g x) ⟹ least_arg_max f P = least_arg_max g P"
unfolding least_arg_max_def using is_arg_max_cong' by metis
lemma least_arg_max_cong': "P = Q ⟹ (⋀x. P x ⟹ f x = g x) ⟹ least_arg_max f P = least_arg_max g Q"
unfolding least_arg_max_def using is_arg_max_cong' by metis
section ‹Congruence rule for fold›
lemma fold_cong':
assumes "(⋀x acc. P acc ⟹ x ∈ set xs ⟹ f x acc = g x acc ∧ P (f x acc))" "P a"
shows "fold f xs a = fold g xs a"
using assms
proof (induction xs arbitrary: a)
case (Cons a xs y)
show ?case
using Cons(2)[OF Cons(3), of a]
by (auto intro!: Cons(2) intro: Cons.IH)
qed auto
section ‹MDP type›