SimplificationRules.java

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

Mutations

28

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

37

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

38

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

41

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

42

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

47

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

48

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

49

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

55

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

59

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.20.3