src/HOL/Inductive.thy
 author wenzelm Tue Jul 05 23:39:49 2016 +0200 (2016-07-05) changeset 63400 249fa34faba2 parent 61955 e96292f32c3c child 63540 f8652d0534fa permissions -rw-r--r--
misc tuning and modernization;
```     1 (*  Title:      HOL/Inductive.thy
```
```     2     Author:     Markus Wenzel, TU Muenchen
```
```     3 *)
```
```     4
```
```     5 section \<open>Knaster-Tarski Fixpoint Theorem and inductive definitions\<close>
```
```     6
```
```     7 theory Inductive
```
```     8 imports Complete_Lattices Ctr_Sugar
```
```     9 keywords
```
```    10   "inductive" "coinductive" "inductive_cases" "inductive_simps" :: thy_decl and
```
```    11   "monos" and
```
```    12   "print_inductives" :: diag and
```
```    13   "old_rep_datatype" :: thy_goal and
```
```    14   "primrec" :: thy_decl
```
```    15 begin
```
```    16
```
```    17 subsection \<open>Least and greatest fixed points\<close>
```
```    18
```
```    19 context complete_lattice
```
```    20 begin
```
```    21
```
```    22 definition lfp :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a"  \<comment> \<open>least fixed point\<close>
```
```    23   where "lfp f = Inf {u. f u \<le> u}"
```
```    24
```
```    25 definition gfp :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a"  \<comment> \<open>greatest fixed point\<close>
```
```    26   where "gfp f = Sup {u. u \<le> f u}"
```
```    27
```
```    28
```
```    29 subsection \<open>Proof of Knaster-Tarski Theorem using @{term lfp}\<close>
```
```    30
```
```    31 text \<open>@{term "lfp f"} is the least upper bound of the set @{term "{u. f u \<le> u}"}\<close>
```
```    32
```
```    33 lemma lfp_lowerbound: "f A \<le> A \<Longrightarrow> lfp f \<le> A"
```
```    34   by (auto simp add: lfp_def intro: Inf_lower)
```
```    35
```
```    36 lemma lfp_greatest: "(\<And>u. f u \<le> u \<Longrightarrow> A \<le> u) \<Longrightarrow> A \<le> lfp f"
```
```    37   by (auto simp add: lfp_def intro: Inf_greatest)
```
```    38
```
```    39 end
```
```    40
```
```    41 lemma lfp_lemma2: "mono f \<Longrightarrow> f (lfp f) \<le> lfp f"
```
```    42   by (iprover intro: lfp_greatest order_trans monoD lfp_lowerbound)
```
```    43
```
```    44 lemma lfp_lemma3: "mono f \<Longrightarrow> lfp f \<le> f (lfp f)"
```
```    45   by (iprover intro: lfp_lemma2 monoD lfp_lowerbound)
```
```    46
```
```    47 lemma lfp_unfold: "mono f \<Longrightarrow> lfp f = f (lfp f)"
```
```    48   by (iprover intro: order_antisym lfp_lemma2 lfp_lemma3)
```
```    49
```
```    50 lemma lfp_const: "lfp (\<lambda>x. t) = t"
```
```    51   by (rule lfp_unfold) (simp add: mono_def)
```
```    52
```
```    53
```
```    54 subsection \<open>General induction rules for least fixed points\<close>
```
```    55
```
```    56 lemma lfp_ordinal_induct [case_names mono step union]:
```
```    57   fixes f :: "'a::complete_lattice \<Rightarrow> 'a"
```
```    58   assumes mono: "mono f"
```
```    59     and P_f: "\<And>S. P S \<Longrightarrow> S \<le> lfp f \<Longrightarrow> P (f S)"
```
```    60     and P_Union: "\<And>M. \<forall>S\<in>M. P S \<Longrightarrow> P (Sup M)"
```
```    61   shows "P (lfp f)"
```
```    62 proof -
```
```    63   let ?M = "{S. S \<le> lfp f \<and> P S}"
```
```    64   have "P (Sup ?M)" using P_Union by simp
```
```    65   also have "Sup ?M = lfp f"
```
```    66   proof (rule antisym)
```
```    67     show "Sup ?M \<le> lfp f" by (blast intro: Sup_least)
```
```    68     then have "f (Sup ?M) \<le> f (lfp f)"
```
```    69       by (rule mono [THEN monoD])
```
```    70     then have "f (Sup ?M) \<le> lfp f"
```
```    71       using mono [THEN lfp_unfold] by simp
```
```    72     then have "f (Sup ?M) \<in> ?M"
```
```    73       using P_Union by simp (intro P_f Sup_least, auto)
```
```    74     then have "f (Sup ?M) \<le> Sup ?M"
```
```    75       by (rule Sup_upper)
```
```    76     then show "lfp f \<le> Sup ?M"
```
```    77       by (rule lfp_lowerbound)
```
```    78   qed
```
```    79   finally show ?thesis .
```
```    80 qed
```
```    81
```
```    82 theorem lfp_induct:
```
```    83   assumes mono: "mono f"
```
```    84     and ind: "f (inf (lfp f) P) \<le> P"
```
```    85   shows "lfp f \<le> P"
```
```    86 proof (induction rule: lfp_ordinal_induct)
```
```    87   case (step S)
```
```    88   then show ?case
```
```    89     by (intro order_trans[OF _ ind] monoD[OF mono]) auto
```
```    90 qed (auto intro: mono Sup_least)
```
```    91
```
```    92 lemma lfp_induct_set:
```
```    93   assumes lfp: "a \<in> lfp f"
```
```    94     and mono: "mono f"
```
```    95     and hyp: "\<And>x. x \<in> f (lfp f \<inter> {x. P x}) \<Longrightarrow> P x"
```
```    96   shows "P a"
```
```    97   by (rule lfp_induct [THEN subsetD, THEN CollectD, OF mono _ lfp]) (auto intro: hyp)
```
```    98
```
```    99 lemma lfp_ordinal_induct_set:
```
```   100   assumes mono: "mono f"
```
```   101     and P_f: "\<And>S. P S \<Longrightarrow> P (f S)"
```
```   102     and P_Union: "\<And>M. \<forall>S\<in>M. P S \<Longrightarrow> P (\<Union>M)"
```
```   103   shows "P (lfp f)"
```
```   104   using assms by (rule lfp_ordinal_induct)
```
```   105
```
```   106
```
```   107 text \<open>Definition forms of \<open>lfp_unfold\<close> and \<open>lfp_induct\<close>, to control unfolding.\<close>
```
```   108
```
```   109 lemma def_lfp_unfold: "h \<equiv> lfp f \<Longrightarrow> mono f \<Longrightarrow> h = f h"
```
```   110   by (auto intro!: lfp_unfold)
```
```   111
```
```   112 lemma def_lfp_induct: "A \<equiv> lfp f \<Longrightarrow> mono f \<Longrightarrow> f (inf A P) \<le> P \<Longrightarrow> A \<le> P"
```
```   113   by (blast intro: lfp_induct)
```
```   114
```
```   115 lemma def_lfp_induct_set:
```
```   116   "A \<equiv> lfp f \<Longrightarrow> mono f \<Longrightarrow> a \<in> A \<Longrightarrow> (\<And>x. x \<in> f (A \<inter> {x. P x}) \<Longrightarrow> P x) \<Longrightarrow> P a"
```
```   117   by (blast intro: lfp_induct_set)
```
```   118
```
```   119 text \<open>Monotonicity of \<open>lfp\<close>!\<close>
```
```   120 lemma lfp_mono: "(\<And>Z. f Z \<le> g Z) \<Longrightarrow> lfp f \<le> lfp g"
```
```   121   by (rule lfp_lowerbound [THEN lfp_greatest]) (blast intro: order_trans)
```
```   122
```
```   123
```
```   124 subsection \<open>Proof of Knaster-Tarski Theorem using \<open>gfp\<close>\<close>
```
```   125
```
```   126 text \<open>@{term "gfp f"} is the greatest lower bound of the set @{term "{u. u \<le> f u}"}\<close>
```
```   127
```
```   128 lemma gfp_upperbound: "X \<le> f X \<Longrightarrow> X \<le> gfp f"
```
```   129   by (auto simp add: gfp_def intro: Sup_upper)
```
```   130
```
```   131 lemma gfp_least: "(\<And>u. u \<le> f u \<Longrightarrow> u \<le> X) \<Longrightarrow> gfp f \<le> X"
```
```   132   by (auto simp add: gfp_def intro: Sup_least)
```
```   133
```
```   134 lemma gfp_lemma2: "mono f \<Longrightarrow> gfp f \<le> f (gfp f)"
```
```   135   by (iprover intro: gfp_least order_trans monoD gfp_upperbound)
```
```   136
```
```   137 lemma gfp_lemma3: "mono f \<Longrightarrow> f (gfp f) \<le> gfp f"
```
```   138   by (iprover intro: gfp_lemma2 monoD gfp_upperbound)
```
```   139
```
```   140 lemma gfp_unfold: "mono f \<Longrightarrow> gfp f = f (gfp f)"
```
```   141   by (iprover intro: order_antisym gfp_lemma2 gfp_lemma3)
```
```   142
```
```   143
```
```   144 subsection \<open>Coinduction rules for greatest fixed points\<close>
```
```   145
```
```   146 text \<open>Weak version.\<close>
```
```   147 lemma weak_coinduct: "a \<in> X \<Longrightarrow> X \<subseteq> f X \<Longrightarrow> a \<in> gfp f"
```
```   148   by (rule gfp_upperbound [THEN subsetD]) auto
```
```   149
```
```   150 lemma weak_coinduct_image: "a \<in> X \<Longrightarrow> g`X \<subseteq> f (g`X) \<Longrightarrow> g a \<in> gfp f"
```
```   151   apply (erule gfp_upperbound [THEN subsetD])
```
```   152   apply (erule imageI)
```
```   153   done
```
```   154
```
```   155 lemma coinduct_lemma: "X \<le> f (sup X (gfp f)) \<Longrightarrow> mono f \<Longrightarrow> sup X (gfp f) \<le> f (sup X (gfp f))"
```
```   156   apply (frule gfp_lemma2)
```
```   157   apply (drule mono_sup)
```
```   158   apply (rule le_supI)
```
```   159   apply assumption
```
```   160   apply (rule order_trans)
```
```   161   apply (rule order_trans)
```
```   162   apply assumption
```
```   163   apply (rule sup_ge2)
```
```   164   apply assumption
```
```   165   done
```
```   166
```
```   167 text \<open>Strong version, thanks to Coen and Frost.\<close>
```
```   168 lemma coinduct_set: "mono f \<Longrightarrow> a \<in> X \<Longrightarrow> X \<subseteq> f (X \<union> gfp f) \<Longrightarrow> a \<in> gfp f"
```
```   169   by (rule weak_coinduct[rotated], rule coinduct_lemma) blast+
```
```   170
```
```   171 lemma gfp_fun_UnI2: "mono f \<Longrightarrow> a \<in> gfp f \<Longrightarrow> a \<in> f (X \<union> gfp f)"
```
```   172   by (blast dest: gfp_lemma2 mono_Un)
```
```   173
```
```   174 lemma gfp_ordinal_induct[case_names mono step union]:
```
```   175   fixes f :: "'a::complete_lattice \<Rightarrow> 'a"
```
```   176   assumes mono: "mono f"
```
```   177     and P_f: "\<And>S. P S \<Longrightarrow> gfp f \<le> S \<Longrightarrow> P (f S)"
```
```   178     and P_Union: "\<And>M. \<forall>S\<in>M. P S \<Longrightarrow> P (Inf M)"
```
```   179   shows "P (gfp f)"
```
```   180 proof -
```
```   181   let ?M = "{S. gfp f \<le> S \<and> P S}"
```
```   182   have "P (Inf ?M)" using P_Union by simp
```
```   183   also have "Inf ?M = gfp f"
```
```   184   proof (rule antisym)
```
```   185     show "gfp f \<le> Inf ?M"
```
```   186       by (blast intro: Inf_greatest)
```
```   187     then have "f (gfp f) \<le> f (Inf ?M)"
```
```   188       by (rule mono [THEN monoD])
```
```   189     then have "gfp f \<le> f (Inf ?M)"
```
```   190       using mono [THEN gfp_unfold] by simp
```
```   191     then have "f (Inf ?M) \<in> ?M"
```
```   192       using P_Union by simp (intro P_f Inf_greatest, auto)
```
```   193     then have "Inf ?M \<le> f (Inf ?M)"
```
```   194       by (rule Inf_lower)
```
```   195     then show "Inf ?M \<le> gfp f"
```
```   196       by (rule gfp_upperbound)
```
```   197   qed
```
```   198   finally show ?thesis .
```
```   199 qed
```
```   200
```
```   201 lemma coinduct:
```
```   202   assumes mono: "mono f"
```
```   203     and ind: "X \<le> f (sup X (gfp f))"
```
```   204   shows "X \<le> gfp f"
```
```   205 proof (induction rule: gfp_ordinal_induct)
```
```   206   case (step S) then show ?case
```
```   207     by (intro order_trans[OF ind _] monoD[OF mono]) auto
```
```   208 qed (auto intro: mono Inf_greatest)
```
```   209
```
```   210
```
```   211 subsection \<open>Even Stronger Coinduction Rule, by Martin Coen\<close>
```
```   212
```
```   213 text \<open>Weakens the condition @{term "X \<subseteq> f X"} to one expressed using both
```
```   214   @{term lfp} and @{term gfp}\<close>
```
```   215 lemma coinduct3_mono_lemma: "mono f \<Longrightarrow> mono (\<lambda>x. f x \<union> X \<union> B)"
```
```   216   by (iprover intro: subset_refl monoI Un_mono monoD)
```
```   217
```
```   218 lemma coinduct3_lemma:
```
```   219   "X \<subseteq> f (lfp (\<lambda>x. f x \<union> X \<union> gfp f)) \<Longrightarrow> mono f \<Longrightarrow>
```
```   220     lfp (\<lambda>x. f x \<union> X \<union> gfp f) \<subseteq> f (lfp (\<lambda>x. f x \<union> X \<union> gfp f))"
```
```   221   apply (rule subset_trans)
```
```   222   apply (erule coinduct3_mono_lemma [THEN lfp_lemma3])
```
```   223   apply (rule Un_least [THEN Un_least])
```
```   224   apply (rule subset_refl, assumption)
```
```   225   apply (rule gfp_unfold [THEN equalityD1, THEN subset_trans], assumption)
```
```   226   apply (rule monoD, assumption)
```
```   227   apply (subst coinduct3_mono_lemma [THEN lfp_unfold], auto)
```
```   228   done
```
```   229
```
```   230 lemma coinduct3: "mono f \<Longrightarrow> a \<in> X \<Longrightarrow> X \<subseteq> f (lfp (\<lambda>x. f x \<union> X \<union> gfp f)) \<Longrightarrow> a \<in> gfp f"
```
```   231   apply (rule coinduct3_lemma [THEN [2] weak_coinduct])
```
```   232   apply (rule coinduct3_mono_lemma [THEN lfp_unfold, THEN ssubst])
```
```   233   apply simp_all
```
```   234   done
```
```   235
```
```   236 text  \<open>Definition forms of \<open>gfp_unfold\<close> and \<open>coinduct\<close>, to control unfolding.\<close>
```
```   237
```
```   238 lemma def_gfp_unfold: "A \<equiv> gfp f \<Longrightarrow> mono f \<Longrightarrow> A = f A"
```
```   239   by (auto intro!: gfp_unfold)
```
```   240
```
```   241 lemma def_coinduct: "A \<equiv> gfp f \<Longrightarrow> mono f \<Longrightarrow> X \<le> f (sup X A) \<Longrightarrow> X \<le> A"
```
```   242   by (iprover intro!: coinduct)
```
```   243
```
```   244 lemma def_coinduct_set: "A \<equiv> gfp f \<Longrightarrow> mono f \<Longrightarrow> a \<in> X \<Longrightarrow> X \<subseteq> f (X \<union> A) \<Longrightarrow> a \<in> A"
```
```   245   by (auto intro!: coinduct_set)
```
```   246
```
```   247 lemma def_Collect_coinduct:
```
```   248   "A \<equiv> gfp (\<lambda>w. Collect (P w)) \<Longrightarrow> mono (\<lambda>w. Collect (P w)) \<Longrightarrow> a \<in> X \<Longrightarrow>
```
```   249     (\<And>z. z \<in> X \<Longrightarrow> P (X \<union> A) z) \<Longrightarrow> a \<in> A"
```
```   250   by (erule def_coinduct_set) auto
```
```   251
```
```   252 lemma def_coinduct3: "A \<equiv> gfp f \<Longrightarrow> mono f \<Longrightarrow> a \<in> X \<Longrightarrow> X \<subseteq> f (lfp (\<lambda>x. f x \<union> X \<union> A)) \<Longrightarrow> a \<in> A"
```
```   253   by (auto intro!: coinduct3)
```
```   254
```
```   255 text \<open>Monotonicity of @{term gfp}!\<close>
```
```   256 lemma gfp_mono: "(\<And>Z. f Z \<le> g Z) \<Longrightarrow> gfp f \<le> gfp g"
```
```   257   by (rule gfp_upperbound [THEN gfp_least]) (blast intro: order_trans)
```
```   258
```
```   259
```
```   260 subsection \<open>Rules for fixed point calculus\<close>
```
```   261
```
```   262 lemma lfp_rolling:
```
```   263   assumes "mono g" "mono f"
```
```   264   shows "g (lfp (\<lambda>x. f (g x))) = lfp (\<lambda>x. g (f x))"
```
```   265 proof (rule antisym)
```
```   266   have *: "mono (\<lambda>x. f (g x))"
```
```   267     using assms by (auto simp: mono_def)
```
```   268   show "lfp (\<lambda>x. g (f x)) \<le> g (lfp (\<lambda>x. f (g x)))"
```
```   269     by (rule lfp_lowerbound) (simp add: lfp_unfold[OF *, symmetric])
```
```   270   show "g (lfp (\<lambda>x. f (g x))) \<le> lfp (\<lambda>x. g (f x))"
```
```   271   proof (rule lfp_greatest)
```
```   272     fix u
```
```   273     assume "g (f u) \<le> u"
```
```   274     moreover then have "g (lfp (\<lambda>x. f (g x))) \<le> g (f u)"
```
```   275       by (intro assms[THEN monoD] lfp_lowerbound)
```
```   276     ultimately show "g (lfp (\<lambda>x. f (g x))) \<le> u"
```
```   277       by auto
```
```   278   qed
```
```   279 qed
```
```   280
```
```   281 lemma lfp_lfp:
```
```   282   assumes f: "\<And>x y w z. x \<le> y \<Longrightarrow> w \<le> z \<Longrightarrow> f x w \<le> f y z"
```
```   283   shows "lfp (\<lambda>x. lfp (f x)) = lfp (\<lambda>x. f x x)"
```
```   284 proof (rule antisym)
```
```   285   have *: "mono (\<lambda>x. f x x)"
```
```   286     by (blast intro: monoI f)
```
```   287   show "lfp (\<lambda>x. lfp (f x)) \<le> lfp (\<lambda>x. f x x)"
```
```   288     by (intro lfp_lowerbound) (simp add: lfp_unfold[OF *, symmetric])
```
```   289   show "lfp (\<lambda>x. lfp (f x)) \<ge> lfp (\<lambda>x. f x x)" (is "?F \<ge> _")
```
```   290   proof (intro lfp_lowerbound)
```
```   291     have *: "?F = lfp (f ?F)"
```
```   292       by (rule lfp_unfold) (blast intro: monoI lfp_mono f)
```
```   293     also have "\<dots> = f ?F (lfp (f ?F))"
```
```   294       by (rule lfp_unfold) (blast intro: monoI lfp_mono f)
```
```   295     finally show "f ?F ?F \<le> ?F"
```
```   296       by (simp add: *[symmetric])
```
```   297   qed
```
```   298 qed
```
```   299
```
```   300 lemma gfp_rolling:
```
```   301   assumes "mono g" "mono f"
```
```   302   shows "g (gfp (\<lambda>x. f (g x))) = gfp (\<lambda>x. g (f x))"
```
```   303 proof (rule antisym)
```
```   304   have *: "mono (\<lambda>x. f (g x))"
```
```   305     using assms by (auto simp: mono_def)
```
```   306   show "g (gfp (\<lambda>x. f (g x))) \<le> gfp (\<lambda>x. g (f x))"
```
```   307     by (rule gfp_upperbound) (simp add: gfp_unfold[OF *, symmetric])
```
```   308   show "gfp (\<lambda>x. g (f x)) \<le> g (gfp (\<lambda>x. f (g x)))"
```
```   309   proof (rule gfp_least)
```
```   310     fix u assume "u \<le> g (f u)"
```
```   311     moreover then have "g (f u) \<le> g (gfp (\<lambda>x. f (g x)))"
```
```   312       by (intro assms[THEN monoD] gfp_upperbound)
```
```   313     ultimately show "u \<le> g (gfp (\<lambda>x. f (g x)))"
```
```   314       by auto
```
```   315   qed
```
```   316 qed
```
```   317
```
```   318 lemma gfp_gfp:
```
```   319   assumes f: "\<And>x y w z. x \<le> y \<Longrightarrow> w \<le> z \<Longrightarrow> f x w \<le> f y z"
```
```   320   shows "gfp (\<lambda>x. gfp (f x)) = gfp (\<lambda>x. f x x)"
```
```   321 proof (rule antisym)
```
```   322   have *: "mono (\<lambda>x. f x x)"
```
```   323     by (blast intro: monoI f)
```
```   324   show "gfp (\<lambda>x. f x x) \<le> gfp (\<lambda>x. gfp (f x))"
```
```   325     by (intro gfp_upperbound) (simp add: gfp_unfold[OF *, symmetric])
```
```   326   show "gfp (\<lambda>x. gfp (f x)) \<le> gfp (\<lambda>x. f x x)" (is "?F \<le> _")
```
```   327   proof (intro gfp_upperbound)
```
```   328     have *: "?F = gfp (f ?F)"
```
```   329       by (rule gfp_unfold) (blast intro: monoI gfp_mono f)
```
```   330     also have "\<dots> = f ?F (gfp (f ?F))"
```
```   331       by (rule gfp_unfold) (blast intro: monoI gfp_mono f)
```
```   332     finally show "?F \<le> f ?F ?F"
```
```   333       by (simp add: *[symmetric])
```
```   334   qed
```
```   335 qed
```
```   336
```
```   337
```
```   338 subsection \<open>Inductive predicates and sets\<close>
```
```   339
```
```   340 text \<open>Package setup.\<close>
```
```   341
```
```   342 lemmas basic_monos =
```
```   343   subset_refl imp_refl disj_mono conj_mono ex_mono all_mono if_bool_eq_conj
```
```   344   Collect_mono in_mono vimage_mono
```
```   345
```
```   346 ML_file "Tools/inductive.ML"
```
```   347
```
```   348 lemmas [mono] =
```
```   349   imp_refl disj_mono conj_mono ex_mono all_mono if_bool_eq_conj
```
```   350   imp_mono not_mono
```
```   351   Ball_def Bex_def
```
```   352   induct_rulify_fallback
```
```   353
```
```   354
```
```   355 subsection \<open>Inductive datatypes and primitive recursion\<close>
```
```   356
```
```   357 text \<open>Package setup.\<close>
```
```   358
```
```   359 ML_file "Tools/Old_Datatype/old_datatype_aux.ML"
```
```   360 ML_file "Tools/Old_Datatype/old_datatype_prop.ML"
```
```   361 ML_file "Tools/Old_Datatype/old_datatype_data.ML"
```
```   362 ML_file "Tools/Old_Datatype/old_rep_datatype.ML"
```
```   363 ML_file "Tools/Old_Datatype/old_datatype_codegen.ML"
```
```   364 ML_file "Tools/Old_Datatype/old_primrec.ML"
```
```   365
```
```   366 ML_file "Tools/BNF/bnf_fp_rec_sugar_util.ML"
```
```   367 ML_file "Tools/BNF/bnf_lfp_rec_sugar.ML"
```
```   368
```
```   369 text \<open>Lambda-abstractions with pattern matching:\<close>
```
```   370 syntax (ASCII)
```
```   371   "_lam_pats_syntax" :: "cases_syn \<Rightarrow> 'a \<Rightarrow> 'b"  ("(%_)" 10)
```
```   372 syntax
```
```   373   "_lam_pats_syntax" :: "cases_syn \<Rightarrow> 'a \<Rightarrow> 'b"  ("(\<lambda>_)" 10)
```
```   374 parse_translation \<open>
```
```   375   let
```
```   376     fun fun_tr ctxt [cs] =
```
```   377       let
```
```   378         val x = Syntax.free (fst (Name.variant "x" (Term.declare_term_frees cs Name.context)));
```
```   379         val ft = Case_Translation.case_tr true ctxt [x, cs];
```
```   380       in lambda x ft end
```
```   381   in [(@{syntax_const "_lam_pats_syntax"}, fun_tr)] end
```
```   382 \<close>
```
```   383
```
```   384 end
```