Op.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-3.9.0).
003  * Copyright (c) 2007-2017 Franz Wilhelmstötter
004  *
005  * Licensed under the Apache License, Version 2.0 (the "License");
006  * you may not use this file except in compliance with the License.
007  * You may obtain a copy of the License at
008  *
009  *      http://www.apache.org/licenses/LICENSE-2.0
010  *
011  * Unless required by applicable law or agreed to in writing, software
012  * distributed under the License is distributed on an "AS IS" BASIS,
013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  * See the License for the specific language governing permissions and
015  * limitations under the License.
016  *
017  * Author:
018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
019  */
020 package org.jenetics.prog.op;
021 
022 import java.util.function.Function;
023 import java.util.function.Supplier;
024 
025 /**
026  * Operation interface. An operation is a function which maps some argument type
027  * with a given <em>arity</em> to a result object of the same type:
028  * {@code T[] -> T}.
029  *
030  <pre>{@code
031  * final Op<Double> add = Op.of("add", 2, v -> v[0] + v[1]);
032  * final Op<Double> add3 = Op.of("add3", 3, v -> v[0] + v[1] + v[2]);
033  * final Op<Double> sub = Op.of("sub", 2, v -> v[0] - v[1]);
034  * final Op<Double> sin = Op.of("sin", 1, v -> Math.sin(v[0]));
035  * }</pre>
036  *
037  * Implementations of the {@code Op} interface are usually immutable and doesn't
038  * maintain internal state. But some instance are ephemeral with changing state.
039  * This classes must override the {@link #get()} method inherited from the
040  {@link Supplier} interface and return a new instance.
041  *
042  @see Var
043  @see Const
044  @see EphemeralConst
045  *
046  @param <T> the argument type of the operation
047  *
048  @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
049  @version 3.9
050  @since 3.9
051  */
052 public interface Op<T> extends Function<T[], T>, Supplier<Op<T>> {
053 
054     /**
055      * Return the name of the operation.
056      *
057      @return the name of the operation
058      */
059     public String name();
060 
061     /**
062      * Return the arity of the operation function. If the arity is zero, the
063      * operation is <em>terminal</em> operation.
064      *
065      @return the arity of the operation
066      */
067     public int arity();
068 
069     /**
070      * Determines if the operation is a terminal operation.
071      *
072      @return {@code true} if the operation is a terminal operation,
073      *         {@code false} otherwise
074      */
075     public default boolean isTerminal() {
076         return arity() == 0;
077     }
078 
079     /**
080      * Return {@code this} operation, or a new instance from the same type, if
081      * the operation needs to maintain internal state. This is essentially the
082      * case for ephemeral constants.
083      *
084      @see EphemeralConst
085      *
086      @return {@code this} operation, or a new instance
087      */
088     @Override
089     public default Op<T> get() {
090         return this;
091     }
092 
093     /**
094      * Create a new operation from the given parameter.
095      *
096      @param name the operation name
097      @param arity the arity of the operation
098      @param function the function executed by the operation. In order to work
099      *        properly, the given function should be stateless and must not have
100      *        side effects.
101      @param <T> the operation type
102      @return a new operation from the given parameter
103      @throws NullPointerException if the given {@code name} or {@code function}
104      *         is {@code null}
105      @throws IllegalArgumentException if the given {@code arity} is smaller
106      *         than zero
107      */
108     public static <T> Op<T> of(
109         final String name,
110         final int arity,
111         final Function<T[], T> function
112     ) {
113         return new Operation<>(name, arity, function);
114     }
115 
116 }