35
36:- module(rdfql_util,
37 [ select_results/6, 38 39 select_results/9, 40 41 42 entailment_module/2 43 ]). 44:- use_module(library(nb_set)). 45:- use_module(library(semweb/rdf_db)). 46:- use_module(library(lists)). 47:- use_module(library(pairs)). 48:- use_module(library(apply)). 49:- use_module(library(xsdp_types)). 50:- use_module(sparql_runtime). 51
52:- meta_predicate
53 select_results(+, +, 0, +, +, +, +, -, 0),
54 select_results(+, +, +, +, -, 0),
55 select_results(+, +, +, -, 0).
61select_results(Distinct, Offset, Limit, SortBy, Result, Goal) :-
62 select_results(Distinct, [], true, [],
63 Offset, Limit, SortBy, Result, Goal).
101:- discontiguous select_results/9. 102
106
107select_results(Distinct, [], _:true, [], Offset, Limit,
108 order_by(Cols), Result, Goal) :-
109 exclude(ground, Cols, SortCols), SortCols \== [],
110 !,
111 group_order(SortCols, GroupedCols),
112 reverse(GroupedCols, RevGroupedCols),
113 maplist(sort_key_goal, RevGroupedCols, GroupedKeys, KeyGenList),
114 list_conj(KeyGenList, KeyGenGoal),
115 sort_template(GroupedKeys, Result, Template),
116 findall(Template, (Goal,rdfql_util:KeyGenGoal), Results0),
117 ( Distinct == distinct
118 -> sort(Results0, Results1)
119 ; Results1 = Results0
120 ),
121 order_by(RevGroupedCols, Results1, Results2),
122 apply_offset(Offset, Results2, Results3),
123 apply_limit(Limit, Results3, Results),
124 member(Result, Results).
132group_order([], []).
133group_order([Col|CT0], [Grouped|GT]) :-
134 Col =.. [Dir,Expr],
135 Grouped =.. [Dir,[Expr|Exprs]],
136 same_order(Dir, CT0, CT, Exprs),
137 group_order(CT, GT).
138
139same_order(Dir, [Col|CT0], CT, [E0|ET]) :-
140 Col =.. [Dir,E0],
141 !,
142 same_order(Dir, CT0, CT, ET).
143same_order(_, CT, CT, []).
144
145list_conj([], true) :- !.
146list_conj([G], G) :- !.
147list_conj([G|T0], (G,T)) :-
148 list_conj(T0, T).
161order_by([], Results, Results).
162order_by([ascending(_)|T], Results0, Results) :-
163 !,
164 keysort(Results0, Results1),
165 pairs_values(Results1, Results2),
166 order_by(T, Results2, Results).
167order_by([descending(_)|T], Results0, Results) :-
168 keysort(Results0, AscSorted),
169 group_pairs_by_key(AscSorted, Grouped),
170 reverse(Grouped, DescSortedKeyedGroups),
171 pairs_values(DescSortedKeyedGroups, DescSortedGroups),
172 append(DescSortedGroups, DescSorted),
173 order_by(T, DescSorted, Results).
178sort_key_goal(ColGroup, KeyGroup, Translate) :-
179 arg(1, ColGroup, Exprs),
180 sort_expr_goal(Exprs, KeyGroup, Translate).
181
182sort_expr_goal([], [], true).
183sort_expr_goal([V], [K], sort_key(V,K)) :- !.
184sort_expr_goal([V|TV], [K|TK], (sort_key(V,K),G)) :-
185 sort_expr_goal(TV, TK, G).
186
187sort_template([], Result, Result).
188sort_template([H0|T], Result, H-Template) :-
189 simplify_sort_key(H0, H),
190 sort_template(T, Result, Template).
191
192simplify_sort_key([One], One) :- !.
193simplify_sort_key(List, Term) :-
194 Term =.. [v|List].
215:- public sort_key/2. 216
217sort_key(Var, Var) :- var(Var), !.
218sort_key(literal(L), sk(4, V)) :-
219 !,
220 simple_literal(L, V).
221sort_key(IRI, sk(N, IRI)) :-
222 ( rdf_is_bnode(IRI)
223 -> N = 2
224 ; N = 3
225 ).
226
227simple_literal(lang(_Lang, SL), SL) :- !.
228simple_literal(type(Type, SL), Number) :-
229 xsdp_numeric_uri(Type, _),
230 atom_number(SL, Number),
231 !.
232simple_literal(type(_Type, SL), SL) :- !.
233simple_literal(SL, SL).
234
235
239
240select_results(Distinct, [], _:true, [], Offset, Limit,
241 _Unsorted, Result, Goal) :-
242 !,
243 select_results(Distinct, Offset, Limit, Result, Goal).
250select_results(distinct, Offset, Limit, Result, Goal) :-
251 !,
252 term_variables(Result, Vars),
253 V =.. [v|Vars],
254 empty_nb_set(Set),
255 Counter = count(0),
256 Goal,
257 add_nb_set(V, Set, New),
258 New == true,
259 apply_limit(Counter, Offset, Limit, Last),
260 ( Last == true -> ! ; true ).
261select_results(_, 0, inf, _, G) :-
262 !,
263 G.
264select_results(_, Offset, Limit, _, G) :-
265 !,
266 Counter = count(0),
267 G,
268 apply_limit(Counter, Offset, Limit, Last),
269 ( Last == true -> ! ; true ).
270
271apply_limit(_, 0, inf, false) :- !.
272apply_limit(Counter, Offset, Limit, Last) :-
273 arg(1, Counter, N0),
274 N is N0 + 1,
275 nb_setarg(1, Counter, N),
276 N > Offset,
277 ( Limit \== inf,
278 N =:= Offset+Limit
279 -> Last = true
280 ; Last = false
281 ).
285apply_offset(N, [_|T], List) :-
286 N > 0,
287 !,
288 N2 is N - 1,
289 apply_offset(N2, T, List).
290apply_offset(_, List, List).
294apply_limit(inf, List, List) :- !.
295apply_limit(Limit, All, List) :-
296 limit(Limit, All, List).
297
298limit(N, [H|T0], [H|T]) :-
299 N > 0,
300 !,
301 N2 is N - 1,
302 limit(N2, T0, T).
303limit(_, _, []).
304
305
329
330select_results(_Distinct, [], Having, AggregateEval, _Offset, _Limit,
331 _Order, _Result, Goal) :-
332 !,
333 aggregate_vars(AggregateEval, Aggregates, AggVars, Eval),
334 AV =.. [a|AggVars],
335 findall(AV, Goal, Group),
336 aggregate(Group, Aggregates),
337 call(Eval),
338 call(Having).
339select_results(_Distinct, Group, Having, AggregateEval, Offset, Limit,
340 _Order, _Result, Goal) :-
341 aggregate_vars(AggregateEval, Aggregates, AggVars, Eval),
342 GV =.. [v|Group],
343 AV =.. [a|AggVars],
344 findall(GV-AV, Goal, Pairs),
345 keysort(Pairs, SortedPairs),
346 group_pairs_by_key(SortedPairs, Groups0),
347 apply_offset(Offset, Groups0, Groups1),
348 apply_limit(Limit, Groups1, Groups),
349 member(GV-G, Groups),
350 aggregate(G, Aggregates),
351 call(Eval),
352 call(Having).
356aggregate([AVT|Group], Aggregates) :-
357 !,
358 AVT =.. [a|AV0],
359 maplist(aggregate_setup, AV0, State0),
360 aggregate_steps(Group, State0, State),
361 maplist(aggregate_bind, Aggregates, State).
362aggregate([], Aggregates) :-
363 maplist(empty_aggregate, Aggregates).
364
365aggregate_setup(count(X), Count) :-
366 aggregate_step(count(X), 0, Count).
367aggregate_setup(distinct(X, _Op), Set) :-
368 ( is_null(X) -> Set = [] ; Set = [X] ).
369aggregate_setup(sum(X0), X) :-
370 sparql_eval_raw(X0, X).
371aggregate_setup(min(X0), X) :-
372 sparql_eval_raw(X0, X).
373aggregate_setup(max(X0), X) :-
374 sparql_eval_raw(X0, X).
375aggregate_setup(avg(X0), X-1) :-
376 sparql_eval_raw(X0, X).
377aggregate_setup(sample(X), X).
378aggregate_setup(group_concat(Expr,_), [X]) :-
379 group_concat_value(Expr, X).
380
381aggregate_steps([], State, State).
382aggregate_steps([HT|T], State0, State) :-
383 HT =.. [a|H],
384 maplist(aggregate_step, H, State0, State1),
385 aggregate_steps(T, State1, State).
386
387aggregate_step(count(X), Count0, Count) :-
388 ( is_null(X) -> Count = Count0 ; Count is Count0 + 1 ).
389aggregate_step(distinct(X, _Op), S0, S) :-
390 ( is_null(X) -> S = S0 ; S = [X|S0] ).
391aggregate_step(sum(X), Sum0, Sum) :-
392 sparql_eval_raw(X+Sum0, Sum).
393aggregate_step(min(X), Min0, Min) :-
394 sparql_eval_raw(min(X, Min0), Min).
395aggregate_step(max(X), Min0, Min) :-
396 sparql_eval_raw(max(X, Min0), Min).
397aggregate_step(avg(X), Sum0-Count0, Sum-Count) :-
398 sparql_eval_raw(X+Sum0, Sum),
399 Count is Count0+1.
400aggregate_step(sample(X), S0, S) :-
401 ( is_null(S0)
402 -> S = X
403 ; S = S0
404 ).
405aggregate_step(group_concat(Expr, _), S0, [X|S0]) :-
406 group_concat_value(Expr, X).
412aggregate_bind(aggregate(Func, Var), State) :-
413 aggregate_bind(Func, Var, State).
414
415aggregate_bind(count(_), Count, Count0) :-
416 rdf_equal(xsd:integer, XSDInt),
417 sparql_eval(numeric(XSDInt, Count0), Count).
418aggregate_bind(sum(_), Sum, Sum0) :-
419 bind_number(Sum0, Sum).
420aggregate_bind(min(_), Min, Min0) :-
421 bind_number(Min0, Min).
422aggregate_bind(max(_), Max, Max0) :-
423 bind_number(Max0, Max).
424aggregate_bind(avg(_), Avg, Sum-Count) :-
425 rdf_equal(xsd:integer, XSDInt),
426 sparql_eval(Sum/numeric(XSDInt, Count), Avg).
427aggregate_bind(sample(_), Sample, Sample).
428aggregate_bind(group_concat(Expr, literal(Sep)), literal(Concat), Parts0) :-
429 ( functor(Expr, distinct, 1)
430 -> sort(Parts0, Parts)
431 ; Parts = Parts0
432 ),
433 maplist(text_of, Parts, Texts),
434 atomic_list_concat(Texts, Sep, Concat).
435aggregate_bind(distinct(_, Op), Value, Set) :-
436 sort(Set, Distinct),
437 aggregate_distinct(Op, Distinct, Value).
441aggregate_distinct(count, Set, Value) :-
442 rdf_equal(xsd:integer, IntType),
443 length(Set, Len),
444 bind_number(numeric(IntType, Len), Value).
445aggregate_distinct(sum, Set, Sum) :-
446 rdf_equal(xsd:integer, IntType),
447 foldl(add, Set, number(IntType, 0), Sum0),
448 bind_number(Sum0, Sum).
449aggregate_distinct(avg, Set, Avg) :-
450 aggregate_distinct(sum, Set, Sum),
451 length(Set, Count),
452 rdf_equal(xsd:integer, XSDInt),
453 sparql_eval(Sum/numeric(XSDInt, Count), Avg).
454
455add(X, Sum0, Sum) :-
456 sparql_eval_raw(X+Sum0, Sum).
457
458text_of(Expr, Atom) :-
459 sparql_eval_raw(Expr, V0),
460 raw_text(V0, Atom).
461
462raw_text(string(X), X).
463raw_text(simple_literal(X), X).
464raw_text(lang(_Lang, SL), SL). 465 466
467bind_number(V0, V) :-
468 ( V0 = numeric(_, _)
469 -> sparql_eval(V0, V)
470 ; V = '$null$'
471 ).
472
473group_concat_value(Expr, Value) :-
474 ( functor(Expr, distinct, 1)
475 -> arg(1, Expr, Value)
476 ; Value = Expr
477 ).
478
479:- rdf_meta empty_aggregate(t). 480
481empty_aggregate(aggregate(count(_), literal(type(xsd:integer, '0')))).
482empty_aggregate(aggregate(sum(_), literal(type(xsd:integer, '0')))).
483empty_aggregate(aggregate(distinct(_,count), literal(type(xsd:integer, '0')))).
484empty_aggregate(aggregate(group_concat(_,_), literal(''))).
497aggregate_vars([], [], [], true).
498aggregate_vars([aggregate(Term0, Into)|T],
499 [aggregate(Term, Into)|AT], [Term|Templ], Q) :-
500 !,
501 x_distinct(Term0, Term),
502 aggregate_vars(T, AT, Templ, Q).
503aggregate_vars([Q0|T], Agg, Templ, Q) :-
504 aggregate_vars(T, Agg, Templ, Q1),
505 mkconj(Q1, Q0, Q).
506
507mkconj(true, Q, Q) :- !.
508mkconj(Q, true, Q) :- !.
509mkconj(A, B, (A,B)).
510
511x_distinct(Term0, Term) :-
512 arg(1, Term0, Spec),
513 compound(Spec),
514 Spec = distinct(_),
515 distinct_x(Term0, Term),
516 !.
517x_distinct(Term, Term).
518
519distinct_x(count(distinct(X)), distinct(X, count)).
520distinct_x(count(sum(X)), distinct(X, sum)).
521distinct_x(count(avg(X)), distinct(X, avg)).
522
523is_null(X) :-
524 ( var(X)
525 -> true
526 ; X == '$null$'
527 ).
528
529
538entailment_module(Entailment, Module) :-
539 cliopatria:entailment(Entailment, Module),
540 !.
541entailment_module(Entailment, _) :-
542 throw(error(existence_error(entailment, Entailment), _)).
543
544:- multifile
545 cliopatria:entailment/2.