theory flash79Bra  imports flash79Rev

  begin
lemma onInv79:

   assumes  a1:"iInv1 \<le> N" and  a2:"iInv2 \<le> N" and  a3:"iInv1~=iInv2  " and

     b1:"r \<in> rules N" and b2:"invf=inv79  iInv1  iInv2 "
   shows  "invHoldForRule' s invf r (invariants   N)"
   proof -
have c1:"ex1P N (% iRule1 .  r=NI_Local_GetX_PutX1 N  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_GetX  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Replace  iRule1 )\<or>ex0P N (  r=NI_ShWb N )\<or>ex0P N (  r=PI_Local_GetX_GetX2 )\<or>ex0P N (  r=NI_Local_PutXAcksDone )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX7 N  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_Get_Nak2  iRule1 )\<or>ex0P N (  r=NI_ReplaceHomeShrVld )\<or>ex1P N (% iRule1 .  r=NI_Remote_Put  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX5 N  iRule1 )\<or>ex0P N (  r=NI_Wb )\<or>ex1P N (% iRule1 .  r=NI_Local_Get_Get  iRule1 )\<or>ex0P N (  r=PI_Local_Replace )\<or>ex1P N (% iRule1 .  r=NI_ReplaceShrVld  iRule1 )\<or>ex2P N (% iRule1  iRule2 .  r=NI_Local_GetX_PutX8 N  iRule1  iRule2 )\<or>ex1P N (% iRule1 .  r=NI_InvAck_2 N  iRule1 )\<or>ex2P N (% iRule1  iRule2 .  r=NI_Remote_Get_Nak2  iRule1  iRule2 )\<or>ex1P N (% iRule1 .  r=PI_Remote_Replace  iRule1 )\<or>ex0P N (  r=NI_Nak_Home )\<or>ex1P N (% iRule1 .  r=NI_Local_Get_Put2  iRule1 )\<or>ex2P N (% iRule1  iRule2 .  r=NI_InvAck_1  iRule1  iRule2 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX11 N  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX6 N  iRule1 )\<or>ex2P N (% iRule1  iRule2 .  r=NI_Remote_Get_Put2  iRule1  iRule2 )\<or>ex0P N (  r=PI_Local_Get_Put )\<or>ex0P N (  r=PI_Local_GetX_PutX1 N )\<or>ex1P N (% iRule1 .  r=NI_InvAck_1_Home  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Remote_Get_Nak1  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_Get_Nak1  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_Nak2  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX10_home N  iRule1 )\<or>ex1P N (% iRule1 .  r=PI_Remote_Get  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_Nak3  iRule1 )\<or>ex2P N (% iRule1  iRule2 .  r=NI_Local_GetX_PutX10 N  iRule1  iRule2 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX2 N  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Remote_Get_Put1  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Remote_PutX  iRule1 )\<or>ex1P N (% iRule1 .  r=Store  iRule1 )\<or>ex0P N (  r=NI_FAck )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX3 N  iRule1 )\<or>ex0P N (  r=PI_Local_GetX_PutX3 )\<or>ex2P N (% iRule1  iRule2 .  r=NI_Remote_GetX_PutX  iRule1  iRule2 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX8_home N  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_Get_Put1 N  iRule1 )\<or>ex0P N (  r=PI_Local_GetX_GetX1 )\<or>ex0P N (  r=StoreHome )\<or>ex2P N (% iRule1  iRule2 .  r=NI_Remote_GetX_Nak  iRule1  iRule2 )\<or>ex1P N (% iRule1 .  r=NI_Inv  iRule1 )\<or>ex1P N (% iRule1 .  r=PI_Remote_PutX  iRule1 )\<or>ex0P N (  r=PI_Local_GetX_PutX4 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX4 N  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Nak  iRule1 )\<or>ex0P N (  r=PI_Local_GetX_PutX2 N )\<or>ex0P N (  r=NI_Local_Put )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_Nak1  iRule1 )\<or>ex0P N (  r=NI_Nak_Clear )\<or>ex0P N (  r=PI_Local_PutX )\<or>ex1P N (% iRule1 .  r=NI_Local_Get_Nak3  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Remote_GetX_Nak_Home  iRule1 )\<or>ex0P N (  r=PI_Local_Get_Get )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX9 N  iRule1 )\<or>ex1P N (% iRule1 .  r=PI_Remote_GetX  iRule1 )\<or>ex0P N (  r=NI_ReplaceHome )\<or>ex1P N (% iRule1 .  r=NI_Remote_GetX_PutX_Home  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_Get_Put3  iRule1 )"

        apply(cut_tac  b1)
        apply auto
        done      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX1 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX1 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_GetX_PutX1 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX1VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_GetX  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_GetX  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_GetX_GetX  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_GetXVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Replace  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Replace  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Replace  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_ReplaceVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= NI_ShWb N )
"

         from c1 have c2:" r= NI_ShWb N "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_ShWb N ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_ShWbVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex0P N (  r= PI_Local_GetX_GetX2 )
"

         from c1 have c2:" r= PI_Local_GetX_GetX2 "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (PI_Local_GetX_GetX2 ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_GetX_GetX2VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex0P N (  r= NI_Local_PutXAcksDone )
"

         from c1 have c2:" r= NI_Local_PutXAcksDone "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_PutXAcksDone ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_Local_PutXAcksDoneVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX7 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX7 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_GetX_PutX7 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX7VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_Get_Nak2  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_Get_Nak2  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_Get_Nak2  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_Get_Nak2VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= NI_ReplaceHomeShrVld )
