1use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
6
7use super::types::{
8 DedekindCutQ, FiniteLinearOrder, FinitePartialOrder, OrderedRange, OrderedTable, Ordering,
9 OrderingBuilder, OrdinalCnf, WqoInstance,
10};
11
12pub fn build_ordering_env(env: &mut Environment) -> Result<(), String> {
14 let type1 = Expr::Sort(Level::succ(Level::zero()));
15 env.add(Declaration::Axiom {
16 name: Name::str("Ordering"),
17 univ_params: vec![],
18 ty: type1.clone(),
19 })
20 .map_err(|e| e.to_string())?;
21 env.add(Declaration::Axiom {
22 name: Name::str("Ordering.less"),
23 univ_params: vec![],
24 ty: Expr::Const(Name::str("Ordering"), vec![]),
25 })
26 .map_err(|e| e.to_string())?;
27 env.add(Declaration::Axiom {
28 name: Name::str("Ordering.equal"),
29 univ_params: vec![],
30 ty: Expr::Const(Name::str("Ordering"), vec![]),
31 })
32 .map_err(|e| e.to_string())?;
33 env.add(Declaration::Axiom {
34 name: Name::str("Ordering.greater"),
35 univ_params: vec![],
36 ty: Expr::Const(Name::str("Ordering"), vec![]),
37 })
38 .map_err(|e| e.to_string())?;
39 let is_le_ty = Expr::Pi(
40 oxilean_kernel::BinderInfo::Default,
41 Name::str("o"),
42 Box::new(Expr::Const(Name::str("Ordering"), vec![])),
43 Box::new(Expr::Const(Name::str("Bool"), vec![])),
44 );
45 env.add(Declaration::Axiom {
46 name: Name::str("Ordering.isLE"),
47 univ_params: vec![],
48 ty: is_le_ty,
49 })
50 .map_err(|e| e.to_string())?;
51 let is_ge_ty = Expr::Pi(
52 oxilean_kernel::BinderInfo::Default,
53 Name::str("o"),
54 Box::new(Expr::Const(Name::str("Ordering"), vec![])),
55 Box::new(Expr::Const(Name::str("Bool"), vec![])),
56 );
57 env.add(Declaration::Axiom {
58 name: Name::str("Ordering.isGE"),
59 univ_params: vec![],
60 ty: is_ge_ty,
61 })
62 .map_err(|e| e.to_string())?;
63 let reverse_ty = Expr::Pi(
64 oxilean_kernel::BinderInfo::Default,
65 Name::str("o"),
66 Box::new(Expr::Const(Name::str("Ordering"), vec![])),
67 Box::new(Expr::Const(Name::str("Ordering"), vec![])),
68 );
69 env.add(Declaration::Axiom {
70 name: Name::str("Ordering.reverse"),
71 univ_params: vec![],
72 ty: reverse_ty,
73 })
74 .map_err(|e| e.to_string())?;
75 let then_ty = Expr::Pi(
76 oxilean_kernel::BinderInfo::Default,
77 Name::str("o1"),
78 Box::new(Expr::Const(Name::str("Ordering"), vec![])),
79 Box::new(Expr::Pi(
80 oxilean_kernel::BinderInfo::Default,
81 Name::str("o2"),
82 Box::new(Expr::Const(Name::str("Ordering"), vec![])),
83 Box::new(Expr::Const(Name::str("Ordering"), vec![])),
84 )),
85 );
86 env.add(Declaration::Axiom {
87 name: Name::str("Ordering.then"),
88 univ_params: vec![],
89 ty: then_ty,
90 })
91 .map_err(|e| e.to_string())?;
92 Ok(())
93}
94#[cfg(test)]
95mod tests {
96 use super::*;
97 fn setup_env() -> Environment {
98 let mut env = Environment::new();
99 let type1 = Expr::Sort(Level::succ(Level::zero()));
100 env.add(Declaration::Axiom {
101 name: Name::str("Bool"),
102 univ_params: vec![],
103 ty: type1,
104 })
105 .expect("operation should succeed");
106 env
107 }
108 #[test]
109 fn test_build_ordering_env() {
110 let mut env = setup_env();
111 assert!(build_ordering_env(&mut env).is_ok());
112 assert!(env.get(&Name::str("Ordering")).is_some());
113 assert!(env.get(&Name::str("Ordering.less")).is_some());
114 assert!(env.get(&Name::str("Ordering.equal")).is_some());
115 assert!(env.get(&Name::str("Ordering.greater")).is_some());
116 }
117 #[test]
118 fn test_ordering_is_le() {
119 let mut env = setup_env();
120 build_ordering_env(&mut env).expect("build_ordering_env should succeed");
121 let decl = env
122 .get(&Name::str("Ordering.isLE"))
123 .expect("declaration 'Ordering.isLE' should exist in env");
124 assert!(matches!(decl, Declaration::Axiom { .. }));
125 }
126 #[test]
127 fn test_ordering_is_ge() {
128 let mut env = setup_env();
129 build_ordering_env(&mut env).expect("build_ordering_env should succeed");
130 let decl = env
131 .get(&Name::str("Ordering.isGE"))
132 .expect("declaration 'Ordering.isGE' should exist in env");
133 assert!(matches!(decl, Declaration::Axiom { .. }));
134 }
135 #[test]
136 fn test_ordering_reverse() {
137 let mut env = setup_env();
138 build_ordering_env(&mut env).expect("build_ordering_env should succeed");
139 let decl = env
140 .get(&Name::str("Ordering.reverse"))
141 .expect("declaration 'Ordering.reverse' should exist in env");
142 assert!(matches!(decl, Declaration::Axiom { .. }));
143 }
144 #[test]
145 fn test_ordering_then() {
146 let mut env = setup_env();
147 build_ordering_env(&mut env).expect("build_ordering_env should succeed");
148 let decl = env
149 .get(&Name::str("Ordering.then"))
150 .expect("declaration 'Ordering.then' should exist in env");
151 assert!(matches!(decl, Declaration::Axiom { .. }));
152 }
153}
154pub fn cmp<T: std::cmp::Ord>(a: &T, b: &T) -> Ordering {
156 Ordering::from_std(a.cmp(b))
157}
158pub fn cmp_by_key<T, K: std::cmp::Ord, F: Fn(&T) -> K>(a: &T, b: &T, key: F) -> Ordering {
160 Ordering::from_std(key(a).cmp(&key(b)))
161}
162pub fn cmp_slices<T: std::cmp::Ord>(a: &[T], b: &[T]) -> Ordering {
164 Ordering::from_std(a.cmp(b))
165}
166pub fn ordering_chain(items: impl IntoIterator<Item = Ordering>) -> Ordering {
168 for item in items {
169 if item != Ordering::Equal {
170 return item;
171 }
172 }
173 Ordering::Equal
174}
175pub fn sorted<T: std::cmp::Ord + Clone>(v: &[T]) -> Vec<T> {
177 let mut result = v.to_vec();
178 result.sort();
179 result
180}
181pub fn sorted_by_key<T: Clone, K: std::cmp::Ord, F: Fn(&T) -> K>(v: &[T], key: F) -> Vec<T> {
183 let mut result = v.to_vec();
184 result.sort_by_key(key);
185 result
186}
187pub fn sorted_desc<T: std::cmp::Ord + Clone>(v: &[T]) -> Vec<T> {
189 let mut result = v.to_vec();
190 result.sort_by(|a, b| b.cmp(a));
191 result
192}
193pub fn merge_sorted<T: std::cmp::Ord + Clone>(a: &[T], b: &[T]) -> Vec<T> {
195 let mut result = Vec::with_capacity(a.len() + b.len());
196 let (mut i, mut j) = (0, 0);
197 while i < a.len() && j < b.len() {
198 if a[i] <= b[j] {
199 result.push(a[i].clone());
200 i += 1;
201 } else {
202 result.push(b[j].clone());
203 j += 1;
204 }
205 }
206 result.extend_from_slice(&a[i..]);
207 result.extend_from_slice(&b[j..]);
208 result
209}
210pub fn is_sorted<T: std::cmp::Ord>(s: &[T]) -> bool {
212 s.windows(2).all(|w| w[0] <= w[1])
213}
214pub fn is_sorted_desc<T: std::cmp::Ord>(s: &[T]) -> bool {
216 s.windows(2).all(|w| w[0] >= w[1])
217}
218pub fn lower_bound<T: std::cmp::Ord>(s: &[T], target: &T) -> usize {
222 let mut lo = 0;
223 let mut hi = s.len();
224 while lo < hi {
225 let mid = lo + (hi - lo) / 2;
226 if s[mid] < *target {
227 lo = mid + 1;
228 } else {
229 hi = mid;
230 }
231 }
232 lo
233}
234pub fn upper_bound<T: std::cmp::Ord>(s: &[T], target: &T) -> usize {
238 let mut lo = 0;
239 let mut hi = s.len();
240 while lo < hi {
241 let mid = lo + (hi - lo) / 2;
242 if s[mid] <= *target {
243 lo = mid + 1;
244 } else {
245 hi = mid;
246 }
247 }
248 lo
249}
250#[cfg(test)]
251mod ordering_extra_tests {
252 use super::*;
253 #[test]
254 fn test_ordering_reverse() {
255 assert_eq!(Ordering::Less.reverse(), Ordering::Greater);
256 assert_eq!(Ordering::Greater.reverse(), Ordering::Less);
257 assert_eq!(Ordering::Equal.reverse(), Ordering::Equal);
258 }
259 #[test]
260 fn test_ordering_then() {
261 assert_eq!(Ordering::Equal.then(Ordering::Less), Ordering::Less);
262 assert_eq!(Ordering::Less.then(Ordering::Greater), Ordering::Less);
263 assert_eq!(Ordering::Greater.then(Ordering::Less), Ordering::Greater);
264 }
265 #[test]
266 fn test_ordering_predicates() {
267 assert!(Ordering::Less.is_lt());
268 assert!(Ordering::Less.is_le());
269 assert!(!Ordering::Less.is_ge());
270 assert!(Ordering::Equal.is_eq());
271 assert!(Ordering::Equal.is_le());
272 assert!(Ordering::Equal.is_ge());
273 assert!(Ordering::Greater.is_gt());
274 assert!(Ordering::Greater.is_ge());
275 assert!(!Ordering::Greater.is_le());
276 }
277 #[test]
278 fn test_ordering_signum() {
279 assert_eq!(Ordering::Less.to_signum(), -1);
280 assert_eq!(Ordering::Equal.to_signum(), 0);
281 assert_eq!(Ordering::Greater.to_signum(), 1);
282 assert_eq!(Ordering::from_signum(-5), Ordering::Less);
283 assert_eq!(Ordering::from_signum(0), Ordering::Equal);
284 assert_eq!(Ordering::from_signum(3), Ordering::Greater);
285 }
286 #[test]
287 fn test_ordering_std_roundtrip() {
288 let o = Ordering::Less;
289 assert_eq!(Ordering::from_std(o.to_std()), o);
290 }
291 #[test]
292 fn test_ordering_display() {
293 assert_eq!(Ordering::Less.to_string(), "lt");
294 assert_eq!(Ordering::Equal.to_string(), "eq");
295 assert_eq!(Ordering::Greater.to_string(), "gt");
296 }
297 #[test]
298 fn test_cmp() {
299 assert_eq!(cmp(&1, &2), Ordering::Less);
300 assert_eq!(cmp(&2, &2), Ordering::Equal);
301 assert_eq!(cmp(&3, &2), Ordering::Greater);
302 }
303 #[test]
304 fn test_ordering_chain() {
305 let result = ordering_chain([Ordering::Equal, Ordering::Equal, Ordering::Less]);
306 assert_eq!(result, Ordering::Less);
307 let all_eq = ordering_chain([Ordering::Equal, Ordering::Equal]);
308 assert_eq!(all_eq, Ordering::Equal);
309 }
310 #[test]
311 fn test_ordering_builder() {
312 let result = OrderingBuilder::new()
313 .field(&1u32, &1u32)
314 .field(&2u32, &3u32)
315 .build();
316 assert_eq!(result, Ordering::Less);
317 }
318 #[test]
319 fn test_sorted() {
320 let v = vec![3, 1, 4, 1, 5, 9, 2, 6];
321 let s = sorted(&v);
322 assert!(is_sorted(&s));
323 }
324 #[test]
325 fn test_sorted_desc() {
326 let v = vec![3, 1, 4, 1, 5];
327 let s = sorted_desc(&v);
328 assert!(is_sorted_desc(&s));
329 }
330 #[test]
331 fn test_merge_sorted() {
332 let a = vec![1, 3, 5];
333 let b = vec![2, 4, 6];
334 let merged = merge_sorted(&a, &b);
335 assert_eq!(merged, vec![1, 2, 3, 4, 5, 6]);
336 assert!(is_sorted(&merged));
337 }
338 #[test]
339 fn test_lower_upper_bound() {
340 let v = vec![1, 2, 2, 3, 4, 5];
341 assert_eq!(lower_bound(&v, &2), 1);
342 assert_eq!(upper_bound(&v, &2), 3);
343 assert_eq!(lower_bound(&v, &6), 6);
344 assert_eq!(upper_bound(&v, &0), 0);
345 }
346 #[test]
347 fn test_is_sorted_is_sorted_desc() {
348 assert!(is_sorted(&[1, 2, 3, 3]));
349 assert!(!is_sorted(&[1, 3, 2]));
350 assert!(is_sorted_desc(&[5, 4, 3, 1]));
351 assert!(!is_sorted_desc(&[1, 2]));
352 }
353 #[test]
354 fn test_cmp_slices() {
355 assert_eq!(cmp_slices(&[1, 2, 3], &[1, 2, 4]), Ordering::Less);
356 assert_eq!(cmp_slices::<i32>(&[], &[]), Ordering::Equal);
357 }
358 #[test]
359 fn test_cmp_by_key() {
360 let a = ("hello", 10);
361 let b = ("world", 5);
362 assert_eq!(cmp_by_key(&a, &b, |x| x.1), Ordering::Greater);
363 }
364}
365#[allow(dead_code)]
368pub fn build_full_ordering_env(env: &mut Environment) -> Result<(), String> {
369 build_ordering_env(env)?;
370 let decide_ty = Expr::Pi(
371 BinderInfo::Default,
372 Name::str("o1"),
373 Box::new(Expr::Const(Name::str("Ordering"), vec![])),
374 Box::new(Expr::Pi(
375 BinderInfo::Default,
376 Name::str("o2"),
377 Box::new(Expr::Const(Name::str("Ordering"), vec![])),
378 Box::new(Expr::Const(Name::str("Bool"), vec![])),
379 )),
380 );
381 env.add(Declaration::Axiom {
382 name: Name::str("Ordering.beq"),
383 univ_params: vec![],
384 ty: decide_ty,
385 })
386 .map_err(|e| e.to_string())?;
387 Ok(())
388}
389#[allow(dead_code)]
391pub fn str_cmp(a: &str, b: &str) -> Ordering {
392 Ordering::from_std(a.cmp(b))
393}
394#[allow(dead_code)]
396pub fn bool_cmp(a: bool, b: bool) -> Ordering {
397 Ordering::from_std(a.cmp(&b))
398}
399#[allow(dead_code)]
401pub fn usize_cmp(a: usize, b: usize) -> Ordering {
402 Ordering::from_std(a.cmp(&b))
403}
404#[allow(dead_code)]
406pub fn i64_cmp(a: i64, b: i64) -> Ordering {
407 Ordering::from_std(a.cmp(&b))
408}
409#[allow(dead_code)]
411pub fn f64_cmp(a: f64, b: f64) -> Ordering {
412 match a.partial_cmp(&b) {
413 Some(o) => Ordering::from_std(o),
414 None => Ordering::Equal,
415 }
416}
417#[allow(dead_code)]
419pub fn ordering_lt<T: std::cmp::Ord>(a: &T, b: &T) -> bool {
420 cmp(a, b).is_lt()
421}
422#[allow(dead_code)]
424pub fn ordering_le<T: std::cmp::Ord>(a: &T, b: &T) -> bool {
425 cmp(a, b).is_le()
426}
427#[allow(dead_code)]
429pub fn ordering_gt<T: std::cmp::Ord>(a: &T, b: &T) -> bool {
430 cmp(a, b).is_gt()
431}
432#[allow(dead_code)]
434pub fn ordering_ge<T: std::cmp::Ord>(a: &T, b: &T) -> bool {
435 cmp(a, b).is_ge()
436}
437#[allow(dead_code)]
439pub fn option_cmp<T: std::cmp::Ord>(a: &Option<T>, b: &Option<T>) -> Ordering {
440 match (a, b) {
441 (None, None) => Ordering::Equal,
442 (None, Some(_)) => Ordering::Less,
443 (Some(_), None) => Ordering::Greater,
444 (Some(x), Some(y)) => cmp(x, y),
445 }
446}
447#[allow(dead_code)]
449pub fn result_cmp<T: std::cmp::Ord, E: std::cmp::Ord>(
450 a: &Result<T, E>,
451 b: &Result<T, E>,
452) -> Ordering {
453 match (a, b) {
454 (Err(e1), Err(e2)) => cmp(e1, e2),
455 (Err(_), Ok(_)) => Ordering::Less,
456 (Ok(_), Err(_)) => Ordering::Greater,
457 (Ok(x), Ok(y)) => cmp(x, y),
458 }
459}
460#[cfg(test)]
461mod ordering_extra_tests2 {
462 use super::*;
463 #[test]
464 fn test_build_full_ordering_env() {
465 let mut env = Environment::new();
466 env.add(Declaration::Axiom {
467 name: Name::str("Bool"),
468 univ_params: vec![],
469 ty: Expr::Sort(Level::succ(Level::zero())),
470 })
471 .expect("operation should succeed");
472 assert!(build_full_ordering_env(&mut env).is_ok());
473 assert!(env.get(&Name::str("Ordering.beq")).is_some());
474 }
475 #[test]
476 fn test_str_cmp() {
477 assert_eq!(str_cmp("abc", "abd"), Ordering::Less);
478 assert_eq!(str_cmp("z", "a"), Ordering::Greater);
479 assert_eq!(str_cmp("x", "x"), Ordering::Equal);
480 }
481 #[test]
482 fn test_bool_cmp() {
483 assert_eq!(bool_cmp(false, true), Ordering::Less);
484 assert_eq!(bool_cmp(true, false), Ordering::Greater);
485 assert_eq!(bool_cmp(true, true), Ordering::Equal);
486 }
487 #[test]
488 fn test_numeric_cmp() {
489 assert_eq!(usize_cmp(3, 5), Ordering::Less);
490 assert_eq!(i64_cmp(-1, 1), Ordering::Less);
491 assert_eq!(f64_cmp(1.5, 1.5), Ordering::Equal);
492 assert_eq!(f64_cmp(2.0, 1.0), Ordering::Greater);
493 }
494 #[test]
495 fn test_ordering_predicates_via_cmp() {
496 assert!(ordering_lt(&1, &2));
497 assert!(ordering_le(&2, &2));
498 assert!(ordering_gt(&5, &3));
499 assert!(ordering_ge(&3, &3));
500 }
501 #[test]
502 fn test_option_cmp() {
503 let a: Option<u32> = None;
504 let b = Some(5u32);
505 assert_eq!(option_cmp(&a, &b), Ordering::Less);
506 assert_eq!(option_cmp(&b, &a), Ordering::Greater);
507 assert_eq!(option_cmp(&a, &a), Ordering::Equal);
508 assert_eq!(option_cmp(&Some(3u32), &Some(5u32)), Ordering::Less);
509 }
510 #[test]
511 fn test_result_cmp() {
512 let ok1: Result<u32, u32> = Ok(1);
513 let ok2: Result<u32, u32> = Ok(2);
514 let err1: Result<u32, u32> = Err(1);
515 assert_eq!(result_cmp(&err1, &ok1), Ordering::Less);
516 assert_eq!(result_cmp(&ok1, &ok2), Ordering::Less);
517 }
518 #[test]
519 fn test_ordering_then_with() {
520 let result = Ordering::Equal.then_with(|| Ordering::Greater);
521 assert_eq!(result, Ordering::Greater);
522 let result2 = Ordering::Less.then_with(|| Ordering::Greater);
523 assert_eq!(result2, Ordering::Less);
524 }
525 #[test]
526 fn test_ordering_builder_chained() {
527 let result = OrderingBuilder::new()
528 .field(&1u32, &1u32)
529 .field(&1u32, &1u32)
530 .field(&5u32, &10u32)
531 .build();
532 assert_eq!(result, Ordering::Less);
533 }
534 #[test]
535 fn test_sorted_by_key() {
536 let v = vec!["banana", "apple", "cherry"];
537 let sorted = sorted_by_key(&v, |s| s.len());
538 assert_eq!(sorted[0], "apple");
539 }
540}
541#[allow(dead_code)]
543pub fn ordering_max<T: std::cmp::Ord + Clone>(a: T, b: T) -> T {
544 if cmp(&a, &b).is_ge() {
545 a
546 } else {
547 b
548 }
549}
550#[allow(dead_code)]
552pub fn ordering_min<T: std::cmp::Ord + Clone>(a: T, b: T) -> T {
553 if cmp(&a, &b).is_le() {
554 a
555 } else {
556 b
557 }
558}
559#[cfg(test)]
560mod ordering_min_max_tests {
561 use super::*;
562 #[test]
563 fn test_ordering_max() {
564 assert_eq!(ordering_max(3u32, 5u32), 5);
565 }
566 #[test]
567 fn test_ordering_min() {
568 assert_eq!(ordering_min(3u32, 5u32), 3);
569 }
570}
571#[allow(dead_code)]
575pub fn kth_smallest<T: std::cmp::Ord + Clone>(v: &[T], k: usize) -> Option<T> {
576 if k >= v.len() {
577 return None;
578 }
579 let mut sorted = v.to_vec();
580 sorted.sort();
581 Some(sorted[k].clone())
582}
583#[allow(dead_code)]
585pub fn kth_largest<T: std::cmp::Ord + Clone>(v: &[T], k: usize) -> Option<T> {
586 if k >= v.len() {
587 return None;
588 }
589 let mut sorted = v.to_vec();
590 sorted.sort_by(|a, b| b.cmp(a));
591 Some(sorted[k].clone())
592}
593#[allow(dead_code)]
595pub fn top_n<T: std::cmp::Ord + Clone>(v: &[T], n: usize) -> Vec<T> {
596 let mut sorted = sorted_desc(v);
597 sorted.truncate(n);
598 sorted
599}
600#[allow(dead_code)]
602pub fn bottom_n<T: std::cmp::Ord + Clone>(v: &[T], n: usize) -> Vec<T> {
603 let mut s = sorted(v);
604 s.truncate(n);
605 s
606}
607#[allow(dead_code)]
609pub fn sorted_intersection<T: std::cmp::Ord + Clone>(a: &[T], b: &[T]) -> Vec<T> {
610 let mut result = Vec::new();
611 let (mut i, mut j) = (0, 0);
612 while i < a.len() && j < b.len() {
613 match a[i].cmp(&b[j]) {
614 std::cmp::Ordering::Equal => {
615 result.push(a[i].clone());
616 i += 1;
617 j += 1;
618 }
619 std::cmp::Ordering::Less => i += 1,
620 std::cmp::Ordering::Greater => j += 1,
621 }
622 }
623 result
624}
625#[allow(dead_code)]
627pub fn sorted_difference<T: std::cmp::Ord + Clone>(a: &[T], b: &[T]) -> Vec<T> {
628 let mut result = Vec::new();
629 let (mut i, mut j) = (0, 0);
630 while i < a.len() {
631 if j >= b.len() {
632 result.push(a[i].clone());
633 i += 1;
634 } else {
635 match a[i].cmp(&b[j]) {
636 std::cmp::Ordering::Equal => {
637 i += 1;
638 j += 1;
639 }
640 std::cmp::Ordering::Less => {
641 result.push(a[i].clone());
642 i += 1;
643 }
644 std::cmp::Ordering::Greater => j += 1,
645 }
646 }
647 }
648 result
649}
650#[allow(dead_code)]
652pub fn sorted_union<T: std::cmp::Ord + Clone>(a: &[T], b: &[T]) -> Vec<T> {
653 let mut merged = merge_sorted(a, b);
654 merged.dedup();
655 merged
656}
657#[cfg(test)]
658mod ordered_table_tests {
659 use super::*;
660 #[test]
661 fn test_ordered_table_insert_get() {
662 let mut t = OrderedTable::new();
663 t.insert("b", 2u32);
664 t.insert("a", 1u32);
665 t.insert("c", 3u32);
666 assert_eq!(t.get(&"a"), Some(&1));
667 assert_eq!(t.get(&"c"), Some(&3));
668 assert_eq!(t.get(&"d"), None);
669 assert_eq!(t.len(), 3);
670 }
671 #[test]
672 fn test_ordered_table_remove() {
673 let mut t = OrderedTable::new();
674 t.insert(1u32, "one");
675 t.insert(2u32, "two");
676 assert_eq!(t.remove(&1), Some("one"));
677 assert_eq!(t.len(), 1);
678 assert_eq!(t.remove(&99), None);
679 }
680 #[test]
681 fn test_ordered_table_keys_sorted() {
682 let mut t = OrderedTable::new();
683 t.insert(3u32, ());
684 t.insert(1u32, ());
685 t.insert(2u32, ());
686 let keys: Vec<_> = t.keys().into_iter().copied().collect();
687 assert_eq!(keys, vec![1, 2, 3]);
688 }
689 #[test]
690 fn test_kth_smallest() {
691 let v = vec![5, 3, 1, 4, 2];
692 assert_eq!(kth_smallest(&v, 0), Some(1));
693 assert_eq!(kth_smallest(&v, 2), Some(3));
694 assert_eq!(kth_smallest(&v, 10), None);
695 }
696 #[test]
697 fn test_kth_largest() {
698 let v = vec![5, 3, 1, 4, 2];
699 assert_eq!(kth_largest(&v, 0), Some(5));
700 assert_eq!(kth_largest(&v, 2), Some(3));
701 }
702 #[test]
703 fn test_top_n() {
704 let v = vec![3, 1, 4, 1, 5, 9, 2, 6];
705 assert_eq!(top_n(&v, 3), vec![9, 6, 5]);
706 }
707 #[test]
708 fn test_bottom_n() {
709 let v = vec![3, 1, 4, 1, 5, 9, 2, 6];
710 assert_eq!(bottom_n(&v, 3), vec![1, 1, 2]);
711 }
712 #[test]
713 fn test_sorted_intersection() {
714 let a = vec![1, 2, 3, 4, 5];
715 let b = vec![2, 4, 6];
716 assert_eq!(sorted_intersection(&a, &b), vec![2, 4]);
717 }
718 #[test]
719 fn test_sorted_difference() {
720 let a = vec![1, 2, 3, 4, 5];
721 let b = vec![2, 4];
722 assert_eq!(sorted_difference(&a, &b), vec![1, 3, 5]);
723 }
724 #[test]
725 fn test_sorted_union() {
726 let a = vec![1, 2, 3];
727 let b = vec![2, 3, 4];
728 assert_eq!(sorted_union(&a, &b), vec![1, 2, 3, 4]);
729 }
730 #[test]
731 fn test_ordered_table_contains_key() {
732 let mut t: OrderedTable<u32, &str> = OrderedTable::new();
733 t.insert(1, "one");
734 assert!(t.contains_key(&1));
735 assert!(!t.contains_key(&2));
736 }
737 #[test]
738 fn test_ordered_table_is_empty() {
739 let t: OrderedTable<u32, u32> = OrderedTable::new();
740 assert!(t.is_empty());
741 }
742 #[test]
743 fn test_ordered_table_values() {
744 let mut t = OrderedTable::new();
745 t.insert(1u32, "a");
746 t.insert(2u32, "b");
747 let vals = t.values();
748 assert_eq!(vals, vec![&"a", &"b"]);
749 }
750}
751pub fn ord_ext_arrow(a: Expr, b: Expr) -> Expr {
753 Expr::Pi(
754 BinderInfo::Default,
755 Name::Anonymous,
756 Box::new(a),
757 Box::new(b),
758 )
759}
760#[allow(dead_code)]
763pub fn axiom_wqo_carrier_ty() -> Expr {
764 ord_ext_arrow(
765 Expr::Const(Name::str("WQO"), vec![]),
766 Expr::Sort(Level::succ(Level::zero())),
767 )
768}
769#[allow(dead_code)]
772pub fn axiom_wqo_le_ty() -> Expr {
773 let wqo = Expr::Const(Name::str("WQO"), vec![]);
774 let carrier_w = Expr::App(
775 Box::new(Expr::Const(Name::str("WQO.carrier"), vec![])),
776 Box::new(Expr::BVar(0)),
777 );
778 Expr::Pi(
779 BinderInfo::Default,
780 Name::str("w"),
781 Box::new(wqo),
782 Box::new(Expr::Pi(
783 BinderInfo::Default,
784 Name::str("a"),
785 Box::new(carrier_w.clone()),
786 Box::new(Expr::Pi(
787 BinderInfo::Default,
788 Name::str("b"),
789 Box::new(carrier_w),
790 Box::new(Expr::Sort(Level::zero())),
791 )),
792 )),
793 )
794}
795#[allow(dead_code)]
798pub fn axiom_wqo_wf_ty() -> Expr {
799 ord_ext_arrow(
800 Expr::Const(Name::str("WQO"), vec![]),
801 Expr::Const(Name::str("WQO.goodPair"), vec![]),
802 )
803}
804#[allow(dead_code)]
807pub fn axiom_dickson_lemma_ty() -> Expr {
808 ord_ext_arrow(
809 Expr::Const(Name::str("WQO"), vec![]),
810 ord_ext_arrow(
811 Expr::Const(Name::str("WQO"), vec![]),
812 Expr::Const(Name::str("WQO"), vec![]),
813 ),
814 )
815}
816#[allow(dead_code)]
819pub fn axiom_dickson_nat_wqo_ty() -> Expr {
820 Expr::Const(Name::str("WQO"), vec![])
821}
822#[allow(dead_code)]
825pub fn axiom_higman_lemma_ty() -> Expr {
826 ord_ext_arrow(
827 Expr::Const(Name::str("WQO"), vec![]),
828 Expr::Const(Name::str("WQO"), vec![]),
829 )
830}
831#[allow(dead_code)]
834pub fn axiom_kruskal_tree_thm_ty() -> Expr {
835 ord_ext_arrow(
836 Expr::Const(Name::str("WQO"), vec![]),
837 Expr::Const(Name::str("WQO"), vec![]),
838 )
839}
840#[allow(dead_code)]
843pub fn axiom_ordinal_type_ty() -> Expr {
844 Expr::Sort(Level::succ(Level::succ(Level::zero())))
845}
846#[allow(dead_code)]
849pub fn axiom_ordinal_zero_ty() -> Expr {
850 Expr::Const(Name::str("Ordinal"), vec![])
851}
852#[allow(dead_code)]
855pub fn axiom_ordinal_succ_ty() -> Expr {
856 ord_ext_arrow(
857 Expr::Const(Name::str("Ordinal"), vec![]),
858 Expr::Const(Name::str("Ordinal"), vec![]),
859 )
860}
861#[allow(dead_code)]
864pub fn axiom_ordinal_add_ty() -> Expr {
865 ord_ext_arrow(
866 Expr::Const(Name::str("Ordinal"), vec![]),
867 ord_ext_arrow(
868 Expr::Const(Name::str("Ordinal"), vec![]),
869 Expr::Const(Name::str("Ordinal"), vec![]),
870 ),
871 )
872}
873#[allow(dead_code)]
876pub fn axiom_ordinal_mul_ty() -> Expr {
877 ord_ext_arrow(
878 Expr::Const(Name::str("Ordinal"), vec![]),
879 ord_ext_arrow(
880 Expr::Const(Name::str("Ordinal"), vec![]),
881 Expr::Const(Name::str("Ordinal"), vec![]),
882 ),
883 )
884}
885#[allow(dead_code)]
888pub fn axiom_ordinal_pow_ty() -> Expr {
889 ord_ext_arrow(
890 Expr::Const(Name::str("Ordinal"), vec![]),
891 ord_ext_arrow(
892 Expr::Const(Name::str("Ordinal"), vec![]),
893 Expr::Const(Name::str("Ordinal"), vec![]),
894 ),
895 )
896}
897#[allow(dead_code)]
900pub fn axiom_ordinal_omega_ty() -> Expr {
901 Expr::Const(Name::str("Ordinal"), vec![])
902}
903#[allow(dead_code)]
906pub fn axiom_ordinal_epsilon0_ty() -> Expr {
907 Expr::Const(Name::str("Ordinal"), vec![])
908}
909#[allow(dead_code)]
912pub fn axiom_ordinal_church_kleene_ty() -> Expr {
913 Expr::Const(Name::str("Ordinal"), vec![])
914}
915#[allow(dead_code)]
918pub fn axiom_ordinal_lt_ty() -> Expr {
919 ord_ext_arrow(
920 Expr::Const(Name::str("Ordinal"), vec![]),
921 ord_ext_arrow(
922 Expr::Const(Name::str("Ordinal"), vec![]),
923 Expr::Sort(Level::zero()),
924 ),
925 )
926}
927#[allow(dead_code)]
930pub fn axiom_ordinal_le_ty() -> Expr {
931 ord_ext_arrow(
932 Expr::Const(Name::str("Ordinal"), vec![]),
933 ord_ext_arrow(
934 Expr::Const(Name::str("Ordinal"), vec![]),
935 Expr::Sort(Level::zero()),
936 ),
937 )
938}
939#[allow(dead_code)]
942pub fn axiom_ordinal_is_limit_ty() -> Expr {
943 ord_ext_arrow(
944 Expr::Const(Name::str("Ordinal"), vec![]),
945 Expr::Sort(Level::zero()),
946 )
947}
948#[allow(dead_code)]
951pub fn axiom_ordinal_comparability_ty() -> Expr {
952 let ord = Expr::Const(Name::str("Ordinal"), vec![]);
953 Expr::Pi(
954 BinderInfo::Default,
955 Name::str("alpha"),
956 Box::new(ord.clone()),
957 Box::new(Expr::Pi(
958 BinderInfo::Default,
959 Name::str("beta"),
960 Box::new(ord),
961 Box::new(Expr::Const(Name::str("Ordinal.trichotomy"), vec![])),
962 )),
963 )
964}
965#[allow(dead_code)]
969pub fn axiom_suslin_problem_ty() -> Expr {
970 Expr::Sort(Level::zero())
971}
972#[allow(dead_code)]
975pub fn axiom_linear_order_ty() -> Expr {
976 ord_ext_arrow(
977 Expr::Sort(Level::succ(Level::zero())),
978 Expr::Sort(Level::succ(Level::succ(Level::zero()))),
979 )
980}
981#[allow(dead_code)]
984pub fn axiom_dense_linear_order_ty() -> Expr {
985 ord_ext_arrow(
986 Expr::Sort(Level::succ(Level::zero())),
987 Expr::Sort(Level::zero()),
988 )
989}
990#[allow(dead_code)]
993pub fn axiom_hausdorff_scattered_ty() -> Expr {
994 ord_ext_arrow(
995 Expr::Sort(Level::succ(Level::zero())),
996 Expr::Sort(Level::zero()),
997 )
998}
999#[allow(dead_code)]
1002pub fn axiom_hausdorff_theorem_ty() -> Expr {
1003 ord_ext_arrow(
1004 Expr::Const(Name::str("LinearOrder"), vec![]),
1005 Expr::Sort(Level::zero()),
1006 )
1007}
1008#[allow(dead_code)]
1011pub fn axiom_ramsey_order_thm_ty() -> Expr {
1012 ord_ext_arrow(
1013 Expr::Const(Name::str("Nat"), vec![]),
1014 ord_ext_arrow(
1015 Expr::Const(Name::str("Nat"), vec![]),
1016 Expr::Sort(Level::zero()),
1017 ),
1018 )
1019}
1020#[allow(dead_code)]
1024pub fn axiom_rationals_universal_linear_order_ty() -> Expr {
1025 Expr::Sort(Level::zero())
1026}
1027#[allow(dead_code)]
1030pub fn axiom_dedekind_cut_ty() -> Expr {
1031 ord_ext_arrow(
1032 Expr::Sort(Level::succ(Level::zero())),
1033 Expr::Sort(Level::succ(Level::zero())),
1034 )
1035}
1036#[allow(dead_code)]
1039pub fn axiom_dedekind_completeness_ty() -> Expr {
1040 Expr::Pi(
1041 BinderInfo::Default,
1042 Name::str("F"),
1043 Box::new(Expr::Sort(Level::succ(Level::zero()))),
1044 Box::new(ord_ext_arrow(
1045 Expr::App(
1046 Box::new(Expr::Const(Name::str("DedekindCut"), vec![])),
1047 Box::new(Expr::BVar(0)),
1048 ),
1049 Expr::BVar(1),
1050 )),
1051 )
1052}
1053#[allow(dead_code)]
1057pub fn axiom_cantor_back_and_forth_ty() -> Expr {
1058 Expr::Sort(Level::zero())
1059}
1060#[allow(dead_code)]
1063pub fn axiom_fraisse_limit_ty() -> Expr {
1064 ord_ext_arrow(
1065 Expr::Const(Name::str("StructureClass"), vec![]),
1066 Expr::Const(Name::str("Structure"), vec![]),
1067 )
1068}
1069#[allow(dead_code)]
1072pub fn axiom_ordered_field_ty() -> Expr {
1073 ord_ext_arrow(
1074 Expr::Sort(Level::succ(Level::zero())),
1075 Expr::Sort(Level::zero()),
1076 )
1077}
1078#[allow(dead_code)]
1082pub fn axiom_ordered_field_archimedean_ty() -> Expr {
1083 Expr::Pi(
1084 BinderInfo::Default,
1085 Name::str("F"),
1086 Box::new(Expr::Sort(Level::succ(Level::zero()))),
1087 Box::new(ord_ext_arrow(
1088 Expr::App(
1089 Box::new(Expr::Const(Name::str("OrderedField"), vec![])),
1090 Box::new(Expr::BVar(0)),
1091 ),
1092 Expr::Sort(Level::zero()),
1093 )),
1094 )
1095}
1096#[allow(dead_code)]
1099pub fn axiom_well_order_induction_ty() -> Expr {
1100 ord_ext_arrow(
1101 Expr::Const(Name::str("WellOrder"), vec![]),
1102 Expr::Const(Name::str("WellOrder.inductionPrinciple"), vec![]),
1103 )
1104}
1105#[allow(dead_code)]
1108pub fn axiom_well_order_isomorphism_ty() -> Expr {
1109 ord_ext_arrow(
1110 Expr::Const(Name::str("WellOrder"), vec![]),
1111 ord_ext_arrow(
1112 Expr::Const(Name::str("WellOrder"), vec![]),
1113 Expr::Sort(Level::zero()),
1114 ),
1115 )
1116}
1117#[allow(dead_code)]
1120pub fn axiom_ordinal_sup_ty() -> Expr {
1121 ord_ext_arrow(
1122 ord_ext_arrow(
1123 Expr::Const(Name::str("Nat"), vec![]),
1124 Expr::Const(Name::str("Ordinal"), vec![]),
1125 ),
1126 Expr::Const(Name::str("Ordinal"), vec![]),
1127 )
1128}
1129#[allow(dead_code)]
1132pub fn axiom_ordinal_cnf_ty() -> Expr {
1133 ord_ext_arrow(
1134 Expr::Const(Name::str("Ordinal"), vec![]),
1135 Expr::App(
1136 Box::new(Expr::Const(Name::str("List"), vec![])),
1137 Box::new(Expr::App(
1138 Box::new(Expr::App(
1139 Box::new(Expr::Const(Name::str("Prod"), vec![])),
1140 Box::new(Expr::Const(Name::str("Ordinal"), vec![])),
1141 )),
1142 Box::new(Expr::Const(Name::str("Nat"), vec![])),
1143 )),
1144 ),
1145 )
1146}
1147#[allow(dead_code)]
1150pub fn axiom_partial_order_antisymmetry_ty() -> Expr {
1151 Expr::Pi(
1152 BinderInfo::Implicit,
1153 Name::str("alpha"),
1154 Box::new(Expr::Sort(Level::succ(Level::zero()))),
1155 Box::new(Expr::Const(
1156 Name::str("PartialOrder.antisymmetryStatement"),
1157 vec![],
1158 )),
1159 )
1160}
1161#[allow(dead_code)]
1164pub fn axiom_total_order_linear_extension_ty() -> Expr {
1165 ord_ext_arrow(
1166 Expr::Const(Name::str("PartialOrder"), vec![]),
1167 Expr::Const(Name::str("TotalOrder"), vec![]),
1168 )
1169}
1170#[allow(dead_code)]
1172pub fn register_ordering_extended(env: &mut Environment) -> Result<(), String> {
1173 let type2 = Expr::Sort(Level::succ(Level::succ(Level::zero())));
1174 let type1 = Expr::Sort(Level::succ(Level::zero()));
1175 let prop = Expr::Sort(Level::zero());
1176 let prereqs: &[(&str, Expr)] = &[
1177 ("WQO", type1.clone()),
1178 ("Ordinal", type1.clone()),
1179 ("LinearOrder", type2.clone()),
1180 ("PartialOrder", type1.clone()),
1181 ("TotalOrder", type1.clone()),
1182 ("WellOrder", type1.clone()),
1183 ("StructureClass", type1.clone()),
1184 ("Structure", type1.clone()),
1185 ("Nat", type1.clone()),
1186 ("List", ord_ext_arrow(type1.clone(), type1.clone())),
1187 (
1188 "Prod",
1189 ord_ext_arrow(type1.clone(), ord_ext_arrow(type1.clone(), type1.clone())),
1190 ),
1191 ("WQO.goodPair", prop.clone()),
1192 ("Ordinal.trichotomy", prop.clone()),
1193 ("WellOrder.inductionPrinciple", prop.clone()),
1194 ("PartialOrder.antisymmetryStatement", prop.clone()),
1195 (
1196 "WQO.carrier",
1197 ord_ext_arrow(Expr::Const(Name::str("WQO"), vec![]), type1.clone()),
1198 ),
1199 ];
1200 for (name, ty) in prereqs {
1201 if !env.contains(&Name::str(*name)) {
1202 env.add(Declaration::Axiom {
1203 name: Name::str(*name),
1204 univ_params: vec![],
1205 ty: ty.clone(),
1206 })
1207 .map_err(|e| e.to_string())?;
1208 }
1209 }
1210 let axioms: &[(&str, Expr)] = &[
1211 ("WQO.le", axiom_wqo_le_ty()),
1212 ("WQO.wf", axiom_wqo_wf_ty()),
1213 ("Dickson.lemma", axiom_dickson_lemma_ty()),
1214 ("Dickson.nat_wqo", axiom_dickson_nat_wqo_ty()),
1215 ("Higman.lemma", axiom_higman_lemma_ty()),
1216 ("Kruskal.treeThm", axiom_kruskal_tree_thm_ty()),
1217 ("Ordinal.zero", axiom_ordinal_zero_ty()),
1218 ("Ordinal.succ", axiom_ordinal_succ_ty()),
1219 ("Ordinal.add", axiom_ordinal_add_ty()),
1220 ("Ordinal.mul", axiom_ordinal_mul_ty()),
1221 ("Ordinal.pow", axiom_ordinal_pow_ty()),
1222 ("Ordinal.omega", axiom_ordinal_omega_ty()),
1223 ("Ordinal.epsilon0", axiom_ordinal_epsilon0_ty()),
1224 ("Ordinal.churchKleene", axiom_ordinal_church_kleene_ty()),
1225 ("Ordinal.lt", axiom_ordinal_lt_ty()),
1226 ("Ordinal.le", axiom_ordinal_le_ty()),
1227 ("Ordinal.isLimit", axiom_ordinal_is_limit_ty()),
1228 ("Ordinal.comparability", axiom_ordinal_comparability_ty()),
1229 ("Suslin.problem", axiom_suslin_problem_ty()),
1230 ("DenseLinearOrder", axiom_dense_linear_order_ty()),
1231 ("Hausdorff.scatteredOrder", axiom_hausdorff_scattered_ty()),
1232 ("Hausdorff.theorem", axiom_hausdorff_theorem_ty()),
1233 ("Ramsey.orderThm", axiom_ramsey_order_thm_ty()),
1234 (
1235 "Rationals.universalLinearOrder",
1236 axiom_rationals_universal_linear_order_ty(),
1237 ),
1238 ("DedekindCut", axiom_dedekind_cut_ty()),
1239 ("DedekindCut.completeness", axiom_dedekind_completeness_ty()),
1240 ("Cantor.backAndForth", axiom_cantor_back_and_forth_ty()),
1241 ("Fraisse.limit", axiom_fraisse_limit_ty()),
1242 ("OrderedField", axiom_ordered_field_ty()),
1243 (
1244 "OrderedField.archimedean",
1245 axiom_ordered_field_archimedean_ty(),
1246 ),
1247 ("WellOrder.induction", axiom_well_order_induction_ty()),
1248 ("WellOrder.isomorphism", axiom_well_order_isomorphism_ty()),
1249 ("Ordinal.sup", axiom_ordinal_sup_ty()),
1250 ("Ordinal.cnfNF", axiom_ordinal_cnf_ty()),
1251 (
1252 "PartialOrder.antisymmetry",
1253 axiom_partial_order_antisymmetry_ty(),
1254 ),
1255 (
1256 "TotalOrder.linearExtension",
1257 axiom_total_order_linear_extension_ty(),
1258 ),
1259 ];
1260 for (name, ty) in axioms {
1261 env.add(Declaration::Axiom {
1262 name: Name::str(*name),
1263 univ_params: vec![],
1264 ty: ty.clone(),
1265 })
1266 .map_err(|e| e.to_string())?;
1267 }
1268 Ok(())
1269}
1270#[cfg(test)]
1271mod extended_ordering_tests {
1272 use super::*;
1273 #[test]
1274 fn test_wqo_instance_reflexive() {
1275 let w = WqoInstance::new(vec![0, 1, 2], |a, b| a <= b);
1276 assert!(w.is_reflexive());
1277 }
1278 #[test]
1279 fn test_wqo_instance_transitive() {
1280 let w = WqoInstance::new(vec![0, 1, 2], |a, b| a <= b);
1281 assert!(w.is_transitive());
1282 }
1283 #[test]
1284 fn test_wqo_good_pair() {
1285 let w = WqoInstance::new(vec![0, 1, 2], |a, b| a <= b);
1286 let seq = vec![2usize, 0, 1];
1287 assert!(w.has_good_pair(&seq));
1288 }
1289 #[test]
1290 fn test_wqo_find_good_pair() {
1291 let w = WqoInstance::new(vec![0, 1, 2], |a, b| a <= b);
1292 let seq = vec![0usize, 1, 2];
1293 let pair = w.find_good_pair(&seq);
1294 assert!(pair.is_some());
1295 }
1296 #[test]
1297 fn test_ordinal_cnf_zero() {
1298 let z = OrdinalCnf::zero();
1299 assert!(z.is_zero());
1300 assert!(z.is_finite());
1301 assert_eq!(z.as_finite(), Some(0));
1302 }
1303 #[test]
1304 fn test_ordinal_cnf_finite() {
1305 let three = OrdinalCnf::finite(3);
1306 assert!(!three.is_zero());
1307 assert!(three.is_finite());
1308 assert_eq!(three.as_finite(), Some(3));
1309 }
1310 #[test]
1311 fn test_ordinal_cnf_omega() {
1312 let w = OrdinalCnf::omega();
1313 assert!(!w.is_finite());
1314 assert!(!w.is_zero());
1315 }
1316 #[test]
1317 fn test_ordinal_cnf_add() {
1318 let a = OrdinalCnf::finite(2);
1319 let b = OrdinalCnf::finite(3);
1320 let sum = a.add(&b);
1321 assert_eq!(sum.as_finite(), Some(3));
1322 }
1323 #[test]
1324 fn test_ordinal_cnf_cmp() {
1325 let a = OrdinalCnf::finite(1);
1326 let b = OrdinalCnf::omega();
1327 assert_eq!(a.ord_cmp(&b), Ordering::Less);
1328 assert_eq!(b.ord_cmp(&a), Ordering::Greater);
1329 assert_eq!(a.ord_cmp(&a), Ordering::Equal);
1330 }
1331 #[test]
1332 fn test_dedekind_cut_in_lower_upper() {
1333 let cut = DedekindCutQ::new(1, 2);
1334 assert!(cut.in_lower(0, 1));
1335 assert!(cut.in_upper(1, 1));
1336 assert!(!cut.in_lower(1, 1));
1337 }
1338 #[test]
1339 fn test_dedekind_cut_cmp() {
1340 let a = DedekindCutQ::new(1, 3);
1341 let b = DedekindCutQ::new(1, 2);
1342 assert_eq!(a.cut_cmp(&b), Ordering::Less);
1343 assert_eq!(b.cut_cmp(&a), Ordering::Greater);
1344 assert_eq!(a.cut_cmp(&a), Ordering::Equal);
1345 }
1346 #[test]
1347 fn test_dedekind_mediant() {
1348 let a = DedekindCutQ::new(1, 3);
1349 let b = DedekindCutQ::new(1, 2);
1350 let m = a.mediant(&b);
1351 assert_eq!(m.numerator, 2);
1352 assert_eq!(m.denominator, 5);
1353 }
1354 #[test]
1355 fn test_finite_linear_order_identity() {
1356 let o = FiniteLinearOrder::identity(4);
1357 assert_eq!(o.size, 4);
1358 assert_eq!(o.rank(0), Some(0));
1359 assert_eq!(o.rank(3), Some(3));
1360 assert_eq!(o.min_elem(), Some(0));
1361 assert_eq!(o.max_elem(), Some(3));
1362 }
1363 #[test]
1364 fn test_finite_linear_order_compare() {
1365 let o = FiniteLinearOrder::identity(3);
1366 assert_eq!(o.compare(0, 1), Ordering::Less);
1367 assert_eq!(o.compare(2, 1), Ordering::Greater);
1368 assert_eq!(o.compare(1, 1), Ordering::Equal);
1369 }
1370 #[test]
1371 fn test_finite_linear_order_reverse() {
1372 let o = FiniteLinearOrder::identity(3);
1373 let r = o.reverse_order();
1374 assert_eq!(r.order, vec![2, 1, 0]);
1375 assert_eq!(r.min_elem(), Some(2));
1376 }
1377 #[test]
1378 fn test_finite_partial_order_discrete() {
1379 let p = FinitePartialOrder::discrete(3);
1380 assert!(p.is_valid());
1381 assert!(!p.is_total());
1382 }
1383 #[test]
1384 fn test_finite_partial_order_chain() {
1385 let mut le = vec![vec![false; 3]; 3];
1386 for i in 0..3usize {
1387 for j in i..3usize {
1388 le[i][j] = true;
1389 }
1390 }
1391 let p = FinitePartialOrder { size: 3, le };
1392 assert!(p.is_valid());
1393 assert!(p.is_total());
1394 assert_eq!(p.maximal_elements(), vec![2]);
1395 }
1396 #[test]
1397 fn test_transitive_closure() {
1398 let mut le = vec![vec![false; 3]; 3];
1399 le[0][0] = true;
1400 le[1][1] = true;
1401 le[2][2] = true;
1402 le[0][1] = true;
1403 le[1][2] = true;
1404 let p = FinitePartialOrder { size: 3, le };
1405 let cl = p.transitive_closure();
1406 assert!(cl.le[0][2]);
1407 }
1408 #[test]
1409 fn test_axiom_wqo_carrier_ty() {
1410 let ty = axiom_wqo_carrier_ty();
1411 assert!(matches!(ty, Expr::Pi(_, _, _, _)));
1412 }
1413 #[test]
1414 fn test_axiom_ordinal_zero_ty() {
1415 let ty = axiom_ordinal_zero_ty();
1416 assert_eq!(ty, Expr::Const(Name::str("Ordinal"), vec![]));
1417 }
1418 #[test]
1419 fn test_axiom_ordinal_add_ty() {
1420 let ty = axiom_ordinal_add_ty();
1421 assert!(matches!(ty, Expr::Pi(_, _, _, _)));
1422 }
1423 #[test]
1424 fn test_register_ordering_extended() {
1425 let mut env = Environment::new();
1426 assert!(register_ordering_extended(&mut env).is_ok());
1427 assert!(env.contains(&Name::str("Ordinal.zero")));
1428 assert!(env.contains(&Name::str("Ordinal.omega")));
1429 assert!(env.contains(&Name::str("Dickson.lemma")));
1430 assert!(env.contains(&Name::str("Higman.lemma")));
1431 assert!(env.contains(&Name::str("Kruskal.treeThm")));
1432 assert!(env.contains(&Name::str("Cantor.backAndForth")));
1433 }
1434}
1435#[allow(dead_code)]
1438pub fn axiom_bounded_lattice_ty() -> Expr {
1439 ord_ext_arrow(
1440 Expr::Sort(Level::succ(Level::zero())),
1441 Expr::Sort(Level::succ(Level::succ(Level::zero()))),
1442 )
1443}
1444#[allow(dead_code)]
1447pub fn axiom_complete_lattice_sup_ty() -> Expr {
1448 Expr::Pi(
1449 BinderInfo::Implicit,
1450 Name::str("L"),
1451 Box::new(Expr::Sort(Level::succ(Level::zero()))),
1452 Box::new(ord_ext_arrow(
1453 ord_ext_arrow(Expr::BVar(0), Expr::Sort(Level::zero())),
1454 Expr::BVar(1),
1455 )),
1456 )
1457}
1458#[allow(dead_code)]
1461pub fn axiom_galois_connection_ty() -> Expr {
1462 Expr::Pi(
1463 BinderInfo::Default,
1464 Name::str("P"),
1465 Box::new(Expr::Sort(Level::succ(Level::zero()))),
1466 Box::new(Expr::Pi(
1467 BinderInfo::Default,
1468 Name::str("Q"),
1469 Box::new(Expr::Sort(Level::succ(Level::zero()))),
1470 Box::new(ord_ext_arrow(
1471 ord_ext_arrow(Expr::BVar(1), Expr::BVar(0)),
1472 ord_ext_arrow(
1473 ord_ext_arrow(Expr::BVar(1), Expr::BVar(2)),
1474 Expr::Sort(Level::zero()),
1475 ),
1476 )),
1477 )),
1478 )
1479}
1480#[allow(dead_code)]
1483pub fn axiom_antichain_maximal_ty() -> Expr {
1484 ord_ext_arrow(
1485 Expr::Const(Name::str("PartialOrder"), vec![]),
1486 Expr::Sort(Level::succ(Level::zero())),
1487 )
1488}
1489#[allow(dead_code)]
1493pub fn axiom_dilworth_theorem_ty() -> Expr {
1494 ord_ext_arrow(
1495 Expr::Const(Name::str("PartialOrder"), vec![]),
1496 Expr::Sort(Level::zero()),
1497 )
1498}
1499#[allow(dead_code)]
1503pub fn axiom_mirsky_theorem_ty() -> Expr {
1504 ord_ext_arrow(
1505 Expr::Const(Name::str("PartialOrder"), vec![]),
1506 Expr::Sort(Level::zero()),
1507 )
1508}
1509#[allow(dead_code)]
1512pub fn axiom_order_iso_ty() -> Expr {
1513 Expr::Pi(
1514 BinderInfo::Default,
1515 Name::str("A"),
1516 Box::new(Expr::Sort(Level::succ(Level::zero()))),
1517 Box::new(Expr::Pi(
1518 BinderInfo::Default,
1519 Name::str("B"),
1520 Box::new(Expr::Sort(Level::succ(Level::zero()))),
1521 Box::new(Expr::Sort(Level::succ(Level::succ(Level::zero())))),
1522 )),
1523 )
1524}
1525#[allow(dead_code)]
1528pub fn axiom_order_embedding_ty() -> Expr {
1529 Expr::Pi(
1530 BinderInfo::Default,
1531 Name::str("A"),
1532 Box::new(Expr::Sort(Level::succ(Level::zero()))),
1533 Box::new(Expr::Pi(
1534 BinderInfo::Default,
1535 Name::str("B"),
1536 Box::new(Expr::Sort(Level::succ(Level::zero()))),
1537 Box::new(Expr::Sort(Level::succ(Level::succ(Level::zero())))),
1538 )),
1539 )
1540}
1541#[allow(dead_code)]
1545pub fn axiom_cofinal_subset_ty() -> Expr {
1546 Expr::Pi(
1547 BinderInfo::Implicit,
1548 Name::str("P"),
1549 Box::new(Expr::Sort(Level::succ(Level::zero()))),
1550 Box::new(ord_ext_arrow(
1551 ord_ext_arrow(Expr::BVar(0), Expr::Sort(Level::zero())),
1552 Expr::Sort(Level::zero()),
1553 )),
1554 )
1555}
1556#[allow(dead_code)]
1559pub fn axiom_cofinality_ordinal_ty() -> Expr {
1560 ord_ext_arrow(
1561 Expr::Const(Name::str("Ordinal"), vec![]),
1562 Expr::Const(Name::str("Ordinal"), vec![]),
1563 )
1564}
1565#[allow(dead_code)]
1568pub fn axiom_regular_cardinal_ty() -> Expr {
1569 ord_ext_arrow(
1570 Expr::Const(Name::str("Ordinal"), vec![]),
1571 Expr::Sort(Level::zero()),
1572 )
1573}
1574#[cfg(test)]
1575mod ordered_range_tests {
1576 use super::*;
1577 #[test]
1578 fn test_ordered_range_contains() {
1579 let r = OrderedRange::new(1u32, 10u32);
1580 assert!(r.contains(&5));
1581 assert!(r.contains(&1));
1582 assert!(r.contains(&10));
1583 assert!(!r.contains(&0));
1584 assert!(!r.contains(&11));
1585 }
1586 #[test]
1587 fn test_ordered_range_contains_range() {
1588 let outer = OrderedRange::new(0u32, 100u32);
1589 let inner = OrderedRange::new(10u32, 50u32);
1590 assert!(outer.contains_range(&inner));
1591 assert!(!inner.contains_range(&outer));
1592 }
1593 #[test]
1594 fn test_ordered_range_overlaps() {
1595 let r1 = OrderedRange::new(1u32, 5u32);
1596 let r2 = OrderedRange::new(4u32, 8u32);
1597 let r3 = OrderedRange::new(6u32, 10u32);
1598 assert!(r1.overlaps(&r2));
1599 assert!(!r1.overlaps(&r3));
1600 }
1601 #[test]
1602 fn test_axiom_dilworth_theorem_ty() {
1603 let ty = axiom_dilworth_theorem_ty();
1604 assert!(matches!(ty, Expr::Pi(_, _, _, _)));
1605 }
1606 #[test]
1607 fn test_axiom_galois_connection_ty() {
1608 let ty = axiom_galois_connection_ty();
1609 assert!(matches!(ty, Expr::Pi(_, _, _, _)));
1610 }
1611 #[test]
1612 fn test_axiom_cofinality_ordinal_ty() {
1613 let ty = axiom_cofinality_ordinal_ty();
1614 assert!(matches!(ty, Expr::Pi(_, _, _, _)));
1615 }
1616 #[test]
1617 fn test_axiom_order_iso_ty() {
1618 let ty = axiom_order_iso_ty();
1619 assert!(matches!(ty, Expr::Pi(_, _, _, _)));
1620 }
1621 #[test]
1622 fn test_axiom_bounded_lattice_ty() {
1623 let ty = axiom_bounded_lattice_ty();
1624 assert!(matches!(ty, Expr::Pi(_, _, _, _)));
1625 }
1626 #[test]
1627 fn test_axiom_complete_lattice_sup_ty() {
1628 let ty = axiom_complete_lattice_sup_ty();
1629 assert!(matches!(ty, Expr::Pi(_, _, _, _)));
1630 }
1631 #[test]
1632 fn test_axiom_antichain_maximal_ty() {
1633 let ty = axiom_antichain_maximal_ty();
1634 assert!(matches!(ty, Expr::Pi(_, _, _, _)));
1635 }
1636 #[test]
1637 fn test_axiom_mirsky_theorem_ty() {
1638 let ty = axiom_mirsky_theorem_ty();
1639 assert!(matches!(ty, Expr::Pi(_, _, _, _)));
1640 }
1641 #[test]
1642 fn test_axiom_cofinal_subset_ty() {
1643 let ty = axiom_cofinal_subset_ty();
1644 assert!(matches!(ty, Expr::Pi(_, _, _, _)));
1645 }
1646 #[test]
1647 fn test_axiom_regular_cardinal_ty() {
1648 let ty = axiom_regular_cardinal_ty();
1649 assert!(matches!(ty, Expr::Pi(_, _, _, _)));
1650 }
1651 #[test]
1652 fn test_axiom_order_embedding_ty() {
1653 let ty = axiom_order_embedding_ty();
1654 assert!(matches!(ty, Expr::Pi(_, _, _, _)));
1655 }
1656}