merged
authorAndreas Lochbihler
Fri, 01 Jun 2012 08:32:26 +0200
changeset 4906960bcc6cf17d6
parent 49068 9bc78a08ff0a
parent 49065 72acba14c12b
child 49070 9819d49d2f39
child 49073 11a732f7d79f
child 49078 f02b4302d5dd
merged
src/HOL/IsaMakefile
     1.1 --- a/src/HOL/Int.thy	Thu May 31 17:10:43 2012 +0200
     1.2 +++ b/src/HOL/Int.thy	Fri Jun 01 08:32:26 2012 +0200
     1.3 @@ -6,193 +6,106 @@
     1.4  header {* The Integers as Equivalence Classes over Pairs of Natural Numbers *} 
     1.5  
     1.6  theory Int
     1.7 -imports Equiv_Relations Wellfounded
     1.8 +imports Equiv_Relations Wellfounded Quotient
     1.9  uses
    1.10    ("Tools/int_arith.ML")
    1.11  begin
    1.12  
    1.13 -subsection {* The equivalence relation underlying the integers *}
    1.14 +subsection {* Definition of integers as a quotient type *}
    1.15  
    1.16 -definition intrel :: "((nat \<times> nat) \<times> (nat \<times> nat)) set" where
    1.17 -  "intrel = {((x, y), (u, v)) | x y u v. x + v = u +y }"
    1.18 +definition intrel :: "(nat \<times> nat) \<Rightarrow> (nat \<times> nat) \<Rightarrow> bool" where
    1.19 +  "intrel = (\<lambda>(x, y) (u, v). x + v = u + y)"
    1.20  
    1.21 -definition "Integ = UNIV//intrel"
    1.22 +lemma intrel_iff [simp]: "intrel (x, y) (u, v) \<longleftrightarrow> x + v = u + y"
    1.23 +  by (simp add: intrel_def)
    1.24  
    1.25 -typedef (open) int = Integ
    1.26 +quotient_type int = "nat \<times> nat" / "intrel"
    1.27    morphisms Rep_Integ Abs_Integ
    1.28 -  unfolding Integ_def by (auto simp add: quotient_def)
    1.29 +proof (rule equivpI)
    1.30 +  show "reflp intrel"
    1.31 +    unfolding reflp_def by auto
    1.32 +  show "symp intrel"
    1.33 +    unfolding symp_def by auto
    1.34 +  show "transp intrel"
    1.35 +    unfolding transp_def by auto
    1.36 +qed
    1.37  
    1.38 -instantiation int :: "{zero, one, plus, minus, uminus, times, ord, abs, sgn}"
    1.39 +lemma eq_Abs_Integ [case_names Abs_Integ, cases type: int]:
    1.40 +     "(!!x y. z = Abs_Integ (x, y) ==> P) ==> P"
    1.41 +by (induct z) auto
    1.42 +
    1.43 +subsection {* Integers form a commutative ring *}
    1.44 +
    1.45 +instantiation int :: comm_ring_1
    1.46  begin
    1.47  
    1.48 -definition
    1.49 -  Zero_int_def: "0 = Abs_Integ (intrel `` {(0, 0)})"
    1.50 +lift_definition zero_int :: "int" is "(0, 0)"
    1.51 +  by simp
    1.52  
    1.53 -definition
    1.54 -  One_int_def: "1 = Abs_Integ (intrel `` {(1, 0)})"
    1.55 +lift_definition one_int :: "int" is "(1, 0)"
    1.56 +  by simp
    1.57  
    1.58 -definition
    1.59 -  add_int_def: "z + w = Abs_Integ
    1.60 -    (\<Union>(x, y) \<in> Rep_Integ z. \<Union>(u, v) \<in> Rep_Integ w.
    1.61 -      intrel `` {(x + u, y + v)})"
    1.62 +lift_definition plus_int :: "int \<Rightarrow> int \<Rightarrow> int"
    1.63 +  is "\<lambda>(x, y) (u, v). (x + u, y + v)"
    1.64 +  by clarsimp
    1.65  
    1.66 -definition
    1.67 -  minus_int_def:
    1.68 -    "- z = Abs_Integ (\<Union>(x, y) \<in> Rep_Integ z. intrel `` {(y, x)})"
    1.69 +lift_definition uminus_int :: "int \<Rightarrow> int"
    1.70 +  is "\<lambda>(x, y). (y, x)"
    1.71 +  by clarsimp
    1.72  
    1.73 -definition
    1.74 -  diff_int_def:  "z - w = z + (-w \<Colon> int)"
    1.75 +lift_definition minus_int :: "int \<Rightarrow> int \<Rightarrow> int"
    1.76 +  is "\<lambda>(x, y) (u, v). (x + v, y + u)"
    1.77 +  by clarsimp
    1.78  
    1.79 -definition
    1.80 -  mult_int_def: "z * w = Abs_Integ
    1.81 -    (\<Union>(x, y) \<in> Rep_Integ z. \<Union>(u,v ) \<in> Rep_Integ w.
    1.82 -      intrel `` {(x*u + y*v, x*v + y*u)})"
    1.83 +lift_definition times_int :: "int \<Rightarrow> int \<Rightarrow> int"
    1.84 +  is "\<lambda>(x, y) (u, v). (x*u + y*v, x*v + y*u)"
    1.85 +proof (clarsimp)
    1.86 +  fix s t u v w x y z :: nat
    1.87 +  assume "s + v = u + t" and "w + z = y + x"
    1.88 +  hence "(s + v) * w + (u + t) * x + u * (w + z) + v * (y + x)
    1.89 +       = (u + t) * w + (s + v) * x + u * (y + x) + v * (w + z)"
    1.90 +    by simp
    1.91 +  thus "(s * w + t * x) + (u * z + v * y) = (u * y + v * z) + (s * x + t * w)"
    1.92 +    by (simp add: algebra_simps)
    1.93 +qed
    1.94  
    1.95 -definition
    1.96 -  le_int_def:
    1.97 -   "z \<le> w \<longleftrightarrow> (\<exists>x y u v. x+v \<le> u+y \<and> (x, y) \<in> Rep_Integ z \<and> (u, v) \<in> Rep_Integ w)"
    1.98 -
    1.99 -definition
   1.100 -  less_int_def: "(z\<Colon>int) < w \<longleftrightarrow> z \<le> w \<and> z \<noteq> w"
   1.101 -
   1.102 -definition
   1.103 -  zabs_def: "\<bar>i\<Colon>int\<bar> = (if i < 0 then - i else i)"
   1.104 -
   1.105 -definition
   1.106 -  zsgn_def: "sgn (i\<Colon>int) = (if i=0 then 0 else if 0<i then 1 else - 1)"
   1.107 -
   1.108 -instance ..
   1.109 +instance
   1.110 +  by default (transfer, clarsimp simp: algebra_simps)+
   1.111  
   1.112  end
   1.113  
   1.114 -
   1.115 -subsection{*Construction of the Integers*}
   1.116 -
   1.117 -lemma intrel_iff [simp]: "(((x,y),(u,v)) \<in> intrel) = (x+v = u+y)"
   1.118 -by (simp add: intrel_def)
   1.119 -
   1.120 -lemma equiv_intrel: "equiv UNIV intrel"
   1.121 -by (simp add: intrel_def equiv_def refl_on_def sym_def trans_def)
   1.122 -
   1.123 -text{*Reduces equality of equivalence classes to the @{term intrel} relation:
   1.124 -  @{term "(intrel `` {x} = intrel `` {y}) = ((x,y) \<in> intrel)"} *}
   1.125 -lemmas equiv_intrel_iff [simp] = eq_equiv_class_iff [OF equiv_intrel UNIV_I UNIV_I]
   1.126 -
   1.127 -text{*All equivalence classes belong to set of representatives*}
   1.128 -lemma [simp]: "intrel``{(x,y)} \<in> Integ"
   1.129 -by (auto simp add: Integ_def intrel_def quotient_def)
   1.130 -
   1.131 -text{*Reduces equality on abstractions to equality on representatives:
   1.132 -  @{prop "\<lbrakk>x \<in> Integ; y \<in> Integ\<rbrakk> \<Longrightarrow> (Abs_Integ x = Abs_Integ y) = (x=y)"} *}
   1.133 -declare Abs_Integ_inject [simp,no_atp]  Abs_Integ_inverse [simp,no_atp]
   1.134 -
   1.135 -text{*Case analysis on the representation of an integer as an equivalence
   1.136 -      class of pairs of naturals.*}
   1.137 -lemma eq_Abs_Integ [case_names Abs_Integ, cases type: int]:
   1.138 -     "(!!x y. z = Abs_Integ(intrel``{(x,y)}) ==> P) ==> P"
   1.139 -apply (rule Abs_Integ_cases [of z]) 
   1.140 -apply (auto simp add: Integ_def quotient_def) 
   1.141 -done
   1.142 -
   1.143 -
   1.144 -subsection {* Arithmetic Operations *}
   1.145 -
   1.146 -lemma minus: "- Abs_Integ(intrel``{(x,y)}) = Abs_Integ(intrel `` {(y,x)})"
   1.147 -proof -
   1.148 -  have "(\<lambda>(x,y). intrel``{(y,x)}) respects intrel"
   1.149 -    by (auto simp add: congruent_def)
   1.150 -  thus ?thesis
   1.151 -    by (simp add: minus_int_def UN_equiv_class [OF equiv_intrel])
   1.152 -qed
   1.153 -
   1.154 -lemma add:
   1.155 -     "Abs_Integ (intrel``{(x,y)}) + Abs_Integ (intrel``{(u,v)}) =
   1.156 -      Abs_Integ (intrel``{(x+u, y+v)})"
   1.157 -proof -
   1.158 -  have "(\<lambda>z w. (\<lambda>(x,y). (\<lambda>(u,v). intrel `` {(x+u, y+v)}) w) z) 
   1.159 -        respects2 intrel"
   1.160 -    by (auto simp add: congruent2_def)
   1.161 -  thus ?thesis
   1.162 -    by (simp add: add_int_def UN_UN_split_split_eq
   1.163 -                  UN_equiv_class2 [OF equiv_intrel equiv_intrel])
   1.164 -qed
   1.165 -
   1.166 -text{*Congruence property for multiplication*}
   1.167 -lemma mult_congruent2:
   1.168 -     "(%p1 p2. (%(x,y). (%(u,v). intrel``{(x*u + y*v, x*v + y*u)}) p2) p1)
   1.169 -      respects2 intrel"
   1.170 -apply (rule equiv_intrel [THEN congruent2_commuteI])
   1.171 - apply (force simp add: mult_ac, clarify) 
   1.172 -apply (simp add: congruent_def mult_ac)  
   1.173 -apply (rename_tac u v w x y z)
   1.174 -apply (subgoal_tac "u*y + x*y = w*y + v*y  &  u*z + x*z = w*z + v*z")
   1.175 -apply (simp add: mult_ac)
   1.176 -apply (simp add: add_mult_distrib [symmetric])
   1.177 -done
   1.178 -
   1.179 -lemma mult:
   1.180 -     "Abs_Integ((intrel``{(x,y)})) * Abs_Integ((intrel``{(u,v)})) =
   1.181 -      Abs_Integ(intrel `` {(x*u + y*v, x*v + y*u)})"
   1.182 -by (simp add: mult_int_def UN_UN_split_split_eq mult_congruent2
   1.183 -              UN_equiv_class2 [OF equiv_intrel equiv_intrel])
   1.184 -
   1.185 -text{*The integers form a @{text comm_ring_1}*}
   1.186 -instance int :: comm_ring_1
   1.187 -proof
   1.188 -  fix i j k :: int
   1.189 -  show "(i + j) + k = i + (j + k)"
   1.190 -    by (cases i, cases j, cases k) (simp add: add add_assoc)
   1.191 -  show "i + j = j + i" 
   1.192 -    by (cases i, cases j) (simp add: add_ac add)
   1.193 -  show "0 + i = i"
   1.194 -    by (cases i) (simp add: Zero_int_def add)
   1.195 -  show "- i + i = 0"
   1.196 -    by (cases i) (simp add: Zero_int_def minus add)
   1.197 -  show "i - j = i + - j"
   1.198 -    by (simp add: diff_int_def)
   1.199 -  show "(i * j) * k = i * (j * k)"
   1.200 -    by (cases i, cases j, cases k) (simp add: mult algebra_simps)
   1.201 -  show "i * j = j * i"
   1.202 -    by (cases i, cases j) (simp add: mult algebra_simps)
   1.203 -  show "1 * i = i"
   1.204 -    by (cases i) (simp add: One_int_def mult)
   1.205 -  show "(i + j) * k = i * k + j * k"
   1.206 -    by (cases i, cases j, cases k) (simp add: add mult algebra_simps)
   1.207 -  show "0 \<noteq> (1::int)"
   1.208 -    by (simp add: Zero_int_def One_int_def)
   1.209 -qed
   1.210 -
   1.211  abbreviation int :: "nat \<Rightarrow> int" where
   1.212    "int \<equiv> of_nat"
   1.213  
   1.214 -lemma int_def: "int m = Abs_Integ (intrel `` {(m, 0)})"
   1.215 -by (induct m) (simp_all add: Zero_int_def One_int_def add)
   1.216 +lemma int_def: "int n = Abs_Integ (n, 0)"
   1.217 +  by (induct n, simp add: zero_int.abs_eq,
   1.218 +    simp add: one_int.abs_eq plus_int.abs_eq)
   1.219  
   1.220 +lemma int_transfer [transfer_rule]:
   1.221 +  "(fun_rel (op =) cr_int) (\<lambda>n. (n, 0)) int"
   1.222 +  unfolding fun_rel_def cr_int_def int_def by simp
   1.223  
   1.224 -subsection {* The @{text "\<le>"} Ordering *}
   1.225 +lemma int_diff_cases:
   1.226 +  obtains (diff) m n where "z = int m - int n"
   1.227 +  by transfer clarsimp
   1.228  
   1.229 -lemma le:
   1.230 -  "(Abs_Integ(intrel``{(x,y)}) \<le> Abs_Integ(intrel``{(u,v)})) = (x+v \<le> u+y)"
   1.231 -by (force simp add: le_int_def)
   1.232 +subsection {* Integers are totally ordered *}
   1.233  
   1.234 -lemma less:
   1.235 -  "(Abs_Integ(intrel``{(x,y)}) < Abs_Integ(intrel``{(u,v)})) = (x+v < u+y)"
   1.236 -by (simp add: less_int_def le order_less_le)
   1.237 +instantiation int :: linorder
   1.238 +begin
   1.239  
   1.240 -instance int :: linorder
   1.241 -proof
   1.242 -  fix i j k :: int
   1.243 -  show antisym: "i \<le> j \<Longrightarrow> j \<le> i \<Longrightarrow> i = j"
   1.244 -    by (cases i, cases j) (simp add: le)
   1.245 -  show "(i < j) = (i \<le> j \<and> \<not> j \<le> i)"
   1.246 -    by (auto simp add: less_int_def dest: antisym) 
   1.247 -  show "i \<le> i"
   1.248 -    by (cases i) (simp add: le)
   1.249 -  show "i \<le> j \<Longrightarrow> j \<le> k \<Longrightarrow> i \<le> k"
   1.250 -    by (cases i, cases j, cases k) (simp add: le)
   1.251 -  show "i \<le> j \<or> j \<le> i"
   1.252 -    by (cases i, cases j) (simp add: le linorder_linear)
   1.253 -qed
   1.254 +lift_definition less_eq_int :: "int \<Rightarrow> int \<Rightarrow> bool"
   1.255 +  is "\<lambda>(x, y) (u, v). x + v \<le> u + y"
   1.256 +  by auto
   1.257 +
   1.258 +lift_definition less_int :: "int \<Rightarrow> int \<Rightarrow> bool"
   1.259 +  is "\<lambda>(x, y) (u, v). x + v < u + y"
   1.260 +  by auto
   1.261 +
   1.262 +instance
   1.263 +  by default (transfer, force)+
   1.264 +
   1.265 +end
   1.266  
   1.267  instantiation int :: distrib_lattice
   1.268  begin
   1.269 @@ -209,14 +122,15 @@
   1.270  
   1.271  end
   1.272  
   1.273 +subsection {* Ordering properties of arithmetic operations *}
   1.274 +
   1.275  instance int :: ordered_cancel_ab_semigroup_add
   1.276  proof
   1.277    fix i j k :: int
   1.278    show "i \<le> j \<Longrightarrow> k + i \<le> k + j"
   1.279 -    by (cases i, cases j, cases k) (simp add: le add)
   1.280 +    by transfer clarsimp
   1.281  qed
   1.282  
   1.283 -
   1.284  text{*Strict Monotonicity of Multiplication*}
   1.285  
   1.286  text{*strict, in 1st argument; proof is by induction on k>0*}
   1.287 @@ -230,15 +144,15 @@
   1.288  done
   1.289  
   1.290  lemma zero_le_imp_eq_int: "(0::int) \<le> k ==> \<exists>n. k = int n"
   1.291 -apply (cases k)
   1.292 -apply (auto simp add: le add int_def Zero_int_def)
   1.293 -apply (rule_tac x="x-y" in exI, simp)
   1.294 +apply transfer
   1.295 +apply clarsimp
   1.296 +apply (rule_tac x="a - b" in exI, simp)
   1.297  done
   1.298  
   1.299  lemma zero_less_imp_eq_int: "(0::int) < k ==> \<exists>n>0. k = int n"
   1.300 -apply (cases k)
   1.301 -apply (simp add: less int_def Zero_int_def)
   1.302 -apply (rule_tac x="x-y" in exI, simp)
   1.303 +apply transfer
   1.304 +apply clarsimp
   1.305 +apply (rule_tac x="a - b" in exI, simp)
   1.306  done
   1.307  
   1.308  lemma zmult_zless_mono2: "[| i<j;  (0::int) < k |] ==> k*i < k*j"
   1.309 @@ -247,8 +161,16 @@
   1.310  done
   1.311  
   1.312  text{*The integers form an ordered integral domain*}
   1.313 -instance int :: linordered_idom
   1.314 -proof
   1.315 +instantiation int :: linordered_idom
   1.316 +begin
   1.317 +
   1.318 +definition
   1.319 +  zabs_def: "\<bar>i\<Colon>int\<bar> = (if i < 0 then - i else i)"
   1.320 +
   1.321 +definition
   1.322 +  zsgn_def: "sgn (i\<Colon>int) = (if i=0 then 0 else if 0<i then 1 else - 1)"
   1.323 +
   1.324 +instance proof
   1.325    fix i j k :: int
   1.326    show "i < j \<Longrightarrow> 0 < k \<Longrightarrow> k * i < k * j"
   1.327      by (rule zmult_zless_mono2)
   1.328 @@ -258,17 +180,17 @@
   1.329      by (simp only: zsgn_def)
   1.330  qed
   1.331  
   1.332 +end
   1.333 +
   1.334  lemma zless_imp_add1_zle: "w < z \<Longrightarrow> w + (1\<Colon>int) \<le> z"
   1.335 -apply (cases w, cases z) 
   1.336 -apply (simp add: less le add One_int_def)
   1.337 -done
   1.338 +  by transfer clarsimp
   1.339  
   1.340  lemma zless_iff_Suc_zadd:
   1.341    "(w \<Colon> int) < z \<longleftrightarrow> (\<exists>n. z = w + int (Suc n))"
   1.342 -apply (cases z, cases w)
   1.343 -apply (auto simp add: less add int_def)
   1.344 -apply (rename_tac a b c d) 
   1.345 -apply (rule_tac x="a+d - Suc(c+b)" in exI) 
   1.346 +apply transfer
   1.347 +apply auto
   1.348 +apply (rename_tac a b c d)
   1.349 +apply (rule_tac x="c+b - Suc(a+d)" in exI)
   1.350  apply arith
   1.351  done
   1.352  
   1.353 @@ -285,37 +207,30 @@
   1.354  context ring_1
   1.355  begin
   1.356  
   1.357 -definition of_int :: "int \<Rightarrow> 'a" where
   1.358 -  "of_int z = the_elem (\<Union>(i, j) \<in> Rep_Integ z. { of_nat i - of_nat j })"
   1.359 -
   1.360 -lemma of_int: "of_int (Abs_Integ (intrel `` {(i,j)})) = of_nat i - of_nat j"
   1.361 -proof -
   1.362 -  have "(\<lambda>(i,j). { of_nat i - (of_nat j :: 'a) }) respects intrel"
   1.363 -    by (auto simp add: congruent_def) (simp add: algebra_simps of_nat_add [symmetric]
   1.364 -            del: of_nat_add) 
   1.365 -  thus ?thesis
   1.366 -    by (simp add: of_int_def UN_equiv_class [OF equiv_intrel])
   1.367 -qed
   1.368 +lift_definition of_int :: "int \<Rightarrow> 'a" is "\<lambda>(i, j). of_nat i - of_nat j"
   1.369 +  by (clarsimp simp add: diff_eq_eq eq_diff_eq diff_add_eq
   1.370 +    of_nat_add [symmetric] simp del: of_nat_add)
   1.371  
   1.372  lemma of_int_0 [simp]: "of_int 0 = 0"
   1.373 -by (simp add: of_int Zero_int_def)
   1.374 +by (simp add: of_int.abs_eq zero_int.abs_eq) (* FIXME: transfer *)
   1.375  
   1.376  lemma of_int_1 [simp]: "of_int 1 = 1"
   1.377 -by (simp add: of_int One_int_def)
   1.378 +by (simp add: of_int.abs_eq one_int.abs_eq) (* FIXME: transfer *)
   1.379  
   1.380  lemma of_int_add [simp]: "of_int (w+z) = of_int w + of_int z"
   1.381 -by (cases w, cases z) (simp add: algebra_simps of_int add)
   1.382 +(* FIXME: transfer *)
   1.383 +by (cases w, cases z) (simp add: algebra_simps of_int.abs_eq plus_int.abs_eq)
   1.384  
   1.385  lemma of_int_minus [simp]: "of_int (-z) = - (of_int z)"
   1.386 -by (cases z) (simp add: algebra_simps of_int minus)
   1.387 +(* FIXME: transfer *)
   1.388 +by (cases z) (simp add: algebra_simps of_int.abs_eq uminus_int.abs_eq)
   1.389  
   1.390  lemma of_int_diff [simp]: "of_int (w - z) = of_int w - of_int z"
   1.391  by (simp add: diff_minus Groups.diff_minus)
   1.392  
   1.393  lemma of_int_mult [simp]: "of_int (w*z) = of_int w * of_int z"
   1.394 -apply (cases w, cases z)
   1.395 -apply (simp add: algebra_simps of_int mult of_nat_mult)
   1.396 -done
   1.397 +by (cases w, cases z, (* FIXME: transfer *)
   1.398 +  simp add: algebra_simps of_int.abs_eq times_int.abs_eq of_nat_mult)
   1.399  
   1.400  text{*Collapse nested embeddings*}
   1.401  lemma of_int_of_nat_eq [simp]: "of_int (int n) = of_nat n"
   1.402 @@ -339,8 +254,9 @@
   1.403  
   1.404  lemma of_int_eq_iff [simp]:
   1.405     "of_int w = of_int z \<longleftrightarrow> w = z"
   1.406 +(* FIXME: transfer *)
   1.407  apply (cases w, cases z)
   1.408 -apply (simp add: of_int)
   1.409 +apply (simp add: of_int.abs_eq int.abs_eq_iff)
   1.410  apply (simp only: diff_eq_eq diff_add_eq eq_diff_eq)
   1.411  apply (simp only: of_nat_add [symmetric] of_nat_eq_iff)
   1.412  done
   1.413 @@ -364,8 +280,9 @@
   1.414  
   1.415  lemma of_int_le_iff [simp]:
   1.416    "of_int w \<le> of_int z \<longleftrightarrow> w \<le> z"
   1.417 -  by (cases w, cases z)
   1.418 -    (simp add: of_int le minus algebra_simps of_nat_add [symmetric] del: of_nat_add)
   1.419 +  by (cases w, cases z) (* FIXME: transfer *)
   1.420 +    (simp add: of_int.abs_eq less_eq_int.abs_eq
   1.421 +      algebra_simps of_nat_add [symmetric] del: of_nat_add)
   1.422  
   1.423  lemma of_int_less_iff [simp]:
   1.424    "of_int w < of_int z \<longleftrightarrow> w < z"
   1.425 @@ -392,39 +309,29 @@
   1.426  lemma of_int_eq_id [simp]: "of_int = id"
   1.427  proof
   1.428    fix z show "of_int z = id z"
   1.429 -    by (cases z) (simp add: of_int add minus int_def diff_minus)
   1.430 +    by (cases z rule: int_diff_cases, simp)
   1.431  qed
   1.432  
   1.433  
   1.434  subsection {* Magnitude of an Integer, as a Natural Number: @{text nat} *}
   1.435  
   1.436 -definition nat :: "int \<Rightarrow> nat" where
   1.437 -  "nat z = the_elem (\<Union>(x, y) \<in> Rep_Integ z. {x-y})"
   1.438 -
   1.439 -lemma nat: "nat (Abs_Integ (intrel``{(x,y)})) = x-y"
   1.440 -proof -
   1.441 -  have "(\<lambda>(x,y). {x-y}) respects intrel"
   1.442 -    by (auto simp add: congruent_def)
   1.443 -  thus ?thesis
   1.444 -    by (simp add: nat_def UN_equiv_class [OF equiv_intrel])
   1.445 -qed
   1.446 +lift_definition nat :: "int \<Rightarrow> nat" is "\<lambda>(x, y). x - y"
   1.447 +  by auto
   1.448  
   1.449  lemma nat_int [simp]: "nat (int n) = n"
   1.450 -by (simp add: nat int_def)
   1.451 +  by transfer simp
   1.452  
   1.453  lemma int_nat_eq [simp]: "int (nat z) = (if 0 \<le> z then z else 0)"
   1.454 -by (cases z) (simp add: nat le int_def Zero_int_def)
   1.455 +  by transfer clarsimp
   1.456  
   1.457  corollary nat_0_le: "0 \<le> z ==> int (nat z) = z"
   1.458  by simp
   1.459  
   1.460  lemma nat_le_0 [simp]: "z \<le> 0 ==> nat z = 0"
   1.461 -by (cases z) (simp add: nat le Zero_int_def)
   1.462 +  by transfer clarsimp
   1.463  
   1.464  lemma nat_le_eq_zle: "0 < w | 0 \<le> z ==> (nat w \<le> nat z) = (w\<le>z)"
   1.465 -apply (cases w, cases z) 
   1.466 -apply (simp add: nat le linorder_not_le [symmetric] Zero_int_def, arith)
   1.467 -done
   1.468 +  by transfer (clarsimp, arith)
   1.469  
   1.470  text{*An alternative condition is @{term "0 \<le> w"} *}
   1.471  corollary nat_mono_iff: "0 < z ==> (nat w < nat z) = (w < z)"
   1.472 @@ -434,9 +341,7 @@
   1.473  by (simp add: nat_le_eq_zle linorder_not_le [symmetric]) 
   1.474  
   1.475  lemma zless_nat_conj [simp]: "(nat w < nat z) = (0 < z & w < z)"
   1.476 -apply (cases w, cases z) 
   1.477 -apply (simp add: nat le Zero_int_def linorder_not_le [symmetric], arith)
   1.478 -done
   1.479 +  by transfer (clarsimp, arith)
   1.480  
   1.481  lemma nonneg_eq_int:
   1.482    fixes z :: int
   1.483 @@ -445,24 +350,22 @@
   1.484    using assms by (blast dest: nat_0_le sym)
   1.485  
   1.486  lemma nat_eq_iff: "(nat w = m) = (if 0 \<le> w then w = int m else m=0)"
   1.487 -by (cases w) (simp add: nat le int_def Zero_int_def, arith)
   1.488 +  by transfer (clarsimp simp add: le_imp_diff_is_add)
   1.489  
   1.490  corollary nat_eq_iff2: "(m = nat w) = (if 0 \<le> w then w = int m else m=0)"
   1.491  by (simp only: eq_commute [of m] nat_eq_iff)
   1.492  
   1.493  lemma nat_less_iff: "0 \<le> w ==> (nat w < m) = (w < of_nat m)"
   1.494 -apply (cases w)
   1.495 -apply (simp add: nat le int_def Zero_int_def linorder_not_le[symmetric], arith)
   1.496 -done
   1.497 +  by transfer (clarsimp, arith)
   1.498  
   1.499  lemma nat_le_iff: "nat x \<le> n \<longleftrightarrow> x \<le> int n"
   1.500 -  by (cases x, simp add: nat le int_def le_diff_conv)
   1.501 +  by transfer (clarsimp simp add: le_diff_conv)
   1.502  
   1.503  lemma nat_mono: "x \<le> y \<Longrightarrow> nat x \<le> nat y"
   1.504 -  by (cases x, cases y, simp add: nat le)
   1.505 +  by transfer auto
   1.506  
   1.507  lemma nat_0_iff[simp]: "nat(i::int) = 0 \<longleftrightarrow> i\<le>0"
   1.508 -by(simp add: nat_eq_iff) arith
   1.509 +  by transfer clarsimp
   1.510  
   1.511  lemma int_eq_iff: "(of_nat m = z) = (m = nat z & 0 \<le> z)"
   1.512  by (auto simp add: nat_eq_iff2)
   1.513 @@ -472,25 +375,24 @@
   1.514  
   1.515  lemma nat_add_distrib:
   1.516       "[| (0::int) \<le> z;  0 \<le> z' |] ==> nat (z+z') = nat z + nat z'"
   1.517 -by (cases z, cases z') (simp add: nat add le Zero_int_def)
   1.518 +  by transfer clarsimp
   1.519  
   1.520  lemma nat_diff_distrib:
   1.521       "[| (0::int) \<le> z';  z' \<le> z |] ==> nat (z-z') = nat z - nat z'"
   1.522 -by (cases z, cases z')
   1.523 -  (simp add: nat add minus diff_minus le Zero_int_def)
   1.524 +  by transfer clarsimp
   1.525  
   1.526  lemma nat_zminus_int [simp]: "nat (- int n) = 0"
   1.527 -by (simp add: int_def minus nat Zero_int_def) 
   1.528 +  by transfer simp
   1.529  
   1.530  lemma zless_nat_eq_int_zless: "(m < nat z) = (int m < z)"
   1.531 -by (cases z) (simp add: nat less int_def, arith)
   1.532 +  by transfer (clarsimp simp add: less_diff_conv)
   1.533  
   1.534  context ring_1
   1.535  begin
   1.536  
   1.537  lemma of_nat_nat: "0 \<le> z \<Longrightarrow> of_nat (nat z) = of_int z"
   1.538 -  by (cases z rule: eq_Abs_Integ)
   1.539 -   (simp add: nat le of_int Zero_int_def of_nat_diff)
   1.540 +  by (cases z rule: eq_Abs_Integ) (* FIXME: transfer *)
   1.541 +   (simp add: nat.abs_eq less_eq_int.abs_eq of_int.abs_eq zero_int.abs_eq of_nat_diff)
   1.542  
   1.543  end
   1.544  
   1.545 @@ -516,7 +418,7 @@
   1.546  by (subst le_minus_iff, simp del: of_nat_Suc)
   1.547  
   1.548  lemma int_zle_neg: "(int n \<le> - int m) = (n = 0 & m = 0)"
   1.549 -by (simp add: int_def le minus Zero_int_def)
   1.550 +  by transfer simp
   1.551  
   1.552  lemma not_int_zless_negative [simp]: "~ (int n < - int m)"
   1.553  by (simp add: linorder_not_less)
   1.554 @@ -550,9 +452,9 @@
   1.555  by (force dest: order_less_le_trans simp add: abs_if linorder_not_less)
   1.556  
   1.557  lemma negD: "x < 0 \<Longrightarrow> \<exists>n. x = - (int (Suc n))"
   1.558 -apply (cases x)
   1.559 -apply (auto simp add: le minus Zero_int_def int_def order_less_le)
   1.560 -apply (rule_tac x="y - Suc x" in exI, arith)
   1.561 +apply transfer
   1.562 +apply clarsimp
   1.563 +apply (rule_tac x="b - Suc a" in exI, arith)
   1.564  done
   1.565  
   1.566  
   1.567 @@ -578,14 +480,6 @@
   1.568    assumes "0 \<le> k" obtains n where "k = int n"
   1.569    using assms by (cases k, simp, simp del: of_nat_Suc)
   1.570  
   1.571 -text{*Contributed by Brian Huffman*}
   1.572 -theorem int_diff_cases:
   1.573 -  obtains (diff) m n where "z = int m - int n"
   1.574 -apply (cases z rule: eq_Abs_Integ)
   1.575 -apply (rule_tac m=x and n=y in diff)
   1.576 -apply (simp add: int_def minus add diff_minus)
   1.577 -done
   1.578 -
   1.579  lemma Let_numeral [simp]: "Let (numeral v) f = f (numeral v)"
   1.580    -- {* Unfold all @{text let}s involving constants *}
   1.581    unfolding Let_def ..
   1.582 @@ -870,12 +764,8 @@
   1.583  
   1.584  subsection{*The functions @{term nat} and @{term int}*}
   1.585  
   1.586 -text{*Simplify the terms @{term "int 0"}, @{term "int(Suc 0)"} and
   1.587 -  @{term "w + - z"}*}
   1.588 -declare Zero_int_def [symmetric, simp]
   1.589 -declare One_int_def [symmetric, simp]
   1.590 -
   1.591 -lemmas diff_int_def_symmetric = diff_int_def [symmetric, simp]
   1.592 +text{*Simplify the term @{term "w + - z"}*}
   1.593 +lemmas diff_int_def_symmetric = diff_def [where 'a=int, symmetric, simp]
   1.594  
   1.595  lemma nat_0 [simp]: "nat 0 = 0"
   1.596  by (simp add: nat_eq_iff)
   1.597 @@ -1771,4 +1661,14 @@
   1.598  
   1.599  lemmas zpower_int = int_power [symmetric]
   1.600  
   1.601 +text {* De-register @{text "int"} as a quotient type: *}
   1.602 +
   1.603 +lemmas [transfer_rule del] =
   1.604 +  int.id_abs_transfer int.rel_eq_transfer zero_int.transfer one_int.transfer
   1.605 +  plus_int.transfer uminus_int.transfer minus_int.transfer times_int.transfer
   1.606 +  int_transfer less_eq_int.transfer less_int.transfer of_int.transfer
   1.607 +  nat.transfer
   1.608 +
   1.609 +declare Quotient_int [quot_del]
   1.610 +
   1.611  end
     2.1 --- a/src/HOL/IsaMakefile	Thu May 31 17:10:43 2012 +0200
     2.2 +++ b/src/HOL/IsaMakefile	Fri Jun 01 08:32:26 2012 +0200
     2.3 @@ -1034,14 +1034,16 @@
     2.4    ex/PER.thy ex/PresburgerEx.thy ex/Primrec.thy				\
     2.5    ex/Quicksort.thy ex/ROOT.ML						\
     2.6    ex/Records.thy ex/ReflectionEx.thy ex/Refute_Examples.thy		\
     2.7 -  ex/SAT_Examples.thy ex/Serbian.thy ex/Set_Theory.thy			\
     2.8 -  ex/Simproc_Tests.thy ex/SVC_Oracle.thy		\
     2.9 -  ex/Seq.thy ex/Sqrt.thy ex/Sqrt_Script.thy 	\
    2.10 +  ex/SAT_Examples.thy ex/Serbian.thy 					\
    2.11 +  ex/Set_Comprehension_Pointfree_Tests.thy ex/Set_Theory.thy		\
    2.12 +  ex/Simproc_Tests.thy ex/SVC_Oracle.thy				\
    2.13 +  ex/Seq.thy ex/Sqrt.thy ex/Sqrt_Script.thy 				\
    2.14    ex/Sudoku.thy ex/Tarski.thy ex/Termination.thy ex/Transfer_Ex.thy	\
    2.15    ex/Transfer_Int_Nat.thy						\
    2.16    ex/Tree23.thy	ex/Unification.thy ex/While_Combinator_Example.thy	\
    2.17    ex/document/root.bib ex/document/root.tex ex/svc_funcs.ML		\
    2.18 -  ex/svc_test.thy ../Tools/interpretation_with_defs.ML
    2.19 +  ex/svc_test.thy ../Tools/interpretation_with_defs.ML			\
    2.20 +  ex/set_comprehension_pointfree.ML
    2.21  	@$(ISABELLE_TOOL) usedir $(OUT)/HOL ex
    2.22  
    2.23  
     3.1 --- a/src/HOL/Metis_Examples/Sets.thy	Thu May 31 17:10:43 2012 +0200
     3.2 +++ b/src/HOL/Metis_Examples/Sets.thy	Fri Jun 01 08:32:26 2012 +0200
     3.3 @@ -195,7 +195,7 @@
     3.4         apply (metis all_not_in_conv)
     3.5        apply (metis all_not_in_conv)
     3.6       apply (metis mem_Collect_eq)
     3.7 -    apply (metis less_int_def singleton_iff)
     3.8 +    apply (metis less_le singleton_iff)
     3.9     apply (metis mem_Collect_eq)
    3.10    apply (metis mem_Collect_eq)
    3.11   apply (metis all_not_in_conv)
     4.1 --- a/src/HOL/Multivariate_Analysis/Topology_Euclidean_Space.thy	Thu May 31 17:10:43 2012 +0200
     4.2 +++ b/src/HOL/Multivariate_Analysis/Topology_Euclidean_Space.thy	Fri Jun 01 08:32:26 2012 +0200
     4.3 @@ -1760,7 +1760,7 @@
     4.4      hence "norm (a + x) \<le> b + norm a" using norm_triangle_ineq[of a x] b by auto
     4.5    }
     4.6    thus ?thesis unfolding bounded_pos using norm_ge_zero[of a] b(1) using add_strict_increasing[of b 0 "norm a"]
     4.7 -    by (auto intro!: add exI[of _ "b + norm a"])
     4.8 +    by (auto intro!: exI[of _ "b + norm a"])
     4.9  qed
    4.10  
    4.11  
     5.1 --- a/src/HOL/Nitpick_Examples/Integer_Nits.thy	Thu May 31 17:10:43 2012 +0200
     5.2 +++ b/src/HOL/Nitpick_Examples/Integer_Nits.thy	Fri Jun 01 08:32:26 2012 +0200
     5.3 @@ -95,6 +95,9 @@
     5.4  nitpick [binary_ints, bits = 9, expect = genuine]
     5.5  oops
     5.6  
     5.7 +(* FIXME
     5.8 +*** Invalid intermediate term ("Nitpick_Nut.the_name"): (ConstName Nitpick.sel0$Nitpick.Quot int \<Rightarrow> nat X).
     5.9 +
    5.10  lemma "nat (of_nat n) = n"
    5.11  nitpick [unary_ints, expect = none]
    5.12  nitpick [binary_ints, expect = none]
    5.13 @@ -205,6 +208,7 @@
    5.14  nitpick [unary_ints, expect = none]
    5.15  nitpick [binary_ints, expect = none]
    5.16  sorry
    5.17 +*)
    5.18  
    5.19  datatype tree = Null | Node nat tree tree
    5.20  
     6.1 --- a/src/HOL/Nitpick_Examples/Manual_Nits.thy	Thu May 31 17:10:43 2012 +0200
     6.2 +++ b/src/HOL/Nitpick_Examples/Manual_Nits.thy	Fri Jun 01 08:32:26 2012 +0200
     6.3 @@ -64,8 +64,10 @@
     6.4  subsection {* 2.5. Natural Numbers and Integers *}
     6.5  
     6.6  lemma "\<lbrakk>i \<le> j; n \<le> (m\<Colon>int)\<rbrakk> \<Longrightarrow> i * n + j * m \<le> i * m + j * n"
     6.7 +(* FIXME
     6.8  nitpick [expect = genuine]
     6.9  nitpick [binary_ints, bits = 16, expect = genuine]
    6.10 +*)
    6.11  oops
    6.12  
    6.13  lemma "\<forall>n. Suc n \<noteq> n \<Longrightarrow> P"
    6.14 @@ -141,11 +143,15 @@
    6.15    Ycoord :: int
    6.16  
    6.17  lemma "Xcoord (p\<Colon>point) = Xcoord (q\<Colon>point)"
    6.18 +(* FIXME: Invalid intermediate term
    6.19  nitpick [show_datatypes, expect = genuine]
    6.20 +*)
    6.21  oops
    6.22  
    6.23  lemma "4 * x + 3 * (y\<Colon>real) \<noteq> 1 / 2"
    6.24 +(* FIXME: Invalid intermediate term
    6.25  nitpick [show_datatypes, expect = genuine]
    6.26 +*)
    6.27  oops
    6.28  
    6.29  subsection {* 2.8. Inductive and Coinductive Predicates *}
     7.1 --- a/src/HOL/Nitpick_Examples/Record_Nits.thy	Thu May 31 17:10:43 2012 +0200
     7.2 +++ b/src/HOL/Nitpick_Examples/Record_Nits.thy	Fri Jun 01 08:32:26 2012 +0200
     7.3 @@ -18,6 +18,7 @@
     7.4    xc :: int
     7.5    yc :: int
     7.6  
     7.7 +(* FIXME: Invalid intermediate term
     7.8  lemma "\<lparr>xc = x, yc = y\<rparr> = p\<lparr>xc := x, yc := y\<rparr>"
     7.9  nitpick [expect = none]
    7.10  sorry
    7.11 @@ -83,5 +84,6 @@
    7.12  lemma "p\<lparr>xc := x, yc := y, zc := z, wc := w\<rparr> = p"
    7.13  nitpick [expect = genuine]
    7.14  oops
    7.15 +*)
    7.16  
    7.17  end
     8.1 --- a/src/HOL/Nitpick_Examples/Typedef_Nits.thy	Thu May 31 17:10:43 2012 +0200
     8.2 +++ b/src/HOL/Nitpick_Examples/Typedef_Nits.thy	Fri Jun 01 08:32:26 2012 +0200
     8.3 @@ -171,6 +171,7 @@
     8.4    Xcoord :: int
     8.5    Ycoord :: int
     8.6  
     8.7 +(* FIXME: Invalid intermediate term
     8.8  lemma "Abs_point_ext (Rep_point_ext a) = a"
     8.9  nitpick [expect = none]
    8.10  by (fact Rep_point_ext_inverse)
    8.11 @@ -182,5 +183,6 @@
    8.12  lemma "Abs_rat (Rep_rat a) = a"
    8.13  nitpick [card = 1, expect = none]
    8.14  by (rule Rep_rat_inverse)
    8.15 +*)
    8.16  
    8.17  end
     9.1 --- a/src/HOL/Quotient_Examples/Quotient_Rat.thy	Thu May 31 17:10:43 2012 +0200
     9.2 +++ b/src/HOL/Quotient_Examples/Quotient_Rat.thy	Fri Jun 01 08:32:26 2012 +0200
     9.3 @@ -114,6 +114,8 @@
     9.4  
     9.5  lemmas [simp] = Respects_def
     9.6  
     9.7 +(* FIXME: (partiality_)descending raises exception TYPE_MATCH
     9.8 +
     9.9  instantiation rat :: comm_ring_1
    9.10  begin
    9.11  
    9.12 @@ -260,5 +262,6 @@
    9.13      then show "\<exists>z\<Colon>int. a * b \<le> z * b * b" by auto
    9.14    qed
    9.15  qed
    9.16 +*)
    9.17  
    9.18  end
    10.1 --- a/src/HOL/Tools/SMT/smt_config.ML	Thu May 31 17:10:43 2012 +0200
    10.2 +++ b/src/HOL/Tools/SMT/smt_config.ML	Fri Jun 01 08:32:26 2012 +0200
    10.3 @@ -9,7 +9,7 @@
    10.4    (*solver*)
    10.5    type solver_info = {
    10.6      name: string,
    10.7 -    class: SMT_Utils.class,
    10.8 +    class: Proof.context -> SMT_Utils.class,
    10.9      avail: unit -> bool,
   10.10      options: Proof.context -> string list }
   10.11    val add_solver: solver_info -> Context.generic -> Context.generic
   10.12 @@ -61,7 +61,7 @@
   10.13  
   10.14  type solver_info = {
   10.15    name: string,
   10.16 -  class: SMT_Utils.class,
   10.17 +  class: Proof.context -> SMT_Utils.class,
   10.18    avail: unit -> bool,
   10.19    options: Proof.context -> string list }
   10.20  
   10.21 @@ -131,7 +131,8 @@
   10.22    | (_, NONE) => default ())
   10.23  
   10.24  fun solver_class_of ctxt =
   10.25 -  solver_info_of no_solver_err (#class o fst o the) ctxt
   10.26 +  let fun class_of ({class, ...}: solver_info, _) = class ctxt
   10.27 +  in solver_info_of no_solver_err (class_of o the) ctxt end
   10.28  
   10.29  fun solver_options_of ctxt =
   10.30    let
    11.1 --- a/src/HOL/Tools/SMT/smt_setup_solvers.ML	Thu May 31 17:10:43 2012 +0200
    11.2 +++ b/src/HOL/Tools/SMT/smt_setup_solvers.ML	Fri Jun 01 08:32:26 2012 +0200
    11.3 @@ -63,7 +63,7 @@
    11.4  
    11.5    fun mk is_remote = {
    11.6      name = make_name is_remote "cvc3",
    11.7 -    class = SMTLIB_Interface.smtlibC,
    11.8 +    class = K SMTLIB_Interface.smtlibC,
    11.9      avail = make_avail is_remote "CVC3",
   11.10      command = make_command is_remote "CVC3",
   11.11      options = cvc3_options,
   11.12 @@ -85,7 +85,7 @@
   11.13  
   11.14  fun yices () = {
   11.15    name = "yices",
   11.16 -  class = SMTLIB_Interface.smtlibC,
   11.17 +  class = K SMTLIB_Interface.smtlibC,
   11.18    avail = make_local_avail "YICES",
   11.19    command = make_local_command "YICES",
   11.20    options = (fn ctxt => [
   11.21 @@ -163,9 +163,16 @@
   11.22        handle SMT_Failure.SMT _ => outcome (swap o split_last)
   11.23      end
   11.24  
   11.25 +  val with_extensions =
   11.26 +    Attrib.setup_config_bool @{binding z3_with_extensions} (K true)
   11.27 +
   11.28 +  fun select_class ctxt =
   11.29 +    if Config.get ctxt with_extensions then Z3_Interface.smtlib_z3C
   11.30 +    else SMTLIB_Interface.smtlibC
   11.31 +
   11.32    fun mk is_remote = {
   11.33      name = make_name is_remote "z3",
   11.34 -    class = Z3_Interface.smtlib_z3C,
   11.35 +    class = select_class,
   11.36      avail = make_avail is_remote "Z3",
   11.37      command = z3_make_command is_remote "Z3",
   11.38      options = z3_options,
    12.1 --- a/src/HOL/Tools/SMT/smt_solver.ML	Thu May 31 17:10:43 2012 +0200
    12.2 +++ b/src/HOL/Tools/SMT/smt_solver.ML	Fri Jun 01 08:32:26 2012 +0200
    12.3 @@ -10,7 +10,7 @@
    12.4    datatype outcome = Unsat | Sat | Unknown
    12.5    type solver_config = {
    12.6      name: string,
    12.7 -    class: SMT_Utils.class,
    12.8 +    class: Proof.context -> SMT_Utils.class,
    12.9      avail: unit -> bool,
   12.10      command: unit -> string list,
   12.11      options: Proof.context -> string list,
   12.12 @@ -146,7 +146,7 @@
   12.13  
   12.14  type solver_config = {
   12.15    name: string,
   12.16 -  class: SMT_Utils.class,
   12.17 +  class: Proof.context -> SMT_Utils.class,
   12.18    avail: unit -> bool,
   12.19    command: unit -> string list,
   12.20    options: Proof.context -> string list,
    13.1 --- a/src/HOL/ex/ROOT.ML	Thu May 31 17:10:43 2012 +0200
    13.2 +++ b/src/HOL/ex/ROOT.ML	Fri Jun 01 08:32:26 2012 +0200
    13.3 @@ -72,7 +72,8 @@
    13.4    "Seq",
    13.5    "Simproc_Tests",
    13.6    "Executable_Relation",
    13.7 -  "FinFunPred"
    13.8 +  "FinFunPred",
    13.9 +  "Set_Comprehension_Pointfree_Tests"
   13.10  ];
   13.11  
   13.12  use_thy "SVC_Oracle";
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/src/HOL/ex/Set_Comprehension_Pointfree_Tests.thy	Fri Jun 01 08:32:26 2012 +0200
    14.3 @@ -0,0 +1,45 @@
    14.4 +(*  Title:      HOL/ex/Set_Comprehension_Pointfree_Tests.thy
    14.5 +    Author:     Lukas Bulwahn
    14.6 +    Copyright   2012 TU Muenchen
    14.7 +*)
    14.8 +
    14.9 +header {* Tests for the set comprehension to pointfree simproc *}
   14.10 +
   14.11 +theory Set_Comprehension_Pointfree_Tests
   14.12 +imports Main
   14.13 +uses "~~/src/HOL/ex/set_comprehension_pointfree.ML"
   14.14 +begin
   14.15 +
   14.16 +simproc_setup finite_Collect ("finite (Collect P)") = {* Set_Comprehension_Pointfree.simproc *}
   14.17 +
   14.18 +lemma
   14.19 +  "finite {f a b| a b. a : A \<and> b : B}"
   14.20 +apply simp (* works :) *)
   14.21 +oops
   14.22 +
   14.23 +lemma
   14.24 +  "finite {f a b| a b. a : A \<and> a : A' \<and> b : B}"
   14.25 +(* apply simp -- does not terminate *)
   14.26 +oops
   14.27 +
   14.28 +lemma
   14.29 +  "finite {f a b| a b. a : A \<and> b : B \<and> b : B'}"
   14.30 +(* apply simp -- does not terminate *)
   14.31 +oops
   14.32 +
   14.33 +lemma
   14.34 +  "finite {f a b c| a b c. a : A \<and> b : B \<and> c : C}"
   14.35 +(* apply simp -- failed *) 
   14.36 +oops
   14.37 +
   14.38 +lemma
   14.39 +  "finite {f a b c d| a b c d. a : A \<and> b : B \<and> c : C \<and> d : D}"
   14.40 +(* apply simp -- failed *)
   14.41 +oops
   14.42 +
   14.43 +lemma
   14.44 +  "finite {f a b c d e | a b c d e. a : A \<and> b : B \<and> c : C \<and> d : D \<and> e : E}"
   14.45 +(* apply simp -- failed *)
   14.46 +oops
   14.47 +
   14.48 +end
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/src/HOL/ex/set_comprehension_pointfree.ML	Fri Jun 01 08:32:26 2012 +0200
    15.3 @@ -0,0 +1,120 @@
    15.4 +(*  Title:      HOL/Tools/set_comprehension_pointfree.ML
    15.5 +    Author:     Felix Kuperjans, Lukas Bulwahn, TU Muenchen
    15.6 +
    15.7 +Simproc for rewriting set comprehensions to pointfree expressions.
    15.8 +*)
    15.9 +
   15.10 +signature SET_COMPREHENSION_POINTFREE =
   15.11 +sig
   15.12 +  val simproc : morphism -> simpset -> cterm -> thm option
   15.13 +end
   15.14 +
   15.15 +structure Set_Comprehension_Pointfree : SET_COMPREHENSION_POINTFREE =
   15.16 +struct
   15.17 +
   15.18 +(* syntactic operations *)
   15.19 +
   15.20 +fun mk_inf (t1, t2) =
   15.21 +  let
   15.22 +    val T = fastype_of t1
   15.23 +  in
   15.24 +    Const (@{const_name Lattices.inf_class.inf}, T --> T --> T) $ t1 $ t2
   15.25 +  end
   15.26 +
   15.27 +fun mk_image t1 t2 =
   15.28 +  let
   15.29 +    val T as Type (@{type_name fun}, [_ , R]) = fastype_of t1
   15.30 +  in
   15.31 +    Const (@{const_name image}, T --> fastype_of t2 --> HOLogic.mk_setT R) $ t1 $ t2
   15.32 +  end;
   15.33 +
   15.34 +fun mk_sigma (t1, t2) =
   15.35 +  let
   15.36 +    val T1 = fastype_of t1
   15.37 +    val T2 = fastype_of t2
   15.38 +    val setT = HOLogic.dest_setT T1
   15.39 +    val resultT = HOLogic.mk_setT (HOLogic.mk_prodT (setT, HOLogic.dest_setT T2))
   15.40 +  in
   15.41 +    Const (@{const_name Sigma}, T1 --> (setT --> T2) --> resultT) $ t1 $ absdummy setT t2
   15.42 +  end;
   15.43 +
   15.44 +fun dest_Bound (Bound x) = x
   15.45 +  | dest_Bound t = raise TERM("dest_Bound", [t]);
   15.46 +
   15.47 +fun dest_Collect (Const (@{const_name Collect}, _) $ Abs (_, _, t)) = t
   15.48 +  | dest_Collect t = raise TERM ("dest_Collect", [t])
   15.49 +
   15.50 +(* Copied from predicate_compile_aux.ML *)
   15.51 +fun strip_ex (Const (@{const_name Ex}, _) $ Abs (x, T, t)) =
   15.52 +  let
   15.53 +    val (xTs, t') = strip_ex t
   15.54 +  in
   15.55 +    ((x, T) :: xTs, t')
   15.56 +  end
   15.57 +  | strip_ex t = ([], t)
   15.58 +
   15.59 +fun list_tupled_abs [] f = f
   15.60 +  | list_tupled_abs [(n, T)] f = (Abs (n, T, f))
   15.61 +  | list_tupled_abs ((n, T)::v::vs) f = HOLogic.mk_split (Abs (n, T, list_tupled_abs (v::vs) f))
   15.62 +  
   15.63 +fun mk_pointfree_expr t =
   15.64 +  let
   15.65 +    val (vs, t'') = strip_ex (dest_Collect t)
   15.66 +    val (eq::conjs) = HOLogic.dest_conj t''
   15.67 +    val f = if fst (HOLogic.dest_eq eq) = Bound (length vs)
   15.68 +            then snd (HOLogic.dest_eq eq)
   15.69 +            else raise TERM("mk_pointfree_expr", [t]);
   15.70 +    val mems = map (apfst dest_Bound o HOLogic.dest_mem) conjs
   15.71 +    val grouped_mems = AList.group (op =) mems
   15.72 +    fun mk_grouped_unions (i, T) =
   15.73 +      case AList.lookup (op =) grouped_mems i of
   15.74 +        SOME ts => foldr1 mk_inf ts
   15.75 +      | NONE => HOLogic.mk_UNIV T
   15.76 +    val complete_sets = map mk_grouped_unions ((length vs - 1) downto 0 ~~ map snd vs)
   15.77 +  in
   15.78 +    mk_image (list_tupled_abs vs f) (foldr1 mk_sigma complete_sets)
   15.79 +  end;
   15.80 +
   15.81 +(* proof tactic *)
   15.82 +
   15.83 +(* This tactic is terribly incomplete *) 
   15.84 +
   15.85 +val goal1_tac_part2 = REPEAT_ALL_NEW (CHANGED o (atac ORELSE' rtac @{thm SigmaI}))
   15.86 +
   15.87 +val goal1_tac = etac @{thm CollectE}
   15.88 +  THEN' REPEAT1 o CHANGED o etac @{thm exE}
   15.89 +  THEN' REPEAT1 o CHANGED o etac @{thm conjE}
   15.90 +  THEN' rtac @{thm image_eqI}
   15.91 +  THEN' RANGE [(REPEAT o CHANGED o stac @{thm split}) THEN' goal1_tac_part2, goal1_tac_part2]
   15.92 +
   15.93 +val goal2_tac = etac @{thm imageE}
   15.94 +  THEN' rtac @{thm CollectI}
   15.95 +  THEN' REPEAT o CHANGED o etac @{thm SigmaE}
   15.96 +  THEN' REPEAT o CHANGED o rtac @{thm exI}
   15.97 +  THEN' REPEAT_ALL_NEW (rtac @{thm conjI})
   15.98 +  THEN_ALL_NEW
   15.99 +    (atac ORELSE'
  15.100 +    (asm_full_simp_tac HOL_basic_ss THEN' stac @{thm split} THEN' rtac @{thm refl}))
  15.101 +
  15.102 +val tac =
  15.103 +  rtac @{thm set_eqI} 1
  15.104 +  THEN rtac @{thm iffI} 1
  15.105 +  THEN goal1_tac 1
  15.106 +  THEN goal2_tac 1
  15.107 +
  15.108 +(* simproc *)
  15.109 +
  15.110 +fun simproc _ ss redex =
  15.111 +  let
  15.112 +    val ctxt = Simplifier.the_context ss
  15.113 +    val _ $ set_compr = term_of redex
  15.114 +  in
  15.115 +    case try mk_pointfree_expr set_compr of
  15.116 +      NONE => NONE
  15.117 +    | SOME pointfree_expr =>
  15.118 +        SOME (Goal.prove ctxt [] []
  15.119 +          (HOLogic.mk_Trueprop (HOLogic.mk_eq (set_compr, pointfree_expr))) (K tac)
  15.120 +        RS @{thm arg_cong[of _ _ finite]} RS @{thm eq_reflection})
  15.121 +  end
  15.122 +
  15.123 +end;