Theory HAOps

(*  Title:      statecharts/HA/HAOps.thy
    Author:     Steffen Helke, Software Engineering Group
    Copyright   2010 Technische Universitaet Berlin
*)

section ‹Constructing Hierarchical Automata›
theory HAOps
imports HA
begin

subsection "Constructing a Composition Function for a PseudoHA"

definition
  EmptyMap :: "'s set => ('s ⇀ (('s,'e,'d)seqauto) set)" where
  "EmptyMap S = (λ a . if a ∈ S then Some {} else None)"

lemma EmptyMap_dom [simp]:
  "dom (EmptyMap S) = S"
by (unfold dom_def EmptyMap_def,auto)

lemma EmptyMap_ran [simp]:
   "S ≠ {} ⟹ ran (EmptyMap S) = {{}}"
by (unfold ran_def EmptyMap_def, auto)

lemma EmptyMap_the [simp]:
   "x ∈ S ⟹ the ((EmptyMap S) x) = {}"
by (unfold ran_def EmptyMap_def, auto)

lemma EmptyMap_ran_override:
  "⟦ S ≠ {}; (S ∩ (dom G)) = {} ⟧ ⟹  
  ran (G ++ EmptyMap S) = insert {} (ran G)"
apply (subst ran_override)
apply (simp add: Int_commute)
apply simp
done

lemma EmptyMap_Union_ran_override:
 "⟦ S ≠ {};  
    S ∩ dom G = {} ⟧ ⟹  
  (Union (ran (G ++ (EmptyMap S)))) = (Union (ran G))"
apply (subst EmptyMap_ran_override)
apply auto
done

lemma EmptyMap_Union_ran_override2:
 "⟦ S ≠ {}; S ∩ dom G1 = {}; 
    dom G1 ∩ dom G2 = {} ⟧ ⟹ 
   ⋃ (ran (G1 ++ EmptyMap S ++ G2)) = (⋃ (ran G1 ∪ ran G2))"
apply (unfold Union_eq UNION_eq EmptyMap_def Int_def ran_def)
apply (simp add: map_add_Some_iff)
apply (unfold dom_def)
apply simp
apply (rule equalityI)
apply (rule subsetI)
apply simp
apply fast
apply (rule subsetI)
apply (rename_tac t)
apply simp
apply (erule bexE)
apply (rename_tac U)
apply simp
apply (erule disjE)
apply (erule exE)
apply (rename_tac v)
apply (rule_tac x=U in exI)
apply simp
apply (rule_tac x=v in exI)
apply auto
done

lemma EmptyMap_Root [simp]:
 "Root {SA} (EmptyMap (States SA)) = SA"
by (unfold Root_def, auto)

lemma EmptyMap_RootEx [simp]:
  "RootEx {SA} (EmptyMap (States SA))"
by (unfold RootEx_def, auto)

lemma EmptyMap_OneAncestor [simp]:
 "OneAncestor {SA} (EmptyMap (States SA))"
by (unfold OneAncestor_def, auto)

lemma EmptyMap_NoCycles [simp]:
  "NoCycles {SA} (EmptyMap (States SA))"
by (unfold NoCycles_def EmptyMap_def , auto)

lemma EmptyMap_IsCompFun [simp]:
 "IsCompFun {SA} (EmptyMap (States SA))"
by (unfold IsCompFun_def, auto)

lemma EmptyMap_hierauto [simp]:
 "(D,{SA}, SAEvents SA, EmptyMap (States SA)) ∈ hierauto"
by (unfold hierauto_def HierAuto_def, auto)

subsection "Extending a Composition Function by a SA"

definition
  FAddSA :: "[('s ⇀ (('s,'e,'d)seqauto) set), 's * ('s,'e,'d)seqauto]
             => ('s ⇀ (('s,'e,'d)seqauto) set)"
           (‹(_ [f+]/ _)› [10,11]10) where
  "FAddSA G SSA = (let  (S,SA) = SSA
                   in
                     (if ((S ∈ dom G) ∧ (S ∉ States SA)) then
                        (G ++ (Map.empty(S ↦ (insert SA (the (G S)))))
                         ++ EmptyMap (States SA))
                      else G))"

