Chris@0: /* $Id$ Chris@0: Chris@0: Part of SWI-Prolog Chris@0: Chris@0: Author: Jan Wielemaker Chris@0: E-mail: wielemak@science.uva.nl Chris@0: WWW: http://www.swi-prolog.org Chris@0: Copyright (C): 2004-2006, University of Amsterdam Chris@0: Chris@0: This program is free software; you can redistribute it and/or Chris@0: modify it under the terms of the GNU General Public License Chris@0: as published by the Free Software Foundation; either version 2 Chris@0: of the License, or (at your option) any later version. Chris@0: Chris@0: This program 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 Lesser General Public Chris@0: License along with this library; if not, write to the Free Software Chris@0: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Chris@0: Chris@0: As a special exception, if you link this library with other files, Chris@0: compiled with a Free Software compiler, to produce an executable, this Chris@0: library does not by itself cause the resulting executable to be covered Chris@0: by the GNU General Public License. This exception does not however Chris@0: invalidate any other reasons why the executable file might be covered by Chris@0: the GNU General Public License. Chris@0: */ Chris@0: Chris@0: :- module(rdfql_util, Chris@0: [ select_results/6, % +Distinct, +Offset, +Limit, Chris@0: % :SortBy, -Result, :Goal Chris@0: entailment_module/2 % +Entailment, -Module Chris@0: ]). Chris@0: :- use_module(library(nb_set)). Chris@0: Chris@0: :- module_transparent Chris@0: select_results/6, Chris@0: select_results/5. Chris@0: Chris@0: %% select_results(+Distinct, +Offset, +Limit, :SortBy, -Result, :Goal) Chris@0: % Chris@0: % Select results for the template Result on backtracking over Chris@0: % Goal. Chris@0: % Chris@0: % @param Distinct Chris@0: % Iff 'distinct', only consider distinct solutions Chris@0: % Chris@0: % @param Offset Chris@0: % Skip the first Offset results. Offset is applied after Chris@0: % Distinct and SortBy Chris@0: % Chris@0: % @param Limit Chris@0: % Only return the first Limit results. Limit is applied Chris@0: % after Distinct, SortBy and Offset. The value 'inf' Chris@0: % returns all values. Chris@0: % Chris@0: % @param SortBy Chris@0: % Either 'unsorted' or the name of a predicate that sorts Chris@0: % the result-set by calling call(SortBy, UnSorted, Sorted) Chris@0: Chris@0: select_results(Distinct, Offset, Limit, unsorted, Result, Goal) :- !, Chris@0: select_results(Distinct, Offset, Limit, Result, Goal). Chris@0: select_results(Distinct, Offset, Limit, order_by(Cols), Result, Goal) :- !, Chris@0: term_variables(Cols, Vars), Chris@0: SortKey =.. [v|Vars], Chris@0: findall(SortKey-Result, Goal, Results0), Chris@0: ( Distinct == distinct Chris@0: -> sort(Results0, Results1) Chris@0: ; keysort(Results0, Results1) Chris@0: ), Chris@0: apply_offset(Offset, Results1, Results2), Chris@0: apply_limit(Limit, Results2, Results), Chris@0: member(_Key-Result, Results). Chris@0: Chris@0: %% select_results(+Distinct, +Offset, +Limit, -Result, :Goal) Chris@0: % Chris@0: % Unsorted version. In this case we can avoid first collecting all Chris@0: % results. Chris@0: Chris@0: select_results(distinct, Offset, Limit, Result, Goal) :- !, Chris@0: term_variables(Result, Vars), Chris@0: V =.. [v|Vars], Chris@0: empty_nb_set(Set), Chris@0: Counter = count(0), Chris@0: Goal, Chris@0: add_nb_set(V, Set, New), Chris@0: New == true, Chris@0: apply_limit(Counter, Offset, Limit, Last), Chris@0: ( Last == true -> ! ; true ). Chris@0: select_results(_, 0, inf, _, G) :- !, Chris@0: G. Chris@0: select_results(_, Offset, Limit, _, G) :- !, Chris@0: Counter = count(0), Chris@0: G, Chris@0: apply_limit(Counter, Offset, Limit, Last), Chris@0: ( Last == true -> ! ; true ). Chris@0: Chris@0: apply_limit(_, 0, inf, false) :- !. Chris@0: apply_limit(Counter, Offset, Limit, Last) :- Chris@0: arg(1, Counter, N0), Chris@0: N is N0 + 1, Chris@0: nb_setarg(1, Counter, N), Chris@0: N > Offset, Chris@0: ( Limit \== inf, Chris@0: N =:= Offset+Limit Chris@0: -> Last = true Chris@0: ; Last = false Chris@0: ). Chris@0: Chris@0: apply_offset(0, List, List) :- !. Chris@0: apply_offset(N, [_|T], List) :- Chris@0: N > 0, Chris@0: N2 is N - 1, Chris@0: apply_offset(N2, T, List). Chris@0: Chris@0: apply_limit(inf, List, List) :- !. Chris@0: apply_limit(0, _, []). Chris@0: apply_limit(N, [H|T0], [H|T]) :- Chris@0: N > 0, Chris@0: N2 is N - 1, Chris@0: apply_offset(N2, T0, T). Chris@0: Chris@0: Chris@0: /******************************* Chris@0: * ENTAILMENT * Chris@0: *******************************/ Chris@0: Chris@0: %% entailment_module(+Entailment, -Module) Chris@0: % Chris@0: % Find the Prolog module implementing the entailment rules for a Chris@0: % semantic web language. Chris@0: Chris@0: entailment_module(Entailment, Module) :- Chris@0: serql:entailment(Entailment, Module), !. Chris@0: entailment_module(Entailment, _) :- Chris@0: throw(error(existence_error(entailment, Entailment), _)). Chris@0: Chris@0: :- multifile Chris@0: serql:entailment/2. Chris@0: