1use crate::{ops::{Add, Sub}, term::{Term, ValueEq}, type_eq::refl};
2
3use super::{add::{a_plus_0_eq_a, a_plus_s_b_eq_s_add_a_b, add_0_a_eq_a, add_associative, add_commutative, add_eq_to_left_eq, s_a_plus_b_eq_s_add_a_b}, succ_eq_to_eq, Int, Succ, Zero};
4
5pub fn a_minus_b_plus_b_eq_a<N, A: Term<Type = N>, B: Term<Type = N>>(
7 ) -> ValueEq<Add<Sub<A, B>, B>, A>
8 where N: Int
9{
10 unsafe {ValueEq::axiom()}
12}
13
14pub fn add_sub_associative<N, A: Term<Type = N>, B: Term<Type = N>, C: Term<Type = N>>(
16 ) -> ValueEq<Add<A, Sub<B, C>>, Sub<Add<A, B>, C>>
17 where N: Int
18{
19 let lemma = -add_associative() + Add::eq(refl(), a_minus_b_plus_b_eq_a()) - a_minus_b_plus_b_eq_a();
21
22 add_eq_to_left_eq(lemma, refl())
23}
24
25#[allow(non_snake_case)]
30pub fn a_plus_b_minus_b_eq_a<N, A: Term<Type = N>, B: Term<Type = N>>(
31 ) -> ValueEq<Sub<Add<A, B>, B>, A>
32 where N: Int
33{
34 add_eq_to_left_eq(a_minus_b_plus_b_eq_a(), refl())
38}
39
40pub fn sub_add_associative<N, A: Term<Type = N>, B: Term<Type = N>, C: Term<Type = N>>(
42) -> ValueEq<Sub<A, Add<B, C>>, Sub<Sub<A, B>, C>>
43where N: Int
44{
45 let lemma = a_minus_b_plus_b_eq_a() - a_minus_b_plus_b_eq_a() + Add::eq(-a_minus_b_plus_b_eq_a(), refl()) - add_associative() + Add::eq(refl(), add_commutative());
47
48 add_eq_to_left_eq(lemma, refl())
49}
50
51pub fn add_sub_commutative<N, A: Term<Type = N>, B: Term<Type = N>, C: Term<Type = N>>(
53) -> ValueEq<Add<Sub<A, B>, C>, Sub<Add<A, C>, B>>
54where N: Int
55{
56 let lemma = -add_associative() + Add::eq(refl(), add_commutative()) + add_associative() + Add::eq(a_minus_b_plus_b_eq_a(), refl()) - a_minus_b_plus_b_eq_a();
58
59 add_eq_to_left_eq(lemma, refl())
60}
61
62pub fn a_minus_sub_b_c_eq_a_plus_sub_c_b<N, A: Term<Type = N>, B: Term<Type = N>, C: Term<Type = N>>(
64 ) -> ValueEq<Sub<A, Sub<B, C>>, Add<A, Sub<C, B>>>
65 where N: Int
66{
67 let lemma = add_associative() + Add::eq(a_minus_b_plus_b_eq_a(), refl()) + Add::eq(refl(), -a_minus_b_plus_b_eq_a()) + add_associative() + Add::eq(refl(), -a_minus_b_plus_b_eq_a());
69
70 add_eq_to_left_eq(lemma, refl())
71}
72
73pub fn sub_sub_associative<N, A: Term<Type = N>, B: Term<Type = N>, C: Term<Type = N>>(
75) -> ValueEq<Sub<A, Sub<B, C>>, Add<Sub<A, B>, C>>
76where N: Int
77{
78 a_minus_sub_b_c_eq_a_plus_sub_c_b() + add_sub_associative() - add_sub_commutative()
80}
81
82pub fn a_minus_a_eq_0<N, A: Term<Type = N>>(
84 ) -> ValueEq<Sub<A, A>, Zero<N>>
85 where N: Int
86{
87 let lemma = a_minus_b_plus_b_eq_a() - a_plus_0_eq_a() + add_commutative();
89
90 add_eq_to_left_eq(lemma, refl())
91}
92
93pub fn a_minus_0_eq_a<N, A: Term<Type = N>>(
95 ) -> ValueEq<Sub<A, Zero<N>>, A>
96where N: Int
97{
98 let lemma = a_minus_b_plus_b_eq_a() - a_plus_0_eq_a();
100
101 add_eq_to_left_eq(lemma, refl())
102}
103
104pub fn s_a_minus_s_b_eq_a_minus_b<N, A: Term<Type = N>, B: Term<Type = N>>(
106 ) -> ValueEq<Sub<Succ<A>, Succ<B>>, Sub<A, B>>
107 where N: Int
108{
109 let lemma = succ_eq_to_eq(-a_plus_s_b_eq_s_add_a_b() + a_minus_b_plus_b_eq_a());
112
113 -a_plus_b_minus_b_eq_a() + Sub::eq(lemma, refl())
115}
116
117#[allow(non_snake_case)]
119pub fn s_a_minus_b_eq_s_sub_a_b<N, A: Term<Type = N>, B: Term<Type = N>>(
120 ) -> ValueEq<Sub<Succ<A>, B>, Succ<Sub<A, B>>>
121 where N: Int
122{
123 let lemma = s_a_plus_b_eq_s_add_a_b() + Succ::eq(a_minus_b_plus_b_eq_a());
125
126 -Sub::eq(lemma, refl()) + a_plus_b_minus_b_eq_a()
128}
129
130pub fn s_a_minus_s_0_eq_a<N, A: Term<Type = N>>(
132 ) -> ValueEq<Sub<Succ<A>, Succ<Zero<N>>>, A>
133 where N: Int
134{
135 s_a_minus_s_b_eq_a_minus_b() + a_minus_0_eq_a()
137}
138
139pub fn s_sub_a_s_b_eq_a_minus_b<N, A: Term<Type = N>, B: Term<Type = N>>(
141 ) -> ValueEq<Succ<Sub<A, Succ<B>>>, Sub<A, B>>
142 where N: Int
143{
144 -s_a_minus_b_eq_s_sub_a_b() + s_a_minus_s_b_eq_a_minus_b()
146}
147
148pub fn s_sub_a_s_0_eq_a<N, A: Term<Type = N>>(
150 ) -> ValueEq<Succ<Sub<A, Succ<Zero<N>>>>, A>
151 where N: Int
152{
153 s_sub_a_s_b_eq_a_minus_b() + a_minus_0_eq_a()
155}
156
157pub fn sub_eq_to_left_eq<N, A: Term<Type = N>, B: Term<Type = N>, C: Term<Type = N>, D: Term<Type = N>>(
159 eq: ValueEq<Sub<A, C>, Sub<B, D>>,
160 c_eq_d: ValueEq<C, D>
161 ) -> ValueEq<A, B>
162 where N: Int
163{
164 -a_minus_b_plus_b_eq_a() + Add::eq(eq, c_eq_d) + a_minus_b_plus_b_eq_a()
166}
167
168pub fn a_minus_sub_a_b_eq_b<N, A: Term<Type = N>, B: Term<Type = N>>(
170) -> ValueEq<Sub<A, Sub<A, B>>, B>
171where N: Int
172{
173 sub_sub_associative() + Add::eq(a_minus_a_eq_0(), refl()) + add_0_a_eq_a()
175}
176
177pub fn sub_eq_to_right_eq<N, A: Term<Type = N>, B: Term<Type = N>, C: Term<Type = N>, D: Term<Type = N>>(
179 eq: ValueEq<Sub<A, C>, Sub<B, D>>,
180 a_eq_b: ValueEq<A, B>
181 ) -> ValueEq<C, D>
182 where N: Int
183{
184 -a_minus_sub_a_b_eq_b() + Sub::eq(a_eq_b, eq) + a_minus_sub_a_b_eq_b()
186}