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.ExampleCoffeeMachine.Input.BUTTON;
021import static de.learnlib.examples.mealy.ExampleCoffeeMachine.Input.CLEAN;
022import static de.learnlib.examples.mealy.ExampleCoffeeMachine.Input.POD;
023import static de.learnlib.examples.mealy.ExampleCoffeeMachine.Input.WATER;
024import net.automatalib.automata.transout.MealyMachine;
025import net.automatalib.automata.transout.MutableMealyMachine;
026import net.automatalib.automata.transout.impl.compact.CompactMealy;
027import net.automatalib.words.Alphabet;
028import net.automatalib.words.impl.Alphabets;
029
030/**
031 * This example represents the Coffee Machine example from
032 * Steffen et al. "Introduction to Active Automata Learning from
033 * a Practical Perspective" (Figure 3)
034 * 
035 * @author Maik Merten <maikmerten@googlemail.com>
036 */
037public class ExampleCoffeeMachine {
038        
039        private static final class InstanceHolder {
040                public static final MealyMachine<?,Input,?,String> INSTANCE;
041                
042                static {
043                        INSTANCE = constructMachine();
044                }
045        }
046        
047        public enum Input {
048                WATER,
049                POD,
050                BUTTON,
051                CLEAN
052        }
053        
054        public final static String out_ok = "ok";
055        public final static String out_error = "error";
056        public final static String out_coffee = "coffee!";
057        
058        private final static Alphabet<Input> ALPHABET = Alphabets.fromEnum(Input.class);
059        
060        
061        public static Alphabet<Input> getInputAlphabet() {
062                return ALPHABET;
063        }
064        
065        public static MealyMachine<?,Input,?,String> getInstance() {
066                return InstanceHolder.INSTANCE;
067        }
068        
069        
070    /**
071     * Construct and return a machine representation of this example
072     * 
073     * @return a Mealy machine representing the coffee machine example
074     */   
075    public static <S,A extends MutableMealyMachine<S,Input,?,String>>
076    A constructMachine(A machine) {
077                
078                S a = machine.addInitialState(),
079                                b = machine.addState(),
080                                c = machine.addState(),
081                                d = machine.addState(),
082                                e = machine.addState(),
083                                f = machine.addState();
084                
085                machine.addTransition(a, WATER, c, out_ok);
086                machine.addTransition(a, POD, b, out_ok);
087                machine.addTransition(a, BUTTON, f, out_error);
088                machine.addTransition(a, CLEAN, a, out_ok);
089
090                machine.addTransition(b, WATER, d, out_ok);
091                machine.addTransition(b, POD, b, out_ok);
092                machine.addTransition(b, BUTTON, f, out_error);
093                machine.addTransition(b, CLEAN, a, out_ok);
094
095                machine.addTransition(c, WATER, c, out_ok);
096                machine.addTransition(c, POD, d, out_ok);
097                machine.addTransition(c, BUTTON, f, out_error);
098                machine.addTransition(c, CLEAN, a, out_ok);
099
100                machine.addTransition(d, WATER, d, out_ok);
101                machine.addTransition(d, POD, d, out_ok);
102                machine.addTransition(d, BUTTON, e, out_coffee);
103                machine.addTransition(d, CLEAN, a, out_ok);
104
105                machine.addTransition(e, WATER, f, out_error);
106                machine.addTransition(e, POD, f, out_error);
107                machine.addTransition(e, BUTTON, f, out_error);
108                machine.addTransition(e, CLEAN, a, out_ok);
109                
110                machine.addTransition(f, WATER, f, out_error);
111                machine.addTransition(f, POD, f, out_error);
112                machine.addTransition(f, BUTTON, f, out_error);
113                machine.addTransition(f, CLEAN, f, out_error);
114                
115
116        return machine;
117    }
118    
119    public static CompactMealy<Input,String> constructMachine() {
120        return constructMachine(new CompactMealy<Input,String>(ALPHABET));
121    }
122        
123}