src/HOL/Library/Complete_Partial_Order2.thy
changeset 81982 bd2779a1da2c
parent 81806 602639414559
equal deleted inserted replaced
81976:d6906956ba34 81982:bd2779a1da2c
   286 
   286 
   287 context fixes ordb :: "'b \<Rightarrow> 'b \<Rightarrow> bool" (infix \<open>\<sqsubseteq>\<close> 60) begin
   287 context fixes ordb :: "'b \<Rightarrow> 'b \<Rightarrow> bool" (infix \<open>\<sqsubseteq>\<close> 60) begin
   288 
   288 
   289 lemma iterates_mono:
   289 lemma iterates_mono:
   290   assumes f: "f \<in> ccpo.iterates (fun_lub Sup) (fun_ord (\<le>)) F"
   290   assumes f: "f \<in> ccpo.iterates (fun_lub Sup) (fun_ord (\<le>)) F"
   291   and mono: "\<And>f. monotone (\<sqsubseteq>) (\<le>) f \<Longrightarrow> monotone (\<sqsubseteq>) (\<le>) (F f)"
   291     and mono: "\<And>f. monotone (\<sqsubseteq>) (\<le>) f \<Longrightarrow> monotone (\<sqsubseteq>) (\<le>) (F f)"
   292   shows "monotone (\<sqsubseteq>) (\<le>) f"
   292   shows "monotone (\<sqsubseteq>) (\<le>) f"
   293 using f
   293   using f
   294 by(induction rule: ccpo.iterates.induct[OF ccpo_fun, consumes 1, case_names step Sup])(blast intro: mono mono_lub)+
   294   by(induction rule: ccpo.iterates.induct[OF ccpo_fun, consumes 1])(blast intro: mono mono_lub)+
   295 
   295 
   296 lemma fixp_preserves_mono:
   296 lemma fixp_preserves_mono:
   297   assumes mono: "\<And>x. monotone (fun_ord (\<le>)) (\<le>) (\<lambda>f. F f x)"
   297   assumes mono: "\<And>x. monotone (fun_ord (\<le>)) (\<le>) (\<lambda>f. F f x)"
   298   and mono2: "\<And>f. monotone (\<sqsubseteq>) (\<le>) f \<Longrightarrow> monotone (\<sqsubseteq>) (\<le>) (F f)"
   298   and mono2: "\<And>f. monotone (\<sqsubseteq>) (\<le>) f \<Longrightarrow> monotone (\<sqsubseteq>) (\<le>) (F f)"
   299   shows "monotone (\<sqsubseteq>) (\<le>) (ccpo.fixp (fun_lub Sup) (fun_ord (\<le>)) F)"
   299   shows "monotone (\<sqsubseteq>) (\<le>) (ccpo.fixp (fun_lub Sup) (fun_ord (\<le>)) F)"
   302   have mono: "monotone (fun_ord (\<le>)) (fun_ord (\<le>)) F"
   302   have mono: "monotone (fun_ord (\<le>)) (fun_ord (\<le>)) F"
   303     by(rule monotoneI)(auto simp add: fun_ord_def intro: monotoneD[OF mono])
   303     by(rule monotoneI)(auto simp add: fun_ord_def intro: monotoneD[OF mono])
   304   let ?iter = "ccpo.iterates (fun_lub Sup) (fun_ord (\<le>)) F"
   304   let ?iter = "ccpo.iterates (fun_lub Sup) (fun_ord (\<le>)) F"
   305   have chain: "\<And>x. Complete_Partial_Order.chain (\<le>) ((\<lambda>f. f x) ` ?iter)"
   305   have chain: "\<And>x. Complete_Partial_Order.chain (\<le>) ((\<lambda>f. f x) ` ?iter)"
   306     by(rule chain_imageI[OF ccpo.chain_iterates[OF ccpo_fun mono]])(simp add: fun_ord_def)
   306     by(rule chain_imageI[OF ccpo.chain_iterates[OF ccpo_fun mono]])(simp add: fun_ord_def)
   307 
       
   308   fix x y
   307   fix x y
   309   assume "x \<sqsubseteq> y"
   308   assume "x \<sqsubseteq> y"
   310   show "?fixp x \<le> ?fixp y"
   309   have "(\<Squnion>f\<in>?iter. f x) \<le> (\<Squnion>f\<in>?iter. f y)"
   311     apply (simp only: ccpo.fixp_def[OF ccpo_fun] fun_lub_apply)
       
   312     using chain
   310     using chain
   313   proof(rule ccpo_Sup_least)
   311   proof(rule ccpo_Sup_least)
   314     fix x'
   312     fix x'
   315     assume "x' \<in> (\<lambda>f. f x) ` ?iter"
   313     assume "x' \<in> (\<lambda>f. f x) ` ?iter"
   316     then obtain f where "f \<in> ?iter" "x' = f x" by blast note this(2)
   314     then obtain f where f: "f \<in> ?iter" "x' = f x" by blast 
   317     also have "f x \<le> f y"
   315     then have "f x \<le> f y"
   318       by(rule monotoneD[OF iterates_mono[OF \<open>f \<in> ?iter\<close> mono2]])(blast intro: \<open>x \<sqsubseteq> y\<close>)+
   316       by (metis \<open>x \<sqsubseteq> y\<close> iterates_mono mono2 monotoneD)
   319     also have "f y \<le> \<Squnion>((\<lambda>f. f y) ` ?iter)" using chain
   317     also have "f y \<le> \<Squnion>((\<lambda>f. f y) ` ?iter)"
   320       by(rule ccpo_Sup_upper)(simp add: \<open>f \<in> ?iter\<close>)
   318       using chain f local.ccpo_Sup_upper by auto
   321     finally show "x' \<le> \<dots>" .
   319     finally show "x' \<le> \<dots>"
       
   320       using f(2) by blast 
   322   qed
   321   qed
       
   322   then show "?fixp x \<le> ?fixp y"
       
   323     unfolding ccpo.fixp_def[OF ccpo_fun] fun_lub_apply .
   323 qed
   324 qed
   324 
   325 
   325 end
   326 end
   326 
   327 
   327 end
   328 end
   329 lemma monotone2monotone:
   330 lemma monotone2monotone:
   330   assumes 2: "\<And>x. monotone ordb ordc (\<lambda>y. f x y)"
   331   assumes 2: "\<And>x. monotone ordb ordc (\<lambda>y. f x y)"
   331   and t: "monotone orda ordb (\<lambda>x. t x)"
   332   and t: "monotone orda ordb (\<lambda>x. t x)"
   332   and 1: "\<And>y. monotone orda ordc (\<lambda>x. f x y)"
   333   and 1: "\<And>y. monotone orda ordc (\<lambda>x. f x y)"
   333   and trans: "transp ordc"
   334   and trans: "transp ordc"
   334   shows "monotone orda ordc (\<lambda>x. f x (t x))"
   335 shows "monotone orda ordc (\<lambda>x. f x (t x))"
   335 by(blast intro: monotoneI transpD[OF trans] monotoneD[OF t] monotoneD[OF 2] monotoneD[OF 1])
   336   using assms unfolding monotone_on_def by (metis UNIV_I transpE)
   336 
   337 
   337 subsection \<open>Continuity\<close>
   338 subsection \<open>Continuity\<close>
   338 
   339 
   339 definition cont :: "('a set \<Rightarrow> 'a) \<Rightarrow> ('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> ('b set \<Rightarrow> 'b) \<Rightarrow> ('b \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> bool"
   340 definition cont :: "('a set \<Rightarrow> 'a) \<Rightarrow> ('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> ('b set \<Rightarrow> 'b) \<Rightarrow> ('b \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> bool"
   340 where
   341 where
   464 
   465 
   465 lemma cont_id [simp, cont_intro]: "\<And>Sup. cont Sup ord Sup ord id"
   466 lemma cont_id [simp, cont_intro]: "\<And>Sup. cont Sup ord Sup ord id"
   466   by(rule contI) simp
   467   by(rule contI) simp
   467 
   468 
   468 lemma cont_id' [simp, cont_intro]: "\<And>Sup. cont Sup ord Sup ord (\<lambda>x. x)"
   469 lemma cont_id' [simp, cont_intro]: "\<And>Sup. cont Sup ord Sup ord (\<lambda>x. x)"
   469   using cont_id[unfolded id_def] .
   470   by (simp add: Inf.INF_identity_eq contI)
   470 
   471 
   471 lemma cont_applyI [cont_intro]:
   472 lemma cont_applyI [cont_intro]:
   472   assumes cont: "cont luba orda lubb ordb g"
   473   assumes cont: "cont luba orda lubb ordb g"
   473   shows "cont (fun_lub luba) (fun_ord orda) lubb ordb (\<lambda>f. g (f x))"
   474   shows "cont (fun_lub luba) (fun_ord orda) lubb ordb (\<lambda>f. g (f x))"
   474   by(rule contI)(drule chain_fun_ordD[where x=x], simp add: fun_lub_apply image_image contD[OF cont])
   475   using assms by (simp add: cont_def chain_fun_ordD fun_lub_apply image_image)
   475 
   476 
   476 lemma call_cont: "cont (fun_lub lub) (fun_ord ord) lub ord (\<lambda>f. f t)"
   477 lemma call_cont: "cont (fun_lub lub) (fun_ord ord) lub ord (\<lambda>f. f t)"
   477   by(simp add: cont_def fun_lub_apply)
   478   by(simp add: cont_def fun_lub_apply)
   478 
   479 
   479 lemma cont_if [cont_intro]:
   480 lemma cont_if [cont_intro]:
   606   let ?iter = "ccpo.iterates (fun_lub Sup) (fun_ord (\<le>)) F"
   607   let ?iter = "ccpo.iterates (fun_lub Sup) (fun_ord (\<le>)) F"
   607   have chain: "\<And>x. Complete_Partial_Order.chain (\<le>) ((\<lambda>f. f x) ` ?iter)"
   608   have chain: "\<And>x. Complete_Partial_Order.chain (\<le>) ((\<lambda>f. f x) ` ?iter)"
   608     by(rule chain_imageI[OF ccpo.chain_iterates[OF ccpo_fun mono]])(simp add: fun_ord_def)
   609     by(rule chain_imageI[OF ccpo.chain_iterates[OF ccpo_fun mono]])(simp add: fun_ord_def)
   609 
   610 
   610   show "?fixp x \<le> ?fixp y" if "x \<sqsubseteq> y" for x y
   611   show "?fixp x \<le> ?fixp y" if "x \<sqsubseteq> y" for x y
   611     apply (simp only: ccpo.fixp_def[OF ccpo_fun] fun_lub_apply)
   612   proof -
   612     using chain
   613     have "(\<Squnion>f\<in>?iter. f x)
   613   proof(rule ccpo_Sup_least)
   614     \<le> (\<Squnion>f\<in>?iter. f y)"
   614     fix x'
   615       using chain
   615     assume "x' \<in> (\<lambda>f. f x) ` ?iter"
   616     proof(rule ccpo_Sup_least)
   616     then obtain f where "f \<in> ?iter" "x' = f x" by blast note this(2)
   617       fix x'
   617     also from _ \<open>x \<sqsubseteq> y\<close> have "f x \<le> f y"
   618       assume "x' \<in> (\<lambda>f. f x) ` ?iter"
   618       by(rule mcont_monoD[OF iterates_mcont[OF \<open>f \<in> ?iter\<close> mcont]])
   619       then obtain f where f: "f \<in> ?iter" "x' = f x" by blast 
   619     also have "f y \<le> \<Squnion>((\<lambda>f. f y) ` ?iter)" using chain
   620       then have "f x \<le> f y"
   620       by(rule ccpo_Sup_upper)(simp add: \<open>f \<in> ?iter\<close>)
   621         by (metis iterates_mcont mcont mcont_monoD that)
   621     finally show "x' \<le> \<dots>" .
   622       also have "f y \<le> \<Squnion>((\<lambda>f. f y) ` ?iter)"
       
   623         using chain f local.ccpo_Sup_upper by auto
       
   624       finally show "x' \<le> \<dots>"
       
   625         using f(2) by blast 
       
   626     qed
       
   627     then show ?thesis
       
   628       by (simp add: ccpo.fixp_def[OF ccpo_fun] fun_lub_apply)
   622   qed
   629   qed
   623 
       
   624   show "?fixp (\<Or>Y) = \<Squnion>(?fixp ` Y)"
   630   show "?fixp (\<Or>Y) = \<Squnion>(?fixp ` Y)"
   625     if chain: "Complete_Partial_Order.chain (\<sqsubseteq>) Y" and Y: "Y \<noteq> {}" for Y
   631     if chain: "Complete_Partial_Order.chain (\<sqsubseteq>) Y" and Y: "Y \<noteq> {}" for Y
   626   proof -
   632   proof -
   627     have "f (\<Or>Y) = \<Squnion>(f ` Y)" if "f \<in> ?iter" for f
   633     have "f (\<Or>Y) = \<Squnion>(f ` Y)" if "f \<in> ?iter" for f
   628       using that mcont chain Y
   634       using that mcont chain Y
   796 subsection \<open>Admissibility\<close>
   802 subsection \<open>Admissibility\<close>
   797 
   803 
   798 lemma admissible_subst:
   804 lemma admissible_subst:
   799   assumes adm: "ccpo.admissible luba orda (\<lambda>x. P x)"
   805   assumes adm: "ccpo.admissible luba orda (\<lambda>x. P x)"
   800   and mcont: "mcont lubb ordb luba orda f"
   806   and mcont: "mcont lubb ordb luba orda f"
   801   shows "ccpo.admissible lubb ordb (\<lambda>x. P (f x))"
   807 shows "ccpo.admissible lubb ordb (\<lambda>x. P (f x))"
   802 apply(rule ccpo.admissibleI)
   808   using assms by (simp add: ccpo.admissible_def chain_imageI mcont_contD mcont_monoD)
   803 apply(frule (1) mcont_contD[OF mcont])
       
   804 apply(auto intro: ccpo.admissibleD[OF adm] chain_imageI dest: mcont_monoD[OF mcont])
       
   805 done
       
   806 
   809 
   807 lemmas [simp, cont_intro] = 
   810 lemmas [simp, cont_intro] = 
   808   admissible_all
   811   admissible_all
   809   admissible_ball
   812   admissible_ball
   810   admissible_const
   813   admissible_const
   833 
   836 
   834 lemma admissible_eqI:
   837 lemma admissible_eqI:
   835   assumes f: "cont luba orda lub ord (\<lambda>x. f x)"
   838   assumes f: "cont luba orda lub ord (\<lambda>x. f x)"
   836     and g: "cont luba orda lub ord (\<lambda>x. g x)"
   839     and g: "cont luba orda lub ord (\<lambda>x. g x)"
   837   shows "ccpo.admissible luba orda (\<lambda>x. f x = g x)"
   840   shows "ccpo.admissible luba orda (\<lambda>x. f x = g x)"
   838   apply(rule ccpo.admissibleI)
   841   by (smt (verit, best) Sup.SUP_cong ccpo.admissible_def contD assms)
   839   apply(simp_all add: contD[OF f] contD[OF g] cong: image_cong)
       
   840   done
       
   841 
   842 
   842 corollary admissible_eq_mcontI [cont_intro]:
   843 corollary admissible_eq_mcontI [cont_intro]:
   843   "\<lbrakk> mcont luba orda lub ord (\<lambda>x. f x); 
   844   "\<lbrakk> mcont luba orda lub ord (\<lambda>x. f x); 
   844     mcont luba orda lub ord (\<lambda>x. g x) \<rbrakk>
   845     mcont luba orda lub ord (\<lambda>x. g x) \<rbrakk>
   845   \<Longrightarrow> ccpo.admissible luba orda (\<lambda>x. f x = g x)"
   846   \<Longrightarrow> ccpo.admissible luba orda (\<lambda>x. f x = g x)"
   864   have "f (luba A) = \<Squnion>(f ` A)" by(simp add: mcont_contD[OF f] chain False)
   865   have "f (luba A) = \<Squnion>(f ` A)" by(simp add: mcont_contD[OF f] chain False)
   865   also have "\<dots> \<le> \<Squnion>(g ` A)"
   866   also have "\<dots> \<le> \<Squnion>(g ` A)"
   866   proof(rule ccpo_Sup_least)
   867   proof(rule ccpo_Sup_least)
   867     from chain show "Complete_Partial_Order.chain (\<le>) (f ` A)"
   868     from chain show "Complete_Partial_Order.chain (\<le>) (f ` A)"
   868       by(rule chain_imageI)(rule mcont_monoD[OF f])
   869       by(rule chain_imageI)(rule mcont_monoD[OF f])
   869     
       
   870     fix x
   870     fix x
   871     assume "x \<in> f ` A"
   871     assume "x \<in> f ` A"
   872     then obtain y where "y \<in> A" "x = f y" by blast note this(2)
   872     then obtain y where "y \<in> A" "x = f y" by blast note this(2)
   873     also have "f y \<le> g y" using le \<open>y \<in> A\<close> by simp
   873     also have "f y \<le> g y" using le \<open>y \<in> A\<close> by simp
   874     also have "Complete_Partial_Order.chain (\<le>) (g ` A)"
   874     also have "Complete_Partial_Order.chain (\<le>) (g ` A)"
  1267     by(rule contD)(simp_all add: chain_rel_prodD1[OF chain] \<open>Y \<noteq> {}\<close>)
  1267     by(rule contD)(simp_all add: chain_rel_prodD1[OF chain] \<open>Y \<noteq> {}\<close>)
  1268   also from cont1 have "\<And>x. f (x, lubb (snd ` Y)) = \<Squnion>((\<lambda>y. f (x, y)) ` snd ` Y)"
  1268   also from cont1 have "\<And>x. f (x, lubb (snd ` Y)) = \<Squnion>((\<lambda>y. f (x, y)) ` snd ` Y)"
  1269     by(rule contD)(simp_all add: chain_rel_prodD2[OF chain] \<open>Y \<noteq> {}\<close>)
  1269     by(rule contD)(simp_all add: chain_rel_prodD2[OF chain] \<open>Y \<noteq> {}\<close>)
  1270   hence "\<Squnion>((\<lambda>x. f (x, lubb (snd ` Y))) ` fst ` Y) = \<Squnion>((\<lambda>x. \<dots> x) ` fst ` Y)" by simp
  1270   hence "\<Squnion>((\<lambda>x. f (x, lubb (snd ` Y))) ` fst ` Y) = \<Squnion>((\<lambda>x. \<dots> x) ` fst ` Y)" by simp
  1271   also have "\<dots> = \<Squnion>((\<lambda>x. f (fst x, snd x)) ` Y)"
  1271   also have "\<dots> = \<Squnion>((\<lambda>x. f (fst x, snd x)) ` Y)"
  1272     unfolding image_image split_def using chain
  1272     unfolding image_image  using chain
  1273     apply(rule diag_Sup)
  1273   proof (rule diag_Sup)
  1274     using monotoneD[OF mono]
  1274     show "\<And>y. y \<in> Y \<Longrightarrow> monotone (rel_prod orda ordb) (\<le>) (\<lambda>x. f (fst x, snd y))"
  1275     by(auto intro: monotoneI)
  1275       by (smt (verit, best) b.order_refl mono monotoneD monotoneI rel_prod_inject rel_prod_sel)
       
  1276   qed (use mono monotoneD in fastforce)
  1276   finally show "f (prod_lub luba lubb Y) = \<Squnion>(f ` Y)" by simp
  1277   finally show "f (prod_lub luba lubb Y) = \<Squnion>(f ` Y)" by simp
  1277 qed
  1278 qed
  1278 
  1279 
  1279 lemma cont_case_prodI:
  1280 lemma cont_case_prodI:
  1280   assumes "monotone (rel_prod orda ordb) (\<le>) (case_prod f)"
  1281   assumes "monotone (rel_prod orda ordb) (\<le>) (case_prod f)"
  1453   shows mcont_insert: "mcont Union (\<subseteq>) Union (\<subseteq>) (insert x)"
  1454   shows mcont_insert: "mcont Union (\<subseteq>) Union (\<subseteq>) (insert x)"
  1454   by(blast intro: mcontI contI monotone_insert)
  1455   by(blast intro: mcontI contI monotone_insert)
  1455 
  1456 
  1456 lemma mono2mono_image [THEN lfp.mono2mono, cont_intro, simp]:
  1457 lemma mono2mono_image [THEN lfp.mono2mono, cont_intro, simp]:
  1457   shows monotone_image: "monotone (\<subseteq>) (\<subseteq>) ((`) f)"
  1458   shows monotone_image: "monotone (\<subseteq>) (\<subseteq>) ((`) f)"
  1458   by(rule monotoneI) blast
  1459   by (simp add: image_mono monoI)
  1459 
  1460 
  1460 lemma cont_image: "cont Union (\<subseteq>) Union (\<subseteq>) ((`) f)"
  1461 lemma cont_image: "cont Union (\<subseteq>) Union (\<subseteq>) ((`) f)"
  1461   by(rule contI)(auto)
  1462   by (meson contI image_Union)
  1462 
  1463 
  1463 lemma mcont2mcont_image [THEN lfp.mcont2mcont, cont_intro, simp]:
  1464 lemma mcont2mcont_image [THEN lfp.mcont2mcont, cont_intro, simp]:
  1464   shows mcont_image: "mcont Union (\<subseteq>) Union (\<subseteq>) ((`) f)"
  1465   shows mcont_image: "mcont Union (\<subseteq>) Union (\<subseteq>) ((`) f)"
  1465   by(blast intro: mcontI monotone_image cont_image)
  1466   by(blast intro: mcontI monotone_image cont_image)
  1466 
  1467 
  1471   by(blast intro: monotoneI Sup_least Sup_upper dest: monotoneD)
  1472   by(blast intro: monotoneI Sup_least Sup_upper dest: monotoneD)
  1472 
  1473 
  1473 lemma cont_Sup:
  1474 lemma cont_Sup:
  1474   assumes "cont lub ord Union (\<subseteq>) f"
  1475   assumes "cont lub ord Union (\<subseteq>) f"
  1475   shows "cont lub ord Sup (\<le>) (\<lambda>x. \<Squnion>f x)"
  1476   shows "cont lub ord Sup (\<le>) (\<lambda>x. \<Squnion>f x)"
  1476 apply(rule contI)
  1477 proof -
  1477 apply(simp add: contD[OF assms])
  1478   have "\<And>Y. \<lbrakk>Complete_Partial_Order.chain ord Y; Y \<noteq> {}\<rbrakk>
  1478 apply(blast intro: Sup_least Sup_upper order_trans order.antisym)
  1479          \<Longrightarrow> \<Squnion> \<Union> (f ` Y) = (\<Squnion>x\<in>Y. \<Squnion> f x)"
  1479 done
  1480     by (blast intro: Sup_least Sup_upper order_trans order.antisym)
       
  1481   with assms show ?thesis
       
  1482     by (force simp: cont_def)
       
  1483 qed
  1480 
  1484 
  1481 lemma mcont_Sup: "mcont lub ord Union (\<subseteq>) f \<Longrightarrow> mcont lub ord Sup (\<le>) (\<lambda>x. \<Squnion>f x)"
  1485 lemma mcont_Sup: "mcont lub ord Union (\<subseteq>) f \<Longrightarrow> mcont lub ord Sup (\<le>) (\<lambda>x. \<Squnion>f x)"
  1482 unfolding mcont_def by(blast intro: monotone_Sup cont_Sup)
  1486   unfolding mcont_def by(blast intro: monotone_Sup cont_Sup)
  1483 
  1487 
  1484 lemma monotone_SUP:
  1488 lemma monotone_SUP:
  1485   "\<lbrakk> monotone ord (\<subseteq>) f; \<And>y. monotone ord (\<le>) (\<lambda>x. g x y) \<rbrakk> \<Longrightarrow> monotone ord (\<le>) (\<lambda>x. \<Squnion>y\<in>f x. g x y)"
  1489   "\<lbrakk> monotone ord (\<subseteq>) f; \<And>y. monotone ord (\<le>) (\<lambda>x. g x y) \<rbrakk> \<Longrightarrow> monotone ord (\<le>) (\<lambda>x. \<Squnion>y\<in>f x. g x y)"
  1486 by(rule monotoneI)(blast dest: monotoneD intro: Sup_upper order_trans intro!: Sup_least)
  1490   by(rule monotoneI)(blast dest: monotoneD intro: Sup_upper order_trans intro!: Sup_least)
  1487 
  1491 
  1488 lemma monotone_SUP2:
  1492 lemma monotone_SUP2:
  1489   "(\<And>y. y \<in> A \<Longrightarrow> monotone ord (\<le>) (\<lambda>x. g x y)) \<Longrightarrow> monotone ord (\<le>) (\<lambda>x. \<Squnion>y\<in>A. g x y)"
  1493   "(\<And>y. y \<in> A \<Longrightarrow> monotone ord (\<le>) (\<lambda>x. g x y)) \<Longrightarrow> monotone ord (\<le>) (\<lambda>x. \<Squnion>y\<in>A. g x y)"
  1490 by(rule monotoneI)(blast intro: Sup_upper order_trans dest: monotoneD intro!: Sup_least)
  1494   by(rule monotoneI)(blast intro: Sup_upper order_trans dest: monotoneD intro!: Sup_least)
  1491 
  1495 
  1492 lemma cont_SUP:
  1496 lemma cont_SUP:
  1493   assumes f: "mcont lub ord Union (\<subseteq>) f"
  1497   assumes f: "mcont lub ord Union (\<subseteq>) f"
  1494   and g: "\<And>y. mcont lub ord Sup (\<le>) (\<lambda>x. g x y)"
  1498   and g: "\<And>y. mcont lub ord Sup (\<le>) (\<lambda>x. g x y)"
  1495   shows "cont lub ord Sup (\<le>) (\<lambda>x. \<Squnion>y\<in>f x. g x y)"
  1499   shows "cont lub ord Sup (\<le>) (\<lambda>x. \<Squnion>y\<in>f x. g x y)"
  1569   \<Longrightarrow> ccpo.admissible lub ord (\<lambda>A. \<forall>x\<in>f A. P A x)"
  1573   \<Longrightarrow> ccpo.admissible lub ord (\<lambda>A. \<forall>x\<in>f A. P A x)"
  1570 unfolding Ball_def by simp
  1574 unfolding Ball_def by simp
  1571 
  1575 
  1572 lemma admissible_Bex'[THEN admissible_subst, cont_intro, simp]:
  1576 lemma admissible_Bex'[THEN admissible_subst, cont_intro, simp]:
  1573   shows admissible_Bex: "ccpo.admissible Union (\<subseteq>) (\<lambda>A. \<exists>x\<in>A. P x)"
  1577   shows admissible_Bex: "ccpo.admissible Union (\<subseteq>) (\<lambda>A. \<exists>x\<in>A. P x)"
  1574 by(rule ccpo.admissibleI)(auto)
  1578   using ccpo.admissible_def by fastforce
  1575 
  1579 
  1576 subsection \<open>Parallel fixpoint induction\<close>
  1580 subsection \<open>Parallel fixpoint induction\<close>
  1577 
  1581 
  1578 context
  1582 context
  1579   fixes luba :: "'a set \<Rightarrow> 'a"
  1583   fixes luba :: "'a set \<Rightarrow> 'a"
  1589 
  1593 
  1590 lemma ccpo_rel_prodI:
  1594 lemma ccpo_rel_prodI:
  1591   "class.ccpo (prod_lub luba lubb) (rel_prod orda ordb) (mk_less (rel_prod orda ordb))"
  1595   "class.ccpo (prod_lub luba lubb) (rel_prod orda ordb) (mk_less (rel_prod orda ordb))"
  1592   (is "class.ccpo ?lub ?ord ?ord'")
  1596   (is "class.ccpo ?lub ?ord ?ord'")
  1593 proof(intro class.ccpo.intro class.ccpo_axioms.intro)
  1597 proof(intro class.ccpo.intro class.ccpo_axioms.intro)
  1594   show "class.order ?ord ?ord'" by(rule order_rel_prodI) intro_locales
  1598   show "class.order ?ord ?ord'" 
  1595 qed(auto 4 4 simp add: prod_lub_def intro: a.ccpo_Sup_upper b.ccpo_Sup_upper a.ccpo_Sup_least b.ccpo_Sup_least rev_image_eqI dest: chain_rel_prodD1 chain_rel_prodD2)
  1599     by(rule order_rel_prodI) intro_locales
       
  1600   show "\<And>A x. \<lbrakk>Complete_Partial_Order.chain (rel_prod orda ordb) A; x \<in> A\<rbrakk>
       
  1601            \<Longrightarrow> rel_prod orda ordb x (prod_lub luba lubb A)"
       
  1602     by (simp add: a.ccpo_Sup_upper b.ccpo_Sup_upper chain_rel_prodD1 chain_rel_prodD2
       
  1603         prod_lub_def rel_prod_sel)
       
  1604   show "\<And>A z. \<lbrakk>Complete_Partial_Order.chain (rel_prod orda ordb) A;
       
  1605             \<And>x. x \<in> A \<Longrightarrow> rel_prod orda ordb x z\<rbrakk>
       
  1606            \<Longrightarrow> rel_prod orda ordb (prod_lub luba lubb A) z"
       
  1607     by (metis (full_types) a.ccpo_Sup_below_iff b.ccpo_Sup_least chain_rel_prodD1
       
  1608         chain_rel_prodD2 imageE prod.sel prod_lub_def rel_prod_sel)
       
  1609 qed
  1596 
  1610 
  1597 interpretation ab: ccpo "prod_lub luba lubb" "rel_prod orda ordb" "mk_less (rel_prod orda ordb)"
  1611 interpretation ab: ccpo "prod_lub luba lubb" "rel_prod orda ordb" "mk_less (rel_prod orda ordb)"
  1598 by(rule ccpo_rel_prodI)
  1612 by(rule ccpo_rel_prodI)
  1599 
  1613 
  1600 lemma monotone_map_prod [simp]:
  1614 lemma monotone_map_prod [simp]:
  1639     hence "ordb ?rhs2 (snd ?lhs)" using g
  1653     hence "ordb ?rhs2 (snd ?lhs)" using g
  1640     proof(rule b.fixp_induct)
  1654     proof(rule b.fixp_induct)
  1641       fix y
  1655       fix y
  1642       assume "ordb y (snd ?lhs)"
  1656       assume "ordb y (snd ?lhs)"
  1643       thus "ordb (g y) (snd ?lhs)"
  1657       thus "ordb (g y) (snd ?lhs)"
  1644         by(subst ab.fixp_unfold)(auto simp add: f g dest: monotoneD[OF g])
  1658         by (smt (verit, best) ab.fixp_unfold f g monotoneD monotone_map_prod
       
  1659             snd_map_prod)
  1645     qed(auto intro: b.ccpo_Sup_least chain_empty)
  1660     qed(auto intro: b.ccpo_Sup_least chain_empty)
  1646     ultimately show "?ord (?rhs1, ?rhs2) ?lhs"
  1661     ultimately show "?ord (?rhs1, ?rhs2) ?lhs"
  1647       by(simp add: rel_prod_conv split_beta)
  1662       by(simp add: rel_prod_conv split_beta)
  1648   qed
  1663   qed
  1649   finally show ?thesis by simp
  1664   finally show ?thesis by simp
  1661   and inverse: "\<And>f. U1 (C1 f) = f"
  1676   and inverse: "\<And>f. U1 (C1 f) = f"
  1662   and inverse2: "\<And>g. U2 (C2 g) = g"
  1677   and inverse2: "\<And>g. U2 (C2 g) = g"
  1663   and adm: "ccpo.admissible (prod_lub (fun_lub luba) (fun_lub lubb)) (rel_prod (fun_ord orda) (fun_ord ordb)) (\<lambda>x. P (fst x) (snd x))"
  1678   and adm: "ccpo.admissible (prod_lub (fun_lub luba) (fun_lub lubb)) (rel_prod (fun_ord orda) (fun_ord ordb)) (\<lambda>x. P (fst x) (snd x))"
  1664   and bot: "P (\<lambda>_. luba {}) (\<lambda>_. lubb {})"
  1679   and bot: "P (\<lambda>_. luba {}) (\<lambda>_. lubb {})"
  1665   and step: "\<And>f g. P (U1 f) (U2 g) \<Longrightarrow> P (U1 (F f)) (U2 (G g))"
  1680   and step: "\<And>f g. P (U1 f) (U2 g) \<Longrightarrow> P (U1 (F f)) (U2 (G g))"
  1666   shows "P (U1 f) (U2 g)"
  1681 shows "P (U1 f) (U2 g)"
  1667 apply(unfold eq1 eq2 inverse inverse2)
  1682   unfolding eq1 eq2 inverse inverse2
  1668 apply(rule parallel_fixp_induct[OF partial_function_definitions.ccpo[OF a] partial_function_definitions.ccpo[OF b] adm])
  1683 proof (rule parallel_fixp_induct[OF partial_function_definitions.ccpo[OF a] partial_function_definitions.ccpo[OF b] adm])
  1669 using F apply(simp add: monotone_def fun_ord_def)
  1684   show "monotone (fun_ord orda) (fun_ord orda) (\<lambda>f. U1 (F (C1 f)))"
  1670 using G apply(simp add: monotone_def fun_ord_def)
  1685     "monotone (fun_ord ordb) (fun_ord ordb) (\<lambda>g. U2 (G (C2 g)))"
  1671 apply(simp add: fun_lub_def bot)
  1686     using F G by(simp_all add: monotone_def fun_ord_def)
  1672 apply(rule step, simp add: inverse inverse2)
  1687   show "P (fun_lub luba {}) (fun_lub lubb {})"
  1673 done
  1688     by (simp add: fun_lub_def bot)
       
  1689   show "\<And>x y. P x y \<Longrightarrow> P (U1 (F (C1 x))) (U2 (G (C2 y)))"
       
  1690     by (simp add: inverse inverse2 local.step)
       
  1691 qed
  1674 
  1692 
  1675 lemmas parallel_fixp_induct_1_1 = parallel_fixp_induct_uc[
  1693 lemmas parallel_fixp_induct_1_1 = parallel_fixp_induct_uc[
  1676   of _ _ _ _ "\<lambda>x. x" _ "\<lambda>x. x" "\<lambda>x. x" _ "\<lambda>x. x",
  1694   of _ _ _ _ "\<lambda>x. x" _ "\<lambda>x. x" "\<lambda>x. x" _ "\<lambda>x. x",
  1677   OF _ _ _ _ _ _ refl refl]
  1695   OF _ _ _ _ _ _ refl refl]
  1678 
  1696 
  1690   by(auto intro!: mcontI monotoneI contI simp add: prod_lub_def)
  1708   by(auto intro!: mcontI monotoneI contI simp add: prod_lub_def)
  1691 
  1709 
  1692 lemma mcont2mcont_fst [cont_intro, simp]:
  1710 lemma mcont2mcont_fst [cont_intro, simp]:
  1693   "mcont lub ord (prod_lub luba lubb) (rel_prod orda ordb) t
  1711   "mcont lub ord (prod_lub luba lubb) (rel_prod orda ordb) t
  1694   \<Longrightarrow> mcont lub ord luba orda (\<lambda>x. fst (t x))"
  1712   \<Longrightarrow> mcont lub ord luba orda (\<lambda>x. fst (t x))"
  1695   by(auto intro!: mcontI monotoneI contI dest: mcont_monoD mcont_contD simp add: rel_prod_sel split_beta prod_lub_def image_image)
  1713   by (simp add: mcont_def monotone_on_def prod_lub_def cont_def image_image rel_prod_sel)
  1696 
  1714 
  1697 lemma monotone_snd: "monotone (rel_prod orda ordb) ordb snd"
  1715 lemma monotone_snd: "monotone (rel_prod orda ordb) ordb snd"
  1698   by(auto intro: monotoneI)
  1716   by(auto intro: monotoneI)
  1699 
  1717 
  1700 lemma mcont_snd: "mcont (prod_lub luba lubb) (rel_prod orda ordb) lubb ordb snd"
  1718 lemma mcont_snd: "mcont (prod_lub luba lubb) (rel_prod orda ordb) lubb ordb snd"
  1747     then have "(THE z. z \<in> A - {x}) = z'"
  1765     then have "(THE z. z \<in> A - {x}) = z'"
  1748       by(intro the_equality)(auto dest: chainD[OF chain] simp add: flat_ord_def)
  1766       by(intro the_equality)(auto dest: chainD[OF chain] simp add: flat_ord_def)
  1749     moreover have "z' \<noteq> y" using \<open>z' \<in> A\<close> * by(auto simp add: flat_ord_def)
  1767     moreover have "z' \<noteq> y" using \<open>z' \<in> A\<close> * by(auto simp add: flat_ord_def)
  1750     ultimately show ?thesis by simp
  1768     ultimately show ?thesis by simp
  1751   qed
  1769   qed
  1752   with z show "\<not> flat_ord x y (flat_lub x A)" by(simp add: flat_ord_def flat_lub_def)
  1770   with z show "\<not> flat_ord x y (flat_lub x A)" 
  1753 qed
  1771     by(simp add: flat_ord_def flat_lub_def)
  1754 
  1772 qed
  1755 end
  1773 
       
  1774 end