From 53402051aab94fe750d84fad4b0eb8d5f4a6eb6f Mon Sep 17 00:00:00 2001 From: GabrielTofvesson Date: Thu, 28 Mar 2019 10:36:55 +0100 Subject: [PATCH] Fix accept states for NFA-DFA translation Implement relevant loops as stdlib functions --- .idea/misc.xml | 2 +- src/FiniteAutomata.kt | 37 ++++++++++++++++------------ src/dev/w1zzrd/automata/Automaton.kt | 8 +++--- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 0319d5d..e32eceb 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/FiniteAutomata.kt b/src/FiniteAutomata.kt index 9bb8693..9e83852 100644 --- a/src/FiniteAutomata.kt +++ b/src/FiniteAutomata.kt @@ -9,25 +9,26 @@ fun main(args: Array){ // Declare states of the NFA val stateS = nfa.makeState("s") - val stateQ1 = nfa.makeState("q1") - val stateQ2 = nfa.makeState("q2", true) - val stateP = nfa.makeState("p") - val stateQ = nfa.makeState("q") - val stateR = nfa.makeState("r", true) + val stateA = nfa.makeState("a") + val stateB = nfa.makeState("b", true) + val stateC = nfa.makeState("c") + val stateD = nfa.makeState("d") + val stateE = nfa.makeState("e", true) - // Add epsilon transition from S to Q1 and P - stateS.addEpsilon(stateQ1, stateP) - // Add regular state-transition connectives - stateQ1.addConnective(0, stateQ1) - stateQ1.addConnective(1, stateQ2) + stateS.addEpsilon(stateA, stateC) - stateQ2.addConnective(0, stateQ1) + stateA.addConnective(1, stateB) - stateP.addConnective(arrayOf(0, 1), stateP) - stateP.addConnective(1, stateQ) + stateB.addConnective(0, stateB) + + stateC.addConnective(1, stateB, stateD) + stateC.addConnective(0, stateB) + + stateD.addConnective(0, stateE) + + stateE.addConnective(arrayOf(0, 1), stateC) - stateQ.addConnective(arrayOf(0, 1), stateR) // Declare S as the initial state nfa.entryPoint = stateS @@ -37,11 +38,15 @@ fun main(args: Array){ // Get a traverser for the DFA and manually traverse the string "1100", then print the resulting state val dtraverser = dfa.makeTraverser() - dtraverser.traverse(1, 1, 0, 0) + dtraverser.traverse(1, 0, 0, 1, 0) + println("DFA simulation:") println(dtraverser.currentState.toString()) + println("Accepts: ${dfa.accepts(1, 0, 0, 1, 0)}\n") // Do the same as above but for the NFA val ntraverser = nfa.makeTraverser() - ntraverser.traverse(1, 1, 0, 0) + ntraverser.traverse(1, 0, 0, 1, 0) + println("NFA simulation:") println(ntraverser.currentState.toString()) + println("Accepts: ${nfa.accepts(1, 0, 0, 1, 0)}") } \ No newline at end of file diff --git a/src/dev/w1zzrd/automata/Automaton.kt b/src/dev/w1zzrd/automata/Automaton.kt index b6b7bf7..918b5c2 100644 --- a/src/dev/w1zzrd/automata/Automaton.kt +++ b/src/dev/w1zzrd/automata/Automaton.kt @@ -243,7 +243,7 @@ class Automaton(val language: Language, val deterministic: Boolean){ // Generate the NFA-DFA state-set-to-state mappings, as well as populating the DFA with the necessary states for(tableState in tableEntries.keys) - oldToNew[tableState] = dfa.makeState(tableState.toReadableString(), tableState.contentsEquals(startingState)) + oldToNew[tableState] = dfa.makeState(tableState.toReadableString(), tableState.isAcceptState()) // Apply the mapping schema determined by the generated state-table to the DFA for(oldState in oldToNew.keys) @@ -351,9 +351,9 @@ class Automaton(val language: Language, val deterministic: Boolean){ if(!contains(state)) add(state) // Recursively traverse epsilon connectives for new connectives (i.e. for states not already traversed) - for(epsilonState in state.getEpsilon()) - if(!contains(epsilonState)) - traverseEpsilon(epsilonState) + state.getEpsilon() + .filterNot { contains(it) } + .forEach { traverseEpsilon(it) } } }