:-use_module(library('semweb/rdf_db')).
:-use_module(library('semweb/rdfs')).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  ENTITY-RELATIONSHIP-RELATIONAL TRANSFORMATION EXAMPLE
%  Author: Jesus Almendros and Luis Iribarne. March 2010.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%%%%%%%%%
% NAMESPACES HANDLING
%%%%%%%%%%%%%%%%%%%%%%%

rdf_db:ns(rdf,  'http://www.w3.org/1999/02/22-rdf-syntax-ns#').
rdf_db:ns(metamodelA,  'http://metamodelA.ecore#').
rdf_db:ns(metamodelB,  'http://metamodelB.ecore#').

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% LOAD (FOR DEBUGGING ONLY)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


load(File):-
        rdf_reset_db,rdf_load(File).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% TRANSFORM (+OntologyInput,+OntologyOutput)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

transform(_,_):-rdf_reset_db,fail.

transform(_,_):-retractall(new(_,_,_)),fail.

transform(FileIn,_):-rdf_load(FileIn,[]),fail.

transform(_,_):-newrdf(A,B,C),assert(new(A,B,C)),fail.

transform(_,_):-rdf_reset_db,fail.

transform(_,_):-new(A,B,C),rdf_global_term(B,D),rdf_assert(A,D,C),fail.

transform(_,FileOut):-rdf_save(FileOut),rdf_reset_db.

 
%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% TRANSFORMATION EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%%

    

%% TABLES

newrdf(N,rdf:type,'http://metamodelB.ecore#table'):-
                    rdf(A,rdf:type,'http://metamodelA.ecore#data'),
                    atom_concat(A,'table',N).

newrdf(N,rdf:type,'http://metamodelB.ecore#table'):-
                    rdf(_,'http://metamodelA.ecore#data.role_of',C),  
                    rdf(C,'http://metamodelA.ecore#role.navigable',E),
                    E=literal(type(_,true)),
                        atom_concat(C,'table',N).

%%% ROWS

newrdf(N,rdf:type,'http://metamodelB.ecore#row'):-
                    rdf(A,rdf:type,'http://metamodelA.ecore#data'),
                    atom_concat(A,'row',N).

newrdf(N,rdf:type,'http://metamodelB.ecore#row'):-   
                    rdf(A,'http://metamodelA.ecore#data.role_of',C),
                    rdf(C,'http://metamodelA.ecore#role.navigable',E),
                    E=literal(type(_,true)),
                    rdf_split_url(_,Pointer,A),
                    atom_concat(C,Pointer,F),
                    atom_concat(F,'row',N).
%% COLS AND KEYS

newrdf(N,rdf:type,'http://metamodelB.ecore#col'):-    
                    rdf(A,rdf:type,'http://metamodelA.ecore#data'),
                    rdf(A,'http://metamodelA.ecore#data.attr_of',B),
                    
                    rdf(B,'http://metamodelA.ecore#attribute.key',C),
                    C=literal(type(_,false)),
                    atom_concat(B,'col',N).

newrdf(N,rdf:type,'http://metamodelB.ecore#key'):-
                    rdf(A,rdf:type,'http://metamodelA.ecore#data'),
                    rdf(A,'http://metamodelA.ecore#data.attr_of',B),
                    
                    rdf(B,'http://metamodelA.ecore#attribute.key',C),
                    C=literal(type(_,true)),
                    atom_concat(B,'key',N).

newrdf(N,rdf:type,'http://metamodelB.ecore#foreign'):-
                        rdf(_,'http://metamodelA.ecore#data.role_of',A),
                        rdf(A,'http://metamodelA.ecore#role.navigable',E),
                        E=literal(type(_,true)),
                         rdf(A,'http://metamodelA.ecore#role.is',D),
                        rdf(G,'http://metamodelA.ecore#data.role_of',A),
                        rdf_split_url(_,PointerG,G),
                        rdf_split_url(_,PointerD,D),
                        atom_concat(A,PointerG,N1),
                        atom_concat(N1,PointerD,N2),
                        atom_concat(N2,'foreign',N).

