theory Arl_Ext
  imports
    "../Setup"
    "../Separation_Logic_Solver/Methods"
    "../Bool_Assn_Setup"

    "Isabelle_LLVM.LLVM_DS_All"
begin

hide_const Proto_EOArray.list_assn

definition arl_elem_assn_ex ::
  "('a, 'b) dr_assn \<Rightarrow> 'a list \<Rightarrow> 'b list \<Rightarrow> ('b::llvm_rep, 'l::len2) array_list \<Rightarrow> nat set \<Rightarrow> ll_assn" where
  "arl_elem_assn_ex A xs xsi arl ex \<equiv> \<upharpoonleft>arl_assn xsi arl ** \<upharpoonleft>(list_assn A (idxe_map xsi |` ex)) xs xsi"

abbreviation "arl_elem_assn A xs arl \<equiv> (EXS xsi. arl_elem_assn_ex A xs xsi arl {})"

lemma
  frame_assumption_rule_dyn :
  "\<lbrakk>P = Q; PS -- Pr \<tturnstile> QS -- Qr\<rbrakk> \<Longrightarrow> P ** PS -- Pr \<tturnstile> Q ** QS -- Qr"
  "\<lbrakk>P = Q; \<box> -- Pr \<tturnstile> QS -- Qr\<rbrakk> \<Longrightarrow> P -- Pr \<tturnstile> Q ** QS -- Qr"
  "\<lbrakk>P = Q; \<box> -- Pr \<tturnstile> \<box> -- Qr\<rbrakk> \<Longrightarrow> P -- Pr \<tturnstile> Q -- Qr"
  apply (simp_all add: conj_entails_mono sep_conj_left_commute sep_conj_commute)

  oops

lemma entails_refl_dyn:
  "\<lbrakk>P = Q; PS \<turnstile> QS \<rbrakk> \<Longrightarrow> P ** PS \<turnstile> Q ** QS"
  "\<lbrakk>P = Q; \<box> \<turnstile> QS\<rbrakk> \<Longrightarrow> P \<turnstile> Q ** QS"
  "\<lbrakk>P = Q; \<box> \<turnstile> \<box>\<rbrakk> \<Longrightarrow> P \<turnstile> Q"
    apply (auto intro: conj_entails_mono)[1]
   apply (simp, isep_assumption, simp)
  apply simp
  done

lemma arl_elem_assn_def':
  "arl_elem_assn A xs xsi = (EXS l. \<upharpoonleft>arl_assn l xsi ** \<upharpoonleft>(list_assn A (Map.empty)) xs l)"
  unfolding arl_elem_assn_ex_def
  by simp

lemma is_pure_pureI:
  "is_pure A \<Longrightarrow> pure_part (\<upharpoonleft>A x y) \<Longrightarrow> \<box> \<turnstile> \<upharpoonleft>A x y"
  by (simp add: extract_pure_assn pure_true_conv)

lemma pure_pure_asm_prefixI:
  "\<flat>\<^sub>passn x y \<Longrightarrow> \<box> \<turnstile> \<upharpoonleft>assn x y"
  by (metis (full_types) dr_assn_pure_asm_prefix_def entails_refl extract_pure_assn pure_true_conv)

lemma snat_assn_le_iso [simp]:
  "\<lbrakk>\<flat>\<^sub>psnat.assn x xi; \<flat>\<^sub>psnat.assn y yi\<rbrakk> \<Longrightarrow> xi < yi \<longleftrightarrow> x < y"
  unfolding snat.assn_def
  by (auto simp add: snat_eq_unat_aux2 unat_mono word_less_nat_alt)

lemmas la_ired_extract[isep_red] = la_red_extract[simplified PRECOND_def SOLVE_AUTO_def]

lemma la_ired_join[isep_red]:
  "R i = None \<and> i<length xs \<and> x=xs!i \<and> y=ys!i
      \<Longrightarrow> is_sep_red \<box> \<box> (\<upharpoonleft>A x y ** \<upharpoonleft>(list_assn A (R(i\<mapsto>ys!i))) xs ys) (\<upharpoonleft>(list_assn A R) xs ys)"
  apply (rule is_sep_redI)
  subgoal premises prems
    apply (isep_drule drule: prems(2))
    apply (isep_drule drule: list_assn_join)
    using prems apply auto
    apply (simp add: fun_upd_idem)
    done
  done

lemma arl_mems_len_rule [vcg_rules]:
  "
  llvm_htriple
  (arl_elem_assn_ex A xs xsi arl ex)
  (arl_len arl)
  (\<lambda>len. \<upharpoonleft>snat.assn (length xs) len ** arl_elem_assn_ex A xs xsi arl ex)
"
  unfolding arl_elem_assn_ex_def
  apply vcg
  apply vcg_compat
  apply isep_extract_pure
  apply (isep_rule rule: pure_pure_asm_prefixI, (auto dest: list_assn_pure_partD)[1])
  apply sep
  done

lemma arl_mems_nth_rule [vcg_rules]:
"
  llvm_htriple
  (arl_elem_assn_ex A xs xsi arl ex ** \<upharpoonleft>snat.assn i ii ** \<up>(i < length xs) ** \<up>(i \<notin> ex))
  (arl_nth arl ii)
  (\<lambda>elem. arl_elem_assn_ex A xs xsi arl (ex \<union> {i}) ** \<upharpoonleft>A (xs ! i) elem ** \<up>(elem = xsi ! i))
"
  unfolding arl_elem_assn_ex_def
  apply vcg
  apply vcg_compat
  apply (sep | find_sep)+
    apply ((auto dest!: list_assn_pure_partD))
  unfolding idxe_map_def
  by (simp add: restrict_map_insert)

unbundle monad_syntax_M

definition [llvm_inline]: "llc_for_range l h c s \<equiv> doM {
  (_,s) \<leftarrow> llc_while (\<lambda>(i,s). ll_cmp (i<h)) (\<lambda>(i,s). doM {
    s\<leftarrow>c i s;
    i \<leftarrow> ll_add i 1;
    Mreturn (i,s)}
  ) (l,s);
  Mreturn s
}"

lemma llc_for_range_rule:
  assumes [vcg_rules]:
    "\<And>i ii si.
     llvm_htriple
      (\<upharpoonleft>snat.assn i ii ** \<up>\<^sub>d(lo\<le>i \<and> i<hi) ** I i si)
      (c ii si)
      (\<lambda>si. I (i+1) si)"
  shows
    "llvm_htriple
      (\<upharpoonleft>snat.assn lo loi ** \<upharpoonleft>snat.assn hi hii ** \<up>(lo\<le>hi) ** I lo si)
      (llc_for_range loi hii c si)
      (\<lambda>si. I hi si)"
  unfolding llc_for_range_def
  apply (rewrite at 1 to "signed_nat 1" signed_nat_def[symmetric])
  apply (rewrite annotate_llc_while[where
    I="\<lambda>(ii,si) t. EXS i. \<upharpoonleft>snat.assn i ii ** \<up>(lo\<le>i \<and> i\<le>hi) ** \<up>\<^sub>!(t=hi-i) ** I i si"
    and R="measure id"])
  apply vcg_monadify
  apply vcg'
  done

definition [llvm_code]:
  "arl_mems_free mem_free arl =
  do {
    len \<leftarrow> arl_len arl;
    llc_for_range 0 len
    (\<lambda>i x.
      do {
        mem \<leftarrow> arl_nth arl i;
        mem_free mem;
        return 0
      }
    )
    (0::1 word);
    arl_free arl
  }"

definition "loop_inv A xs xsi arl i si \<equiv> arl_elem_assn_ex A xs xsi arl {0..<i}"

