SimplificationRules.java

1
package net.bmahe.genetics4j.gp.math;
2
3
import java.util.Arrays;
4
import java.util.List;
5
6
import org.apache.commons.lang3.Validate;
7
import org.apache.logging.log4j.LogManager;
8
import org.apache.logging.log4j.Logger;
9
10
import net.bmahe.genetics4j.core.chromosomes.TreeNode;
11
import net.bmahe.genetics4j.gp.InputSpec;
12
import net.bmahe.genetics4j.gp.Operation;
13
import net.bmahe.genetics4j.gp.OperationFactories;
14
import net.bmahe.genetics4j.gp.OperationFactory;
15
import net.bmahe.genetics4j.gp.spec.mutation.ImmutableRule;
16
import net.bmahe.genetics4j.gp.spec.mutation.Rule;
17
import net.bmahe.genetics4j.gp.utils.TreeNodeUtils;
18
19
public class SimplificationRules {
20
	final static public Logger logger = LogManager.getLogger(SimplificationRules.class);
21
22
	public final static double DEFAULT_EPSILON = 0.0001;
23
24
	protected static boolean isOperation(final TreeNode<Operation<?>> node, final String name) {
25
		Validate.notNull(node);
26
		Validate.notBlank(name);
27 5 1. isOperation : removed call to java/lang/String::equals → NO_COVERAGE
2. isOperation : replaced boolean return with true for net/bmahe/genetics4j/gp/math/SimplificationRules::isOperation → NO_COVERAGE
3. isOperation : removed call to net/bmahe/genetics4j/core/chromosomes/TreeNode::getData → NO_COVERAGE
4. isOperation : replaced boolean return with false for net/bmahe/genetics4j/gp/math/SimplificationRules::isOperation → NO_COVERAGE
5. isOperation : removed call to net/bmahe/genetics4j/gp/Operation::getName → NO_COVERAGE
		return name.equals(node.getData().getName());
28
	}
29
30
	protected static boolean hasChildOperation(final TreeNode<Operation<?>> node, final int childIndex,
31
			final String name) {
32
		Validate.notNull(node);
33
		Validate.isTrue(childIndex >= 0);
34
		Validate.notBlank(name);
35
36 6 1. hasChildOperation : removed call to java/util/List::size → NO_COVERAGE
2. hasChildOperation : changed conditional boundary → NO_COVERAGE
3. hasChildOperation : removed conditional - replaced comparison check with false → NO_COVERAGE
4. hasChildOperation : removed conditional - replaced comparison check with true → NO_COVERAGE
5. hasChildOperation : negated conditional → NO_COVERAGE
6. hasChildOperation : removed call to net/bmahe/genetics4j/core/chromosomes/TreeNode::getChildren → NO_COVERAGE
		if (node.getChildren().size() <= childIndex) {
37 2 1. hasChildOperation : Substituted 0 with 1 → NO_COVERAGE
2. hasChildOperation : replaced boolean return with true for net/bmahe/genetics4j/gp/math/SimplificationRules::hasChildOperation → NO_COVERAGE
			return false;
38
		}
39
40 2 1. hasChildOperation : replaced call to net/bmahe/genetics4j/core/chromosomes/TreeNode::getChild with receiver → NO_COVERAGE
2. hasChildOperation : removed call to net/bmahe/genetics4j/core/chromosomes/TreeNode::getChild → NO_COVERAGE
		final TreeNode<Operation<?>> child = node.getChild(childIndex);
41 5 1. hasChildOperation : removed call to java/lang/String::equals → NO_COVERAGE
2. hasChildOperation : replaced boolean return with false for net/bmahe/genetics4j/gp/math/SimplificationRules::hasChildOperation → NO_COVERAGE
3. hasChildOperation : removed call to net/bmahe/genetics4j/core/chromosomes/TreeNode::getData → NO_COVERAGE
4. hasChildOperation : removed call to net/bmahe/genetics4j/gp/Operation::getName → NO_COVERAGE
5. hasChildOperation : replaced boolean return with true for net/bmahe/genetics4j/gp/math/SimplificationRules::hasChildOperation → NO_COVERAGE
		return name.equals(child.getData().getName());
42
	}
43
44
	protected static <T> T getChildAs(final TreeNode<Operation<?>> node, final int childIndex, final Class<T> clazz) {
45 2 1. getChildAs : removed call to net/bmahe/genetics4j/core/chromosomes/TreeNode::getChild → NO_COVERAGE
2. getChildAs : replaced call to net/bmahe/genetics4j/core/chromosomes/TreeNode::getChild with receiver → NO_COVERAGE
		final TreeNode<Operation<?>> child = node.getChild(childIndex);
46 1 1. getChildAs : removed call to net/bmahe/genetics4j/core/chromosomes/TreeNode::getData → NO_COVERAGE
		final Operation<?> operation = child.getData();
47 1 1. getChildAs : replaced return value with null for net/bmahe/genetics4j/gp/math/SimplificationRules::getChildAs → NO_COVERAGE
		return (T) operation;
48
	}
49
50
	protected static boolean isEqual(final double v1, final double v2, final double epsilon) {
51
		Validate.isTrue(epsilon >= 0);
52
53 10 1. isEqual : replaced call to java/lang/Math::abs with argument → NO_COVERAGE
2. isEqual : Replaced double subtraction with addition → NO_COVERAGE
3. isEqual : changed conditional boundary → NO_COVERAGE
4. isEqual : removed call to java/lang/Math::abs → NO_COVERAGE
5. isEqual : removed conditional - replaced comparison check with false → NO_COVERAGE
6. isEqual : negated conditional → NO_COVERAGE
7. isEqual : removed conditional - replaced comparison check with true → NO_COVERAGE
8. isEqual : Substituted 0 with 1 → NO_COVERAGE
9. isEqual : replaced boolean return with true for net/bmahe/genetics4j/gp/math/SimplificationRules::isEqual → NO_COVERAGE
10. isEqual : Substituted 1 with 0 → NO_COVERAGE
		return Math.abs(v2 - v1) < epsilon;
54
	}
55
56
	protected static boolean isEqual(final double v1, final double v2) {
57 4 1. isEqual : Substituted 1.0E-4 with 1.0 → NO_COVERAGE
2. isEqual : removed call to net/bmahe/genetics4j/gp/math/SimplificationRules::isEqual → NO_COVERAGE
3. isEqual : replaced boolean return with true for net/bmahe/genetics4j/gp/math/SimplificationRules::isEqual → NO_COVERAGE
4. isEqual : replaced boolean return with false for net/bmahe/genetics4j/gp/math/SimplificationRules::isEqual → NO_COVERAGE
		return isEqual(v1, v2, DEFAULT_EPSILON);
58
	}
59
60
	@SuppressWarnings("unchecked")
61
	final public static Rule ADD_TWO_COEFFCIENTS = ImmutableRule
62
			.of((t) -> isOperation(t, Functions.NAME_ADD) && hasChildOperation(t, 0, Terminals.TYPE_COEFFICIENT)
63
					&& hasChildOperation(t, 1, Terminals.TYPE_COEFFICIENT), (program, t) -> {
64
65
						final InputSpec inputSpec = program.inputSpec();
66
67
						final CoefficientOperation<Double> firstCoefficient = getChildAs(t,
68
								0,
69
								CoefficientOperation.class);
70
						final Double firstValue = firstCoefficient.value();
71
72
						final CoefficientOperation<Double> secondCoefficient = getChildAs(t,
73
								1,
74
								CoefficientOperation.class);
75
						final Double secondValue = secondCoefficient.value();
76
77
						final OperationFactory coefficientFactory = OperationFactories
78
								.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, firstValue + secondValue);
79
80
						final Operation<?> newOperation = coefficientFactory.build(inputSpec);
81
82
						return new TreeNode<>(newOperation);
83
					});
