Theory FWProgressAux

(*  Title:      JinjaThreads/Framework/FWProgressAux.thy
    Author:     Andreas Lochbihler
*)

section ‹Auxiliary definitions for the progress theorem for the multithreaded semantics›

theory FWProgressAux
imports
  FWSemantics
begin

abbreviation collect_waits :: "('l,'t,'x,'m,'w,'o) thread_action  ('l + 't + 't) set"
where "collect_waits ta  collect_locks tal <+> collect_cond_actions tac <+> collect_interrupts tai"

lemma collect_waits_unfold:
  "collect_waits ta = {l. Lock  set (tal $ l)} <+> {t. Join t  set tac} <+> collect_interrupts tai"
by(simp add: collect_locks_def)

context multithreaded_base begin

definition must_sync :: "'t  'x  'm  bool" (‹_  _,/ _/  [50, 0,0] 81) where
  "t  x, m   (ta x' m' s. t  x, m -ta x', m'  shr s = m  actions_ok s t ta)"

lemma must_sync_def2:
  "t  x, m   (ta x' m' s. t  x, m -ta x', m'  actions_ok s t ta)"
by(fastforce simp add: must_sync_def intro: cond_action_oks_shr_change)

lemma must_syncI:
  "ta x' m' s. t  x, m -ta x', m'  actions_ok s t ta  t  x, m "
by(fastforce simp add: must_sync_def2)

lemma must_syncE:
  " t  x, m ; ta x' m' s.  t  x, m -ta x', m'; actions_ok s t ta; m = shr s   thesis   thesis"
by(fastforce simp only: must_sync_def)

definition can_sync :: "'t  'x  'm  ('l + 't + 't) set  bool" (‹_  _,/ _/ _/  [50,0,0,0] 81) where
  "t  x, m LT   ta x' m'. t  x, m -ta x', m'  (LT = collect_waits ta)"

lemma can_syncI:
  " t  x, m -ta x', m';
     LT = collect_waits ta 
   t  x, m LT "
by(cases ta)(fastforce simp add: can_sync_def)

lemma can_syncE:
  assumes "t  x, m LT "
  obtains ta x' m'
  where "t  x, m -ta x', m'"
  and "LT = collect_waits ta"
  using assms
by(clarsimp simp add: can_sync_def)

inductive_set active_threads :: "('l,'t,'x,'m,'w) state  't set"
for s :: "('l,'t,'x,'m,'w) state"
where
  normal:
  "ln.  thr s t = Some (x, ln);
     ln = no_wait_locks;
     t  (x, shr s) -ta x'm';
     actions_ok s t ta 
   t  active_threads s"
| acquire: 
  "ln.  thr s t = Some (x, ln);
     ln  no_wait_locks;
     ¬ waiting (wset s t);
     may_acquire_all (locks s) t ln 
   t  active_threads s"

lemma active_threads_iff:
  "active_threads s = 
  {t. x ln. thr s t = Some (x, ln) 
             (if ln = no_wait_locks 
              then ta x' m'. t  (x, shr s) -ta (x', m')  actions_ok s t ta
              else ¬ waiting (wset s t)  may_acquire_all (locks s) t ln)}"
apply(auto elim!: active_threads.cases intro: active_threads.intros)
apply blast
done

lemma active_thread_ex_red:
  assumes "t  active_threads s"
  shows "ta s'. s -tta s'"
using assms
proof cases
  case (normal x ta x'm' ln)
  with redT_updWs_total[of t "wset s" "taw"]
  show ?thesis
    by(cases x'm')(fastforce intro!: redT_normal simp del: split_paired_Ex)
next
  case acquire thus ?thesis
    by(fastforce intro: redT_acquire simp del: split_paired_Ex simp add: neq_no_wait_locks_conv)
qed

end

text ‹Well-formedness conditions for final›

context final_thread begin

inductive not_final_thread :: "('l,'t,'x,'m,'w) state  't  bool"
for s :: "('l,'t,'x,'m,'w) state" and t :: "'t" where
  not_final_thread_final: "ln.  thr s t = (x, ln); ¬ final x   not_final_thread s t"
| not_final_thread_wait_locks: "ln.  thr s t = (x, ln); ln  no_wait_locks   not_final_thread s t"
| not_final_thread_wait_set: "ln.  thr s t = (x, ln); wset s t = w   not_final_thread s t"


declare not_final_thread.cases [elim]

lemmas not_final_thread_cases = not_final_thread.cases [consumes 1, case_names final wait_locks wait_set]

