(*  Title:      HOL/Auth/n_german_lemma_inv__40_on_rules.thy
    Author:     Yongjian Li and Kaiqiang Duan, State Key Lab of Computer Science, Institute of Software, Chinese Academy of Sciences
    Copyright    2016 State Key Lab of Computer Science, Institute of Software, Chinese Academy of Sciences
*)

(*header{*The n_german Protocol Case Study*}*)

theory n_german_lemma_inv__40_on_rules imports n_german_lemma_on_inv__40
begin
section{*All lemmas on causal relation between inv__40*}
lemma lemma_inv__40_on_rules:
  assumes b1: "r \<in> rules N" and b2: "(\<exists> p__Inv2. p__Inv2\<le>N\<and>f=inv__40  p__Inv2)"
  shows "invHoldForRule s f r (invariants N)"
  proof -
  have c1: "(\<exists> i d. i\<le>N\<and>d\<le>N\<and>r=n_Store  i d)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendReqS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendReqE__part__0  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendReqE__part__1  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvReqS N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvReqE N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInv__part__0  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInv__part__1  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInvAck  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvInvAck  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendGntS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendGntE N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvGntS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvGntE  i)"
  apply (cut_tac b1, auto) done
    moreover {
      assume d1: "(\<exists> i d. i\<le>N\<and>d\<le>N\<and>r=n_Store  i d)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_StoreVsinv__40) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_SendReqS  i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_SendReqSVsinv__40) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_SendReqE__part__0  i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_SendReqE__part__0Vsinv__40) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_SendReqE__part__1  i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_SendReqE__part__1Vsinv__40) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_RecvReqS N i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_RecvReqSVsinv__40) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_RecvReqE N i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_RecvReqEVsinv__40) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_SendInv__part__0  i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_SendInv__part__0Vsinv__40) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_SendInv__part__1  i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_SendInv__part__1Vsinv__40) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_SendInvAck  i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_SendInvAckVsinv__40) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_RecvInvAck  i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_RecvInvAckVsinv__40) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_SendGntS  i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_SendGntSVsinv__40) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_SendGntE N i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_SendGntEVsinv__40) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_RecvGntS  i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_RecvGntSVsinv__40) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_RecvGntE  i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_RecvGntEVsinv__40) done
    }

  ultimately show "invHoldForRule s f r (invariants N)"
  by satx
qed

end


(*  Title:      HOL/Auth/n_germanSimp_lemma_inv__25_on_rules.thy
    Author:     Yongjian Li and Kaiqiang Duan, State Key Lab of Computer Science, Institute of Software, Chinese Academy of Sciences
    Copyright    2016 State Key Lab of Computer Science, Institute of Software, Chinese Academy of Sciences
*)

header{*The n_germanSimp Protocol Case Study*}

theory n_germanSimp_lemma_inv__25_on_rules imports n_germanSimp_lemma_on_inv__25
begin
section{*All lemmas on causal relation between inv__25*}
lemma lemma_inv__25_on_rules:
  assumes b1: "r \<in> rules N" and b2: "(\<exists> p__Inv4. p__Inv4\<le>N\<and>f=inv__25  p__Inv4)"
  shows "invHoldForRule s f r (invariants N)"
  proof -
  have c1: "(\<exists> i d. i\<le>N\<and>d\<le>N\<and>r=n_Store  i d)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvReqS N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvReqE__part__0 N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvReqE__part__1 N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInv__part__0  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInv__part__1  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInvAck  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvInvAck  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendGntS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendGntE N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvGntS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvGntE  i)"
  apply (cut_tac b1, auto) done
    moreover {
      assume d1: "(\<exists> i d. i\<le>N\<and>d\<le>N\<and>r=n_Store  i d)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_StoreVsinv__25) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_RecvReqS N i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_RecvReqSVsinv__25) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_RecvReqE__part__0 N i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_RecvReqE__part__0Vsinv__25) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_RecvReqE__part__1 N i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_RecvReqE__part__1Vsinv__25) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_SendInv__part__0  i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_SendInv__part__0Vsinv__25) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_SendInv__part__1  i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_SendInv__part__1Vsinv__25) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_SendInvAck  i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_SendInvAckVsinv__25) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_RecvInvAck  i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_RecvInvAckVsinv__25) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_SendGntS  i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_SendGntSVsinv__25) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_SendGntE N i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_SendGntEVsinv__25) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_RecvGntS  i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_RecvGntSVsinv__25) done
    }

    moreover {
      assume d1: "(\<exists> i. i\<le>N\<and>r=n_RecvGntE  i)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_RecvGntEVsinv__25) done
    }

  ultimately show "invHoldForRule s f r (invariants N)"
  by satx
qed

end


theory InferSound
  imports InferDef
