Theory LTL_Impl

theory LTL_Impl
imports LTL_FGXU Boolean_Expression_Checkers_AList_Mapping
(*  
    Author:      Salomon Sickert
    License:     BSD
*)

section ‹LTL Code Equations›

theory LTL_Impl
  imports Main 
    "../LTL_FGXU" 
    Boolean_Expression_Checkers.Boolean_Expression_Checkers 
    Boolean_Expression_Checkers.Boolean_Expression_Checkers_AList_Mapping
begin

subsection ‹Subformulae›

fun G_list :: "'a ltl ⇒'a ltl list"
where 
  "G_list (φ and ψ) = List.union (G_list φ) (G_list ψ)"
| "G_list (φ or ψ) = List.union (G_list φ) (G_list ψ)"
| "G_list (F φ) = G_list φ"
| "G_list (G φ) = List.insert (G φ) (G_list φ)"
| "G_list (X φ) = G_list φ"
| "G_list (φ U ψ) = List.union (G_list φ) (G_list ψ)"
| "G_list φ = []"

lemma G_eq_G_list:
  "G φ = set (G_list φ)"
  by (induction φ) auto

lemma G_list_distinct:
  "distinct (G_list φ)"
  by (induction φ) auto

subsection ‹Propositional Equivalence›

fun ifex_of_ltl :: "'a ltl ⇒ 'a ltl ifex" 
where
  "ifex_of_ltl true = Trueif"
| "ifex_of_ltl false = Falseif"
| "ifex_of_ltl (φ and ψ) = normif Mapping.empty (ifex_of_ltl φ) (ifex_of_ltl ψ) Falseif"
| "ifex_of_ltl (φ or ψ) = normif Mapping.empty (ifex_of_ltl φ) Trueif (ifex_of_ltl ψ)"
| "ifex_of_ltl φ = IF φ Trueif Falseif"

lemma val_ifex: 
  "val_ifex (ifex_of_ltl b) s = (⊨P) {x. s x} b"
  by (induction b) (simp add: agree_Nil val_normif)+

lemma reduced_ifex: 
  "reduced (ifex_of_ltl b) {}"
  by (induction b) (simp; metis keys_empty reduced_normif)+

lemma ifex_of_ltl_reduced_bdt_checker: 
  "reduced_bdt_checkers ifex_of_ltl (λy s. {x. s x} ⊨P y)"
  by (unfold reduced_bdt_checkers_def; insert val_ifex reduced_ifex; blast)

lemma [code]: 
  "(φ ≡P ψ) = equiv_test ifex_of_ltl φ ψ"
  by (simp add: ltl_prop_equiv_def reduced_bdt_checkers.equiv_test[OF ifex_of_ltl_reduced_bdt_checker]; fastforce) 

lemma [code]: 
  "(φ ⟶P ψ) = impl_test ifex_of_ltl φ ψ"
  by (simp add: ltl_prop_implies_def reduced_bdt_checkers.impl_test[OF ifex_of_ltl_reduced_bdt_checker]; force)

― ‹Check Code Export› 
export_code "(≡P)" "(⟶P)" checking

subsection ‹Remove Constants›

fun remove_constantsP :: "'a ltl ⇒ 'a ltl"
where
  "remove_constantsP (φ and ψ) = (
    case (remove_constantsP φ) of
        false ⇒ false
      | true ⇒ remove_constantsP ψ
      | φ' ⇒ (case remove_constantsP ψ of 
          false ⇒ false 
        | true ⇒ φ' 
        | ψ' ⇒ φ' and ψ'))"
| "remove_constantsP (φ or ψ) = (
    case (remove_constantsP φ) of
        true ⇒ true
      | false ⇒ remove_constantsP ψ
      | φ' ⇒ (case remove_constantsP ψ of 
          true ⇒ true 
        | false ⇒ φ' 
        | ψ' ⇒ φ' or ψ'))"
| "remove_constantsP φ = φ"

lemma remove_constants_correct: 
  "S ⊨P φ ⟷ S ⊨P remove_constantsP φ"
  by (induction φ arbitrary: S) (auto split: ltl.split)

subsection ‹And/Or Constructors›  

fun in_and
where
  "in_and x (y and z) = (in_and x y ∨ in_and x z)"
| "in_and x y = (x = y)"

fun in_or
where
  "in_or x (y or z) = (in_or x y ∨ in_or x z)"
| "in_or x y = (x = y)"
 
lemma in_entailment: 
  "in_and x y ⟹ S ⊨P y ⟹ S ⊨P x"
  "in_or x y ⟹ S ⊨P x ⟹ S ⊨P y"
  by (induction y) auto

definition mk_and
where
  "mk_and f x y = (case f x of false ⇒ false | true ⇒ f y 
    | x' ⇒ (case f y of false ⇒ false | true ⇒ x' 
    | y' ⇒ if in_and x' y' then y' else if in_and y' x' then x' else x' and y'))"

definition mk_and' 
where
  "mk_and' x y ≡ case y of false ⇒ false | true ⇒ x | _ ⇒ x and y"

definition mk_or 
where
  "mk_or f x y = (case f x of true ⇒ true | false ⇒ f y 
    | x' ⇒ (case f y of true ⇒ true | false ⇒ x' 
    | y' ⇒ if in_or x' y' then y' else if in_or y' x' then x' else x' or y'))"

definition mk_or'
where
  "mk_or' x y ≡ case y of true ⇒ true | false ⇒ x | _ ⇒ x or y"

lemma mk_and_correct: 
  "S ⊨P mk_and f x y ⟷ S ⊨P f x and f y"
proof -
  have X: "⋀x' y'. S ⊨P (if in_and x' y' then y' else if in_and y' x' then x' else x' and y')
    ⟷ S ⊨P x' and y'"
    using in_entailment by auto
  show ?thesis
    unfolding mk_and_def ltl.split X by (cases "f x"; cases "f y"; simp) 
qed

lemma mk_and'_correct: 
  "S ⊨P mk_and' x y ⟷ S ⊨P x and y"
  unfolding mk_and'_def by (cases y; simp) 

lemma mk_or_correct: 
  "S ⊨P mk_or f x y ⟷ S ⊨P f x or f y"
proof -
  have X: "⋀x' y'. S ⊨P (if in_or x' y' then y' else if in_or y' x' then x' else x' or y')
    ⟷ S ⊨P x' or y'"
    using in_entailment by auto
  show ?thesis
    unfolding mk_or_def ltl.split X by (cases "f x"; cases "f y"; simp) 
qed

lemma mk_or'_correct: 
  "S ⊨P mk_or' x y ⟷ S ⊨P x or y"
  unfolding mk_or'_def by (cases y; simp) 

end