![JAR search and dependency download from the Maven repository](/logo.png)
rationals.BinaryAutomaton Maven / Gradle / Ivy
Show all versions of org.semanticweb.hermit Show documentation
/*______________________________________________________________________________
*
* Copyright 2005 Arnaud Bailly - NORSYS/LIFL
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* (1) Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* (2) Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* (3) The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Created on 22 juin 2005
*
*/
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;
import rationals.DefaultStateFactory.DefaultState;
/**
* A specialization of Automaton for handling two letters alphabets.
*
* A binary automaton is just an ordinary finite states automaton with an
* alphabet of two elements. A binary automaton may not contain
* epsilon
transitions but may be non-deterministic.
*
* This implementation uses bitset matrices for handling transitions with an
* expected increase in efficiency and decrease in size of automata.
*
* @author nono
* @version $Id: BinaryAutomaton.java 2 2006-08-24 14:41:48Z oqube $
*/
public class BinaryAutomaton extends Automaton {
private Object one;
private Object zero;
// array of transitions
private BitSet[][] trans;
private BitSet[][] reverse;
// next index to use in trans
private int idx;
/**
* This class implements Set for Transition objects which are computed on
* the fly from an array of bitsets.
*
* @author nono
* @version $Id: BinaryAutomaton.java 2 2006-08-24 14:41:48Z oqube $
*/
class TransitionSet implements Set {
private BitSet from;
private BitSet[][] trans;
private BitSet bits;
/**
* @param fromSet
* the set of states indices to take into account
* @param trans the set of transitions
*/
public TransitionSet(BitSet fromSet,BitSet[][] trans) {
this.from = fromSet;
this.trans = trans;
}
public boolean equals(Object obj) {
TransitionSet ts = (TransitionSet) obj;
return (ts == null) ? false
: (ts.from.equals(from) && ts.trans == trans);
}
public int hashCode() {
return from.hashCode() << 9 ^trans.hashCode() ;
}
public String toString() {
return super.toString();
}
private int modcount = 0;
private int mods = 0;
private int frombit = -1;
private int tobit = -1;
private int lblbit = -1;
private Iterator it = new Iterator() {
/*
* (non-Javadoc)
* @see java.util.Iterator#remove()
*/
public void remove() {
// NOT IMPLEMENTED
}
public boolean hasNext() {
return from.nextSetBit(frombit) > -1 ;
}
public Object next() {
frombit = from.nextSetBit(frombit);
if (frombit == -1)
throw new NoSuchElementException();
mods++;
modcount++;
if (mods != modcount)
throw new ConcurrentModificationException();
// construct transition
DefaultStateFactory.DefaultState from = null;/*getStateFactory().new DefaultStateFactory.DefaultState(frombit,false,false);*/
from.initial = BinaryAutomaton.this.initials().contains(from);
from.terminal = BinaryAutomaton.this.terminals().contains(from);
DefaultStateFactory.DefaultState to = null; /*new DefaultStateFactory.DefaultState(tobit,false,false);*/
to.initial = BinaryAutomaton.this.initials().contains(to);
to.terminal = BinaryAutomaton.this.terminals().contains(to);
Transition tr = new Transition(from,lblbit == 1 ? one : zero,to);
/* advance iterator */
//bit++;
return tr;
}
};
/*
* (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) {
return false;
}
/*
* (non-Javadoc)
*
* @see java.util.Set#containsAll(java.util.Collection)
*/
public boolean containsAll(Collection c) {
return false;
}
/*
* (non-Javadoc)
*
* @see java.util.Set#removeAll(java.util.Collection)
*/
public boolean removeAll(Collection c) {
return false;
}
/*
* (non-Javadoc)
*
* @see java.util.Set#retainAll(java.util.Collection)
*/
public boolean retainAll(Collection c) {
return false;
}
/*
* (non-Javadoc)
*
* @see java.util.Set#iterator()
*/
public Iterator iterator() {
/* reset iterator */
frombit = 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;
}
}
/**
* Construct a binary automaton with given objects as zero and one.
*
* This objects may then be passed in Transition objects labels. Note that
* equality is tested using ==
, not method
* equals()
. This means that a reference must be kept by the
* caller or methods {@see #zero()}and {@see #one()}may later be called.
* This also means that one of the object may be null
.
*
* The two parameters must be different in the sense of == operator.
*
* @param one
* the Object in transitions labels denoting one
* @param zero
* the Object in transitions labels denoting zero
*/
public BinaryAutomaton(Object one, Object zero) {
if (one == zero)
throw new IllegalArgumentException("Labels may not be identical");
this.one = one;
this.zero = zero;
// ensure factory is default state factory
setStateFactory(new DefaultStateFactory(this));
// make initial trans array
trans = new BitSet[0][0];
reverse = new BitSet[0][0];
alphabet.add(one);
alphabet.add(zero);
idx = 0;
}
public BinaryAutomaton() {
this(null, new Object());
}
/*
* (non-Javadoc)
*
* @see rationals.Rational#accessibleAndCoAccessibleStates()
*/
public Set accessibleAndCoAccessibleStates() {
// TODO Auto-generated method stub
return super.accessibleAndCoAccessibleStates();
}
/*
* (non-Javadoc)
*
* @see rationals.Rational#accessibleStates()
*/
public Set accessibleStates() {
// TODO Auto-generated method stub
return super.accessibleStates();
}
/*
* (non-Javadoc)
*
* @see rationals.Rational#accessibleStates(java.util.Set)
*/
public Set accessibleStates(Set states) {
// TODO Auto-generated method stub
return super.accessibleStates(states);
}
/*
* (non-Javadoc)
*
* @see rationals.Rational#accessibleStates(rationals.State)
*/
public Set accessibleStates(State state) {
// TODO Auto-generated method stub
return super.accessibleStates(state);
}
/*
* (non-Javadoc)
*
* @see rationals.Rational#addState(boolean, boolean)
*/
public State addState(boolean initial, boolean terminal) {
DefaultStateFactory.DefaultState st = (DefaultStateFactory.DefaultState) super
.addState(initial, terminal);
// add a new row to the matrix
idx = st.i;
BitSet[][] ntr = new BitSet[idx + 1][];
System.arraycopy(trans, 0, ntr, 0, idx);
ntr[idx] = new BitSet[2];
ntr[idx][0] = new BitSet();
ntr[idx][1] = new BitSet();
trans = ntr;
// do the same for reverse
ntr = new BitSet[idx + 1][];
System.arraycopy(reverse, 0, ntr, 0, idx);
ntr[idx] = new BitSet[2];
ntr[idx][0] = new BitSet();
ntr[idx][1] = new BitSet();
reverse = ntr;
return st;
}
/*
* (non-Javadoc)
*
* @see rationals.Rational#addTransition(rationals.Transition)
*/
public void addTransition(Transition transition)
throws NoSuchStateException {
// extract states' indices
DefaultStateFactory.DefaultState from = (DefaultStateFactory.DefaultState) transition
.start();
DefaultStateFactory.DefaultState to = (DefaultStateFactory.DefaultState) transition
.end();
int i = transition.label() == one ? 1
: (transition.label() == zero) ? 0 : -1;
if (i == -1)
throw new IllegalArgumentException(
"Bad transition label for binary automaton");
// update transition matrix
try {
trans[from.i][i].set(to.i);
reverse[to.i][i].set(from.i);
} catch (ArrayIndexOutOfBoundsException e) {
throw new NoSuchStateException("Invalid from or to state in "
+ transition);
}
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#clone()
*/
public Object clone() {
// TODO Auto-generated method stub
return super.clone();
}
/*
* (non-Javadoc)
*
* @see rationals.Rational#delta()
*/
public Set delta() {
// TODO Auto-generated method stub
return super.delta();
}
/*
* (non-Javadoc)
*
* @see rationals.StateMachine#delta(java.util.Set)
*/
public Set delta(Set s) {
// TODO Auto-generated method stub
return super.delta(s);
}
/*
* (non-Javadoc)
*
* @see rationals.Rational#delta(rationals.State, java.lang.Object)
*/
public Set delta(State state, Object label) {
// TODO Auto-generated method stub
return super.delta(state, label);
}
/*
* (non-Javadoc)
*
* @see rationals.Rational#delta(rationals.State)
*/
public Set delta(State state) {
// TODO Auto-generated method stub
return super.delta(state);
}
/*
* (non-Javadoc)
*
* @see rationals.Rational#deltaFrom(rationals.State, rationals.State)
*/
public Set deltaFrom(State from, State to) {
// TODO Auto-generated method stub
return super.deltaFrom(from, to);
}
/*
* (non-Javadoc)
*
* @see rationals.Rational#deltaMinusOne(rationals.State, java.lang.Object)
*/
public Set deltaMinusOne(State state, Object label) {
// TODO Auto-generated method stub
return super.deltaMinusOne(state, label);
}
/*
* (non-Javadoc)
*
* @see rationals.Rational#deltaMinusOne(rationals.State)
*/
public Set deltaMinusOne(State st) {
// TODO Auto-generated method stub
return super.deltaMinusOne(st);
}
// ACCESSORS
public Object getOne() {
return one;
}
public void setOne(Object one) {
this.one = one;
}
public Object getZero() {
return zero;
}
public void setZero(Object zero) {
this.zero = zero;
}
}