Annotation of researchv10dc/cmd/icon/tests/mindfa.icn, revision 1.1

1.1     ! root        1: ### mindfa -- minimize a DFA
        !             2: 
        !             3: record dfa(Q,S,d,q0,F)          # a DFA
        !             4: 
        !             5: procedure main()
        !             6: 
        !             7:    x := getdfa()
        !             8:    every 1 to 10 do
        !             9:       showdfa("Reduced",minimize(showdfa("Original",x)))
        !            10: 
        !            11: end
        !            12: 
        !            13: ## - getdfa() -- accept a dfa from input, return it
        !            14: ##
        !            15: procedure getdfa()
        !            16: local Q,S,d,q0,F
        !            17: local q,a
        !            18: 
        !            19:    Q := readset("Enter states (1 character names): ")
        !            20:    S := readset("Enter input alphabet: ")
        !            21:    F := readset("Enter Final states (subset of states): ")
        !            22:    writes("What is the start state? ")
        !            23:    q0 := read()
        !            24:    d := table()
        !            25:    every q := !Q & a := !S do {
        !            26:       writes("enter delta(",q,",",a,") = ")
        !            27:       d[q||":"||a] := read()
        !            28:       }
        !            29:    return dfa(Q,S,d,q0,F)
        !            30: 
        !            31: end
        !            32: 
        !            33: 
        !            34: ## readset(s) - get a set
        !            35: #
        !            36: procedure readset(s)
        !            37: local t1
        !            38: 
        !            39:    writes(s)
        !            40:    t1 := []
        !            41:    every put(t1,!cset(read()))  # the cset removes duplicates
        !            42:    return t1
        !            43: 
        !            44: end
        !            45: 
        !            46: ## showdfa(msg,D) -- show a dfa
        !            47: #
        !            48: procedure showdfa(msg,D)
        !            49: local q,a
        !            50: 
        !            51:    every 1 to 3 do write()
        !            52:    write(msg," Deterministic Finite Automaton is:")
        !            53:    write()
        !            54:    write("\t(Q,S,delta,q0,F)")
        !            55:    write()
        !            56:    write("where:")
        !            57:    write()
        !            58:    writeset("Q",D.Q)
        !            59:    writeset("S",D.S)
        !            60:    writeset("F",D.F)
        !            61:    write("\tStart state is ",D.q0)
        !            62:    write("\tDelta: ")
        !            63:    every q := !D.Q do {
        !            64:       every writes("\td(",q,",",a := !D.S,") = ",D.d[q||":"||a])
        !            65:       write()
        !            66:       }
        !            67:    return D
        !            68: 
        !            69: end
        !            70: 
        !            71: ## writeset(msg,s) -- display a set
        !            72: #
        !            73: procedure writeset(msg,s)
        !            74: local tmp
        !            75:    tmp := ""
        !            76:    every tmp ||:= !s || ","
        !            77:    write("\t",msg," = {",tmp[1:-1],"}")
        !            78:    return
        !            79: end
        !            80: 
        !            81: ## minimize(D) -- minimize a dfa
        !            82: #
        !            83: global distab, dlists
        !            84: 
        !            85: procedure minimize(D)
        !            86: local F,QF
        !            87: local p,q,a,cs
        !            88: 
        !            89:    distab := table()
        !            90:    dlists := table()
        !            91:    F := D.F
        !            92:    QF := diff(D.Q,D.F)
        !            93:    every p := !F & q := !QF do
        !            94:       distab[cset(p||q)] := "X"
        !            95:    every ((p := !F & q := !F) |
        !            96:           (p := !QF & q := !QF)) & p ~== q do
        !            97:       if \distab[cset(D.d[p||":"||(a:=!D.S)]||D.d[q||":"||a])] then {
        !            98:          distab[cset(p||q)] := "X"
        !            99:          marklists(dlists[cset(p||q)])
        !           100:          }
        !           101:       else
        !           102:          every a := !D.S do
        !           103:             if D.d[p||":"||a] ~== D.d[q||":"||a] then {
        !           104:                cs := cset(D.d[p||":"||a]||D.d[q||":"||a])
        !           105:                if cs == cset(p||q) then next
        !           106:                /dlists[cs] := []
        !           107:                put(dlists[cs],cset(p||q))
        !           108:                }
        !           109: 
        !           110:    return makemdfa(D,distab)
        !           111: 
        !           112: end
        !           113: 
        !           114: ## marklists(l) -- recursively mark the pair of nodes
        !           115: #                  on list l.
        !           116: procedure marklists(l)
        !           117: local e
        !           118: 
        !           119:    if /l then return
        !           120:    every e := !l do {
        !           121:       distab[e] := "X"
        !           122:       marklists(dlists[e])
        !           123:       }
        !           124:    return
        !           125: 
        !           126: end
        !           127: 
        !           128: ## makemdfa(D,DT) -- Use the table from the minimization
        !           129: #                    to construct the minimal dfa
        !           130: procedure makemdfa(D,DT)
        !           131: local elist, etab, qset, tlist, echeck
        !           132: local p, q, Delta, q0
        !           133: 
        !           134:    etab := table()              # table of new states
        !           135:    qset := ''
        !           136:    every p := !D.Q do {
        !           137:       qset ++:= p
        !           138:       plike := equiv(p,etab) | cset(p)
        !           139:       every q := !diff(D.Q,qset) & p ~== q do
        !           140:          if /distab[cset(p||q)] then {
        !           141:             plike ++:= equiv(q,etab) | q
        !           142:             }
        !           143:       etab[plike] := plike
        !           144:       }
        !           145:    tlist := []
        !           146:    elist := []
        !           147:    Delta := table()
        !           148:    q0 := equiv(D.q0,etab)       # start state of reduced machine
        !           149:    put(tlist,q0)
        !           150:    put(elist,q0)                # only worry about states reachable
        !           151:                                 #   from [q0]
        !           152:    echeck := table()            #   keep track of states
        !           153:    echeck[q0] := q0
        !           154:    while q := get(tlist) do
        !           155:       every a := !D.S do {
        !           156:          Delta[q||":"||a] := equivdelta(q,a,D,etab)
        !           157:          if /echeck[Delta[q||":"||a]] then {
        !           158:             echeck[Delta[q||":"||a]] := Delta[q||":"||a]
        !           159:             put(tlist,Delta[q||":"||a])
        !           160:             put(elist,Delta[q||":"||a])
        !           161:             }
        !           162:          }
        !           163: 
        !           164:    return dfa(elist,D.S,Delta,q0,finalstates(D,elist))
        !           165: end
        !           166: 
        !           167: ## equiv(q,el) -- return the equivalence class in el containing q
        !           168: #
        !           169: procedure equiv(q,el)
        !           170:    every p := !el do
        !           171:       if p++q == p then return p
        !           172: end
        !           173: 
        !           174: ## equivdelta(p,a,D,el) -- apply delta to equiv. classes
        !           175: #
        !           176: procedure equivdelta(p,a,D,el)
        !           177: local q, r
        !           178:    q := !p               # any state in equiv. class p
        !           179:    r := D.d[q||":"||a]   # find state in original dfa
        !           180: 
        !           181:    return equiv(r,el)    # return its equivalence class
        !           182: end
        !           183: 
        !           184: 
        !           185: ## finalstates(D,el) -- build the set of final states
        !           186: #
        !           187: procedure finalstates(D,el)
        !           188: local flist, p, q
        !           189: 
        !           190:    ftab := table()
        !           191:    every p := !D.F do
        !           192:       ftab[q := equiv(p,el)] := q
        !           193:    flist := []
        !           194:    every put(flist,(!sort(ftab))[1])
        !           195:    return flist
        !           196: end
        !           197: 
        !           198: 
        !           199: ## diff(l1,l2) -- return the difference of two sets
        !           200: #
        !           201: procedure diff(l1,l2)
        !           202: local l,t1,t2
        !           203: 
        !           204:    t1 := ''
        !           205:    every t1 ++:= !l1
        !           206: 
        !           207:    t2 := ''
        !           208:    every t2 ++:= !l2
        !           209: 
        !           210:    l := []
        !           211:    every put(l,!(t1--t2))
        !           212:    if *l = 0 then fail
        !           213:    return l
        !           214: end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.