1use oxilean_kernel::{
6 BinderInfo, Declaration, Environment, Expr, InductiveEnv, InductiveType, IntroRule, Level, Name,
7};
8
9use super::types::{Coproduct, InjectionMap, Pair, Sum3, Sum4, SumChain, SumStats, Tagged};
10
11pub fn build_sum_env(env: &mut Environment, ind_env: &mut InductiveEnv) -> Result<(), String> {
13 let type1 = Expr::Sort(Level::succ(Level::zero()));
14 let sum_ty = Expr::Pi(
15 BinderInfo::Default,
16 Name::str("α"),
17 Box::new(type1.clone()),
18 Box::new(Expr::Pi(
19 BinderInfo::Default,
20 Name::str("β"),
21 Box::new(type1.clone()),
22 Box::new(type1.clone()),
23 )),
24 );
25 let inl_ty = Expr::Pi(
26 BinderInfo::Implicit,
27 Name::str("α"),
28 Box::new(type1.clone()),
29 Box::new(Expr::Pi(
30 BinderInfo::Implicit,
31 Name::str("β"),
32 Box::new(type1.clone()),
33 Box::new(Expr::Pi(
34 BinderInfo::Default,
35 Name::str("a"),
36 Box::new(Expr::BVar(1)),
37 Box::new(Expr::App(
38 Box::new(Expr::App(
39 Box::new(Expr::Const(Name::str("Sum"), vec![])),
40 Box::new(Expr::BVar(2)),
41 )),
42 Box::new(Expr::BVar(1)),
43 )),
44 )),
45 )),
46 );
47 let inr_ty = Expr::Pi(
48 BinderInfo::Implicit,
49 Name::str("α"),
50 Box::new(type1.clone()),
51 Box::new(Expr::Pi(
52 BinderInfo::Implicit,
53 Name::str("β"),
54 Box::new(type1.clone()),
55 Box::new(Expr::Pi(
56 BinderInfo::Default,
57 Name::str("b"),
58 Box::new(Expr::BVar(0)),
59 Box::new(Expr::App(
60 Box::new(Expr::App(
61 Box::new(Expr::Const(Name::str("Sum"), vec![])),
62 Box::new(Expr::BVar(2)),
63 )),
64 Box::new(Expr::BVar(1)),
65 )),
66 )),
67 )),
68 );
69 let sum_ind = InductiveType::new(
70 Name::str("Sum"),
71 vec![],
72 2,
73 0,
74 sum_ty.clone(),
75 vec![
76 IntroRule {
77 name: Name::str("Sum.inl"),
78 ty: inl_ty.clone(),
79 },
80 IntroRule {
81 name: Name::str("Sum.inr"),
82 ty: inr_ty.clone(),
83 },
84 ],
85 );
86 ind_env.add(sum_ind).map_err(|e| format!("{}", e))?;
87 env.add(Declaration::Axiom {
88 name: Name::str("Sum"),
89 univ_params: vec![],
90 ty: sum_ty,
91 })
92 .map_err(|e| e.to_string())?;
93 env.add(Declaration::Axiom {
94 name: Name::str("Sum.inl"),
95 univ_params: vec![],
96 ty: inl_ty,
97 })
98 .map_err(|e| e.to_string())?;
99 env.add(Declaration::Axiom {
100 name: Name::str("Sum.inr"),
101 univ_params: vec![],
102 ty: inr_ty,
103 })
104 .map_err(|e| e.to_string())?;
105 build_sum_combinators(env)?;
106 Ok(())
107}
108pub fn build_sum_combinators(env: &mut Environment) -> Result<(), String> {
110 let type1 = Expr::Sort(Level::succ(Level::zero()));
111 let elim_ty = Expr::Pi(
112 BinderInfo::Implicit,
113 Name::str("α"),
114 Box::new(type1.clone()),
115 Box::new(Expr::Pi(
116 BinderInfo::Implicit,
117 Name::str("β"),
118 Box::new(type1.clone()),
119 Box::new(Expr::Pi(
120 BinderInfo::Implicit,
121 Name::str("γ"),
122 Box::new(type1.clone()),
123 Box::new(Expr::Pi(
124 BinderInfo::Default,
125 Name::str("f"),
126 Box::new(Expr::Pi(
127 BinderInfo::Default,
128 Name::str("_"),
129 Box::new(Expr::BVar(2)),
130 Box::new(Expr::BVar(1)),
131 )),
132 Box::new(Expr::Pi(
133 BinderInfo::Default,
134 Name::str("g"),
135 Box::new(Expr::Pi(
136 BinderInfo::Default,
137 Name::str("_"),
138 Box::new(Expr::BVar(2)),
139 Box::new(Expr::BVar(2)),
140 )),
141 Box::new(Expr::Pi(
142 BinderInfo::Default,
143 Name::str("s"),
144 Box::new(Expr::App(
145 Box::new(Expr::App(
146 Box::new(Expr::Const(Name::str("Sum"), vec![])),
147 Box::new(Expr::BVar(4)),
148 )),
149 Box::new(Expr::BVar(3)),
150 )),
151 Box::new(Expr::BVar(3)),
152 )),
153 )),
154 )),
155 )),
156 )),
157 );
158 env.add(Declaration::Axiom {
159 name: Name::str("Sum.elim"),
160 univ_params: vec![],
161 ty: elim_ty,
162 })
163 .map_err(|e| e.to_string())?;
164 let map_ty = Expr::Pi(
165 BinderInfo::Implicit,
166 Name::str("α"),
167 Box::new(type1.clone()),
168 Box::new(Expr::Pi(
169 BinderInfo::Implicit,
170 Name::str("β"),
171 Box::new(type1.clone()),
172 Box::new(Expr::Pi(
173 BinderInfo::Implicit,
174 Name::str("γ"),
175 Box::new(type1.clone()),
176 Box::new(Expr::Pi(
177 BinderInfo::Implicit,
178 Name::str("δ"),
179 Box::new(type1.clone()),
180 Box::new(Expr::Pi(
181 BinderInfo::Default,
182 Name::str("f"),
183 Box::new(Expr::Pi(
184 BinderInfo::Default,
185 Name::str("_"),
186 Box::new(Expr::BVar(3)),
187 Box::new(Expr::BVar(2)),
188 )),
189 Box::new(Expr::Pi(
190 BinderInfo::Default,
191 Name::str("g"),
192 Box::new(Expr::Pi(
193 BinderInfo::Default,
194 Name::str("_"),
195 Box::new(Expr::BVar(3)),
196 Box::new(Expr::BVar(2)),
197 )),
198 Box::new(Expr::Pi(
199 BinderInfo::Default,
200 Name::str("s"),
201 Box::new(Expr::App(
202 Box::new(Expr::App(
203 Box::new(Expr::Const(Name::str("Sum"), vec![])),
204 Box::new(Expr::BVar(5)),
205 )),
206 Box::new(Expr::BVar(4)),
207 )),
208 Box::new(Expr::App(
209 Box::new(Expr::App(
210 Box::new(Expr::Const(Name::str("Sum"), vec![])),
211 Box::new(Expr::BVar(4)),
212 )),
213 Box::new(Expr::BVar(3)),
214 )),
215 )),
216 )),
217 )),
218 )),
219 )),
220 )),
221 );
222 env.add(Declaration::Axiom {
223 name: Name::str("Sum.map"),
224 univ_params: vec![],
225 ty: map_ty,
226 })
227 .map_err(|e| e.to_string())?;
228 let swap_ty = Expr::Pi(
229 BinderInfo::Implicit,
230 Name::str("α"),
231 Box::new(type1.clone()),
232 Box::new(Expr::Pi(
233 BinderInfo::Implicit,
234 Name::str("β"),
235 Box::new(type1.clone()),
236 Box::new(Expr::Pi(
237 BinderInfo::Default,
238 Name::str("s"),
239 Box::new(Expr::App(
240 Box::new(Expr::App(
241 Box::new(Expr::Const(Name::str("Sum"), vec![])),
242 Box::new(Expr::BVar(1)),
243 )),
244 Box::new(Expr::BVar(0)),
245 )),
246 Box::new(Expr::App(
247 Box::new(Expr::App(
248 Box::new(Expr::Const(Name::str("Sum"), vec![])),
249 Box::new(Expr::BVar(1)),
250 )),
251 Box::new(Expr::BVar(2)),
252 )),
253 )),
254 )),
255 );
256 env.add(Declaration::Axiom {
257 name: Name::str("Sum.swap"),
258 univ_params: vec![],
259 ty: swap_ty,
260 })
261 .map_err(|e| e.to_string())?;
262 let is_left_ty = Expr::Pi(
263 BinderInfo::Implicit,
264 Name::str("α"),
265 Box::new(type1.clone()),
266 Box::new(Expr::Pi(
267 BinderInfo::Implicit,
268 Name::str("β"),
269 Box::new(type1.clone()),
270 Box::new(Expr::Pi(
271 BinderInfo::Default,
272 Name::str("s"),
273 Box::new(Expr::App(
274 Box::new(Expr::App(
275 Box::new(Expr::Const(Name::str("Sum"), vec![])),
276 Box::new(Expr::BVar(1)),
277 )),
278 Box::new(Expr::BVar(0)),
279 )),
280 Box::new(Expr::Const(Name::str("Bool"), vec![])),
281 )),
282 )),
283 );
284 env.add(Declaration::Axiom {
285 name: Name::str("Sum.isLeft"),
286 univ_params: vec![],
287 ty: is_left_ty.clone(),
288 })
289 .map_err(|e| e.to_string())?;
290 env.add(Declaration::Axiom {
291 name: Name::str("Sum.isRight"),
292 univ_params: vec![],
293 ty: is_left_ty,
294 })
295 .map_err(|e| e.to_string())?;
296 Ok(())
297}
298pub fn partition<A, B>(xs: Vec<Coproduct<A, B>>) -> (Vec<A>, Vec<B>) {
300 let mut lefts = Vec::new();
301 let mut rights = Vec::new();
302 for x in xs {
303 match x {
304 Coproduct::Inl(a) => lefts.push(a),
305 Coproduct::Inr(b) => rights.push(b),
306 }
307 }
308 (lefts, rights)
309}
310pub fn lefts<A: Clone, B>(xs: &[Coproduct<A, B>]) -> Vec<A> {
312 xs.iter()
313 .filter_map(|c| match c {
314 Coproduct::Inl(a) => Some(a.clone()),
315 _ => None,
316 })
317 .collect()
318}
319pub fn rights<A, B: Clone>(xs: &[Coproduct<A, B>]) -> Vec<B> {
321 xs.iter()
322 .filter_map(|c| match c {
323 Coproduct::Inr(b) => Some(b.clone()),
324 _ => None,
325 })
326 .collect()
327}
328pub fn try_map<A, C, E>(xs: Vec<A>, f: impl Fn(A) -> Result<C, E>) -> Vec<Coproduct<E, C>> {
330 xs.into_iter()
331 .map(|a| match f(a) {
332 Ok(c) => Coproduct::Inr(c),
333 Err(e) => Coproduct::Inl(e),
334 })
335 .collect()
336}
337pub trait Bifunctor {
339 type Left;
341 type Right;
343 type Mapped<C, D>;
345 fn bimap_trait<C, D>(
347 self,
348 f: impl FnOnce(Self::Left) -> C,
349 g: impl FnOnce(Self::Right) -> D,
350 ) -> Self::Mapped<C, D>;
351}
352pub fn distribute_left<A: Clone, B, C>(
354 s: Coproduct<Pair<A, B>, Pair<A, C>>,
355) -> Pair<A, Coproduct<B, C>> {
356 match s {
357 Coproduct::Inl(Pair { fst: a, snd: b }) => Pair {
358 fst: a,
359 snd: Coproduct::Inl(b),
360 },
361 Coproduct::Inr(Pair { fst: a, snd: c }) => Pair {
362 fst: a,
363 snd: Coproduct::Inr(c),
364 },
365 }
366}
367pub fn factor_left<A: Clone, B, C>(
369 p: Pair<A, Coproduct<B, C>>,
370) -> Coproduct<Pair<A, B>, Pair<A, C>> {
371 let Pair { fst: a, snd: s } = p;
372 match s {
373 Coproduct::Inl(b) => Coproduct::Inl(Pair { fst: a, snd: b }),
374 Coproduct::Inr(c) => Coproduct::Inr(Pair { fst: a, snd: c }),
375 }
376}
377pub fn make_sum_inl(alpha: Expr, beta: Expr, a: Expr) -> Expr {
379 let base = Expr::Const(Name::str("Sum.inl"), vec![]);
380 let e1 = Expr::App(Box::new(base), Box::new(alpha));
381 let e2 = Expr::App(Box::new(e1), Box::new(beta));
382 Expr::App(Box::new(e2), Box::new(a))
383}
384pub fn make_sum_inr(alpha: Expr, beta: Expr, b: Expr) -> Expr {
386 let base = Expr::Const(Name::str("Sum.inr"), vec![]);
387 let e1 = Expr::App(Box::new(base), Box::new(alpha));
388 let e2 = Expr::App(Box::new(e1), Box::new(beta));
389 Expr::App(Box::new(e2), Box::new(b))
390}
391pub fn make_sum_type(alpha: Expr, beta: Expr) -> Expr {
393 Expr::App(
394 Box::new(Expr::App(
395 Box::new(Expr::Const(Name::str("Sum"), vec![])),
396 Box::new(alpha),
397 )),
398 Box::new(beta),
399 )
400}
401pub fn registered_sum_names(env: &Environment) -> Vec<String> {
403 let candidates = [
404 "Sum",
405 "Sum.inl",
406 "Sum.inr",
407 "Sum.elim",
408 "Sum.map",
409 "Sum.swap",
410 "Sum.isLeft",
411 "Sum.isRight",
412 ];
413 candidates
414 .iter()
415 .filter(|n| env.get(&Name::str(**n)).is_some())
416 .map(|s| s.to_string())
417 .collect()
418}
419#[cfg(test)]
420mod tests {
421 use super::*;
422 fn setup_env() -> (Environment, InductiveEnv) {
423 let mut env = Environment::new();
424 let ind_env = InductiveEnv::new();
425 let type1 = Expr::Sort(Level::succ(Level::zero()));
426 env.add(Declaration::Axiom {
427 name: Name::str("Bool"),
428 univ_params: vec![],
429 ty: type1,
430 })
431 .expect("operation should succeed");
432 (env, ind_env)
433 }
434 #[test]
435 fn test_build_sum_env() {
436 let (mut env, mut ind_env) = setup_env();
437 assert!(build_sum_env(&mut env, &mut ind_env).is_ok());
438 assert!(env.get(&Name::str("Sum")).is_some());
439 assert!(env.get(&Name::str("Sum.inl")).is_some());
440 assert!(env.get(&Name::str("Sum.inr")).is_some());
441 }
442 #[test]
443 fn test_sum_inl() {
444 let (mut env, mut ind_env) = setup_env();
445 build_sum_env(&mut env, &mut ind_env).expect("build_sum_env should succeed");
446 let inl_decl = env
447 .get(&Name::str("Sum.inl"))
448 .expect("declaration 'Sum.inl' should exist in env");
449 assert!(matches!(inl_decl, Declaration::Axiom { .. }));
450 }
451 #[test]
452 fn test_sum_inr() {
453 let (mut env, mut ind_env) = setup_env();
454 build_sum_env(&mut env, &mut ind_env).expect("build_sum_env should succeed");
455 let inr_decl = env
456 .get(&Name::str("Sum.inr"))
457 .expect("declaration 'Sum.inr' should exist in env");
458 assert!(matches!(inr_decl, Declaration::Axiom { .. }));
459 }
460 #[test]
461 fn test_sum_combinators_registered() {
462 let (mut env, mut ind_env) = setup_env();
463 build_sum_env(&mut env, &mut ind_env).expect("build_sum_env should succeed");
464 assert!(env.get(&Name::str("Sum.elim")).is_some());
465 assert!(env.get(&Name::str("Sum.map")).is_some());
466 assert!(env.get(&Name::str("Sum.swap")).is_some());
467 assert!(env.get(&Name::str("Sum.isLeft")).is_some());
468 assert!(env.get(&Name::str("Sum.isRight")).is_some());
469 }
470 #[test]
471 fn test_coproduct_inl() {
472 let c: Coproduct<i32, &str> = Coproduct::inl(42);
473 assert!(c.is_left());
474 assert!(!c.is_right());
475 }
476 #[test]
477 fn test_coproduct_inr() {
478 let c: Coproduct<i32, &str> = Coproduct::inr("hello");
479 assert!(c.is_right());
480 assert!(!c.is_left());
481 }
482 #[test]
483 fn test_coproduct_elim() {
484 let l: Coproduct<i32, &str> = Coproduct::inl(5);
485 let r: Coproduct<i32, &str> = Coproduct::inr("hi");
486 assert_eq!(l.elim(|n| n * 2, |s| s.len() as i32), 10);
487 assert_eq!(r.elim(|n| n * 2, |s| s.len() as i32), 2);
488 }
489 #[test]
490 fn test_coproduct_swap() {
491 let c: Coproduct<i32, &str> = Coproduct::inl(3);
492 let swapped = c.swap();
493 assert!(swapped.is_right());
494 assert_eq!(swapped.into_right(), Some(3));
495 }
496 #[test]
497 fn test_coproduct_bimap() {
498 let c: Coproduct<i32, &str> = Coproduct::inl(5);
499 let mapped = c.bimap(|n| n * 2, |s: &str| s.len());
500 assert_eq!(mapped.into_left(), Some(10));
501 let c2: Coproduct<i32, &str> = Coproduct::inr("hello");
502 let mapped2 = c2.bimap(|n| n * 2, |s: &str| s.len());
503 assert_eq!(mapped2.into_right(), Some(5));
504 }
505 #[test]
506 fn test_coproduct_map_left() {
507 let c: Coproduct<i32, &str> = Coproduct::inl(3);
508 let m = c.map_left(|n| n + 1);
509 assert_eq!(m.into_left(), Some(4));
510 }
511 #[test]
512 fn test_coproduct_map_right() {
513 let c: Coproduct<i32, &str> = Coproduct::inr("world");
514 let m = c.map_right(|s: &str| s.to_uppercase());
515 assert_eq!(m.into_right(), Some("WORLD".to_string()));
516 }
517 #[test]
518 fn test_coproduct_into_result() {
519 let l: Coproduct<String, i32> = Coproduct::inl("err".to_string());
520 let r: Coproduct<String, i32> = Coproduct::inr(42);
521 assert!(l.into_result().is_err());
522 assert_eq!(r.into_result().expect("into_result should succeed"), 42);
523 }
524 #[test]
525 fn test_coproduct_from_result() {
526 let ok: Result<i32, String> = Ok(5);
527 let err: Result<i32, String> = Err("oops".to_string());
528 assert!(Coproduct::from_result(ok).is_right());
529 assert!(Coproduct::from_result(err).is_left());
530 }
531 #[test]
532 fn test_partition() {
533 let xs: Vec<Coproduct<i32, &str>> = vec![
534 Coproduct::inl(1),
535 Coproduct::inr("a"),
536 Coproduct::inl(2),
537 Coproduct::inr("b"),
538 ];
539 let (ls, rs) = partition(xs);
540 assert_eq!(ls, vec![1, 2]);
541 assert_eq!(rs, vec!["a", "b"]);
542 }
543 #[test]
544 fn test_lefts_rights() {
545 let xs: Vec<Coproduct<i32, &str>> =
546 vec![Coproduct::inl(10), Coproduct::inr("x"), Coproduct::inl(20)];
547 assert_eq!(lefts(&xs), vec![10, 20]);
548 assert_eq!(rights(&xs), vec!["x"]);
549 }
550 #[test]
551 fn test_try_map() {
552 let xs = vec![2, 0, 4];
553 let result = try_map(xs, |n: i32| if n == 0 { Err("zero") } else { Ok(100 / n) });
554 assert!(result[0].is_right());
555 assert!(result[1].is_left());
556 assert!(result[2].is_right());
557 }
558 #[test]
559 fn test_sum3_elim() {
560 let s: Sum3<i32, &str, bool> = Sum3::In1(7);
561 let result = s.elim(
562 |n| n * 2,
563 |s: &str| s.len() as i32,
564 |b| if b { 1 } else { 0 },
565 );
566 assert_eq!(result, 14);
567 let s2: Sum3<i32, &str, bool> = Sum3::In3(true);
568 let result2 = s2.elim(
569 |n| n * 2,
570 |s: &str| s.len() as i32,
571 |b| if b { 1 } else { 0 },
572 );
573 assert_eq!(result2, 1);
574 }
575 #[test]
576 fn test_sum3_predicates() {
577 let s1: Sum3<i32, &str, bool> = Sum3::In1(1);
578 let s2: Sum3<i32, &str, bool> = Sum3::In2("hi");
579 let s3: Sum3<i32, &str, bool> = Sum3::In3(false);
580 assert!(s1.is_first());
581 assert!(s2.is_second());
582 assert!(s3.is_third());
583 }
584 #[test]
585 fn test_pair_operations() {
586 let p = Pair::new(1, "hello");
587 let swapped = p.swap();
588 assert_eq!(swapped.fst, "hello");
589 assert_eq!(swapped.snd, 1);
590 let p2 = Pair::new(3, 4);
591 let mapped = p2.map_fst(|n| n * 10);
592 assert_eq!(mapped.fst, 30);
593 assert_eq!(mapped.snd, 4);
594 }
595 #[test]
596 fn test_pair_tuple_round_trip() {
597 let p = Pair::from_tuple((42, "test"));
598 let t = p.into_tuple();
599 assert_eq!(t, (42, "test"));
600 }
601 #[test]
602 fn test_distribute_left() {
603 let s: Coproduct<Pair<i32, &str>, Pair<i32, bool>> = Coproduct::Inl(Pair::new(5, "hello"));
604 let p = distribute_left(s);
605 assert_eq!(p.fst, 5);
606 assert!(p.snd.is_left());
607 }
608 #[test]
609 fn test_factor_left() {
610 let p = Pair::new(10i32, Coproduct::<&str, bool>::Inr(true));
611 let s = factor_left(p);
612 assert!(s.is_right());
613 let inner = s.into_right().expect("into_right should succeed");
614 assert_eq!(inner.fst, 10);
615 }
616 #[test]
617 fn test_tagged_map() {
618 let t = Tagged::new("label", 5);
619 let t2 = t.map(|n| n * 2);
620 assert_eq!(t2.tag, "label");
621 assert_eq!(t2.value, 10);
622 }
623 #[test]
624 fn test_tagged_map_tag() {
625 let t = Tagged::new(1u32, "value");
626 let t2 = t.map_tag(|n| n.to_string());
627 assert_eq!(t2.tag, "1");
628 assert_eq!(t2.value, "value");
629 }
630 #[test]
631 fn test_make_sum_type_expr() {
632 let alpha = Expr::Const(Name::str("Nat"), vec![]);
633 let beta = Expr::Const(Name::str("Bool"), vec![]);
634 let sum_ty = make_sum_type(alpha, beta);
635 assert!(matches!(sum_ty, Expr::App(_, _)));
636 }
637 #[test]
638 fn test_registered_sum_names() {
639 let (mut env, mut ind_env) = setup_env();
640 build_sum_env(&mut env, &mut ind_env).expect("build_sum_env should succeed");
641 let names = registered_sum_names(&env);
642 assert!(names.contains(&"Sum".to_string()));
643 assert!(names.contains(&"Sum.inl".to_string()));
644 assert!(names.contains(&"Sum.inr".to_string()));
645 assert!(names.len() >= 5);
646 }
647}
648pub type SumResult<E, A> = Coproduct<E, A>;
650pub fn lift_result<A, E>(r: Result<A, E>) -> SumResult<E, A> {
652 Coproduct::from_result(r)
653}
654pub fn sequence_sum<A: Clone, E: Clone>(xs: Vec<SumResult<E, A>>) -> SumResult<E, Vec<A>> {
656 let mut results = Vec::new();
657 for x in xs {
658 match x {
659 Coproduct::Inl(e) => return Coproduct::Inl(e),
660 Coproduct::Inr(a) => results.push(a),
661 }
662 }
663 Coproduct::Inr(results)
664}
665pub fn traverse_sum<A, B: Clone, E: Clone>(
667 xs: Vec<A>,
668 f: impl Fn(A) -> SumResult<E, B>,
669) -> SumResult<E, Vec<B>> {
670 sequence_sum(xs.into_iter().map(f).collect())
671}
672#[cfg(test)]
673mod sum_extra_tests {
674 use super::*;
675 #[test]
676 fn test_sum_chain_map_right() {
677 let c: Coproduct<String, i32> = Coproduct::inr(5);
678 let chain = SumChain::new(c).map(|n| n * 2);
679 assert!(chain.is_ok());
680 assert_eq!(chain.into_inner().into_right(), Some(10));
681 }
682 #[test]
683 fn test_sum_chain_short_circuit_left() {
684 let c: Coproduct<String, i32> = Coproduct::inl("error".to_string());
685 let chain = SumChain::new(c).map(|n: i32| n * 2);
686 assert!(chain.is_err());
687 }
688 #[test]
689 fn test_sum_chain_flat_map() {
690 let c: Coproduct<String, i32> = Coproduct::inr(5);
691 let chain = SumChain::new(c).flat_map(|n| {
692 if n > 0 {
693 Coproduct::inr(n * 10)
694 } else {
695 Coproduct::inl("negative".to_string())
696 }
697 });
698 assert!(chain.is_ok());
699 assert_eq!(chain.into_inner().into_right(), Some(50));
700 }
701 #[test]
702 fn test_sum_stats_from_slice() {
703 let xs: Vec<Coproduct<i32, &str>> =
704 vec![Coproduct::inl(1), Coproduct::inr("a"), Coproduct::inl(2)];
705 let stats = SumStats::from_slice(&xs);
706 assert_eq!(stats.left_count, 2);
707 assert_eq!(stats.right_count, 1);
708 assert_eq!(stats.total(), 3);
709 }
710 #[test]
711 fn test_sum_stats_all_left() {
712 let xs: Vec<Coproduct<i32, &str>> = vec![Coproduct::inl(1), Coproduct::inl(2)];
713 let stats = SumStats::from_slice(&xs);
714 assert!(stats.all_left());
715 }
716 #[test]
717 fn test_sum_stats_all_right() {
718 let xs: Vec<Coproduct<i32, &str>> = vec![Coproduct::inr("x"), Coproduct::inr("y")];
719 let stats = SumStats::from_slice(&xs);
720 assert!(stats.all_right());
721 }
722 #[test]
723 fn test_sum4_elim() {
724 let s: Sum4<i32, &str, bool, f32> = Sum4::In3(true);
725 let result: i32 = s.elim(|n| n, |_| 0, |b| if b { 1 } else { 0 }, |_| -1);
726 assert_eq!(result, 1);
727 }
728 #[test]
729 fn test_sum4_tag() {
730 let s: Sum4<i32, &str, bool, f32> = Sum4::In2("hi");
731 assert_eq!(s.tag(), 2);
732 assert!(s.is_second());
733 }
734 #[test]
735 fn test_lift_result_ok() {
736 let r: Result<i32, String> = Ok(42);
737 assert!(lift_result(r).is_right());
738 }
739 #[test]
740 fn test_lift_result_err() {
741 let r: Result<i32, String> = Err("oops".to_string());
742 assert!(lift_result(r).is_left());
743 }
744 #[test]
745 fn test_sequence_sum_all_ok() {
746 let xs: Vec<SumResult<String, i32>> = vec![Coproduct::inr(1), Coproduct::inr(2)];
747 let result = sequence_sum(xs);
748 assert_eq!(result.into_right(), Some(vec![1, 2]));
749 }
750 #[test]
751 fn test_sequence_sum_first_error() {
752 let xs: Vec<SumResult<String, i32>> =
753 vec![Coproduct::inr(1), Coproduct::inl("err".to_string())];
754 let result = sequence_sum(xs);
755 assert!(result.is_left());
756 }
757 #[test]
758 fn test_traverse_sum_success() {
759 let xs = vec![1i32, 2, 3];
760 let result = traverse_sum(xs, |n| -> SumResult<String, i32> { Coproduct::inr(n * 2) });
761 assert_eq!(result.into_right(), Some(vec![2, 4, 6]));
762 }
763 #[test]
764 fn test_traverse_sum_error() {
765 let xs = vec![1i32, 0, 3];
766 let result = traverse_sum(xs, |n| -> SumResult<String, i32> {
767 if n == 0 {
768 Coproduct::inl("zero".to_string())
769 } else {
770 Coproduct::inr(100 / n)
771 }
772 });
773 assert!(result.is_left());
774 }
775 #[test]
776 fn test_injection_map() {
777 let mut map = InjectionMap::new();
778 map.register(1, "Left");
779 map.register(2, "Right");
780 assert_eq!(map.get(1), Some("Left"));
781 assert!(map.get(3).is_none());
782 assert_eq!(map.len(), 2);
783 }
784 #[test]
785 fn test_sum4_is_fourth() {
786 let s: Sum4<i32, &str, bool, f64> = Sum4::In4(2.72);
787 assert!(s.is_fourth());
788 assert!(!s.is_first());
789 }
790 #[test]
791 fn test_sum_chain_flat_map_short_circuit() {
792 let c: Coproduct<String, i32> = Coproduct::inr(-5);
793 let chain = SumChain::new(c).flat_map(|n| -> Coproduct<String, i32> {
794 if n > 0 {
795 Coproduct::inr(n)
796 } else {
797 Coproduct::inl("negative".to_string())
798 }
799 });
800 assert!(chain.is_err());
801 }
802}
803pub(super) fn sm_ext_sum_categorical_coproduct(env: &mut Environment) -> Result<(), String> {
805 use oxilean_kernel::{BinderInfo as Bi, Declaration, Expr, Level, Name};
806 let type1 = Expr::Sort(Level::succ(Level::zero()));
807 let prop = Expr::Sort(Level::zero());
808 let ty = Expr::Pi(
809 Bi::Implicit,
810 Name::str("A"),
811 Box::new(type1.clone()),
812 Box::new(Expr::Pi(
813 Bi::Implicit,
814 Name::str("B"),
815 Box::new(type1.clone()),
816 Box::new(Expr::Pi(
817 Bi::Implicit,
818 Name::str("Z"),
819 Box::new(type1),
820 Box::new(prop),
821 )),
822 )),
823 );
824 match env.add(Declaration::Axiom {
825 name: Name::str("Sum.categoricalCoproduct"),
826 univ_params: vec![],
827 ty,
828 }) {
829 Ok(()) | Err(_) => Ok(()),
830 }
831}
832pub(super) fn sm_ext_sum_universal_property(env: &mut Environment) -> Result<(), String> {
834 use oxilean_kernel::{BinderInfo as Bi, Declaration, Expr, Level, Name};
835 let type1 = Expr::Sort(Level::succ(Level::zero()));
836 let prop = Expr::Sort(Level::zero());
837 let ty = Expr::Pi(
838 Bi::Implicit,
839 Name::str("A"),
840 Box::new(type1.clone()),
841 Box::new(Expr::Pi(
842 Bi::Implicit,
843 Name::str("B"),
844 Box::new(type1.clone()),
845 Box::new(Expr::Pi(
846 Bi::Implicit,
847 Name::str("Z"),
848 Box::new(type1),
849 Box::new(Expr::Pi(
850 Bi::Default,
851 Name::str("f"),
852 Box::new(Expr::Pi(
853 Bi::Default,
854 Name::str("_"),
855 Box::new(Expr::BVar(2)),
856 Box::new(Expr::BVar(1)),
857 )),
858 Box::new(Expr::Pi(
859 Bi::Default,
860 Name::str("g"),
861 Box::new(Expr::Pi(
862 Bi::Default,
863 Name::str("_"),
864 Box::new(Expr::BVar(2)),
865 Box::new(Expr::BVar(2)),
866 )),
867 Box::new(prop),
868 )),
869 )),
870 )),
871 )),
872 );
873 match env.add(Declaration::Axiom {
874 name: Name::str("Sum.universalProperty"),
875 univ_params: vec![],
876 ty,
877 }) {
878 Ok(()) | Err(_) => Ok(()),
879 }
880}
881pub(super) fn sm_ext_inl_injective(env: &mut Environment) -> Result<(), String> {
883 use oxilean_kernel::{BinderInfo as Bi, Declaration, Expr, Level, Name};
884 let type1 = Expr::Sort(Level::succ(Level::zero()));
885 let prop = Expr::Sort(Level::zero());
886 let ty = Expr::Pi(
887 Bi::Implicit,
888 Name::str("A"),
889 Box::new(type1.clone()),
890 Box::new(Expr::Pi(
891 Bi::Implicit,
892 Name::str("B"),
893 Box::new(type1),
894 Box::new(Expr::Pi(
895 Bi::Default,
896 Name::str("a1"),
897 Box::new(Expr::BVar(1)),
898 Box::new(Expr::Pi(
899 Bi::Default,
900 Name::str("a2"),
901 Box::new(Expr::BVar(2)),
902 Box::new(prop),
903 )),
904 )),
905 )),
906 );
907 match env.add(Declaration::Axiom {
908 name: Name::str("Sum.inlInjective"),
909 univ_params: vec![],
910 ty,
911 }) {
912 Ok(()) | Err(_) => Ok(()),
913 }
914}
915pub(super) fn sm_ext_inr_injective(env: &mut Environment) -> Result<(), String> {
917 use oxilean_kernel::{BinderInfo as Bi, Declaration, Expr, Level, Name};
918 let type1 = Expr::Sort(Level::succ(Level::zero()));
919 let prop = Expr::Sort(Level::zero());
920 let ty = Expr::Pi(
921 Bi::Implicit,
922 Name::str("A"),
923 Box::new(type1.clone()),
924 Box::new(Expr::Pi(
925 Bi::Implicit,
926 Name::str("B"),
927 Box::new(type1),
928 Box::new(Expr::Pi(
929 Bi::Default,
930 Name::str("b1"),
931 Box::new(Expr::BVar(0)),
932 Box::new(Expr::Pi(
933 Bi::Default,
934 Name::str("b2"),
935 Box::new(Expr::BVar(1)),
936 Box::new(prop),
937 )),
938 )),
939 )),
940 );
941 match env.add(Declaration::Axiom {
942 name: Name::str("Sum.inrInjective"),
943 univ_params: vec![],
944 ty,
945 }) {
946 Ok(()) | Err(_) => Ok(()),
947 }
948}
949pub(super) fn sm_ext_inl_inr_disjoint(env: &mut Environment) -> Result<(), String> {
951 use oxilean_kernel::{BinderInfo as Bi, Declaration, Expr, Level, Name};
952 let type1 = Expr::Sort(Level::succ(Level::zero()));
953 let prop = Expr::Sort(Level::zero());
954 let ty = Expr::Pi(
955 Bi::Implicit,
956 Name::str("A"),
957 Box::new(type1.clone()),
958 Box::new(Expr::Pi(
959 Bi::Implicit,
960 Name::str("B"),
961 Box::new(type1),
962 Box::new(Expr::Pi(
963 Bi::Default,
964 Name::str("a"),
965 Box::new(Expr::BVar(1)),
966 Box::new(Expr::Pi(
967 Bi::Default,
968 Name::str("b"),
969 Box::new(Expr::BVar(1)),
970 Box::new(prop),
971 )),
972 )),
973 )),
974 );
975 match env.add(Declaration::Axiom {
976 name: Name::str("Sum.inlInrDisjoint"),
977 univ_params: vec![],
978 ty,
979 }) {
980 Ok(()) | Err(_) => Ok(()),
981 }
982}
983pub(super) fn sm_ext_sum_functor_id(env: &mut Environment) -> Result<(), String> {
985 use oxilean_kernel::{BinderInfo as Bi, Declaration, Expr, Level, Name};
986 let type1 = Expr::Sort(Level::succ(Level::zero()));
987 let prop = Expr::Sort(Level::zero());
988 let ty = Expr::Pi(
989 Bi::Implicit,
990 Name::str("A"),
991 Box::new(type1.clone()),
992 Box::new(Expr::Pi(
993 Bi::Implicit,
994 Name::str("B"),
995 Box::new(type1),
996 Box::new(prop),
997 )),
998 );
999 match env.add(Declaration::Axiom {
1000 name: Name::str("Sum.functorId"),
1001 univ_params: vec![],
1002 ty,
1003 }) {
1004 Ok(()) | Err(_) => Ok(()),
1005 }
1006}
1007pub(super) fn sm_ext_sum_functor_compose(env: &mut Environment) -> Result<(), String> {
1009 use oxilean_kernel::{Declaration, Expr, Name};
1010 let prop = Expr::Sort(oxilean_kernel::Level::zero());
1011 match env.add(Declaration::Axiom {
1012 name: Name::str("Sum.functorCompose"),
1013 univ_params: vec![],
1014 ty: prop,
1015 }) {
1016 Ok(()) | Err(_) => Ok(()),
1017 }
1018}
1019pub(super) fn sm_ext_sum_bifunctor_id(env: &mut Environment) -> Result<(), String> {
1021 use oxilean_kernel::{Declaration, Expr, Name};
1022 let prop = Expr::Sort(oxilean_kernel::Level::zero());
1023 match env.add(Declaration::Axiom {
1024 name: Name::str("Sum.bifunctorId"),
1025 univ_params: vec![],
1026 ty: prop,
1027 }) {
1028 Ok(()) | Err(_) => Ok(()),
1029 }
1030}
1031pub(super) fn sm_ext_sum_monad_return(env: &mut Environment) -> Result<(), String> {
1033 use oxilean_kernel::{BinderInfo as Bi, Declaration, Expr, Level, Name};
1034 let type1 = Expr::Sort(Level::succ(Level::zero()));
1035 let ty = Expr::Pi(
1036 Bi::Implicit,
1037 Name::str("E"),
1038 Box::new(type1.clone()),
1039 Box::new(Expr::Pi(
1040 Bi::Implicit,
1041 Name::str("A"),
1042 Box::new(type1),
1043 Box::new(Expr::Pi(
1044 Bi::Default,
1045 Name::str("a"),
1046 Box::new(Expr::BVar(0)),
1047 Box::new(Expr::App(
1048 Box::new(Expr::App(
1049 Box::new(Expr::Const(Name::str("Sum"), vec![])),
1050 Box::new(Expr::BVar(2)),
1051 )),
1052 Box::new(Expr::BVar(1)),
1053 )),
1054 )),
1055 )),
1056 );
1057 match env.add(Declaration::Axiom {
1058 name: Name::str("Sum.monadReturn"),
1059 univ_params: vec![],
1060 ty,
1061 }) {
1062 Ok(()) | Err(_) => Ok(()),
1063 }
1064}
1065pub(super) fn sm_ext_sum_monad_bind(env: &mut Environment) -> Result<(), String> {
1067 use oxilean_kernel::{Declaration, Expr, Name};
1068 let prop = Expr::Sort(oxilean_kernel::Level::zero());
1069 match env.add(Declaration::Axiom {
1070 name: Name::str("Sum.monadBind"),
1071 univ_params: vec![],
1072 ty: prop,
1073 }) {
1074 Ok(()) | Err(_) => Ok(()),
1075 }
1076}
1077pub(super) fn sm_ext_sum_monad_left_id(env: &mut Environment) -> Result<(), String> {
1079 use oxilean_kernel::{Declaration, Expr, Name};
1080 let prop = Expr::Sort(oxilean_kernel::Level::zero());
1081 match env.add(Declaration::Axiom {
1082 name: Name::str("Sum.monadLeftId"),
1083 univ_params: vec![],
1084 ty: prop,
1085 }) {
1086 Ok(()) | Err(_) => Ok(()),
1087 }
1088}
1089pub(super) fn sm_ext_sum_monad_right_id(env: &mut Environment) -> Result<(), String> {
1091 use oxilean_kernel::{Declaration, Expr, Name};
1092 let prop = Expr::Sort(oxilean_kernel::Level::zero());
1093 match env.add(Declaration::Axiom {
1094 name: Name::str("Sum.monadRightId"),
1095 univ_params: vec![],
1096 ty: prop,
1097 }) {
1098 Ok(()) | Err(_) => Ok(()),
1099 }
1100}
1101pub(super) fn sm_ext_sum_monad_assoc(env: &mut Environment) -> Result<(), String> {
1103 use oxilean_kernel::{Declaration, Expr, Name};
1104 let prop = Expr::Sort(oxilean_kernel::Level::zero());
1105 match env.add(Declaration::Axiom {
1106 name: Name::str("Sum.monadAssoc"),
1107 univ_params: vec![],
1108 ty: prop,
1109 }) {
1110 Ok(()) | Err(_) => Ok(()),
1111 }
1112}
1113pub(super) fn sm_ext_sum_applicative_pure(env: &mut Environment) -> Result<(), String> {
1115 use oxilean_kernel::{BinderInfo as Bi, Declaration, Expr, Level, Name};
1116 let type1 = Expr::Sort(Level::succ(Level::zero()));
1117 let ty = Expr::Pi(
1118 Bi::Implicit,
1119 Name::str("E"),
1120 Box::new(type1.clone()),
1121 Box::new(Expr::Pi(
1122 Bi::Implicit,
1123 Name::str("A"),
1124 Box::new(type1),
1125 Box::new(Expr::Pi(
1126 Bi::Default,
1127 Name::str("a"),
1128 Box::new(Expr::BVar(0)),
1129 Box::new(Expr::App(
1130 Box::new(Expr::App(
1131 Box::new(Expr::Const(Name::str("Sum"), vec![])),
1132 Box::new(Expr::BVar(2)),
1133 )),
1134 Box::new(Expr::BVar(1)),
1135 )),
1136 )),
1137 )),
1138 );
1139 match env.add(Declaration::Axiom {
1140 name: Name::str("Sum.applicativePure"),
1141 univ_params: vec![],
1142 ty,
1143 }) {
1144 Ok(()) | Err(_) => Ok(()),
1145 }
1146}
1147pub(super) fn sm_ext_sum_applicative_ap(env: &mut Environment) -> Result<(), String> {
1149 use oxilean_kernel::{Declaration, Expr, Name};
1150 let prop = Expr::Sort(oxilean_kernel::Level::zero());
1151 match env.add(Declaration::Axiom {
1152 name: Name::str("Sum.applicativeAp"),
1153 univ_params: vec![],
1154 ty: prop,
1155 }) {
1156 Ok(()) | Err(_) => Ok(()),
1157 }
1158}
1159pub(super) fn sm_ext_sum_swap_involution(env: &mut Environment) -> Result<(), String> {
1161 use oxilean_kernel::{BinderInfo as Bi, Declaration, Expr, Level, Name};
1162 let type1 = Expr::Sort(Level::succ(Level::zero()));
1163 let prop = Expr::Sort(Level::zero());
1164 let sum_ab = Expr::App(
1165 Box::new(Expr::App(
1166 Box::new(Expr::Const(Name::str("Sum"), vec![])),
1167 Box::new(Expr::BVar(1)),
1168 )),
1169 Box::new(Expr::BVar(0)),
1170 );
1171 let ty = Expr::Pi(
1172 Bi::Implicit,
1173 Name::str("A"),
1174 Box::new(type1.clone()),
1175 Box::new(Expr::Pi(
1176 Bi::Implicit,
1177 Name::str("B"),
1178 Box::new(type1),
1179 Box::new(Expr::Pi(
1180 Bi::Default,
1181 Name::str("s"),
1182 Box::new(sum_ab),
1183 Box::new(prop),
1184 )),
1185 )),
1186 );
1187 match env.add(Declaration::Axiom {
1188 name: Name::str("Sum.swapInvolution"),
1189 univ_params: vec![],
1190 ty,
1191 }) {
1192 Ok(()) | Err(_) => Ok(()),
1193 }
1194}
1195pub(super) fn sm_ext_sum_assoc_iso(env: &mut Environment) -> Result<(), String> {
1197 use oxilean_kernel::{BinderInfo as Bi, Declaration, Expr, Level, Name};
1198 let type1 = Expr::Sort(Level::succ(Level::zero()));
1199 let ty = Expr::Pi(
1200 Bi::Implicit,
1201 Name::str("A"),
1202 Box::new(type1.clone()),
1203 Box::new(Expr::Pi(
1204 Bi::Implicit,
1205 Name::str("B"),
1206 Box::new(type1.clone()),
1207 Box::new(Expr::Pi(
1208 Bi::Implicit,
1209 Name::str("C"),
1210 Box::new(type1),
1211 Box::new(Expr::Const(Name::str("Prop"), vec![])),
1212 )),
1213 )),
1214 );
1215 match env.add(Declaration::Axiom {
1216 name: Name::str("Sum.assocIso"),
1217 univ_params: vec![],
1218 ty,
1219 }) {
1220 Ok(()) | Err(_) => Ok(()),
1221 }
1222}
1223pub(super) fn sm_ext_sum_void_initial(env: &mut Environment) -> Result<(), String> {
1225 use oxilean_kernel::{BinderInfo as Bi, Declaration, Expr, Level, Name};
1226 let type1 = Expr::Sort(Level::succ(Level::zero()));
1227 let ty = Expr::Pi(
1228 Bi::Implicit,
1229 Name::str("A"),
1230 Box::new(type1),
1231 Box::new(Expr::Const(Name::str("Prop"), vec![])),
1232 );
1233 match env.add(Declaration::Axiom {
1234 name: Name::str("Sum.voidInitial"),
1235 univ_params: vec![],
1236 ty,
1237 }) {
1238 Ok(()) | Err(_) => Ok(()),
1239 }
1240}
1241pub(super) fn sm_ext_sum_distributes_over_prod(env: &mut Environment) -> Result<(), String> {
1243 use oxilean_kernel::{BinderInfo as Bi, Declaration, Expr, Level, Name};
1244 let type1 = Expr::Sort(Level::succ(Level::zero()));
1245 let ty = Expr::Pi(
1246 Bi::Implicit,
1247 Name::str("A"),
1248 Box::new(type1.clone()),
1249 Box::new(Expr::Pi(
1250 Bi::Implicit,
1251 Name::str("B"),
1252 Box::new(type1.clone()),
1253 Box::new(Expr::Pi(
1254 Bi::Implicit,
1255 Name::str("C"),
1256 Box::new(type1),
1257 Box::new(Expr::Const(Name::str("Prop"), vec![])),
1258 )),
1259 )),
1260 );
1261 match env.add(Declaration::Axiom {
1262 name: Name::str("Sum.distributesOverProd"),
1263 univ_params: vec![],
1264 ty,
1265 }) {
1266 Ok(()) | Err(_) => Ok(()),
1267 }
1268}
1269pub(super) fn sm_ext_sum_disjoint_union(env: &mut Environment) -> Result<(), String> {
1271 use oxilean_kernel::{BinderInfo as Bi, Declaration, Expr, Level, Name};
1272 let type1 = Expr::Sort(Level::succ(Level::zero()));
1273 let prop = Expr::Sort(Level::zero());
1274 let sum_ab = Expr::App(
1275 Box::new(Expr::App(
1276 Box::new(Expr::Const(Name::str("Sum"), vec![])),
1277 Box::new(Expr::BVar(1)),
1278 )),
1279 Box::new(Expr::BVar(0)),
1280 );
1281 let ty = Expr::Pi(
1282 Bi::Implicit,
1283 Name::str("A"),
1284 Box::new(type1.clone()),
1285 Box::new(Expr::Pi(
1286 Bi::Implicit,
1287 Name::str("B"),
1288 Box::new(type1),
1289 Box::new(Expr::Pi(
1290 Bi::Default,
1291 Name::str("s"),
1292 Box::new(sum_ab),
1293 Box::new(prop),
1294 )),
1295 )),
1296 );
1297 match env.add(Declaration::Axiom {
1298 name: Name::str("Sum.disjointUnion"),
1299 univ_params: vec![],
1300 ty,
1301 }) {
1302 Ok(()) | Err(_) => Ok(()),
1303 }
1304}
1305pub(super) fn sm_ext_sum_case_analysis(env: &mut Environment) -> Result<(), String> {
1307 use oxilean_kernel::{BinderInfo as Bi, Declaration, Expr, Level, Name};
1308 let type1 = Expr::Sort(Level::succ(Level::zero()));
1309 let prop = Expr::Sort(Level::zero());
1310 let ty = Expr::Pi(
1311 Bi::Implicit,
1312 Name::str("A"),
1313 Box::new(type1.clone()),
1314 Box::new(Expr::Pi(
1315 Bi::Implicit,
1316 Name::str("B"),
1317 Box::new(type1.clone()),
1318 Box::new(Expr::Pi(
1319 Bi::Implicit,
1320 Name::str("P"),
1321 Box::new(Expr::Pi(
1322 Bi::Default,
1323 Name::str("_"),
1324 Box::new(Expr::App(
1325 Box::new(Expr::App(
1326 Box::new(Expr::Const(Name::str("Sum"), vec![])),
1327 Box::new(Expr::BVar(1)),
1328 )),
1329 Box::new(Expr::BVar(0)),
1330 )),
1331 Box::new(type1.clone()),
1332 )),
1333 Box::new(Expr::Pi(
1334 Bi::Default,
1335 Name::str("hl"),
1336 Box::new(Expr::Pi(
1337 Bi::Default,
1338 Name::str("a"),
1339 Box::new(Expr::BVar(2)),
1340 Box::new(prop.clone()),
1341 )),
1342 Box::new(Expr::Pi(
1343 Bi::Default,
1344 Name::str("hr"),
1345 Box::new(Expr::Pi(
1346 Bi::Default,
1347 Name::str("b"),
1348 Box::new(Expr::BVar(2)),
1349 Box::new(prop.clone()),
1350 )),
1351 Box::new(Expr::Pi(
1352 Bi::Default,
1353 Name::str("s"),
1354 Box::new(Expr::App(
1355 Box::new(Expr::App(
1356 Box::new(Expr::Const(Name::str("Sum"), vec![])),
1357 Box::new(Expr::BVar(4)),
1358 )),
1359 Box::new(Expr::BVar(3)),
1360 )),
1361 Box::new(prop),
1362 )),
1363 )),
1364 )),
1365 )),
1366 )),
1367 );
1368 match env.add(Declaration::Axiom {
1369 name: Name::str("Sum.caseAnalysis"),
1370 univ_params: vec![],
1371 ty,
1372 }) {
1373 Ok(()) | Err(_) => Ok(()),
1374 }
1375}
1376pub(super) fn sm_ext_tagged_union_semantics(env: &mut Environment) -> Result<(), String> {
1378 use oxilean_kernel::{Declaration, Expr, Name};
1379 let prop = Expr::Sort(oxilean_kernel::Level::zero());
1380 match env.add(Declaration::Axiom {
1381 name: Name::str("Sum.taggedUnionSemantics"),
1382 univ_params: vec![],
1383 ty: prop,
1384 }) {
1385 Ok(()) | Err(_) => Ok(()),
1386 }
1387}
1388pub(super) fn sm_ext_sum_partition_complete(env: &mut Environment) -> Result<(), String> {
1390 use oxilean_kernel::{Declaration, Expr, Name};
1391 let prop = Expr::Sort(oxilean_kernel::Level::zero());
1392 match env.add(Declaration::Axiom {
1393 name: Name::str("Sum.partitionComplete"),
1394 univ_params: vec![],
1395 ty: prop,
1396 }) {
1397 Ok(()) | Err(_) => Ok(()),
1398 }
1399}
1400pub(super) fn sm_ext_sum_lefts_count(env: &mut Environment) -> Result<(), String> {
1402 use oxilean_kernel::{Declaration, Expr, Name};
1403 let prop = Expr::Sort(oxilean_kernel::Level::zero());
1404 match env.add(Declaration::Axiom {
1405 name: Name::str("Sum.leftsCount"),
1406 univ_params: vec![],
1407 ty: prop,
1408 }) {
1409 Ok(()) | Err(_) => Ok(()),
1410 }
1411}
1412pub(super) fn sm_ext_sum_traversal_naturality(env: &mut Environment) -> Result<(), String> {
1414 use oxilean_kernel::{Declaration, Expr, Name};
1415 let prop = Expr::Sort(oxilean_kernel::Level::zero());
1416 match env.add(Declaration::Axiom {
1417 name: Name::str("Sum.traversalNaturality"),
1418 univ_params: vec![],
1419 ty: prop,
1420 }) {
1421 Ok(()) | Err(_) => Ok(()),
1422 }
1423}
1424pub(super) fn sm_ext_sum_traversal_id(env: &mut Environment) -> Result<(), String> {
1426 use oxilean_kernel::{Declaration, Expr, Name};
1427 let prop = Expr::Sort(oxilean_kernel::Level::zero());
1428 match env.add(Declaration::Axiom {
1429 name: Name::str("Sum.traversalId"),
1430 univ_params: vec![],
1431 ty: prop,
1432 }) {
1433 Ok(()) | Err(_) => Ok(()),
1434 }
1435}
1436pub(super) fn sm_ext_sum_path_space(env: &mut Environment) -> Result<(), String> {
1438 use oxilean_kernel::{BinderInfo as Bi, Declaration, Expr, Level, Name};
1439 let type1 = Expr::Sort(Level::succ(Level::zero()));
1440 let prop = Expr::Sort(Level::zero());
1441 let sum_ab = Expr::App(
1442 Box::new(Expr::App(
1443 Box::new(Expr::Const(Name::str("Sum"), vec![])),
1444 Box::new(Expr::BVar(1)),
1445 )),
1446 Box::new(Expr::BVar(0)),
1447 );
1448 let ty = Expr::Pi(
1449 Bi::Implicit,
1450 Name::str("A"),
1451 Box::new(type1.clone()),
1452 Box::new(Expr::Pi(
1453 Bi::Implicit,
1454 Name::str("B"),
1455 Box::new(type1),
1456 Box::new(Expr::Pi(
1457 Bi::Default,
1458 Name::str("s"),
1459 Box::new(sum_ab.clone()),
1460 Box::new(Expr::Pi(
1461 Bi::Default,
1462 Name::str("t"),
1463 Box::new(sum_ab),
1464 Box::new(prop),
1465 )),
1466 )),
1467 )),
1468 );
1469 match env.add(Declaration::Axiom {
1470 name: Name::str("Sum.pathSpace"),
1471 univ_params: vec![],
1472 ty,
1473 }) {
1474 Ok(()) | Err(_) => Ok(()),
1475 }
1476}
1477pub(super) fn sm_ext_sum_path_inl(env: &mut Environment) -> Result<(), String> {
1479 use oxilean_kernel::{Declaration, Expr, Name};
1480 let prop = Expr::Sort(oxilean_kernel::Level::zero());
1481 match env.add(Declaration::Axiom {
1482 name: Name::str("Sum.pathInl"),
1483 univ_params: vec![],
1484 ty: prop,
1485 }) {
1486 Ok(()) | Err(_) => Ok(()),
1487 }
1488}
1489pub(super) fn sm_ext_sum_path_inr(env: &mut Environment) -> Result<(), String> {
1491 use oxilean_kernel::{Declaration, Expr, Name};
1492 let prop = Expr::Sort(oxilean_kernel::Level::zero());
1493 match env.add(Declaration::Axiom {
1494 name: Name::str("Sum.pathInr"),
1495 univ_params: vec![],
1496 ty: prop,
1497 }) {
1498 Ok(()) | Err(_) => Ok(()),
1499 }
1500}
1501pub(super) fn sm_ext_sigma_intro(env: &mut Environment) -> Result<(), String> {
1503 use oxilean_kernel::{BinderInfo as Bi, Declaration, Expr, Level, Name};
1504 let type1 = Expr::Sort(Level::succ(Level::zero()));
1505 let ty = Expr::Pi(
1506 Bi::Default,
1507 Name::str("A"),
1508 Box::new(type1.clone()),
1509 Box::new(Expr::Pi(
1510 Bi::Default,
1511 Name::str("B"),
1512 Box::new(Expr::Pi(
1513 Bi::Default,
1514 Name::str("_"),
1515 Box::new(Expr::BVar(0)),
1516 Box::new(type1.clone()),
1517 )),
1518 Box::new(type1),
1519 )),
1520 );
1521 match env.add(Declaration::Axiom {
1522 name: Name::str("Sigma.intro"),
1523 univ_params: vec![],
1524 ty,
1525 }) {
1526 Ok(()) | Err(_) => Ok(()),
1527 }
1528}