"

         from c1 have c2:" r= NI_ReplaceHomeShrVld "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_ReplaceHomeShrVld ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_ReplaceHomeShrVldVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Remote_Put  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Remote_Put  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Remote_Put  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_PutVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX5 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX5 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_GetX_PutX5 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX5VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= NI_Wb )
"

         from c1 have c2:" r= NI_Wb "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Wb ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_WbVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_Get_Get  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_Get_Get  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_Get_Get  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_Get_GetVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= PI_Local_Replace )
"

         from c1 have c2:" r= PI_Local_Replace "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (PI_Local_Replace ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_ReplaceVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_ReplaceShrVld  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_ReplaceShrVld  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_ReplaceShrVld  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_ReplaceShrVldVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex2P N (% iRule1  iRule2 .  r= NI_Local_GetX_PutX8 N  iRule1  iRule2 )
"

         from c1 obtain  iRule1  iRule2  where c2:"  iRule1~=iRule2    \<and>   iRule1 \<le> N \<and>   iRule2 \<le> N \<and>  r= NI_Local_GetX_PutX8 N  iRule1  iRule2 "
         by (auto simp add: ex2P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_GetX_PutX8 N  iRule1  iRule2 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX8VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_InvAck_2 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_InvAck_2 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_InvAck_2 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_InvAck_2VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex2P N (% iRule1  iRule2 .  r= NI_Remote_Get_Nak2  iRule1  iRule2 )
"

         from c1 obtain  iRule1  iRule2  where c2:"  iRule1~=iRule2    \<and>   iRule1 \<le> N \<and>   iRule2 \<le> N \<and>  r= NI_Remote_Get_Nak2  iRule1  iRule2 "
         by (auto simp add: ex2P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Remote_Get_Nak2  iRule1  iRule2 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_Get_Nak2VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= PI_Remote_Replace  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= PI_Remote_Replace  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (PI_Remote_Replace  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis PI_Remote_ReplaceVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= NI_Nak_Home )
"

         from c1 have c2:" r= NI_Nak_Home "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Nak_Home ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_Nak_HomeVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_Get_Put2  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_Get_Put2  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_Get_Put2  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_Get_Put2VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex2P N (% iRule1  iRule2 .  r= NI_InvAck_1  iRule1  iRule2 )
"

         from c1 obtain  iRule1  iRule2  where c2:"  iRule1~=iRule2    \<and>   iRule1 \<le> N \<and>   iRule2 \<le> N \<and>  r= NI_InvAck_1  iRule1  iRule2 "
         by (auto simp add: ex2P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_InvAck_1  iRule1  iRule2 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_InvAck_1VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX11 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX11 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_GetX_PutX11 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX11VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX6 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX6 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_GetX_PutX6 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX6VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex2P N (% iRule1  iRule2 .  r= NI_Remote_Get_Put2  iRule1  iRule2 )
"

         from c1 obtain  iRule1  iRule2  where c2:"  iRule1~=iRule2    \<and>   iRule1 \<le> N \<and>   iRule2 \<le> N \<and>  r= NI_Remote_Get_Put2  iRule1  iRule2 "
         by (auto simp add: ex2P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Remote_Get_Put2  iRule1  iRule2 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_Get_Put2VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= PI_Local_Get_Put )
"

         from c1 have c2:" r= PI_Local_Get_Put "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (PI_Local_Get_Put ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_Get_PutVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex0P N (  r= PI_Local_GetX_PutX1 N )
"

         from c1 have c2:" r= PI_Local_GetX_PutX1 N "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (PI_Local_GetX_PutX1 N ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_GetX_PutX1VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_InvAck_1_Home  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_InvAck_1_Home  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_InvAck_1_Home  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_InvAck_1_HomeVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Remote_Get_Nak1  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Remote_Get_Nak1  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Remote_Get_Nak1  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_Get_Nak1VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_Get_Nak1  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_Get_Nak1  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_Get_Nak1  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_Get_Nak1VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_Nak2  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_Nak2  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_GetX_Nak2  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_Nak2VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX10_home N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX10_home N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_GetX_PutX10_home N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX10_homeVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= PI_Remote_Get  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= PI_Remote_Get  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (PI_Remote_Get  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis PI_Remote_GetVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_Nak3  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_Nak3  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_GetX_Nak3  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_Nak3VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex2P N (% iRule1  iRule2 .  r= NI_Local_GetX_PutX10 N  iRule1  iRule2 )
"

         from c1 obtain  iRule1  iRule2  where c2:"  iRule1~=iRule2    \<and>   iRule1 \<le> N \<and>   iRule2 \<le> N \<and>  r= NI_Local_GetX_PutX10 N  iRule1  iRule2 "
         by (auto simp add: ex2P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_GetX_PutX10 N  iRule1  iRule2 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX10VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX2 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX2 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_GetX_PutX2 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX2VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Remote_Get_Put1  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Remote_Get_Put1  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Remote_Get_Put1  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_Get_Put1VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Remote_PutX  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Remote_PutX  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Remote_PutX  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_PutXVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= Store  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= Store  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (Store  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis StoreVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= NI_FAck )
"

         from c1 have c2:" r= NI_FAck "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_FAck ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_FAckVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX3 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX3 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_GetX_PutX3 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX3VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= PI_Local_GetX_PutX3 )
"

         from c1 have c2:" r= PI_Local_GetX_PutX3 "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (PI_Local_GetX_PutX3 ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_GetX_PutX3VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex2P N (% iRule1  iRule2 .  r= NI_Remote_GetX_PutX  iRule1  iRule2 )
"

         from c1 obtain  iRule1  iRule2  where c2:"  iRule1~=iRule2    \<and>   iRule1 \<le> N \<and>   iRule2 \<le> N \<and>  r= NI_Remote_GetX_PutX  iRule1  iRule2 "
         by (auto simp add: ex2P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Remote_GetX_PutX  iRule1  iRule2 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_GetX_PutXVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX8_home N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX8_home N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_GetX_PutX8_home N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX8_homeVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_Get_Put1 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_Get_Put1 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_Get_Put1 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_Get_Put1VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= PI_Local_GetX_GetX1 )
"

         from c1 have c2:" r= PI_Local_GetX_GetX1 "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (PI_Local_GetX_GetX1 ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_GetX_GetX1VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex0P N (  r= StoreHome )
"

         from c1 have c2:" r= StoreHome "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (StoreHome ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis StoreHomeVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex2P N (% iRule1  iRule2 .  r= NI_Remote_GetX_Nak  iRule1  iRule2 )
"

         from c1 obtain  iRule1  iRule2  where c2:"  iRule1~=iRule2    \<and>   iRule1 \<le> N \<and>   iRule2 \<le> N \<and>  r= NI_Remote_GetX_Nak  iRule1  iRule2 "
         by (auto simp add: ex2P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Remote_GetX_Nak  iRule1  iRule2 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_GetX_NakVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Inv  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Inv  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Inv  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_InvVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= PI_Remote_PutX  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= PI_Remote_PutX  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (PI_Remote_PutX  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis PI_Remote_PutXVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= PI_Local_GetX_PutX4 )
"

         from c1 have c2:" r= PI_Local_GetX_PutX4 "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (PI_Local_GetX_PutX4 ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_GetX_PutX4VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX4 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX4 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_GetX_PutX4 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX4VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Nak  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Nak  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Nak  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_NakVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= PI_Local_GetX_PutX2 N )
"

         from c1 have c2:" r= PI_Local_GetX_PutX2 N "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (PI_Local_GetX_PutX2 N ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_GetX_PutX2VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex0P N (  r= NI_Local_Put )
"

         from c1 have c2:" r= NI_Local_Put "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_Put ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_Local_PutVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_Nak1  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_Nak1  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_GetX_Nak1  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_Nak1VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= NI_Nak_Clear )
"

         from c1 have c2:" r= NI_Nak_Clear "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Nak_Clear ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_Nak_ClearVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex0P N (  r= PI_Local_PutX )
"

         from c1 have c2:" r= PI_Local_PutX "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (PI_Local_PutX ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_PutXVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_Get_Nak3  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_Get_Nak3  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_Get_Nak3  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_Get_Nak3VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Remote_GetX_Nak_Home  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Remote_GetX_Nak_Home  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Remote_GetX_Nak_Home  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_GetX_Nak_HomeVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= PI_Local_Get_Get )
"

         from c1 have c2:" r= PI_Local_Get_Get "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (PI_Local_Get_Get ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_Get_GetVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX9 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX9 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_GetX_PutX9 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX9VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= PI_Remote_GetX  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= PI_Remote_GetX  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (PI_Remote_GetX  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis PI_Remote_GetXVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= NI_ReplaceHome )
"

         from c1 have c2:" r= NI_ReplaceHome "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_ReplaceHome ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_ReplaceHomeVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Remote_GetX_PutX_Home  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Remote_GetX_PutX_Home  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Remote_GetX_PutX_Home  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_GetX_PutX_HomeVsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_Get_Put3  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_Get_Put3  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv79  iInv1  iInv2 ) (NI_Local_Get_Put3  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_Get_Put3VsInv79 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }ultimately show "invHoldForRule' s invf r (invariants N) "
          by blast
     qed
end


theory UserDataTypeType
  imports
    Main
    "Ecore-GROOVE-Mapping.Type_Model_Graph_Mapping"
    "Ecore-GROOVE-Mapping.Identifier_List"
begin

section "Definition of a type model which introduces a User defined data type"

definition tmod_userdatatype :: "'t Id \<Rightarrow> 't type_model" where
  "tmod_userdatatype name = \<lparr>
    Class = {},
    Enum = {},
    UserDataType = {name},
    Field = {},
    FieldSig = (\<lambda>x. undefined),
    EnumValue = {},
    Inh = {},
    Prop = {},
    Constant = {},
    ConstType = (\<lambda>x. undefined)
  \<rparr>"

lemma tmod_userdatatype_correct: "type_model (tmod_userdatatype name)"
proof (intro type_model.intro)
  have "asym {} \<and> irrefl {}"
    by (simp add: asym.intros irrefl_def)
  then show "asym (Inh (tmod_userdatatype name)) \<and> irrefl ((Inh (tmod_userdatatype name))\<^sup>+)"
    unfolding tmod_userdatatype_def
    by simp
qed (simp_all add: tmod_userdatatype_def)

lemma tmod_userdatatype_combine_correct:
  assumes "type_model Tmod"
  assumes new_userdatatype: "name \<notin> Class Tmod \<union> Enum Tmod \<union> UserDataType Tmod"
  assumes "\<And>x. x \<in> Class Tmod \<union> Enum Tmod \<union> UserDataType Tmod \<Longrightarrow> \<not>id_in_ns name (Identifier x) \<and> \<not>id_in_ns x (Identifier name)"
  shows "type_model (tmod_combine Tmod (tmod_userdatatype name))"
proof (intro tmod_combine_full_distinct_correct)
  show "type_model (tmod_userdatatype name)"
    by (fact tmod_userdatatype_correct)
next
  show "(Class Tmod \<union> Enum Tmod \<union> UserDataType Tmod) \<inter> (Class (tmod_userdatatype name) \<union> Enum (tmod_userdatatype name) \<union> UserDataType (tmod_userdatatype name)) = {}"
    unfolding tmod_userdatatype_def
    using new_userdatatype
    by simp
qed (simp_all add: assms tmod_userdatatype_def)

section "Encoding of an User defined data type as Node Type in GROOVE"

definition tg_userdatatype_as_node_type :: "'t Id \<Rightarrow> 't \<Rightarrow> ('t list) type_graph" where
  "tg_userdatatype_as_node_type name data_edge = \<lparr>
    NT = {type (id_to_list name), string},
    ET = {(type (id_to_list name), edge [data_edge], string)},
    inh = {(type (id_to_list name), type (id_to_list name)), (string, string)},
    abs = {},
    mult = (\<lambda>x. (if x = (type (id_to_list name), edge [data_edge], string) then (\<^bold>0..\<^emph>, \<^bold>1..\<^bold>1) else undefined)),
    contains = {}
  \<rparr>"

lemma tg_userdatatype_as_node_type_correct: "type_graph (tg_userdatatype_as_node_type name data_edge)"
proof (intro type_graph.intro)
  fix n
  assume "n \<in> NT (tg_userdatatype_as_node_type name data_edge)"
  then have "n = type (id_to_list name) \<or> n = string"
    unfolding tg_userdatatype_as_node_type_def
    by simp
  then show "n \<in> Lab\<^sub>t \<union> Lab\<^sub>p"
    using Lab\<^sub>p_def Lab\<^sub>t.simps
    by blast
next
  fix s l t
  assume "(s, l, t) \<in> ET (tg_userdatatype_as_node_type name data_edge)"
  then show "s \<in> NT (tg_userdatatype_as_node_type name data_edge) \<and> l \<in> Lab\<^sub>e \<union> Lab\<^sub>f \<and> t \<in> NT (tg_userdatatype_as_node_type name data_edge)"
  proof (intro conjI)
    assume "(s, l, t) \<in> ET (tg_userdatatype_as_node_type name data_edge)"
    then show "s \<in> NT (tg_userdatatype_as_node_type name data_edge)"
      unfolding tg_userdatatype_as_node_type_def
      by simp
  next
    assume "(s, l, t) \<in> ET (tg_userdatatype_as_node_type name data_edge)"
    then have "l = edge [data_edge]"
      unfolding tg_userdatatype_as_node_type_def
      by simp
    then show "l \<in> Lab\<^sub>e \<union> Lab\<^sub>f"
      by (simp add: Lab\<^sub>e.rule_edge_labels)
  next
    assume "(s, l, t) \<in> ET (tg_userdatatype_as_node_type name data_edge)"
    then show "t \<in> NT (tg_userdatatype_as_node_type name data_edge)"
      unfolding tg_userdatatype_as_node_type_def
      by simp
  qed
next
  have "Relation.Field (inh (tg_userdatatype_as_node_type name data_edge)) = {type (id_to_list name), string}"
    unfolding tg_userdatatype_as_node_type_def
    by fastforce
  then show "Relation.Field (inh (tg_userdatatype_as_node_type name data_edge)) = NT (tg_userdatatype_as_node_type name data_edge)"
    unfolding tg_userdatatype_as_node_type_def
    by simp
next
  fix e
  assume e_def: "e \<in> ET (tg_userdatatype_as_node_type name data_edge)"
  have "multiplicity_pair (\<^bold>0..\<^emph>, \<^bold>1..\<^bold>1)"
  proof (intro multiplicity_pair.intro)
    show "multiplicity (m_in (\<^bold>0..\<^emph>, \<^bold>1..\<^bold>1))"
      by (simp add: multiplicity_def)
  next
    show "multiplicity (m_out (\<^bold>0..\<^emph>, \<^bold>1..\<^bold>1))"
      by (simp add: multiplicity_def)
  qed
  then show "multiplicity_pair (mult (tg_userdatatype_as_node_type name data_edge) e)"
    using e_def
    unfolding tg_userdatatype_as_node_type_def
    by simp
next
  show "Partial_order (inh (tg_userdatatype_as_node_type name data_edge))"
    unfolding partial_order_on_def preorder_on_def
  proof (intro conjI)
    show "Refl (inh (tg_userdatatype_as_node_type name data_edge))"
      unfolding refl_on_def tg_userdatatype_as_node_type_def
      by simp
  next
    show "trans (inh (tg_userdatatype_as_node_type name data_edge))"
      unfolding trans_def tg_userdatatype_as_node_type_def
      by simp
  next
    show "antisym (inh (tg_userdatatype_as_node_type name data_edge))"
      unfolding antisym_def tg_userdatatype_as_node_type_def
      by simp
  qed
qed (simp_all add: tg_userdatatype_as_node_type_def)

lemma tg_userdatatype_as_node_type_combine_inh:
  assumes "type_graph TG"
  shows "(inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))\<^sup>+ =
    inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge)"
proof
  show "(inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))\<^sup>+ \<subseteq>
    inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge)"
  proof
    fix x
    assume "x \<in> (inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))\<^sup>+"
    then have "x \<in> (inh TG)\<^sup>+ \<union> inh (tg_userdatatype_as_node_type name data_edge)"
    proof (induct x)
      case (Pair a b)
      then show ?case
      proof (induct)
        case (base y)
        then show ?case
          by auto
      next
        case (step y z)
        then show ?case
        proof (elim UnE)
          assume yz_def: "(y, z) \<in> inh TG"
          assume ay_def: "(a, y) \<in> (inh TG)\<^sup>+"
          show ?thesis
            using yz_def ay_def
            by auto
        next
          assume yz_def: "(y, z) \<in> inh (tg_userdatatype_as_node_type name data_edge)"
          assume ay_def: "(a, y) \<in> (inh TG)\<^sup>+"
          show ?thesis
            using yz_def ay_def
            unfolding tg_userdatatype_as_node_type_def
            by auto
        next
          assume yz_def: "(y, z) \<in> inh TG"
          assume ay_def: "(a, y) \<in> inh (tg_userdatatype_as_node_type name data_edge)"
          show ?thesis
            using yz_def ay_def
            unfolding tg_userdatatype_as_node_type_def
            by auto
        next
          assume yz_def: "(y, z) \<in> inh (tg_userdatatype_as_node_type name data_edge)"
          assume ay_def: "(a, y) \<in> inh (tg_userdatatype_as_node_type name data_edge)"
          show ?thesis
            using yz_def ay_def
            unfolding tg_userdatatype_as_node_type_def
            by auto
        qed
      qed
    qed
    then show "x \<in> inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge)"
      by (simp add: assms type_graph.validity_inh_trans)
  qed
next
  show "inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge) \<subseteq>
    (inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))\<^sup>+"
    by auto
qed

lemma tg_userdatatype_as_node_type_combine_correct:
  assumes "type_graph TG"
  assumes combined_node_types: "NT TG \<inter> {type (id_to_list name), string} \<subseteq> {string}"
  shows "type_graph (tg_combine TG (tg_userdatatype_as_node_type name data_edge))"
proof (intro tg_combine_merge_correct)
  show "type_graph (tg_userdatatype_as_node_type name data_edge)"
    by (fact tg_userdatatype_as_node_type_correct)
next
  show "ET TG \<inter> ET (tg_userdatatype_as_node_type name data_edge) = {}"
    unfolding tg_userdatatype_as_node_type_def
    using assms type_graph.structure_edges_wellformed_src_node
    by fastforce
next
  fix l s1 t1 s2 t2
  assume edge1: "(s1, l, t1) \<in> ET TG"
  assume edge2: "(s2, l, t2) \<in> ET TG"
  assume "(s1, s2) \<in> (inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))\<^sup>+ - inh TG \<or>
    (s2, s1) \<in> (inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))\<^sup>+ - inh TG"
  then have "(s1, s2) \<in> inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge) - inh TG \<or>
    (s2, s1) \<in> inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge) - inh TG"
    by (simp add: assms tg_userdatatype_as_node_type_combine_inh)
  then have "(s1, s2) \<in> inh (tg_userdatatype_as_node_type name data_edge) \<or>
    (s2, s1) \<in> inh (tg_userdatatype_as_node_type name data_edge)"
    by blast
  then have src_eq: "s1 = s2"
    unfolding tg_userdatatype_as_node_type_def
    by auto
  assume "(t1, t2) \<in> (inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))\<^sup>+ \<or>
    (t2, t1) \<in> (inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))\<^sup>+"
  then have "(t1, t2) \<in> inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge) \<or>
    (t2, t1) \<in> inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge)"
    by (simp add: assms tg_userdatatype_as_node_type_combine_inh)
  then have "(t1, t2) \<in> inh TG \<or> (t2, t1) \<in> inh TG \<or>
    (t1, t2) = (type (id_to_list name), type (id_to_list name)) \<or> (t1, t2) = (string, string)"
    unfolding tg_userdatatype_as_node_type_def
    by auto
  then have tgt_eq: "t1 = t2"
  proof (elim disjE)
    assume "(t1, t2) \<in> inh TG"
    then show ?thesis
      using assms(1) edge1 edge2 src_eq type_graph.structure_edges_wellformed_src_node
      using type_graph.validity_edges_inh type_graph.validity_inh_node
      by fastforce
  next
    assume "(t2, t1) \<in> inh TG"
    then show ?thesis
      using assms(1) edge1 edge2 src_eq type_graph.structure_edges_wellformed_src_node
      using type_graph.validity_edges_inh type_graph.validity_inh_node
      by fastforce
  qed (simp_all)
  show "s1 = s2 \<and> t1 = t2"
    using src_eq tgt_eq
    by simp
next
  fix l s1 t1 s2 t2
  assume edge1: "(s1, l, t1) \<in> ET TG"
  assume edge2: "(s2, l, t2) \<in> ET TG"
  assume "(t1, t2) \<in> (inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))\<^sup>+ - inh TG \<or>
    (t2, t1) \<in> (inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))\<^sup>+ - inh TG"
  then have "(t1, t2) \<in> inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge) - inh TG \<or>
    (t2, t1) \<in> inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge) - inh TG"
    by (simp add: assms tg_userdatatype_as_node_type_combine_inh)
  then have "(t1, t2) \<in> inh (tg_userdatatype_as_node_type name data_edge) \<or>
    (t2, t1) \<in> inh (tg_userdatatype_as_node_type name data_edge)"
    by blast
  then have tgt_eq: "t1 = t2"
    unfolding tg_userdatatype_as_node_type_def
    by auto
  assume "(s1, s2) \<in> (inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))\<^sup>+ \<or>
    (s2, s1) \<in> (inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))\<^sup>+"
  then have "(s1, s2) \<in> inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge) \<or>
    (s2, s1) \<in> inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge)"
    by (simp add: assms tg_userdatatype_as_node_type_combine_inh)
  then have "(s1, s2) \<in> inh TG \<or> (s2, s1) \<in> inh TG \<or>
    (s1, s2) = (type (id_to_list name), type (id_to_list name)) \<or> (s1, s2) = (string, string)"
    unfolding tg_userdatatype_as_node_type_def
    by auto
  then have src_eq: "s1 = s2"
  proof (elim disjE)
    assume "(s1, s2) \<in> inh TG"
    then show ?thesis
      using assms(1) edge1 edge2 tgt_eq type_graph.structure_edges_wellformed_tgt_node
      using type_graph.validity_edges_inh type_graph.validity_inh_node
      by fastforce
  next
    assume "(s2, s1) \<in> inh TG"
    then show ?thesis
      using assms(1) edge1 edge2 tgt_eq type_graph.structure_edges_wellformed_tgt_node
      using type_graph.validity_edges_inh type_graph.validity_inh_node
      by fastforce
  qed (simp_all)
  show "s1 = s2 \<and> t1 = t2"
    using src_eq tgt_eq
    by simp
