:-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(mmA,  'http://metamodelA.ecore#').
rdf_db:ns(mmB,  'http://metamodelB.ecore#').

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


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

load_models(File1,File2):-
        rdf_reset_db,rdf_load(File1),rdf_load(File2).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 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.

%%%%%%%%%%%%%%%%%
% GENERATE_ID
%%%%%%%%%%%%%%%%%

generate_id([Id|RId],IdG):-generate_id2(RId,IdRId),atom_concat(Id,IdRId,IdG).

generate_id2([Object],Object).

generate_id2([Id|RId],IdG):-Id=literal(type(_,Pointer)),!,generate_id2(RId,IdRId),atom_concat(Pointer,IdRId,IdG).

generate_id2([Id|RId],IdG):-rdf_split_url(_,Pointer,Id),generate_id2(RId,IdRId),atom_concat(Pointer,IdRId,IdG).

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

    

%% TABLES

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

newrdf(N,rdf:type,'http://metamodelB.ecore#table'):-
                       
                    rdf(C,'http://metamodelA.ecore#role.navigable',E),
                    E=literal(type(_,true)),
                    generate_id([C,'table2'],N).
                         

%%% ROWS

newrdf(N,rdf:type,'http://metamodelB.ecore#row'):-
                    rdf(A,rdf:type,'http://metamodelA.ecore#data'),
                    generate_id([A,'row1'],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)),
                    generate_id([C,A,'row2'],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)),
                    generate_id([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)),
                    generate_id([B,'key'],N).
                    

newrdf(N,rdf:type,'http://metamodelB.ecore#foreign'):-
 
                        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),
                        generate_id([A,G,D,'foreign1'],N).
                        

newrdf(N,rdf:type,'http://metamodelB.ecore#foreign'):-
                        
                        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),
                        generate_id([A,G,D3,'foreign2'],N).
                        

%% REL TABLES AND ROWS

newrdf(T,'http://metamodelB.ecore#table.has',R):-
            rdf(A,rdf:type,'http://metamodelA.ecore#data'),
            generate_id([A,'table1'],T),
            generate_id([A,'row1'],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)),
                generate_id([C,'table2'],T),
                generate_id([C,A,'row2'],R).
                
                
%%% REL ROWS AND COLS,KEYS,FOREIGNS

newrdf(R,'http://metamodelB.ecore#row.is_col',CL):-
                    rdf(A,rdf:type,'http://metamodelA.ecore#data'),
                    
                    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)),
                    generate_id([A,'row1'],R),
                    generate_id([B,'col'],CL).
                    

newrdf(R,'http://metamodelB.ecore#row.is_key',K):-
                    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)),
                    generate_id([A,'row1'],R),
                    generate_id([B,'key'],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(CF,'http://metamodelA.ecore#role.is',D),
                    rdf(G,'http://metamodelA.ecore#data.role_of',CF),
                    generate_id([CF,A,'row2'],R),
                    generate_id([CF,G,D,'foreign1'],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(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),
                    generate_id([C,A,'row2'],R),
                    generate_id([C,G,D3,'foreign2'],FN).
                    
                

%% TABLE NAMES

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

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

%% ROW NAMES

 

newrdf(N,'http://metamodelB.ecore#row.name',B):-
                    rdf(A,'http://metamodelA.ecore#data.name',B),
                    generate_id([A,'row1'],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),
                    generate_id([C,A,'row2'],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)),
                    generate_id([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)),
                    generate_id([A,'key'],N).
                    

newrdf(N,'http://metamodelB.ecore#foreign.name',literal(type(String,K))):-
                        
                        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(_,PointerH,NH),
                        rdf_split_url(_,PointerF,NF),
                        atom_concat(NB,PointerH,B1),
                        atom_concat(B1,PointerF,K),
                        generate_id([A,G,D,'foreign1'],N).
                        

newrdf(N,'http://metamodelB.ecore#foreign.name',literal(type(String,K))):-
                        
                        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(_,PointerH,NH),
                        rdf_split_url(_,PointerF,NF),
                        atom_concat(NB,PointerH,B1),
                        atom_concat(B1,PointerF,K),
                        generate_id([A,G,D3,'foreign2'],N).
                                                 

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)),
                    generate_id([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)),
                    generate_id([A,'key'],N).
                    

newrdf(N,'http://metamodelB.ecore#foreign.type',T):-
                        
                        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(D,'http://metamodelA.ecore#qualifier.type',T),
                        generate_id([A,G,D,'foreign1'],N).
                        
                        
newrdf(N,'http://metamodelB.ecore#foreign.type',T):-
                        
                        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(D3,'http://metamodelA.ecore#qualifier.type',T),
                        generate_id([A,G,D3,'foreign2'],N).