Theory VC_KAD_dual

(* Title: Verification Component Based on KAD for Forward Reasoning
   Author: Victor Gomes, Georg Struth
   Maintainer: Victor Gomes <victor.gomes@cl.cam.ac.uk>
               Georg Struth <g.struth@sheffield.ac.uk> 
*)

subsection‹Verification Component for Forward Reasoning›

theory VC_KAD_dual
  imports VC_KAD
begin

context modal_kleene_algebra
begin

text ‹This component supports the verification of simple while programs
in a partial correctness setting.›

subsubsection ‹Basic Strongest Postcondition Calculus›

text ‹In modal Kleene algebra, strongest postconditions are backward diamond operators. These
are linked with forward boxes aka weakest preconditions by a Galois connection.  This duality has been
implemented in the AFP entry for Kleene algebra with domain and is picked up automatically in
the following proofs.›

lemma r_ad [simp]: "r (ad p) = ad p"
  using a_closure addual.ars_r_def am_d_def domrangefix by auto

lemma bdia_export1: "x| (r p  r t) = r t  x| p"
  by (metis ardual.ads_d_def ardual.ds.ddual.rsr2 ardual.ds.fdia_mult bdia_def)

lemma bdia_export2: "r p  x| q = x  r p| q"
  using ardual.ads_d_def ardual.am2 ardual.fdia_export_2 bdia_def by auto

lemma bdia_seq [simp]: "x  y| q = y| x| q"
  by (simp add: ardual.ds.fdia_mult)

lemma bdia_seq_var: "x| p  p'  y| p'  q  x  y| p  q"
  by (metis ardual.ds.fd_subdist_1 ardual.ds.fdia_mult dual_order.trans join.sup_absorb2)

lemma bdia_cond_var [simp]: "if p then x else y fi| q = x| (d p  r q) + y| (ad p  r q)"
  by (metis (no_types, lifting) bdia_export1 a4' a_de_morgan a_de_morgan_var_3 a_subid_aux1' ardual.ds.fdia_add2 dka.dnso1 dka.dsg4 domrange dpdz.dnso1 cond_def join.sup.absorb_iff1 rangedom)

lemma bdia_while: "x| (d t  r p)  r p   while t do x od| p  r p  ad t"
proof -
  assume "x| (d t  r p)  r p"
  hence "d t  x| p  r p"
    by (metis bdia_export1 dka.dsg4 domrange rangedom)
  hence "(d t  x)| p  r p"
    by (meson ardual.fdemodalisation22 ardual.kat_2_equiv_opp star_sim1)
  hence "r (ad t)  (d t  x)| p  r p  ad t"
    by (metis ardual.dpdz.dsg4 ars_r_def mult_isol r_ad)
  thus ?thesis
    by (metis bdia_export2 while_def r_ad)
qed

lemma bdia_whilei: "r p  r i  r i  ad t  r q  x| (d t  r i)  r i  while t inv i do x od| p  r q"
proof -
  assume a1: "r p  r i" and a2: "r i  ad t  r q" and "x| (d t  r i)  r i"
  hence "while t inv i do x od| i  r i  ad t"
    by (simp add: bdia_while whilei_def)
  hence "while t inv i do x od| i  r q"
    using a2 dual_order.trans by blast
  hence "r i  |while t inv i do x od] r q"
    using ars_r_def box_diamond_galois_1 domrange by fastforce
  hence "r p  |while t inv i do x od] r q"
    using a1 dual_order.trans by blast
  thus ?thesis
    using ars_r_def box_diamond_galois_1 domrange by fastforce
qed

lemma bdia_whilei_break: "y| p  r i  r i  ad t  r q  x| (d t  r i)  r i  y  (while t inv i do x od)| p  r q"
  using bdia_whilei ardual.ads_d_def ardual.ds.fdia_mult bdia_def by auto
 
end

subsubsection ‹Floyd's Assignment Rule›

lemma bdia_assign [simp]: "rel_antirange_kleene_algebra.bdia (v ::= e) P = λs. w. s v = e (s(v := w))  P (s(v:=w))"
  apply (simp add: rel_antirange_kleene_algebra.bdia_def gets_def p2r_def rel_ar_def)
  apply safe
  by (metis fun_upd_apply fun_upd_triv fun_upd_upd, fastforce)

lemma d_p2r [simp]: "rel_antirange_kleene_algebra.ars_r  P = P"
  by (simp add: p2r_def rel_antirange_kleene_algebra.ars_r_def rel_ar_def)

abbreviation fspec_sugar :: "'a pred  'a rel  'a pred  bool" ("FPRE _ _ POST _" [64,64,64] 63) where
  "FPRE P X POST Q  rel_antirange_kleene_algebra.bdia X P  rel_antirange_kleene_algebra.ars_r Q"

end