src/HOL/Nominal/Examples/Lam_substs.thy
changeset 18284 cd217d16c90d
parent 18269 3f36e2165e51
child 18298 f7899cb24c79
equal deleted inserted replaced
18283:f8a49f09a202 18284:cd217d16c90d
    15                      | Lam "\<guillemotleft>name\<guillemotright>lam" ("Lam [_]._" [100,100] 100)
    15                      | Lam "\<guillemotleft>name\<guillemotright>lam" ("Lam [_]._" [100,100] 100)
    16 
    16 
    17 section {* Strong induction principles for lam *}
    17 section {* Strong induction principles for lam *}
    18 
    18 
    19 lemma lam_induct_aux:
    19 lemma lam_induct_aux:
    20   fixes P :: "lam \<Rightarrow> 'a \<Rightarrow> bool"
    20   fixes P :: "'a \<Rightarrow> lam \<Rightarrow> bool"
    21   and   f :: "'a \<Rightarrow> 'a"
    21   and   f :: "'a \<Rightarrow> 'a"
    22   assumes fs: "\<And>x. finite ((supp (f x))::name set)"
    22   assumes fs: "\<And>x. finite ((supp (f x))::name set)"
    23       and h1: "\<And>x a. P (Var  a) x"  
    23       and h1: "\<And>x a. P x (Var  a)"  
    24       and h2: "\<And>x t1 t2. (\<forall>z. P t1 z) \<Longrightarrow> (\<forall>z. P t2 z) \<Longrightarrow> P (App t1 t2) x" 
    24       and h2: "\<And>x t1 t2. (\<And>z. P z t1) \<Longrightarrow> (\<And>z. P z t2) \<Longrightarrow> P x (App t1 t2)" 
    25       and h3: "\<And>x a t. a\<sharp>f x \<Longrightarrow> (\<forall>z. P t z) \<Longrightarrow> P (Lam [a].t) x"
    25       and h3: "\<And>x a t. a\<sharp>f x \<Longrightarrow> (\<And>z. P z t) \<Longrightarrow> P x (Lam [a].t)"
    26   shows "\<forall>(pi::name prm) x. P (pi\<bullet>t) x"
    26   shows "\<And>(pi::name prm) x. P x (pi\<bullet>t)"
    27 proof (induct rule: lam.induct_weak)
    27 proof (induct rule: lam.induct_weak)
    28   case (Lam a t)
    28   case (Lam a t)
    29   have ih: "\<forall>(pi::name prm) x. P (pi\<bullet>t) x" by fact
    29   have ih: "\<And>(pi::name prm) x. P x (pi\<bullet>t)" by fact
    30   show "\<forall>(pi::name prm) x. P (pi\<bullet>(Lam [a].t)) x"
    30   show "\<And>(pi::name prm) x. P x (pi\<bullet>(Lam [a].t))"
    31   proof (intro strip, simp add: abs_perm)
    31   proof (simp add: abs_perm)
    32     fix x::"'a" and pi::"name prm"
    32     fix x::"'a" and pi::"name prm"
    33     have "\<exists>c::name. c\<sharp>(f x,pi\<bullet>a,pi\<bullet>t)"
    33     have "\<exists>c::name. c\<sharp>(f x,pi\<bullet>a,pi\<bullet>t)"
    34       by (rule at_exists_fresh[OF at_name_inst], simp add: supp_prod fs_name1 fs)
    34       by (rule at_exists_fresh[OF at_name_inst], simp add: supp_prod fs_name1 fs)
    35     then obtain c::"name" 
    35     then obtain c::"name" 
    36       where f1: "c\<noteq>(pi\<bullet>a)" and f2: "c\<sharp>(f x)" and f3: "c\<sharp>(pi\<bullet>t)" 
    36       where f1: "c\<noteq>(pi\<bullet>a)" and f2: "c\<sharp>(f x)" and f3: "c\<sharp>(pi\<bullet>t)" 
    37       by (force simp add: fresh_prod fresh_atm)
    37       by (force simp add: fresh_prod fresh_atm)
    38     have "Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>t)) = Lam [(pi\<bullet>a)].(pi\<bullet>t)" using f1 f3
    38     have "Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>t)) = Lam [(pi\<bullet>a)].(pi\<bullet>t)" using f1 f3
    39       by (simp add: lam.inject alpha)
    39       by (simp add: lam.inject alpha)
    40     moreover
    40     moreover
    41     from ih have "\<forall>x. P (([(c,pi\<bullet>a)]@pi)\<bullet>t) x" by force
    41     from ih have "\<And>x. P x (([(c,pi\<bullet>a)]@pi)\<bullet>t)" by force
    42     hence "\<forall>x. P ([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>t)) x" by (simp add: pt_name2[symmetric])
    42     hence "\<And>x. P x ([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>t))" by (simp add: pt_name2[symmetric])
    43     hence "P (Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>t))) x" using h3 f2
    43     hence "P x (Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>t)))" using h3 f2
    44       by (auto simp add: fresh_def at_fin_set_supp[OF at_name_inst, OF fs])
    44       by (auto simp add: fresh_def at_fin_set_supp[OF at_name_inst, OF fs])
    45     ultimately show "P (Lam [(pi\<bullet>a)].(pi\<bullet>t)) x" by simp
    45     ultimately show "P x (Lam [(pi\<bullet>a)].(pi\<bullet>t))" by simp
    46   qed
    46   qed
    47 qed (auto intro: h1 h2)
    47 qed (auto intro: h1 h2)
    48 
    48 
    49 lemma lam_induct'[case_names Fin Var App Lam]: 
    49 lemma lam_induct'[case_names Fin Var App Lam]: 
    50   fixes P :: "lam \<Rightarrow> 'a \<Rightarrow> bool"
    50   fixes P :: "'a \<Rightarrow> lam \<Rightarrow> bool"
    51   and   x :: "'a"
    51   and   x :: "'a"
    52   and   t :: "lam"
    52   and   t :: "lam"
    53   and   f :: "'a \<Rightarrow> 'a"
    53   and   f :: "'a \<Rightarrow> 'a"
    54   assumes fs: "\<And>x. finite ((supp (f x))::name set)"
    54   assumes fs: "\<And>x. finite ((supp (f x))::name set)"
    55   and     h1: "\<And>x a. P (Var  a) x" 
    55   and     h1: "\<And>x a. P x (Var  a)" 
    56   and     h2: "\<And>x t1 t2. (\<forall>z. P t1 z)\<Longrightarrow>(\<forall>z. P t2 z)\<Longrightarrow>P (App t1 t2) x" 
    56   and     h2: "\<And>x t1 t2. (\<And>z. P z t1)\<Longrightarrow>(\<And>z. P z t2)\<Longrightarrow>P x (App t1 t2)" 
    57   and     h3: "\<And>x a t. a\<sharp>f x \<Longrightarrow> (\<forall>z. P t z)\<Longrightarrow> P (Lam [a].t) x"
    57   and     h3: "\<And>x a t. a\<sharp>f x \<Longrightarrow> (\<And>z. P z t)\<Longrightarrow> P x (Lam [a].t)"
    58   shows  "P t x"
    58   shows  "P x t"
    59 proof - 
    59 proof - 
    60   from fs h1 h2 h3 have "\<forall>(pi::name prm) x. P (pi\<bullet>t) x" by (rule lam_induct_aux, auto)
    60   from fs h1 h2 h3 have "\<And>(pi::name prm) x. P x (pi\<bullet>t)" by (rule lam_induct_aux, auto)
    61   hence "P (([]::name prm)\<bullet>t) x" by blast
    61   hence "P x (([]::name prm)\<bullet>t)" by blast
    62   thus "P t x" by simp
    62   thus "P x t" by simp
    63 qed
    63 qed
    64 
    64 
    65 lemma lam_induct[case_names Var App Lam]: 
    65 lemma lam_induct[case_names Var App Lam]: 
    66   fixes P :: "lam \<Rightarrow> ('a::fs_name) \<Rightarrow> bool"
    66   fixes P :: "('a::fs_name) \<Rightarrow> lam \<Rightarrow> bool"
    67   and   x :: "'a::fs_name"
    67   and   x :: "'a::fs_name"
    68   and   t :: "lam"
    68   and   t :: "lam"
    69   assumes h1: "\<And>x a. P (Var  a) x" 
    69   assumes h1: "\<And>x a. P x (Var  a)" 
    70   and     h2: "\<And>x t1 t2. (\<forall>z. P t1 z)\<Longrightarrow>(\<forall>z. P t2 z)\<Longrightarrow>P (App t1 t2) x" 
    70   and     h2: "\<And>x t1 t2. (\<And>z. P z t1)\<Longrightarrow>(\<And>z. P z t2)\<Longrightarrow>P x (App t1 t2)" 
    71   and     h3: "\<And>x a t. a\<sharp>x \<Longrightarrow> (\<forall>z. P t z)\<Longrightarrow> P (Lam [a].t) x"
    71   and     h3: "\<And>x a t. a\<sharp>x \<Longrightarrow> (\<And>z. P z t)\<Longrightarrow> P x (Lam [a].t)"
    72   shows  "P t x"
    72   shows  "P x t"
    73 by (rule lam_induct'[of "\<lambda>x. x" "P"], 
    73 apply(rule lam_induct'[of "\<lambda>x. x" "P"])
    74     simp_all add: fs_name1 fresh_def[symmetric], auto intro: h1 h2 h3)
    74 apply(simp add: fs_name1)
       
    75 apply(auto intro: h1 h2 h3)
       
    76 done
    75 
    77 
    76 types 'a f1_ty  = "name\<Rightarrow>('a::pt_name)"
    78 types 'a f1_ty  = "name\<Rightarrow>('a::pt_name)"
    77       'a f2_ty  = "'a\<Rightarrow>'a\<Rightarrow>('a::pt_name)"
    79       'a f2_ty  = "'a\<Rightarrow>'a\<Rightarrow>('a::pt_name)"
    78       'a f3_ty  = "name\<Rightarrow>'a\<Rightarrow>('a::pt_name)"
    80       'a f3_ty  = "name\<Rightarrow>'a\<Rightarrow>('a::pt_name)"
    79 
    81 
   923   and     a1: "\<forall>c. fun (Var c) = f1 c" 
   925   and     a1: "\<forall>c. fun (Var c) = f1 c" 
   924   and     a2: "\<forall>t1 t2. fun (App t1 t2) = f2 (fun t1) (fun t2)" 
   926   and     a2: "\<forall>t1 t2. fun (App t1 t2) = f2 (fun t1) (fun t2)" 
   925   and     a3: "\<forall>a t. a\<sharp>(f1,f2,f3) \<longrightarrow> fun (Lam [a].t) = f3 a (fun t)"
   927   and     a3: "\<forall>a t. a\<sharp>(f1,f2,f3) \<longrightarrow> fun (Lam [a].t) = f3 a (fun t)"
   926   shows "fun t = rfun f1 f2 f3 t"
   928   shows "fun t = rfun f1 f2 f3 t"
   927 (*apply(nominal_induct t rule: lam_induct')*)
   929 (*apply(nominal_induct t rule: lam_induct')*)
   928 apply (rule lam_induct'[of "\<lambda>_. (f1,f2,f3)" "\<lambda>t _. fun t = rfun f1 f2 f3 t"])
   930 apply (rule lam_induct'[of "\<lambda>_. (f1,f2,f3)" "\<lambda>_ t. fun t = rfun f1 f2 f3 t"])
   929 (* finite support *)
   931 (* finite support *)
   930 apply(rule f)
   932 apply(rule f)
   931 (* VAR *)
   933 (* VAR *)
   932 apply(simp add: a1 rfun_Var[OF f, OF c, symmetric])
   934 apply(simp add: a1 rfun_Var[OF f, OF c, symmetric])
   933 (* APP *)
   935 (* APP *)
  1037   and   f2::"('a::pt_name) f2_ty'"
  1039   and   f2::"('a::pt_name) f2_ty'"
  1038   and   f3::"('a::pt_name) f3_ty'"
  1040   and   f3::"('a::pt_name) f3_ty'"
  1039   assumes f: "finite ((supp (f1,f2,f3))::name set)" 
  1041   assumes f: "finite ((supp (f1,f2,f3))::name set)" 
  1040   and     c: "(\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name) t. a\<sharp>f3 t a y))"
  1042   and     c: "(\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name) t. a\<sharp>f3 t a y))"
  1041   shows "fst (rfun_gen' f1 f2 f3 t) = t"
  1043   shows "fst (rfun_gen' f1 f2 f3 t) = t"
  1042 apply(rule lam_induct'[of "\<lambda>_. (f1,f2,f3)" "\<lambda>t _. fst (rfun_gen' f1 f2 f3 t) = t"])
  1044 apply(rule lam_induct'[of "\<lambda>_. (f1,f2,f3)" "\<lambda>_ t. fst (rfun_gen' f1 f2 f3 t) = t"])
  1043 apply(simp add: f)
  1045 apply(simp add: f)
  1044 apply(unfold rfun_gen'_def)
  1046 apply(unfold rfun_gen'_def)
  1045 apply(simp only: rfun_Var[OF fsupp'[OF f],OF fcb'[OF f, OF c]])
  1047 apply(simp only: rfun_Var[OF fsupp'[OF f],OF fcb'[OF f, OF c]])
  1046 apply(simp)
  1048 apply(simp)
  1047 apply(simp only: rfun_App[OF fsupp'[OF f],OF fcb'[OF f, OF c]])
  1049 apply(simp only: rfun_App[OF fsupp'[OF f],OF fcb'[OF f, OF c]])
  1368   fixes pi:: "name prm"
  1370   fixes pi:: "name prm"
  1369   and   t1:: "lam"
  1371   and   t1:: "lam"
  1370   and   t2:: "lam"
  1372   and   t2:: "lam"
  1371   and   a :: "name"
  1373   and   a :: "name"
  1372   shows "pi\<bullet>(t1[a::=t2]) = (pi\<bullet>t1)[(pi\<bullet>a)::=(pi\<bullet>t2)]"
  1374   shows "pi\<bullet>(t1[a::=t2]) = (pi\<bullet>t1)[(pi\<bullet>a)::=(pi\<bullet>t2)]"
       
  1375 thm lam_induct
  1373 apply(nominal_induct t1 rule: lam_induct)
  1376 apply(nominal_induct t1 rule: lam_induct)
  1374 apply(auto)
  1377 apply(auto)
  1375 apply(auto simp add: perm_bij fresh_prod fresh_atm)
  1378 apply(auto simp add: perm_bij fresh_prod fresh_atm)
  1376 apply(subgoal_tac "(aa\<bullet>ab)\<sharp>(aa\<bullet>a,aa\<bullet>b)")(*A*)
  1379 apply(subgoal_tac "(aa\<bullet>ab)\<sharp>(aa\<bullet>a,aa\<bullet>b)")(*A*)
  1377 apply(simp) 
  1380 apply(simp)