| author | wenzelm |
| Thu, 24 Apr 2025 23:29:57 +0200 | |
| changeset 82584 | 7ab0fb5d9919 |
| parent 82393 | 88064da0ae76 |
| child 82774 | 2865a6618cba |
| permissions | -rw-r--r-- |
| 69184 | 1 |
(* Title: HOL/Library/Comparator.thy |
2 |
Author: Florian Haftmann, TU Muenchen |
|
3 |
*) |
|
4 |
||
5 |
theory Comparator |
|
6 |
imports Main |
|
7 |
begin |
|
8 |
||
9 |
section \<open>Comparators on linear quasi-orders\<close> |
|
10 |
||
| 69251 | 11 |
subsection \<open>Basic properties\<close> |
12 |
||
| 69184 | 13 |
datatype comp = Less | Equiv | Greater |
14 |
||
15 |
locale comparator = |
|
| 82388 | 16 |
fixes cmp :: \<open>'a \<Rightarrow> 'a \<Rightarrow> comp\<close> |
17 |
assumes refl [simp]: \<open>\<And>a. cmp a a = Equiv\<close> |
|
18 |
and trans_equiv: \<open>\<And>a b c. cmp a b = Equiv \<Longrightarrow> cmp b c = Equiv \<Longrightarrow> cmp a c = Equiv\<close> |
|
19 |
assumes trans_less: \<open>cmp a b = Less \<Longrightarrow> cmp b c = Less \<Longrightarrow> cmp a c = Less\<close> |
|
20 |
and greater_iff_sym_less: \<open>\<And>b a. cmp b a = Greater \<longleftrightarrow> cmp a b = Less\<close> |
|
| 69184 | 21 |
begin |
22 |
||
23 |
text \<open>Dual properties\<close> |
|
24 |
||
25 |
lemma trans_greater: |
|
| 82388 | 26 |
\<open>cmp a c = Greater\<close> if \<open>cmp a b = Greater\<close> \<open>cmp b c = Greater\<close> |
| 69184 | 27 |
using that greater_iff_sym_less trans_less by blast |
28 |
||
29 |
lemma less_iff_sym_greater: |
|
| 82388 | 30 |
\<open>cmp b a = Less \<longleftrightarrow> cmp a b = Greater\<close> |
| 69184 | 31 |
by (simp add: greater_iff_sym_less) |
32 |
||
33 |
text \<open>The equivalence part\<close> |
|
34 |
||
35 |
lemma sym: |
|
| 82388 | 36 |
\<open>cmp b a = Equiv \<longleftrightarrow> cmp a b = Equiv\<close> |
| 69184 | 37 |
by (metis (full_types) comp.exhaust greater_iff_sym_less) |
38 |
||
39 |
lemma reflp: |
|
| 82388 | 40 |
\<open>reflp (\<lambda>a b. cmp a b = Equiv)\<close> |
| 69184 | 41 |
by (rule reflpI) simp |
42 |
||
43 |
lemma symp: |
|
| 82388 | 44 |
\<open>symp (\<lambda>a b. cmp a b = Equiv)\<close> |
| 69184 | 45 |
by (rule sympI) (simp add: sym) |
46 |
||
47 |
lemma transp: |
|
| 82388 | 48 |
\<open>transp (\<lambda>a b. cmp a b = Equiv)\<close> |
| 69184 | 49 |
by (rule transpI) (fact trans_equiv) |
50 |
||
51 |
lemma equivp: |
|
| 82388 | 52 |
\<open>equivp (\<lambda>a b. cmp a b = Equiv)\<close> |
| 69184 | 53 |
using reflp symp transp by (rule equivpI) |
54 |
||
55 |
text \<open>The strict part\<close> |
|
56 |
||
57 |
lemma irreflp_less: |
|
| 82388 | 58 |
\<open>irreflp (\<lambda>a b. cmp a b = Less)\<close> |
| 69184 | 59 |
by (rule irreflpI) simp |
60 |
||
61 |
lemma irreflp_greater: |
|
| 82388 | 62 |
\<open>irreflp (\<lambda>a b. cmp a b = Greater)\<close> |
| 69184 | 63 |
by (rule irreflpI) simp |
64 |
||
65 |
lemma asym_less: |
|
| 82388 | 66 |
\<open>cmp b a \<noteq> Less\<close> if \<open>cmp a b = Less\<close> |
| 69184 | 67 |
using that greater_iff_sym_less by force |
68 |
||
69 |
lemma asym_greater: |
|
| 82388 | 70 |
\<open>cmp b a \<noteq> Greater\<close> if \<open>cmp a b = Greater\<close> |
| 69184 | 71 |
using that greater_iff_sym_less by force |
72 |
||
73 |
lemma asymp_less: |
|
| 82388 | 74 |
\<open>asymp (\<lambda>a b. cmp a b = Less)\<close> |
75 |
using irreflp_less by (auto dest: asym_less) |
|
| 69184 | 76 |
|
77 |
lemma asymp_greater: |
|
| 82388 | 78 |
\<open>asymp (\<lambda>a b. cmp a b = Greater)\<close> |
79 |
using irreflp_greater by (auto dest: asym_greater) |
|
| 69184 | 80 |
|
|
69246
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
81 |
lemma trans_equiv_less: |
| 82388 | 82 |
\<open>cmp a c = Less\<close> if \<open>cmp a b = Equiv\<close> and \<open>cmp b c = Less\<close> |
|
69246
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
83 |
using that |
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
84 |
by (metis (full_types) comp.exhaust greater_iff_sym_less trans_equiv trans_less) |
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
85 |
|
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
86 |
lemma trans_less_equiv: |
| 82388 | 87 |
\<open>cmp a c = Less\<close> if \<open>cmp a b = Less\<close> and \<open>cmp b c = Equiv\<close> |
|
69246
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
88 |
using that |
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
89 |
by (metis (full_types) comp.exhaust greater_iff_sym_less trans_equiv trans_less) |
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
90 |
|
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
91 |
lemma trans_equiv_greater: |
| 82388 | 92 |
\<open>cmp a c = Greater\<close> if \<open>cmp a b = Equiv\<close> and \<open>cmp b c = Greater\<close> |
|
69246
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
93 |
using that by (simp add: sym [of a b] greater_iff_sym_less trans_less_equiv) |
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
94 |
|
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
95 |
lemma trans_greater_equiv: |
| 82388 | 96 |
\<open>cmp a c = Greater\<close> if \<open>cmp a b = Greater\<close> and \<open>cmp b c = Equiv\<close> |
|
69246
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
97 |
using that by (simp add: sym [of b c] greater_iff_sym_less trans_equiv_less) |
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
98 |
|
| 69184 | 99 |
lemma transp_less: |
| 82388 | 100 |
\<open>transp (\<lambda>a b. cmp a b = Less)\<close> |
| 69184 | 101 |
by (rule transpI) (fact trans_less) |
102 |
||
103 |
lemma transp_greater: |
|
| 82388 | 104 |
\<open>transp (\<lambda>a b. cmp a b = Greater)\<close> |
| 69184 | 105 |
by (rule transpI) (fact trans_greater) |
106 |
||
107 |
text \<open>The reflexive part\<close> |
|
108 |
||
109 |
lemma reflp_not_less: |
|
| 82388 | 110 |
\<open>reflp (\<lambda>a b. cmp a b \<noteq> Less)\<close> |
| 69184 | 111 |
by (rule reflpI) simp |
112 |
||
113 |
lemma reflp_not_greater: |
|
| 82388 | 114 |
\<open>reflp (\<lambda>a b. cmp a b \<noteq> Greater)\<close> |
| 69184 | 115 |
by (rule reflpI) simp |
116 |
||
117 |
lemma quasisym_not_less: |
|
| 82388 | 118 |
\<open>cmp a b = Equiv\<close> if \<open>cmp a b \<noteq> Less\<close> and \<open>cmp b a \<noteq> Less\<close> |
| 69184 | 119 |
using that comp.exhaust greater_iff_sym_less by auto |
120 |
||
121 |
lemma quasisym_not_greater: |
|
| 82388 | 122 |
\<open>cmp a b = Equiv\<close> if \<open>cmp a b \<noteq> Greater\<close> and \<open>cmp b a \<noteq> Greater\<close> |
| 69184 | 123 |
using that comp.exhaust greater_iff_sym_less by auto |
124 |
||
125 |
lemma trans_not_less: |
|
| 82388 | 126 |
\<open>cmp a c \<noteq> Less\<close> if \<open>cmp a b \<noteq> Less\<close> \<open>cmp b c \<noteq> Less\<close> |
| 69184 | 127 |
using that by (metis comp.exhaust greater_iff_sym_less trans_equiv trans_less) |
128 |
||
129 |
lemma trans_not_greater: |
|
| 82388 | 130 |
\<open>cmp a c \<noteq> Greater\<close> if \<open>cmp a b \<noteq> Greater\<close> \<open>cmp b c \<noteq> Greater\<close> |
| 69184 | 131 |
using that greater_iff_sym_less trans_not_less by blast |
132 |
||
133 |
lemma transp_not_less: |
|
| 82388 | 134 |
\<open>transp (\<lambda>a b. cmp a b \<noteq> Less)\<close> |
| 69184 | 135 |
by (rule transpI) (fact trans_not_less) |
136 |
||
137 |
lemma transp_not_greater: |
|
| 82388 | 138 |
\<open>transp (\<lambda>a b. cmp a b \<noteq> Greater)\<close> |
| 69184 | 139 |
by (rule transpI) (fact trans_not_greater) |
140 |
||
|
69246
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
141 |
text \<open>Substitution under equivalences\<close> |
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
142 |
|
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
143 |
lemma equiv_subst_left: |
| 82388 | 144 |
\<open>cmp z y = comp \<longleftrightarrow> cmp x y = comp\<close> if \<open>cmp z x = Equiv\<close> for comp |
|
69246
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
145 |
proof - |
| 82388 | 146 |
from that have \<open>cmp x z = Equiv\<close> |
|
69246
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
147 |
by (simp add: sym) |
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
148 |
with that show ?thesis |
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
149 |
by (cases comp) (auto intro: trans_equiv trans_equiv_less trans_equiv_greater) |
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
150 |
qed |
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
151 |
|
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
152 |
lemma equiv_subst_right: |
| 82388 | 153 |
\<open>cmp x z = comp \<longleftrightarrow> cmp x y = comp\<close> if \<open>cmp z y = Equiv\<close> for comp |
|
69246
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
154 |
proof - |
| 82388 | 155 |
from that have \<open>cmp y z = Equiv\<close> |
|
69246
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
156 |
by (simp add: sym) |
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
157 |
with that show ?thesis |
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
158 |
by (cases comp) (auto intro: trans_equiv trans_less_equiv trans_greater_equiv) |
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
159 |
qed |
|
c1fe9dcc274a
concrecte sorting algorithms beyond insertion sort
haftmann
parents:
69194
diff
changeset
|
160 |
|
| 69184 | 161 |
end |
162 |
||
| 82388 | 163 |
typedef 'a comparator = \<open>{cmp :: 'a \<Rightarrow> 'a \<Rightarrow> comp. comparator cmp}\<close>
|
| 69184 | 164 |
morphisms compare Abs_comparator |
165 |
proof - |
|
| 82388 | 166 |
have \<open>comparator (\<lambda>_ _. Equiv)\<close> |
| 69184 | 167 |
by standard simp_all |
168 |
then show ?thesis |
|
169 |
by auto |
|
170 |
qed |
|
171 |
||
172 |
setup_lifting type_definition_comparator |
|
173 |
||
| 82388 | 174 |
global_interpretation compare: comparator \<open>compare cmp\<close> |
| 69184 | 175 |
using compare [of cmp] by simp |
176 |
||
| 82388 | 177 |
lift_definition flat :: \<open>'a comparator\<close> |
178 |
is \<open>\<lambda>_ _. Equiv\<close> by standard simp_all |
|
| 69184 | 179 |
|
180 |
instantiation comparator :: (linorder) default |
|
181 |
begin |
|
182 |
||
| 82388 | 183 |
lift_definition default_comparator :: \<open>'a comparator\<close> |
184 |
is \<open>\<lambda>x y. if x < y then Less else if x > y then Greater else Equiv\<close> |
|
| 69184 | 185 |
by standard (auto split: if_splits) |
186 |
||
187 |
instance .. |
|
188 |
||
189 |
end |
|
190 |
||
| 82393 | 191 |
lemma compare_default_eq_Less_iff [simp]: |
192 |
\<open>compare default x y = Less \<longleftrightarrow> x < y\<close> |
|
193 |
by transfer simp |
|
194 |
||
195 |
lemma compare_default_eq_Equiv_iff [simp]: |
|
196 |
\<open>compare default x y = Equiv \<longleftrightarrow> x = y\<close> |
|
197 |
by transfer auto |
|
198 |
||
199 |
lemma compare_default_eq_Greater_iff [simp]: |
|
200 |
\<open>compare default x y = Greater \<longleftrightarrow> x > y\<close> |
|
201 |
by transfer auto |
|
202 |
||
| 69184 | 203 |
text \<open>A rudimentary quickcheck setup\<close> |
204 |
||
205 |
instantiation comparator :: (enum) equal |
|
206 |
begin |
|
207 |
||
| 82388 | 208 |
lift_definition equal_comparator :: \<open>'a comparator \<Rightarrow> 'a comparator \<Rightarrow> bool\<close> |
209 |
is \<open>\<lambda>f g. \<forall>x \<in> set Enum.enum. f x = g x\<close> . |
|
| 69184 | 210 |
|
211 |
instance |
|
212 |
by (standard; transfer) (auto simp add: enum_UNIV) |
|
213 |
||
214 |
end |
|
215 |
||
216 |
lemma [code]: |
|
| 82388 | 217 |
\<open>HOL.equal cmp1 cmp2 \<longleftrightarrow> Enum.enum_all (\<lambda>x. compare cmp1 x = compare cmp2 x)\<close> |
| 69184 | 218 |
by transfer (simp add: enum_UNIV) |
219 |
||
220 |
lemma [code nbe]: |
|
| 82388 | 221 |
\<open>HOL.equal (cmp :: 'a::enum comparator) cmp \<longleftrightarrow> True\<close> |
| 69184 | 222 |
by (fact equal_refl) |
223 |
||
224 |
instantiation comparator :: ("{linorder, typerep}") full_exhaustive
|
|
225 |
begin |
|
226 |
||
227 |
definition full_exhaustive_comparator :: |
|
| 82388 | 228 |
\<open>('a comparator \<times> (unit \<Rightarrow> term) \<Rightarrow> (bool \<times> term list) option)
|
229 |
\<Rightarrow> natural \<Rightarrow> (bool \<times> term list) option\<close> |
|
230 |
where \<open>full_exhaustive_comparator f s = |
|
| 69184 | 231 |
Quickcheck_Exhaustive.orelse |
232 |
(f (flat, (\<lambda>u. Code_Evaluation.Const (STR ''Comparator.flat'') TYPEREP('a comparator))))
|
|
| 82388 | 233 |
(f (default, (\<lambda>u. Code_Evaluation.Const (STR ''HOL.default_class.default'') TYPEREP('a comparator))))\<close>
|
| 69184 | 234 |
|
235 |
instance .. |
|
236 |
||
237 |
end |
|
238 |
||
| 69251 | 239 |
|
240 |
subsection \<open>Fundamental comparator combinators\<close> |
|
| 69194 | 241 |
|
| 82388 | 242 |
lift_definition reversed :: \<open>'a comparator \<Rightarrow> 'a comparator\<close> |
243 |
is \<open>\<lambda>cmp a b. cmp b a\<close> |
|
| 69184 | 244 |
proof - |
| 82388 | 245 |
fix cmp :: \<open>'a \<Rightarrow> 'a \<Rightarrow> comp\<close> |
246 |
assume \<open>comparator cmp\<close> |
|
| 69184 | 247 |
then interpret comparator cmp . |
| 82388 | 248 |
show \<open>comparator (\<lambda>a b. cmp b a)\<close> |
| 69184 | 249 |
by standard (auto intro: trans_equiv trans_less simp: greater_iff_sym_less) |
250 |
qed |
|
251 |
||
| 82393 | 252 |
lemma compare_reversed_apply [simp]: |
253 |
\<open>compare (reversed cmp) x y = compare cmp y x\<close> |
|
254 |
by transfer simp |
|
255 |
||
| 82388 | 256 |
lift_definition key :: \<open>('b \<Rightarrow> 'a) \<Rightarrow> 'a comparator \<Rightarrow> 'b comparator\<close>
|
257 |
is \<open>\<lambda>f cmp a b. cmp (f a) (f b)\<close> |
|
| 69184 | 258 |
proof - |
| 82388 | 259 |
fix cmp :: \<open>'a \<Rightarrow> 'a \<Rightarrow> comp\<close> and f :: \<open>'b \<Rightarrow> 'a\<close> |
260 |
assume \<open>comparator cmp\<close> |
|
| 69184 | 261 |
then interpret comparator cmp . |
| 82388 | 262 |
show \<open>comparator (\<lambda>a b. cmp (f a) (f b))\<close> |
| 69184 | 263 |
by standard (auto intro: trans_equiv trans_less simp: greater_iff_sym_less) |
264 |
qed |
|
265 |
||
| 82393 | 266 |
lemma compare_key_apply [simp]: |
267 |
\<open>compare (key f cmp) x y = compare cmp (f x) (f y)\<close> |
|
268 |
by transfer simp |
|
269 |
||
270 |
lift_definition prod_lex :: \<open>'a comparator \<Rightarrow> 'b comparator \<Rightarrow> ('a \<times> 'b) comparator\<close>
|
|
271 |
is \<open>\<lambda>f g (a, c) (b, d). case f a b of Less \<Rightarrow> Less | Equiv \<Rightarrow> g c d | Greater \<Rightarrow> Greater\<close> |
|
272 |
proof - |
|
273 |
fix f :: \<open>'a \<Rightarrow> 'a \<Rightarrow> comp\<close> and g :: \<open>'b \<Rightarrow> 'b \<Rightarrow> comp\<close> |
|
274 |
assume \<open>comparator f\<close> |
|
275 |
then interpret f: comparator f . |
|
276 |
assume \<open>comparator g\<close> |
|
277 |
then interpret g: comparator g . |
|
278 |
define h where \<open>h = (\<lambda>(a, c) (b, d). case f a b of Less \<Rightarrow> Less | Equiv \<Rightarrow> g c d | Greater \<Rightarrow> Greater)\<close> |
|
279 |
then have h_apply [simp]: \<open>h (a, c) (b, d) = (case f a b of Less \<Rightarrow> Less | Equiv \<Rightarrow> g c d | Greater \<Rightarrow> Greater)\<close> for a b c d |
|
280 |
by simp |
|
281 |
have h_equiv: \<open>h p q = Equiv \<longleftrightarrow> f (fst p) (fst q) = Equiv \<and> g (snd p) (snd q) = Equiv\<close> for p q |
|
282 |
by (cases p; cases q) (simp split: comp.split) |
|
283 |
have h_less: \<open>h p q = Less \<longleftrightarrow> f (fst p) (fst q) = Less \<or> f (fst p) (fst q) = Equiv \<and> g (snd p) (snd q) = Less\<close> for p q |
|
284 |
by (cases p; cases q) (simp split: comp.split) |
|
285 |
have h_greater: \<open>h p q = Greater \<longleftrightarrow> f (fst p) (fst q) = Greater \<or> f (fst p) (fst q) = Equiv \<and> g (snd p) (snd q) = Greater\<close> for p q |
|
286 |
by (cases p; cases q) (simp split: comp.split) |
|
287 |
have \<open>comparator h\<close> |
|
288 |
apply standard |
|
289 |
apply (simp_all add: h_equiv h_less h_greater f.greater_iff_sym_less g.greater_iff_sym_less f.sym g.sym) |
|
290 |
apply (auto intro: f.trans_equiv g.trans_equiv f.trans_less g.trans_less f.trans_less_equiv f.trans_equiv_less) |
|
291 |
done |
|
292 |
then show \<open>comparator (\<lambda>(a, c) (b, d). case f a b of Less \<Rightarrow> Less |
|
293 |
| Equiv \<Rightarrow> g c d |
|
294 |
| Greater \<Rightarrow> Greater)\<close> |
|
295 |
by (simp add: h_def) |
|
296 |
qed |
|
297 |
||
298 |
lemma compare_prod_lex_apply: |
|
299 |
\<open>compare (prod_lex cmp1 cmp2) p q = |
|
300 |
(case compare (key fst cmp1) p q of Less \<Rightarrow> Less | Equiv \<Rightarrow> compare (key snd cmp2) p q | Greater \<Rightarrow> Greater)\<close> |
|
301 |
by transfer (simp add: split_def) |
|
302 |
||
| 69251 | 303 |
|
304 |
subsection \<open>Direct implementations for linear orders on selected types\<close> |
|
305 |
||
| 82388 | 306 |
definition comparator_bool :: \<open>bool comparator\<close> |
307 |
where [simp, code_abbrev]: \<open>comparator_bool = default\<close> |
|
| 69251 | 308 |
|
309 |
lemma compare_comparator_bool [code abstract]: |
|
| 82388 | 310 |
\<open>compare comparator_bool = (\<lambda>p q. |
| 69251 | 311 |
if p then if q then Equiv else Greater |
| 82388 | 312 |
else if q then Less else Equiv)\<close> |
| 82393 | 313 |
by (auto simp add: fun_eq_iff) |
| 69251 | 314 |
|
| 82388 | 315 |
definition raw_comparator_nat :: \<open>nat \<Rightarrow> nat \<Rightarrow> comp\<close> |
316 |
where [simp]: \<open>raw_comparator_nat = compare default\<close> |
|
| 69251 | 317 |
|
318 |
lemma default_comparator_nat [simp, code]: |
|
| 82388 | 319 |
\<open>raw_comparator_nat (0::nat) 0 = Equiv\<close> |
320 |
\<open>raw_comparator_nat (Suc m) 0 = Greater\<close> |
|
321 |
\<open>raw_comparator_nat 0 (Suc n) = Less\<close> |
|
322 |
\<open>raw_comparator_nat (Suc m) (Suc n) = raw_comparator_nat m n\<close> |
|
| 69251 | 323 |
by (transfer; simp)+ |
324 |
||
| 82388 | 325 |
definition comparator_nat :: \<open>nat comparator\<close> |
326 |
where [simp, code_abbrev]: \<open>comparator_nat = default\<close> |
|
| 69251 | 327 |
|
328 |
lemma compare_comparator_nat [code abstract]: |
|
| 82388 | 329 |
\<open>compare comparator_nat = raw_comparator_nat\<close> |
| 69251 | 330 |
by simp |
331 |
||
| 82388 | 332 |
definition comparator_linordered_group :: \<open>'a::linordered_ab_group_add comparator\<close> |
333 |
where [simp, code_abbrev]: \<open>comparator_linordered_group = default\<close> |
|
| 69251 | 334 |
|
335 |
lemma comparator_linordered_group [code abstract]: |
|
| 82388 | 336 |
\<open>compare comparator_linordered_group = (\<lambda>a b. |
| 69251 | 337 |
let c = a - b in if c < 0 then Less |
| 82388 | 338 |
else if c = 0 then Equiv else Greater)\<close> |
| 69251 | 339 |
proof (rule ext)+ |
340 |
fix a b :: 'a |
|
| 82388 | 341 |
show \<open>compare comparator_linordered_group a b = |
| 69251 | 342 |
(let c = a - b in if c < 0 then Less |
| 82388 | 343 |
else if c = 0 then Equiv else Greater)\<close> |
| 69251 | 344 |
by (simp add: Let_def not_less) (transfer; auto) |
345 |
qed |
|
346 |
||
| 69184 | 347 |
end |