| author | wenzelm | 
| Sun, 01 Nov 2020 14:30:09 +0100 | |
| changeset 72534 | e0c6522d5d43 | 
| parent 71038 | bd3d4702b4f2 | 
| child 72607 | feebdaa346e5 | 
| permissions | -rw-r--r-- | 
| 71035 | 1  | 
(* Title: Interval  | 
2  | 
Author: Christoph Traut, TU Muenchen  | 
|
3  | 
Fabian Immler, TU Muenchen  | 
|
4  | 
*)  | 
|
5  | 
section \<open>Interval Type\<close>  | 
|
6  | 
theory Interval  | 
|
7  | 
imports  | 
|
8  | 
Complex_Main  | 
|
9  | 
Lattice_Algebras  | 
|
10  | 
Set_Algebras  | 
|
11  | 
begin  | 
|
12  | 
||
13  | 
text \<open>A type of non-empty, closed intervals.\<close>  | 
|
14  | 
||
15  | 
typedef (overloaded) 'a interval =  | 
|
16  | 
  "{(a::'a::preorder, b). a \<le> b}"
 | 
|
17  | 
morphisms bounds_of_interval Interval  | 
|
18  | 
by auto  | 
|
19  | 
||
20  | 
setup_lifting type_definition_interval  | 
|
21  | 
||
22  | 
lift_definition lower::"('a::preorder) interval \<Rightarrow> 'a" is fst .
 | 
|
23  | 
||
24  | 
lift_definition upper::"('a::preorder) interval \<Rightarrow> 'a" is snd .
 | 
|
25  | 
||
26  | 
lemma interval_eq_iff: "a = b \<longleftrightarrow> lower a = lower b \<and> upper a = upper b"  | 
|
27  | 
by transfer auto  | 
|
28  | 
||
29  | 
lemma interval_eqI: "lower a = lower b \<Longrightarrow> upper a = upper b \<Longrightarrow> a = b"  | 
|
30  | 
by (auto simp: interval_eq_iff)  | 
|
31  | 
||
32  | 
lemma lower_le_upper[simp]: "lower i \<le> upper i"  | 
|
33  | 
by transfer auto  | 
|
34  | 
||
35  | 
lift_definition set_of :: "'a::preorder interval \<Rightarrow> 'a set" is "\<lambda>x. {fst x .. snd x}" .
 | 
|
36  | 
||
37  | 
lemma set_of_eq: "set_of x = {lower x .. upper x}"
 | 