next
  fix l s1 t1 s2 t2
  assume edge1: "(s1, l, t1) \<in> ET TG"
  assume "(s2, l, t2) \<in> ET (tg_userdatatype_as_node_type name data_edge)"
  then have edge2: "(s2, l, t2) = (type (id_to_list name), edge [data_edge], string)"
    unfolding tg_userdatatype_as_node_type_def
    by simp
  then have not_inh_tg: "(s1, s2) \<notin> inh TG \<and> (s2, s1) \<notin> inh TG"
    using assms type_graph.structure_inheritance_wellformed_first_node
    using type_graph.structure_inheritance_wellformed_second_node
    by fastforce
  assume "(s1, s2) \<in> (inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))\<^sup>+ \<or>
    (s2, s1) \<in> (inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))\<^sup>+"
  then have "(s1, s2) \<in> inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge) \<or>
    (s2, s1) \<in> inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge)"
    by (simp add: assms tg_userdatatype_as_node_type_combine_inh)
  then have src_eq: "s1 = s2"
    unfolding tg_userdatatype_as_node_type_def
    using not_inh_tg
    by auto
  assume "(t1, t2) \<in> (inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))\<^sup>+ \<or>
    (t2, t1) \<in> (inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))\<^sup>+"
  then have "(t1, t2) \<in> inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge) \<or>
    (t2, t1) \<in> inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge)"
    by (simp add: assms tg_userdatatype_as_node_type_combine_inh)
  then show "s1 = s2 \<and> t1 = t2"
    using assms(1) edge1 edge2 src_eq not_inh_tg
    using type_graph.structure_edges_wellformed_src_node type_graph.validity_inh_node
    by blast
