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

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
replaced boolean return with false for net/bmahe/genetics4j/gp/math/SimplificationRules::isOperation → NO_COVERAGE

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

29

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

38

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

39

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

2.2
Location : hasChildOperation
Killed by : none
negated conditional → 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
changed conditional boundary → NO_COVERAGE

40

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

43

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

44

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
replaced boolean return with true for net/bmahe/genetics4j/gp/math/SimplificationRules::hasChildOperation → NO_COVERAGE

45

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

50

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

51

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

52

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

58

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

62

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