% Lusenti Simone 717030
%
%
%
%% Gestione delle espressioni regolari
%regular_expression(RE), vero se RE è una regexp (caso base atomic/1).
regular_expression(RE) :- atomic(RE).
regular_expression([RE|REs]) :- regular_expression(RE), regular_expression(REs).
regular_expression(or(RE1,RE2)) :- regular_expression(RE1), regular_expression(RE2).
regular_expression(star(RE)) :- regular_expression(RE).
regular_expression(plus(RE)) :- regular_expression(RE).
% PROBLEMI: devo controllare che l'argomento di oneOf sia una lista di
% atomi... uso una funzione di supporto??? Così non funziona...
%regular_expression(oneof(RE)) :- RE=[].
% regular_expression(oneof([H|RE])) :- is_list(RE), RE\=[], atomic(H),
% regular_expression(oneof(RE)).
%% Manipolazione knowledge base degli NFA
clear_nfas :- retract(initial(_,_)), retract(final(_,_)), retract(delta(_,_,_,_)).
clear_nfa(FA_Id) :- nonvar(FA_Id), !, retract(initial(FA_Id,_)), retract(final(FA_Id,_)), retract(delta(FA_Id,_,_,_)).
list_nfas :- findall(FA_Id,compile2nfa(FA_Id,_),FAs).
list_nfa(FA_Id) :- nonvar(FA_Id), findall(FA_Id,compile2nfa(FA_Id,_),FAs).
%% Predicati di supporto
%da inserire nella knowledge base tramite assert
%delta(FA_Id, Initial, Input, Final)
%initial(FA_Id, State)
%final(FA_Id, State)
% compile2nfa(FA_Id, RE) è vero quando RE è compilabile in un automa
% nella base di dati (FA_Id è l'identificatore dell'automa nella base
% di dati Prolog).
%Numerazione degli stati...
% nfa_status(FA_ID, Status, StatusList) :- nonvar(Status),
% assert(append(Status,StatusList)).
:- dynamic last_status/2.
:- dynamic final/2.
:- dynamic initial/2.
:- dynamic delta/2.
%compile2nfa
compile2nfa(FA_Id, RE) :- regular_expression(RE), assert(initial(FA_Id,0)), assert(last_status(FA_Id,0)), parse_expression(FA_Id, RE).
%funzione ricorsiva per "decomporre" la regexp
%
% se ho terminato la RegExp (lista vuota) allora l'ultimo stato creato
% sarà finale
%PROBLEMA: Come numerare gli stati...
%PROBLEMA: Ricorsione infinita su "Simbolo []"
%espressione vuota
parse_expression(FA_Id, []) :- write('Stop ricorsione: Lista vuota'), nl.
%atomica
%PROBLEMA: Test RE\=[] per evitare ricorsine infinita... funzionerà?
parse_expression(FA_Id, RE) :- atomic(RE), write('Simbolo '), write(RE), nl, parse_expression(FA_Id, []).
%chiusura
parse_expression(FA_Id, star(RE)) :- write('Zero o più volte '),write(RE),nl, parse_expression(FA_Id, RE).
%or
parse_expression(FA_Id, or(RE1,RE2)) :- write('O '), write(RE1), write(' o '),write(RE2), nl, parse_expression(FA_Id, RE1), parse_expression(FA_Id, RE2).
%plus
parse_expression(FA_Id, plus(RE)) :- write('Almeno una volta '), write(RE), nl, parse_expression(FA_Id, RE).
%oneof
parse_expression(FA_Id, oneof(RE)) :- is_list(RE), write('Una espressione tra '), write(RE), nl, parse_expression(FA_Id, RE).
%lista
parse_expression(FA_Id, [H|RE]) :- write('Concatenazione di '), write(H), write(', '), write(RE), nl, parse_expression(FA_Id,H), parse_expression(FA_Id, RE).
% recognize(FA_Id, Input) è vero quando Input applicato a FA_ID porta in
% uno stato accettante.