84
85
	@SuppressWarnings("unchecked")
86
	final public static Rule MUL_TWO_COEFFICIENTS = ImmutableRule
87
			.of((t) -> isOperation(t, Functions.NAME_MUL) && hasChildOperation(t, 0, Terminals.TYPE_COEFFICIENT)
88
					&& hasChildOperation(t, 1, Terminals.TYPE_COEFFICIENT), (program, t) -> {
89
90
						final InputSpec inputSpec = program.inputSpec();
91
92
						final CoefficientOperation<Double> firstCoefficient = getChildAs(t,
93
								0,
94
								CoefficientOperation.class);
95
						final Double firstValue = firstCoefficient.value();
96
97
						final CoefficientOperation<Double> secondCoefficient = getChildAs(t,
98
								1,
99
								CoefficientOperation.class);
100
						final Double secondValue = secondCoefficient.value();
101
102
						final OperationFactory coefficientFactory = OperationFactories
103
								.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, firstValue * secondValue);
104
105
						final Operation<?> newOperation = coefficientFactory.build(inputSpec);
106
107
						return new TreeNode<>(newOperation);
108
					});
109
110
	@SuppressWarnings("unchecked")
111
	final public static Rule SUB_TWO_COEFFICIENTS = ImmutableRule
112
			.of((t) -> isOperation(t, Functions.NAME_SUB) && hasChildOperation(t, 0, Terminals.TYPE_COEFFICIENT)
113
					&& hasChildOperation(t, 1, Terminals.TYPE_COEFFICIENT), (program, t) -> {
114
115
						final InputSpec inputSpec = program.inputSpec();
116
117
						final CoefficientOperation<Double> firstCoefficient = getChildAs(t,
118
								0,
119
								CoefficientOperation.class);
120
						final Double firstValue = firstCoefficient.value();
121
122
						final CoefficientOperation<Double> secondCoefficient = getChildAs(t,
123
								1,
124
								CoefficientOperation.class);
125
						final Double secondValue = secondCoefficient.value();
126
127
						final OperationFactory coefficientFactory = OperationFactories
128
								.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, firstValue - secondValue);
129
130
						final Operation<?> newOperation = coefficientFactory.build(inputSpec);
131
132
						return new TreeNode<>(newOperation);
133
					});
