1use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
6
7use super::types::{
8 FloatInterval, IntervalScheduler, KrawczykSolver, RangeMinSegTree, ScheduledJob,
9 ValidatedInterval,
10};
11
12#[allow(dead_code)]
14pub fn prop() -> Expr {
15 Expr::Sort(Level::zero())
16}
17#[allow(dead_code)]
19pub fn type1() -> Expr {
20 Expr::Sort(Level::succ(Level::zero()))
21}
22#[allow(dead_code)]
24pub fn type2() -> Expr {
25 Expr::Sort(Level::succ(Level::succ(Level::zero())))
26}
27#[allow(dead_code)]
29pub fn nat_ty() -> Expr {
30 Expr::Const(Name::str("Nat"), vec![])
31}
32#[allow(dead_code)]
34pub fn bool_ty() -> Expr {
35 Expr::Const(Name::str("Bool"), vec![])
36}
37#[allow(dead_code)]
39pub fn unit_ty() -> Expr {
40 Expr::Const(Name::str("Unit"), vec![])
41}
42#[allow(dead_code)]
44pub fn range_ty() -> Expr {
45 Expr::Const(Name::str("Range"), vec![])
46}
47#[allow(dead_code)]
49pub fn range_iterator_ty() -> Expr {
50 Expr::Const(Name::str("RangeIterator"), vec![])
51}
52#[allow(dead_code)]
54pub fn list_of(elem_ty: Expr) -> Expr {
55 app(Expr::Const(Name::str("List"), vec![]), elem_ty)
56}
57#[allow(dead_code)]
59pub fn array_of(elem_ty: Expr) -> Expr {
60 app(Expr::Const(Name::str("Array"), vec![]), elem_ty)
61}
62#[allow(dead_code)]
64pub fn option_of(elem_ty: Expr) -> Expr {
65 app(Expr::Const(Name::str("Option"), vec![]), elem_ty)
66}
67#[allow(dead_code)]
69pub fn prod_of(a: Expr, b: Expr) -> Expr {
70 app2(Expr::Const(Name::str("Prod"), vec![]), a, b)
71}
72#[allow(dead_code)]
74pub fn monad_of(m: Expr) -> Expr {
75 app(Expr::Const(Name::str("Monad"), vec![]), m)
76}
77#[allow(dead_code)]
79pub fn iff(a: Expr, b: Expr) -> Expr {
80 app2(Expr::Const(Name::str("Iff"), vec![]), a, b)
81}
82#[allow(dead_code)]
84pub fn arrow(a: Expr, b: Expr) -> Expr {
85 Expr::Pi(
86 BinderInfo::Default,
87 Name::str("_"),
88 Box::new(a),
89 Box::new(b),
90 )
91}
92#[allow(dead_code)]
94pub fn app(f: Expr, a: Expr) -> Expr {
95 Expr::App(Box::new(f), Box::new(a))
96}
97#[allow(dead_code)]
99pub fn app2(f: Expr, a: Expr, b: Expr) -> Expr {
100 app(app(f, a), b)
101}
102#[allow(dead_code)]
104pub fn app3(f: Expr, a: Expr, b: Expr, c: Expr) -> Expr {
105 app(app2(f, a, b), c)
106}
107#[allow(dead_code)]
109pub fn app4(f: Expr, a: Expr, b: Expr, c: Expr, d: Expr) -> Expr {
110 app(app3(f, a, b, c), d)
111}
112#[allow(dead_code)]
114pub fn implicit_pi(name: &str, ty: Expr, body: Expr) -> Expr {
115 Expr::Pi(
116 BinderInfo::Implicit,
117 Name::str(name),
118 Box::new(ty),
119 Box::new(body),
120 )
121}
122#[allow(dead_code)]
124pub fn default_pi(name: &str, ty: Expr, body: Expr) -> Expr {
125 Expr::Pi(
126 BinderInfo::Default,
127 Name::str(name),
128 Box::new(ty),
129 Box::new(body),
130 )
131}
132#[allow(dead_code)]
134pub fn inst_pi(name: &str, ty: Expr, body: Expr) -> Expr {
135 Expr::Pi(
136 BinderInfo::InstImplicit,
137 Name::str(name),
138 Box::new(ty),
139 Box::new(body),
140 )
141}
142#[allow(dead_code)]
144pub fn eq_expr(ty: Expr, a: Expr, b: Expr) -> Expr {
145 app3(Expr::Const(Name::str("Eq"), vec![]), ty, a, b)
146}
147#[allow(dead_code)]
149pub fn add_axiom(
150 env: &mut Environment,
151 name: &str,
152 univ_params: Vec<Name>,
153 ty: Expr,
154) -> Result<(), String> {
155 env.add(Declaration::Axiom {
156 name: Name::str(name),
157 univ_params,
158 ty,
159 })
160 .map_err(|e| e.to_string())
161}
162#[allow(dead_code)]
164pub fn type_to_type() -> Expr {
165 arrow(type1(), type1())
166}
167#[allow(dead_code)]
169pub fn and_prop(a: Expr, b: Expr) -> Expr {
170 app2(Expr::Const(Name::str("And"), vec![]), a, b)
171}
172#[allow(dead_code)]
174pub fn le_nat(a: Expr, b: Expr) -> Expr {
175 app2(Expr::Const(Name::str("Nat.le"), vec![]), a, b)
176}
177#[allow(dead_code)]
179pub fn lt_nat(a: Expr, b: Expr) -> Expr {
180 app2(Expr::Const(Name::str("Nat.lt"), vec![]), a, b)
181}
182#[allow(dead_code)]
184pub fn sub_nat(a: Expr, b: Expr) -> Expr {
185 app2(Expr::Const(Name::str("Nat.sub"), vec![]), a, b)
186}
187#[allow(dead_code)]
189pub fn mod_nat(a: Expr, b: Expr) -> Expr {
190 app2(Expr::Const(Name::str("Nat.mod"), vec![]), a, b)
191}
192#[allow(dead_code)]
194pub fn ge_nat(a: Expr, b: Expr) -> Expr {
195 le_nat(b, a)
196}
197#[allow(dead_code)]
199pub fn eq_true(e: Expr) -> Expr {
200 eq_expr(bool_ty(), e, Expr::Const(Name::str("Bool.true"), vec![]))
201}
202pub fn build_range_env(env: &mut Environment) -> Result<(), String> {
207 add_axiom(env, "Range", vec![], type1())?;
208 let range_mk_ty = default_pi(
209 "start",
210 nat_ty(),
211 default_pi("stop", nat_ty(), default_pi("step", nat_ty(), range_ty())),
212 );
213 add_axiom(env, "Range.mk", vec![], range_mk_ty)?;
214 let range_start_ty = arrow(range_ty(), nat_ty());
215 add_axiom(env, "Range.start", vec![], range_start_ty)?;
216 let range_stop_ty = arrow(range_ty(), nat_ty());
217 add_axiom(env, "Range.stop", vec![], range_stop_ty)?;
218 let range_step_ty = arrow(range_ty(), nat_ty());
219 add_axiom(env, "Range.step", vec![], range_step_ty)?;
220 let of_nat_ty = default_pi("start", nat_ty(), default_pi("stop", nat_ty(), range_ty()));
221 add_axiom(env, "Range.ofNat", vec![], of_nat_ty)?;
222 let single_ty = arrow(nat_ty(), range_ty());
223 add_axiom(env, "Range.single", vec![], single_ty)?;
224 let with_step_ty = default_pi(
225 "start",
226 nat_ty(),
227 default_pi("stop", nat_ty(), default_pi("step", nat_ty(), range_ty())),
228 );
229 add_axiom(env, "Range.withStep", vec![], with_step_ty)?;
230 let for_in_ty = default_pi(
231 "m",
232 type_to_type(),
233 default_pi("α", type1(), default_pi("β", type1(), type2())),
234 );
235 add_axiom(env, "ForIn", vec![], for_in_ty)?;
236 let for_in_method_ty = implicit_pi(
237 "m",
238 type_to_type(),
239 implicit_pi(
240 "α",
241 type1(),
242 implicit_pi(
243 "β",
244 type1(),
245 inst_pi(
246 "_inst",
247 app3(
248 Expr::Const(Name::str("ForIn"), vec![]),
249 Expr::BVar(2),
250 Expr::BVar(1),
251 Expr::BVar(0),
252 ),
253 default_pi(
254 "container",
255 Expr::BVar(2),
256 default_pi(
257 "init",
258 Expr::BVar(2),
259 default_pi(
260 "body",
261 arrow(Expr::BVar(3), app(Expr::BVar(6), Expr::BVar(4))),
262 app(Expr::BVar(6), Expr::BVar(4)),
263 ),
264 ),
265 ),
266 ),
267 ),
268 ),
269 );
270 add_axiom(env, "ForIn.forIn", vec![], for_in_method_ty)?;
271 let inst_for_in_range_ty = app3(
272 Expr::Const(Name::str("ForIn"), vec![]),
273 Expr::Const(Name::str("Id"), vec![]),
274 range_ty(),
275 nat_ty(),
276 );
277 add_axiom(env, "instForInRangeNat", vec![], inst_for_in_range_ty)?;
278 let iterator_ty = default_pi("α", type1(), default_pi("σ", type1(), type2()));
279 add_axiom(env, "Iterator", vec![], iterator_ty)?;
280 let next_ty = implicit_pi(
281 "α",
282 type1(),
283 implicit_pi(
284 "σ",
285 type1(),
286 inst_pi(
287 "_inst",
288 app2(
289 Expr::Const(Name::str("Iterator"), vec![]),
290 Expr::BVar(1),
291 Expr::BVar(0),
292 ),
293 default_pi(
294 "state",
295 Expr::BVar(1),
296 option_of(prod_of(Expr::BVar(3), Expr::BVar(2))),
297 ),
298 ),
299 ),
300 );
301 add_axiom(env, "Iterator.next", vec![], next_ty)?;
302 let has_next_ty = implicit_pi(
303 "α",
304 type1(),
305 implicit_pi(
306 "σ",
307 type1(),
308 inst_pi(
309 "_inst",
310 app2(
311 Expr::Const(Name::str("Iterator"), vec![]),
312 Expr::BVar(1),
313 Expr::BVar(0),
314 ),
315 default_pi("state", Expr::BVar(1), bool_ty()),
316 ),
317 ),
318 );
319 add_axiom(env, "Iterator.hasNext", vec![], has_next_ty)?;
320 add_axiom(env, "RangeIterator", vec![], type1())?;
321 let inst_iter_ty = app2(
322 Expr::Const(Name::str("Iterator"), vec![]),
323 nat_ty(),
324 range_iterator_ty(),
325 );
326 add_axiom(env, "instIteratorNatRangeIterator", vec![], inst_iter_ty)?;
327 let is_empty_ty = arrow(range_ty(), bool_ty());
328 add_axiom(env, "Range.isEmpty", vec![], is_empty_ty)?;
329 let size_ty = arrow(range_ty(), nat_ty());
330 add_axiom(env, "Range.size", vec![], size_ty)?;
331 let contains_ty = default_pi("r", range_ty(), default_pi("n", nat_ty(), bool_ty()));
332 add_axiom(env, "Range.contains", vec![], contains_ty)?;
333 let to_list_ty = arrow(range_ty(), list_of(nat_ty()));
334 add_axiom(env, "Range.toList", vec![], to_list_ty)?;
335 let for_m_ty = implicit_pi(
336 "m",
337 type_to_type(),
338 inst_pi(
339 "_inst",
340 monad_of(Expr::BVar(0)),
341 default_pi(
342 "r",
343 range_ty(),
344 default_pi(
345 "body",
346 arrow(nat_ty(), app(Expr::BVar(3), unit_ty())),
347 app(Expr::BVar(3), unit_ty()),
348 ),
349 ),
350 ),
351 );
352 add_axiom(env, "Range.forM", vec![], for_m_ty)?;
353 let foldl_ty = implicit_pi(
354 "β",
355 type1(),
356 default_pi(
357 "f",
358 arrow(Expr::BVar(0), arrow(nat_ty(), Expr::BVar(1))),
359 default_pi(
360 "init",
361 Expr::BVar(1),
362 default_pi("r", range_ty(), Expr::BVar(3)),
363 ),
364 ),
365 );
366 add_axiom(env, "Range.foldl", vec![], foldl_ty)?;
367 let all_ty = default_pi(
368 "r",
369 range_ty(),
370 default_pi("pred", arrow(nat_ty(), bool_ty()), bool_ty()),
371 );
372 add_axiom(env, "Range.all", vec![], all_ty)?;
373 let any_ty = default_pi(
374 "r",
375 range_ty(),
376 default_pi("pred", arrow(nat_ty(), bool_ty()), bool_ty()),
377 );
378 add_axiom(env, "Range.any", vec![], any_ty)?;
379 let array_range_ty = arrow(nat_ty(), array_of(nat_ty()));
380 add_axiom(env, "Array.range", vec![], array_range_ty)?;
381 let list_range_ty = arrow(nat_ty(), list_of(nat_ty()));
382 add_axiom(env, "List.range", vec![], list_range_ty)?;
383 let list_iota_ty = arrow(nat_ty(), list_of(nat_ty()));
384 add_axiom(env, "List.iota", vec![], list_iota_ty)?;
385 let enum_from_ty = implicit_pi(
386 "α",
387 type1(),
388 default_pi(
389 "start",
390 nat_ty(),
391 default_pi(
392 "l",
393 list_of(Expr::BVar(1)),
394 list_of(prod_of(nat_ty(), Expr::BVar(2))),
395 ),
396 ),
397 );
398 add_axiom(env, "List.enumFrom", vec![], enum_from_ty)?;
399 let size_mk_ty = default_pi(
400 "start",
401 nat_ty(),
402 default_pi(
403 "stop",
404 nat_ty(),
405 eq_expr(
406 nat_ty(),
407 app(
408 Expr::Const(Name::str("Range.size"), vec![]),
409 app3(
410 Expr::Const(Name::str("Range.mk"), vec![]),
411 Expr::BVar(1),
412 Expr::BVar(0),
413 Expr::Const(Name::str("Nat.one"), vec![]),
414 ),
415 ),
416 sub_nat(Expr::BVar(0), Expr::BVar(1)),
417 ),
418 ),
419 );
420 add_axiom(env, "Range.size_mk", vec![], size_mk_ty)?;
421 let contains_iff_ty = default_pi(
422 "start",
423 nat_ty(),
424 default_pi(
425 "stop",
426 nat_ty(),
427 default_pi(
428 "step",
429 nat_ty(),
430 default_pi(
431 "n",
432 nat_ty(),
433 iff(
434 eq_true(app2(
435 Expr::Const(Name::str("Range.contains"), vec![]),
436 app3(
437 Expr::Const(Name::str("Range.mk"), vec![]),
438 Expr::BVar(3),
439 Expr::BVar(2),
440 Expr::BVar(1),
441 ),
442 Expr::BVar(0),
443 )),
444 and_prop(
445 le_nat(Expr::BVar(3), Expr::BVar(0)),
446 and_prop(
447 lt_nat(Expr::BVar(0), Expr::BVar(2)),
448 eq_expr(
449 nat_ty(),
450 mod_nat(sub_nat(Expr::BVar(0), Expr::BVar(3)), Expr::BVar(1)),
451 Expr::Const(Name::str("Nat.zero"), vec![]),
452 ),
453 ),
454 ),
455 ),
456 ),
457 ),
458 ),
459 );
460 add_axiom(env, "Range.contains_iff", vec![], contains_iff_ty)?;
461 let to_list_length_ty = default_pi(
462 "r",
463 range_ty(),
464 eq_expr(
465 nat_ty(),
466 app(
467 Expr::Const(Name::str("List.length"), vec![]),
468 app(
469 Expr::Const(Name::str("Range.toList"), vec![]),
470 Expr::BVar(0),
471 ),
472 ),
473 app(Expr::Const(Name::str("Range.size"), vec![]), Expr::BVar(0)),
474 ),
475 );
476 add_axiom(env, "Range.toList_length", vec![], to_list_length_ty)?;
477 let is_empty_iff_ty = default_pi(
478 "r",
479 range_ty(),
480 iff(
481 eq_true(app(
482 Expr::Const(Name::str("Range.isEmpty"), vec![]),
483 Expr::BVar(0),
484 )),
485 ge_nat(
486 app(Expr::Const(Name::str("Range.start"), vec![]), Expr::BVar(0)),
487 app(Expr::Const(Name::str("Range.stop"), vec![]), Expr::BVar(0)),
488 ),
489 ),
490 );
491 add_axiom(env, "Range.isEmpty_iff", vec![], is_empty_iff_ty)?;
492 let range_length_ty = default_pi(
493 "n",
494 nat_ty(),
495 eq_expr(
496 nat_ty(),
497 app(
498 Expr::Const(Name::str("List.length"), vec![]),
499 app(Expr::Const(Name::str("List.range"), vec![]), Expr::BVar(0)),
500 ),
501 Expr::BVar(0),
502 ),
503 );
504 add_axiom(env, "List.range_length", vec![], range_length_ty)?;
505 let iota_length_ty = default_pi(
506 "n",
507 nat_ty(),
508 eq_expr(
509 nat_ty(),
510 app(
511 Expr::Const(Name::str("List.length"), vec![]),
512 app(Expr::Const(Name::str("List.iota"), vec![]), Expr::BVar(0)),
513 ),
514 Expr::BVar(0),
515 ),
516 );
517 add_axiom(env, "List.iota_length", vec![], iota_length_ty)?;
518 Ok(())
519}
520#[allow(dead_code)]
522pub fn mk_range(start: Expr, stop: Expr, step: Expr) -> Expr {
523 app3(
524 Expr::Const(Name::str("Range.mk"), vec![]),
525 start,
526 stop,
527 step,
528 )
529}
530#[allow(dead_code)]
532pub fn mk_range_of_nat(start: Expr, stop: Expr) -> Expr {
533 app2(Expr::Const(Name::str("Range.ofNat"), vec![]), start, stop)
534}
535#[allow(dead_code)]
537pub fn mk_range_single(n: Expr) -> Expr {
538 app(Expr::Const(Name::str("Range.single"), vec![]), n)
539}
540#[allow(dead_code)]
542pub fn mk_for_in(container: Expr, init: Expr, body: Expr) -> Expr {
543 app3(
544 Expr::Const(Name::str("ForIn.forIn"), vec![]),
545 container,
546 init,
547 body,
548 )
549}
550#[allow(dead_code)]
552pub fn mk_range_to_list(r: Expr) -> Expr {
553 app(Expr::Const(Name::str("Range.toList"), vec![]), r)
554}
555#[allow(dead_code)]
557pub fn mk_range_size(r: Expr) -> Expr {
558 app(Expr::Const(Name::str("Range.size"), vec![]), r)
559}
560#[allow(dead_code)]
562pub fn mk_list_range(n: Expr) -> Expr {
563 app(Expr::Const(Name::str("List.range"), vec![]), n)
564}
565#[allow(dead_code)]
567pub fn mk_array_range(n: Expr) -> Expr {
568 app(Expr::Const(Name::str("Array.range"), vec![]), n)
569}
570#[allow(dead_code)]
572pub fn mk_list_iota(n: Expr) -> Expr {
573 app(Expr::Const(Name::str("List.iota"), vec![]), n)
574}
575#[allow(dead_code)]
577pub fn mk_range_is_empty(r: Expr) -> Expr {
578 app(Expr::Const(Name::str("Range.isEmpty"), vec![]), r)
579}
580#[allow(dead_code)]
582pub fn mk_range_contains(r: Expr, n: Expr) -> Expr {
583 app2(Expr::Const(Name::str("Range.contains"), vec![]), r, n)
584}
585#[allow(dead_code)]
587pub fn mk_range_foldl(f: Expr, init: Expr, r: Expr) -> Expr {
588 app3(Expr::Const(Name::str("Range.foldl"), vec![]), f, init, r)
589}
590#[allow(dead_code)]
592pub fn mk_range_all(r: Expr, pred: Expr) -> Expr {
593 app2(Expr::Const(Name::str("Range.all"), vec![]), r, pred)
594}
595#[allow(dead_code)]
597pub fn mk_range_any(r: Expr, pred: Expr) -> Expr {
598 app2(Expr::Const(Name::str("Range.any"), vec![]), r, pred)
599}
600#[allow(dead_code)]
602pub fn mk_range_start(r: Expr) -> Expr {
603 app(Expr::Const(Name::str("Range.start"), vec![]), r)
604}
605#[allow(dead_code)]
607pub fn mk_range_stop(r: Expr) -> Expr {
608 app(Expr::Const(Name::str("Range.stop"), vec![]), r)
609}
610#[allow(dead_code)]
612pub fn mk_range_step(r: Expr) -> Expr {
613 app(Expr::Const(Name::str("Range.step"), vec![]), r)
614}
615#[allow(dead_code)]
617pub fn mk_range_with_step(start: Expr, stop: Expr, step: Expr) -> Expr {
618 app3(
619 Expr::Const(Name::str("Range.withStep"), vec![]),
620 start,
621 stop,
622 step,
623 )
624}
625#[allow(dead_code)]
627pub fn mk_list_enum_from(start: Expr, l: Expr) -> Expr {
628 app2(Expr::Const(Name::str("List.enumFrom"), vec![]), start, l)
629}
630#[allow(dead_code)]
632pub fn mk_range_for_m(r: Expr, body: Expr) -> Expr {
633 app2(Expr::Const(Name::str("Range.forM"), vec![]), r, body)
634}
635#[allow(dead_code)]
637pub fn mk_iterator_next(state: Expr) -> Expr {
638 app(Expr::Const(Name::str("Iterator.next"), vec![]), state)
639}
640#[allow(dead_code)]
642pub fn mk_iterator_has_next(state: Expr) -> Expr {
643 app(Expr::Const(Name::str("Iterator.hasNext"), vec![]), state)
644}
645#[cfg(test)]
646mod tests {
647 use super::*;
648 fn make_env() -> Environment {
649 let mut env = Environment::new();
650 build_range_env(&mut env).expect("build_range_env should succeed");
651 env
652 }
653 #[test]
654 fn test_build_range_env_succeeds() {
655 let mut env = Environment::new();
656 assert!(build_range_env(&mut env).is_ok());
657 }
658 #[test]
659 fn test_range_type_exists() {
660 let env = make_env();
661 assert!(env.get(&Name::str("Range")).is_some());
662 }
663 #[test]
664 fn test_range_mk_exists() {
665 let env = make_env();
666 assert!(env.get(&Name::str("Range.mk")).is_some());
667 }
668 #[test]
669 fn test_range_start_exists() {
670 let env = make_env();
671 assert!(env.get(&Name::str("Range.start")).is_some());
672 }
673 #[test]
674 fn test_range_stop_exists() {
675 let env = make_env();
676 assert!(env.get(&Name::str("Range.stop")).is_some());
677 }
678 #[test]
679 fn test_range_step_exists() {
680 let env = make_env();
681 assert!(env.get(&Name::str("Range.step")).is_some());
682 }
683 #[test]
684 fn test_range_of_nat_exists() {
685 let env = make_env();
686 assert!(env.get(&Name::str("Range.ofNat")).is_some());
687 }
688 #[test]
689 fn test_range_single_exists() {
690 let env = make_env();
691 assert!(env.get(&Name::str("Range.single")).is_some());
692 }
693 #[test]
694 fn test_range_with_step_exists() {
695 let env = make_env();
696 assert!(env.get(&Name::str("Range.withStep")).is_some());
697 }
698 #[test]
699 fn test_for_in_exists() {
700 let env = make_env();
701 assert!(env.get(&Name::str("ForIn")).is_some());
702 }
703 #[test]
704 fn test_for_in_method_exists() {
705 let env = make_env();
706 assert!(env.get(&Name::str("ForIn.forIn")).is_some());
707 }
708 #[test]
709 fn test_inst_for_in_range_nat_exists() {
710 let env = make_env();
711 assert!(env.get(&Name::str("instForInRangeNat")).is_some());
712 }
713 #[test]
714 fn test_iterator_exists() {
715 let env = make_env();
716 assert!(env.get(&Name::str("Iterator")).is_some());
717 }
718 #[test]
719 fn test_iterator_next_exists() {
720 let env = make_env();
721 assert!(env.get(&Name::str("Iterator.next")).is_some());
722 }
723 #[test]
724 fn test_iterator_has_next_exists() {
725 let env = make_env();
726 assert!(env.get(&Name::str("Iterator.hasNext")).is_some());
727 }
728 #[test]
729 fn test_range_iterator_exists() {
730 let env = make_env();
731 assert!(env.get(&Name::str("RangeIterator")).is_some());
732 }
733 #[test]
734 fn test_inst_iterator_nat_range_exists() {
735 let env = make_env();
736 assert!(env
737 .get(&Name::str("instIteratorNatRangeIterator"))
738 .is_some());
739 }
740 #[test]
741 fn test_range_is_empty_exists() {
742 let env = make_env();
743 assert!(env.get(&Name::str("Range.isEmpty")).is_some());
744 }
745 #[test]
746 fn test_range_size_exists() {
747 let env = make_env();
748 assert!(env.get(&Name::str("Range.size")).is_some());
749 }
750 #[test]
751 fn test_range_contains_exists() {
752 let env = make_env();
753 assert!(env.get(&Name::str("Range.contains")).is_some());
754 }
755 #[test]
756 fn test_range_to_list_exists() {
757 let env = make_env();
758 assert!(env.get(&Name::str("Range.toList")).is_some());
759 }
760 #[test]
761 fn test_range_for_m_exists() {
762 let env = make_env();
763 assert!(env.get(&Name::str("Range.forM")).is_some());
764 }
765 #[test]
766 fn test_range_foldl_exists() {
767 let env = make_env();
768 assert!(env.get(&Name::str("Range.foldl")).is_some());
769 }
770 #[test]
771 fn test_range_all_exists() {
772 let env = make_env();
773 assert!(env.get(&Name::str("Range.all")).is_some());
774 }
775 #[test]
776 fn test_range_any_exists() {
777 let env = make_env();
778 assert!(env.get(&Name::str("Range.any")).is_some());
779 }
780 #[test]
781 fn test_array_range_exists() {
782 let env = make_env();
783 assert!(env.get(&Name::str("Array.range")).is_some());
784 }
785 #[test]
786 fn test_list_range_exists() {
787 let env = make_env();
788 assert!(env.get(&Name::str("List.range")).is_some());
789 }
790 #[test]
791 fn test_list_iota_exists() {
792 let env = make_env();
793 assert!(env.get(&Name::str("List.iota")).is_some());
794 }
795 #[test]
796 fn test_list_enum_from_exists() {
797 let env = make_env();
798 assert!(env.get(&Name::str("List.enumFrom")).is_some());
799 }
800 #[test]
801 fn test_range_size_mk_exists() {
802 let env = make_env();
803 assert!(env.get(&Name::str("Range.size_mk")).is_some());
804 }
805 #[test]
806 fn test_range_contains_iff_exists() {
807 let env = make_env();
808 assert!(env.get(&Name::str("Range.contains_iff")).is_some());
809 }
810 #[test]
811 fn test_range_to_list_length_exists() {
812 let env = make_env();
813 assert!(env.get(&Name::str("Range.toList_length")).is_some());
814 }
815 #[test]
816 fn test_range_is_empty_iff_exists() {
817 let env = make_env();
818 assert!(env.get(&Name::str("Range.isEmpty_iff")).is_some());
819 }
820 #[test]
821 fn test_list_range_length_exists() {
822 let env = make_env();
823 assert!(env.get(&Name::str("List.range_length")).is_some());
824 }
825 #[test]
826 fn test_list_iota_length_exists() {
827 let env = make_env();
828 assert!(env.get(&Name::str("List.iota_length")).is_some());
829 }
830 #[test]
831 fn test_mk_range() {
832 let r = mk_range(
833 Expr::Const(Name::str("a"), vec![]),
834 Expr::Const(Name::str("b"), vec![]),
835 Expr::Const(Name::str("c"), vec![]),
836 );
837 assert!(matches!(r, Expr::App(_, _)));
838 }
839 #[test]
840 fn test_mk_range_of_nat() {
841 let r = mk_range_of_nat(
842 Expr::Const(Name::str("a"), vec![]),
843 Expr::Const(Name::str("b"), vec![]),
844 );
845 assert!(matches!(r, Expr::App(_, _)));
846 }
847 #[test]
848 fn test_mk_range_single() {
849 let r = mk_range_single(Expr::Const(Name::str("n"), vec![]));
850 assert!(matches!(r, Expr::App(_, _)));
851 }
852 #[test]
853 fn test_mk_for_in() {
854 let f = mk_for_in(
855 Expr::Const(Name::str("c"), vec![]),
856 Expr::Const(Name::str("i"), vec![]),
857 Expr::Const(Name::str("b"), vec![]),
858 );
859 assert!(matches!(f, Expr::App(_, _)));
860 }
861 #[test]
862 fn test_mk_range_to_list() {
863 let l = mk_range_to_list(Expr::Const(Name::str("r"), vec![]));
864 assert!(matches!(l, Expr::App(_, _)));
865 }
866 #[test]
867 fn test_mk_range_size() {
868 let s = mk_range_size(Expr::Const(Name::str("r"), vec![]));
869 assert!(matches!(s, Expr::App(_, _)));
870 }
871 #[test]
872 fn test_mk_list_range() {
873 let l = mk_list_range(Expr::Const(Name::str("n"), vec![]));
874 assert!(matches!(l, Expr::App(_, _)));
875 }
876 #[test]
877 fn test_all_declarations_are_axioms() {
878 let env = make_env();
879 for name in [
880 "Range",
881 "Range.mk",
882 "Range.start",
883 "Range.stop",
884 "Range.step",
885 "Range.ofNat",
886 "Range.single",
887 "Range.withStep",
888 "ForIn",
889 "ForIn.forIn",
890 "instForInRangeNat",
891 "Iterator",
892 "Iterator.next",
893 "Iterator.hasNext",
894 "RangeIterator",
895 "instIteratorNatRangeIterator",
896 "Range.isEmpty",
897 "Range.size",
898 "Range.contains",
899 "Range.toList",
900 "Range.forM",
901 "Range.foldl",
902 "Range.all",
903 "Range.any",
904 "Array.range",
905 "List.range",
906 "List.iota",
907 "List.enumFrom",
908 ] {
909 let decl = env.get(&Name::str(name)).expect("operation should succeed");
910 assert!(
911 matches!(decl, Declaration::Axiom { .. }),
912 "{} should be an axiom",
913 name
914 );
915 }
916 }
917 #[test]
918 fn test_env_declaration_count() {
919 let env = make_env();
920 assert!(env.len() >= 30);
921 }
922 #[test]
923 fn test_range_mk_type_is_pi() {
924 let env = make_env();
925 let decl = env
926 .get(&Name::str("Range.mk"))
927 .expect("declaration 'Range.mk' should exist in env");
928 assert!(decl.ty().is_pi());
929 }
930 #[test]
931 fn test_range_foldl_type_is_pi() {
932 let env = make_env();
933 let decl = env
934 .get(&Name::str("Range.foldl"))
935 .expect("declaration 'Range.foldl' should exist in env");
936 assert!(decl.ty().is_pi());
937 }
938 #[test]
939 fn test_range_type_is_sort() {
940 let env = make_env();
941 let decl = env
942 .get(&Name::str("Range"))
943 .expect("declaration 'Range' should exist in env");
944 assert!(decl.ty().is_sort());
945 }
946 #[test]
947 fn test_range_iterator_type_is_sort() {
948 let env = make_env();
949 let decl = env
950 .get(&Name::str("RangeIterator"))
951 .expect("declaration 'RangeIterator' should exist in env");
952 assert!(decl.ty().is_sort());
953 }
954}
955pub fn rng_ext_type1() -> Expr {
956 Expr::Sort(Level::succ(Level::zero()))
957}
958pub fn rng_ext_type2() -> Expr {
959 Expr::Sort(Level::succ(Level::succ(Level::zero())))
960}
961pub fn rng_ext_prop() -> Expr {
962 Expr::Sort(Level::zero())
963}
964pub fn rng_ext_arrow(dom: Expr, cod: Expr) -> Expr {
965 Expr::Pi(
966 BinderInfo::Default,
967 Name::str("_"),
968 Box::new(dom),
969 Box::new(cod),
970 )
971}
972pub fn rng_ext_pi(name: &str, dom: Expr, body: Expr) -> Expr {
973 Expr::Pi(
974 BinderInfo::Default,
975 Name::str(name),
976 Box::new(dom),
977 Box::new(body),
978 )
979}
980pub fn rng_ext_ipi(name: &str, dom: Expr, body: Expr) -> Expr {
981 Expr::Pi(
982 BinderInfo::Implicit,
983 Name::str(name),
984 Box::new(dom),
985 Box::new(body),
986 )
987}
988pub fn rng_ext_app(f: Expr, a: Expr) -> Expr {
989 Expr::App(Box::new(f), Box::new(a))
990}
991pub fn rng_ext_app2(f: Expr, a: Expr, b: Expr) -> Expr {
992 rng_ext_app(rng_ext_app(f, a), b)
993}
994pub fn rng_ext_app3(f: Expr, a: Expr, b: Expr, c: Expr) -> Expr {
995 rng_ext_app(rng_ext_app2(f, a, b), c)
996}
997pub fn rng_ext_nat() -> Expr {
998 Expr::Const(Name::str("Nat"), vec![])
999}
1000pub fn rng_ext_float() -> Expr {
1001 Expr::Const(Name::str("Float"), vec![])
1002}
1003pub fn rng_ext_bool() -> Expr {
1004 Expr::Const(Name::str("Bool"), vec![])
1005}
1006pub fn rng_ext_interval() -> Expr {
1007 Expr::Const(Name::str("Interval"), vec![])
1008}
1009pub fn rng_ext_interval_of(ty: Expr) -> Expr {
1010 rng_ext_app(Expr::Const(Name::str("Interval"), vec![]), ty)
1011}
1012pub fn rng_ext_eq(ty: Expr, a: Expr, b: Expr) -> Expr {
1013 rng_ext_app3(Expr::Const(Name::str("Eq"), vec![]), ty, a, b)
1014}
1015pub fn rng_ext_and(a: Expr, b: Expr) -> Expr {
1016 rng_ext_app2(Expr::Const(Name::str("And"), vec![]), a, b)
1017}
1018pub fn rng_ext_iff(a: Expr, b: Expr) -> Expr {
1019 rng_ext_app2(Expr::Const(Name::str("Iff"), vec![]), a, b)
1020}
1021pub fn rng_ext_le(a: Expr, b: Expr) -> Expr {
1022 rng_ext_app2(Expr::Const(Name::str("LE.le"), vec![]), a, b)
1023}
1024pub fn rng_ext_lt(a: Expr, b: Expr) -> Expr {
1025 rng_ext_app2(Expr::Const(Name::str("LT.lt"), vec![]), a, b)
1026}
1027pub fn rng_ext_add_axiom(env: &mut Environment, name: &str, ty: Expr) -> Result<(), String> {
1028 env.add(Declaration::Axiom {
1029 name: Name::str(name),
1030 univ_params: vec![],
1031 ty,
1032 })
1033 .map_err(|e| e.to_string())
1034}
1035pub fn axiom_interval_type_ty() -> Expr {
1037 rng_ext_arrow(rng_ext_type1(), rng_ext_type1())
1038}
1039pub fn axiom_interval_mk_ty() -> Expr {
1041 rng_ext_ipi(
1042 "α",
1043 rng_ext_type1(),
1044 rng_ext_pi(
1045 "lo",
1046 Expr::BVar(0),
1047 rng_ext_pi("hi", Expr::BVar(1), rng_ext_interval_of(Expr::BVar(2))),
1048 ),
1049 )
1050}
1051pub fn axiom_interval_lo_ty() -> Expr {
1053 rng_ext_ipi(
1054 "α",
1055 rng_ext_type1(),
1056 rng_ext_arrow(rng_ext_interval_of(Expr::BVar(0)), Expr::BVar(0)),
1057 )
1058}
1059pub fn axiom_interval_hi_ty() -> Expr {
1061 rng_ext_ipi(
1062 "α",
1063 rng_ext_type1(),
1064 rng_ext_arrow(rng_ext_interval_of(Expr::BVar(0)), Expr::BVar(0)),
1065 )
1066}
1067pub fn axiom_interval_valid_ty() -> Expr {
1069 rng_ext_ipi(
1070 "α",
1071 rng_ext_type1(),
1072 Expr::Pi(
1073 BinderInfo::InstImplicit,
1074 Name::str("_"),
1075 Box::new(rng_ext_app(
1076 Expr::Const(Name::str("Ord"), vec![]),
1077 Expr::BVar(0),
1078 )),
1079 Box::new(rng_ext_arrow(
1080 rng_ext_interval_of(Expr::BVar(1)),
1081 rng_ext_prop(),
1082 )),
1083 ),
1084 )
1085}
1086pub fn axiom_interval_contains_ty() -> Expr {
1088 rng_ext_ipi(
1089 "α",
1090 rng_ext_type1(),
1091 Expr::Pi(
1092 BinderInfo::InstImplicit,
1093 Name::str("_"),
1094 Box::new(rng_ext_app(
1095 Expr::Const(Name::str("Ord"), vec![]),
1096 Expr::BVar(0),
1097 )),
1098 Box::new(rng_ext_pi(
1099 "iv",
1100 rng_ext_interval_of(Expr::BVar(1)),
1101 rng_ext_pi("x", Expr::BVar(2), rng_ext_prop()),
1102 )),
1103 ),
1104 )
1105}
1106pub fn axiom_interval_add_ty() -> Expr {
1108 rng_ext_arrow(
1109 rng_ext_interval_of(rng_ext_float()),
1110 rng_ext_arrow(
1111 rng_ext_interval_of(rng_ext_float()),
1112 rng_ext_interval_of(rng_ext_float()),
1113 ),
1114 )
1115}
1116pub fn axiom_interval_sub_ty() -> Expr {
1118 rng_ext_arrow(
1119 rng_ext_interval_of(rng_ext_float()),
1120 rng_ext_arrow(
1121 rng_ext_interval_of(rng_ext_float()),
1122 rng_ext_interval_of(rng_ext_float()),
1123 ),
1124 )
1125}
1126pub fn axiom_interval_mul_ty() -> Expr {
1128 rng_ext_arrow(
1129 rng_ext_interval_of(rng_ext_float()),
1130 rng_ext_arrow(
1131 rng_ext_interval_of(rng_ext_float()),
1132 rng_ext_interval_of(rng_ext_float()),
1133 ),
1134 )
1135}
1136pub fn axiom_interval_div_ty() -> Expr {
1138 rng_ext_arrow(
1139 rng_ext_interval_of(rng_ext_float()),
1140 rng_ext_arrow(
1141 rng_ext_interval_of(rng_ext_float()),
1142 rng_ext_interval_of(rng_ext_float()),
1143 ),
1144 )
1145}
1146pub fn axiom_interval_width_ty() -> Expr {
1148 rng_ext_arrow(rng_ext_interval_of(rng_ext_float()), rng_ext_float())
1149}
1150pub fn axiom_interval_midpoint_ty() -> Expr {
1152 rng_ext_arrow(rng_ext_interval_of(rng_ext_float()), rng_ext_float())
1153}
1154pub fn axiom_interval_intersect_ty() -> Expr {
1156 rng_ext_arrow(
1157 rng_ext_interval_of(rng_ext_float()),
1158 rng_ext_arrow(
1159 rng_ext_interval_of(rng_ext_float()),
1160 rng_ext_app(
1161 Expr::Const(Name::str("Option"), vec![]),
1162 rng_ext_interval_of(rng_ext_float()),
1163 ),
1164 ),
1165 )
1166}
1167pub fn axiom_interval_hull_ty() -> Expr {
1169 rng_ext_arrow(
1170 rng_ext_interval_of(rng_ext_float()),
1171 rng_ext_arrow(
1172 rng_ext_interval_of(rng_ext_float()),
1173 rng_ext_interval_of(rng_ext_float()),
1174 ),
1175 )
1176}
1177pub fn axiom_interval_subset_ty() -> Expr {
1179 rng_ext_arrow(
1180 rng_ext_interval_of(rng_ext_float()),
1181 rng_ext_arrow(rng_ext_interval_of(rng_ext_float()), rng_ext_prop()),
1182 )
1183}
1184pub fn axiom_moore_inclusion_monotone_ty() -> Expr {
1186 rng_ext_prop()
1187}
1188pub fn axiom_moore_fundamental_theorem_ty() -> Expr {
1190 rng_ext_prop()
1191}
1192pub fn axiom_interval_newton_step_ty() -> Expr {
1194 rng_ext_arrow(
1195 rng_ext_arrow(rng_ext_float(), rng_ext_float()),
1196 rng_ext_arrow(
1197 rng_ext_interval_of(rng_ext_float()),
1198 rng_ext_arrow(
1199 rng_ext_interval_of(rng_ext_float()),
1200 rng_ext_interval_of(rng_ext_float()),
1201 ),
1202 ),
1203 )
1204}
1205pub fn axiom_interval_newton_converges_ty() -> Expr {
1207 rng_ext_prop()
1208}
1209pub fn axiom_krawczyk_operator_ty() -> Expr {
1211 rng_ext_arrow(
1212 rng_ext_arrow(rng_ext_float(), rng_ext_float()),
1213 rng_ext_arrow(
1214 rng_ext_interval_of(rng_ext_float()),
1215 rng_ext_interval_of(rng_ext_float()),
1216 ),
1217 )
1218}
1219pub fn axiom_krawczyk_enclosure_ty() -> Expr {
1221 rng_ext_prop()
1222}
1223pub fn axiom_gauss_seidel_interval_step_ty() -> Expr {
1225 rng_ext_pi(
1226 "n",
1227 rng_ext_nat(),
1228 rng_ext_arrow(
1229 rng_ext_interval_of(rng_ext_float()),
1230 rng_ext_interval_of(rng_ext_float()),
1231 ),
1232 )
1233}
1234pub fn axiom_validated_numerics_enclosure_ty() -> Expr {
1236 rng_ext_arrow(
1237 rng_ext_arrow(rng_ext_float(), rng_ext_float()),
1238 rng_ext_arrow(rng_ext_interval_of(rng_ext_float()), rng_ext_prop()),
1239 )
1240}
1241pub fn axiom_interval_presheaf_ty() -> Expr {
1243 rng_ext_type2()
1244}
1245pub fn axiom_interval_valued_probability_ty() -> Expr {
1247 rng_ext_type1()
1248}
1249pub fn axiom_ivp_measure_ty() -> Expr {
1251 rng_ext_arrow(
1252 Expr::Const(Name::str("IntervalValuedProbability"), vec![]),
1253 rng_ext_interval_of(rng_ext_float()),
1254 )
1255}
1256pub fn axiom_modal_interval_ty() -> Expr {
1258 rng_ext_type1()
1259}
1260pub fn axiom_modal_interval_dual_ty() -> Expr {
1262 rng_ext_arrow(
1263 Expr::Const(Name::str("ModalInterval"), vec![]),
1264 Expr::Const(Name::str("ModalInterval"), vec![]),
1265 )
1266}
1267pub fn axiom_interval_linear_system_solve_ty() -> Expr {
1269 rng_ext_pi(
1270 "n",
1271 rng_ext_nat(),
1272 rng_ext_arrow(
1273 rng_ext_interval_of(rng_ext_float()),
1274 rng_ext_app(
1275 Expr::Const(Name::str("Option"), vec![]),
1276 rng_ext_interval_of(rng_ext_float()),
1277 ),
1278 ),
1279 )
1280}
1281pub fn axiom_dempster_shafer_belief_ty() -> Expr {
1283 rng_ext_arrow(
1284 Expr::Const(Name::str("DempsterShafer"), vec![]),
1285 rng_ext_interval_of(rng_ext_float()),
1286 )
1287}
1288pub fn axiom_dempster_shafer_plausibility_ty() -> Expr {
1290 rng_ext_arrow(
1291 Expr::Const(Name::str("DempsterShafer"), vec![]),
1292 rng_ext_interval_of(rng_ext_float()),
1293 )
1294}
1295pub fn axiom_fuzzy_interval_ty() -> Expr {
1297 rng_ext_type1()
1298}
1299pub fn axiom_fuzzy_interval_alpha_cut_ty() -> Expr {
1301 rng_ext_arrow(
1302 Expr::Const(Name::str("FuzzyInterval"), vec![]),
1303 rng_ext_arrow(rng_ext_float(), rng_ext_interval_of(rng_ext_float())),
1304 )
1305}
1306pub fn axiom_segment_tree_ty() -> Expr {
1308 rng_ext_arrow(
1309 rng_ext_type1(),
1310 rng_ext_arrow(rng_ext_nat(), rng_ext_type1()),
1311 )
1312}
1313pub fn axiom_segment_tree_query_ty() -> Expr {
1315 rng_ext_ipi(
1316 "α",
1317 rng_ext_type1(),
1318 rng_ext_ipi(
1319 "n",
1320 rng_ext_nat(),
1321 rng_ext_pi(
1322 "tree",
1323 rng_ext_app2(
1324 Expr::Const(Name::str("SegmentTree"), vec![]),
1325 Expr::BVar(1),
1326 Expr::BVar(0),
1327 ),
1328 rng_ext_pi(
1329 "l",
1330 rng_ext_nat(),
1331 rng_ext_pi("r", rng_ext_nat(), Expr::BVar(4)),
1332 ),
1333 ),
1334 ),
1335 )
1336}
1337pub fn axiom_segment_tree_update_ty() -> Expr {
1339 rng_ext_ipi(
1340 "α",
1341 rng_ext_type1(),
1342 rng_ext_ipi(
1343 "n",
1344 rng_ext_nat(),
1345 rng_ext_pi(
1346 "tree",
1347 rng_ext_app2(
1348 Expr::Const(Name::str("SegmentTree"), vec![]),
1349 Expr::BVar(1),
1350 Expr::BVar(0),
1351 ),
1352 rng_ext_pi(
1353 "i",
1354 rng_ext_nat(),
1355 rng_ext_pi(
1356 "val",
1357 Expr::BVar(3),
1358 rng_ext_app2(
1359 Expr::Const(Name::str("SegmentTree"), vec![]),
1360 Expr::BVar(4),
1361 Expr::BVar(3),
1362 ),
1363 ),
1364 ),
1365 ),
1366 ),
1367 )
1368}
1369pub fn axiom_weighted_job_ty() -> Expr {
1371 rng_ext_type1()
1372}
1373pub fn axiom_interval_scheduling_optimal_ty() -> Expr {
1375 rng_ext_arrow(
1376 rng_ext_app(
1377 Expr::Const(Name::str("List"), vec![]),
1378 Expr::Const(Name::str("WeightedJob"), vec![]),
1379 ),
1380 rng_ext_app(
1381 Expr::Const(Name::str("List"), vec![]),
1382 Expr::Const(Name::str("WeightedJob"), vec![]),
1383 ),
1384 )
1385}
1386pub fn axiom_interval_scheduling_dp_correct_ty() -> Expr {
1388 rng_ext_prop()
1389}
1390pub fn axiom_range_foldl_correct_ty() -> Expr {
1392 rng_ext_prop()
1393}
1394pub fn axiom_range_all_iff_ty() -> Expr {
1396 rng_ext_prop()
1397}
1398pub fn axiom_range_any_iff_ty() -> Expr {
1400 rng_ext_prop()
1401}
1402pub fn axiom_interval_correct_rounding_ty() -> Expr {
1404 rng_ext_prop()
1405}
1406pub fn axiom_interval_subtraction_anticlosure_ty() -> Expr {
1408 rng_ext_prop()
1409}
1410pub fn axiom_interval_pow_ty() -> Expr {
1412 rng_ext_pi(
1413 "iv",
1414 rng_ext_interval_of(rng_ext_float()),
1415 rng_ext_pi("n", rng_ext_nat(), rng_ext_interval_of(rng_ext_float())),
1416 )
1417}
1418pub fn axiom_interval_sqrt_ty() -> Expr {
1420 rng_ext_arrow(
1421 rng_ext_interval_of(rng_ext_float()),
1422 rng_ext_app(
1423 Expr::Const(Name::str("Option"), vec![]),
1424 rng_ext_interval_of(rng_ext_float()),
1425 ),
1426 )
1427}
1428pub fn axiom_interval_exp_ty() -> Expr {
1430 rng_ext_arrow(
1431 rng_ext_interval_of(rng_ext_float()),
1432 rng_ext_interval_of(rng_ext_float()),
1433 )
1434}
1435pub fn axiom_interval_log_ty() -> Expr {
1437 rng_ext_arrow(
1438 rng_ext_interval_of(rng_ext_float()),
1439 rng_ext_app(
1440 Expr::Const(Name::str("Option"), vec![]),
1441 rng_ext_interval_of(rng_ext_float()),
1442 ),
1443 )
1444}
1445pub fn axiom_interval_sin_ty() -> Expr {
1447 rng_ext_arrow(
1448 rng_ext_interval_of(rng_ext_float()),
1449 rng_ext_interval_of(rng_ext_float()),
1450 )
1451}
1452pub fn axiom_interval_cos_ty() -> Expr {
1454 rng_ext_arrow(
1455 rng_ext_interval_of(rng_ext_float()),
1456 rng_ext_interval_of(rng_ext_float()),
1457 )
1458}
1459pub fn axiom_interval_abs_ty() -> Expr {
1461 rng_ext_arrow(
1462 rng_ext_interval_of(rng_ext_float()),
1463 rng_ext_interval_of(rng_ext_float()),
1464 )
1465}
1466pub fn axiom_interval_neg_ty() -> Expr {
1468 rng_ext_arrow(
1469 rng_ext_interval_of(rng_ext_float()),
1470 rng_ext_interval_of(rng_ext_float()),
1471 )
1472}
1473pub fn register_range_extended(env: &mut Environment) -> Result<(), String> {
1475 rng_ext_add_axiom(env, "Interval", axiom_interval_type_ty())?;
1476 rng_ext_add_axiom(env, "Interval.mk", axiom_interval_mk_ty())?;
1477 rng_ext_add_axiom(env, "Interval.lo", axiom_interval_lo_ty())?;
1478 rng_ext_add_axiom(env, "Interval.hi", axiom_interval_hi_ty())?;
1479 rng_ext_add_axiom(env, "Interval.valid", axiom_interval_valid_ty())?;
1480 rng_ext_add_axiom(env, "Interval.contains", axiom_interval_contains_ty())?;
1481 rng_ext_add_axiom(env, "Interval.add", axiom_interval_add_ty())?;
1482 rng_ext_add_axiom(env, "Interval.sub", axiom_interval_sub_ty())?;
1483 rng_ext_add_axiom(env, "Interval.mul", axiom_interval_mul_ty())?;
1484 rng_ext_add_axiom(env, "Interval.div", axiom_interval_div_ty())?;
1485 rng_ext_add_axiom(env, "Interval.width", axiom_interval_width_ty())?;
1486 rng_ext_add_axiom(env, "Interval.midpoint", axiom_interval_midpoint_ty())?;
1487 rng_ext_add_axiom(env, "Interval.intersect", axiom_interval_intersect_ty())?;
1488 rng_ext_add_axiom(env, "Interval.hull", axiom_interval_hull_ty())?;
1489 rng_ext_add_axiom(env, "Interval.subset", axiom_interval_subset_ty())?;
1490 rng_ext_add_axiom(
1491 env,
1492 "MooreArithmetic.inclusion_monotone",
1493 axiom_moore_inclusion_monotone_ty(),
1494 )?;
1495 rng_ext_add_axiom(
1496 env,
1497 "MooreArithmetic.fundamental_theorem",
1498 axiom_moore_fundamental_theorem_ty(),
1499 )?;
1500 rng_ext_add_axiom(env, "IntervalNewton.step", axiom_interval_newton_step_ty())?;
1501 rng_ext_add_axiom(
1502 env,
1503 "IntervalNewton.converges",
1504 axiom_interval_newton_converges_ty(),
1505 )?;
1506 rng_ext_add_axiom(env, "Krawczyk.operator", axiom_krawczyk_operator_ty())?;
1507 rng_ext_add_axiom(
1508 env,
1509 "Krawczyk.enclosure_theorem",
1510 axiom_krawczyk_enclosure_ty(),
1511 )?;
1512 rng_ext_add_axiom(
1513 env,
1514 "ValidatedNumerics.enclosure",
1515 axiom_validated_numerics_enclosure_ty(),
1516 )?;
1517 rng_ext_add_axiom(env, "IntervalPresheaf", axiom_interval_presheaf_ty())?;
1518 rng_ext_add_axiom(
1519 env,
1520 "IntervalValuedProbability",
1521 axiom_interval_valued_probability_ty(),
1522 )?;
1523 rng_ext_add_axiom(
1524 env,
1525 "IntervalValuedProbability.measure",
1526 axiom_ivp_measure_ty(),
1527 )?;
1528 rng_ext_add_axiom(env, "ModalInterval", axiom_modal_interval_ty())?;
1529 rng_ext_add_axiom(env, "ModalInterval.dual", axiom_modal_interval_dual_ty())?;
1530 rng_ext_add_axiom(env, "FuzzyInterval", axiom_fuzzy_interval_ty())?;
1531 rng_ext_add_axiom(
1532 env,
1533 "FuzzyInterval.alpha_cut",
1534 axiom_fuzzy_interval_alpha_cut_ty(),
1535 )?;
1536 rng_ext_add_axiom(env, "SegmentTree", axiom_segment_tree_ty())?;
1537 rng_ext_add_axiom(env, "WeightedJob", axiom_weighted_job_ty())?;
1538 rng_ext_add_axiom(
1539 env,
1540 "IntervalScheduling.dpCorrect",
1541 axiom_interval_scheduling_dp_correct_ty(),
1542 )?;
1543 rng_ext_add_axiom(env, "Range.foldl_correct", axiom_range_foldl_correct_ty())?;
1544 rng_ext_add_axiom(env, "Range.all_iff", axiom_range_all_iff_ty())?;
1545 rng_ext_add_axiom(env, "Range.any_iff", axiom_range_any_iff_ty())?;
1546 rng_ext_add_axiom(
1547 env,
1548 "IntervalArithmetic.correctRounding",
1549 axiom_interval_correct_rounding_ty(),
1550 )?;
1551 rng_ext_add_axiom(env, "Interval.pow", axiom_interval_pow_ty())?;
1552 rng_ext_add_axiom(env, "Interval.sqrt", axiom_interval_sqrt_ty())?;
1553 rng_ext_add_axiom(env, "Interval.exp", axiom_interval_exp_ty())?;
1554 rng_ext_add_axiom(env, "Interval.log", axiom_interval_log_ty())?;
1555 rng_ext_add_axiom(env, "Interval.sin", axiom_interval_sin_ty())?;
1556 rng_ext_add_axiom(env, "Interval.cos", axiom_interval_cos_ty())?;
1557 rng_ext_add_axiom(env, "Interval.abs", axiom_interval_abs_ty())?;
1558 rng_ext_add_axiom(env, "Interval.neg", axiom_interval_neg_ty())?;
1559 Ok(())
1560}
1561#[cfg(test)]
1562mod range_extended_tests {
1563 use super::*;
1564 #[test]
1565 fn test_register_range_extended_succeeds() {
1566 let mut env = Environment::new();
1567 build_range_env(&mut env).expect("build_range_env should succeed");
1568 assert!(register_range_extended(&mut env).is_ok());
1569 }
1570 #[test]
1571 fn test_register_range_extended_axioms_present() {
1572 let mut env = Environment::new();
1573 build_range_env(&mut env).expect("build_range_env should succeed");
1574 register_range_extended(&mut env).expect("unwrap should succeed");
1575 assert!(env.get(&Name::str("Interval")).is_some());
1576 assert!(env.get(&Name::str("Interval.add")).is_some());
1577 assert!(env
1578 .get(&Name::str("MooreArithmetic.fundamental_theorem"))
1579 .is_some());
1580 assert!(env.get(&Name::str("SegmentTree")).is_some());
1581 assert!(env.get(&Name::str("FuzzyInterval")).is_some());
1582 assert!(env.get(&Name::str("ModalInterval")).is_some());
1583 }
1584 #[test]
1585 fn test_float_interval_new() {
1586 let iv = FloatInterval::new(1.0, 3.0);
1587 assert_eq!(iv.lo(), 1.0);
1588 assert_eq!(iv.hi(), 3.0);
1589 assert_eq!(iv.width(), 2.0);
1590 assert_eq!(iv.midpoint(), 2.0);
1591 }
1592 #[test]
1593 fn test_float_interval_contains() {
1594 let iv = FloatInterval::new(0.0, 1.0);
1595 assert!(iv.contains(0.5));
1596 assert!(iv.contains(0.0));
1597 assert!(iv.contains(1.0));
1598 assert!(!iv.contains(-0.1));
1599 assert!(!iv.contains(1.1));
1600 }
1601 #[test]
1602 fn test_float_interval_add() {
1603 let a = FloatInterval::new(1.0, 2.0);
1604 let b = FloatInterval::new(3.0, 4.0);
1605 let c = a.add(b);
1606 assert_eq!(c.lo(), 4.0);
1607 assert_eq!(c.hi(), 6.0);
1608 }
1609 #[test]
1610 fn test_float_interval_sub() {
1611 let a = FloatInterval::new(1.0, 3.0);
1612 let b = FloatInterval::new(1.0, 2.0);
1613 let c = a.sub(b);
1614 assert_eq!(c.lo(), -1.0);
1615 assert_eq!(c.hi(), 2.0);
1616 }
1617 #[test]
1618 fn test_float_interval_mul() {
1619 let a = FloatInterval::new(2.0, 3.0);
1620 let b = FloatInterval::new(4.0, 5.0);
1621 let c = a.mul(b);
1622 assert_eq!(c.lo(), 8.0);
1623 assert_eq!(c.hi(), 15.0);
1624 }
1625 #[test]
1626 fn test_float_interval_neg() {
1627 let a = FloatInterval::new(1.0, 3.0);
1628 let b = a.neg();
1629 assert_eq!(b.lo(), -3.0);
1630 assert_eq!(b.hi(), -1.0);
1631 }
1632 #[test]
1633 fn test_float_interval_intersect() {
1634 let a = FloatInterval::new(1.0, 5.0);
1635 let b = FloatInterval::new(3.0, 8.0);
1636 let c = a.intersect(b).expect("intersect should succeed");
1637 assert_eq!(c.lo(), 3.0);
1638 assert_eq!(c.hi(), 5.0);
1639 }
1640 #[test]
1641 fn test_float_interval_disjoint() {
1642 let a = FloatInterval::new(1.0, 2.0);
1643 let b = FloatInterval::new(3.0, 4.0);
1644 assert!(a.intersect(b).is_none());
1645 }
1646 #[test]
1647 fn test_float_interval_hull() {
1648 let a = FloatInterval::new(1.0, 3.0);
1649 let b = FloatInterval::new(2.0, 5.0);
1650 let h = a.hull(b);
1651 assert_eq!(h.lo(), 1.0);
1652 assert_eq!(h.hi(), 5.0);
1653 }
1654 #[test]
1655 fn test_float_interval_abs_positive() {
1656 let a = FloatInterval::new(2.0, 5.0);
1657 let b = a.abs();
1658 assert_eq!(b.lo(), 2.0);
1659 assert_eq!(b.hi(), 5.0);
1660 }
1661 #[test]
1662 fn test_float_interval_abs_negative() {
1663 let a = FloatInterval::new(-5.0, -2.0);
1664 let b = a.abs();
1665 assert_eq!(b.lo(), 2.0);
1666 assert_eq!(b.hi(), 5.0);
1667 }
1668 #[test]
1669 fn test_float_interval_abs_mixed() {
1670 let a = FloatInterval::new(-3.0, 5.0);
1671 let b = a.abs();
1672 assert_eq!(b.lo(), 0.0);
1673 assert_eq!(b.hi(), 5.0);
1674 }
1675 #[test]
1676 fn test_float_interval_subset() {
1677 let a = FloatInterval::new(2.0, 4.0);
1678 let b = FloatInterval::new(1.0, 5.0);
1679 assert!(a.is_subset_of(b));
1680 assert!(!b.is_subset_of(a));
1681 }
1682 #[test]
1683 fn test_scheduled_job_overlaps() {
1684 let j1 = ScheduledJob::new(0, 0, 5, 1);
1685 let j2 = ScheduledJob::new(1, 3, 8, 1);
1686 let j3 = ScheduledJob::new(2, 5, 10, 1);
1687 assert!(j1.overlaps(&j2));
1688 assert!(!j1.overlaps(&j3));
1689 }
1690 #[test]
1691 fn test_interval_scheduler_basic() {
1692 let jobs = vec![
1693 ScheduledJob::new(0, 0, 3, 3),
1694 ScheduledJob::new(1, 1, 4, 2),
1695 ScheduledJob::new(2, 3, 6, 4),
1696 ];
1697 let mut sched = IntervalScheduler::new(jobs);
1698 let w = sched.max_weight_schedule();
1699 assert!(w >= 4);
1700 }
1701 #[test]
1702 fn test_interval_scheduler_no_overlap() {
1703 let jobs = vec![
1704 ScheduledJob::new(0, 0, 2, 1),
1705 ScheduledJob::new(1, 2, 4, 2),
1706 ScheduledJob::new(2, 4, 6, 3),
1707 ];
1708 let mut sched = IntervalScheduler::new(jobs);
1709 let w = sched.max_weight_schedule();
1710 assert_eq!(w, 6);
1711 }
1712 #[test]
1713 fn test_seg_tree_build_query() {
1714 let values = vec![5i64, 3, 7, 1, 9, 2];
1715 let tree = RangeMinSegTree::build(&values);
1716 assert_eq!(tree.query_min(0, 5), Some(1));
1717 assert_eq!(tree.query_min(0, 2), Some(3));
1718 assert_eq!(tree.query_min(3, 5), Some(1));
1719 }
1720 #[test]
1721 fn test_seg_tree_update() {
1722 let values = vec![5i64, 3, 7, 1, 9, 2];
1723 let mut tree = RangeMinSegTree::build(&values);
1724 tree.update(3, 10);
1725 assert_eq!(tree.query_min(0, 5), Some(2));
1726 }
1727 #[test]
1728 fn test_seg_tree_empty() {
1729 let tree = RangeMinSegTree::build(&[]);
1730 assert!(tree.is_empty());
1731 assert_eq!(tree.query_min(0, 0), None);
1732 }
1733 #[test]
1734 fn test_krawczyk_finds_root_of_linear() {
1735 let solver = KrawczykSolver::new(50, 1e-10);
1736 let x0 = FloatInterval::new(1.0, 3.0);
1737 let result = solver.solve(x0, |x| x - 2.0, |_iv| FloatInterval::new(1.0, 1.0));
1738 assert!(result.is_some());
1739 let root_iv = result.expect("result should be valid");
1740 assert!(root_iv.contains(2.0));
1741 }
1742 #[test]
1743 fn test_validated_interval_verified() {
1744 let iv = FloatInterval::new(1.0, 2.0);
1745 let vi = ValidatedInterval::verified(iv, "test");
1746 assert!(vi.is_verified());
1747 assert_eq!(vi.certificate(), "test");
1748 }
1749 #[test]
1750 fn test_validated_interval_add() {
1751 let a = ValidatedInterval::verified(FloatInterval::new(1.0, 2.0), "a");
1752 let b = ValidatedInterval::verified(FloatInterval::new(3.0, 4.0), "b");
1753 let c = a.add(&b);
1754 assert!(c.is_verified());
1755 assert_eq!(c.interval().lo(), 4.0);
1756 assert_eq!(c.interval().hi(), 6.0);
1757 }
1758 #[test]
1759 fn test_validated_interval_unverified_propagates() {
1760 let a = ValidatedInterval::verified(FloatInterval::new(1.0, 2.0), "a");
1761 let b = ValidatedInterval::unverified(FloatInterval::new(3.0, 4.0));
1762 let c = a.add(&b);
1763 assert!(!c.is_verified());
1764 }
1765 #[test]
1766 fn test_axiom_type_builders_interval() {
1767 let _ = axiom_interval_type_ty();
1768 let _ = axiom_interval_mk_ty();
1769 let _ = axiom_interval_add_ty();
1770 let _ = axiom_interval_mul_ty();
1771 let _ = axiom_interval_width_ty();
1772 let _ = axiom_interval_midpoint_ty();
1773 let _ = axiom_interval_newton_step_ty();
1774 let _ = axiom_krawczyk_operator_ty();
1775 let _ = axiom_segment_tree_query_ty();
1776 let _ = axiom_interval_scheduling_optimal_ty();
1777 }
1778}