1 package net.bmahe.genetics4j.gp; 2 3 import java.util.List; 4 import java.util.function.BiFunction; 5 6 import org.immutables.value.Value; 7 import org.immutables.value.Value.Parameter; 8 9 /** 10 * Represents an operation (function or terminal) in genetic programming. 11 * 12 * <p>An operation defines a computational unit that can be used as a node in genetic programming trees. 13 * Operations can be either functions (with arguments) or terminals (without arguments). Each operation 14 * has a defined signature including the types it accepts as input and the type it returns. 15 * 16 * <p>Operations are the building blocks of genetic programming expressions and define: 17 * <ul> 18 * <li>The computation to perform</li> 19 * <li>Type constraints for strongly-typed GP</li> 20 * <li>Arity (number of arguments)</li> 21 * <li>Whether it's a terminal or function</li> 22 * </ul> 23 * 24 * <p>Common operation types include: 25 * <ul> 26 * <li><strong>Mathematical functions</strong>: +, -, *, /, sin, cos, exp</li> 27 * <li><strong>Logical functions</strong>: AND, OR, NOT, IF-THEN-ELSE</li> 28 * <li><strong>Terminals</strong>: constants, variables, input values</li> 29 * <li><strong>Domain-specific</strong>: problem-specific functions and operators</li> 30 * </ul> 31 * 32 * @param <T> the base type used for computation in this operation 33 * @see OperationFactory 34 * @see net.bmahe.genetics4j.gp.program.Program 35 */ 36 @Value.Immutable 37 public abstract class Operation<T> { 38 39 /** 40 * Returns the name of this operation. 41 * 42 * @return the operation name, used for identification and display 43 */ 44 @Parameter 45 public abstract String getName(); 46 47 /** 48 * Returns the list of types that this operation accepts as arguments. 49 * 50 * <p>For strongly-typed genetic programming, this defines the type constraints 51 * for each argument position. The list size determines the operation's arity. 52 * 53 * @return the list of accepted argument types, empty for terminals 54 */ 55 @SuppressWarnings("rawtypes") 56 @Parameter 57 public abstract List<Class> acceptedTypes(); 58 59 /** 60 * Returns the type that this operation returns. 61 * 62 * @return the return type of this operation 63 */ 64 @SuppressWarnings("rawtypes") 65 @Parameter 66 public abstract Class returnedType(); 67 68 /** 69 * Returns the computation function for this operation. 70 * 71 * @return a function that takes input arguments and parameters and returns the computed result 72 */ 73 @Parameter 74 @Value.Auxiliary 75 public abstract BiFunction<T[], Object[], Object> compute(); 76 77 /** 78 * Returns a human-readable name for this operation. 79 * 80 * <p>By default, this returns the same value as {@link #getName()}, but can be 81 * overridden to provide more descriptive names for display purposes. 82 * 83 * @return the pretty name for display purposes 84 */ 85 @Value.Default 86 public String getPrettyName() { 87 return getName(); 88 } 89 90 /** 91 * Applies this operation to the given input and parameters. 92 * 93 * @param input the input arguments to the operation 94 * @param parameters additional parameters for the operation 95 * @return the result of applying this operation 96 */ 97 public Object apply(final T[] input, final Object[] parameters) { 98 final BiFunction<T[], Object[], Object> function = compute(); 99 return function.apply(input, parameters); 100 } 101 102 /** 103 * Returns the arity (number of arguments) of this operation. 104 * 105 * @return the number of arguments this operation accepts 106 */ 107 public int getArity() { 108 return acceptedTypes().size(); 109 } 110 111 /** 112 * Checks if this operation is a terminal (has no arguments). 113 * 114 * @return {@code true} if this operation takes no arguments, {@code false} otherwise 115 */ 116 public boolean isTerminal() { 117 return getArity() == 0; 118 } 119 }