begin

    (* ##### inference correctness lemma 1 *)

lemma ivl_const_main: "\<lbrakk> dir_sol_sat t_sub p_sub c_list; const_scheme x ds tau c_list ds'\<rbrakk> \<Longrightarrow> full_subst_type t_sub p_sub tau_n tau \<in> const_type x"
  apply (case_tac x)
              apply (auto)
              apply (simp_all add: full_subst_type_def)
              apply (simp_all add: pure_fun_s_def)
              apply (simp_all add: pure_fun_def)
              apply (simp_all add: unlim_def)
        apply (simp_all add: is_own_def)
      apply (auto)
  done

lemma ivl_op_main: "full_subst_type t_sub p_sub tau_n (op_scheme x) = op_type x"
  apply (case_tac x)
       apply (auto)
       apply (simp_all add: full_subst_type_def)
       apply (simp_all add: pure_fun_s_def)
       apply (simp_all add: pure_fun_def)
  done

lemma ivl_pair_ih: "\<lbrakk> \<And>env tau r_s r_x r_m c_list ds ds'.
           \<lbrakk>infer_type env ds e tau r_s r_x r_m c_list ds'; dir_sol_sat t_sub p_sub c_list\<rbrakk>
           \<Longrightarrow> well_typed (dir_subst_tenv (fill_tsub t_sub tau_n) env) delta (dir_subst_penv t_sub p_sub r_s) e (full_subst_type t_sub p_sub tau_n tau)
                (diff_use_env (dir_subst_penv t_sub p_sub r_s) (dir_subst_penv t_sub p_sub r_m))
                (diff_use_env (dir_subst_penv t_sub p_sub r_x) (dir_subst_penv t_sub p_sub r_m));
  infer_type env ds e tau r_s r_x r_m c_list ds'; dir_sol_sat t_sub p_sub c_list\<rbrakk> \<Longrightarrow>
  well_typed (dir_subst_tenv (fill_tsub t_sub tau_n) env) delta (dir_subst_penv t_sub p_sub r_s) e (full_subst_type t_sub p_sub tau_n tau)
                (diff_use_env (dir_subst_penv t_sub p_sub r_s) (dir_subst_penv t_sub p_sub r_m))
                (diff_use_env (dir_subst_penv t_sub p_sub r_x) (dir_subst_penv t_sub p_sub r_m))"
  apply (auto)
  done

lemma ivl_if_ih: "\<lbrakk> \<And>env tau r_s r_x r_m c_list ds ds'.
           \<lbrakk>infer_type env ds e tau r_s r_x r_m c_list ds'; dir_sol_sat t_sub p_sub c_list\<rbrakk>
           \<Longrightarrow> well_typed (dir_subst_tenv (fill_tsub t_sub tau_n) env) delta (dir_subst_penv t_sub p_sub r_s) e (full_subst_type t_sub p_sub tau_n tau)
                (diff_use_env (dir_subst_penv t_sub p_sub r_s) (dir_subst_penv t_sub p_sub r_m))
                (diff_use_env (dir_subst_penv t_sub p_sub r_x) (dir_subst_penv t_sub p_sub r_m));
  infer_type env ds e tau r_s r_x r_m c_list ds'; dir_sol_sat t_sub p_sub c_list \<rbrakk> \<Longrightarrow>
  well_typed (dir_subst_tenv (fill_tsub t_sub tau_n) env) delta (dir_subst_penv t_sub p_sub r_s) e (full_subst_type t_sub p_sub tau_n tau)
                (diff_use_env (dir_subst_penv t_sub p_sub r_s) (dir_subst_penv t_sub p_sub r_m))
                (diff_use_env (dir_subst_penv t_sub p_sub r_x) (dir_subst_penv t_sub p_sub r_m))"
  apply (auto)
  done

lemma ivl_lam_ih: "\<lbrakk> \<And>env tau r_s r_x r_m c_list ds ds'.
           \<lbrakk>infer_type env ds e tau r_s r_x r_m c_list ds'; dir_sol_sat t_sub p_sub c_list\<rbrakk>
           \<Longrightarrow> well_typed (dir_subst_tenv (fill_tsub t_sub tau_n) env) delta (dir_subst_penv t_sub p_sub r_s) e (full_subst_type t_sub p_sub tau_n tau)
                (diff_use_env (dir_subst_penv t_sub p_sub r_s) (dir_subst_penv t_sub p_sub r_m))
                (diff_use_env (dir_subst_penv t_sub p_sub r_x) (dir_subst_penv t_sub p_sub r_m));
   infer_type env ds e tau r_s r_x r_m c_list ds'; dir_sol_sat t_sub p_sub c_list \<rbrakk> \<Longrightarrow>
  well_typed (dir_subst_tenv (fill_tsub t_sub tau_n) env) delta (dir_subst_penv t_sub p_sub r_s) e (full_subst_type t_sub p_sub tau_n tau)
                (diff_use_env (dir_subst_penv t_sub p_sub r_s) (dir_subst_penv t_sub p_sub r_m))
                (diff_use_env (dir_subst_penv t_sub p_sub r_x) (dir_subst_penv t_sub p_sub r_m))"
  apply (auto)
  done

lemma ivl_app_ih: "\<lbrakk> \<And>env tau r_s r_x r_m c_list ds ds'.
           \<lbrakk>infer_type env ds e tau r_s r_x r_m c_list ds'; dir_sol_sat t_sub p_sub c_list\<rbrakk>
           \<Longrightarrow> well_typed (dir_subst_tenv (fill_tsub t_sub tau_n) env) delta (dir_subst_penv t_sub p_sub r_s) e (full_subst_type t_sub p_sub tau_n tau)
                (diff_use_env (dir_subst_penv t_sub p_sub r_s) (dir_subst_penv t_sub p_sub r_m))
                (diff_use_env (dir_subst_penv t_sub p_sub r_x) (dir_subst_penv t_sub p_sub r_m));
   infer_type env ds e tau r_s r_x r_m c_list ds'; dir_sol_sat t_sub p_sub c_list\<rbrakk> \<Longrightarrow>
  well_typed (dir_subst_tenv (fill_tsub t_sub tau_n) env) delta (dir_subst_penv t_sub p_sub r_s) e (full_subst_type t_sub p_sub tau_n tau)
                (diff_use_env (dir_subst_penv t_sub p_sub r_s) (dir_subst_penv t_sub p_sub r_m))
                (diff_use_env (dir_subst_penv t_sub p_sub r_x) (dir_subst_penv t_sub p_sub r_m))"
  apply (auto)
  done

lemma ivl_var_leq_perm: "\<lbrakk> req_type tau_n = Prim \<rbrakk> \<Longrightarrow>
  leq_perm (end_req_perm (full_subst_type t_sub p_sub tau_n (VarScheme b)))
      (dir_subst_penv t_sub p_sub (one_var_env (Var x) (XType b)) (Var x))"
  apply (simp add: full_subst_type_def)
  apply (simp add: end_req_perm_def)
  apply (simp add: dir_subst_penv_def)
  apply (simp add: one_var_env_def)
  apply (case_tac "t_sub b")
   apply (auto)
  apply (case_tac "req_type a")
    apply (auto)
  done

lemma dir_aff_leq: "\<lbrakk> dir_subst_type t_sub p_sub tau_v tau; aff_leq (req_type tau) r \<rbrakk> \<Longrightarrow>
  aff_leq (req_type (full_subst_type_f t_sub p_sub tau_n tau_v)) r"
  apply (induct tau_v)
         apply (auto)
  done

lemma dir_subst_type_eq: "\<lbrakk> dir_subst_type t_sub p_sub tau_v tau \<rbrakk> \<Longrightarrow> full_subst_type t_sub p_sub tau_n tau_v = tau"
  apply (induct tau_v arbitrary: tau)
         apply (auto)
         apply (simp_all add: full_subst_type_def)
  done

lemma mini_disj_lift_use_env_rev: "\<lbrakk> mini_disj_use_env r_x r_s \<rbrakk> \<Longrightarrow> mini_disj_use_env r_x (lift_use_env r_s r)"
  apply (case_tac r)
    apply (auto)
  apply (simp add: mini_disj_use_env_def)
  done

lemma infer_valid_left: "\<lbrakk> infer_type env ds e tau r_s r_x r_m c_list ds'; dir_sol_sat t_sub p_sub c_list; req_type tau_n = Prim \<rbrakk> \<Longrightarrow>
  well_typed (dir_subst_tenv (fill_tsub t_sub tau_n) env) delta (dir_subst_penv t_sub p_sub r_s) e (full_subst_type t_sub p_sub tau_n tau)
    (diff_use_env (dir_subst_penv t_sub p_sub r_s) (dir_subst_penv t_sub p_sub r_m)) (diff_use_env (dir_subst_penv t_sub p_sub r_x) (dir_subst_penv t_sub p_sub r_m))"
  apply (induct e arbitrary: env tau r_s r_x r_m c_list ds ds')
        apply (auto)
    (* const case *)
             apply (rule_tac ivl_const_main)
              apply (simp_all)
            apply (rule_tac self_diff_leq_use_env)
           apply (rule_tac id_leq_use_env)
    (* op case *)
          apply (rule_tac ivl_op_main)
         apply (rule_tac self_diff_leq_use_env)
        apply (rule_tac id_leq_use_env)
    (* var case *)
       apply (simp add: dir_subst_tenv_def)
       apply (simp add: fill_tsub_def)
       apply (case_tac "t_sub a")
        apply (auto)
        apply (simp add: full_subst_type_def)
       apply (simp add: full_subst_type_def)
      apply (simp add: fill_tsub_def)
      apply (cut_tac x="Var x'" and tau="full_subst_type t_sub p_sub tau_n (VarScheme a)" and
        r_s="dir_subst_penv t_sub p_sub (one_var_env (Var x') (XType a))" in ereq_leq_use_envx)
       apply (rule_tac ivl_var_leq_perm)
       apply (auto)
      apply (rule_tac x="dir_subst_penv t_sub p_sub (one_var_env (Var x') (XType a))" in exI)
      apply (rule_tac x="full_subst_type t_sub p_sub tau_n (VarScheme a)" in exI)
      apply (simp add: full_subst_type_def)
      apply (simp add: dir_subst_tenv_def)
      apply (auto)
          apply (case_tac "t_sub a")
           apply (auto)
         apply (rule_tac dist_diff_leq_use_env_gen)
         apply (rule_tac id_leq_use_env)
        apply (rule_tac dist_comp_leq_use_env)
         apply (simp_all)
       apply (rule_tac id_leq_use_env)
        apply (rule_tac id_leq_use_env)
       apply (rule_tac id_leq_use_env)
      apply (rule_tac dist_diff_leq_use_env_gen)
       apply (simp)
      apply (rule_tac self_comp_leq_use_env2)
    (* pair case. exepected type *)
    (* - prelim: solution satisfaction *)(*
     apply (cut_tac ?cl2.0="semi_disj_crn r_m2 (lift_var_env r_x1 (SVar p)) d @ semi_disj_crn r_m1 (comp_var_env r_s2 (lift_var_env r_x2 (SVar p))) d @ cl1 @ cl2" in sol_sat_append2)
      apply (auto)
     apply (cut_tac ?cl2.0="semi_disj_crn r_m1 (comp_var_env r_s2 (lift_var_env r_x2 (SVar p))) d @ cl1 @ cl2" in sol_sat_append2)
      apply (auto)*)
     apply (simp add: full_subst_type_def)
     apply (cut_tac ?cl2.0="semi_disj_crn r_m2 r_x1 d @ semi_disj_crn r_m1 r_s2 d @ cl1 @ cl2" in sol_sat_append2)
      apply (auto)
     apply (cut_tac ?cl2.0="semi_disj_crn r_m1 r_s2 d @ cl1 @ cl2" in sol_sat_append2)
      apply (auto)
     apply (cut_tac ?cl2.0="cl1 @ cl2" in sol_sat_append2)
      apply (auto)
    (* - prelim: initial disjointness statements *)
     apply (cut_tac r_x="r_m2" and r_s="r_x1" in sol_sat_mini_disj_use_env)
        apply (rule_tac sol_sat_append1)
        apply (auto)
       apply (rule_tac r_s="comp_var_env (comp_var_env r_s1 (lift_var_env r_x1 (SVar p))) (comp_var_env r_s2 (lift_var_env r_x2 (SVar p)))" in finite_sub_dom)
        apply (simp)
       apply (rule_tac comp_sub_dom2)
       apply (rule_tac comp_sub_dom1)
       apply (rule_tac infer_m_sub_dom)
       apply (simp)
      apply (rule_tac r_s="comp_var_env (comp_var_env r_s1 (lift_var_env r_x1 (SVar p))) (comp_var_env r_s2 (lift_var_env r_x2 (SVar p)))" in finite_sub_dom)
       apply (simp)
      apply (rule_tac comp_sub_dom1)
      apply (rule_tac comp_sub_dom2)
      apply (rule_tac lift_sub_dom2)
      apply (rule_tac id_sub_dom)
     apply (cut_tac r_x="r_m1" and r_s="r_s2" in sol_sat_mini_disj_use_env)
        apply (rule_tac sol_sat_append1)
        apply (auto)
       apply (rule_tac r_s="comp_var_env (comp_var_env r_s1 (lift_var_env r_x1 (SVar p))) (comp_var_env r_s2 (lift_var_env r_x2 (SVar p)))" in finite_sub_dom)
        apply (simp)
       apply (rule_tac comp_sub_dom1)
       apply (rule_tac comp_sub_dom1)
       apply (rule_tac infer_m_sub_dom)
       apply (simp)
      apply (rule_tac r_s="comp_var_env (comp_var_env r_s1 (lift_var_env r_x1 (SVar p))) (comp_var_env r_s2 (lift_var_env r_x2 (SVar p)))" in finite_sub_dom)
       apply (simp)
      apply (rule_tac comp_sub_dom2)
      apply (rule_tac comp_sub_dom1)
      apply (rule_tac id_sub_dom)
     apply (cut_tac r_x="lift_var_env r_x1 (SVar p)" and r_s="lift_var_env r_x2 (SVar p)" in sol_sat_disj_use_env)
        apply (rule_tac sol_sat_append1)
        apply (auto)
       apply (rule_tac r_s="comp_var_env (comp_var_env r_s1 (lift_var_env r_x1 (SVar p))) (comp_var_env r_s2 (lift_var_env r_x2 (SVar p)))" in finite_sub_dom)
        apply (simp)
       apply (rule_tac comp_sub_dom1)
       apply (rule_tac comp_sub_dom2)
       apply (rule_tac id_sub_dom)
      apply (rule_tac r_s="comp_var_env (comp_var_env r_s1 (lift_var_env r_x1 (SVar p))) (comp_var_env r_s2 (lift_var_env r_x2 (SVar p)))" in finite_sub_dom)
       apply (simp)
      apply (rule_tac comp_sub_dom2)
      apply (rule_tac comp_sub_dom2)
      apply (rule_tac id_sub_dom)
(*
     apply (cut_tac r_x="comp_var_env r_s1 (lift_var_env r_x1 (SVar p))" and r_s="comp_var_env r_s2 (lift_var_env r_x2 (SVar p))" and d="d" in sol_sat_disj_use_env)
        apply (rule_tac ?cl2.0="cl1 @ cl2" in sol_sat_append1)
        apply (simp)
       apply (rule_tac r_s="comp_var_env (comp_var_env r_s1 (lift_var_env r_x1 (SVar p))) (comp_var_env r_s2 (lift_var_env r_x2 (SVar p)))" in finite_sub_dom)
        apply (simp)
       apply (rule_tac comp_sub_dom1)
       apply (rule_tac id_sub_dom)
      apply (rule_tac r_s="comp_var_env (comp_var_env r_s1 (lift_var_env r_x1 (SVar p))) (comp_var_env r_s2 (lift_var_env r_x2 (SVar p)))" in finite_sub_dom)
       apply (simp)
      apply (rule_tac comp_sub_dom2)
      apply (rule_tac id_sub_dom)*)
    (* - expected permission environments *)
     apply (rule_tac x="diff_use_env (dir_subst_penv t_sub p_sub (comp_var_env (comp_var_env r_s1 (lift_var_env r_x1 (SVar p)))
        (comp_var_env r_s2 (lift_var_env r_x2 (SVar p))))) (dir_subst_penv t_sub p_sub r_m1)" in exI)
     apply (rule_tac x="diff_use_env (dir_subst_penv t_sub p_sub (comp_var_env (comp_var_env r_s1 (lift_var_env r_x1 (SVar p)))
        (comp_var_env r_s2 (lift_var_env r_x2 (SVar p)))))
        (dir_subst_penv t_sub p_sub (comp_var_env r_m1 r_m2))" in exI)
     apply (rule_tac x="diff_use_env (dir_subst_penv t_sub p_sub r_x1) (dir_subst_penv t_sub p_sub r_m1)" in exI)
     apply (auto)
    (* - induction for e1 *)
      apply (cut_tac env="env" and delta="delta" and ds="ds" and e="e1" and tau="t1" and r_s="r_s1" and r_x="r_x1" and r_m="r_m1" and
        c_list="cl1" and ds'="ds2" and t_sub="t_sub" and p_sub="p_sub" and tau_n="tau_n" in ivl_pair_ih)
         apply (auto)
        apply (simp add: full_subst_type_def)
       apply (rule_tac sol_sat_append1)
       apply (simp)
    (* > remove [S2 + lift(X2, p)] using the precision lemma *)
      apply (simp add: comp_sol_subst_penv)
      apply (rule_tac well_typed_comp_perms_prec)
(*
    (* > get into form [(S1 + lift(X1, p)) - M1] + [(S2 + lift(X2, p)) - M1] *)
      apply (simp add: comp_sol_subst_penv)
      apply (rule_tac t="diff_use_env
              (comp_use_env (comp_use_env (dir_subst_penv t_sub p_sub r_s1) (dir_subst_penv t_sub p_sub (lift_var_env r_x1 (SVar p))))
                (comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p)))))
              (dir_subst_penv t_sub p_sub r_m1)" and
        s="comp_use_env (diff_use_env (comp_use_env (dir_subst_penv t_sub p_sub r_s1) (dir_subst_penv t_sub p_sub (lift_var_env r_x1 (SVar p))))
              (dir_subst_penv t_sub p_sub r_m1))
                (diff_use_env (comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p))))
              (dir_subst_penv t_sub p_sub r_m1))" in subst)
       apply (rule_tac dist_diff_comp_use_env)
    (* > increase [(S2 + lift(X2, p)) - M1] to (S2 + lift(X2, p)) *)
      apply (rule_tac r_c="comp_use_env
              (diff_use_env (comp_use_env (dir_subst_penv t_sub p_sub r_s1) (dir_subst_penv t_sub p_sub (lift_var_env r_x1 (SVar p))))
                (dir_subst_penv t_sub p_sub r_m1))
              (comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p))))" in well_typed_decr_end_perm)
    (* > remove (S2 + lift(X2, p)) from the start + end perms *)
        apply (rule_tac well_typed_comp_perms)*)
    (* > transform [(S1 + lift(X1, p)) - M1] into (S1 - M1) + lift(X1 - M1, p) *)
       apply (rule_tac t="dir_subst_penv t_sub p_sub (lift_var_env r_x1 (SVar p))" and
              s="lift_use_env (dir_subst_penv t_sub p_sub r_x1) (sol_subst_perm p_sub (SVar p))" in subst)
        apply (rule_tac lift_sol_subst_penv)
       apply (simp_all)
      apply (rule_tac t="diff_use_env (comp_use_env (dir_subst_penv t_sub p_sub r_s1) (lift_use_env (dir_subst_penv t_sub p_sub r_x1) (p_sub p))) (dir_subst_penv t_sub p_sub r_m1)"
          and s="comp_use_env (diff_use_env (dir_subst_penv t_sub p_sub r_s1) (dir_subst_penv t_sub p_sub r_m1))
            (diff_use_env (lift_use_env (dir_subst_penv t_sub p_sub r_x1) (p_sub p)) (dir_subst_penv t_sub p_sub r_m1))" in subst)
       apply (rule_tac dist_diff_comp_use_env)
      apply (simp add: lift_diff_use_env)
    (* > remove lifts and cancel X1 *)
      apply (rule_tac well_typed_comp_lift_perms)
       apply (cut_tac r_s="dir_subst_penv t_sub p_sub r_s1" and r_x="dir_subst_penv t_sub p_sub r_x1" in cancel_comp_use_env2)
        apply (rule_tac env="env" and e="e1" and c_list="cl1" in infer_x_leq_use_env)
        apply (auto)
       apply (cut_tac r_s="diff_use_env (dir_subst_penv t_sub p_sub r_s1) (dir_subst_penv t_sub p_sub r_m1)" and
          r_x="diff_use_env (dir_subst_penv t_sub p_sub r_x1) (dir_subst_penv t_sub p_sub r_m1)" in cancel_comp_use_env2)
        apply (rule_tac dist_diff_leq_use_env)
        apply (rule_tac env="env" and e="e1" and c_list="cl1" in infer_x_leq_use_env)
        apply (auto)
    (* - proof of bound changes *)
       apply (simp add: full_subst_type_def)
      apply (rule_tac self_diff_leq_use_env)
(*
       apply (rule_tac dist_comp_leq_use_env)
        apply (rule_tac self_comp_leq_use_env1)
       apply (rule_tac comp_leq_use_env2)
       apply (rule_tac self_diff_leq_use_env)
      apply (rule_tac comp_leq_use_env1)
      apply (rule_tac dist_diff_leq_use_env)
      apply (rule_tac comp_leq_use_env2)
      apply (rule_tac lift_leq_var_env)
      apply (rule_tac id_leq_use_env)*)
    (* - induction for e2. *)
     apply (rule_tac x="diff_use_env (dir_subst_penv t_sub p_sub r_x2) (dir_subst_penv t_sub p_sub r_m2)" in exI)
     apply (cut_tac env="env" and delta="delta" and ds="ds2" and e="e2" and tau="t2" and r_s="r_s2" and r_x="r_x2" and r_m="r_m2" and
        c_list="cl2" and ds'="ds3" and t_sub="t_sub" and p_sub="p_sub" and tau_n="tau_n" in ivl_pair_ih)
        apply (auto)
            apply (simp add: full_subst_type_def)
           apply (rule_tac sol_sat_append2)
           apply (simp)
          apply (simp add: comp_sol_subst_penv)
    (* > reduce end perms *)
          apply (rule_tac ?r_s2.0="diff_use_env (diff_use_env (comp_use_env
              (comp_use_env (dir_subst_penv t_sub p_sub r_s1) (dir_subst_penv t_sub p_sub (lift_var_env r_x1 (SVar p))))
              (comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p))))) (dir_subst_penv t_sub p_sub r_m2))
              (dir_subst_penv t_sub p_sub r_m1)" and rx="diff_use_env (diff_use_env (dir_subst_penv t_sub p_sub r_x2)
              (dir_subst_penv t_sub p_sub r_m2)) (dir_subst_penv t_sub p_sub r_m1)" in well_typed_simul_end_perm)
    (*
           apply (rule_tac ?r_s2.0="diff_use_env (comp_use_env (comp_use_env (dir_subst_penv t_sub p_sub r_s1) (dir_subst_penv t_sub p_sub (lift_var_env r_x1 (SVar p))))
              (diff_use_env (comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p)))) (dir_subst_penv t_sub p_sub r_m2)))
              (dir_subst_penv t_sub p_sub r_m1)" and rx="diff_use_env (diff_use_env (dir_subst_penv t_sub p_sub r_x2)
              (dir_subst_penv t_sub p_sub r_m2)) (dir_subst_penv t_sub p_sub r_m1)" in well_typed_simul_end_perm)*)
             apply (rule_tac well_typed_diff_perms)
              apply (rule_tac well_typed_comp_perms_prec2)
    (* - unroll lifts *)
               apply (rule_tac t="dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p))" and
                s="lift_use_env (dir_subst_penv t_sub p_sub r_x2) (sol_subst_perm p_sub (SVar p))" in subst)
                apply (rule_tac lift_sol_subst_penv)
               apply (rule_tac t="diff_use_env (comp_use_env (dir_subst_penv t_sub p_sub r_s2) (lift_use_env (dir_subst_penv t_sub p_sub r_x2) (sol_subst_perm p_sub (SVar p))))
                (dir_subst_penv t_sub p_sub r_m2)" and s="comp_use_env (diff_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub r_m2))
                (diff_use_env (lift_use_env (dir_subst_penv t_sub p_sub r_x2) (sol_subst_perm p_sub (SVar p))) (dir_subst_penv t_sub p_sub r_m2))" in subst)
                apply (rule_tac dist_diff_comp_use_env)
               apply (simp add: lift_diff_use_env)
               apply (rule_tac well_typed_comp_lift_perms)
    (* - cancellations *)
                apply (cut_tac r_s="dir_subst_penv t_sub p_sub r_s2" and r_x="dir_subst_penv t_sub p_sub r_x2" in cancel_comp_use_env2)
                 apply (rule_tac env="env" and e="e2" and c_list="cl2" in infer_x_leq_use_env)
                 apply (auto)
                apply (cut_tac r_s="diff_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub r_m2)" and
                    r_x="diff_use_env (dir_subst_penv t_sub p_sub r_x2) (dir_subst_penv t_sub p_sub r_m2)" in cancel_comp_use_env2)
                 apply (rule_tac dist_diff_leq_use_env)
                 apply (rule_tac env="env" and e="e2" and c_list="cl2" in infer_x_leq_use_env)
                apply (auto)
               apply (simp add: full_subst_type_def)
               apply (rule_tac self_diff_leq_use_env)
    (* - disjointness used to remove r_s1 *)(*
              apply (rule_tac comm_disj_use_env)
              apply (simp)*)
    (* - proving that r_m1 can be subtracted out *)
             apply (simp add: own_env_vars_def)
             apply (case_tac "dir_subst_penv t_sub p_sub r_s2 x = NoPerm")
              apply (cut_tac e="e2" and ?r_s1.0="dir_subst_penv t_sub p_sub r_s2" and x="x" in well_typed_no_npv_use)
                apply (auto)(*
             apply (case_tac "dir_subst_penv t_sub p_sub r_s1 x \<noteq> OwnPerm")
              apply (cut_tac r_x="dir_subst_penv t_sub p_sub r_m1" and r_s="dir_subst_penv t_sub p_sub r_s1" and x="x" in leq_use_no_own)
                apply (simp)
               apply (rule_tac c_list="cl1" in infer_m_leq_use_env)
               apply (auto)
             apply (cut_tac r_x="dir_subst_penv t_sub p_sub r_s1" and r_s="comp_use_env (dir_subst_penv t_sub p_sub r_s1) (dir_subst_penv t_sub p_sub (lift_var_env r_x1 (SVar p)))"
                and r_ex="dir_subst_penv t_sub p_sub r_s2" in disj_leq_use_env1)
               apply (rule_tac r_s="comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p)))" in disj_leq_use_env2)
                apply (simp)
               apply (rule_tac self_comp_leq_use_env1)
              apply (rule_tac self_comp_leq_use_env1)
             apply (simp add: disj_use_env_def)*)
             apply (simp add: mini_disj_use_env_def)
    (* - end perm bounds correctness *)
            apply (rule_tac lhs_flip_use_env)
            apply (rule_tac lhs_unroll_dcl_use_env)
            apply (rule_tac id_leq_use_env)
    (*
            apply (rule_tac dist_diff_leq_use_env)
            apply (rule_tac dist_diff_leq_use_env)
            apply (rule_tac lhs_dist_dcl_use_env)
            apply (rule_tac dist_comp_leq_use_env)
    apply (rule_tac self_diff_leq_use_env)
             apply (rule_tac comp_leq_use_env1)
             apply (rule_tac self_diff_leq_use_env)
            apply (rule_tac self_comp_leq_use_env2)*)
           apply (rule_tac rhs_unroll_dcl_use_env)
           apply (rule_tac dist_diff_leq_use_env)
           apply (rule_tac mini_disj_diff_leq_use_env2)
            apply (rule_tac comp_leq_use_env2)
            apply (rule_tac comp_leq_use_env2)
            apply (rule_tac lift_leq_var_env)
            apply (rule_tac id_leq_use_env)
           apply (rule_tac r_s="dir_subst_penv t_sub p_sub r_s2" in mini_disj_leq_use_env2)
            apply (simp)
           apply (rule_tac infer_x_leq_use_env)
           apply (simp)(*
            apply (rule_tac r_s="comp_use_env (dir_subst_penv t_sub p_sub r_s1) (dir_subst_penv t_sub p_sub (lift_var_env r_x1 (SVar p)))" in disj_leq_use_env1)
             apply (rule_tac r_s="comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p)))" in disj_leq_use_env2)
              apply (simp)
             apply (rule_tac comp_leq_use_env2)
             apply (rule_tac lift_leq_var_env)
             apply (rule_tac id_leq_use_env)
            apply (rule_tac comp_leq_use_env1)
            apply (rule_tac e="e1" and c_list="cl1" in infer_m_leq_use_env)
            apply (simp)
           apply (rule_tac comp_leq_use_env2)
           apply (rule_tac comp_leq_use_env2)
           apply (rule_tac lift_leq_var_env)
           apply (rule_tac id_leq_use_env)*)
          apply (rule_tac self_diff_leq_use_env)
      (* - native permission bound constraint e1 *)
         apply (rule_tac t="lift_use_env (diff_use_env (dir_subst_penv t_sub p_sub r_x1) (dir_subst_penv t_sub p_sub r_m1)) (p_sub p)" and
          s="diff_use_env (lift_use_env (dir_subst_penv t_sub p_sub r_x1) (p_sub p)) (dir_subst_penv t_sub p_sub r_m1)" in subst)
          apply (rule_tac lift_diff_use_env)
         apply (simp add: comp_sol_subst_penv)
         apply (rule_tac rhs_unroll_dcl_use_env)
         apply (rule_tac mini_disj_diff_leq_use_env2)
          apply (simp add: lift_sol_subst_penvx)
          apply (rule_tac dist_diff_leq_use_env)
          apply (rule_tac comp_leq_use_env1)
          apply (rule_tac self_comp_leq_use_env2)
         apply (rule_tac r_s="lift_use_env (dir_subst_penv t_sub p_sub r_x1) (p_sub p)" in mini_disj_leq_use_env2)
          apply (rule_tac mini_disj_lift_use_env_rev)
          apply (simp)
         apply (rule_tac self_diff_leq_use_env)(*
          apply (rule_tac r_s="comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p)))" in disj_leq_use_env1)
           apply (rule_tac r_s="comp_use_env (dir_subst_penv t_sub p_sub r_s1) (dir_subst_penv t_sub p_sub (lift_var_env r_x1 (SVar p)))" in disj_leq_use_env2)
            apply (rule_tac comm_disj_use_env)
            apply (simp)
           apply (simp add: lift_sol_subst_penvx)
           apply (rule_tac diff_leq_use_env)
           apply (rule_tac self_comp_leq_use_env2)
          apply (rule_tac comp_leq_use_env1)
          apply (rule_tac c_list="cl2" in infer_m_leq_use_env)
          apply (simp)
         apply (rule_tac dist_diff_leq_use_env)
         apply (simp add: lift_sol_subst_penvx)
         apply (rule_tac comp_leq_use_env1)
         apply (rule_tac self_comp_leq_use_env2)*)
      (* - native permission bound constraint e2 *)
        apply (rule_tac t="lift_use_env (diff_use_env (dir_subst_penv t_sub p_sub r_x2) (dir_subst_penv t_sub p_sub r_m2)) (p_sub p)" and
          s="diff_use_env (lift_use_env (dir_subst_penv t_sub p_sub r_x2) (p_sub p)) (dir_subst_penv t_sub p_sub r_m2)" in subst)
         apply (rule_tac lift_diff_use_env)
        apply (simp add: comp_sol_subst_penv)
        apply (rule_tac rhs_unroll_dcl_use_env)
        apply (rule_tac dist_diff_leq_use_env)
        apply (rule_tac mini_disj_diff_leq_use_env2)
         apply (simp add: lift_sol_subst_penvx)
         apply (rule_tac comp_leq_use_env2)
         apply (rule_tac self_comp_leq_use_env2)
        apply (rule_tac mini_disj_lift_use_env_rev)
        apply (rule_tac r_s="dir_subst_penv t_sub p_sub r_s2" in mini_disj_leq_use_env2)
         apply (simp)
        apply (rule_tac infer_x_leq_use_env)
        apply (simp)(*
         apply (rule_tac r_s="comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p)))" in disj_leq_use_env2)
          apply (rule_tac r_s="comp_use_env (dir_subst_penv t_sub p_sub r_s1) (dir_subst_penv t_sub p_sub (lift_var_env r_x1 (SVar p)))" in disj_leq_use_env1)
           apply (simp)
          apply (rule_tac comp_leq_use_env1)
          apply (rule_tac c_list="cl1" in infer_m_leq_use_env)
          apply (simp)
         apply (simp add: lift_sol_subst_penvx)
         apply (rule_tac self_comp_leq_use_env2)
        apply (rule_tac comp_leq_use_env2)
        apply (simp add: lift_sol_subst_penvx)
        apply (rule_tac self_comp_leq_use_env2)*)
    (* - affinity requirements *)
       apply (rule_tac max_aff_leq)
        apply (rule_tac dir_aff_leq)
         apply (simp_all)
       apply (rule_tac tau="tau_xa" in dir_aff_leq)
        apply (simp_all)
    (* - disjointness requirement *)
      apply (rule_tac r_s="dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p))" in disj_leq_use_env2)
       apply (rule_tac r_s="dir_subst_penv t_sub p_sub (lift_var_env r_x1 (SVar p))" in disj_leq_use_env1)
        apply (simp)
       apply (rule_tac t="dir_subst_penv t_sub p_sub (lift_var_env r_x1 (SVar p))" and
          s="lift_use_env (dir_subst_penv t_sub p_sub r_x1) (p_sub p)" in subst)
        apply (rule_tac lift_sol_subst_penvx)
       apply (rule_tac dist_lift_leq_use_env)
       apply (rule_tac self_diff_leq_use_env)
      apply (rule_tac t="dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p))" and
          s="lift_use_env (dir_subst_penv t_sub p_sub r_x2) (p_sub p)" in subst)
       apply (rule_tac lift_sol_subst_penvx)
      apply (rule_tac dist_lift_leq_use_env)
      apply (rule_tac self_diff_leq_use_env)
(*
      apply (rule_tac r_s="comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p)))" in disj_leq_use_env2)
       apply (rule_tac r_s="comp_use_env (dir_subst_penv t_sub p_sub r_s1) (dir_subst_penv t_sub p_sub (lift_var_env r_x1 (SVar p)))" in disj_leq_use_env1)
        apply (simp add: comp_sol_subst_penv)
       apply (rule_tac t="dir_subst_penv t_sub p_sub (lift_var_env r_x1 (SVar p))" and
          s="lift_use_env (dir_subst_penv t_sub p_sub r_x1) (p_sub p)" in subst)
        apply (rule_tac lift_sol_subst_penvx)
       apply (rule_tac comp_leq_use_env2)
       apply (rule_tac dist_lift_leq_use_env)
       apply (rule_tac self_diff_leq_use_env)
      apply (rule_tac comp_leq_use_env2)
      apply (rule_tac t="dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p))" and
          s="lift_use_env (dir_subst_penv t_sub p_sub r_x2) (p_sub p)" in subst)
       apply (rule_tac lift_sol_subst_penvx)
      apply (rule_tac dist_lift_leq_use_env)
      apply (rule_tac self_diff_leq_use_env)*)
    (* - final existential *)
     apply (rule_tac x="dir_subst_penv t_sub p_sub (comp_var_env r_m1 r_m2)" in exI)
     apply (auto)
        apply (rule_tac rhs_diff_leq_use_env)
        apply (rule_tac id_leq_use_env)
       apply (rule_tac dist_diff_leq_use_env)
       apply (rule_tac if_zero_leq_var_env)
       apply (rule_tac dist_comp_leq_var_env)
        apply (rule_tac comp_leq_var_env1)
        apply (rule_tac comp_leq_var_env2)
        apply (rule_tac id_leq_use_env)
       apply (rule_tac comp_leq_var_env2)
       apply (rule_tac comp_leq_var_env2)
       apply (rule_tac id_leq_use_env)
      apply (rule_tac dist_comp_leq_var_env)
       apply (rule_tac comp_leq_var_env1)
       apply (rule_tac comp_leq_var_env1)
       apply (rule_tac c_list="cl1" in infer_m_leq_use_env)
       apply (auto)
      apply (rule_tac comp_leq_var_env2)
      apply (rule_tac comp_leq_var_env1)
      apply (rule_tac c_list="cl2" in infer_m_leq_use_env)
      apply (simp)
     apply (simp add: pair_req_def)
     apply (auto)
      apply (rule_tac leq_empty_use_env)
     apply (case_tac "sol_subst_perm p_sub (SVar p) = NoPerm")
      apply (simp)
     apply (simp add: if_zero_pos_var_env)
     apply (rule_tac dist_diff_leq_use_env)
     apply (simp add: comp_sol_subst_penv)
     apply (rule_tac dist_comp_leq_use_env)
      apply (rule_tac comp_leq_use_env1)
      apply (rule_tac t="dir_subst_penv t_sub p_sub (lift_var_env r_x1 (SVar p))" and
        s="lift_use_env (dir_subst_penv t_sub p_sub r_x1) (p_sub p)" in subst)
       apply (rule_tac lift_sol_subst_penvx)
      apply (rule_tac dist_lift_leq_use_env)
      apply (rule_tac self_diff_leq_use_env)
     apply (rule_tac comp_leq_use_env2)
     apply (rule_tac t="dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p))" and
        s="lift_use_env (dir_subst_penv t_sub p_sub r_x2) (p_sub p)" in subst)
      apply (rule_tac lift_sol_subst_penvx)
     apply (rule_tac dist_lift_leq_use_env)
     apply (rule_tac self_diff_leq_use_env)
    (* if case. prelim: satisfiability sub-constraints *)
    apply (cut_tac p_sub="p_sub" and ?cl2.0="cl1 @ cl2 @ cl3" in sol_sat_append2)
     apply (simp)
    apply (cut_tac p_sub="p_sub" and ?cl2.0="cl2 @ cl3" in sol_sat_append2)
     apply (simp)
    (* - prelim: disjointness constraints *)
    apply (cut_tac p_sub="p_sub" and r_x="r_m1" and r_s="comp_var_env r_s2 r_s3" in sol_sat_mini_disj_use_env)
       apply (rule_tac sol_sat_append1)
       apply (simp)
      apply (rule_tac r_s="comp_var_env r_s1 (comp_var_env r_s2 r_s3)" in finite_sub_dom)
       apply (simp)
      apply (rule_tac comp_sub_dom1)
      apply (rule_tac infer_m_sub_dom)
      apply (auto)
     apply (rule_tac r_s="comp_var_env r_s1 (comp_var_env r_s2 r_s3)" in finite_sub_dom)
      apply (simp)
     apply (rule_tac comp_sub_dom2)
     apply (rule_tac id_sub_dom)
    (* - induction on e1 *)
    apply (rule_tac x="diff_use_env (dir_subst_penv t_sub p_sub r_x1) (dir_subst_penv t_sub p_sub r_m1)" in exI)
    apply (rule_tac x="diff_use_env (dir_subst_penv t_sub p_sub (comp_var_env r_s1 (comp_var_env r_s2 r_s3))) (dir_subst_penv t_sub p_sub r_m1)" in exI)
    apply (auto)
     apply (rule_tac t="dir_subst_penv t_sub p_sub (comp_var_env r_s1 (comp_var_env r_s2 r_s3))"
      and s="comp_use_env (dir_subst_penv t_sub p_sub r_s1) (dir_subst_penv t_sub p_sub (comp_var_env r_s2 r_s3))" in subst)
      apply (simp add: comp_sol_subst_penv)
    apply (cut_tac env="env" and delta="delta" and ds="ds" and e="e1" and tau="t1" and r_s="r_s1" and r_x="r_x1" and r_m="r_m1" and
        c_list="cl1" and ds'="ds2" and t_sub="t_sub" and p_sub="p_sub" and tau_n="tau_n" in ivl_if_ih)
        apply (auto)
      apply (rule_tac sol_sat_append1)
      apply (simp)
     apply (rule_tac well_typed_comp_perms_prec)
     apply (case_tac t1)
            apply (auto)
      apply (simp add: full_subst_type_def)
     apply (simp add: full_subst_type_def)
    (* - induction on e2 *)
    apply (rule_tac x="diff_use_env (dir_subst_penv t_sub p_sub r_x2) (dir_subst_penv t_sub p_sub (comp_var_env r_m1 (comp_var_env r_m2 r_m3)))" in exI)
    apply (auto)
     apply (simp add: comp_sol_subst_penv)
     apply (cut_tac env="env" and delta="delta" and ds="ds2" and e="e2" and tau="t2" and r_s="r_s2" and r_x="r_x2" and r_m="r_m2" and
        c_list="cl2" and ds'="ds3" and t_sub="t_sub" and p_sub="p_sub" and tau_n="tau_n" in ivl_if_ih)
        apply (auto)
      apply (rule_tac sol_sat_append1)
      apply (simp)
     apply (rule_tac ?r_s2.0="diff_use_env (diff_use_env (comp_use_env (diff_use_env (dir_subst_penv t_sub p_sub r_s1)
        (dir_subst_penv t_sub p_sub r_m1)) (comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub r_s3)))
        (dir_subst_penv t_sub p_sub r_m2)) (dir_subst_penv t_sub p_sub r_m3)" and rx="diff_use_env (diff_use_env (dir_subst_penv t_sub p_sub r_x2)
        (dir_subst_penv t_sub p_sub r_m2)) (dir_subst_penv t_sub p_sub r_m3)" in well_typed_simul_end_perm)
        apply (rule_tac ?r_s1.0="comp_use_env (diff_use_env (dir_subst_penv t_sub p_sub r_s1) (dir_subst_penv t_sub p_sub r_m1))
          (comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub r_s3))" in well_typed_incr_start_perm)
         apply (rule_tac well_typed_diff_end_perm)
          apply (rule_tac well_typed_comp_perms_prec2)
          apply (rule_tac well_typed_comp_perms_prec)
          apply (simp_all)
         apply (rule_tac comp_leq_use_env2)
         apply (rule_tac comp_leq_use_env2)
         apply (rule_tac infer_m_leq_use_env)
         apply (auto)
        apply (rule_tac dist_comp_leq_use_env)
         apply (rule_tac dist_diff_leq_use_env)
         apply (rule_tac self_comp_leq_use_env1)
        apply (rule_tac rhs_dist_dcl_use_env)
        apply (rule_tac comp_leq_use_env2)
        apply (rule_tac mini_disj_diff_leq_use_env2)
         apply (rule_tac id_leq_use_env)
        apply (simp)
       apply (rule_tac lhs_dist_dcl_use_env)
       apply (rule_tac rhs_fold_dcl_use_env)
       apply (rule_tac dist_comp_leq_use_env)
        apply (rule_tac lhs_unroll_dcl_use_env)
        apply (rule_tac dist_diff_leq_use_env)
        apply (rule_tac self_comp_leq_use_env1)
       apply (rule_tac dist_diff_leq_use_env_gen)
        apply (rule_tac self_comp_leq_use_env2)
       apply (rule_tac self_comp_leq_use_env2)
      apply (rule_tac dist_diff_leq_use_env)
      apply (rule_tac comp_leq_use_env2)
      apply (rule_tac comp_leq_use_env1)
      apply (rule_tac c_list="cl2" in infer_x_leq_use_env)
      apply (simp)
     apply (rule_tac lhs_fold_dcl_use_env)
     apply (rule_tac rhs_unroll_dcl_use_env)
     apply (rule_tac dist_diff_leq_use_env)
     apply (rule_tac mini_disj_diff_leq_use_env2)
      apply (rule_tac id_leq_use_env)
     apply (rule_tac r_s="comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub r_s3)" in mini_disj_leq_use_env2)
      apply (simp)
     apply (rule_tac comp_leq_use_env1)
     apply (rule_tac c_list="cl2" in infer_x_leq_use_env)
     apply (simp)
      (* - induction on e3 *)
    apply (rule_tac x="diff_use_env (dir_subst_penv t_sub p_sub r_x3) (dir_subst_penv t_sub p_sub (comp_var_env r_m1 (comp_var_env r_m2 r_m3)))" in exI)
    apply (auto)
     apply (simp add: comp_sol_subst_penv)
     apply (cut_tac env="env" and delta="delta" and ds="ds3" and e="e3" and tau="t3" and r_s="r_s3" and r_x="r_x3" and r_m="r_m3" and
        c_list="cl3" and ds'="ds'" and t_sub="t_sub" and p_sub="p_sub" and tau_n="tau_n" in ivl_if_ih)
        apply (auto)
      apply (rule_tac sol_sat_append2)
      apply (simp)
     apply (rule_tac ?r_s2.0="diff_use_env (diff_use_env (comp_use_env (diff_use_env (dir_subst_penv t_sub p_sub r_s1)
        (dir_subst_penv t_sub p_sub r_m1)) (comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub r_s3)))
        (dir_subst_penv t_sub p_sub r_m3)) (dir_subst_penv t_sub p_sub r_m2)" and rx="diff_use_env (diff_use_env (dir_subst_penv t_sub p_sub r_x3)
        (dir_subst_penv t_sub p_sub r_m3)) (dir_subst_penv t_sub p_sub r_m2)" in well_typed_simul_end_perm)
        apply (rule_tac ?r_s1.0="comp_use_env (diff_use_env (dir_subst_penv t_sub p_sub r_s1) (dir_subst_penv t_sub p_sub r_m1))
          (comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub r_s3))" in well_typed_incr_start_perm)
         apply (rule_tac well_typed_diff_end_perm)
          apply (rule_tac well_typed_comp_perms_prec2)
          apply (rule_tac well_typed_comp_perms_prec2)
          apply (simp add: dir_subst_type_eq)
         apply (rule_tac comp_leq_use_env2)
         apply (rule_tac comp_leq_use_env1)
         apply (rule_tac infer_m_leq_use_env)
         apply (auto)
        apply (rule_tac dist_comp_leq_use_env)
         apply (rule_tac dist_diff_leq_use_env)
         apply (rule_tac self_comp_leq_use_env1)
        apply (rule_tac mini_disj_diff_leq_use_env2)
         apply (rule_tac self_comp_leq_use_env2)
        apply (simp)
       apply (rule_tac lhs_dist_dcl_use_env)
       apply (rule_tac rhs_fold_dcl_use_env)
       apply (rule_tac dist_comp_leq_use_env)
        apply (rule_tac lhs_unroll_dcl_use_env)
        apply (rule_tac dist_diff_leq_use_env_gen)
         apply (rule_tac self_comp_leq_use_env1)
        apply (simp add: comm_comp_use_env)
        apply (rule_tac id_leq_use_env)
       apply (rule_tac dist_diff_leq_use_env_gen)
        apply (rule_tac self_comp_leq_use_env2)
       apply (simp add: comm_comp_use_env)
       apply (rule_tac self_comp_leq_use_env2)
      apply (rule_tac dist_diff_leq_use_env)
      apply (rule_tac comp_leq_use_env2)
      apply (rule_tac comp_leq_use_env2)
      apply (rule_tac infer_x_leq_use_env)
      apply (auto)
     apply (rule_tac lhs_fold_dcl_use_env)
     apply (simp add: comm_comp_use_env)
     apply (rule_tac rhs_unroll_dcl_use_env)
     apply (rule_tac dist_diff_leq_use_env_gen)
      apply (rule_tac mini_disj_diff_leq_use_env2)
       apply (rule_tac id_leq_use_env)
      apply (rule_tac r_s="comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub r_s3)" in mini_disj_leq_use_env2)
       apply (simp)
      apply (rule_tac comp_leq_use_env2)
      apply (rule_tac infer_x_leq_use_env)
      apply (auto)
     apply (rule_tac id_leq_use_env)
    apply (simp add: dist_diff_comp_use_env)
    apply (simp add: comp_sol_subst_penv)
    (* lam case *)
   apply (simp add: full_subst_type_def)
   apply (rule_tac x="dir_subst_penv t_sub p_sub (rem_var_env r_s' (Var x1a))" in exI)
   apply (auto)
    (* - induction on e *)
      apply (cut_tac env="add_env env (Var x1a) a" and delta="delta" and ds="insert a ds" and e="e" and tau="t2" and r_s="r_s'" and r_x="r_x'" and r_m="r_m'" and
        c_list="cl" and ds'="ds2" and t_sub="t_sub" and p_sub="p_sub" and tau_n="tau_n" in ivl_lam_ih)
         apply (auto)
        apply (simp add: full_subst_type_def)
       apply (rule_tac sol_sat_append2)
       apply (simp)
      apply (rule_tac x="diff_use_env (dir_subst_penv t_sub p_sub r_x') (dir_subst_penv t_sub p_sub r_m')" in exI)
      apply (rule_tac x="diff_use_env (dir_subst_penv t_sub p_sub r_s') (dir_subst_penv t_sub p_sub r_m')" in exI)
      apply (simp add: rem_sol_subst_penv)
      apply (rule_tac ?r_s1.0="add_use_env (rem_use_env (dir_subst_penv t_sub p_sub r_s') (Var x1a)) (Var x1a)
        (dir_subst_permx t_sub p_sub (r_s' (Var x1a)))" in well_typed_incr_start_perm)
       apply (case_tac "dir_subst_permx t_sub p_sub (r_s' (Var x1a)) \<noteq> (dir_subst_penv t_sub p_sub r_s') (Var x1a)")
        apply (simp add: dir_subst_penv_def)
       apply (simp add: add_rem_use_env)
       apply (cut_tac t_sub="t_sub" and tau_n="tau_n" and x="x1a" and env="env" and a="a" and p_sub="p_sub" in add_sol_subst_tenv)
       apply (simp add: full_subst_type_def)
      apply (rule_tac dist_add_leq_use_env_gen)
       apply (rule_tac id_leq_use_env)
      apply (simp)
     apply (rule_tac sol_sat_aff_use_envx)
      apply (rule_tac sol_sat_append1)
      apply (simp_all)
    apply (rule_tac id_leq_use_env)
   apply (rule_tac x="empty_use_env" in exI)
   apply (auto)
      apply (simp add: subst_empty_var_env)
      apply (rule_tac id_leq_use_env)
     apply (rule_tac id_leq_use_env)
    apply (rule_tac leq_empty_use_env)
   apply (simp add: subst_empty_var_env)
   apply (rule_tac id_leq_use_env)
    (* app case. prelim: satisfiability constraints *)
  apply (cut_tac p_sub="p_sub" and ?cl2.0="semi_disj_crn r_m2 r_x1 d @ semi_disj_crn r_m1 r_s2 d @ cl1 @ cl2" in sol_sat_append2)
   apply (simp)
  apply (cut_tac p_sub="p_sub" and ?cl2.0="semi_disj_crn r_m1 r_s2 d @ cl1 @ cl2" in sol_sat_append2)
   apply (simp)
  apply (cut_tac p_sub="p_sub" and ?cl2.0="cl1 @ cl2" in sol_sat_append2)
   apply (simp)
    (* - prelim: disjointness constraints *)
  apply (cut_tac p_sub="p_sub" in sol_sat_disj_use_env)
     apply (rule_tac sol_sat_append1)
     apply (simp)
    apply (rule_tac r_s="comp_var_env (comp_var_env r_s1 r_x1) (comp_var_env r_s2 (lift_var_env r_x2 (SVar p)))" in finite_sub_dom)
     apply (simp)
    apply (rule_tac comp_sub_dom1)
    apply (rule_tac comp_sub_dom2)
    apply (rule_tac id_sub_dom)
   apply (rule_tac r_s="comp_var_env (comp_var_env r_s1 r_x1) (comp_var_env r_s2 (lift_var_env r_x2 (SVar p)))" in finite_sub_dom)
    apply (simp)
   apply (rule_tac comp_sub_dom2)
   apply (rule_tac comp_sub_dom2)
   apply (rule_tac id_sub_dom)
    (* - prelim: semi-disjointness constraint 1 *)
  apply (cut_tac r_x="r_m2" and r_s="r_x1" and p_sub="p_sub" in sol_sat_mini_disj_use_env)
     apply (rule_tac sol_sat_append1)
     apply (simp)
      apply (rule_tac r_s="comp_var_env (comp_var_env r_s1 r_x1) (comp_var_env r_s2 (lift_var_env r_x2 (SVar p)))" in finite_sub_dom)
       apply (simp)
      apply (rule_tac comp_sub_dom2)
      apply (rule_tac comp_sub_dom1)
      apply (rule_tac infer_m_sub_dom)
      apply (simp)
     apply (rule_tac r_s="comp_var_env (comp_var_env r_s1 r_x1) (comp_var_env r_s2 (lift_var_env r_x2 (SVar p)))" in finite_sub_dom)
      apply (simp)
     apply (rule_tac comp_sub_dom1)
     apply (rule_tac comp_sub_dom2)
     apply (rule_tac id_sub_dom)
    (* - prelim: semi-disjointness constraint 2 *)
  apply (cut_tac r_x="r_m1" and r_s="r_s2" and p_sub="p_sub" in sol_sat_mini_disj_use_env)
     apply (rule_tac sol_sat_append1)
     apply (simp)
      apply (rule_tac r_s="comp_var_env (comp_var_env r_s1 r_x1) (comp_var_env r_s2 (lift_var_env r_x2 (SVar p)))" in finite_sub_dom)
       apply (simp)
      apply (rule_tac comp_sub_dom1)
      apply (rule_tac comp_sub_dom1)
      apply (rule_tac infer_m_sub_dom)
      apply (simp)
     apply (rule_tac r_s="comp_var_env (comp_var_env r_s1 r_x1) (comp_var_env r_s2 (lift_var_env r_x2 (SVar p)))" in finite_sub_dom)
      apply (simp)
     apply (rule_tac comp_sub_dom2)
     apply (rule_tac comp_sub_dom1)
     apply (rule_tac id_sub_dom)
    (* - prelim: inequalities *)(*
  apply (cut_tac c_list="cl1" and r_m="r_m1" and r_s="r_s1" and t_sub="t_sub" and p_sub="p_sub" in infer_m_leq_use_env)
   apply (simp)
  apply (cut_tac r_x="r_m2" and r_s="r_s2" and r="SVar p" and t_sub="t_sub" and p_sub="p_sub" in lift_leq_var_env)
   apply (rule_tac c_list="cl2" in infer_m_leq_use_env)
   apply (simp)*)
  apply (cut_tac c_list="cl1" and r_x="r_x1" and r_s="r_s1" and t_sub="t_sub" and p_sub="p_sub" in infer_x_leq_use_env)
   apply (simp)
  apply (cut_tac c_list="cl2" and r_x="r_x2" and r_s="r_s2" and t_sub="t_sub" and p_sub="p_sub" in infer_x_leq_use_env)
   apply (simp)
  apply (cut_tac r_x="r_x2" and r_s="r_s2" and r="SVar p" in lift_leq_var_env)
    apply (simp)
    (* - existentials *)
  apply (rule_tac x="full_subst_type t_sub p_sub tau_n t1" in exI)
  apply (rule_tac x="sol_subst_perm p_sub (SVar p)" in exI)
  apply (rule_tac x="sol_subst_aff p_sub (AffVar q)" in exI)
  apply (rule_tac x="diff_use_env (dir_subst_penv t_sub p_sub (comp_var_env (comp_var_env r_s1 r_x1)
      (comp_var_env r_s2 (lift_var_env r_x2 (SVar p))))) (dir_subst_penv t_sub p_sub r_m1)" in exI)
  apply (rule_tac x="diff_use_env (dir_subst_penv t_sub p_sub r_x1) (dir_subst_penv t_sub p_sub r_m1)" in exI)
  apply (auto)
    (* - induction for e1. *)
  apply (simp add: comp_sol_subst_penv)
   apply (cut_tac env="env" and delta="delta" and ds="ds" and e="e1" and tau="tau_f" and r_s="r_s1" and r_x="r_x1" and r_m="r_m1" and
        c_list="cl1" and ds'="ds2" and t_sub="t_sub" and p_sub="p_sub" and tau_n="tau_n" in ivl_app_ih)
      apply (auto)
    apply (rule_tac sol_sat_append1)
    apply (simp)
   apply (rule_tac well_typed_comp_perms_prec)
   apply (rule_tac well_typed_comp_perms_prec)
   apply (simp add: dir_subst_type_eq)
    (* - induction for e2. *)
  apply (rule_tac x="diff_use_env (dir_subst_penv t_sub p_sub r_x2) (dir_subst_penv t_sub p_sub r_m2)" in exI)
  apply (rule_tac x="diff_use_env (diff_use_env (dir_subst_penv t_sub p_sub (comp_var_env (comp_var_env r_s1 r_x1)
      (comp_var_env r_s2 (lift_var_env r_x2 (SVar p))))) (dir_subst_penv t_sub p_sub r_m1)) (dir_subst_penv t_sub p_sub r_m2)" in exI)
  apply (auto)
   apply (simp add: comp_sol_subst_penv)
   apply (cut_tac env="env" and delta="delta" and ds="ds2" and e="e2" and tau="t1" and r_s="r_s2" and r_x="r_x2" and r_m="r_m2" and
        c_list="cl2" and ds'="ds3" and t_sub="t_sub" and p_sub="p_sub" and tau_n="tau_n" in ivl_app_ih)
      apply (auto)
    apply (rule_tac sol_sat_append2)
    apply (simp)
   apply (rule_tac r_c="diff_use_env (comp_use_env (diff_use_env (comp_use_env (dir_subst_penv t_sub p_sub r_s1) (dir_subst_penv t_sub p_sub r_x1))
      (dir_subst_penv t_sub p_sub r_m1)) (comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p)))))
                (dir_subst_penv t_sub p_sub r_m2)" in well_typed_decr_end_perm)
     apply (rule_tac ?r_s1.0="comp_use_env (diff_use_env (comp_use_env (dir_subst_penv t_sub p_sub r_s1) (dir_subst_penv t_sub p_sub r_x1))
      (dir_subst_penv t_sub p_sub r_m1)) (comp_use_env (dir_subst_penv t_sub p_sub r_s2) (dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p))))" in well_typed_incr_start_perm)
      apply (rule_tac well_typed_comp_perms_prec2)
      apply (rule_tac well_typed_comp_perms_prec)
      apply (simp)
     apply (rule_tac rhs_dist_dcl_use_env)
     apply (rule_tac dist_comp_leq_use_env)
      apply (rule_tac self_comp_leq_use_env1)
     apply (rule_tac comp_leq_use_env2)
     apply (rule_tac mini_disj_diff_leq_use_env)
      apply (rule_tac id_leq_use_env)
     apply (rule_tac mini_disj_comp_use_env_alt)
      apply (simp)
     apply (rule_tac t="dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p))" and
        s="lift_use_env (dir_subst_penv t_sub p_sub r_x2) (sol_subst_perm p_sub (SVar p))" in subst)
      apply (rule_tac lift_sol_subst_penv)
     apply (rule_tac mini_disj_lift_use_env_rev)
     apply (rule_tac r_s="dir_subst_penv t_sub p_sub r_s2" in mini_disj_leq_use_env2)
      apply (simp_all)
    apply (rule_tac dist_diff_leq_use_env)
    apply (rule_tac lhs_dist_dcl_use_env)
    apply (rule_tac dist_comp_leq_use_env)
     apply (rule_tac self_comp_leq_use_env1)
    apply (rule_tac comp_leq_use_env2)
    apply (rule_tac self_diff_leq_use_env)
   apply (rule_tac dist_diff_leq_use_env)
   apply (rule_tac mini_disj_diff_leq_use_env2)
    apply (rule_tac comp_leq_use_env2)
    apply (rule_tac comp_leq_use_env2)
    apply (rule_tac lift_leq_var_env)
    apply (rule_tac id_leq_use_env)
   apply (rule_tac r_s="dir_subst_penv t_sub p_sub r_s2" in mini_disj_leq_use_env2)
    apply (simp_all)
    (* - final existentials. *)
  apply (rule_tac x="dir_subst_penv t_sub p_sub (comp_var_env (comp_var_env r_m1 r_x1) (comp_var_env r_m2 (lift_var_env r_x2 (SVar p))))" in exI)
  apply (simp add: comp_sol_subst_penv)
  apply (auto)
    (* - end permission bound *)
       apply (rule_tac rhs_fold_dcl_use_env)
       apply (rule_tac rhs_fold_dcl_use_env)
       apply (rule_tac dist_diff_leq_use_env_gen)
        apply (rule_tac id_leq_use_env)
       apply (rule_tac t="dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p))" and
        s="lift_use_env (dir_subst_penv t_sub p_sub r_x2) (sol_subst_perm p_sub (SVar p))" in subst)
        apply (rule_tac lift_sol_subst_penv)
       apply (rule_tac dist_comp_leq_use_env)
        apply (rule_tac comp_leq_use_env1)
        apply (rule_tac self_comp_leq_use_env1)
       apply (rule_tac dist_comp_leq_use_env)
        apply (rule_tac comp_leq_use_env2)
        apply (rule_tac self_comp_leq_use_env1)
       apply (rule_tac dist_comp_leq_use_env)
        apply (rule_tac dist_comp_leq_use_env)
         apply (rule_tac comp_leq_use_env1)
         apply (rule_tac comp_leq_use_env2)
         apply (rule_tac self_diff_leq_use_env)
        apply (rule_tac comp_leq_use_env2)
        apply (rule_tac comp_leq_use_env2)
        apply (auto)
        apply (rule_tac dist_lift_leq_use_env)
        apply (rule_tac self_diff_leq_use_env)
       apply (rule_tac id_leq_use_env)
    (* - subtractability bound *)
      apply (rule_tac dist_comp_leq_use_env)
       apply (rule_tac mini_disj_diff_leq_use_env2)
        apply (rule_tac dist_diff_leq_use_env)
        apply (rule_tac comp_leq_use_env1)
        apply (rule_tac self_comp_leq_use_env2)
       apply (rule_tac r_s="dir_subst_penv t_sub p_sub r_x1" in mini_disj_leq_use_env2)
        apply (simp)
       apply (rule_tac self_diff_leq_use_env)
      apply (rule_tac t="lift_use_env (diff_use_env (dir_subst_penv t_sub p_sub r_x2) (dir_subst_penv t_sub p_sub r_m2)) (p_sub p)"
        and s="diff_use_env (lift_use_env (dir_subst_penv t_sub p_sub r_x2) (p_sub p)) (dir_subst_penv t_sub p_sub r_m2)" in subst)
       apply (rule_tac lift_diff_use_env)
      apply (rule_tac dist_diff_leq_use_env)
       apply (rule_tac t="dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p))" and
        s="lift_use_env (dir_subst_penv t_sub p_sub r_x2) (sol_subst_perm p_sub (SVar p))" in subst)
       apply (rule_tac lift_sol_subst_penv)
      apply (auto)
      apply (rule_tac mini_disj_diff_leq_use_env2)
       apply (rule_tac comp_leq_use_env2)
       apply (rule_tac self_comp_leq_use_env2)
      apply (rule_tac mini_disj_lift_use_env_rev)
      apply (rule_tac r_s="dir_subst_penv t_sub p_sub r_s2" in mini_disj_leq_use_env2)
       apply (simp)
      apply (rule_tac infer_x_leq_use_env)
      apply (simp)
    (* - disjointness *)
     apply (rule_tac r_s="dir_subst_penv t_sub p_sub r_x1" in disj_leq_use_env1)
      apply (rule_tac r_s="dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p))" in disj_leq_use_env2)
       apply (simp)
      apply (rule_tac t="dir_subst_penv t_sub p_sub (lift_var_env r_x2 (SVar p))" and
        s="lift_use_env (dir_subst_penv t_sub p_sub r_x2) (sol_subst_perm p_sub (SVar p))" in subst)
       apply (rule_tac lift_sol_subst_penv)
      apply (auto)
      apply (rule_tac dist_lift_leq_use_env)
      apply (rule_tac self_diff_leq_use_env)
     apply (rule_tac self_diff_leq_use_env)
    (* - relative bound *)
    apply (rule_tac dist_diff_leq_use_env)
    apply (rule_tac if_zero_leq_var_env)
    apply (simp add: comp_sol_subst_penv)
    apply (rule_tac dist_comp_leq_use_env)
     apply (rule_tac comp_leq_use_env1)
     apply (rule_tac self_comp_leq_use_env2)
    apply (rule_tac comp_leq_use_env2)
    apply (rule_tac self_comp_leq_use_env2)
    (* - subtractant bound *)
   apply (rule_tac dist_comp_leq_use_env)
    apply (rule_tac comp_leq_use_env1)
    apply (rule_tac dist_comp_leq_use_env)
     apply (rule_tac comp_leq_use_env1)
     apply (rule_tac c_list="cl1" in infer_m_leq_use_env)
     apply (auto)
    apply (rule_tac self_comp_leq_use_env2)
   apply (rule_tac dist_comp_leq_use_env)
    apply (rule_tac comp_leq_use_env2)
    apply (rule_tac comp_leq_use_env1)
    apply (rule_tac c_list="cl2" in infer_m_leq_use_env)
    apply (auto)
   apply (rule_tac comp_leq_use_env2)
   apply (rule_tac self_comp_leq_use_env2)
    (* - requirements bound *)
  apply (simp add: app_req_def)
  apply (auto)
   apply (rule_tac leq_empty_use_env)
  apply (rule_tac dist_diff_leq_use_env_gen)
   apply (case_tac "dir_subst_permx t_sub p_sub (XType a) = NoPerm")
    apply (case_tac "req_type (full_subst_type t_sub p_sub tau_n (VarScheme a))")
      apply (auto)
     apply (simp add: full_subst_type_def)
    apply (simp add: full_subst_type_def)
   apply (simp add: if_zero_pos_var_env)
   apply (simp add: comp_sol_subst_penv)
   apply (rule_tac dist_comp_leq_use_env)
    apply (rule_tac comp_leq_use_env1)
    apply (rule_tac self_diff_leq_use_env)
   apply (rule_tac comp_leq_use_env2)
   apply (rule_tac diff_leq_use_env)
   apply (rule_tac lift_leq_var_env)
   apply (rule_tac id_leq_use_env)
  apply (rule_tac self_comp_leq_use_env2)
  done