lemma not_final_thread_cases2 [consumes 2, case_names final wait_locks wait_set]:
  "ln.  not_final_thread s t; thr s t = (x, ln);
     ¬ final x  thesis; ln  no_wait_locks  thesis; w. wset s t = w  thesis 
   thesis"
by(auto)

lemma not_final_thread_iff:
  "not_final_thread s t  (x ln. thr s t = (x, ln)  (¬ final x  ln  no_wait_locks  (w. wset s t = w)))"
by(auto intro: not_final_thread.intros)

lemma not_final_thread_conv:
  "not_final_thread s t  thr s t  None  ¬ final_thread s t"
by(auto simp add: final_thread_def intro: not_final_thread.intros)

lemma not_final_thread_existsE:
  assumes "not_final_thread s t"
  and "x ln. thr s t = (x, ln)  thesis"
  shows thesis
using assms by blast

lemma not_final_thread_final_thread_conv:
  "thr s t  None  ¬ final_thread s t  not_final_thread s t"
by(simp add: not_final_thread_iff final_thread_def)

lemma may_join_cond_action_oks:
  assumes "t'. Join t'  set cas  ¬ not_final_thread s t'  t  t'"
  shows "cond_action_oks s t cas"
using assms
proof (induct cas)
  case Nil thus ?case by clarsimp
