Theory Mask

subsection ‹Permission masks: Maps from heap locations to permission amounts›

theory Mask
  imports PosRat
begin

subsubsection ‹Definitions›

type_synonym field = string
type_synonym address = nat
type_synonym heap_loc = "address × field"

type_synonym mask = "heap_loc ⇒ prat"
type_synonym bmask = "heap_loc ⇒ bool"

definition null where "null = 0"

definition full_mask :: "mask" where
  "full_mask hl = (if fst hl = null then pnone else pwrite)"


definition multiply_mask :: "prat ⇒ mask ⇒ mask" where
  "multiply_mask p π hl = pmult p (π hl)"

fun empty_mask where
  "empty_mask hl = pnone"

fun empty_bmask where
  "empty_bmask hl = False"

fun add_acc where "add_acc π hl p = π(hl := padd (π hl) p)"

inductive rm_acc where
  "π hl = padd p r ⟹ rm_acc π hl p (π(hl := r))"

fun add_masks where
  "add_masks π' π hl = padd (π' hl) (π hl)"

definition greater_mask where
  "greater_mask π' π ⟷ (∃r. π' = add_masks π r)"

fun uni_mask where
  "uni_mask hl p = empty_mask(hl := p)"

fun valid_mask :: "mask ⇒ bool" where
  "valid_mask π ⟷ (∀hl. pgte pwrite (π hl)) ∧ (∀f. π (null, f) = pnone)"

definition valid_null :: "mask ⇒ bool" where
  "valid_null π ⟷ (∀f. π (null, f) = pnone)"

definition equal_on_mask where
  "equal_on_mask π h h' ⟷ (∀hl. ppos (π hl) ⟶ h hl = h' hl)"

definition equal_on_bmask where
  "equal_on_bmask π h h' ⟷ (∀hl. π hl ⟶ h hl = h' hl)"

definition big_add_masks where
  "big_add_masks Π Π' h = add_masks (Π h) (Π' h)"

definition big_greater_mask where
  "big_greater_mask Π Π' ⟷ (∀h. greater_mask (Π h) (Π' h))"

definition greater_bmask where
  "greater_bmask H H' ⟷ (∀h. H' h ⟶ H h)"

definition update_dm where
  "update_dm dm π π' hl ⟷ (dm hl ∨ pgt (π hl) (π' hl))"

fun pre_get_m where "pre_get_m φ = fst φ"
fun pre_get_h where "pre_get_h φ = snd φ"
fun srm_acc where "srm_acc φ hl p = (rm_acc (pre_get_m φ) hl p, pre_get_h φ)"


datatype val = Bool (the_bool: bool) | Address (the_address: address) | Rat (the_rat: prat)

definition upper_bounded :: "mask ⇒ prat ⇒ bool" where
  "upper_bounded π p ⟷ (∀hl. pgte p (π hl))"




subsubsection ‹Lemmas›

lemma ssubsetI:
  assumes "⋀π h. (π, h) ∈ A ⟹ (π, h) ∈ B"
  shows "A ⊆ B"
  using assms by auto

lemma double_inclusion:
  assumes "A ⊆ B"
      and "B ⊆ A"
    shows "A = B"
  using assms by blast

lemma add_masks_comm:
  "add_masks a b = add_masks b a"
proof (rule ext)
  fix x show "add_masks a b x = add_masks b a x"
    by (metis Rep_prat_inverse add.commute add_masks.simps padd.rep_eq)
qed

lemma add_masks_asso:
  "add_masks (add_masks a b) c = add_masks a (add_masks b c)"
proof (rule ext)
  fix x show "add_masks (add_masks a b) c x = add_masks a (add_masks b c) x"
    by (metis Rep_prat_inverse add.assoc add_masks.simps padd.rep_eq)
qed

lemma minus_empty:
  "π = add_masks π empty_mask"
proof (rule ext)
  fix x show "π x = add_masks π empty_mask x"
    by (metis Rep_prat_inverse add.right_neutral add_masks.simps empty_mask.simps padd.rep_eq pnone.rep_eq)
qed

lemma add_acc_uni_mask:
  "add_acc π hl p = add_masks π (uni_mask hl p)"
proof (rule ext)
  fix x show "add_acc π hl p x = add_masks π (uni_mask hl p) x"
    by (metis (no_types, opaque_lifting) add_acc.simps add_masks.simps fun_upd_apply minus_empty uni_mask.simps)
qed

lemma add_masks_equiv_valid_null:
  "valid_null (add_masks a b) ⟷ valid_null a ∧ valid_null b"
  by (metis (mono_tags, lifting) add_masks.simps padd_zero valid_null_def)