end


(*
 * Copyright 2014, General Dynamics C4 Systems
 *
 * SPDX-License-Identifier: GPL-2.0-only
 *)

theory ArchLevityCatch_AI
imports
  "ArchBCorres_AI"
  "Lib.LemmaBucket"
  "Lib.SplitRule"
begin

context Arch begin global_naming X64

lemma asid_high_bits_of_shift :
  "asid_high_bits_of (ucast x << asid_low_bits) = x"
  apply (simp add: asid_high_bits_of_def)
  apply (rule word_eqI)
  apply (simp add: word_size nth_ucast nth_shiftr nth_shiftl asid_low_bits_def)
  done

lemma  ptrFormPAddr_addFromPPtr :
  "ptrFromPAddr (Platform.X64.addrFromPPtr x) = x"
  by (simp add: ptrFromPAddr_def Platform.X64.addrFromPPtr_def)

(****** From GeneralLib *******)

lemma asid_high_bits_of_add_ucast:
  "is_aligned w asid_low_bits \<Longrightarrow>
  asid_high_bits_of (ucast (x::9 word) + w) = asid_high_bits_of w"
  apply (rule word_eqI)
  apply (simp add: word_size asid_high_bits_of_def nth_ucast nth_shiftr is_aligned_nth)
  apply (subst word_plus_and_or_coroll)
   apply (rule word_eqI)
   apply (clarsimp simp: nth_ucast)
   apply (drule test_bit_size)
   apply (simp add: word_size asid_low_bits_def)
  apply (auto dest: test_bit_size simp: word_size asid_low_bits_def nth_ucast)
  done

