Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "fmt"
- "sort"
- )
- func main() {
- inputData()
- }
- type Node struct {
- numState int
- related []*Node
- signals []string
- isFinal bool
- }
- type NewNode struct {
- numState int
- nodes nodeArray
- related []*NewNode
- signals map[*NewNode][]string
- isFinal bool
- }
- type nodeArray []*Node
- type dNodeArray []*NewNode
- var setSignals []string
- var startState int
- func inputData() {
- setSignals = make([]string, 0)
- var numStates int
- var numTransition int
- fmt.Scanf("%d", &numStates)
- fmt.Scanf("%d", &numTransition)
- nodes := make(nodeArray, 0)
- for i := 0; i < numStates; i++ {
- node := Node{i, make(nodeArray, 0), make([]string, 0), false}
- nodes = append(nodes, &node)
- }
- nodes.fillAutomata(numStates, numTransition)
- nodes.runDet()
- }
- func (self nodeArray) fillAutomata(n, m int) {
- for i := 0; i < m; i++ {
- var (
- currentState int
- toState int
- signal string
- )
- fmt.Scan(¤tState, &toState, &signal)
- self[currentState].addRelatedNode(self[toState])
- self[currentState].addSignal(signal)
- if signal != "lambda" {
- checkAndAddSignal(signal)
- }
- }
- for i := 0; i < n; i++ {
- var isFinalState bool
- fmt.Scan(&isFinalState)
- self[i].isFinal = isFinalState
- }
- fmt.Scan(&startState)
- }
- func (self *Node) addSignal(signal string) {
- self.signals = append(self.signals, signal)
- }
- func (self *Node) addRelatedNode(node *Node) {
- self.related = append(self.related, node)
- }
- func checkAndAddSignal(signal string) {
- var isContained bool
- for _, sym := range setSignals {
- if sym == signal {
- isContained = true
- }
- }
- if !isContained {
- setSignals = append(setSignals, signal)
- }
- }
- func closure(nodes nodeArray) (dNode *NewNode) {
- dNode = new(NewNode)
- dNode.numState = 0
- dNode.nodes = make(nodeArray, 0)
- dNode.related = make(dNodeArray, 0)
- dNode.signals = make(map[*NewNode][]string, 0)
- dNode.isFinal = false
- for _, node := range nodes {
- dfs(node, dNode)
- }
- return dNode
- }
- func dfs(node *Node, dnode *NewNode) {
- if !search(node, dnode.nodes) {
- dnode.nodes = append(dnode.nodes, node)
- for i, relatedElement := range node.related {
- if node.signals[i] == "lambda" {
- dfs(relatedElement, dnode)
- }
- }
- }
- }
- func search(node *Node, nodes nodeArray) bool {
- for _, element := range nodes {
- if element.numState == node.numState {
- return true
- }
- }
- return false
- }
- func (self nodeArray) runDet() {
- q0 := closure(nodeArray{self[startState]})
- countStates := 0
- q0.numState = countStates
- detArray := make(dNodeArray, 0)
- detArray = append(detArray, q0)
- stk := make(dNodeArray, 0)
- stk = append(stk, q0)
- countStates += 1
- for len(stk) > 0 {
- posLastElem := len(stk) -1
- z := stk[posLastElem]
- stk = stk[:posLastElem]
- for _, node := range z.nodes {
- if node.isFinal {
- z.isFinal = true
- break
- }
- }
- for _, signalSym := range setSignals {
- t := make(nodeArray, 0)
- for _, node := range z.nodes {
- for i, sig := range node.signals {
- if sig == signalSym {
- t = append(t, node.related[i])
- }
- }
- }
- newState := closure(t)
- _, searched := getAndSearchInTrans(newState, detArray)
- if !searched {
- newState.numState = countStates
- countStates += 1
- detArray = append(detArray, newState)
- stk = append(stk, newState)
- } else {
- newState, _ = getAndSearchInTrans(newState, detArray)
- }
- z.signals[newState] = append(z.signals[newState], signalSym)
- _, search := getAndSearchInTrans(newState, z.related)
- if !search {
- z.related = append(z.related, newState)
- }
- }
- }
- makeDotStruct(self[startState], detArray)
- }
- func getAndSearchInTrans(dnode *NewNode, dNodes dNodeArray ) (*NewNode, bool) {
- count := 0
- for _, node := range dNodes {
- count = 0
- if len(node.nodes) != len(dnode.nodes) {
- continue
- }
- for _, anotherNode := range node.nodes {
- for _, nanotherNode := range dnode.nodes {
- if anotherNode.numState == nanotherNode.numState {
- count += 1
- }
- }
- }
- if len(node.nodes) == count {
- return node, true
- }
- }
- return dnode, false
- }
- func makeDotStruct(nstartState *Node, detArray dNodeArray) {
- fmt.Print("digraph {\n\trankdir = LR\n\tdummy [label = \"\", shape = none]\n")
- for _, node := range detArray {
- count := 0
- fmt.Print("\t", node.numState)
- fmt.Print(" [label = \"[")
- sort.Sort(node.nodes)
- for _, rel := range node.nodes {
- if count < len(node.nodes) - 1 {
- fmt.Printf("%d ", rel.numState)
- count += 1
- } else {
- fmt.Print(rel.numState)
- }
- }
- count = 0
- fmt.Print("]\", shape =")
- if node.isFinal {
- fmt.Print(" doublecircle]\n")
- } else {
- fmt.Print(" circle]\n")
- }
- }
- fmt.Println("\tdummy -> ", nstartState.numState)
- for _, node := range detArray {
- for _, relatedNode := range node.related {
- count := 0
- fmt.Print("\t", node.numState, " -> ", relatedNode.numState)
- fmt.Print(" [label = \"")
- for _, signal := range node.signals[relatedNode] {
- if count < len(node.signals[relatedNode]) - 1 {
- count += 1
- fmt.Print(signal, " ")
- } else {
- fmt.Print(signal)
- }
- }
- count = 0
- fmt.Print("\"]\n")
- }
- }
- fmt.Print("}")
- }
- func (nodes nodeArray) Len() int{
- return len(nodes)
- }
- func (nodes nodeArray) Swap(i, j int) {
- nodes[i], nodes[j] = nodes[j], nodes[i]
- }
- func (nodes nodeArray) Less(i, j int) bool {
- return nodes[i].numState < nodes[j].numState
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement