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