All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.mmm.base.lang.Conjunction Maven / Gradle / Ivy

/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
 * http://www.apache.org/licenses/LICENSE-2.0 */
package io.github.mmm.base.lang;

/**
 * {@link Enum} with the common boolean conjunction operators {@link #AND}, {@link #OR}, {@link #NAND}, and
 * {@link #NOR}.
 *
 * @since 1.0.0
 */
public enum Conjunction {
  /**
   * This conjunction is {@code true} if and only if all arguments are {@code true}.
   */
  AND("and", "&") {

    @Override
    public boolean eval(boolean arg1, boolean arg2) {

      return arg1 && arg2;
    }

    @Override
    public boolean evalEmpty() {

      return true;
    }

    @Override
    public boolean isNegating() {

      return false;
    }

    @Override
    public Conjunction negate() {

      return NAND;
    }
  },

  /**
   * This conjunction is {@code true} if and only if at least one argument is {@code true}.
   */
  OR("or", "|") {

    @Override
    public boolean eval(boolean arg1, boolean arg2) {

      return arg1 || arg2;
    }

    @Override
    public boolean evalEmpty() {

      return false;
    }

    @Override
    public boolean isNegating() {

      return false;
    }

    @Override
    public Conjunction negate() {

      return NOR;
    }
  },

  /**
   * This is the negation of {@link #AND}. It is only {@code true} if at least one argument is {@code false}.
   */
  NAND("nand", "!&") {

    @Override
    public boolean eval(boolean arg1, boolean arg2) {

      return !(arg1 && arg2);
    }

    @Override
    public boolean evalEmpty() {

      return false;
    }

    @Override
    public boolean isNegating() {

      return true;
    }

    @Override
    public Conjunction negate() {

      return AND;
    }
  },

  /**
   * This is the negation of {@link #OR}. It is only {@code true} if all arguments are {@code false} .
   */
  NOR("nor", "!|") {

    @Override
    public boolean eval(boolean arg1, boolean arg2) {

      return !(arg1 || arg2);
    }

    @Override
    public boolean evalEmpty() {

      return true;
    }

    @Override
    public boolean isNegating() {

      return true;
    }

    @Override
    public Conjunction negate() {

      return OR;
    }
  },

  /**
   * This conjunction is {@code true} if and only if two arguments differ (exactly one of two arguments if
   * {@code true}).
   */
  XOR("xor", "!=") {

    @Override
    public boolean eval(boolean arg1, boolean arg2) {

      return arg1 ^ arg2;
    }

    @Override
    public boolean evalEmpty() {

      return false;
    }

    @Override
    public boolean isNegating() {

      return true;
    }

    @Override
    public Conjunction negate() {

      return EQ;
    }
  },

  /**
   * This conjunction is {@code true} if and only if two arguments equal.
   */
  EQ("eq", "=") {

    @Override
    public boolean eval(boolean arg1, boolean arg2) {

      return arg1 == arg2;
    }

    @Override
    public boolean eval(boolean... arguments) {

      if (arguments.length == 0) {
        return evalEmpty();
      }
      int i = 0;
      boolean first = arguments[i++];
      while (i < arguments.length) {
        boolean next = arguments[i++];
        if (first != next) {
          return false;
        }
      }
      return true;
    }

    @Override
    public boolean evalEmpty() {

      return true;
    }

    @Override
    public boolean isNegating() {

      return false;
    }

    @Override
    public Conjunction negate() {

      return XOR;
    }
  };

  private final String syntax;

  private final String name;

  /**
   * The constructor.
   *
   * @param name is the {@link #getName() name}.
   * @param syntax is the {@link #getSyntax() syntax}.
   */
  private Conjunction(String name, String syntax) {

    this.syntax = syntax;
    this.name = name;
  }

  /**
   * This method evaluates this conjunction for the given boolean {@code arguments}.
   *
   * @param arg1 the first argument.
   * @param arg2 the second argument.
   * @return the result of this conjunction applied to the given two arguments.
   */
  public abstract boolean eval(boolean arg1, boolean arg2);

  /**
   * @return {@code true} if this {@link Conjunction} is negating the final result and therefore not left-associative,
   *         {@code false} otherwise.
   */
  public abstract boolean isNegating();

  /**
   * Evaluates this {@link Conjunction} for the given boolean {@code arguments}. 
* ATTENTION: The result is NOT the same as a applying the {@link Conjunction} left-associative as * {@link #eval(boolean, boolean) binary} operation because a {@link #negate() negation} is applied to the final * result. Example: {@code NOR(a, b, c) = !(OR(a, b, c))} what is not the same as {@code NOR(NOR(a, b), c)}. * * @param arguments the boolean values to evaluate. * @return the result of this {@link Conjunction} applied to the given {@code arguments}. */ public boolean eval(boolean... arguments) { if (isNegating()) { return !negate().eval(arguments); } if (arguments.length == 0) { return evalEmpty(); } int i = 0; boolean result = arguments[i++]; while (i < arguments.length) { result = eval(result, arguments[i++]); } return result; } /** * @return the result of {@link #eval(boolean...)} for no argument (an empty argument array). */ public abstract boolean evalEmpty(); /** * @return the syntax used for technical representation (e.g. '{@literal &&}' for {@link #AND}). */ public String getSyntax() { return this.syntax; } /** * @return the name and {@link Object#toString() string representation} (e.g. "and" for {@link #AND}). */ public String getName() { return this.name; } /** * @return the negation of this {@link Conjunction} that {@link #eval(boolean...) evaluates} to the negated result. */ public abstract Conjunction negate(); @Override public String toString() { return this.name; } /** * @param syntax the {@link #getSyntax() syntax} of the requested {@link Conjunction}. * @return the requested {@link Conjunction} or {@code null} if no such {@link Conjunction} exists. */ public static Conjunction ofSyntax(String syntax) { for (Conjunction conjunction : values()) { if (conjunction.syntax.equals(syntax)) { return conjunction; } } return null; } /** * @param name is the {@link #getName() name} of the requested {@link Conjunction}. * @return the requested {@link Conjunction} or {@code null} if no such {@link Conjunction} exists. */ public static Conjunction ofName(String name) { for (Conjunction conjunction : values()) { if (conjunction.name.equals(name)) { return conjunction; } } return null; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy