Chris@0: /* This file is part of ClioPatria. Chris@0: Chris@0: Author: Chris@0: HTTP: http://e-culture.multimedian.nl/ Chris@0: GITWEB: http://gollem.science.uva.nl/git/ClioPatria.git Chris@0: GIT: git://gollem.science.uva.nl/home/git/ClioPatria.git Chris@0: GIT: http://gollem.science.uva.nl/home/git/ClioPatria.git Chris@0: Copyright: 2007, E-Culture/MultimediaN Chris@0: Chris@0: ClioPatria is free software: you can redistribute it and/or modify Chris@0: it under the terms of the GNU General Public License as published by Chris@0: the Free Software Foundation, either version 2 of the License, or Chris@0: (at your option) any later version. Chris@0: Chris@0: ClioPatria is distributed in the hope that it will be useful, Chris@0: but WITHOUT ANY WARRANTY; without even the implied warranty of Chris@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Chris@0: GNU General Public License for more details. Chris@0: Chris@0: You should have received a copy of the GNU General Public License Chris@0: along with ClioPatria. If not, see . Chris@0: */ Chris@0: Chris@0: :- module(sesame_tests, Chris@0: [ test/1, Chris@0: test/0, Chris@0: view/1, Chris@0: in/1 Chris@0: ]). Chris@0: :- use_module(serql). Chris@0: :- use_module(library(rdf_ntriples)). Chris@0: :- use_module(library('semweb/rdf_db')). Chris@0: :- use_module(library(readutil)). Chris@0: :- use_module(library(debug)). Chris@0: :- use_module(rdfs_entailment, []). Chris@0: Chris@0: :- multifile Chris@0: user:file_search_path/2. Chris@0: Chris@0: user:file_search_path(sesame, '/staff/jan/src/openrdf'). Chris@0: Chris@0: Chris@0: test_dir(construct, Dir) :- Chris@0: absolute_file_name(sesame('test/files/testcases/SeRQL/CfwQuery'), Dir, Chris@0: [ file_type(directory), Chris@0: access(read) Chris@0: ]). Chris@0: Chris@0: assert_rdfs_triples :- Chris@0: catch(nb_getval(rdfs_triples, Triples), _, fail), !, Chris@0: forall(member(rdf(S,P,O), Triples), rdf_assert(S,P,O)). Chris@0: assert_rdfs_triples :- Chris@0: absolute_file_name(sesame('test/files/testcases/SeRQL/CfwQuery/test000-out.nt'), NT, Chris@0: [ access(read) Chris@0: ]), Chris@0: load_rdf_ntriples(NT, Triples), Chris@0: nb_setval(rdfs_triples, Triples), Chris@0: forall(member(rdf(S,P,O), Triples), rdf_assert(S,P,O)). Chris@0: Chris@0: test :- Chris@0: test_dir(construct, Dir), Chris@0: atom_concat(Dir, '/*-query', Pattern), Chris@0: expand_file_name(Pattern, Files), Chris@0: maplist(test_base, Files, Bases), Chris@0: ( member(Base, Bases), Chris@0: ( test_file(Base, true) Chris@0: -> put('.'), flush_output Chris@0: ; format('Test failed: ~w~n', [Base]) Chris@0: ), Chris@0: fail Chris@0: ; nl Chris@0: ). Chris@0: Chris@0: test_base(File, Base) :- Chris@0: atom_concat(Base, '-query', File). Chris@0: Chris@0: Chris@0: test(N) :- Chris@0: test_dir(construct, Dir), Chris@0: sformat(File, '~`0t~d~3|', [N]), Chris@0: concat_atom([Dir, '/test', File], Base), Chris@0: test_file(Base). Chris@0: Chris@0: view(N) :- Chris@0: test_dir(construct, Dir), Chris@0: sformat(File, '~`0t~d~3|', [N]), Chris@0: concat_atom([Dir, '/test', File], Base), Chris@0: atom_concat(Base, '-query', Query), Chris@0: edit(Query). Chris@0: in(N) :- Chris@0: test_dir(construct, Dir), Chris@0: sformat(File, '~`0t~d~3|', [N]), Chris@0: concat_atom([Dir, '/test', File], Base), Chris@0: atom_concat(Base, '-in.nt', Query), Chris@0: edit(Query). Chris@0: Chris@0: test_file(Base) :- Chris@0: test_file(Base, false). Chris@0: Chris@0: test_file(Base, Silent) :- Chris@0: atom_concat(Base, '-query', Query), Chris@0: atom_concat(Base, '-in.nt', InFile), Chris@0: atom_concat(Base, '-out.nt', OutFile), Chris@0: read_file_to_codes(Query, Codes, []), Chris@0: atom_codes(Text, Codes), % easier debugging Chris@0: rdf_reset_db, Chris@0: assert_rdfs_triples, Chris@0: load_rdf_ntriples(InFile, Triples), Chris@0: forall(member(rdf(S,P,O), Triples), rdf_assert(S,P,O)), Chris@0: findall(Statement, Chris@0: serql_query(Text, Statement, [entailment(rdfs)]), Chris@0: Statements), Chris@0: load_rdf_ntriples(OutFile, OutTriples), Chris@0: ( compare_triples(Statements, OutTriples, _Subst) Chris@0: -> true Chris@0: ; ( Silent == true Chris@0: -> fail Chris@0: ; report_difference(Statements, OutTriples), Chris@0: edit(Query) Chris@0: ) Chris@0: ). Chris@0: Chris@0: Chris@0: report_difference(Statements, OutTriples) :- Chris@0: format(user_error, 'WRONG ANSWER~n~n', []), Chris@0: format(user_error, ' *** Result ***:~n', []), Chris@0: list_triples(Statements, user_error), Chris@0: format(user_error, ' *** Official Result ***:~n', []), Chris@0: list_triples(OutTriples, user_error). Chris@0: Chris@0: Chris@0: list_triples([], _). Chris@0: list_triples([rdf(S,P,O)|T], Stream) :- Chris@0: rdf_global_id(LS, S), Chris@0: rdf_global_id(LP, P), Chris@0: ( nonvar(O), O = literal(_) Chris@0: -> LO = O Chris@0: ; rdf_global_id(LO, O) Chris@0: ), Chris@0: format(Stream, 'rdf(~p, ~p, ~p).~n', [LS, LP, LO]), Chris@0: list_triples(T, Stream). Chris@0: Chris@0: Chris@0: /******************************* Chris@0: * COMPARING * Chris@0: *******************************/ Chris@0: Chris@0: %% compare_triples(+PlRDF, +NTRDF, -Substitions) Chris@0: % Chris@0: % Compare two models and if they are equal, return a list of Chris@0: % PlID = NTID, mapping NodeID elements. Chris@0: Chris@0: Chris@0: compare_triples(A, B, Substitutions) :- Chris@0: compare_list(A, B, [], Substitutions). Chris@0: Chris@0: compare_list([], [], S, S). Chris@0: compare_list(L1, L2, S0, S) :- Chris@0: take_bag(L1, B1, E1, R1), !, Chris@0: take_bag(L2, B2, E2, R2), Chris@0: compare_field(B1, B2, S0, S1), Chris@0: compare_bags(E1, E2, S1, S2), Chris@0: compare_list(R1, R2, S2, S). Chris@0: compare_list([H1|T1], In2, S0, S) :- Chris@0: select(H2, In2, T2), Chris@0: compare_triple(H1, H2, S0, S1), % put(.), flush_output, Chris@0: compare_list(T1, T2, S1, S). Chris@0: Chris@0: compare_triple(rdf(Subj1,P1,O1), rdf(Subj2, P2, O2), S0, S) :- Chris@0: compare_field(Subj1, Subj2, S0, S1), Chris@0: compare_field(P1, P2, S1, S2), Chris@0: compare_field(O1, O2, S2, S). Chris@0: Chris@0: compare_field(X, X, S, S) :- !. Chris@0: compare_field(literal(X), xml(X), S, S) :- !. % TBD Chris@0: compare_field(NS:Name, Atom, S, S) :- Chris@0: rdf_global_id(NS:Name, Atom), !. Chris@0: compare_field(X, node(Id), S, S) :- Chris@0: memberchk(X=Id, S), !. Chris@0: compare_field(X, node(Id), S, [X=Id|S]) :- Chris@0: \+ memberchk(X=_, S), Chris@0: atom(X), Chris@0: rdf_is_bnode(X), !, Chris@0: debug(bnode, 'Assume ~w = ~w~n', [X, node(Id)]). Chris@0: Chris@0: Chris@0: %% compare_bags(+Members1, +Members2, +S0, -S) Chris@0: % Chris@0: % Order of _1, _2, etc. are not relevant in BadID reification. Are Chris@0: % they in general? Anyway, we'll normalise the order of the bags Chris@0: Chris@0: compare_bags([], [], S, S). Chris@0: compare_bags([E1|T1], M, S0, S) :- Chris@0: select(E2, M, T2), Chris@0: compare_field(E1, E2, S0, S1), Chris@0: compare_bags(T1, T2, S1, S). Chris@0: Chris@0: take_bag(Triples, Bag, Elems, RestTriples) :- Chris@0: select(rdf(Bag, Type, BagClass), Triples, T1), Chris@0: compare_field(rdf:type, Type, [], []), Chris@0: compare_field(rdf:'Bag', BagClass, [], []), Chris@0: bag_members(T1, Bag, Elems, RestTriples). Chris@0: Chris@0: bag_members([], _, [], []). Chris@0: bag_members([rdf(Bag, IsElm, E)|T], Bag, [E|ET], Rest) :- Chris@0: member_prop(IsElm), !, Chris@0: bag_members(T, Bag, ET, Rest). Chris@0: bag_members([T0|T], Bag, Elems, [T0|R]) :- Chris@0: bag_members(T, Bag, Elems, R). Chris@0: Chris@0: member_prop(rdf:Name) :- Chris@0: atom_codes(Name, [0'_|Codes]), Chris@0: number_codes(_N, Codes), !. Chris@0: member_prop(Prop) :- Chris@0: atom(Prop), Chris@0: rdf_parser:rdf_name_space(NS), Chris@0: atom_concat(NS, Name, Prop), Chris@0: atom_codes(Name, [0'_|Codes]), Chris@0: number_codes(_N, Codes), !.