diff -r 518a1464f1ac -r 791c44b1d130 src/HOL/List.thy --- a/src/HOL/List.thy Sun Nov 02 20:01:43 2025 +0100 +++ b/src/HOL/List.thy Sun Nov 02 20:36:24 2025 +0100 @@ -8226,129 +8226,214 @@ by (simp_all add: add: lexordp_def) -text \Executable ranges\ - -class discrete_linordered_semidom_with_range = discrete_linordered_semidom + - assumes finite_atLeastLessThan: \finite {a.. +text \Executable intervals\ + +context preorder +begin + +lemma forall_less_eq_iff [code_unfold]: + \(\n\b. P n) \ (\n\{..b}. P n)\ + by auto + +lemma exists_less_eq_iff [code_unfold]: + \(\n\b. P n) \ (\n\{..b}. P n)\ + by auto + +lemma forall_less_iff [code_unfold]: + \(\n (\n\{.. + by auto + +lemma exists_less_iff [code_unfold]: + \(\n (\n\{.. + by auto + +lemma forall_greater_eq_iff [code_unfold]: + \(\n\a. P n) \ (\n\{a..}. P n)\ + by auto + +lemma exists_greater_eq_iff [code_unfold]: + \(\n\a. P n) \ (\n\{a..}. P n)\ + by auto + +lemma forall_greater_iff [code_unfold]: + \(\n>a. P n) \ (\n\{a<..}. P n)\ + by auto + +lemma exists_greater_iff [code_unfold]: + \(\n>a. P n) \ (\n\{a<..}. P n)\ + by auto + +end + +class interval = linorder + comm_semiring_1_cancel + + assumes finite_atLeastAtMost: \finite {a..b}\ + assumes dec_less_imp_less_eq: \a - 1 < b \ a \ b\ + assumes less_inc_imp_less_eq: \a < b + 1 \ a \ b\ + assumes dec_greater_eq_self_imp_bot: \a \ a - 1 \ a \ c\ + assumes inc_less_eq_self_imp_top: \b + 1 \ b \ d \ b\ begin context begin -qualified definition range :: \'a \ 'a \ 'a list\ \ \only for code generation\ - where range_eq: \range a b = sorted_list_of_set {a.. - -qualified lemma set_range_eq [simp]: - \set (range a b) = {a.. - using finite_atLeastLessThan by (simp add: range_eq) - -qualified lemma distinct_range [simp]: - \distinct (range a b)\ - by (simp add: range_eq) - -qualified lemma range_code [code]: - \range a b = (if a < b then a # range (a + 1) b else [])\ -proof (cases \a < b\) - case True - then have \{a.. - by (auto simp flip: less_iff_succ_less_eq less_eq_iff_succ_less) - then show ?thesis - by (auto simp add: range_eq finite_atLeastLessThan intro!: insort_is_Cons) -next - case False - then show ?thesis - by (simp add: range_eq) -qed - -qualified lemma atLeastLessThan_eq_range [code]: - \{a.. +qualified lemma less_imp_less_eq_dec: + \c < b \ a < b \ a \ b - 1\ + using local.dec_less_imp_less_eq local.not_less by blast + +qualified lemma less_imp_in_less_eq: + \a < c \ a < b \ a + 1 \ b\ + using local.less_inc_imp_less_eq local.not_less by blast + +qualified lemma less_eq_dec_imp_less: + \c < b \ a \ b - 1 \ a < b\ + using local.dec_greater_eq_self_imp_bot local.dual_order.trans local.not_le by blast + +qualified lemma inc_less_eq_imp_less: + \a < c \ a + 1 \ b \ a < b\ + using local.inc_less_eq_self_imp_top local.not_le local.order.strict_trans2 by blast + +qualified definition interval :: \'a \ 'a \ 'a list\ \ \only for code generation\ + where interval_eq: \interval a b = sorted_list_of_set {a..b}\ + +qualified lemma set_interval_eq [simp]: + \set (interval a b) = {a..b}\ + using finite_atLeastAtMost [of a b] by (simp add: interval_eq) + +qualified lemma distinct_interval [simp]: + \distinct (interval a b)\ + by (simp add: interval_eq) + +qualified lemma interval_code [code]: + \interval a b = (if a < b then a # interval (a + 1) b else if a = b then [a] else [])\ +proof - + consider (less) \a < b\ | (eq) \a = b\ | (greater) \a > b\ + using less_linear by blast + then show ?thesis proof cases + case less + then have \{a..b} = insert a {a + 1..b}\ + by (auto simp add: not_le dest: less_imp_le local.inc_less_eq_imp_less dest!: less_inc_imp_less_eq) + moreover have \{a + 1..b} - {a} = {a + 1..b}\ + using less by (auto dest: local.inc_less_eq_imp_less) + moreover have \insort a (sorted_list_of_set {a + 1..b}) = a # sorted_list_of_set {a + 1..b}\ + using finite_atLeastAtMost [of \a + 1\ b] less + by (auto intro!: insort_is_Cons dest: local.inc_less_eq_imp_less less_imp_le) + ultimately show ?thesis + using less finite_atLeastAtMost [of \a + 1\ b] + by (simp add: interval_eq) + next + case eq + then show ?thesis + by (simp add: interval_eq) + next + case greater + then show ?thesis + by (auto simp add: interval_eq) + qed +qed + +qualified lemma atLeastAtMost_eq_interval [code]: + \{a..b} = set (interval a b)\ by simp -qualified lemma atLeastAtMost_eq_range [code]: - \{a..b} = set (range a (b + 1))\ - by (auto simp flip: less_eq_iff_succ_less) - -qualified lemma greaterThanLessThan_eq_range [code]: - \{a<.. - by (auto simp add: less_eq_iff_succ_less) - -qualified lemma greaterThanAtMost_eq_range [code]: - \{a<..b} = set (range (a + 1) (b + 1))\ - by (auto simp add: less_eq_iff_succ_less) - -qualified definition all_range :: \('a \ bool) \ 'a \ 'a \ bool\ \ \only for code generation\ - where all_range_iff [code_abbrev, simp]: \all_range P a b \ (\n\{a.. - -qualified lemma all_range_code [code]: - \all_range P a b \ (a < b \ P a \ all_range P (a + 1) b)\ - by (auto simp add: Ball_def simp flip: less_iff_succ_less_eq) - (auto simp add: le_less) - -lemma forall_atLeastAtMost_iff [code_unfold]: - \(\n\{a..b}. P n) \ all_range P a (b + 1)\ - by (simp add: atLeastAtMost_eq_range) - -lemma forall_greaterThanLessThan_iff [code_unfold]: - \(\n\{a<.. all_range P (a + 1) b\ - by (simp add: greaterThanLessThan_eq_range) - -lemma forall_greaterThanAtMost_iff [code_unfold]: - \(\n\{a<..b}. P n) \ all_range P (a + 1) (b + 1)\ - by (simp add: greaterThanAtMost_eq_range) - -lemma exists_atLeastLessThan [code_unfold]: - \(\n\{a.. \ all_range (Not \ P) a b\ +qualified lemma atLeastLessThan_eq_interval [code]: + \{a.. + by (auto simp add: Let_def not_less local.less_imp_less_eq_dec intro: dec_greater_eq_self_imp_bot) + +qualified lemma greaterThanAtMost_eq_interval [code]: + \{a<..b} = (let c = a + 1 in if a < c then set (interval c b) else {})\ + by (auto simp add: Let_def not_less dec_less_imp_less_eq intro: inc_less_eq_self_imp_top) + +qualified lemma greaterThanLessThan_eq_interval [code]: + \{a<.. d < b then set (interval c d) else {})\ + by (auto simp add: Let_def not_less dec_less_imp_less_eq + dest: local.less_imp_less_eq_dec local.inc_less_eq_imp_less local.less_eq_dec_imp_less) + +qualified definition all_interval :: \('a \ bool) \ 'a \ 'a \ bool\ \ \only for code generation\ + where all_interval_iff [code_post, simp]: \all_interval P a b \ (\n\{a..b}. P n)\ + +qualified lemma all_interval_code [code]: + \all_interval P a b \ ((a < b \ P a \ all_interval P (a + 1) b) \ (a = b \ P a))\ + by (simp only: all_interval_iff interval_code [of a b] flip: set_interval_eq) auto + +qualified lemma forall_atLeastAtMost_iff [code_unfold]: + \(\n\{a..b}. P n) \ all_interval P a b\ by simp -lemma exists_atLeastAtMost_iff [code_unfold]: - \(\n\{a..b}. P n) \ \ all_range (Not \ P) a (b + 1)\ - by (simp add: atLeastAtMost_eq_range) - -lemma exists_greaterThanLessThan_iff [code_unfold]: - \(\n\{a<.. \ all_range (Not \ P) (a + 1) b\ - by (simp add: greaterThanLessThan_eq_range) - -lemma exists_greaterThanAtMost_iff [code_unfold]: - \(\n\{a<..b}. P n) \ \ all_range (Not \ P) (a + 1) (b + 1)\ - by (simp add: greaterThanAtMost_eq_range) +qualified lemma exists_atLeastAtMost_iff [code_unfold]: + \(\n\{a..b}. P n) \ \ all_interval (Not \ P) a b\ + using forall_atLeastAtMost_iff [of a b \Not \ P\] by simp + +qualified lemma forall_atLeastLessThan_iff [code_unfold]: + \(\n\{a.. (let d = b - 1 in d < b \ all_interval P a d)\ + by (auto simp add: not_less Let_def intro: local.less_eq_dec_imp_less local.less_imp_less_eq_dec elim!: bspec) + +qualified lemma exists_atLeastLessThan_iff [code_unfold]: + \(\n\{a.. (let d = b - 1 in d < b \ \ all_interval (Not \ P) a d)\ + using forall_atLeastLessThan_iff [of a b \Not \ P\] by (auto simp add: Let_def) + +qualified lemma forall_greaterThanAtMost_iff [code_unfold]: + \(\n\{a<..b}. P n) \ (let c = a + 1 in a < c \ all_interval P c b)\ + by (auto simp add: Let_def not_less intro: local.less_imp_in_less_eq local.inc_less_eq_imp_less elim!: bspec) + +qualified lemma exists_greaterThanAtMost_iff [code_unfold]: + \(\n\{a<..b}. P n) \ (let c = a + 1 in a < c \ \ all_interval (Not \ P) c b)\ + using forall_greaterThanAtMost_iff [of a b \Not \ P\] by (auto simp add: Let_def) + +qualified lemma forall_greaterThanLessThan_iff [code_unfold]: + \(\n\{a<.. (let c = a + 1; d = b - 1 in a < c \ d < b \ all_interval P c d)\ + by (auto simp add: Let_def not_less local.less_imp_in_less_eq local.less_imp_less_eq_dec + intro: local.inc_less_eq_imp_less local.less_eq_dec_imp_less elim!: bspec) + +qualified lemma exists_greaterThanLessThan_iff [code_unfold]: + \(\n\{a<.. (let c = a + 1; d = b - 1 in a < c \ d < b \ \ all_interval (Not \ P) c d)\ + using forall_greaterThanLessThan_iff [of a b \Not \ P\] by (auto simp add: Let_def) end end -instance nat :: discrete_linordered_semidom_with_range - by standard auto - -instance int :: discrete_linordered_semidom_with_range - by standard auto - -lemma all_nat_less_eq [code_unfold]: - "(\m (\m \ {0..{a..} = {a..top}\ + by auto + +lemma greaterThan_eq_greaterThanAtMost_top [code, code_unfold]: + \{a<..} = {a<..top}\ by auto -lemma all_nat_less [code_unfold]: - "(\m\n. P m) \ (\m \ {0..n}. P m)" for n :: nat +end + +class interval_bot = interval + order_bot +begin + +lemma atMost_eq_atLeastAtMost_bot [code, code_unfold]: + \{..b} = {bot..b}\ by auto -lemma ex_nat_less_eq [code_unfold]: - "(\m (\m \ {0..{.. by auto -lemma ex_nat_less [code_unfold]: - "(\m\n. P m) \ (\m \ {0..n}. P m)" for n :: nat - by auto +end + +instance nat :: interval_bot + by standard simp_all + +instance int :: interval + by standard simp_all context begin -qualified lemma range_eq_upt [simp]: - \List.range m n = [m.. - by (simp add: List.range_eq) - -qualified lemma range_eq_upto [simp]: - \List.range i k = [i..k - 1]\ - using atLeastLessThanPlusOne_atLeastAtMost_int [of i \k - 1\] - by (simp add: List.range_eq) +qualified lemma interval_eq_upt [simp]: + \List.interval m n = [m.. + by (simp add: List.interval_eq flip: atLeastLessThanSuc_atLeastAtMost) + +qualified lemma interval_eq_upto [simp]: + \List.interval i k = [i..k]\ + by (simp add: List.interval_eq) end