lemma FAddSA_dom [simp]:
 "(S ∉ (dom (A::('a => ('a,'c,'d)seqauto set option)))) ⟹
   ((A [f+] (S,(SA::('a,'c,'d)seqauto))) = A)"
by (unfold FAddSA_def Let_def, auto)

lemma FAddSA_States [simp]:
 "(S ∈ (States (SA::('a,'c,'d)seqauto))) ⟹
   (((A::('a => ('a,'c,'d)seqauto set option)) [f+] (S,SA)) = A)"
by (unfold FAddSA_def Let_def, auto)

lemma FAddSA_dom_insert [simp]:
 "⟦ S ∈ (dom A); S ∉  States SA ⟧ ⟹ 
   (((A [f+] (S,SA)) S) = Some (insert SA (the (A S))))"
by (unfold FAddSA_def Let_def restrict_def, auto)

lemma FAddSA_States_neq [simp]:
 "⟦ S' ∉ States (SA::('a,'c,'d)seqauto); S ≠  S' ⟧ ⟹ 
  ((((A::('a => ('a,'c,'d)seqauto set option)) [f+] (S,SA)) S') = (A S'))"
apply (case_tac "S ∈ dom A")
apply (case_tac "S ∈ States SA")
apply auto
apply (case_tac "S' ∈ dom A")
apply (unfold FAddSA_def Let_def)
apply auto
apply (simp add: dom_None)
done

lemma FAddSA_dom_emptyset [simp]:
 "⟦ S ∈ (dom A); S ∉ States SA; S' ∈ States (SA::('a,'c,'d)seqauto) ⟧ ⟹  
    ((((A::('a => ('a,'c,'d)seqauto set option))) [f+] (S,SA)) S') = (Some {})"
apply (unfold FAddSA_def Let_def)
apply auto
apply (unfold EmptyMap_def)
apply auto
done

lemma FAddSA_dom_dom_States [simp]:
  "⟦ S ∈ (dom F); S ∉ States SA ⟧ ⟹ 
    (dom ((F::('a ⇀ (('a,'b,'d)seqauto) set)) [f+] (S, SA))) = 
    ((dom F) ∪ (States (SA::('a,'b,'d)seqauto)))"
by (unfold FAddSA_def Let_def, auto)

lemma FAddSA_dom_dom [simp]:
  "S ∉ (dom F) ⟹   
   (dom ((F::('a ⇀ (('a,'b,'d)seqauto) set)) [f+] 
       (S,(SA::('a,'b,'d)seqauto)))) = (dom F)"
by (unfold FAddSA_def Let_def, auto)

lemma FAddSA_States_dom [simp]:
  "S ∈ (States SA) ⟹  
   (dom ((F::('a ⇀ (('a,'b,'d)seqauto) set)) [f+] 
        (S,(SA::('a,'b,'d)seqauto)))) = (dom F)"
by (unfold FAddSA_def Let_def, auto)

lemma FAddSA_dom_insert_dom_disjunct [simp]:
   "⟦ S ∈ dom G; States SA ∩ dom G = {} ⟧ ⟹ ((G [f+] (S,SA)) S) = Some (insert SA (the (G S)))"
apply (rule  FAddSA_dom_insert)
apply auto
done

lemma FAddSA_Union_ran:
 "⟦ S ∈ dom G; (States SA) ∩ (dom G) = {} ⟧ ⟹ 
   (⋃ (ran (G [f+] (S,SA)))) = (insert SA (⋃ (ran G)))"
apply (unfold FAddSA_def Let_def)
apply simp
apply (rule conjI)
prefer 2
apply (rule impI)
apply (unfold Int_def)
apply simp
apply (fold Int_def)
apply (rule impI)
apply (subst EmptyMap_Union_ran_override)
apply auto
done

lemma FAddSA_Union_ran2:
 "⟦ S ∈ dom G1; (States SA) ∩ (dom G1) = {}; (dom G1 ∩ dom G2) = {} ⟧ ⟹
   (⋃ (ran ((G1 [f+] (S,SA)) ++ G2))) = (insert SA (⋃ ((ran G1) ∪ (ran G2))))"
apply (unfold FAddSA_def Let_def)
apply (simp (no_asm_simp))
apply (rule conjI)
apply (rule impI)
apply (subst EmptyMap_Union_ran_override2)
apply simp
apply simp
apply simp
apply fast
apply (subst Union_Un_distrib)
apply (subst Union_ran_override2)
apply auto
done

lemma FAddSA_ran:
  "⟦ ∀ T ∈ dom G . T ≠ S ⟶ (the (G T) ∩ the (G S)) = {};  
     S ∈ dom G; (States SA) ∩  (dom G) = {} ⟧ ⟹  
    ran (G [f+] (S,SA)) = insert {} (insert (insert SA (the (G S))) (ran G - {the (G S)}))"
apply (unfold FAddSA_def Let_def)
apply simp
apply (rule conjI)
apply (rule impI)+
prefer 2
apply fast
apply (simp add: EmptyMap_ran_override)
apply (unfold ran_def)
apply auto
apply (rename_tac Y X a xa xb)
apply (erule_tac x=a in allE)
apply simp
apply (erule_tac x=a in allE)
apply simp
done

lemma FAddSA_RootEx_def: 
  "⟦ S ∈ dom G; (States SA) ∩ (dom G) = {} ⟧ ⟹ 
    RootEx F (G [f+] (S,SA)) = (∃! A . A ∈ F ∧ A ∉ insert SA (⋃ (ran G)))"
apply (unfold RootEx_def)
apply (simp only: FAddSA_Union_ran Int_commute)
done

lemma FAddSA_RootEx:
  "⟦ ⋃ (ran G) = F - {Root F G}; 
     dom G = ⋃(States ` F); 
     (dom G ∩ States SA) = {}; S ∈ dom G; 
     RootEx F G ⟧ ⟹ RootEx (insert SA F) (G [f+] (S,SA))"
apply (simp add: FAddSA_RootEx_def Int_commute cong: rev_conj_cong)
apply (auto cong: conj_cong) 
done

lemma FAddSA_Root_def:
  "⟦ S ∈ dom G; (States SA) ∩ (dom G) = {} ⟧  ⟹ 
   (Root F (G [f+] (S,SA)) = (@ A . A ∈ F ∧ A ∉ insert SA (⋃ (ran G))))" 
apply (unfold Root_def)
apply (simp only: FAddSA_Union_ran Int_commute)
done

lemma FAddSA_RootEx_Root: 
  "⟦ Union (ran G) = F - {Root F G};  
     ⋃(States ` F) = dom G; 
     (dom G ∩ States SA) = {}; S ∈ dom G;
     RootEx F G ⟧ ⟹ (Root (insert SA F) (G [f+] (S,SA))) = (Root F G)"
apply (simp add: FAddSA_Root_def Int_commute cong: rev_conj_cong)
apply (simp cong:conj_cong)
done

lemma FAddSA_OneAncestor:
  "⟦ ⋃ (ran G) = F - {Root F G}; 
     (dom G ∩ States SA) = {}; S ∈ dom G; 
     ⋃(States ` F) = dom G; RootEx F G;
     OneAncestor F G ⟧ ⟹ OneAncestor (insert SA F) (G [f+] (S,SA))"
apply (subst OneAncestor_def)
apply simp
apply (rule ballI)
apply (rename_tac SAA)
apply (case_tac "SA = SAA")
apply (rule_tac a=S in ex1I)
apply (rule conjI)
apply simp
apply fast
apply (subst FAddSA_dom_insert)
apply simp
apply (simp add:Int_def)
apply simp
apply (rename_tac T)
apply (erule conjE bexE exE disjE)+
apply (rename_tac SAAA)
apply simp
apply (erule conjE)
apply (subst not_not [THEN sym])
apply (rule notI)
apply (case_tac "T ∈ States SAA")
apply blast
apply (drule_tac A=G and S=S and SA=SAA in FAddSA_States_neq)
apply fast
apply simp
apply (case_tac "SAA ∉ Union (ran G)")
apply (frule ran_dom_the)
prefer 2
apply fast
apply blast
apply simp
apply (erule conjE)
apply (simp add: States_Int_not_mem)
apply (unfold OneAncestor_def)
apply (drule_tac G=G and S=S and SA=SA in FAddSA_RootEx_Root)
apply simp
apply simp
apply simp
apply simp
apply (erule_tac x=SAA in ballE)
prefer 2
apply simp
apply simp
apply (erule conjE bexE ex1E exE disjE)+
apply (rename_tac T SAAA)
apply (rule_tac a=T in ex1I)
apply (rule conjI)
apply fast
apply (case_tac "T = S")
apply simp
apply (case_tac "S ∉ States SA")
apply simp
apply simp
apply (subst FAddSA_States_neq)
apply blast
apply (rule not_sym)
apply simp
apply simp
apply (rename_tac U)
apply simp
apply (erule conjE bexE)+
apply (rename_tac SAAAA)
apply simp
apply (erule conjE disjE)+
apply (frule FAddSA_dom_emptyset)
prefer 2
apply fast
back
back
apply simp
apply blast
apply simp
apply (erule_tac x=U in allE)
apply (erule impE)
prefer 2
apply simp
apply (rule conjI)
apply fast
apply (case_tac "S ≠ U")
apply (subgoal_tac "U ∉ States SA")
apply (drule_tac A=G in FAddSA_States_neq)
apply fast
apply simp
apply blast
apply (drule_tac A=G and SA=SA in FAddSA_dom_insert)
apply simp
apply blast
apply auto
done

lemma FAddSA_NoCycles:
  "⟦ (States SA ∩ dom G) = {}; S ∈ dom G;
     dom G = ⋃(States ` F); NoCycles F G ⟧ ⟹ 
     NoCycles  (insert SA F) (G [f+] (S,SA))"
apply (unfold NoCycles_def)
apply (rule ballI impI)+
apply (rename_tac SAA)
apply (case_tac "∃ s ∈ SAA. s ∈ States SA")
apply simp
apply (erule bexE)+
apply (rename_tac SAAA T)
apply (rule_tac x=T in bexI)
apply simp
apply (subst FAddSA_dom_emptyset)
apply simp
apply fast
apply blast
apply simp
apply simp
apply simp
apply simp
apply (erule_tac x=SAA in ballE)
prefer 2
apply simp
apply auto[1]
apply (unfold UNION_eq Pow_def)
apply simp
apply (case_tac "SAA = {}")
apply fast
apply simp
apply (erule bexE)+
apply (rename_tac SAAA T)
apply (rule_tac x=T in bexI)
prefer 2
apply simp
apply (case_tac "T=S")
apply simp
apply (subst FAddSA_dom_insert)
apply auto
done

lemma FAddSA_IsCompFun:
 "⟦ (States SA ∩ (⋃(States ` F))) = {};
     S ∈ (⋃(States ` F)); 
     IsCompFun F G ⟧ ⟹  IsCompFun (insert SA F) (G [f+] (S,SA))"
apply (unfold IsCompFun_def)
apply (erule conjE)+
apply (simp add: Int_commute FAddSA_RootEx_Root FAddSA_RootEx FAddSA_OneAncestor FAddSA_NoCycles)
apply (rule conjI)
apply (subst FAddSA_dom_dom_States)
apply simp
apply blast
apply (simp add: Un_commute)
apply (simp add: FAddSA_Union_ran)
apply (case_tac "SA = Root F G")
prefer 2
apply blast
apply (subgoal_tac "States (Root F G) ⊆  ⋃(States ` F)")
apply simp
apply (frule subset_lemma)
apply auto
done

lemma FAddSA_HierAuto:
  "⟦ (States SA ∩ (⋃(States ` F))) = {};
      S ∈ (⋃(States ` F)); 
      HierAuto D F E G ⟧ ⟹ HierAuto D (insert SA F) (E ∪ SAEvents SA) (G [f+] (S,SA))"
apply (unfold HierAuto_def)
apply auto
apply (simp add: MutuallyDistinct_Insert)
apply (rule FAddSA_IsCompFun)
apply auto
done

lemma FAddSA_HierAuto_insert [simp]:
  "⟦ (States SA ∩ HAStates HA) = {};
      S ∈ HAStates HA ⟧ ⟹ 
    HierAuto (HAInitValue HA)                  
             (insert SA (SAs HA))              
             (HAEvents HA ∪ SAEvents SA)      
             (CompFun HA [f+] (S,SA))"
apply (unfold HAStates_def)
apply (rule FAddSA_HierAuto)
apply auto
done

subsection "Constructing a PseudoHA" 

definition
  PseudoHA :: "[('s,'e,'d)seqauto,'d data] => ('s,'e,'d)hierauto" where
  "PseudoHA SA D = Abs_hierauto(D,{SA}, SAEvents SA ,EmptyMap (States SA))"

lemma PseudoHA_SAs [simp]:
  "SAs (PseudoHA SA D) = {SA}"
by (unfold PseudoHA_def SAs_def, simp add: Abs_hierauto_inverse)

lemma PseudoHA_Events [simp]:
  "HAEvents (PseudoHA SA D) = SAEvents SA"
by (unfold PseudoHA_def HAEvents_def, simp add: Abs_hierauto_inverse)
 
lemma PseudoHA_CompFun [simp]:
  "CompFun (PseudoHA SA D) = EmptyMap (States SA)"
by (unfold PseudoHA_def CompFun_def, simp add: Abs_hierauto_inverse)

lemma PseudoHA_HAStates [simp]:
  "HAStates (PseudoHA SA D) = (States SA)"
by (unfold HAStates_def, auto)

lemma PseudoHA_HAInitValue [simp]:
  "(HAInitValue (PseudoHA SA D)) = D"
by (unfold PseudoHA_def Let_def HAInitValue_def, simp add: Abs_hierauto_inverse)
 
lemma PseudoHA_CompFun_the [simp]: 
 "S ∈ States A ⟹ (the (CompFun (PseudoHA A D) S)) = {}"
by simp

lemma PseudoHA_CompFun_ran [simp]:
 "(ran (CompFun (PseudoHA SA D))) = {{}}"
by auto

lemma PseudoHA_HARoot [simp]:
 "(HARoot (PseudoHA SA D)) = SA"
by (unfold HARoot_def, auto)

lemma PseudoHA_HAInitState [simp]:
  "HAInitState (PseudoHA A D) = InitState A"
apply (unfold HAInitState_def)
apply simp
done

lemma PseudoHA_HAInitStates [simp]:
  "HAInitStates (PseudoHA A D) = {InitState A}" 
apply (unfold HAInitStates_def)
apply simp
done

lemma PseudoHA_Chi [simp]:
  "S ∈ States A ⟹ Chi (PseudoHA A D) S = {}"
apply (unfold Chi_def restrict_def)
apply auto
done

lemma PseudoHA_ChiRel [simp]:
  "ChiRel (PseudoHA A D) = {}"
apply (unfold ChiRel_def)
apply simp
done

lemma PseudoHA_InitConf [simp]:
 "InitConf (PseudoHA A D) = {InitState A}"
apply (unfold InitConf_def)
apply simp
done

subsection ‹Extending a HA by a SA (‹AddSA›)›

definition
  AddSA :: "[('s,'e,'d)hierauto, 's * ('s,'e,'d)seqauto]
             => ('s,'e,'d)hierauto"
           (‹(_ [++]/ _)› [10,11]10) where
  "AddSA HA SSA = (let (S,SA) = SSA;
                        DNew = HAInitValue HA;
                        FNew = insert SA (SAs HA);
                        ENew  = HAEvents HA ∪ SAEvents SA;
                        GNew  = CompFun HA [f+] (S,SA)
                   in
                       Abs_hierauto(DNew,FNew,ENew,GNew))"

definition
  AddHA :: "[('s,'e,'d)hierauto, 's * ('s,'e,'d)hierauto]
             => ('s,'e,'d)hierauto"
           (‹(_ [**]/ _)› [10,11]10) where
  "AddHA HA1 SHA =
            (let (S,HA2)     = SHA;
                 (D1,F1,E1,G1) = Rep_hierauto (HA1 [++] (S,HARoot HA2));
                 (D2,F2,E2,G2) = Rep_hierauto HA2;
                 FNew       = F1 ∪ F2;
                 ENew       = E1 ∪ E2;
                 GNew       = G1 ++ G2
             in
                 Abs_hierauto(D1,FNew,ENew,GNew))"

lemma AddSA_SAs:
  "⟦ (States SA ∩  HAStates HA) = {}; 
      S ∈ HAStates HA ⟧ ⟹ (SAs (HA [++] (S,SA))) = insert SA (SAs HA)"
apply (unfold Let_def AddSA_def)
apply (subst SAs_def)
apply (simp add: hierauto_def Abs_hierauto_inverse)
done

lemma AddSA_Events:
  "⟦ (States SA ∩ HAStates HA) = {}; 
      S ∈ HAStates HA ⟧ ⟹
     HAEvents (HA [++] (S,SA)) = (HAEvents HA) ∪ (SAEvents SA)"
apply (unfold Let_def AddSA_def)
apply (subst HAEvents_def)
apply (simp add: hierauto_def Abs_hierauto_inverse)
done

lemma AddSA_CompFun:
   "⟦ (States SA ∩  HAStates HA) = {}; 
      S ∈ HAStates HA ⟧ ⟹  
     CompFun (HA [++] (S,SA)) = (CompFun HA [f+] (S,SA))"
apply (unfold Let_def AddSA_def)
apply (subst CompFun_def)
apply (simp add: hierauto_def Abs_hierauto_inverse)
done

lemma AddSA_HAStates:
   "⟦ (States SA ∩ HAStates HA) = {}; 
       S ∈ HAStates HA ⟧ ⟹
      HAStates (HA [++] (S,SA)) = (HAStates HA) ∪ (States SA)"
apply (unfold HAStates_def)
apply (subst AddSA_SAs)
apply (unfold HAStates_def)
apply auto
done

lemma AddSA_HAInitValue:
   "⟦ (States SA ∩ HAStates HA) = {};
       S ∈ HAStates HA ⟧ ⟹
      (HAInitValue (HA [++] (S,SA))) = (HAInitValue HA)"
apply (unfold Let_def AddSA_def)
apply (subst HAInitValue_def)
apply (simp add: hierauto_def Abs_hierauto_inverse)
done

lemma AddSA_HARoot:
   "⟦ (States SA ∩ HAStates HA) = {};
      S ∈ HAStates HA ⟧ ⟹ 
      (HARoot (HA [++] (S,SA))) = (HARoot HA)"
apply (unfold HARoot_def)
apply (simp add: AddSA_CompFun AddSA_SAs)
apply (subst FAddSA_RootEx_Root)
apply auto
apply (simp only: HAStates_SA_mem)
apply (unfold HAStates_def)
apply fast
done

lemma AddSA_CompFun_the: 
 "⟦ (States SA ∩ HAStates A) = {}; 
    S ∈ HAStates A ⟧ ⟹ 
  (the ((CompFun (A [++] (S,SA))) S)) = insert SA (the ((CompFun A) S))"
by (simp add: AddSA_CompFun)

lemma AddSA_CompFun_the2:
 "⟦ S' ∈ States (SA::('a,'c,'d)seqauto); 
    (States SA ∩ HAStates A) = {};
    S ∈ HAStates A ⟧ ⟹
    the ((CompFun (A [++] (S,SA))) S') = {}"
apply (simp add: AddSA_CompFun)
apply (subst FAddSA_dom_emptyset)
apply auto
done

lemma AddSA_CompFun_the3:
 "⟦ S' ∉ States (SA::('a,'c,'d)seqauto); 
    S ≠ S'; 
    (States SA ∩ HAStates A) = {}; 
    S ∈ HAStates A ⟧ ⟹ 
   (the ((CompFun (A [++] (S,SA))) S')) = (the ((CompFun A) S'))"
by (simp add: AddSA_CompFun)

lemma AddSA_CompFun_ran:
 "⟦ (States SA ∩ HAStates A) = {};
     S ∈ HAStates A ⟧ ⟹ 
   ran (CompFun (A [++] (S,SA))) = 
       insert {} (insert (insert SA (the ((CompFun A) S))) (ran (CompFun A) - {the ((CompFun A) S)}))"
apply (simp add: AddSA_CompFun)
apply (subst FAddSA_ran)
apply auto
apply (fast dest: CompFun_Int_disjoint) 
done

lemma AddSA_CompFun_ran2:
 "⟦ (States SA1 ∩ HAStates A) = {};
    (States SA2 ∩ (HAStates A ∪ States SA1)) = {};
     S ∈ HAStates A;
     T ∈ States SA1 ⟧ ⟹
   ran (CompFun ((A [++] (S,SA1)) [++] (T,SA2))) = 
       insert {} (insert {SA2} (ran (CompFun (A  [++] (S,SA1)))))"
apply (simp add: AddSA_HAStates AddSA_CompFun)
apply (subst FAddSA_ran)
apply (rule ballI)
apply (rule impI)
apply (subst AddSA_CompFun [THEN sym])
apply simp
apply simp
apply (subst AddSA_CompFun [THEN sym])
apply simp
apply simp
apply (rule CompFun_Int_disjoint)
apply simp
apply (simp add: AddSA_HAStates)
apply (simp add: AddSA_HAStates)
apply (case_tac "S ∈ States SA1")
apply simp
apply (simp only: dom_CompFun [THEN sym])
apply (frule FAddSA_dom_dom_States)
apply fast
apply simp
apply (case_tac "S ∈ States SA1")
apply simp
apply fast
apply (subst FAddSA_dom_dom_States)
apply simp
apply simp
apply simp
apply (case_tac "S ∈  States SA1")
apply simp
apply fast
apply (subst FAddSA_dom_dom_States)
apply simp
apply simp
apply simp
apply (case_tac "S ∈  States SA1")
apply simp
apply fast
apply simp
apply fast
done

lemma AddSA_CompFun_ran_not_mem:
 "⟦ States SA2 ∩ (HAStates A ∪ States SA1) = {};
    States SA1 ∩ HAStates A = {};
    S ∈ HAStates A ⟧ ⟹ 
   {SA2} ∉ ran (CompFun A [f+] (S, SA1))"
  apply (cut_tac HA="A [++] (S,SA1)" and Sas="{SA2}" in ran_CompFun_is_not_SA)
  apply (metis AddSA_HAStates SA_States_disjunct2 SAs_States_HAStates insert_subset)
   apply (simp add: AddSA_HAStates AddSA_CompFun)
  done

lemma AddSA_CompFun_ran3:
 "⟦ (States SA1 ∩ HAStates A) = {};
    (States SA2 ∩ (HAStates A ∪ States SA1)) = {};
    (States SA3 ∩ (HAStates A ∪ States SA1 ∪ States SA2)) = {};
     S ∈ HAStates A; 
     T ∈ States SA1 ⟧ ⟹ 
    ran (CompFun ((A [++] (S,SA1)) [++] (T,SA2) [++] (T,SA3))) = 
       insert {} (insert {SA3,SA2} (ran (CompFun (A  [++] (S,SA1)))))"
  apply (simp add: AddSA_HAStates AddSA_CompFun)
  apply (subst FAddSA_ran)
  apply (metis AddSA_CompFun AddSA_HAStates CompFun_Int_disjoint UnCI dom_CompFun)
  apply (metis AddSA_CompFun AddSA_HAStates UnCI dom_CompFun)
  apply (metis AddSA_CompFun AddSA_HAStates UnCI dom_CompFun)

  apply (subst AddSA_CompFun [THEN sym])
    back
    apply simp
   apply simp

  apply (subst AddSA_CompFun [THEN sym])
    back
    apply (simp add: AddSA_HAStates)
   apply (simp add: AddSA_HAStates)
  apply (subst AddSA_CompFun_ran2)
      apply fast
     apply fast
    apply fast
   apply fast
  apply (simp add: AddSA_CompFun)
  apply (subst  FAddSA_dom_insert)
    apply (subst FAddSA_dom_dom_States)
      apply simp
     apply fast
    apply simp
   apply fast
  apply (subst FAddSA_dom_emptyset)
     apply simp
    apply fast
   apply simp
  apply simp
  apply (subst  FAddSA_dom_insert)
    apply (subst FAddSA_dom_dom_States)
      apply simp
     apply fast
    apply simp
   apply fast
  apply (subst FAddSA_dom_emptyset)
     apply simp
    apply fast
   apply simp
  apply simp
  by (simp add: AddSA_CompFun_ran_not_mem insert_Diff_if insert_commute)

lemma AddSA_CompFun_PseudoHA_ran:
  "⟦ S ∈ States RootSA;
     States RootSA ∩ States SA = {} ⟧ ⟹ 
     (ran (CompFun ((PseudoHA RootSA D) [++] (S,SA)))) = (insert {} {{SA}})"
apply (subst AddSA_CompFun_ran)
apply auto
done

lemma AddSA_CompFun_PseudoHA_ran2:
  "⟦ States SA1 ∩ States RootSA = {};
     States SA2 ∩ (States RootSA ∪ States SA1) = {}; 
     S ∈ States RootSA ⟧ ⟹  
     (ran (CompFun ((PseudoHA RootSA D) [++] (S,SA1) [++] (S,SA2)))) = (insert {} {{SA2,SA1}})"
apply (subst AddSA_CompFun_ran) 
prefer 3
apply (subst AddSA_CompFun_the)
apply simp
apply simp
apply (subst AddSA_CompFun_PseudoHA_ran)
apply fast
apply fast
apply (subst AddSA_CompFun_the)
apply simp
apply simp
apply simp
apply fast
apply (simp add: AddSA_HAStates)
apply (simp add: AddSA_HAStates)
done

lemma AddSA_HAInitStates [simp]:
 "⟦ States SA ∩ HAStates A = {};
    S ∈ HAStates A ⟧ ⟹
   HAInitStates (A [++] (S,SA)) = insert (InitState SA) (HAInitStates A)"
apply (unfold HAInitStates_def)
apply (simp add: AddSA_SAs)
done

lemma AddSA_HAInitState [simp]:
 "⟦ States SA ∩ HAStates A = {};
    S ∈ HAStates A ⟧ ⟹
  HAInitState (A [++] (S,SA)) = (HAInitState A)"
apply (unfold HAInitState_def)
apply (simp add: AddSA_HARoot)
done

lemma AddSA_Chi [simp]:
 "⟦ States SA ∩ HAStates A = {};
   S ∈ HAStates A ⟧ ⟹  
  Chi (A [++] (S,SA)) S = (States SA) ∪ (Chi A S)"
apply (unfold Chi_def restrict_def)
apply (simp add: AddSA_SAs AddSA_HAStates AddSA_CompFun_the)
apply auto
done

lemma AddSA_Chi2 [simp]:
 "⟦ States SA ∩ HAStates A = {};
    S ∈ HAStates A;  
    T ∈ States SA ⟧ ⟹
    Chi (A [++] (S,SA)) T = {}"
apply (unfold Chi_def restrict_def)
apply (simp add: AddSA_SAs AddSA_HAStates AddSA_CompFun_the2)
done

lemma AddSA_Chi3 [simp]:
 "⟦ States SA ∩ HAStates A = {};
    S ∈ HAStates A; 
    T ∉ States SA; T ≠ S ⟧ ⟹
    Chi (A [++] (S,SA)) T = Chi A T"
apply (unfold Chi_def restrict_def)
apply (simp add: AddSA_SAs AddSA_HAStates AddSA_CompFun_the3)
apply auto
done

lemma AddSA_ChiRel [simp]:
 "⟦ States SA ∩ HAStates A = {};
    S ∈ HAStates A ⟧ ⟹ 
   ChiRel (A [++] (S,SA)) = { (T,T') . T = S ∧ T' ∈ States SA } ∪ (ChiRel A)" 
apply (unfold ChiRel_def)
apply (simp add: AddSA_HAStates)
apply safe
apply (rename_tac T U)
apply (case_tac "T ∈ States SA")
apply simp
apply simp
apply (rename_tac T U)
apply (case_tac "T ≠ S")
apply (case_tac "T ∈  States SA")
apply simp
apply simp
apply simp
apply (rename_tac T U)
apply (case_tac "T ∈  States SA")
apply simp
apply simp
apply (cut_tac A=A and T=T in Chi_HAStates)
apply fast
apply (case_tac "T ∈ States SA")
apply simp
apply simp
apply (cut_tac A=A and T=T in Chi_HAStates)
apply fast
apply fast
apply (rename_tac T U)
apply (case_tac "T ≠ S")
apply (case_tac "T ∈ States SA")
apply simp
apply simp
apply simp
apply (rename_tac T U)
apply (case_tac "T ∈  States SA")
apply auto
apply (metis AddSA_Chi AddSA_Chi3 Int_iff Un_iff empty_iff)
done

lemma help_InitConf:
  "⟦States SA ∩ HAStates A = {} ⟧ ⟹ {p. fst p ≠ InitState SA ∧ snd p ≠ InitState SA ∧ 
       p ∈  insert (InitState SA) (HAInitStates A) × insert (InitState SA) (HAInitStates A) ∧  
       (p ∈  {S} × States SA ∨  p ∈  ChiRel A)} = 
   (HAInitStates A × HAInitStates A ∩  ChiRel A)"    
apply auto
apply (cut_tac A=SA in InitState_States)
apply (cut_tac A=A in HAInitStates_HAStates, fast)
apply (cut_tac A=SA in InitState_States)
apply (cut_tac A=A in HAInitStates_HAStates, fast)
done
 
lemma AddSA_InitConf [simp]:
 "⟦ States SA ∩ HAStates A = {};
    S ∈ InitConf A ⟧ ⟹ 
    InitConf (A [++] (S,SA)) = insert (InitState SA) (InitConf A)"
apply (frule InitConf_HAStates2)
apply (unfold InitConf_def)
apply (simp del: insert_Times_insert)
  apply auto
  apply (rename_tac T)
   apply (case_tac "T=S")
  apply auto
  prefer 3
   apply (rule_tac R="(HAInitStates A) × (HAInitStates A) ∩ ChiRel A" in trancl_subseteq)
 apply auto
 apply (rotate_tac 3)
 apply (frule trancl_collect)
   prefer 2
   apply fast
  apply auto
   apply (cut_tac A=SA in InitState_States)
   apply (frule ChiRel_HAStates)
   apply fast
  apply (frule ChiRel_HAStates)
  apply (cut_tac A=SA in InitState_States)
  apply fast
 apply (subst help_InitConf [THEN sym])
  apply fast
 apply auto
apply (rule_tac b=S in rtrancl_into_rtrancl)
 apply auto
  prefer 2
  apply (erule rtranclE)
   apply auto
 prefer 2
 apply (erule rtranclE)
  apply auto
 apply (rule_tac R="(HAInitStates A) × (HAInitStates A) ∩ ChiRel A" in trancl_subseteq)
apply auto
done

lemma AddSA_InitConf2 [simp]:
 "⟦ States SA ∩ HAStates A = {};
    S ∉ InitConf A;
  S ∈ HAStates A ⟧ ⟹
  InitConf (A [++] (S,SA)) = InitConf A"
apply (unfold InitConf_def)
apply simp
apply auto
 apply (rename_tac T)
 prefer 2
 apply (rule_tac R="(HAInitStates A) × (HAInitStates A) ∩ ChiRel A" in trancl_subseteq)
  apply auto
apply (case_tac "T=InitState SA")
 apply auto
 prefer 2
 apply (rotate_tac 3)
 apply (frule trancl_collect)
   prefer 2
   apply fast
  apply auto
   apply (cut_tac A=SA in InitState_States)
   apply (frule ChiRel_HAStates)
   apply fast
  apply (cut_tac A=SA in InitState_States)
  apply (frule ChiRel_HAStates)
 apply fast
 apply (cut_tac A=SA in InitState_States)
 apply (cut_tac A=A in HAInitStates_HAStates)
 apply (subst help_InitConf [THEN sym])
  apply fast
 apply auto
apply (rule_tac b="InitState SA" in rtrancl_induct)
  apply auto
  apply (frule ChiRel_HAStates2)
  apply (cut_tac A=SA in InitState_States)
  apply fast
 prefer 2
 apply (frule ChiRel_HAStates)
 apply (cut_tac A=SA in InitState_States)
 apply fast
apply (rule rtrancl_into_rtrancl)
 apply auto
done

subsection "Theorems for Calculating Wellformedness of HA"

lemma PseudoHA_HAStates_IFF:
 "(States SA) = X  ⟹ (HAStates (PseudoHA SA D)) = X"
apply simp
done

lemma AddSA_SAs_IFF:
 "⟦ States SA ∩ HAStates HA = {};
    S ∈ HAStates HA;
    (SAs HA) = X ⟧ ⟹ (SAs (HA [++] (S, SA))) = (insert SA X)"
apply (subst AddSA_SAs)
apply auto
done

lemma AddSA_Events_IFF:
 "⟦ States SA ∩ HAStates HA = {}; 
    S ∈ HAStates HA; 
    (HAEvents HA) = HAE;
    (SAEvents SA) = SAE;  
    (HAE ∪ SAE) = X ⟧ ⟹ (HAEvents (HA [++] (S, SA))) = X"
apply (subst AddSA_Events)
apply auto
done

lemma AddSA_CompFun_IFF:
 "⟦ States SA ∩  HAStates HA = {};
    S ∈ HAStates HA;
    (CompFun HA) = HAG;
    (HAG [f+] (S, SA)) = X ⟧ ⟹ (CompFun (HA [++] (S, SA))) = X"
apply (subst AddSA_CompFun)
apply auto
done

lemma AddSA_HAStates_IFF: 
 "⟦ States SA ∩ HAStates HA = {};
    S ∈ HAStates HA;
    (HAStates HA) = HAS;
    (States SA) = SAS;
    (HAS ∪ SAS) = X ⟧ ⟹ (HAStates (HA [++] (S, SA))) = X"
apply (subst AddSA_HAStates)
apply auto
done

lemma AddSA_HAInitValue_IFF:
 "⟦ States SA ∩ HAStates HA = {};
    S ∈ HAStates HA;
    (HAInitValue HA) = X ⟧ ⟹ (HAInitValue (HA [++] (S, SA))) = X"
apply (subst AddSA_HAInitValue)
apply auto
done

lemma AddSA_HARoot_IFF:
 "⟦ States SA ∩ HAStates HA = {};
    S ∈ HAStates HA;
    (HARoot HA) = X ⟧ ⟹ (HARoot (HA [++] (S, SA))) = X"
apply (subst AddSA_HARoot)
apply auto
done

lemma AddSA_InitConf_IFF:
 "⟦ InitConf A = Y;
    States SA ∩ HAStates A = {};
    S ∈ HAStates A; 
    (if S ∈ Y then insert (InitState SA) Y else Y) = X ⟧ ⟹ 
    InitConf (A [++] (S,SA)) = X" 
apply (case_tac "S ∈ Y")
apply auto
done

lemma AddSA_CompFun_ran_IFF:
  "⟦ (States SA ∩ HAStates A) = {}; 
     S ∈ HAStates A;
     (insert {} (insert (insert SA (the ((CompFun A) S))) (ran (CompFun A) - {the ((CompFun A) S)}))) = X ⟧ ⟹
     ran (CompFun (A [++] (S,SA))) = X"
apply (subst  AddSA_CompFun_ran)
apply auto
done

lemma AddSA_CompFun_ran2_IFF:
 "⟦ (States SA1 ∩ HAStates A) = {}; 
    (States SA2 ∩ (HAStates A ∪ States SA1)) = {};
    S ∈ HAStates A;
    T ∈ States SA1;
    insert {} (insert {SA2} (ran (CompFun (A  [++] (S,SA1))))) = X ⟧ ⟹
    ran (CompFun ((A [++] (S,SA1)) [++] (T,SA2))) = X"
apply (subst AddSA_CompFun_ran2)
apply auto
done
   
lemma AddSA_CompFun_ran3_IFF:
 "⟦ (States SA1 ∩ HAStates A) = {};
    (States SA2 ∩ (HAStates A ∪ States SA1)) = {};
    (States SA3 ∩ (HAStates A ∪ States SA1 ∪ States SA2)) = {};
     S ∈ HAStates A;
     T ∈ States SA1;
     insert {} (insert {SA3,SA2} (ran (CompFun (A  [++] (S,SA1))))) = X ⟧ ⟹
     ran (CompFun ((A [++] (S,SA1)) [++] (T,SA2) [++] (T,SA3))) = X" 
apply (subst AddSA_CompFun_ran3)
apply auto
done

lemma AddSA_CompFun_PseudoHA_ran_IFF:
  "⟦ S ∈ States RootSA; 
     States RootSA ∩ States SA = {};
   (insert {} {{SA}}) = X ⟧ ⟹ 
   (ran (CompFun ((PseudoHA RootSA D) [++] (S,SA)))) = X"
apply (subst AddSA_CompFun_PseudoHA_ran)
apply auto
done

lemma AddSA_CompFun_PseudoHA_ran2_IFF:
  "⟦ States SA1 ∩ States RootSA = {};
     States SA2 ∩ (States RootSA ∪ States SA1) = {};
     S ∈ States RootSA;
     (insert {} {{SA2,SA1}}) = X ⟧ ⟹ 
     (ran (CompFun ((PseudoHA RootSA D) [++] (S,SA1) [++] (S,SA2)))) = X" 
apply (subst AddSA_CompFun_PseudoHA_ran2)
apply auto
done


ML ‹

val AddSA_SAs_IFF = @{thm AddSA_SAs_IFF};
val AddSA_Events_IFF = @{thm AddSA_Events_IFF};
val AddSA_CompFun_IFF = @{thm AddSA_CompFun_IFF};
val AddSA_HAStates_IFF = @{thm AddSA_HAStates_IFF};
val PseudoHA_HAStates_IFF = @{thm PseudoHA_HAStates_IFF};
val AddSA_HAInitValue_IFF = @{thm AddSA_HAInitValue_IFF};
val AddSA_CompFun_ran_IFF = @{thm AddSA_CompFun_ran_IFF};
val AddSA_HARoot_IFF = @{thm AddSA_HARoot_IFF};
val insert_inter = @{thm insert_inter};
val insert_notmem = @{thm insert_notmem};
val PseudoHA_CompFun = @{thm PseudoHA_CompFun};
val PseudoHA_Events = @{thm PseudoHA_Events};
val PseudoHA_SAs = @{thm PseudoHA_SAs};
val PseudoHA_HARoot = @{thm PseudoHA_HARoot};
val PseudoHA_HAInitValue = @{thm PseudoHA_HAInitValue};
val PseudoHA_CompFun_ran = @{thm PseudoHA_CompFun_ran};
val Un_empty_right = @{thm Un_empty_right};
val insert_union = @{thm insert_union};


fun wellformed_tac ctxt L i =
  FIRST[resolve_tac ctxt [AddSA_SAs_IFF] i,
        resolve_tac ctxt [AddSA_Events_IFF] i,
        resolve_tac ctxt [AddSA_CompFun_IFF] i,
        resolve_tac ctxt [AddSA_HAStates_IFF] i,
        resolve_tac ctxt [PseudoHA_HAStates_IFF] i,
        resolve_tac ctxt [AddSA_HAInitValue_IFF] i,
        resolve_tac ctxt [AddSA_HARoot_IFF] i,
        resolve_tac ctxt [AddSA_CompFun_ran_IFF] i,
        resolve_tac ctxt [insert_inter] i,
        resolve_tac ctxt [insert_notmem] i,
        CHANGED (simp_tac (ctxt |> put_simpset HOL_basic_ss |> Simplifier.add_simps
           ([PseudoHA_HARoot, PseudoHA_CompFun, PseudoHA_CompFun_ran,PseudoHA_Events,PseudoHA_SAs,insert_union,
            PseudoHA_HAInitValue,Un_empty_right] @ L)) i),
        fast_tac ctxt i,
        CHANGED (simp_tac ctxt i)];
›

method_setup wellformed  = ‹Attrib.thms >> (fn thms => fn ctxt => (METHOD (fn facts => 
                                       (HEADGOAL (wellformed_tac ctxt (facts @ thms))))))›

end