134
135
	@SuppressWarnings("unchecked")
136
	final public static Rule SUB_INPUT_FROM_SAME_INPUT = ImmutableRule.of((t) -> {
137
		if (isOperation(t, Functions.NAME_SUB) == false) {
138
			return false;
139
		}
140
141
		if (hasChildOperation(t, 0, Terminals.TYPE_INPUT) == false) {
142
			return false;
143
		}
144
145
		if (hasChildOperation(t, 1, Terminals.TYPE_INPUT) == false) {
146
			return false;
147
		}
148
149
		final InputOperation<?> firstInput = (InputOperation<Double>) t.getChild(0).getData();
150
151
		final InputOperation<?> secondInput = (InputOperation<Double>) t.getChild(1).getData();
152
153
		return firstInput.index() == secondInput.index();
154
	}, (program, t) -> {
155
156
		final InputSpec inputSpec = program.inputSpec();
157
158
		final OperationFactory coefficientFactory = OperationFactories
159
				.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, 0.0d);
160
161
		final Operation<?> newOperation = coefficientFactory.build(inputSpec);
162
163
		return new TreeNode<>(newOperation);
164
	});
165
166
	@SuppressWarnings("unchecked")
167
	final public static Rule SUB_ZERO_FROM_INPUT = ImmutableRule.of((t) -> {
168
		if (isOperation(t, Functions.NAME_SUB) == false) {
169
			return false;
170
		}
171
172
		if (hasChildOperation(t, 0, Terminals.TYPE_INPUT) == false) {
173
			return false;
174
		}
175
176
		if (hasChildOperation(t, 1, Terminals.TYPE_INPUT) == false) {
177
			return false;
178
		}
179
180
		if (hasChildOperation(t, 0, Terminals.TYPE_COEFFICIENT) == false) {
181
			return false;
182
		}
183
184
		if (hasChildOperation(t, 1, Terminals.TYPE_COEFFICIENT) == false) {
185
			return false;
186
		}
187
188
		final CoefficientOperation<Double> firstCoefficient = (CoefficientOperation<Double>) t.getChild(0).getData();
189
190
		return isEqual(firstCoefficient.value(), 0.0d);
191
	}, (program, t) -> {
192
193
		final InputSpec inputSpec = program.inputSpec();
194
195
		final OperationFactory coefficientFactory = OperationFactories
196
				.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, 0.0d);
197
198
		final Operation<?> newOperation = coefficientFactory.build(inputSpec);
199
200
		return new TreeNode<>(newOperation);
201
	});
202
203
	@SuppressWarnings("unchecked")
204
	final public static Rule DIV_TWO_COEFFICIENT_FINITE = ImmutableRule.of((t) -> {
205
		if (isOperation(t, Functions.NAME_DIV) == false) {
206
			return false;
207
		}
208
209
		if (hasChildOperation(t, 0, Terminals.TYPE_COEFFICIENT) == false) {
210
			return false;
211
		}
212
213
		if (hasChildOperation(t, 1, Terminals.TYPE_COEFFICIENT) == false) {
214
			return false;
215
		}
216
217
		final CoefficientOperation<Double> firstCoefficient = (CoefficientOperation<Double>) t.getChild(0).getData();
218
219
		final CoefficientOperation<Double> secondCoefficient = (CoefficientOperation<Double>) t.getChild(1).getData();
220
221
		return Double.isFinite(firstCoefficient.value() / secondCoefficient.value());
222
	}, (program, t) -> {
223
224
		final InputSpec inputSpec = program.inputSpec();
225
226
		final CoefficientOperation<Double> firstCoefficient = getChildAs(t, 0, CoefficientOperation.class);
227
		final Double firstValue = firstCoefficient.value();
228
229
		final CoefficientOperation<Double> secondCoefficient = getChildAs(t, 1, CoefficientOperation.class);
230
		final Double secondValue = secondCoefficient.value();
231
232
		final OperationFactory coefficientFactory = OperationFactories
233
				.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, firstValue / secondValue);
234
235
		final Operation<?> newOperation = coefficientFactory.build(inputSpec);
236
237
		return new TreeNode<>(newOperation);
238
	});
239
240
	@SuppressWarnings("unchecked")
241
	final public static Rule ADD_INPUT_TO_SAME_INPUT = ImmutableRule.of((t) -> {
242
		boolean result = isOperation(t, Functions.NAME_ADD) && hasChildOperation(t, 0, Terminals.TYPE_INPUT)
243
				&& hasChildOperation(t, 1, Terminals.TYPE_INPUT);
244
245
		if (result == false) {
246
			return false;
247
		}
248
249
		final InputOperation<?> firstInput = getChildAs(t, 0, InputOperation.class);
250
		final InputOperation<?> secondInput = getChildAs(t, 1, InputOperation.class);
251
252
		return firstInput.index() == secondInput.index();
253
	}, (program, t) -> {
254
255
		final InputSpec inputSpec = program.inputSpec();
256
257
		final TreeNode<Operation<?>> multBaseTreeNode = new TreeNode<Operation<?>>(Functions.MUL.build(inputSpec));
258
259
		final OperationFactory coefficientFactory = OperationFactories
260
				.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, 2.0d);
261
		final TreeNode<Operation<?>> timesTwoTreeNode = new TreeNode<Operation<?>>(coefficientFactory.build(inputSpec));
262
		multBaseTreeNode.addChild(timesTwoTreeNode);
263
264
		final InputOperation<?> firstInput = (InputOperation<Double>) t.getChild(0).getData();
265
		final TreeNode<Operation<?>> firstInputTreeNode = new TreeNode<Operation<?>>(firstInput);
266
		multBaseTreeNode.addChild(firstInputTreeNode);
267
268
		return multBaseTreeNode;
269
	});
