Theory PCTL
theory PCTL
imports
  "../Discrete_Time_Markov_Chain"
  "Gauss-Jordan-Elim-Fun.Gauss_Jordan_Elim_Fun"
  "HOL-Library.While_Combinator"
  "HOL-Library.Monad_Syntax"
begin
section ‹Adapt Gauss-Jordan elimination to DTMCs›
locale Finite_DTMC =
  fixes K :: "'s ⇒ 's pmf" and S :: "'s set" and ρ :: "'s ⇒ real" and ι :: "'s ⇒ 's ⇒ real"
  assumes ι_nonneg[simp]: "⋀s t. 0 ≤ ι s t" and ρ_nonneg[simp]: "⋀s. 0 ≤ ρ s"
  assumes measurable_ι: "(λ(a, b). ι a b) ∈ borel_measurable (count_space UNIV ⨂⇩M count_space UNIV)"
  assumes finite_S[simp]: "finite S" and S_not_empty: "S ≠ {}"
  assumes E_closed: "(⋃s∈S. set_pmf (K s)) ⊆ S"
begin
lemma measurable_ι'[measurable (raw)]:
  "f ∈ measurable M (count_space UNIV) ⟹ g ∈ measurable M (count_space UNIV) ⟹
    (λx. ι (f x) (g x)) ∈ borel_measurable M"
  using measurable_compose[OF _ measurable_ι, of "λx. (f x, g x)" M] by simp
lemma measurable_ρ[measurable]: "ρ ∈ borel_measurable (count_space UNIV)"
  by simp
sublocale R?: MC_with_rewards K ι ρ
  by standard (auto intro: ι_nonneg ρ_nonneg)
lemma single_l:
  fixes s and x :: real assumes "s ∈ S"
  shows "(∑s'∈S. (if s' = s then 1 else 0) * l s') = x ⟷ l s = x"
  by (simp add: assms if_distrib [of "λx. x * a" for a] cong: if_cong)
definition "order = (SOME f. bij_betw f {..< card S} S)"
lemma
  shows bij_order[simp]: "bij_betw order {..< card S} S"
    and inj_order[simp]: "inj_on order {..<card S}"
    and image_order[simp]: "order ` {..<card S} = S"
    and order_S[simp, intro]: "⋀i. i < card S ⟹ order i ∈ S"
proof -
  from finite_same_card_bij[OF _ finite_S] show "bij_betw order {..< card S} S"
    unfolding order_def by (rule someI_ex) auto
  then show "inj_on order {..<card S}" "order ` {..<card S} = S"
    unfolding bij_betw_def by auto
  then show "⋀i. i < card S ⟹ order i ∈ S"
    by auto
qed
lemma order_Ex:
  assumes "s ∈ S" obtains i where "i < card S" "s = order i"
proof -
  from ‹s ∈ S› have "s ∈ order ` {..<card S}"
    by simp
  with that show thesis
    by (auto simp del: image_order)
qed
definition "iorder = the_inv_into {..<card S} order"
lemma bij_iorder: "bij_betw iorder S {..<card S}"
  unfolding iorder_def by (rule bij_betw_the_inv_into bij_order)+
lemma iorder_image_eq: "iorder ` S = {..<card S}"
  and inj_iorder: "inj_on iorder S"
  using bij_iorder  unfolding bij_betw_def by auto
lemma order_iorder: "⋀s. s ∈ S ⟹ order (iorder s) = s"
  unfolding iorder_def using bij_order
  by (intro f_the_inv_into_f) (auto simp: bij_betw_def)
definition gauss_jordan' :: "('s ⇒ 's ⇒ real) ⇒ ('s ⇒ real) ⇒ ('s ⇒ real) option" where
  "gauss_jordan' M a = do {
     let M' = (λi j. if j = card S then a (order i) else M (order i) (order j)) ;
     sol ← gauss_jordan M' (card S) ;
     Some (λi. sol (iorder i) (card S))
  }"
lemma gauss_jordan'_correct:
  assumes "gauss_jordan' M a = Some f"
  shows "∀s∈S. (∑s'∈S. M s s' * f s') = a s"
proof -
  note ‹gauss_jordan' M a = Some f›
  moreover define M' where "M' = (λi j. if j = card S then
    a (order i) else M (order i) (order j))"
  ultimately obtain sol where sol: "gauss_jordan M' (card S) = Some sol"
    and f: "f = (λi. sol (iorder i) (card S))"
    by (auto simp: gauss_jordan'_def Let_def split: bind_split_asm)
  from gauss_jordan_correct[OF sol]
  have "∀i∈{..<card S}. (∑j<card S. M (order i) (order j) * sol j (card S)) = a (order i)"
    unfolding solution_def M'_def by (simp add: atLeast0LessThan)
  then show ?thesis
    unfolding iorder_image_eq[symmetric] f using inj_iorder
    by (subst (asm) sum.reindex) (auto simp: order_iorder)
qed
lemma gauss_jordan'_complete:
  assumes exists: "∀s∈S. (∑s'∈S. M s s' * x s') = a s"
  assumes unique: "⋀y. ∀s∈S. (∑s'∈S. M s s' * y s') = a s ⟹ ∀s∈S. y s = x s"
  shows "∃y. gauss_jordan' M a = Some y"
proof -
  define M' where "M' = (λi j. if j = card S then
    a (order i) else M (order i) (order j))"
  { fix x
    have iorder_neq_card_S: "⋀s. s ∈ S ⟹ iorder s ≠ card S"
      using iorder_image_eq by (auto simp: set_eq_iff less_le)
    have "solution2 M' (card S) (card S) x ⟷
      (∀s∈{..<card S}. (∑s'∈{..<card S}. M' s s' * x s') = M' s (card S))"
      unfolding solution2_def by (auto simp: atLeast0LessThan)
    also have "… ⟷ (∀s∈S. (∑s'∈S. M s s' * x (iorder s')) = a s)"
      unfolding iorder_image_eq[symmetric] M'_def
      using inj_iorder iorder_neq_card_S
      by (simp add: sum.reindex order_iorder)
    finally have "solution2 M' (card S) (card S) x ⟷
      (∀s∈S. (∑s'∈S. M s s' * x (iorder s')) = a s)" . }
  note sol2_eq = this
  have "usolution M' (card S) (card S) (λi. x (order i))"
    unfolding usolution_def
  proof safe
    from exists show "solution2 M' (card S) (card S) (λi. x (order i))"
      by (simp add: sol2_eq order_iorder)
  next
    fix y j assume y: "solution2 M' (card S) (card S) y" and "j < card S"
    then have "∀s∈S. (∑s'∈S. M s s' * y (iorder s')) = a s"
      by (simp add: sol2_eq)
    from unique[OF this]
    have "∀i∈{..<card S}. y i = x (order i)"
      unfolding iorder_image_eq[symmetric]
      by (simp add: order_iorder)
    with ‹j < card S› show "y j = x (order j)" by simp
  qed
  from gauss_jordan_complete[OF _ this]
  show ?thesis
    by (auto simp: gauss_jordan'_def simp: M'_def)
qed
end
section ‹pCTL model checking›
subsection ‹Syntax›