%%------------------------------------------------------------------------- %% 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(_).