Theory Data

section ‹Data›

text ‹This theory defines the data types and notations, and some preliminary results about them.›

theory Data
  imports Main
begin

subsection ‹Function notations›

abbreviation ε :: "'a  'b" where
  "ε  λx. None"

fun combine :: "('a  'b)  ('a   'b)  ('a  'b)" (‹_;;_› 20) where
  "(f ;; g) x = (if g x = None then f x else g x)"

lemma dom_combination_dom_union: "dom (τ;;τ') = dom τ  dom τ'"
  by auto

subsection ‹Values, expressions and execution contexts›

datatype const = Unit | F | T

datatype (RIDV: 'r, LIDV: 'l,'v) val = 
  CV const
| Var 'v
| Loc 'l
| Rid 'r
| Lambda 'v "('r,'l,'v) expr"
and (RIDE: 'r, LIDE: 'l,'v) expr =
  VE "('r,'l,'v) val"
| Apply "('r,'l,'v) expr" "('r,'l,'v) expr"
| Ite "('r,'l,'v) expr" "('r,'l,'v) expr" "('r,'l,'v) expr"
| Ref "('r,'l,'v) expr"
| Read "('r,'l,'v) expr"
| Assign "('r,'l,'v) expr" "('r,'l,'v) expr"
| Rfork "('r,'l,'v) expr"
| Rjoin "('r,'l,'v) expr"

datatype (RIDC: 'r, LIDC: 'l,'v) cntxt = 
  Hole ()
| ApplyL "('r,'l,'v) cntxt" "('r,'l,'v) expr" 
| ApplyR "('r,'l,'v) val" "('r,'l,'v) cntxt"
| Ite "('r,'l,'v) cntxt" "('r,'l,'v) expr" "('r,'l,'v) expr"
| Ref "('r,'l,'v) cntxt"
| Read "('r,'l,'v) cntxt"
| AssignL "('r,'l,'v) cntxt" "('r,'l,'v) expr"
| AssignR 'l "('r,'l,'v) cntxt"
| Rjoin "('r,'l,'v) cntxt"

subsection ‹Plugging and decomposing›

fun plug :: "('r,'l,'v) cntxt  ('r,'l,'v) expr  ('r,'l,'v) expr" (infix  60) where
  "  e = e"
| "ApplyL  e1  e = Apply (  e) e1"
| "ApplyR val   e = Apply (VE val) (  e)"
| "Ite  e1 e2  e = Ite (  e) e1 e2"
| "Ref   e = Ref (  e)"
| "Read   e = Read (  e)"
| "AssignL  e1  e = Assign (  e) e1"
| "AssignR l   e = Assign (VE (Loc l)) (  e)"
| "Rjoin   e = Rjoin (  e)"

translations
  "[x]"  "  x"

lemma injective_cntxt [simp]: "([e1] = [e2]) = (e1 = e2)" by (induction ) auto

lemma VE_empty_cntxt [simp]: "(VE v = [e]) = ( =   VE v = e)" by (cases , auto) 

inductive redex :: "('r,'l,'v) expr  bool" where
  app: "redex (Apply (VE (Lambda x e)) (VE v))"
| iteTrue: "redex (Ite (VE (CV T)) e1 e2)"
| iteFalse: "redex (Ite (VE (CV F)) e1 e2)"
| ref: "redex (Ref (VE v))"
| read: "redex (Read (VE (Loc l)))"
| assign: "redex (Assign (VE (Loc l)) (VE v))"
| rfork: "redex (Rfork e)"
| rjoin: "redex (Rjoin (VE (Rid r)))"

inductive_simps redex_simps [simp]: "redex e"
inductive_cases redexE [elim]: "redex e"

lemma plugged_redex_not_val [simp]: "redex r  (  r)  (VE t)" by (cases ) auto

inductive decompose :: "('r,'l,'v) expr  ('r,'l,'v) cntxt  ('r,'l,'v) expr  bool" where
  top_redex: "redex e  decompose e  e"
| lapply: " ¬redex (Apply e1 e2); decompose e1  r   decompose (Apply e1 e2) (ApplyL  e2) r"
| rapply: " ¬redex (Apply (VE v) e); decompose e  r   decompose (Apply (VE v) e) (ApplyR v ) r"
| ite: " ¬redex (Ite e1 e2 e3); decompose e1  r   decompose (Ite e1 e2 e3) (Ite  e2 e3) r"
| ref: " ¬redex (Ref e); decompose e  r   decompose (Ref e) (Ref ) r"
| read: " ¬redex (Read e); decompose e  r   decompose (Read e) (Read ) r"
| lassign: " ¬redex (Assign e1 e2); decompose e1  r   decompose (Assign e1 e2) (AssignL  e2) r"
| rassign: " ¬redex (Assign (VE (Loc l)) e2); decompose e2  r   decompose (Assign (VE (Loc l)) e2) (AssignR l ) r"
| rjoin:  " ¬redex (Rjoin e); decompose e  r   decompose (Rjoin e) (Rjoin ) r"

inductive_cases decomposeE [elim]: "decompose e  r"

lemma plug_decomposition_equivalence: "redex r  decompose e  r = ([r] = e)"
proof (rule iffI)
  assume x: "decompose e  r"
  show "[r] = e" 
  proof (use x in induct rule: decompose.induct)
    case (top_redex e)
    thus "[e] = e" by simp
  next
    case (lapply e1 e2  r)
    have "(ApplyL  e2) [r] = Apply ([r]) e2" by simp
    also have "... = Apply e1 e2" using [r] = e1 by simp
    then show ?case by simp
  qed simp+
next
  assume red: "redex r" and  eq: "[r] = e"
  have "decompose ([r])  r" by (induct ) (use red in auto intro: decompose.intros)
  thus "decompose e  r" by (simp add: eq)
qed

lemma unique_decomposition: "decompose e 1 r1  decompose e 2 r2  1 = 2  r1 = r2"
  by (induct arbitrary: 2 rule: decompose.induct) auto

lemma completion_eq [simp]:
  assumes
    red_e: "redex r" and
    red_e': "redex r'"
  shows "([r] = ℰ'[r']) = ( = ℰ'  r = r')"
proof (rule iffI)
  show "[r] = ℰ'[r']   = ℰ'  r = r'"
  proof (rule conjI)
    assume eq: "[r] = ℰ'[r']"
    have "decompose ([r])  r" using plug_decomposition_equivalence red_e by blast
    hence fst_decomp:"decompose (ℰ'[r'])  r" by (simp add: eq)
    have snd_decomp: "decompose (ℰ'[r']) ℰ' r'" using plug_decomposition_equivalence red_e' by blast
    show cntxts_eq: " = ℰ'" using fst_decomp snd_decomp unique_decomposition by blast
    show "r = r'" using cntxts_eq eq by simp
  qed
qed simp

subsection ‹Stores and states›

type_synonym ('r,'l,'v) store = "'l  ('r,'l,'v) val"
type_synonym ('r,'l,'v) local_state = "('r,'l,'v) store × ('r,'l,'v) store × ('r,'l,'v) expr"
type_synonym ('r,'l,'v) global_state = "'r  ('r,'l,'v) local_state"

fun doms :: "('r,'l,'v) local_state  'l set" where
  "doms (σ,τ,e) = dom σ  dom τ"

fun LID_snapshot :: "('r,'l,'v) local_state  ('r,'l,'v) store" (‹_σ 200) where
  "LID_snapshot (σ,τ,e) = σ"

fun LID_local_store :: "('r,'l,'v) local_state  ('r,'l,'v) store" (‹_τ 200) where
  "LID_local_store (σ,τ,e) = τ"

fun LID_expression :: "('r,'l,'v) local_state  ('r,'l,'v) expr" (‹_e 200) where
  "LID_expression (σ,τ,e) = e"

end