next
  have "antisym (inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))"
    using assms type_graph.validity_inh_antisym
    unfolding antisym_def tg_userdatatype_as_node_type_def
    by simp
  then show "antisym ((inh TG \<union> inh (tg_userdatatype_as_node_type name data_edge))\<^sup>+)"
    by (simp add: assms tg_userdatatype_as_node_type_combine_inh)
qed (simp_all add: tg_userdatatype_as_node_type_def assms)

subsection "Transformation functions"

definition tmod_userdatatype_to_tg_userdatatype_as_node_type :: "'t \<Rightarrow> 't type_model \<Rightarrow> ('t list) type_graph" where
  "tmod_userdatatype_to_tg_userdatatype_as_node_type data_edge Tmod = \<lparr>
    NT = type ` id_to_list ` UserDataType Tmod \<union> {string},
    ET = type ` id_to_list ` UserDataType Tmod \<times> {edge [data_edge]} \<times> {string},
    inh = type ` id_to_list ` UserDataType Tmod \<times> type ` id_to_list ` UserDataType Tmod \<union> {(string, string)},
    abs = {},
    mult = (\<lambda>x. (if x \<in> type ` id_to_list ` UserDataType Tmod \<times> {edge [data_edge]} \<times> {string} then (\<^bold>0..\<^emph>, \<^bold>1..\<^bold>1) else undefined)),
    contains = {}
  \<rparr>"