lemma asid_high_bits_of_add:
  "\<lbrakk>is_aligned w asid_low_bits; x \<le> 2 ^ asid_low_bits - 1\<rbrakk>
   \<Longrightarrow> asid_high_bits_of (w + x) = asid_high_bits_of w"
  apply (rule word_eqI)
  apply (simp add: word_size asid_high_bits_of_def nth_ucast nth_shiftr
                   is_aligned_nth)
  apply (drule le2p_bits_unset, simp add: asid_low_bits_def word_bits_def)
  apply (subst word_plus_and_or_coroll)
   apply (rule word_eqI)
   apply (clarsimp simp: word_size)
   apply (case_tac "na < asid_low_bits")
    apply (simp add: asid_low_bits_def linorder_not_less word_bits_def)
  apply (auto dest: test_bit_size
              simp: asid_low_bits_def nth_ucast)
  done

lemma pageBits_less_word_bits [simp]:
  "pageBits < word_bits" by (simp add: pageBits_def word_bits_conv)

lemma mask_out_8_le_kernel_base:
  "(x && ~~ mask 8 \<ge> kernel_base >> 20) = (x \<ge> kernel_base >> 20)"
  apply (rule iffI)
   apply (erule order_trans, rule word_and_le2)
  apply (drule_tac n=8 in neg_mask_mono_le)
  apply (simp add: kernel_base_def mask_def)
  done

