CS 481 Automata, Winter 1998 
NFA (with-e) to NFA (without-e) CONVERSION
CPROLOG SOURCE CODE
-------------------------------------------


symbol(X) :- delta(_,X,_), X \== nil.
alphabet(A) :- setof(X,symbol(X),A).
all_final_states(F) :- setof(X,final_state(X),F).
state(S) :- delta(S,_,_).
state(S) :- delta(_,_,S).
all_states(S) :- setof(X,state(X),S1), setof(X,state(X),S2),
                 union(S1,S2,S).
member(X,[X|L]) :- !.
member(X,[Y|L]) :- member(X,L).
union([],S,S).
union([X|L],S1,S) :- member(X,S1),!,union(L,S1,S).
union([X|L],S1,[X|S]) :- union(L,S1,S). 
intersect([],S,[]).
intersect([X|L],S1,[X|S]) :- member(X,S1),!,intersect(L,S1,S).
intersect([X|L],S1,S) :- intersect(L,S1,S). 
e_path(Q,Q).
e_path(Q,R) :- delta(Q,nil,R).
e_path(Q,R) :- delta(Q,nil,P), e_path(P,R).
e_closure(Q,C) :- setof(R,e_path(Q,R),C).
set_e_closure([],[]).
set_e_closure([Q|L],D) :- e_closure(Q,C), set_e_closure(L,M),
                          union(C,M,D).
set_d([],X,[]).
set_d([Q|L],X,D) :- d(Q,X,P1), set_d(L,X,P2), union(P1,P2,D).
d(Q,A,S) :- setof(P,delta(Q,A,P),S),!.
d(Q,A,[]).
rm_etrans :- tell('out.dat'),alphabet(A),print_start,all_states(S),
             process(A,S),decide_final(S), told.
print_start :- start_state(S), write(start_state), write('('), write(S),
               write(')'), write('.'),nl. 
process(A,[]).
process(A,[Q|L]) :- process_state(A,Q), process(A,L).
process_state([],Q).
process_state([X|L],Q) :- e_closure(Q,C), set_d(C,X,D),
              set_e_closure(D,P), output(Q,X,P), process_state(L,Q).
output(Q,X,[]).
output(Q,X,[P|L]) :- write(delta),write('('),write(Q),write(','),
                     write(X), write(','), write(P), write(')'),
                     write('.'), nl, output(Q,X,L).
decide_final([]).
decide_final([Q|L]) :- e_closure(Q,C), all_final_states(F),
                       intersect(C,F,S), S \== [], !, write(final_state),
                       write('('), write(Q), write(')'), write('.'), nl,
                       decide_final(L).
decide_final([Q|L]) :- decide_final(L).





1/23/1998