%%-------------------------------------------------------------------------
%% Programa: Forma normal de Greibach
%%
%%
%% Manera de ejecutarse:
%%
%% lee_datos:-
%% assertz(gram("A1",[ ["A2","A3"] ]), gram),
%% assertz(gram("A2",[ ["A3","A1"], ["b"] ]), gram),
%% assertz(gram("A3",[ ["A1","A2"], ["a"] ]), gram).
%%
%%
%% gram("NOMBRE_DE_VARIABLE", [[PRODUCCION_1], [PRODUCCION_2], ..., [PRODUCCION_N]])
%%
%% PRODUCCION_N =
%% "PARTE_DE_PRODUCCION", ""PARTE_DE_PRODUCCION", ... "PARTE_DE_PRODUCCION"
%%
%%
cciones)
%% A1 ---------> A2 A3
%% A2 ---------> A3 A1 | b
%% A3 ---------> A1 A2 | a
%%-------------------------------------------------------------------------
domains
st = string
lst = st*
producciones = lst*
database - gram
gram(st, producciones)
database - temp
temp(producciones)
database - g_s
g_s(st, producciones)
predicates
entorno
lee_datos
paso1
paso2
paso3
ok(st, lst)
inserta(st, lst, producciones)
unir(lst, lst, lst)
al_final(producciones, producciones, producciones)
resultado
new(lst, lst)
new_prod(st)
inserta_B(st, lst)
change(st, st)
agrega(producciones, lst)
modifica(st)
clauses
entorno:-
makewindow(1,7,7,"Forma Normal de Greibach GNF",0,0,25,80).
lee_datos:-
assertz(gram("A1",[ ["A2","A3"] ]), gram),
assertz(gram("A2",[ ["A3","A1"], ["b"] ]), gram),
assertz(gram("A3",[ ["A1","A2"], ["a"] ]), gram).
paso1:-
gram(Nom, [Prod|_]), ok(Nom, Prod), fail.
paso1:-!.
paso2:-
gram(Nom, [[H|_]|_]),
Nom = H, frontstr(1,Nom,_,Num), concat("B",Num,Name),
gram(Name,_), change(Nom, Name), fail.
paso2:-!.
paso3:-
g_s(Nom,_),
modifica(Nom), fail.
paso3:-!.
modifica(N):-
gram(Nom, [[N|H]|T]),
g_s(N, Producs),
agrega(Producs, H),
temp(Prod), al_final(Prod, T, New_prods), !,
retractall(gram(Nom,[[N|H]|T]), gram), %% elimina Ak --> Ak alfa
assertz(g_s(Nom, New_prods), g_s),
retractall(_,temp), assertz(temp([]), temp),
paso3.
change(A, B):-
gram(A, [_|Ta]),
agrega(Ta,[B]), temp(Prod), al_final(Prod, Ta, New_prods), !,
retractall(gram(A,_), gram), %% elimina Ak --> Ak alfa
assertz(g_s(A, New_prods), g_s),
retractall(_,temp), assertz(temp([]), temp).
agrega([],_):-!.
agrega([H|T], B):-
unir(H,B,H1), temp(Prod),
al_final(Prod,[H1],New_prods), !,
retractall(_,temp), assertz(temp(New_prods), temp),
agrega(T, B).
agrega(T,B):-
agrega(T,B),
write("Fin\n", T, "\n", B), readchar(_), !.
ok(_,[]):-!.
ok(N, [H|_]):-
N = N, frontchar(H, Frente, Rest), char_int(Frente, Asc),
frontstr(1,H,_,Rest1), str_int(Rest1, N1),
frontstr(1,N,_,Rest2), str_int(Rest2, N2),
ok(N, [H|Resto]):- %% N2 < N1
gram(H, Nuevo),
inserta(N, Resto, Nuevo), !,
gram(N, [Prod|_]), ok(N, Prod), !,
new_prod(N).
inserta(_, _, []):-!.
inserta(N, Resto, [New_H|New_T]):-
unir(New_H, Resto, Unido), %% en ese orden.
temp(Temp),
al_final(Temp, [Unido], New_temp), %% lista temporal.
retractall(_, temp), assertz(temp(New_temp), temp), !,
inserta(N, Resto, New_T), !,
gram(N, [_|Tail]),
al_final(New_temp, Tail, New_tail), %% corrige original.
!, retractall(gram(N,_), gram), retractall(_, temp),
assertz(gram(N, New_tail), gram), !,
assertz(temp([]), temp).
unir([], Lista, Lista).
unir([X|L1], Lista2, [X|L3]):-
unir(L1, Lista2, L3).
al_final([], Lista, Lista).
al_final([X|L1], Lista2, [X|L3]):-
al_final(L1, Lista2, L3).
new_prod(N):-
gram(N,[H|_]), new(H, New_prod),
frontstr(1,N,_,Num), concat("B", Num, New_name),
not(gram(New_name,_)), !,
inserta_B(New_name, New_prod),
unir(New_prod, [New_name], New_produc),
inserta_B(New_name, New_produc).
new([_|T], T):-!.
inserta_B(Name, Prod):- %% es el primero
assertz(gram(Name, [Prod]), gram), !.
resultado:-
gram(N, Produccs),
write("\n", N, " ===> ", Produccs),
fail.
resultado:-
g_s(N, Produccs),
write("\n", N, " ===> ", Produccs),
fail.
goal
entorno,
retractall(_,gram), retractall(_,g_s),
retractall(_,temp), assertz(temp([]), temp),
lee_datos,
paso1,
paso2,
paso3,
resultado,
readchar(_).