lemma valid_maskI:
  assumes "⋀hl. pgte pwrite (π hl)"
      and "⋀f. π (null, f) = pnone"
    shows "valid_mask π"
  by (simp add: assms(1) assms(2))

lemma greater_mask_equiv_def:
  "greater_mask π' π ⟷ (∀hl. pgte (π' hl) (π hl))"
  (is "?A ⟷ ?B")
proof (rule iffI)
  show "?A ⟹ ?B"
  proof (clarify)
    fix hl assume "greater_mask π' π"
    then obtain r where "π' = add_masks π r"
      using greater_mask_def by blast
    then show "pgte (π' hl) (π hl)"
      using Rep_prat padd.rep_eq pgte.rep_eq by auto
  qed
  show "?B ⟹ ?A"
  proof -
    assume ?B
    let ?r = "λhl. (SOME p. π' hl = padd (π hl) p)"
    have "π' = add_masks π ?r"
    proof (rule ext)
      fix hl
      have "π' hl = padd (π hl) (?r hl)"
        by (meson ‹∀hl. pgte (π' hl) (π hl)› p_greater_exists someI_ex)
      then show "π' hl = add_masks π ?r hl"
        by auto
    qed
    then show ?A
      using greater_mask_def by blast
  qed
qed

lemma greater_maskI:
  assumes "⋀hl. pgte (π' hl) (π hl)"
  shows "greater_mask π' π"
  by (simp add: assms greater_mask_equiv_def)

lemma greater_mask_properties:
  "greater_mask π π"
  "greater_mask a b ∧ greater_mask b c ⟹ greater_mask a c"
  "greater_mask π' π ∧ greater_mask π π' ⟹ π = π'"
  apply (simp add: greater_maskI pgte.rep_eq)
  apply (metis add_masks_asso greater_mask_def)
proof (rule ext)
  fix x assume "greater_mask π' π ∧ greater_mask π π'"
  then show "π x = π' x"
    by (meson greater_mask_equiv_def pgte_antisym)
qed

lemma greater_mask_decomp:
  assumes "greater_mask a (add_masks b c)"
  shows "∃a1 a2. a = add_masks a1 a2 ∧ greater_mask a1 b ∧ greater_mask a2 c"
  by (metis add_masks_asso assms greater_mask_def greater_mask_properties(1))

lemma valid_empty:
  "valid_mask empty_mask"
  by (metis empty_mask.simps le_add_same_cancel1 p_greater_exists padd.rep_eq pgte.rep_eq pnone.rep_eq valid_mask.simps)

lemma upper_valid_aux:
  assumes "valid_mask a"
      and "a = add_masks b c"
    shows "valid_mask b"
proof (rule valid_maskI)
  show "⋀hl. pgte pwrite (b hl)"
    using assms(1) assms(2) p_greater_exists padd_asso by fastforce
  fix f show " b (null, f) = pnone"
    by (metis add_masks_comm assms(1) assms(2) empty_mask.simps greater_mask_def greater_mask_equiv_def minus_empty pgte_antisym valid_mask.simps)
qed

lemma upper_valid:
  assumes "valid_mask a"
      and "a = add_masks b c"
    shows "valid_mask b ∧ valid_mask c"
  using add_masks_comm assms(1) assms(2) upper_valid_aux by blast

lemma equal_on_bmaskI:
  assumes "⋀hl. π hl ⟹ h hl = h' hl"
  shows "equal_on_bmask π h h'"
  using assms equal_on_bmask_def by blast

lemma big_add_greater:
  "big_greater_mask (big_add_masks A B) B"
  by (metis add_masks_comm big_add_masks_def big_greater_mask_def greater_mask_def)

lemma big_greater_iff:
  "big_greater_mask A B ⟹ (∃C. A = big_add_masks B C)"
proof -
  assume "big_greater_mask A B"
  let ?C = "λh. SOME r. A h = add_masks (B h) r"
  have "A = big_add_masks B ?C"
  proof (rule ext)
    fix x
    have "A x = add_masks (B x) (?C x)"
    proof (rule ext)
      fix xa 
      have "A x = add_masks (B x) (SOME r. A x = add_masks (B x) r)"
        by (metis (mono_tags, lifting) ‹big_greater_mask A B› big_greater_mask_def greater_mask_def someI_ex)
      then show "A x xa = add_masks (B x) (SOME r. A x = add_masks (B x) r) xa"
        by auto
    qed
    then show "A x = big_add_masks B (λh. SOME r. A h = add_masks (B h) r) x"
      by (metis (no_types, lifting) big_add_masks_def)
  qed
  then show "∃C. A = big_add_masks B C"
    by fast
qed

lemma big_add_masks_asso:
  "big_add_masks A (big_add_masks B C) = big_add_masks (big_add_masks A B) C"
proof (rule ext)
  fix x show "big_add_masks A (big_add_masks B C) x = big_add_masks (big_add_masks A B) C x"
    by (simp add: add_masks_asso big_add_masks_def)
qed

lemma big_add_mask_neutral:
  "big_add_masks Π (λ_. empty_mask) = Π"
proof (rule ext)
  fix x show "big_add_masks Π (λ_. empty_mask) x = Π x"
    by (metis big_add_masks_def minus_empty)
qed

lemma sym_equal_on_mask:
  "equal_on_mask π a b ⟷ equal_on_mask π b a"
proof -
  have "⋀a b. equal_on_mask π a b ⟹ equal_on_mask π b a"
    by (simp add: equal_on_mask_def)
  then show ?thesis by blast
qed

lemma greater_mask_uni_equiv:
  "greater_mask π (uni_mask hl r) ⟷ pgte (π hl) r"
  by (metis add_masks_comm fun_upd_apply greater_mask_def greater_mask_equiv_def minus_empty uni_mask.simps)

lemma greater_mask_uniI:
  assumes "pgte (π hl) r"
  shows "greater_mask π (uni_mask hl r)"
  using greater_mask_uni_equiv assms by metis

lemma greater_bmask_refl:
  "greater_bmask H H"
  by (simp add: greater_bmask_def)

lemma greater_bmask_trans:
  assumes "greater_bmask A B"
      and "greater_bmask B C"
    shows "greater_bmask A C"
  by (metis assms(1) assms(2) greater_bmask_def)

lemma update_dm_same:
  "update_dm dm π π = dm"
proof (rule ext)
  fix x show "update_dm dm π π x = dm x"
    by (simp add: pgt.rep_eq update_dm_def)
qed

lemma update_trans:
  assumes "greater_mask π π'"
      and "greater_mask π' π''"
  shows "update_dm (update_dm dm π π') π' π'' = update_dm dm π π''"
proof (rule ext)
  fix hl show "update_dm (update_dm dm π π') π' π'' hl = update_dm dm π π'' hl"
  proof -
    have "update_dm (update_dm dm π π') π' π'' hl ⟷ (update_dm dm π π') hl ∨ pgt (π' hl) (π'' hl)"
      using update_dm_def by metis
    also have "... ⟷ dm hl ∨ pgt (π hl) (π' hl) ∨ pgt (π' hl) (π'' hl)"
      using update_dm_def by metis
    moreover have "update_dm dm π π'' hl ⟷ dm hl ∨ pgt (π hl) (π'' hl)"
      using update_dm_def by metis
    moreover have "pgt (π hl) (π' hl) ∨ pgt (π' hl) (π'' hl) ⟷ pgt (π hl) (π'' hl)"
    proof
      show "pgt (π hl) (π' hl) ∨ pgt (π' hl) (π'' hl) ⟹ pgt (π hl) (π'' hl)"
        by (metis assms(1) assms(2) greater_mask_equiv_def greater_mask_properties(2) not_pgte_charact pgte_antisym)
      show "pgt (π hl) (π'' hl) ⟹ pgt (π hl) (π' hl) ∨ pgt (π' hl) (π'' hl)"
        by (metis assms(1) greater_mask_equiv_def not_pgte_charact pgte_antisym)
    qed
    ultimately show ?thesis by blast
  qed
qed

lemma equal_on_bmask_greater:
  assumes "equal_on_bmask π' h h'"
      and "greater_bmask π' π"
    shows "equal_on_bmask π h h'"
  by (metis (mono_tags, lifting) assms(1) assms(2) equal_on_bmask_def greater_bmask_def)

lemma update_dm_equal_bmask:
  assumes "π = add_masks π' m"   
  shows "equal_on_bmask (update_dm dm π π') h' h ⟷ equal_on_mask m h h' ∧ equal_on_bmask dm h h'"
proof -
  have "equal_on_bmask (update_dm dm π π') h' h ⟷ (∀hl. update_dm dm π π' hl ⟶ h' hl = h hl)"
    by (simp add: equal_on_bmask_def)
  moreover have "⋀hl. update_dm dm π π' hl ⟷ dm hl ∨ pgt (π hl) (π' hl)"
    by (simp add: update_dm_def)
  moreover have "(∀hl. update_dm dm π π' hl ⟶ h' hl = h hl) ⟷ equal_on_mask m h h' ∧ equal_on_bmask dm h h'"
  proof
    show "∀hl. update_dm dm π π' hl ⟶ h' hl = h hl ⟹ equal_on_mask m h h' ∧ equal_on_bmask dm h h'"
      by (simp add: assms equal_on_bmask_def equal_on_mask_def padd.rep_eq pgt.rep_eq ppos.rep_eq update_dm_def)
    assume "equal_on_mask m h h' ∧ equal_on_bmask dm h h'"
    then have "⋀hl. update_dm dm π π' hl ⟹ h' hl = h hl"
      by (metis (full_types) add.right_neutral add_masks.simps assms dual_order.strict_iff_order equal_on_bmask_def equal_on_mask_def padd.rep_eq pgt.rep_eq pnone.rep_eq ppos_eq_pnone update_dm_def)
    then show "∀hl. update_dm dm π π' hl ⟶ h' hl = h hl"
      by simp
  qed
  then show ?thesis
    by (simp add: calculation)
qed

lemma const_sum_mask_greater:
  assumes "add_masks a b = add_masks c d"
      and "greater_mask a c"
    shows "greater_mask d b"
proof (rule ccontr)
  assume "¬ greater_mask d b"
  then obtain hl where "¬ pgte (d hl) (b hl)"
    using greater_mask_equiv_def by blast
  then have "pgt (b hl) (d hl)"
    using not_pgte_charact by auto
  then have "pgt (padd (a hl) (b hl)) (padd (c hl) (d hl))"
    by (metis assms(2) greater_mask_equiv_def padd_comm pgte_pgt)
  then show "False"
    by (metis add_masks.simps assms(1) not_pgte_charact order_refl pgte.rep_eq)
qed

lemma add_masks_cancellative:
  assumes "add_masks b c = add_masks b d"
    shows "c = d"
proof (rule ext)
  fix x show "c x = d x"
    by (metis assms(1) const_sum_mask_greater greater_mask_properties(1) greater_mask_properties(3))
qed

lemma equal_on_maskI:
  assumes "⋀hl. ppos (π hl) ⟹ h hl = h' hl"
  shows "equal_on_mask π h h'"
  by (simp add: assms equal_on_mask_def)

lemma greater_equal_on_mask:
  assumes "equal_on_mask π' h h'"
      and "greater_mask π' π"
    shows "equal_on_mask π h h'"
proof (rule equal_on_maskI)
  fix hl assume asm: "ppos (π hl)"
  then show "h hl = h' hl"
    by (metis assms(1) assms(2) equal_on_mask_def greater_mask_equiv_def less_le_trans pgte.rep_eq ppos.rep_eq)
qed

lemma equal_on_mask_sum:
  "equal_on_mask π1 h h' ∧ equal_on_mask π2 h h' ⟷ equal_on_mask (add_masks π1 π2) h h'"
proof
  show "equal_on_mask (add_masks π1 π2) h h' ⟹ equal_on_mask π1 h h' ∧ equal_on_mask π2 h h'"
    using add_masks_comm greater_equal_on_mask greater_mask_def by blast
  assume asm0: "equal_on_mask π1 h h' ∧ equal_on_mask π2 h h'"
  show "equal_on_mask (add_masks π1 π2) h h'"
  proof (rule equal_on_maskI)
    fix hl assume "ppos (add_masks π1 π2 hl)"
    then show "h hl = h' hl"
    proof (cases "ppos (π1 hl)")
      case True
      then show ?thesis
        by (meson asm0 equal_on_mask_def)
    next
      case False
      then show ?thesis
        by (metis asm0 ‹ppos (add_masks π1 π2 hl)› add_masks.simps equal_on_mask_def padd_zero ppos_eq_pnone)
    qed
  qed
qed

lemma valid_larger_mask:
  "valid_mask π ⟷ greater_mask full_mask π "
  by (metis fst_eqD full_mask_def greater_maskI greater_mask_def not_one_le_zero not_pgte_charact pgt_implies_pgte pgte.rep_eq pnone.rep_eq pwrite.rep_eq surjective_pairing upper_valid_aux valid_mask.elims(1))

lemma valid_mask_full_mask:
  "valid_mask full_mask"
  using greater_mask_properties(1) valid_larger_mask by blast

lemma mult_greater:
  assumes "greater_mask a b"
  shows "greater_mask (multiply_mask p a) (multiply_mask p b)"
  by (metis (full_types) assms greater_mask_equiv_def multiply_mask_def p_greater_exists pmult_distr)

lemma mult_write_mask:
  "multiply_mask pwrite π = π"
proof (rule ext)
  fix x show "multiply_mask pwrite π x = π x"
    by (simp add: multiply_mask_def pmult_special(1))
qed

lemma mult_distr_masks:
  "multiply_mask a (add_masks b c) = add_masks (multiply_mask a b) (multiply_mask a c)"
proof (rule ext)
  fix x show "multiply_mask a (add_masks b c) x = add_masks (multiply_mask a b) (multiply_mask a c) x"
    by (simp add: multiply_mask_def pmult_distr)
qed

lemma mult_add_states:
  "multiply_mask (padd a b) π = add_masks (multiply_mask a π) (multiply_mask b π)"
proof (rule ext)
  fix x show "multiply_mask (padd a b) π x = add_masks (multiply_mask a π) (multiply_mask b π) x"    
    by (simp add: multiply_mask_def pmult_comm pmult_distr)
qed

lemma upper_boundedI:
  assumes "⋀hl. pgte p (π hl)"
  shows "upper_bounded π p"
  by (simp add: assms upper_bounded_def)

lemma upper_bounded_smaller:
  assumes "upper_bounded π a"
  shows "upper_bounded (multiply_mask p π) (pmult p a)"  
  by (metis assms multiply_mask_def p_greater_exists pmult_distr upper_bounded_def)

lemma upper_bounded_bigger:
  assumes "upper_bounded π a"
      and "pgte b a"
    shows "upper_bounded π b"
  by (meson assms(1) assms(2) order_trans pgte.rep_eq upper_bounded_def)


lemma valid_mult:
  assumes "valid_mask π"
      and "pgte pwrite p"
    shows "valid_mask (multiply_mask p π)"
proof (rule valid_maskI)
  have "upper_bounded π pwrite"
    using assms(1) upper_bounded_def by auto
  then have "upper_bounded (multiply_mask p π) (pmult p pwrite)"
    by (simp add: upper_bounded_smaller)
  then show "⋀hl. pgte pwrite (multiply_mask p π hl)"
    by (metis assms(2) pmult_comm pmult_special(1) upper_bounded_bigger upper_bounded_def)
  show "⋀f. multiply_mask p π (null, f) = pnone"
    by (metis Rep_prat_inverse add_0_left assms(1) multiply_mask_def padd.rep_eq padd_cancellative pmult_distr pnone.rep_eq valid_mask.elims(1))
qed

lemma valid_sum:
  assumes "valid_mask a"
      and "valid_mask b"
      and "upper_bounded a ma"
      and "upper_bounded b mb"
      and "pgte pwrite (padd ma mb)"
    shows "valid_mask (add_masks a b)"
      and "upper_bounded (add_masks a b) (padd ma mb)"
proof (rule valid_maskI)
  show "⋀hl. pgte pwrite (add_masks a b hl)"
  proof -
    fix hl 
    have "pgte (padd ma mb) (add_masks a b hl)"
      by (metis (mono_tags, lifting) add_masks.simps add_mono_thms_linordered_semiring(1) assms(3) assms(4) padd.rep_eq pgte.rep_eq upper_bounded_def)
    then show "pgte pwrite (add_masks a b hl)"
      by (meson assms(5) dual_order.trans pgte.rep_eq)
  qed
  show "⋀f. add_masks a b (null, f) = pnone"
    by (metis Rep_prat_inverse add_0_left add_masks.simps assms(1) assms(2) padd.rep_eq pnone.rep_eq valid_mask.simps)
  show "upper_bounded (add_masks a b) (padd ma mb)"
    using add_mono_thms_linordered_semiring(1) assms(3) assms(4) padd.rep_eq pgte.rep_eq upper_bounded_def by fastforce
qed

lemma valid_multiply:
  assumes "valid_mask a"
      and "upper_bounded a ma"
      and "pgte pwrite (pmult ma p)"
    shows "valid_mask (multiply_mask p a)"
  by (metis (no_types, opaque_lifting) assms(1) assms(2) assms(3) multiply_mask_def pmult_comm pmult_special(2) upper_bounded_bigger upper_bounded_def upper_bounded_smaller valid_mask.elims(1))

lemma greater_mult:
  assumes "greater_mask a b"
  shows "greater_mask (multiply_mask p a) (multiply_mask p b)"
  by (metis Rep_prat assms greater_mask_equiv_def mem_Collect_eq mult_left_mono multiply_mask_def pgte.rep_eq pmult.rep_eq)

end