270
271
	@SuppressWarnings("unchecked")
272
	final public static Rule MULTIPLY_INPUT_WITH_SAME_INPUT = ImmutableRule.of((t) -> {
273
274
		if (isOperation(t, Functions.NAME_MUL) == false) {
275
			return false;
276
		}
277
278
		if (hasChildOperation(t, 0, Terminals.TYPE_INPUT) == false) {
279
			return false;
280
		}
281
		if (hasChildOperation(t, 1, Terminals.TYPE_INPUT) == false) {
282
			return false;
283
		}
284
285
		final InputOperation<?> firstInput = (InputOperation<Double>) t.getChild(0).getData();
286
287
		final InputOperation<?> secondInput = (InputOperation<Double>) t.getChild(1).getData();
288
289
		return firstInput.index() == secondInput.index();
290
	}, (program, t) -> {
291
292
		final InputSpec inputSpec = program.inputSpec();
293
294
		final TreeNode<Operation<?>> expBaseTreeNode = new TreeNode<Operation<?>>(Functions.EXP.build(inputSpec));
295
296
		final InputOperation<?> firstInput = (InputOperation<Double>) t.getChild(0).getData();
297
		final TreeNode<Operation<?>> firstInputTreeNode = new TreeNode<Operation<?>>(firstInput);
298
		expBaseTreeNode.addChild(firstInputTreeNode);
299
300
		final OperationFactory coefficientFactory = OperationFactories
301
				.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, 2.0d);
302
		final TreeNode<Operation<?>> twoTreeNode = new TreeNode<Operation<?>>(coefficientFactory.build(inputSpec));
303
		expBaseTreeNode.addChild(twoTreeNode);
304
305
		return expBaseTreeNode;
306
	});
307
308
	@SuppressWarnings("unchecked")
309
	final public static Rule MULTIPLY_INPUT_WITH_EXP_SAME_INPUT_COEFF = ImmutableRule.of((t) -> {
310
		// ex: MULT( EXP( INPUT[0], 3), INPUT[0])
311
		// ==> EXP( INPUT[0], 4)
312
313
		if (isOperation(t, Functions.NAME_MUL) == false) {
314
			return false;
315
		}
316
		if (hasChildOperation(t, 0, Functions.NAME_EXP) == false) {
317
			return false;
318
		}
319
		if (hasChildOperation(t, 1, Terminals.TYPE_INPUT) == false) {
320
			return false;
321
		}
322
323
		final TreeNode<Operation<?>> expTreeNode = t.getChild(0);
324
		if (hasChildOperation(expTreeNode, 0, Terminals.TYPE_INPUT) == false) {
325
			return false;
326
		}
327
		if (hasChildOperation(expTreeNode, 1, Terminals.TYPE_COEFFICIENT) == false) {
328
			return false;
329
		}
330
331
		final InputOperation<?> expInput = getChildAs(expTreeNode, 0, InputOperation.class);
332
		final InputOperation<?> secondInput = getChildAs(t, 1, InputOperation.class);
333
334
		return expInput.index() == secondInput.index();
335
	}, (program, t) -> {
336
337
		final InputSpec inputSpec = program.inputSpec();
338
		final TreeNode<Operation<?>> originalExpTreeNode = t.getChild(0);
339
		final CoefficientOperation<Double> originalCoefficientExp = getChildAs(originalExpTreeNode,
340
				1,
341
				CoefficientOperation.class);
342
343
		final TreeNode<Operation<?>> expBaseTreeNode = new TreeNode<Operation<?>>(Functions.EXP.build(inputSpec));
344
345
		final InputOperation<?> firstInput = (InputOperation<Double>) t.getChild(0).getData();
346
		final TreeNode<Operation<?>> firstInputTreeNode = new TreeNode<Operation<?>>(firstInput);
347
		expBaseTreeNode.addChild(firstInputTreeNode);
348
349
		final OperationFactory coefficientFactory = OperationFactories
350
				.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, originalCoefficientExp.value() + 1.0d);
351
		final TreeNode<Operation<?>> newCoeffTreeNode = new TreeNode<Operation<?>>(coefficientFactory.build(inputSpec));
352
		expBaseTreeNode.addChild(newCoeffTreeNode);
353
354
		return expBaseTreeNode;
355
	});
356
357
	@SuppressWarnings("unchecked")
