123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- package enfa
-
- import "fmt"
-
- type transitionInput struct {
- srcState int
- input string
- }
-
- type destState map[int]bool
-
- type ENFA struct {
- initState int
- currentState map[int]bool
- totalStates []int
- finalStates []int
- transition map[transitionInput]destState
- inputMap map[string]bool
- }
-
- //New a new NFA
- func NewENFA(initState int, isFinal bool) *ENFA {
-
- retNFA := &ENFA{
- transition: make(map[transitionInput]destState),
- inputMap: make(map[string]bool),
- initState: initState}
-
- retNFA.currentState = make(map[int]bool)
- retNFA.currentState[initState] = true
- retNFA.AddState(initState, isFinal)
- return retNFA
- }
-
- //Add new state in this NFA
- func (d *ENFA) AddState(state int, isFinal bool) {
- if state == -1 {
- fmt.Println("Cannot add state as -1, it is dead state")
- return
- }
-
- d.totalStates = append(d.totalStates, state)
- if isFinal {
- d.finalStates = append(d.finalStates, state)
- }
- }
-
- //Add new transition function into NFA
- func (d *ENFA) AddTransition(srcState int, input string, dstStateList ...int) {
- find := false
-
- //find input if exist in NFA input List
- if _, ok := d.inputMap[input]; !ok {
- //not exist, new input in this NFA
- d.inputMap[input] = true
- }
-
- for _, v := range d.totalStates {
- if v == srcState {
- find = true
- }
- }
-
- if !find {
- fmt.Println("No such state:", srcState, " in current NFA")
- return
- }
-
- dstMap := make(map[int]bool)
- for _, destState := range dstStateList {
- dstMap[destState] = true
- }
-
- targetTrans := transitionInput{srcState: srcState, input: input}
- d.transition[targetTrans] = dstMap
- }
-
- func (d *ENFA) CheckPathExist(src int, input string, dst int) bool {
- retMap, _ := d.transition[transitionInput{srcState: src, input: input}]
- if _, ok := retMap[dst]; ok {
- return true
- }
- return false
- }
-
- func (d *ENFA) Input(testInput string) []int {
- updateCurrentState := make(map[int]bool)
- for current, _ := range d.currentState {
- for _, realTestInput := range []string{testInput, "*", "?"} {
- intputTrans := transitionInput{srcState: current, input: realTestInput}
- valMap, ok := d.transition[intputTrans]
- if ok {
- for dst, _ := range valMap {
- updateCurrentState[dst] = true
-
- //Update epsilon input way... if exist
- epsilonTrans := transitionInput{srcState: dst}
- if eMap, ok := d.transition[epsilonTrans]; ok {
- for eDst, _ := range eMap {
- updateCurrentState[eDst] = true
- }
- }
- }
- } else {
- //dead state, remove in current state
- //do nothing.
- }
- }
- }
-
- //update curret state
- d.currentState = updateCurrentState
-
- //return result
- var ret []int
- for state, _ := range updateCurrentState {
- ret = append(ret, state)
- }
- return ret
- }
-
- //To verify current state if it is final state
- func (d *ENFA) Verify() bool {
- for _, val := range d.finalStates {
- for cState, _ := range d.currentState {
- if val == cState {
- return true
- }
- }
- }
- return false
- }
-
- //Reset NFA state to initilize state, but all state and transition function will remain
- func (d *ENFA) Reset() {
- initState := make(map[int]bool)
- initState[d.initState] = true
- d.currentState = initState
- }
-
- //Verify if list of input could be accept by NFA or not
- func (d *ENFA) VerifyInputs(inputs []string) bool {
- for _, v := range inputs {
- d.Input(v)
- }
- return d.Verify()
- }
-
- //To print detail transition table contain of current NFA
- func (d *ENFA) PrintTransitionTable() {
- fmt.Println("===================================================")
- //list all inputs
- var inputList []string
- for key, _ := range d.inputMap {
- if key == "" {
- fmt.Printf("\tε|")
- } else {
- fmt.Printf("\t%s|", key)
- }
- inputList = append(inputList, key)
- }
-
- fmt.Printf("\n")
- fmt.Println("---------------------------------------------------")
-
- for _, state := range d.totalStates {
- fmt.Printf("%d |", state)
- for _, key := range inputList {
- checkInput := transitionInput{srcState: state, input: key}
- if dstState, ok := d.transition[checkInput]; ok {
- fmt.Printf("\t")
- for val, _ := range dstState {
- fmt.Printf("%d,", val)
- }
- fmt.Printf("|")
- } else {
- fmt.Printf("\tNA|")
- }
- }
- fmt.Printf("\n")
- }
-
- fmt.Println("---------------------------------------------------")
- fmt.Println("===================================================")
- }
|