simplify_arithmetic.pl 5.05 KB
Newer Older
Thierry Martinez's avatar
Thierry Martinez committed
1 2 3 4 5 6
:- module(
  arithmetic_simplify,
  [
    simplify/2
  ]).

Thierry Martinez's avatar
Thierry Martinez committed
7 8 9 10 11 12 13
simplify(Value, Value) :-
  number(Value),
  !.

simplify(Parameter, Parameter) :-
  atom(Parameter),
  !.
Thierry Martinez's avatar
Thierry Martinez committed
14

Thierry Martinez's avatar
Thierry Martinez committed
15 16
simplify(p(ParameterIndex), p(ParameterIndex)) :-
  !.
Thierry Martinez's avatar
Thierry Martinez committed
17

Thierry Martinez's avatar
Thierry Martinez committed
18 19
simplify([Variable], [Variable]) :-
  !.
Thierry Martinez's avatar
Thierry Martinez committed
20 21

simplify(- A, Result) :-
Thierry Martinez's avatar
Thierry Martinez committed
22
  !,
Thierry Martinez's avatar
Thierry Martinez committed
23 24 25 26
  simplify(A, Asimplified),
  simplify_opposite(Asimplified, Result).

simplify(A + B, Result) :-
Thierry Martinez's avatar
Thierry Martinez committed
27
  !,
Thierry Martinez's avatar
Thierry Martinez committed
28 29 30 31 32
  simplify(A, Asimplified),
  simplify(B, Bsimplified),
  simplify_addition(Asimplified, Bsimplified, Result).

simplify(A - B, Result) :-
Thierry Martinez's avatar
Thierry Martinez committed
33
  !,
Thierry Martinez's avatar
Thierry Martinez committed
34 35 36 37 38
  simplify(A, Asimplified),
  simplify(B, Bsimplified),
  simplify_difference(Asimplified, Bsimplified, Result).

simplify(A * B, Result) :-
Thierry Martinez's avatar
Thierry Martinez committed
39
  !,
Thierry Martinez's avatar
Thierry Martinez committed
40 41 42 43 44
  simplify(A, Asimplified),
  simplify(B, Bsimplified),
  simplify_multiplication(Asimplified, Bsimplified, Result).

simplify(A / B, Result) :-
Thierry Martinez's avatar
Thierry Martinez committed
45
  !,
Thierry Martinez's avatar
Thierry Martinez committed
46 47 48 49 50
  simplify(A, Asimplified),
  simplify(B, Bsimplified),
  simplify_division(Asimplified, Bsimplified, Result).

simplify(A ^ B, Result) :-
Thierry Martinez's avatar
Thierry Martinez committed
51
  !,
Thierry Martinez's avatar
Thierry Martinez committed
52 53 54 55 56
  simplify(A, Asimplified),
  simplify(B, Bsimplified),
  simplify_power(Asimplified, Bsimplified, Result).

simplify(sqrt(A), Result) :-
Thierry Martinez's avatar
Thierry Martinez committed
57 58
  !,
  simplify(A ^ 0.5, Result).
Thierry Martinez's avatar
Thierry Martinez committed
59 60

simplify(exp(A), Result) :-
Thierry Martinez's avatar
Thierry Martinez committed
61
  !,
Thierry Martinez's avatar
Thierry Martinez committed
62 63 64 65
  simplify(A, Asimplified),
  simplify_exp(Asimplified, Result).

simplify(log(A), Result) :-
Thierry Martinez's avatar
Thierry Martinez committed
66
  !,
Thierry Martinez's avatar
Thierry Martinez committed
67 68 69 70
  simplify(A, Asimplified),
  simplify_log(Asimplified, Result).

simplify(cos(A), Result) :-
Thierry Martinez's avatar
Thierry Martinez committed
71
  !,
Thierry Martinez's avatar
Thierry Martinez committed
72 73 74 75
  simplify(A, Asimplified),
  simplify_cos(Asimplified, Result).

simplify(sin(A), Result) :-
Thierry Martinez's avatar
Thierry Martinez committed
76
  !,
Thierry Martinez's avatar
Thierry Martinez committed
77 78 79
  simplify(A, Asimplified),
  simplify_sin(Asimplified, Result).

Thierry Martinez's avatar
Thierry Martinez committed
80 81 82 83
simplify('MA'(E), 'MA'(Simplified)) :-
  !,
  simplify(E, Simplified).

Thierry Martinez's avatar
Thierry Martinez committed
84 85
simplify(E, _Result) :-
  type_error(arithmetic_expression, E).
Thierry Martinez's avatar
Thierry Martinez committed
86

Thierry Martinez's avatar
Thierry Martinez committed
87 88
simplify_opposite(Value, ValueOpp) :-
  number(Value),
Thierry Martinez's avatar
Thierry Martinez committed
89 90 91 92 93 94
  !,
  ValueOpp is -Value.

simplify_opposite(A, - A).


Thierry Martinez's avatar
Thierry Martinez committed
95
simplify_addition(0, A, A) :-
Thierry Martinez's avatar
Thierry Martinez committed
96 97
  !.