lemma mask_out_8_less_kernel_base:
  "(x && ~~ mask 8 < kernel_base >> 20) = (x < kernel_base >> 20)"
  using mask_out_8_le_kernel_base[where x=x]
  by (simp add: linorder_not_less[symmetric])

lemma aobj_ref_arch_cap[simp]:
  "aobj_ref (arch_default_cap aty ptr us dev) = Some ptr"
  apply (case_tac aty)
   apply (simp_all add: aobj_ref_def arch_default_cap_def p_assoc_help)
  done

end
end


theory SM_POR
imports SM_Sticky
begin

  context transition_system_concurrent begin
    lemma pac_en_blocked':
      assumes A: "s \<in> nodes" "path w s" "pac p \<inter> {a. en a s} \<inter> set w = {}"
      assumes IS: "\<And>s' a. \<lbrakk>pac p \<inter> {a. en a s} = pac p \<inter> {a. en a s'};
        psen p s = psen p s'; en a s'; a\<notin>pac p \<rbrakk> \<Longrightarrow>
        pac p \<inter> {b. en b (ex a s')} = pac p \<inter> {a. en a s'} \<and> psen p (ex a s') = psen p s'"
      shows "pac p \<inter> set w = {}"
    proof (rule words_fin_blocked[OF _ A(2,3)])
      fix w
      assume "path w s" "pac p \<inter> set w = {}"
      hence "pac p \<inter> {a. en a s} = pac p \<inter> {a. en a (target w s)} \<and> psen p s = psen p (fold ex w s)"
      proof (induction w rule: rev_induct)
        case (snoc a w)
        from snoc have
          "pac p \<inter> {a. en a s} = pac p \<inter> {a. en a (target w s)}"
          "psen p s = psen p (fold ex w s)"
          by auto
        with IS[OF this] snoc.prems show ?case by auto
      qed simp
      thus "pac p \<inter> {a. en a (target w s)} \<subseteq> pac p \<inter> {a. en a s}" by blast
    qed

  end

  context cprog begin
    definition is_ample_static :: "cmdc \<Rightarrow> bool" where
      "is_ample_static c \<equiv> \<forall>a c'. cfgc c a c' \<longrightarrow>
        read_globals a = {} \<and> write_globals a = {}"

  end

  context visible_prog
  begin
    lemma None_ga_en_conv[simp]:
      "None\<in>ga_en gc \<longleftrightarrow> ga_en gc = {None}"
      by (auto simp: ga_en_def stutter_extend_en_def)

    lemma genabled_no_global_read_indep_other_pids:
      assumes "read_globals a = {}"
      assumes "pid'\<noteq>pid"
      shows "(pid,c,a, c')\<in>ga_gen (ga_gex (pid',cac') gc)
        \<longleftrightarrow> (pid,c,a, c')\<in>ga_gen gc"
      using assms
      apply (auto
        simp: ga_gen_def ga_gex_def ex_pres_en
        split: prod.splits)
      done

  end

  definition pid_pac :: "pid \<Rightarrow> global_action option set" where
    "pid_pac pid \<equiv> Collect (\<lambda>Some (pid',_) \<Rightarrow> pid'=pid | None \<Rightarrow> True)"

  lemma pid_pac_None[simp]: "None \<in> pid_pac pid"
    by (auto simp: pid_pac_def)

  context visible_prog
  begin

    definition pid_procs :: "pid_global_config \<Rightarrow> pid set" where
      "pid_procs gc \<equiv> {0..<length (pid_global_config.processes gc)}"

    definition pid_psen :: "pid \<Rightarrow> pid_global_config \<Rightarrow> global_action option set"
      where "pid_psen pid gc \<equiv> insert None
        (Some`{(pid,c,a,c') | c a c'. c = cmd_of_pid gc pid \<and> cfgc c a c'})"

    sublocale jsys: transition_system_concurrent
      ga_ex "\<lambda> a p. a \<in> ga_en p" "\<lambda> p. p = pid_init_gc"
      pid_procs pid_pac pid_psen

      apply unfold_locales

      apply (auto simp: pid_procs_def) []

      apply (auto
        simp: pid_pac_def pid_psen_def ga_en_def ga_gen_def
        simp: stutter_extend_en_def
        split: option.splits
        ) []

      apply (auto
        simp: pid_pac_def pid_psen_def ga_en_def ga_gen_def
        simp: stutter_extend_en_def ga_ex_def ga_gex_def
        split: option.splits if_split_asm prod.splits
        ) []
      done

  end

  locale ample_prog = sticky_prog +
    fixes ga_ample :: "pid_global_config \<Rightarrow> global_action option set"
    assumes ga_ample_approx:
    "\<lbrakk>gc \<in> (g_E ga_automaton)\<^sup>* `` g_V0 ga_automaton; ga_ample gc \<noteq> ga_en gc\<rbrakk> \<Longrightarrow>
      ga_ample gc \<inter> sticky_ga = {}
    \<and> ga_ample gc \<noteq> {}
    \<and> (\<exists>pid.
        ga_ample gc = ga_en gc \<inter> pid_pac pid
      \<and> is_ample_static (cmd_of_pid gc pid))"

  begin

    lemma pid_enabled_ample:
      assumes REACH[simp, intro!]: "gc \<in> ga.E\<^sup>* `` ga.V0"
      shows "jsys.ample_set gc (ga_ample gc)"
    proof (cases "ga_ample gc = ga_en gc")
      case True thus ?thesis using jsys.ample_en by auto
    next
      case False
      from ga_ample_approx[OF REACH False] obtain pid where
        AMPLE_SS: "ga_ample gc \<subseteq> ga_en gc"
      and NE: "ga_ample gc \<noteq> {}"
      and NS: "ga_ample gc \<inter> sticky_ga = {}"
      and AMPLE_FMT: "ga_ample gc = pid_pac pid \<inter> ga_en gc"
      and A_STATIC: "is_ample_static (cmd_of_pid gc pid)"
        by blast
      hence aux1: "ga_ample gc = ga_ample gc \<inter> ga_en gc" by blast

      from False NE AMPLE_SS have NN: "None \<notin> ga_en gc" by auto

      from A_STATIC have LOC: "
        \<And>c a c'. Some (pid, c,a,c') \<in> pid_psen pid gc
          \<Longrightarrow> read_globals a = {} \<and> write_globals a = {}"
        unfolding is_ample_static_def pid_psen_def
        by auto
      from A_STATIC have LOC': "
        \<And>c a c'. Some (pid, c,a,c') \<in> pid_pac pid \<inter> ga_en gc
          \<Longrightarrow> read_globals a = {} \<and> write_globals a = {}"
        unfolding is_ample_static_def pid_pac_def ga_en_def
        by (auto split: prod.splits simp:  ga_gen_def)

      from reachable_alt[symmetric] REACH
      have REACH': "gc \<in> jsys.nodes" by simp

      have INV':
        "\<And>c a c'. Some (pid,c,a,c')\<in>ga_en gc
        \<Longrightarrow> Some (pid,c,a,c') \<notin> jsys.visible"
        using NS sticky_ga_approx_visible
        apply (clarsimp simp: AMPLE_FMT pid_pac_def split: option.splits)
        apply blast
        done

      {
        fix ga gc'
        assume en_eq: "pid_pac pid \<inter> ga_en gc = pid_pac pid \<inter> ga_en gc'"
        assume psen_eq: "pid_psen pid gc = pid_psen pid gc'"
        assume ga_en: "ga \<in> ga_en gc'"
        assume ga_not_pid: "ga \<notin> pid_pac pid"

        from en_eq NN have [simp]: "None \<notin> ga_en gc'"
          using pid_pac_None
          by blast

        with ga_en have "ga\<noteq>None" by metis
        then obtain pid' c a c' where [simp]: "ga = Some (pid',c,a,c')"
          by (cases ga) auto

        from ga_not_pid have [simp]: "pid'\<noteq>pid" by (auto simp: pid_pac_def)

        have [simp]: "\<And>cac. Some (pid,cac) \<in> ga_en gc'
          \<longleftrightarrow> Some (pid,cac) \<in> ga_en gc"
          using en_eq unfolding pid_pac_def
            by (auto split: option.splits)
        hence pid_gen_gc'_gc: "\<And>cac. (pid,cac) \<in> ga_gen gc'
          \<longleftrightarrow> (pid,cac) \<in> ga_gen gc"
          unfolding ga_en_def
          by simp

        have "cmd_of_pid (ga_gex (pid', c, a, c') gc') pid
          = cmd_of_pid gc' pid"
          by (auto simp: ga_gex_def split: prod.splits)
        hence G1: "pid_psen pid (ga_ex ga gc') = pid_psen pid gc'"
          by (auto simp: pid_psen_def ga_gex_def ga_ex_def
            split: prod.splits)

        have pid_ge_ex_invar: "\<And>cac.
          (pid,cac)\<in>ga_gen (ga_ex (Some (pid', c, a, c')) gc') \<longleftrightarrow>
          (pid,cac)\<in>ga_gen gc'"
          apply (clarsimp simp: ga_en_def ga_ex_def)
        proof
          fix c'' a'' c'''
          assume A: "(pid, c'', a'', c''') \<in> ga_gen (ga_gex (pid', c, a, c') gc')"
          hence "Some (pid, c'', a'', c''') \<in> pid_psen pid (ga_gex (pid', c, a, c') gc')"
            by (auto simp: pid_psen_def ga_gen_def)
          hence "Some (pid, c'', a'', c''') \<in> pid_psen pid gc" using G1 psen_eq
            by (simp add: ga_ex_def)
          from LOC[OF this]
            have "read_globals a'' = {}" by simp
          from genabled_no_global_read_indep_other_pids[OF this \<open>pid'\<noteq>pid\<close>] A
          show "((pid, c'', a'', c''') \<in> ga_gen gc')" ..
        next
          fix c'' a'' c'''
          assume A: "((pid, c'', a'', c''') \<in> ga_gen gc')"
          hence "Some (pid, c'', a'', c''') \<in> pid_psen pid gc'"
            by (auto simp: pid_psen_def ga_gen_def)
          hence "Some (pid, c'', a'', c''') \<in> pid_psen pid gc" using psen_eq
            by (simp)
          from LOC[OF this] have "read_globals a'' = {}" by simp
          from genabled_no_global_read_indep_other_pids[OF this \<open>pid'\<noteq>pid\<close>] A
          show "(pid, c'', a'', c''') \<in> ga_gen (ga_gex (pid', c, a, c') gc')" ..
        qed

        have [simp]:
          "ga_gen (ga_ex (Some (pid', c, a, c')) gc') \<noteq> {}"
          "ga_gen gc' \<noteq> {}"
        proof -
          from NN NE obtain cac2 where "Some (pid,cac2) \<in> ga_en gc"
            unfolding AMPLE_FMT
            apply (clarsimp simp: ex_in_conv[symmetric])
            using NN
            apply (auto simp: pid_pac_def split: option.splits)
            done
          hence "(pid,cac2) \<in> ga_gen gc" by (auto simp: ga_en_def)
          hence 1: "(pid,cac2) \<in> ga_gen gc'"
            by (simp add: pid_gen_gc'_gc)
          thus "ga_gen gc' \<noteq> {}" by blast
          from 1 have "(pid,cac2) \<in> ga_gen (ga_ex (Some (pid', c, a, c')) gc')"
            by (simp add: pid_ge_ex_invar pid_gen_gc'_gc)
          thus "ga_gen (ga_ex (Some (pid', c, a, c')) gc') \<noteq> {}" by blast
        qed

        have G2: "pid_pac pid \<inter> ga_en (ga_ex ga gc') =
             pid_pac pid \<inter> ga_en gc'"
          apply (auto simp: pid_pac_def split: option.splits)
          apply (auto simp add: ga_en_def stutter_extend_en_def
              pid_ge_ex_invar
              split: if_split_asm) [2]
          done
        note G1 G2
      } note aux=this

      show ?thesis
        apply (subst AMPLE_FMT)
        apply (rule jsys.restrict_ample_set[unfolded Collect_mem_eq])
        apply (simp add: reachable_alt del: ga_automaton_simps)
        using NE AMPLE_FMT apply blast
        using NS AMPLE_FMT apply blast
        apply safe []
        apply (rename_tac ga1 ga2)
        apply (case_tac "(ga1,ga2)" rule: ind.cases)
        using NN apply (simp_all) [4]
        apply (simp_all add: pid_pac_def LOC' INV') []

        apply (rule jsys.pac_en_blocked'[OF REACH'])
        unfolding Collect_mem_eq
        apply assumption+
        apply (rule conjI)
        apply (rule aux, assumption+)
        apply (rule aux, assumption+)
        done
    qed

    sublocale jsys: ample_abstract
      ga_ex "\<lambda> a p. a \<in> ga_en p" "\<lambda> p. p = pid_init_gc"
      pid_interp_gc ind "jsys.scut\<inverse>\<inverse>" "\<lambda> a p. a \<in> ga_ample p"
      apply unfold_locales
      unfolding Collect_mem_eq
      apply (rule pid_enabled_ample)
      apply (simp add: reachable_alt)
      done

    definition "ample_rel \<equiv> rel_of_enex (ga_ample, ga_ex)"
    definition "ample_succ \<equiv> succ_of_enex (ga_ample, ga_ex)"

    definition reduced_automaton
      where "reduced_automaton =
        \<lparr> g_V = UNIV, g_E = ample_rel, g_V0 = {pid_init_gc}, sa_L = pid_interp_gc \<rparr>"

    lemma reduced_automaton_simps[simp]:
      "g_V reduced_automaton = UNIV"
      "g_E reduced_automaton = ample_rel"
      "g_V0 reduced_automaton = {pid_init_gc}"
      "sa_L reduced_automaton = pid_interp_gc"
      unfolding reduced_automaton_def by auto

    sublocale ample: sa reduced_automaton by unfold_locales auto

    lemma jsys_R_lang_eq: "snth ` jsys.R.language = Collect ample.accept"
      apply (subst system_complete_language_eq_lsystem_accept)
      using ample.sa_axioms
      unfolding reduced_automaton_def ample_rel_def
      apply simp
      apply (auto simp: ample_rel_def sngp_sym_conv)
      done

    lemma ample_accept_subset: "ample.accept w \<Longrightarrow> lv.sa.accept w"
    proof -
      assume "ample.accept w"
      hence "w \<in> snth ` jsys.R.language" by (simp add: jsys_R_lang_eq)
      hence "w \<in> snth ` jsys.language" using jsys.reduction_language_subset by auto
      with jsys_lang_eq show "lv.sa.accept w" by auto
    qed

    lemma ample_accept_stuttering:
      assumes A: "lv.sa.accept w"
      obtains w' where "w\<approx>w'" "ample.accept w'"
    proof -
      from A have "w \<in> snth ` jsys.language" by (simp add: jsys_lang_eq)
      then obtain w' where "w \<approx> w'" "w' \<in> snth ` jsys.R.language"
        by (auto elim!: jsys.reduction_language_stuttering)
      hence "ample.accept w'" by (simp add: jsys_R_lang_eq)
      thus ?thesis using \<open>w\<approx>w'\<close> by (blast intro: that)
    qed
  end

end


(*  Title:      HOL/Auth/n_germanSymIndex_lemma_on_inv__31.thy
    Author:     Yongjian Li and Kaiqiang Duan, State Key Lab of Computer Science, Institute of Software, Chinese Academy of Sciences
    Copyright    2016 State Key Lab of Computer Science, Institute of Software, Chinese Academy of Sciences
*)

header{*The n_germanSymIndex Protocol Case Study*}

theory n_germanSymIndex_lemma_on_inv__31 imports n_germanSymIndex_base
begin
section{*All lemmas on causal relation between inv__31 and some rule r*}
lemma n_RecvReqSVsinv__31:
assumes a1: "(\<exists> i. i\<le>N\<and>r=n_RecvReqS N i)" and
a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2)"
shows "invHoldForRule s f r (invariants N)" (is "?P1 s \<or> ?P2 s \<or> ?P3 s")
proof -
from a1 obtain i where a1:"i\<le>N\<and>r=n_RecvReqS N i" apply fastforce done
from a2 obtain p__Inv0 p__Inv2 where a2:"p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2" apply fastforce done
have "(i=p__Inv2)\<or>(i=p__Inv0)\<or>(i~=p__Inv0\<and>i~=p__Inv2)" apply (cut_tac a1 a2, auto) done
moreover {
  assume b1: "(i=p__Inv2)"
  have "?P3 s"
  apply (cut_tac a1 a2 b1, simp, rule_tac x="(neg (andForm (eqn (IVar (Field (Para (Ident ''Cache'') p__Inv0) ''State'')) (Const E)) (eqn (IVar (Para (Ident ''ShrSet'') p__Inv2)) (Const true))))" in exI, auto) done
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i=p__Inv0)"
  have "?P3 s"
  apply (cut_tac a1 a2 b1, simp, rule_tac x="(neg (andForm (eqn (IVar (Field (Para (Ident ''Cache'') p__Inv0) ''State'')) (Const E)) (eqn (IVar (Para (Ident ''ShrSet'') p__Inv2)) (Const true))))" in exI, auto) done
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i~=p__Inv0\<and>i~=p__Inv2)"
  have "?P3 s"
  apply (cut_tac a1 a2 b1, simp, rule_tac x="(neg (andForm (eqn (IVar (Field (Para (Ident ''Cache'') p__Inv0) ''State'')) (Const E)) (eqn (IVar (Para (Ident ''ShrSet'') p__Inv2)) (Const true))))" in exI, auto) done
  then have "invHoldForRule s f r (invariants N)" by auto
}
ultimately show "invHoldForRule s f r (invariants N)" by satx
qed

lemma n_RecvReqEVsinv__31:
assumes a1: "(\<exists> i. i\<le>N\<and>r=n_RecvReqE N i)" and
a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2)"
shows "invHoldForRule s f r (invariants N)" (is "?P1 s \<or> ?P2 s \<or> ?P3 s")
proof -
from a1 obtain i where a1:"i\<le>N\<and>r=n_RecvReqE N i" apply fastforce done
from a2 obtain p__Inv0 p__Inv2 where a2:"p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2" apply fastforce done
have "(i=p__Inv2)\<or>(i=p__Inv0)\<or>(i~=p__Inv0\<and>i~=p__Inv2)" apply (cut_tac a1 a2, auto) done
moreover {
  assume b1: "(i=p__Inv2)"
  have "?P3 s"
  apply (cut_tac a1 a2 b1, simp, rule_tac x="(neg (andForm (eqn (IVar (Field (Para (Ident ''Cache'') p__Inv0) ''State'')) (Const E)) (eqn (IVar (Para (Ident ''ShrSet'') p__Inv2)) (Const true))))" in exI, auto) done
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i=p__Inv0)"
  have "?P3 s"
  apply (cut_tac a1 a2 b1, simp, rule_tac x="(neg (andForm (eqn (IVar (Field (Para (Ident ''Cache'') p__Inv0) ''State'')) (Const E)) (eqn (IVar (Para (Ident ''ShrSet'') p__Inv2)) (Const true))))" in exI, auto) done
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i~=p__Inv0\<and>i~=p__Inv2)"
  have "?P3 s"
  apply (cut_tac a1 a2 b1, simp, rule_tac x="(neg (andForm (eqn (IVar (Field (Para (Ident ''Cache'') p__Inv0) ''State'')) (Const E)) (eqn (IVar (Para (Ident ''ShrSet'') p__Inv2)) (Const true))))" in exI, auto) done
  then have "invHoldForRule s f r (invariants N)" by auto
}
ultimately show "invHoldForRule s f r (invariants N)" by satx
qed

