src/HOL/List.thy
changeset 23240 7077dc80a14b
parent 23235 eb365b39b36d
child 23245 57aee3d85ff3
equal deleted inserted replaced
23239:3648e97da60b 23240:7077dc80a14b
   226 subsubsection {* List comprehehsion *}
   226 subsubsection {* List comprehehsion *}
   227 
   227 
   228 text{* Input syntax for Haskell-like list comprehension
   228 text{* Input syntax for Haskell-like list comprehension
   229 notation. Typical example: @{text"[(x,y). x \<leftarrow> xs, y \<leftarrow> ys, x \<noteq> y]"}, the list of all pairs of distinct elements from @{text xs} and @{text ys}.
   229 notation. Typical example: @{text"[(x,y). x \<leftarrow> xs, y \<leftarrow> ys, x \<noteq> y]"}, the list of all pairs of distinct elements from @{text xs} and @{text ys}.
   230 
   230 
   231 There are a number of differences to Haskell.  The general synatx is
   231 There are two differences to Haskell.  The general synatx is
   232 @{text"[e. p \<leftarrow> xs, \<dots>]"} rather than \verb![x| x <- xs, ...]!. The
   232 @{text"[e. p \<leftarrow> xs, \<dots>]"} rather than \verb![x| x <- xs, ...]!. Patterns in
   233 first qualifier must be a generator (@{text"p \<leftarrow> xs"}). Patterns in
   233 generators can only be tuples (at the moment).
   234 generators can only be tuples (at the moment). Finally, guards are
   234 
   235 translated into filters, which simplifies theorem proving.
   235 To avoid misunderstandings, the translation is not reversed upon
       
   236 output. You can add the inverse translations in your own theory if you
       
   237 desire.
       
   238 
       
   239 Hint: formulae containing complex list comprehensions may become quite
       
   240 unreadable after the simplifier has finished with them. It can be
       
   241 helpful to introduce definitions for such list comprehensions and
       
   242 treat them separately in suitable lemmas.
   236 *}
   243 *}
   237 (*
   244 (*
   238 The print translation from internal form to list comprehensions would
   245 Proper theorem proving support would be nice. For example, if
   239 be nice. Unfortunately one cannot just turn the translations around
       
   240 because in the final equality @{text p} occurs twice on the
       
   241 right-hand side. Due to this restriction, the translation must be hand-coded.
       
   242 
       
   243 A more substantial extension would be proper theorem proving
       
   244 support. For example, it would be nice if
       
   245 @{text"set[f x y. x \<leftarrow> xs, y \<leftarrow> ys, P x y]"}
   246 @{text"set[f x y. x \<leftarrow> xs, y \<leftarrow> ys, P x y]"}
   246 produced something like
   247 produced something like
   247 @{term"{z. EX x: set xs. EX y:set ys. P x y \<and> z = f x y}"}.
   248 @{term"{z. EX x: set xs. EX y:set ys. P x y \<and> z = f x y}"}.
   248 *)
   249 *)
   249 
   250 
   250 nonterminals lc_qual
   251 nonterminals lc_qual lc_quals
   251 
   252 
   252 syntax
   253 syntax
   253 "_listcompr" :: "'a \<Rightarrow> pttrn \<Rightarrow> 'b list \<Rightarrow> lc_qual \<Rightarrow> 'a list"  ("[_ . _ \<leftarrow> __")
   254 "_listcompr" :: "'a \<Rightarrow> lc_qual \<Rightarrow> lc_quals \<Rightarrow> 'a list"  ("[_ . __")
   254 "_listcompr" :: "'a \<Rightarrow> pttrn \<Rightarrow> 'b list \<Rightarrow> lc_qual \<Rightarrow> 'a list"  ("[_ . _ <- __")
   255 "_lc_gen" :: "pttrn \<Rightarrow> 'a list \<Rightarrow> lc_qual" ("_ \<leftarrow> _")
   255 "_lc_end" :: "lc_qual" ("]")
   256 "_lc_gen" :: "pttrn \<Rightarrow> 'a list \<Rightarrow> lc_qual" ("_ <- _")
   256 "_lc_gen" :: "pttrn \<Rightarrow> 'a list \<Rightarrow> lc_qual \<Rightarrow> lc_qual" (",_ \<leftarrow> __")
   257 "_lc_test" :: "bool \<Rightarrow> lc_qual" ("_")
   257 "_lc_gen" :: "pttrn \<Rightarrow> 'a list \<Rightarrow> lc_qual \<Rightarrow> lc_qual" (",_ <- __")
   258 "_lc_end" :: "lc_quals" ("]")
   258 "_lc_test" :: "bool \<Rightarrow> lc_qual \<Rightarrow> lc_qual" (",__")
   259 "_lc_quals" :: "lc_qual \<Rightarrow> lc_quals \<Rightarrow> lc_quals" (", __")
   259 
       
   260 
   260 
   261 translations
   261 translations
   262 "[e. p\<leftarrow>xs]" => "map (%p. e) xs"
   262 "[e. p\<leftarrow>xs]" => "map (%p. e) xs"
   263 "_listcompr e p xs (_lc_gen q ys Q)" =>
   263 "_listcompr e (_lc_gen p xs) (_lc_quals Q Qs)"
   264  "concat (map (%p. _listcompr e q ys Q) xs)"
   264  => "concat (map (%p. _listcompr e Q Qs) xs)"
   265 "_listcompr e p xs (_lc_test P Q)" => "_listcompr e p (filter (%p. P) xs) Q"
   265 "[e. P]" => "if P then [e] else []"
   266 
   266 "_listcompr e (_lc_test P) (_lc_quals Q Qs)"
   267 (* Some examples:
   267  => "if P then (_listcompr e Q Qs) else []"
   268 term "[(x,y). x \<leftarrow> xs, x<y]"
   268 
   269 term "[(x,y). x \<leftarrow> xs, x<y, z\<leftarrow>zs]"
   269 (*
   270 term "[(x,y). x \<leftarrow> xs, y \<leftarrow> ys, x<y]"
   270 term "[(x,y,z). b]"
   271 term "[(x,y,z). x \<leftarrow> xs, y \<leftarrow> ys, z\<leftarrow> zs]"
   271 term "[(x,y,z). x \<leftarrow> xs]"
   272 term "[x. x \<leftarrow> xs, x < a, x > b]"
   272 term "[(x,y,z). x<a, x>b]"
       
   273 term "[(x,y,z). x<a, x\<leftarrow>xs]"
       
   274 term "[(x,y,z). x\<leftarrow>xs, x>b]"
       
   275 term "[(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys]"
       
   276 term "[(x,y,z). x<a, x>b, x=d]"
       
   277 term "[(x,y,z). x<a, x>b, y\<leftarrow>ys]"
       
   278 term "[(x,y,z). x<a, x\<leftarrow>xs,y>b]"
       
   279 term "[(x,y,z). x<a, x\<leftarrow>xs, y\<leftarrow>ys]"
       
   280 term "[(x,y,z). x\<leftarrow>xs, x>b, y<a]"
       
   281 term "[(x,y,z). x\<leftarrow>xs, x>b, y\<leftarrow>ys]"
       
   282 term "[(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys,y>x]"
       
   283 term "[(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys,z\<leftarrow>zs]"
   273 *)
   284 *)
       
   285 
   274 
   286 
   275 subsubsection {* @{const Nil} and @{const Cons} *}
   287 subsubsection {* @{const Nil} and @{const Cons} *}
   276 
   288 
   277 lemma not_Cons_self [simp]:
   289 lemma not_Cons_self [simp]:
   278   "xs \<noteq> x # xs"
   290   "xs \<noteq> x # xs"