Nominal-General/Nominal2_Base.thy
changeset 2470 bdb1eab47161
parent 2467 67b3933c3190
child 2475 486d4647bb37
equal deleted inserted replaced
2469:4a6e78bd9de9 2470:bdb1eab47161
   442 lemma ex_eqvt:
   442 lemma ex_eqvt:
   443   shows "p \<bullet> (\<exists>x. P x) = (\<exists>x. (p \<bullet> P) x)"
   443   shows "p \<bullet> (\<exists>x. P x) = (\<exists>x. (p \<bullet> P) x)"
   444   unfolding permute_fun_def permute_bool_def
   444   unfolding permute_fun_def permute_bool_def
   445   by (auto, rule_tac x="p \<bullet> x" in exI, simp)
   445   by (auto, rule_tac x="p \<bullet> x" in exI, simp)
   446 
   446 
       
   447 lemma all_eqvt:
       
   448   shows "p \<bullet> (\<forall>x. P x) = (\<forall>x. (p \<bullet> P) x)"
       
   449   unfolding permute_fun_def permute_bool_def
       
   450   by (auto, drule_tac x="p \<bullet> x" in spec, simp)
       
   451 
   447 lemma permute_boolE:
   452 lemma permute_boolE:
   448   fixes P::"bool"
   453   fixes P::"bool"
   449   shows "p \<bullet> P \<Longrightarrow> P"
   454   shows "p \<bullet> P \<Longrightarrow> P"
   450   by (simp add: permute_bool_def)
   455   by (simp add: permute_bool_def)
   451 
   456 
   485 lemma swap_set_in:
   490 lemma swap_set_in:
   486   assumes a: "a \<in> S" "b \<notin> S" "sort_of a = sort_of b"
   491   assumes a: "a \<in> S" "b \<notin> S" "sort_of a = sort_of b"
   487   shows "(a \<rightleftharpoons> b) \<bullet> S \<noteq> S"
   492   shows "(a \<rightleftharpoons> b) \<bullet> S \<noteq> S"
   488   unfolding permute_set_eq
   493   unfolding permute_set_eq
   489   using a by (auto simp add: swap_atom)
   494   using a by (auto simp add: swap_atom)
       
   495 
       
   496 lemma mem_permute_iff:
       
   497   shows "(p \<bullet> x) \<in> (p \<bullet> X) \<longleftrightarrow> x \<in> X"
       
   498   unfolding mem_def permute_fun_def permute_bool_def
       
   499   by simp
       
   500 
       
   501 lemma mem_eqvt:
       
   502   shows "p \<bullet> (x \<in> A) \<longleftrightarrow> (p \<bullet> x) \<in> (p \<bullet> A)"
       
   503   unfolding mem_def
       
   504   by (simp add: permute_fun_app_eq)
       
   505 
       
   506 lemma insert_eqvt:
       
   507   shows "p \<bullet> (insert x A) = insert (p \<bullet> x) (p \<bullet> A)"
       
   508   unfolding permute_set_eq_image image_insert ..
       
   509 
   490 
   510 
   491 subsection {* Permutations for units *}
   511 subsection {* Permutations for units *}
   492 
   512 
   493 instantiation unit :: pt
   513 instantiation unit :: pt
   494 begin
   514 begin
   994 
  1014 
   995 lemma fresh_Pair: 
  1015 lemma fresh_Pair: 
   996   shows "a \<sharp> (x, y) \<longleftrightarrow> a \<sharp> x \<and> a \<sharp> y"
  1016   shows "a \<sharp> (x, y) \<longleftrightarrow> a \<sharp> x \<and> a \<sharp> y"
   997   by (simp add: fresh_def supp_Pair)
  1017   by (simp add: fresh_def supp_Pair)
   998 
  1018 
       
  1019 lemma supp_Unit:
       
  1020   shows "supp () = {}"
       
  1021   by (simp add: supp_def)
       
  1022 
       
  1023 lemma fresh_Unit:
       
  1024   shows "a \<sharp> ()"
       
  1025   by (simp add: fresh_def supp_Unit)
       
  1026 
       
  1027 
       
  1028 
   999 instance prod :: (fs, fs) fs
  1029 instance prod :: (fs, fs) fs
  1000 apply default
  1030 apply default
  1001 apply (induct_tac x)
  1031 apply (induct_tac x)
  1002 apply (simp add: supp_Pair finite_supp)
  1032 apply (simp add: supp_Pair finite_supp)
  1003 done
  1033 done
  1073 apply (induct_tac x)
  1103 apply (induct_tac x)
  1074 apply (simp_all add: supp_Nil supp_Cons finite_supp)
  1104 apply (simp_all add: supp_Nil supp_Cons finite_supp)
  1075 done
  1105 done
  1076 
  1106 
  1077 
  1107 
  1078 section {* Support and freshness for applications *}
  1108 section {* Support and Freshness for Applications *}
  1079 
  1109 
  1080 lemma fresh_conv_MOST: 
  1110 lemma fresh_conv_MOST: 
  1081   shows "a \<sharp> x \<longleftrightarrow> (MOST b. (a \<rightleftharpoons> b) \<bullet> x = x)"
  1111   shows "a \<sharp> x \<longleftrightarrow> (MOST b. (a \<rightleftharpoons> b) \<bullet> x = x)"
  1082   unfolding fresh_def supp_def 
  1112   unfolding fresh_def supp_def 
  1083   unfolding MOST_iff_cofinite by simp
  1113   unfolding MOST_iff_cofinite by simp
  1101   shows "supp (f x) \<subseteq> (supp f) \<union> (supp x)"
  1131   shows "supp (f x) \<subseteq> (supp f) \<union> (supp x)"
  1102   using fresh_fun_app
  1132   using fresh_fun_app
  1103   unfolding fresh_def
  1133   unfolding fresh_def
  1104   by auto
  1134   by auto
  1105 
  1135 
  1106 text {* support of equivariant functions *}
  1136 text {* Support of Equivariant Functions *}
  1107 
  1137 
  1108 lemma supp_fun_eqvt:
  1138 lemma supp_fun_eqvt:
  1109   assumes a: "\<And>p. p \<bullet> f = f"
  1139   assumes a: "\<And>p. p \<bullet> f = f"
  1110   shows "supp f = {}"
  1140   shows "supp f = {}"
  1111   unfolding supp_def 
  1141   unfolding supp_def 
  1192   shows "supp (insert x S) = supp x \<union> supp S"
  1222   shows "supp (insert x S) = supp x \<union> supp S"
  1193   using fin
  1223   using fin
  1194   by (simp add: supp_of_fin_sets)
  1224   by (simp add: supp_of_fin_sets)
  1195 
  1225 
  1196 
  1226 
  1197 section {* Concrete atoms types *}
  1227 section {* Fresh-Star *}
       
  1228 
       
  1229 
       
  1230 text {* The fresh-star generalisation of fresh is used in strong
       
  1231   induction principles. *}
       
  1232 
       
  1233 definition 
       
  1234   fresh_star :: "atom set \<Rightarrow> 'a::pt \<Rightarrow> bool" ("_ \<sharp>* _" [80,80] 80)
       
  1235 where 
       
  1236   "as \<sharp>* x \<equiv> \<forall>a \<in> as. a \<sharp> x"
       
  1237 
       
  1238 lemma fresh_star_prod:
       
  1239   fixes as::"atom set"
       
  1240   shows "as \<sharp>* (x, y) = (as \<sharp>* x \<and> as \<sharp>* y)" 
       
  1241   by (auto simp add: fresh_star_def fresh_Pair)
       
  1242 
       
  1243 lemma fresh_star_union:
       
  1244   shows "(as \<union> bs) \<sharp>* x = (as \<sharp>* x \<and> bs \<sharp>* x)"
       
  1245   by (auto simp add: fresh_star_def)
       
  1246 
       
  1247 lemma fresh_star_insert:
       
  1248   shows "(insert a as) \<sharp>* x = (a \<sharp> x \<and> as \<sharp>* x)"
       
  1249   by (auto simp add: fresh_star_def)
       
  1250 
       
  1251 lemma fresh_star_Un_elim:
       
  1252   "((as \<union> bs) \<sharp>* x \<Longrightarrow> PROP C) \<equiv> (as \<sharp>* x \<Longrightarrow> bs \<sharp>* x \<Longrightarrow> PROP C)"
       
  1253   unfolding fresh_star_def
       
  1254   apply(rule)
       
  1255   apply(erule meta_mp)
       
  1256   apply(auto)
       
  1257   done
       
  1258 
       
  1259 lemma fresh_star_insert_elim:
       
  1260   "(insert a as \<sharp>* x \<Longrightarrow> PROP C) \<equiv> (a \<sharp> x \<Longrightarrow> as \<sharp>* x \<Longrightarrow> PROP C)"
       
  1261   unfolding fresh_star_def
       
  1262   by rule (simp_all add: fresh_star_def)
       
  1263 
       
  1264 lemma fresh_star_empty_elim:
       
  1265   "({} \<sharp>* x \<Longrightarrow> PROP C) \<equiv> PROP C"
       
  1266   by (simp add: fresh_star_def)
       
  1267 
       
  1268 lemma fresh_star_unit_elim: 
       
  1269   shows "(a \<sharp>* () \<Longrightarrow> PROP C) \<equiv> PROP C"
       
  1270   by (simp add: fresh_star_def fresh_Unit) 
       
  1271 
       
  1272 lemma fresh_star_prod_elim: 
       
  1273   shows "(a \<sharp>* (x, y) \<Longrightarrow> PROP C) \<equiv> (a \<sharp>* x \<Longrightarrow> a \<sharp>* y \<Longrightarrow> PROP C)"
       
  1274   by (rule, simp_all add: fresh_star_prod)
       
  1275 
       
  1276 lemma fresh_star_zero:
       
  1277   shows "as \<sharp>* (0::perm)"
       
  1278   unfolding fresh_star_def
       
  1279   by (simp add: fresh_zero_perm)
       
  1280 
       
  1281 lemma fresh_star_plus:
       
  1282   fixes p q::perm
       
  1283   shows "\<lbrakk>a \<sharp>* p;  a \<sharp>* q\<rbrakk> \<Longrightarrow> a \<sharp>* (p + q)"
       
  1284   unfolding fresh_star_def
       
  1285   by (simp add: fresh_plus_perm)
       
  1286 
       
  1287 lemma fresh_star_permute_iff:
       
  1288   shows "(p \<bullet> a) \<sharp>* (p \<bullet> x) \<longleftrightarrow> a \<sharp>* x"
       
  1289   unfolding fresh_star_def
       
  1290   by (metis mem_permute_iff permute_minus_cancel(1) fresh_permute_iff)
       
  1291 
       
  1292 lemma fresh_star_eqvt:
       
  1293   shows "(p \<bullet> (as \<sharp>* x)) = (p \<bullet> as) \<sharp>* (p \<bullet> x)"
       
  1294 unfolding fresh_star_def
       
  1295 unfolding Ball_def
       
  1296 apply(simp add: all_eqvt)
       
  1297 apply(subst permute_fun_def)
       
  1298 apply(simp add: imp_eqvt fresh_eqvt mem_eqvt)
       
  1299 done
       
  1300 
       
  1301 
       
  1302 section {* Induction principle for permutations *}
       
  1303 
       
  1304 
       
  1305 lemma perm_struct_induct[consumes 1, case_names zero swap]:
       
  1306   assumes S: "supp p \<subseteq> S"
       
  1307   and zero: "P 0"
       
  1308   and swap: "\<And>p a b. \<lbrakk>P p; supp p \<subseteq> S; a \<in> S; b \<in> S; a \<noteq> b; sort_of a = sort_of b\<rbrakk> \<Longrightarrow> P ((a \<rightleftharpoons> b) + p)"
       
  1309   shows "P p"
       
  1310 proof -
       
  1311   have "finite (supp p)" by (simp add: finite_supp)
       
  1312   then show "P p" using S
       
  1313   proof(induct A\<equiv>"supp p" arbitrary: p rule: finite_psubset_induct)
       
  1314     case (psubset p)
       
  1315     then have ih: "\<And>q. supp q \<subset> supp p \<Longrightarrow> P q" by auto
       
  1316     have as: "supp p \<subseteq> S" by fact
       
  1317     { assume "supp p = {}"
       
  1318       then have "p = 0" by (simp add: supp_perm expand_perm_eq)
       
  1319       then have "P p" using zero by simp
       
  1320     }
       
  1321     moreover
       
  1322     { assume "supp p \<noteq> {}"
       
  1323       then obtain a where a0: "a \<in> supp p" by blast
       
  1324       then have a1: "p \<bullet> a \<in> S" "a \<in> S" "sort_of (p \<bullet> a) = sort_of a" "p \<bullet> a \<noteq> a"
       
  1325         using as by (auto simp add: supp_atom supp_perm swap_atom)
       
  1326       let ?q = "(p \<bullet> a \<rightleftharpoons> a) + p"
       
  1327       have a2: "supp ?q \<subseteq> supp p" unfolding supp_perm by (auto simp add: swap_atom)
       
  1328       moreover
       
  1329       have "a \<notin> supp ?q" by (simp add: supp_perm)
       
  1330       then have "supp ?q \<noteq> supp p" using a0 by auto
       
  1331       ultimately have "supp ?q \<subset> supp p" using a2 by auto
       
  1332       then have "P ?q" using ih by simp
       
  1333       moreover
       
  1334       have "supp ?q \<subseteq> S" using as a2 by simp
       
  1335       ultimately  have "P ((p \<bullet> a \<rightleftharpoons> a) + ?q)" using as a1 swap by simp 
       
  1336       moreover 
       
  1337       have "p = (p \<bullet> a \<rightleftharpoons> a) + ?q" by (simp add: expand_perm_eq)
       
  1338       ultimately have "P p" by simp
       
  1339     }
       
  1340     ultimately show "P p" by blast
       
  1341   qed
       
  1342 qed
       
  1343 
       
  1344 lemma perm_simple_struct_induct[case_names zero swap]:
       
  1345   assumes zero: "P 0"
       
  1346   and     swap: "\<And>p a b. \<lbrakk>P p; a \<noteq> b; sort_of a = sort_of b\<rbrakk> \<Longrightarrow> P ((a \<rightleftharpoons> b) + p)"
       
  1347   shows "P p"
       
  1348 by (rule_tac S="supp p" in perm_struct_induct)
       
  1349    (auto intro: zero swap)
       
  1350 
       
  1351 lemma perm_subset_induct[consumes 1, case_names zero swap plus]:
       
  1352   assumes S: "supp p \<subseteq> S"
       
  1353   assumes zero: "P 0"
       
  1354   assumes swap: "\<And>a b. \<lbrakk>sort_of a = sort_of b; a \<noteq> b; a \<in> S; b \<in> S\<rbrakk> \<Longrightarrow> P (a \<rightleftharpoons> b)"
       
  1355   assumes plus: "\<And>p1 p2. \<lbrakk>P p1; P p2; supp p1 \<subseteq> S; supp p2 \<subseteq> S\<rbrakk> \<Longrightarrow> P (p1 + p2)"
       
  1356   shows "P p"
       
  1357 using S
       
  1358 by (induct p rule: perm_struct_induct)
       
  1359    (auto intro: zero plus swap simp add: supp_swap)
       
  1360 
       
  1361 lemma supp_perm_eq:
       
  1362   assumes "(supp x) \<sharp>* p"
       
  1363   shows "p \<bullet> x = x"
       
  1364 proof -
       
  1365   from assms have "supp p \<subseteq> {a. a \<sharp> x}"
       
  1366     unfolding supp_perm fresh_star_def fresh_def by auto
       
  1367   then show "p \<bullet> x = x"
       
  1368   proof (induct p rule: perm_struct_induct)
       
  1369     case zero
       
  1370     show "0 \<bullet> x = x" by simp
       
  1371   next
       
  1372     case (swap p a b)
       
  1373     then have "a \<sharp> x" "b \<sharp> x" "p \<bullet> x = x" by simp_all
       
  1374     then show "((a \<rightleftharpoons> b) + p) \<bullet> x = x" by (simp add: swap_fresh_fresh)
       
  1375   qed
       
  1376 qed
       
  1377 
       
  1378 lemma supp_perm_eq_test:
       
  1379   assumes "(supp x) \<sharp>* p"
       
  1380   shows "p \<bullet> x = x"
       
  1381 proof -
       
  1382   from assms have "supp p \<subseteq> {a. a \<sharp> x}"
       
  1383     unfolding supp_perm fresh_star_def fresh_def by auto
       
  1384   then show "p \<bullet> x = x"
       
  1385   proof (induct p rule: perm_subset_induct)
       
  1386     case zero
       
  1387     show "0 \<bullet> x = x" by simp
       
  1388   next
       
  1389     case (swap a b)
       
  1390     then have "a \<sharp> x" "b \<sharp> x" by simp_all
       
  1391     then show "(a \<rightleftharpoons> b) \<bullet> x = x" by (simp add: swap_fresh_fresh)
       
  1392   next
       
  1393     case (plus p1 p2)
       
  1394     have "p1 \<bullet> x = x" "p2 \<bullet> x = x" by fact+
       
  1395     then show "(p1 + p2) \<bullet> x = x" by simp
       
  1396   qed
       
  1397 qed
       
  1398 
       
  1399 
       
  1400 section {* Avoiding of atom sets *}
       
  1401 
       
  1402 text {* 
       
  1403   For every set of atoms, there is another set of atoms
       
  1404   avoiding a finitely supported c and there is a permutation
       
  1405   which 'translates' between both sets.
       
  1406 *}
       
  1407 
       
  1408 lemma at_set_avoiding_aux:
       
  1409   fixes Xs::"atom set"
       
  1410   and   As::"atom set"
       
  1411   assumes b: "Xs \<subseteq> As"
       
  1412   and     c: "finite As"
       
  1413   shows "\<exists>p. (p \<bullet> Xs) \<inter> As = {} \<and> (supp p) \<subseteq> (Xs \<union> (p \<bullet> Xs))"
       
  1414 proof -
       
  1415   from b c have "finite Xs" by (rule finite_subset)
       
  1416   then show ?thesis using b
       
  1417   proof (induct rule: finite_subset_induct)
       
  1418     case empty
       
  1419     have "0 \<bullet> {} \<inter> As = {}" by simp
       
  1420     moreover
       
  1421     have "supp (0::perm) \<subseteq> {} \<union> 0 \<bullet> {}" by (simp add: supp_zero_perm)
       
  1422     ultimately show ?case by blast
       
  1423   next
       
  1424     case (insert x Xs)
       
  1425     then obtain p where
       
  1426       p1: "(p \<bullet> Xs) \<inter> As = {}" and 
       
  1427       p2: "supp p \<subseteq> (Xs \<union> (p \<bullet> Xs))" by blast
       
  1428     from `x \<in> As` p1 have "x \<notin> p \<bullet> Xs" by fast
       
  1429     with `x \<notin> Xs` p2 have "x \<notin> supp p" by fast
       
  1430     hence px: "p \<bullet> x = x" unfolding supp_perm by simp
       
  1431     have "finite (As \<union> p \<bullet> Xs)"
       
  1432       using `finite As` `finite Xs`
       
  1433       by (simp add: permute_set_eq_image)
       
  1434     then obtain y where "y \<notin> (As \<union> p \<bullet> Xs)" "sort_of y = sort_of x"
       
  1435       by (rule obtain_atom)
       
  1436     hence y: "y \<notin> As" "y \<notin> p \<bullet> Xs" "sort_of y = sort_of x"
       
  1437       by simp_all
       
  1438     let ?q = "(x \<rightleftharpoons> y) + p"
       
  1439     have q: "?q \<bullet> insert x Xs = insert y (p \<bullet> Xs)"
       
  1440       unfolding insert_eqvt
       
  1441       using `p \<bullet> x = x` `sort_of y = sort_of x`
       
  1442       using `x \<notin> p \<bullet> Xs` `y \<notin> p \<bullet> Xs`
       
  1443       by (simp add: swap_atom swap_set_not_in)
       
  1444     have "?q \<bullet> insert x Xs \<inter> As = {}"
       
  1445       using `y \<notin> As` `p \<bullet> Xs \<inter> As = {}`
       
  1446       unfolding q by simp
       
  1447     moreover
       
  1448     have "supp ?q \<subseteq> insert x Xs \<union> ?q \<bullet> insert x Xs"
       
  1449       using p2 unfolding q
       
  1450       by (intro subset_trans [OF supp_plus_perm])
       
  1451          (auto simp add: supp_swap)
       
  1452     ultimately show ?case by blast
       
  1453   qed
       
  1454 qed
       
  1455 
       
  1456 lemma at_set_avoiding:
       
  1457   assumes a: "finite Xs"
       
  1458   and     b: "finite (supp c)"
       
  1459   obtains p::"perm" where "(p \<bullet> Xs)\<sharp>*c" and "(supp p) \<subseteq> (Xs \<union> (p \<bullet> Xs))"
       
  1460   using a b at_set_avoiding_aux [where Xs="Xs" and As="Xs \<union> supp c"]
       
  1461   unfolding fresh_star_def fresh_def by blast
       
  1462 
       
  1463 lemma at_set_avoiding2:
       
  1464   assumes "finite xs"
       
  1465   and     "finite (supp c)" "finite (supp x)"
       
  1466   and     "xs \<sharp>* x"
       
  1467   shows "\<exists>p. (p \<bullet> xs) \<sharp>* c \<and> supp x \<sharp>* p"
       
  1468 using assms
       
  1469 apply(erule_tac c="(c, x)" in at_set_avoiding)
       
  1470 apply(simp add: supp_Pair)
       
  1471 apply(rule_tac x="p" in exI)
       
  1472 apply(simp add: fresh_star_prod)
       
  1473 apply(subgoal_tac "\<forall>a \<in> supp p. a \<sharp> x")
       
  1474 apply(auto simp add: fresh_star_def fresh_def supp_perm)[1]
       
  1475 apply(auto simp add: fresh_star_def fresh_def)
       
  1476 done
       
  1477 
       
  1478 lemma at_set_avoiding2_atom:
       
  1479   assumes "finite (supp c)" "finite (supp x)"
       
  1480   and     b: "a \<sharp> x"
       
  1481   shows "\<exists>p. (p \<bullet> a) \<sharp> c \<and> supp x \<sharp>* p"
       
  1482 proof -
       
  1483   have a: "{a} \<sharp>* x" unfolding fresh_star_def by (simp add: b)
       
  1484   obtain p where p1: "(p \<bullet> {a}) \<sharp>* c" and p2: "supp x \<sharp>* p"
       
  1485     using at_set_avoiding2[of "{a}" "c" "x"] assms a by blast
       
  1486   have c: "(p \<bullet> a) \<sharp> c" using p1
       
  1487     unfolding fresh_star_def Ball_def 
       
  1488     by(erule_tac x="p \<bullet> a" in allE) (simp add: permute_set_eq)
       
  1489   hence "p \<bullet> a \<sharp> c \<and> supp x \<sharp>* p" using p2 by blast
       
  1490   then show "\<exists>p. (p \<bullet> a) \<sharp> c \<and> supp x \<sharp>* p" by blast
       
  1491 qed
       
  1492 
       
  1493 
       
  1494 section {* Concrete Atoms Types *}
  1198 
  1495 
  1199 text {*
  1496 text {*
  1200   Class @{text at_base} allows types containing multiple sorts of atoms.
  1497   Class @{text at_base} allows types containing multiple sorts of atoms.
  1201   Class @{text at} only allows types with a single sort.
  1498   Class @{text at} only allows types with a single sort.
  1202 *}
  1499 *}
  1268 apply(simp add: supp_at_base)
  1565 apply(simp add: supp_at_base)
  1269 apply(auto)
  1566 apply(auto)
  1270 done
  1567 done
  1271 
  1568 
  1272 section {* Infrastructure for concrete atom types *}
  1569 section {* Infrastructure for concrete atom types *}
  1273 
       
  1274 
  1570 
  1275 section {* A swapping operation for concrete atoms *}
  1571 section {* A swapping operation for concrete atoms *}
  1276   
  1572   
  1277 definition
  1573 definition
  1278   flip :: "'a::at_base \<Rightarrow> 'a \<Rightarrow> perm" ("'(_ \<leftrightarrow> _')")
  1574   flip :: "'a::at_base \<Rightarrow> 'a \<Rightarrow> perm" ("'(_ \<leftrightarrow> _')")
  1437   (@{const_name "permute"}, SOME @{typ "perm \<Rightarrow> 'a::pt \<Rightarrow> 'a"}) *}
  1733   (@{const_name "permute"}, SOME @{typ "perm \<Rightarrow> 'a::pt \<Rightarrow> 'a"}) *}
  1438 setup {* Sign.add_const_constraint
  1734 setup {* Sign.add_const_constraint
  1439   (@{const_name "atom"}, SOME @{typ "'a::at_base \<Rightarrow> atom"}) *}
  1735   (@{const_name "atom"}, SOME @{typ "'a::at_base \<Rightarrow> atom"}) *}
  1440 
  1736 
  1441 
  1737 
       
  1738 
       
  1739 section {* The freshness lemma according to Andy Pitts *}
       
  1740 
       
  1741 lemma freshness_lemma:
       
  1742   fixes h :: "'a::at \<Rightarrow> 'b::pt"
       
  1743   assumes a: "\<exists>a. atom a \<sharp> (h, h a)"
       
  1744   shows  "\<exists>x. \<forall>a. atom a \<sharp> h \<longrightarrow> h a = x"
       
  1745 proof -
       
  1746   from a obtain b where a1: "atom b \<sharp> h" and a2: "atom b \<sharp> h b"
       
  1747     by (auto simp add: fresh_Pair)
       
  1748   show "\<exists>x. \<forall>a. atom a \<sharp> h \<longrightarrow> h a = x"
       
  1749   proof (intro exI allI impI)
       
  1750     fix a :: 'a
       
  1751     assume a3: "atom a \<sharp> h"
       
  1752     show "h a = h b"
       
  1753     proof (cases "a = b")
       
  1754       assume "a = b"
       
  1755       thus "h a = h b" by simp
       
  1756     next
       
  1757       assume "a \<noteq> b"
       
  1758       hence "atom a \<sharp> b" by (simp add: fresh_at_base)
       
  1759       with a3 have "atom a \<sharp> h b" 
       
  1760         by (rule fresh_fun_app)
       
  1761       with a2 have d1: "(atom b \<rightleftharpoons> atom a) \<bullet> (h b) = (h b)"
       
  1762         by (rule swap_fresh_fresh)
       
  1763       from a1 a3 have d2: "(atom b \<rightleftharpoons> atom a) \<bullet> h = h"
       
  1764         by (rule swap_fresh_fresh)
       
  1765       from d1 have "h b = (atom b \<rightleftharpoons> atom a) \<bullet> (h b)" by simp
       
  1766       also have "\<dots> = ((atom b \<rightleftharpoons> atom a) \<bullet> h) ((atom b \<rightleftharpoons> atom a) \<bullet> b)"
       
  1767         by (rule permute_fun_app_eq)
       
  1768       also have "\<dots> = h a"
       
  1769         using d2 by simp
       
  1770       finally show "h a = h b"  by simp
       
  1771     qed
       
  1772   qed
       
  1773 qed
       
  1774 
       
  1775 lemma freshness_lemma_unique:
       
  1776   fixes h :: "'a::at \<Rightarrow> 'b::pt"
       
  1777   assumes a: "\<exists>a. atom a \<sharp> (h, h a)"
       
  1778   shows "\<exists>!x. \<forall>a. atom a \<sharp> h \<longrightarrow> h a = x"
       
  1779 proof (rule ex_ex1I)
       
  1780   from a show "\<exists>x. \<forall>a. atom a \<sharp> h \<longrightarrow> h a = x"
       
  1781     by (rule freshness_lemma)
       
  1782 next
       
  1783   fix x y
       
  1784   assume x: "\<forall>a. atom a \<sharp> h \<longrightarrow> h a = x"
       
  1785   assume y: "\<forall>a. atom a \<sharp> h \<longrightarrow> h a = y"
       
  1786   from a x y show "x = y"
       
  1787     by (auto simp add: fresh_Pair)
       
  1788 qed
       
  1789 
       
  1790 text {* packaging the freshness lemma into a function *}
       
  1791 
       
  1792 definition
       
  1793   fresh_fun :: "('a::at \<Rightarrow> 'b::pt) \<Rightarrow> 'b"
       
  1794 where
       
  1795   "fresh_fun h = (THE x. \<forall>a. atom a \<sharp> h \<longrightarrow> h a = x)"
       
  1796 
       
  1797 lemma fresh_fun_apply:
       
  1798   fixes h :: "'a::at \<Rightarrow> 'b::pt"
       
  1799   assumes a: "\<exists>a. atom a \<sharp> (h, h a)"
       
  1800   assumes b: "atom a \<sharp> h"
       
  1801   shows "fresh_fun h = h a"
       
  1802 unfolding fresh_fun_def
       
  1803 proof (rule the_equality)
       
  1804   show "\<forall>a'. atom a' \<sharp> h \<longrightarrow> h a' = h a"
       
  1805   proof (intro strip)
       
  1806     fix a':: 'a
       
  1807     assume c: "atom a' \<sharp> h"
       
  1808     from a have "\<exists>x. \<forall>a. atom a \<sharp> h \<longrightarrow> h a = x" by (rule freshness_lemma)
       
  1809     with b c show "h a' = h a" by auto
       
  1810   qed
       
  1811 next
       
  1812   fix fr :: 'b
       
  1813   assume "\<forall>a. atom a \<sharp> h \<longrightarrow> h a = fr"
       
  1814   with b show "fr = h a" by auto
       
  1815 qed
       
  1816 
       
  1817 lemma fresh_fun_apply':
       
  1818   fixes h :: "'a::at \<Rightarrow> 'b::pt"
       
  1819   assumes a: "atom a \<sharp> h" "atom a \<sharp> h a"
       
  1820   shows "fresh_fun h = h a"
       
  1821   apply (rule fresh_fun_apply)
       
  1822   apply (auto simp add: fresh_Pair intro: a)
       
  1823   done
       
  1824 
       
  1825 lemma fresh_fun_eqvt:
       
  1826   fixes h :: "'a::at \<Rightarrow> 'b::pt"
       
  1827   assumes a: "\<exists>a. atom a \<sharp> (h, h a)"
       
  1828   shows "p \<bullet> (fresh_fun h) = fresh_fun (p \<bullet> h)"
       
  1829   using a
       
  1830   apply (clarsimp simp add: fresh_Pair)
       
  1831   apply (subst fresh_fun_apply', assumption+)
       
  1832   apply (drule fresh_permute_iff [where p=p, THEN iffD2])
       
  1833   apply (drule fresh_permute_iff [where p=p, THEN iffD2])
       
  1834   apply (simp add: atom_eqvt permute_fun_app_eq [where f=h])
       
  1835   apply (erule (1) fresh_fun_apply' [symmetric])
       
  1836   done
       
  1837 
       
  1838 lemma fresh_fun_supports:
       
  1839   fixes h :: "'a::at \<Rightarrow> 'b::pt"
       
  1840   assumes a: "\<exists>a. atom a \<sharp> (h, h a)"
       
  1841   shows "(supp h) supports (fresh_fun h)"
       
  1842   apply (simp add: supports_def fresh_def [symmetric])
       
  1843   apply (simp add: fresh_fun_eqvt [OF a] swap_fresh_fresh)
       
  1844   done
       
  1845 
       
  1846 notation fresh_fun (binder "FRESH " 10)
       
  1847 
       
  1848 lemma FRESH_f_iff:
       
  1849   fixes P :: "'a::at \<Rightarrow> 'b::pure"
       
  1850   fixes f :: "'b \<Rightarrow> 'c::pure"
       
  1851   assumes P: "finite (supp P)"
       
  1852   shows "(FRESH x. f (P x)) = f (FRESH x. P x)"
       
  1853 proof -
       
  1854   obtain a::'a where "atom a \<notin> supp P"
       
  1855     using P by (rule obtain_at_base)
       
  1856   hence "atom a \<sharp> P"
       
  1857     by (simp add: fresh_def)
       
  1858   show "(FRESH x. f (P x)) = f (FRESH x. P x)"
       
  1859     apply (subst fresh_fun_apply' [where a=a, OF _ pure_fresh])
       
  1860     apply (cut_tac `atom a \<sharp> P`)
       
  1861     apply (simp add: fresh_conv_MOST)
       
  1862     apply (elim MOST_rev_mp, rule MOST_I, clarify)
       
  1863     apply (simp add: permute_fun_def permute_pure expand_fun_eq)
       
  1864     apply (subst fresh_fun_apply' [where a=a, OF `atom a \<sharp> P` pure_fresh])
       
  1865     apply (rule refl)
       
  1866     done
       
  1867 qed
       
  1868 
       
  1869 lemma FRESH_binop_iff:
       
  1870   fixes P :: "'a::at \<Rightarrow> 'b::pure"
       
  1871   fixes Q :: "'a::at \<Rightarrow> 'c::pure"
       
  1872   fixes binop :: "'b \<Rightarrow> 'c \<Rightarrow> 'd::pure"
       
  1873   assumes P: "finite (supp P)" 
       
  1874   and     Q: "finite (supp Q)"
       
  1875   shows "(FRESH x. binop (P x) (Q x)) = binop (FRESH x. P x) (FRESH x. Q x)"
       
  1876 proof -
       
  1877   from assms have "finite (supp P \<union> supp Q)" by simp
       
  1878   then obtain a::'a where "atom a \<notin> (supp P \<union> supp Q)"
       
  1879     by (rule obtain_at_base)
       
  1880   hence "atom a \<sharp> P" and "atom a \<sharp> Q"
       
  1881     by (simp_all add: fresh_def)
       
  1882   show ?thesis
       
  1883     apply (subst fresh_fun_apply' [where a=a, OF _ pure_fresh])
       
  1884     apply (cut_tac `atom a \<sharp> P` `atom a \<sharp> Q`)
       
  1885     apply (simp add: fresh_conv_MOST)
       
  1886     apply (elim MOST_rev_mp, rule MOST_I, clarify)
       
  1887     apply (simp add: permute_fun_def permute_pure expand_fun_eq)
       
  1888     apply (subst fresh_fun_apply' [where a=a, OF `atom a \<sharp> P` pure_fresh])
       
  1889     apply (subst fresh_fun_apply' [where a=a, OF `atom a \<sharp> Q` pure_fresh])
       
  1890     apply (rule refl)
       
  1891     done
       
  1892 qed
       
  1893 
       
  1894 lemma FRESH_conj_iff:
       
  1895   fixes P Q :: "'a::at \<Rightarrow> bool"
       
  1896   assumes P: "finite (supp P)" and Q: "finite (supp Q)"
       
  1897   shows "(FRESH x. P x \<and> Q x) \<longleftrightarrow> (FRESH x. P x) \<and> (FRESH x. Q x)"
       
  1898 using P Q by (rule FRESH_binop_iff)
       
  1899 
       
  1900 lemma FRESH_disj_iff:
       
  1901   fixes P Q :: "'a::at \<Rightarrow> bool"
       
  1902   assumes P: "finite (supp P)" and Q: "finite (supp Q)"
       
  1903   shows "(FRESH x. P x \<or> Q x) \<longleftrightarrow> (FRESH x. P x) \<or> (FRESH x. Q x)"
       
  1904 using P Q by (rule FRESH_binop_iff)
       
  1905 
       
  1906 
  1442 section {* Library functions for the nominal infrastructure *}
  1907 section {* Library functions for the nominal infrastructure *}
  1443 
  1908 
  1444 use "nominal_library.ML"
  1909 use "nominal_library.ML"
  1445 
  1910 
  1446 
  1911