lemma empty_arl_elem_assn_ex_sepD:
  "arl_elem_assn_ex A xs xsi arl {0..<length xs} \<turnstile> \<upharpoonleft>arl_assn xsi arl"
  unfolding arl_elem_assn_ex_def
  apply isep_assumption
  apply isep_extract_pure
  apply (isep_drule drule: list_assn_free_none)
  apply (auto dest: list_assn_pure_partD)
  done

(*
  uint
  unat
  sint
  snat
*)

(*uint \<longrightarrow> unat*)
lemma "uint c1 = a1 \<Longrightarrow> unat c1 = nat a1" by auto

(*uint \<longrightarrow> sint*)
lemma uint_sint_pos:
  "\<lbrakk>uint c1 = a1; a1 < 2^(word_len c1 - 1)\<rbrakk> \<Longrightarrow> sint c1 = a1"
  by (simp add: sint_eq_uint_2pl uint_power_lower word_less_def)

lemma uint_sint_neg:
  "\<lbrakk>uint c1 = a1; a1 \<ge> 2^(word_len c1 - 1)\<rbrakk> \<Longrightarrow> sint c1 = a1 - 2^(word_len c1)"
  using word_sint_msb_eq word_size msb_uint_big by (metis (full_types))

(*uint \<rightarrow> snat*)
lemma uint_snat_pos:
  "\<lbrakk>uint c1 = a1; a1 < 2^(word_len c1 - 1)\<rbrakk> \<Longrightarrow> snat c1 = nat a1"
  by (simp add: snat_eq_unat_aux1 unat_def)

lemma uint_snat_neg:
  "\<lbrakk>uint c1 = a1; a1 \<ge> 2^(word_len c1 - 1)\<rbrakk> \<Longrightarrow> snat c1 = 0"
  unfolding snat_def
  apply (auto simp add: uint_sint_neg)
  using less_le_not_le by blast

(*unat \<longrightarrow> uint*)
lemma "unat c1 = a1 \<Longrightarrow> uint c1 = int a1" by auto

(*unat \<longrightarrow> snat*)
lemma "\<lbrakk>unat c1 = a1; a1 < 2^(word_len c1 - 1)\<rbrakk> \<Longrightarrow> snat c1 = a1" using snat_eq_unat by blast
lemma "\<lbrakk>unat c1 = a1; a1 \<ge> 2^(word_len c1 - 1)\<rbrakk> \<Longrightarrow> snat c1 = 0"
proof -
  assume "unat c1 = a1" "a1 \<ge> 2^(word_len c1 - 1)"

  hence "msb c1" using msb_unat_big by blast
  hence "sint c1 < 0" using word_msb_sint by blast

  thus "snat c1 = 0" by (simp add: snat_def)
qed

(*unat \<longrightarrow> sint*)

lemma "uint c1 = a1 \<Longrightarrow> unat c1 = nat a1" by auto (*uint \<longrightarrow> unat*)

lemma "snat c1 = a1 \<Longrightarrow> \<not>msb c1 \<Longrightarrow> sint c1 = int a1"
  by (simp add: sint_eq_uint snat_eq_unat(2) snat_invar_def uint_nat)
lemma "\<lbrakk>snat c1 = a1; msb c1\<rbrakk> \<Longrightarrow> a1 = 0"
  unfolding snat_def using word_msb_sint by force

lemma arl_mems_free_rule:
  assumes
    mem_free_rule:
    "\<And>el eli.
      llvm_htriple
      (\<upharpoonleft>A el eli)
      (mem_free eli)
      (\<lambda>_. \<box>)
    "
  shows
    "
      llvm_htriple
      (arl_elem_assn_ex A xs xsi arl {})
      (arl_mems_free mem_free arl)
      (\<lambda>_. \<box>)
    "
  unfolding arl_mems_free_def
  supply llc_for_range_rule[where I="loop_inv A xs xsi arl", vcg_rules]
  apply vcg
  apply vcg_rl
  unfolding loop_inv_def apply vcg_solve (*pre cond*)
  subgoal for asf r sa i ii si (*step*)
    supply mem_free_rule[vcg_rules]
    apply vcg
    apply (simp only: atLeast0_lessThan_Suc)
    apply vcg_solve
    done
  subgoal (*after loop*)
    apply vcg_solve
    unfolding arl_elem_assn_ex_def
    apply vcg
    apply vcg_compat
    apply isep_extract_pure
    apply (isep_drule drule: list_assn_free_none)
     apply (auto dest: list_assn_pure_partD)
    done
  done

end


           (*-------------------------------------------*
            |        CSP-Prover on Isabelle2004         |
            |               December 2004               |
            |                   June 2005  (modified)   |
            |              September 2005  (modified)   |
            |                                           |
            |        CSP-Prover on Isabelle2005         |
            |                October 2005  (modified)   |
            |                  April 2006  (modified)   |
            |                  March 2007  (modified)   |
            |                                           |
            |        CSP-Prover on Isabelle2009         |
            |                   June 2009  (modified)   |
            |                                           |
            |        Yoshinao Isobe (AIST JAPAN)        |
            *-------------------------------------------*)

theory CSP_T_law_step
imports CSP_T_traces
begin

(*****************************************************************

         1. step laws
         2.
         3.
         4.

 *****************************************************************)

(*********************************************************
                    stop expansion
 *********************************************************)

(*------------------*
 |      csp law     |
 *------------------*)

lemma cspT_STOP_step: "STOP =T[M1,M2] ? :{} -> Pf"
apply (simp add: cspT_semantics)
apply (simp add: traces_iff)
done

(* to avoide producing free variables (Pf) in tactics *)

lemma cspT_STOP_step_DIV: "STOP =T[M1,M2] ? x:{} -> DIV"
apply (simp add: cspT_semantics)
apply (simp add: traces_iff)
done

(*********************************************************
                    Act_prefix expansion
 *********************************************************)

(*------------------*
 |      csp law     |
 *------------------*)

lemma cspT_Act_prefix_step: "a -> P =T[M,M] ? x:{a} -> P"
apply (simp add: cspT_semantics)
apply (simp add: traces_iff)
done

(*********************************************************
                    Ext choice expansion
 *********************************************************)

(*------------------*
 |      csp law     |
 *------------------*)

lemma cspT_Ext_choice_step:
  "(? :X -> Pf) [+] (? :Y -> Qf) =T[M,M]
      ? x:(X Un Y) ->
                (IF (x : X & x : Y) THEN (Pf x |~| Qf x)
                 ELSE IF (x : X) THEN Pf x
                 ELSE Qf x)"
apply (simp add: cspT_semantics)
apply (rule order_antisym)

(* => *)
 apply (rule)
 apply (simp add: in_traces)
 apply (elim disjE conjE exE)
 apply (simp_all)

 apply (rule_tac x="a" in exI)
 apply (rule_tac x="s" in exI)
 apply (simp)

 apply (rule_tac x="a" in exI)
 apply (rule_tac x="s" in exI)
 apply (simp)

(* <= *)
 apply (rule)
 apply (simp add: in_traces)
 apply (elim disjE conjE exE)
 apply (simp_all)

 apply (case_tac "a : Y")
 apply (simp_all add: in_traces)

 apply (case_tac "a : X")
 apply (simp_all add: in_traces)
done

(*********************************************************
                    Parallel expansion
 *********************************************************)

(*------------------*
 |      csp law     |
 *------------------*)

