Package bgu.bio.ds.automata

Source Code of bgu.bio.ds.automata.TransitionTable

package bgu.bio.ds.automata;

import java.util.Arrays;

import bgu.bio.util.alphabet.constrain.ConstrainedAlphabet;
import dk.brics.automaton.Automaton;
import dk.brics.automaton.RegExp;
import dk.brics.automaton.State;
import dk.brics.automaton.Transition;

/**
* The Class TransitionTable.
*/
public class TransitionTable {
 
  /** The constrained alphabet to be used in the table. */
  private ConstrainedAlphabet constrainedAlphabet;
 
  /** The regular expression over {@link #constrainedAlphabet} letters. */
  private String expression;
 
  /** The transition table holding all the transitions over the regular expression {@link #expression}. the first dimension is the hashed char of
   * from the {@link #constrainedAlphabet}, the second and third dimension are the origin, destination states (respectively)
   * */
  private int[][][] transitionTable; // [hash char][origin][destination]
 
  /** The accepting states in the table. */
  private int[] acceptingStates;
 
  /** The starting state in the table. */
  private int startingState;

  /** The number of states the table (the depth of dimensions 2 and 3 in {@link #transitionTable}). */
  private int numOfStates;
 
  /** equal to {@link #constrainedAlphabet} number of letters. */
  private int alphabetSize;
 
  /**
   * Instantiates a new transition table.
   *
   * @param expression the regular expression
   * @param constrainedAlphabet the constrained alphabet to be used
   */
  public TransitionTable(String expression, ConstrainedAlphabet constrainedAlphabet) {
    this.constrainedAlphabet = constrainedAlphabet;
    this.expression = expression;
    this.alphabetSize = this.constrainedAlphabet.size();
    build()
  }
 
  /**
   * Builds the transition table data.
   */
  public void build() {
    RegExp regexp = new RegExp(this.expression);
    Automaton automata = regexp.toAutomaton(true);
    numOfStates = automata.getNumberOfStates();
    //System.out.println("Number of states " + numOfStates);
   
    State[] states = new State[numOfStates];
    automata.getStates().toArray(states);
   
    //Get Accepting states and starting state
    this.startingState = indexOf(automata.getInitialState(), states);
    this.buildAcceptingStates(states);
   
    //initialize the transition table
    this.transitionTable = new int[this.alphabetSize][numOfStates][numOfStates];
   
    int[][] transitionTableLastDestination = new int[this.alphabetSize][numOfStates];
    for(int origin=0;origin<numOfStates;origin++){
      for(Transition t : states[origin].getTransitions()){
        int destination = indexOf(t.getDest(), states);
        /* Calculate transition characters */
        /* transitions have a range that needs to be covered */
        String transString1=transitionCharacters(t.getMin(), t.getMax());
        /* Calculate the transition */
        for (int idx1=0; idx1<transString1.length();idx1++){
          char tchar=transString1.charAt(idx1);
          // For [charIndex, destinationState, originState]
          int lastDest = transitionTableLastDestination[constrainedAlphabet.encode(tchar)][origin];
          this.transitionTable[constrainedAlphabet.encode(tchar)][origin][lastDest] = destination;
          transitionTableLastDestination[constrainedAlphabet.encode(tchar)][origin]++;
        }
      }
    }
   
    //Trim all the arrays
    trimDestinations(transitionTableLastDestination);
  }
 
 
  /**
   * Trim destinations in the {@link #transitionTable}. trim the third dimension of the table according to the {@link #expression}.
   *
   * @param transitionTableLastDestination the transition table last destination
   */
  private void trimDestinations(int[][] transitionTableLastDestination) {
    for (int i=0;i<this.alphabetSize;i++)
    {
      for (int j=0;j<this.numOfStates;j++)
      {
        int[] newArr = new int[transitionTableLastDestination[i][j]];
        for (int k = 0; k < newArr.length; k++) {
          newArr[k] = this.transitionTable[i][j][k];
        }
        this.transitionTable[i][j] = newArr;
      }
    }
  }

  /**
   * Builds the accepting states.
   *
   * @param states the states in the automaton
   */
  private void buildAcceptingStates(State[] states) {
    int[] acc = new int[numOfStates];
   
    int pos = 0;
    for (int i=0;i<states.length;i++)
    {
      if (states[i].isAccept()){
        acc[pos] = i;
        pos++;
      }   
    }
    this.acceptingStates = new int[pos];
    for (int i=0;i<pos;i++)
    {
      this.acceptingStates[i] = acc[i];
    }
  }

  /**
   * Gets the transitions.
   *
   * @param c - a hashed character from the constraint alphabet
   *
   * @return the array of transitions ([origin][destination])  in the automaton that have the character c.
   */
  public int[][] getTransitions(int c)
  {
    return this.transitionTable[c];
  }
 
  /**
   * Gets the accepting states id's in the table.
   *
   * @return the accepting states id's
   */
  public int[] getAcceptingStates()
  {
    return this.acceptingStates;
  }
 
  /**
   * Gets the starting state.
   *
   * @return the starting state
   */
  public int getStartingState()
  {
    return this.startingState;
  }
 
  /**
   * Index of state in the array of states.
   *
   * @param state the state
   * @param stateArray the state array
   *
   * @return the int
   */
  protected final int indexOf(State state,State[] stateArray)
  {
    for (int i=0;i<stateArray.length;i++)
    {
      if (state.equals(stateArray[i]))
        return i;
    }
    return -1;
  }
 
  /**
   * Transition characters.
   *
   * @param transitionCharacterMin2 the transition character min2
   * @param transitionCharacterMax2 the transition character max2
   *
   * @return the string
   */
  protected final String transitionCharacters(char transitionCharacterMin2, char transitionCharacterMax2){
    String transString="";
    /* Deal with "don't care" transitions */
    if (transitionCharacterMin2=='\u0000' || transitionCharacterMax2=='\uffff')
      /* Deal with "don't care" transitions */
      transString=this.constrainedAlphabet.lettersToString();
    else
      /* Deal with normal transitions */
      for (char tchar2=transitionCharacterMin2;tchar2<=transitionCharacterMax2;tchar2++)
        transString=transString+tchar2;
    return transString;
  }
 
  /* (non-Javadoc)
   * @see java.lang.Object#toString()
   */
  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();
    for (int i=0;i<this.alphabetSize;i++)
    {
      for (int j=0;j<this.numOfStates;j++)
      {
        int len = this.transitionTable[i][j].length;
        if (len>0){
          builder.append("<"+this.constrainedAlphabet.decode(i)+","+j+"> [");
        }
        for (int x=0;x<len;x++)
        {
          builder.append(" " + this.transitionTable[i][j][x]);
        }
        if (len>0){
          builder.append("]\n");
        }
      }
    }
    builder.append("Starting state is: " + this.startingState + "\n");
    builder.append("Accepting states are: " + Arrays.toString(this.acceptingStates) + "\n");
   
    return builder.toString();
  }
 
  /**
   * Gets the number of states in the automaton.
   *
   * @return the number of states in the automaton.
   */
  public int getNumOfStates() {
    return numOfStates;
  }

  /**
   * Gets the alphabet size.
   *
   * @return the alphabet size
   */
  public int getAlphabetSize() {
    return alphabetSize;
  }
}
TOP

Related Classes of bgu.bio.ds.automata.TransitionTable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.