diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2013-01-27 23:51:56 +0000 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2013-01-27 23:51:56 +0000 |
commit | 6ab0c0f5bf14ed9c15370407b9ee7e0b4b089ae1 (patch) | |
tree | 926065cf45450116098db664e3c61dced9e1f21a /tests/general/mindfa.icn | |
download | icon-6ab0c0f5bf14ed9c15370407b9ee7e0b4b089ae1.tar.gz |
Initial upstream version 9.4.3upstream/9.4.3
Diffstat (limited to 'tests/general/mindfa.icn')
-rw-r--r-- | tests/general/mindfa.icn | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/tests/general/mindfa.icn b/tests/general/mindfa.icn new file mode 100644 index 0000000..f4a0795 --- /dev/null +++ b/tests/general/mindfa.icn @@ -0,0 +1,214 @@ +### mindfa -- minimize a DFA + +record dfa(Q,S,d,q0,F) # a DFA + +procedure main() + + x := getdfa() + every 1 to 10 do + showdfa("Reduced",minimize(showdfa("Original",x))) + +end + +## - getdfa() -- accept a dfa from input, return it +## +procedure getdfa() +local Q,S,d,q0,F +local q,a + + Q := readset("Enter states (1 character names): ") + S := readset("Enter input alphabet: ") + F := readset("Enter Final states (subset of states): ") + writes("What is the start state? ") + q0 := read() + d := table() + every q := !Q & a := !S do { + writes("enter delta(",q,",",a,") = ") + d[q||":"||a] := read() + } + return dfa(Q,S,d,q0,F) + +end + + +## readset(s) - get a set +# +procedure readset(s) +local t1 + + writes(s) + t1 := [] + every put(t1,!cset(read())) # the cset removes duplicates + return t1 + +end + +## showdfa(msg,D) -- show a dfa +# +procedure showdfa(msg,D) +local q,a + + every 1 to 3 do write() + write(msg," Deterministic Finite Automaton is:") + write() + write("\t(Q,S,delta,q0,F)") + write() + write("where:") + write() + writeset("Q",D.Q) + writeset("S",D.S) + writeset("F",D.F) + write("\tStart state is ",D.q0) + write("\tDelta: ") + every q := !D.Q do { + every writes("\td(",q,",",a := !D.S,") = ",D.d[q||":"||a]) + write() + } + return D + +end + +## writeset(msg,s) -- display a set +# +procedure writeset(msg,s) +local tmp + tmp := "" + every tmp ||:= !s || "," + write("\t",msg," = {",tmp[1:-1],"}") + return +end + +## minimize(D) -- minimize a dfa +# +global distab, dlists + +procedure minimize(D) +local F,QF +local p,q,a,cs + + distab := table() + dlists := table() + F := D.F + QF := diff(D.Q,D.F) + every p := !F & q := !QF do + distab[cset(p||q)] := "X" + every ((p := !F & q := !F) | + (p := !QF & q := !QF)) & p ~== q do + if \distab[cset(D.d[p||":"||(a:=!D.S)]||D.d[q||":"||a])] then { + distab[cset(p||q)] := "X" + marklists(dlists[cset(p||q)]) + } + else + every a := !D.S do + if D.d[p||":"||a] ~== D.d[q||":"||a] then { + cs := cset(D.d[p||":"||a]||D.d[q||":"||a]) + if cs == cset(p||q) then next + /dlists[cs] := [] + put(dlists[cs],cset(p||q)) + } + + return makemdfa(D,distab) + +end + +## marklists(l) -- recursively mark the pair of nodes +# on list l. +procedure marklists(l) +local e + + if /l then return + every e := !l do { + distab[e] := "X" + marklists(dlists[e]) + } + return + +end + +## makemdfa(D,DT) -- Use the table from the minimization +# to construct the minimal dfa +procedure makemdfa(D,DT) +local elist, etab, qset, tlist, echeck +local p, q, Delta, q0 + + etab := table() # table of new states + qset := '' + every p := !D.Q do { + qset ++:= p + plike := equiv(p,etab) | cset(p) + every q := !diff(D.Q,qset) & p ~== q do + if /distab[cset(p||q)] then { + plike ++:= equiv(q,etab) | q + } + etab[plike] := plike + } + tlist := [] + elist := [] + Delta := table() + q0 := equiv(D.q0,etab) # start state of reduced machine + put(tlist,q0) + put(elist,q0) # only worry about states reachable + # from [q0] + echeck := table() # keep track of states + echeck[q0] := q0 + while q := get(tlist) do + every a := !D.S do { + Delta[q||":"||a] := equivdelta(q,a,D,etab) + if /echeck[Delta[q||":"||a]] then { + echeck[Delta[q||":"||a]] := Delta[q||":"||a] + put(tlist,Delta[q||":"||a]) + put(elist,Delta[q||":"||a]) + } + } + + return dfa(elist,D.S,Delta,q0,finalstates(D,elist)) +end + +## equiv(q,el) -- return the equivalence class in el containing q +# +procedure equiv(q,el) + every p := !el do + if p++q == p then return p +end + +## equivdelta(p,a,D,el) -- apply delta to equiv. classes +# +procedure equivdelta(p,a,D,el) +local q, r + q := !p # any state in equiv. class p + r := D.d[q||":"||a] # find state in original dfa + + return equiv(r,el) # return its equivalence class +end + + +## finalstates(D,el) -- build the set of final states +# +procedure finalstates(D,el) +local flist, p, q + + ftab := table() + every p := !D.F do + ftab[q := equiv(p,el)] := q + flist := [] + every put(flist,(!sort(ftab))[1]) + return flist +end + + +## diff(l1,l2) -- return the difference of two sets +# +procedure diff(l1,l2) +local l,t1,t2 + + t1 := '' + every t1 ++:= !l1 + + t2 := '' + every t2 ++:= !l2 + + l := [] + every put(l,!(t1--t2)) + if *l = 0 then fail + return l +end |