/*
 * GeneralizedLogicProgram.java
 *
 * Copyright (C) 2006 - 2007 Martin Slota
 *
 * This program 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.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

/*
 * History:
 * v0.1 (2007-02-12): initial version
 * v0.2 (2007-02-12):
 * - implementation, tests and docs taken from LogicProgram
 * v0.2.1 (2007-02-14):
 * - equals() fixed
 * v0.2.2 (2007-03-06):
 * - renamed to GeneralizedLogicProgram
 * - inherits from LinkedHashSet instead of ArrayList
 * - equals(), hashCode() and toString() deleted (super implementations are OK)
 * v1.0.0 (2007-05-05):
 * - the calls to the static isGroundStatic in LpGroundDecider replaced by a
 *   separate instance of LpGroundDecider
 */

package lp.unit;

import java.util.Iterator;
import java.util.LinkedHashSet;

import lp.struct.LpRule;
import lp.struct.util.LpGroundDecider;

/**
 * A default implementation of the {@link LogicProgram} interface.
 *
 * @author Martin Slota
 * @version 1.0.0
 */
public class GeneralizedLogicProgram extends LinkedHashSet<LpRule>
		implements LogicProgram {
	/**
	 * A static {@link LpGroundDecider} instance used in the {@link #isGround()}
	 * method.
	 */
	private static final LpGroundDecider GD = new LpGroundDecider();
	
	/**
	 * Creates a new instance of {@code GeneralizedLogicProgram} representing an
	 * empty logic program.
	 */
	public GeneralizedLogicProgram() {
		// do nothing
	}
	
	/**
	 * {@inheritDoc}
	 */
	public LpRule get(int index) {
		if (index < 0 || index >= size()) {
			throw new IndexOutOfBoundsException("No such rule!");
		}
		int i = 0;
		Iterator<LpRule> iter = iterator();
		while (i < index) {
			iter.next();
			i++;
		}
		return iter.next();
	}
	
	/**
	 * {@inheritDoc}
	 */
	public boolean isGround() {
		synchronized (GD) {
			for (LpRule r : this) {
				if (!GD.isGround(r))
					return false;
			}
			return true;
		}
	}
}