001/* Copyright (C) 2013 TU Dortmund 002 * This file is part of AutomataLib, http://www.automatalib.net/. 003 * 004 * AutomataLib is free software; you can redistribute it and/or 005 * modify it under the terms of the GNU Lesser General Public 006 * License version 3.0 as published by the Free Software Foundation. 007 * 008 * AutomataLib is distributed in the hope that it will be useful, 009 * but WITHOUT ANY WARRANTY; without even the implied warranty of 010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 011 * Lesser General Public License for more details. 012 * 013 * You should have received a copy of the GNU Lesser General Public 014 * License along with AutomataLib; if not, see 015 * http://www.gnu.de/documents/lgpl.en.html. 016 */ 017package net.automatalib.brics; 018 019import java.util.Collection; 020import java.util.Set; 021 022import net.automatalib.automata.abstractimpl.AbstractDeterministicAutomaton; 023import net.automatalib.automata.fsa.DFA; 024import net.automatalib.automata.fsa.abstractimpl.AbstractDFA; 025import dk.brics.automaton.Automaton; 026import dk.brics.automaton.State; 027 028/** 029 * Adapter class for wrapping a Brics automaton as a {@link DFA}. 030 * <p> 031 * This adapter is backed by the Brics automaton, so changes to the {@link Automaton} 032 * are reflected. Please note that any changes which result in a loss of determinism 033 * will result in incorrect behavior exposed by this class until determinism is restored. 034 * 035 * @author Malte Isberner <malte.isberner@gmail.com> 036 * 037 */ 038public class BricsDFA extends AbstractBricsAutomaton implements 039 DFA<State, Character> { 040 041 private static Automaton requireDeterministic(Automaton aut, boolean mayDeterminize) { 042 if(aut.isDeterministic()) { 043 if(!mayDeterminize) 044 throw new IllegalArgumentException("A BricsDFA expects a deterministic automaton"); 045 aut.determinize(); 046 } 047 return aut; 048 } 049 050 /** 051 * Constructor. If the specified automaton is not deterministic, this will result 052 * in an {@link IllegalArgumentException}. 053 * @param automaton the Brics automaton to wrap. 054 */ 055 public BricsDFA(Automaton automaton) { 056 this(automaton, false); 057 } 058 059 /** 060 * Constructor. If <tt>mayDeterminize</tt> is false, this constructor behaves as the above 061 * {@link #BricsDFA(Automaton)}. Otherwise, if the specified automaton is not deterministic, 062 * it is determinized beforehand by invoking {@link Automaton#determinize()}. 063 * @param automaton the Brics automaton to wrap. 064 * @param mayDeterminize whether or not a possible nondeterministic automaton may be 065 * determinized. 066 */ 067 public BricsDFA(Automaton automaton, boolean mayDeterminize) { 068 super(requireDeterministic(automaton, mayDeterminize)); 069 } 070 071 /* 072 * (non-Javadoc) 073 * @see net.automatalib.ts.acceptors.AcceptorTS#accepts(java.lang.Iterable) 074 */ 075 @Override 076 public boolean accepts(Iterable<Character> input) { 077 return AbstractDFA.accepts(this, input); 078 } 079 080 /* 081 * (non-Javadoc) 082 * @see net.automatalib.ts.simple.SimpleDTS#getInitialState() 083 */ 084 @Override 085 public State getInitialState() { 086 return automaton.getInitialState(); 087 } 088 089 /* 090 * (non-Javadoc) 091 * @see net.automatalib.ts.simple.SimpleDTS#getSuccessor(java.lang.Object, java.lang.Object) 092 */ 093 @Override 094 public State getSuccessor(State state, Character input) { 095 return state.step(input.charValue()); 096 } 097 098 /* 099 * (non-Javadoc) 100 * @see net.automatalib.ts.simple.SimpleDTS#getSuccessor(java.lang.Object, java.lang.Iterable) 101 */ 102 @Override 103 public State getSuccessor(State state, Iterable<Character> input) { 104 return AbstractDeterministicAutomaton.getSuccessor(this, state, input); 105 } 106 107 /* 108 * (non-Javadoc) 109 * @see net.automatalib.ts.simple.SimpleDTS#getState(java.lang.Iterable) 110 */ 111 @Override 112 public State getState(Iterable<Character> input) { 113 return AbstractDeterministicAutomaton.getState(this, input); 114 } 115 116 /* 117 * (non-Javadoc) 118 * @see net.automatalib.ts.DeterministicTransitionSystem#getTransition(java.lang.Object, java.lang.Object) 119 */ 120 @Override 121 public State getTransition(State state, Character input) { 122 return state.step(input.charValue()); 123 } 124 125 /* 126 * (non-Javadoc) 127 * @see net.automatalib.brics.AbstractBricsAutomaton#getTransitions(dk.brics.automaton.State, java.lang.Character) 128 */ 129 @Override 130 public Collection<State> getTransitions(State state, Character input) { 131 return AbstractDeterministicAutomaton.getTransitions(this, state, input); 132 } 133 134 /* 135 * (non-Javadoc) 136 * @see net.automatalib.ts.abstractimpl.AbstractTS#getSuccessors(java.lang.Object, java.lang.Object) 137 */ 138 @Override 139 public Set<State> getSuccessors(State state, Character input) { 140 return AbstractDeterministicAutomaton.getSuccessors(this, state, input); 141 } 142 143 144}