lemma n_SendInv__part__0Vsinv__31:
assumes a1: "(\<exists> i. i\<le>N\<and>r=n_SendInv__part__0  i)" and
a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2)"
shows "invHoldForRule s f r (invariants N)" (is "?P1 s \<or> ?P2 s \<or> ?P3 s")
proof -
from a1 obtain i where a1:"i\<le>N\<and>r=n_SendInv__part__0  i" apply fastforce done
from a2 obtain p__Inv0 p__Inv2 where a2:"p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2" apply fastforce done
have "(i=p__Inv2)\<or>(i=p__Inv0)\<or>(i~=p__Inv0\<and>i~=p__Inv2)" apply (cut_tac a1 a2, auto) done
moreover {
  assume b1: "(i=p__Inv2)"
  have "?P1 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i=p__Inv0)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i~=p__Inv0\<and>i~=p__Inv2)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
ultimately show "invHoldForRule s f r (invariants N)" by satx
qed

lemma n_SendInv__part__1Vsinv__31:
assumes a1: "(\<exists> i. i\<le>N\<and>r=n_SendInv__part__1  i)" and
a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2)"
shows "invHoldForRule s f r (invariants N)" (is "?P1 s \<or> ?P2 s \<or> ?P3 s")
proof -
from a1 obtain i where a1:"i\<le>N\<and>r=n_SendInv__part__1  i" apply fastforce done
from a2 obtain p__Inv0 p__Inv2 where a2:"p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2" apply fastforce done
have "(i=p__Inv2)\<or>(i=p__Inv0)\<or>(i~=p__Inv0\<and>i~=p__Inv2)" apply (cut_tac a1 a2, auto) done
moreover {
  assume b1: "(i=p__Inv2)"
  have "?P1 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i=p__Inv0)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i~=p__Inv0\<and>i~=p__Inv2)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
ultimately show "invHoldForRule s f r (invariants N)" by satx
qed

lemma n_SendInvAckVsinv__31:
assumes a1: "(\<exists> i. i\<le>N\<and>r=n_SendInvAck  i)" and
a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2)"
shows "invHoldForRule s f r (invariants N)" (is "?P1 s \<or> ?P2 s \<or> ?P3 s")
proof -
from a1 obtain i where a1:"i\<le>N\<and>r=n_SendInvAck  i" apply fastforce done
from a2 obtain p__Inv0 p__Inv2 where a2:"p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2" apply fastforce done
have "(i=p__Inv2)\<or>(i=p__Inv0)\<or>(i~=p__Inv0\<and>i~=p__Inv2)" apply (cut_tac a1 a2, auto) done
moreover {
  assume b1: "(i=p__Inv2)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i=p__Inv0)"
  have "?P1 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i~=p__Inv0\<and>i~=p__Inv2)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
ultimately show "invHoldForRule s f r (invariants N)" by satx
qed

lemma n_RecvGntSVsinv__31:
assumes a1: "(\<exists> i. i\<le>N\<and>r=n_RecvGntS  i)" and
a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2)"
shows "invHoldForRule s f r (invariants N)" (is "?P1 s \<or> ?P2 s \<or> ?P3 s")
proof -
from a1 obtain i where a1:"i\<le>N\<and>r=n_RecvGntS  i" apply fastforce done
from a2 obtain p__Inv0 p__Inv2 where a2:"p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2" apply fastforce done
have "(i=p__Inv2)\<or>(i=p__Inv0)\<or>(i~=p__Inv0\<and>i~=p__Inv2)" apply (cut_tac a1 a2, auto) done
moreover {
  assume b1: "(i=p__Inv2)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i=p__Inv0)"
  have "?P1 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i~=p__Inv0\<and>i~=p__Inv2)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
ultimately show "invHoldForRule s f r (invariants N)" by satx
qed

lemma n_RecvGntEVsinv__31:
assumes a1: "(\<exists> i. i\<le>N\<and>r=n_RecvGntE  i)" and
a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2)"
shows "invHoldForRule s f r (invariants N)" (is "?P1 s \<or> ?P2 s \<or> ?P3 s")
proof -
from a1 obtain i where a1:"i\<le>N\<and>r=n_RecvGntE  i" apply fastforce done
from a2 obtain p__Inv0 p__Inv2 where a2:"p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2" apply fastforce done
have "(i=p__Inv2)\<or>(i=p__Inv0)\<or>(i~=p__Inv0\<and>i~=p__Inv2)" apply (cut_tac a1 a2, auto) done
moreover {
  assume b1: "(i=p__Inv2)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i=p__Inv0)"
  have "?P3 s"
  apply (cut_tac a1 a2 b1, simp, rule_tac x="(neg (andForm (eqn (IVar (Para (Ident ''InvSet'') p__Inv2)) (Const true)) (eqn (IVar (Field (Para (Ident ''Chan2'') p__Inv0) ''Cmd'')) (Const GntE))))" in exI, auto) done
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i~=p__Inv0\<and>i~=p__Inv2)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
ultimately show "invHoldForRule s f r (invariants N)" by satx
qed

