edu.stanford.nlp.fsm.DFSA Maven / Gradle / Ivy
package edu.stanford.nlp.fsm;
import edu.stanford.nlp.util.Scored;
import java.io.IOException;
import java.io.Writer;
import java.util.*;
/**
* DFSA: A class for representing a deterministic finite state automaton
* without epsilon transitions.
*
* @author Dan Klein
* @author Michel Galley (AT&T FSM library format printing)
* @author Sarah Spikes ([email protected]) - cleanup and filling in types
*/
public final class DFSA implements Scored {
Object dfsaID;
DFSAState initialState;
public DFSA(DFSAState initialState, double score) {
this.initialState = initialState;
this.score = score;
}
public DFSA(DFSAState initialState) {
this.initialState = initialState;
this.score = Double.NaN;
}
public double score;
public double score() {
return score;
}
public DFSAState initialState() {
return initialState;
}
public void setInitialState(DFSAState initialState) {
this.initialState = initialState;
}
public Set> states() {
Set> visited = new HashSet>();
List> toVisit = new ArrayList>();
toVisit.add(initialState());
exploreStates(toVisit, visited);
return visited;
}
private static void exploreStates(List> toVisit, Set> visited) {
while (!toVisit.isEmpty()) {
DFSAState state = toVisit.get(toVisit.size() - 1);
toVisit.remove(toVisit.size() - 1);
if (!visited.contains(state)) {
toVisit.addAll(state.successorStates());
visited.add(state);
}
}
}
public DFSA(Object dfsaID) {
this.dfsaID = dfsaID;
this.score = 0;
}
private static void printTrieDFSAHelper(DFSAState state, int level) {
if (state.isAccepting()) {
return;
}
Set inputs = state.continuingInputs();
for (T input : inputs) {
DFSATransition transition = state.transition(input);
System.out.print(level);
System.out.print(input);
for (int i = 0; i < level; i++) {
System.out.print(" ");
}
System.out.print(transition.score());
System.out.print(" ");
System.out.println(input);
printTrieDFSAHelper(transition.target(), level + 1);
}
}
public static void printTrieDFSA(DFSA dfsa) {
System.err.println("DFSA: " + dfsa.dfsaID);
printTrieDFSAHelper(dfsa.initialState(), 2);
}
public void printAttFsmFormat(Writer w) throws IOException {
Queue> q = new LinkedList>();
Set> visited = new HashSet>();
q.offer(initialState);
while(q.peek() != null) {
DFSAState state = q.poll();
if(state == null || visited.contains(state))
continue;
visited.add(state);
if (state.isAccepting()) {
w.write(state.toString()+"\t"+state.score()+"\n");
continue;
}
TreeSet inputs = new TreeSet(state.continuingInputs());
for (T input : inputs) {
DFSATransition transition = state.transition(input);
DFSAState target = transition.target();
if(!visited.contains(target))
q.add(target);
w.write(state.toString()+"\t"+target.toString()+"\t"+transition.getInput()+"\t"+transition.score()+"\n");
}
}
}
private static void printTrieAsRulesHelper(DFSAState state, String prefix, Writer w) throws IOException {
if (state.isAccepting()) {
return;
}
Set inputs = state.continuingInputs();
for (T input : inputs) {
DFSATransition transition = state.transition(input);
DFSAState target = transition.target();
Set inputs2 = target.continuingInputs();
boolean allTerminate = true;
for (T input2 : inputs2) {
DFSATransition transition2 = target.transition(input2);
DFSAState target2 = transition2.target();
if (target2.isAccepting()) {
// it's a binary end rule. Print it.
w.write(prefix + " --> " + input + " " + input2 + "\n");
} else {
allTerminate = false;
}
}
if (!allTerminate) {
// there are some longer continuations. Print continuation rule
String newPrefix = prefix + "_" + input;
w.write(prefix + " --> " + input + " " + newPrefix + "\n");
printTrieAsRulesHelper(transition.target(), newPrefix, w);
}
}
}
public static void printTrieAsRules(DFSA dfsa, Writer w) throws IOException {
printTrieAsRulesHelper(dfsa.initialState(), dfsa.dfsaID.toString(), w);
}
}