358
	final public static Rule MUL_1_WITH_ANYTHING = ImmutableRule.of((t) -> {
359
		if (isOperation(t, Functions.NAME_MUL) == false) {
360
			return false;
361
		}
362
363
		if (hasChildOperation(t, 0, Terminals.TYPE_COEFFICIENT) == false) {
364
			return false;
365
		}
366
367
		final CoefficientOperation<Double> firstCoefficient = (CoefficientOperation<Double>) t.getChild(0).getData();
368
369
		return firstCoefficient.value() < 1 + 0.0001 && firstCoefficient.value() > 1 - .0001;
370
	}, (program, t) -> {
371
372
		return t.getChild(1);
373
	});
374
375
	@SuppressWarnings("unchecked")
376
	final public static Rule MUL_ANYTHING_WITH_1 = ImmutableRule.of((t) -> {
377
		if (isOperation(t, Functions.NAME_MUL) == false) {
378
			return false;
379
		}
380
381
		if (hasChildOperation(t, 1, Terminals.TYPE_COEFFICIENT) == false) {
382
			return false;
383
		}
384
385
		final CoefficientOperation<Double> secondCoefficient = (CoefficientOperation<Double>) t.getChild(1).getData();
386
387
		return isEqual(secondCoefficient.value(), 1);
388
	}, (program, t) -> {
389
390
		return t.getChild(0);
391
	});
392
393
	@SuppressWarnings("unchecked")
394
	final public static Rule ADD_0_WITH_ANYTHING = ImmutableRule.of((t) -> {
395
		if (isOperation(t, Functions.NAME_ADD) == false) {
396
			return false;
397
		}
398
399
		if (hasChildOperation(t, 0, Terminals.TYPE_COEFFICIENT) == false) {
400
			return false;
401
		}
402
403
		final CoefficientOperation<Double> firstCoefficient = (CoefficientOperation<Double>) t.getChild(0).getData();
404
405
		return isEqual(firstCoefficient.value(), 0.0d);
406
	}, (program, t) -> {
407
408
		return t.getChild(1);
409
	});
410
411
	@SuppressWarnings("unchecked")
412
	final public static Rule ADD_ANYTHING_WITH_0 = ImmutableRule.of((t) -> {
413
		if (isOperation(t, Functions.NAME_ADD) == false) {
414
			return false;
415
		}
416
417
		if (hasChildOperation(t, 1, Terminals.TYPE_COEFFICIENT) == false) {
418
			return false;
419
		}
420
421
		final CoefficientOperation<Double> secondCoefficient = (CoefficientOperation<Double>) t.getChild(1).getData();
422
423
		return isEqual(secondCoefficient.value(), 0.0d);
424
	}, (program, t) -> {
425
426
		return t.getChild(0);
427
	});
428
429
	@SuppressWarnings("unchecked")
430
	final public static Rule MUL_0_WITH_ANYTHING = ImmutableRule.of((t) -> {
431
		if (isOperation(t, Functions.NAME_MUL) == false) {
432
			return false;
433
		}
434
435
		if (hasChildOperation(t, 0, Terminals.TYPE_COEFFICIENT) == false) {
436
			return false;
437
		}
438
439
		final CoefficientOperation<Double> firstCoefficient = (CoefficientOperation<Double>) t.getChild(0).getData();
440
441
		return isEqual(firstCoefficient.value(), 0.0d);
442
	}, (program, t) -> {
443
444
		final InputSpec inputSpec = program.inputSpec();
445
446
		final OperationFactory zeroFactory = OperationFactories
447
				.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, 0.0d);
448
449
		return new TreeNode<>(zeroFactory.build(inputSpec));
450
	});
451
452
	@SuppressWarnings("unchecked")
453
	final public static Rule MUL_ANYTHING_WITH_0 = ImmutableRule.of((t) -> {
454
		if (isOperation(t, Functions.NAME_MUL) == false) {
455
			return false;
456
		}
457
458
		if (hasChildOperation(t, 1, Terminals.TYPE_COEFFICIENT) == false) {
459
			return false;
460
		}
461
462
		final CoefficientOperation<Double> secondCoefficient = (CoefficientOperation<Double>) t.getChild(1).getData();
463
464
		return secondCoefficient.value() < 1 + 0.0001 && secondCoefficient.value() > 1 - .0001;
465
	}, (program, t) -> {
466
		final InputSpec inputSpec = program.inputSpec();
467
468
		final OperationFactory zeroFactory = OperationFactories
469
				.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, 0.0d);
470
471
		return new TreeNode<>(zeroFactory.build(inputSpec));
472
	});
473
474
	@SuppressWarnings("unchecked")
475
	final public static Rule POW_0 = ImmutableRule.of((t) -> {
476
		if (isOperation(t, Functions.NAME_POW) == false) {
477
			return false;
478
		}
479
480
		if (hasChildOperation(t, 1, Terminals.TYPE_COEFFICIENT) == false) {
481
			return false;
482
		}
483
484
		final CoefficientOperation<Double> secondCoefficient = (CoefficientOperation<Double>) t.getChild(1).getData();
485
486
		return isEqual(secondCoefficient.value(), 0);
487
	}, (program, t) -> {
488
		final InputSpec inputSpec = program.inputSpec();
489
490
		final OperationFactory oneFactory = OperationFactories
491
				.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, 1.0d);
492
493
		return new TreeNode<>(oneFactory.build(inputSpec));
494
	});
