Advertisement
Guest User

NFA to DFA (new)

a guest
Sep 24th, 2017
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 5.46 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "fmt"
  5.     "sort"
  6. )
  7.  
  8. func main() {
  9.     inputData()
  10. }
  11.  
  12. type Node struct {
  13.     numState    int
  14.     related     []*Node
  15.     signals     []string
  16.     isFinal     bool
  17. }
  18.  
  19. type NewNode struct {
  20.     numState    int
  21.     nodes       nodeArray
  22.     related     []*NewNode
  23.     signals     map[*NewNode][]string
  24.     isFinal     bool
  25. }
  26.  
  27. type nodeArray []*Node
  28. type dNodeArray []*NewNode
  29. var setSignals []string
  30. var startState int
  31.  
  32. func inputData() {
  33.     setSignals = make([]string, 0)
  34.     var numStates int
  35.     var numTransition int
  36.     fmt.Scanf("%d", &numStates)
  37.     fmt.Scanf("%d", &numTransition)
  38.     nodes := make(nodeArray, 0)
  39.     for i := 0; i < numStates; i++ {
  40.         node := Node{i, make(nodeArray, 0), make([]string, 0), false}
  41.         nodes = append(nodes, &node)
  42.     }
  43.     nodes.fillAutomata(numStates, numTransition)
  44.     nodes.runDet()
  45. }
  46.  
  47. func (self nodeArray) fillAutomata(n, m int) {
  48.     for i := 0; i < m; i++ {
  49.         var (
  50.             currentState int
  51.             toState int
  52.             signal string
  53.         )
  54.         fmt.Scan(&currentState, &toState, &signal)
  55.         self[currentState].addRelatedNode(self[toState])
  56.         self[currentState].addSignal(signal)
  57.  
  58.         if signal != "lambda" {
  59.             checkAndAddSignal(signal)
  60.         }
  61.     }
  62.  
  63.     for i := 0; i < n; i++ {
  64.         var isFinalState bool
  65.         fmt.Scan(&isFinalState)
  66.         self[i].isFinal = isFinalState
  67.     }
  68.     fmt.Scan(&startState)
  69. }
  70.  
  71. func (self *Node) addSignal(signal string) {
  72.     self.signals = append(self.signals, signal)
  73. }
  74.  
  75. func (self *Node) addRelatedNode(node *Node) {
  76.     self.related = append(self.related, node)
  77. }
  78.  
  79. func checkAndAddSignal(signal string) {
  80.     var isContained bool
  81.     for _, sym := range setSignals {
  82.         if sym == signal {
  83.             isContained = true
  84.         }
  85.     }
  86.     if !isContained {
  87.         setSignals = append(setSignals, signal)
  88.     }
  89. }
  90.  
  91. func closure(nodes nodeArray) (dNode *NewNode) {
  92.     dNode = new(NewNode)
  93.     dNode.numState = 0
  94.     dNode.nodes = make(nodeArray, 0)
  95.     dNode.related = make(dNodeArray, 0)
  96.     dNode.signals = make(map[*NewNode][]string, 0)
  97.     dNode.isFinal = false
  98.  
  99.     for _, node := range nodes {
  100.         dfs(node, dNode)
  101.     }
  102.     return dNode
  103. }
  104.  
  105. func dfs(node *Node, dnode *NewNode) {
  106.     if !search(node, dnode.nodes) {
  107.         dnode.nodes = append(dnode.nodes, node)
  108.  
  109.         for i, relatedElement := range node.related {
  110.             if node.signals[i] == "lambda" {
  111.                 dfs(relatedElement, dnode)
  112.             }
  113.         }
  114.     }
  115. }
  116.  
  117. func search(node *Node, nodes nodeArray) bool {
  118.     for _, element := range nodes {
  119.         if element.numState == node.numState {
  120.             return true
  121.         }
  122.     }
  123.     return false
  124. }
  125.  
  126. func (self nodeArray) runDet() {
  127.     q0 := closure(nodeArray{self[startState]})
  128.     countStates := 0
  129.     q0.numState = countStates
  130.     detArray := make(dNodeArray, 0)
  131.     detArray = append(detArray, q0)
  132.  
  133.     stk := make(dNodeArray, 0)
  134.     stk = append(stk, q0)
  135.  
  136.     countStates += 1
  137.     for len(stk) > 0 {
  138.         posLastElem := len(stk) -1
  139.         z := stk[posLastElem]
  140.         stk = stk[:posLastElem]
  141.         for _, node := range z.nodes {
  142.             if node.isFinal {
  143.                 z.isFinal = true
  144.                 break
  145.             }
  146.         }
  147.  
  148.         for _, signalSym := range setSignals {
  149.             t := make(nodeArray, 0)
  150.             for _, node := range z.nodes {
  151.                 for i, sig := range node.signals {
  152.                     if sig == signalSym {
  153.                         t = append(t, node.related[i])
  154.                     }
  155.                 }
  156.             }
  157.  
  158.             newState := closure(t)
  159.             _, searched := getAndSearchInTrans(newState, detArray)
  160.             if !searched {
  161.                 newState.numState = countStates
  162.                 countStates += 1
  163.                 detArray = append(detArray, newState)
  164.                 stk = append(stk, newState)
  165.  
  166.             } else {
  167.                 newState, _ = getAndSearchInTrans(newState, detArray)
  168.             }
  169.  
  170.             z.signals[newState] = append(z.signals[newState], signalSym)
  171.  
  172.             _, search := getAndSearchInTrans(newState, z.related)
  173.             if !search {
  174.                 z.related = append(z.related, newState)
  175.             }
  176.  
  177.         }
  178.     }
  179.     makeDotStruct(self[startState], detArray)
  180. }
  181.  
  182. func getAndSearchInTrans(dnode *NewNode, dNodes dNodeArray ) (*NewNode, bool) {
  183.     count := 0
  184.     for _, node := range dNodes {
  185.         count = 0
  186.         if len(node.nodes) != len(dnode.nodes) {
  187.             continue
  188.         }
  189.  
  190.         for _, anotherNode := range node.nodes {
  191.             for _, nanotherNode := range dnode.nodes {
  192.                 if anotherNode.numState == nanotherNode.numState {
  193.                     count += 1
  194.                 }
  195.             }
  196.         }
  197.  
  198.         if len(node.nodes) == count {
  199.             return node, true
  200.         }
  201.     }
  202.     return dnode, false
  203. }
  204.  
  205. func makeDotStruct(nstartState *Node, detArray dNodeArray) {
  206.     fmt.Print("digraph {\n\trankdir = LR\n\tdummy [label = \"\", shape = none]\n")
  207.  
  208.     for _, node := range detArray {
  209.         count := 0
  210.         fmt.Print("\t", node.numState)
  211.         fmt.Print(" [label = \"[")
  212.         sort.Sort(node.nodes)
  213.         for _, rel := range node.nodes {
  214.             if count < len(node.nodes) - 1 {
  215.                 fmt.Printf("%d ", rel.numState)
  216.                 count += 1
  217.             } else {
  218.                 fmt.Print(rel.numState)
  219.             }
  220.         }
  221.         count = 0
  222.         fmt.Print("]\", shape =")
  223.         if node.isFinal {
  224.             fmt.Print(" doublecircle]\n")
  225.         } else {
  226.             fmt.Print(" circle]\n")
  227.         }
  228.     }
  229.  
  230.     fmt.Println("\tdummy -> ", nstartState.numState)
  231.  
  232.     for _, node := range detArray {
  233.         for _, relatedNode := range node.related {
  234.             count := 0
  235.             fmt.Print("\t", node.numState, " -> ", relatedNode.numState)
  236.             fmt.Print(" [label = \"")
  237.             for _, signal := range node.signals[relatedNode] {
  238.                 if count < len(node.signals[relatedNode]) - 1 {
  239.                     count += 1
  240.                     fmt.Print(signal, " ")
  241.                 } else {
  242.                     fmt.Print(signal)
  243.                 }
  244.             }
  245.             count = 0
  246.             fmt.Print("\"]\n")
  247.         }
  248.     }
  249.     fmt.Print("}")
  250. }
  251.  
  252. func (nodes nodeArray) Len() int{
  253.     return len(nodes)
  254. }
  255.  
  256. func (nodes nodeArray) Swap(i, j int) {
  257.     nodes[i], nodes[j] = nodes[j], nodes[i]
  258. }
  259.  
  260. func (nodes nodeArray) Less(i, j int) bool {
  261.     return nodes[i].numState < nodes[j].numState
  262. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement