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.automata.abstractimpl; 018 019import java.util.Collection; 020 021import net.automatalib.automata.MutableDeterministic; 022 023 024/** 025 * Abstract base class for mutable deterministic automata. 026 * 027 * @author Malte Isberner <malte.isberner@gmail.com> 028 * 029 * @param <S> state class 030 * @param <I> input symbol class 031 * @param <T> transition class 032 * @param <SP> state property class 033 * @param <TP> transition property class 034 */ 035public abstract class AbstractMutableDeterministic<S,I,T,SP,TP> extends 036 AbstractDeterministicAutomaton<S,I,T> implements 037 MutableDeterministic<S,I,T,SP,TP> { 038 039 040 /** 041 * Provides a realization of {@link MutableDeterministic#addTransition(Object, Object, Object)} 042 * using {@link MutableDeterministic#getTransition(Object, Object)} and 043 * {@link MutableDeterministic#setTransition(Object, Object, Object)}. 044 * @see MutableDeterministic#addTransition(Object, Object, Object) 045 */ 046 public static <S,I,T,SP,TP> void addTransition(MutableDeterministic<S, I, T, SP, TP> $this, 047 S state, I input, T transition) { 048 T currTrans = $this.getTransition(state, input); 049 if(currTrans != null) 050 throw new IllegalStateException("Cannot add transition " + transition 051 + " to deterministic automaton: transition already defined for state " 052 + state + " and input " + input + "."); 053 $this.setTransition(state, input, transition); 054 } 055 056 /** 057 * Provides a realization of {@link MutableDeterministic#removeTransition(Object, Object, Object)} 058 * using {@link MutableDeterministic#getTransition(Object, Object)} and 059 * {@link MutableDeterministic#setTransition(Object, Object, Object)}. 060 * @see MutableDeterministic#removeTransition(Object, Object, Object) 061 */ 062 public static <S,I,T,SP,TP> void removeTransition(MutableDeterministic<S, I, T, SP, TP> $this, 063 S state, I input, T transition) { 064 if(transition == null) 065 return; 066 T currTrans = $this.getTransition(state, input); 067 if(transition.equals(currTrans)) 068 $this.setTransition(state, input, null); 069 } 070 071 /** 072 * Provides a realization of {@link MutableDeterministic#removeAllTransitions(Object, Object)} 073 * using {@link MutableDeterministic#setTransition(Object, Object, Object)}. 074 * @see MutableDeterministic#removeAllTransitions(Object, Object) 075 */ 076 public static <S,I,T,SP,TP> void removeAllTransitions(MutableDeterministic<S,I,T,SP,TP> $this, S state, I input) { 077 $this.setTransition(state, input, null); 078 } 079 080 /** 081 * Provides a realization of {@link MutableDeterministic#setTransitions(Object, Object, Collection)} 082 * using {@link MutableDeterministic#setTransition(Object, Object, Object)} 083 * @see MutableDeterministic#setTransitions(Object, Object, Collection) 084 */ 085 public static <S,I,T,SP,TP> void setTransitions(MutableDeterministic<S,I,T,SP,TP> $this, 086 S state, I input, Collection<? extends T> transitions) { 087 088 int num = transitions.size(); 089 if(num > 1) { 090 throw new IllegalArgumentException("Deterministic automaton can not " 091 + "have multiple transitions for the same input symbol."); 092 } 093 094 T trans = (num > 0) ? transitions.iterator().next() : null; 095 096 $this.setTransition(state, input, trans); 097 } 098 099 /** 100 * Provides a realization of {@link MutableDeterministic#setTransition(Object, Object, Object, Object)} 101 * using {@link MutableDeterministic#createTransition(Object, Object)} and 102 * {@link MutableDeterministic#setTransition(Object, Object, Object)}. 103 * @see MutableDeterministic#setTransition(Object, Object, Object, Object) 104 */ 105 public static <S,I,T,SP,TP> void setTransition(MutableDeterministic<S, I, T, SP, TP> $this, 106 S state, I input, S successor, TP property) { 107 T trans = $this.createTransition(successor, property); 108 $this.setTransition(state, input, trans); 109 } 110 111 112 /** 113 * Provides a realization of {@link MutableDeterministic#setInitial(Object, boolean)} 114 * using {@link MutableDeterministic#getInitialState()} and 115 * {@link MutableDeterministic#setInitialState(Object)}. 116 * @see MutableDeterministic#setInitial(Object, boolean) 117 */ 118 public static <S,I,T,SP,TP> void setInitial(MutableDeterministic<S,I,T,SP,TP> $this, 119 S state, boolean initial) { 120 S currInitial = $this.getInitialState(); 121 if(state.equals(currInitial)) { 122 if(!initial) 123 $this.setInitialState(null); 124 } 125 else if(currInitial == null) 126 $this.setInitialState(state); 127 else 128 throw new IllegalStateException("Cannot set state '" + state + "' as " 129 + "additional initial state (current initial state: '" 130 + currInitial + "'."); 131 } 132 133 ////////////////////////////////////////////////////////////////////////////////////////////// 134 135 /* 136 * (non-Javadoc) 137 * @see net.automatalib.automata.MutableAutomaton#addTransition(java.lang.Object, java.lang.Object, java.lang.Object) 138 */ 139 @Override 140 public void addTransition(S state, I input, T transition) { 141 addTransition(this, state, input, transition); 142 } 143 144 @Override 145 public void addTransitions(S state, I input, Collection<? extends T> transitions) { 146 AbstractMutableAutomaton.addTransitions(this, state, input, transitions); 147 } 148 /* 149 * (non-Javadoc) 150 * @see net.automatalib.automata.MutableAutomaton#addTransition(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object) 151 */ 152 @Override 153 public T addTransition(S state, I input, S successor, TP property) { 154 return AbstractMutableAutomaton.addTransition(this, state, input, successor, property); 155 } 156 157 /* 158 * (non-Javadoc) 159 * @see net.automatalib.automata.MutableAutomaton#removeTransition(java.lang.Object, java.lang.Object, java.lang.Object) 160 */ 161 @Override 162 public void removeTransition(S state, I input, T transition) { 163 removeTransition(this, state, input, transition); 164 } 165 166 /* 167 * (non-Javadoc) 168 * @see net.automatalib.automata.MutableAutomaton#removeAllTransitions(java.lang.Object, java.lang.Object) 169 */ 170 @Override 171 public void removeAllTransitions(S state, I input) { 172 removeAllTransitions(this, state, input); 173 } 174 175 /* 176 * (non-Javadoc) 177 * @see net.automatalib.automata.MutableAutomaton#setInitial(java.lang.Object, boolean) 178 */ 179 @Override 180 public void setInitial(S state, boolean initial) { 181 setInitial(this, state, initial); 182 } 183 184 /* 185 * (non-Javadoc) 186 * @see net.automatalib.automata.MutableAutomaton#setTransitions(java.lang.Object, java.lang.Object, java.util.Collection) 187 */ 188 @Override 189 public void setTransitions(S state, I input, Collection<? extends T> transitions) { 190 setTransitions(this, state, input, transitions); 191 } 192 193 /* 194 * (non-Javadoc) 195 * @see net.automatalib.automata.MutableDeterministic#setTransition(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object) 196 */ 197 @Override 198 public void setTransition(S state, I input, S succ, TP properties) { 199 setTransition(this, state, input, succ, properties); 200 } 201 202 /* 203 * (non-Javadoc) 204 * @see net.automatalib.automata.MutableAutomaton#addInitialState(java.lang.Object) 205 */ 206 @Override 207 public S addInitialState(SP property) { 208 return AbstractMutableAutomaton.addInitialState(this, property); 209 } 210 211 /* 212 * (non-Javadoc) 213 * @see net.automatalib.automata.MutableAutomaton#addInitialState() 214 */ 215 @Override 216 public S addInitialState() { 217 return AbstractMutableAutomaton.addInitialState(this); 218 } 219 220 /* 221 * (non-Javadoc) 222 * @see net.automatalib.automata.MutableAutomaton#addState() 223 */ 224 @Override 225 public S addState() { 226 return AbstractMutableAutomaton.addState(this); 227 } 228}