next
  case (Cons ca cas)
  note IH =  t'. Join t'  set cas  ¬ not_final_thread s t'  t  t' 
              cond_action_oks s t cas
  note ass = t'. Join t'  set (ca # cas)  ¬ not_final_thread s t'  t  t'
  hence "t'. Join t'  set cas  ¬ not_final_thread s t'  t  t'" by simp
  hence "cond_action_oks s t cas" by(rule IH)
  moreover have "cond_action_ok s t ca"
  proof(cases ca)
    case (Join t')
    with ass have "¬ not_final_thread s t'" "t  t'" by auto
    thus ?thesis using Join by(auto simp add: not_final_thread_iff)
  next
    case Yield thus ?thesis by simp
  qed
  ultimately show ?case by simp
qed

end

context multithreaded begin

lemma red_not_final_thread:
  "s -tta s'  not_final_thread s t"
by(fastforce elim: redT.cases intro: not_final_thread.intros dest: final_no_red)

lemma redT_preserves_final_thread:
  " s -t'ta s'; final_thread s t   final_thread s' t"
apply(erule redT.cases)
 apply(clarsimp simp add: final_thread_def)
apply(auto simp add: final_thread_def dest: redT_updTs_None redT_updTs_Some final_no_red intro: redT_updWs_None_implies_None)
done

end

context multithreaded_base begin

definition wset_Suspend_ok :: "('l,'t,'x,'m,'w) state set  ('l,'t,'x,'m,'w) state set"
where
  "wset_Suspend_ok I = 
  {s. s  I  
      (t  dom (wset s). s0I. s1I. ttas x x0 ta w' ln' ln''. s0 -tta s1  s1 -▹ttas→* s  
           thr s0 t = (x0, no_wait_locks)  t  x0, shr s0 -ta x, shr s1  Suspend w'  set taw 
           actions_ok s0 t ta  thr s1 t = (x, ln')  thr s t = (x, ln''))}"

lemma wset_Suspend_okI:
  " s  I;
     t w. wset s t = w  s0I. s1I. ttas x x0 ta w' ln' ln''. s0 -tta s1  s1 -▹ttas→* s  
           thr s0 t = (x0, no_wait_locks)  t  x0, shr s0 -ta x, shr s1  Suspend w'  set taw 
           actions_ok s0 t ta  thr s1 t = (x, ln')  thr s t = (x, ln'') 
   s  wset_Suspend_ok I"
unfolding wset_Suspend_ok_def by blast

lemma wset_Suspend_okD1:
  "s  wset_Suspend_ok I  s  I"
unfolding wset_Suspend_ok_def by blast

lemma wset_Suspend_okD2:
  " s  wset_Suspend_ok I; wset s t = w 
   s0I. s1I. ttas x x0 ta w' ln' ln''. s0 -tta s1  s1 -▹ttas→* s  
            thr s0 t = (x0, no_wait_locks)  t  x0, shr s0 -ta x, shr s1  Suspend w'  set taw 
            actions_ok s0 t ta  thr s1 t = (x, ln')  thr s t = (x, ln'')"
unfolding wset_Suspend_ok_def by blast

lemma wset_Suspend_ok_imp_wset_thread_ok:
  "s  wset_Suspend_ok I  wset_thread_ok (wset s) (thr s)"
apply(rule wset_thread_okI)
apply(rule ccontr)
apply(auto dest: wset_Suspend_okD2)
done

lemma invariant3p_wset_Suspend_ok:
  assumes I: "invariant3p redT I"
  shows "invariant3p redT (wset_Suspend_ok I)"
proof(rule invariant3pI)
  fix s tl s'
  assume wso: "s  wset_Suspend_ok I" 
    and "redT s tl s'"
  moreover obtain t' ta where tl: "tl = (t', ta)" by(cases tl)
  ultimately have red: "s -t'ta s'" by simp 
  moreover from wso have "s  I" by(rule wset_Suspend_okD1)
  ultimately have "s'  I" by(rule invariant3pD[OF I])
  thus "s'  wset_Suspend_ok I"
  proof(rule wset_Suspend_okI)
    fix t w
    assume ws't: "wset s' t = w"
    show "s0I. s1I. ttas x x0 ta w' ln' ln''. s0 -tta s1  s1 -▹ttas→* s' 
                   thr s0 t = (x0, no_wait_locks)  t  x0, shr s0 -ta x, shr s1 
                   Suspend w'  set taw  actions_ok s0 t ta 
                   thr s1 t = (x, ln')  thr s' t = (x, ln'')"
    proof(cases "t = t'")
      case False
      with red ws't obtain w' where wst: "wset s t = w'"
        by cases(auto 4 4 dest: redT_updWs_Some_otherD split: wait_set_status.split_asm)
      from wset_Suspend_okD2[OF wso this] obtain s0 s1 ttas x x0 ta' w' ln' ln''
        where reuse: "s0  I" "s1  I" "s0 -tta' s1" "thr s0 t = (x0, no_wait_locks)"
          "t  x0, shr s0 -ta' x, shr s1" "Suspend w'  set ta'w" "actions_ok s0 t ta'" "thr s1 t = (x, ln')"
        and step: "s1 -▹ttas→* s" and tst: "thr s t = (x, ln'')" by blast
      from step red have "s1 -▹ttas@[(t', ta)]→* s'" unfolding RedT_def by(rule rtrancl3p_step)
      moreover from red tst False have "thr s' t = (x, ln'')"
        by(cases)(auto intro: redT_updTs_Some)
      ultimately show ?thesis using reuse by blast
    next
      case True
      from red show ?thesis
      proof(cases)
        case (redT_normal x x' m)
        note red' = t'  x, shr s -ta x', m
          and tst' = thr s t' = (x, no_wait_locks)
          and aok = actions_ok s t' ta
          and s' = redT_upd s t' ta x' m s'
        from s' have ws': "redT_updWs t' (wset s) taw (wset s')"
          and m: "m = shr s'" 
          and ts't: "thr s' t' = (x', redT_updLns (locks s) t' (snd (the (thr s t'))) tal)" by auto
        from aok have nwait: "¬ waiting (wset s t')"
          by(auto simp add: wset_actions_ok_def waiting_def split: if_split_asm)
        have "w'. Suspend w'  set taw"
        proof(cases "wset s t")
          case None
          from redT_updWs_None_SomeD[OF ws', OF ws't None] 
          show ?thesis ..
        next
          case (Some w')
          with True aok have "Notified  set taw  WokenUp  set taw"
            by(auto simp add: wset_actions_ok_def split: if_split_asm)
          with ws' show ?thesis using ws't unfolding True
            by(rule redT_updWs_WokenUp_SuspendD)
        qed
        with tst' ts't aok s  I s'  I red red' show ?thesis 
          unfolding True m by blast
      next
        case (redT_acquire x n ln) 
        with ws't True have "wset s t = w" by auto
        from wset_Suspend_okD2[OF wso this] thr s t' = (x, ln) True
        obtain s0 s1 ttas x0 ta' w' ln' ln''
          where reuse: "s0  I" "s1  I" "s0 -tta' s1" "thr s0 t = (x0, no_wait_locks)"
            "t  x0, shr s0 -ta' x, shr s1" "Suspend w'  set ta'w" "actions_ok s0 t ta'" "thr s1 t = (x, ln')"
          and step: "s1 -▹ttas→* s" by fastforce
        from step red have "s1 -▹ttas@[(t', ta)]→* s'" unfolding RedT_def by(rule rtrancl3p_step)
        moreover from redT_acquire True have "thr s' t = (x, no_wait_locks)" by simp
        ultimately show ?thesis using reuse by blast
      qed
    qed
  qed
qed

end

end