Theory TSO_litmus
theory TSO_litmus
imports
"../TSO_Code_Gen"
"HOL-Library.Code_Target_Nat"
begin
subsection‹ A TSO litmus test\label{sec:tso-litmus} ›
text‹
The classic TSO litmus test \<^citet>‹‹\S1› in
"OwensSarkarSewell:2009"›: write buffering allows both threads
to read zero, which is impossible under sequential consistency.
›
definition iwp2_3_a :: "(nat × nat) tso" where
"iwp2_3_a = do {
x ← tso.Ref.ref 0
; y ← tso.Ref.ref 0
; xvr ← tso.Ref.ref 0
; yvr ← tso.Ref.ref 0
; ( ( do { x := 1 ; yv ← !y ; yvr := yv } )
∥ ( do { y := 1 ; xv ← !x ; xvr := xv } ) )
; xv <- !xvr
; yv <- !yvr
; tso.return (xv, yv)
}"
code_thms iwp2_3_a
export_code iwp2_3_a in Haskell
schematic_goal iwp2_3_a:
shows "⦉heap.empty, ?xs, Some (0, 0)⦊ ≤ prog.p2s (tso.t2p iwp2_3_a)"
supply heap.simps[simp]
apply (rule inhabits.I)
unfolding iwp2_3_a_def
apply (simp add: prog.p2s.t2p)
apply (rule inhabits.spec.bind')
apply (rule inhabits.tso.bind')
apply (rule inhabits.tso.Ref.ref[where r="Ref 0"], simp; fail)
apply (simp add: tso.bind.returnL)
apply (rule inhabits.tso.bind')
apply (rule inhabits.tso.Ref.ref[where r="Ref 1"], simp)
apply (simp add: tso.bind.returnL)
apply (rule inhabits.tso.bind')
apply (rule inhabits.tso.Ref.ref[where r="Ref 2"], simp)
apply (simp add: tso.bind.returnL)
apply (rule inhabits.tso.bind')
apply (rule inhabits.tso.Ref.ref[where r="Ref 3"], simp)
apply (simp add: tso.bind.returnL)
apply (rule inhabits.tso.commit')+
apply simp
apply (rule inhabits.tso.bind')
apply (simp add: tso.t2s.parallel prog.p2s.bind prog.p2s.parallel prog.p2s.t2p)
apply (rule inhabits.spec.bind')
apply (rule inhabits.spec.parallelL')
apply (rule inhabits.spec.bind')
apply (rule inhabits.tso.bind')
apply (rule inhabits.tso.Ref.update)
apply (simp add: tso.bind.returnL)
apply (rule inhabits.tso.bind')
apply (rule inhabits.tso.Ref.lookup)
apply (simp add: tso.bind.returnL)
apply (rule inhabits.tso.Ref.update)
apply (rule inhabits.tau)
apply (simp add: spec.idle.bind_le_conv spec.idle.tso.t2s_le; fail)
apply (simp add: spec.bind.mono spec.interference.tso.t2s_le flip: spec.bind.bind; fail)
apply (rule inhabits.spec.parallelR')
apply (rule inhabits.spec.bind')
apply (rule inhabits.tso.bind')
apply (rule inhabits.tso.Ref.update)
apply (simp add: tso.bind.returnL)
apply (rule inhabits.tso.bind')
apply (rule inhabits.tso.Ref.lookup)
apply (simp add: tso.bind.returnL)
apply (rule inhabits.tso.Ref.update)
apply (rule inhabits.tau)
apply (simp add: spec.idle.bind_le_conv spec.idle.tso.t2s_le; fail)
apply (simp add: spec.bind.mono spec.interference.tso.t2s_le flip: spec.bind.bind; fail)
apply clarsimp
apply (rule inhabits.spec.parallelL')
apply (rule inhabits.spec.bind'[OF inhabits.tso.commit])+
apply (simp add: tso.t2s.return split_def prog.bind.returnL raw.MFENCE.Nil flip: prog.p2s.bind)
apply (rule inhabits.tau)
apply (simp add: spec.idle.p2s_le; fail)
apply (simp add: spec.bind.mono spec.interference.tso.t2s_le flip: spec.bind.bind; fail)
apply (rule inhabits.spec.parallelR')
apply (rule inhabits.spec.bind'[OF inhabits.tso.commit])+
apply (simp add: tso.t2s.return split_def prog.bind.returnL raw.MFENCE.Nil flip: prog.p2s.bind)
apply (rule inhabits.tau)
apply (simp add: spec.idle.p2s_le; fail)
apply (simp add: prog.p2s.interference_wind_bind; fail)
apply (simp add: prog.parallel.return flip: prog.p2s.parallel)
apply (rule inhabits.tau)
apply (simp add: spec.idle.p2s_le; fail)
apply (simp add: prog.bind.returnL flip: prog.p2s.bind)
apply (subst tso.t2s.return[symmetric])
apply (rule inhabits.tau)
apply (simp add: spec.idle.tso.t2s_le; fail)
apply (simp add: tso.bind.return)
apply (rule inhabits.tso.bind')
apply (rule inhabits.tso.Ref.lookup)
apply (simp add: Ref.get_def apply_writes_def tso.bind.return)
apply (rule inhabits.tso.bind')
apply (rule inhabits.tso.Ref.lookup)
apply (simp add: Ref.get_def apply_writes_def tso.bind.return tso.t2s.return)
apply (rule inhabits.prog.return)
apply (simp add: spec.bind.returnL spec.idle.p2s_le raw.MFENCE.Nil prog.bind.returnL)
apply (rule inhabits.prog.return)
done
thm iwp2_3_a[simplified apply_writes_def, simplified]
end