Thierry Martinez's avatar
Thierry Martinez committed
98
simplify_addition(A, 0, A) :-
Thierry Martinez's avatar
Thierry Martinez committed
99 100
  !.

Thierry Martinez's avatar
Thierry Martinez committed
101 102 103
simplify_addition(Value1, Value2, Value) :-
  number(Value1),
  number(Value2),
Thierry Martinez's avatar
Thierry Martinez committed
104 105 106
  !,
  Value is Value1 + Value2.

Thierry Martinez's avatar
Thierry Martinez committed
107 108
simplify_addition(A, Value, Result) :-
  number(Value),
Thierry Martinez's avatar
Thierry Martinez committed
109 110 111
  Value < 0,
  !,
  ValueOpp is -Value,
Thierry Martinez's avatar
Thierry Martinez committed
112
  Result = A - ValueOpp.
Thierry Martinez's avatar
Thierry Martinez committed
113

Thierry Martinez's avatar
Thierry Martinez committed
114 115
simplify_addition(A, Value * B, Result) :-
  number(Value),
Thierry Martinez's avatar
Thierry Martinez committed
116 117 118
  Value < 0,
  !,
  ValueOpp is -Value,
Thierry Martinez's avatar
Thierry Martinez committed
119
  Result = A - ValueOpp * B.
Thierry Martinez's avatar
Thierry Martinez committed
120

121 122 123 124 125 126 127 128 129 130 131
simplify_addition(-A, B, C) :-
  !,
  simplify_difference(B, A, C).

simplify_addition(A, -B, C) :-
  !,
  simplify_difference(A, B, C).

simplify_addition(A, A, 2 * A) :-
  !.

Thierry Martinez's avatar
Thierry Martinez committed
132 133 134
simplify_addition(A, B, A + B).


Thierry Martinez's avatar
Thierry Martinez committed
135
simplify_difference(0, A, AOpp) :-
Thierry Martinez's avatar
Thierry Martinez committed
136 137 138
  !,
  simplify_opposite(A, AOpp).

Thierry Martinez's avatar
Thierry Martinez committed
139
simplify_difference(A, 0, A) :-
Thierry Martinez's avatar
Thierry Martinez committed
140 141
  !.

Thierry Martinez's avatar
Thierry Martinez committed
142 143 144
simplify_difference(Value1, Value2, Value) :-
  number(Value1),
  number(Value2),
Thierry Martinez's avatar
Thierry Martinez committed
145 146 147
  !,
  Value is Value1 + Value2.

Thierry Martinez's avatar
Thierry Martinez committed
148 149
simplify_difference(A, Value, Result) :-
  number(Value),
Thierry Martinez's avatar
Thierry Martinez committed
150 151 152
  Value < 0,
  !,
  ValueOpp is -Value,
Thierry Martinez's avatar
Thierry Martinez committed
153
  Result = A + ValueOpp.
Thierry Martinez's avatar
Thierry Martinez committed
154

Thierry Martinez's avatar
Thierry Martinez committed
155 156
simplify_difference(A, Value * B, Result) :-
  number(Value),
Thierry Martinez's avatar
Thierry Martinez committed
157 158 159
  Value < 0,
  !,
  ValueOpp is -Value,
Thierry Martinez's avatar
Thierry Martinez committed
160
  Result = A + ValueOpp * B.
Thierry Martinez's avatar
Thierry Martinez committed
161

162 163 164 165 166 167 168 169 170 171 172
simplify_difference(A, A, 0) :-
  !.

simplify_difference(A, -B, C) :-
  !,
  simplify_addition(A, B, C).

simplify_difference(-A, B, -C) :-
  !,
  simplify_addition(A, B, C).

Thierry Martinez's avatar
Thierry Martinez committed
173 174 175
simplify_difference(A, B, A - B).


Thierry Martinez's avatar
Thierry Martinez committed
176
simplify_multiplication(0, _B, 0) :-
Thierry Martinez's avatar
Thierry Martinez committed
177 178
  !.

Thierry Martinez's avatar
Thierry Martinez committed
179
simplify_multiplication(_A, 0, 0) :-
Thierry Martinez's avatar
Thierry Martinez committed
180 181
  !.

Thierry Martinez's avatar
Thierry Martinez committed
182
simplify_multiplication(1, B, B) :-
Thierry Martinez's avatar
Thierry Martinez committed
183 184
  !.

Thierry Martinez's avatar
Thierry Martinez committed
185
simplify_multiplication(1 / A, B, Result) :-
Thierry Martinez's avatar
Thierry Martinez committed
186 187 188
  !,
  simplify_division(B, A, Result).

Thierry Martinez's avatar
Thierry Martinez committed
189
simplify_multiplication(A, 1 / B, Result) :-
Thierry Martinez's avatar
Thierry Martinez committed
190 191 192
  !,
  simplify_division(A, B, Result).

Thierry Martinez's avatar
Thierry Martinez committed
193
simplify_multiplication(A, 1, A) :-
Thierry Martinez's avatar
Thierry Martinez committed
194 195
  !.

