1use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
6
7use super::types::{OrdResult, Permutation, SortedMap, SortedSet};
8
9pub fn build_ord_env(env: &mut Environment) -> Result<(), String> {
11 let type1 = Expr::Sort(Level::succ(Level::zero()));
12 let type2 = Expr::Sort(Level::succ(Level::succ(Level::zero())));
13 let ordering_ty = type1.clone();
14 env.add(Declaration::Axiom {
15 name: Name::str("Ordering"),
16 univ_params: vec![],
17 ty: ordering_ty,
18 })
19 .map_err(|e| e.to_string())?;
20 for variant in &["Ordering.lt", "Ordering.eq", "Ordering.gt"] {
21 env.add(Declaration::Axiom {
22 name: Name::str(*variant),
23 univ_params: vec![],
24 ty: Expr::Const(Name::str("Ordering"), vec![]),
25 })
26 .map_err(|e| e.to_string())?;
27 }
28 let ord_ty = Expr::Pi(
29 BinderInfo::Default,
30 Name::str("α"),
31 Box::new(type1.clone()),
32 Box::new(type2.clone()),
33 );
34 env.add(Declaration::Axiom {
35 name: Name::str("Ord"),
36 univ_params: vec![],
37 ty: ord_ty,
38 })
39 .map_err(|e| e.to_string())?;
40 let compare_ty = Expr::Pi(
41 BinderInfo::Implicit,
42 Name::str("α"),
43 Box::new(type1.clone()),
44 Box::new(Expr::Pi(
45 BinderInfo::InstImplicit,
46 Name::str("_"),
47 Box::new(Expr::App(
48 Box::new(Expr::Const(Name::str("Ord"), vec![])),
49 Box::new(Expr::BVar(0)),
50 )),
51 Box::new(Expr::Pi(
52 BinderInfo::Default,
53 Name::str("a"),
54 Box::new(Expr::BVar(1)),
55 Box::new(Expr::Pi(
56 BinderInfo::Default,
57 Name::str("b"),
58 Box::new(Expr::BVar(2)),
59 Box::new(Expr::Const(Name::str("Ordering"), vec![])),
60 )),
61 )),
62 )),
63 );
64 env.add(Declaration::Axiom {
65 name: Name::str("Ord.compare"),
66 univ_params: vec![],
67 ty: compare_ty,
68 })
69 .map_err(|e| e.to_string())?;
70 add_ordering_predicate(env, "Ordering.isLT")?;
71 add_ordering_predicate(env, "Ordering.isEQ")?;
72 add_ordering_predicate(env, "Ordering.isGT")?;
73 add_ordering_predicate(env, "Ordering.isLE")?;
74 add_ordering_predicate(env, "Ordering.isGE")?;
75 let swap_ty = Expr::Pi(
76 BinderInfo::Default,
77 Name::str("o"),
78 Box::new(Expr::Const(Name::str("Ordering"), vec![])),
79 Box::new(Expr::Const(Name::str("Ordering"), vec![])),
80 );
81 env.add(Declaration::Axiom {
82 name: Name::str("Ordering.swap"),
83 univ_params: vec![],
84 ty: swap_ty,
85 })
86 .map_err(|e| e.to_string())?;
87 let then_ty = Expr::Pi(
88 BinderInfo::Default,
89 Name::str("o1"),
90 Box::new(Expr::Const(Name::str("Ordering"), vec![])),
91 Box::new(Expr::Pi(
92 BinderInfo::Default,
93 Name::str("o2"),
94 Box::new(Expr::Const(Name::str("Ordering"), vec![])),
95 Box::new(Expr::Const(Name::str("Ordering"), vec![])),
96 )),
97 );
98 env.add(Declaration::Axiom {
99 name: Name::str("Ordering.then"),
100 univ_params: vec![],
101 ty: then_ty,
102 })
103 .map_err(|e| e.to_string())?;
104 Ok(())
105}
106pub fn add_ordering_predicate(env: &mut Environment, name: &str) -> Result<(), String> {
108 let ty = Expr::Pi(
109 BinderInfo::Default,
110 Name::str("o"),
111 Box::new(Expr::Const(Name::str("Ordering"), vec![])),
112 Box::new(Expr::Const(Name::str("Bool"), vec![])),
113 );
114 env.add(Declaration::Axiom {
115 name: Name::str(name),
116 univ_params: vec![],
117 ty,
118 })
119 .map_err(|e| e.to_string())
120}
121pub fn compare<T: Ord>(a: &T, b: &T) -> OrdResult {
123 OrdResult::from_std(a.cmp(b))
124}
125pub fn compare_by_key<T, K: Ord, F: Fn(&T) -> K>(a: &T, b: &T, key: F) -> OrdResult {
127 OrdResult::from_std(key(a).cmp(&key(b)))
128}
129pub fn compare_slices<T: Ord>(a: &[T], b: &[T]) -> OrdResult {
131 OrdResult::from_std(a.cmp(b))
132}
133pub fn ord_min<T: Ord>(a: T, b: T) -> T {
135 if a <= b {
136 a
137 } else {
138 b
139 }
140}
141pub fn ord_max<T: Ord>(a: T, b: T) -> T {
143 if a >= b {
144 a
145 } else {
146 b
147 }
148}
149pub fn ord_clamp<T: Ord>(val: T, lo: T, hi: T) -> T {
151 if val < lo {
152 lo
153 } else if val > hi {
154 hi
155 } else {
156 val
157 }
158}
159pub fn sort_by<T, F>(v: &mut [T], mut cmp: F)
161where
162 F: FnMut(&T, &T) -> OrdResult,
163{
164 v.sort_by(|a, b| cmp(a, b).to_std());
165}
166pub fn is_sorted<T: Ord>(s: &[T]) -> bool {
168 s.windows(2).all(|w| w[0] <= w[1])
169}
170pub fn is_sorted_desc<T: Ord>(s: &[T]) -> bool {
172 s.windows(2).all(|w| w[0] >= w[1])
173}
174pub fn ord_binary_search<T: Ord>(s: &[T], target: &T) -> Result<usize, usize> {
178 s.binary_search(target)
179}
180pub fn compare_chain(comparisons: &[OrdResult]) -> OrdResult {
184 comparisons
185 .iter()
186 .copied()
187 .fold(OrdResult::Equal, OrdResult::then)
188}
189pub fn reverse_cmp<T, F>(a: &T, b: &T, cmp: F) -> OrdResult
191where
192 F: Fn(&T, &T) -> OrdResult,
193{
194 cmp(a, b).swap()
195}
196pub fn lt<T: Ord>(a: &T, b: &T) -> bool {
198 a < b
199}
200pub fn le<T: Ord>(a: &T, b: &T) -> bool {
202 a <= b
203}
204pub fn gt<T: Ord>(a: &T, b: &T) -> bool {
206 a > b
207}
208pub fn ge<T: Ord>(a: &T, b: &T) -> bool {
210 a >= b
211}
212pub fn eq<T: Ord>(a: &T, b: &T) -> bool {
214 a == b
215}
216pub fn ne<T: Ord>(a: &T, b: &T) -> bool {
218 a != b
219}
220#[cfg(test)]
221mod tests {
222 use super::*;
223 #[test]
224 fn test_build_ord_env() {
225 let mut env = Environment::new();
226 assert!(build_ord_env(&mut env).is_ok());
227 assert!(env.get(&Name::str("Ordering")).is_some());
228 assert!(env.get(&Name::str("Ord")).is_some());
229 assert!(env.get(&Name::str("Ord.compare")).is_some());
230 }
231 #[test]
232 fn test_ord_result_swap() {
233 assert_eq!(OrdResult::Less.swap(), OrdResult::Greater);
234 assert_eq!(OrdResult::Greater.swap(), OrdResult::Less);
235 assert_eq!(OrdResult::Equal.swap(), OrdResult::Equal);
236 }
237 #[test]
238 fn test_ord_result_then() {
239 assert_eq!(OrdResult::Equal.then(OrdResult::Less), OrdResult::Less);
240 assert_eq!(OrdResult::Less.then(OrdResult::Greater), OrdResult::Less);
241 }
242 #[test]
243 fn test_ord_result_predicates() {
244 let lt = OrdResult::Less;
245 let eq = OrdResult::Equal;
246 let gt = OrdResult::Greater;
247 assert!(lt.is_lt() && lt.is_le() && !lt.is_eq() && !lt.is_gt() && !lt.is_ge());
248 assert!(eq.is_eq() && eq.is_le() && eq.is_ge() && !eq.is_lt() && !eq.is_gt());
249 assert!(gt.is_gt() && gt.is_ge() && !gt.is_lt() && !gt.is_eq() && !gt.is_le());
250 }
251 #[test]
252 fn test_compare() {
253 assert_eq!(compare(&1, &2), OrdResult::Less);
254 assert_eq!(compare(&2, &2), OrdResult::Equal);
255 assert_eq!(compare(&3, &2), OrdResult::Greater);
256 }
257 #[test]
258 fn test_compare_chain() {
259 let chain = compare_chain(&[OrdResult::Equal, OrdResult::Equal, OrdResult::Less]);
260 assert_eq!(chain, OrdResult::Less);
261 let all_eq = compare_chain(&[OrdResult::Equal, OrdResult::Equal]);
262 assert_eq!(all_eq, OrdResult::Equal);
263 }
264 #[test]
265 fn test_sort_by() {
266 let mut v = vec![3, 1, 4, 1, 5, 9, 2, 6];
267 sort_by(&mut v, |a, b| compare(a, b));
268 assert!(is_sorted(&v));
269 }
270 #[test]
271 fn test_is_sorted() {
272 assert!(is_sorted(&[1, 2, 3, 4]));
273 assert!(!is_sorted(&[1, 3, 2]));
274 assert!(is_sorted_desc(&[4, 3, 2, 1]));
275 assert!(!is_sorted_desc(&[1, 2, 3]));
276 }
277 #[test]
278 fn test_ord_min_max_clamp() {
279 assert_eq!(ord_min(3, 5), 3);
280 assert_eq!(ord_max(3, 5), 5);
281 assert_eq!(ord_clamp(10, 0, 5), 5);
282 assert_eq!(ord_clamp(-1, 0, 5), 0);
283 assert_eq!(ord_clamp(3, 0, 5), 3);
284 }
285 #[test]
286 fn test_compare_by_key() {
287 let a = ("b", 1);
288 let b = ("a", 2);
289 let res = compare_by_key(&a, &b, |x| x.0);
290 assert_eq!(res, OrdResult::Greater);
291 }
292 #[test]
293 fn test_compare_slices() {
294 let a = &[1, 2, 3][..];
295 let b = &[1, 2, 4][..];
296 assert_eq!(compare_slices(a, b), OrdResult::Less);
297 }
298 #[test]
299 fn test_signum() {
300 assert_eq!(OrdResult::Less.to_signum(), -1);
301 assert_eq!(OrdResult::Equal.to_signum(), 0);
302 assert_eq!(OrdResult::Greater.to_signum(), 1);
303 }
304 #[test]
305 fn test_display() {
306 assert_eq!(OrdResult::Less.to_string(), "lt");
307 assert_eq!(OrdResult::Equal.to_string(), "eq");
308 assert_eq!(OrdResult::Greater.to_string(), "gt");
309 }
310 #[test]
311 fn test_named_predicates() {
312 assert!(lt(&1, &2));
313 assert!(le(&2, &2));
314 assert!(gt(&3, &2));
315 assert!(ge(&2, &2));
316 assert!(eq(&5, &5));
317 assert!(ne(&5, &6));
318 }
319 #[test]
320 fn test_reverse_cmp() {
321 let res = reverse_cmp(&1i32, &2i32, |a, b| compare(a, b));
322 assert_eq!(res, OrdResult::Greater);
323 }
324 #[test]
325 fn test_binary_search() {
326 let v = vec![1, 3, 5, 7, 9];
327 assert!(ord_binary_search(&v, &5).is_ok());
328 assert!(ord_binary_search(&v, &4).is_err());
329 }
330 #[test]
331 fn test_to_from_std() {
332 let o = OrdResult::Less;
333 assert_eq!(OrdResult::from_std(o.to_std()), o);
334 }
335}
336pub fn multi_key_compare<K: Ord>(key_pairs: &[(K, K)]) -> OrdResult {
341 for (a, b) in key_pairs {
342 let r = compare(a, b);
343 if r != OrdResult::Equal {
344 return r;
345 }
346 }
347 OrdResult::Equal
348}
349pub fn median<T: Ord + Clone>(v: &[T]) -> Option<T> {
353 if v.is_empty() {
354 return None;
355 }
356 let mut sorted = v.to_vec();
357 sorted.sort();
358 Some(sorted[(sorted.len() - 1) / 2].clone())
359}
360pub fn is_subset<T: Ord>(v: &[T], u: &[T]) -> bool {
362 v.iter().all(|item| u.binary_search(item).is_ok())
363}
364#[cfg(test)]
365mod ord_extra_tests {
366 use super::*;
367 #[test]
368 fn test_sorted_map_insert_get() {
369 let mut m: SortedMap<u32, &str> = SortedMap::new();
370 m.insert(3, "three");
371 m.insert(1, "one");
372 m.insert(2, "two");
373 assert_eq!(m.get(&1), Some(&"one"));
374 assert_eq!(m.get(&3), Some(&"three"));
375 assert!(m.get(&5).is_none());
376 }
377 #[test]
378 fn test_sorted_map_keys_ordered() {
379 let mut m: SortedMap<u32, u32> = SortedMap::new();
380 m.insert(5, 50);
381 m.insert(1, 10);
382 m.insert(3, 30);
383 let keys: Vec<_> = m.keys().copied().collect();
384 assert_eq!(keys, vec![1, 3, 5]);
385 }
386 #[test]
387 fn test_sorted_map_remove() {
388 let mut m: SortedMap<u32, u32> = SortedMap::new();
389 m.insert(1, 100);
390 assert_eq!(m.remove(&1), Some(100));
391 assert!(m.get(&1).is_none());
392 }
393 #[test]
394 fn test_sorted_set_insert_contains() {
395 let mut s: SortedSet<u32> = SortedSet::new();
396 s.insert(5);
397 s.insert(3);
398 s.insert(7);
399 assert!(s.contains(&3));
400 assert!(s.contains(&5));
401 assert!(!s.contains(&4));
402 }
403 #[test]
404 fn test_sorted_set_union_intersection() {
405 let mut a: SortedSet<u32> = SortedSet::new();
406 a.insert(1);
407 a.insert(2);
408 a.insert(3);
409 let mut b: SortedSet<u32> = SortedSet::new();
410 b.insert(2);
411 b.insert(3);
412 b.insert(4);
413 let u = a.union(&b);
414 assert_eq!(u.len(), 4);
415 let i = a.intersection(&b);
416 assert_eq!(i.len(), 2);
417 assert!(i.contains(&2));
418 assert!(i.contains(&3));
419 }
420 #[test]
421 fn test_sorted_set_difference() {
422 let mut a: SortedSet<u32> = SortedSet::new();
423 a.insert(1);
424 a.insert(2);
425 a.insert(3);
426 let mut b: SortedSet<u32> = SortedSet::new();
427 b.insert(2);
428 let diff = a.difference(&b);
429 assert_eq!(diff.len(), 2);
430 assert!(diff.contains(&1));
431 assert!(diff.contains(&3));
432 }
433 #[test]
434 fn test_multi_key_compare() {
435 let result = multi_key_compare(&[(1u32, 1u32), (2u32, 3u32)]);
436 assert_eq!(result, OrdResult::Less);
437 let all_eq = multi_key_compare(&[(1u32, 1u32), (2u32, 2u32)]);
438 assert_eq!(all_eq, OrdResult::Equal);
439 }
440 #[test]
441 fn test_median() {
442 assert_eq!(median(&[3u32, 1, 4, 1, 5]), Some(3));
443 assert_eq!(median::<u32>(&[]), None);
444 assert_eq!(median(&[2u32, 4]), Some(2));
445 }
446 #[test]
447 fn test_is_subset() {
448 let u = vec![1u32, 2, 3, 4, 5];
449 let v = vec![2u32, 4];
450 assert!(is_subset(&v, &u));
451 let w = vec![2u32, 6];
452 assert!(!is_subset(&w, &u));
453 }
454}
455#[allow(dead_code)]
457pub fn compare_option<T: Ord>(a: &Option<T>, b: &Option<T>) -> OrdResult {
458 match (a, b) {
459 (None, None) => OrdResult::Equal,
460 (None, Some(_)) => OrdResult::Less,
461 (Some(_), None) => OrdResult::Greater,
462 (Some(x), Some(y)) => compare(x, y),
463 }
464}
465#[allow(dead_code)]
467pub fn compare_bool(a: bool, b: bool) -> OrdResult {
468 OrdResult::from_std(a.cmp(&b))
469}
470#[cfg(test)]
471mod ord_final_tests {
472 use super::*;
473 #[test]
474 fn test_compare_option() {
475 assert_eq!(compare_option::<u32>(&None, &None), OrdResult::Equal);
476 assert_eq!(compare_option::<u32>(&None, &Some(1)), OrdResult::Less);
477 assert_eq!(compare_option::<u32>(&Some(1), &None), OrdResult::Greater);
478 }
479 #[test]
480 fn test_compare_bool() {
481 assert_eq!(compare_bool(false, true), OrdResult::Less);
482 assert_eq!(compare_bool(true, true), OrdResult::Equal);
483 }
484}
485pub fn topological_sort(n: usize, edges: &[(usize, usize)]) -> Result<Vec<usize>, String> {
490 let mut in_degree = vec![0usize; n];
491 let mut adj: Vec<Vec<usize>> = vec![Vec::new(); n];
492 for &(from, to) in edges {
493 adj[from].push(to);
494 in_degree[to] += 1;
495 }
496 let mut queue: std::collections::VecDeque<usize> =
497 (0..n).filter(|&i| in_degree[i] == 0).collect();
498 let mut result = Vec::new();
499 while let Some(node) = queue.pop_front() {
500 result.push(node);
501 for &next in &adj[node] {
502 in_degree[next] -= 1;
503 if in_degree[next] == 0 {
504 queue.push_back(next);
505 }
506 }
507 }
508 if result.len() == n {
509 Ok(result)
510 } else {
511 Err("cycle detected in dependency graph".to_string())
512 }
513}
514pub fn dense_rank<T: Ord>(v: &[T]) -> Vec<usize> {
519 let mut indexed: Vec<(usize, &T)> = v.iter().enumerate().collect();
520 indexed.sort_by_key(|(_, val)| *val);
521 let mut rank = vec![0usize; v.len()];
522 let mut current_rank = 0usize;
523 for i in 0..indexed.len() {
524 if i > 0 && indexed[i].1 != indexed[i - 1].1 {
525 current_rank += 1;
526 }
527 rank[indexed[i].0] = current_rank;
528 }
529 rank
530}
531pub fn competition_rank<T: Ord>(v: &[T]) -> Vec<usize> {
534 let n = v.len();
535 if n == 0 {
536 return Vec::new();
537 }
538 let mut ranks = vec![1usize; n];
539 for i in 0..n {
540 for j in 0..n {
541 if i != j && v[j] < v[i] {
542 ranks[i] += 1;
543 }
544 }
545 }
546 ranks
547}
548pub trait OrdExt: Ord + Sized {
550 fn clamped(self, lo: Self, hi: Self) -> Self {
552 ord_clamp(self, lo, hi)
553 }
554 fn ord_cmp(&self, other: &Self) -> OrdResult {
556 compare(self, other)
557 }
558 fn strictly_between(&self, lo: &Self, hi: &Self) -> bool {
560 self > lo && self < hi
561 }
562 fn in_range(&self, lo: &Self, hi: &Self) -> bool {
564 self >= lo && self <= hi
565 }
566}
567impl<T: Ord> OrdExt for T {}
568pub fn build_ord_min(env: &mut Environment) -> Result<(), String> {
570 use oxilean_kernel::{BinderInfo, Declaration, Expr, Level, Name};
571 let type1 = Expr::Sort(Level::succ(Level::zero()));
572 let ty = Expr::Pi(
573 BinderInfo::Implicit,
574 Name::str("α"),
575 Box::new(type1.clone()),
576 Box::new(Expr::Pi(
577 BinderInfo::InstImplicit,
578 Name::str("_"),
579 Box::new(Expr::App(
580 Box::new(Expr::Const(Name::str("Ord"), vec![])),
581 Box::new(Expr::BVar(0)),
582 )),
583 Box::new(Expr::Pi(
584 BinderInfo::Default,
585 Name::str("a"),
586 Box::new(Expr::BVar(1)),
587 Box::new(Expr::Pi(
588 BinderInfo::Default,
589 Name::str("b"),
590 Box::new(Expr::BVar(2)),
591 Box::new(Expr::BVar(3)),
592 )),
593 )),
594 )),
595 );
596 env.add(Declaration::Axiom {
597 name: Name::str("Ord.min"),
598 univ_params: vec![],
599 ty,
600 })
601 .map_err(|e| e.to_string())
602}
603pub fn build_ord_max(env: &mut Environment) -> Result<(), String> {
605 use oxilean_kernel::{BinderInfo, Declaration, Expr, Level, Name};
606 let type1 = Expr::Sort(Level::succ(Level::zero()));
607 let ty = Expr::Pi(
608 BinderInfo::Implicit,
609 Name::str("α"),
610 Box::new(type1.clone()),
611 Box::new(Expr::Pi(
612 BinderInfo::InstImplicit,
613 Name::str("_"),
614 Box::new(Expr::App(
615 Box::new(Expr::Const(Name::str("Ord"), vec![])),
616 Box::new(Expr::BVar(0)),
617 )),
618 Box::new(Expr::Pi(
619 BinderInfo::Default,
620 Name::str("a"),
621 Box::new(Expr::BVar(1)),
622 Box::new(Expr::Pi(
623 BinderInfo::Default,
624 Name::str("b"),
625 Box::new(Expr::BVar(2)),
626 Box::new(Expr::BVar(3)),
627 )),
628 )),
629 )),
630 );
631 env.add(Declaration::Axiom {
632 name: Name::str("Ord.max"),
633 univ_params: vec![],
634 ty,
635 })
636 .map_err(|e| e.to_string())
637}
638#[cfg(test)]
639mod ord_advanced_tests {
640 use super::*;
641 #[test]
642 fn test_topological_sort_dag() {
643 let result = topological_sort(3, &[(0, 1), (1, 2)]).expect("operation should succeed");
644 assert!(result.iter().position(|&x| x == 0) < result.iter().position(|&x| x == 1));
645 assert!(result.iter().position(|&x| x == 1) < result.iter().position(|&x| x == 2));
646 }
647 #[test]
648 fn test_topological_sort_cycle() {
649 assert!(topological_sort(2, &[(0, 1), (1, 0)]).is_err());
650 }
651 #[test]
652 fn test_topological_sort_empty() {
653 let result = topological_sort(0, &[]).expect("operation should succeed");
654 assert!(result.is_empty());
655 }
656 #[test]
657 fn test_dense_rank_basic() {
658 let v = vec![3u32, 1, 4, 1, 5, 9, 2, 6];
659 let ranks = dense_rank(&v);
660 assert_eq!(ranks[1], 0);
661 assert_eq!(ranks[3], 0);
662 }
663 #[test]
664 fn test_dense_rank_all_equal() {
665 let v = vec![5u32, 5, 5];
666 let ranks = dense_rank(&v);
667 assert!(ranks.iter().all(|&r| r == 0));
668 }
669 #[test]
670 fn test_competition_rank() {
671 let v = vec![1u32, 2, 2, 3];
672 let ranks = competition_rank(&v);
673 assert_eq!(ranks[0], 1);
674 assert_eq!(ranks[1], 2);
675 assert_eq!(ranks[2], 2);
676 assert_eq!(ranks[3], 4);
677 }
678 #[test]
679 fn test_ord_ext_clamped() {
680 assert_eq!(5u32.clamped(1, 10), 5);
681 assert_eq!(0u32.clamped(1, 10), 1);
682 assert_eq!(15u32.clamped(1, 10), 10);
683 }
684 #[test]
685 fn test_ord_ext_strictly_between() {
686 assert!(5u32.strictly_between(&1, &10));
687 assert!(!1u32.strictly_between(&1, &10));
688 assert!(!10u32.strictly_between(&1, &10));
689 }
690 #[test]
691 fn test_ord_ext_in_range() {
692 assert!(5u32.in_range(&1, &10));
693 assert!(1u32.in_range(&1, &10));
694 assert!(10u32.in_range(&1, &10));
695 assert!(!0u32.in_range(&1, &10));
696 }
697 #[test]
698 fn test_permutation_identity() {
699 let p = Permutation::identity(3);
700 assert!(p.is_identity());
701 }
702 #[test]
703 fn test_permutation_from_sort_order() {
704 let v = vec![3u32, 1, 2];
705 let p = Permutation::from_sort_order(&v);
706 let sorted = p.apply(&v);
707 assert_eq!(sorted, vec![1, 2, 3]);
708 }
709 #[test]
710 fn test_permutation_inverse() {
711 let v = vec![3u32, 1, 2];
712 let p = Permutation::from_sort_order(&v);
713 let inv = p.inverse();
714 let composed = p.compose(&inv);
715 assert!(composed.is_identity());
716 }
717 #[test]
718 fn test_permutation_compose() {
719 let p = Permutation {
720 perm: vec![1, 0, 2],
721 };
722 let q = Permutation {
723 perm: vec![0, 1, 2],
724 };
725 let pq = p.compose(&q);
726 assert_eq!(pq.perm, vec![1, 0, 2]);
727 }
728 #[test]
729 fn test_build_ord_min_max() {
730 let mut env = Environment::new();
731 build_ord_env(&mut env).expect("build_ord_env should succeed");
732 assert!(build_ord_min(&mut env).is_ok());
733 assert!(build_ord_max(&mut env).is_ok());
734 }
735 #[test]
736 fn test_sorted_map_overwrite() {
737 let mut m: SortedMap<u32, u32> = SortedMap::new();
738 m.insert(1, 100);
739 m.insert(1, 200);
740 assert_eq!(m.get(&1), Some(&200));
741 assert_eq!(m.len(), 1);
742 }
743 #[test]
744 fn test_sorted_set_remove() {
745 let mut s: SortedSet<u32> = SortedSet::new();
746 s.insert(3);
747 s.insert(5);
748 assert!(s.remove(&3));
749 assert!(!s.contains(&3));
750 assert!(!s.remove(&3));
751 }
752}
753pub fn ord_e_type1() -> Expr {
754 Expr::Sort(Level::succ(Level::zero()))
755}
756pub fn ord_e_type2() -> Expr {
757 Expr::Sort(Level::succ(Level::succ(Level::zero())))
758}
759pub fn ord_e_prop() -> Expr {
760 Expr::Sort(Level::zero())
761}
762pub fn ord_e_arrow(dom: Expr, cod: Expr) -> Expr {
763 Expr::Pi(
764 BinderInfo::Default,
765 Name::str("_"),
766 Box::new(dom),
767 Box::new(cod),
768 )
769}
770pub fn ord_e_pi(name: &str, dom: Expr, body: Expr) -> Expr {
771 Expr::Pi(
772 BinderInfo::Default,
773 Name::str(name),
774 Box::new(dom),
775 Box::new(body),
776 )
777}
778pub fn ord_e_ipi(name: &str, dom: Expr, body: Expr) -> Expr {
779 Expr::Pi(
780 BinderInfo::Implicit,
781 Name::str(name),
782 Box::new(dom),
783 Box::new(body),
784 )
785}
786pub fn ord_e_app(f: Expr, a: Expr) -> Expr {
787 Expr::App(Box::new(f), Box::new(a))
788}
789pub fn ord_e_app2(f: Expr, a: Expr, b: Expr) -> Expr {
790 ord_e_app(ord_e_app(f, a), b)
791}
792pub fn ord_e_app3(f: Expr, a: Expr, b: Expr, c: Expr) -> Expr {
793 ord_e_app(ord_e_app2(f, a, b), c)
794}
795pub fn ord_e_nat() -> Expr {
796 Expr::Const(Name::str("Nat"), vec![])
797}
798pub fn ord_e_bool() -> Expr {
799 Expr::Const(Name::str("Bool"), vec![])
800}
801pub fn ord_e_prop_app2(name: &str, a: Expr, b: Expr) -> Expr {
802 ord_e_app2(Expr::Const(Name::str(name), vec![]), a, b)
803}
804pub fn ord_e_eq(ty: Expr, a: Expr, b: Expr) -> Expr {
805 ord_e_app3(Expr::Const(Name::str("Eq"), vec![]), ty, a, b)
806}
807pub fn ord_e_and(a: Expr, b: Expr) -> Expr {
808 ord_e_prop_app2("And", a, b)
809}
810pub fn ord_e_iff(a: Expr, b: Expr) -> Expr {
811 ord_e_prop_app2("Iff", a, b)
812}
813pub fn ord_e_ordering() -> Expr {
814 Expr::Const(Name::str("Ordering"), vec![])
815}
816pub fn ord_e_ord_inst(alpha: Expr) -> Expr {
817 ord_e_app(Expr::Const(Name::str("Ord"), vec![]), alpha)
818}
819pub fn ord_e_add_axiom(env: &mut Environment, name: &str, ty: Expr) -> Result<(), String> {
820 env.add(Declaration::Axiom {
821 name: Name::str(name),
822 univ_params: vec![],
823 ty,
824 })
825 .map_err(|e| e.to_string())
826}
827pub fn axiom_ord_cat_ty() -> Expr {
829 ord_e_type2()
830}
831pub fn axiom_ord_cat_obj_ty() -> Expr {
833 ord_e_arrow(Expr::Const(Name::str("OrdCat"), vec![]), ord_e_type1())
834}
835pub fn axiom_monotone_map_ty() -> Expr {
837 ord_e_ipi(
838 "α",
839 ord_e_type1(),
840 ord_e_ipi(
841 "β",
842 ord_e_type1(),
843 Expr::Pi(
844 BinderInfo::InstImplicit,
845 Name::str("_"),
846 Box::new(ord_e_ord_inst(Expr::BVar(1))),
847 Box::new(Expr::Pi(
848 BinderInfo::InstImplicit,
849 Name::str("_"),
850 Box::new(ord_e_ord_inst(Expr::BVar(1))),
851 Box::new(ord_e_type1()),
852 )),
853 ),
854 ),
855 )
856}
857pub fn axiom_monotone_map_mk_ty() -> Expr {
859 ord_e_ipi(
860 "α",
861 ord_e_type1(),
862 ord_e_ipi(
863 "β",
864 ord_e_type1(),
865 ord_e_pi(
866 "f",
867 ord_e_arrow(Expr::BVar(1), Expr::BVar(0)),
868 ord_e_pi(
869 "mono",
870 Expr::Const(Name::str("MonotoneMap.mono_proof_ty"), vec![]),
871 Expr::Const(Name::str("MonotoneMap"), vec![]),
872 ),
873 ),
874 ),
875 )
876}
877pub fn axiom_monotone_maps_form_cat_ty() -> Expr {
879 ord_e_prop()
880}
881pub fn axiom_galois_connection_ty() -> Expr {
883 ord_e_ipi(
884 "α",
885 ord_e_type1(),
886 ord_e_ipi(
887 "β",
888 ord_e_type1(),
889 Expr::Pi(
890 BinderInfo::InstImplicit,
891 Name::str("_"),
892 Box::new(ord_e_ord_inst(Expr::BVar(1))),
893 Box::new(Expr::Pi(
894 BinderInfo::InstImplicit,
895 Name::str("_"),
896 Box::new(ord_e_ord_inst(Expr::BVar(1))),
897 Box::new(ord_e_pi(
898 "l",
899 ord_e_arrow(Expr::BVar(3), Expr::BVar(2)),
900 ord_e_pi("r", ord_e_arrow(Expr::BVar(3), Expr::BVar(4)), ord_e_prop()),
901 )),
902 )),
903 ),
904 ),
905 )
906}
907pub fn axiom_galois_adjoint_iff_ty() -> Expr {
909 ord_e_prop()
910}
911pub fn axiom_ord_enriched_cat_ty() -> Expr {
913 ord_e_type2()
914}
915pub fn axiom_fixpoint_exists_ty() -> Expr {
917 ord_e_ipi(
918 "α",
919 ord_e_type1(),
920 Expr::Pi(
921 BinderInfo::InstImplicit,
922 Name::str("_"),
923 Box::new(ord_e_ord_inst(Expr::BVar(0))),
924 Box::new(ord_e_pi(
925 "f",
926 ord_e_arrow(Expr::BVar(1), Expr::BVar(1)),
927 ord_e_prop(),
928 )),
929 ),
930 )
931}
932pub fn axiom_knaster_tarski_ty() -> Expr {
934 ord_e_ipi(
935 "α",
936 ord_e_type1(),
937 Expr::Pi(
938 BinderInfo::InstImplicit,
939 Name::str("_"),
940 Box::new(ord_e_app(
941 Expr::Const(Name::str("CompleteLattice"), vec![]),
942 Expr::BVar(0),
943 )),
944 Box::new(ord_e_pi(
945 "f",
946 ord_e_arrow(Expr::BVar(1), Expr::BVar(1)),
947 Expr::BVar(2),
948 )),
949 ),
950 )
951}
952pub fn axiom_knaster_tarski_least_ty() -> Expr {
954 ord_e_prop()
955}
956pub fn axiom_scott_continuous_ty() -> Expr {
958 ord_e_ipi(
959 "α",
960 ord_e_type1(),
961 ord_e_ipi(
962 "β",
963 ord_e_type1(),
964 Expr::Pi(
965 BinderInfo::InstImplicit,
966 Name::str("_"),
967 Box::new(ord_e_ord_inst(Expr::BVar(1))),
968 Box::new(Expr::Pi(
969 BinderInfo::InstImplicit,
970 Name::str("_"),
971 Box::new(ord_e_ord_inst(Expr::BVar(1))),
972 Box::new(ord_e_pi(
973 "f",
974 ord_e_arrow(Expr::BVar(3), Expr::BVar(2)),
975 ord_e_prop(),
976 )),
977 )),
978 ),
979 ),
980 )
981}
982pub fn axiom_dcpo_ty() -> Expr {
984 ord_e_type2()
985}
986pub fn axiom_dcpo_lfp_ty() -> Expr {
988 ord_e_pi(
989 "D",
990 Expr::Const(Name::str("DCPO"), vec![]),
991 ord_e_pi(
992 "f",
993 ord_e_arrow(
994 ord_e_app(
995 Expr::Const(Name::str("DCPO.carrier"), vec![]),
996 Expr::BVar(0),
997 ),
998 ord_e_app(
999 Expr::Const(Name::str("DCPO.carrier"), vec![]),
1000 Expr::BVar(0),
1001 ),
1002 ),
1003 ord_e_app(
1004 Expr::Const(Name::str("DCPO.carrier"), vec![]),
1005 Expr::BVar(1),
1006 ),
1007 ),
1008 )
1009}
1010pub fn axiom_omega_cpo_ty() -> Expr {
1012 ord_e_type2()
1013}
1014pub fn axiom_omega_cpo_chain_limit_ty() -> Expr {
1016 ord_e_pi(
1017 "D",
1018 Expr::Const(Name::str("OmegaCPO"), vec![]),
1019 ord_e_pi(
1020 "chain",
1021 ord_e_arrow(
1022 ord_e_nat(),
1023 ord_e_app(
1024 Expr::Const(Name::str("OmegaCPO.carrier"), vec![]),
1025 Expr::BVar(0),
1026 ),
1027 ),
1028 ord_e_app(
1029 Expr::Const(Name::str("OmegaCPO.carrier"), vec![]),
1030 Expr::BVar(1),
1031 ),
1032 ),
1033 )
1034}
1035pub fn axiom_lazy_eval_ord_ty() -> Expr {
1037 ord_e_ipi(
1038 "α",
1039 ord_e_type1(),
1040 Expr::Pi(
1041 BinderInfo::InstImplicit,
1042 Name::str("_"),
1043 Box::new(ord_e_ord_inst(Expr::BVar(0))),
1044 Box::new(ord_e_pi(
1045 "a",
1046 ord_e_app(Expr::Const(Name::str("Thunk"), vec![]), Expr::BVar(1)),
1047 ord_e_pi(
1048 "b",
1049 ord_e_app(Expr::Const(Name::str("Thunk"), vec![]), Expr::BVar(2)),
1050 ord_e_ordering(),
1051 ),
1052 )),
1053 ),
1054 )
1055}
1056pub fn axiom_sorting_network_correct_ty() -> Expr {
1058 ord_e_pi(
1059 "n",
1060 ord_e_nat(),
1061 ord_e_pi(
1062 "net",
1063 ord_e_app(
1064 Expr::Const(Name::str("SortingNetwork"), vec![]),
1065 Expr::BVar(0),
1066 ),
1067 ord_e_prop(),
1068 ),
1069 )
1070}
1071pub fn axiom_comparison_sort_lower_bound_ty() -> Expr {
1073 ord_e_prop()
1074}
1075pub fn axiom_btree_invariant_ty() -> Expr {
1077 ord_e_ipi(
1078 "α",
1079 ord_e_type1(),
1080 Expr::Pi(
1081 BinderInfo::InstImplicit,
1082 Name::str("_"),
1083 Box::new(ord_e_ord_inst(Expr::BVar(0))),
1084 Box::new(ord_e_pi(
1085 "t",
1086 ord_e_app(Expr::Const(Name::str("BTree"), vec![]), Expr::BVar(1)),
1087 ord_e_prop(),
1088 )),
1089 ),
1090 )
1091}
1092pub fn axiom_red_black_balance_ty() -> Expr {
1094 ord_e_ipi(
1095 "α",
1096 ord_e_type1(),
1097 Expr::Pi(
1098 BinderInfo::InstImplicit,
1099 Name::str("_"),
1100 Box::new(ord_e_ord_inst(Expr::BVar(0))),
1101 Box::new(ord_e_pi(
1102 "t",
1103 ord_e_app(Expr::Const(Name::str("RBTree"), vec![]), Expr::BVar(1)),
1104 ord_e_prop(),
1105 )),
1106 ),
1107 )
1108}
1109pub fn axiom_well_founded_lt_ty() -> Expr {
1111 ord_e_ipi(
1112 "α",
1113 ord_e_type1(),
1114 Expr::Pi(
1115 BinderInfo::InstImplicit,
1116 Name::str("_"),
1117 Box::new(ord_e_ord_inst(Expr::BVar(0))),
1118 Box::new(ord_e_app(
1119 Expr::Const(Name::str("WellFounded"), vec![]),
1120 Expr::Const(Name::str("LT.lt"), vec![]),
1121 )),
1122 ),
1123 )
1124}
1125pub fn axiom_antisymm_ty() -> Expr {
1127 ord_e_ipi(
1128 "α",
1129 ord_e_type1(),
1130 Expr::Pi(
1131 BinderInfo::InstImplicit,
1132 Name::str("_"),
1133 Box::new(ord_e_ord_inst(Expr::BVar(0))),
1134 Box::new(ord_e_pi(
1135 "a",
1136 Expr::BVar(1),
1137 ord_e_pi(
1138 "b",
1139 Expr::BVar(2),
1140 ord_e_pi(
1141 "h1",
1142 ord_e_prop_app2("LE.le", Expr::BVar(1), Expr::BVar(0)),
1143 ord_e_pi(
1144 "h2",
1145 ord_e_prop_app2("LE.le", Expr::BVar(1), Expr::BVar(2)),
1146 ord_e_eq(Expr::BVar(4), Expr::BVar(3), Expr::BVar(2)),
1147 ),
1148 ),
1149 ),
1150 )),
1151 ),
1152 )
1153}
1154pub fn axiom_transitivity_ty() -> Expr {
1156 ord_e_ipi(
1157 "α",
1158 ord_e_type1(),
1159 Expr::Pi(
1160 BinderInfo::InstImplicit,
1161 Name::str("_"),
1162 Box::new(ord_e_ord_inst(Expr::BVar(0))),
1163 Box::new(ord_e_pi(
1164 "a",
1165 Expr::BVar(1),
1166 ord_e_pi(
1167 "b",
1168 Expr::BVar(2),
1169 ord_e_pi(
1170 "c",
1171 Expr::BVar(3),
1172 ord_e_pi(
1173 "hab",
1174 ord_e_prop_app2("LE.le", Expr::BVar(2), Expr::BVar(1)),
1175 ord_e_pi(
1176 "hbc",
1177 ord_e_prop_app2("LE.le", Expr::BVar(2), Expr::BVar(1)),
1178 ord_e_prop_app2("LE.le", Expr::BVar(4), Expr::BVar(2)),
1179 ),
1180 ),
1181 ),
1182 ),
1183 )),
1184 ),
1185 )
1186}
1187pub fn axiom_totality_ty() -> Expr {
1189 ord_e_ipi(
1190 "α",
1191 ord_e_type1(),
1192 Expr::Pi(
1193 BinderInfo::InstImplicit,
1194 Name::str("_"),
1195 Box::new(ord_e_ord_inst(Expr::BVar(0))),
1196 Box::new(ord_e_pi(
1197 "a",
1198 Expr::BVar(1),
1199 ord_e_pi(
1200 "b",
1201 Expr::BVar(2),
1202 ord_e_app2(
1203 Expr::Const(Name::str("Or"), vec![]),
1204 ord_e_prop_app2("LE.le", Expr::BVar(1), Expr::BVar(0)),
1205 ord_e_prop_app2("LE.le", Expr::BVar(0), Expr::BVar(1)),
1206 ),
1207 ),
1208 )),
1209 ),
1210 )
1211}
1212pub fn axiom_reflexivity_ty() -> Expr {
1214 ord_e_ipi(
1215 "α",
1216 ord_e_type1(),
1217 Expr::Pi(
1218 BinderInfo::InstImplicit,
1219 Name::str("_"),
1220 Box::new(ord_e_ord_inst(Expr::BVar(0))),
1221 Box::new(ord_e_pi(
1222 "a",
1223 Expr::BVar(1),
1224 ord_e_prop_app2("LE.le", Expr::BVar(0), Expr::BVar(0)),
1225 )),
1226 ),
1227 )
1228}
1229pub fn axiom_monotone_ty() -> Expr {
1231 ord_e_ipi(
1232 "α",
1233 ord_e_type1(),
1234 ord_e_ipi(
1235 "β",
1236 ord_e_type1(),
1237 Expr::Pi(
1238 BinderInfo::InstImplicit,
1239 Name::str("_"),
1240 Box::new(ord_e_ord_inst(Expr::BVar(1))),
1241 Box::new(Expr::Pi(
1242 BinderInfo::InstImplicit,
1243 Name::str("_"),
1244 Box::new(ord_e_ord_inst(Expr::BVar(1))),
1245 Box::new(ord_e_pi(
1246 "f",
1247 ord_e_arrow(Expr::BVar(3), Expr::BVar(2)),
1248 ord_e_prop(),
1249 )),
1250 )),
1251 ),
1252 ),
1253 )
1254}
1255pub fn axiom_strict_mono_ty() -> Expr {
1257 ord_e_ipi(
1258 "α",
1259 ord_e_type1(),
1260 ord_e_ipi(
1261 "β",
1262 ord_e_type1(),
1263 Expr::Pi(
1264 BinderInfo::InstImplicit,
1265 Name::str("_"),
1266 Box::new(ord_e_ord_inst(Expr::BVar(1))),
1267 Box::new(Expr::Pi(
1268 BinderInfo::InstImplicit,
1269 Name::str("_"),
1270 Box::new(ord_e_ord_inst(Expr::BVar(1))),
1271 Box::new(ord_e_pi(
1272 "f",
1273 ord_e_arrow(Expr::BVar(3), Expr::BVar(2)),
1274 ord_e_prop(),
1275 )),
1276 )),
1277 ),
1278 ),
1279 )
1280}
1281pub fn axiom_complete_lattice_ty() -> Expr {
1283 ord_e_arrow(ord_e_type1(), ord_e_type2())
1284}
1285pub fn axiom_complete_lattice_ssup_ty() -> Expr {
1287 ord_e_ipi(
1288 "α",
1289 ord_e_type1(),
1290 Expr::Pi(
1291 BinderInfo::InstImplicit,
1292 Name::str("_"),
1293 Box::new(ord_e_app(
1294 Expr::Const(Name::str("CompleteLattice"), vec![]),
1295 Expr::BVar(0),
1296 )),
1297 Box::new(ord_e_pi(
1298 "S",
1299 ord_e_app(Expr::Const(Name::str("Set"), vec![]), Expr::BVar(1)),
1300 Expr::BVar(2),
1301 )),
1302 ),
1303 )
1304}
1305pub fn axiom_complete_lattice_sinf_ty() -> Expr {
1307 ord_e_ipi(
1308 "α",
1309 ord_e_type1(),
1310 Expr::Pi(
1311 BinderInfo::InstImplicit,
1312 Name::str("_"),
1313 Box::new(ord_e_app(
1314 Expr::Const(Name::str("CompleteLattice"), vec![]),
1315 Expr::BVar(0),
1316 )),
1317 Box::new(ord_e_pi(
1318 "S",
1319 ord_e_app(Expr::Const(Name::str("Set"), vec![]), Expr::BVar(1)),
1320 Expr::BVar(2),
1321 )),
1322 ),
1323 )
1324}
1325pub fn axiom_upper_bound_ty() -> Expr {
1327 ord_e_ipi(
1328 "α",
1329 ord_e_type1(),
1330 Expr::Pi(
1331 BinderInfo::InstImplicit,
1332 Name::str("_"),
1333 Box::new(ord_e_ord_inst(Expr::BVar(0))),
1334 Box::new(ord_e_pi(
1335 "S",
1336 ord_e_app(Expr::Const(Name::str("Set"), vec![]), Expr::BVar(1)),
1337 ord_e_pi("x", Expr::BVar(2), ord_e_prop()),
1338 )),
1339 ),
1340 )
1341}
1342pub fn axiom_lower_bound_ty() -> Expr {
1344 ord_e_ipi(
1345 "α",
1346 ord_e_type1(),
1347 Expr::Pi(
1348 BinderInfo::InstImplicit,
1349 Name::str("_"),
1350 Box::new(ord_e_ord_inst(Expr::BVar(0))),
1351 Box::new(ord_e_pi(
1352 "S",
1353 ord_e_app(Expr::Const(Name::str("Set"), vec![]), Expr::BVar(1)),
1354 ord_e_pi("x", Expr::BVar(2), ord_e_prop()),
1355 )),
1356 ),
1357 )
1358}
1359pub fn axiom_is_lub_ty() -> Expr {
1361 ord_e_ipi(
1362 "α",
1363 ord_e_type1(),
1364 Expr::Pi(
1365 BinderInfo::InstImplicit,
1366 Name::str("_"),
1367 Box::new(ord_e_ord_inst(Expr::BVar(0))),
1368 Box::new(ord_e_pi(
1369 "S",
1370 ord_e_app(Expr::Const(Name::str("Set"), vec![]), Expr::BVar(1)),
1371 ord_e_pi("x", Expr::BVar(2), ord_e_prop()),
1372 )),
1373 ),
1374 )
1375}
1376pub fn axiom_is_glb_ty() -> Expr {
1378 ord_e_ipi(
1379 "α",
1380 ord_e_type1(),
1381 Expr::Pi(
1382 BinderInfo::InstImplicit,
1383 Name::str("_"),
1384 Box::new(ord_e_ord_inst(Expr::BVar(0))),
1385 Box::new(ord_e_pi(
1386 "S",
1387 ord_e_app(Expr::Const(Name::str("Set"), vec![]), Expr::BVar(1)),
1388 ord_e_pi("x", Expr::BVar(2), ord_e_prop()),
1389 )),
1390 ),
1391 )
1392}
1393pub fn axiom_order_iso_ty() -> Expr {
1395 ord_e_ipi(
1396 "α",
1397 ord_e_type1(),
1398 ord_e_ipi(
1399 "β",
1400 ord_e_type1(),
1401 Expr::Pi(
1402 BinderInfo::InstImplicit,
1403 Name::str("_"),
1404 Box::new(ord_e_ord_inst(Expr::BVar(1))),
1405 Box::new(Expr::Pi(
1406 BinderInfo::InstImplicit,
1407 Name::str("_"),
1408 Box::new(ord_e_ord_inst(Expr::BVar(1))),
1409 Box::new(ord_e_type1()),
1410 )),
1411 ),
1412 ),
1413 )
1414}
1415pub fn axiom_order_embedding_ty() -> Expr {
1417 ord_e_ipi(
1418 "α",
1419 ord_e_type1(),
1420 ord_e_ipi(
1421 "β",
1422 ord_e_type1(),
1423 Expr::Pi(
1424 BinderInfo::InstImplicit,
1425 Name::str("_"),
1426 Box::new(ord_e_ord_inst(Expr::BVar(1))),
1427 Box::new(Expr::Pi(
1428 BinderInfo::InstImplicit,
1429 Name::str("_"),
1430 Box::new(ord_e_ord_inst(Expr::BVar(1))),
1431 Box::new(ord_e_type1()),
1432 )),
1433 ),
1434 ),
1435 )
1436}
1437pub fn axiom_antichain_ty() -> Expr {
1439 ord_e_ipi(
1440 "α",
1441 ord_e_type1(),
1442 Expr::Pi(
1443 BinderInfo::InstImplicit,
1444 Name::str("_"),
1445 Box::new(ord_e_ord_inst(Expr::BVar(0))),
1446 Box::new(ord_e_pi(
1447 "S",
1448 ord_e_app(Expr::Const(Name::str("Set"), vec![]), Expr::BVar(1)),
1449 ord_e_prop(),
1450 )),
1451 ),
1452 )
1453}
1454pub fn axiom_dilworth_theorem_ty() -> Expr {
1456 ord_e_prop()
1457}
1458pub fn axiom_mirskys_theorem_ty() -> Expr {
1460 ord_e_prop()
1461}
1462pub fn axiom_compare_eq_iff_ty() -> Expr {
1464 ord_e_ipi(
1465 "α",
1466 ord_e_type1(),
1467 Expr::Pi(
1468 BinderInfo::InstImplicit,
1469 Name::str("_"),
1470 Box::new(ord_e_ord_inst(Expr::BVar(0))),
1471 Box::new(ord_e_pi(
1472 "a",
1473 Expr::BVar(1),
1474 ord_e_pi(
1475 "b",
1476 Expr::BVar(2),
1477 ord_e_iff(
1478 ord_e_eq(
1479 ord_e_ordering(),
1480 ord_e_app2(
1481 Expr::Const(Name::str("Ord.compare"), vec![]),
1482 Expr::BVar(1),
1483 Expr::BVar(0),
1484 ),
1485 Expr::Const(Name::str("Ordering.eq"), vec![]),
1486 ),
1487 ord_e_eq(Expr::BVar(3), Expr::BVar(1), Expr::BVar(0)),
1488 ),
1489 ),
1490 )),
1491 ),
1492 )
1493}
1494pub fn axiom_compare_swap_ty() -> Expr {
1496 ord_e_ipi(
1497 "α",
1498 ord_e_type1(),
1499 Expr::Pi(
1500 BinderInfo::InstImplicit,
1501 Name::str("_"),
1502 Box::new(ord_e_ord_inst(Expr::BVar(0))),
1503 Box::new(ord_e_pi(
1504 "a",
1505 Expr::BVar(1),
1506 ord_e_pi(
1507 "b",
1508 Expr::BVar(2),
1509 ord_e_eq(
1510 ord_e_ordering(),
1511 ord_e_app2(
1512 Expr::Const(Name::str("Ord.compare"), vec![]),
1513 Expr::BVar(1),
1514 Expr::BVar(0),
1515 ),
1516 ord_e_app(
1517 Expr::Const(Name::str("Ordering.swap"), vec![]),
1518 ord_e_app2(
1519 Expr::Const(Name::str("Ord.compare"), vec![]),
1520 Expr::BVar(0),
1521 Expr::BVar(1),
1522 ),
1523 ),
1524 ),
1525 ),
1526 )),
1527 ),
1528 )
1529}
1530pub fn axiom_bool_ord_ty() -> Expr {
1532 ord_e_ord_inst(ord_e_bool())
1533}
1534pub fn axiom_nat_ord_ty() -> Expr {
1536 ord_e_ord_inst(ord_e_nat())
1537}
1538pub fn axiom_prod_ord_ty() -> Expr {
1540 ord_e_ipi(
1541 "α",
1542 ord_e_type1(),
1543 ord_e_ipi(
1544 "β",
1545 ord_e_type1(),
1546 Expr::Pi(
1547 BinderInfo::InstImplicit,
1548 Name::str("_"),
1549 Box::new(ord_e_ord_inst(Expr::BVar(1))),
1550 Box::new(Expr::Pi(
1551 BinderInfo::InstImplicit,
1552 Name::str("_"),
1553 Box::new(ord_e_ord_inst(Expr::BVar(1))),
1554 Box::new(ord_e_ord_inst(ord_e_app2(
1555 Expr::Const(Name::str("Prod"), vec![]),
1556 Expr::BVar(3),
1557 Expr::BVar(2),
1558 ))),
1559 )),
1560 ),
1561 ),
1562 )
1563}
1564pub fn axiom_list_ord_ty() -> Expr {
1566 ord_e_ipi(
1567 "α",
1568 ord_e_type1(),
1569 Expr::Pi(
1570 BinderInfo::InstImplicit,
1571 Name::str("_"),
1572 Box::new(ord_e_ord_inst(Expr::BVar(0))),
1573 Box::new(ord_e_ord_inst(ord_e_app(
1574 Expr::Const(Name::str("List"), vec![]),
1575 Expr::BVar(1),
1576 ))),
1577 ),
1578 )
1579}
1580pub fn axiom_option_ord_ty() -> Expr {
1582 ord_e_ipi(
1583 "α",
1584 ord_e_type1(),
1585 Expr::Pi(
1586 BinderInfo::InstImplicit,
1587 Name::str("_"),
1588 Box::new(ord_e_ord_inst(Expr::BVar(0))),
1589 Box::new(ord_e_ord_inst(ord_e_app(
1590 Expr::Const(Name::str("Option"), vec![]),
1591 Expr::BVar(1),
1592 ))),
1593 ),
1594 )
1595}
1596pub fn axiom_heyting_algebra_ty() -> Expr {
1598 ord_e_arrow(ord_e_type1(), ord_e_type2())
1599}
1600pub fn axiom_boolean_algebra_ty() -> Expr {
1602 ord_e_arrow(ord_e_type1(), ord_e_type2())
1603}
1604pub fn register_ord_extended(env: &mut Environment) -> Result<(), String> {
1606 ord_e_add_axiom(env, "OrdCat", axiom_ord_cat_ty())?;
1607 ord_e_add_axiom(env, "OrdCat.obj", axiom_ord_cat_obj_ty())?;
1608 ord_e_add_axiom(
1609 env,
1610 "MonotoneMapsFormCat",
1611 axiom_monotone_maps_form_cat_ty(),
1612 )?;
1613 ord_e_add_axiom(
1614 env,
1615 "GaloisConnection.adjoint_iff",
1616 axiom_galois_adjoint_iff_ty(),
1617 )?;
1618 ord_e_add_axiom(env, "OrdEnrichedCat", axiom_ord_enriched_cat_ty())?;
1619 ord_e_add_axiom(
1620 env,
1621 "KnasterTarski.least_fixpoint",
1622 axiom_knaster_tarski_least_ty(),
1623 )?;
1624 ord_e_add_axiom(env, "DCPO", axiom_dcpo_ty())?;
1625 ord_e_add_axiom(env, "OmegaCPO", axiom_omega_cpo_ty())?;
1626 ord_e_add_axiom(
1627 env,
1628 "ComparisonSortLowerBound",
1629 axiom_comparison_sort_lower_bound_ty(),
1630 )?;
1631 ord_e_add_axiom(env, "WellFounded.lt", axiom_well_founded_lt_ty())?;
1632 ord_e_add_axiom(env, "Antisymm", axiom_antisymm_ty())?;
1633 ord_e_add_axiom(env, "Transitivity", axiom_transitivity_ty())?;
1634 ord_e_add_axiom(env, "Totality", axiom_totality_ty())?;
1635 ord_e_add_axiom(env, "Reflexivity", axiom_reflexivity_ty())?;
1636 ord_e_add_axiom(env, "Monotone", axiom_monotone_ty())?;
1637 ord_e_add_axiom(env, "StrictMono", axiom_strict_mono_ty())?;
1638 ord_e_add_axiom(env, "CompleteLattice", axiom_complete_lattice_ty())?;
1639 ord_e_add_axiom(env, "UpperBound", axiom_upper_bound_ty())?;
1640 ord_e_add_axiom(env, "LowerBound", axiom_lower_bound_ty())?;
1641 ord_e_add_axiom(env, "IsLUB", axiom_is_lub_ty())?;
1642 ord_e_add_axiom(env, "IsGLB", axiom_is_glb_ty())?;
1643 ord_e_add_axiom(env, "OrderIso", axiom_order_iso_ty())?;
1644 ord_e_add_axiom(env, "OrderEmbedding", axiom_order_embedding_ty())?;
1645 ord_e_add_axiom(env, "Antichain", axiom_antichain_ty())?;
1646 ord_e_add_axiom(env, "DilworthTheorem", axiom_dilworth_theorem_ty())?;
1647 ord_e_add_axiom(env, "MirskysTheorem", axiom_mirskys_theorem_ty())?;
1648 ord_e_add_axiom(env, "OrdCompare.compare_eq_iff", axiom_compare_eq_iff_ty())?;
1649 ord_e_add_axiom(env, "OrdCompare.compare_swap", axiom_compare_swap_ty())?;
1650 ord_e_add_axiom(env, "BoolOrd", axiom_bool_ord_ty())?;
1651 ord_e_add_axiom(env, "NatOrd", axiom_nat_ord_ty())?;
1652 ord_e_add_axiom(env, "ProdOrd", axiom_prod_ord_ty())?;
1653 ord_e_add_axiom(env, "ListOrd", axiom_list_ord_ty())?;
1654 ord_e_add_axiom(env, "OptionOrd", axiom_option_ord_ty())?;
1655 ord_e_add_axiom(env, "HeytingAlgebra", axiom_heyting_algebra_ty())?;
1656 ord_e_add_axiom(env, "BooleanAlgebra", axiom_boolean_algebra_ty())?;
1657 Ok(())
1658}