lemma cspT_Parallel_step:
  "(? :Y -> Pf) |[X]| (? :Z -> Qf) =T[M,M]
      ? x:((X Int Y Int Z) Un (Y - X) Un (Z - X))
         -> IF (x : X) THEN (Pf x |[X]| Qf x)
               ELSE IF (x : Y & x : Z) THEN ((Pf x |[X]| ? x:Z -> Qf x)
                                     |~| (? x:Y -> Pf x |[X]| Qf x))
               ELSE IF (x : Y) THEN (Pf x |[X]| ? x:Z -> Qf x)
               ELSE (? x:Y -> Pf x |[X]| Qf x)"
apply (simp add: cspT_semantics)
apply (rule order_antisym)

(* => *)
 apply (rule)
 apply (insert trace_nil_or_Tick_or_Ev)
 apply (drule_tac x="t" in spec)
 apply (elim disjE conjE exE)

 (* <> *)
  apply (simp)

 (* [Tick]t *)
  apply (simp add: in_traces)

 (* [Ev .]t *)
  apply (simp add: in_traces)
  apply (elim disjE conjE exE)

  (* 1 *)
  apply (simp)

  (* 2 *)
  apply (simp add: par_tr_head)
  apply (elim conjE exE)
  apply (case_tac "a : Y")
   apply (simp)
   apply (rule disjI2)
   apply (rule_tac x="<>" in exI)
   apply (rule_tac x="sb" in exI)
   apply (simp)
   (* a ~: Y *)
   apply (simp)
   apply (rule_tac x="<>" in exI)
   apply (rule_tac x="sb" in exI)
   apply (simp)

  (* 3 *)
  apply (simp add: par_tr_head)
  apply (elim conjE exE)
  apply (case_tac "a : Z")
   apply (simp)
   apply (rule disjI1)
   apply (rule_tac x="sb" in exI)
   apply (rule_tac x="<>" in exI)
   apply (simp)
   (* a ~: Z *)
   apply (simp)
   apply (rule_tac x="sb" in exI)
   apply (rule_tac x="<>" in exI)
   apply (simp)

  (* 4 *)
  apply (simp add: par_tr_head)
  apply (elim disjE conjE exE)

   (* 4-1 *)
   apply (simp)
   apply (rule_tac x="sb" in exI)
   apply (rule_tac x="sc" in exI)
   apply (simp)

   (* 4-2 *)
   apply (case_tac "a : Z")
    apply (simp)
    apply (rule disjI1)
    apply (rule_tac x="sb" in exI)
    apply (rule_tac x="<Ev ab> ^^^ sc" in exI)
    apply (simp)
    (* a ~: Z *)
    apply (simp)
    apply (rule_tac x="sb" in exI)
    apply (rule_tac x="<Ev ab> ^^^ sc" in exI)
    apply (simp)

   (* 4-3 *)
   apply (simp)
   apply (case_tac "a : Y")
    apply (simp)
    apply (rule disjI2)
    apply (rule_tac x="<Ev aa> ^^^ sb" in exI)
    apply (rule_tac x="sc" in exI)
    apply (simp)
    (* a ~: Y *)
    apply (simp)
    apply (rule_tac x="<Ev aa> ^^^ sb" in exI)
    apply (rule_tac x="sc" in exI)
    apply (simp)

