:-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).