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 */
017
018package de.learnlib.examples.mealy;
019
020import static de.learnlib.examples.mealy.ExampleStack.Input.POP;
021import static de.learnlib.examples.mealy.ExampleStack.Input.PUSH;
022import static de.learnlib.examples.mealy.ExampleStack.Output.EMPTY;
023import static de.learnlib.examples.mealy.ExampleStack.Output.FULL;
024import static de.learnlib.examples.mealy.ExampleStack.Output.OK;
025import net.automatalib.automata.transout.MealyMachine;
026import net.automatalib.automata.transout.MutableMealyMachine;
027import net.automatalib.automata.transout.impl.compact.CompactMealy;
028import net.automatalib.words.Alphabet;
029import net.automatalib.words.impl.Alphabets;
030
031/**
032 * This example encodes a small stack with a capacity of three elements
033 * and "push" and "pop" operations as Mealy machine. Outputs are
034 * "ok", "empty" and "full".
035 * 
036 * @author Maik Merten <maikmerten@googlemail.com>
037 */
038public class ExampleStack {
039        private static final class InstanceHolder {
040                public static final MealyMachine<?,Input,?,Output> INSTANCE;
041                
042                static {
043                        INSTANCE = constructMachine();
044                }
045        }
046        
047        public enum Input {
048                PUSH,
049                POP
050        }
051        
052        public enum Output {
053                OK,
054                EMPTY,
055                FULL
056        }
057
058    
059    private final static Alphabet<Input> ALPHABET = Alphabets.fromEnum(Input.class); 
060    
061    
062    public static Alphabet<Input> getInputAlphabet() {
063        return ALPHABET;
064    }
065    
066    public static MealyMachine<?,Input,?,Output> getInstance() {
067        return InstanceHolder.INSTANCE;
068    }
069    
070    /**
071     * Construct and return a machine representation of this example
072     * 
073     * @return machine instance of the example
074     */
075    public static <S,A extends MutableMealyMachine<S,Input,?,Output>> 
076    A constructMachine(A fm) {
077        S s0 = fm.addInitialState(),
078                s1 = fm.addState(),
079                s2 = fm.addState(),
080                s3 = fm.addState();
081        
082        fm.addTransition(s0, PUSH, s1, OK);
083        fm.addTransition(s0, POP, s0, EMPTY);
084        
085        fm.addTransition(s1, PUSH, s2, OK);
086        fm.addTransition(s1, POP, s0, OK);
087        
088        fm.addTransition(s2, PUSH, s3, OK);
089        fm.addTransition(s2, POP, s1, OK);
090        
091        fm.addTransition(s3, PUSH, s3, FULL);
092        fm.addTransition(s3, POP, s2, OK);
093        
094        return fm;
095    }
096    
097    public static CompactMealy<Input, Output> constructMachine() {
098        return constructMachine(new CompactMealy<Input,Output>(ALPHABET));
099    }
100    
101}