35
36:- module(sparql_runtime,
37 [ sparql_true/1, 38 sparql_eval/2, 39 sparql_eval_raw/2, 40 sparql_simplify/2, 41 sparql_subquery/3, 42 sparql_update/1, 43 sparql_find/5, 44 sparql_minus/2, 45 sparql_group/1, 46 sparql_group/3, 47 sparql_service/5, 48 sparql_reset_bnodes/0
49 ]). 50:- use_module(library(semweb/rdf_db)). 51:- use_module(library(semweb/rdf11), [rdf_lexical_form/2]). 52:- use_module(library(xsdp_types)). 53:- use_module(library(lists)). 54:- use_module(library(apply)). 55:- use_module(library(assoc)). 56:- use_module(library(ordsets)). 57:- use_module(library(uri)). 58:- use_module(library(dcg/basics)). 59:- use_module(library(semweb/sparql_client)). 60:- use_module(library(debug)). 61:- use_module(library(error)). 62:- if(exists_source(library(uuid))). 63:- use_module(library(uuid)). 64:- endif. 65
66:- discontiguous
67 term_expansion/2. 68
69:- meta_predicate
70 sparql_find(?, ?, ?, ?, 0),
71 sparql_minus(0, 0),
72 sparql_group(0),
73 sparql_group(0, +, +),
74 sparql_subquery(+, 0, +),
75 sparql_update(:). 76
84
85:- thread_local
86 bnode_store/2. 87
92
93sparql_true(Term) :-
94 typed_eval(boolean, Term, Result),
95 !,
96 true(Result).
97
98true(boolean(true)).
99
101
102eval(Var, unbound(Var)) :-
103 var(Var),
104 !.
105eval(literal(Literal), Result) :-
106 !,
107 eval_literal(Literal, Result).
108eval(Atom, iri(Atom)) :-
109 atom(Atom),
110 !.
111eval(built_in(Term), Result) :-
112 !,
113 op(Term, Result).
114eval(Term, Result) :-
115 sparql_op(Term),
116 !,
117 op(Term, Result).
118eval(function(Term), Result) :-
119 !,
120 ( xsd_cast(Term, Type, Value0)
121 -> eval(Value0, Value),
122 eval_cast(Type, Value, Result)
123 ; eval_function(Term, Result)
124 ).
125eval(Term, Term). 126
130
131typed_eval(no_eval, Term, Term).
132typed_eval(any, Term, Result) :-
133 eval(Term, Result).
134typed_eval(simple_literal, Term, Result) :-
135 eval(Term, Result).
136typed_eval(boolean, Term, Result) :-
137 eval(Term, Result0),
138 effective_boolean_value(Result0, Result).
139typed_eval(numeric, Term, Result) :-
140 eval(Term, Result),
141 Result = numeric(_,_).
142
143
144eval_literal(type(Type, Atom), Value) :-
145 !,
146 eval_typed_literal(Type, Atom, Value).
147eval_literal(lang(Lang, Atom), lang(Lang, Atom)) :- !.
148eval_literal(Atom, simple_literal(Atom)) :-
149 atom(Atom),
150 !.
151
152eval_typed_literal(Type, Atom, numeric(Type, Value)) :-
153 xsdp_numeric_uri(Type, Generic),
154 !,
155 numeric_literal_value(Generic, Atom, Value).
156eval_typed_literal(Type, Atom, Value) :-
157 eval_known_typed_literal(Type, Atom, Value0),
158 !,
159 Value = Value0.
160eval_typed_literal(Type, Atom, type(Type, Atom)).
161
167
168:- rdf_meta eval_known_typed_literal(r, +, t). 169
170eval_known_typed_literal(xsd:boolean, Atom, boolean(Atom)).
171eval_known_typed_literal(xsd:string, Atom, string(Atom)).
172eval_known_typed_literal(xsd:gYear, Atom, time(xsd:gYear, Atom)).
173eval_known_typed_literal(xsd:gYearMonth, Atom, time(xsd:gYearMonth, Atom)).
174eval_known_typed_literal(xsd:date, Atom, time(xsd:date, Atom)).
175eval_known_typed_literal(xsd:dateTime, Atom, time(xsd:dateTime, Atom)).
176
185
186numeric_literal_value(Type, Text, Value) :-
187 rdf_equal(Type, xsd:integer),
188 !,
189 atom(Text),
190 atom_number(Text, Value),
191 integer(Value).
192numeric_literal_value(Type, Text, Value) :-
193 rdf_equal(Type, xsd:decimal),
194 !,
195 atom(Text),
196 atom_number(Text, Value).
197numeric_literal_value(_, Text, Value) :-
198 atom(Text),
199 atom_number(Text, Value),
200 !.
201numeric_literal_value(_, Text, Value) :-
202 catch(rdf_text_to_float(Text, Value), _, fail).
203
204rdf_text_to_float(Text, Value) :-
205 atom_codes(Text, Codes),
206 optional_sign(Codes, Rest, Sign),
207 ( Rest = [0'.|_]
208 -> number_codes(NonnegValue, [0'0|Rest])
209 ; last(Rest, 0'.)
210 -> append(Rest, [0'0], NonnegCodes),
211 number_codes(NonnegCodes, NonnegValue)
212 ),
213 Value is NonnegValue*Sign.
214
215optional_sign([0'+|Rest], Rest, 1) :- !.
216optional_sign([0'-|Rest], Rest, -1) :- !.
217optional_sign(Rest, Rest, 1).
218
219
221
222eval_any(Term, Value) :-
223 eval(Term, Value),
224 !.
225eval_any(_, boolean(error)).
226
227eval_boolean(Term, Bool) :-
228 eval(Term, Value),
229 effective_boolean_value(Value, Bool),
230 !.
231eval_boolean(_, boolean(error)).
232
233eval_numeric(Term, Numeric) :-
234 eval(Term, Numeric),
235 Numeric = numeric(_,_),
236 !.
237eval_numeric(_, boolean(error)).
238
240
241term_expansion((:- sparql_op(Decls)), Clauses) :-
242 maplist(decl_op, Decls, Clauses).
243
244decl_op(Term, op_decl(Gen, Args)) :-
245 functor(Term, Name, Arity),
246 functor(Gen, Name, Arity),
247 Term =.. [Name|Args].
248
249
253
254expand_op((op(Op,Result) :- Body),
255 [(op(Op1,Result) :- Body1), sparql_op(Op1)]) :-
256 rdf_global_term(Op, Op0),
257 functor(Op0, Name, Arity),
258 functor(Op1, Name, Arity),
259 ( op_decl(Op1, Types)
260 -> true
261 ; Op0 =.. [Name|Args],
262 maplist(op_arg_type, Args, Types)
263 ),
264 Op0 =.. [Name|Args0],
265 Op1 =.. [Name|Args1],
266 maplist(convert_goal, Types, Args1, Args0, ConvertList),
267 list_to_conj(ConvertList, Convert),
268 mkconj(Convert, Body, Body1).
269
270op_arg_type(Var, any) :- var(Var), !.
271op_arg_type(boolean(_), boolean) :- !.
272op_arg_type(numeric(_,_), numeric) :- !.
273op_arg_type(simple_literal(_), simple_literal) :- !.
274op_arg_type(_, any).
275
276list_to_conj([], true).
277list_to_conj([G], G) :- !.
278list_to_conj([H|T], G) :-
279 list_to_conj(T, G1),
280 mkconj(H, G1, G).
281
282mkconj(true, G, G) :- !.
283mkconj(G, true, G) :- !.
284mkconj(G1,G2,(G1,G2)).
285
286convert_goal(no_eval, Arg, Arg, true).
287convert_goal(any, Arg0, Arg1, eval_any(Arg0, Arg1)).
288convert_goal(simple_literal, Arg0, Arg1, eval_any(Arg0, Arg1)).
289convert_goal(boolean, Arg0, Arg1, eval_boolean(Arg0, Arg1)).
290convert_goal(numeric, Arg0, Arg1, eval_numeric(Arg0, Arg1)).
291
292term_expansion((op(Op,Result) :- Body), Clauses) :-
293 expand_op((op(Op,Result) :- Body), Clauses).
294term_expansion((op(Op,Result)), Clauses) :-
295 expand_op((op(Op,Result) :- true), Clauses).
296
302
303:- rdf_meta op(t,t). 304:- discontiguous op/2, op_decl/2, sparql_op/1. 305
306:- sparql_op([ bound(no_eval)
307 ]). 308
310op(not(boolean(X)), boolean(Result)) :-
311 not(X, Result).
312op(+(numeric(Type, X)), numeric(Type, X)).
313op(-(numeric(Type, X)), numeric(Type, Result)) :-
314 Result is -X.
315
317op(bound(X), boolean(Result)) :-
318 (bound(X) -> Result = true ; Result = false).
319op(isiri(X), boolean(Result)) :-
320 (isiri(X) -> Result = true ; Result = false).
321op(isuri(X), boolean(Result)) :-
322 (isiri(X) -> Result = true ; Result = false).
323op(isblank(X), boolean(Result)) :-
324 (isblank(X) -> Result = true ; Result = false).
325op(isliteral(X), boolean(Result)) :-
326 (isliteral(X) -> Result = true ; Result = false).
327
328:- sparql_op([ iri(any, no_eval),
329 str(no_eval)
330 ]). 331
333op(str(X), simple_literal(Str)) :-
334 str(X, Str).
335op(lang(X), simple_literal(Lang)) :-
336 lang(X, Lang).
337op(datatype(X), Type) :-
338 datatype(X, Type).
339op(strdt(simple_literal(Lex), iri(Type)), type(Type, Lex)).
340op(strlang(simple_literal(Lex), simple_literal(Lang)), lang(Lang, Lex)).
341:- if(current_predicate(uuid/1)). 342op(uuid, iri(URNUUID)) :-
343 uuid(UUID),
344 atom_concat('urn:uuid:', UUID, URNUUID).
345op(struuid, simple_literal(UUID)) :-
346 uuid(UUID).
347:- endif. 348op(bnode, iri(Id)) :-
349 rdf_bnode(Id).
350op(bnode(simple_literal(Id)), iri(BNode)) :-
351 id_to_bnode(Id, BNode).
352op(iri(Spec, Base), iri(URI)) :-
353 iri(Spec, Base, URI).
354
357op(and(boolean(A), boolean(B)), boolean(Result)) :-
358 sparql_and(A, B, Result).
359op(or(boolean(A), boolean(B)), boolean(Result)) :-
360 sparql_or(A, B, Result).
361
362:- sparql_op([ coalesce(no_eval)
363 ]). 364
366op(if(Test, V1, V2), Result) :-
367 typed_eval(boolean, Test, TestResult),
368 ( TestResult == boolean(true)
369 -> eval(V1, Result)
370 ; TestResult == boolean(false)
371 -> eval(V2, Result)
372 ).
373op(coalesce(List), Result) :-
374 member(Expr, List),
375 ground(Expr),
376 eval(Expr, Result),
377 \+ invalid(Result),
378 !.
379
380invalid('$null$').
381invalid(boolean(error)).
382
384op(X = Y, boolean(Result)) :-
385 ( equal(X, Y)
386 -> Result = true
387 ; Result = false
388 ).
389op(X \= Y, boolean(Result)) :-
390 ( equal(X, Y)
391 -> Result = false
392 ; Result = true
393 ).
394
395equal(X, X) :- !.
396equal(numeric(_, X), numeric(_, Y)) :- X =:= Y.
397equal(boolean(A), boolean(B)) :-
398 eq_bool(A, B, true).
399
400op(X < Y, boolean(Result)) :-
401 ( lt(X,Y)
402 -> Result = true
403 ; functor(X, Name, Arity),
404 functor(Y, Name, Arity)
405 -> Result = false
406 ).
407op(X > Y, boolean(Result)) :-
408 ( gt(X,Y)
409 -> Result = true
410 ; functor(X, Name, Arity),
411 functor(Y, Name, Arity)
412 -> Result = false
413 ).
414op(X =< Y, boolean(Result)) :-
415 ( leq(X,Y)
416 -> Result = true
417 ; functor(X, Name, Arity),
418 functor(Y, Name, Arity)
419 -> Result = false
420 ).
421op(X >= Y, boolean(Result)) :-
422 ( geq(X,Y)
423 -> Result = true
424 ; functor(X, Name, Arity),
425 functor(Y, Name, Arity)
426 -> Result = false
427 ).
428
429lt(numeric(_, X), numeric(_, Y)) :- X < Y.
430lt(simple_literal(X), simple_literal(Y)) :- X @< Y.
431lt(string(X), string(Y)) :- X @< Y.
432lt(time(T, X), time(T, Y)) :- X @< Y.
433lt(type(T, X), type(T, Y)) :- X @< Y.
434
435gt(numeric(_, X), numeric(_, Y)) :- X > Y.
436gt(simple_literal(X), simple_literal(Y)) :- X @> Y.
437gt(string(X), string(Y)) :- X @> Y.
438gt(time(T, X), time(T, Y)) :- X @> Y.
439gt(type(T, X), type(T, Y)) :- X @> Y.
440
441leq(numeric(_, X), numeric(_, Y)) :- X =< Y.
442leq(simple_literal(X), simple_literal(Y)) :- X @=< Y.
443leq(string(X), string(Y)) :- X @=< Y.
444leq(time(T, X), time(T, Y)) :- X @=< Y.
445leq(type(T, X), type(T, Y)) :- X @=< Y.
446
447geq(numeric(_, X), numeric(_, Y)) :- X >= Y.
448geq(simple_literal(X), simple_literal(Y)) :- X @>= Y.
449geq(string(X), string(Y)) :- X @>= Y.
450geq(time(T, X), time(T, Y)) :- X @>= Y.
451geq(type(T, X), type(T, Y)) :- X @>= Y.
452
454op(numeric(TX, X) * numeric(TY, Y), numeric(Type, Result)) :-
455 Result is X * Y,
456 combine_types(TX, TY, Type).
457op(numeric(TX, X) / numeric(TY, Y), numeric(Type, Result)) :-
458 Y =\= 0,
459 Result is X / Y,
460 combine_types_div(TX, TY, Type).
461op(numeric(TX, X) + numeric(TY, Y), numeric(Type, Result)) :-
462 Result is X + Y,
463 combine_types(TX, TY, Type).
464op(numeric(TX, X) - numeric(TY, Y), numeric(Type, Result)) :-
465 Result is X - Y,
466 combine_types(TX, TY, Type).
468op(min(numeric(TX, X), numeric(TY, Y)), numeric(Type, Result)) :-
469 ( X < Y
470 -> Type = TX, Result = X
471 ; X > Y
472 -> Type = TY, Result = Y
473 ; combine_types(TX, TY, Type),
474 ( Type == TX
475 -> Result = X
476 ; Result = Y
477 )
478 ).
479op(max(numeric(TX, X), numeric(TY, Y)), numeric(Type, Result)) :-
480 ( X > Y
481 -> Type = TX, Result = X
482 ; X < Y
483 -> Type = TY, Result = Y
484 ; combine_types(TX, TY, Type),
485 ( Type == TX
486 -> Result = X
487 ; Result = Y
488 )
489 ).
490
492
493op(in(Value, List), boolean(Result)) :-
494 sparql_in(Value, List, Result).
495op(not_in(Value, List), boolean(Result)) :-
496 sparql_in(Value, List, R0),
497 not(R0, Result).
498
499sparql_in(Value, List, Result) :-
500 ( memberchk(Value, List)
501 -> Result = true
502 ; member(E, List),
503 eval(E, EV),
504 rdf_equal(Value, EV)
505 -> Result = true
506 ; Result = false
507 ).
508
509
511
512:- sparql_op([ strlen(any),
513 substr(any, numeric),
514 substr(any, numeric, numeric),
515 ucase(any),
516 lcase(any),
517 strstarts(any, any),
518 strends(any, any),
519 contains(any, any),
520 strbefore(any, any),
521 strafter(any, any),
522 encode_for_uri(any),
523 concat(no_eval)
524 ]). 525
526op(strlen(A), numeric(xsd:integer, Len)) :-
527 string_op(A, Len, strlen).
528op(substr(A, numeric(xsd:integer, Start)), R) :-
529 string_int_op_string(A, Start, R, substr).
530op(substr(A, numeric(xsd:integer, Start), numeric(xsd:integer, Len)), R) :-
531 string_int_int_op_string(A, Start, Len, R, substr).
532op(ucase(A), U) :-
533 string_op_string(A, U, ucase).
534op(lcase(A), U) :-
535 string_op_string(A, U, lcase).
536op(strstarts(String, Starts), boolean(True)) :-
537 argument_compatible(String, Starts, True, strstarts).
538op(strends(String, Starts), boolean(True)) :-
539 argument_compatible(String, Starts, True, strends).
540op(contains(String, Starts), boolean(True)) :-
541 argument_compatible(String, Starts, True, contains).
542op(strbefore(A1, A2), R) :-
543 string_string_op(A1, A2, R, strbefore).
544op(strafter(A1, A2), R) :-
545 string_string_op(A1, A2, R, strafter).
546op(encode_for_uri(S), simple_literal(URI)) :-
547 str_value(S, Text),
548 uri_encoded(path, Text, IRI),
549 uri_iri(URI, IRI).
550op(concat(List), R) :-
551 maplist(eval, List, Evaluated),
552 maplist(str_text, Evaluated, StrList),
553 atomic_list_concat(StrList, Lex),
554 ( maplist(is_string, Evaluated)
555 -> R = string(Lex)
556 ; maplist(is_lang(L), Evaluated)
557 -> R = lang(L, Lex)
558 ; R = simple_literal(Lex)
559 ).
560op(langmatches(simple_literal(Lang),
561 simple_literal(Pat)),
562 boolean(Result)) :-
563 (lang_matches(Lang, Pat) -> Result = true ; Result = false).
564op(regex(A, simple_literal(Pat)), boolean(Result)) :-
565 string_op(A, Result, regex(Pat, '')).
566op(regex(A, simple_literal(Pat), simple_literal(Flags)), boolean(Result)) :-
567 string_op(A, Result, regex(Pat, Flags)).
568op(compiled_regex(Regex, A), boolean(Result)) :-
569 string_op(A, Result, compiled_regex(Regex)).
570op(replace(simple_literal(Input),
571 simple_literal(Pattern),
572 simple_literal(Replace),
573 simple_literal(Flags)),
574 simple_literal(Result)) :-
575 regex_replace(Input, Pattern, Replace, Flags, Result).
576op(replace(string(Input),
577 simple_literal(Pattern),
578 simple_literal(Replace),
579 simple_literal(Flags)),
580 string(Result)) :-
581 regex_replace(Input, Pattern, Replace, Flags, Result).
582op(replace(lang(Lang, Input),
583 simple_literal(Pattern),
584 simple_literal(Replace),
585 simple_literal(Flags)),
586 lang(Lang, Result)) :-
587 regex_replace(Input, Pattern, Replace, Flags, Result).
588
590
591:- sparql_op([ isnumeric(any)
592 ]). 593
594op(isnumeric(A), boolean(True)) :-
595 ( A = numeric(_,_) -> True = true ; True = false ).
596op(abs(numeric(T, A1)), numeric(T, R)) :-
597 R is abs(A1).
598op(round(numeric(T, A1)), numeric(T, R)) :-
599 R is round(A1).
600op(ceil(numeric(T, A1)), numeric(T, R)) :-
601 R is ceil(A1).
602op(floor(numeric(T, A1)), numeric(T, R)) :-
603 R is floor(A1).
604op(rand, numeric(xsd:double, R)) :-
605 R is random_float.
606
608
609op(now, time(xsd:dateTime, Date)) :-
610 get_time(Now),
611 format_time(atom(Date), '%FT%T.%3f%:z', Now).
612op(year(time(Type, DateTime)), numeric(xsd:integer, Year)) :-
613 time_part(year, Type, DateTime, Year).
614op(month(time(Type, DateTime)), numeric(xsd:integer, Month)) :-
615 time_part(month, Type, DateTime, Month).
616op(day(time(Type, DateTime)), numeric(xsd:integer, Day)) :-
617 time_part(day, Type, DateTime, Day).
618op(hours(time(Type, DateTime)), numeric(xsd:integer, Hours)) :-
619 time_part(hours, Type, DateTime, Hours).
620op(minutes(time(Type, DateTime)), numeric(xsd:integer, Minutes)) :-
621 time_part(minutes, Type, DateTime, Minutes).
622op(seconds(time(Type, DateTime)), numeric(xsd:decimal, Seconds)) :-
623 time_part(seconds, Type, DateTime, Seconds).
624op(timezone(time(Type, DateTime)), type(xsd:dayTimeDuration, Timezone)) :-
625 time_part(tzs, Type, DateTime, TZs),
626 phrase(tz_offset(TZOffset), TZs),
627 xsd_duration_seconds(Timezone, TZOffset).
628op(tz(time(Type, DateTime)), simple_literal(TZ)) :-
629 time_part(tz, Type, DateTime, TZ).
630
632
633:- sparql_op([ md5(any),
634 sha1(any),
635 sha256(any),
636 sha384(any),
637 sha512(any)
638 ]). 639
640op(md5(String), simple_literal(Hash)) :-
641 string_hash(String, Hash, md5).
642op(sha1(String), simple_literal(Hash)) :-
643 string_hash(String, Hash, sha1).
644op(sha256(String), simple_literal(Hash)) :-
645 string_hash(String, Hash, sha256).
646op(sha384(String), simple_literal(Hash)) :-
647 string_hash(String, Hash, sha384).
648op(sha512(String), simple_literal(Hash)) :-
649 string_hash(String, Hash, sha512).
650
651
652 655
656string_hash(simple_literal(S), Hash, Algorithm) :-
657 atom_hash(Algorithm, S, Hash).
658string_hash(string(S), Hash, Algorithm) :-
659 atom_hash(Algorithm, S, Hash).
660
661atom_hash(md5, S, Hash) :-
662 !,
663 rdf_atom_md5(S, 1, Hash).
664atom_hash(SHA, S, Hash) :-
665 sha_hash(S, HashCodes,
666 [ algorithm(SHA),
667 encoding(utf8)
668 ]),
669 hash_atom(HashCodes, Hash).
670
671
672 675
677
678:- if(current_predicate(sub_string/5)). 679time_part(year, _Type, String, Value) :-
680 !,
681 sub_string(String, 0, 4, _, Digits),
682 number_string(Value, Digits).
683time_part(month, _Type, String, Value) :-
684 !,
685 sub_string(String, 5, 2, _, Digits),
686 number_string(Value, Digits).
687time_part(day, _Type, String, Value) :-
688 !,
689 sub_string(String, 8, 2, _, Digits),
690 number_string(Value, Digits).
691:- endif. 692time_part(Part, _Type, DateTime, Value) :-
693 atom_codes(DateTime, Codes),
694 phrase(time_dcg(Part, Value), Codes, _).
695
696time_dcg(year, Year) --> digits4(Year).
697time_dcg(month, Month) --> time_dcg(year, _), "-", digits2(Month).
698time_dcg(day, Day) --> time_dcg(month, _), "-", digits2(Day).
699time_dcg(hours, Hours) --> time_dcg(day, _), "T", digits2(Hours).
700time_dcg(minutes, Min) --> time_dcg(hours, _), ":", digits2(Min).
701time_dcg(seconds, Sec) --> time_dcg(minutes, _), ":", number(Sec).
702time_dcg(tzs, TZs) --> time_dcg(seconds, _), string_without("", TZs).
703time_dcg(tz, TZ) --> time_dcg(tzs, TZs), { atom_codes(TZ, TZs) }.
704
705tz_offset(TZOffset) -->
706 "Z", !, { TZOffset = 0 }.
707tz_offset(TZOffset) -->
708 "+", digits2(Hours), ":", digits2(Minutes),
709 { TZOffset is Hours*3600+Minutes*60 }.
710tz_offset(TZOffset) -->
711 "-", digits2(Hours), ":", digits2(Minutes),
712 { TZOffset is -(Hours*3600+Minutes*60) }.
713
719
720xsd_duration_seconds(XSDDuration, Secs) :-
721 var(XSDDuration),
722 !,
723 must_be(number, Secs),
724 phrase(xsd_duration(Secs), Codes),
725 atom_codes(XSDDuration, Codes).
726
727xsd_duration(Secs) -->
728 { Secs < 0, !, PosSecs is -Secs },
729 "-",
730 xsd_duration(PosSecs).
731xsd_duration(Secs) -->
732 { Secs =:= 0 },
733 !,
734 "PT0S".
735xsd_duration(Secs) -->
736 "P",
737 xsd_duration_days(Secs, Rem),
738 xsd_duration_time(Rem).
739
740xsd_duration_days(Secs, Rem) -->
741 { Days is Secs // (24*3600),
742 Days > 0,
743 !,
744 Rem is Secs - Days*24*3600
745 },
746 integer(Days),
747 "D".
748xsd_duration_days(Secs, Secs) --> "".
749
750xsd_duration_time(Secs) -->
751 { Secs =:= 0 },
752 !.
753xsd_duration_time(Secs) -->
754 "T",
755 xsd_duration_hours(Secs, S1),
756 xsd_duration_minutes(S1, S2),
757 xsd_duration_seconds(S2).
758
759xsd_duration_hours(Secs, Rem) -->
760 { Hours is Secs // 3600,
761 Hours > 0,
762 !,
763 Rem is Secs - Hours*3600
764 },
765 integer(Hours),
766 "H".
767xsd_duration_hours(Secs, Secs) --> "".
768
769xsd_duration_minutes(Secs, Rem) -->
770 { Min is Secs // 60,
771 Min > 0,
772 !,
773 Rem is Secs - Min*60
774 },
775 integer(Min),
776 "M".
777xsd_duration_minutes(Secs, Secs) --> "".
778
779xsd_duration_seconds(Secs) -->
780 { Secs =:= 0 },
781 !.
782xsd_duration_seconds(Secs) -->
783 number(Secs),
784 "S".
785
786
787digits4(Value) -->
788 digit(D1),digit(D2),digit(D3),digit(D4),
789 { number_codes(Value, [D1,D2,D3,D4]) }.
790digits2(Value) -->
791 digit(D1),digit(D2),
792 { number_codes(Value, [D1,D2]) }.
793
794
795 798
799is_string(string(_)).
800is_lang(L, lang(L,_)).
801
803
804string_op(simple_literal(A), R, Op) :-
805 atom_op(Op, A, R).
806string_op(lang(_, A), R, Op) :-
807 atom_op(Op, A, R).
808string_op(string(A), R, Op) :-
809 atom_op(Op, A, R).
810
812
813string_op_string(simple_literal(A), simple_literal(R), Op) :-
814 atom_op(Op, A, R).
815string_op_string(lang(L,A), lang(L,R), Op) :-
816 atom_op(Op, A, R).
817string_op_string(string(A), string(R), Op) :-
818 atom_op(Op, A, R).
819
821
822string_int_op_string(simple_literal(S0), I, simple_literal(S), Op) :-
823 atom_op(Op, S0, I, S).
824string_int_op_string(lang(L, S0), I, lang(L, S), Op) :-
825 atom_op(Op, S0, I, S).
826string_int_op_string(string(S0), I, string(S), Op) :-
827 atom_op(Op, S0, I, S).
828
830
831string_int_int_op_string(simple_literal(S0), I1, I2, simple_literal(S), Op) :-
832 atom_op(Op, S0, I1, I2, S).
833string_int_int_op_string(lang(L, S0), I1, I2, lang(L, S), Op) :-
834 atom_op(Op, S0, I1, I2, S).
835string_int_int_op_string(string(S0), I1, I2, string(S), Op) :-
836 atom_op(Op, S0, I1, I2, S).
837
841
842string_string_op(simple_literal(A1), simple_literal(A2), Result, Op) :-
843 ( atom_op(Op, A1, A2, R)
844 -> Result = simple_literal(R)
845 ; Result = simple_literal('')
846 ).
847string_string_op(simple_literal(A1), string(A2), Result, Op) :-
848 ( atom_op(Op, A1, A2, R)
849 -> Result = simple_literal(R)
850 ; Result = simple_literal('')
851 ).
852string_string_op(string(A1), simple_literal(A2), Result, Op) :-
853 ( atom_op(Op, A1, A2, R)
854 -> Result = string(R)
855 ; Result = simple_literal('')
856 ).
857string_string_op(string(A1), string(A2), Result, Op) :-
858 ( atom_op(Op, A1, A2, R)
859 -> Result = string(R)
860 ; Result = simple_literal('')
861 ).
862string_string_op(lang(L, A1), lang(L, A2), Result, Op) :-
863 ( atom_op(Op, A1, A2, R)
864 -> Result = lang(L, R)
865 ; Result = simple_literal('')
866 ).
867string_string_op(lang(L, A1), string(A2), Result, Op) :-
868 ( atom_op(Op, A1, A2, R)
869 -> Result = lang(L, R)
870 ; Result = simple_literal('')
871 ).
872string_string_op(lang(L, A1), simple_literal(A2), Result, Op) :-
873 ( atom_op(Op, A1, A2, R)
874 -> Result = lang(L, R)
875 ; Result = simple_literal('')
876 ).
877
879
880iri(simple_literal(URI0), Base, URI) :-
881 !,
882 uri_normalized(URI0, Base, URI).
883iri(string(URI0), Base, URI) :-
884 uri_normalized(URI0, Base, URI).
885iri(iri(URI), _, URI).
886
888
889argument_compatible(simple_literal(A1), simple_literal(A2), Bool, Op) :-
890 !,
891 arg_compatible(Op, A1, A2, Bool).
892argument_compatible(simple_literal(A1), string(A2), Bool, Op) :-
893 !,
894 arg_compatible(Op, A1, A2, Bool).
895argument_compatible(string(A1), simple_literal(A2), Bool, Op) :-
896 !,
897 arg_compatible(Op, A1, A2, Bool).
898argument_compatible(string(A1), string(A2), Bool, Op) :-
899 !,
900 arg_compatible(Op, A1, A2, Bool).
901argument_compatible(lang(L,A1), lang(L,A2), Bool, Op) :-
902 !,
903 arg_compatible(Op, A1, A2, Bool).
904argument_compatible(lang(_,A1), simple_literal(A2), Bool, Op) :-
905 !,
906 arg_compatible(Op, A1, A2, Bool).
907argument_compatible(lang(_,A1), string(A2), Bool, Op) :-
908 !,
909 arg_compatible(Op, A1, A2, Bool).
910argument_compatible(_, _, boolean(error), _).
911
912arg_compatible(Op, A1, A2, Bool) :-
913 ( arg_compatible(Op, A1, A2)
914 -> Bool = true
915 ; Bool = false
916 ).
917
918arg_compatible(strstarts, A1, A2) :- sub_atom(A1, 0, _, _, A2).
919arg_compatible(strends, A1, A2) :- sub_atom(A1, _, _, 0, A2).
920arg_compatible(contains, A1, A2) :- sub_atom(A1, _, _, _, A2), !.
921
922
924
925atom_op(strlen, A, Len) :-
926 atom_length(A, Len).
927atom_op(ucase, A, U) :-
928 upcase_atom(A, U).
929atom_op(lcase, A, U) :-
930 downcase_atom(A, U).
931atom_op(compiled_regex(Regex), Data, Matches) :-
932 ( compiled_regex(Regex, Data)
933 -> Matches = true
934 ; Matches = false
935 ).
936atom_op(regex(Pat, Flags), Data, Matches) :-
937 ( regex(Data, Pat, Flags)
938 -> Matches = true
939 ; Matches = false
940 ).
941
943
944atom_op(substr, Atom, Start, Sub) :-
945 S is Start - 1,
946 ( sub_atom(Atom, S, _, 0, Sub0)
947 -> Sub = Sub0
948 ; Sub = '' 949 ).
950atom_op(strbefore, Atom, Search, Before) :-
951 ( Search == ''
952 -> Before = ''
953 ; sub_atom(Atom, BL, _, _, Search)
954 -> sub_atom(Atom, 0, BL, _, Before)
955 ).
956atom_op(strafter, Atom, Search, After) :-
957 ( sub_atom(Atom, _, _, AL, Search)
958 -> sub_atom(Atom, _, AL, 0, After)
959 ).
960
962
963atom_op(substr, Atom, Start, Len, Sub) :-
964 S is Start - 1,
965 ( sub_atom(Atom, S, Len, _, Sub0)
966 -> Sub = Sub0
967 ; sub_atom(Atom, S, _, 0, Sub0)
968 -> Sub = Sub0
969 ; Sub = '' 970 ).
971
972
976
978
979combine_types_div(TX, TY, T) :-
980 rdf_equal(xsd:integer, IntType),
981 xsdp_numeric_uri(TX, IntType),
982 xsdp_numeric_uri(TY, IntType),
983 !,
984 rdf_equal(xsd:decimal, T).
985combine_types_div(TX, TY, T) :-
986 combine_types(TX, TY, T).
987
989
991combine_types(TL, TR, T) :-
992 xsdp_numeric_uri(TL, STL),
993 xsdp_numeric_uri(TR, STR),
994 promote_types(STL, STR, T).
995
996promote_types(TL, TR, T) :-
997 type_index(TL, IL),
998 type_index(TR, IR),
999 TI is max(IL, IR),
1000 type_index(T, TI),
1001 !.
1002
1003term_expansion(type_index(NS:Local, I), type_index(URI, I)) :-
1004 rdf_global_id(NS:Local, URI).
1005
1006type_index(xsd:integer, 1).
1007type_index(xsd:decimal, 2).
1008type_index(xsd:float, 3).
1009type_index(xsd:double, 4).
1010
1011
1016
1017:- rdf_meta rdf_equal(t,t,-). 1018
1019rdf_equal(X, X, boolean(true)) :- !.
1020rdf_equal(boolean(A), boolean(B), boolean(Eq)) :-
1021 !,
1022 eq_bool(A, B, Eq).
1023rdf_equal(_, _, boolean(false)).
1024
1025
1026eq_bool(X, X, true) :- !.
1027eq_bool(true, false, false) :- !.
1028eq_bool(false, true, false) :- !.
1029eq_bool(X, Y, true) :-
1030 boolean_value(X, V1),
1031 boolean_value(Y, V2),
1032 V1 == V2,
1033 !.
1034eq_bool(_, _, false).
1035
1040
1041boolean_value(true, true) :- !.
1042boolean_value(false, false) :- !.
1043boolean_value('0', false) :- !.
1044boolean_value('', false) :- !.
1045boolean_value(False, false) :-
1046 downcase_atom(False, false),
1047 !.
1048boolean_value(_, true).
1049
1050
1051 1054
1060
1061term_expansion(xsd_cast(term,type,arg), Clauses) :-
1062 findall(Clause, xsd_cast_clause(Clause), Clauses).
1063
1064xsd_cast_clause(xsd_cast(Term, Type, Arg)) :-
1065 ( xsdp_numeric_uri(Type, _)
1066 ; rdf_equal(xsd:dateTime, Type)
1067 ; rdf_equal(xsd:boolean, Type)
1068 ),
1069 Term =.. [Type,Arg].
1070
1071xsd_cast(term,type,arg).
1072
1078
1079eval_cast(Type, simple_literal(Value), Result) :-
1080 atom(Value),
1081 !,
1082 eval_typed_literal(Type, Value, Result).
1083eval_cast(Type, numeric(_, Value0), numeric(Type, Value)) :-
1084 xsdp_numeric_uri(Type, Generic),
1085 ( rdf_equal(Generic, xsd:integer)
1086 -> Value is integer(Value0)
1087 ; ( rdf_equal(Generic, xsd:float)
1088 ; rdf_equal(Generic, xsd:double)
1089 )
1090 -> Value is float(Value0)
1091 ; Value = Value0
1092 ).
1093
1094
1099
1100:- multifile
1101 sparql:function/2,
1102 sparql:current_function/1. 1103
1104eval_function(Term0, Result) :-
1105 Term0 =.. [F|Args0],
1106 eval_args(Args0, Args),
1107 Term =.. [F|Args],
1108 sparql:function(Term, Result0),
1109 !,
1110 eval(Result0, Result).
1111eval_function(Term, boolean(error)) :-
1112 sparql:current_function(Term),
1113 !.
1114eval_function(Term, _) :-
1115 functor(Term, Name, Arity),
1116 throw(error(existence_error(sparql_function, Name/Arity), _)).
1117
1118eval_args([], []).
1119eval_args([H0|T0], [H|T]) :-
1120 sparql_eval(H0, H),
1121 eval_args(T0, T).
1122
1123
1124 1127
1129
1130not(true, false).
1131not(false, true).
1132not(error, error).
1133
1138
1139bound(X) :- nonvar(X).
1140
1144
1145str(Var, _) :-
1146 var(Var), !, fail.
1147str(literal(X), Str) :-
1148 !,
1149 str_literal(X, Str).
1150str(IRI, IRI) :-
1151 atom(IRI),
1152 !,
1153 \+ rdf_is_bnode(IRI).
1154str(Expr, Str) :-
1155 eval(Expr, Value),
1156 str_value(Value, Str).
1157
1158str_value(simple_literal(X), X).
1159str_value(lang(_, X), X).
1160str_value(boolean(X), X).
1161str_value(string(X), X).
1162str_value(iri(IRI), IRI).
1163
1164str_literal(type(_, Str), Str) :- !.
1165str_literal(lang(_, Str), Str) :- !.
1166str_literal(Str, Str).
1167
1168str_text(simple_literal(X), X).
1169str_text(lang(_, X), X).
1170str_text(string(X), X).
1171
1172
1176
1177lang(lang(Lang,_), Lang) :- !.
1178lang(string(_), '').
1179lang(simple_literal(_), '').
1180lang(type(_,_), '').
1181lang(numeric(_,_), '').
1182
1186
1187:- rdf_meta
1188 datatype(t,t). 1189
1190datatype(0, _) :- !, fail.
1191datatype(literal(type(Type, _)), iri(Type)) :- !.
1192datatype(numeric(Type, _), iri(Type)) :- !.
1193datatype(boolean(_), iri(xsd:boolean)) :- !.
1194datatype(time(Type, _), iri(Type)) :- !.
1195datatype(string(_), iri(xsd_string)) :- !.
1196datatype(Expr, Type) :-
1197 eval(Expr, Value),
1198 Value \== Expr,
1199 datatype(Value, Type).
1200
1201
1203
1204sparql_and(true, true, true) :- !.
1205sparql_and(true, error, error) :- !.
1206sparql_and(error, true, error) :- !.
1207sparql_and(_, _, false).
1208
1210
1211sparql_or(true, _, true) :- !.
1212sparql_or(_, true, true) :- !.
1213sparql_or(false, false, false) :- !.
1214sparql_or(_, _, error).
1215
1219
1220isiri(IRI) :-
1221 atom(IRI),
1222 !,
1223 \+ rdf_is_bnode(IRI).
1224isiri(literal(_)) :- !, fail.
1225isiri(Expr) :-
1226 eval(Expr, Value),
1227 Value = iri(IRI),
1228 \+ rdf_is_bnode(IRI).
1229
1230isblank(IRI) :-
1231 atom(IRI),
1232 !,
1233 rdf_is_bnode(IRI).
1234isblank(literal(_)) :- !, fail.
1235isblank(Expr) :-
1236 eval(Expr, Value),
1237 Value = iri(IRI),
1238 rdf_is_bnode(IRI).
1239
1240isliteral(literal(_)) :- !.
1241isliteral(Atom) :-
1242 atom(Atom), !, fail.
1243isliteral(Expr) :-
1244 eval(Expr, Value),
1245 Value \= iri(_).
1246
1247
1248 1251
1252:- if(exists_source(library(pcre))). 1253:- use_module(library(pcre)). 1254
1256
1257regex(String, Pattern, '') :-
1258 !,
1259 re_match(Pattern, String).
1260regex(String, Pattern, Flags) :-
1261 re_match(Pattern/Flags, String).
1262
1267
1268compiled_regex(Regex, String) :-
1269 re_match(Regex, String).
1270
1271regex_obj(Pattern, Flags, Regex) :-
1272 flag_options(Flags, Options),
1273 re_compile(Pattern, Regex, Options).
1274
1275flag_options(Flags, Options) :-
1276 atom_chars(Flags, Chars),
1277 maplist(re_flag_option, Chars, Options).
1278
1279re_flag_option(Flag, Option) :-
1280 re_flag_option_(Flag, Option),
1281 !.
1282re_flag_option(Flag, _) :-
1283 existence_error(re_flag, Flag).
1284
1285re_flag_option_(i, caseless(true)).
1286re_flag_option_(m, multiline(true)).
1287re_flag_option_(x, extended(true)).
1288re_flag_option_(s, dotall(true)).
1289
1290
1292
1293regex_replace(Input, Pattern, Replace, Flags, Result) :-
1294 re_replace(Pattern/Flags, Replace, Input, ResultS),
1295 atom_string(Result, ResultS).
1296
1297:- else. 1298
1304
1305:- dynamic
1306 pattern_cache/3. 1307
1308regex(String, Pattern, Flags) :-
1309 with_mutex(sparql_regex,
1310 ( regex_obj(Pattern, Flags, Regex),
1311 send(Regex, search, string(String)))).
1312
1313regex_obj(Pattern, Flags, Regex) :-
1314 pattern_cache(Pattern, Flags, Regex),
1315 !.
1316regex_obj(Pattern, Flags, Regex) :-
1317 make_regex(Pattern, Flags, Regex),
1318 asserta(pattern_cache(Pattern, Flags, Regex)).
1319
1320make_regex(Pattern, i, Regex) :-
1321 !,
1322 new(Regex, regex(Pattern, @(off))).
1323make_regex(Pattern, _, Regex) :-
1324 !,
1325 new(Regex, regex(Pattern)).
1326
1333
1334compiled_regex(@(Regex), String) :-
1335 send(@(Regex), search, string(String)).
1336
1338
1339regex_replace(Input, Pattern, Replace0, Flags, Result) :-
1340 dollar_replace(Replace0, Replace),
1341 with_mutex(sparql_regex,
1342 locked_replace(Input, Pattern, Replace, Flags, Result)).
1343
1344dollar_replace(Replace0, Replace) :-
1345 sub_atom(Replace0, _, _, _, $),
1346 !,
1347 regex_replace(Replace0, '\\$([0-9])', '\\\\1', '', Replace).
1348dollar_replace(Replace, Replace).
1349
1350
1351locked_replace(Input, Pattern, Replace, Flags, Result) :-
1352 regex_obj(Pattern, Flags, Regex),
1353 new(S, string('%s', Input)),
1354 send(Regex, for_all, S,
1355 message(@(arg1), replace, @(arg2), Replace)),
1356 get(S, value, Result).
1357
1358:- endif. 1359
1360
1364
1365effective_boolean_value(boolean(X), boolean(True)) :-
1366 !,
1367 True = X.
1368effective_boolean_value(string(X), boolean(True)) :-
1369 !,
1370 (X == '' -> True = false ; True = true).
1371effective_boolean_value(simple_literal(X), boolean(True)) :-
1372 !,
1373 (X == '' -> True = false ; True = true).
1374effective_boolean_value(numeric(_, X), boolean(True)) :-
1375 !,
1376 (X =:= 0 -> True = false ; True = true).
1377effective_boolean_value(_, boolean(error)).
1378
1382
1383sparql_eval(Expr, Expr) :-
1384 is_rdf(Expr),
1385 !.
1386sparql_eval(Expr, Result) :-
1387 eval(Expr, Result0),
1388 !,
1389 to_rdf(Result0, Result).
1390sparql_eval(Expr, '$null$') :-
1391 debug(sparql(eval), '~p --> NULL', [Expr]).
1392
1396
1397sparql_eval_raw(Expr, Result) :-
1398 ( eval(Expr, Result0)
1399 -> Result = Result0
1400 ; Result = '$null$',
1401 debug(sparql(eval), '~p --> NULL', [Expr])
1402 ).
1403
1404:- rdf_meta
1405 to_rdf(+,t). 1406
1407to_rdf(numeric(Type, Value), literal(type(Type, Atom))) :-
1408 !,
1409 atom_number(Atom, Value).
1410to_rdf(boolean(Val), literal(type(xsd:boolean, Val))) :- !.
1411to_rdf(type(T, Val), literal(type(T, Val))) :- !.
1412to_rdf(lang(L, Val), literal(lang(L, Val))) :- !.
1413to_rdf(simple_literal(L), literal(L)) :- !.
1414to_rdf(string(L), literal(type(xsd:string, L))) :- !.
1415to_rdf(time(Type, D), literal(type(Type, D))) :- !.
1416to_rdf(iri(IRI), IRI) :- !.
1417to_rdf(X, X) :- is_rdf(X).
1418
1422
1423is_rdf(IRI) :- atom(IRI).
1424is_rdf(Var) :- var(Var), !, fail.
1425is_rdf(literal(_)).
1426
1427
1428 1431
1446
1447sparql_find(From, To, F, T, Q) :-
1448 empty_assoc(Visited),
1449 ( nonvar(From)
1450 -> sparql_find_f(From, To, F, T, Q, Visited)
1451 ; nonvar(To)
1452 -> sparql_find_b(From, To, F, T, Q, Visited)
1453 ; query_graph(Q, Graph)
1454 -> rdf_current_node(Graph, From),
1455 sparql_find_f(From, To, F, T, Q, Visited)
1456 ; rdf_current_node(From),
1457 sparql_find_f(From, To, F, T, Q, Visited)
1458 ).
1459
1460sparql_find_f(Place, Place, _, _, _, _).
1461sparql_find_f(From, To, F, T, Q, Visited) :-
1462 copy_term(t(F,T,Q), t(From, Tmp, Q2)),
1463 call(Q2),
1464 \+ get_assoc(Tmp, Visited, _),
1465 put_assoc(Tmp, Visited, true, V2),
1466 sparql_find_f(Tmp, To, F, T, Q, V2).
1467
1468
1469sparql_find_b(Place, Place, _, _, _, _).
1470sparql_find_b(From, To, F, T, Q, Visited) :-
1471 copy_term(t(F,T,Q), t(Tmp, To, Q2)),
1472 call(Q2),
1473 \+ get_assoc(Tmp, Visited, _),
1474 put_assoc(Tmp, Visited, true, V2),
1475 sparql_find_b(From, Tmp, F, T, Q, V2).
1476
1477
1482
1483query_graph(V, _) :-
1484 var(V), !, fail.
1485query_graph(_:Q, G) :-
1486 query_graph(Q, G).
1487query_graph((A,B), G) :-
1488 ( query_graph(A, G)
1489 ; query_graph(B, G)
1490 ).
1491query_graph((A;B), G) :-
1492 ( query_graph(A, G)
1493 ; query_graph(B, G)
1494 ).
1495query_graph((A->B), G) :-
1496 ( query_graph(A, G)
1497 ; query_graph(B, G)
1498 ).
1499query_graph((A*->B), G) :-
1500 ( query_graph(A, G)
1501 ; query_graph(B, G)
1502 ).
1503query_graph(rdf(_,_,_,G:_), G).
1504
1505
1510
1511rdf_current_node(Graph, R) :-
1512 rdf_graph(Graph),
1513 setof(R,
1514 ( rdf(S,_,O,Graph),
1515 ( R = S
1516 ; atom(O),
1517 R = O
1518 )
1519 ),
1520 Rs),
1521 member(R, Rs).
1522
1523
1528
1529rdf_current_node(From) :-
1530 rdf_subject(From).
1531rdf_current_node(From) :-
1532 findall(R, (rdf(_,_,R), \+ (atom(R), rdf_subject(R))), Rs),
1533 sort(Rs, Set),
1534 member(From, Set).
1535
1536
1548
1549sparql_minus(QLeft, QRight) :-
1550 term_variables(QLeft, VarsLeft0), sort(VarsLeft0, VarsLeft),
1551 term_variables(QRight, VarsRight0), sort(VarsRight0, VarsRight),
1552 ord_intersection(VarsLeft, VarsRight, VarsCommon),
1553 ( VarsCommon == []
1554 -> QLeft
1555 ; ord_subtract(VarsLeft, VarsCommon, ExtraLeft),
1556 VLeft =.. [v|ExtraLeft],
1557 VCommon =.. [v|VarsCommon],
1558 findall(VCommon-VLeft, (QLeft,cond_bind_null(VarsLeft)), AllSols),
1559 AllSols \== [],
1560 sort(AllSols, AllSorted),
1561 findall(VCommon, (QRight,cond_bind_null(VarsCommon)), MinusSols),
1562 sort(MinusSols, MinusSorted),
1563 member(VCommon-VLeft, AllSorted),
1564 \+ memberchk(VCommon, MinusSorted)
1565 ).
1566
1567cond_bind_null([]).
1568cond_bind_null([H|T]) :-
1569 ( var(H)
1570 -> H = '$null$'
1571 ; true
1572 ),
1573 cond_bind_null(T).
1574
1575
1576 1579
1584
1585sparql_group(Goal) :-
1586 call(Goal).
1587
1592
1593sparql_group(Goal, OuterVars, InnerVars) :-
1594 call(Goal),
1595 OuterVars = InnerVars.
1596
1597
1598 1601
1611
1612sparql_service(Silent, URL, Prefixes, Bindings, QText) :-
1613 parse_url(URL, Options),
1614 maplist(prefix_line, Prefixes, PrefLines),
1615 partition(bound_binding, Bindings, In, Out),
1616 maplist(proj, Out, Proj),
1617 atomics_to_string(Proj, " ", Projection),
1618 format(string(SubSel), 'SELECT ~w WHERE {', [Projection]),
1619 maplist(binding_line, In, BindLines),
1620 append([ PrefLines, [SubSel], BindLines, [QText], ["}"] ], Lines),
1621 atomics_to_string(Lines, "\n", Query),
1622 debug(sparql(service), 'SERVICE:~n~w', [Query]),
1623 maplist(binding_var, Out, Vars),
1624 Row =.. [row|Vars],
1625 ( Silent == error
1626 -> sparql_query(Query, Row, Options)
1627 ; catch(sparql_query(Query, Row, Options), _, true)
1628 ).
1629
1630prefix_line(Pref-URL, Line) :-
1631 format(string(Line), 'PREFIX ~w: <~w>', [Pref, URL]).
1632
1633bound_binding(_Name = Var) :-
1634 ground(Var).
1635
1636proj(Name=_, Proj) :-
1637 format(string(Proj), '?~w', [Name]).
1638
1639binding_line(Name=IRI, Line) :-
1640 atom(IRI),
1641 !,
1642 with_output_to(string(QIRI),
1643 turtle:turtle_write_uri(current_output, IRI)),
1644 format(string(Line), 'BIND(~s as ?~w)', [QIRI, Name]).
1645binding_line(Name=Literal, Line) :-
1646 rdf_lexical_form(Literal, Lex),
1647 ( Lex = ^^(String,Type)
1648 -> with_output_to(
1649 string(QString),
1650 turtle:turtle_write_quoted_string(current_output, String)),
1651 with_output_to(
1652 string(QType),
1653 turtle:turtle_write_uri(current_output, Type)),
1654 format(string(Line), 'BIND(~s^^<~w> as ?~w)',
1655 [QString, QType, Name])
1656 ; Lex = @(String,Lang)
1657 -> with_output_to(
1658 string(QString),
1659 turtle:turtle_write_quoted_string(current_output, String)),
1660 format(string(Line), 'BIND(~s@~w as ?~w)',
1661 [QString, Lang, Name])
1662 ).
1663
1664binding_var(_Name=Var, Var).
1665
1666
1667 1670
1674
1675sparql_reset_bnodes :-
1676 retractall(bnode_store(_,_)).
1677
1678
1679 1682
1687
1688sparql_simplify(sparql_true(E), G) :-
1689 simplify_true(E, G),
1690 !.
1691sparql_simplify(sparql_eval(E, V), G) :-
1692 simplify_eval(E, V, G),
1693 !.
1694sparql_simplify(Goal, Goal).
1695
1696
1702
1703simplify_true(Var, Var) :- 1704 var(Var),
1705 !,
1706 fail.
1707simplify_true(or(A0,B0), (A;B)) :-
1708 !,
1709 simplify_true(A0, A),
1710 simplify_true(B0, B).
1711simplify_true(and(A0,B0), (A,B)) :-
1712 !,
1713 simplify_true(A0, A),
1714 simplify_true(B0, B).
1715simplify_true(A0=B0, A=B) :-
1716 !,
1717 peval(A0, A, IsResource),
1718 peval(B0, B, IsResource),
1719 IsResource == true. 1720simplify_true(A0\=B0, A\=B) :-
1721 !,
1722 peval(A0, A, IsResource),
1723 peval(B0, B, IsResource),
1724 IsResource == true. 1725simplify_true(Expr, sparql_true(PExpr)) :-
1726 simplify_expression(Expr, PExpr).
1727
1728simplify_expression(Var, Var) :-
1729 var(Var),
1730 !.
1731simplify_expression(Term0, Term) :-
1732 ground(Term0),
1733 !,
1734 eval(Term0, Term).
1735simplify_expression(Term0, Term) :-
1736 list_arg(Term0),
1737 !,
1738 Term0 =.. [Name,Args0],
1739 maplist(simplify_expression, Args0, Args),
1740 Term =.. [Name,Args].
1741simplify_expression(Term0, Term) :-
1742 compound(Term0),
1743 !,
1744 Term0 =.. [Name|Args0],
1745 maplist(simplify_expression, Args0, Args),
1746 Term1 =.. [Name|Args],
1747 simplify_test(Term1, Term).
1748simplify_expression(Term, Term).
1749
1750list_arg(concat(_)).
1751list_arg(coalesce(_)).
1752
1757
1758simplify_test(regex(String, simple_literal(Pattern), simple_literal(Flags)),
1759 compiled_regex(Regex, String)) :-
1760 atom(Pattern), atom(Flags),
1761 !,
1762 regex_obj(Pattern, Flags, Regex).
1763simplify_test(Expr, Expr).
1764
1766
1767simplify_eval(Expr, Var, Goal) :-
1768 simplify_expression(Expr, Expr1),
1769 Goal = sparql_eval(Expr1, Var).
1770
1771peval(Var, Var, IsResource) :-
1772 var(Var),
1773 !,
1774 ( get_attr(Var, annotations, Annot),
1775 memberchk(resource, Annot)
1776 -> IsResource = true
1777 ; true
1778 ).
1779peval(Resource, Resource, true) :-
1780 atom(Resource).
1781
1782
1783 1786
1798
1799sparql_subquery(Proj, Query, Solutions) :-
1800 vars_in_bindings(Proj, Vars),
1801 Reply =.. [row|Vars],
1802 sparql:select_results(Solutions, Reply, Query),
1803 debug(sparql(subquery), 'SubQuery result: ~q', [Proj]),
1804 unify_projection(Proj).
1805
1806vars_in_bindings([], []).
1807vars_in_bindings([_Outer=Var|T0], [Var|T]) :-
1808 vars_in_bindings(T0, T).
1809
1810
1811unify_projection([]).
1812unify_projection([V=V|T]) :-
1813 unify_projection(T).
1814
1815
1816 1819
1825
1826sparql_update(Module:Updates) :-
1827 rdf_transaction(update(Updates, Module), 'SPARQL').
1828
1829update([], _).
1830update([H|T], M) :-
1831 update(H, M),
1832 update(T, M).
1833update(insert_data(Quads), _) :-
1834 materialize_bnodes(Quads),
1835 maplist(insert_triple(user), Quads).
1836update(delete_data(Quads), _) :-
1837 maplist(delete_triple(user), Quads).
1838update(delete_where(Quads), _):-
1839 maplist(delete_triples(user), Quads).
1840update(add(_Silent, From, To), _) :- 1841 db(From, FromDB),
1842 db(To, ToDB),
1843 forall(rdf(S,P,O,FromDB:Line),
1844 rdf_assert(S,P,O,ToDB:Line)).
1845update(move(_Silent, From, To), _) :-
1846 db(From, FromGraph),
1847 db(To, ToGraph),
1848 rdf_retractall(_,_,_,ToGraph),
1849 forall(rdf(S,P,O,FromGraph:Line),
1850 ( rdf_retractall(S,P,O,FromGraph:Line),
1851 rdf_assert(S,P,O,ToGraph:Line)
1852 )).
1853update(copy(_Silent, From, To), _) :-
1854 db(From, FromGraph),
1855 db(To, ToGraph),
1856 rdf_retractall(_,_,_,ToGraph),
1857 forall(rdf(S,P,O,FromGraph:Line),
1858 rdf_assert(S,P,O,ToGraph:Line)).
1859update(modify(With, Modify, _Using, Query), Module) :-
1860 db(With, Graph),
1861 forall(Module:Query,
1862 modify(Modify, Graph)).
1863update(load(_Silent, URI, Into), _) :-
1864 ( Into = graph(Graph)
1865 -> rdf_load(URI, [graph(Graph), multifile(true)])
1866 ; rdf_load(URI)
1867 ).
1868update(clear(_Silent, Clear), _) :-
1869 clear_db(Clear).
1870
1871db(default, user).
1872db(graph(G), G).
1873
1874modify(delete(Delete), Graph) :-
1875 maplist(delete_triple(Graph), Delete).
1876modify(insert(Insert), Graph) :-
1877 maplist(insert_triple(Graph), Insert).
1878modify(replace(Delete, Insert), Graph) :-
1879 maplist(delete_triple(Graph), Delete),
1880 maplist(insert_triple(Graph), Insert).
1881
1883
1884insert_triple(Graph, rdf(S0,P,O0)) :-
1885 !,
1886 modify_subject(S0, S),
1887 modify_object(O0, O),
1888 rdf_assert(S,P,O, Graph).
1889insert_triple(_, rdf(S0,P,O0,G0)) :-
1890 graph(G0, G),
1891 modify_subject(S0, S),
1892 modify_object(O0, O),
1893 rdf_assert(S,P,O,G).
1894
1898
1899delete_triple(Graph, rdf(S,P,O0)) :-
1900 !,
1901 modify_object(O0, O),
1902 rdf_retractall(S,P,O,Graph).
1903delete_triple(_, rdf(S,P,O0,G0)) :-
1904 !,
1905 graph(G0, G),
1906 modify_object(O0, O),
1907 rdf_retractall(S,P,O,G).
1908
1910
1911delete_triples(G0, Triple):-
1912 ( Triple = rdf(S,P,O),
1913 G = G0
1914 ; Triple = rdf(S,P,O,G)
1915 ),
1916 forall(
1917 rdf(S,P,O),
1918 delete_triple(G, rdf(S,P,O))
1919 ).
1920
1921materialize_bnodes(Term) :-
1922 term_variables(Term, Vars),
1923 assign_bnodes(Vars, 0).
1924
1925assign_bnodes([], _).
1926assign_bnodes([bnode(Id)|T], Id) :-
1927 Id2 is Id + 1,
1928 assign_bnodes(T, Id2).
1929
1930modify_subject(bnode(Id), BNode) :-
1931 !,
1932 id_to_bnode(Id, BNode).
1933modify_subject(S, S).
1934
1935modify_object(literal(_Q,V), literal(V)) :- !.
1936modify_object(bnode(Id), BNode) :-
1937 !,
1938 id_to_bnode(Id, BNode).
1939modify_object(O, O).
1940
1941id_to_bnode(Id, BNode):-
1942 ( bnode_store(Id, BN)
1943 -> BN = BNode
1944 ; rdf_bnode(BN),
1945 asserta(bnode_store(Id, BN))
1946 -> BN = BNode
1947 ).
1948
1950
1951graph(G:L, Graph) :-
1952 atom(G),
1953 !,
1954 ( integer(L)
1955 -> Graph = (G:L)
1956 ; Graph = G
1957 ).
1958graph(G, G).
1959
1964
1965clear_db(all) :-
1966 rdf_retractall(_,_,_).
1967clear_db(default) :-
1968 rdf_retractall(_,_,_,user).
1969clear_db(named) :-
1970 forall((rdf_graph(Graph), Graph \== user),
1971 rdf_retractall(_,_,_,Graph)).
1972clear_db(graph(Graph)) :-
1973 rdf_retractall(_,_,_,Graph)