1#![allow(unreachable_code)]
4
5use crate::*;
6
7pub fn modus_tollens<A: Prop, B: Prop>(f: Imply<A, B>) -> Imply<Not<B>, Not<A>> {
11 Rc::new(move |x| {
12 let f = f.clone();
13 Rc::new(move |y| match x(f(y)) {})
14 })
15}
16
17pub fn rev_modus_tollens<A: DProp, B: DProp>(f: Imply<Not<B>, Not<A>>) -> Imply<A, B> {
19 imply::rev_double_neg(Rc::new(move |x| {
20 let f = f.clone();
21 Rc::new(move |y| match x(f(y)) {})
22 }))
23}
24
25pub fn rev_modus_tollens_excm<A: Prop, B: Prop>(
27 f: Imply<Not<B>, Not<A>>,
28 excm_a: ExcM<A>,
29 excm_b: ExcM<B>,
30) -> Imply<A, B> {
31 imply::rev_double_neg_excm(Rc::new(move |x| {
32 let f = f.clone();
33 Rc::new(move |y| match x(f(y)) {})
34 }), excm_a, excm_b)
35}
36
37pub fn rev_modus_tollens_eq_excm<A: Prop, B: Prop>(
39 f: Imply<Not<B>, Not<A>>,
40 eq_excm_a_excm_b: Eq<ExcM<A>, ExcM<B>>,
41) -> Imply<A, B> {
42 imply::rev_double_neg_eq_excm(Rc::new(move |x| {
43 let f = f.clone();
44 Rc::new(move |y| match x(f(y)) {})
45 }), eq_excm_a_excm_b)
46}
47
48pub fn rev_modus_tollens_imply_excm<A: Prop, B: Prop>(
50 f: Imply<Not<B>, Not<A>>,
51 a_excm_b: Imply<A, ExcM<B>>,
52) -> Imply<A, B> {
53 imply::rev_double_neg_imply_excm(Rc::new(move |x| {
54 let f = f.clone();
55 Rc::new(move |y| match x(f(y)) {})
56 }), a_excm_b)
57}
58
59pub fn transitivity<A: Prop, B: Prop, C: Prop>(
61 f: Imply<A, B>,
62 g: Imply<B, C>,
63) -> Imply<A, C> {
64 Rc::new(move |x| g(f(x)))
65}
66
67pub fn modus_ponens<A: Prop, B: Prop>(
69 f: Imply<A, B>,
70 a: A,
71) -> B {
72 f(a)
73}
74
75pub fn rev_modus_ponens<A: Prop, B: Prop>(g: Imply<B, A>, f: Not<A>) -> Not<B> {
77 Rc::new(move |b| f(g(b)))
78}
79
80pub fn reorder_args<A: Prop, B: Prop, C: Prop>(
82 f: Imply<A, Imply<B, C>>
83) -> Imply<B, Imply<A, C>> {
84 Rc::new(move |x| {
85 let f = f.clone();
86 Rc::new(move |y| f(y)(x.clone()))
87 })
88}
89
90pub fn double_neg<A: DProp, B: Prop>(f: Imply<A, B>) -> Imply<Not<Not<A>>, Not<Not<B>>> {
92 Rc::new(move |nn_a| not::double(f(not::rev_double(nn_a))))
93}
94
95pub fn rev_double_neg<A: DProp, B: DProp>(f: Imply<Not<Not<A>>, Not<Not<B>>>) -> Imply<A, B> {
97 use Either::*;
98
99 let a = <A as Decidable>::decide();
100 let b = <B as Decidable>::decide();
101 match (a, b) {
102 (_, Left(b)) => b.map_any(),
103 (Right(a), _) => Rc::new(move |x| match a(x) {}),
104 (Left(a), Right(b)) => match f(not::double(a))(b) {}
105 }
106}
107
108pub fn rev_double_neg_excm<A: Prop, B: Prop>(
110 f: Imply<Not<Not<A>>, Not<Not<B>>>,
111 excm_a: ExcM<A>,
112 excm_b: ExcM<B>,
113) -> Imply<A, B> {
114 use Either::*;
115
116 match (excm_a, excm_b) {
117 (_, Left(b)) => b.map_any(),
118 (Right(a), _) => Rc::new(move |x| match a(x) {}),
119 (Left(a), Right(b)) => match f(not::double(a))(b) {}
120 }
121}
122
123pub fn rev_double_neg_eq_excm<A: Prop, B: Prop>(
125 f: Imply<Not<Not<A>>, Not<Not<B>>>,
126 eq_excm_a_excm_b: Eq<ExcM<A>, ExcM<B>>,
127) -> Imply<A, B> {
128 use Either::*;
129
130 Rc::new(move |a| {
131 match eq_excm_a_excm_b.0(Left(a.clone())) {
132 Left(b) => b,
133 Right(nb) => match f(not::double(a))(nb) {}
134 }
135 })
136}
137
138pub fn rev_double_neg_imply_excm<A: Prop, B: Prop>(
140 f: Imply<Not<Not<A>>, Not<Not<B>>>,
141 a_excm_b: Imply<A, ExcM<B>>,
142) -> Imply<A, B> {
143 use Either::*;
144
145 Rc::new(move |a| {
146 match a_excm_b(a.clone()) {
147 Left(b) => b,
148 Right(nb) => match f(not::double(a))(nb) {}
149 }
150 })
151}
152
153pub fn to_or_da<A: DProp, B: Prop>(f: Imply<A, B>) -> Or<Not<A>, B> {
155 to_or_excm_a(f, A::decide())
156}
157
158pub fn to_or_excm_a<A: Prop, B: Prop>(f: Imply<A, B>, excm_a: ExcM<A>) -> Or<Not<A>, B> {
160 use Either::*;
161
162 match excm_a {
163 Left(a) => Right(f(a)),
164 Right(na) => Left(na),
165 }
166}
167
168pub fn to_or_db<A: Prop, B: DProp>(f: Imply<A, B>) -> Or<Not<A>, B> {
170 to_or_excm_b(f, B::decide())
171}
172
173pub fn to_or_excm_b<A: Prop, B: Prop>(f: Imply<A, B>, excm_b: ExcM<B>) -> Or<Not<A>, B> {
175 use Either::*;
176
177 match excm_b {
178 Left(b) => Right(b),
179 Right(nb) => Left(modus_tollens(f)(nb)),
180 }
181}
182
183pub fn from_or<A: Prop, B: Prop>(f: Or<Not<A>, B>) -> Imply<A, B> {
185 Rc::new(move |a| {
186 match f.clone() {
187 Left(na) => absurd()(na(a)),
188 Right(b) => b,
189 }
190 })
191}
192
193pub fn flip_neg_left<A: DProp, B: Prop>(f: Imply<Not<A>, B>) -> Imply<Not<B>, A> {
195 let g = imply::modus_tollens(f);
196 Rc::new(move |x| not::rev_double(g(x)))
197}
198
199pub fn flip_neg_left_excm<A: Prop, B: Prop>(f: Imply<Not<A>, B>, excm: ExcM<A>) -> Imply<Not<B>, A> {
201 let g = imply::modus_tollens(f);
202 Rc::new(move |x| not::rev_double_excm(g(x), excm.clone()))
203}
204
205pub fn flip_neg_right<A: Prop, B: Prop>(f: Imply<A, Not<B>>) -> Imply<B, Not<A>> {
207 let g = imply::modus_tollens(f);
208 Rc::new(move |x| g(not::double(x)))
209}
210
211pub fn chain<A: Prop, B: Prop, C: Prop>(f: Imply<And<A, B>, C>) -> Imply<A, Imply<B, C>> {
213 Rc::new(move |x| {
214 let f = f.clone();
215 Rc::new(move |y| f((x.clone(), y)))
216 })
217}
218
219pub fn rev_chain<A: Prop, B: Prop, C: Prop>(f: Imply<A, Imply<B, C>>) -> Imply<And<A, B>, C> {
221 Rc::new(move |(a, b)| f(a)(b))
222}
223
224pub fn in_left_arg<A: Prop, B: Prop, C: Prop>(f: Imply<A, B>, (_, g1): Eq<A, C>) -> Imply<C, B> {
226 transitivity(g1, f)
227}
228
229pub fn in_right_arg<A: Prop, B: Prop, C: Prop>(f: Imply<A, B>, (g0, _): Eq<B, C>) -> Imply<A, C> {
231 transitivity(f, g0)
232}
233
234pub fn in_left<A: Prop, B: Prop, C: Prop, F>(
236 ab: Imply<A, B>,
237 f: F
238) -> Imply<C, B>
239 where F: Fn(C) -> A + 'static
240{
241 Rc::new(move |c| ab(f(c)))
242}
243
244pub fn in_right<A: Prop, B: Prop, C: Prop, F>(
246 ab: Imply<A, B>,
247 f: F
248) -> Imply<A, C>
249 where F: Fn(A, B) -> C + 'static
250{
251 Rc::new(move |a| f(a.clone(), ab(a)))
252}
253
254pub fn eq_left<A: Prop, B: Prop, C: Prop>((ab, ba): Eq<A, B>) -> Eq<Imply<A, C>, Imply<B, C>> {
256 (Rc::new(move |ac| transitivity(ba.clone(), ac)),
257 Rc::new(move |bc| transitivity(ab.clone(), bc)))
258}
259
260pub fn eq_right<A: Prop, B: Prop, C: Prop>((ab, ba): Eq<A, B>) -> Eq<Imply<C, A>, Imply<C, B>> {
262 (Rc::new(move |ca| transitivity(ca, ab.clone())),
263 Rc::new(move |cb| transitivity(cb, ba.clone())))
264}
265
266pub fn join<A: Prop, B: Prop, C: Prop>(f: Imply<A, C>, _: Imply<B, C>) -> Imply<And<A, B>, C> {
268 Rc::new(move |(a, _)| f.clone()(a))
269}
270
271pub fn absurd<A: Prop>() -> Imply<False, A> {
273 Rc::new(|x| match x {})
274}
275
276pub fn id<A: Prop>() -> Imply<A, A> {
278 Rc::new(|x| x)
279}
280
281pub fn or_split_da<A: DProp, B: Prop, C: Prop>(
283 f: Imply<A, Or<B, C>>
284) -> Or<Imply<A, B>, Imply<A, C>> {
285 or_split_excm_a(f, A::decide())
286}
287
288pub fn or_split_excm_a<A: Prop, B: Prop, C: Prop>(
290 f: Imply<A, Or<B, C>>,
291 excm_a: ExcM<A>
292) -> Or<Imply<A, B>, Imply<A, C>> {
293 match excm_a {
294 Left(a) => match f(a) {
295 Left(b) => Left(b.map_any()),
296 Right(c) => Right(c.map_any())
297 }
298 Right(na) => Left(Rc::new(move |a| not::absurd(na.clone(), a)))
299 }
300}
301
302pub fn or_split_db<A: Prop, B: DProp, C: Prop>(
304 f: Imply<A, Or<B, C>>
305) -> Or<Imply<A, B>, Imply<A, C>> {
306 match B::decide() {
307 Left(b) => Left(b.map_any()),
308 Right(nb) => Right(Rc::new(move |a| match f(a) {
309 Left(b) => not::absurd(nb.clone(), b),
310 Right(c) => c
311 }))
312 }
313}
314
315pub fn or_split_dc<A: Prop, B: Prop, C: DProp>(
317 f: Imply<A, Or<B, C>>
318) -> Or<Imply<A, B>, Imply<A, C>> {
319 match C::decide() {
320 Left(c) => Right(c.map_any()),
321 Right(nc) => Left(Rc::new(move |a| match f(a) {
322 Left(b) => b,
323 Right(c) => not::absurd(nc.clone(), c)
324 }))
325 }
326}
327
328pub fn and_map<A: Prop, B: Prop>(a: A) -> Imply<B, And<A, B>> {
330 Rc::new(move |b| (a.clone(), b))
331}
332
333pub fn total<A: DProp, B: Prop>() -> Or<Imply<A, B>, Imply<B, A>> {
337 total_excm(A::decide())
338}
339
340pub fn total_excm<A: Prop, B: Prop>(excm_a: ExcM<A>) -> Or<Imply<A, B>, Imply<B, A>> {
344 match excm_a {
345 Left(a) => Right(a.map_any()),
346 Right(na) => Left(rev_modus_tollens_imply_excm(na.clone().map_any(),
347 Rc::new(move |a| not::absurd(na.clone(), a)))),
348 }
349}
350
351pub fn reduce<A: Prop, B: Prop>(x: Imply<A, Imply<A, B>>) -> Imply<A, B> {
353 Rc::new(move |a| x(a.clone())(a))
354}