added yet another code generator example
authorhaftmann
Wed, 30 Aug 2006 08:34:45 +0200
changeset 204360af8655ab0bb
parent 20435 d2a30fed7596
child 20437 0eb5e30fd620
added yet another code generator example
src/HOL/IsaMakefile
src/HOL/ex/CodeCollections.thy
src/HOL/ex/ROOT.ML
     1.1 --- a/src/HOL/IsaMakefile	Wed Aug 30 08:30:09 2006 +0200
     1.2 +++ b/src/HOL/IsaMakefile	Wed Aug 30 08:34:45 2006 +0200
     1.3 @@ -640,7 +640,7 @@
     1.4  
     1.5  $(LOG)/HOL-ex.gz: $(OUT)/HOL Library/Commutative_Ring.thy			\
     1.6    ex/Abstract_NAT.thy ex/Antiquote.thy ex/BT.thy ex/BinEx.thy			\
     1.7 -  ex/Chinese.thy ex/Classical.thy ex/Classpackage.thy                           \
     1.8 +  ex/Chinese.thy ex/Classical.thy ex/Classpackage.thy ex/CodeCollections.thy \
     1.9    ex/CodeEmbed.thy ex/CodeRandom.thy ex/CodeRevappl.thy			\
    1.10    ex/CodeOperationalEquality.thy ex/Codegenerator.thy ex/Commutative_RingEx.thy               \
    1.11    ex/Commutative_Ring_Complete.thy ex/Guess.thy ex/Hebrew.thy			\
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/HOL/ex/CodeCollections.thy	Wed Aug 30 08:34:45 2006 +0200
     2.3 @@ -0,0 +1,417 @@
     2.4 +(*  ID:         $Id$
     2.5 +    Author:     Florian Haftmann, TU Muenchen
     2.6 +*)
     2.7 +
     2.8 +header {* Collection classes as examples for code generation *}
     2.9 +
    2.10 +theory CodeCollections
    2.11 +imports CodeOperationalEquality
    2.12 +begin
    2.13 +
    2.14 +section {* Collection classes as examples for code generation *}
    2.15 +
    2.16 +class ordered = eq +
    2.17 +  constrains eq :: "'a \<Rightarrow> 'a \<Rightarrow> bool"
    2.18 +  fixes le :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infix "\<^loc><<=" 65)
    2.19 +  fixes lt :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infix "\<^loc><<" 65)
    2.20 +  assumes order_refl: "x \<^loc><<= x"
    2.21 +  assumes order_trans: "x \<^loc><<= y ==> y \<^loc><<= z ==> x \<^loc><<= z"
    2.22 +  assumes order_antisym: "x \<^loc><<= y ==> y \<^loc><<= x ==> x = y"
    2.23 +
    2.24 +declare order_refl [simp, intro]
    2.25 +
    2.26 +defs
    2.27 +  lt_def: "x << y == (x <<= y \<and> x \<noteq> y)"
    2.28 +
    2.29 +lemma lt_intro [intro]:
    2.30 +  assumes "x <<= y" and "x \<noteq> y"
    2.31 +  shows "x << y"
    2.32 +unfolding lt_def ..
    2.33 +
    2.34 +lemma lt_elim [elim]:
    2.35 +  assumes "(x::'a::ordered) << y"
    2.36 +  and Q: "!!x y::'a::ordered. x <<= y \<Longrightarrow> x \<noteq> y \<Longrightarrow> P"
    2.37 +  shows P
    2.38 +proof -
    2.39 +  from prems have R1: "x <<= y" and R2: "x \<noteq> y" by (simp_all add: lt_def)
    2.40 +  show P by (rule Q [OF R1 R2])
    2.41 +qed
    2.42 +
    2.43 +lemma lt_trans:
    2.44 +  assumes "x << y" and "y << z"
    2.45 +  shows "x << z"
    2.46 +proof
    2.47 +  from prems lt_def have prems': "x <<= y" "y <<= z" by auto
    2.48 +  show "x <<= z" by (rule order_trans, auto intro: prems')
    2.49 +next
    2.50 +  show "x \<noteq> z"
    2.51 +  proof
    2.52 +    from prems lt_def have prems': "x <<= y" "y <<= z" "x \<noteq> y" by auto
    2.53 +    assume "x = z"
    2.54 +    with prems' have "x <<= y" and "y <<= x" by auto
    2.55 +    with order_antisym have "x = y" .
    2.56 +    with prems' show False by auto
    2.57 +  qed
    2.58 +qed
    2.59 +
    2.60 +definition (in ordered)
    2.61 +  min :: "'a \<Rightarrow> 'a \<Rightarrow> 'a"
    2.62 +  "min x y = (if x \<^loc><<= y then x else y)"
    2.63 +  max :: "'a \<Rightarrow> 'a \<Rightarrow> 'a"
    2.64 +  "max x y = (if x \<^loc><<= y then y else x)"
    2.65 +
    2.66 +definition
    2.67 +  min :: "'a::ordered \<Rightarrow> 'a \<Rightarrow> 'a"
    2.68 +  "min x y = (if x <<= y then x else y)"
    2.69 +  max :: "'a::ordered \<Rightarrow> 'a \<Rightarrow> 'a"
    2.70 +  "max x y = (if x <<= y then y else x)"
    2.71 +
    2.72 +consts
    2.73 +  abs_sorted :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> bool"
    2.74 +
    2.75 +function
    2.76 +  "abs_sorted cmp [] = True"
    2.77 +  "abs_sorted cmp [x] = True"
    2.78 +  "abs_sorted cmp (x#y#xs) = (cmp x y \<and> abs_sorted cmp (y#xs))"
    2.79 +by pat_completeness simp_all
    2.80 +termination by (auto_term "measure (length o snd)")
    2.81 +
    2.82 +abbreviation (in ordered)
    2.83 +  "sorted \<equiv> abs_sorted le"
    2.84 +
    2.85 +abbreviation
    2.86 +  "sorted \<equiv> abs_sorted le"
    2.87 +
    2.88 +lemma (in ordered) sorted_weakening:
    2.89 +  assumes "sorted (x # xs)"
    2.90 +  shows "sorted xs"
    2.91 +using prems proof (induct xs)
    2.92 +  case Nil show ?case by simp 
    2.93 +next
    2.94 +  case (Cons x' xs)
    2.95 +  from this(5) have "sorted (x # x' # xs)" .
    2.96 +  then show "sorted (x' # xs)" by auto
    2.97 +qed
    2.98 +
    2.99 +instance bool :: ordered
   2.100 +  "p <<= q == (p --> q)"
   2.101 +  by default (unfold ordered_bool_def, blast+)
   2.102 +
   2.103 +instance nat :: ordered
   2.104 +  "m <<= n == m <= n"
   2.105 +  by default (simp_all add: ordered_nat_def)
   2.106 +
   2.107 +instance int :: ordered
   2.108 +  "k <<= l == k <= l"
   2.109 +  by default (simp_all add: ordered_int_def)
   2.110 +
   2.111 +instance unit :: ordered
   2.112 +  "u <<= v == True"
   2.113 +  by default (simp_all add:  ordered_unit_def)
   2.114 +
   2.115 +consts
   2.116 +  le_option' :: "'a::ordered option \<Rightarrow> 'a option \<Rightarrow> bool"
   2.117 +
   2.118 +function
   2.119 +  "le_option' None y = True"
   2.120 +  "le_option' (Some x) None = False"
   2.121 +  "le_option' (Some x) (Some y) = x <<= y"
   2.122 +  by pat_completeness simp_all
   2.123 +termination by (auto_term "{}")
   2.124 +
   2.125 +instance (ordered) option :: ordered
   2.126 +  "x <<= y == le_option' x y"
   2.127 +proof (default, unfold ordered_option_def)
   2.128 +  fix x
   2.129 +  show "le_option' x x" by (cases x) simp_all
   2.130 +next
   2.131 +  fix x y z
   2.132 +  assume "le_option' x y" "le_option' y z"
   2.133 +  then show "le_option' x z"
   2.134 +    by (cases x, simp_all, cases y, simp_all, cases z, simp_all)
   2.135 +    (erule order_trans, assumption)
   2.136 +next
   2.137 +  fix x y
   2.138 +  assume "le_option' x y" "le_option' y x"
   2.139 +  then show "x = y"
   2.140 +    by (cases x, simp_all, cases y, simp_all, cases y, simp_all)
   2.141 +    (erule order_antisym, assumption)
   2.142 +qed
   2.143 +
   2.144 +lemma [simp, code]:
   2.145 +  "None <<= y = True"
   2.146 +  "Some x <<= None = False"
   2.147 +  "Some v <<= Some w = v <<= w"
   2.148 +  unfolding ordered_option_def le_option'.simps by rule+
   2.149 +
   2.150 +consts
   2.151 +  le_pair' :: "'a::ordered \<times> 'b::ordered \<Rightarrow> 'a \<times> 'b \<Rightarrow> bool"
   2.152 +
   2.153 +function
   2.154 +  "le_pair' (x1, y1) (x2, y2) = (x1 << x2 \<or> x1 = x2 \<and> y1 <<= y2)"
   2.155 +  by pat_completeness simp_all
   2.156 +termination by (auto_term "{}")
   2.157 +
   2.158 +instance (ordered, ordered) * :: ordered
   2.159 +  "x <<= y == le_pair' x y"
   2.160 +apply (default, unfold "ordered_*_def", unfold split_paired_all)
   2.161 +apply simp_all
   2.162 +apply (auto intro: lt_trans order_trans)[1]
   2.163 +unfolding lt_def apply (auto intro: order_antisym)[1]
   2.164 +done
   2.165 +
   2.166 +lemma [simp, code]:
   2.167 +  "(x1, y1) <<= (x2, y2) = (x1 << x2 \<or> x1 = x2 \<and> y1 <<= y2)"
   2.168 +  unfolding "ordered_*_def" le_pair'.simps ..
   2.169 +
   2.170 +(* consts
   2.171 +  le_list' :: "'a::ordered list \<Rightarrow> 'a list \<Rightarrow> bool"
   2.172 +
   2.173 +function
   2.174 +  "le_list' [] ys = True"
   2.175 +  "le_list' (x#xs) [] = False"
   2.176 +  "le_list' (x#xs) (y#ys) = (x << y \<or> x = y \<and> le_list' xs ys)"
   2.177 +    by pat_completeness simp_all
   2.178 +termination by (auto_term "measure (length o fst)")
   2.179 +
   2.180 +instance (ordered) list :: ordered
   2.181 +  "xs <<= ys == le_list' xs ys"
   2.182 +proof (default, unfold "ordered_list_def")
   2.183 +  fix xs
   2.184 +  show "le_list' xs xs" by (induct xs) simp_all
   2.185 +next
   2.186 +  fix xs ys zs
   2.187 +  assume "le_list' xs ys" and "le_list' ys zs"
   2.188 +  then show "le_list' xs zs"
   2.189 +  apply (induct xs zs rule: le_list'.induct)
   2.190 +  apply simp_all
   2.191 +  apply (cases ys) apply simp_all
   2.192 +  
   2.193 +  apply (induct ys) apply simp_all
   2.194 +  apply (induct ys)
   2.195 +  apply simp_all
   2.196 +  apply (induct zs)
   2.197 +  apply simp_all
   2.198 +next
   2.199 +  fix xs ys
   2.200 +  assume "le_list' xs ys" and "le_list' ys xs"
   2.201 +  show "xs = ys" sorry
   2.202 +qed
   2.203 +
   2.204 +lemma [simp, code]:
   2.205 +  "[] <<= ys = True"
   2.206 +  "(x#xs) <<= [] = False"
   2.207 +  "(x#xs) <<= (y#ys) = (x << y \<or> x = y \<and> xs <<= ys)"
   2.208 +  unfolding "ordered_list_def" le_list'.simps by rule+*)
   2.209 +
   2.210 +class infimum = ordered +
   2.211 +  fixes inf
   2.212 +  assumes inf: "inf \<^loc><<= x"
   2.213 +
   2.214 +lemma (in infimum)
   2.215 +  assumes prem: "a \<^loc><<= inf"
   2.216 +  shows no_smaller: "a = inf"
   2.217 +using prem inf by (rule order_antisym)
   2.218 +
   2.219 +consts
   2.220 +  abs_max_of :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'a list \<Rightarrow> 'a"
   2.221 +
   2.222 +ML {* set quick_and_dirty *}
   2.223 +function
   2.224 +  "abs_max_of cmp inff [] = inff"
   2.225 +  "abs_max_of cmp inff [x] = x"
   2.226 +  "abs_max_of cmp inff (x#xs) =
   2.227 +     ordered.max cmp x (abs_max_of cmp inff xs)"
   2.228 +apply pat_completeness sorry
   2.229 +
   2.230 +abbreviation (in infimum)
   2.231 +  "max_of xs \<equiv> abs_max_of le inf"
   2.232 +
   2.233 +abbreviation
   2.234 +  "max_of xs \<equiv> abs_max_of le inf"
   2.235 +
   2.236 +instance bool :: infimum
   2.237 +  "inf == False"
   2.238 +  by default (simp add: infimum_bool_def)
   2.239 +
   2.240 +instance nat :: infimum
   2.241 +  "inf == 0"
   2.242 +  by default (simp add: infimum_nat_def)
   2.243 +
   2.244 +instance unit :: infimum
   2.245 +  "inf == ()"
   2.246 +  by default (simp add: infimum_unit_def)
   2.247 +
   2.248 +instance (ordered) option :: infimum
   2.249 +  "inf == None"
   2.250 +  by default (simp add: infimum_option_def)
   2.251 +
   2.252 +instance (infimum, infimum) * :: infimum
   2.253 +  "inf == (inf, inf)"
   2.254 +  by default (unfold "infimum_*_def", unfold split_paired_all, auto intro: inf)
   2.255 +
   2.256 +class enum = ordered +
   2.257 +  fixes enum :: "'a list"
   2.258 +  assumes member_enum: "x \<in> set enum"
   2.259 +  and ordered_enum: "abs_sorted le enum"
   2.260 +
   2.261 +(*
   2.262 +FIXME:
   2.263 +- abbreviations must be propagated before locale introduction
   2.264 +- then also now shadowing may occur
   2.265 +*)
   2.266 +(*abbreviation (in enum)
   2.267 +  "local.sorted \<equiv> abs_sorted le"*)
   2.268 +
   2.269 +instance bool :: enum
   2.270 +  (* FIXME: better name handling of definitions *)
   2.271 +  "_1": "enum == [False, True]"
   2.272 +  by default (simp_all add: enum_bool_def)
   2.273 +
   2.274 +instance unit :: enum
   2.275 +  "_2": "enum == [()]"
   2.276 +  by default (simp_all add: enum_unit_def)
   2.277 +
   2.278 +(*consts
   2.279 +  product :: "'a list \<Rightarrow> 'b list \<Rightarrow> ('a * 'b) list"
   2.280 +
   2.281 +primrec
   2.282 +  "product [] ys = []"
   2.283 +  "product (x#xs) ys = map (Pair x) ys @ product xs ys"
   2.284 +
   2.285 +lemma product_all:
   2.286 +  assumes "x \<in> set xs" "y \<in> set ys"
   2.287 +  shows "(x, y) \<in> set (product xs ys)"
   2.288 +using prems proof (induct xs)
   2.289 +  case Nil
   2.290 +  then have False by auto
   2.291 +  then show ?case ..
   2.292 +next
   2.293 +  case (Cons z xs)
   2.294 +  then show ?case
   2.295 +  proof (cases "x = z")
   2.296 +    case True
   2.297 +    with Cons have "(x, y) \<in> set (product (x # xs) ys)" by simp
   2.298 +    with True show ?thesis by simp
   2.299 +  next
   2.300 +    case False
   2.301 +    with Cons have "x \<in> set xs" by auto
   2.302 +    with Cons have "(x, y) \<in> set (product xs ys)" by auto
   2.303 +    then show "(x, y) \<in> set (product (z#xs) ys)" by auto
   2.304 +  qed
   2.305 +qed
   2.306 +
   2.307 +lemma product_sorted:
   2.308 +  assumes "sorted xs" "sorted ys"
   2.309 +  shows "sorted (product xs ys)"
   2.310 +using prems proof (induct xs)
   2.311 +  case Nil
   2.312 +  then show ?case by simp
   2.313 +next
   2.314 +  case (Cons x xs)
   2.315 +  from Cons ordered.sorted_weakening have "sorted xs" by auto
   2.316 +  with Cons have "sorted (product xs ys)" by auto
   2.317 +  then show ?case apply simp
   2.318 +  proof -
   2.319 +    assume 
   2.320 +apply simp
   2.321 +  
   2.322 +  proof (cases "x = z")
   2.323 +    case True
   2.324 +    with Cons have "(x, y) \<in> set (product (x # xs) ys)" by simp
   2.325 +    with True show ?thesis by simp
   2.326 +  next
   2.327 +    case False
   2.328 +    with Cons have "x \<in> set xs" by auto
   2.329 +    with Cons have "(x, y) \<in> set (product xs ys)" by auto
   2.330 +    then show "(x, y) \<in> set (product (z#xs) ys)" by auto
   2.331 +  qed
   2.332 +qed
   2.333 +
   2.334 +instance (enum, enum) * :: enum
   2.335 +  "_3": "enum == product enum enum"
   2.336 +apply default
   2.337 +apply (simp_all add: "enum_*_def")
   2.338 +apply (unfold split_paired_all)
   2.339 +apply (rule product_all)
   2.340 +apply (rule member_enum)+
   2.341 +sorry*)
   2.342 +
   2.343 +instance (enum) option :: enum
   2.344 +  "_4": "enum == None # map Some enum"
   2.345 +proof (default, unfold enum_option_def)
   2.346 +  fix x :: "'a::enum option"
   2.347 +  show "x \<in> set (None # map Some enum)"
   2.348 +  proof (cases x)
   2.349 +    case None then show ?thesis by auto
   2.350 +  next
   2.351 +    case (Some x) then show ?thesis by (auto intro: member_enum)
   2.352 +  qed
   2.353 +next
   2.354 +  show "sorted (None # map Some (enum :: ('a::enum) list))"
   2.355 +  sorry
   2.356 +  (*proof (cases "enum :: 'a list")
   2.357 +    case Nil then show ?thesis by simp
   2.358 +  next
   2.359 +   case (Cons x xs)
   2.360 +   then have "sorted (None # map Some (x # xs))" sorry
   2.361 +   then show ?thesis apply simp
   2.362 +  apply simp_all
   2.363 +  apply auto*)
   2.364 +qed
   2.365 +
   2.366 +ML {* reset quick_and_dirty *}
   2.367 +
   2.368 +consts
   2.369 +  get_first :: "('a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'a option"
   2.370 +
   2.371 +primrec
   2.372 +  "get_first p [] = None"
   2.373 +  "get_first p (x#xs) = (if p x then Some x else get_first p xs)"
   2.374 +
   2.375 +consts
   2.376 +  get_index :: "('a \<Rightarrow> bool) \<Rightarrow> nat \<Rightarrow> 'a list \<Rightarrow> nat option"
   2.377 +
   2.378 +primrec
   2.379 +  "get_index p n [] = None"
   2.380 +  "get_index p n (x#xs) = (if p x then Some n else get_index p (Suc n) xs)"
   2.381 +
   2.382 +definition
   2.383 +  between :: "'a::enum \<Rightarrow> 'a \<Rightarrow> 'a option"
   2.384 +  "between x y = get_first (\<lambda>z. x << z & z << y) enum"
   2.385 +
   2.386 +definition
   2.387 +  index :: "'a::enum \<Rightarrow> nat"
   2.388 +  "index x = the (get_index (\<lambda>y. y = x) 0 enum)"
   2.389 +
   2.390 +definition
   2.391 +  add :: "'a::enum \<Rightarrow> 'a \<Rightarrow> 'a"
   2.392 +  "add x y =
   2.393 +    (let
   2.394 +      enm = enum
   2.395 +    in enm ! ((index x + index y) mod length enm))"
   2.396 +
   2.397 +consts
   2.398 +  sum :: "'a::{enum, infimum} list \<Rightarrow> 'a"
   2.399 +
   2.400 +primrec
   2.401 +  "sum [] = inf"
   2.402 +  "sum (x#xs) = add x (sum xs)"
   2.403 +
   2.404 +definition
   2.405 +  "test1 = sum [None, Some True, None, Some False]"
   2.406 +  "test2 = (inf :: nat \<times> unit)"
   2.407 +
   2.408 +code_generate eq
   2.409 +code_generate "op <<="
   2.410 +code_generate "op <<"
   2.411 +code_generate inf
   2.412 +code_generate between
   2.413 +code_generate index
   2.414 +code_generate sum
   2.415 +code_generate test1
   2.416 +code_generate test2
   2.417 +
   2.418 +code_serialize ml (-)
   2.419 +
   2.420 +end
   2.421 \ No newline at end of file
     3.1 --- a/src/HOL/ex/ROOT.ML	Wed Aug 30 08:30:09 2006 +0200
     3.2 +++ b/src/HOL/ex/ROOT.ML	Wed Aug 30 08:34:45 2006 +0200
     3.3 @@ -7,6 +7,7 @@
     3.4  no_document time_use_thy "Classpackage";
     3.5  no_document time_use_thy "Codegenerator";
     3.6  no_document time_use_thy "CodeOperationalEquality";
     3.7 +no_document time_use_thy "CodeCollections";
     3.8  no_document time_use_thy "CodeEval";
     3.9  no_document time_use_thy "CodeRandom";
    3.10