495
496
	@SuppressWarnings("unchecked")
497
	final public static Rule POW_1 = ImmutableRule.of((t) -> {
498
		if (isOperation(t, Functions.NAME_POW) == false) {
499
			return false;
500
		}
501
502
		if (hasChildOperation(t, 1, Terminals.TYPE_COEFFICIENT) == false) {
503
			return false;
504
		}
505
506
		final CoefficientOperation<Double> secondCoefficient = (CoefficientOperation<Double>) t.getChild(1).getData();
507
508
		return isEqual(secondCoefficient.value(), 1);
509
	}, (program, t) -> {
510
511
		return t.getChild(0);
512
	});
513
514
	@SuppressWarnings("unchecked")
515
	final public static Rule COS_OF_COEFFICIENT = ImmutableRule.of((t) -> {
516
		if (isOperation(t, Functions.NAME_COS) == false) {
517
			return false;
518
		}
519
520
		return hasChildOperation(t, 0, Terminals.TYPE_COEFFICIENT);
521
	}, (program, t) -> {
522
523
		final InputSpec inputSpec = program.inputSpec();
524
525
		final CoefficientOperation<Double> cosCoefficient = (CoefficientOperation<Double>) t.getChild(0).getData();
526
527
		final double cosValue = Math.cos(cosCoefficient.value());
528
529
		final OperationFactory cosValueOperationFactory = OperationFactories
530
				.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, cosValue);
531
532
		return new TreeNode<>(cosValueOperationFactory.build(inputSpec));
533
	});
534
535
	@SuppressWarnings("unchecked")
536
	final public static Rule SIN_OF_COEFFICIENT = ImmutableRule.of((t) -> {
537
		if (isOperation(t, Functions.NAME_SIN) == false) {
538
			return false;
539
		}
540
541
		return hasChildOperation(t, 0, Terminals.TYPE_COEFFICIENT);
542
	}, (program, t) -> {
543
544
		final InputSpec inputSpec = program.inputSpec();
545
546
		final CoefficientOperation<Double> sinCoefficient = (CoefficientOperation<Double>) t.getChild(0).getData();
547
548
		final double sinValue = Math.sin(sinCoefficient.value());
549
550
		final OperationFactory sinValueOperationFactory = OperationFactories
551
				.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, sinValue);
552
553
		return new TreeNode<>(sinValueOperationFactory.build(inputSpec));
554
	});
555
556
	final public static Rule SUB_SAME_BRANCHES = ImmutableRule.of((t) -> {
557
		if (isOperation(t, Functions.NAME_SUB) == false) {
558
			return false;
559
		}
560
561
		return TreeNodeUtils.areSame(t.getChild(0), t.getChild(1));
562
	}, (program, t) -> {
563
564
		final InputSpec inputSpec = program.inputSpec();
565
566
		final OperationFactory zeroFactory = OperationFactories
567
				.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, 0.0d);
568
569
		return new TreeNode<>(zeroFactory.build(inputSpec));
570
	});
571
572
	final public static Rule ADD_SAME_BRANCHES = ImmutableRule.of((t) -> {
573
		if (isOperation(t, Functions.NAME_ADD) == false) {
574
			return false;
575
		}
576
577
		return TreeNodeUtils.areSame(t.getChild(0), t.getChild(1));
578
	}, (program, t) -> {
579
580
		final InputSpec inputSpec = program.inputSpec();
581
582
		final TreeNode<Operation<?>> baseAdd = new TreeNode<>(Functions.ADD.build(inputSpec));
583
584
		final OperationFactory twoFactory = OperationFactories
585
				.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, 2.0d);
586
		baseAdd.addChild(new TreeNode<>(twoFactory.build(inputSpec)));
587
588
		baseAdd.addChild(t.getChild(0)); // TODO copy it instead?
589
590
		return baseAdd;
591
	});
592
593
	final public static Rule DIV_SAME_BRANCHES = ImmutableRule.of((t) -> {
594
		if (isOperation(t, Functions.NAME_DIV) == false) {
595
			return false;
596
		}
597
598
		return TreeNodeUtils.areSame(t.getChild(0), t.getChild(1));
599
	}, (program, t) -> {
600
601
		final InputSpec inputSpec = program.inputSpec();
602
603
		final OperationFactory oneFactory = OperationFactories
604
				.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, 1.0d);
605
606
		return new TreeNode<>(oneFactory.build(inputSpec));
607
	});
608
609
	@SuppressWarnings("unchecked")
