예제 #1
0
        // This constructor creates a Turing machine definition. The arguments are:
        // (Note: We use "symbol" and "letter" as synonims.)
        // - the tape alphabet size (int, >= 1)
        // - a blank symbol (>= 0, <(alphabet size))
        // - the set of letters that are part of the input alphabet, subset of the tape alphabet,
        //   it is an array of bools of length = alphabet size. The blank symbol
        //   must not be part of the input alphabet. newMachineInputAlphabet[a] contains
        //   true of false whether or not letter a is part of the input alphabet.
        // - the number of states (int, >= 1)
        // - an initial state (>= 0, <(number of states))
        // - a transition matrix, with lines being states, 3 columns beeing one letter and content being
        //   the new state, the new letter and the direction.
        //   ie. newMachinesTransitions[s1,3*a] = s2 means that when the machine is in state s1
        //   and reads letter a, it goes in state s2. Special values -1 and -2 respectively mean
        //   reject and accept.
        //   newMachinesTransitions[s1,3*a+1] = a2 means the written letter is a2
        //   newMachinesTransitions[s1,3*a+2] = d means the machine will go in direction d
        //   with 0 beeing "don't move", 1 beeing "go one step right", and 2 beeing "go one step left".
        public TuringMachineDefinitionById(int newMachineTapeAlphabetSize,
                                           int newMachineBlankSymbol,
                                           FrozenVector <bool> newMachineInputAlphabet,
                                           int newMachineNumberOfStates,
                                           int newMachineInitialState,
                                           FrozenMatrix <int> newMachineTransitionMatrix)
        {
            /* Store tape alphabet size. */
            if (!(newMachineTapeAlphabetSize >= 1))
            {
                throw new TuringMachineException("Tape alphabet size should be >= 1, but it is " + newMachineTapeAlphabetSize);
            }
            tapeAlphabetSize = newMachineTapeAlphabetSize;



            /* Now check and store the blank symbol.. */
            if (!(newMachineBlankSymbol >= 0 && newMachineBlankSymbol < tapeAlphabetSize))
            {
                throw new TuringMachineException("Blank symbol ("
                                                 + newMachineBlankSymbol
                                                 + ") is out of range. It should be in [0,"
                                                 + tapeAlphabetSize
                                                 + "[");
            }
            blank = newMachineBlankSymbol;



            /* Chack and store input alphabet. */
            if (newMachineInputAlphabet != null)
            {
                if (newMachineInputAlphabet.Length != newMachineTapeAlphabetSize)
                {
                    throw new TuringMachineException("Given input alphabet vector length ("
                                                     + newMachineInputAlphabet.Length
                                                     + ") should equal tape alphabet size ("
                                                     + tapeAlphabetSize
                                                     + ").");
                }
                if (newMachineInputAlphabet[newMachineBlankSymbol])
                {
                    throw new TuringMachineException("Blank symbol must not be part of input alphabet.");
                }
                inputAlphabet = newMachineInputAlphabet;
            }
            else
            {
                // All but the blank symbol.
                var inputAlphabetTempMatrix = new bool[tapeAlphabetSize];
                for (int i = 0; i < tapeAlphabetSize; i++)
                {
                    if (i != newMachineBlankSymbol)
                    {
                        inputAlphabetTempMatrix[i] = true;
                    }
                    else
                    {
                        inputAlphabetTempMatrix[i] = false;
                    }
                }
                inputAlphabet = new FrozenVector <bool>(inputAlphabetTempMatrix);
            }



            /* Store number of states. */
            if (!(newMachineNumberOfStates >= 1))
            {
                throw new TuringMachineException("Number of states should be >= 1, but it is " + tapeAlphabetSize);
            }
            numberOfStates = newMachineNumberOfStates;



            /* Now check and store the initial state. */
            if (!(newMachineInitialState >= 0 && newMachineInitialState < numberOfStates))
            {
                throw new TuringMachineException("Initial state ("
                                                 + newMachineInitialState
                                                 + ") is out of range. It should be in [0,"
                                                 + numberOfStates
                                                 + "[");
            }
            initialState = newMachineInitialState;



            /* Now check the transition matrix and store optimized version
             * of this matrix using ints for destination states. */
            if (newMachineTransitionMatrix.GetLength(0) != numberOfStates)
            {
                throw new TuringMachineException("Transition matrix has "
                                                 + newMachineTransitionMatrix.GetLength(0)
                                                 + " lines while it should have "
                                                 + numberOfStates
                                                 + " lines which is the number of states.");
            }
            if (newMachineTransitionMatrix.GetLength(1) != 3 * tapeAlphabetSize)
            {
                throw new TuringMachineException("Transition matrix has "
                                                 + newMachineTransitionMatrix.GetLength(1)
                                                 + " columns while it should have "
                                                 + (3 * tapeAlphabetSize)
                                                 + " columns which is 3 times the number of letters in the alphabet.");
            }
            for (int s = 0; s < numberOfStates; s++)
            {
                for (int l = 0; l < tapeAlphabetSize; l += 3)
                {
                    if (!(newMachineTransitionMatrix[s, l] >= -2 && newMachineTransitionMatrix[s, l] < numberOfStates))
                    {
                        throw new TuringMachineException("Transitions matrix references a state ("
                                                         + newMachineTransitionMatrix[s, l]
                                                         + ") that is out of range. It should be in [-2,"
                                                         + numberOfStates
                                                         + "[");
                    }
                    if (!(newMachineTransitionMatrix[s, l + 1] >= 0 && newMachineTransitionMatrix[s, l + 1] < tapeAlphabetSize))
                    {
                        throw new TuringMachineException("Transitions matrix references a letter ("
                                                         + newMachineTransitionMatrix[s, l]
                                                         + ") that is out of range. It should be in [0,"
                                                         + tapeAlphabetSize
                                                         + "[");
                    }
                    if (!(newMachineTransitionMatrix[s, l + 2] >= -1 && newMachineTransitionMatrix[s, l + 2] <= 1))
                    {
                        throw new TuringMachineException("Transitions matrix references a direction ("
                                                         + newMachineTransitionMatrix[s, l]
                                                         + ") that is out of range. It should be in [-1,1].");
                    }
                }
            }
            transitionMatrix = newMachineTransitionMatrix;
        }
