<commit_before>/*
 * Copyright (c) 2006-2008 <NAME>, <NAME>, <NAME>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package com.dmdirc.actions;

import java.util.ArrayDeque;
import java.util.Deque;

/**
 * A condition tree specifies in which order a group of conditions will be
 * executed.
 *
 * @author chris
 */
public class ConditionTree {

    /** The possible operations on a condition tree. */
    public static enum OPERATION {
        /** Only passes if both subtrees are true. */
        AND,
        /** Passes if either of the subtrees are true. */
        OR,
        /** Passes if the specified argument is true. */
        VAR,
        /** Only passes iof the left subtree fails to pass. */
        NOT,
        /** Doesn't do anything (an empty tree). */
        NOOP
    }

    /** The left subtree of this tree. */
    private ConditionTree leftArg = null;

    /** The right subtree of this tree. */
    private ConditionTree rightArg = null;

    /** The argument of this tree (only used for VAR ops). */
    private int argument = -1;

    /** The operation that this tree performs. */
    private final OPERATION op;

    /**
     * Creates a new ConditionTree for a binary operation.
     *
     * @param op The binary operation to perform
     * @param leftArg The left argument/subtree
     * @param rightArg The right argument/subtree
     */
    private ConditionTree(final OPERATION op, final ConditionTree leftArg,
            final ConditionTree rightArg) {
        this.op = op;
        this.leftArg = leftArg;
        this.rightArg = rightArg;
    }

    /**
     * Creates a new ConditionTree for a unary operation.
     *
     * @param op
     * @param argument
     */
    private ConditionTree(final OPERATION op, final ConditionTree argument) {
        this.op = op;
        this.leftArg = argument;
    }

    /**
     * Creates a new ConditionTree for a VAR operation with the specified
     * argument number.
     *
     * @param argument The number of the argument that's to be tested.
     */
    private ConditionTree(final int argument) {
        this.op = OPERATION.VAR;
        this.argument = argument;
    }

    /**
     * Creates a new ConditionTree for a NOOP operation.
     */
    private ConditionTree() {
        this.op = OPERATION.NOOP;
    }

    /**
     * Retrieves the highest argument number that is used in this condition tree.
     *
     * @return The highest argument number used in this tree
     */
    public int getMaximumArgument() {
        if (this.op == OPERATION.NOOP) {
            return 0;
        } else if (this.op == OPERATION.VAR) {
            return argument;
        } else if (this.op == OPERATION.NOT) {
            return leftArg.getMaximumArgument();
        } else {
            return Math.max(leftArg.getMaximumArgument(), rightArg.getMaximumArgument());
        }
    }

    /**
     * Evaluates this tree with the specified conditions. Returns the result
     * of the evaluation.
     *
     * @param conditions The binary values of each of the conditions used in
     * this three
     * @return The result of the evaluation of this tree
     */
    public boolean evaluate(final boolean[] conditions) {
        switch (op) {
            case VAR:
                return conditions[argument];
            case NOT:
                return !leftArg.evaluate(conditions);
            case AND:
                return leftArg.evaluate(conditions) && rightArg.evaluate(conditions);
            case OR:
                return leftArg.evaluate(conditions) || rightArg.evaluate(conditions);
            default:
                return true;
        }
    }

    /**
     * Retrieves a String representation of this ConditionTree. The string
     * representation is a normalised formula describing this tree and all of
     * its children. The output of this method will generate an identical tree
     * if passed to parseString.
     *
     * @return A string representation of this tree
     */
    @Override
    public String toString() {
        switch (op) {
        case VAR:
            return String.valueOf(argument);
        case NOT:
            return "!" + leftArg;
        case AND:
            return "(" + leftArg + "&" + rightArg + ")";
        case OR:
            return "(" + leftArg + "|" + rightArg + ")";
        default:
            return "";
        }
    }
<commit_msg>ConditionTrees now implement equals and hashcode Additional work on issue 1566 <commit_after>/*
 * Copyright (c) 2006-2008 <NAME>, <NAME>, <NAME>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package com.dmdirc.actions;

import java.util.ArrayDeque;
import java.util.Deque;

/**
 * A condition tree specifies in which order a group of conditions will be
 * executed.
 *
 * @author chris
 */
public class ConditionTree {

