View source with formatted comments or as raw
   1/*  Part of ClioPatria SPARQL server
   2
   3    Author:        Jan Wielemaker
   4    E-mail:        J.Wielemaker@vu.nl
   5    WWW:           http://www.swi-prolog.org
   6    Copyright (C): 2012 VU University Amsterdam
   7
   8    This program is free software; you can redistribute it and/or
   9    modify it under the terms of the GNU General Public License
  10    as published by the Free Software Foundation; either version 2
  11    of the License, or (at your option) any later version.
  12
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17
  18    You should have received a copy of the GNU General Public
  19    License along with this library; if not, write to the Free Software
  20    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21
  22    As a special exception, if you link this library with other files,
  23    compiled with a Free Software compiler, to produce an executable, this
  24    library does not by itself cause the resulting executable to be covered
  25    by the GNU General Public License. This exception does not however
  26    invalidate any other reasons why the executable file might be covered by
  27    the GNU General Public License.
  28*/
  29
  30:- module(jena_properties, []).
  31:- use_module(library(semweb/rdfs)).
  32:- use_module(library(semweb/rdf_db)).
  33:- use_module(library(aggregate)).
  34:- use_module(sparql_runtime).
  35
  36:- multifile
  37	sparql:functional_property/2,
  38	sparql:current_functional_property/3.
  39
  40ns(apf,   'http://jena.hpl.hp.com/ARQ/property#').
  41ns(lists, 'http://jena.hpl.hp.com/ARQ/list#').
  42ns(Prefix, URI) :-
  43	rdf_current_ns(Prefix, URI).
  44
  45alias('java:com.hp.hpl.jena.sparql.pfunction.library.',
  46      'http://jena.hpl.hp.com/ARQ/property#').
  47alias('java:com.hp.hpl.jena.query.pfunction.library.',
  48      'http://jena.hpl.hp.com/ARQ/property#').
  49
  50property_alias(Prefix:Local, Global) :-
  51	ns(Prefix, URI),
  52	alias(AliasBase, URI),
  53	atom_concat(AliasBase, Local, Global).
  54
  55absolute_uri(Prefix:Local, Global) :-
  56	ns(Prefix, URI),
  57	atom_concat(URI, Local, Global).
  58
  59term_expansion((sparql:functional_property(S, NS:Term0) :- Body),
  60	       [ (sparql:functional_property(S, Term) :- Body),
  61		 sparql:current_functional_property(P, P, Argc)
  62	       | Aliases
  63	       ]) :-
  64	Term0 =.. [Name|Args],
  65	length(Args, Argc),
  66	absolute_uri(NS:Name, P),
  67	Term =.. [P|Args],
  68	findall(sparql:current_functional_property(P1, P, Argc),
  69		property_alias(NS:Name, P1),
  70		Aliases).
  71
  72
  73		 /*******************************
  74		 *    JENA PROPERTY FUNCTIONS	*
  75		 *******************************/
  76
  77% See http://jena.sourceforge.net/ARQ/library-propfunc.html
  78
  79% (S apf:assign, O) is basically unification.
  80
  81sparql:functional_property(S, apf:assign(O)) :-
  82	(   S = O
  83	->  true
  84	;   sparql_true(S=O)
  85	).
  86
  87
  88		 /*******************************
  89		 *	       LISTS		*
  90		 *******************************/
  91
  92rdf_list(S) :-
  93	rdf_equal(S, rdf:nil).
  94rdf_list(S) :-
  95	rdf(S, rdf:first, _).
  96
  97rdf_container(Container) :-
  98	container_class(Class),
  99	rdfs_individual_of(Container, Class).
 100
 101:- rdf_meta container_class(r).
 102
 103container_class(rdf:'Bag').
 104container_class(rdf:'Seq').
 105container_class(rdf:'Alt').
 106
 107% (S, lists:member, O) means that O is a member of the collection S. In
 108% Jena, S may be unbound, finding all lists on the database.
 109
 110sparql:functional_property(S, lists:member(O)) :-
 111	rdf_list(S),
 112	rdfs_member(O, S).
 113
 114sparql:functional_property(S, rdfs:member(O)) :-
 115	rdf_container(S),
 116	rdfs_member(O, S).
 117
 118sparql:functional_property(S, apf:bag(O)) :-
 119	nonvar(S),
 120	rdfs_individual_of(S, rdfs:'Bag'),
 121	rdfs_member(O, S).
 122sparql:functional_property(S, apf:seq(O)) :-
 123	nonvar(S),
 124	rdfs_individual_of(S, rdfs:'Seq'),
 125	rdfs_member(O, S).
 126sparql:functional_property(S, apf:alt(O)) :-
 127	nonvar(S),
 128	rdfs_individual_of(S, rdfs:'Alt'),
 129	rdfs_member(O, S).
 130
 131
 132% (S, lists:length, O) is true when O is the length of the collection S.
 133% Again, S may be unbound.
 134
 135sparql:functional_property(S, lists:length(O)) :-
 136	rdf_list(S),
 137	aggregate_all(count, rdfs_member(_, S), Len),
 138	rdf_equal(xsd:integer, IntType),
 139	atom_number(String, Len),
 140	O = literal(type(IntType, String)).
 141
 142sparql:functional_property(S, lists:index(literal(type(IntType, Index)),
 143					  Element)) :-
 144	rdf_list(S),
 145	rdf_equal(xsd:integer, IntType),
 146	(   var(Index)
 147	->  rdfs_nth1(I, S, Element),
 148	    atom_number(Index, I)
 149	;   atom_number(Index, I),
 150	    rdfs_nth1(I, S, Element)
 151	->  true
 152	).
 153
 154
 155rdfs_nth1(0, Set, Element) :-
 156	rdf_has(Set, rdf:first, Element).
 157rdfs_nth1(I, Set, Element) :-
 158	var(I), !,
 159	rdf_has(Set, rdf:rest, Tail),
 160	rdfs_nth1(I0, Tail, Element),
 161	I is I0 + 1.
 162rdfs_nth1(I, Set, Element) :-
 163	I2 is I - 1,
 164	rdf_has(Set, rdf:rest, Tail),
 165	rdfs_nth1(I2, Tail, Element).