610
	final public static Rule EXP_OF_COEFFICIENT = ImmutableRule.of((t) -> {
611
		if (isOperation(t, Functions.NAME_EXP) == false) {
612
			return false;
613
		}
614
615
		return hasChildOperation(t, 0, Terminals.TYPE_COEFFICIENT);
616
	}, (program, t) -> {
617
618
		final InputSpec inputSpec = program.inputSpec();
619
620
		final CoefficientOperation<Double> expCoefficient = (CoefficientOperation<Double>) t.getChild(0).getData();
621
622
		final double expValue = Math.exp(expCoefficient.value());
623
624
		final OperationFactory expValueOperationFactory = OperationFactories
625
				.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, expValue);
626
627
		return new TreeNode<>(expValueOperationFactory.build(inputSpec));
628
	});
629
630
	@SuppressWarnings("unchecked")
631
	final public static Rule POW_TWO_COEFFICIENTS = ImmutableRule
632
			.of((t) -> isOperation(t, Functions.NAME_POW) && hasChildOperation(t, 0, Terminals.TYPE_COEFFICIENT)
633
					&& hasChildOperation(t, 1, Terminals.TYPE_COEFFICIENT), (program, t) -> {
634
635
						final InputSpec inputSpec = program.inputSpec();
636
637
						final CoefficientOperation<Double> firstCoefficient = getChildAs(t,
638
								0,
639
								CoefficientOperation.class);
640
						final Double firstValue = firstCoefficient.value();
641
642
						final CoefficientOperation<Double> secondCoefficient = getChildAs(t,
643
								1,
644
								CoefficientOperation.class);
645
						final Double secondValue = secondCoefficient.value();
646
647
						final OperationFactory coefficientFactory = OperationFactories.ofCoefficient(
648
								Terminals.TYPE_COEFFICIENT,
649
								Double.class,
650
								Math.pow(firstValue, secondValue));
651
652
						final Operation<?> newOperation = coefficientFactory.build(inputSpec);
653
654
						return new TreeNode<>(newOperation);
655
					});
656
657
	/**
658
	 * multiplication of the same branch -> square of the first branch
659
	 */
660
	final public static Rule MUL_SAME_BRANCHES = ImmutableRule.of((t) -> {
661
		if (isOperation(t, Functions.NAME_MUL) == false) {
662
			return false;
663
		}
664
665
		return TreeNodeUtils.areSame(t.getChild(0), t.getChild(1));
666
	}, (program, t) -> {
667
668
		final InputSpec inputSpec = program.inputSpec();
669
670
		final TreeNode<Operation<?>> powNode = new TreeNode<>(Functions.POW.build(inputSpec));
671
672
		powNode.addChild(t.getChild(0));
673
		powNode.addChild(new TreeNode<>(
674
				OperationFactories.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, 2.0d).build(inputSpec)));
675
676
		return powNode;
677
	});
678
679
	final public static Rule COS_PI = ImmutableRule.of((t) -> {
680
		if (isOperation(t, Functions.NAME_COS) == false) {
681
			return false;
682
		}
683
684
		return hasChildOperation(t, 0, Terminals.NAME_PI);
685
	}, (program, t) -> {
686
687
		final InputSpec inputSpec = program.inputSpec();
688
689
		final OperationFactory minusOneFactory = OperationFactories
690
				.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, -1.0d);
691
692
		return new TreeNode<>(minusOneFactory.build(inputSpec));
693
	});
694
695
	final public static Rule SIN_PI = ImmutableRule.of((t) -> {
696
		if (isOperation(t, Functions.NAME_SIN) == false) {
697
			return false;
698
		}
699
700
		return hasChildOperation(t, 0, Terminals.NAME_PI);
701
	}, (program, t) -> {
702
703
		final InputSpec inputSpec = program.inputSpec();
704
705
		final OperationFactory zeroFactory = OperationFactories
706
				.ofCoefficient(Terminals.TYPE_COEFFICIENT, Double.class, -0.0d);
707
708
		return new TreeNode<>(zeroFactory.build(inputSpec));
709
	});
710
711
	final public static List<Rule> SIMPLIFY_RULES = Arrays.asList(MUL_SAME_BRANCHES,
712
			ADD_TWO_COEFFCIENTS,
713
			MUL_TWO_COEFFICIENTS,
714
			SUB_TWO_COEFFICIENTS,
715
			SUB_INPUT_FROM_SAME_INPUT,
716
			SUB_ZERO_FROM_INPUT,
717
			DIV_TWO_COEFFICIENT_FINITE,
718
			ADD_INPUT_TO_SAME_INPUT,
719
			MULTIPLY_INPUT_WITH_SAME_INPUT,
720
			MUL_1_WITH_ANYTHING,
721
			MUL_ANYTHING_WITH_1,
722
			MUL_0_WITH_ANYTHING,
723
			MUL_ANYTHING_WITH_0,
724
			POW_0,
725
			POW_1,
726
			COS_OF_COEFFICIENT,
727
			SIN_OF_COEFFICIENT,
728
			SUB_SAME_BRANCHES,
729
			ADD_SAME_BRANCHES,
730
			DIV_SAME_BRANCHES,
731
			EXP_OF_COEFFICIENT,
732
			POW_TWO_COEFFICIENTS,
733
			ADD_0_WITH_ANYTHING,
734
			ADD_ANYTHING_WITH_0,
735
			COS_PI,
736
			SIN_PI);
