540 lines
19 KiB
Plaintext
540 lines
19 KiB
Plaintext
(*
|
|
* Copyright 2014, General Dynamics C4 Systems
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-only
|
|
*)
|
|
|
|
(* Title: System_S
|
|
* Description: High-level security model of the kernel.
|
|
*)
|
|
|
|
(*
|
|
Naming conventions:
|
|
- Names of sets end with an `s'.
|
|
Hence `rights', `caps', `states'.
|
|
Try to avoid other names that end in `s'.
|
|
*)
|
|
|
|
theory System_S
|
|
imports "Word_Lib.WordSetup"
|
|
begin
|
|
|
|
(* System entities: Definition of entities that constitute the system
|
|
*)
|
|
|
|
type_synonym entity_id = word32 (* kernel objects - identified by a UID *)
|
|
|
|
datatype
|
|
right = Read (* Authorise reading of information *)
|
|
| Write (* Authorise writing of information *)
|
|
| Take (* Having sufficient authority to take a capability from another entity *)
|
|
| Grant (* Having sufficient authority to propagate a capability to another entity *)
|
|
| Create (* Confers the authority to create new entities *)
|
|
| Store (* Simulates CNodeCap - get caps of said entity *)
|
|
|
|
record cap =
|
|
target :: entity_id (* The entity over which it has control *)
|
|
rights :: "right set" (* The control it has over that entity *)
|
|
|
|
datatype entity = Entity "cap set"
|
|
declare entity.splits [split]
|
|
|
|
type_synonym state = "entity_id \<Rightarrow> entity option"
|
|
|
|
type_synonym modify_state = "state \<Rightarrow> state"
|
|
type_synonym modify_state_n = "state \<Rightarrow> state set"
|
|
type_synonym mask = "right set"
|
|
|
|
definition
|
|
null_entity :: "entity" where
|
|
"null_entity \<equiv> Entity {}"
|
|
|
|
definition
|
|
all_rights :: "right set" where
|
|
"all_rights \<equiv> UNIV"
|
|
|
|
lemma all_rights_def2:
|
|
"all_rights = {Read, Write, Take, Grant, Create, Store}"
|
|
apply (clarsimp simp: all_rights_def, rule, simp_all, rule, simp)
|
|
apply (metis right.exhaust)
|
|
done
|
|
|
|
definition
|
|
entity_ids :: "state \<Rightarrow> entity_id set" where
|
|
"entity_ids s \<equiv> dom s"
|
|
|
|
definition
|
|
is_entity :: "state \<Rightarrow> entity_id \<Rightarrow> bool" where
|
|
"is_entity s e \<equiv> s e \<noteq> None"
|
|
|
|
definition
|
|
exist :: "state \<Rightarrow> cap \<Rightarrow> bool" where
|
|
"exist s c \<equiv> is_entity s (target c)"
|
|
|
|
(* Manipulating entities. *)
|
|
definition
|
|
direct_caps :: "entity \<Rightarrow> cap set"
|
|
where
|
|
"direct_caps e \<equiv> case e of (Entity c) \<Rightarrow> c"
|
|
|
|
definition
|
|
direct_caps_of :: "state \<Rightarrow> entity_id \<Rightarrow> cap set"
|
|
where
|
|
"direct_caps_of s p \<equiv>
|
|
case s p of
|
|
None \<Rightarrow> {}
|
|
| Some (Entity e) \<Rightarrow> e"
|
|
|
|
definition
|
|
store_connected_direct :: "state \<Rightarrow> (entity_id \<times> entity_id) set" where
|
|
"store_connected_direct s \<equiv> {(e\<^sub>x, e\<^sub>y). \<exists>cap. cap \<in> direct_caps_of s e\<^sub>x \<and>
|
|
Store \<in> rights cap \<and>
|
|
target cap = e\<^sub>y}"
|
|
|
|
definition
|
|
store_connected :: "state \<Rightarrow> (entity_id \<times> entity_id) set" where
|
|
"store_connected s \<equiv> (store_connected_direct s)^*"
|
|
|
|
definition
|
|
(* returns all capabilities an entity has access to
|
|
(via store or directly) *)
|
|
caps_of :: "state \<Rightarrow> entity_id \<Rightarrow> cap set" where
|
|
"caps_of s e \<equiv> \<Union>(direct_caps_of s ` {e' . (e,e') \<in> store_connected s})"
|
|
|
|
lemma caps_rel:
|
|
"caps_of s e = \<Union>(direct_caps_of s ` store_connected s `` {e})"
|
|
by (simp add: caps_of_def Image_def)
|
|
|
|
definition (* All the different capabilities of the system *)
|
|
all_caps_of :: "state \<Rightarrow> cap set" where
|
|
"all_caps_of s \<equiv> \<Union>e. direct_caps_of s e"
|
|
|
|
definition
|
|
read_cap :: "entity_id \<Rightarrow> cap" where
|
|
"read_cap e\<^sub>x \<equiv> \<lparr>target = e\<^sub>x, rights = {Read}\<rparr>"
|
|
|
|
definition
|
|
write_cap :: "entity_id \<Rightarrow> cap" where
|
|
"write_cap e\<^sub>x \<equiv> \<lparr>target = e\<^sub>x, rights = {Write}\<rparr>"
|
|
|
|
definition
|
|
take_cap :: "entity_id \<Rightarrow> cap" where
|
|
"take_cap e\<^sub>x \<equiv> \<lparr>target = e\<^sub>x, rights = {Take}\<rparr>"
|
|
|
|
definition
|
|
grant_cap :: "entity_id \<Rightarrow> cap" where
|
|
"grant_cap e\<^sub>x \<equiv> \<lparr>target = e\<^sub>x, rights = {Grant}\<rparr>"
|
|
|
|
definition
|
|
create_cap :: "entity_id \<Rightarrow> cap" where
|
|
"create_cap e\<^sub>x \<equiv> \<lparr>target = e\<^sub>x, rights = {Create}\<rparr>"
|
|
|
|
definition
|
|
store_cap :: "entity_id \<Rightarrow> cap" where
|
|
"store_cap e \<equiv> \<lparr>target = e, rights = {Store}\<rparr>"
|
|
|
|
definition
|
|
full_cap :: "entity_id \<Rightarrow> cap" where
|
|
"full_cap e \<equiv> \<lparr>target = e, rights = all_rights \<rparr>"
|
|
|
|
|
|
|
|
(* System operations: primitive kernel operations *)
|
|
|
|
datatype sysOPs =
|
|
SysCreate entity_id cap cap
|
|
| SysTake entity_id cap cap mask
|
|
| SysGrant entity_id cap cap mask
|
|
| SysCopy entity_id cap cap mask
|
|
| SysRemove entity_id cap cap
|
|
| SysRemoveSet entity_id cap "cap set"
|
|
| SysRevoke entity_id cap
|
|
| SysDestroy entity_id cap
|
|
|
|
|
|
(* determine if an operation is allowed in the given state_s *)
|
|
primrec
|
|
legal :: "sysOPs \<Rightarrow> state \<Rightarrow> bool"
|
|
where
|
|
"legal (SysCreate e c\<^sub>1 c\<^sub>2) s = (is_entity s e \<and> is_entity s (target c\<^sub>1) \<and> \<not> (is_entity s (target c\<^sub>2)) \<and>
|
|
{c\<^sub>1, c\<^sub>2} \<subseteq> caps_of s e \<and>
|
|
Write \<in> rights c\<^sub>1 \<and> Store \<in> rights c\<^sub>1 \<and> Create \<in> rights c\<^sub>2)"
|
|
|
|
| "legal (SysTake e c\<^sub>1 c\<^sub>2 r) s = (is_entity s e \<and> is_entity s (target c\<^sub>1) \<and>
|
|
c\<^sub>1 \<in> caps_of s e \<and> c\<^sub>2 \<in> caps_of s (target c\<^sub>1) \<and> Take \<in> rights c\<^sub>1)"
|
|
|
|
| "legal (SysGrant e c\<^sub>1 c\<^sub>2 r) s = (is_entity s e \<and> is_entity s (target c\<^sub>1) \<and>
|
|
{c\<^sub>1,c\<^sub>2} \<subseteq> caps_of s e \<and> Grant \<in> rights c\<^sub>1)"
|
|
|
|
| "legal (SysCopy e c\<^sub>1 c\<^sub>2 r) s = (is_entity s e \<and> is_entity s (target c\<^sub>1) \<and>
|
|
{c\<^sub>1,c\<^sub>2} \<subseteq> caps_of s e \<and> Store \<in> rights c\<^sub>1)"
|
|
|
|
| "legal (SysRemove e c\<^sub>1 c\<^sub>2) s = (is_entity s e \<and> c\<^sub>1 \<in> caps_of s e)"
|
|
|
|
| "legal (SysRemoveSet e c C) s = (is_entity s e \<and> c \<in> caps_of s e)"
|
|
|
|
| "legal (SysRevoke e c) s = (is_entity s e \<and> c \<in> caps_of s e)"
|
|
|
|
| "legal (SysDestroy e c) s = (is_entity s e \<and> c \<in> caps_of s e \<and> {Create} = rights c \<and>
|
|
target c \<notin> target ` (all_caps_of s - {c}))"
|
|
|
|
(* Following functions define how each of the sysOPs modifies the
|
|
* system state_s
|
|
*)
|
|
|
|
definition
|
|
diminish :: "right set \<Rightarrow> cap \<Rightarrow> cap" where
|
|
"diminish R cap \<equiv> cap \<lparr> rights := rights cap \<inter> R \<rparr>"
|
|
|
|
definition
|
|
createOperation ::
|
|
"entity_id \<Rightarrow> cap \<Rightarrow> cap \<Rightarrow> modify_state" where
|
|
"createOperation e c\<^sub>1 c\<^sub>2 s \<equiv>
|
|
s (target c\<^sub>1 \<mapsto> Entity (insert (full_cap (target c\<^sub>2))
|
|
(direct_caps_of s (target c\<^sub>1))),
|
|
target c\<^sub>2 \<mapsto> null_entity)"
|
|
|
|
lemma createOperation_def2:
|
|
"createOperation e c\<^sub>1 c\<^sub>2 s \<equiv>
|
|
let new_cap = \<lparr> target = target c\<^sub>2, rights = all_rights \<rparr>;
|
|
newTarget = ({new_cap} \<union> direct_caps_of s (target c\<^sub>1) )
|
|
in
|
|
s (target c\<^sub>1 \<mapsto> Entity newTarget, target c\<^sub>2 \<mapsto> null_entity)"
|
|
by (simp add: createOperation_def Let_def full_cap_def null_entity_def)
|
|
|
|
definition
|
|
takeOperation :: "entity_id \<Rightarrow> cap \<Rightarrow> cap \<Rightarrow> right set \<Rightarrow> modify_state" where
|
|
"takeOperation e c\<^sub>1 c\<^sub>2 R s \<equiv>
|
|
s (e \<mapsto> Entity (insert (diminish R c\<^sub>2) (direct_caps_of s e)))"
|
|
|
|
lemma takeOperation_def2:
|
|
"takeOperation e c\<^sub>1 c\<^sub>2 R s \<equiv>
|
|
s (e \<mapsto> Entity ({diminish R c\<^sub>2} \<union> direct_caps_of s e))"
|
|
by (clarsimp simp: takeOperation_def caps_of_def)
|
|
|
|
definition
|
|
grantOperation ::
|
|
"entity_id \<Rightarrow> cap \<Rightarrow> cap \<Rightarrow> right set \<Rightarrow> modify_state" where
|
|
"grantOperation e c\<^sub>1 c\<^sub>2 R s \<equiv>
|
|
s (target c\<^sub>1 \<mapsto> Entity (insert (diminish R c\<^sub>2) (direct_caps_of s (target c\<^sub>1)) )) "
|
|
|
|
lemma grantOperation_def2:
|
|
"grantOperation e c\<^sub>1 c\<^sub>2 R s \<equiv>
|
|
s (target c\<^sub>1 \<mapsto> Entity ( {diminish R c\<^sub>2} \<union> direct_caps_of s (target c\<^sub>1)))"
|
|
by (clarsimp simp: grantOperation_def caps_of_def)
|
|
|
|
definition
|
|
copyOperation ::
|
|
"entity_id \<Rightarrow> cap \<Rightarrow> cap \<Rightarrow> right set \<Rightarrow> modify_state" where
|
|
"copyOperation sRef c\<^sub>1 c\<^sub>2 R s \<equiv>
|
|
s (target c\<^sub>1 \<mapsto> Entity (insert (diminish R c\<^sub>2) (direct_caps_of s (target c\<^sub>1)))) "
|
|
|
|
definition
|
|
removeOperation ::
|
|
"entity_id \<Rightarrow> cap \<Rightarrow> cap \<Rightarrow> modify_state" where
|
|
"removeOperation e c\<^sub>1 c\<^sub>2 s \<equiv>
|
|
if is_entity s (target c\<^sub>1)
|
|
then
|
|
s ((target c\<^sub>1) \<mapsto> Entity ((direct_caps_of s (target c\<^sub>1)) - {c\<^sub>2} ))
|
|
else
|
|
s"
|
|
|
|
lemma removeOperation_simpler:
|
|
"removeOperation e c\<^sub>1 c\<^sub>2 s \<equiv>
|
|
(case s (target c\<^sub>1) of
|
|
None \<Rightarrow> s
|
|
| Some (Entity caps) \<Rightarrow> s (target c\<^sub>1 \<mapsto> Entity (caps - {c\<^sub>2})))"
|
|
by (rule eq_reflection, simp add: removeOperation_def is_entity_def direct_caps_of_def
|
|
split: if_split_asm option.splits)
|
|
|
|
definition
|
|
removeSetOperation ::
|
|
"entity_id \<Rightarrow> cap \<Rightarrow> cap set \<Rightarrow> modify_state" where
|
|
"removeSetOperation e c C s \<equiv>
|
|
if is_entity s (target c) then
|
|
s ((target c) \<mapsto> Entity ((direct_caps_of s (target c)) - C ))
|
|
else
|
|
s"
|
|
|
|
lemma removeSetOperation_simpler:
|
|
"removeSetOperation e c caps s \<equiv>
|
|
(case s (target c) of
|
|
None \<Rightarrow> s
|
|
| Some (Entity caps') \<Rightarrow> s (target c \<mapsto> Entity (caps' - caps)))"
|
|
by (auto simp: removeSetOperation_def is_entity_def direct_caps_of_def
|
|
intro!: eq_reflection
|
|
split: if_split_asm option.splits)
|
|
|
|
lemma removeSetOperation_fold_removeOperation:
|
|
"removeSetOperation e c (set caps) s = fold (removeOperation e c) caps s"
|
|
apply (subst foldr_fold [symmetric])
|
|
apply (fastforce simp: removeOperation_def direct_caps_of_def is_entity_def)
|
|
apply (rule sym)
|
|
apply (induct caps)
|
|
apply (fastforce simp: removeSetOperation_def removeOperation_def direct_caps_of_def is_entity_def)
|
|
apply (fastforce simp: removeSetOperation_def removeOperation_def direct_caps_of_def is_entity_def)
|
|
done
|
|
|
|
definition
|
|
removeSetOfCaps :: "(entity_id \<Rightarrow> cap set) \<Rightarrow> modify_state"
|
|
where
|
|
"removeSetOfCaps cap_map s \<equiv> \<lambda>e.
|
|
if is_entity s e
|
|
then Some (Entity ((direct_caps_of s e) - cap_map e ))
|
|
else None"
|
|
|
|
definition
|
|
caps_to_entity :: "entity_id \<Rightarrow> entity_id \<Rightarrow> state \<Rightarrow> cap set"
|
|
where
|
|
"caps_to_entity e e' s \<equiv> {cap. cap \<in> direct_caps_of s e' \<and> target cap = e}"
|
|
|
|
definition
|
|
revokeOperation :: "entity_id \<Rightarrow> cap \<Rightarrow> modify_state_n" where
|
|
"revokeOperation e c s \<equiv>
|
|
{s'. \<exists>cap_map. \<forall>e'. cap_map e' \<subseteq> caps_to_entity (target c) e' s \<and>
|
|
s' = removeSetOfCaps cap_map s}"
|
|
|
|
definition
|
|
destroyOperation :: "entity_id \<Rightarrow> cap \<Rightarrow> modify_state" where
|
|
"destroyOperation e c s \<equiv> s(target c := None)"
|
|
|
|
|
|
(* Non deterministically executing system calls:
|
|
* How we execute a single operation
|
|
*)
|
|
primrec
|
|
step' :: "sysOPs \<Rightarrow> modify_state_n"
|
|
where
|
|
"step' (SysCreate e c\<^sub>1 c\<^sub>2) s = {createOperation e c\<^sub>1 c\<^sub>2 s}"
|
|
| "step' (SysTake e c\<^sub>1 c\<^sub>2 R) s = {takeOperation e c\<^sub>1 c\<^sub>2 R s}"
|
|
| "step' (SysGrant e c\<^sub>1 c\<^sub>2 R) s = {grantOperation e c\<^sub>1 c\<^sub>2 R s}"
|
|
| "step' (SysCopy e c\<^sub>1 c\<^sub>2 R) s = {copyOperation e c\<^sub>1 c\<^sub>2 R s}"
|
|
| "step' (SysRemove e c\<^sub>1 c\<^sub>2) s = {removeOperation e c\<^sub>1 c\<^sub>2 s}"
|
|
| "step' (SysRemoveSet e c C) s = {removeSetOperation e c C s}"
|
|
| "step' (SysRevoke e c) s = revokeOperation e c s"
|
|
| "step' (SysDestroy e c) s = {destroyOperation e c s}"
|
|
|
|
(* single operation is allowed only if it is legal in the current state_s *)
|
|
definition
|
|
step :: "sysOPs \<Rightarrow> modify_state_n" where
|
|
"step cmd s \<equiv> if legal cmd s then (step' cmd s) \<union> {s} else {s}"
|
|
|
|
(* execution of a list of commands (from back of list)
|
|
*)
|
|
primrec
|
|
execute :: "sysOPs list \<Rightarrow> state \<Rightarrow> state set"
|
|
where
|
|
"execute [] s = {s}"
|
|
| "execute (cmd#cmds) s = \<Union> (step cmd ` ( execute cmds s ))"
|
|
|
|
|
|
|
|
(***************************
|
|
* Lemmas about the model. *
|
|
***************************)
|
|
|
|
lemma Int_all_rights [simp]: "c \<inter> all_rights = c"
|
|
by (simp add: all_rights_def)
|
|
|
|
lemma is_entity_dom: "is_entity s e = (e \<in> dom s)"
|
|
by (simp add: is_entity_def dom_def)
|
|
|
|
lemma is_entity_imp_not_None:
|
|
"is_entity s e \<Longrightarrow> s e \<noteq> None"
|
|
by (simp add: is_entity_def)
|
|
|
|
lemma store_connected_refl [simp]:
|
|
"(e, e) \<in> store_connected s"
|
|
by (simp add: store_connected_def)
|
|
|
|
lemma no_caps_of_imp_not_connected [rule_format]:
|
|
"\<lbrakk>(e, x) \<in> store_connected s\<rbrakk>
|
|
\<Longrightarrow> direct_caps_of s e = {} \<longrightarrow> x = e"
|
|
apply (unfold store_connected_def)
|
|
apply (erule rtrancl.induct)
|
|
apply simp
|
|
apply (clarsimp simp: store_connected_direct_def direct_caps_of_def)
|
|
done
|
|
|
|
lemma no_direct_caps_of_no_caps_of:
|
|
"(direct_caps_of s e = {}) = (caps_of s e = {})"
|
|
apply (rule iffI)
|
|
apply (clarsimp simp add: caps_of_def)
|
|
apply (drule (1) no_caps_of_imp_not_connected)
|
|
apply simp
|
|
apply (clarsimp simp add: caps_of_def store_connected_def)
|
|
done
|
|
|
|
lemma no_direct_caps_of_imp_no_caps_of:
|
|
"direct_caps_of s e = {} \<Longrightarrow> caps_of s e = {}"
|
|
by (rule no_direct_caps_of_no_caps_of [THEN iffD1])
|
|
|
|
lemma no_caps_of_imp_no_direct_caps_of:
|
|
"caps_of s e = {} \<Longrightarrow> direct_caps_of s e = {}"
|
|
by (rule no_direct_caps_of_no_caps_of [THEN iffD2])
|
|
|
|
lemma store_connected_direct_in_store_connected:
|
|
"(x, y) \<in> store_connected_direct s \<Longrightarrow> (x, y) \<in> store_connected s"
|
|
by (simp add: store_connected_def)
|
|
|
|
lemma no_diminish [simp]:
|
|
"diminish all_rights c = c"
|
|
by (simp add: diminish_def)
|
|
|
|
lemma no_diminish_image [simp]:
|
|
"diminish all_rights ` C = C"
|
|
by (fastforce)
|
|
|
|
lemma diminish_diminish [simp]:
|
|
"diminish dimR2 (diminish dimR1 sc) = diminish (dimR1 \<inter> dimR2) sc"
|
|
by (clarsimp simp add: diminish_def Int_assoc)
|
|
|
|
lemma diminish_range_diminish [simp]:
|
|
"diminish dimR2 ` diminish dimR1 ` ssc = diminish (dimR1 \<inter> dimR2) ` ssc"
|
|
apply (rule set_eqI)
|
|
apply (rule iffI)
|
|
apply (clarsimp)
|
|
apply (clarsimp simp del: diminish_diminish simp add: diminish_diminish [symmetric])
|
|
done
|
|
|
|
lemma execute_not_empty:
|
|
"execute ops s \<noteq> {}"
|
|
apply (induct ops)
|
|
apply (simp)
|
|
apply (simp add: step_def del: if_image_distrib, fast)
|
|
done
|
|
|
|
lemma execute_append [intro]:
|
|
"\<And> s s' s'' opsA. \<lbrakk> s'' \<in> execute opsA s; s' \<in> execute opsB s'' \<rbrakk> \<Longrightarrow> s' \<in> execute (opsB @ opsA) s"
|
|
apply (induct opsB)
|
|
apply (simp)
|
|
apply (atomize)
|
|
apply (clarsimp)
|
|
apply (rule bexI)
|
|
apply (assumption)
|
|
by (drule spec | drule(1) mp)+
|
|
|
|
(* Lemma on caps *)
|
|
|
|
lemma heapAdd_read_cap [simp]:
|
|
"target (read_cap e) = e"
|
|
by (simp add: read_cap_def)
|
|
|
|
lemma rights_read_cap [simp]:
|
|
"rights (read_cap e) = {Read}"
|
|
by (simp add: read_cap_def)
|
|
|
|
lemma heapAdd_write_cap [simp]:
|
|
"target (write_cap e) = e"
|
|
by (simp add: write_cap_def)
|
|
|
|
lemma rights_write_cap [simp]:
|
|
"rights (write_cap e) = {Write}"
|
|
by (simp add: write_cap_def)
|
|
|
|
lemma heapAdd_take_cap [simp]:
|
|
"target (take_cap e) = e"
|
|
by (simp add: take_cap_def)
|
|
|
|
lemma rights_take_cap [simp]:
|
|
"rights (take_cap e) = {Take}"
|
|
by (simp add: take_cap_def)
|
|
|
|
lemma heapAdd_grant_cap [simp]:
|
|
"target (grant_cap e) = e"
|
|
by (simp add: grant_cap_def)
|
|
|
|
lemma rights_grant_cap [simp]:
|
|
"rights (grant_cap e) = {Grant}"
|
|
by (simp add: grant_cap_def)
|
|
|
|
lemma heapAdd_create_cap [simp]:
|
|
"target (create_cap e) = e"
|
|
by (simp add: create_cap_def)
|
|
|
|
lemma rights_create_cap [simp]:
|
|
"rights (create_cap e) = {Create}"
|
|
by (simp add: create_cap_def)
|
|
|
|
lemma heapAdd_store_cap [simp]:
|
|
"target (store_cap e) = e"
|
|
by (simp add: store_cap_def)
|
|
|
|
lemma rights_store_cap [simp]:
|
|
"rights (store_cap e) = {Store}"
|
|
by (simp add: store_cap_def)
|
|
|
|
lemma heapAdd_full_cap [simp]:
|
|
"target (full_cap e) = e"
|
|
by (simp add: full_cap_def)
|
|
|
|
lemma rights_full_cap [simp]:
|
|
"rights (full_cap e) = all_rights"
|
|
by (simp add: full_cap_def)
|
|
|
|
lemma entity_diminish [simp]:
|
|
"target (diminish R c) = target c"
|
|
by (simp add: diminish_def)
|
|
|
|
lemma rights_diminish [simp]:
|
|
"rights (diminish R c) = rights c \<inter> R"
|
|
by (simp add: diminish_def)
|
|
|
|
(* Lemmas on caps_of *)
|
|
|
|
lemma caps_of_imp_some_direct_cap:
|
|
"c \<in> caps_of s e \<Longrightarrow> \<exists>e'. c \<in> direct_caps_of s e'"
|
|
by (auto simp: caps_of_def)
|
|
|
|
lemma caps_of_imp_some_store_connected_direct_cap:
|
|
"c \<in> caps_of s e \<Longrightarrow> \<exists>e'. (e, e') \<in> store_connected s \<and> c \<in> direct_caps_of s e'"
|
|
by (auto simp: caps_of_def)
|
|
|
|
lemma direct_cap_in_cap:
|
|
"c \<in> direct_caps_of s e \<Longrightarrow> c \<in> caps_of s e"
|
|
by (auto simp: caps_of_def store_connected_def)
|
|
|
|
lemma all_caps_ofE [elim!]:
|
|
"\<lbrakk> c \<in> all_caps_of s; \<And>e'. c \<in> direct_caps_of s e' \<Longrightarrow> P \<rbrakk> \<Longrightarrow> P"
|
|
by (fastforce simp add: all_caps_of_def)
|
|
|
|
lemma all_caps_ofI [intro]:
|
|
"c \<in> direct_caps_of s e' \<Longrightarrow> c \<in> all_caps_of s"
|
|
by (fastforce simp add: all_caps_of_def)
|
|
|
|
(* Lemmas on entities *)
|
|
|
|
lemma entity_not_not_entity:
|
|
"\<lbrakk>is_entity s e\<^sub>1; \<not> is_entity s e\<^sub>2\<rbrakk> \<Longrightarrow> e\<^sub>1 \<noteq> e\<^sub>2"
|
|
by (auto simp: is_entity_def)
|
|
|
|
lemma no_direct_caps_of_in_nonEntity:
|
|
"\<not> is_entity s e \<Longrightarrow> direct_caps_of s e = {}"
|
|
by (auto simp: direct_caps_of_def is_entity_def split:option.splits)
|
|
|
|
lemma not_is_entity_imp_no_direct_caps_of:
|
|
"\<not> is_entity s e \<Longrightarrow> caps_of s e = {}"
|
|
by (drule no_direct_caps_of_in_nonEntity, erule no_direct_caps_of_imp_no_caps_of)
|
|
|
|
lemma direct_caps_of_imp_is_entity:
|
|
"c \<in> direct_caps_of s e \<Longrightarrow> is_entity s e"
|
|
by (auto intro: classical dest: no_direct_caps_of_in_nonEntity)
|
|
|
|
lemma caps_of_imp_is_entity:
|
|
"c \<in> caps_of s e \<Longrightarrow> is_entity s e"
|
|
by (auto intro: classical dest: not_is_entity_imp_no_direct_caps_of)
|
|
|
|
(* Lemmas on store_connected *)
|
|
|
|
lemma store_caps_of_store_connected_direct:
|
|
"\<lbrakk>c \<in> direct_caps_of s e; Store \<in> rights c\<rbrakk>
|
|
\<Longrightarrow> (e, target c) \<in> store_connected_direct s"
|
|
by (fastforce simp: store_connected_direct_def)
|
|
|
|
lemma store_caps_store_connected:
|
|
"\<lbrakk>c \<in> caps_of s e; Store \<in> rights c\<rbrakk> \<Longrightarrow> (e, target c) \<in> store_connected s"
|
|
apply (clarsimp simp: store_connected_def caps_of_def)
|
|
by (frule (1) store_caps_of_store_connected_direct, simp)
|
|
|
|
end
|