%Metamodel A
%(1) All attributes of a data have distint names
attribute_distinct_names:-rdf(Data,mmA:'data.attr_of',Att1),
rdf(Data,mmA:'data.attr_of',Att2),
Att1\=Att2,
rdf(Att1,mmA:'attribute.name',Name1),
rdf(Att2,mmA:'attribute.name',Name2),
Name1=Name2.
%(2) Each data has a key attribute
exists_key:-setof(Att,(rdf(_,mmA:'data.attr_of',Att),rdf(Att,mmA:'attribute.key',literal(type(_,true)))),Keys),Keys=[].
%(3) Each data has a unique key attribute
unique_key :- rdf(Data,mmA:'data.attr_of',Att1),
rdf(Data,mmA:'data.attr_of',Att2),
Att1\=Att2,
rdf(Att1,mmA:'attribute.key',literal(type(_,true))),
rdf(Att2,mmA:'attribute.key',literal(type(_,true))).
%(4) Each attribute is associated to exactly one data
unique_data_attribute:-rdf(Att,rdf:type,mmA:attribute),
rdf(Att,mmA:'attribute.is',Data1),
rdf(Att,mmA:'attribute.is',Data2),
Data1\=Data2.
%(5) Each data is contained in exactly one store
unique_store_data:-
setof(Store,rdf(_,mmA:'data.contained_in',Store),Stores),Stores=[_,_|_].
%(6) All data have distinct names
unique_name_data :- rdf(Data,mmA:'data.name',Name1),
rdf(Data,mmA:'data.name',Name2),
Name1\=Name2.
%(7) All data have distinct containers
unique_container_data :-rdf(Data,mmA:'data.container',Container1),
rdf(Data,mmA:'data.container',Container2),
Container1\=Container2.
%(8) Each qualifier is associated to exactly one role
unique_role_qualifier :- rdf(Qualifier,mmA:'qualifier.has',Role1),
rdf(Qualifier,mmA:'qualifier.has',Role2),
Role1\=Role2.
%(9) All qualifier names of a data are distinct
unique_name_qualifier :- rdf(Qualifier,mmA:'qualifier.name',Name1),
rdf(Qualifier,mmA:'qualifier.name',Name2),
Name1\=Name2.
%(10) All qualifiers are key attributes
qualifiers_are_keys :- rdf(_,mmA:'qualifier.name',Name),
\+
(rdf(Attribute,mmA:'attribute.name',Name),rdf(Attribute,mmA:'attribute.key',literal(type(_,true)))).
%(11) Each relation has two roles
two_roles_relation :-
setof(Role,rdf(_,mmA:'relation.is_role',Role),Roles),Roles\=[_,_].
%(12) All relation names are distinct
unique_name_relations:-rdf(Relation1,mmA:'relation.name',Name1),
rdf(Relation2,mmA:'relation.name',Name2),
Relation1\=Relation2,
Name1=Name2.
%(13) Each role is associated to exactly one relation
unique_relation_role:-rdf(Role,mmA:'role.has_role',Relation1),
rdf(Role,mmA:'role.has_role',Relation2),
Relation1\=Relation2.
%(14) Each role is associated to exactly one data
unique_data_role:-rdf(Role,mmA:'role.isdata',Data1),
rdf(Role,mmA:'role.isdata',Data2),
Data1\=Data2.
%(15) All role names of a data are distinct
unique_role_names_data :-rdf(Data,mmA:'data.role_of',Role1),
rdf(Data,mmA:'data.role_of',Role2),
rdf(Role1,mmA:'role.name',Name1),
rdf(Role2,mmA:'role.name',Name2),
Role1\=Role2,
Name1=Name2.
%(16) Each store is associated to exactly one data
unique_data_store :- rdf(Store,mmA:'store.contains',Data1),
rdf(Store,mmA:'store.contains',Data2),
Data1\=Data2.
%Metamodel B
%(17) All col names of a row are distinct
unique_col_names_row :-rdf(Row,mmB:'row.is_col',Col1),
rdf(Row,mmB:'row.is_col',Col2),
Col1\=Col2,
rdf(Col1,mmB:'col:name',Name1),
rdf(Col2,mmB:'col:name',Name2),
Name1=Name2.
%(18) All foreign names of a row are distinct
unique_foreign_names_row :-rdf(Row,mmB:'row.is_foreign',Foreign1),
rdf(Row,mmB:'row.is_foreign',Foreign2),
Foreign1\=Foreign2,
rdf(Foreign1,mmB:'foreign:name',Name1),
rdf(Foreign2,mmB:'foreign:name',Name2),
Name1=Name2.
%(19) All key names of a row are distinct
unique_key_names_row :-rdf(Row,mmB:'row.is_key',Key1),
rdf(Row,mmB:'row.is_key',Key2),
Key1\=Key2,
rdf(Key1,mmB:'key:name',Name1),
rdf(Key2,mmB:'key:name',Name2),
Name1=Name2.
%(20) All foreigns of a row are keys of another row
foreign_keys:-rdf(R,mmB:'row.is_foreign',A),
rdf(R,mmB:'row.name',N),
rdf(A,mmB:'foreign.name',Name),
N=literal(type(_,RC)),
Name=literal(type(_,NN)),
concat(RC,NameKey,NN),
\+
rdf(_,mmB:'key.name',literal(type(_,NameKey))).
%(21) Each table is associated to exactly one row
unique_table_row :- rdf(Table,mmB:'table.has',Row1),
rdf(Table,mmB:'table.has',Row2),
Row1\=Row2.
%(22) Each row is associated to exactly one table
unique_row_table:-rdf(Row,mmB:'row.table',Table1),
rdf(Row,mmB:'row.table',Table2),
Table1\=Table2.
%(23) Each key is associated to exactly one row
unique_row_key :- rdf(Key,mmB:'key.has_key',Row1),
rdf(Key,mmB:'key.has_key',Row2),
Row1\=Row2.
%(24) Each col is associated to exactly one row
unique_row_col :- rdf(Col,mmB:'col.has_col',Row1),
rdf(Col,mmB:'col.has_col',Row2),
Row1\=Row2.
%(25) Each foreign is associated to exactly one row
unique_row_foreign :- rdf(Foreign,mmB:'foreign.has_foreign',Row1),
rdf(Foreign,mmB:'foreign.has_foreign',Row2),
Row1\=Row2.
%(26) All table names are distinct
unique_table_names :- rdf(Table1,mmB:'table.name',Name1),
rdf(Table2,mmB:'table.name',Name2),
Table1\=Table2,
Name1=Name2.
%(27) All row names are distinct
unique_row_names :- rdf(Row1,mmB:'row.name',Name1),
rdf(Row2,mmB:'row.name',Name2),
Row1\=Row2,
Name1=Name2.
%(28) All rows have exactly one key
unique_key_row :- rdf(Row,mmB:'row.is_key',Key1),
rdf(Row,mmB:'row.is_key',Key2),
Key1\=Key2.
%(29) All rows have either all keys and cols or all foreigns
well_formed_rows:-rdf(Row,mmB:'row.is_key',_),
rdf(Row,mmB:'row.is_foreign',_).
well_formed_rows:-rdf(Row,mmB:'row.is_col',_),
rdf(Row,mmB:'row.is_foreign',_).
%Transformation
%(30) Key and col names and types are names and types of attributes
names_and_types :- rdf(_,mmB:'key.name',Name),
\+rdf(_,mmA:'attribute.name',Name).
names_and_types :- rdf(_,mmB:'key.type',Type),
\+rdf(_,mmA:'attribute.type',Type).
names_and_types :- rdf(_,mmB:'col.name',Name),
\+rdf(_,mmA:'attribute.name',Name).
names_and_types :- rdf(_,mmB:'col.type',Type),
\+rdf(_,mmA:'attribute.type',Type).
%(31) Table names are either container names or role names
containers_or_roles :- rdf(_,mmB:'table.name',Name),
\+rdf(_,mmA:'role.name',Name),
\+rdf(_,mmA:'data.container',Name).
%(32) Row names are data names or concatenations of role names and
data
data_or_roles_and_data :- rdf(_,mmB:'row.name',Name),
Name=literal(type(_,N)),
\+
rdf(_,mmA:'data.name',Name),
\+
(rdf(_,mmA:'role.name',Name1),
rdf(_,mmA:'data.name',Name2),
Name1=literal(type(_,N1)),
Name2=literal(type(_,N2)),
concat(N1,N2,N)).
%(33) Foreign names are concatenations of roles, data and key
attributes
foreign_names :-
rdf(_,mmB:'foreign.name',Name),Name=literal(type(_,N)),
\+
(rdf(_,mmA:'role.name',Name1),Name1=literal(type(_,N1)),
rdf(_,mmA:'data.name',Name2),Name2=literal(type(_,N2)),
rdf(_,mmA:'attribute.name',Name3),Name3=literal(type(_,N3)),
rdf(_,mmA:'attribute.key',Key),
Key=literal(type(_,true)),
concat(N1,N2,NAux),
concat(NAux,N3,N)).