1#![allow(unreachable_code)]
4
5use crate::*;
6
7pub fn transitivity<A: Prop, B: Prop, C: Prop>((f0, f1): Eq<A, B>, (g0, g1): Eq<B, C>) -> Eq<A, C> {
9 (Rc::new(move |x| g0(f0(x))), Rc::new(move |x| f1(g1(x))))
10}
11
12pub fn trans3<A: Prop, B: Prop, C: Prop, D: Prop>(
14 ab: Eq<A, B>,
15 bc: Eq<B, C>,
16 cd: Eq<C, D>
17) -> Eq<A, D> {transitivity(ab, transitivity(bc, cd))}
18
19pub fn trans4<A: Prop, B: Prop, C: Prop, D: Prop, E: Prop>(
21 ab: Eq<A, B>,
22 bc: Eq<B, C>,
23 cd: Eq<C, D>,
24 de: Eq<D, E>
25) -> Eq<A, E> {transitivity(trans3(ab, bc, cd), de)}
26
27pub fn trans5<A: Prop, B: Prop, C: Prop, D: Prop, E: Prop, F: Prop>(
29 ab: Eq<A, B>,
30 bc: Eq<B, C>,
31 cd: Eq<C, D>,
32 de: Eq<D, E>,
33 ef: Eq<E, F>,
34) -> Eq<A, F> {transitivity(trans4(ab, bc, cd, de), ef)}
35
36pub fn double_neg<A: Prop>(a: A) -> Eq<A, Not<Not<A>>> {
38 let double_neg = a.double_neg();
39 (Rc::new(move |x| not::double(x)), Rc::new(move |x| double_neg(x)))
40}
41
42pub fn symmetry<A: Prop, B: Prop>((f0, f1): Eq<A, B>) -> Eq<B, A> {
44 (f1, f0)
45}
46
47pub fn neq_symmetry<A: Prop, B: Prop>(neq: Not<Eq<A, B>>) -> Not<Eq<B, A>> {
49 Rc::new(move |eq| neq(symmetry(eq)))
50}
51
52pub fn imply_to_or_da<A: DProp, B: Prop>() -> Eq<Imply<A, B>, Or<Not<A>, B>> {
54 (Rc::new(move |x| imply::to_or_da(x)), Rc::new(move |x| imply::from_or(x)))
55}
56
57pub fn imply_to_or_db<A: Prop, B: DProp>() -> Eq<Imply<A, B>, Or<Not<A>, B>> {
59 (Rc::new(move |x| imply::to_or_db(x)), Rc::new(move |x| imply::from_or(x)))
60}
61
62pub fn refl<A: Prop>() -> Eq<A, A> {
64 (Rc::new(move |x| x), Rc::new(move |x| x))
65}
66
67pub fn anti<A: Prop>((f0, f1): Eq<A, Not<A>>) -> False {
69 let na: Not<A> = Rc::new(move |a| f0(a.clone())(a));
70 let a = f1(na.clone());
71 na(a)
72}
73
74pub fn true_eq<A: Prop>(a: A) -> Eq<A, True> {
79 (True.map_any(), Rc::new(move |_| a.clone()))
80}
81
82pub fn modus_tollens<A: Prop, B: Prop>((f0, f1): Eq<A, B>) -> Eq<Not<B>, Not<A>> {
84 let f02 = imply::modus_tollens(f0);
85 let f12 = imply::modus_tollens(f1);
86 (f02, f12)
87}
88
89pub fn rev_modus_tollens<A: DProp, B: DProp>((f0, f1): Eq<Not<A>, Not<B>>) -> Eq<B, A> {
91 let f02 = imply::rev_modus_tollens(f0);
92 let f12 = imply::rev_modus_tollens(f1);
93 (f02, f12)
94}
95
96pub fn rev_modus_tollens_excm<A: Prop, B: Prop>(
98 (f0, f1): Eq<Not<A>, Not<B>>,
99 excm_a: ExcM<A>,
100 excm_b: ExcM<B>,
101) -> Eq<B, A> {
102 let f02 = imply::rev_modus_tollens_excm(f0, excm_b.clone(), excm_a.clone());
103 let f12 = imply::rev_modus_tollens_excm(f1, excm_a, excm_b);
104 (f02, f12)
105}
106
107pub fn rev_modus_tollens_eq_excm<A: Prop, B: Prop>(
109 (f0, f1): Eq<Not<A>, Not<B>>,
110 eq_excm_a_excm_b: Eq<ExcM<A>, ExcM<B>>,
111) -> Eq<B, A> {
112 let f02 = imply::rev_modus_tollens_eq_excm(f0, eq::symmetry(eq_excm_a_excm_b.clone()));
113 let f12 = imply::rev_modus_tollens_eq_excm(f1, eq_excm_a_excm_b);
114 (f02, f12)
115}
116
117pub fn rev_modus_tollens_imply_excm<A: Prop, B: Prop>(
119 (f0, f1): Eq<Not<A>, Not<B>>,
120 a_excm_b: Imply<A, ExcM<B>>,
121 b_excm_a: Imply<B, ExcM<A>>,
122) -> Eq<B, A> {
123 let f02 = imply::rev_modus_tollens_imply_excm(f0, b_excm_a);
124 let f12 = imply::rev_modus_tollens_imply_excm(f1, a_excm_b);
125 (f02, f12)
126}
127
128pub fn is_true<A: Prop>((f0, _): Eq<True, A>) -> A {
130 f0(True)
131}
132
133pub fn is_false<A: Prop>((_, f1): Eq<False, A>) -> Not<A> {
135 f1
136}
137
138pub fn to_eq_false<A: Prop>(n_a: Not<A>) -> Eq<A, False> {
140 (n_a, imply::absurd())
141}
142
143pub fn contra<A: Prop, B: DProp>(f: Not<Eq<A, B>>, a: A) -> Not<B> {
145 contra_excm(f, a, B::decide())
146}
147
148pub fn contra_excm<A: Prop, B: Prop>(
150 f: Not<Eq<A, B>>,
151 a: A,
152 excm_b: ExcM<B>
153) -> Not<B> {
154 match excm_b {
155 Left(b) => not::absurd(f, and::to_eq_pos((a, b))),
156 Right(not_b) => not_b,
157 }
158}
159
160pub fn assoc_right<A: DProp, B: DProp, C: DProp>((f0, f1): Eq<Eq<A, B>, C>) -> Imply<A, Eq<B, C>> {
162 match (A::decide(), C::decide()) {
163 (Right(not_a), _) => Rc::new(move |x| match not_a.clone()(x) {}),
164 (_, Left(c)) =>
165 Rc::new(move |x| (c.clone().map_any(), f1.clone()(c.clone()).0(x).map_any())),
166 (Left(a), Right(not_c)) => {
167 let g = imply::rev_modus_ponens(f0, not_c.clone());
169 let not_b = eq::contra(g, a);
170 and::to_eq_neg((not_b, not_c)).map_any()
171 }
172 }
173}
174
175pub fn assoc_left<A: DProp, B: DProp, C: DProp>((f0, f1): Eq<Eq<A, B>, C>) -> Imply<Eq<B, C>, A> {
177 match (A::decide(), B::decide(), C::decide()) {
178 (Left(a), _, _) => a.map_any(),
179 (Right(not_a), Right(not_b), Right(not_c)) =>
180 match not_c(f0(and::to_eq_neg((not_a, not_b)))) {},
181 (_, Left(b), Right(not_c)) =>
182 Rc::new(move |(fb, _)| match not_c.clone()(fb(b.clone())) {}),
183 (_, Right(not_b), Left(c)) =>
184 Rc::new(move |(_, fc)| match not_b.clone()(fc(c.clone())) {}),
185 (Right(not_a), Left(b), Left(c)) => {
186 let (_, g1) = f1(c);
188 let a = g1(b);
189 match not_a(a) {}
190 }
191 }
192}
193
194pub fn assoc<A: DProp, B: DProp, C: DProp>(f: Eq<Eq<A, B>, C>) -> Eq<A, Eq<B, C>> {
196 (assoc_right(f.clone()), assoc_left(f))
197}
198
199pub fn swap_right<A: Prop, B: Prop, C: Prop>((f0, f1): Eq<A, Eq<B, C>>) -> Eq<A, Eq<C, B>> {
201 (Rc::new(move |x| {let (g0, g1) = f0(x); (g1, g0)}),
202 Rc::new(move |(g1, g0)| f1((g0, g1))))
203}
204
205pub fn swap_left<A: Prop, B: Prop, C: Prop>(f: Eq<Eq<A, B>, C>) -> Eq<Eq<B, A>, C> {
207 symmetry(swap_right(symmetry(f)))
208}
209
210pub fn in_left_arg<A: Prop, B: Prop, C: Prop>(f: Eq<A, B>, g: Eq<A, C>) -> Eq<C, B> {
212 symmetry(transitivity(symmetry(f), g))
213}
214
215pub fn in_right_arg<A: Prop, B: Prop, C: Prop>(f: Eq<A, B>, g: Eq<B, C>) -> Eq<A, C> {
217 transitivity(f, g)
218}
219
220pub fn in_left<A: Prop, B: Prop, C: Prop, F, G>(
222 eq_ab: Eq<A, B>,
223 f: F,
224 g: G,
225) -> Eq<C, B>
226 where F: Fn(A) -> C + 'static,
227 G: Fn(C) -> A + 'static
228{in_left_arg(eq_ab, (Rc::new(f), Rc::new(g)))}
229
230pub fn in_right<A: Prop, B: Prop, C: Prop, F, G>(
232 eq_ab: Eq<A, B>,
233 f: F,
234 g: G,
235) -> Eq<A, C>
236 where F: Fn(B) -> C + 'static,
237 G: Fn(C) -> B + 'static
238{eq::symmetry(in_left(eq::symmetry(eq_ab), f, g))}
239
240pub fn eq_left<A: Prop, B: Prop, C: Prop>(x: Eq<A, B>) -> Eq<Eq<A, C>, Eq<B, C>> {
242 let x2 = symmetry(x.clone());
243 (Rc::new(move |ac| in_left_arg(ac, x.clone())),
244 Rc::new(move |bc| in_left_arg(bc, x2.clone())))
245}
246
247pub fn eq_right<A: Prop, B: Prop, C: Prop>(x: Eq<A, B>) -> Eq<Eq<C, A>, Eq<C, B>> {
249 let x2 = symmetry(x.clone());
250 (Rc::new(move |ac| in_right_arg(ac, x.clone())),
251 Rc::new(move |bc| in_right_arg(bc, x2.clone())))
252}
253
254pub fn symmetry_eq<A: Prop, B: Prop>() -> Eq<Eq<A, B>, Eq<B, A>> {
256 (Rc::new(move |x| eq::symmetry(x)),
257 Rc::new(move |x| eq::symmetry(x)))
258}
259
260pub fn assoc_eq<A: DProp, B: DProp, C: DProp>() -> Eq<Eq<Eq<A, B>, C>, Eq<A, Eq<B, C>>> {
262 (Rc::new(move |x| eq::assoc(x)), Rc::new(move |x| {
263 let x2 = eq::symmetry(x);
264 let x3 = eq::in_left_arg(x2, symmetry_eq());
265 let x4 = eq::assoc(x3);
266 let x5 = eq::symmetry(x4);
267 eq::in_left_arg(x5, symmetry_eq())
268 }))
269}
270
271pub fn transpose<A: DProp, B: DProp, C: DProp, D: DProp>(
273 f: Eq<Eq<A, B>, Eq<C, D>>
274) -> Eq<Eq<A, C>, Eq<B, D>> {
275 let f = eq::in_left_arg(f, eq::symmetry_eq());
276 let f = eq::in_right_arg(f, eq::symmetry_eq());
277 let f = eq::assoc(f);
278 let f = eq::in_right_arg(f, eq::symmetry_eq());
279 let f = eq::in_right_arg(f, eq::assoc_eq());
280 let f = eq::symmetry(f);
281 let f = eq::assoc(f);
282 let f = eq::symmetry(f);
283 let f = eq::assoc(f);
284 eq::in_left_arg(f, eq::symmetry_eq())
285}
286
287pub fn triangle<A: DProp, B: DProp, C: DProp>(f: Eq<Eq<A, B>, Eq<C, B>>) -> Eq<A, C> {
289 let f = eq::transpose(f);
290 f.1(eq::refl())
291}
292
293pub fn inv_triangle<A: DProp, B: DProp, C: DProp>(
295 f: Eq<Not<Eq<A, B>>, Not<Eq<C, B>>>
296) -> Eq<A, C> {
297 let f = eq::rev_modus_tollens(f);
298 let f = eq::symmetry(f);
299 eq::triangle(f)
300}
301
302pub fn absurd() -> Eq<False, False> {
304 (imply::absurd(), imply::absurd())
305}
306
307pub fn neq_left<A: Prop, B: Prop, C: Prop>(
309 eq_ab: Eq<A, B>,
310 neq_ac: Not<Eq<A, C>>
311) -> Not<Eq<B, C>> {
312 Rc::new(move |eq_bc| neq_ac(transitivity(eq_ab.clone(), eq_bc)))
313}
314
315pub fn neq_right<A: Prop, B: Prop, C: Prop>(
317 eq_ab: Eq<A, B>,
318 neq_bc: Not<Eq<B, C>>
319) -> Not<Eq<A, C>> {
320 Rc::new(move |eq_ac| neq_bc(transitivity(symmetry(eq_ab.clone()), eq_ac)))
321}
322
323pub fn neq_to_nand<A: Prop, B: Prop>(neq: Not<Eq<A, B>>) -> Not<And<A, B>> {
325 Rc::new(move |(a, b)| neq((b.map_any(), a.map_any())))
326}
327
328pub fn neq_to_eq_not<A: DProp, B: DProp>(x: Not<Eq<A, B>>) -> Eq<A, Not<B>> {
330 let x2 = x.clone();
331 (Rc::new(move |a| {
332 let x = x2.clone();
333 Rc::new(move |b| x.clone()((b.map_any(), a.clone().map_any())))
334 }),
335 Rc::new(move |nb| match A::decide() {
336 Left(a) => a,
337 Right(na) => not::absurd(x.clone(), eq::rev_modus_tollens((na.map_any(), nb.map_any()))),
338 }))
339}
340
341pub fn eq_not_to_neq<A: Prop, B: Prop>(f: Eq<A, Not<B>>) -> Not<Eq<A, B>> {
343 Rc::new(move |eq_ab| anti(in_left_arg(f.clone(), eq_ab)))
344}
345
346pub fn eq_to_eq_excm<A: Prop, B: Prop>(x: Eq<A, B>) -> Eq<ExcM<A>, ExcM<B>> {
348 let x2 = x.clone();
349 (
350 Rc::new(move |excm_a| {
351 let x = x2.clone();
352 match excm_a {
353 Left(a) => Left(x.0(a)),
354 Right(na) => Right(eq::modus_tollens(x).1(na)),
355 }
356 }),
357 Rc::new(move |excm_b| {
358 let x = x.clone();
359 match excm_b {
360 Left(b) => Left(x.1(b)),
361 Right(nb) => Right(eq::modus_tollens(x).0(nb)),
362 }
363 })
364 )
365}