(* <= *)
 apply (rule)+
 apply (drule_tac x="t" in spec)
 apply (elim disjE conjE exE)

 (* <> *)
  apply (simp)

 (* [Tick]t *)
  apply (simp add: in_traces)

 (* [Ev .]t *)
  apply (simp add: in_traces)
  apply (elim disjE conjE exE)

  (* 1 *)
  apply (simp add: in_traces)
  apply (elim conjE exE)
  apply (rule_tac x="<Ev a> ^^^ sa" in exI)
  apply (rule_tac x="<Ev a> ^^^ ta" in exI)
  apply (simp add: par_tr_head)

  (* 2 *)
  apply (simp add: in_traces)
  apply (case_tac "a : Z")
   apply (simp add: in_traces)
   apply (erule disjE)

    apply (elim conjE exE)
    apply (rule_tac x="<Ev a> ^^^ sa" in exI)
    apply (rule_tac x="ta" in exI)
    apply (simp add: par_tr_head)

    apply (elim conjE exE)
    apply (rule_tac x="sa" in exI)
    apply (rule_tac x="<Ev a> ^^^ ta" in exI)
    apply (simp add: par_tr_head)

  (* 3 *)
  apply (simp add: in_traces)
  apply (elim conjE exE)

   apply (rule_tac x="<Ev a> ^^^ sa" in exI)
   apply (rule_tac x="ta" in exI)
   apply (simp add: par_tr_head)

   apply (simp add: in_traces)
   apply (case_tac "a : Y")

    apply (simp add: in_traces)
    apply (erule disjE)
     apply (elim conjE exE)
     apply (rule_tac x="<Ev a> ^^^ sa" in exI)
     apply (rule_tac x="ta" in exI)
     apply (simp add: par_tr_head)
     (* *)
     apply (elim conjE exE)
     apply (rule_tac x="sa" in exI)
     apply (rule_tac x="<Ev a> ^^^ ta" in exI)
     apply (simp add: par_tr_head)

    apply (simp add: in_traces)
    apply (elim conjE exE)
    apply (rule_tac x="sa" in exI)
    apply (rule_tac x="<Ev a> ^^^ ta" in exI)
    apply (simp add: par_tr_head)
done

(*********************************************************
                      Hide expansion
 *********************************************************)

(*------------------*
 |      csp law     |
 *------------------*)

