/*******************************************************************************
 * GenRGenS v.1.0, Generation of Random Genomic Sequences                      *
 * Copyright (C) 2001  Alain Denise/Yann Ponty                                 *
 *                                                                             *
 * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. *
 *******************************************************************************/

package GenRGenS.grammar;

import java.util.Vector;

/**
 * classe ContextFreeGrammarProduction 
 *     contient a la fois partie gauche et partie droite         
 *     le nombre de lettre est fixé a la création                
 *     une reference hors des limites provoque une exception
 */


public class ContextFreeGrammarProduction
{
		private int[] lettre;

    /**
     * Construit une instance de <code>ContextFreeGrammarProduction</code> de taille fixée.
     * Elle modélise une règle de la grammaire.
     * @param nombreDeLettres Le nombres de symboles de la règle (= NBRègle de la partie droite + 1)
     */
		ContextFreeGrammarProduction(int nombreDeLettres)
		{
				lettre = new int[nombreDeLettres];
		}

		
		/** 
		 * Construit une instance de <code>ContextFreeGrammarProduction</code> de contenu fixé.
     * Elle modélise une règle de la grammaire.
     * @param symboles Un vecteur générique ne contenant que des instances de <code>Integer</code> 
     * dont les contenus entiers sont les index des symbole de la règle.
		 */
		ContextFreeGrammarProduction(Vector symboles)
				throws BadGrammarException
		{
				if (symboles.isEmpty())
						throw(new BadGrammarException("incorrect Vector for ContextFreeGrammarProduction construction"));
				int longueur;
				lettre = new int[longueur=symboles.size()];
				
				for (int i=0;i<longueur;i++)
						lettre[i]=((Integer) symboles.get(i)).intValue();						
		}

    /**
     * Modifie le contenu d'une règle.
     * Substitue à un symbole présent un autre symbole décrit par son index.
     * @param index L'emplacement du symbole à modifier.
     * @param valeur L'index du symbole à lui substituer.
     */

		void put(int index, int valeur)
		{
				if (index<lettre.length)
						lettre[index]=valeur;
				else
						throw( new IndexOutOfBoundsException());
		}
		
		/**
		 * Renvoie l'index d'un symbole de la règle selon sa position.
		 * @param index L'emplacement dans la règle du symbole.
		 * @return L'index du symbole visé.
		 */

		int get(int index)
		{
				if (index<lettre.length)
						return(lettre[index]);
				else
						throw( new IndexOutOfBoundsException());
		}

		/**
		 * Renvoie la partie gauche de la règle.
		 * @return L'index de la partie gauche de la règle.
		 */
		int getLHS()
		{ return(lettre[0]); };
		
		/**
		 * Renvoie le nombre de symbole dans cette règle.
		 * @return Le nombre de symbole dans cette règle.
		 */
		int size()
		{	return(lettre.length); };

		/**
		 * Le langage associé à cette règle est il réduit à epsilon ?
		 * @return true si la règle ne dérive qu'epsilon, false sinon.
		 */
		boolean isEpsilonProduction()
		{	return(lettre.length==1);	};

		/**
		 * Le langage associé à cette règle est il réduit à un symbole terminal ?
		 * @return true si la règle ne dérive qu'un terminal, false sinon.
		 */
		boolean isTerminalProduction()
		{ return(lettre.length==2 && lettre[1]<0); };

		/**
		 * Le langage associé à cette règle est il réduit à celui d'un symbole non-terminal ?
		 * @return true si la règle ne dérive qu'un non-terminal, false sinon.
		 */
		boolean isSingleProduction()
		{ return(lettre.length==2 && lettre[1]>=0);	};
		
		/**
		 * Renvoie une représentation littérale de cette instance.
		 */
		String print()
		{
				String temp="";
				for (int i=0;i<lettre.length;i++)	temp+=lettre[i]+" ";
				return(temp);
		}

}
