package aalg.algebra;

/**
 * Field is algebraic structure with two commutative and associative binary operations
 * usually named addition and multiplication. Structure is closed with respect to these operations.
 * There are two identity elements - additive identity (e.g. zero) and multiplicative
 * identity (e.g. one). Each element has additive inverse and each element except zero
 * has multiplicative inverse. Multiplication is distributive over addition.
 * @author Ing. Petr Ležák
 *
 * @param <T> type of element
 */
public interface IField<T extends IElement> extends IAlgebraicStructure<T> {
	/**
	 * Performs additive operation.
	 * @param a operand
	 * @param b operand
	 * @return a + b
	 */
	public T add (final T a, final T b);
	
	/**
	 * Performs inverse operation to addition.
	 * @param a operand
	 * @param b operand
	 * @return y = a - b; y + b = a
	 */
	public T subtract (final T a, final T b);
	
	/**
	 * Performs multiplicative operation.
	 * @param a operand
	 * @param b operand
	 * @return a * b
	 */
	public T multiply (final T a, final T b);

	/**
	 * Performs inverse operation to multiplication.
	 * If b is zero null is returned.
	 * @param a operand
	 * @param b operand
	 * @return y = a / b; y * b = a
	 */
	public T divide (final T a, final T b);
	
	/**
	 * Returns additive inverse element to given one.
	 * Inverse element exists for each element of field. 
	 * @param x operand
	 * @return y = -x; x + y = 0
	 */
	public T additiveInverse (final T x);
	
	/**
	 * Returns multiplicative inverse element to given one.
	 * Inverse element exists for each element of field except zero. For zero
	 * null is returned.
	 * @param x operand
	 * @return y = 1 / x; x * y = 1
	 */
	public T multiplicativeInverse (final T x);
	
	/**
	 * Returns additive identity element.
	 * @return 0; x + 0 = x
	 */
	public T getAdditiveIdentity();
	
	/**
	 * Returns multiplicative identity element.
	 * @return 1; x * 1 = x
	 */
	public T getMultiplicativeIdentity();
	
	/**
	 * Returns commutative group with same set of elements as field and additive operation.
	 * @return additive group
	 */
	public IGroup<T> getAdditiveGroup();
	
	/**
	 * Returns commutative group with same set of elements as field without zero
	 * and multiplicative operation.
	 * @return multiplicative group
	 */
	public IGroup<T> getMultiplicativeGroup();
}