lemma tmod_userdatatype_to_tg_userdatatype_as_node_type_proj:
  shows "tmod_userdatatype_to_tg_userdatatype_as_node_type data_edge (tmod_userdatatype name) = tg_userdatatype_as_node_type name data_edge"
  unfolding tmod_userdatatype_to_tg_userdatatype_as_node_type_def tmod_userdatatype_def tg_userdatatype_as_node_type_def
  by auto

lemma tmod_userdatatype_to_tg_userdatatype_as_node_type_func:
  shows "tg_combine_mapping_function (tmod_userdatatype_to_tg_userdatatype_as_node_type data_edge) (tmod_userdatatype name) (tg_userdatatype_as_node_type name data_edge)"
  by (intro tg_combine_mapping_function.intro)
    (auto simp add: tmod_userdatatype_to_tg_userdatatype_as_node_type_def tmod_userdatatype_def tg_userdatatype_as_node_type_def tmod_combine_def)

definition tg_userdatatype_as_node_type_to_tmod_userdatatype :: "('t list) type_graph \<Rightarrow> 't type_model" where
  "tg_userdatatype_as_node_type_to_tmod_userdatatype TG = \<lparr>
    Class = {},
    Enum = {},
    UserDataType = list_to_id ` unlabel ` (NT TG \<inter> Lab\<^sub>t),
    Field = {},
    FieldSig = (\<lambda>x. undefined),
    EnumValue = {},
    Inh = {},
    Prop = {},
    Constant = {},
    ConstType = (\<lambda>x. undefined)
  \<rparr>"