lemma n_SendReqE__part__1Vsinv__31:
  assumes a1: "\<exists> i. i\<le>N\<and>r=n_SendReqE__part__1  i" and
  a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2)"
  shows "invHoldForRule s f r (invariants N)"
  apply (rule noEffectOnRule, cut_tac a1 a2, auto) done

lemma n_StoreVsinv__31:
  assumes a1: "\<exists> i d. i\<le>N\<and>d\<le>N\<and>r=n_Store  i d" and
  a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2)"
  shows "invHoldForRule s f r (invariants N)"
  apply (rule noEffectOnRule, cut_tac a1 a2, auto) done

lemma n_RecvInvAckVsinv__31:
  assumes a1: "\<exists> i. i\<le>N\<and>r=n_RecvInvAck  i" and
  a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2)"
  shows "invHoldForRule s f r (invariants N)"
  apply (rule noEffectOnRule, cut_tac a1 a2, auto) done

lemma n_SendGntSVsinv__31:
  assumes a1: "\<exists> i. i\<le>N\<and>r=n_SendGntS  i" and
  a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2)"
  shows "invHoldForRule s f r (invariants N)"
  apply (rule noEffectOnRule, cut_tac a1 a2, auto) done

lemma n_SendReqE__part__0Vsinv__31:
  assumes a1: "\<exists> i. i\<le>N\<and>r=n_SendReqE__part__0  i" and
  a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2)"
  shows "invHoldForRule s f r (invariants N)"
  apply (rule noEffectOnRule, cut_tac a1 a2, auto) done

lemma n_SendReqSVsinv__31:
  assumes a1: "\<exists> i. i\<le>N\<and>r=n_SendReqS  i" and
  a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2)"
  shows "invHoldForRule s f r (invariants N)"
  apply (rule noEffectOnRule, cut_tac a1 a2, auto) done

lemma n_SendGntEVsinv__31:
  assumes a1: "\<exists> i. i\<le>N\<and>r=n_SendGntE N i" and
  a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__31  p__Inv0 p__Inv2)"
  shows "invHoldForRule s f r (invariants N)"
  apply (rule noEffectOnRule, cut_tac a1 a2, auto) done

end