Theory Export_Code

theory Export_Code
imports LTL_Compat LTL_Rabin_Impl Rewriting Code_Target_Numeral
(*  
    Author:      Salomon Sickert
    License:     BSD
*)

section ‹Code Generation›

theory Export_Code
  imports Main LTL_Compat LTL_Rabin_Impl 
    "HOL-Library.AList_Mapping" (* Future, Performance: Replace by LC *) 
    LTL.Rewriting
    "HOL-Library.Code_Target_Numeral" 
begin

subsection ‹External Interface›

― ‹Fix the type to match the type of the LTL parser›

definition 
  "ltlc_to_rabin eager mode (φc :: String.literal ltlc) ≡
    (let
      φn = ltlc_to_ltln φc;
      Σ = map set (subseqs (atoms_list φn));
      φ = ltln_to_ltl (simplify mode φn)
     in
      (if eager then ltl_to_generalized_rabinC_af𝔘 Σ φ else ltl_to_generalized_rabinC_af Σ φ))"

theorem ltlc_to_rabin_exec_correct:
  assumes "range w ⊆ Pow (atoms_ltlc φc)"
  shows "w ⊨c φc ⟷ acceptGR_LTS (ltlc_to_rabin eager mode φc) w" 
  (is "?lhs = ?rhs")
proof -
  let n = "ltlc_to_ltln φc"
  let  = "map set (subseqs (atoms_list ?φn))"
  let  = "ltln_to_ltl (simplify mode ?φn)"

  have "set ?Σ = Pow (atoms_ltln ?φn)"
    unfolding atoms_list_correct[symmetric] subseqs_powset[symmetric] list.set_map ..  
  hence R: "range w ⊆ set ?Σ"
    using assms ltlc_to_ltln_atoms[symmetric] by metis

  have "w ⊨c φc ⟷ w ⊨ ?φ"
    by (simp only: ltlc_to_ltln_semantics simplify_correct ltln_to_ltl_semantics)
  also
  have "… ⟷ ?rhs"
    using ltl_to_generalized_rabinC_af𝔘_correct[OF R] ltl_to_generalized_rabinC_af_correct[OF R] 
    unfolding ltlc_to_rabin_def Let_def by auto
  finally
  show ?thesis
    by simp
qed

subsection ‹Normalize Equivalence Classes During DFS-Search›

fun norm_rep
where
  "norm_rep (i, (q, ν, p)) (q', ν', p') = (
    let 
      eq_q = (q = q'); eq_p = (p = p');
      q'' = if eq_q then q' else if q = p' then p' else q;
      p'' = if eq_p then p' else if p = q' then q' else p
    in 
      (i | (eq_q & eq_p & ν = ν'), q'', ν, p''))"

fun norm_fold :: "('a, 'b) transition ⇒ ('a, 'b) transition list ⇒ (bool * 'a * 'b * 'a)"
where
  "norm_fold (q, ν, p) xs = foldl_break norm_rep fst (False, q, ν, if q = p then q else p) xs"

definition norm_insert :: "('a, 'b) transition ⇒ ('a, 'b) transition list ⇒ (bool * ('a, 'b) transition list)"
where
  "norm_insert x xs ≡ let (i, x') = norm_fold x xs in if i then (i, xs) else (i, x' # xs)" 

lemma norm_fold:
  "norm_fold (q, ν, p) xs = ((q, ν, p) ∈ set xs, q, ν, p)"
proof (induction xs rule: rev_induct)
  case (snoc x xs)
    obtain q' ν' p' where x_def: "x = (q', ν', p')"
      by (blast intro: prod_cases3)
    show ?case
      using snoc by (auto simp add: x_def foldl_break_append)
qed simp  

lemma norm_insert: 
  "norm_insert x xs = (x ∈ set xs, List.insert x xs)"
proof -
  obtain q ν p where x_def: "x = (q, ν, p)"
    by (blast intro: prod_cases3)
  show ?thesis
    unfolding x_def norm_insert_def norm_fold by simp
qed
 
declare list_dfs_def [code del]
declare norm_insert_def [code_unfold]

lemma list_dfs_norm_insert [code]: 
  "list_dfs succ S [] = S"
  "list_dfs succ S (x # xs) = (let (memb, S') = norm_insert x S in list_dfs succ S' (if memb then xs else succ x @ xs))"
  unfolding list_dfs_def Let_def norm_insert by simp+ 

subsection ‹Register Code Equations›

lemma [code]:
  "↑Δ× f (AList_Mapping.Mapping xs) c = AList_Mapping.Mapping (map_ran (λa b. f a b c) xs)"
proof -
  have "⋀x. (Δ× f (map_of xs) c) x = (map_of (map (λ(k, v). (k, f k v c)) xs)) x"
    by (induction xs) auto
  thus ?thesis
    by (transfer; simp add: map_ran_def)
qed

lemmas ltl_to_rabin_base_code_export [code, code_unfold] =
  ltl_to_rabin_base_code_def.ltl_to_generalized_rabinC.simps
  ltl_to_rabin_base_code_def.reachable_transitionsC_def 
  ltl_to_rabin_base_code_def.mappingsC_code 
  ltl_to_rabin_base_code_def.deltaC.simps
  ltl_to_rabin_base_code_def.initialC.simps 
  ltl_to_rabin_base_code_def.Acc_infC.simps 
  ltl_to_rabin_base_code_def.Acc_finC.simps
  ltl_to_rabin_base_code_def.max_rank_ofC_def

lemmas M_finC_lhs [code del, code_unfold] = 
  M_finC_af𝔘_lhs_def M_finC_af_lhs_def 

― ‹Test code export›
export_code truec Iff_ltlc Nop true Abs AList_Mapping.Mapping set ltlc_to_rabin checking

― ‹Export translator (and also constructors)›
export_code truec Iff_ltlc Nop true Abs AList_Mapping.Mapping set ltlc_to_rabin 
  in SML module_name LTL file ‹../Code/LTL_to_DRA_Translator.sml›

end