lemma tg_userdatatype_as_node_type_to_tmod_userdatatype_proj:
  shows "tg_userdatatype_as_node_type_to_tmod_userdatatype (tg_userdatatype_as_node_type name data_edge) = tmod_userdatatype name"
proof-
  have "list_to_id ` unlabel ` {type (id_to_list name)} = {name}"
    by (simp add: id_to_list_inverse)
  then have "list_to_id ` unlabel ` ({type (id_to_list name), string} \<inter> Lab\<^sub>t) = {name}"
    by (simp add: Lab\<^sub>t.rule_type_labels)
  then have "list_to_id ` unlabel ` (NT (tg_userdatatype_as_node_type name data_edge) \<inter> Lab\<^sub>t) = {name}"
    unfolding tg_userdatatype_as_node_type_def
    by simp
  then show "tg_userdatatype_as_node_type_to_tmod_userdatatype (tg_userdatatype_as_node_type name data_edge) = tmod_userdatatype name"
    unfolding tg_userdatatype_as_node_type_to_tmod_userdatatype_def tmod_userdatatype_def
    by simp
qed

lemma tg_userdatatype_as_node_type_to_tmod_userdatatype_func:
  shows "tmod_combine_mapping_function (tg_userdatatype_as_node_type_to_tmod_userdatatype) (tg_userdatatype_as_node_type name data_edge) (tmod_userdatatype name)"
