src/HOL/Set_Interval.thy
changeset 69593 3dda49e08b9d
parent 69502 0cf906072e20
child 69700 7a92cbec7030
equal deleted inserted replaced
69592:a80d8ec6c998 69593:3dda49e08b9d
    53   "{l..u} == {l..} Int {..u}"
    53   "{l..u} == {l..} Int {..u}"
    54 
    54 
    55 end
    55 end
    56 
    56 
    57 
    57 
    58 text\<open>A note of warning when using @{term"{..<n}"} on type @{typ
    58 text\<open>A note of warning when using \<^term>\<open>{..<n}\<close> on type \<^typ>\<open>nat\<close>: it is equivalent to \<^term>\<open>{0::nat..<n}\<close> but some lemmas involving
    59 nat}: it is equivalent to @{term"{0::nat..<n}"} but some lemmas involving
    59 \<^term>\<open>{m..<n}\<close> may not exist in \<^term>\<open>{..<n}\<close>-form as well.\<close>
    60 @{term"{m..<n}"} may not exist in @{term"{..<n}"}-form as well.\<close>
       
    61 
    60 
    62 syntax (ASCII)
    61 syntax (ASCII)
    63   "_UNION_le"   :: "'a => 'a => 'b set => 'b set"       ("(3UN _<=_./ _)" [0, 0, 10] 10)
    62   "_UNION_le"   :: "'a => 'a => 'b set => 'b set"       ("(3UN _<=_./ _)" [0, 0, 10] 10)
    64   "_UNION_less" :: "'a => 'a => 'b set => 'b set"       ("(3UN _<_./ _)" [0, 0, 10] 10)
    63   "_UNION_less" :: "'a => 'a => 'b set => 'b set"       ("(3UN _<_./ _)" [0, 0, 10] 10)
    65   "_INTER_le"   :: "'a => 'a => 'b set => 'b set"       ("(3INT _<=_./ _)" [0, 0, 10] 10)
    64   "_INTER_le"   :: "'a => 'a => 'b set => 'b set"       ("(3INT _<=_./ _)" [0, 0, 10] 10)
   670     and Inf_greaterThanLessThan[simp]: "x < y \<Longrightarrow> Inf { x <..< y} = x"
   669     and Inf_greaterThanLessThan[simp]: "x < y \<Longrightarrow> Inf { x <..< y} = x"
   671   by (auto intro!: Inf_eqI Sup_eqI intro: dense_le dense_le_bounded dense_ge dense_ge_bounded)
   670   by (auto intro!: Inf_eqI Sup_eqI intro: dense_le dense_le_bounded dense_ge dense_ge_bounded)
   672 
   671 
   673 subsection \<open>Intervals of natural numbers\<close>
   672 subsection \<open>Intervals of natural numbers\<close>
   674 
   673 
   675 subsubsection \<open>The Constant @{term lessThan}\<close>
   674 subsubsection \<open>The Constant \<^term>\<open>lessThan\<close>\<close>
   676 
   675 
   677 lemma lessThan_0 [simp]: "lessThan (0::nat) = {}"
   676 lemma lessThan_0 [simp]: "lessThan (0::nat) = {}"
   678 by (simp add: lessThan_def)
   677 by (simp add: lessThan_def)
   679 
   678 
   680 lemma lessThan_Suc: "lessThan (Suc k) = insert k (lessThan k)"
   679 lemma lessThan_Suc: "lessThan (Suc k) = insert k (lessThan k)"
   681 by (simp add: lessThan_def less_Suc_eq, blast)
   680 by (simp add: lessThan_def less_Suc_eq, blast)
   682 
   681 
   683 text \<open>The following proof is convenient in induction proofs where
   682 text \<open>The following proof is convenient in induction proofs where
   684 new elements get indices at the beginning. So it is used to transform
   683 new elements get indices at the beginning. So it is used to transform
   685 @{term "{..<Suc n}"} to @{term "0::nat"} and @{term "{..< n}"}.\<close>
   684 \<^term>\<open>{..<Suc n}\<close> to \<^term>\<open>0::nat\<close> and \<^term>\<open>{..< n}\<close>.\<close>
   686 
   685 
   687 lemma zero_notin_Suc_image: "0 \<notin> Suc ` A"
   686 lemma zero_notin_Suc_image: "0 \<notin> Suc ` A"
   688   by auto
   687   by auto
   689 
   688 
   690 lemma lessThan_Suc_eq_insert_0: "{..<Suc n} = insert 0 (Suc ` {..<n})"
   689 lemma lessThan_Suc_eq_insert_0: "{..<Suc n} = insert 0 (Suc ` {..<n})"
   697   unfolding lessThan_Suc_atMost[symmetric] lessThan_Suc_eq_insert_0[of "Suc n"] ..
   696   unfolding lessThan_Suc_atMost[symmetric] lessThan_Suc_eq_insert_0[of "Suc n"] ..
   698 
   697 
   699 lemma UN_lessThan_UNIV: "(\<Union>m::nat. lessThan m) = UNIV"
   698 lemma UN_lessThan_UNIV: "(\<Union>m::nat. lessThan m) = UNIV"
   700 by blast
   699 by blast
   701 
   700 
   702 subsubsection \<open>The Constant @{term greaterThan}\<close>
   701 subsubsection \<open>The Constant \<^term>\<open>greaterThan\<close>\<close>
   703 
   702 
   704 lemma greaterThan_0: "greaterThan 0 = range Suc"
   703 lemma greaterThan_0: "greaterThan 0 = range Suc"
   705   unfolding greaterThan_def
   704   unfolding greaterThan_def
   706   by (blast dest: gr0_conv_Suc [THEN iffD1])
   705   by (blast dest: gr0_conv_Suc [THEN iffD1])
   707 
   706 
   710   by (auto elim: linorder_neqE)
   709   by (auto elim: linorder_neqE)
   711 
   710 
   712 lemma INT_greaterThan_UNIV: "(\<Inter>m::nat. greaterThan m) = {}"
   711 lemma INT_greaterThan_UNIV: "(\<Inter>m::nat. greaterThan m) = {}"
   713   by blast
   712   by blast
   714 
   713 
   715 subsubsection \<open>The Constant @{term atLeast}\<close>
   714 subsubsection \<open>The Constant \<^term>\<open>atLeast\<close>\<close>
   716 
   715 
   717 lemma atLeast_0 [simp]: "atLeast (0::nat) = UNIV"
   716 lemma atLeast_0 [simp]: "atLeast (0::nat) = UNIV"
   718 by (unfold atLeast_def UNIV_def, simp)
   717 by (unfold atLeast_def UNIV_def, simp)
   719 
   718 
   720 lemma atLeast_Suc: "atLeast (Suc k) = atLeast k - {k}"
   719 lemma atLeast_Suc: "atLeast (Suc k) = atLeast k - {k}"
   724   by (auto simp add: greaterThan_def atLeast_def less_Suc_eq_le)
   723   by (auto simp add: greaterThan_def atLeast_def less_Suc_eq_le)
   725 
   724 
   726 lemma UN_atLeast_UNIV: "(\<Union>m::nat. atLeast m) = UNIV"
   725 lemma UN_atLeast_UNIV: "(\<Union>m::nat. atLeast m) = UNIV"
   727   by blast
   726   by blast
   728 
   727 
   729 subsubsection \<open>The Constant @{term atMost}\<close>
   728 subsubsection \<open>The Constant \<^term>\<open>atMost\<close>\<close>
   730 
   729 
   731 lemma atMost_0 [simp]: "atMost (0::nat) = {0}"
   730 lemma atMost_0 [simp]: "atMost (0::nat) = {0}"
   732   by (simp add: atMost_def)
   731   by (simp add: atMost_def)
   733 
   732 
   734 lemma atMost_Suc: "atMost (Suc k) = insert (Suc k) (atMost k)"
   733 lemma atMost_Suc: "atMost (Suc k) = insert (Suc k) (atMost k)"
   735   unfolding atMost_def by (auto simp add: less_Suc_eq order_le_less)
   734   unfolding atMost_def by (auto simp add: less_Suc_eq order_le_less)
   736 
   735 
   737 lemma UN_atMost_UNIV: "(\<Union>m::nat. atMost m) = UNIV"
   736 lemma UN_atMost_UNIV: "(\<Union>m::nat. atMost m) = UNIV"
   738   by blast
   737   by blast
   739 
   738 
   740 subsubsection \<open>The Constant @{term atLeastLessThan}\<close>
   739 subsubsection \<open>The Constant \<^term>\<open>atLeastLessThan\<close>\<close>
   741 
   740 
   742 text\<open>The orientation of the following 2 rules is tricky. The lhs is
   741 text\<open>The orientation of the following 2 rules is tricky. The lhs is
   743 defined in terms of the rhs.  Hence the chosen orientation makes sense
   742 defined in terms of the rhs.  Hence the chosen orientation makes sense
   744 in this theory --- the reverse orientation complicates proofs (eg
   743 in this theory --- the reverse orientation complicates proofs (eg
   745 nontermination). But outside, when the definition of the lhs is rarely
   744 nontermination). But outside, when the definition of the lhs is rarely
   766 
   765 
   767 lemma atLeast0_lessThan_Suc_eq_insert_0: "{0..<Suc n} = insert 0 (Suc ` {0..<n})"
   766 lemma atLeast0_lessThan_Suc_eq_insert_0: "{0..<Suc n} = insert 0 (Suc ` {0..<n})"
   768   by (simp add: atLeast0LessThan lessThan_Suc_eq_insert_0)
   767   by (simp add: atLeast0LessThan lessThan_Suc_eq_insert_0)
   769 
   768 
   770 
   769 
   771 subsubsection \<open>The Constant @{term atLeastAtMost}\<close>
   770 subsubsection \<open>The Constant \<^term>\<open>atLeastAtMost\<close>\<close>
   772 
   771 
   773 lemma Icc_eq_insert_lb_nat: "m \<le> n \<Longrightarrow> {m..n} = insert m {Suc m..n}"
   772 lemma Icc_eq_insert_lb_nat: "m \<le> n \<Longrightarrow> {m..n} = insert m {Suc m..n}"
   774 by auto
   773 by auto
   775 
   774 
   776 lemma atLeast0_atMost_Suc:
   775 lemma atLeast0_atMost_Suc:
   780 lemma atLeast0_atMost_Suc_eq_insert_0:
   779 lemma atLeast0_atMost_Suc_eq_insert_0:
   781   "{0..Suc n} = insert 0 (Suc ` {0..n})"
   780   "{0..Suc n} = insert 0 (Suc ` {0..n})"
   782   by (simp add: atLeast0AtMost atMost_Suc_eq_insert_0)
   781   by (simp add: atLeast0AtMost atMost_Suc_eq_insert_0)
   783 
   782 
   784 
   783 
   785 subsubsection \<open>Intervals of nats with @{term Suc}\<close>
   784 subsubsection \<open>Intervals of nats with \<^term>\<open>Suc\<close>\<close>
   786 
   785 
   787 text\<open>Not a simprule because the RHS is too messy.\<close>
   786 text\<open>Not a simprule because the RHS is too messy.\<close>
   788 lemma atLeastLessThanSuc:
   787 lemma atLeastLessThanSuc:
   789     "{m..<Suc n} = (if m \<le> n then insert n {m..<n} else {})"
   788     "{m..<Suc n} = (if m \<le> n then insert n {m..<n} else {})"
   790 by (auto simp add: atLeastLessThan_def)
   789 by (auto simp add: atLeastLessThan_def)
   807 by (auto simp add: atLeastAtMost_def)
   806 by (auto simp add: atLeastAtMost_def)
   808 
   807 
   809 lemma atLeastAtMost_insertL: "m \<le> n \<Longrightarrow> insert m {Suc m..n} = {m ..n}"
   808 lemma atLeastAtMost_insertL: "m \<le> n \<Longrightarrow> insert m {Suc m..n} = {m ..n}"
   810 by auto
   809 by auto
   811 
   810 
   812 text \<open>The analogous result is useful on @{typ int}:\<close>
   811 text \<open>The analogous result is useful on \<^typ>\<open>int\<close>:\<close>
   813 (* here, because we don't have an own int section *)
   812 (* here, because we don't have an own int section *)
   814 lemma atLeastAtMostPlus1_int_conv:
   813 lemma atLeastAtMostPlus1_int_conv:
   815   "m <= 1+n \<Longrightarrow> {m..1+n} = insert (1+n) {m..n::int}"
   814   "m <= 1+n \<Longrightarrow> {m..1+n} = insert (1+n) {m..n::int}"
   816   by (auto intro: set_eqI)
   815   by (auto intro: set_eqI)
   817 
   816 
  1793 text\<open>The above introduces some pretty alternative syntaxes for
  1792 text\<open>The above introduces some pretty alternative syntaxes for
  1794 summation over intervals:
  1793 summation over intervals:
  1795 \begin{center}
  1794 \begin{center}
  1796 \begin{tabular}{lll}
  1795 \begin{tabular}{lll}
  1797 Old & New & \LaTeX\\
  1796 Old & New & \LaTeX\\
  1798 @{term[source]"\<Sum>x\<in>{a..b}. e"} & @{term"\<Sum>x=a..b. e"} & @{term[mode=latex_sum]"\<Sum>x=a..b. e"}\\
  1797 @{term[source]"\<Sum>x\<in>{a..b}. e"} & \<^term>\<open>\<Sum>x=a..b. e\<close> & @{term[mode=latex_sum]"\<Sum>x=a..b. e"}\\
  1799 @{term[source]"\<Sum>x\<in>{a..<b}. e"} & @{term"\<Sum>x=a..<b. e"} & @{term[mode=latex_sum]"\<Sum>x=a..<b. e"}\\
  1798 @{term[source]"\<Sum>x\<in>{a..<b}. e"} & \<^term>\<open>\<Sum>x=a..<b. e\<close> & @{term[mode=latex_sum]"\<Sum>x=a..<b. e"}\\
  1800 @{term[source]"\<Sum>x\<in>{..b}. e"} & @{term"\<Sum>x\<le>b. e"} & @{term[mode=latex_sum]"\<Sum>x\<le>b. e"}\\
  1799 @{term[source]"\<Sum>x\<in>{..b}. e"} & \<^term>\<open>\<Sum>x\<le>b. e\<close> & @{term[mode=latex_sum]"\<Sum>x\<le>b. e"}\\
  1801 @{term[source]"\<Sum>x\<in>{..<b}. e"} & @{term"\<Sum>x<b. e"} & @{term[mode=latex_sum]"\<Sum>x<b. e"}
  1800 @{term[source]"\<Sum>x\<in>{..<b}. e"} & \<^term>\<open>\<Sum>x<b. e\<close> & @{term[mode=latex_sum]"\<Sum>x<b. e"}
  1802 \end{tabular}
  1801 \end{tabular}
  1803 \end{center}
  1802 \end{center}
  1804 The left column shows the term before introduction of the new syntax,
  1803 The left column shows the term before introduction of the new syntax,
  1805 the middle column shows the new (default) syntax, and the right column
  1804 the middle column shows the new (default) syntax, and the right column
  1806 shows a special syntax. The latter is only meaningful for latex output
  1805 shows a special syntax. The latter is only meaningful for latex output
  1807 and has to be activated explicitly by setting the print mode to
  1806 and has to be activated explicitly by setting the print mode to
  1808 \<open>latex_sum\<close> (e.g.\ via \<open>mode = latex_sum\<close> in
  1807 \<open>latex_sum\<close> (e.g.\ via \<open>mode = latex_sum\<close> in
  1809 antiquotations). It is not the default \LaTeX\ output because it only
  1808 antiquotations). It is not the default \LaTeX\ output because it only
  1810 works well with italic-style formulae, not tt-style.
  1809 works well with italic-style formulae, not tt-style.
  1811 
  1810 
  1812 Note that for uniformity on @{typ nat} it is better to use
  1811 Note that for uniformity on \<^typ>\<open>nat\<close> it is better to use
  1813 @{term"\<Sum>x::nat=0..<n. e"} rather than \<open>\<Sum>x<n. e\<close>: \<open>sum\<close> may
  1812 \<^term>\<open>\<Sum>x::nat=0..<n. e\<close> rather than \<open>\<Sum>x<n. e\<close>: \<open>sum\<close> may
  1814 not provide all lemmas available for @{term"{m..<n}"} also in the
  1813 not provide all lemmas available for \<^term>\<open>{m..<n}\<close> also in the
  1815 special form for @{term"{..<n}"}.\<close>
  1814 special form for \<^term>\<open>{..<n}\<close>.\<close>
  1816 
  1815 
  1817 text\<open>This congruence rule should be used for sums over intervals as
  1816 text\<open>This congruence rule should be used for sums over intervals as
  1818 the standard theorem @{text[source]sum.cong} does not work well
  1817 the standard theorem @{text[source]sum.cong} does not work well
  1819 with the simplifier who adds the unsimplified premise @{term"x\<in>B"} to
  1818 with the simplifier who adds the unsimplified premise \<^term>\<open>x\<in>B\<close> to
  1820 the context.\<close>
  1819 the context.\<close>
  1821 
  1820 
  1822 lemmas sum_ivl_cong = sum.ivl_cong
  1821 lemmas sum_ivl_cong = sum.ivl_cong
  1823 
  1822 
  1824 (* FIXME why are the following simp rules but the corresponding eqns
  1823 (* FIXME why are the following simp rules but the corresponding eqns