newrdf(N,rdf:type,'http://metamodelB.ecore#foreign'):-
                        rdf(_,'http://metamodelA.ecore#data.role_of',A),
                        rdf(A,'http://metamodelA.ecore#role.navigable',E),
                        E=literal(type(_,true)),
                         rdf(A,'http://metamodelA.ecore#role.has_role',D),
                        rdf(D,'http://metamodelA.ecore#relation.is_role',D2),
                        rdf(D2,'http://metamodelA.ecore#role.is',D3),
                        D2\==A,
                        rdf(G,'http://metamodelA.ecore#data.role_of',A),
                        rdf_split_url(_,PointerG,G),
                        rdf_split_url(_,PointerD,D3),
                        atom_concat(A,PointerG,N1),
                        atom_concat(N1,PointerD,N2),
                        atom_concat(N2,'foreign',N).

%% REL TABLES AND ROWS

newrdf(T,'http://metamodelB.ecore#table.has',R):-
            rdf(A,rdf:type,'http://metamodelA.ecore#data'),
            atom_concat(A,'table',T),
            atom_concat(A,'row',R).

newrdf(T,'http://metamodelB.ecore#table.has',R):-
                rdf(A,'http://metamodelA.ecore#data.role_of',C),
                rdf(C,'http://metamodelA.ecore#role.navigable',E),
                E=literal(type(_,true)),
                rdf_split_url(_,Pointer,A),
                atom_concat(C,'table',T),
                atom_concat(C,Pointer,F),atom_concat(F,'row',R).
                
%%% REL ROWS AND COLS,KEYS,FOREIGNS

newrdf(R,'http://metamodelB.ecore#row.is_col',CL):-
                    rdf(A,rdf:type,'http://metamodelA.ecore#data'),
                    atom_concat(A,'row',R),
                    rdf(A,'http://metamodelA.ecore#data.attr_of',B),
                    rdf(B,'http://metamodelA.ecore#attribute.name',_),
                    rdf(B,'http://metamodelA.ecore#attribute.key',C),
                    C=literal(type(_,false)),
                    atom_concat(B,'col',CL).

newrdf(R,'http://metamodelB.ecore#row.is_key',K):-
                    rdf(A,rdf:type,'http://metamodelA.ecore#data'),
                    atom_concat(A,'row',R),
                    rdf(A,'http://metamodelA.ecore#data.attr_of',B),
                    rdf(B,'http://metamodelA.ecore#attribute.name',_),
                    rdf(B,'http://metamodelA.ecore#attribute.key',C),
                    C=literal(type(_,true)),
                    atom_concat(B,'col',K).

newrdf(R,'http://metamodelB.ecore#row.is_foreign',FN):-   
                    rdf(A,'http://metamodelA.ecore#data.role_of',CF),
                    rdf(CF,'http://metamodelA.ecore#role.navigable',E),
                    E=literal(type(_,true)),
                    rdf_split_url(_,Pointer,A),
                    atom_concat(CF,Pointer,F),
                    atom_concat(F,'row',R),
                    rdf(CF,'http://metamodelA.ecore#role.is',D),
                    rdf(G,'http://metamodelA.ecore#data.role_of',CF),
                    rdf_split_url(_,PointerG,G),
                    rdf_split_url(_,PointerD,D),
                    atom_concat(CF,PointerG,N1),
                    atom_concat(N1,PointerD,N2),
                    atom_concat(N2,'foreign',FN).

newrdf(R,'http://metamodelB.ecore#row.is_foreign',FN):-   
                    rdf(A,'http://metamodelA.ecore#data.role_of',C),
                    rdf(C,'http://metamodelA.ecore#role.navigable',E),
                    E=literal(type(_,true)),
                    rdf_split_url(_,Pointer,A),
                    atom_concat(C,Pointer,F),
                    atom_concat(F,'row',R),    
                     rdf(C,'http://metamodelA.ecore#role.has_role',D),
                    rdf(D,'http://metamodelA.ecore#relation.is_role',D2),
                    rdf(D2,'http://metamodelA.ecore#role.is',D3),
                    D2\==C,
                    rdf(G,'http://metamodelA.ecore#data.role_of',C),
                    rdf_split_url(_,PointerG,G),
                    rdf_split_url(_,PointerD,D3),
                    atom_concat(C,PointerG,N1),
                    atom_concat(N1,PointerD,N2),
                    atom_concat(N2,'foreign',FN).
                

