package rationals; import java.lang.reflect.Array; import java.util.BitSet; import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; /** * This class is used by Automaton objects to create new states on A user can * implement its own version of StateFactory by providing an implementation for * createState * * @author Arnaud.Bailly - bailly@lifl.fr * @version Thu Apr 25 2002 */ public class DefaultStateFactory implements StateFactory, Cloneable { public class DefaultState implements State { public final int i; boolean initial; boolean terminal; Automaton a; DefaultState(int i, boolean initial, boolean terminal) { this.i = i; this.a = automaton; this.initial = initial; this.terminal = terminal; } /* * (non-Javadoc) * * @see salvo.jesus.graph.Vertex#getObject() */ public Object getObject() { return new Integer(i); } /* * (non-Javadoc) * * @see salvo.jesus.graph.Vertex#setObject(java.lang.Object) */ public void setObject(Object object) { /* NOOP */ } /* * (non-Javadoc) * * @see rationals.State#setInitial(boolean) */ public State setInitial(boolean initial) { this.initial = initial; if(initial) a.initials().add(this); else a.initials().remove(this); return this; } /* * (non-Javadoc) * * @see rationals.State#setTerminal(boolean) */ public State setTerminal(boolean terminal) { this.terminal = terminal; if(terminal) a.terminals().add(this); else a.terminals().remove(this); return this; } /* * (non-Javadoc) * * @see rationals.State#isInitial() */ public boolean isInitial() { return this.initial; } /* * (non-Javadoc) * * @see rationals.State#isTerminal() */ public boolean isTerminal() { return this.terminal; } public String toString() { return Integer.toString(i); } public boolean equals(Object o) { try { DefaultState ds = (DefaultState) o; return (ds.i == i) && (a == ds.a); } catch (ClassCastException e) { return false; } } public int hashCode() { return i; } } class DefaultStateSet implements Set { private DefaultStateFactory df; /** * @param set */ public DefaultStateSet(DefaultStateSet set, DefaultStateFactory df) { this.bits = (BitSet) set.bits.clone(); this.df = df; } /** * */ public DefaultStateSet(DefaultStateFactory df) { this.df = df; } public boolean equals(Object obj) { DefaultStateSet dss = (DefaultStateSet) obj; return (dss == null) ? false : (dss.bits.equals(bits) && dss.df == df); } public int hashCode() { return bits.hashCode(); } public String toString() { StringBuffer sb = new StringBuffer(); sb.append('['); String b = bits.toString(); sb.append(b.substring(1, b.length() - 1)); sb.append(']'); return sb.toString(); } int modcount = 0; int mods = 0; int bit = -1; BitSet bits = new BitSet(); Iterator it = new Iterator() { public void remove() { if (bit > 0) bits.clear(bit); } public boolean hasNext() { return bits.nextSetBit(bit) > -1; } public Object next() { bit = bits.nextSetBit(bit); if (bit == -1) throw new NoSuchElementException(); DefaultState ds = new DefaultState(bit, false, false); ds.initial = automaton.initials().contains(ds); ds.terminal = automaton.terminals().contains(ds); mods++; modcount++; if (mods != modcount) throw new ConcurrentModificationException(); /* advance iterator */ bit++; return ds; } }; /* * (non-Javadoc) * * @see java.util.Set#size() */ public int size() { return bits.cardinality(); } /* * (non-Javadoc) * * @see java.util.Set#clear() */ public void clear() { modcount++; bits.clear(); } /* * (non-Javadoc) * * @see java.util.Set#isEmpty() */ public boolean isEmpty() { return bits.isEmpty(); } /* * (non-Javadoc) * * @see java.util.Set#toArray() */ public Object[] toArray() { Object[] ret = new Object[size()]; Iterator it = iterator(); int i = 0; while (it.hasNext()) { ret[i++] = it.next(); } return ret; } /* * (non-Javadoc) * * @see java.util.Set#add(java.lang.Object) */ public boolean add(Object o) { DefaultState ds = (DefaultState) o; if (bits.get(ds.i)) return false; bits.set(ds.i); modcount++; return true; } /* * (non-Javadoc) * * @see java.util.Set#contains(java.lang.Object) */ public boolean contains(Object o) { DefaultState ds = (DefaultState) o; return bits.get(ds.i); } /* * (non-Javadoc) * * @see java.util.Set#remove(java.lang.Object) */ public boolean remove(Object o) { DefaultState ds = (DefaultState) o; if (!bits.get(ds.i)) return false; bits.clear(ds.i); modcount++; return true; } /* * (non-Javadoc) * * @see java.util.Set#addAll(java.util.Collection) */ public boolean addAll(Collection c) { DefaultStateSet dss = (DefaultStateSet) c; bits.or(dss.bits); modcount++; return true; } /* * (non-Javadoc) * * @see java.util.Set#containsAll(java.util.Collection) */ public boolean containsAll(Collection c) { DefaultStateSet dss = (DefaultStateSet) c; BitSet bs = new BitSet(); bs.or(bits); bs.and(dss.bits); modcount++; return bs.equals(dss.bits); } /* * (non-Javadoc) * * @see java.util.Set#removeAll(java.util.Collection) */ public boolean removeAll(Collection c) { DefaultStateSet dss = (DefaultStateSet) c; bits.andNot(dss.bits); modcount++; return true; } /* * (non-Javadoc) * * @see java.util.Set#retainAll(java.util.Collection) */ public boolean retainAll(Collection c) { DefaultStateSet dss = (DefaultStateSet) c; bits.and(dss.bits); modcount++; return true; } /* * (non-Javadoc) * * @see java.util.Set#iterator() */ public Iterator iterator() { /* reset iterator */ bit = modcount = mods = 0; return it; } /* * (non-Javadoc) * * @see java.util.Set#toArray(java.lang.Object[]) */ public Object[] toArray(Object[] a) { Object[] ret; if (a.length == size()) ret = a; else { /* create array dynamically */ ret = (Object[]) Array.newInstance(a.getClass().getComponentType(), size()); } Iterator it = iterator(); int i = 0; while (it.hasNext()) { DefaultState ds = (DefaultState) it.next(); ret[ds.i] = ds; } return ret; } } // ////////////////////////////////////////////////////// // FIELDS // ///////////////////////////////////////////////////// protected int id = 0; Automaton automaton; // ////////////////////////////////////////////////////// // PUBLIC METHODS // ///////////////////////////////////////////////////// DefaultStateFactory(Automaton a) { this.automaton = a; } /** * Creates a new state which is initial and terminal or not, depending on the * value of parameters. * * @param initial * if true, this state will be initial; otherwise this state will be * non initial. * @param terminal * if true, this state will be terminal; otherwise this state will be * non terminal. */ public State create(boolean initial, boolean terminal) { return new DefaultState(id++, initial, terminal); } /* * (non-Javadoc) * * @see rationals.StateFactory#stateSet() */ public Set stateSet() { return new DefaultStateSet(this); } /* * (non-Javadoc) * * @see rationals.StateFactory#stateSet(java.util.Set) */ public Set stateSet(Set s) { return new DefaultStateSet((DefaultStateSet) s, this); } public Object clone() { DefaultStateFactory cl; try { cl = (DefaultStateFactory) super.clone(); } catch (CloneNotSupportedException e) { cl = null; } cl.id = 0; return cl; } /* * (non-Javadoc) * * @see rationals.StateFactory#setAutomaton(rationals.Automaton) */ public void setAutomaton(Automaton automaton) { this.automaton = automaton; } }