|
38  | 
by transfer simp  | 
|
39  | 
||
40  | 
context notes [[typedef_overloaded]] begin  | 
|
41  | 
||
42  | 
lift_definition(code_dt) Interval'::"'a::preorder \<Rightarrow> 'a::preorder \<Rightarrow> 'a interval option"  | 
|
43  | 
is "\<lambda>a b. if a \<le> b then Some (a, b) else None"  | 
|
44  | 
by auto  | 
|
45  | 
||
| 71038 | 46  | 
lemma Interval'_split:  | 
47  | 
"P (Interval' a b) \<longleftrightarrow>  | 
|
48  | 
(\<forall>ivl. a \<le> b \<longrightarrow> lower ivl = a \<longrightarrow> upper ivl = b \<longrightarrow> P (Some ivl)) \<and> (\<not>a\<le>b \<longrightarrow> P None)"  | 
|
49  | 
by transfer auto  | 
|
50  | 
||
51  | 
lemma Interval'_split_asm:  | 
|
52  | 
"P (Interval' a b) \<longleftrightarrow>  | 
|
53  | 
\<not>((\<exists>ivl. a \<le> b \<and> lower ivl = a \<and> upper ivl = b \<and> \<not>P (Some ivl)) \<or> (\<not>a\<le>b \<and> \<not>P None))"  | 
|
54  | 
unfolding Interval'_split  | 
|
55  | 
by auto  | 
|
56  | 
||
57  | 
lemmas Interval'_splits = Interval'_split Interval'_split_asm  | 
|
58  | 
||
59  | 
lemma Interval'_eq_Some: "Interval' a b = Some i \<Longrightarrow> lower i = a \<and> upper i = b"  | 
|
60  | 
by (simp split: Interval'_splits)  | 
|
61  | 
||
| 71035 | 62  | 
end  | 
63  | 
||
64  | 
instantiation "interval" :: ("{preorder,equal}") equal
 | 
|
65  | 
begin  | 
|
66  | 
||
67  | 
definition "equal_class.equal a b \<equiv> (lower a = lower b) \<and> (upper a = upper b)"  | 
|
68  | 
||
69  | 
instance proof qed (simp add: equal_interval_def interval_eq_iff)  | 
|
70  | 
end  | 
|
71  | 
||
72  | 
instantiation interval :: ("preorder") ord begin
 | 
|
73  | 
||
74  | 
definition less_eq_interval :: "'a interval \<Rightarrow> 'a interval \<Rightarrow> bool"  | 
|
75  | 
where "less_eq_interval a b \<longleftrightarrow> lower b \<le> lower a \<and> upper a \<le> upper b"  | 
|
76  | 
||
77  | 
definition less_interval :: "'a interval \<Rightarrow> 'a interval \<Rightarrow> bool"  | 
|
78  | 
where "less_interval x y = (x \<le> y \<and> \<not> y \<le> x)"  | 
|
79  | 
||
80  | 
instance proof qed  | 
|
81  | 
end  | 
|
82  | 
||
83  | 
instantiation interval :: ("lattice") semilattice_sup
 | 
|
84  | 
begin  | 
|
85  | 
||
86  | 
lift_definition sup_interval :: "'a interval \<Rightarrow> 'a interval \<Rightarrow> 'a interval"  | 
|
87  | 
is "\<lambda>(a, b) (c, d). (inf a c, sup b d)"  | 
|
88  | 
by (auto simp: le_infI1 le_supI1)  | 
|
89  | 
||
90  | 
lemma lower_sup[simp]: "lower (sup A B) = inf (lower A) (lower B)"  | 
|
91  | 
by transfer auto  | 
|
92  | 
||
93  | 
lemma upper_sup[simp]: "upper (sup A B) = sup (upper A) (upper B)"  | 
|
94  | 
by transfer auto  | 
|
95  | 
||
96  | 
instance proof qed (auto simp: less_eq_interval_def less_interval_def interval_eq_iff)  | 
|
97  | 
end  | 
|
98  | 
||
99  | 
lemma set_of_interval_union: "set_of A \<union> set_of B \<subseteq> set_of (sup A B)" for A::"'a::lattice interval"  | 
|
100  | 
by (auto simp: set_of_eq)  | 
|
101  | 
||
102  | 
lemma interval_union_commute: "sup A B = sup B A" for A::"'a::lattice interval"  | 
|
103  | 
by (auto simp add: interval_eq_iff inf.commute sup.commute)  | 
|
104  | 
||
105  | 
lemma interval_union_mono1: "set_of a \<subseteq> set_of (sup a A)" for A :: "'a::lattice interval"  | 
|
106  | 
using set_of_interval_union by blast  | 
|
107  | 
||
108  | 
lemma interval_union_mono2: "set_of A \<subseteq> set_of (sup a A)" for A :: "'a::lattice interval"  | 
|
109  | 
using set_of_interval_union by blast  | 
|
110  | 
||
111  | 
lift_definition interval_of :: "'a::preorder \<Rightarrow> 'a interval" is "\<lambda>x. (x, x)"  | 
|
112  | 
by auto  | 
|
113  | 
||
114  | 
lemma lower_interval_of[simp]: "lower (interval_of a) = a"  | 
|
115  | 
by transfer auto  | 
|
116  | 
||
117  | 
lemma upper_interval_of[simp]: "upper (interval_of a) = a"  | 
|
118  | 
by transfer auto  | 
|
119  | 
||
120  | 
definition width :: "'a::{preorder,minus} interval \<Rightarrow> 'a"
 | 
|
121  | 
where "width i = upper i - lower i"  | 
|
122  | 
||
123  | 
||
124  | 
instantiation "interval" :: ("ordered_ab_semigroup_add") ab_semigroup_add
 | 
|
125  | 
begin  | 
|
126  | 
||
127  | 
lift_definition plus_interval::"'a interval \<Rightarrow> 'a interval \<Rightarrow> 'a interval"  | 
|
128  | 
is "\<lambda>(a, b). \<lambda>(c, d). (a + c, b + d)"  | 
|
129  | 
by (auto intro!: add_mono)  | 
|
130  | 
lemma lower_plus[simp]: "lower (plus A B) = plus (lower A) (lower B)"  | 
|
131  | 
by transfer auto  | 
|
132  | 
lemma upper_plus[simp]: "upper (plus A B) = plus (upper A) (upper B)"  | 
|
133  | 
by transfer auto  | 
|
134  | 
||
135  | 
instance proof qed (auto simp: interval_eq_iff less_eq_interval_def ac_simps)  | 
|
136  | 
end  | 
|
137  | 
||
138  | 
instance "interval" :: ("{ordered_ab_semigroup_add, lattice}") ordered_ab_semigroup_add
 | 
|
139  | 
proof qed (auto simp: less_eq_interval_def intro!: add_mono)  | 
|
140  | 
||
141  | 
instantiation "interval" :: ("{preorder,zero}") zero
 | 
|
142  | 
begin  | 
|
143  | 
||
144  | 
lift_definition zero_interval::"'a interval" is "(0, 0)" by auto  | 
|
145  | 
lemma lower_zero[simp]: "lower 0 = 0"  | 
|
146  | 
by transfer auto  | 
|
147  | 
lemma upper_zero[simp]: "upper 0 = 0"  | 
|
148  | 
by transfer auto  | 
|
149  | 
instance proof qed  | 
|
150  | 
end  | 
|
151  | 
||
152  | 
instance "interval" :: ("{ordered_comm_monoid_add}") comm_monoid_add
 | 
|
153  | 
proof qed (auto simp: interval_eq_iff)  | 
|
154  | 
||
155  | 
instance "interval" :: ("{ordered_comm_monoid_add,lattice}") ordered_comm_monoid_add ..
 | 
|
156  | 
||
157  | 
instantiation "interval" :: ("{ordered_ab_group_add}") uminus
 | 
|
158  | 
begin  | 
|
159  | 
||
160  | 
lift_definition uminus_interval::"'a interval \<Rightarrow> 'a interval" is "\<lambda>(a, b). (-b, -a)" by auto  | 
|
161  | 
lemma lower_uminus[simp]: "lower (- A) = - upper A"  | 
|
162  | 
by transfer auto  | 
|
163  | 
lemma upper_uminus[simp]: "upper (- A) = - lower A"  | 
|
164  | 
by transfer auto  | 
|
165  | 
instance ..  | 
|
166  | 
end  | 
|
167  | 
||
168  | 
instantiation "interval" :: ("{ordered_ab_group_add}") minus
 | 
|
169  | 
begin  | 
|
170  | 
||
171  | 
definition minus_interval::"'a interval \<Rightarrow> 'a interval \<Rightarrow> 'a interval"  | 
|
172  | 
where "minus_interval a b = a + - b"  | 
|
173  | 
lemma lower_minus[simp]: "lower (minus A B) = minus (lower A) (upper B)"  | 
|
174  | 
by (auto simp: minus_interval_def)  | 
|
175  | 
lemma upper_minus[simp]: "upper (minus A B) = minus (upper A) (lower B)"  | 
|
176  | 
by (auto simp: minus_interval_def)  | 
|
177  | 
||
178  | 
instance ..  | 
|
179  | 
end  | 
|
180  | 
||
181  | 
instantiation "interval" :: (linordered_semiring) times  | 
|
182  | 
begin  | 
|
183  | 
||
184  | 
lift_definition times_interval :: "'a interval \<Rightarrow> 'a interval \<Rightarrow> 'a interval"  | 
|
185  | 
is "\<lambda>(a1, a2). \<lambda>(b1, b2).  | 
|
186  | 
(let x1 = a1 * b1; x2 = a1 * b2; x3 = a2 * b1; x4 = a2 * b2  | 
|
187  | 
in (min x1 (min x2 (min x3 x4)), max x1 (max x2 (max x3 x4))))"  | 
|
188  | 
by (auto simp: Let_def intro!: min.coboundedI1 max.coboundedI1)  | 
|
189  | 
||
190  | 
lemma lower_times:  | 
|
191  | 
  "lower (times A B) = Min {lower A * lower B, lower A * upper B, upper A * lower B, upper A * upper B}"
 | 
|
192  | 
by transfer (auto simp: Let_def)  | 
|
193  | 
||
194  | 
lemma upper_times:  | 
|
195  | 
  "upper (times A B) = Max {lower A * lower B, lower A * upper B, upper A * lower B, upper A * upper B}"
 | 
|
196  | 
by transfer (auto simp: Let_def)  | 
|
197  | 
||
198  | 
instance ..  | 
|
199  | 
end  | 
|
200  | 
||
201  | 
lemma interval_eq_set_of_iff: "X = Y \<longleftrightarrow> set_of X = set_of Y" for X Y::"'a::order interval"  | 
|
202  | 
by (auto simp: set_of_eq interval_eq_iff)  | 
|
203  | 
||
204  | 
||
205  | 
subsection \<open>Membership\<close>  | 
|
206  | 
||
207  | 
abbreviation (in preorder) in_interval ("(_/ \<in>\<^sub>i _)" [51, 51] 50)
 | 
|
208  | 
where "in_interval x X \<equiv> x \<in> set_of X"  | 
|
209  | 
||
210  | 
lemma in_interval_to_interval[intro!]: "a \<in>\<^sub>i interval_of a"  | 
|
211  | 
by (auto simp: set_of_eq)  | 
|
212  | 
||
213  | 
lemma plus_in_intervalI:  | 
|
214  | 
fixes x y :: "'a :: ordered_ab_semigroup_add"  | 
|
215  | 
shows "x \<in>\<^sub>i X \<Longrightarrow> y \<in>\<^sub>i Y \<Longrightarrow> x + y \<in>\<^sub>i X + Y"  | 
|
216  | 
by (simp add: add_mono_thms_linordered_semiring(1) set_of_eq)  | 
|
217  | 
||
218  | 
lemma connected_set_of[intro, simp]:  | 
|
219  | 
"connected (set_of X)" for X::"'a::linear_continuum_topology interval"  | 
|
220  | 
by (auto simp: set_of_eq )  | 
|
221  | 
||
222  | 
lemma ex_sum_in_interval_lemma: "\<exists>xa\<in>{la .. ua}. \<exists>xb\<in>{lb .. ub}. x = xa + xb"
 | 
|
223  | 
if "la \<le> ua" "lb \<le> ub" "la + lb \<le> x" "x \<le> ua + ub"  | 
|
224  | 
"ua - la \<le> ub - lb"  | 
|
225  | 
for la b c d::"'a::linordered_ab_group_add"  | 
|
226  | 
proof -  | 
|
227  | 
define wa where "wa = ua - la"  | 
|
228  | 
define wb where "wb = ub - lb"  | 
|
229  | 
define w where "w = wa + wb"  | 
|
230  | 
define d where "d = x - la - lb"  | 
|
231  | 
define da where "da = max 0 (min wa (d - wa))"  | 
|
232  | 
define db where "db = d - da"  | 
|
233  | 
from that have nonneg: "0 \<le> wa" "0 \<le> wb" "0 \<le> w" "0 \<le> d" "d \<le> w"  | 
|
234  | 
by (auto simp add: wa_def wb_def w_def d_def add.commute le_diff_eq)  | 
|
235  | 
have "0 \<le> db"  | 
|
236  | 
by (auto simp: da_def nonneg db_def intro!: min.coboundedI2)  | 
|
237  | 
have "x = (la + da) + (lb + db)"  | 
|
238  | 
by (simp add: da_def db_def d_def)  | 
|
239  | 
moreover  | 
|
240  | 
have "x - la - ub \<le> da"  | 
|
241  | 
using that  | 
|
242  | 
unfolding da_def  | 
|
243  | 
by (intro max.coboundedI2) (auto simp: wa_def d_def diff_le_eq diff_add_eq)  | 
|
244  | 
then have "db \<le> wb"  | 
|
245  | 
by (auto simp: db_def d_def wb_def algebra_simps)  | 
|
246  | 
  with \<open>0 \<le> db\<close> that nonneg have "lb + db \<in> {lb..ub}"
 | 
|
247  | 
by (auto simp: wb_def algebra_simps)  | 
|
248  | 
moreover  | 
|
249  | 
have "da \<le> wa"  | 
|
250  | 
by (auto simp: da_def nonneg)  | 
|
251  | 
  then have "la + da \<in> {la..ua}"
 | 
|
252  | 
by (auto simp: da_def wa_def algebra_simps)  | 
|
253  | 
ultimately show ?thesis  | 
|
254  | 
by force  | 
|
255  | 
qed  | 
|
256  | 
||
257  | 
||
258  | 
lemma ex_sum_in_interval: "\<exists>xa\<ge>la. xa \<le> ua \<and> (\<exists>xb\<ge>lb. xb \<le> ub \<and> x = xa + xb)"  | 
|
259  | 
if a: "la \<le> ua" and b: "lb \<le> ub" and x: "la + lb \<le> x" "x \<le> ua + ub"  | 
|
260  | 
for la b c d::"'a::linordered_ab_group_add"  | 
|
261  | 
proof -  | 
|
262  | 
from linear consider "ua - la \<le> ub - lb" | "ub - lb \<le> ua - la"  | 
|
263  | 
by blast  | 
|
264  | 
then show ?thesis  | 
|
265  | 
proof cases  | 
|
266  | 
case 1  | 
|
267  | 
from ex_sum_in_interval_lemma[OF that 1]  | 
|
268  | 
show ?thesis by auto  | 
|
269  | 
next  | 
|
270  | 
case 2  | 
|
271  | 
from x have "lb + la \<le> x" "x \<le> ub + ua" by (simp_all add: ac_simps)  | 
|
272  | 
from ex_sum_in_interval_lemma[OF b a this 2]  | 
|
273  | 
show ?thesis by auto  | 
|
274  | 
qed  | 
|
275  | 
qed  | 
|
276  | 
||
277  | 
lemma Icc_plus_Icc:  | 
|
278  | 
  "{a .. b} + {c .. d} = {a + c .. b + d}"
 | 
|
279  | 
if "a \<le> b" "c \<le> d"  | 
|
280  | 
for a b c d::"'a::linordered_ab_group_add"  | 
|
281  | 
using ex_sum_in_interval[OF that]  | 
|
282  | 
by (auto intro: add_mono simp: atLeastAtMost_iff Bex_def set_plus_def)  | 
|
283  | 
||
284  | 
lemma set_of_plus:  | 
|
285  | 
fixes A :: "'a::linordered_ab_group_add interval"  | 
|
286  | 
shows "set_of (A + B) = set_of A + set_of B"  | 
|
287  | 
using Icc_plus_Icc[of "lower A" "upper A" "lower B" "upper B"]  | 
|
288  | 
by (auto simp: set_of_eq)  | 
|
289  | 
||
290  | 
lemma plus_in_intervalE:  | 
|
291  | 
fixes xy :: "'a :: linordered_ab_group_add"  | 
|
292  | 
assumes "xy \<in>\<^sub>i X + Y"  | 
|
293  | 
obtains x y where "xy = x + y" "x \<in>\<^sub>i X" "y \<in>\<^sub>i Y"  | 
|
294  | 
using assms  | 
|
295  | 
unfolding set_of_plus set_plus_def  | 
|
296  | 
by auto  | 
|
297  | 
||
298  | 
lemma set_of_uminus: "set_of (-X) = {- x | x. x \<in> set_of X}"
 | 
|
299  | 
for X :: "'a :: ordered_ab_group_add interval"  | 
|
300  | 
by (auto simp: set_of_eq simp: le_minus_iff minus_le_iff  | 
|
301  | 
intro!: exI[where x="-x" for x])  | 
|
302  | 
||
303  | 
lemma uminus_in_intervalI:  | 
|
304  | 
fixes x :: "'a :: ordered_ab_group_add"  | 
|
305  | 
shows "x \<in>\<^sub>i X \<Longrightarrow> -x \<in>\<^sub>i -X"  | 
|
306  | 
by (auto simp: set_of_uminus)  | 
|
307  | 
||
308  | 
lemma uminus_in_intervalD:  | 
|
309  | 
fixes x :: "'a :: ordered_ab_group_add"  | 
|
310  | 
shows "x \<in>\<^sub>i - X \<Longrightarrow> - x \<in>\<^sub>i X"  | 
|
311  | 
by (auto simp: set_of_uminus)  | 
|
312  | 
||
313  | 
lemma minus_in_intervalI:  | 
|
314  | 
fixes x y :: "'a :: ordered_ab_group_add"  | 
|
315  | 
shows "x \<in>\<^sub>i X \<Longrightarrow> y \<in>\<^sub>i Y \<Longrightarrow> x - y \<in>\<^sub>i X - Y"  | 
|
316  | 
by (metis diff_conv_add_uminus minus_interval_def plus_in_intervalI uminus_in_intervalI)  | 
|
317  | 
||
318  | 
lemma set_of_minus: "set_of (X - Y) = {x - y | x y . x \<in> set_of X \<and> y \<in> set_of Y}"
 | 
|
319  | 
for X Y :: "'a :: linordered_ab_group_add interval"  | 
|
320  | 
unfolding minus_interval_def set_of_plus set_of_uminus set_plus_def  | 
|
321  | 
by force  | 
|
322  | 
||
323  | 
lemma times_in_intervalI:  | 
|
324  | 
fixes x y::"'a::linordered_ring"  | 
|
325  | 
assumes "x \<in>\<^sub>i X" "y \<in>\<^sub>i Y"  | 
|
326  | 
shows "x * y \<in>\<^sub>i X * Y"  | 
|
327  | 
proof -  | 
|
328  | 
define X1 where "X1 \<equiv> lower X"  | 
|
329  | 
define X2 where "X2 \<equiv> upper X"  | 
|
330  | 
define Y1 where "Y1 \<equiv> lower Y"  | 
|
331  | 
define Y2 where "Y2 \<equiv> upper Y"  | 
|
332  | 
from assms have assms: "X1 \<le> x" "x \<le> X2" "Y1 \<le> y" "y \<le> Y2"  | 
|
333  | 
by (auto simp: X1_def X2_def Y1_def Y2_def set_of_eq)  | 
|
334  | 
have "(X1 * Y1 \<le> x * y \<or> X1 * Y2 \<le> x * y \<or> X2 * Y1 \<le> x * y \<or> X2 * Y2 \<le> x * y) \<and>  | 
|
335  | 
(X1 * Y1 \<ge> x * y \<or> X1 * Y2 \<ge> x * y \<or> X2 * Y1 \<ge> x * y \<or> X2 * Y2 \<ge> x * y)"  | 
|
336  | 
proof (cases x "0::'a" rule: linorder_cases)  | 
|
337  | 
case x0: less  | 
|
338  | 
show ?thesis  | 
|
339  | 
proof (cases "y < 0")  | 
|
340  | 
case y0: True  | 
|
341  | 
from y0 x0 assms have "x * y \<le> X1 * y" by (intro mult_right_mono_neg, auto)  | 
|
342  | 
also from x0 y0 assms have "X1 * y \<le> X1 * Y1" by (intro mult_left_mono_neg, auto)  | 
|
343  | 
finally have 1: "x * y \<le> X1 * Y1".  | 
|
344  | 
show ?thesis proof(cases "X2 \<le> 0")  | 
|
345  | 
case True  | 
|
346  | 
with assms have "X2 * Y2 \<le> X2 * y" by (auto intro: mult_left_mono_neg)  | 
|
347  | 
also from assms y0 have "... \<le> x * y" by (auto intro: mult_right_mono_neg)  | 
|
348  | 
finally have "X2 * Y2 \<le> x * y".  | 
|
349  | 
with 1 show ?thesis by auto  | 
|
350  | 
next  | 
|
351  | 
case False  | 
|
352  | 
with assms have "X2 * Y1 \<le> X2 * y" by (auto intro: mult_left_mono)  | 
|
353  | 
also from assms y0 have "... \<le> x * y" by (auto intro: mult_right_mono_neg)  | 
|
354  | 
finally have "X2 * Y1 \<le> x * y".  | 
|
355  | 
with 1 show ?thesis by auto  | 
|
356  | 
qed  | 
|
357  | 
next  | 
|
358  | 
case False  | 
|
359  | 
then have y0: "y \<ge> 0" by auto  | 
|
360  | 
from x0 y0 assms have "X1 * Y2 \<le> x * Y2" by (intro mult_right_mono, auto)  | 
|
361  | 
also from y0 x0 assms have "... \<le> x * y" by (intro mult_left_mono_neg, auto)  | 
|
362  | 
finally have 1: "X1 * Y2 \<le> x * y".  | 
|
363  | 
show ?thesis  | 
|
364  | 
proof(cases "X2 \<le> 0")  | 
|
365  | 
case X2: True  | 
|
366  | 
from assms y0 have "x * y \<le> X2 * y" by (intro mult_right_mono)  | 
|
367  | 
also from assms X2 have "... \<le> X2 * Y1" by (auto intro: mult_left_mono_neg)  | 
|
368  | 
finally have "x * y \<le> X2 * Y1".  | 
|
369  | 
with 1 show ?thesis by auto  | 
|
370  | 
next  | 
|
371  | 
case X2: False  | 
|
372  | 
from assms y0 have "x * y \<le> X2 * y" by (intro mult_right_mono)  | 
|
373  | 
also from assms X2 have "... \<le> X2 * Y2" by (auto intro: mult_left_mono)  | 
|
374  | 
finally have "x * y \<le> X2 * Y2".  | 
|
375  | 
with 1 show ?thesis by auto  | 
|
376  | 
qed  | 
|
377  | 
qed  | 
|
378  | 
next  | 
|
379  | 
case [simp]: equal  | 
|
380  | 
with assms show ?thesis by (cases "Y2 \<le> 0", auto intro:mult_sign_intros)  | 
|
381  | 
next  | 
|
382  | 
case x0: greater  | 
|
383  | 
show ?thesis  | 
|
384  | 
proof (cases "y < 0")  | 
|
385  | 
case y0: True  | 
|
386  | 
from x0 y0 assms have "X2 * Y1 \<le> X2 * y" by (intro mult_left_mono, auto)  | 
|
387  | 
also from y0 x0 assms have "X2 * y \<le> x * y" by (intro mult_right_mono_neg, auto)  | 
|
388  | 
finally have 1: "X2 * Y1 \<le> x * y".  | 
|
389  | 
show ?thesis  | 
|
390  | 
proof(cases "Y2 \<le> 0")  | 
|
391  | 
case Y2: True  | 
|
392  | 
from x0 assms have "x * y \<le> x * Y2" by (auto intro: mult_left_mono)  | 
|
393  | 
also from assms Y2 have "... \<le> X1 * Y2" by (auto intro: mult_right_mono_neg)  | 
|
394  | 
finally have "x * y \<le> X1 * Y2".  | 
|
395  | 
with 1 show ?thesis by auto  | 
|
396  | 
next  | 
|
397  | 
case Y2: False  | 
|
398  | 
from x0 assms have "x * y \<le> x * Y2" by (auto intro: mult_left_mono)  | 
|
399  | 
also from assms Y2 have "... \<le> X2 * Y2" by (auto intro: mult_right_mono)  | 
|
400  | 
finally have "x * y \<le> X2 * Y2".  | 
|
401  | 
with 1 show ?thesis by auto  | 
|
402  | 
qed  | 
|
403  | 
next  | 
|
404  | 
case y0: False  | 
|
405  | 
from x0 y0 assms have "x * y \<le> X2 * y" by (intro mult_right_mono, auto)  | 
|
406  | 
also from y0 x0 assms have "... \<le> X2 * Y2" by (intro mult_left_mono, auto)  | 
|
407  | 
finally have 1: "x * y \<le> X2 * Y2".  | 
|
408  | 
show ?thesis  | 
|
409  | 
proof(cases "X1 \<le> 0")  | 
|
410  | 
case True  | 
|
411  | 
with assms have "X1 * Y2 \<le> X1 * y" by (auto intro: mult_left_mono_neg)  | 
|
412  | 
also from assms y0 have "... \<le> x * y" by (auto intro: mult_right_mono)  | 
|
413  | 
finally have "X1 * Y2 \<le> x * y".  | 
|
414  | 
with 1 show ?thesis by auto  | 
|
415  | 
next  | 
|
416  | 
case False  | 
|
417  | 
with assms have "X1 * Y1 \<le> X1 * y" by (auto intro: mult_left_mono)  | 
|
418  | 
also from assms y0 have "... \<le> x * y" by (auto intro: mult_right_mono)  | 
|
419  | 
finally have "X1 * Y1 \<le> x * y".  | 
|
420  | 
with 1 show ?thesis by auto  | 
|
421  | 
qed  | 
|
422  | 
qed  | 
|
423  | 
qed  | 
|
424  | 
hence min:"min (X1 * Y1) (min (X1 * Y2) (min (X2 * Y1) (X2 * Y2))) \<le> x * y"  | 
|
425  | 
and max:"x * y \<le> max (X1 * Y1) (max (X1 * Y2) (max (X2 * Y1) (X2 * Y2)))"  | 
|
426  | 
by (auto simp:min_le_iff_disj le_max_iff_disj)  | 
|
427  | 
show ?thesis using min max  | 
|
428  | 
by (auto simp: Let_def X1_def X2_def Y1_def Y2_def set_of_eq lower_times upper_times)  | 
|
429  | 
qed  | 
|
430  | 
||
431  | 
lemma times_in_intervalE:  | 
|
432  | 
  fixes xy :: "'a :: {linordered_semiring, real_normed_algebra, linear_continuum_topology}"
 | 
|
433  | 
\<comment> \<open>TODO: linear continuum topology is pretty strong\<close>  | 
|
434  | 
assumes "xy \<in>\<^sub>i X * Y"  | 
|
435  | 
obtains x y where "xy = x * y" "x \<in>\<^sub>i X" "y \<in>\<^sub>i Y"  | 
|
436  | 
proof -  | 
|
437  | 
let ?mult = "\<lambda>(x, y). x * y"  | 
|
438  | 
let ?XY = "set_of X \<times> set_of Y"  | 
|
439  | 
have cont: "continuous_on ?XY ?mult"  | 
|
440  | 
by (auto intro!: tendsto_eq_intros simp: continuous_on_def split_beta')  | 
|
441  | 
have conn: "connected (?mult ` ?XY)"  | 
|
442  | 
by (rule connected_continuous_image[OF cont]) auto  | 
|
443  | 
have "lower (X * Y) \<in> ?mult ` ?XY" "upper (X * Y) \<in> ?mult ` ?XY"  | 
|
444  | 
by (auto simp: set_of_eq lower_times upper_times min_def max_def split: if_splits)  | 
|
445  | 
from connectedD_interval[OF conn this, of xy] assms  | 
|
446  | 
obtain x y where "xy = x * y" "x \<in>\<^sub>i X" "y \<in>\<^sub>i Y" by (auto simp: set_of_eq)  | 
|
447  | 
then show ?thesis ..  | 
|
448  | 
qed  | 
|
449  | 
||
450  | 
lemma set_of_times: "set_of (X * Y) = {x * y | x y. x \<in> set_of X \<and> y \<in> set_of Y}"
 | 
|
451  | 
  for X Y::"'a :: {linordered_ring, real_normed_algebra, linear_continuum_topology} interval"
 | 
|
452  | 
by (auto intro!: times_in_intervalI elim!: times_in_intervalE)  | 
|
453  | 
||
454  | 
instance "interval" :: (linordered_idom) cancel_semigroup_add  | 
|
455  | 
proof qed (auto simp: interval_eq_iff)  | 
|
456  | 
||
457  | 
lemma interval_mul_commute: "A * B = B * A" for A B:: "'a::linordered_idom interval"  | 
|
458  | 
by (simp add: interval_eq_iff lower_times upper_times ac_simps)  | 
|
459  | 
||
460  | 
lemma interval_times_zero_right[simp]: "A * 0 = 0" for A :: "'a::linordered_ring interval"  | 
|
461  | 
by (simp add: interval_eq_iff lower_times upper_times ac_simps)  | 
|
462  | 
||
463  | 
lemma interval_times_zero_left[simp]:  | 
|
464  | 
"0 * A = 0" for A :: "'a::linordered_ring interval"  | 
|
465  | 
by (simp add: interval_eq_iff lower_times upper_times ac_simps)  | 
|
466  | 
||
467  | 
instantiation "interval" :: ("{preorder,one}") one
 | 
|
468  | 
begin  | 
|
469  | 
||
470  | 
lift_definition one_interval::"'a interval" is "(1, 1)" by auto  | 
|
471  | 
lemma lower_one[simp]: "lower 1 = 1"  | 
|
472  | 
by transfer auto  | 
|
473  | 
lemma upper_one[simp]: "upper 1 = 1"  | 
|
474  | 
by transfer auto  | 
|
475  | 
instance proof qed  | 
|
476  | 
end  | 
|
477  | 
||
478  | 
instance interval :: ("{one, preorder, linordered_semiring}") power
 | 
|
479  | 
proof qed  | 
|
480  | 
||
481  | 
lemma set_of_one[simp]: "set_of (1::'a::{one, order} interval) = {1}"
 | 
|
482  | 
by (auto simp: set_of_eq)  | 
|
483  | 
||
484  | 
instance "interval" ::  | 
|
485  | 
  ("{linordered_idom,linordered_ring, real_normed_algebra, linear_continuum_topology}") monoid_mult
 | 
|
486  | 
apply standard  | 
|
487  | 
unfolding interval_eq_set_of_iff set_of_times  | 
|
488  | 
subgoal  | 
|
489  | 
by (auto simp: interval_eq_set_of_iff set_of_times; metis mult.assoc)  | 
|
490  | 
by auto  | 
|
491  | 
||
492  | 
lemma one_times_ivl_left[simp]: "1 * A = A" for A :: "'a::linordered_idom interval"  | 
|
493  | 
by (simp add: interval_eq_iff lower_times upper_times ac_simps min_def max_def)  | 
|
494  | 
||
495  | 
lemma one_times_ivl_right[simp]: "A * 1 = A" for A :: "'a::linordered_idom interval"  | 
|
496  | 
by (metis interval_mul_commute one_times_ivl_left)  | 
|
497  | 
||
498  | 
lemma set_of_power_mono: "a^n \<in> set_of (A^n)" if "a \<in> set_of A"  | 
|
499  | 
for a :: "'a::linordered_idom"  | 
|
500  | 
using that  | 
|
501  | 
by (induction n) (auto intro!: times_in_intervalI)  | 
|
502  | 
||
503  | 
lemma set_of_add_cong:  | 
|
504  | 
"set_of (A + B) = set_of (A' + B')"  | 
|
505  | 
if "set_of A = set_of A'" "set_of B = set_of B'"  | 
|
506  | 
for A :: "'a::linordered_ab_group_add interval"  | 
|
507  | 
unfolding set_of_plus that ..  | 
|
508  | 
||
509  | 
lemma set_of_add_inc_left:  | 
|
510  | 
"set_of (A + B) \<subseteq> set_of (A' + B)"  | 
|
511  | 
if "set_of A \<subseteq> set_of A'"  | 
|
512  | 
for A :: "'a::linordered_ab_group_add interval"  | 
|
513  | 
unfolding set_of_plus using that by (auto simp: set_plus_def)  | 
|
514  | 
||
515  | 
lemma set_of_add_inc_right:  | 
|
516  | 
"set_of (A + B) \<subseteq> set_of (A + B')"  | 
|
517  | 
if "set_of B \<subseteq> set_of B'"  | 
|
518  | 
for A :: "'a::linordered_ab_group_add interval"  | 
|
519  | 
using set_of_add_inc_left[OF that]  | 
|
520  | 
by (simp add: add.commute)  | 
|
521  | 
||
522  | 
lemma set_of_add_inc:  | 
|
523  | 
"set_of (A + B) \<subseteq> set_of (A' + B')"  | 
|
524  | 
if "set_of A \<subseteq> set_of A'" "set_of B \<subseteq> set_of B'"  | 
|
525  | 
for A :: "'a::linordered_ab_group_add interval"  | 
|
526  | 
using set_of_add_inc_left[OF that(1)] set_of_add_inc_right[OF that(2)]  | 
|
527  | 
by auto  | 
|
528  | 
||
529  | 
lemma set_of_neg_inc:  | 
|
530  | 
"set_of (-A) \<subseteq> set_of (-A')"  | 
|
531  | 
if "set_of A \<subseteq> set_of A'"  | 
|
532  | 
for A :: "'a::ordered_ab_group_add interval"  | 
|
533  | 
using that  | 
|
534  | 
unfolding set_of_uminus  | 
|
535  | 
by auto  | 
|
536  | 
||
537  | 
lemma set_of_sub_inc_left:  | 
|
538  | 
"set_of (A - B) \<subseteq> set_of (A' - B)"  | 
|
539  | 
if "set_of A \<subseteq> set_of A'"  | 
|
540  | 
for A :: "'a::linordered_ab_group_add interval"  | 
|
541  | 
using that  | 
|
542  | 
unfolding set_of_minus  | 
|
543  | 
by auto  | 
|
544  | 
||
545  | 
lemma set_of_sub_inc_right:  | 
|
546  | 
"set_of (A - B) \<subseteq> set_of (A - B')"  | 
|
547  | 
if "set_of B \<subseteq> set_of B'"  | 
|
548  | 
for A :: "'a::linordered_ab_group_add interval"  | 
|
549  | 
using that  | 
|
550  | 
unfolding set_of_minus  | 
|
551  | 
by auto  | 
|
552  | 
||
553  | 
lemma set_of_sub_inc:  | 
|
554  | 
"set_of (A - B) \<subseteq> set_of (A' - B')"  | 
|
555  | 
if "set_of A \<subseteq> set_of A'" "set_of B \<subseteq> set_of B'"  | 
|
556  | 
for A :: "'a::linordered_idom interval"  | 
|
557  | 
using set_of_sub_inc_left[OF that(1)] set_of_sub_inc_right[OF that(2)]  | 
|
558  | 
by auto  | 
|
559  | 
||
560  | 
lemma set_of_mul_inc_right:  | 
|
561  | 
"set_of (A * B) \<subseteq> set_of (A * B')"  | 
|
562  | 
if "set_of B \<subseteq> set_of B'"  | 
|
563  | 
for A :: "'a::linordered_ring interval"  | 
|
564  | 
using that  | 
|
565  | 
apply transfer  | 
|
566  | 
apply (clarsimp simp add: Let_def)  | 
|
567  | 
apply (intro conjI)  | 
|
568  | 
apply (metis linear min.coboundedI1 min.coboundedI2 mult_left_mono mult_left_mono_neg order_trans)  | 
|
569  | 
apply (metis linear min.coboundedI1 min.coboundedI2 mult_left_mono mult_left_mono_neg order_trans)  | 
|
570  | 
apply (metis linear min.coboundedI1 min.coboundedI2 mult_left_mono mult_left_mono_neg order_trans)  | 
|
571  | 
apply (metis linear min.coboundedI1 min.coboundedI2 mult_left_mono mult_left_mono_neg order_trans)  | 
|
572  | 
apply (metis linear max.coboundedI1 max.coboundedI2 mult_left_mono mult_left_mono_neg order_trans)  | 
|
573  | 
apply (metis linear max.coboundedI1 max.coboundedI2 mult_left_mono mult_left_mono_neg order_trans)  | 
|
574  | 
apply (metis linear max.coboundedI1 max.coboundedI2 mult_left_mono mult_left_mono_neg order_trans)  | 
|
575  | 
apply (metis linear max.coboundedI1 max.coboundedI2 mult_left_mono mult_left_mono_neg order_trans)  | 
|
576  | 
done  | 
|
577  | 
||
578  | 
lemma set_of_distrib_left:  | 
|
579  | 
"set_of (B * (A1 + A2)) \<subseteq> set_of (B * A1 + B * A2)"  | 
|
580  | 
for A1 :: "'a::linordered_ring interval"  | 
|
581  | 
apply transfer  | 
|
582  | 
apply (clarsimp simp: Let_def distrib_left distrib_right)  | 
|
583  | 
apply (intro conjI)  | 
|
584  | 
apply (metis add_mono min.cobounded1 min.left_commute)  | 
|
585  | 
apply (metis add_mono min.cobounded1 min.left_commute)  | 
|
586  | 
apply (metis add_mono min.cobounded1 min.left_commute)  | 
|
587  | 
apply (metis add_mono min.assoc min.cobounded2)  | 
|
588  | 
apply (meson add_mono order.trans max.cobounded1 max.cobounded2)  | 
|
589  | 
apply (meson add_mono order.trans max.cobounded1 max.cobounded2)  | 
|
590  | 
apply (meson add_mono order.trans max.cobounded1 max.cobounded2)  | 
|
591  | 
apply (meson add_mono order.trans max.cobounded1 max.cobounded2)  | 
|
592  | 
done  | 
|
593  | 
||
594  | 
lemma set_of_distrib_right:  | 
|
595  | 
"set_of ((A1 + A2) * B) \<subseteq> set_of (A1 * B + A2 * B)"  | 
|
596  | 
  for A1 A2 B :: "'a::{linordered_ring, real_normed_algebra, linear_continuum_topology} interval"
 | 
|
597  | 
unfolding set_of_times set_of_plus set_plus_def  | 
|
598  | 
apply clarsimp  | 
|
599  | 
subgoal for b a1 a2  | 
|
600  | 
apply (rule exI[where x="a1 * b"])  | 
|
601  | 
apply (rule conjI)  | 
|
602  | 
subgoal by force  | 
|
603  | 
subgoal  | 
|
604  | 
apply (rule exI[where x="a2 * b"])  | 
|
605  | 
apply (rule conjI)  | 
|
606  | 
subgoal by force  | 
|
607  | 
subgoal by (simp add: algebra_simps)  | 
|
608  | 
done  | 
|
609  | 
done  | 
|
610  | 
done  | 
|
611  | 
||
612  | 
lemma set_of_mul_inc_left:  | 
|
613  | 
"set_of (A * B) \<subseteq> set_of (A' * B)"  | 
|
614  | 
if "set_of A \<subseteq> set_of A'"  | 
|
615  | 
  for A :: "'a::{linordered_ring, real_normed_algebra, linear_continuum_topology} interval"
 | 
|
616  | 
using that  | 
|
617  | 
unfolding set_of_times  | 
|
618  | 
by auto  | 
|
619  | 
||
620  | 
lemma set_of_mul_inc:  | 
|
621  | 
"set_of (A * B) \<subseteq> set_of (A' * B')"  | 
|
622  | 
if "set_of A \<subseteq> set_of A'" "set_of B \<subseteq> set_of B'"  | 
|
623  | 
  for A :: "'a::{linordered_ring, real_normed_algebra, linear_continuum_topology} interval"
 | 
|
624  | 
using that unfolding set_of_times by auto  | 
|
625  | 
||
626  | 
lemma set_of_pow_inc:  | 
|
627  | 
"set_of (A^n) \<subseteq> set_of (A'^n)"  | 
|
628  | 
if "set_of A \<subseteq> set_of A'"  | 
|
629  | 
  for A :: "'a::{linordered_idom, real_normed_algebra, linear_continuum_topology} interval"
 | 
|
630  | 
using that  | 
|
631  | 
by (induction n, simp_all add: set_of_mul_inc)  | 
|
632  | 
||
633  | 
lemma set_of_distrib_right_left:  | 
|
634  | 
"set_of ((A1 + A2) * (B1 + B2)) \<subseteq> set_of (A1 * B1 + A1 * B2 + A2 * B1 + A2 * B2)"  | 
|
635  | 
  for A1 :: "'a::{linordered_idom, real_normed_algebra, linear_continuum_topology} interval"
 | 
|
636  | 
proof-  | 
|
637  | 
have "set_of ((A1 + A2) * (B1 + B2)) \<subseteq> set_of (A1 * (B1 + B2) + A2 * (B1 + B2))"  | 
|
638  | 
by (rule set_of_distrib_right)  | 
|
639  | 
also have "... \<subseteq> set_of ((A1 * B1 + A1 * B2) + A2 * (B1 + B2))"  | 
|
640  | 
by (rule set_of_add_inc_left[OF set_of_distrib_left])  | 
|
641  | 
also have "... \<subseteq> set_of ((A1 * B1 + A1 * B2) + (A2 * B1 + A2 * B2))"  | 
|
642  | 
by (rule set_of_add_inc_right[OF set_of_distrib_left])  | 
|
643  | 
finally show ?thesis  | 
|
644  | 
by (simp add: add.assoc)  | 
|
645  | 
qed  | 
|
646  | 
||
647  | 
lemma mult_bounds_enclose_zero1:  | 
|
648  | 
"min (la * lb) (min (la * ub) (min (lb * ua) (ua * ub))) \<le> 0"  | 
|
649  | 
"0 \<le> max (la * lb) (max (la * ub) (max (lb * ua) (ua * ub)))"  | 
|
650  | 
if "la \<le> 0" "0 \<le> ua"  | 
|
651  | 
for la lb ua ub:: "'a::linordered_idom"  | 
|
652  | 
subgoal by (metis (no_types, hide_lams) that eq_iff min_le_iff_disj mult_zero_left mult_zero_right  | 
|
653  | 
zero_le_mult_iff)  | 
|
654  | 
subgoal by (metis that le_max_iff_disj mult_zero_right order_refl zero_le_mult_iff)  | 
|
655  | 
done  | 
|
656  | 
||
657  | 
lemma mult_bounds_enclose_zero2:  | 
|
658  | 
"min (la * lb) (min (la * ub) (min (lb * ua) (ua * ub))) \<le> 0"  | 
|
659  | 
"0 \<le> max (la * lb) (max (la * ub) (max (lb * ua) (ua * ub)))"  | 
|
660  | 
if "lb \<le> 0" "0 \<le> ub"  | 
|
661  | 
for la lb ua ub:: "'a::linordered_idom"  | 
|
662  | 
using mult_bounds_enclose_zero1[OF that, of la ua]  | 
|
663  | 
by (simp_all add: ac_simps)  | 
|
664  | 
||
665  | 
lemma set_of_mul_contains_zero:  | 
|
666  | 
"0 \<in> set_of (A * B)"  | 
|
667  | 
if "0 \<in> set_of A \<or> 0 \<in> set_of B"  | 
|
668  | 
for A :: "'a::linordered_idom interval"  | 
|
669  | 
using that  | 
|
670  | 
by (auto simp: set_of_eq lower_times upper_times algebra_simps mult_le_0_iff  | 
|
671  | 
mult_bounds_enclose_zero1 mult_bounds_enclose_zero2)  | 
|
672  | 
||
673  | 
instance "interval" :: (linordered_semiring) mult_zero  | 
|
674  | 
apply standard  | 
|
675  | 
subgoal by transfer auto  | 
|
676  | 
subgoal by transfer auto  | 
|
677  | 
done  | 
|
678  | 
||
679  | 
lift_definition min_interval::"'a::linorder interval \<Rightarrow> 'a interval \<Rightarrow> 'a interval" is  | 
|
680  | 
"\<lambda>(l1, u1). \<lambda>(l2, u2). (min l1 l2, min u1 u2)"  | 
|
681  | 
by (auto simp: min_def)  | 
|
682  | 
lemma lower_min_interval[simp]: "lower (min_interval x y) = min (lower x) (lower y)"  | 
|
683  | 
by transfer auto  | 
|
684  | 
lemma upper_min_interval[simp]: "upper (min_interval x y) = min (upper x) (upper y)"  | 
|
685  | 
by transfer auto  | 
|
686  | 
||
687  | 
lemma min_intervalI:  | 
|
688  | 
"a \<in>\<^sub>i A \<Longrightarrow> b \<in>\<^sub>i B \<Longrightarrow> min a b \<in>\<^sub>i min_interval A B"  | 
|
689  | 
by (auto simp: set_of_eq min_def)  | 
|
690  | 
||
691  | 
lift_definition max_interval::"'a::linorder interval \<Rightarrow> 'a interval \<Rightarrow> 'a interval" is  | 
|
692  | 
"\<lambda>(l1, u1). \<lambda>(l2, u2). (max l1 l2, max u1 u2)"  | 
|
693  | 
by (auto simp: max_def)  | 
|
694  | 
lemma lower_max_interval[simp]: "lower (max_interval x y) = max (lower x) (lower y)"  | 
|
695  | 
by transfer auto  | 
|
696  | 
lemma upper_max_interval[simp]: "upper (max_interval x y) = max (upper x) (upper y)"  | 
|
697  | 
by transfer auto  | 
|
698  | 
||
699  | 
lemma max_intervalI:  | 
|
700  | 
"a \<in>\<^sub>i A \<Longrightarrow> b \<in>\<^sub>i B \<Longrightarrow> max a b \<in>\<^sub>i max_interval A B"  | 
|
701  | 
by (auto simp: set_of_eq max_def)  | 
|
702  | 
||
703  | 
lift_definition abs_interval::"'a::linordered_idom interval \<Rightarrow> 'a interval" is  | 
|
704  | 
"(\<lambda>(l,u). (if l < 0 \<and> 0 < u then 0 else min \<bar>l\<bar> \<bar>u\<bar>, max \<bar>l\<bar> \<bar>u\<bar>))"  | 
|
705  | 
by auto  | 
|
706  | 
||
707  | 
lemma lower_abs_interval[simp]:  | 
|
708  | 
"lower (abs_interval x) = (if lower x < 0 \<and> 0 < upper x then 0 else min \<bar>lower x\<bar> \<bar>upper x\<bar>)"  | 
|
709  | 
by transfer auto  | 
|
710  | 
lemma upper_abs_interval[simp]: "upper (abs_interval x) = max \<bar>lower x\<bar> \<bar>upper x\<bar>"  | 
|
711  | 
by transfer auto  | 
|
712  | 
||
713  | 
lemma in_abs_intervalI1:  | 
|
714  | 
  "lx < 0 \<Longrightarrow> 0 < ux \<Longrightarrow> 0 \<le> xa \<Longrightarrow> xa \<le> max (- lx) (ux) \<Longrightarrow> xa \<in> abs ` {lx..ux}"
 | 
|
715  | 
for xa::"'a::linordered_idom"  | 
|
716  | 
by (metis abs_minus_cancel abs_of_nonneg atLeastAtMost_iff image_eqI le_less le_max_iff_disj  | 
|
717  | 
le_minus_iff neg_le_0_iff_le order_trans)  | 
|
718  | 
||
719  | 
lemma in_abs_intervalI2:  | 
|
720  | 
"min (\<bar>lx\<bar>) \<bar>ux\<bar> \<le> xa \<Longrightarrow> xa \<le> max \<bar>lx\<bar> \<bar>ux\<bar> \<Longrightarrow> lx \<le> ux \<Longrightarrow> 0 \<le> lx \<or> ux \<le> 0 \<Longrightarrow>  | 
|
721  | 
    xa \<in> abs ` {lx..ux}"
 | 
|
722  | 
for xa::"'a::linordered_idom"  | 
|
723  | 
by (force intro: image_eqI[where x="-xa"] image_eqI[where x="xa"])  | 
|
724  | 
||
725  | 
lemma set_of_abs_interval: "set_of (abs_interval x) = abs ` set_of x"  | 
|
726  | 
by (auto simp: set_of_eq not_less intro: in_abs_intervalI1 in_abs_intervalI2 cong del: image_cong_simp)  | 
|
727  | 
||
728  | 
fun split_domain :: "('a::preorder interval \<Rightarrow> 'a interval list) \<Rightarrow> 'a interval list \<Rightarrow> 'a interval list list"
 | 
|
729  | 
where "split_domain split [] = [[]]"  | 
|
730  | 
| "split_domain split (I#Is) = (  | 
|
731  | 
let S = split I;  | 
|
732  | 
D = split_domain split Is  | 
|
733  | 
in concat (map (\<lambda>d. map (\<lambda>s. s # d) S) D)  | 
|
734  | 
)"  | 
|
735  | 
||
736  | 
context notes [[typedef_overloaded]] begin  | 
|
737  | 
lift_definition(code_dt) split_interval::"'a::linorder interval \<Rightarrow> 'a \<Rightarrow> ('a interval \<times> 'a interval)"
 | 
|
738  | 
is "\<lambda>(l, u) x. ((min l x, max l x), (min u x, max u x))"  | 
|
739  | 
by (auto simp: min_def)  | 
|
740  | 
end  | 
|
741  | 
||
742  | 
lemma split_domain_nonempty:  | 
|
743  | 
assumes "\<And>I. split I \<noteq> []"  | 
|
744  | 
shows "split_domain split I \<noteq> []"  | 
|
745  | 
using last_in_set assms  | 
|
746  | 
by (induction I, auto)  | 
|
747  | 
||
| 
71037
 
f630f2e707a6
refactor Approximation.thy to use more abstract type of intervals
 
immler 
parents: 
71035 
diff
changeset
 | 
748  | 
lemma lower_split_interval1: "lower (fst (split_interval X m)) = min (lower X) m"  | 
| 
 
f630f2e707a6
refactor Approximation.thy to use more abstract type of intervals
 
immler 
parents: 
71035 
diff
changeset
 | 
749  | 
and lower_split_interval2: "lower (snd (split_interval X m)) = min (upper X) m"  | 
| 
 
f630f2e707a6
refactor Approximation.thy to use more abstract type of intervals
 
immler 
parents: 
71035 
diff
changeset
 | 
750  | 
and upper_split_interval1: "upper (fst (split_interval X m)) = max (lower X) m"  | 
| 
 
f630f2e707a6
refactor Approximation.thy to use more abstract type of intervals
 
immler 
parents: 
71035 
diff
changeset
 | 
751  | 
and upper_split_interval2: "upper (snd (split_interval X m)) = max (upper X) m"  | 
| 
 
f630f2e707a6
refactor Approximation.thy to use more abstract type of intervals
 
immler 
parents: 
71035 
diff
changeset
 | 
752  | 
subgoal by transfer auto  | 
| 
 
f630f2e707a6
refactor Approximation.thy to use more abstract type of intervals
 
immler 
parents: 
71035 
diff
changeset
 | 
753  | 
subgoal by transfer (auto simp: min.commute)  | 
| 
 
f630f2e707a6
refactor Approximation.thy to use more abstract type of intervals
 
immler 
parents: 
71035 
diff
changeset
 | 
754  | 
subgoal by transfer (auto simp: )  | 
| 
 
f630f2e707a6
refactor Approximation.thy to use more abstract type of intervals
 
immler 
parents: 
71035 
diff
changeset
 | 
755  | 
subgoal by transfer (auto simp: )  | 
| 
 
f630f2e707a6
refactor Approximation.thy to use more abstract type of intervals
 
immler 
parents: 
71035 
diff
changeset
 | 
756  | 
done  | 
| 71035 | 757  | 
|
758  | 
lemma split_intervalD: "split_interval X x = (A, B) \<Longrightarrow> set_of X \<subseteq> set_of A \<union> set_of B"  | 
|
759  | 
unfolding set_of_eq  | 
|
760  | 
by transfer (auto simp: min_def max_def split: if_splits)  | 
|
761  | 
||
762  | 
instantiation interval :: ("{topological_space, preorder}") topological_space
 | 
|
763  | 
begin  | 
|
764  | 
||
765  | 
definition open_interval_def[code del]: "open (X::'a interval set) =  | 
|
766  | 
(\<forall>x\<in>X.  | 
|
767  | 
\<exists>A B.  | 
|
768  | 
open A \<and>  | 
|
769  | 
open B \<and>  | 
|
770  | 
lower x \<in> A \<and> upper x \<in> B \<and> Interval ` (A \<times> B) \<subseteq> X)"  | 
|
771  | 
||
772  | 
instance  | 
|
773  | 
proof  | 
|
774  | 
  show "open (UNIV :: ('a interval) set)"
 | 
|
775  | 
unfolding open_interval_def by auto  | 
|
776  | 
next  | 
|
777  | 
  fix S T :: "('a interval) set"
 | 
|
778  | 
assume "open S" "open T"  | 
|
779  | 
show "open (S \<inter> T)"  | 
|
780  | 
unfolding open_interval_def  | 
|
781  | 
proof (safe)  | 
|
782  | 
fix x assume "x \<in> S" "x \<in> T"  | 
|
783  | 
from \<open>x \<in> S\<close> \<open>open S\<close> obtain Sl Su where S:  | 
|
784  | 
"open Sl" "open Su" "lower x \<in> Sl" "upper x \<in> Su" "Interval ` (Sl \<times> Su) \<subseteq> S"  | 
|
785  | 
by (auto simp: open_interval_def)  | 
|
786  | 
from \<open>x \<in> T\<close> \<open>open T\<close> obtain Tl Tu where T:  | 
|
787  | 
"open Tl" "open Tu" "lower x \<in> Tl" "upper x \<in> Tu" "Interval ` (Tl \<times> Tu) \<subseteq> T"  | 
|
788  | 
by (auto simp: open_interval_def)  | 
|
789  | 
||
790  | 
let ?L = "Sl \<inter> Tl" and ?U = "Su \<inter> Tu"  | 
|
791  | 
have "open ?L \<and> open ?U \<and> lower x \<in> ?L \<and> upper x \<in> ?U \<and> Interval ` (?L \<times> ?U) \<subseteq> S \<inter> T"  | 
|
792  | 
using S T by (auto simp add: open_Int)  | 
|
793  | 
then show "\<exists>A B. open A \<and> open B \<and> lower x \<in> A \<and> upper x \<in> B \<and> Interval ` (A \<times> B) \<subseteq> S \<inter> T"  | 
|
794  | 
by fast  | 
|
795  | 
qed  | 
|
796  | 
qed (unfold open_interval_def, fast)  | 
|
797  | 
||
798  | 
end  | 
|
799  | 
||
800  | 
||
801  | 
subsection \<open>Quickcheck\<close>  | 
|
802  | 
||
803  | 
lift_definition Ivl::"'a \<Rightarrow> 'a::preorder \<Rightarrow> 'a interval" is "\<lambda>a b. (min a b, b)"  | 
|
804  | 
by (auto simp: min_def)  | 
|
805  | 
||
806  | 
instantiation interval :: ("{exhaustive,preorder}") exhaustive
 | 
|
807  | 
begin  | 
|
808  | 
||
809  | 
definition exhaustive_interval::"('a interval \<Rightarrow> (bool \<times> term list) option)
 | 
|
810  | 
\<Rightarrow> natural \<Rightarrow> (bool \<times> term list) option"  | 
|
811  | 
where  | 
|
812  | 
"exhaustive_interval f d =  | 
|
813  | 
Quickcheck_Exhaustive.exhaustive (\<lambda>x. Quickcheck_Exhaustive.exhaustive (\<lambda>y. f (Ivl x y)) d) d"  | 
|
814  | 
||
815  | 
instance ..  | 
|
816  | 
||
817  | 
end  | 
|
818  | 
||
819  | 
definition (in term_syntax) [code_unfold]:  | 
|
820  | 
  "valtermify_interval x y = Code_Evaluation.valtermify (Ivl::'a::{preorder,typerep}\<Rightarrow>_) {\<cdot>} x {\<cdot>} y"
 | 
|
821  | 
||
822  | 
instantiation interval :: ("{full_exhaustive,preorder,typerep}") full_exhaustive
 | 
|
823  | 
begin  | 
|
824  | 
||
825  | 
definition full_exhaustive_interval::  | 
|
826  | 
  "('a interval \<times> (unit \<Rightarrow> term) \<Rightarrow> (bool \<times> term list) option)
 | 
|
827  | 
\<Rightarrow> natural \<Rightarrow> (bool \<times> term list) option" where  | 
|
828  | 
"full_exhaustive_interval f d =  | 
|
829  | 
Quickcheck_Exhaustive.full_exhaustive  | 
|
830  | 
(\<lambda>x. Quickcheck_Exhaustive.full_exhaustive (\<lambda>y. f (valtermify_interval x y)) d) d"  | 
|
831  | 
||
832  | 
instance ..  | 
|
833  | 
||
834  | 
end  | 
|
835  | 
||
836  | 
instantiation interval :: ("{random,preorder,typerep}") random
 | 
|
837  | 
begin  | 
|
838  | 
||
839  | 
definition random_interval ::  | 
|
840  | 
"natural  | 
|
841  | 
\<Rightarrow> natural \<times> natural  | 
|
842  | 
     \<Rightarrow> ('a interval \<times> (unit \<Rightarrow> term)) \<times> natural \<times> natural" where
 | 
|
843  | 
"random_interval i =  | 
|
844  | 
scomp (Quickcheck_Random.random i)  | 
|
845  | 
(\<lambda>man. scomp (Quickcheck_Random.random i) (\<lambda>exp. Pair (valtermify_interval man exp)))"  | 
|
846  | 
||
847  | 
instance ..  | 
|
848  | 
||
849  | 
end  | 
|
850  | 
||
851  | 
lifting_update interval.lifting  | 
|
852  | 
lifting_forget interval.lifting  | 
|
853  | 
||
854  | 
end  |