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;
020import java.util.Collections;
021import java.util.HashSet;
022import java.util.Set;
023
024import net.automatalib.automata.MutableAutomaton;
025
026
027/**
028 * Abstract base class for mutable automata.
029 * 
030 * @author Malte Isberner <malte.isberner@gmail.com>
031 *
032 * @param <S> state class
033 * @param <I> input symbol class
034 * @param <T> transition class
035 * @param <SP> state property class
036 * @param <TP> transition property class
037 */
038public abstract class AbstractMutableAutomaton<S, I, T,SP,TP> extends AbstractAutomaton<S,I,T>
039                implements MutableAutomaton<S,I,T,SP,TP> {
040
041        
042        /**
043         * Provides a realization of {@link MutableAutomaton#addInitialState(Object)} using
044         * {@link MutableAutomaton#addState(Object)} and {@link MutableAutomaton#setInitial(Object, boolean)}.
045         * @see MutableAutomaton#addInitialState(Object)
046         */
047        public static <S,I,T,SP,TP> S addInitialState(MutableAutomaton<S, I, T, SP, TP> $this, SP property) {
048                S state = $this.addState(property);
049                $this.setInitial(state, true);
050                return state;
051        }
052        
053        /**
054         * Provides a realization of {@link MutableAutomaton#addInitialState()} using
055         * {@link MutableAutomaton#addInitialState(Object)}.
056         * @see MutableAutomaton#addInitialState()
057         */
058        public static <S,I,T,SP,TP> S addInitialState(MutableAutomaton<S,I,T,SP,TP> $this) {
059                return $this.addInitialState(null);
060        }
061        
062        /**
063         * Provides a realization of {@link MutableAutomaton#addState()} using
064         * {@link MutableAutomaton#addState(Object)}.
065         * @see MutableAutomaton#addState()
066         */
067        public static <S,I,T,SP,TP> S addState(MutableAutomaton<S,I,T,SP,TP> $this) {
068                return $this.addState(null);
069        }
070        
071        /**
072         * Provides a realization of {@link MutableAutomaton#addTransition(Object, Object, Object)}
073         * using {@link MutableAutomaton#getTransitions(Object, Object)} and
074         * {@link MutableAutomaton#setTransitions(Object, Object, java.util.Collection)}.
075         * @see MutableAutomaton#addTransition(Object, Object, Object)
076         */
077        public static <S,I,T,SP,TP> void addTransition(MutableAutomaton<S, I, T, SP, TP> $this, S state, I input, T transition) {
078                Set<T> transitions = new HashSet<T>($this.getTransitions(state, input));
079                if(!transitions.add(transition))
080                        return;
081                $this.setTransitions(state, input, transitions);
082        }
083        
084        public static <S,I,T,SP,TP> void addTransitions(MutableAutomaton<S,I,T,SP,TP> $this, S state, I input, Collection<? extends T> transitions) {
085                Set<T> oldTransitions = new HashSet<T>($this.getTransitions(state, input));
086                if(!oldTransitions.addAll(transitions))
087                        return;
088                $this.setTransitions(state, input, transitions);
089        }
090        
091        /**
092         * Provides a realization of {@link MutableAutomaton#addTransition(Object, Object, Object, Object)}
093         * using {@link MutableAutomaton#createTransition(Object, Object)} and
094         * {@link MutableAutomaton#addTransition(Object, Object, Object)}.
095         * @see MutableAutomaton#addTransition(Object, Object, Object, Object)
096         */
097        public static <S,I,T,SP,TP> T addTransition(MutableAutomaton<S, I, T, SP, TP> $this,
098                        S state, I input, S succ, TP property) {
099                T trans = $this.createTransition(succ, property);
100                $this.addTransition(state, input, trans);
101                return trans;
102        }
103        
104        /**
105         * Provides a realization of {@link MutableAutomaton#removeTransition(Object, Object, Object)}
106         * using {@link MutableAutomaton#getTransitions(Object, Object)} and
107         * {@link MutableAutomaton#setTransitions(Object, Object, java.util.Collection)}
108         * @see MutableAutomaton#removeTransition(Object, Object, Object)
109         */
110        public static <S,I,T,SP,TP> void removeTransition(MutableAutomaton<S, I, T, SP, TP> $this, S state, I input, T transition) {
111                Set<T> transitions = new HashSet<T>($this.getTransitions(state, input));
112                if(!transitions.remove(transition))
113                        return;
114                $this.setTransitions(state, input, transitions);
115        }
116        
117        /**
118         * Provides a realization of {@link MutableAutomaton#removeAllTransitions(Object, Object)}
119         * using {@link MutableAutomaton#setTransitions(Object, Object, java.util.Collection)}
120         */
121        public static <S,I,T,SP,TP> void removeAllTransitions(MutableAutomaton<S,I,T,SP,TP> $this, S state, I input) {
122                $this.setTransitions(state, input, Collections.<T>emptySet());
123        }
124        
125        //////////////////////////////////////////////////////////////////////////////////////////////
126
127        /*
128         * (non-Javadoc)
129         * @see net.automatalib.automata.MutableAutomaton#removeTransition(java.lang.Object, java.lang.Object, java.lang.Object)
130         */
131        @Override
132        public void removeTransition(S state, I input, T transition) {
133                removeTransition(this, state, input, transition);
134        }
135        
136        /*
137         * (non-Javadoc)
138         * @see net.automatalib.automata.MutableAutomaton#removeAllTransitions(java.lang.Object, java.lang.Object)
139         */
140        @Override
141        public void removeAllTransitions(S state, I input) {
142                removeAllTransitions(this, state, input);
143        }
144        
145        /*
146         * (non-Javadoc)
147         * @see net.automatalib.automata.MutableAutomaton#addTransition(java.lang.Object, java.lang.Object, java.lang.Object)
148         */
149        @Override
150        public void addTransition(S state, I input, T transition) {
151                addTransition(this, state, input, transition);
152        }
153        
154        /*
155         * (non-Javadoc)
156         * @see net.automatalib.automata.MutableAutomaton#addTransitions(java.lang.Object, java.lang.Object, java.util.Collection)
157         */
158        @Override
159        public void addTransitions(S state, I input, Collection<? extends T> transitions) {
160                addTransitions(this, state, input, transitions);
161        }
162
163        /*
164         * (non-Javadoc)
165         * @see net.automatalib.automata.MutableAutomaton#addTransition(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object)
166         */
167        @Override
168        public T addTransition(S state, I input, S successor, TP properties) {
169                return addTransition(this, state, input, successor, properties);
170        }
171        
172        /*
173         * (non-Javadoc)
174         * @see net.automatalib.automata.MutableAutomaton#addInitialState(java.lang.Object)
175         */
176        @Override
177        public S addInitialState(SP property) {
178                return addInitialState(this, property);
179        }
180        
181        /*
182         * (non-Javadoc)
183         * @see net.automatalib.automata.MutableAutomaton#addState()
184         */
185        @Override
186        public S addState() {
187                return addState(this);
188        }
189        
190        /*
191         * (non-Javadoc)
192         * @see net.automatalib.automata.MutableAutomaton#addInitialState()
193         */
194        @Override
195        public S addInitialState() {
196                return addInitialState(this);
197        }
198}