Thierry Martinez's avatar
Thierry Martinez committed
196
simplify_multiplication(-1, B, BOpp) :-
Thierry Martinez's avatar
Thierry Martinez committed
197 198 199
  !,
  simplify_opposite(B, BOpp).

Thierry Martinez's avatar
Thierry Martinez committed
200
simplify_multiplication(A, -1, AOpp) :-
Thierry Martinez's avatar
Thierry Martinez committed
201 202 203
  !,
  simplify_opposite(A, AOpp).

Thierry Martinez's avatar
Thierry Martinez committed
204 205
simplify_multiplication(A / B, B ^ Value, Result) :-
  number(Value),
Thierry Martinez's avatar
Thierry Martinez committed
206 207
  !,
  ValuePred is Value - 1,
Thierry Martinez's avatar
Thierry Martinez committed
208
  simplify_power(B, ValuePred, BPowerValuePred),
Thierry Martinez's avatar
Thierry Martinez committed
209 210 211 212
  simplify_multiplication(A, BPowerValuePred, Result).

simplify_multiplication(A / B, sqrt(B), Result) :-
  !,
Thierry Martinez's avatar
Thierry Martinez committed
213
  simplify_power(B, 0.5, SqrtB),
Thierry Martinez's avatar
Thierry Martinez committed
214 215
  simplify_division(A, SqrtB, Result).

Thierry Martinez's avatar
Thierry Martinez committed
216 217 218
simplify_multiplication(Value1, Value2, Result) :-
  number(Value1),
  number(Value2),
Thierry Martinez's avatar
Thierry Martinez committed
219
  !,
Thierry Martinez's avatar
Thierry Martinez committed
220
  Result is Value1 * Value2.
Thierry Martinez's avatar
Thierry Martinez committed
221 222 223 224

simplify_multiplication(A, B, A * B).


Thierry Martinez's avatar
Thierry Martinez committed
225
simplify_division(0, _B, 0) :-
Thierry Martinez's avatar
Thierry Martinez committed
226 227
  !.

Thierry Martinez's avatar
Thierry Martinez committed
228
simplify_division(A, 1, A) :-
Thierry Martinez's avatar
Thierry Martinez committed
229 230
  !.

Thierry Martinez's avatar
Thierry Martinez committed
231 232 233
simplify_division(Value1, Value2, Result) :-
  number(Value1),
  number(Value2),
Thierry Martinez's avatar
Thierry Martinez committed
234
  !,
Thierry Martinez's avatar
Thierry Martinez committed
235
  Result is Value1 / Value2.
Thierry Martinez's avatar
Thierry Martinez committed
236 237 238 239

simplify_division(A, B, A / B).


Thierry Martinez's avatar
Thierry Martinez committed
240
simplify_power(A, 1, A) :-
Thierry Martinez's avatar
Thierry Martinez committed
241 242
  !.

Thierry Martinez's avatar
Thierry Martinez committed
243
simplify_power(A, 0.5, sqrt(A)) :-
Thierry Martinez's avatar
Thierry Martinez committed
244 245
  !.

Thierry Martinez's avatar
Thierry Martinez committed
246
simplify_power(A, -1, AInv) :-
Thierry Martinez's avatar
Thierry Martinez committed
247 248 249
  !,
  simplify_division(1, A, AInv).

Thierry Martinez's avatar
Thierry Martinez committed
250
simplify_power(A, -0.5, InvSqrtA) :-
Thierry Martinez's avatar
Thierry Martinez committed
251 252 253
  !,
  simplify_division(1, sqrt(A), InvSqrtA).

Thierry Martinez's avatar
Thierry Martinez committed
254 255 256
simplify_power(Value1, Value2, Result) :-
  number(Value1),
  number(Value2),
Thierry Martinez's avatar
Thierry Martinez committed
257
  !,
Thierry Martinez's avatar
Thierry Martinez committed
258
  Result is Value1 ^ Value2.
Thierry Martinez's avatar
Thierry Martinez committed
259 260 261 262 263 264

simplify_power(A, B, Result) :-
  !,
  Result = A ^ B.


Thierry Martinez's avatar
Thierry Martinez committed
265 266
simplify_exp(Value, ExpValue) :-
  number(Value),
Thierry Martinez's avatar
Thierry Martinez committed
267 268 269 270 271 272 273 274 275 276 277 278 279
  !,
  ExpValue is exp(Value).

simplify_exp(log(A), A) :-
  !.

simplify_exp(B * log(A), Result) :-
  !,
  simplify_power(A, B, Result).

simplify_exp(A, exp(A)).


Thierry Martinez's avatar
Thierry Martinez committed
280 281
simplify_log(Value, LogValue) :-
  number(Value),
Thierry Martinez's avatar
Thierry Martinez committed
282 283 284 285 286 287 288 289 290 291 292 293 294
  !,
  LogValue is log(Value).

simplify_log(exp(A), A) :-
  !.

simplify_log(A, log(A)).


simplify_cos(A, cos(A)).


simplify_sin(A, sin(A)).