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