proof (intro tmod_combine_mapping_function.intro)
  show "tg_userdatatype_as_node_type_to_tmod_userdatatype (tg_userdatatype_as_node_type name data_edge) = tmod_userdatatype name"
    by (fact tg_userdatatype_as_node_type_to_tmod_userdatatype_proj)
next
  fix TGX
  have "(NT (tg_userdatatype_as_node_type name data_edge) \<inter> Lab\<^sub>t) \<subseteq>
    (NT (tg_combine (tg_userdatatype_as_node_type name data_edge) TGX) \<inter> Lab\<^sub>t)"
    unfolding tg_combine_def
    by fastforce
  then have "list_to_id ` unlabel ` (NT (tg_userdatatype_as_node_type name data_edge) \<inter> Lab\<^sub>t) \<subseteq>
    list_to_id ` unlabel ` (NT (tg_combine (tg_userdatatype_as_node_type name data_edge) TGX) \<inter> Lab\<^sub>t)"
    by fastforce
  then show "UserDataType (tg_userdatatype_as_node_type_to_tmod_userdatatype (tg_userdatatype_as_node_type name data_edge)) \<subseteq>
    UserDataType (tg_userdatatype_as_node_type_to_tmod_userdatatype (tg_combine (tg_userdatatype_as_node_type name data_edge) TGX))"
    unfolding tg_userdatatype_as_node_type_to_tmod_userdatatype_def
    by simp
qed (simp_all add: tg_userdatatype_as_node_type_to_tmod_userdatatype_def)

end


theory newzfc imports ZFC_in_HOL.ZFC_in_HOL
begin

axiomatization Collect :: "('a \<Rightarrow> bool) \<Rightarrow> 'a set" \<comment> \<open>comprehension\<close>
  and member :: "'a \<Rightarrow> 'a set \<Rightarrow> bool" \<comment> \<open>membership\<close>
  where mem_Collect_eq [iff, code_unfold]: "member a (Collect P) = P a"
    and Collect_mem_eq [simp]: "Collect (\<lambda>x. member x A) = A"

(*
syntax
  "_Coll" :: "pttrn \<Rightarrow> bool \<Rightarrow> 'a set"    ("(1{_./ _})")
translations
  "{x. P}" \<rightleftharpoons> "CONST Collect (\<lambda>x. P)"

class top =
  fixes top :: 'a ("\<top>")
*)
(*
definition image :: "('a \<Rightarrow> 'b) \<Rightarrow> 'a set \<Rightarrow> 'b set"    (infixr "`" 90)
  where "f ` A = {y. \<exists>x\<in>A. y = f x}"
*)
abbreviation UNIV :: "'a set"
  where "UNIV \<equiv> top"

abbreviation range :: "('a \<Rightarrow> 'b) \<Rightarrow> 'b set"  \<comment> \<open>of function\<close>
  where "range f \<equiv> f ` UNIV"

class Sup =
  fixes Sup :: "'a set \<Rightarrow> 'a"  ("\<Squnion>")

(*
abbreviation Union :: "'a set set \<Rightarrow> 'a set"  ("\<Union>")
  where "\<Union>S \<equiv> \<Squnion>S"
*)
definition Pow :: "'a set \<Rightarrow> 'a set set"
  where Pow_def: "Pow A = {B. B \<subseteq> A}"

definition inv_into :: "'a set \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> ('b \<Rightarrow> 'a)" where
"inv_into A f = (\<lambda>x. SOME y. y \<in> A \<and> f y = x)"

lemma inv_into_def2: "inv_into A f x = (SOME y. y \<in> A \<and> f y = x)"
by(simp add: inv_into_def)

abbreviation inv :: "('a \<Rightarrow> 'b) \<Rightarrow> ('b \<Rightarrow> 'a)" where
"inv \<equiv> inv_into UNIV"

