%%           -*-Mode: prolog;-*-

:- multifile rx/2.
:- multifile macro/2.

%% Pereira-Riley composition

%% TODO: introduce symbols in transitions through pred_module interface
macro(prc(A,B),
      skip(l,mark(l,A))
          o
        filter
          o
      skip(r,mark(r,B))
     ).

macro(filter, ~ $ [t2,t1]).

macro(exa,[a,b x [],c x [],d]).
macro(exb,[a x d,[] x e,d x a]).

rx(mark(LR,A),Fa) :-
    fsa_regex:rx(A,Fa0),
    fsa_data:fsa_transitions(Fa0,Trans0),
    fsa_data:fsa_states_number(Fa0,NrStates),
    fsa_data:fsa_start_states(Fa0,Starts),
    fsa_data:fsa_final_states(Fa0,Finals),
    fsa_data:fsa_jumps(Fa0,Jumps),
    mark_trans(Trans0,Trans1,Trans2,LR),
    mark_trans(Jumps,Trans2,[],LR),
    sort(Trans1,Trans),
    fsa_data:fsa_construct(NrStates,Starts,Finals,Trans,[],Fa).

mark_trans([],L,L,_).
mark_trans([H|T],[H1|L0],L,LR) :-
    mark_trans1(LR,H,H1),
    mark_trans(T,L0,L,LR).


mark_trans1(l,jump(A,B),        trans(A,[]/t2,B)).
mark_trans1(r,jump(A,B),        trans(A,t1/[],B)).

mark_trans1(r,trans(A,X0/Y,B), trans(A, X/Y, B)):-
    (	X0 == []
    ->	X = t1
    ;   X=X0
    ).

mark_trans1(l,trans(A,X/Y0,B), trans(A, X/Y, B)):-
    (	Y0 == []
    ->	Y = t2
    ;   Y=Y0
    ).
    

%% voor elke toestand, voeg []:t1 toe.
rx(skip(LR,A),Fa) :-
    fsa_regex:rx(A,Fa0),
    fsa_data:fsa_copy_except(transitions,Fa0,Fa,Trans0,Trans),
    fsa_data:fsa_states_set(Fa0,States),
    skip(States,Trans1,Trans0,LR),
    sort(Trans1,Trans).

skip([],Trs,Trs,_).
skip([H0|T0],[H|Trs0],Trs,LR) :-
    skip1(LR,H0,H),
    skip(T0,Trs0,Trs,LR).

skip1(l,H,trans(H,[]/t1,H)).
skip1(r,H,trans(H,t2/[],H)).