    /** The possible operations on a condition tree. */
    public static enum OPERATION {
        /** Only passes if both subtrees are true. */
        AND,
        /** Passes if either of the subtrees are true. */
        OR,
        /** Passes if the specified argument is true. */
        VAR,
        /** Only passes iof the left subtree fails to pass. */
        NOT,
        /** Doesn't do anything (an empty tree). */
        NOOP
    }

    /** The left subtree of this tree. */
    private ConditionTree leftArg = null;

    /** The right subtree of this tree. */
    private ConditionTree rightArg = null;

    /** The argument of this tree (only used for VAR ops). */
    private int argument = -1;

    /** The operation that this tree performs. */
    private final OPERATION op;

    /**
     * Creates a new ConditionTree for a binary operation.
     *
     * @param op The binary operation to perform
     * @param leftArg The left argument/subtree
     * @param rightArg The right argument/subtree
     */
    private ConditionTree(final OPERATION op, final ConditionTree leftArg,
            final ConditionTree rightArg) {
        this.op = op;
        this.leftArg = leftArg;
        this.rightArg = rightArg;
    }

    /**
     * Creates a new ConditionTree for a unary operation.
     *
     * @param op
     * @param argument
     */
    private ConditionTree(final OPERATION op, final ConditionTree argument) {
        this.op = op;
        this.leftArg = argument;
    }

    /**
     * Creates a new ConditionTree for a VAR operation with the specified
     * argument number.
     *
     * @param argument The number of the argument that's to be tested.
     */
    private ConditionTree(final int argument) {
        this.op = OPERATION.VAR;
        this.argument = argument;
    }

    /**
     * Creates a new ConditionTree for a NOOP operation.
     */
    private ConditionTree() {
        this.op = OPERATION.NOOP;
    }

    /**
     * Retrieves the highest argument number that is used in this condition tree.
     *
     * @return The highest argument number used in this tree
     */
    public int getMaximumArgument() {
        if (this.op == OPERATION.NOOP) {
            return 0;
        } else if (this.op == OPERATION.VAR) {
            return argument;
        } else if (this.op == OPERATION.NOT) {
            return leftArg.getMaximumArgument();
        } else {
            return Math.max(leftArg.getMaximumArgument(), rightArg.getMaximumArgument());
        }
    }

    /**
     * Evaluates this tree with the specified conditions. Returns the result
     * of the evaluation.
     *
     * @param conditions The binary values of each of the conditions used in
     * this three
     * @return The result of the evaluation of this tree
     */
    public boolean evaluate(final boolean[] conditions) {
        switch (op) {
            case VAR:
                return conditions[argument];
            case NOT:
                return !leftArg.evaluate(conditions);
            case AND:
                return leftArg.evaluate(conditions) && rightArg.evaluate(conditions);
            case OR:
                return leftArg.evaluate(conditions) || rightArg.evaluate(conditions);
            default:
                return true;
        }
    }

    /** {@inheritDoc} */
    @Override
    public boolean equals(final Object obj) {
        return obj instanceof ConditionTree
                && toString().equals(((ConditionTree) obj).toString());
    }

    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        return toString().hashCode();
    }

    /**
     * Retrieves a String representation of this ConditionTree. The string
     * representation is a normalised formula describing this tree and all of
     * its children. The output of this method will generate an identical tree
     * if passed to parseString.
     *
     * @return A string representation of this tree
     */
    @Override
    public String toString() {
        switch (op) {
        case VAR:
            return String.valueOf(argument);
        case NOT:
            return "!" + leftArg;
        case AND:
            return "(" + leftArg + "&" + rightArg + ")";
        case OR:
            return "(" + leftArg + "|" + rightArg + ")";
        default:
            return "";
        }
    }

{'fraction_non_alphanumeric': 0.0836600142551675, 'fraction_numerical': 0.0021382751247327157, 'mean_word_length': 2.201654306902453, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '239882', 'n_tokens_mistral': 2937, 'n_tokens_neox': 2812, 'n_words': 1185}