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 de.learnlib.examples.mealy;
018
019import net.automatalib.automata.transout.MutableMealyMachine;
020import net.automatalib.automata.transout.impl.compact.CompactMealy;
021import net.automatalib.words.Alphabet;
022import net.automatalib.words.impl.Alphabets;
023
024/**
025 * This class generates a Mealy machine consisting of a two-dimensional grid of
026 * states. Each transition has unique output.
027 *
028 * @author Maik Merten <maikmerten@googlemail.com>
029 */
030public class ExampleGrid {
031
032    private final static Alphabet<Character> ALPHABET = Alphabets.characters('x', 'y');
033    
034    public static Alphabet<Character> getInputAlphabet() {
035        return ALPHABET;
036    }
037    
038
039    /**
040     * Construct and return a machine representation of this example
041     * 
042     * @param xsize number of states in x direction
043     * @param ysize number of states in y direction
044     * @return a Mealy machine with (xsize * ysize) states
045     */
046    @SuppressWarnings("unchecked")
047    public static <S,A extends MutableMealyMachine<S,Character,?,Integer>>
048    A constructMachine(A fm, int xsize, int ysize) {
049
050        // create 2D grid of states
051        S[][] stategrid
052                = (S[][])new Object[xsize][ysize];
053        for (int x = 0; x < xsize; ++x) {
054            for (int y = 0; y < ysize; ++y) {
055                stategrid[x][y] = (x == 0 && y == 0) ? fm.addInitialState() : fm.addState();
056            }
057        }
058
059        // create transitions with unique output
060        int output = 0;
061        for (int x = 0; x < xsize; ++x) {
062            for (int y = 0; y < ysize; ++y) {
063                // determine successor states in x and y direction
064                int succ_x = x < (xsize - 1) ? x + 1 : x;
065                int succ_y = y < (ysize - 1) ? y + 1 : y;
066
067                // transition in x direction
068                fm.addTransition(stategrid[x][y], 'x', stategrid[succ_x][y], output++);
069                // transition in y direction
070                fm.addTransition(stategrid[x][y], 'y', stategrid[x][succ_y], output++);
071            }
072        }
073
074        return fm;
075    }
076    
077    public static CompactMealy<Character, Integer> constructMachine(int xsize, int ysize) {
078        return constructMachine(new CompactMealy<Character,Integer>(ALPHABET), xsize, ysize);
079    }
080}