예제 #2
0
        // This constructor creates a Turing machine definition. The arguments are:
        // (Note: We use "symbol" and "letter" as synonims.)
        //
        // IDS OR CUSTOM TYPES?
        // States and letters have a double representation. They can bee seen as
        // integer ids (positions in the matrix, newMachineBlankSymbolId, newMachineInitialStateId)
        // or as TState and TAlphabet (types you choose). The mapping between this 2 representations
        // is acomplished using newMachineTapeAlphabet and newMachineStates. It is not mandatory
        // to use this 2 representations. You may be happy with just integers. In that case,
        // pass <int,int> as <TAlphabet,TState> and null as newMachineTapeAlphabet and newMachineStates.
        // The number of states and letters will then be computer using matrix lengths.
        // You can have a mix of the 2, for example state as ids only but letters as cutom type.
        //
        // - the tape alphabet (length >= 1)
        // - a blank symbol (>= 0, <(alphabet size))
        // - the set of letters that are part of the input alphabet, subset of the tape alphabet,
        //   it is an array of bools of length = alphabet size. The blank symbol
        //   must not be part of the input alphabet. newMachineInputAlphabet[a] contains
        //   true of false whether or not letter a is part of the input alphabet.
        //   If you want the input alphabet to be all the tape alphabet except blank,
        //   then you can pass null as this argument.
        // - states (length >= 1)
        // - an initial state (>= 0, <(number of states))
        // - a transition matrix, with lines being states, 3 columns beeing one letter and content being
        //   the new state, the new letter and the direction.
        //   ie. newMachinesTransitions[s1,3*a] = s2 means that when the machine is in state s1
        //   and reads letter a, it goes in state s2. Special values -1 and -2 respectively mean
        //   reject and accept.
        //   newMachinesTransitions[s1,3*a+1] = a2 means the written letter is a2
        //   newMachinesTransitions[s1,3*a+2] = d means the machine will go in direction d
        //   with 0 beeing "don't move", 1 beeing "go one step right", and 2 beeing "go one step left".
        //
        // About FrozenVector and FrozenMatrix:
        // This object requires that you use FrozenVector and FrozenMatrix for
        // the transitions matrix and the vector of final states.
        // As FrozenVector and FrozenMatrix are read-only, they can safely be
        // shared accross machines definitions. For convenience, a overrided
        // constructor is provided, that takes usual arrays, and converts them
        // to FrozenMatrix/Vector.
        //
        public TuringMachineDefinition(ICollection <TAlphabet> newMachineTapeAlphabet,
                                       int newMachineBlankSymbolId,
                                       FrozenVector <bool> newMachineInputAlphabet,
                                       ICollection <TState> newMachineStates,
                                       int newMachineInitialStateId,
                                       FrozenMatrix <int> newMachineTransitions)
        {
            int tapeAlphabetSize;

            /* Store alphabet and check it is correct (ie no duplicates). */
            if (newMachineTapeAlphabet != null)
            {
                tapeAlphabet = new TAlphabet[newMachineTapeAlphabet.Count];
                newMachineTapeAlphabet.CopyTo(tapeAlphabet, 0);
                tapeAlphabetIds = new Dictionary <TAlphabet, int>();
                int i = 0;
                foreach (TAlphabet a in newMachineTapeAlphabet)
                {
                    if (tapeAlphabetIds.ContainsKey(a))
                    {
                        throw new FiniteStateMachineException("Duplicated letter in newMachineAlphabet : " + a);
                    }
                    tapeAlphabetIds.Add(a, i);
                    i++;
                }
                // newMachineAlphabet array has authority for giving the number of letters
                tapeAlphabetSize = tapeAlphabet.Length;
            }
            else
            {
                if (typeof(TAlphabet) != typeof(int))
                {
                    throw new FiniteStateMachineException("You passed null as newMachineAlphabet, so I deduce that you want to identify"
                                                          + " letters with ids instead of TAlphabet type, but did not choose int as TAlphabet"
                                                          + " so this is inconsistant.");
                }
                // the matrix has authority for giving the number of letters
                tapeAlphabetSize = newMachineTransitions.GetLength(1) / 3;
            }


            int numberOfStates;

            /* Store states and check it is correct (ie no duplicates). */
            if (newMachineStates != null)
            {
                states = new TState[newMachineStates.Count];
                newMachineStates.CopyTo(states, 0);
                stateIds = new Dictionary <TState, int>();
                int i = 0;
                foreach (TState s in newMachineStates)
                {
                    if (stateIds.ContainsKey(s))
                    {
                        throw new FiniteStateMachineException("Duplicated state in newMachineStates : " + s);
                    }
                    stateIds.Add(s, i);
                    i++;
                }
                // newMachineStates array has auothority for giving the number of letters
                numberOfStates = states.Length;
            }
            else
            {
                if (typeof(TState) != typeof(int))
                {
                    throw new FiniteStateMachineException("You passed null as newMachineStates, so I deduce that you want to identify"
                                                          + " states with ids instead of TState type, but did not choose int as TState"
                                                          + " so this is inconsistant.");
                }
                // the matrix has authority for giving the number of states
                numberOfStates = newMachineTransitions.GetLength(0);
            }


            /* Now build our internal FiniteStateMachineDefinitionById. */
            definitionById = new TuringMachineDefinitionById(tapeAlphabetSize,
                                                             newMachineBlankSymbolId,
                                                             newMachineInputAlphabet,
                                                             numberOfStates,
                                                             newMachineInitialStateId,
                                                             newMachineTransitions);
        }
예제 #3
0
        /* This constructor creates a finite state machine definition. The arguments are:
         * - the alphabet size (int, >= 0)
         * - the number of states (int, >= 1)
         * - an initial state (>= 0, <(number of states))
         * - a transition matrix, with lines being states, columns beeing letters and content being the new states,
         *   ie newMachinesTransitions[s1,a] = s2 means that when the machine is in state s1
         *   and reads letter a, it goes in state s2.
         * - an array of booleans, as many as states, which say if the state is final or not
         */
        public FiniteStateMachineDefinitionById(int newMachineAlphabetSize,
                                                int newMachineNumberOfStates,
                                                int newMachineInitialState,
                                                FrozenMatrix <int> newMachineTransitionMatrix,
                                                FrozenVector <bool> newMachineFinalStates)
        {
            /* Store alphabet size. */
            if (!(newMachineAlphabetSize >= 0))
            {
                throw new FiniteStateMachineException("Alphabet size is negative (" + newMachineAlphabetSize + ")");
            }
            alphabetSize = newMachineAlphabetSize;

            /* Store number of states. */
            if (!(newMachineNumberOfStates >= 1))
            {
                throw new FiniteStateMachineException("Number of states should be >= 1, but it is " + newMachineAlphabetSize);
            }
            numberOfStates = newMachineNumberOfStates;

            /* Now check and store the initial state. */
            if (!(newMachineInitialState >= 0 && newMachineInitialState < numberOfStates))
            {
                throw new FiniteStateMachineException("Initial state ("
                                                      + newMachineInitialState
                                                      + ") is out of range. It should be in [0,"
                                                      + numberOfStates
                                                      + "[");
            }
            initialState = newMachineInitialState;

            /* Now check the transition matrix and store optimized version
             * of this matrix using ints for destination states. */
            if (newMachineTransitionMatrix.GetLength(0) != numberOfStates)
            {
                throw new FiniteStateMachineException("Transition matrix has "
                                                      + newMachineTransitionMatrix.GetLength(0)
                                                      + " lines while it should have "
                                                      + numberOfStates
                                                      + " lines which is the number of states.");
            }
            if (newMachineTransitionMatrix.GetLength(1) != alphabetSize)
            {
                throw new FiniteStateMachineException("Transition matrix has "
                                                      + newMachineTransitionMatrix.GetLength(1)
                                                      + " columns while it should have "
                                                      + alphabetSize
                                                      + " columns which is the number of letters in the alphabet.");
            }
            for (int s = 0; s < numberOfStates; s++)
            {
                for (int l = 0; l < alphabetSize; l++)
                {
                    if (!(newMachineTransitionMatrix[s, l] >= 0 && newMachineTransitionMatrix[s, l] < numberOfStates))
                    {
                        throw new FiniteStateMachineException("Transitions matrix references a state ("
                                                              + newMachineTransitionMatrix[s, l]
                                                              + ") that is out of range. It should be in [0,"
                                                              + numberOfStates
                                                              + "[");
                    }
                }
            }
            transitionMatrix = newMachineTransitionMatrix;

            /* Check and store final states. */
            if (newMachineFinalStates.Length != numberOfStates)
            {
                throw new FiniteStateMachineException("Final states array has "
                                                      + newMachineFinalStates.Length
                                                      + " elements while it should have "
                                                      + numberOfStates
                                                      + " elements which is the number of states.");
            }
            finalStates = newMachineFinalStates;
        }