%% TABLE NAMES

newrdf(N,'http://metamodelB.ecore#table.name',B):-
                        rdf(A,'http://metamodelA.ecore#data.container',B),
                        atom_concat(A,'table',N).

newrdf(N,'http://metamodelB.ecore#table.name',B):-
                    rdf(_,'http://metamodelA.ecore#data.role_of',A),
                    rdf(A,'http://metamodelA.ecore#role.name',B),
                    rdf(A,'http://metamodelA.ecore#role.navigable',C),
                    C=literal(type(_,true)),atom_concat(A,'table',N).

%% ROW NAMES

newrdf(N,'http://metamodelB.ecore#row.name',B):-
                    rdf(A,'http://metamodelA.ecore#data.name',B),
                    atom_concat(A,'row',N).

newrdf(N,'http://metamodelB.ecore#row.name',literal(type(Str,F))):-
                    rdf(A,'http://metamodelA.ecore#data.name',B),
                    B=literal(type(Str,BN)),
                    rdf(A,'http://metamodelA.ecore#data.role_of',C),
                    rdf(C,'http://metamodelA.ecore#role.name',D),
                    D=literal(type(_,DN)),
                    rdf(C,'http://metamodelA.ecore#role.navigable',E),
                    E=literal(type(_,true)),
                    rdf_split_url(_,Pointer,BN),
                    atom_concat(DN,Pointer,F),
                    rdf_split_url(_,Pointer2,A),
                    atom_concat(C,Pointer2,K),
                    atom_concat(K,'row',N).

%%% COL AND KEY NAMES

newrdf(N,'http://metamodelB.ecore#col.name',B):-
                    rdf(J,rdf:type,'http://metamodelA.ecore#data'),
                    rdf(J,'http://metamodelA.ecore#data.attr_of',A),
                    rdf(A,'http://metamodelA.ecore#attribute.name',B),
                    rdf(A,'http://metamodelA.ecore#attribute.key',C),
                    C=literal(type(_,false)),
                    atom_concat(A,'col',N).

newrdf(N,'http://metamodelB.ecore#key.name',B):-
                    rdf(J,rdf:type,'http://metamodelA.ecore#data'),
                    rdf(J,'http://metamodelA.ecore#data.attr_of',A),
                    rdf(A,'http://metamodelA.ecore#attribute.name',B),
                    rdf(A,'http://metamodelA.ecore#attribute.key',C),
                    C=literal(type(_,true)),
                    atom_concat(A,'key',N).

newrdf(N,'http://metamodelB.ecore#foreign.name',literal(type(String,K))):-
                        rdf(_,'http://metamodelA.ecore#data.role_of',A),
                        rdf(A,'http://metamodelA.ecore#role.name',B),
                        B=literal(type(String,NB)),
                        rdf(A,'http://metamodelA.ecore#role.navigable',E),
                        E=literal(type(_,true)),
                         rdf(A,'http://metamodelA.ecore#role.is',D),
                        rdf(D,'http://metamodelA.ecore#qualifier.name',F),
                        F=literal(type(_,NF)),
                        rdf(G,'http://metamodelA.ecore#data.role_of',A),
                        rdf(G,'http://metamodelA.ecore#data.name',H),
                        H=literal(type(_,NH)),
                        rdf_split_url(_,PointerG,G),
                        rdf_split_url(_,PointerD,D),
                        atom_concat(A,PointerG,N1),
                        atom_concat(N1,PointerD,N2),
                        atom_concat(N2,'foreign',N),
                        rdf_split_url(_,PointerH,NH),
                        rdf_split_url(_,PointerF,NF),
                        atom_concat(NB,PointerH,B1),
                        atom_concat(B1,PointerF,K).

newrdf(N,'http://metamodelB.ecore#foreign.name',literal(type(String,K))):-
                        rdf(_,'http://metamodelA.ecore#data.role_of',A),
                        rdf(A,'http://metamodelA.ecore#role.name',B),
                        B=literal(type(String,NB)),
                        rdf(A,'http://metamodelA.ecore#role.navigable',E),
                        E=literal(type(_,true)),
                        rdf(A,'http://metamodelA.ecore#role.has_role',D),
                        rdf(D,'http://metamodelA.ecore#relation.is_role',D2),
                        rdf(D2,'http://metamodelA.ecore#role.is',D3),
                        D2\==A,
                        rdf(D3,'http://metamodelA.ecore#qualifier.name',F),
                        F=literal(type(_,NF)),
                        rdf(G,'http://metamodelA.ecore#data.role_of',A),
                        rdf(G,'http://metamodelA.ecore#data.name',H),
                        H=literal(type(_,NH)),
                        rdf_split_url(_,PointerG,G),
                        rdf_split_url(_,PointerD,D3),
                        atom_concat(A,PointerG,N1),
                        atom_concat(N1,PointerD,N2),
                        atom_concat(N2,'foreign',N),
                        rdf_split_url(_,PointerH,NH),
                        rdf_split_url(_,PointerF,NF),
                        atom_concat(NB,PointerH,B1),
                        atom_concat(B1,PointerF,K).

newrdf(N,'http://metamodelB.ecore#col.type',B):-
                    rdf(J,rdf:type,'http://metamodelA.ecore#data'),
                    rdf(J,'http://metamodelA.ecore#data.attr_of',A),
                    rdf(A,'http://metamodelA.ecore#attribute.type',B),
                    rdf(A,'http://metamodelA.ecore#attribute.key',C),
                    C=literal(type(_,false)),
                    atom_concat(A,'col',N).

newrdf(N,'http://metamodelB.ecore#key.type',B):-
                    rdf(J,rdf:type,'http://metamodelA.ecore#data'),
                    rdf(J,'http://metamodelA.ecore#data.attr_of',A),
                    rdf(A,'http://metamodelA.ecore#attribute.type',B),
                    rdf(A,'http://metamodelA.ecore#attribute.key',C),
                    C=literal(type(_,true)),
                    atom_concat(A,'key',N).

newrdf(N,'http://metamodelB.ecore#foreign.type',T):-
                        rdf(_,'http://metamodelA.ecore#data.role_of',A),
                        rdf(A,'http://metamodelA.ecore#role.navigable',E),
                        E=literal(type(_,true)),
                         rdf(A,'http://metamodelA.ecore#role.is',D),
                        rdf(G,'http://metamodelA.ecore#data.role_of',A),
                        rdf_split_url(_,PointerG,G),
                        rdf_split_url(_,PointerD,D),
                        atom_concat(A,PointerG,N1),
                        atom_concat(N1,PointerD,N2),
                        atom_concat(N2,'foreign',N),
                        rdf(D,'http://metamodelA.ecore#qualifier.type',T).
                        
newrdf(N,'http://metamodelB.ecore#foreign.type',T):-
                        rdf(_,'http://metamodelA.ecore#data.role_of',A),
                        rdf(A,'http://metamodelA.ecore#role.navigable',E),
                        E=literal(type(_,true)),
                         rdf(A,'http://metamodelA.ecore#role.has_role',D),
                        rdf(D,'http://metamodelA.ecore#relation.is_role',D2),
                        rdf(D2,'http://metamodelA.ecore#role.is',D3),
                        D2\==A,                        
                        rdf(G,'http://metamodelA.ecore#data.role_of',A),
                        rdf_split_url(_,PointerG,G),
                        rdf_split_url(_,PointerD,D3),
                        atom_concat(A,PointerG,N1),
                        atom_concat(N1,PointerD,N2),
                        atom_concat(N2,'foreign',N),
                        rdf(D3,'http://metamodelA.ecore#qualifier.type',T).