// $Id: PropositionVariables.java,v 1.5 2004/02/27 16:30:00 m31 Exp $
//
// This file is part of the program suite "Principia Mathematica II"
// which is a working prototype for the main project:
// "Hilbert II" - http://www.qedeq.org
//
// Copyright 2001-2004  Michael Meyling <mime@qedeq.org>.
//
// "Principia Mathematica II" is free software; you can redistribute
// it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

package com.meyling.principia.logic.basic;


import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


/**
 * Set of proposition variables.
 *
 * @version $Revision: 1.5 $
 * @author  Michael Meyling
 */
public class PropositionVariables {

    /** here is the list */
    private final Map variables;


    /**
     * Construct an empty set of proposition variables.
     */
    public PropositionVariables() {
        variables = new HashMap();
    }


    /**
     * Construct a new set of proposition variables with the same entires as
     * the given one.
     *
     * @param   already these proposition variable entries should be added
     */
    public PropositionVariables(final PropositionVariables already) {
        variables = new HashMap(already.getMap());
    }


    /**
     * Construct a new set of proposition variables with some initial entries.
     *
     * @param   already these proposition variable entries should be added
     */
    public PropositionVariables(final PropositionVariable[] already) {
        variables = new HashMap();
        for (int i = 0; i < already.length; i++) {
            String name = already[i].toString();
            if (!variables.containsKey(name)) {
                variables.put(name, already[i]);
            }
        }
    }


    /**
     * Add a proposition variable to the set.
     *
     * @param   variable    add this variable
     */
    public final void add(final PropositionVariable variable) {
        String name = variable.toString();
        if (!variables.containsKey(name)) {
            variables.put(name, variable);
        }
    }


    /**
     * Check if a certain proposition variable is
     * already in the set.
     *
     * @param   variable    check for this variable
     * @return  is <code>variable</code> already there?
     */
    public final boolean contains(final PropositionVariable variable) {
        return variables.containsKey(variable.toString());
    }


    /**
     * Does this object have an empty intersection with another
     * set of proposition variables?
     *
     * @param   variables   to build intersection with
     * @return  is the intersection empty?
     */
    public final boolean emptyIntersection(final PropositionVariables variables) {
        for (Iterator iterator
                = variables.getMap().entrySet().iterator();
                iterator.hasNext(); ) {
            Map.Entry entry = (Map.Entry) iterator.next();
            if (this.variables.containsKey(entry.getKey())) {
                return false;
            }
        }
        return true;
    }


    /**
     * Does this object contain another
     * set of proposition variables?
     *
     * @param   variables   check this set
     * @return  is <code>variables</code> a subset?
     */
    public final boolean contains(final PropositionVariables variables) {
        for (Iterator iterator
                = variables.getMap().entrySet().iterator();
                iterator.hasNext(); ) {
            Map.Entry entry = (Map.Entry) iterator.next();
            if (!this.variables.containsKey(entry.getKey())) {
                return false;
            }
        }
        return true;
    }


    /**
     * Add all these proposition variables.
     *
     * @param   newOnes these should be added
     */
    public final void addAll(final PropositionVariables newOnes) {
        for (Iterator iterator
                = newOnes.getMap().entrySet().iterator();
                iterator.hasNext(); ) {
            Map.Entry entry = (Map.Entry) iterator.next();
            if (!variables.containsKey(entry.getKey())) {
                variables.put(entry.getKey(), entry.getValue());
            }
        }
    }


    /**
     * Get number of elements in the set.
     *
     * @return element number of set
     */
    public final int getSize() {
        return variables.size();
    }


    /**
     * Get highest number of each entry.
     *
     * @return  maxiumum of number value for all entries,
     *          if getSize() == 0 it returns -1
     */
    public final int getHighestNumber() {
        int maximum = -1;   // minimum number value is 0
        for (Iterator iterator = variables.entrySet().iterator();
                iterator.hasNext(); ) {
            Map.Entry entry = (Map.Entry) iterator.next();
            final int number = ((PropositionVariable) entry.getValue())
                .getNumber();
            if (maximum < number) {
                maximum = number;
            }
        }
        return maximum;
    }


    /**
     * Remove a proposition variable or a pattern variable from the set.
     *
     * @param   variable    remove this one
     */
    public final void remove(final PropositionVariable variable) {
        variables.remove(variable.toString());
    }


    /**
     * Get the set of proposition variables and pattern variables.
     *
     * @return  set of variables
     */
    private final Map getMap() {
        return variables;
    }


    /**
     * Get a readable string representation of this object.
     *
     * @return  description of this object
     */
    public final String toString() {
        StringBuffer result = new StringBuffer("{");
        boolean notFirst = false;
        for (Iterator iterator = variables.entrySet().iterator();
                iterator.hasNext(); ) {
            Map.Entry entry = (Map.Entry) iterator.next();
            if (notFirst) {
                result.append(", ");
            } else {
                notFirst = true;
            }
            result.append((String) entry.getKey());
        }
        result.append("}");
        return result.toString();
    }


    /**
     * Is this object equal to another one?
     *
     * @param   variables object to compare with
     * @return  do all their entries are equal?
     */
    public final boolean equals(PropositionVariables variables) {
        if (variables.getMap().size() != this.variables.size()) {
            return false;
        }
        for (Iterator iterator = variables.getMap().entrySet().iterator();
                iterator.hasNext(); ) {
            Map.Entry entry = (Map.Entry) iterator.next();
            if (!this.variables.containsKey(entry.getKey())) {
                return false;
            }
        }
        return true;
    }


}
