Theory J1Deadlock

(*  Title:      JinjaThreads/Compiler/J1Deadlock.thy
    Author:     Andreas Lochbihler
*)

section ‹Deadlock perservation for the intermediate language›

theory J1Deadlock imports
  J1
  "../Framework/FWDeadlock"
  "../Common/ExternalCallWF"
begin

context J1_heap_base begin

lemma IUF_red_taD:
  "True,P,t ⊢1 e, s -ta e', s'
   e' ta' s'. False,P,t ⊢1 e, s -ta' e', s' 
     collect_locks ta'l  collect_locks tal  set ta'c  set tac  collect_interrupts ta'i  collect_interrupts tai 
     (s. Red1_mthr.actions_ok s t ta')"

  and IUFs_reds_taD:
  "True,P,t ⊢1 es, s [-ta→] es', s'
   es' ta' s'. False,P,t ⊢1 es, s [-ta'→] es', s' 
     collect_locks ta'l  collect_locks tal  set ta'c  set tac  collect_interrupts ta'i  collect_interrupts tai 
     (s. Red1_mthr.actions_ok s t ta')"
proof(induct rule: red1_reds1.inducts)
  case Red1InstanceOf thus ?case
    using [[hypsubst_thin = true]]
    by(auto intro!: exI red1_reds1.Red1InstanceOf simp del: split_paired_Ex)((subst fst_conv snd_conv wset_def)+, simp)
next
  case Red1CallExternal thus ?case
    by(fastforce simp del: split_paired_Ex dest: red_external_ta_satisfiable[where final="final_expr1 :: ('addr expr1 × 'addr val list) × ('addr expr1 × 'addr val list) list  bool"] intro: red1_reds1.Red1CallExternal)
next
  case Lock1Synchronized thus ?case
    by(auto intro!: exI exI[where x="(K$ None, (Map.empty, undefined), Map.empty, {})"] red1_reds1.Lock1Synchronized simp del: split_paired_Ex simp add: lock_ok_las_def finfun_upd_apply may_lock.intros(1))
next
  case (Synchronized1Red2 e s ta e' s' V a)
  then obtain e' ta' s'
    where "False,P,t ⊢1 e,s -ta' e',s'"
    and L: "collect_locks ta'l  collect_locks tal  set ta'c  set tac  collect_interrupts ta'i  collect_interrupts tai"
    and aok: "s. Red1_mthr.actions_ok s t ta'"
    by blast
  from False,P,t ⊢1 e,s -ta' e',s' have "False,P,t ⊢1 insync⇘V(a) e, s -ta' insync⇘V(a) e', s'"
    by(rule red1_reds1.Synchronized1Red2)
  thus ?case using L aok by blast
next
  case Unlock1Synchronized thus ?case
    by(auto simp del: split_paired_Ex intro!: exI exI[where x="(K$ (t, 0), (Map.empty, undefined), Map.empty, {})"] red1_reds1.Unlock1Synchronized simp add: lock_ok_las_def finfun_upd_apply)
next
  case Unlock1SynchronizedFail thus ?case
    by(auto simp del: split_paired_Ex intro!: exI exI[where x="(K$ (t, 0), (Map.empty, undefined), Map.empty, {})"] red1_reds1.Unlock1Synchronized simp add: lock_ok_las_def finfun_upd_apply collect_locks_def split: if_split_asm)
next
  case Synchronized1Throw2 thus ?case
    by(auto simp del: split_paired_Ex intro!: exI exI[where x="(K$ (t, 0), (Map.empty, undefined), Map.empty, {})"] red1_reds1.Synchronized1Throw2 simp add: lock_ok_las_def finfun_upd_apply)
next
  case Synchronized1Throw2Fail thus ?case
    by(auto simp del: split_paired_Ex intro!: exI exI[where x="(K$ (t, 0), (Map.empty, undefined), Map.empty, {})"] red1_reds1.Synchronized1Throw2 simp add: lock_ok_las_def finfun_upd_apply collect_locks_def split: if_split_asm)
qed(fastforce intro: red1_reds1.intros)+

lemma IUF_Red1_taD:
  assumes "True,P,t ⊢1 ex/exs, h -ta ex'/exs', h'"
  shows "ex' exs' h' ta'. False,P,t ⊢1 ex/exs, h -ta' ex'/exs', h' 
     collect_locks ta'l  collect_locks tal  set ta'c  set tac  collect_interrupts ta'i  collect_interrupts tai 
     (s. Red1_mthr.actions_ok s t ta')"
using assms
apply(cases)
apply(safe dest!: IUF_red_taD)
  apply(simp del: split_paired_Ex)
  apply(rule exI conjI)+
  apply(erule red1Red)
  apply simp
  apply blast
 apply(rule exI conjI red1Call)+
 apply(auto simp add: lock_ok_las_def)
apply(rule exI conjI red1Return)+
apply auto
done

lemma mred1'_mred1_must_sync_eq:
  "Red1_mthr.must_sync False P t x (shr s) = Red1_mthr.must_sync True P t x (shr s)"
proof
  assume "Red1_mthr.must_sync False P t x (shr s)"
  thus "Red1_mthr.must_sync True P t x (shr s)"
    by(rule Red1_mthr.must_syncE)(rule Red1_mthr.must_syncI, auto simp add: split_def simp del: split_paired_Ex intro: Red1_False_into_Red1_True)
next
  assume "Red1_mthr.must_sync True P t x (shr s)"
  thus "Red1_mthr.must_sync False P t x (shr s)"
    apply(rule Red1_mthr.must_syncE)
    apply(rule Red1_mthr.must_syncI)
    apply(cases x)
    apply(auto simp add: split_beta split_paired_Ex)
    apply(drule IUF_Red1_taD)
    apply simp
    apply blast
    done
qed

lemma Red1_Red1'_deadlock_inv:
  "Red1_mthr.deadlock True P s = Red1_mthr.deadlock False P s"
proof(rule iffI)
  assume dead: "Red1_mthr.deadlock True P s"
  show "Red1_mthr.deadlock False P s"
  proof(rule multithreaded_base.deadlockI)
    fix t x
    assume tst: "thr s t = (x, no_wait_locks)"
      and nfin: "¬ final_expr1 x"
      and wst: "wset s t = None"
    with dead obtain ms: "Red1_mthr.must_sync True P t x (shr s)"
      and cs [rule_format]: "LT. Red1_mthr.can_sync True P t x (shr s) LT 
               (ltLT. final_thread.must_wait final_expr1 s t lt (dom (thr s)))"
      by(rule Red1_mthr.deadlockD1)
    from ms[folded mred1'_mred1_must_sync_eq]
    show "Red1_mthr.must_sync False P t x (shr s) 
             (LT. Red1_mthr.can_sync False P t x (shr s) LT 
                   (ltLT. final_thread.must_wait final_expr1 s t lt (dom (thr s))))"
    proof
      show "LT. Red1_mthr.can_sync False P t x (shr s) LT 
         (ltLT. final_thread.must_wait final_expr1 s t lt (dom (thr s)))"
      proof(intro strip)
        fix LT
        assume "Red1_mthr.can_sync False P t x (shr s) LT"
        then obtain ta x' m' where "mred1' P t (x, shr s) ta (x', m')" 
          and [simp]: "LT = collect_locks tal <+> collect_cond_actions tac <+> collect_interrupts tai"
          by(rule Red1_mthr.can_syncE)
        hence "mred1 P t (x, shr s) ta (x', m')" by(auto simp add: split_beta intro: Red1_False_into_Red1_True)
        hence "Red1_mthr.can_sync True P t x (shr s) LT" by(rule Red1_mthr.can_syncI) simp
        thus "ltLT. final_thread.must_wait final_expr1 s t lt (dom (thr s))" by(rule cs)
      qed
    qed
  next
    fix t x ln l
    assume "thr s t = (x, ln)" "0 < ln $ l" "¬ waiting (wset s t)"
    thus "l t'. 0 < ln $ l  t  t'  thr s t'  None  has_lock ((locks s) $ l) t'"
      by(rule Red1_mthr.deadlockD2[OF dead]) blast
  next
    fix t x w
    assume "thr s t = (x, no_wait_locks)"
    thus "wset s t  PostWS w"
      by(rule Red1_mthr.deadlockD3[OF dead, rule_format])
  qed
next
  assume dead: "Red1_mthr.deadlock False P s"
  show "Red1_mthr.deadlock True P s"
  proof(rule Red1_mthr.deadlockI)
    fix t x
    assume tst: "thr s t = (x, no_wait_locks)"
      and nfin: "¬ final_expr1 x"
      and wst: "wset s t = None"
    with dead obtain ms: "Red1_mthr.must_sync False P t x (shr s)"
      and cs [rule_format]: "LT. Red1_mthr.can_sync False P t x (shr s) LT 
               (ltLT. final_thread.must_wait final_expr1 s t lt (dom (thr s)))"
      by(rule Red1_mthr.deadlockD1)
    from ms[unfolded mred1'_mred1_must_sync_eq]
    show "Red1_mthr.must_sync True P t x (shr s) 
             (LT. Red1_mthr.can_sync True P t x (shr s) LT 
                   (ltLT. final_thread.must_wait final_expr1 s t lt (dom (thr s))))"
    proof
      show "LT. Red1_mthr.can_sync True P t x (shr s) LT 
         (ltLT. final_thread.must_wait final_expr1 s t lt (dom (thr s)))"
      proof(intro strip)
        fix LT
        assume "Red1_mthr.can_sync True P t x (shr s) LT"
        then obtain ta x' m' where "mred1 P t (x, shr s) ta (x', m')" 
          and [simp]: "LT = collect_locks tal <+> collect_cond_actions tac <+> collect_interrupts tai"
          by(rule Red1_mthr.can_syncE)
        then obtain e xs exs e' xs' exs' where x [simp]: "x = ((e, xs), exs)" "x' = ((e', xs'), exs')"
          and red: "True,P,t ⊢1 (e, xs)/exs, shr s -ta (e', xs')/exs', m'" by(cases x, cases x') fastforce
        from IUF_Red1_taD[OF red] obtain ex'' exs'' h'' ta' 
          where red': "False,P,t ⊢1 (e, xs)/exs,shr s -ta' ex''/exs'',h''"
          and "collect_locks ta'l <+> collect_cond_actions ta'c <+> collect_interrupts ta'i  collect_locks tal <+> collect_cond_actions tac <+> collect_interrupts tai"
          by auto blast
        then obtain LT' where cs': "Red1_mthr.can_sync False P t x (shr s) LT'" 
          and LT': "LT'  LT" by(cases ex'')(fastforce intro!: Red1_mthr.can_syncI)
        with cs[of LT'] show "ltLT. final_thread.must_wait final_expr1 s t lt (dom (thr s))" by auto
      qed
    qed
  next
    fix t x ln l
    assume "thr s t = (x, ln)" "0 < ln $ l" "¬ waiting (wset s t)"
    thus "l t'. 0 < ln $ l  t  t'  thr s t'  None  has_lock ((locks s) $ l) t'"
      by(rule Red1_mthr.deadlockD2[OF dead]) blast
  next
    fix t x w
    assume "thr s t = (x, no_wait_locks)"
    thus "wset s t  PostWS w"
      by(rule Red1_mthr.deadlockD3[OF dead, rule_format])
  qed
qed

end

end