Chris@0
|
1 /* $Id$
|
Chris@0
|
2
|
Chris@0
|
3 Part of SWI-Prolog
|
Chris@0
|
4
|
Chris@0
|
5 Author: Jan Wielemaker
|
Chris@0
|
6 E-mail: wielemak@science.uva.nl
|
Chris@0
|
7 WWW: http://www.swi-prolog.org
|
Chris@0
|
8 Copyright (C): 2004-2006, University of Amsterdam
|
Chris@0
|
9
|
Chris@0
|
10 This program is free software; you can redistribute it and/or
|
Chris@0
|
11 modify it under the terms of the GNU General Public License
|
Chris@0
|
12 as published by the Free Software Foundation; either version 2
|
Chris@0
|
13 of the License, or (at your option) any later version.
|
Chris@0
|
14
|
Chris@0
|
15 This program is distributed in the hope that it will be useful,
|
Chris@0
|
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
Chris@0
|
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
Chris@0
|
18 GNU General Public License for more details.
|
Chris@0
|
19
|
Chris@0
|
20 You should have received a copy of the GNU Lesser General Public
|
Chris@0
|
21 License along with this library; if not, write to the Free Software
|
Chris@0
|
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Chris@0
|
23
|
Chris@0
|
24 As a special exception, if you link this library with other files,
|
Chris@0
|
25 compiled with a Free Software compiler, to produce an executable, this
|
Chris@0
|
26 library does not by itself cause the resulting executable to be covered
|
Chris@0
|
27 by the GNU General Public License. This exception does not however
|
Chris@0
|
28 invalidate any other reasons why the executable file might be covered by
|
Chris@0
|
29 the GNU General Public License.
|
Chris@0
|
30 */
|
Chris@0
|
31
|
Chris@0
|
32 :- module(test_manifest,
|
Chris@0
|
33 [ current_manifest/1, % ?Manifest
|
Chris@0
|
34 current_test/2, % ?Manifest, ?Test
|
Chris@0
|
35
|
Chris@0
|
36 test_name/2, % ?Test, ?Name
|
Chris@0
|
37 test_query/2, % +Test, -QueryCodes
|
Chris@0
|
38
|
Chris@0
|
39 test_query_file/2, % +Test, -QueryFile
|
Chris@0
|
40 test_data_file/2, % +Test, -DataFile
|
Chris@0
|
41 test_result_file/2, % +Test, -ResultFile
|
Chris@0
|
42
|
Chris@0
|
43 % EDIT
|
Chris@0
|
44 show_test/1, % NameOrURL
|
Chris@0
|
45 edit_test/1, % NameOrURL
|
Chris@0
|
46 show_test_data/1, % NameOrURL
|
Chris@0
|
47 edit_test_data/1, % NameOrURL
|
Chris@0
|
48 edit_test_result/1, % NameOrURL
|
Chris@0
|
49
|
Chris@0
|
50 % LOAD
|
Chris@0
|
51 load_manifests/1, % +RootManifest
|
Chris@0
|
52
|
Chris@0
|
53 % UTIL
|
Chris@0
|
54 load_triples_to_db/1, % +FileOrURL
|
Chris@0
|
55 load_triples/2, % +FileOrURL, -Triples
|
Chris@0
|
56 file_url/2 % ?File, ?URL
|
Chris@0
|
57 ]).
|
Chris@0
|
58 :- use_module(library(rdf)).
|
Chris@0
|
59 :- use_module(library(url)).
|
Chris@0
|
60 :- use_module(library('semweb/rdf_db')).
|
Chris@0
|
61 :- use_module(library('semweb/rdfs')).
|
Chris@0
|
62 :- use_module(rdf_turtle).
|
Chris@0
|
63
|
Chris@0
|
64 :- dynamic
|
Chris@0
|
65 mf_rdf/3.
|
Chris@0
|
66 :- rdf_meta
|
Chris@0
|
67 mf_rdf(r, r, o).
|
Chris@0
|
68
|
Chris@0
|
69 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
Chris@0
|
70 Generic code to deal with W3C/Semantic web test manifests. These are RDF
|
Chris@0
|
71 files in either RDF/XML or Turtle format.
|
Chris@0
|
72
|
Chris@0
|
73 As we have to do reasoning on the complete graph and frequently clear
|
Chris@0
|
74 the graph during testing we keep the triples for the manifest in the
|
Chris@0
|
75 Prolog database as mf_rdf(S,P,O).
|
Chris@0
|
76 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
Chris@0
|
77
|
Chris@0
|
78
|
Chris@0
|
79 % namespaces used to process the manifests and test suite.
|
Chris@0
|
80 :- rdf_register_ns(mf,
|
Chris@0
|
81 'http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#').
|
Chris@0
|
82 :- rdf_register_ns(mfx,
|
Chris@0
|
83 'http://jena.hpl.hp.com/2005/05/test-manifest-extra#').
|
Chris@0
|
84 :- rdf_register_ns(qt,
|
Chris@0
|
85 'http://www.w3.org/2001/sw/DataAccess/tests/test-query#').
|
Chris@0
|
86 :- rdf_register_ns(r,
|
Chris@0
|
87 'http://www.w3.org/2001/sw/DataAccess/tests/result-set#').
|
Chris@0
|
88
|
Chris@0
|
89 % namespaces used in some of the test-suites to enhance readability.
|
Chris@0
|
90 :- rdf_register_ns(tbool,
|
Chris@0
|
91 'http://www.w3.org/2001/sw/DataAccess/tests/data/ValueTesting/boolean-0#').
|
Chris@0
|
92 :- rdf_register_ns(texttype,
|
Chris@0
|
93 'http://www.w3.org/2001/sw/DataAccess/tests/data/ValueTesting/extendedType-0#').
|
Chris@0
|
94 :- rdf_register_ns(tpromote, 'http://www.w3.org/2001/sw/DataAccess/tests/data/ValueTesting/typePromotion-0#').
|
Chris@0
|
95 :- rdf_register_ns(ex, 'http://example.org/#').
|
Chris@0
|
96
|
Chris@0
|
97
|
Chris@0
|
98 data_dir('Tests/sparql/data-xml').
|
Chris@0
|
99
|
Chris@0
|
100
|
Chris@0
|
101 /*******************************
|
Chris@0
|
102 * QUERY *
|
Chris@0
|
103 *******************************/
|
Chris@0
|
104
|
Chris@0
|
105 %% current_manifest(?Manifest)
|
Chris@0
|
106 %
|
Chris@0
|
107 % True if Manifest is a test-manifest
|
Chris@0
|
108
|
Chris@0
|
109 current_manifest(Manifest) :-
|
Chris@0
|
110 mf_rdf(Manifest, rdf:type, mf:'Manifest').
|
Chris@0
|
111
|
Chris@0
|
112 %% current_test(?Manifest, ?Test)
|
Chris@0
|
113 %
|
Chris@0
|
114 % True if Test is a test in Manifest.
|
Chris@0
|
115
|
Chris@0
|
116 current_test(Manifest, Test) :-
|
Chris@0
|
117 current_manifest(Manifest),
|
Chris@0
|
118 mf_rdf(Manifest, mf:entries, Collection),
|
Chris@0
|
119 mf_member(Test, Collection).
|
Chris@0
|
120
|
Chris@0
|
121
|
Chris@0
|
122 %% test_name(?Test, ?Name)
|
Chris@0
|
123 %
|
Chris@0
|
124 % True if Name is the name associated with Test.
|
Chris@0
|
125
|
Chris@0
|
126 test_name(Test, Name) :-
|
Chris@0
|
127 var(Test), var(Name), !,
|
Chris@0
|
128 mf_rdf(Test, mf:name, literal(Name)).
|
Chris@0
|
129 test_name(Test, Name) :-
|
Chris@0
|
130 mf_rdf(Test, mf:name, literal(Name)), !.
|
Chris@0
|
131
|
Chris@0
|
132
|
Chris@0
|
133 %% test_query_file(+Test, -File)
|
Chris@0
|
134 %
|
Chris@0
|
135 % Get the file containing the query of Test
|
Chris@0
|
136
|
Chris@0
|
137 test_query_file(Test, File) :- % Normal cases
|
Chris@0
|
138 mf_rdf(Test, mf:action, Action),
|
Chris@0
|
139 mf_rdf(Action, qt:query, FileURI),
|
Chris@0
|
140 parse_url(FileURI, Parts), !,
|
Chris@0
|
141 memberchk(path(File), Parts).
|
Chris@0
|
142 test_query_file(Test, File) :- % SyntaxDev cases
|
Chris@0
|
143 mf_rdf(Test, mf:action, FileURI),
|
Chris@0
|
144 parse_url(FileURI, Parts), !,
|
Chris@0
|
145 memberchk(path(File), Parts).
|
Chris@0
|
146
|
Chris@0
|
147
|
Chris@0
|
148 %% test_data_file(+Test, -File)
|
Chris@0
|
149 %
|
Chris@0
|
150 % Get the file containing the data for Test
|
Chris@0
|
151
|
Chris@0
|
152 test_data_file(Test, File) :-
|
Chris@0
|
153 mf_rdf(Test, mf:action, Action),
|
Chris@0
|
154 mf_rdf(Action, qt:data, FileURI),
|
Chris@0
|
155 parse_url(FileURI, Parts), !,
|
Chris@0
|
156 memberchk(path(File), Parts).
|
Chris@0
|
157
|
Chris@0
|
158
|
Chris@0
|
159 %% test_result_file(+Test, -File)
|
Chris@0
|
160 %
|
Chris@0
|
161 % Test containg the result
|
Chris@0
|
162
|
Chris@0
|
163 test_result_file(Test, File) :-
|
Chris@0
|
164 mf_rdf(Test, mf:result, FileURI),
|
Chris@0
|
165 parse_url(FileURI, Parts), !,
|
Chris@0
|
166 memberchk(path(File), Parts).
|
Chris@0
|
167
|
Chris@0
|
168
|
Chris@0
|
169 %% test_query(+Test, -QueryCodes)
|
Chris@0
|
170
|
Chris@0
|
171 test_query(Test, Codes) :-
|
Chris@0
|
172 test_query_file(Test, File), !,
|
Chris@0
|
173 read_file_to_codes(File, Codes, []).
|
Chris@0
|
174 test_query(Test, _) :-
|
Chris@0
|
175 format('Cannot get query for test ~q~n', [Test]),
|
Chris@0
|
176 fail.
|
Chris@0
|
177
|
Chris@0
|
178
|
Chris@0
|
179 /*******************************
|
Chris@0
|
180 * LIST/EDIT *
|
Chris@0
|
181 *******************************/
|
Chris@0
|
182
|
Chris@0
|
183 show_test(Name) :-
|
Chris@0
|
184 test_name(Test, Name), !,
|
Chris@0
|
185 show_test(Test).
|
Chris@0
|
186 show_test(Test) :-
|
Chris@0
|
187 test_query(Test, Codes),
|
Chris@0
|
188 format('~s', [Codes]).
|
Chris@0
|
189
|
Chris@0
|
190
|
Chris@0
|
191 edit_test(Name) :-
|
Chris@0
|
192 test_name(Test, Name), !,
|
Chris@0
|
193 edit_test(Test).
|
Chris@0
|
194 edit_test(Test) :-
|
Chris@0
|
195 test_query_file(Test, File),
|
Chris@0
|
196 edit(file(File)).
|
Chris@0
|
197
|
Chris@0
|
198 show_test_data(Name) :-
|
Chris@0
|
199 test_name(Test, Name), !,
|
Chris@0
|
200 show_test_data(Test).
|
Chris@0
|
201 show_test_data(Test) :-
|
Chris@0
|
202 test_data_file(Test, File),
|
Chris@0
|
203 read_file_to_codes(File, Codes, []),
|
Chris@0
|
204 format('~s', [Codes]).
|
Chris@0
|
205
|
Chris@0
|
206 edit_test_data(Name) :-
|
Chris@0
|
207 test_name(Test, Name), !,
|
Chris@0
|
208 edit_test_data(Test).
|
Chris@0
|
209 edit_test_data(Test) :-
|
Chris@0
|
210 test_data_file(Test, File),
|
Chris@0
|
211 edit(file(File)).
|
Chris@0
|
212
|
Chris@0
|
213 edit_test_result(Name) :-
|
Chris@0
|
214 test_name(Test, Name), !,
|
Chris@0
|
215 edit_test_result(Test).
|
Chris@0
|
216 edit_test_result(Test) :-
|
Chris@0
|
217 test_result_file(Test, File),
|
Chris@0
|
218 edit(file(File)).
|
Chris@0
|
219
|
Chris@0
|
220
|
Chris@0
|
221 /************a*******************
|
Chris@0
|
222 * LOAD MANIFEST *
|
Chris@0
|
223 *******************************/
|
Chris@0
|
224
|
Chris@0
|
225 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
Chris@0
|
226 TBD: This should move in the generic semantic libraries, connected to
|
Chris@0
|
227 the core using a plugin extension mechanism.
|
Chris@0
|
228 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
Chris@0
|
229
|
Chris@0
|
230 %% load_manifests(+RootOrAlias)
|
Chris@0
|
231 %
|
Chris@0
|
232 % Load the manifest files
|
Chris@0
|
233
|
Chris@0
|
234 load_manifests(dawg) :- !,
|
Chris@0
|
235 data_dir(Dir),
|
Chris@0
|
236 atom_concat(Dir, '/manifest.{ttl,rdf}', Pattern),
|
Chris@0
|
237 expand_file_name(Pattern, [File]),
|
Chris@0
|
238 file_url(File, URL),
|
Chris@0
|
239 load_manifests(URL).
|
Chris@0
|
240 load_manifests(arq) :- !,
|
Chris@0
|
241 file_url('../ARQ/testing/ARQ/manifest-arq.ttl', URL),
|
Chris@0
|
242 load_manifests(URL).
|
Chris@0
|
243 load_manifests(Root) :-
|
Chris@0
|
244 retractall(mf_rdf(_,_,_)),
|
Chris@0
|
245 rdf_reset_db,
|
Chris@0
|
246 load_schemas,
|
Chris@0
|
247 load_manifest(Root),
|
Chris@0
|
248 forall(rdf(S,P,O), assert(mf_rdf(S,P,O))),
|
Chris@0
|
249 rdf_reset_db,
|
Chris@0
|
250 test_statistics.
|
Chris@0
|
251
|
Chris@0
|
252 test_statistics :-
|
Chris@0
|
253 findall(M, current_manifest(M), Ms),
|
Chris@0
|
254 length(Ms, MN),
|
Chris@0
|
255 findall(T, current_test(_, T), Ts),
|
Chris@0
|
256 length(Ts, TN),
|
Chris@0
|
257 format('Loaded ~D manifests with ~D tests~n', [MN, TN]).
|
Chris@0
|
258
|
Chris@0
|
259 load_schemas :-
|
Chris@0
|
260 data_dir(Dir),
|
Chris@0
|
261 atom_concat(Dir, '/test-manifest.rdf', S1),
|
Chris@0
|
262 atom_concat(Dir, '/test-dawg.rdf', S2),
|
Chris@0
|
263 atom_concat(Dir, '/test-query.rdf', S3),
|
Chris@0
|
264 maplist(load_triples_to_db, [S1,S2,S3]).
|
Chris@0
|
265
|
Chris@0
|
266 load_manifest(URL) :-
|
Chris@0
|
267 format('Loading ~w ...~n', [URL]),
|
Chris@0
|
268 load_triples_to_db(URL),
|
Chris@0
|
269 sub_manifests(URL, SubManifests),
|
Chris@0
|
270 forall(member(S, SubManifests),
|
Chris@0
|
271 load_manifest(S)).
|
Chris@0
|
272
|
Chris@0
|
273 sub_manifests(URL, List) :-
|
Chris@0
|
274 rdf(URL, mfx:include, Collection), !,
|
Chris@0
|
275 findall(S, rdfs_member(S, Collection), List).
|
Chris@0
|
276 sub_manifests(_, []).
|
Chris@0
|
277
|
Chris@0
|
278
|
Chris@0
|
279
|
Chris@0
|
280 /*******************************
|
Chris@0
|
281 * LOAD FILES *
|
Chris@0
|
282 *******************************/
|
Chris@0
|
283
|
Chris@0
|
284 %% load_triples_to_db(+File)
|
Chris@0
|
285 %
|
Chris@0
|
286 % Load triples from a file into a the RDF database
|
Chris@0
|
287
|
Chris@0
|
288 load_triples_to_db(URL) :-
|
Chris@0
|
289 file_url(File, URL), !,
|
Chris@0
|
290 load_triples_to_db(File).
|
Chris@0
|
291 load_triples_to_db(File) :-
|
Chris@0
|
292 file_name_extension(_, Ext, File),
|
Chris@0
|
293 ( load_triples_to_db(Ext, File)
|
Chris@0
|
294 -> true
|
Chris@0
|
295 ; assert(user:load_failed(File))
|
Chris@0
|
296 ).
|
Chris@0
|
297
|
Chris@0
|
298 load_triples_to_db(rdf, File) :- !, % RDF/XML
|
Chris@0
|
299 rdf_load(File, [silent(true)]).
|
Chris@0
|
300 load_triples_to_db(ttl, File) :- !, % Turtle
|
Chris@0
|
301 absolute_file_name(File, Path),
|
Chris@0
|
302 rdf_load_turtle_file(File, Triples, []),
|
Chris@0
|
303 maplist(assert_triple(Path), Triples).
|
Chris@0
|
304 load_triples_to_db(n3, File) :- !, % Turtle
|
Chris@0
|
305 absolute_file_name(File, Path),
|
Chris@0
|
306 rdf_load_turtle_file(File, Triples, []),
|
Chris@0
|
307 maplist(assert_triple(Path), Triples).
|
Chris@0
|
308
|
Chris@0
|
309 assert_triple(DB, rdf(S,P,O)) :-
|
Chris@0
|
310 rdf_assert(S,P,O, DB).
|
Chris@0
|
311
|
Chris@0
|
312 %% load_triples(+File, -RDFList)
|
Chris@0
|
313 %
|
Chris@0
|
314 % Load file into a list of rdf(S,P,O) terms
|
Chris@0
|
315
|
Chris@0
|
316 load_triples(File, Triples) :-
|
Chris@0
|
317 file_name_extension(_, Ext, File),
|
Chris@0
|
318 load_triples(Ext, File, Triples).
|
Chris@0
|
319
|
Chris@0
|
320 load_triples(rdf, File, Triples) :- !,
|
Chris@0
|
321 load_rdf(File, Triples).
|
Chris@0
|
322 load_triples(ttl, File, Triples) :- !,
|
Chris@0
|
323 rdf_load_turtle_file(File, Triples, []).
|
Chris@0
|
324
|
Chris@0
|
325
|
Chris@0
|
326 /*******************************
|
Chris@0
|
327 * URL *
|
Chris@0
|
328 *******************************/
|
Chris@0
|
329
|
Chris@0
|
330 file_url(File, URL) :-
|
Chris@0
|
331 ground(File), !,
|
Chris@0
|
332 absolute_file_name(File, Path),
|
Chris@0
|
333 atom_concat('file://', Path, URL).
|
Chris@0
|
334 file_url(File, URL) :-
|
Chris@0
|
335 atom_concat('file://', File, URL).
|
Chris@0
|
336
|
Chris@0
|
337
|
Chris@0
|
338 /*******************************
|
Chris@0
|
339 * UTIL *
|
Chris@0
|
340 *******************************/
|
Chris@0
|
341
|
Chris@0
|
342 mf_member(Element, Set) :-
|
Chris@0
|
343 mf_rdf(Set, rdf:first, Element).
|
Chris@0
|
344 mf_member(Element, Set) :-
|
Chris@0
|
345 mf_rdf(Set, rdf:rest, Tail),
|
Chris@0
|
346 mf_member(Element, Tail).
|