definition wf :: "('a \<times> 'a) set \<Rightarrow> bool"
  where "wf r \<longleftrightarrow> (\<forall>P. (\<forall>x. (\<forall>y. (y, x) \<in> r \<longrightarrow> P y) \<longrightarrow> P x) \<longrightarrow> (\<forall>x. P x))"

axiomatization elts :: "V \<Rightarrow> V set"
 where ext [intro?]:    "elts x = elts y \<Longrightarrow> x=y"
   and down_raw:        "Y \<subseteq> elts x \<Longrightarrow> Y \<in> range elts"
   and Union_raw:       "X \<in> range elts \<Longrightarrow> Union (elts ` X) \<in> range elts"
   and Pow_raw:         "X \<in> range elts \<Longrightarrow> inv elts ` Pow X \<in> range elts"
   and replacement_raw: "X \<in> range elts \<Longrightarrow> f ` X \<in> range elts"
   and inf_raw:         "range (g :: nat \<Rightarrow> V) \<in> range elts"
   and foundation:      "wf {(x,y). x \<in> elts y}"

theorem t1 : \<open>A \<Longrightarrow> A\<close>
proof -
  assume H:\<open>A\<close>
  show \<open>A\<close>
    by (rule  H)
qed

axiomatization qwe :: "bool set"

theorem t2 : \<open>elts 0=elts 0\<close>
  oops
(**)

end


           (*-------------------------------------------*
            |        CSP-Prover on Isabelle2004         |
            |               December 2004               |
            |                   July 2005  (modified)   |
            |                                           |
            |        CSP-Prover on Isabelle2005         |
            |                October 2005  (modified)   |
            |                  April 2006  (modified)   |
            |                                           |
            |        CSP-Prover on Isabelle2009-2       |
            |                October 2010  (modified)   |
            |                                           |
            |        CSP-Prover on Isabelle2017         |
            |                  April 2018  (modified)   |
            |                                           |
            |        Yoshinao Isobe (AIST JAPAN)        |
            *-------------------------------------------*)

theory Domain_T_cpo
imports Domain_T CSP.CPO
begin

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

         1. Domain_T is a pointed cpo.
         2.
         3.
         4.

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

(*  The following simplification rules are deleted in this theory file *)
(*  because they unexpectly rewrite UnionT and InterT.                 *)
(*                  Union (B ` A) = (UN x:A. B x)                      *)
(*                  Inter (B ` A) = (INT x:A. B x)                     *)

(*
declare Union_image_eq [simp del]
declare Inter_image_eq [simp del]
*)
(* no simp rules in Isabelle 2017
declare Sup_image_eq [simp del]
declare Inf_image_eq [simp del]
*)

(*********************************************************
                      Bottom in Dom_T
 *********************************************************)
(* isabelle 2009-1
instance domT :: (type) bot0
by (intro_classes)

defs (overloaded)
  bottom_domT_def   :  "Bot == {<>}t"
*)

instantiation domT :: (type) bot0
begin

definition
  bottom_domT_def : "Bot == {<>}t"

instance ..

end

lemma bottom_domT : "Bot <= (T::'a domT)"
by (simp add: bottom_domT_def)

instance domT :: (type) bot
apply (intro_classes)
by (simp add: bottom_domT)

(**********************************************************
      lemmas used in a proof that domain_T is a cpo.
 **********************************************************)

(* UnionT Ts is an upper bound of Ts *)

lemma UnionT_isUB : "(UnionT Ts) isUB Ts"
apply (simp add: isUB_def)
apply (simp add: subdomT_iff)
apply (intro allI impI)
apply (subgoal_tac "Ts ~= {}")
apply (simp)
apply (rule_tac x=y in bexI)
by (auto)

(* UnionT Ts is the least upper bound of Ts *)

lemma UnionT_isLUB : "Ts ~= {} ==> UnionT Ts isLUB Ts"
apply (simp add: isLUB_def UnionT_isUB)
apply (simp add: isUB_def)
apply (simp add: subdomT_iff)
apply (intro allI impI)
apply (erule bexE)
apply (drule_tac x="T" in spec)
by (simp)

(* the least upper bound of Ts is UnionT Ts *)

lemma isLUB_UnionT_only_if: "[| Ts ~= {} ; T isLUB Ts |] ==> T = UnionT Ts"
apply (insert UnionT_isLUB[of Ts])
apply (simp)
apply (rule LUB_unique)
by (simp_all)

(* iff *)

lemma isLUB_UnionT : "Ts ~= {} ==> (T isLUB Ts) = (T = UnionT Ts)"
apply (rule iffI)
apply (simp add: isLUB_UnionT_only_if)
apply (simp add: UnionT_isLUB)
done

(* LUB is UnionT Ts *)

lemma LUB_UnionT : "Ts ~= {} ==> LUB Ts = UnionT Ts"
by (simp add: isLUB_LUB UnionT_isLUB)

(**********************************************************
                 ( domT, <= ) is a CPO
 **********************************************************)

instance domT :: (type) cpo
apply (intro_classes)
apply (simp add: hasLUB_def)
apply (rule_tac x="UnionT X" in exI)
apply (simp add: directed_def UnionT_isLUB)
done

(**********************************************************
              ( domT, <= ) is a pointed CPO
 **********************************************************)

instance domT :: (type) cpo_bot
by (intro_classes)

(****************** to add them again ******************)

(*
declare Union_image_eq [simp]
declare Inter_image_eq [simp]
*)
(*
declare Sup_image_eq [simp]
declare Inf_image_eq [simp]
*)

end