737
738
}

Mutations

27

1.1
Location : isOperation
Killed by : none
removed call to java/lang/String::equals → NO_COVERAGE

2.2
Location : isOperation
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/gp/math/SimplificationRules::isOperation → NO_COVERAGE

3.3
Location : isOperation
Killed by : none
removed call to net/bmahe/genetics4j/core/chromosomes/TreeNode::getData → NO_COVERAGE

4.4
Location : isOperation
Killed by : none
replaced boolean return with false for net/bmahe/genetics4j/gp/math/SimplificationRules::isOperation → NO_COVERAGE

5.5
Location : isOperation
Killed by : none
removed call to net/bmahe/genetics4j/gp/Operation::getName → NO_COVERAGE

36

1.1
Location : hasChildOperation
Killed by : none
removed call to java/util/List::size → NO_COVERAGE

2.2
Location : hasChildOperation
Killed by : none
changed conditional boundary → NO_COVERAGE

3.3
Location : hasChildOperation
Killed by : none
removed conditional - replaced comparison check with false → NO_COVERAGE

4.4
Location : hasChildOperation
Killed by : none
removed conditional - replaced comparison check with true → NO_COVERAGE

5.5
Location : hasChildOperation
Killed by : none
negated conditional → NO_COVERAGE

6.6
Location : hasChildOperation
Killed by : none
removed call to net/bmahe/genetics4j/core/chromosomes/TreeNode::getChildren → NO_COVERAGE

37

1.1
Location : hasChildOperation
Killed by : none
Substituted 0 with 1 → NO_COVERAGE

2.2
Location : hasChildOperation
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/gp/math/SimplificationRules::hasChildOperation → NO_COVERAGE

40

1.1
Location : hasChildOperation
Killed by : none
replaced call to net/bmahe/genetics4j/core/chromosomes/TreeNode::getChild with receiver → NO_COVERAGE

2.2
Location : hasChildOperation
Killed by : none
removed call to net/bmahe/genetics4j/core/chromosomes/TreeNode::getChild → NO_COVERAGE

41

1.1
Location : hasChildOperation
Killed by : none
removed call to java/lang/String::equals → NO_COVERAGE

2.2
Location : hasChildOperation
Killed by : none
replaced boolean return with false for net/bmahe/genetics4j/gp/math/SimplificationRules::hasChildOperation → NO_COVERAGE

3.3
Location : hasChildOperation
Killed by : none
removed call to net/bmahe/genetics4j/core/chromosomes/TreeNode::getData → NO_COVERAGE

4.4
Location : hasChildOperation
Killed by : none
removed call to net/bmahe/genetics4j/gp/Operation::getName → NO_COVERAGE

5.5
Location : hasChildOperation
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/gp/math/SimplificationRules::hasChildOperation → NO_COVERAGE

45

1.1
Location : getChildAs
Killed by : none
removed call to net/bmahe/genetics4j/core/chromosomes/TreeNode::getChild → NO_COVERAGE

2.2
Location : getChildAs
Killed by : none
replaced call to net/bmahe/genetics4j/core/chromosomes/TreeNode::getChild with receiver → NO_COVERAGE

46

1.1
Location : getChildAs
Killed by : none
removed call to net/bmahe/genetics4j/core/chromosomes/TreeNode::getData → NO_COVERAGE

47

1.1
Location : getChildAs
Killed by : none
replaced return value with null for net/bmahe/genetics4j/gp/math/SimplificationRules::getChildAs → NO_COVERAGE

53

1.1
Location : isEqual
Killed by : none
replaced call to java/lang/Math::abs with argument → NO_COVERAGE

2.2
Location : isEqual
Killed by : none
Replaced double subtraction with addition → NO_COVERAGE

3.3
Location : isEqual
Killed by : none
changed conditional boundary → NO_COVERAGE

4.4
Location : isEqual
Killed by : none
removed call to java/lang/Math::abs → NO_COVERAGE

5.5
Location : isEqual
Killed by : none
removed conditional - replaced comparison check with false → NO_COVERAGE

6.6
Location : isEqual
Killed by : none
negated conditional → NO_COVERAGE

7.7
Location : isEqual
Killed by : none
removed conditional - replaced comparison check with true → NO_COVERAGE

8.8
Location : isEqual
Killed by : none
Substituted 0 with 1 → NO_COVERAGE

9.9
Location : isEqual
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/gp/math/SimplificationRules::isEqual → NO_COVERAGE

10.10
Location : isEqual
Killed by : none
Substituted 1 with 0 → NO_COVERAGE

57

1.1
Location : isEqual
Killed by : none
Substituted 1.0E-4 with 1.0 → NO_COVERAGE

2.2
Location : isEqual
Killed by : none
removed call to net/bmahe/genetics4j/gp/math/SimplificationRules::isEqual → NO_COVERAGE

3.3
Location : isEqual
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/gp/math/SimplificationRules::isEqual → NO_COVERAGE

4.4
Location : isEqual
Killed by : none
replaced boolean return with false for net/bmahe/genetics4j/gp/math/SimplificationRules::isEqual → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.19.6