lemma cspT_Hiding_step:
  "(? :Y -> Pf) -- X =T[M,M]
      IF (Y Int X = {}) THEN (? x:Y -> (Pf x -- X))
                         ELSE ((? x:(Y-X) -> (Pf x -- X))
                               [> (! x:(Y Int X) .. (Pf x -- X)))"
apply (simp add: cspT_semantics)
apply (rule order_antisym)

 (* => *)
 apply (rule)
 apply (simp add: in_traces)
 apply (elim conjE exE)
 apply (erule disjE, simp)
 apply (elim conjE exE)

 apply (case_tac "Y Int X = {}")
  apply (simp)
  apply (case_tac "a : X", fast)
  apply (simp)
  apply (rule_tac x="sa" in exI)
  apply (simp)

  (* Y Int X ~= {} *)
  apply (simp)
  apply (case_tac "a : X")
   apply (simp)
   apply (fast)
  (* a ~: X *)
   apply (simp)
   apply (fast)

 (* <= *)
 apply (rule)
 apply (case_tac "Y Int X = {}")
  apply (simp add: in_traces)
  apply (erule disjE, simp)
   apply (rule_tac x="<>" in exI)
   apply (simp)

  apply (elim conjE exE)
  apply (case_tac "a : X", fast)
   apply (rule_tac x="<Ev a> ^^^ sa" in exI)
   apply (simp)

 (* Y Int X = {} *)
  apply (simp add: in_traces)
  apply (erule disjE, simp)
   apply (rule_tac x="<>" in exI)
   apply (simp)

  apply (erule disjE)
  (* a~:X *)
   apply (elim conjE exE)
   apply (rule_tac x="<Ev a> ^^^ sa" in exI)
   apply (simp)
  (* a:X *)
   apply (erule disjE, simp)
    apply (rule_tac x="<>" in exI)
    apply (simp)

   apply (elim conjE exE bexE)
   apply (rule_tac x="<Ev a> ^^^ s" in exI)
   apply (simp)
done

(*********************************************************
                    Renaming expansion
 *********************************************************)

(*------------------*
 |      csp law     |
 *------------------*)

lemma cspT_Renaming_step:
  "(? :X -> Pf) [[r]] =T[M,M]
    ? y:(r `` X) -> (! x:{x. x:X & (x,y):r} .. (Pf x)[[r]])"
apply (simp add: cspT_semantics)
apply (rule order_antisym)

(* => *)
 apply (rule)
 apply (simp add: in_traces)
 apply (elim disjE conjE exE)
  (* 1 *)
  apply (simp)

  (* 2 *)
  apply (rule disjI2)
  apply (simp add: ren_tr_decompo)
  apply (elim conjE exE)
  apply (rule_tac x="b" in exI)
  apply (rule_tac x="ta" in exI)
  apply (simp)
  apply (fast)

(* <= *)
 apply (rule)
 apply (simp add: in_traces)
 apply (erule disjE, simp)
 apply (elim disjE conjE exE)
  apply (simp add: Image_iff)
  apply (erule bexE)
  apply (rule_tac x="<Ev x>" in exI)
  apply (simp)
 (* *)
  apply (rule_tac x="<Ev aa> ^^^ sa" in exI)
  apply (simp)
done

(*********************************************************
            Sequential composition expansion
 *********************************************************)

(*------------------*
 |      csp law     |
 *------------------*)

lemma cspT_Seq_compo_step:
  "(? :X -> Pf) ;; Q =T[M,M] ? x:X -> (Pf x ;; Q)"
apply (simp add: cspT_semantics)
apply (rule order_antisym)

(* => *)
 apply (rule)
 apply (simp add: in_traces)
 apply (elim conjE exE disjE)
 apply (simp_all)

  (* 1 *)
 apply (fast)

  (* 2 *)
 apply (insert trace_last_nil_or_unnil)
 apply (drule_tac x="sa" in spec)
 apply (erule disjE, simp)
 apply (elim conjE exE, simp)
 apply (simp add: appt_assoc_sym)
 apply (rule_tac x="a" in exI)
 apply (rule_tac x="sb ^^^ ta" in exI)
 apply (simp add: appt_assoc)
 apply (fast)

(* <= *)
 apply (rule)
 apply (simp add: in_traces)
 apply (erule disjE, simp)
 apply (rule disjI1)
 apply (rule_tac x="<>" in exI)
 apply (simp)
 apply (elim disjE conjE exE)

 (* 1 *)
  apply (rule disjI1)
  apply (rule_tac x="<Ev a> ^^^ sa" in exI, simp)

 (* 2 *)
  apply (rule disjI2)
  apply (rule_tac x="<Ev a> ^^^ sa" in exI)
  apply (rule_tac x="ta" in exI)
  apply (simp add: appt_assoc)
done

(*********************************************************
                    Depth_rest expansion
 *********************************************************)

(*------------------*
 |      csp law     |
 *------------------*)

lemma cspT_Depth_rest_step:
  "(? :X -> Pf) |. (Suc n) =T[M,M] ? x:X -> (Pf x |. n)"
apply (simp add: cspT_semantics)
apply (rule order_antisym)

(* => *)
 apply (rule)
 apply (simp add: in_traces)
 apply (elim disjE conjE exE)
 apply (simp_all)

(* <= *)
 apply (rule)
 apply (simp add: in_traces)
 apply (elim disjE conjE exE)
 apply (simp_all)
done

(*********************************************************)

lemmas cspT_step = cspT_STOP_step       cspT_Act_prefix_step
                   cspT_Ext_choice_step cspT_Parallel_step
                   cspT_Hiding_step     cspT_Renaming_step
                   cspT_Seq_compo_step  cspT_Depth_rest_step

lemmas cspT_light_step = cspT_STOP_step  cspT_Act_prefix_step

lemmas cspT_step_rw = cspT_STOP_step_DIV       cspT_Act_prefix_step
                   cspT_Ext_choice_step cspT_Parallel_step
                   cspT_Hiding_step     cspT_Renaming_step
                   cspT_Seq_compo_step  cspT_Depth_rest_step

lemmas cspT_light_step_rw = cspT_STOP_step_DIV  cspT_Act_prefix_step

end