src/HOL/Library/Complete_Partial_Order2.thy
changeset 67399 eab6ce8368fa
parent 66244 4c999b5d78e2
child 68980 5717fbc55521
equal deleted inserted replaced
67398:5eb932e604a2 67399:eab6ce8368fa
     8   Main Lattice_Syntax
     8   Main Lattice_Syntax
     9 begin
     9 begin
    10 
    10 
    11 lemma chain_transfer [transfer_rule]:
    11 lemma chain_transfer [transfer_rule]:
    12   includes lifting_syntax
    12   includes lifting_syntax
    13   shows "((A ===> A ===> op =) ===> rel_set A ===> op =) Complete_Partial_Order.chain Complete_Partial_Order.chain"
    13   shows "((A ===> A ===> (=)) ===> rel_set A ===> (=)) Complete_Partial_Order.chain Complete_Partial_Order.chain"
    14 unfolding chain_def[abs_def] by transfer_prover
    14 unfolding chain_def[abs_def] by transfer_prover
    15 
    15 
    16 lemma linorder_chain [simp, intro!]:
    16 lemma linorder_chain [simp, intro!]:
    17   fixes Y :: "_ :: linorder set"
    17   fixes Y :: "_ :: linorder set"
    18   shows "Complete_Partial_Order.chain op \<le> Y"
    18   shows "Complete_Partial_Order.chain (\<le>) Y"
    19 by(auto intro: chainI)
    19 by(auto intro: chainI)
    20 
    20 
    21 lemma fun_lub_apply: "\<And>Sup. fun_lub Sup Y x = Sup ((\<lambda>f. f x) ` Y)"
    21 lemma fun_lub_apply: "\<And>Sup. fun_lub Sup Y x = Sup ((\<lambda>f. f x) ` Y)"
    22 by(simp add: fun_lub_def image_def)
    22 by(simp add: fun_lub_def image_def)
    23 
    23 
    45 by(auto 4 3 simp add: chain_def)
    45 by(auto 4 3 simp add: chain_def)
    46 
    46 
    47 
    47 
    48 context ccpo begin
    48 context ccpo begin
    49 
    49 
    50 lemma ccpo_fun: "class.ccpo (fun_lub Sup) (fun_ord op \<le>) (mk_less (fun_ord op \<le>))"
    50 lemma ccpo_fun: "class.ccpo (fun_lub Sup) (fun_ord (\<le>)) (mk_less (fun_ord (\<le>)))"
    51   by standard (auto 4 3 simp add: mk_less_def fun_ord_def fun_lub_apply
    51   by standard (auto 4 3 simp add: mk_less_def fun_ord_def fun_lub_apply
    52     intro: order.trans antisym chain_imageI ccpo_Sup_upper ccpo_Sup_least)
    52     intro: order.trans antisym chain_imageI ccpo_Sup_upper ccpo_Sup_least)
    53 
    53 
    54 lemma ccpo_Sup_below_iff: "Complete_Partial_Order.chain op \<le> Y \<Longrightarrow> Sup Y \<le> x \<longleftrightarrow> (\<forall>y\<in>Y. y \<le> x)"
    54 lemma ccpo_Sup_below_iff: "Complete_Partial_Order.chain (\<le>) Y \<Longrightarrow> Sup Y \<le> x \<longleftrightarrow> (\<forall>y\<in>Y. y \<le> x)"
    55 by(fast intro: order_trans[OF ccpo_Sup_upper] ccpo_Sup_least)
    55 by(fast intro: order_trans[OF ccpo_Sup_upper] ccpo_Sup_least)
    56 
    56 
    57 lemma Sup_minus_bot: 
    57 lemma Sup_minus_bot: 
    58   assumes chain: "Complete_Partial_Order.chain op \<le> A"
    58   assumes chain: "Complete_Partial_Order.chain (\<le>) A"
    59   shows "\<Squnion>(A - {\<Squnion>{}}) = \<Squnion>A"
    59   shows "\<Squnion>(A - {\<Squnion>{}}) = \<Squnion>A"
    60     (is "?lhs = ?rhs")
    60     (is "?lhs = ?rhs")
    61 proof (rule antisym)
    61 proof (rule antisym)
    62   show "?lhs \<le> ?rhs"
    62   show "?lhs \<le> ?rhs"
    63     by (blast intro: ccpo_Sup_least chain_Diff[OF chain] ccpo_Sup_upper[OF chain])
    63     by (blast intro: ccpo_Sup_least chain_Diff[OF chain] ccpo_Sup_upper[OF chain])
    69   qed
    69   qed
    70 qed
    70 qed
    71 
    71 
    72 lemma mono_lub:
    72 lemma mono_lub:
    73   fixes le_b (infix "\<sqsubseteq>" 60)
    73   fixes le_b (infix "\<sqsubseteq>" 60)
    74   assumes chain: "Complete_Partial_Order.chain (fun_ord op \<le>) Y"
    74   assumes chain: "Complete_Partial_Order.chain (fun_ord (\<le>)) Y"
    75   and mono: "\<And>f. f \<in> Y \<Longrightarrow> monotone le_b op \<le> f"
    75   and mono: "\<And>f. f \<in> Y \<Longrightarrow> monotone le_b (\<le>) f"
    76   shows "monotone op \<sqsubseteq> op \<le> (fun_lub Sup Y)"
    76   shows "monotone (\<sqsubseteq>) (\<le>) (fun_lub Sup Y)"
    77 proof(rule monotoneI)
    77 proof(rule monotoneI)
    78   fix x y
    78   fix x y
    79   assume "x \<sqsubseteq> y"
    79   assume "x \<sqsubseteq> y"
    80 
    80 
    81   have chain'': "\<And>x. Complete_Partial_Order.chain op \<le> ((\<lambda>f. f x) ` Y)"
    81   have chain'': "\<And>x. Complete_Partial_Order.chain (\<le>) ((\<lambda>f. f x) ` Y)"
    82     using chain by(rule chain_imageI)(simp add: fun_ord_def)
    82     using chain by(rule chain_imageI)(simp add: fun_ord_def)
    83   then show "fun_lub Sup Y x \<le> fun_lub Sup Y y" unfolding fun_lub_apply
    83   then show "fun_lub Sup Y x \<le> fun_lub Sup Y y" unfolding fun_lub_apply
    84   proof(rule ccpo_Sup_least)
    84   proof(rule ccpo_Sup_least)
    85     fix x'
    85     fix x'
    86     assume "x' \<in> (\<lambda>f. f x) ` Y"
    86     assume "x' \<in> (\<lambda>f. f x) ` Y"
    94 qed
    94 qed
    95 
    95 
    96 context
    96 context
    97   fixes le_b (infix "\<sqsubseteq>" 60) and Y f
    97   fixes le_b (infix "\<sqsubseteq>" 60) and Y f
    98   assumes chain: "Complete_Partial_Order.chain le_b Y" 
    98   assumes chain: "Complete_Partial_Order.chain le_b Y" 
    99   and mono1: "\<And>y. y \<in> Y \<Longrightarrow> monotone le_b op \<le> (\<lambda>x. f x y)"
    99   and mono1: "\<And>y. y \<in> Y \<Longrightarrow> monotone le_b (\<le>) (\<lambda>x. f x y)"
   100   and mono2: "\<And>x a b. \<lbrakk> x \<in> Y; a \<sqsubseteq> b; a \<in> Y; b \<in> Y \<rbrakk> \<Longrightarrow> f x a \<le> f x b"
   100   and mono2: "\<And>x a b. \<lbrakk> x \<in> Y; a \<sqsubseteq> b; a \<in> Y; b \<in> Y \<rbrakk> \<Longrightarrow> f x a \<le> f x b"
   101 begin
   101 begin
   102 
   102 
   103 lemma Sup_mono: 
   103 lemma Sup_mono: 
   104   assumes le: "x \<sqsubseteq> y" and x: "x \<in> Y" and y: "y \<in> Y"
   104   assumes le: "x \<sqsubseteq> y" and x: "x \<in> Y" and y: "y \<in> Y"
   105   shows "\<Squnion>(f x ` Y) \<le> \<Squnion>(f y ` Y)" (is "_ \<le> ?rhs")
   105   shows "\<Squnion>(f x ` Y) \<le> \<Squnion>(f y ` Y)" (is "_ \<le> ?rhs")
   106 proof(rule ccpo_Sup_least)
   106 proof(rule ccpo_Sup_least)
   107   from chain show chain': "Complete_Partial_Order.chain op \<le> (f x ` Y)" when "x \<in> Y" for x
   107   from chain show chain': "Complete_Partial_Order.chain (\<le>) (f x ` Y)" when "x \<in> Y" for x
   108     by(rule chain_imageI) (insert that, auto dest: mono2)
   108     by(rule chain_imageI) (insert that, auto dest: mono2)
   109 
   109 
   110   fix x'
   110   fix x'
   111   assume "x' \<in> f x ` Y"
   111   assume "x' \<in> f x ` Y"
   112   then obtain y' where "y' \<in> Y" "x' = f x y'" by blast note this(2)
   112   then obtain y' where "y' \<in> Y" "x' = f x y'" by blast note this(2)
   116   finally show "x' \<le> ?rhs" .
   116   finally show "x' \<le> ?rhs" .
   117 qed(rule x)
   117 qed(rule x)
   118 
   118 
   119 lemma diag_Sup: "\<Squnion>((\<lambda>x. \<Squnion>(f x ` Y)) ` Y) = \<Squnion>((\<lambda>x. f x x) ` Y)" (is "?lhs = ?rhs")
   119 lemma diag_Sup: "\<Squnion>((\<lambda>x. \<Squnion>(f x ` Y)) ` Y) = \<Squnion>((\<lambda>x. f x x) ` Y)" (is "?lhs = ?rhs")
   120 proof(rule antisym)
   120 proof(rule antisym)
   121   have chain1: "Complete_Partial_Order.chain op \<le> ((\<lambda>x. \<Squnion>(f x ` Y)) ` Y)"
   121   have chain1: "Complete_Partial_Order.chain (\<le>) ((\<lambda>x. \<Squnion>(f x ` Y)) ` Y)"
   122     using chain by(rule chain_imageI)(rule Sup_mono)
   122     using chain by(rule chain_imageI)(rule Sup_mono)
   123   have chain2: "\<And>y'. y' \<in> Y \<Longrightarrow> Complete_Partial_Order.chain op \<le> (f y' ` Y)" using chain
   123   have chain2: "\<And>y'. y' \<in> Y \<Longrightarrow> Complete_Partial_Order.chain (\<le>) (f y' ` Y)" using chain
   124     by(rule chain_imageI)(auto dest: mono2)
   124     by(rule chain_imageI)(auto dest: mono2)
   125   have chain3: "Complete_Partial_Order.chain op \<le> ((\<lambda>x. f x x) ` Y)"
   125   have chain3: "Complete_Partial_Order.chain (\<le>) ((\<lambda>x. f x x) ` Y)"
   126     using chain by(rule chain_imageI)(auto intro: monotoneD[OF mono1] mono2 order.trans)
   126     using chain by(rule chain_imageI)(auto intro: monotoneD[OF mono1] mono2 order.trans)
   127 
   127 
   128   show "?lhs \<le> ?rhs" using chain1
   128   show "?lhs \<le> ?rhs" using chain1
   129   proof(rule ccpo_Sup_least)
   129   proof(rule ccpo_Sup_least)
   130     fix x'
   130     fix x'
   160 
   160 
   161 end
   161 end
   162 
   162 
   163 lemma Sup_image_mono_le:
   163 lemma Sup_image_mono_le:
   164   fixes le_b (infix "\<sqsubseteq>" 60) and Sup_b ("\<Or>_" [900] 900)
   164   fixes le_b (infix "\<sqsubseteq>" 60) and Sup_b ("\<Or>_" [900] 900)
   165   assumes ccpo: "class.ccpo Sup_b op \<sqsubseteq> lt_b"
   165   assumes ccpo: "class.ccpo Sup_b (\<sqsubseteq>) lt_b"
   166   assumes chain: "Complete_Partial_Order.chain op \<sqsubseteq> Y"
   166   assumes chain: "Complete_Partial_Order.chain (\<sqsubseteq>) Y"
   167   and mono: "\<And>x y. \<lbrakk> x \<sqsubseteq> y; x \<in> Y \<rbrakk> \<Longrightarrow> f x \<le> f y"
   167   and mono: "\<And>x y. \<lbrakk> x \<sqsubseteq> y; x \<in> Y \<rbrakk> \<Longrightarrow> f x \<le> f y"
   168   shows "Sup (f ` Y) \<le> f (\<Or>Y)"
   168   shows "Sup (f ` Y) \<le> f (\<Or>Y)"
   169 proof(rule ccpo_Sup_least)
   169 proof(rule ccpo_Sup_least)
   170   show "Complete_Partial_Order.chain op \<le> (f ` Y)"
   170   show "Complete_Partial_Order.chain (\<le>) (f ` Y)"
   171     using chain by(rule chain_imageI)(rule mono)
   171     using chain by(rule chain_imageI)(rule mono)
   172 
   172 
   173   fix x
   173   fix x
   174   assume "x \<in> f ` Y"
   174   assume "x \<in> f ` Y"
   175   then obtain y where "y \<in> Y" and "x = f y" by blast note this(2)
   175   then obtain y where "y \<in> Y" and "x = f y" by blast note this(2)
   178   finally show "x \<le> \<dots>" .
   178   finally show "x \<le> \<dots>" .
   179 qed
   179 qed
   180 
   180 
   181 lemma swap_Sup:
   181 lemma swap_Sup:
   182   fixes le_b (infix "\<sqsubseteq>" 60)
   182   fixes le_b (infix "\<sqsubseteq>" 60)
   183   assumes Y: "Complete_Partial_Order.chain op \<sqsubseteq> Y"
   183   assumes Y: "Complete_Partial_Order.chain (\<sqsubseteq>) Y"
   184   and Z: "Complete_Partial_Order.chain (fun_ord op \<le>) Z"
   184   and Z: "Complete_Partial_Order.chain (fun_ord (\<le>)) Z"
   185   and mono: "\<And>f. f \<in> Z \<Longrightarrow> monotone op \<sqsubseteq> op \<le> f"
   185   and mono: "\<And>f. f \<in> Z \<Longrightarrow> monotone (\<sqsubseteq>) (\<le>) f"
   186   shows "\<Squnion>((\<lambda>x. \<Squnion>(x ` Y)) ` Z) = \<Squnion>((\<lambda>x. \<Squnion>((\<lambda>f. f x) ` Z)) ` Y)"
   186   shows "\<Squnion>((\<lambda>x. \<Squnion>(x ` Y)) ` Z) = \<Squnion>((\<lambda>x. \<Squnion>((\<lambda>f. f x) ` Z)) ` Y)"
   187   (is "?lhs = ?rhs")
   187   (is "?lhs = ?rhs")
   188 proof(cases "Y = {}")
   188 proof(cases "Y = {}")
   189   case True
   189   case True
   190   then show ?thesis
   190   then show ?thesis
   191     by (simp add: image_constant_conv cong del: strong_SUP_cong)
   191     by (simp add: image_constant_conv cong del: strong_SUP_cong)
   192 next
   192 next
   193   case False
   193   case False
   194   have chain1: "\<And>f. f \<in> Z \<Longrightarrow> Complete_Partial_Order.chain op \<le> (f ` Y)"
   194   have chain1: "\<And>f. f \<in> Z \<Longrightarrow> Complete_Partial_Order.chain (\<le>) (f ` Y)"
   195     by(rule chain_imageI[OF Y])(rule monotoneD[OF mono])
   195     by(rule chain_imageI[OF Y])(rule monotoneD[OF mono])
   196   have chain2: "Complete_Partial_Order.chain op \<le> ((\<lambda>x. \<Squnion>(x ` Y)) ` Z)" using Z
   196   have chain2: "Complete_Partial_Order.chain (\<le>) ((\<lambda>x. \<Squnion>(x ` Y)) ` Z)" using Z
   197   proof(rule chain_imageI)
   197   proof(rule chain_imageI)
   198     fix f g
   198     fix f g
   199     assume "f \<in> Z" "g \<in> Z"
   199     assume "f \<in> Z" "g \<in> Z"
   200       and "fun_ord op \<le> f g"
   200       and "fun_ord (\<le>) f g"
   201     from chain1[OF \<open>f \<in> Z\<close>] show "\<Squnion>(f ` Y) \<le> \<Squnion>(g ` Y)"
   201     from chain1[OF \<open>f \<in> Z\<close>] show "\<Squnion>(f ` Y) \<le> \<Squnion>(g ` Y)"
   202     proof(rule ccpo_Sup_least)
   202     proof(rule ccpo_Sup_least)
   203       fix x
   203       fix x
   204       assume "x \<in> f ` Y"
   204       assume "x \<in> f ` Y"
   205       then obtain y where "y \<in> Y" "x = f y" by blast note this(2)
   205       then obtain y where "y \<in> Y" "x = f y" by blast note this(2)
   206       also have "\<dots> \<le> g y" using \<open>fun_ord op \<le> f g\<close> by(simp add: fun_ord_def)
   206       also have "\<dots> \<le> g y" using \<open>fun_ord (\<le>) f g\<close> by(simp add: fun_ord_def)
   207       also have "\<dots> \<le> \<Squnion>(g ` Y)" using chain1[OF \<open>g \<in> Z\<close>]
   207       also have "\<dots> \<le> \<Squnion>(g ` Y)" using chain1[OF \<open>g \<in> Z\<close>]
   208         by(rule ccpo_Sup_upper)(simp add: \<open>y \<in> Y\<close>)
   208         by(rule ccpo_Sup_upper)(simp add: \<open>y \<in> Y\<close>)
   209       finally show "x \<le> \<Squnion>(g ` Y)" .
   209       finally show "x \<le> \<Squnion>(g ` Y)" .
   210     qed
   210     qed
   211   qed
   211   qed
   212   have chain3: "\<And>x. Complete_Partial_Order.chain op \<le> ((\<lambda>f. f x) ` Z)"
   212   have chain3: "\<And>x. Complete_Partial_Order.chain (\<le>) ((\<lambda>f. f x) ` Z)"
   213     using Z by(rule chain_imageI)(simp add: fun_ord_def)
   213     using Z by(rule chain_imageI)(simp add: fun_ord_def)
   214   have chain4: "Complete_Partial_Order.chain op \<le> ((\<lambda>x. \<Squnion>((\<lambda>f. f x) ` Z)) ` Y)"
   214   have chain4: "Complete_Partial_Order.chain (\<le>) ((\<lambda>x. \<Squnion>((\<lambda>f. f x) ` Z)) ` Y)"
   215     using Y
   215     using Y
   216   proof(rule chain_imageI)
   216   proof(rule chain_imageI)
   217     fix f x y
   217     fix f x y
   218     assume "x \<sqsubseteq> y"
   218     assume "x \<sqsubseteq> y"
   219     show "\<Squnion>((\<lambda>f. f x) ` Z) \<le> \<Squnion>((\<lambda>f. f y) ` Z)" (is "_ \<le> ?rhs") using chain3
   219     show "\<Squnion>((\<lambda>f. f x) ` Z) \<le> \<Squnion>((\<lambda>f. f y) ` Z)" (is "_ \<le> ?rhs") using chain3
   266   qed
   266   qed
   267   ultimately show "?lhs = ?rhs" by(rule antisym)
   267   ultimately show "?lhs = ?rhs" by(rule antisym)
   268 qed
   268 qed
   269 
   269 
   270 lemma fixp_mono:
   270 lemma fixp_mono:
   271   assumes fg: "fun_ord op \<le> f g"
   271   assumes fg: "fun_ord (\<le>) f g"
   272   and f: "monotone op \<le> op \<le> f"
   272   and f: "monotone (\<le>) (\<le>) f"
   273   and g: "monotone op \<le> op \<le> g"
   273   and g: "monotone (\<le>) (\<le>) g"
   274   shows "ccpo_class.fixp f \<le> ccpo_class.fixp g"
   274   shows "ccpo_class.fixp f \<le> ccpo_class.fixp g"
   275 unfolding fixp_def
   275 unfolding fixp_def
   276 proof(rule ccpo_Sup_least)
   276 proof(rule ccpo_Sup_least)
   277   fix x
   277   fix x
   278   assume "x \<in> ccpo_class.iterates f"
   278   assume "x \<in> ccpo_class.iterates f"
   287 qed(rule chain_iterates[OF f])
   287 qed(rule chain_iterates[OF f])
   288 
   288 
   289 context fixes ordb :: "'b \<Rightarrow> 'b \<Rightarrow> bool" (infix "\<sqsubseteq>" 60) begin
   289 context fixes ordb :: "'b \<Rightarrow> 'b \<Rightarrow> bool" (infix "\<sqsubseteq>" 60) begin
   290 
   290 
   291 lemma iterates_mono:
   291 lemma iterates_mono:
   292   assumes f: "f \<in> ccpo.iterates (fun_lub Sup) (fun_ord op \<le>) F"
   292   assumes f: "f \<in> ccpo.iterates (fun_lub Sup) (fun_ord (\<le>)) F"
   293   and mono: "\<And>f. monotone op \<sqsubseteq> op \<le> f \<Longrightarrow> monotone op \<sqsubseteq> op \<le> (F f)"
   293   and mono: "\<And>f. monotone (\<sqsubseteq>) (\<le>) f \<Longrightarrow> monotone (\<sqsubseteq>) (\<le>) (F f)"
   294   shows "monotone op \<sqsubseteq> op \<le> f"
   294   shows "monotone (\<sqsubseteq>) (\<le>) f"
   295 using f
   295 using f
   296 by(induction rule: ccpo.iterates.induct[OF ccpo_fun, consumes 1, case_names step Sup])(blast intro: mono mono_lub)+
   296 by(induction rule: ccpo.iterates.induct[OF ccpo_fun, consumes 1, case_names step Sup])(blast intro: mono mono_lub)+
   297 
   297 
   298 lemma fixp_preserves_mono:
   298 lemma fixp_preserves_mono:
   299   assumes mono: "\<And>x. monotone (fun_ord op \<le>) op \<le> (\<lambda>f. F f x)"
   299   assumes mono: "\<And>x. monotone (fun_ord (\<le>)) (\<le>) (\<lambda>f. F f x)"
   300   and mono2: "\<And>f. monotone op \<sqsubseteq> op \<le> f \<Longrightarrow> monotone op \<sqsubseteq> op \<le> (F f)"
   300   and mono2: "\<And>f. monotone (\<sqsubseteq>) (\<le>) f \<Longrightarrow> monotone (\<sqsubseteq>) (\<le>) (F f)"
   301   shows "monotone op \<sqsubseteq> op \<le> (ccpo.fixp (fun_lub Sup) (fun_ord op \<le>) F)"
   301   shows "monotone (\<sqsubseteq>) (\<le>) (ccpo.fixp (fun_lub Sup) (fun_ord (\<le>)) F)"
   302   (is "monotone _ _ ?fixp")
   302   (is "monotone _ _ ?fixp")
   303 proof(rule monotoneI)
   303 proof(rule monotoneI)
   304   have mono: "monotone (fun_ord op \<le>) (fun_ord op \<le>) F"
   304   have mono: "monotone (fun_ord (\<le>)) (fun_ord (\<le>)) F"
   305     by(rule monotoneI)(auto simp add: fun_ord_def intro: monotoneD[OF mono])
   305     by(rule monotoneI)(auto simp add: fun_ord_def intro: monotoneD[OF mono])
   306   let ?iter = "ccpo.iterates (fun_lub Sup) (fun_ord op \<le>) F"
   306   let ?iter = "ccpo.iterates (fun_lub Sup) (fun_ord (\<le>)) F"
   307   have chain: "\<And>x. Complete_Partial_Order.chain op \<le> ((\<lambda>f. f x) ` ?iter)"
   307   have chain: "\<And>x. Complete_Partial_Order.chain (\<le>) ((\<lambda>f. f x) ` ?iter)"
   308     by(rule chain_imageI[OF ccpo.chain_iterates[OF ccpo_fun mono]])(simp add: fun_ord_def)
   308     by(rule chain_imageI[OF ccpo.chain_iterates[OF ccpo_fun mono]])(simp add: fun_ord_def)
   309 
   309 
   310   fix x y
   310   fix x y
   311   assume "x \<sqsubseteq> y"
   311   assume "x \<sqsubseteq> y"
   312   show "?fixp x \<le> ?fixp y"
   312   show "?fixp x \<le> ?fixp y"
   415   "monotone orda (fun_ord ordb) f \<longleftrightarrow> (\<forall>x. monotone orda ordb (\<lambda>y. f y x))"
   415   "monotone orda (fun_ord ordb) f \<longleftrightarrow> (\<forall>x. monotone orda ordb (\<lambda>y. f y x))"
   416 by(auto simp add: monotone_def fun_ord_def)
   416 by(auto simp add: monotone_def fun_ord_def)
   417 
   417 
   418 context preorder begin
   418 context preorder begin
   419 
   419 
   420 lemma transp_le [simp, cont_intro]: "transp op \<le>"
   420 lemma transp_le [simp, cont_intro]: "transp (\<le>)"
   421 by(rule transpI)(rule order_trans)
   421 by(rule transpI)(rule order_trans)
   422 
   422 
   423 lemma monotone_const [simp, cont_intro]: "monotone ord op \<le> (\<lambda>_. c)"
   423 lemma monotone_const [simp, cont_intro]: "monotone ord (\<le>) (\<lambda>_. c)"
   424 by(rule monotoneI) simp
   424 by(rule monotoneI) simp
   425 
   425 
   426 end
   426 end
   427 
   427 
   428 lemma transp_le [cont_intro, simp]:
   428 lemma transp_le [cont_intro, simp]:
   515   "mcont luba orda (fun_lub lubb) (fun_ord ordb) f \<longleftrightarrow> (\<forall>x. mcont luba orda lubb ordb (\<lambda>y. f y x))"
   515   "mcont luba orda (fun_lub lubb) (fun_ord ordb) f \<longleftrightarrow> (\<forall>x. mcont luba orda lubb ordb (\<lambda>y. f y x))"
   516 by(auto simp add: monotone_fun_ord_apply cont_fun_lub_apply mcont_def)
   516 by(auto simp add: monotone_fun_ord_apply cont_fun_lub_apply mcont_def)
   517 
   517 
   518 context ccpo begin
   518 context ccpo begin
   519 
   519 
   520 lemma cont_const [simp, cont_intro]: "cont luba orda Sup op \<le> (\<lambda>x. c)"
   520 lemma cont_const [simp, cont_intro]: "cont luba orda Sup (\<le>) (\<lambda>x. c)"
   521 by (rule contI) (simp add: image_constant_conv cong del: strong_SUP_cong)
   521 by (rule contI) (simp add: image_constant_conv cong del: strong_SUP_cong)
   522 
   522 
   523 lemma mcont_const [cont_intro, simp]:
   523 lemma mcont_const [cont_intro, simp]:
   524   "mcont luba orda Sup op \<le> (\<lambda>x. c)"
   524   "mcont luba orda Sup (\<le>) (\<lambda>x. c)"
   525 by(simp add: mcont_def)
   525 by(simp add: mcont_def)
   526 
   526 
   527 lemma cont_apply:
   527 lemma cont_apply:
   528   assumes 2: "\<And>x. cont lubb ordb Sup op \<le> (\<lambda>y. f x y)"
   528   assumes 2: "\<And>x. cont lubb ordb Sup (\<le>) (\<lambda>y. f x y)"
   529   and t: "cont luba orda lubb ordb (\<lambda>x. t x)"
   529   and t: "cont luba orda lubb ordb (\<lambda>x. t x)"
   530   and 1: "\<And>y. cont luba orda Sup op \<le> (\<lambda>x. f x y)"
   530   and 1: "\<And>y. cont luba orda Sup (\<le>) (\<lambda>x. f x y)"
   531   and mono: "monotone orda ordb (\<lambda>x. t x)"
   531   and mono: "monotone orda ordb (\<lambda>x. t x)"
   532   and mono2: "\<And>x. monotone ordb op \<le> (\<lambda>y. f x y)"
   532   and mono2: "\<And>x. monotone ordb (\<le>) (\<lambda>y. f x y)"
   533   and mono1: "\<And>y. monotone orda op \<le> (\<lambda>x. f x y)"
   533   and mono1: "\<And>y. monotone orda (\<le>) (\<lambda>x. f x y)"
   534   shows "cont luba orda Sup op \<le> (\<lambda>x. f x (t x))"
   534   shows "cont luba orda Sup (\<le>) (\<lambda>x. f x (t x))"
   535 proof
   535 proof
   536   fix Y
   536   fix Y
   537   assume chain: "Complete_Partial_Order.chain orda Y" and "Y \<noteq> {}"
   537   assume chain: "Complete_Partial_Order.chain orda Y" and "Y \<noteq> {}"
   538   moreover from chain have chain': "Complete_Partial_Order.chain ordb (t ` Y)"
   538   moreover from chain have chain': "Complete_Partial_Order.chain ordb (t ` Y)"
   539     by(rule chain_imageI)(rule monotoneD[OF mono])
   539     by(rule chain_imageI)(rule monotoneD[OF mono])
   541     by(simp add: contD[OF 1] contD[OF t] contD[OF 2] image_image)
   541     by(simp add: contD[OF 1] contD[OF t] contD[OF 2] image_image)
   542       (rule diag_Sup[OF chain], auto intro: monotone2monotone[OF mono2 mono monotone_const transpI] monotoneD[OF mono1])
   542       (rule diag_Sup[OF chain], auto intro: monotone2monotone[OF mono2 mono monotone_const transpI] monotoneD[OF mono1])
   543 qed
   543 qed
   544 
   544 
   545 lemma mcont2mcont':
   545 lemma mcont2mcont':
   546   "\<lbrakk> \<And>x. mcont lub' ord' Sup op \<le> (\<lambda>y. f x y);
   546   "\<lbrakk> \<And>x. mcont lub' ord' Sup (\<le>) (\<lambda>y. f x y);
   547      \<And>y. mcont lub ord Sup op \<le> (\<lambda>x. f x y);
   547      \<And>y. mcont lub ord Sup (\<le>) (\<lambda>x. f x y);
   548      mcont lub ord lub' ord' (\<lambda>y. t y) \<rbrakk>
   548      mcont lub ord lub' ord' (\<lambda>y. t y) \<rbrakk>
   549   \<Longrightarrow> mcont lub ord Sup op \<le> (\<lambda>x. f x (t x))"
   549   \<Longrightarrow> mcont lub ord Sup (\<le>) (\<lambda>x. f x (t x))"
   550 unfolding mcont_def by(blast intro: transp_le monotone2monotone cont_apply)
   550 unfolding mcont_def by(blast intro: transp_le monotone2monotone cont_apply)
   551 
   551 
   552 lemma mcont2mcont:
   552 lemma mcont2mcont:
   553   "\<lbrakk>mcont lub' ord' Sup op \<le> (\<lambda>x. f x); mcont lub ord lub' ord' (\<lambda>x. t x)\<rbrakk> 
   553   "\<lbrakk>mcont lub' ord' Sup (\<le>) (\<lambda>x. f x); mcont lub ord lub' ord' (\<lambda>x. t x)\<rbrakk> 
   554   \<Longrightarrow> mcont lub ord Sup op \<le> (\<lambda>x. f (t x))"
   554   \<Longrightarrow> mcont lub ord Sup (\<le>) (\<lambda>x. f (t x))"
   555 by(rule mcont2mcont'[OF _ mcont_const]) 
   555 by(rule mcont2mcont'[OF _ mcont_const]) 
   556 
   556 
   557 context
   557 context
   558   fixes ord :: "'b \<Rightarrow> 'b \<Rightarrow> bool" (infix "\<sqsubseteq>" 60) 
   558   fixes ord :: "'b \<Rightarrow> 'b \<Rightarrow> bool" (infix "\<sqsubseteq>" 60) 
   559   and lub :: "'b set \<Rightarrow> 'b" ("\<Or>_" [900] 900)
   559   and lub :: "'b set \<Rightarrow> 'b" ("\<Or>_" [900] 900)
   560 begin
   560 begin
   561 
   561 
   562 lemma cont_fun_lub_Sup:
   562 lemma cont_fun_lub_Sup:
   563   assumes chainM: "Complete_Partial_Order.chain (fun_ord op \<le>) M"
   563   assumes chainM: "Complete_Partial_Order.chain (fun_ord (\<le>)) M"
   564   and mcont [rule_format]: "\<forall>f\<in>M. mcont lub op \<sqsubseteq> Sup op \<le> f"
   564   and mcont [rule_format]: "\<forall>f\<in>M. mcont lub (\<sqsubseteq>) Sup (\<le>) f"
   565   shows "cont lub op \<sqsubseteq> Sup op \<le> (fun_lub Sup M)"
   565   shows "cont lub (\<sqsubseteq>) Sup (\<le>) (fun_lub Sup M)"
   566 proof(rule contI)
   566 proof(rule contI)
   567   fix Y
   567   fix Y
   568   assume chain: "Complete_Partial_Order.chain op \<sqsubseteq> Y"
   568   assume chain: "Complete_Partial_Order.chain (\<sqsubseteq>) Y"
   569     and Y: "Y \<noteq> {}"
   569     and Y: "Y \<noteq> {}"
   570   from swap_Sup[OF chain chainM mcont[THEN mcont_mono]]
   570   from swap_Sup[OF chain chainM mcont[THEN mcont_mono]]
   571   show "fun_lub Sup M (\<Or>Y) = \<Squnion>(fun_lub Sup M ` Y)"
   571   show "fun_lub Sup M (\<Or>Y) = \<Squnion>(fun_lub Sup M ` Y)"
   572     by(simp add: mcont_contD[OF mcont chain Y] fun_lub_apply cong: image_cong)
   572     by(simp add: mcont_contD[OF mcont chain Y] fun_lub_apply cong: image_cong)
   573 qed
   573 qed
   574 
   574 
   575 lemma mcont_fun_lub_Sup:
   575 lemma mcont_fun_lub_Sup:
   576   "\<lbrakk> Complete_Partial_Order.chain (fun_ord op \<le>) M;
   576   "\<lbrakk> Complete_Partial_Order.chain (fun_ord (\<le>)) M;
   577     \<forall>f\<in>M. mcont lub ord Sup op \<le> f \<rbrakk>
   577     \<forall>f\<in>M. mcont lub ord Sup (\<le>) f \<rbrakk>
   578   \<Longrightarrow> mcont lub op \<sqsubseteq> Sup op \<le> (fun_lub Sup M)"
   578   \<Longrightarrow> mcont lub (\<sqsubseteq>) Sup (\<le>) (fun_lub Sup M)"
   579 by(simp add: mcont_def cont_fun_lub_Sup mono_lub)
   579 by(simp add: mcont_def cont_fun_lub_Sup mono_lub)
   580 
   580 
   581 lemma iterates_mcont:
   581 lemma iterates_mcont:
   582   assumes f: "f \<in> ccpo.iterates (fun_lub Sup) (fun_ord op \<le>) F"
   582   assumes f: "f \<in> ccpo.iterates (fun_lub Sup) (fun_ord (\<le>)) F"
   583   and mono: "\<And>f. mcont lub op \<sqsubseteq> Sup op \<le> f \<Longrightarrow> mcont lub op \<sqsubseteq> Sup op \<le> (F f)"
   583   and mono: "\<And>f. mcont lub (\<sqsubseteq>) Sup (\<le>) f \<Longrightarrow> mcont lub (\<sqsubseteq>) Sup (\<le>) (F f)"
   584   shows "mcont lub op \<sqsubseteq> Sup op \<le> f"
   584   shows "mcont lub (\<sqsubseteq>) Sup (\<le>) f"
   585 using f
   585 using f
   586 by(induction rule: ccpo.iterates.induct[OF ccpo_fun, consumes 1, case_names step Sup])(blast intro: mono mcont_fun_lub_Sup)+
   586 by(induction rule: ccpo.iterates.induct[OF ccpo_fun, consumes 1, case_names step Sup])(blast intro: mono mcont_fun_lub_Sup)+
   587 
   587 
   588 lemma fixp_preserves_mcont:
   588 lemma fixp_preserves_mcont:
   589   assumes mono: "\<And>x. monotone (fun_ord op \<le>) op \<le> (\<lambda>f. F f x)"
   589   assumes mono: "\<And>x. monotone (fun_ord (\<le>)) (\<le>) (\<lambda>f. F f x)"
   590   and mcont: "\<And>f. mcont lub op \<sqsubseteq> Sup op \<le> f \<Longrightarrow> mcont lub op \<sqsubseteq> Sup op \<le> (F f)"
   590   and mcont: "\<And>f. mcont lub (\<sqsubseteq>) Sup (\<le>) f \<Longrightarrow> mcont lub (\<sqsubseteq>) Sup (\<le>) (F f)"
   591   shows "mcont lub op \<sqsubseteq> Sup op \<le> (ccpo.fixp (fun_lub Sup) (fun_ord op \<le>) F)"
   591   shows "mcont lub (\<sqsubseteq>) Sup (\<le>) (ccpo.fixp (fun_lub Sup) (fun_ord (\<le>)) F)"
   592   (is "mcont _ _ _ _ ?fixp")
   592   (is "mcont _ _ _ _ ?fixp")
   593 unfolding mcont_def
   593 unfolding mcont_def
   594 proof(intro conjI monotoneI contI)
   594 proof(intro conjI monotoneI contI)
   595   have mono: "monotone (fun_ord op \<le>) (fun_ord op \<le>) F"
   595   have mono: "monotone (fun_ord (\<le>)) (fun_ord (\<le>)) F"
   596     by(rule monotoneI)(auto simp add: fun_ord_def intro: monotoneD[OF mono])
   596     by(rule monotoneI)(auto simp add: fun_ord_def intro: monotoneD[OF mono])
   597   let ?iter = "ccpo.iterates (fun_lub Sup) (fun_ord op \<le>) F"
   597   let ?iter = "ccpo.iterates (fun_lub Sup) (fun_ord (\<le>)) F"
   598   have chain: "\<And>x. Complete_Partial_Order.chain op \<le> ((\<lambda>f. f x) ` ?iter)"
   598   have chain: "\<And>x. Complete_Partial_Order.chain (\<le>) ((\<lambda>f. f x) ` ?iter)"
   599     by(rule chain_imageI[OF ccpo.chain_iterates[OF ccpo_fun mono]])(simp add: fun_ord_def)
   599     by(rule chain_imageI[OF ccpo.chain_iterates[OF ccpo_fun mono]])(simp add: fun_ord_def)
   600 
   600 
   601   {
   601   {
   602     fix x y
   602     fix x y
   603     assume "x \<sqsubseteq> y"
   603     assume "x \<sqsubseteq> y"
   614         by(rule ccpo_Sup_upper)(simp add: \<open>f \<in> ?iter\<close>)
   614         by(rule ccpo_Sup_upper)(simp add: \<open>f \<in> ?iter\<close>)
   615       finally show "x' \<le> \<dots>" .
   615       finally show "x' \<le> \<dots>" .
   616     qed
   616     qed
   617   next
   617   next
   618     fix Y
   618     fix Y
   619     assume chain: "Complete_Partial_Order.chain op \<sqsubseteq> Y"
   619     assume chain: "Complete_Partial_Order.chain (\<sqsubseteq>) Y"
   620       and Y: "Y \<noteq> {}"
   620       and Y: "Y \<noteq> {}"
   621     { fix f
   621     { fix f
   622       assume "f \<in> ?iter"
   622       assume "f \<in> ?iter"
   623       hence "f (\<Or>Y) = \<Squnion>(f ` Y)"
   623       hence "f (\<Or>Y) = \<Squnion>(f ` Y)"
   624         using mcont chain Y by(rule mcont_contD[OF iterates_mcont]) }
   624         using mcont chain Y by(rule mcont_contD[OF iterates_mcont]) }
   632 
   632 
   633 end
   633 end
   634 
   634 
   635 context
   635 context
   636   fixes F :: "'c \<Rightarrow> 'c" and U :: "'c \<Rightarrow> 'b \<Rightarrow> 'a" and C :: "('b \<Rightarrow> 'a) \<Rightarrow> 'c" and f
   636   fixes F :: "'c \<Rightarrow> 'c" and U :: "'c \<Rightarrow> 'b \<Rightarrow> 'a" and C :: "('b \<Rightarrow> 'a) \<Rightarrow> 'c" and f
   637   assumes mono: "\<And>x. monotone (fun_ord op \<le>) op \<le> (\<lambda>f. U (F (C f)) x)"
   637   assumes mono: "\<And>x. monotone (fun_ord (\<le>)) (\<le>) (\<lambda>f. U (F (C f)) x)"
   638   and eq: "f \<equiv> C (ccpo.fixp (fun_lub Sup) (fun_ord op \<le>) (\<lambda>f. U (F (C f))))"
   638   and eq: "f \<equiv> C (ccpo.fixp (fun_lub Sup) (fun_ord (\<le>)) (\<lambda>f. U (F (C f))))"
   639   and inverse: "\<And>f. U (C f) = f"
   639   and inverse: "\<And>f. U (C f) = f"
   640 begin
   640 begin
   641 
   641 
   642 lemma fixp_preserves_mono_uc:
   642 lemma fixp_preserves_mono_uc:
   643   assumes mono2: "\<And>f. monotone ord op \<le> (U f) \<Longrightarrow> monotone ord op \<le> (U (F f))"
   643   assumes mono2: "\<And>f. monotone ord (\<le>) (U f) \<Longrightarrow> monotone ord (\<le>) (U (F f))"
   644   shows "monotone ord op \<le> (U f)"
   644   shows "monotone ord (\<le>) (U f)"
   645 using fixp_preserves_mono[OF mono mono2] by(subst eq)(simp add: inverse)
   645 using fixp_preserves_mono[OF mono mono2] by(subst eq)(simp add: inverse)
   646 
   646 
   647 lemma fixp_preserves_mcont_uc:
   647 lemma fixp_preserves_mcont_uc:
   648   assumes mcont: "\<And>f. mcont lubb ordb Sup op \<le> (U f) \<Longrightarrow> mcont lubb ordb Sup op \<le> (U (F f))"
   648   assumes mcont: "\<And>f. mcont lubb ordb Sup (\<le>) (U f) \<Longrightarrow> mcont lubb ordb Sup (\<le>) (U (F f))"
   649   shows "mcont lubb ordb Sup op \<le> (U f)"
   649   shows "mcont lubb ordb Sup (\<le>) (U f)"
   650 using fixp_preserves_mcont[OF mono mcont] by(subst eq)(simp add: inverse)
   650 using fixp_preserves_mcont[OF mono mcont] by(subst eq)(simp add: inverse)
   651 
   651 
   652 end
   652 end
   653 
   653 
   654 lemmas fixp_preserves_mono1 = fixp_preserves_mono_uc[of "\<lambda>x. x" _ "\<lambda>x. x", OF _ _ refl]
   654 lemmas fixp_preserves_mono1 = fixp_preserves_mono_uc[of "\<lambda>x. x" _ "\<lambda>x. x", OF _ _ refl]
   671 
   671 
   672 lemma (in preorder) monotone_if_bot:
   672 lemma (in preorder) monotone_if_bot:
   673   fixes bot
   673   fixes bot
   674   assumes mono: "\<And>x y. \<lbrakk> x \<le> y; \<not> (x \<le> bound) \<rbrakk> \<Longrightarrow> ord (f x) (f y)"
   674   assumes mono: "\<And>x y. \<lbrakk> x \<le> y; \<not> (x \<le> bound) \<rbrakk> \<Longrightarrow> ord (f x) (f y)"
   675   and bot: "\<And>x. \<not> x \<le> bound \<Longrightarrow> ord bot (f x)" "ord bot bot"
   675   and bot: "\<And>x. \<not> x \<le> bound \<Longrightarrow> ord bot (f x)" "ord bot bot"
   676   shows "monotone op \<le> ord (\<lambda>x. if x \<le> bound then bot else f x)"
   676   shows "monotone (\<le>) ord (\<lambda>x. if x \<le> bound then bot else f x)"
   677 by(rule monotoneI)(auto intro: bot intro: mono order_trans)
   677 by(rule monotoneI)(auto intro: bot intro: mono order_trans)
   678 
   678 
   679 lemma (in ccpo) mcont_if_bot:
   679 lemma (in ccpo) mcont_if_bot:
   680   fixes bot and lub ("\<Or>_" [900] 900) and ord (infix "\<sqsubseteq>" 60)
   680   fixes bot and lub ("\<Or>_" [900] 900) and ord (infix "\<sqsubseteq>" 60)
   681   assumes ccpo: "class.ccpo lub op \<sqsubseteq> lt"
   681   assumes ccpo: "class.ccpo lub (\<sqsubseteq>) lt"
   682   and mono: "\<And>x y. \<lbrakk> x \<le> y; \<not> x \<le> bound \<rbrakk> \<Longrightarrow> f x \<sqsubseteq> f y"
   682   and mono: "\<And>x y. \<lbrakk> x \<le> y; \<not> x \<le> bound \<rbrakk> \<Longrightarrow> f x \<sqsubseteq> f y"
   683   and cont: "\<And>Y. \<lbrakk> Complete_Partial_Order.chain op \<le> Y; Y \<noteq> {}; \<And>x. x \<in> Y \<Longrightarrow> \<not> x \<le> bound \<rbrakk> \<Longrightarrow> f (\<Squnion>Y) = \<Or>(f ` Y)"
   683   and cont: "\<And>Y. \<lbrakk> Complete_Partial_Order.chain (\<le>) Y; Y \<noteq> {}; \<And>x. x \<in> Y \<Longrightarrow> \<not> x \<le> bound \<rbrakk> \<Longrightarrow> f (\<Squnion>Y) = \<Or>(f ` Y)"
   684   and bot: "\<And>x. \<not> x \<le> bound \<Longrightarrow> bot \<sqsubseteq> f x"
   684   and bot: "\<And>x. \<not> x \<le> bound \<Longrightarrow> bot \<sqsubseteq> f x"
   685   shows "mcont Sup op \<le> lub op \<sqsubseteq> (\<lambda>x. if x \<le> bound then bot else f x)" (is "mcont _ _ _ _ ?g")
   685   shows "mcont Sup (\<le>) lub (\<sqsubseteq>) (\<lambda>x. if x \<le> bound then bot else f x)" (is "mcont _ _ _ _ ?g")
   686 proof(intro mcontI contI)
   686 proof(intro mcontI contI)
   687   interpret c: ccpo lub "op \<sqsubseteq>" lt by(fact ccpo)
   687   interpret c: ccpo lub "(\<sqsubseteq>)" lt by(fact ccpo)
   688   show "monotone op \<le> op \<sqsubseteq> ?g" by(rule monotone_if_bot)(simp_all add: mono bot)
   688   show "monotone (\<le>) (\<sqsubseteq>) ?g" by(rule monotone_if_bot)(simp_all add: mono bot)
   689 
   689 
   690   fix Y
   690   fix Y
   691   assume chain: "Complete_Partial_Order.chain op \<le> Y" and Y: "Y \<noteq> {}"
   691   assume chain: "Complete_Partial_Order.chain (\<le>) Y" and Y: "Y \<noteq> {}"
   692   show "?g (\<Squnion>Y) = \<Or>(?g ` Y)"
   692   show "?g (\<Squnion>Y) = \<Or>(?g ` Y)"
   693   proof(cases "Y \<subseteq> {x. x \<le> bound}")
   693   proof(cases "Y \<subseteq> {x. x \<le> bound}")
   694     case True
   694     case True
   695     hence "\<Squnion>Y \<le> bound" using chain by(auto intro: ccpo_Sup_least)
   695     hence "\<Squnion>Y \<le> bound" using chain by(auto intro: ccpo_Sup_least)
   696     moreover have "Y \<inter> {x. \<not> x \<le> bound} = {}" using True by auto
   696     moreover have "Y \<inter> {x. \<not> x \<le> bound} = {}" using True by auto
   697     ultimately show ?thesis using True Y
   697     ultimately show ?thesis using True Y
   698       by (auto simp add: image_constant_conv cong del: c.strong_SUP_cong)
   698       by (auto simp add: image_constant_conv cong del: c.strong_SUP_cong)
   699   next
   699   next
   700     case False
   700     case False
   701     let ?Y = "Y \<inter> {x. \<not> x \<le> bound}"
   701     let ?Y = "Y \<inter> {x. \<not> x \<le> bound}"
   702     have chain': "Complete_Partial_Order.chain op \<le> ?Y"
   702     have chain': "Complete_Partial_Order.chain (\<le>) ?Y"
   703       using chain by(rule chain_subset) simp
   703       using chain by(rule chain_subset) simp
   704 
   704 
   705     from False obtain y where ybound: "\<not> y \<le> bound" and y: "y \<in> Y" by blast
   705     from False obtain y where ybound: "\<not> y \<le> bound" and y: "y \<in> Y" by blast
   706     hence "\<not> \<Squnion>Y \<le> bound" by (metis ccpo_Sup_upper chain order.trans)
   706     hence "\<not> \<Squnion>Y \<le> bound" by (metis ccpo_Sup_upper chain order.trans)
   707     hence "?g (\<Squnion>Y) = f (\<Squnion>Y)" by simp
   707     hence "?g (\<Squnion>Y) = f (\<Squnion>Y)" by simp
   724       case True
   724       case True
   725       hence "f ` ?Y = ?g ` Y" by auto
   725       hence "f ` ?Y = ?g ` Y" by auto
   726       thus ?thesis by(rule arg_cong)
   726       thus ?thesis by(rule arg_cong)
   727     next
   727     next
   728       case False
   728       case False
   729       have chain'': "Complete_Partial_Order.chain op \<sqsubseteq> (insert bot (f ` ?Y))"
   729       have chain'': "Complete_Partial_Order.chain (\<sqsubseteq>) (insert bot (f ` ?Y))"
   730         using chain by(auto intro!: chainI bot dest: chainD intro: mono)
   730         using chain by(auto intro!: chainI bot dest: chainD intro: mono)
   731       hence chain''': "Complete_Partial_Order.chain op \<sqsubseteq> (f ` ?Y)" by(rule chain_subset) blast
   731       hence chain''': "Complete_Partial_Order.chain (\<sqsubseteq>) (f ` ?Y)" by(rule chain_subset) blast
   732       have "bot \<sqsubseteq> \<Or>(f ` ?Y)" using y ybound by(blast intro: c.order_trans[OF bot] c.ccpo_Sup_upper[OF chain'''])
   732       have "bot \<sqsubseteq> \<Or>(f ` ?Y)" using y ybound by(blast intro: c.order_trans[OF bot] c.ccpo_Sup_upper[OF chain'''])
   733       hence "\<Or>(insert bot (f ` ?Y)) \<sqsubseteq> \<Or>(f ` ?Y)" using chain''
   733       hence "\<Or>(insert bot (f ` ?Y)) \<sqsubseteq> \<Or>(f ` ?Y)" using chain''
   734         by(auto intro: c.ccpo_Sup_least c.ccpo_Sup_upper[OF chain''']) 
   734         by(auto intro: c.ccpo_Sup_least c.ccpo_Sup_upper[OF chain''']) 
   735       with _ have "\<dots> = \<Or>(insert bot (f ` ?Y))"
   735       with _ have "\<dots> = \<Or>(insert bot (f ` ?Y))"
   736         by(rule c.antisym)(blast intro: c.ccpo_Sup_least[OF chain'''] c.ccpo_Sup_upper[OF chain''])
   736         by(rule c.antisym)(blast intro: c.ccpo_Sup_least[OF chain'''] c.ccpo_Sup_upper[OF chain''])
   820   "(Q \<Longrightarrow> ccpo.admissible lub ord (\<lambda>x. P x))
   820   "(Q \<Longrightarrow> ccpo.admissible lub ord (\<lambda>x. P x))
   821   \<Longrightarrow> ccpo.admissible lub ord (\<lambda>x. Q \<longrightarrow> P x)"
   821   \<Longrightarrow> ccpo.admissible lub ord (\<lambda>x. Q \<longrightarrow> P x)"
   822 by(rule ccpo.admissibleI)(auto dest: ccpo.admissibleD)
   822 by(rule ccpo.admissibleI)(auto dest: ccpo.admissibleD)
   823 
   823 
   824 lemma admissible_not_mem' [THEN admissible_subst, cont_intro, simp]:
   824 lemma admissible_not_mem' [THEN admissible_subst, cont_intro, simp]:
   825   shows admissible_not_mem: "ccpo.admissible Union op \<subseteq> (\<lambda>A. x \<notin> A)"
   825   shows admissible_not_mem: "ccpo.admissible Union (\<subseteq>) (\<lambda>A. x \<notin> A)"
   826 by(rule ccpo.admissibleI) auto
   826 by(rule ccpo.admissibleI) auto
   827 
   827 
   828 lemma admissible_eqI:
   828 lemma admissible_eqI:
   829   assumes f: "cont luba orda lub ord (\<lambda>x. f x)"
   829   assumes f: "cont luba orda lub ord (\<lambda>x. f x)"
   830   and g: "cont luba orda lub ord (\<lambda>x. g x)"
   830   and g: "cont luba orda lub ord (\<lambda>x. g x)"
   845 by(subst iff_conv_conj_imp)(rule admissible_conj)
   845 by(subst iff_conv_conj_imp)(rule admissible_conj)
   846 
   846 
   847 context ccpo begin
   847 context ccpo begin
   848 
   848 
   849 lemma admissible_leI:
   849 lemma admissible_leI:
   850   assumes f: "mcont luba orda Sup op \<le> (\<lambda>x. f x)"
   850   assumes f: "mcont luba orda Sup (\<le>) (\<lambda>x. f x)"
   851   and g: "mcont luba orda Sup op \<le> (\<lambda>x. g x)"
   851   and g: "mcont luba orda Sup (\<le>) (\<lambda>x. g x)"
   852   shows "ccpo.admissible luba orda (\<lambda>x. f x \<le> g x)"
   852   shows "ccpo.admissible luba orda (\<lambda>x. f x \<le> g x)"
   853 proof(rule ccpo.admissibleI)
   853 proof(rule ccpo.admissibleI)
   854   fix A
   854   fix A
   855   assume chain: "Complete_Partial_Order.chain orda A"
   855   assume chain: "Complete_Partial_Order.chain orda A"
   856     and le: "\<forall>x\<in>A. f x \<le> g x"
   856     and le: "\<forall>x\<in>A. f x \<le> g x"
   857     and False: "A \<noteq> {}"
   857     and False: "A \<noteq> {}"
   858   have "f (luba A) = \<Squnion>(f ` A)" by(simp add: mcont_contD[OF f] chain False)
   858   have "f (luba A) = \<Squnion>(f ` A)" by(simp add: mcont_contD[OF f] chain False)
   859   also have "\<dots> \<le> \<Squnion>(g ` A)"
   859   also have "\<dots> \<le> \<Squnion>(g ` A)"
   860   proof(rule ccpo_Sup_least)
   860   proof(rule ccpo_Sup_least)
   861     from chain show "Complete_Partial_Order.chain op \<le> (f ` A)"
   861     from chain show "Complete_Partial_Order.chain (\<le>) (f ` A)"
   862       by(rule chain_imageI)(rule mcont_monoD[OF f])
   862       by(rule chain_imageI)(rule mcont_monoD[OF f])
   863     
   863     
   864     fix x
   864     fix x
   865     assume "x \<in> f ` A"
   865     assume "x \<in> f ` A"
   866     then obtain y where "y \<in> A" "x = f y" by blast note this(2)
   866     then obtain y where "y \<in> A" "x = f y" by blast note this(2)
   867     also have "f y \<le> g y" using le \<open>y \<in> A\<close> by simp
   867     also have "f y \<le> g y" using le \<open>y \<in> A\<close> by simp
   868     also have "Complete_Partial_Order.chain op \<le> (g ` A)"
   868     also have "Complete_Partial_Order.chain (\<le>) (g ` A)"
   869       using chain by(rule chain_imageI)(rule mcont_monoD[OF g])
   869       using chain by(rule chain_imageI)(rule mcont_monoD[OF g])
   870     hence "g y \<le> \<Squnion>(g ` A)" by(rule ccpo_Sup_upper)(simp add: \<open>y \<in> A\<close>)
   870     hence "g y \<le> \<Squnion>(g ` A)" by(rule ccpo_Sup_upper)(simp add: \<open>y \<in> A\<close>)
   871     finally show "x \<le> \<dots>" .
   871     finally show "x \<le> \<dots>" .
   872   qed
   872   qed
   873   also have "\<dots> = g (luba A)" by(simp add: mcont_contD[OF g] chain False)
   873   also have "\<dots> = g (luba A)" by(simp add: mcont_contD[OF g] chain False)
   876 
   876 
   877 end
   877 end
   878 
   878 
   879 lemma admissible_leI:
   879 lemma admissible_leI:
   880   fixes ord (infix "\<sqsubseteq>" 60) and lub ("\<Or>_" [900] 900)
   880   fixes ord (infix "\<sqsubseteq>" 60) and lub ("\<Or>_" [900] 900)
   881   assumes "class.ccpo lub op \<sqsubseteq> (mk_less op \<sqsubseteq>)"
   881   assumes "class.ccpo lub (\<sqsubseteq>) (mk_less (\<sqsubseteq>))"
   882   and "mcont luba orda lub op \<sqsubseteq> (\<lambda>x. f x)"
   882   and "mcont luba orda lub (\<sqsubseteq>) (\<lambda>x. f x)"
   883   and "mcont luba orda lub op \<sqsubseteq> (\<lambda>x. g x)"
   883   and "mcont luba orda lub (\<sqsubseteq>) (\<lambda>x. g x)"
   884   shows "ccpo.admissible luba orda (\<lambda>x. f x \<sqsubseteq> g x)"
   884   shows "ccpo.admissible luba orda (\<lambda>x. f x \<sqsubseteq> g x)"
   885 using assms by(rule ccpo.admissible_leI)
   885 using assms by(rule ccpo.admissible_leI)
   886 
   886 
   887 declare ccpo_class.admissible_leI[cont_intro]
   887 declare ccpo_class.admissible_leI[cont_intro]
   888 
   888 
   889 context ccpo begin
   889 context ccpo begin
   890 
   890 
   891 lemma admissible_not_below: "ccpo.admissible Sup op \<le> (\<lambda>x. \<not> op \<le> x y)"
   891 lemma admissible_not_below: "ccpo.admissible Sup (\<le>) (\<lambda>x. \<not> (\<le>) x y)"
   892 by(rule ccpo.admissibleI)(simp add: ccpo_Sup_below_iff)
   892 by(rule ccpo.admissibleI)(simp add: ccpo_Sup_below_iff)
   893 
   893 
   894 end
   894 end
   895 
   895 
   896 lemma (in preorder) preorder [cont_intro, simp]: "class.preorder op \<le> (mk_less op \<le>)"
   896 lemma (in preorder) preorder [cont_intro, simp]: "class.preorder (\<le>) (mk_less (\<le>))"
   897 by(unfold_locales)(auto simp add: mk_less_def intro: order_trans)
   897 by(unfold_locales)(auto simp add: mk_less_def intro: order_trans)
   898 
   898 
   899 context partial_function_definitions begin
   899 context partial_function_definitions begin
   900 
   900 
   901 lemmas [cont_intro, simp] =
   901 lemmas [cont_intro, simp] =
   916 setup \<open>Sign.map_naming Name_Space.parent_path\<close>
   916 setup \<open>Sign.map_naming Name_Space.parent_path\<close>
   917 
   917 
   918 context ccpo begin
   918 context ccpo begin
   919 
   919 
   920 lemma compactI:
   920 lemma compactI:
   921   assumes "ccpo.admissible Sup op \<le> (\<lambda>y. \<not> x \<le> y)"
   921   assumes "ccpo.admissible Sup (\<le>) (\<lambda>y. \<not> x \<le> y)"
   922   shows "ccpo.compact Sup op \<le> x"
   922   shows "ccpo.compact Sup (\<le>) x"
   923 using assms
   923 using assms
   924 proof(rule ccpo.compact.intros)
   924 proof(rule ccpo.compact.intros)
   925   have neq: "(\<lambda>y. x \<noteq> y) = (\<lambda>y. \<not> x \<le> y \<or> \<not> y \<le> x)" by(auto)
   925   have neq: "(\<lambda>y. x \<noteq> y) = (\<lambda>y. \<not> x \<le> y \<or> \<not> y \<le> x)" by(auto)
   926   show "ccpo.admissible Sup op \<le> (\<lambda>y. x \<noteq> y)"
   926   show "ccpo.admissible Sup (\<le>) (\<lambda>y. x \<noteq> y)"
   927     by(subst neq)(rule admissible_disj admissible_not_below assms)+
   927     by(subst neq)(rule admissible_disj admissible_not_below assms)+
   928 qed
   928 qed
   929 
   929 
   930 lemma compact_bot:
   930 lemma compact_bot:
   931   assumes "x = Sup {}"
   931   assumes "x = Sup {}"
   932   shows "ccpo.compact Sup op \<le> x"
   932   shows "ccpo.compact Sup (\<le>) x"
   933 proof(rule compactI)
   933 proof(rule compactI)
   934   show "ccpo.admissible Sup op \<le> (\<lambda>y. \<not> x \<le> y)" using assms
   934   show "ccpo.admissible Sup (\<le>) (\<lambda>y. \<not> x \<le> y)" using assms
   935     by(auto intro!: ccpo.admissibleI intro: ccpo_Sup_least chain_empty)
   935     by(auto intro!: ccpo.admissibleI intro: ccpo_Sup_least chain_empty)
   936 qed
   936 qed
   937 
   937 
   938 end
   938 end
   939 
   939 
   952 end
   952 end
   953 
   953 
   954 context ccpo begin
   954 context ccpo begin
   955 
   955 
   956 lemma fixp_strong_induct:
   956 lemma fixp_strong_induct:
   957   assumes [cont_intro]: "ccpo.admissible Sup op \<le> P"
   957   assumes [cont_intro]: "ccpo.admissible Sup (\<le>) P"
   958   and mono: "monotone op \<le> op \<le> f"
   958   and mono: "monotone (\<le>) (\<le>) f"
   959   and bot: "P (\<Squnion>{})"
   959   and bot: "P (\<Squnion>{})"
   960   and step: "\<And>x. \<lbrakk> x \<le> ccpo_class.fixp f; P x \<rbrakk> \<Longrightarrow> P (f x)"
   960   and step: "\<And>x. \<lbrakk> x \<le> ccpo_class.fixp f; P x \<rbrakk> \<Longrightarrow> P (f x)"
   961   shows "P (ccpo_class.fixp f)"
   961   shows "P (ccpo_class.fixp f)"
   962 proof(rule fixp_induct[where P="\<lambda>x. x \<le> ccpo_class.fixp f \<and> P x", THEN conjunct2])
   962 proof(rule fixp_induct[where P="\<lambda>x. x \<le> ccpo_class.fixp f \<and> P x", THEN conjunct2])
   963   note [cont_intro] = admissible_leI
   963   note [cont_intro] = admissible_leI
   964   show "ccpo.admissible Sup op \<le> (\<lambda>x. x \<le> ccpo_class.fixp f \<and> P x)" by simp
   964   show "ccpo.admissible Sup (\<le>) (\<lambda>x. x \<le> ccpo_class.fixp f \<and> P x)" by simp
   965 next
   965 next
   966   show "\<Squnion>{} \<le> ccpo_class.fixp f \<and> P (\<Squnion>{})"
   966   show "\<Squnion>{} \<le> ccpo_class.fixp f \<and> P (\<Squnion>{})"
   967     by(auto simp add: bot intro: ccpo_Sup_least chain_empty)
   967     by(auto simp add: bot intro: ccpo_Sup_least chain_empty)
   968 next
   968 next
   969   fix x
   969   fix x
   995 apply (simp_all add: inverse eq)
   995 apply (simp_all add: inverse eq)
   996 done
   996 done
   997 
   997 
   998 end
   998 end
   999 
   999 
  1000 subsection \<open>@{term "op ="} as order\<close>
  1000 subsection \<open>@{term "(=)"} as order\<close>
  1001 
  1001 
  1002 definition lub_singleton :: "('a set \<Rightarrow> 'a) \<Rightarrow> bool"
  1002 definition lub_singleton :: "('a set \<Rightarrow> 'a) \<Rightarrow> bool"
  1003 where "lub_singleton lub \<longleftrightarrow> (\<forall>a. lub {a} = a)"
  1003 where "lub_singleton lub \<longleftrightarrow> (\<forall>a. lub {a} = a)"
  1004 
  1004 
  1005 definition the_Sup :: "'a set \<Rightarrow> 'a"
  1005 definition the_Sup :: "'a set \<Rightarrow> 'a"
  1013 
  1013 
  1014 lemma (in partial_function_definitions) lub_singleton [cont_intro, simp]: "lub_singleton lub"
  1014 lemma (in partial_function_definitions) lub_singleton [cont_intro, simp]: "lub_singleton lub"
  1015 by(rule ccpo.lub_singleton)(rule Partial_Function.ccpo[OF partial_function_definitions_axioms])
  1015 by(rule ccpo.lub_singleton)(rule Partial_Function.ccpo[OF partial_function_definitions_axioms])
  1016 
  1016 
  1017 lemma preorder_eq [cont_intro, simp]:
  1017 lemma preorder_eq [cont_intro, simp]:
  1018   "class.preorder op = (mk_less op =)"
  1018   "class.preorder (=) (mk_less (=))"
  1019 by(unfold_locales)(simp_all add: mk_less_def)
  1019 by(unfold_locales)(simp_all add: mk_less_def)
  1020 
  1020 
  1021 lemma monotone_eqI [cont_intro]:
  1021 lemma monotone_eqI [cont_intro]:
  1022   assumes "class.preorder ord (mk_less ord)"
  1022   assumes "class.preorder ord (mk_less ord)"
  1023   shows "monotone op = ord f"
  1023   shows "monotone (=) ord f"
  1024 proof -
  1024 proof -
  1025   interpret preorder ord "mk_less ord" by fact
  1025   interpret preorder ord "mk_less ord" by fact
  1026   show ?thesis by(simp add: monotone_def)
  1026   show ?thesis by(simp add: monotone_def)
  1027 qed
  1027 qed
  1028 
  1028 
  1029 lemma cont_eqI [cont_intro]: 
  1029 lemma cont_eqI [cont_intro]: 
  1030   fixes f :: "'a \<Rightarrow> 'b"
  1030   fixes f :: "'a \<Rightarrow> 'b"
  1031   assumes "lub_singleton lub"
  1031   assumes "lub_singleton lub"
  1032   shows "cont the_Sup op = lub ord f"
  1032   shows "cont the_Sup (=) lub ord f"
  1033 proof(rule contI)
  1033 proof(rule contI)
  1034   fix Y :: "'a set"
  1034   fix Y :: "'a set"
  1035   assume "Complete_Partial_Order.chain op = Y" "Y \<noteq> {}"
  1035   assume "Complete_Partial_Order.chain (=) Y" "Y \<noteq> {}"
  1036   then obtain a where "Y = {a}" by(auto simp add: chain_def)
  1036   then obtain a where "Y = {a}" by(auto simp add: chain_def)
  1037   thus "f (the_Sup Y) = lub (f ` Y)" using assms
  1037   thus "f (the_Sup Y) = lub (f ` Y)" using assms
  1038     by(simp add: the_Sup_def lub_singleton_def)
  1038     by(simp add: the_Sup_def lub_singleton_def)
  1039 qed
  1039 qed
  1040 
  1040 
  1041 lemma mcont_eqI [cont_intro, simp]:
  1041 lemma mcont_eqI [cont_intro, simp]:
  1042   "\<lbrakk> class.preorder ord (mk_less ord); lub_singleton lub \<rbrakk>
  1042   "\<lbrakk> class.preorder ord (mk_less ord); lub_singleton lub \<rbrakk>
  1043   \<Longrightarrow> mcont the_Sup op = lub ord f"
  1043   \<Longrightarrow> mcont the_Sup (=) lub ord f"
  1044 by(simp add: mcont_def cont_eqI monotone_eqI)
  1044 by(simp add: mcont_def cont_eqI monotone_eqI)
  1045 
  1045 
  1046 subsection \<open>ccpo for products\<close>
  1046 subsection \<open>ccpo for products\<close>
  1047 
  1047 
  1048 definition prod_lub :: "('a set \<Rightarrow> 'a) \<Rightarrow> ('b set \<Rightarrow> 'b) \<Rightarrow> ('a \<times> 'b) set \<Rightarrow> 'a \<times> 'b"
  1048 definition prod_lub :: "('a set \<Rightarrow> 'a) \<Rightarrow> ('b set \<Rightarrow> 'b) \<Rightarrow> ('a \<times> 'b) set \<Rightarrow> 'a \<times> 'b"
  1240 using cont_prodD2[OF assms] by simp
  1240 using cont_prodD2[OF assms] by simp
  1241 
  1241 
  1242 context ccpo begin
  1242 context ccpo begin
  1243 
  1243 
  1244 lemma cont_prodI: 
  1244 lemma cont_prodI: 
  1245   assumes mono: "monotone (rel_prod orda ordb) op \<le> f"
  1245   assumes mono: "monotone (rel_prod orda ordb) (\<le>) f"
  1246   and cont1: "\<And>x. cont lubb ordb Sup op \<le> (\<lambda>y. f (x, y))"
  1246   and cont1: "\<And>x. cont lubb ordb Sup (\<le>) (\<lambda>y. f (x, y))"
  1247   and cont2: "\<And>y. cont luba orda Sup op \<le> (\<lambda>x. f (x, y))"
  1247   and cont2: "\<And>y. cont luba orda Sup (\<le>) (\<lambda>x. f (x, y))"
  1248   and "class.preorder orda (mk_less orda)"
  1248   and "class.preorder orda (mk_less orda)"
  1249   and "class.preorder ordb (mk_less ordb)"
  1249   and "class.preorder ordb (mk_less ordb)"
  1250   shows "cont (prod_lub luba lubb) (rel_prod orda ordb) Sup op \<le> f"
  1250   shows "cont (prod_lub luba lubb) (rel_prod orda ordb) Sup (\<le>) f"
  1251 proof(rule contI)
  1251 proof(rule contI)
  1252   interpret a: preorder orda "mk_less orda" by fact 
  1252   interpret a: preorder orda "mk_less orda" by fact 
  1253   interpret b: preorder ordb "mk_less ordb" by fact
  1253   interpret b: preorder ordb "mk_less ordb" by fact
  1254   
  1254   
  1255   fix Y
  1255   fix Y
  1269     by(auto intro: monotoneI)
  1269     by(auto intro: monotoneI)
  1270   finally show "f (prod_lub luba lubb Y) = \<Squnion>(f ` Y)" by simp
  1270   finally show "f (prod_lub luba lubb Y) = \<Squnion>(f ` Y)" by simp
  1271 qed
  1271 qed
  1272 
  1272 
  1273 lemma cont_case_prodI:
  1273 lemma cont_case_prodI:
  1274   assumes "monotone (rel_prod orda ordb) op \<le> (case_prod f)"
  1274   assumes "monotone (rel_prod orda ordb) (\<le>) (case_prod f)"
  1275   and "\<And>x. cont lubb ordb Sup op \<le> (\<lambda>y. f x y)"
  1275   and "\<And>x. cont lubb ordb Sup (\<le>) (\<lambda>y. f x y)"
  1276   and "\<And>y. cont luba orda Sup op \<le> (\<lambda>x. f x y)"
  1276   and "\<And>y. cont luba orda Sup (\<le>) (\<lambda>x. f x y)"
  1277   and "class.preorder orda (mk_less orda)"
  1277   and "class.preorder orda (mk_less orda)"
  1278   and "class.preorder ordb (mk_less ordb)"
  1278   and "class.preorder ordb (mk_less ordb)"
  1279   shows "cont (prod_lub luba lubb) (rel_prod orda ordb) Sup op \<le> (case_prod f)"
  1279   shows "cont (prod_lub luba lubb) (rel_prod orda ordb) Sup (\<le>) (case_prod f)"
  1280 by(rule cont_prodI)(simp_all add: assms)
  1280 by(rule cont_prodI)(simp_all add: assms)
  1281 
  1281 
  1282 lemma cont_case_prod_iff:
  1282 lemma cont_case_prod_iff:
  1283   "\<lbrakk> monotone (rel_prod orda ordb) op \<le> (case_prod f);
  1283   "\<lbrakk> monotone (rel_prod orda ordb) (\<le>) (case_prod f);
  1284      class.preorder orda (mk_less orda); lub_singleton luba;
  1284      class.preorder orda (mk_less orda); lub_singleton luba;
  1285      class.preorder ordb (mk_less ordb); lub_singleton lubb \<rbrakk>
  1285      class.preorder ordb (mk_less ordb); lub_singleton lubb \<rbrakk>
  1286   \<Longrightarrow> cont (prod_lub luba lubb) (rel_prod orda ordb) Sup op \<le> (case_prod f) \<longleftrightarrow>
  1286   \<Longrightarrow> cont (prod_lub luba lubb) (rel_prod orda ordb) Sup (\<le>) (case_prod f) \<longleftrightarrow>
  1287    (\<forall>x. cont lubb ordb Sup op \<le> (\<lambda>y. f x y)) \<and> (\<forall>y. cont luba orda Sup op \<le> (\<lambda>x. f x y))"
  1287    (\<forall>x. cont lubb ordb Sup (\<le>) (\<lambda>y. f x y)) \<and> (\<forall>y. cont luba orda Sup (\<le>) (\<lambda>x. f x y))"
  1288 by(blast dest: cont_case_prodD1 cont_case_prodD2 intro: cont_case_prodI)
  1288 by(blast dest: cont_case_prodD1 cont_case_prodD2 intro: cont_case_prodI)
  1289 
  1289 
  1290 end
  1290 end
  1291 
  1291 
  1292 context partial_function_definitions begin
  1292 context partial_function_definitions begin
  1337 
  1337 
  1338 subsection \<open>Complete lattices as ccpo\<close>
  1338 subsection \<open>Complete lattices as ccpo\<close>
  1339 
  1339 
  1340 context complete_lattice begin
  1340 context complete_lattice begin
  1341 
  1341 
  1342 lemma complete_lattice_ccpo: "class.ccpo Sup op \<le> op <"
  1342 lemma complete_lattice_ccpo: "class.ccpo Sup (\<le>) (<)"
  1343 by(unfold_locales)(fast intro: Sup_upper Sup_least)+
  1343 by(unfold_locales)(fast intro: Sup_upper Sup_least)+
  1344 
  1344 
  1345 lemma complete_lattice_ccpo': "class.ccpo Sup op \<le> (mk_less op \<le>)"
  1345 lemma complete_lattice_ccpo': "class.ccpo Sup (\<le>) (mk_less (\<le>))"
  1346 by(unfold_locales)(auto simp add: mk_less_def intro: Sup_upper Sup_least)
  1346 by(unfold_locales)(auto simp add: mk_less_def intro: Sup_upper Sup_least)
  1347 
  1347 
  1348 lemma complete_lattice_partial_function_definitions: 
  1348 lemma complete_lattice_partial_function_definitions: 
  1349   "partial_function_definitions op \<le> Sup"
  1349   "partial_function_definitions (\<le>) Sup"
  1350 by(unfold_locales)(auto intro: Sup_least Sup_upper)
  1350 by(unfold_locales)(auto intro: Sup_least Sup_upper)
  1351 
  1351 
  1352 lemma complete_lattice_partial_function_definitions_dual:
  1352 lemma complete_lattice_partial_function_definitions_dual:
  1353   "partial_function_definitions op \<ge> Inf"
  1353   "partial_function_definitions (\<ge>) Inf"
  1354 by(unfold_locales)(auto intro: Inf_lower Inf_greatest)
  1354 by(unfold_locales)(auto intro: Inf_lower Inf_greatest)
  1355 
  1355 
  1356 lemmas [cont_intro, simp] =
  1356 lemmas [cont_intro, simp] =
  1357   Partial_Function.ccpo[OF complete_lattice_partial_function_definitions]
  1357   Partial_Function.ccpo[OF complete_lattice_partial_function_definitions]
  1358   Partial_Function.ccpo[OF complete_lattice_partial_function_definitions_dual]
  1358   Partial_Function.ccpo[OF complete_lattice_partial_function_definitions_dual]
  1359 
  1359 
  1360 lemma mono2mono_inf:
  1360 lemma mono2mono_inf:
  1361   assumes f: "monotone ord op \<le> (\<lambda>x. f x)" 
  1361   assumes f: "monotone ord (\<le>) (\<lambda>x. f x)" 
  1362   and g: "monotone ord op \<le> (\<lambda>x. g x)"
  1362   and g: "monotone ord (\<le>) (\<lambda>x. g x)"
  1363   shows "monotone ord op \<le> (\<lambda>x. f x \<sqinter> g x)"
  1363   shows "monotone ord (\<le>) (\<lambda>x. f x \<sqinter> g x)"
  1364 by(auto 4 3 dest: monotoneD[OF f] monotoneD[OF g] intro: le_infI1 le_infI2 intro!: monotoneI)
  1364 by(auto 4 3 dest: monotoneD[OF f] monotoneD[OF g] intro: le_infI1 le_infI2 intro!: monotoneI)
  1365 
  1365 
  1366 lemma mcont_const [simp]: "mcont lub ord Sup op \<le> (\<lambda>_. c)"
  1366 lemma mcont_const [simp]: "mcont lub ord Sup (\<le>) (\<lambda>_. c)"
  1367 by(rule ccpo.mcont_const[OF complete_lattice_ccpo])
  1367 by(rule ccpo.mcont_const[OF complete_lattice_ccpo])
  1368 
  1368 
  1369 lemma mono2mono_sup:
  1369 lemma mono2mono_sup:
  1370   assumes f: "monotone ord op \<le> (\<lambda>x. f x)"
  1370   assumes f: "monotone ord (\<le>) (\<lambda>x. f x)"
  1371   and g: "monotone ord op \<le> (\<lambda>x. g x)"
  1371   and g: "monotone ord (\<le>) (\<lambda>x. g x)"
  1372   shows "monotone ord op \<le> (\<lambda>x. f x \<squnion> g x)"
  1372   shows "monotone ord (\<le>) (\<lambda>x. f x \<squnion> g x)"
  1373 by(auto 4 3 intro!: monotoneI intro: sup.coboundedI1 sup.coboundedI2 dest: monotoneD[OF f] monotoneD[OF g])
  1373 by(auto 4 3 intro!: monotoneI intro: sup.coboundedI1 sup.coboundedI2 dest: monotoneD[OF f] monotoneD[OF g])
  1374 
  1374 
  1375 lemma Sup_image_sup: 
  1375 lemma Sup_image_sup: 
  1376   assumes "Y \<noteq> {}"
  1376   assumes "Y \<noteq> {}"
  1377   shows "\<Squnion>(op \<squnion> x ` Y) = x \<squnion> \<Squnion>Y"
  1377   shows "\<Squnion>((\<squnion>) x ` Y) = x \<squnion> \<Squnion>Y"
  1378 proof(rule Sup_eqI)
  1378 proof(rule Sup_eqI)
  1379   fix y
  1379   fix y
  1380   assume "y \<in> op \<squnion> x ` Y"
  1380   assume "y \<in> (\<squnion>) x ` Y"
  1381   then obtain z where "y = x \<squnion> z" and "z \<in> Y" by blast
  1381   then obtain z where "y = x \<squnion> z" and "z \<in> Y" by blast
  1382   from \<open>z \<in> Y\<close> have "z \<le> \<Squnion>Y" by(rule Sup_upper)
  1382   from \<open>z \<in> Y\<close> have "z \<le> \<Squnion>Y" by(rule Sup_upper)
  1383   with _ show "y \<le> x \<squnion> \<Squnion>Y" unfolding \<open>y = x \<squnion> z\<close> by(rule sup_mono) simp
  1383   with _ show "y \<le> x \<squnion> \<Squnion>Y" unfolding \<open>y = x \<squnion> z\<close> by(rule sup_mono) simp
  1384 next
  1384 next
  1385   fix y
  1385   fix y
  1386   assume upper: "\<And>z. z \<in> op \<squnion> x ` Y \<Longrightarrow> z \<le> y"
  1386   assume upper: "\<And>z. z \<in> (\<squnion>) x ` Y \<Longrightarrow> z \<le> y"
  1387   show "x \<squnion> \<Squnion>Y \<le> y" unfolding Sup_insert[symmetric]
  1387   show "x \<squnion> \<Squnion>Y \<le> y" unfolding Sup_insert[symmetric]
  1388   proof(rule Sup_least)
  1388   proof(rule Sup_least)
  1389     fix z
  1389     fix z
  1390     assume "z \<in> insert x Y"
  1390     assume "z \<in> insert x Y"
  1391     from assms obtain z' where "z' \<in> Y" by blast
  1391     from assms obtain z' where "z' \<in> Y" by blast
  1394     also have "\<dots> \<le> y" by(rule upper)(auto split: if_split_asm intro: \<open>z' \<in> Y\<close>)
  1394     also have "\<dots> \<le> y" by(rule upper)(auto split: if_split_asm intro: \<open>z' \<in> Y\<close>)
  1395     finally show "z \<le> y" .
  1395     finally show "z \<le> y" .
  1396   qed
  1396   qed
  1397 qed
  1397 qed
  1398 
  1398 
  1399 lemma mcont_sup1: "mcont Sup op \<le> Sup op \<le> (\<lambda>y. x \<squnion> y)"
  1399 lemma mcont_sup1: "mcont Sup (\<le>) Sup (\<le>) (\<lambda>y. x \<squnion> y)"
  1400 by(auto 4 3 simp add: mcont_def sup.coboundedI1 sup.coboundedI2 intro!: monotoneI contI intro: Sup_image_sup[symmetric])
  1400 by(auto 4 3 simp add: mcont_def sup.coboundedI1 sup.coboundedI2 intro!: monotoneI contI intro: Sup_image_sup[symmetric])
  1401 
  1401 
  1402 lemma mcont_sup2: "mcont Sup op \<le> Sup op \<le> (\<lambda>x. x \<squnion> y)"
  1402 lemma mcont_sup2: "mcont Sup (\<le>) Sup (\<le>) (\<lambda>x. x \<squnion> y)"
  1403 by(subst sup_commute)(rule mcont_sup1)
  1403 by(subst sup_commute)(rule mcont_sup1)
  1404 
  1404 
  1405 lemma mcont2mcont_sup [cont_intro, simp]:
  1405 lemma mcont2mcont_sup [cont_intro, simp]:
  1406   "\<lbrakk> mcont lub ord Sup op \<le> (\<lambda>x. f x);
  1406   "\<lbrakk> mcont lub ord Sup (\<le>) (\<lambda>x. f x);
  1407      mcont lub ord Sup op \<le> (\<lambda>x. g x) \<rbrakk>
  1407      mcont lub ord Sup (\<le>) (\<lambda>x. g x) \<rbrakk>
  1408   \<Longrightarrow> mcont lub ord Sup op \<le> (\<lambda>x. f x \<squnion> g x)"
  1408   \<Longrightarrow> mcont lub ord Sup (\<le>) (\<lambda>x. f x \<squnion> g x)"
  1409 by(best intro: ccpo.mcont2mcont'[OF complete_lattice_ccpo] mcont_sup1 mcont_sup2 ccpo.mcont_const[OF complete_lattice_ccpo])
  1409 by(best intro: ccpo.mcont2mcont'[OF complete_lattice_ccpo] mcont_sup1 mcont_sup2 ccpo.mcont_const[OF complete_lattice_ccpo])
  1410 
  1410 
  1411 end
  1411 end
  1412 
  1412 
  1413 lemmas [cont_intro] = admissible_leI[OF complete_lattice_ccpo']
  1413 lemmas [cont_intro] = admissible_leI[OF complete_lattice_ccpo']
  1414 
  1414 
  1415 context complete_distrib_lattice begin
  1415 context complete_distrib_lattice begin
  1416 
  1416 
  1417 lemma mcont_inf1: "mcont Sup op \<le> Sup op \<le> (\<lambda>y. x \<sqinter> y)"
  1417 lemma mcont_inf1: "mcont Sup (\<le>) Sup (\<le>) (\<lambda>y. x \<sqinter> y)"
  1418 by(auto intro: monotoneI contI simp add: le_infI2 inf_Sup mcont_def)
  1418 by(auto intro: monotoneI contI simp add: le_infI2 inf_Sup mcont_def)
  1419 
  1419 
  1420 lemma mcont_inf2: "mcont Sup op \<le> Sup op \<le> (\<lambda>x. x \<sqinter> y)"
  1420 lemma mcont_inf2: "mcont Sup (\<le>) Sup (\<le>) (\<lambda>x. x \<sqinter> y)"
  1421 by(auto intro: monotoneI contI simp add: le_infI1 Sup_inf mcont_def)
  1421 by(auto intro: monotoneI contI simp add: le_infI1 Sup_inf mcont_def)
  1422 
  1422 
  1423 lemma mcont2mcont_inf [cont_intro, simp]:
  1423 lemma mcont2mcont_inf [cont_intro, simp]:
  1424   "\<lbrakk> mcont lub ord Sup op \<le> (\<lambda>x. f x);
  1424   "\<lbrakk> mcont lub ord Sup (\<le>) (\<lambda>x. f x);
  1425     mcont lub ord Sup op \<le> (\<lambda>x. g x) \<rbrakk>
  1425     mcont lub ord Sup (\<le>) (\<lambda>x. g x) \<rbrakk>
  1426   \<Longrightarrow> mcont lub ord Sup op \<le> (\<lambda>x. f x \<sqinter> g x)"
  1426   \<Longrightarrow> mcont lub ord Sup (\<le>) (\<lambda>x. f x \<sqinter> g x)"
  1427 by(best intro: ccpo.mcont2mcont'[OF complete_lattice_ccpo] mcont_inf1 mcont_inf2 ccpo.mcont_const[OF complete_lattice_ccpo])
  1427 by(best intro: ccpo.mcont2mcont'[OF complete_lattice_ccpo] mcont_inf1 mcont_inf2 ccpo.mcont_const[OF complete_lattice_ccpo])
  1428 
  1428 
  1429 end
  1429 end
  1430 
  1430 
  1431 interpretation lfp: partial_function_definitions "op \<le> :: _ :: complete_lattice \<Rightarrow> _" Sup
  1431 interpretation lfp: partial_function_definitions "(\<le>) :: _ :: complete_lattice \<Rightarrow> _" Sup
  1432 by(rule complete_lattice_partial_function_definitions)
  1432 by(rule complete_lattice_partial_function_definitions)
  1433 
  1433 
  1434 declaration \<open>Partial_Function.init "lfp" @{term lfp.fixp_fun} @{term lfp.mono_body}
  1434 declaration \<open>Partial_Function.init "lfp" @{term lfp.fixp_fun} @{term lfp.mono_body}
  1435   @{thm lfp.fixp_rule_uc} @{thm lfp.fixp_induct_uc} NONE\<close>
  1435   @{thm lfp.fixp_rule_uc} @{thm lfp.fixp_induct_uc} NONE\<close>
  1436 
  1436 
  1437 interpretation gfp: partial_function_definitions "op \<ge> :: _ :: complete_lattice \<Rightarrow> _" Inf
  1437 interpretation gfp: partial_function_definitions "(\<ge>) :: _ :: complete_lattice \<Rightarrow> _" Inf
  1438 by(rule complete_lattice_partial_function_definitions_dual)
  1438 by(rule complete_lattice_partial_function_definitions_dual)
  1439 
  1439 
  1440 declaration \<open>Partial_Function.init "gfp" @{term gfp.fixp_fun} @{term gfp.mono_body}
  1440 declaration \<open>Partial_Function.init "gfp" @{term gfp.fixp_fun} @{term gfp.mono_body}
  1441   @{thm gfp.fixp_rule_uc} @{thm gfp.fixp_induct_uc} NONE\<close>
  1441   @{thm gfp.fixp_rule_uc} @{thm gfp.fixp_induct_uc} NONE\<close>
  1442 
  1442 
  1443 lemma insert_mono [partial_function_mono]:
  1443 lemma insert_mono [partial_function_mono]:
  1444    "monotone (fun_ord op \<subseteq>) op \<subseteq> A \<Longrightarrow> monotone (fun_ord op \<subseteq>) op \<subseteq> (\<lambda>y. insert x (A y))"
  1444    "monotone (fun_ord (\<subseteq>)) (\<subseteq>) A \<Longrightarrow> monotone (fun_ord (\<subseteq>)) (\<subseteq>) (\<lambda>y. insert x (A y))"
  1445 by(rule monotoneI)(auto simp add: fun_ord_def dest: monotoneD)
  1445 by(rule monotoneI)(auto simp add: fun_ord_def dest: monotoneD)
  1446 
  1446 
  1447 lemma mono2mono_insert [THEN lfp.mono2mono, cont_intro, simp]:
  1447 lemma mono2mono_insert [THEN lfp.mono2mono, cont_intro, simp]:
  1448   shows monotone_insert: "monotone op \<subseteq> op \<subseteq> (insert x)"
  1448   shows monotone_insert: "monotone (\<subseteq>) (\<subseteq>) (insert x)"
  1449 by(rule monotoneI) blast
  1449 by(rule monotoneI) blast
  1450 
  1450 
  1451 lemma mcont2mcont_insert[THEN lfp.mcont2mcont, cont_intro, simp]:
  1451 lemma mcont2mcont_insert[THEN lfp.mcont2mcont, cont_intro, simp]:
  1452   shows mcont_insert: "mcont Union op \<subseteq> Union op \<subseteq> (insert x)"
  1452   shows mcont_insert: "mcont Union (\<subseteq>) Union (\<subseteq>) (insert x)"
  1453 by(blast intro: mcontI contI monotone_insert)
  1453 by(blast intro: mcontI contI monotone_insert)
  1454 
  1454 
  1455 lemma mono2mono_image [THEN lfp.mono2mono, cont_intro, simp]:
  1455 lemma mono2mono_image [THEN lfp.mono2mono, cont_intro, simp]:
  1456   shows monotone_image: "monotone op \<subseteq> op \<subseteq> (op ` f)"
  1456   shows monotone_image: "monotone (\<subseteq>) (\<subseteq>) ((`) f)"
  1457 by(rule monotoneI) blast
  1457 by(rule monotoneI) blast
  1458 
  1458 
  1459 lemma cont_image: "cont Union op \<subseteq> Union op \<subseteq> (op ` f)"
  1459 lemma cont_image: "cont Union (\<subseteq>) Union (\<subseteq>) ((`) f)"
  1460 by(rule contI)(auto)
  1460 by(rule contI)(auto)
  1461 
  1461 
  1462 lemma mcont2mcont_image [THEN lfp.mcont2mcont, cont_intro, simp]:
  1462 lemma mcont2mcont_image [THEN lfp.mcont2mcont, cont_intro, simp]:
  1463   shows mcont_image: "mcont Union op \<subseteq> Union op \<subseteq> (op ` f)"
  1463   shows mcont_image: "mcont Union (\<subseteq>) Union (\<subseteq>) ((`) f)"
  1464 by(blast intro: mcontI monotone_image cont_image)
  1464 by(blast intro: mcontI monotone_image cont_image)
  1465 
  1465 
  1466 context complete_lattice begin
  1466 context complete_lattice begin
  1467 
  1467 
  1468 lemma monotone_Sup [cont_intro, simp]:
  1468 lemma monotone_Sup [cont_intro, simp]:
  1469   "monotone ord op \<subseteq> f \<Longrightarrow> monotone ord op \<le> (\<lambda>x. \<Squnion>f x)"
  1469   "monotone ord (\<subseteq>) f \<Longrightarrow> monotone ord (\<le>) (\<lambda>x. \<Squnion>f x)"
  1470 by(blast intro: monotoneI Sup_least Sup_upper dest: monotoneD)
  1470 by(blast intro: monotoneI Sup_least Sup_upper dest: monotoneD)
  1471 
  1471 
  1472 lemma cont_Sup:
  1472 lemma cont_Sup:
  1473   assumes "cont lub ord Union op \<subseteq> f"
  1473   assumes "cont lub ord Union (\<subseteq>) f"
  1474   shows "cont lub ord Sup op \<le> (\<lambda>x. \<Squnion>f x)"
  1474   shows "cont lub ord Sup (\<le>) (\<lambda>x. \<Squnion>f x)"
  1475 apply(rule contI)
  1475 apply(rule contI)
  1476 apply(simp add: contD[OF assms])
  1476 apply(simp add: contD[OF assms])
  1477 apply(blast intro: Sup_least Sup_upper order_trans antisym)
  1477 apply(blast intro: Sup_least Sup_upper order_trans antisym)
  1478 done
  1478 done
  1479 
  1479 
  1480 lemma mcont_Sup: "mcont lub ord Union op \<subseteq> f \<Longrightarrow> mcont lub ord Sup op \<le> (\<lambda>x. \<Squnion>f x)"
  1480 lemma mcont_Sup: "mcont lub ord Union (\<subseteq>) f \<Longrightarrow> mcont lub ord Sup (\<le>) (\<lambda>x. \<Squnion>f x)"
  1481 unfolding mcont_def by(blast intro: monotone_Sup cont_Sup)
  1481 unfolding mcont_def by(blast intro: monotone_Sup cont_Sup)
  1482 
  1482 
  1483 lemma monotone_SUP:
  1483 lemma monotone_SUP:
  1484   "\<lbrakk> monotone ord op \<subseteq> f; \<And>y. monotone ord op \<le> (\<lambda>x. g x y) \<rbrakk> \<Longrightarrow> monotone ord op \<le> (\<lambda>x. \<Squnion>y\<in>f x. g x y)"
  1484   "\<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)"
  1485 by(rule monotoneI)(blast dest: monotoneD intro: Sup_upper order_trans intro!: Sup_least)
  1485 by(rule monotoneI)(blast dest: monotoneD intro: Sup_upper order_trans intro!: Sup_least)
  1486 
  1486 
  1487 lemma monotone_SUP2:
  1487 lemma monotone_SUP2:
  1488   "(\<And>y. y \<in> A \<Longrightarrow> monotone ord op \<le> (\<lambda>x. g x y)) \<Longrightarrow> monotone ord op \<le> (\<lambda>x. \<Squnion>y\<in>A. g x y)"
  1488   "(\<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)"
  1489 by(rule monotoneI)(blast intro: Sup_upper order_trans dest: monotoneD intro!: Sup_least)
  1489 by(rule monotoneI)(blast intro: Sup_upper order_trans dest: monotoneD intro!: Sup_least)
  1490 
  1490 
  1491 lemma cont_SUP:
  1491 lemma cont_SUP:
  1492   assumes f: "mcont lub ord Union op \<subseteq> f"
  1492   assumes f: "mcont lub ord Union (\<subseteq>) f"
  1493   and g: "\<And>y. mcont lub ord Sup op \<le> (\<lambda>x. g x y)"
  1493   and g: "\<And>y. mcont lub ord Sup (\<le>) (\<lambda>x. g x y)"
  1494   shows "cont lub ord Sup op \<le> (\<lambda>x. \<Squnion>y\<in>f x. g x y)"
  1494   shows "cont lub ord Sup (\<le>) (\<lambda>x. \<Squnion>y\<in>f x. g x y)"
  1495 proof(rule contI)
  1495 proof(rule contI)
  1496   fix Y
  1496   fix Y
  1497   assume chain: "Complete_Partial_Order.chain ord Y"
  1497   assume chain: "Complete_Partial_Order.chain ord Y"
  1498     and Y: "Y \<noteq> {}"
  1498     and Y: "Y \<noteq> {}"
  1499   show "\<Squnion>(g (lub Y) ` f (lub Y)) = \<Squnion>((\<lambda>x. \<Squnion>(g x ` f x)) ` Y)" (is "?lhs = ?rhs")
  1499   show "\<Squnion>(g (lub Y) ` f (lub Y)) = \<Squnion>((\<lambda>x. \<Squnion>(g x ` f x)) ` Y)" (is "?lhs = ?rhs")
  1553     qed
  1553     qed
  1554   qed
  1554   qed
  1555 qed
  1555 qed
  1556 
  1556 
  1557 lemma mcont_SUP [cont_intro, simp]:
  1557 lemma mcont_SUP [cont_intro, simp]:
  1558   "\<lbrakk> mcont lub ord Union op \<subseteq> f; \<And>y. mcont lub ord Sup op \<le> (\<lambda>x. g x y) \<rbrakk>
  1558   "\<lbrakk> mcont lub ord Union (\<subseteq>) f; \<And>y. mcont lub ord Sup (\<le>) (\<lambda>x. g x y) \<rbrakk>
  1559   \<Longrightarrow> mcont lub ord Sup op \<le> (\<lambda>x. \<Squnion>y\<in>f x. g x y)"
  1559   \<Longrightarrow> mcont lub ord Sup (\<le>) (\<lambda>x. \<Squnion>y\<in>f x. g x y)"
  1560 by(blast intro: mcontI cont_SUP monotone_SUP mcont_mono)
  1560 by(blast intro: mcontI cont_SUP monotone_SUP mcont_mono)
  1561 
  1561 
  1562 end
  1562 end
  1563 
  1563 
  1564 lemma admissible_Ball [cont_intro, simp]:
  1564 lemma admissible_Ball [cont_intro, simp]:
  1565   "\<lbrakk> \<And>x. ccpo.admissible lub ord (\<lambda>A. P A x);
  1565   "\<lbrakk> \<And>x. ccpo.admissible lub ord (\<lambda>A. P A x);
  1566      mcont lub ord Union op \<subseteq> f;
  1566      mcont lub ord Union (\<subseteq>) f;
  1567      class.ccpo lub ord (mk_less ord) \<rbrakk>
  1567      class.ccpo lub ord (mk_less ord) \<rbrakk>
  1568   \<Longrightarrow> ccpo.admissible lub ord (\<lambda>A. \<forall>x\<in>f A. P A x)"
  1568   \<Longrightarrow> ccpo.admissible lub ord (\<lambda>A. \<forall>x\<in>f A. P A x)"
  1569 unfolding Ball_def by simp
  1569 unfolding Ball_def by simp
  1570 
  1570 
  1571 lemma admissible_Bex'[THEN admissible_subst, cont_intro, simp]:
  1571 lemma admissible_Bex'[THEN admissible_subst, cont_intro, simp]:
  1572   shows admissible_Bex: "ccpo.admissible Union op \<subseteq> (\<lambda>A. \<exists>x\<in>A. P x)"
  1572   shows admissible_Bex: "ccpo.admissible Union (\<subseteq>) (\<lambda>A. \<exists>x\<in>A. P x)"
  1573 by(rule ccpo.admissibleI)(auto)
  1573 by(rule ccpo.admissibleI)(auto)
  1574 
  1574 
  1575 subsection \<open>Parallel fixpoint induction\<close>
  1575 subsection \<open>Parallel fixpoint induction\<close>
  1576 
  1576 
  1577 context
  1577 context