# HG changeset patch # User nipkow # Date 1180988838 -7200 # Node ID 7077dc80a14bc10502eef0b9546fa86f37e20d90 # Parent 3648e97da60bb8aa1f417016b2da6f4336f0acd4 tuned list comprehension diff -r 3648e97da60b -r 7077dc80a14b src/HOL/List.thy --- a/src/HOL/List.thy Mon Jun 04 21:04:20 2007 +0200 +++ b/src/HOL/List.thy Mon Jun 04 22:27:18 2007 +0200 @@ -228,50 +228,62 @@ text{* Input syntax for Haskell-like list comprehension notation. Typical example: @{text"[(x,y). x \ xs, y \ ys, x \ y]"}, the list of all pairs of distinct elements from @{text xs} and @{text ys}. -There are a number of differences to Haskell. The general synatx is -@{text"[e. p \ xs, \]"} rather than \verb![x| x <- xs, ...]!. The -first qualifier must be a generator (@{text"p \ xs"}). Patterns in -generators can only be tuples (at the moment). Finally, guards are -translated into filters, which simplifies theorem proving. +There are two differences to Haskell. The general synatx is +@{text"[e. p \ xs, \]"} rather than \verb![x| x <- xs, ...]!. Patterns in +generators can only be tuples (at the moment). + +To avoid misunderstandings, the translation is not reversed upon +output. You can add the inverse translations in your own theory if you +desire. + +Hint: formulae containing complex list comprehensions may become quite +unreadable after the simplifier has finished with them. It can be +helpful to introduce definitions for such list comprehensions and +treat them separately in suitable lemmas. *} (* -The print translation from internal form to list comprehensions would -be nice. Unfortunately one cannot just turn the translations around -because in the final equality @{text p} occurs twice on the -right-hand side. Due to this restriction, the translation must be hand-coded. - -A more substantial extension would be proper theorem proving -support. For example, it would be nice if +Proper theorem proving support would be nice. For example, if @{text"set[f x y. x \ xs, y \ ys, P x y]"} produced something like @{term"{z. EX x: set xs. EX y:set ys. P x y \ z = f x y}"}. *) -nonterminals lc_qual +nonterminals lc_qual lc_quals syntax -"_listcompr" :: "'a \ pttrn \ 'b list \ lc_qual \ 'a list" ("[_ . _ \ __") -"_listcompr" :: "'a \ pttrn \ 'b list \ lc_qual \ 'a list" ("[_ . _ <- __") -"_lc_end" :: "lc_qual" ("]") -"_lc_gen" :: "pttrn \ 'a list \ lc_qual \ lc_qual" (",_ \ __") -"_lc_gen" :: "pttrn \ 'a list \ lc_qual \ lc_qual" (",_ <- __") -"_lc_test" :: "bool \ lc_qual \ lc_qual" (",__") - +"_listcompr" :: "'a \ lc_qual \ lc_quals \ 'a list" ("[_ . __") +"_lc_gen" :: "pttrn \ 'a list \ lc_qual" ("_ \ _") +"_lc_gen" :: "pttrn \ 'a list \ lc_qual" ("_ <- _") +"_lc_test" :: "bool \ lc_qual" ("_") +"_lc_end" :: "lc_quals" ("]") +"_lc_quals" :: "lc_qual \ lc_quals \ lc_quals" (", __") translations "[e. p\xs]" => "map (%p. e) xs" -"_listcompr e p xs (_lc_gen q ys Q)" => - "concat (map (%p. _listcompr e q ys Q) xs)" -"_listcompr e p xs (_lc_test P Q)" => "_listcompr e p (filter (%p. P) xs) Q" - -(* Some examples: -term "[(x,y). x \ xs, x xs, xzs]" -term "[(x,y). x \ xs, y \ ys, x xs, y \ ys, z\ zs]" -term "[x. x \ xs, x < a, x > b]" +"_listcompr e (_lc_gen p xs) (_lc_quals Q Qs)" + => "concat (map (%p. _listcompr e Q Qs) xs)" +"[e. P]" => "if P then [e] else []" +"_listcompr e (_lc_test P) (_lc_quals Q Qs)" + => "if P then (_listcompr e Q Qs) else []" + +(* +term "[(x,y,z). b]" +term "[(x,y,z). x \ xs]" +term "[(x,y,z). xb]" +term "[(x,y,z). xxs]" +term "[(x,y,z). x\xs, x>b]" +term "[(x,y,z). x\xs, y\ys]" +term "[(x,y,z). xb, x=d]" +term "[(x,y,z). xb, y\ys]" +term "[(x,y,z). xxs,y>b]" +term "[(x,y,z). xxs, y\ys]" +term "[(x,y,z). x\xs, x>b, yxs, x>b, y\ys]" +term "[(x,y,z). x\xs, y\ys,y>x]" +term "[(x,y,z). x\xs, y\ys,z\zs]" *) + subsubsection {* @{const Nil} and @{const Cons} *} lemma not_Cons_self [simp]: