// Initialize the state and create a 0-length tape. internal TuringMachineExecutionById(TuringMachineDefinitionById machineDefinition) { definition = machineDefinition; }
// 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); }