constructive/
constructive.rs

1/*
2
3It is desirable to be able to predict whether a theorem
4is constructive or not using composition of theorems:
5
6    x : [constructive] true, y : [constructive] true
7    ------------------------------------------------
8    (x, y) : [constructive] true
9
10In general, one would like to have normal paths, such as:
11
12    and[constructive] <=> and
13
14However, in order to do this prediction safely,
15one must prove that the operation is safe for these predictions.
16
17This safety property is proved using excluded middle for the tautology of some proposition:
18
19    x^true | !(x^true)
20
21This means, either we know `x` is constructive or non-constructive.
22
23*/
24
25use prop::*;
26use std::rc::Rc;
27use prop::Either::*;
28use prop::hooo::*;
29
30fn main() {
31}
32
33pub type Safe<A> = ExcM<Tauto<A>>;
34
35pub fn and_is_safe<A: Prop, B: Prop>(
36    safe_a: Safe<A>,
37    safe_b: Safe<B>
38) -> Safe<And<A, B>> {
39    match (safe_a, safe_b) {
40        (Left(tauto_a), Left(tauto_b)) => Left(tauto_and(tauto_a, tauto_b)),
41        (Right(n_tauto_a), _) => Right(Rc::new(move |tauto_ab| {
42            n_tauto_a(tauto_rev_and(tauto_ab).0)
43        })),
44        (_, Right(n_tauto_b)) => Right(Rc::new(move |tauto_ab| {
45            n_tauto_b(tauto_rev_and(tauto_ab).1)
46        }))
47    }
48}
49
50pub fn or_is_safe<A: Prop, B: Prop>(
51    safe_a: Safe<A>,
52    safe_b: Safe<B>
53) -> Safe<Or<A, B>> {
54    match (safe_a, safe_b) {
55        (Left(tauto_a), _) => Left(tauto_or_left(tauto_a)),
56        (_, Left(tauto_b)) => Left(tauto_or_right(tauto_b)),
57        (Right(n_tauto_a), Right(n_tauto_b)) => Right(Rc::new(move |tauto_or_ab| {
58            match tauto_rev_or(tauto_or_ab) {
59                Left(tauto_a) => n_tauto_a(tauto_a),
60                Right(tauto_b) => n_tauto_b(tauto_b),
61            }
62        }))
63    }
64}
65
66pub fn not_is_safe<A: DProp>(
67    safe_a: Safe<A>
68) -> Safe<Not<A>> {
69    match safe_a {
70        Left(tauto_a) => Right(tauto_rev_not(tauto_not_double(tauto_a))),
71        Right(n_tauto_a) => Left(tauto_not(n_tauto_a)),
72    }
73}