220 "splice (x#xs) ys = (if ys=[] then x#xs else x # hd ys # splice xs (tl ys))" |
220 "splice (x#xs) ys = (if ys=[] then x#xs else x # hd ys # splice xs (tl ys))" |
221 -- {*Warning: simpset does not contain the second eqn but a derived one. *} |
221 -- {*Warning: simpset does not contain the second eqn but a derived one. *} |
222 |
222 |
223 subsubsection {* List comprehension *} |
223 subsubsection {* List comprehension *} |
224 |
224 |
225 text{* Input syntax for Haskell-like list comprehension |
225 text{* Input syntax for Haskell-like list comprehension notation. |
226 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}. |
226 Typical example: @{text"[(x,y). x \<leftarrow> xs, y \<leftarrow> ys, x \<noteq> y]"}, |
227 |
227 the list of all pairs of distinct elements from @{text xs} and @{text ys}. |
228 There are two differences to Haskell. The general synatx is |
228 The syntax is as in Haskell, except that @{text"|"} becomes a dot |
229 @{text"[e. p \<leftarrow> xs, \<dots>]"} rather than \verb![x| x <- xs, ...]!. Patterns in |
229 (like in Isabelle's set comprehension): @{text"[e. x \<leftarrow> xs, \<dots>]"} rather than |
230 generators can only be tuples (at the moment). |
230 \verb![e| x <- xs, ...]!. |
|
231 |
|
232 The qualifiers after the dot are |
|
233 \begin{description} |
|
234 \item[generators] @{text"p \<leftarrow> xs"}, |
|
235 where @{text p} is a pattern and @{text xs} an expression of list type, |
|
236 \item[guards] @{text"b"}, where @{text b} is a boolean expression, or |
|
237 \item[local bindings] @{text"let x = e"}. |
|
238 \end{description} |
231 |
239 |
232 To avoid misunderstandings, the translation is not reversed upon |
240 To avoid misunderstandings, the translation is not reversed upon |
233 output. You can add the inverse translations in your own theory if you |
241 output. You can add the inverse translations in your own theory if you |
234 desire. |
242 desire. |
235 |
243 |
236 Hint: formulae containing complex list comprehensions may become quite |
244 It is easy to write short list comprehensions which stand for complex |
237 unreadable after the simplifier has finished with them. It can be |
245 expressions. During proofs, they may become unreadable (and |
238 helpful to introduce definitions for such list comprehensions and |
246 mangled). In such cases it can be advisable to introduce separate |
239 treat them separately in suitable lemmas. |
247 definitions for the list comprehensions in question. *} |
240 *} |
248 |
241 (* |
249 (* |
242 Proper theorem proving support would be nice. For example, if |
250 Proper theorem proving support would be nice. For example, if |
243 @{text"set[f x y. x \<leftarrow> xs, y \<leftarrow> ys, P x y]"} |
251 @{text"set[f x y. x \<leftarrow> xs, y \<leftarrow> ys, P x y]"} |
244 produced something like |
252 produced something like |
245 @{term"{z. EX x: set xs. EX y:set ys. P x y \<and> z = f x y}"}. |
253 @{term"{z. EX x: set xs. EX y:set ys. P x y \<and> z = f x y}"}. |
247 |
255 |
248 nonterminals lc_qual lc_quals |
256 nonterminals lc_qual lc_quals |
249 |
257 |
250 syntax |
258 syntax |
251 "_listcompr" :: "'a \<Rightarrow> lc_qual \<Rightarrow> lc_quals \<Rightarrow> 'a list" ("[_ . __") |
259 "_listcompr" :: "'a \<Rightarrow> lc_qual \<Rightarrow> lc_quals \<Rightarrow> 'a list" ("[_ . __") |
252 "_lc_gen" :: "pttrn \<Rightarrow> 'a list \<Rightarrow> lc_qual" ("_ <- _") |
260 "_lc_gen" :: "'a \<Rightarrow> 'a list \<Rightarrow> lc_qual" ("_ <- _") |
253 "_lc_test" :: "bool \<Rightarrow> lc_qual" ("_") |
261 "_lc_test" :: "bool \<Rightarrow> lc_qual" ("_") |
|
262 "_lc_let" :: "letbinds => lc_qual" ("let _") |
254 "_lc_end" :: "lc_quals" ("]") |
263 "_lc_end" :: "lc_quals" ("]") |
255 "_lc_quals" :: "lc_qual \<Rightarrow> lc_quals \<Rightarrow> lc_quals" (", __") |
264 "_lc_quals" :: "lc_qual \<Rightarrow> lc_quals \<Rightarrow> lc_quals" (", __") |
|
265 "_lc_abs" :: "'a => 'b list => 'b list" |
256 |
266 |
257 translations |
267 translations |
258 "[e. p<-xs]" => "map (%p. e) xs" |
268 "[e. p<-xs]" => "concat(map (_lc_abs p [e]) xs)" |
259 "_listcompr e (_lc_gen p xs) (_lc_quals Q Qs)" |
269 "_listcompr e (_lc_gen p xs) (_lc_quals Q Qs)" |
260 => "concat (map (%p. _listcompr e Q Qs) xs)" |
270 => "concat (map (_lc_abs p (_listcompr e Q Qs)) xs)" |
261 "[e. P]" => "if P then [e] else []" |
271 "[e. P]" => "if P then [e] else []" |
262 "_listcompr e (_lc_test P) (_lc_quals Q Qs)" |
272 "_listcompr e (_lc_test P) (_lc_quals Q Qs)" |
263 => "if P then (_listcompr e Q Qs) else []" |
273 => "if P then (_listcompr e Q Qs) else []" |
|
274 "_listcompr e (_lc_let b) (_lc_quals Q Qs)" |
|
275 => "_Let b (_listcompr e Q Qs)" |
264 |
276 |
265 syntax (xsymbols) |
277 syntax (xsymbols) |
266 "_lc_gen" :: "pttrn \<Rightarrow> 'a list \<Rightarrow> lc_qual" ("_ \<leftarrow> _") |
278 "_lc_gen" :: "'a \<Rightarrow> 'a list \<Rightarrow> lc_qual" ("_ \<leftarrow> _") |
267 syntax (HTML output) |
279 syntax (HTML output) |
268 "_lc_gen" :: "pttrn \<Rightarrow> 'a list \<Rightarrow> lc_qual" ("_ \<leftarrow> _") |
280 "_lc_gen" :: "'a \<Rightarrow> 'a list \<Rightarrow> lc_qual" ("_ \<leftarrow> _") |
269 |
281 |
|
282 parse_translation (advanced) {* |
|
283 let |
|
284 |
|
285 fun abs_tr0 ctxt p es = |
|
286 let |
|
287 val x = Free (Name.variant (add_term_free_names (p$es, [])) "x", dummyT); |
|
288 val case1 = Syntax.const "_case1" $ p $ es; |
|
289 val case2 = Syntax.const "_case1" $ Syntax.const Term.dummy_patternN |
|
290 $ Syntax.const @{const_name Nil}; |
|
291 val cs = Syntax.const "_case2" $ case1 $ case2 |
|
292 val ft = DatatypeCase.case_tr false DatatypePackage.datatype_of_constr |
|
293 ctxt [x, cs] |
|
294 in lambda x ft end; |
|
295 |
|
296 fun abs_tr ctxt [x as Free (s, T), r] = |
|
297 let val thy = ProofContext.theory_of ctxt; |
|
298 val s' = Sign.intern_const thy s |
|
299 in if Sign.declared_const thy s' then abs_tr0 ctxt x r else lambda x r |
|
300 end |
|
301 | abs_tr ctxt [p,es] = abs_tr0 ctxt p es |
|
302 |
|
303 in [("_lc_abs", abs_tr)] end |
|
304 *} |
270 |
305 |
271 (* |
306 (* |
272 term "[(x,y,z). b]" |
307 term "[(x,y,z). b]" |
273 term "[(x,y,z). x \<leftarrow> xs]" |
308 term "[(x,y). Cons True x \<leftarrow> xs]" |
|
309 term "[(x,y,z). Cons x [] \<leftarrow> xs]" |
274 term "[(x,y,z). x<a, x>b]" |
310 term "[(x,y,z). x<a, x>b]" |
275 term "[(x,y,z). x<a, x\<leftarrow>xs]" |
311 term "[(x,y,z). x<a, x\<leftarrow>xs]" |
276 term "[(x,y,z). x\<leftarrow>xs, x>b]" |
312 term "[(x,y,z). x\<leftarrow>xs, x>b]" |
277 term "[(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys]" |
313 term "[(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys]" |
278 term "[(x,y,z). x<a, x>b, x=d]" |
314 term "[(x,y,z). x<a, x>b, x=d]" |
281 term "[(x,y,z). x<a, x\<leftarrow>xs, y\<leftarrow>ys]" |
317 term "[(x,y,z). x<a, x\<leftarrow>xs, y\<leftarrow>ys]" |
282 term "[(x,y,z). x\<leftarrow>xs, x>b, y<a]" |
318 term "[(x,y,z). x\<leftarrow>xs, x>b, y<a]" |
283 term "[(x,y,z). x\<leftarrow>xs, x>b, y\<leftarrow>ys]" |
319 term "[(x,y,z). x\<leftarrow>xs, x>b, y\<leftarrow>ys]" |
284 term "[(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys,y>x]" |
320 term "[(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys,y>x]" |
285 term "[(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys,z\<leftarrow>zs]" |
321 term "[(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys,z\<leftarrow>zs]" |
|
322 term "[(x,y). x\<leftarrow>xs, let xx = x+x, y\<leftarrow>ys, y \<noteq> xx]" |
286 *) |
323 *) |
287 |
|
288 |
324 |
289 subsubsection {* @{const Nil} and @{const Cons} *} |
325 subsubsection {* @{const Nil} and @{const Cons} *} |
290 |
326 |
291 lemma not_Cons_self [simp]: |
327 lemma not_Cons_self [simp]: |
292 "xs \<noteq> x # xs" |
328 "xs \<noteq> x # xs" |
1542 |
1581 |
1543 subsubsection {* @{text list_all2} *} |
1582 subsubsection {* @{text list_all2} *} |
1544 |
1583 |
1545 lemma list_all2_lengthD [intro?]: |
1584 lemma list_all2_lengthD [intro?]: |
1546 "list_all2 P xs ys ==> length xs = length ys" |
1585 "list_all2 P xs ys ==> length xs = length ys" |
1547 by (simp add: list_all2_def) |
1586 by (simp add: list_all2_def) |
1548 |
1587 |
1549 lemma list_all2_Nil [iff, code]: "list_all2 P [] ys = (ys = [])" |
1588 lemma list_all2_Nil [iff, code]: "list_all2 P [] ys = (ys = [])" |
1550 by (simp add: list_all2_def) |
1589 by (simp add: list_all2_def) |
1551 |
1590 |
1552 lemma list_all2_Nil2 [iff, code]: "list_all2 P xs [] = (xs = [])" |
1591 lemma list_all2_Nil2 [iff, code]: "list_all2 P xs [] = (xs = [])" |
1553 by (simp add: list_all2_def) |
1592 by (simp add: list_all2_def) |
1554 |
1593 |
1555 lemma list_all2_Cons [iff, code]: |
1594 lemma list_all2_Cons [iff, code]: |
1556 "list_all2 P (x # xs) (y # ys) = (P x y \<and> list_all2 P xs ys)" |
1595 "list_all2 P (x # xs) (y # ys) = (P x y \<and> list_all2 P xs ys)" |
1557 by (auto simp add: list_all2_def) |
1596 by (auto simp add: list_all2_def) |
1558 |
1597 |
1559 lemma list_all2_Cons1: |
1598 lemma list_all2_Cons1: |
1560 "list_all2 P (x # xs) ys = (\<exists>z zs. ys = z # zs \<and> P x z \<and> list_all2 P xs zs)" |
1599 "list_all2 P (x # xs) ys = (\<exists>z zs. ys = z # zs \<and> P x z \<and> list_all2 P xs zs)" |
1561 by (cases ys) auto |
1600 by (cases ys) auto |
1562 |
1601 |
1624 qed simp |
1663 qed simp |
1625 qed simp |
1664 qed simp |
1626 |
1665 |
1627 lemma list_all2_all_nthI [intro?]: |
1666 lemma list_all2_all_nthI [intro?]: |
1628 "length a = length b \<Longrightarrow> (\<And>n. n < length a \<Longrightarrow> P (a!n) (b!n)) \<Longrightarrow> list_all2 P a b" |
1667 "length a = length b \<Longrightarrow> (\<And>n. n < length a \<Longrightarrow> P (a!n) (b!n)) \<Longrightarrow> list_all2 P a b" |
1629 by (simp add: list_all2_conv_all_nth) |
1668 by (simp add: list_all2_conv_all_nth) |
1630 |
1669 |
1631 lemma list_all2I: |
1670 lemma list_all2I: |
1632 "\<forall>x \<in> set (zip a b). split P x \<Longrightarrow> length a = length b \<Longrightarrow> list_all2 P a b" |
1671 "\<forall>x \<in> set (zip a b). split P x \<Longrightarrow> length a = length b \<Longrightarrow> list_all2 P a b" |
1633 by (simp add: list_all2_def) |
1672 by (simp add: list_all2_def) |
1634 |
1673 |
1635 lemma list_all2_nthD: |
1674 lemma list_all2_nthD: |
1636 "\<lbrakk> list_all2 P xs ys; p < size xs \<rbrakk> \<Longrightarrow> P (xs!p) (ys!p)" |
1675 "\<lbrakk> list_all2 P xs ys; p < size xs \<rbrakk> \<Longrightarrow> P (xs!p) (ys!p)" |
1637 by (simp add: list_all2_conv_all_nth) |
1676 by (simp add: list_all2_conv_all_nth) |
1638 |
1677 |
1639 lemma list_all2_nthD2: |
1678 lemma list_all2_nthD2: |
1640 "\<lbrakk>list_all2 P xs ys; p < size ys\<rbrakk> \<Longrightarrow> P (xs!p) (ys!p)" |
1679 "\<lbrakk>list_all2 P xs ys; p < size ys\<rbrakk> \<Longrightarrow> P (xs!p) (ys!p)" |
1641 by (frule list_all2_lengthD) (auto intro: list_all2_nthD) |
1680 by (frule list_all2_lengthD) (auto intro: list_all2_nthD) |
1642 |
1681 |
1643 lemma list_all2_map1: |
1682 lemma list_all2_map1: |
1644 "list_all2 P (map f as) bs = list_all2 (\<lambda>x y. P (f x) y) as bs" |
1683 "list_all2 P (map f as) bs = list_all2 (\<lambda>x y. P (f x) y) as bs" |
1645 by (simp add: list_all2_conv_all_nth) |
1684 by (simp add: list_all2_conv_all_nth) |
1646 |
1685 |
1647 lemma list_all2_map2: |
1686 lemma list_all2_map2: |
1648 "list_all2 P as (map f bs) = list_all2 (\<lambda>x y. P x (f y)) as bs" |
1687 "list_all2 P as (map f bs) = list_all2 (\<lambda>x y. P x (f y)) as bs" |
1649 by (auto simp add: list_all2_conv_all_nth) |
1688 by (auto simp add: list_all2_conv_all_nth) |
1650 |
1689 |
1651 lemma list_all2_refl [intro?]: |
1690 lemma list_all2_refl [intro?]: |
1652 "(\<And>x. P x x) \<Longrightarrow> list_all2 P xs xs" |
1691 "(\<And>x. P x x) \<Longrightarrow> list_all2 P xs xs" |
1653 by (simp add: list_all2_conv_all_nth) |
1692 by (simp add: list_all2_conv_all_nth) |
1654 |
1693 |
1655 lemma list_all2_update_cong: |
1694 lemma list_all2_update_cong: |
1656 "\<lbrakk> i<size xs; list_all2 P xs ys; P x y \<rbrakk> \<Longrightarrow> list_all2 P (xs[i:=x]) (ys[i:=y])" |
1695 "\<lbrakk> i<size xs; list_all2 P xs ys; P x y \<rbrakk> \<Longrightarrow> list_all2 P (xs[i:=x]) (ys[i:=y])" |
1657 by (simp add: list_all2_conv_all_nth nth_list_update) |
1696 by (simp add: list_all2_conv_all_nth nth_list_update) |
1658 |
1697 |
1659 lemma list_all2_update_cong2: |
1698 lemma list_all2_update_cong2: |
1660 "\<lbrakk>list_all2 P xs ys; P x y; i < length ys\<rbrakk> \<Longrightarrow> list_all2 P (xs[i:=x]) (ys[i:=y])" |
1699 "\<lbrakk>list_all2 P xs ys; P x y; i < length ys\<rbrakk> \<Longrightarrow> list_all2 P (xs[i:=x]) (ys[i:=y])" |
1661 by (simp add: list_all2_lengthD list_all2_update_cong) |
1700 by (simp add: list_all2_lengthD list_all2_update_cong) |
1662 |
1701 |
1663 lemma list_all2_takeI [simp,intro?]: |
1702 lemma list_all2_takeI [simp,intro?]: |
1664 "\<And>n ys. list_all2 P xs ys \<Longrightarrow> list_all2 P (take n xs) (take n ys)" |
1703 "\<And>n ys. list_all2 P xs ys \<Longrightarrow> list_all2 P (take n xs) (take n ys)" |
1665 apply (induct xs) |
1704 apply (induct xs) |
1666 apply simp |
1705 apply simp |
2554 lexord :: "('a * 'a)set \<Rightarrow> ('a list * 'a list) set" |
2593 lexord :: "('a * 'a)set \<Rightarrow> ('a list * 'a list) set" |
2555 "lexord r == {(x,y). \<exists> a v. y = x @ a # v \<or> |
2594 "lexord r == {(x,y). \<exists> a v. y = x @ a # v \<or> |
2556 (\<exists> u a b v w. (a,b) \<in> r \<and> x = u @ (a # v) \<and> y = u @ (b # w))}" |
2595 (\<exists> u a b v w. (a,b) \<in> r \<and> x = u @ (a # v) \<and> y = u @ (b # w))}" |
2557 |
2596 |
2558 lemma lexord_Nil_left[simp]: "([],y) \<in> lexord r = (\<exists> a x. y = a # x)" |
2597 lemma lexord_Nil_left[simp]: "([],y) \<in> lexord r = (\<exists> a x. y = a # x)" |
2559 by (unfold lexord_def, induct_tac y, auto) |
2598 by (unfold lexord_def, induct_tac y, auto) |
2560 |
2599 |
2561 lemma lexord_Nil_right[simp]: "(x,[]) \<notin> lexord r" |
2600 lemma lexord_Nil_right[simp]: "(x,[]) \<notin> lexord r" |
2562 by (unfold lexord_def, induct_tac x, auto) |
2601 by (unfold lexord_def, induct_tac x, auto) |
2563 |
2602 |
2564 lemma lexord_cons_cons[simp]: |
2603 lemma lexord_cons_cons[simp]: |
2565 "((a # x, b # y) \<in> lexord r) = ((a,b)\<in> r | (a = b & (x,y)\<in> lexord r))" |
2604 "((a # x, b # y) \<in> lexord r) = ((a,b)\<in> r | (a = b & (x,y)\<in> lexord r))" |
2566 apply (unfold lexord_def, safe, simp_all) |
2605 apply (unfold lexord_def, safe, simp_all) |
2567 apply (case_tac u, simp, simp) |
2606 apply (case_tac u, simp, simp) |
2570 by force |
2609 by force |
2571 |
2610 |
2572 lemmas lexord_simps = lexord_Nil_left lexord_Nil_right lexord_cons_cons |
2611 lemmas lexord_simps = lexord_Nil_left lexord_Nil_right lexord_cons_cons |
2573 |
2612 |
2574 lemma lexord_append_rightI: "\<exists> b z. y = b # z \<Longrightarrow> (x, x @ y) \<in> lexord r" |
2613 lemma lexord_append_rightI: "\<exists> b z. y = b # z \<Longrightarrow> (x, x @ y) \<in> lexord r" |
2575 by (induct_tac x, auto) |
2614 by (induct_tac x, auto) |
2576 |
2615 |
2577 lemma lexord_append_left_rightI: |
2616 lemma lexord_append_left_rightI: |
2578 "(a,b) \<in> r \<Longrightarrow> (u @ a # x, u @ b # y) \<in> lexord r" |
2617 "(a,b) \<in> r \<Longrightarrow> (u @ a # x, u @ b # y) \<in> lexord r" |
2579 by (induct_tac u, auto) |
2618 by (induct_tac u, auto) |
2580 |
2619 |
2581 lemma lexord_append_leftI: " (u,v) \<in> lexord r \<Longrightarrow> (x @ u, x @ v) \<in> lexord r" |
2620 lemma lexord_append_leftI: " (u,v) \<in> lexord r \<Longrightarrow> (x @ u, x @ v) \<in> lexord r" |
2582 by (induct x, auto) |
2621 by (induct x, auto) |
2583 |
2622 |
2584 lemma lexord_append_leftD: |
2623 lemma lexord_append_leftD: |
2585 "\<lbrakk> (x @ u, x @ v) \<in> lexord r; (! a. (a,a) \<notin> r) \<rbrakk> \<Longrightarrow> (u,v) \<in> lexord r" |
2624 "\<lbrakk> (x @ u, x @ v) \<in> lexord r; (! a. (a,a) \<notin> r) \<rbrakk> \<Longrightarrow> (u,v) \<in> lexord r" |
2586 by (erule rev_mp, induct_tac x, auto) |
2625 by (erule rev_mp, induct_tac x, auto) |
2587 |
2626 |
2588 lemma lexord_take_index_conv: |
2627 lemma lexord_take_index_conv: |
2589 "((x,y) : lexord r) = |
2628 "((x,y) : lexord r) = |
2590 ((length x < length y \<and> take (length x) y = x) \<or> |
2629 ((length x < length y \<and> take (length x) y = x) \<or> |
2591 (\<exists>i. i < min(length x)(length y) & take i x = take i y & (x!i,y!i) \<in> r))" |
2630 (\<exists>i. i < min(length x)(length y) & take i x = take i y & (x!i,y!i) \<in> r))" |
2645 |
2684 |
2646 definition |
2685 definition |
2647 "measures fs = inv_image (lex less_than) (%a. map (%f. f a) fs)" |
2686 "measures fs = inv_image (lex less_than) (%a. map (%f. f a) fs)" |
2648 |
2687 |
2649 lemma wf_measures[recdef_wf, simp]: "wf (measures fs)" |
2688 lemma wf_measures[recdef_wf, simp]: "wf (measures fs)" |
2650 unfolding measures_def |
2689 unfolding measures_def |
2651 by blast |
2690 by blast |
2652 |
2691 |
2653 lemma in_measures[simp]: |
2692 lemma in_measures[simp]: |
2654 "(x, y) \<in> measures [] = False" |
2693 "(x, y) \<in> measures [] = False" |
2655 "(x, y) \<in> measures (f # fs) |
2694 "(x, y) \<in> measures (f # fs) |
2656 = (f x < f y \<or> (f x = f y \<and> (x, y) \<in> measures fs))" |
2695 = (f x < f y \<or> (f x = f y \<and> (x, y) \<in> measures fs))" |
2657 unfolding measures_def |
2696 unfolding measures_def |
2658 by auto |
2697 by auto |
2659 |
2698 |
2660 lemma measures_less: "f x < f y ==> (x, y) \<in> measures (f#fs)" |
2699 lemma measures_less: "f x < f y ==> (x, y) \<in> measures (f#fs)" |
2661 by simp |
2700 by simp |
2662 |
2701 |
2663 lemma measures_lesseq: "f x <= f y ==> (x, y) \<in> measures fs ==> (x, y) \<in> measures (f#fs)" |
2702 lemma measures_lesseq: "f x <= f y ==> (x, y) \<in> measures fs ==> (x, y) \<in> measures (f#fs)" |
2664 by auto |
2703 by auto |
2665 |
2704 |
2666 (* install the lexicographic_order method and the "fun" command *) |
2705 (* install the lexicographic_order method and the "fun" command *) |
2667 use "Tools/function_package/lexicographic_order.ML" |
2706 use "Tools/function_package/lexicographic_order.ML" |
2668 use "Tools/function_package/fundef_datatype.ML" |
2707 use "Tools/function_package/fundef_datatype.ML" |
2669 setup LexicographicOrder.setup |
2708 setup LexicographicOrder.setup |
2897 show ?case by (induct xs) (auto simp add: Cons aux) |
2936 show ?case by (induct xs) (auto simp add: Cons aux) |
2898 qed |
2937 qed |
2899 |
2938 |
2900 lemma mem_iff [code post]: |
2939 lemma mem_iff [code post]: |
2901 "x mem xs \<longleftrightarrow> x \<in> set xs" |
2940 "x mem xs \<longleftrightarrow> x \<in> set xs" |
2902 by (induct xs) auto |
2941 by (induct xs) auto |
2903 |
2942 |
2904 lemmas in_set_code [code unfold] = mem_iff [symmetric] |
2943 lemmas in_set_code [code unfold] = mem_iff [symmetric] |
2905 |
2944 |
2906 lemma empty_null [code inline]: |
2945 lemma empty_null [code inline]: |
2907 "xs = [] \<longleftrightarrow> null xs" |
2946 "xs = [] \<longleftrightarrow> null xs" |
2908 by (cases xs) simp_all |
2947 by (cases xs) simp_all |
2909 |
2948 |
2910 lemmas null_empty [code post] = |
2949 lemmas null_empty [code post] = |
2911 empty_null [symmetric] |
2950 empty_null [symmetric] |
2912 |
2951 |
2913 lemma list_inter_conv: |
2952 lemma list_inter_conv: |
2914 "set (list_inter xs ys) = set xs \<inter> set ys" |
2953 "set (list_inter xs ys) = set xs \<inter> set ys" |
2915 by (induct xs) auto |
2954 by (induct xs) auto |
2916 |
2955 |
2917 lemma list_all_iff [code post]: |
2956 lemma list_all_iff [code post]: |
2918 "list_all P xs \<longleftrightarrow> (\<forall>x \<in> set xs. P x)" |
2957 "list_all P xs \<longleftrightarrow> (\<forall>x \<in> set xs. P x)" |
2919 by (induct xs) auto |
2958 by (induct xs) auto |
2920 |
2959 |
2921 lemmas list_ball_code [code unfold] = list_all_iff [symmetric] |
2960 lemmas list_ball_code [code unfold] = list_all_iff [symmetric] |
2922 |
2961 |
2923 lemma list_all_append [simp]: |
2962 lemma list_all_append [simp]: |
2924 "list_all P (xs @ ys) \<longleftrightarrow> (list_all P xs \<and> list_all P ys)" |
2963 "list_all P (xs @ ys) \<longleftrightarrow> (list_all P xs \<and> list_all P ys)" |
2925 by (induct xs) auto |
2964 by (induct xs) auto |
2926 |
2965 |
2927 lemma list_all_rev [simp]: |
2966 lemma list_all_rev [simp]: |
2928 "list_all P (rev xs) \<longleftrightarrow> list_all P xs" |
2967 "list_all P (rev xs) \<longleftrightarrow> list_all P xs" |
2929 by (simp add: list_all_iff) |
2968 by (simp add: list_all_iff) |
2930 |
2969 |
2931 lemma list_all_length: |
2970 lemma list_all_length: |
2932 "list_all P xs \<longleftrightarrow> (\<forall>n < length xs. P (xs ! n))" |
2971 "list_all P xs \<longleftrightarrow> (\<forall>n < length xs. P (xs ! n))" |
2933 unfolding list_all_iff by (auto intro: all_nth_imp_all_set) |
2972 unfolding list_all_iff by (auto intro: all_nth_imp_all_set) |
2934 |
2973 |
2935 lemma list_ex_iff [code post]: |
2974 lemma list_ex_iff [code post]: |
2936 "list_ex P xs \<longleftrightarrow> (\<exists>x \<in> set xs. P x)" |
2975 "list_ex P xs \<longleftrightarrow> (\<exists>x \<in> set xs. P x)" |
2937 by (induct xs) simp_all |
2976 by (induct xs) simp_all |
2938 |
2977 |
2939 lemmas list_bex_code [code unfold] = |
2978 lemmas list_bex_code [code unfold] = |
2940 list_ex_iff [symmetric] |
2979 list_ex_iff [symmetric] |
2941 |
2980 |
2942 lemma list_ex_length: |
2981 lemma list_ex_length: |
2943 "list_ex P xs \<longleftrightarrow> (\<exists>n < length xs. P (xs ! n))" |
2982 "list_ex P xs \<longleftrightarrow> (\<exists>n < length xs. P (xs ! n))" |
2944 unfolding list_ex_iff set_conv_nth by auto |
2983 unfolding list_ex_iff set_conv_nth by auto |
2945 |
2984 |
2946 lemma filtermap_conv: |
2985 lemma filtermap_conv: |
2947 "filtermap f xs = map (\<lambda>x. the (f x)) (filter (\<lambda>x. f x \<noteq> None) xs)" |
2986 "filtermap f xs = map (\<lambda>x. the (f x)) (filter (\<lambda>x. f x \<noteq> None) xs)" |
2948 by (induct xs) (simp_all split: option.split) |
2987 by (induct xs) (simp_all split: option.split) |
2949 |
2988 |
2950 lemma map_filter_conv [simp]: |
2989 lemma map_filter_conv [simp]: |
2951 "map_filter f P xs = map f (filter P xs)" |
2990 "map_filter f P xs = map f (filter P xs)" |
2952 by (induct xs) auto |
2991 by (induct xs) auto |
2953 |
2992 |
2954 lemma [code inline]: "listsum (map f xs) = foldl (%n x. n + f x) 0 xs" |
2993 lemma [code inline]: "listsum (map f xs) = foldl (%n x. n + f x) 0 xs" |
2955 by (simp add: listsum_foldr foldl_map [symmetric] foldl_foldr1) |
2994 by (simp add: listsum_foldr foldl_map [symmetric] foldl_foldr1) |
2956 |
2995 |
2957 |
2996 |
2958 text {* Code for bounded quantification over nats. *} |
2997 text {* Code for bounded quantification over nats. *} |
2959 |
2998 |
2960 lemma atMost_upto [code unfold]: |
2999 lemma atMost_upto [code unfold]: |
2961 "{..n} = set [0..n]" |
3000 "{..n} = set [0..n]" |
2962 by auto |
3001 by auto |
2963 |
3002 |
2964 lemma atLeast_upt [code unfold]: |
3003 lemma atLeast_upt [code unfold]: |
2965 "{..<n} = set [0..<n]" |
3004 "{..<n} = set [0..<n]" |
2966 by auto |
3005 by auto |
2967 |
3006 |
2968 lemma greaterThanLessThan_upd [code unfold]: |
3007 lemma greaterThanLessThan_upd [code unfold]: |
2969 "{n<..<m} = set [Suc n..<m]" |
3008 "{n<..<m} = set [Suc n..<m]" |
2970 by auto |
3009 by auto |
2971 |
3010 |
2972 lemma atLeastLessThan_upd [code unfold]: |
3011 lemma atLeastLessThan_upd [code unfold]: |
2973 "{n..<m} = set [n..<m]" |
3012 "{n..<m} = set [n..<m]" |
2974 by auto |
3013 by auto |
2975 |
3014 |
2976 lemma greaterThanAtMost_upto [code unfold]: |
3015 lemma greaterThanAtMost_upto [code unfold]: |
2977 "{n<..m} = set [Suc n..m]" |
3016 "{n<..m} = set [Suc n..m]" |
2978 by auto |
3017 by auto |
2979 |
3018 |
2980 lemma atLeastAtMost_upto [code unfold]: |
3019 lemma atLeastAtMost_upto [code unfold]: |
2981 "{n..m} = set [n..m]" |
3020 "{n..m} = set [n..m]" |
2982 by auto |
3021 by auto |
2983 |
3022 |
2984 lemma all_nat_less_eq [code unfold]: |
3023 lemma all_nat_less_eq [code unfold]: |
2985 "(\<forall>m<n\<Colon>nat. P m) \<longleftrightarrow> (\<forall>m \<in> {0..<n}. P m)" |
3024 "(\<forall>m<n\<Colon>nat. P m) \<longleftrightarrow> (\<forall>m \<in> {0..<n}. P m)" |
2986 by auto |
3025 by auto |
2987 |
3026 |
2988 lemma ex_nat_less_eq [code unfold]: |
3027 lemma ex_nat_less_eq [code unfold]: |
2989 "(\<exists>m<n\<Colon>nat. P m) \<longleftrightarrow> (\<exists>m \<in> {0..<n}. P m)" |
3028 "(\<exists>m<n\<Colon>nat. P m) \<longleftrightarrow> (\<exists>m \<in> {0..<n}. P m)" |
2990 by auto |
3029 by auto |
2991 |
3030 |
2992 lemma all_nat_less [code unfold]: |
3031 lemma all_nat_less [code unfold]: |
2993 "(\<forall>m\<le>n\<Colon>nat. P m) \<longleftrightarrow> (\<forall>m \<in> {0..n}. P m)" |
3032 "(\<forall>m\<le>n\<Colon>nat. P m) \<longleftrightarrow> (\<forall>m \<in> {0..n}. P m)" |
2994 by auto |
3033 by auto |
2995 |
3034 |
2996 lemma ex_nat_less [code unfold]: |
3035 lemma ex_nat_less [code unfold]: |
2997 "(\<exists>m\<le>n\<Colon>nat. P m) \<longleftrightarrow> (\<exists>m \<in> {0..n}. P m)" |
3036 "(\<exists>m\<le>n\<Colon>nat. P m) \<longleftrightarrow> (\<exists>m \<in> {0..n}. P m)" |
2998 by auto |
3037 by auto |
2999 |
3038 |
3000 lemma foldl_append_append: "\<And> ss ss'. foldl (op @) (ss@ss') xs = ss@(foldl (op @) ss' xs)" |
3039 lemma foldl_append_append: "\<And> ss ss'. foldl (op @) (ss@ss') xs = ss@(foldl (op @) ss' xs)" |
3001 by (induct xs, simp_all) |
3040 by (induct xs, simp_all) |
3002 |
3041 |
3003 lemma foldl_append_map_set: "\<And> ss. set (foldl (op @) ss (map f xs)) = set ss \<union> UNION (set xs) (\<lambda>x. set (f x))" |
3042 lemma foldl_append_map_set: "\<And> ss. set (foldl (op @) ss (map f xs)) = set ss \<union> UNION (set xs) (\<lambda>x. set (f x))" |
3004 proof(induct xs) |
3043 proof(induct xs) |
3005 case Nil thus ?case by simp |
3044 case Nil thus ?case by simp |
3006 next |
3045 next |
3007 case (Cons x xs ss) |
3046 case (Cons x xs ss) |
3008 have "set (foldl op @ ss (map f (x # xs))) = set (foldl op @ (ss @ f x) (map f xs))" by simp |
3047 have "set (foldl op @ ss (map f (x # xs))) = set (foldl op @ (ss @ f x) (map f xs))" by simp |
3009 also have "\<dots> = set (ss@ f x) \<union> UNION (set xs) (\<lambda>x. set (f x))" using prems by simp |
3048 also have "\<dots> = set (ss@ f x) \<union> UNION (set xs) (\<lambda>x. set (f x))" |
|
3049 using prems by simp |
3010 also have "\<dots>= set ss \<union> set (f x) \<union> UNION (set xs) (\<lambda>x. set (f x))" by simp |
3050 also have "\<dots>= set ss \<union> set (f x) \<union> UNION (set xs) (\<lambda>x. set (f x))" by simp |
3011 also have "\<dots> = set ss \<union> UNION (set (x#xs)) (\<lambda>x. set (f x))" |
3051 also have "\<dots> = set ss \<union> UNION (set (x#xs)) (\<lambda>x. set (f x))" |
3012 by (simp add: Un_assoc) |
3052 by (simp add: Un_assoc) |
3013 finally show ?case by simp |
3053 finally show ?case by simp |
3014 qed |
3054 qed |