470 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
		
		
			
		
	
	
			470 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| 
								 | 
							
								/*  $Id$
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Part of SWI-Prolog
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Author:        Jan Wielemaker
							 | 
						||
| 
								 | 
							
								    E-mail:        wielemak@science.uva.nl
							 | 
						||
| 
								 | 
							
								    WWW:           http://www.swi-prolog.org
							 | 
						||
| 
								 | 
							
								    Copyright (C): 1985-2005, University of Amsterdam
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    This program is free software; you can redistribute it and/or
							 | 
						||
| 
								 | 
							
								    modify it under the terms of the GNU General Public License
							 | 
						||
| 
								 | 
							
								    as published by the Free Software Foundation; either version 2
							 | 
						||
| 
								 | 
							
								    of the License, or (at your option) any later version.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    This program is distributed in the hope that it will be useful,
							 | 
						||
| 
								 | 
							
								    but WITHOUT ANY WARRANTY; without even the implied warranty of
							 | 
						||
| 
								 | 
							
								    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
							 | 
						||
| 
								 | 
							
								    GNU General Public License for more details.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    You should have received a copy of the GNU Lesser General Public
							 | 
						||
| 
								 | 
							
								    License along with this library; if not, write to the Free Software
							 | 
						||
| 
								 | 
							
								    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    As a special exception, if you link this library with other files,
							 | 
						||
| 
								 | 
							
								    compiled with a Free Software compiler, to produce an executable, this
							 | 
						||
| 
								 | 
							
								    library does not by itself cause the resulting executable to be covered
							 | 
						||
| 
								 | 
							
								    by the GNU General Public License. This exception does not however
							 | 
						||
| 
								 | 
							
								    invalidate any other reasons why the executable file might be covered by
							 | 
						||
| 
								 | 
							
								    the GNU General Public License.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:- module(rdfs,
							 | 
						||
| 
								 | 
							
									  [ rdfs_subproperty_of/2,	% ?SubProperties, ?Property
							 | 
						||
| 
								 | 
							
									    rdfs_subclass_of/2,		% ?SubClass, ?Class
							 | 
						||
| 
								 | 
							
									    rdfs_class_property/2,	% +Class, ?Property
							 | 
						||
| 
								 | 
							
									    rdfs_individual_of/2,	% ?Resource, ?Class
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									    rdfs_label/2,		% ?Resource, ?Label
							 | 
						||
| 
								 | 
							
									    rdfs_label/3,		% ?Resource, ?Language, ?Label
							 | 
						||
| 
								 | 
							
									    rdfs_ns_label/2,		% +Resource, -Label
							 | 
						||
| 
								 | 
							
									    rdfs_ns_label/3,		% +Resource, ?Label, -Label
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									    rdfs_member/2,		% ?Object, +Set
							 | 
						||
| 
								 | 
							
									    rdfs_list_to_prolog_list/2,	% +Set, -List
							 | 
						||
| 
								 | 
							
									    rdfs_assert_list/3,		% +List, -Resource, +DB
							 | 
						||
| 
								 | 
							
									    rdfs_assert_list/2,		% +List, -Resource
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									    rdfs_find/5			% +String, +Dom, +Props, +Method, -Subj
							 | 
						||
| 
								 | 
							
									  ]).
							 | 
						||
| 
								 | 
							
								:- use_module(library(debug)).
							 | 
						||
| 
								 | 
							
								:- use_module(library(rdf)).
							 | 
						||
| 
								 | 
							
								:- use_module(library(lists)).
							 | 
						||
| 
								 | 
							
								:- use_module(rdf_db).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/** <module> RDFS handling
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This module provides various primitives for  more high-level handling of
							 | 
						||
| 
								 | 
							
								RDF models from an RDFS viewpoint. Note  that there exist two approaches
							 | 
						||
| 
								 | 
							
								for languages on top of RDF:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									* Provide new predicates according to the concept of the high
							 | 
						||
| 
								 | 
							
									  level language (used in this module)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									* Extend rdf/3 relation with triples _implied_ by the high-level
							 | 
						||
| 
								 | 
							
									  semantics.  This approach is taken by the SeRQL system.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										 /*******************************
							 | 
						||
| 
								 | 
							
										 *	    EXPANSION		*
							 | 
						||
| 
								 | 
							
										 *******************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:- rdf_meta
							 | 
						||
| 
								 | 
							
									rdfs_subproperty_of(r,r),
							 | 
						||
| 
								 | 
							
									rdfs_subclass_of(r,r),
							 | 
						||
| 
								 | 
							
									rdfs_class_property(r,r),
							 | 
						||
| 
								 | 
							
									rdfs_individual_of(r,r),
							 | 
						||
| 
								 | 
							
									rdfs_label(r,-).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										 /*******************************
							 | 
						||
| 
								 | 
							
										 *	PROPERTY HIERARCHY	*
							 | 
						||
| 
								 | 
							
										 *******************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	rdfs_subproperty_of(+SubProperty, ?Property) is nondet.
							 | 
						||
| 
								 | 
							
								%%	rdfs_subproperty_of(?SubProperty, +Property) is nondet.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Query the property hierarchy.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdfs_subproperty_of(SubProperty, Property) :-
							 | 
						||
| 
								 | 
							
									rdf_reachable(SubProperty, rdfs:subPropertyOf, Property).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										 /*******************************
							 | 
						||
| 
								 | 
							
										 *	  CLASS HIERARCHY	*
							 | 
						||
| 
								 | 
							
										 *******************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	rdfs_subclass_of(+Class, ?Super) is nondet.
							 | 
						||
| 
								 | 
							
								%%	rdfs_subclass_of(?Class, +Super) is nondet.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Generate  sub/super  classes.  rdf_reachable/3    considers  the
							 | 
						||
| 
								 | 
							
								%	rdfs:subPropertyOf relation as well  as   cycles.  Note  that by
							 | 
						||
| 
								 | 
							
								%	definition all classes are  subclass   of  rdfs:Resource, a case
							 | 
						||
| 
								 | 
							
								%	which is dealt with by the 1st and 3th clauses :-(
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	According to production 2.4 "rdfs:Datatype", Each instance of
							 | 
						||
| 
								 | 
							
								%	rdfs:Datatype is a subclass of rdfs:Literal.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdfs_subclass_of(Class, Super) :-
							 | 
						||
| 
								 | 
							
									rdf_equal(rdfs:'Resource', Resource),
							 | 
						||
| 
								 | 
							
									Super == Resource, !,
							 | 
						||
| 
								 | 
							
									(   nonvar(Class)
							 | 
						||
| 
								 | 
							
									->  true			% must check for being a class?
							 | 
						||
| 
								 | 
							
									;   rdfs_individual_of(Class, rdfs:'Class')
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								rdfs_subclass_of(Class, Super) :-
							 | 
						||
| 
								 | 
							
									rdf_reachable(Class, rdfs:subClassOf, Super).
							 | 
						||
| 
								 | 
							
								rdfs_subclass_of(Class, Super) :-
							 | 
						||
| 
								 | 
							
									nonvar(Class),
							 | 
						||
| 
								 | 
							
									var(Super),
							 | 
						||
| 
								 | 
							
									\+ rdf_reachable(Class, rdfs:subClassOf, rdfs:'Resource'),
							 | 
						||
| 
								 | 
							
									rdfs_individual_of(Class, rdfs:'Class'),
							 | 
						||
| 
								 | 
							
									rdf_equal(Super, rdfs:'Resource').
							 | 
						||
| 
								 | 
							
								rdfs_subclass_of(Class, Super) :-	% production 2.4
							 | 
						||
| 
								 | 
							
									(   nonvar(Class)
							 | 
						||
| 
								 | 
							
									->  rdf_has(Class, rdf:type, CType),
							 | 
						||
| 
								 | 
							
									    rdf_reachable(CType, rdfs:subClassOf, rdfs:'Datatype'),
							 | 
						||
| 
								 | 
							
									    \+ rdf_reachable(Class, rdfs:subClassOf, rdfs:'Literal'),
							 | 
						||
| 
								 | 
							
									    rdf_equal(Super, rdfs:'Literal')
							 | 
						||
| 
								 | 
							
									;   nonvar(Super)
							 | 
						||
| 
								 | 
							
									->  rdf_reachable(Super, rdfs:subClassOf, rdfs:'Literal'),
							 | 
						||
| 
								 | 
							
									    rdfs_individual_of(Class, rdfs:'Datatype')
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										 /*******************************
							 | 
						||
| 
								 | 
							
										 *	    INDIVIDUALS		*
							 | 
						||
| 
								 | 
							
										 *******************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	rdfs_individual_of(+Resource, +Class) is semidet.
							 | 
						||
| 
								 | 
							
								%%	rdfs_individual_of(+Resource, -Class) is nondet.
							 | 
						||
| 
								 | 
							
								%%	rdfs_individual_of(-Resource, +Class) is nondet.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Generate resources belonging to a class   or  classes a resource
							 | 
						||
| 
								 | 
							
								%	belongs to. We assume everything at the `object' end of a triple
							 | 
						||
| 
								 | 
							
								%	is a class. A validator should confirm this property.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	rdfs_individual_of(+, -) does  not  exploit   domain  and  range
							 | 
						||
| 
								 | 
							
								%	properties, deriving that if rdf(R,  P,   _)  is  present R must
							 | 
						||
| 
								 | 
							
								%	satisfy the domain of P (and similar for range).
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	There are a few hacks:
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%		* Any resource is an individual of rdfs:Resource
							 | 
						||
| 
								 | 
							
								%		* literal(_) is an individual of rdfs:Literal
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdfs_individual_of(Resource, Class) :-
							 | 
						||
| 
								 | 
							
									nonvar(Resource), !,
							 | 
						||
| 
								 | 
							
									(   nonvar(Class)
							 | 
						||
| 
								 | 
							
									->  (   rdfs_individual_of_r_c(Resource, Class)
							 | 
						||
| 
								 | 
							
									    ->	true
							 | 
						||
| 
								 | 
							
									    )
							 | 
						||
| 
								 | 
							
									;   rdfs_individual_of_r_c(Resource, Class)
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								rdfs_individual_of(Resource, Class) :-
							 | 
						||
| 
								 | 
							
									nonvar(Class), !,
							 | 
						||
| 
								 | 
							
									(   rdf_equal(Class, rdfs:'Resource')
							 | 
						||
| 
								 | 
							
									->  rdf_subject(Resource)
							 | 
						||
| 
								 | 
							
									;   rdfs_subclass_of(SubClass, Class),
							 | 
						||
| 
								 | 
							
									    rdf_has(Resource, rdf:type, SubClass)
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								rdfs_individual_of(_Resource, _Class) :-
							 | 
						||
| 
								 | 
							
									throw(error(instantiation_error, _)).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdfs_individual_of_r_c(literal(_), Class) :- !,
							 | 
						||
| 
								 | 
							
									rdfs_subclass_of(Class, rdfs:'Literal').
							 | 
						||
| 
								 | 
							
								rdfs_individual_of_r_c(Resource, Class) :-
							 | 
						||
| 
								 | 
							
									rdf_has(Resource, rdf:type, MyClass),
							 | 
						||
| 
								 | 
							
									rdfs_subclass_of(MyClass, Class).
							 | 
						||
| 
								 | 
							
								rdfs_individual_of_r_c(_, Class) :-
							 | 
						||
| 
								 | 
							
									rdf_equal(Class, rdfs:'Resource').
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	rdfs_label(+Resource, -Label).
							 | 
						||
| 
								 | 
							
								%%	rdfs_label(-Resource, +Label).
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Convert between class and label.  If the label is generated from
							 | 
						||
| 
								 | 
							
								%	the resource the it uses both rdf:label and its sub-properties,
							 | 
						||
| 
								 | 
							
								%	but labels registered with rdf:label are returned first.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdfs_label(Resource, Label) :-
							 | 
						||
| 
								 | 
							
									rdfs_label(Resource, _, Label).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	rdfs_label(+Resource, ?Lang, -Label) is multi.
							 | 
						||
| 
								 | 
							
								%%	rdfs_label(+Resource, ?Lang, +Label) is semidet.
							 | 
						||
| 
								 | 
							
								%%	rdfs_label(-Resource, ?Lang, ?Label) is nondet.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Resource  has  Label  in  Lang.  If  Resource  is  nonvar  calls
							 | 
						||
| 
								 | 
							
								%	take_label/3 which is guaranteed to succeed label.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdfs_label(Resource, Lang, Label) :-
							 | 
						||
| 
								 | 
							
									nonvar(Resource), !,
							 | 
						||
| 
								 | 
							
									take_label(Resource, Lang, Label).
							 | 
						||
| 
								 | 
							
								rdfs_label(Resource, Lang, Label) :-
							 | 
						||
| 
								 | 
							
									rdf_has(Resource, rdfs:label, literal(lang(Lang, Label))).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	rdfs_ns_label(+Resource, -Label) is multi.
							 | 
						||
| 
								 | 
							
								%%	rdfs_ns_label(+Resource, ?Lang, -Label) is multi.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Present label with  namespace  indication.   This  predicate  is
							 | 
						||
| 
								 | 
							
								%	indented  to  provide  meaningful  short   names  applicable  to
							 | 
						||
| 
								 | 
							
								%	ontology maintainers.  Note that this predicate is non-deterministic
							 | 
						||
| 
								 | 
							
								%	if the resource has multiple rdfs:label properties
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdfs_ns_label(Resource, Label) :-
							 | 
						||
| 
								 | 
							
									rdfs_ns_label(Resource, _, Label).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdfs_ns_label(Resource, Lang, Label) :-
							 | 
						||
| 
								 | 
							
									rdfs_label(Resource, Lang, Label0),
							 | 
						||
| 
								 | 
							
									(   rdf_global_id(NS:_, Resource),
							 | 
						||
| 
								 | 
							
									    Label0 \== ''
							 | 
						||
| 
								 | 
							
									->  atomic_list_concat([NS, Label0], :, Label)
							 | 
						||
| 
								 | 
							
									;   \+ rdf_has(Resource, rdfs:label, _)
							 | 
						||
| 
								 | 
							
									->  Label = Resource
							 | 
						||
| 
								 | 
							
									;   member(Sep, [#,/]),
							 | 
						||
| 
								 | 
							
									    sub_atom(Resource, B, L, A, Sep),
							 | 
						||
| 
								 | 
							
									    sub_atom(Resource, _, A, 0, Frag),
							 | 
						||
| 
								 | 
							
									    \+ sub_atom(Frag, _, _, _, Sep)
							 | 
						||
| 
								 | 
							
									->  Len is B+L,
							 | 
						||
| 
								 | 
							
									    sub_atom(Resource, 0, Len, _, NS),
							 | 
						||
| 
								 | 
							
									    atomic_list_concat([NS, Label0], :, Label)
							 | 
						||
| 
								 | 
							
									;   Label = Label0
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	take_label(+Resource, ?Lang, -Label) is multi.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Get the label to use for a  resource in the give Language. First
							 | 
						||
| 
								 | 
							
								%	tries label_of/3.  If this fails, break the Resource over # or /
							 | 
						||
| 
								 | 
							
								%	and if all fails, unify Label with Resource.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								take_label(Resource, Lang, Label) :-
							 | 
						||
| 
								 | 
							
									(   label_of(Resource, Lang, Label)
							 | 
						||
| 
								 | 
							
									*-> true
							 | 
						||
| 
								 | 
							
									;   after_char(Resource, '#', Local)
							 | 
						||
| 
								 | 
							
									->  Label = Local
							 | 
						||
| 
								 | 
							
									;   after_char(Resource, '/', Local)
							 | 
						||
| 
								 | 
							
									->  Label = Local
							 | 
						||
| 
								 | 
							
									;   Label = Resource
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								after_char(Atom, Char, Rest) :-
							 | 
						||
| 
								 | 
							
									State = last(-),
							 | 
						||
| 
								 | 
							
									(   sub_atom(Atom, _, _, L, Char),
							 | 
						||
| 
								 | 
							
									    nb_setarg(1, State, L),
							 | 
						||
| 
								 | 
							
									    fail
							 | 
						||
| 
								 | 
							
									;   arg(1, State, L),
							 | 
						||
| 
								 | 
							
									    L \== (-)
							 | 
						||
| 
								 | 
							
									),
							 | 
						||
| 
								 | 
							
									sub_atom(Atom, _, L, 0, Rest).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	label_of(+Resource, ?Lang, ?Label) is nondet.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	True if rdf_has(Resource, rdfs:label,   literal(Lang, Label)) is
							 | 
						||
| 
								 | 
							
								%	true,  but  guaranteed  to  generate    rdfs:label   before  any
							 | 
						||
| 
								 | 
							
								%	subproperty thereof.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								label_of(Resource, Lang, Label) :-
							 | 
						||
| 
								 | 
							
									rdf(Resource, rdfs:label, literal(lang(Lang, Label))).
							 | 
						||
| 
								 | 
							
								label_of(Resource, Lang, Label) :-
							 | 
						||
| 
								 | 
							
									rdf_equal(rdfs:label, LabelP),
							 | 
						||
| 
								 | 
							
									rdf_has(Resource, LabelP, literal(lang(Lang, Label)), P),
							 | 
						||
| 
								 | 
							
									P \== LabelP.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	rdfs_class_property(+Class, ?Property)
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Enumerate the properties in the domain of Class.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdfs_class_property(Class, Property) :-
							 | 
						||
| 
								 | 
							
									rdfs_individual_of(Property, rdf:'Property'),
							 | 
						||
| 
								 | 
							
									rdf_has(Property, rdfs:domain, Domain),
							 | 
						||
| 
								 | 
							
									rdfs_subclass_of(Class, Domain).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										 /*******************************
							 | 
						||
| 
								 | 
							
										 *	     COLLECTIONS	*
							 | 
						||
| 
								 | 
							
										 *******************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	rdfs_member(?Element, +Set)
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	As Prolog member on sets.  Operates both on attributes parsed as
							 | 
						||
| 
								 | 
							
								%	parseType="Collection" as well as on Bag, Set and Alt.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdfs_member(Element, Set) :-
							 | 
						||
| 
								 | 
							
									rdf_has(Set, rdf:first, _),
							 | 
						||
| 
								 | 
							
									rdfs_collection_member(Element, Set).
							 | 
						||
| 
								 | 
							
								rdfs_member(Element, Set) :-
							 | 
						||
| 
								 | 
							
									rdfs_individual_of(Set, rdfs:'Container'), !,
							 | 
						||
| 
								 | 
							
									(   nonvar(Element)
							 | 
						||
| 
								 | 
							
									->  rdf(Set, Predicate, Element),
							 | 
						||
| 
								 | 
							
									    rdf_member_property(Predicate, _N)
							 | 
						||
| 
								 | 
							
									;   between(1, infinite, N),
							 | 
						||
| 
								 | 
							
									    rdf_member_property(Prop, N),
							 | 
						||
| 
								 | 
							
									    (	rdf(Set, Prop, Member)
							 | 
						||
| 
								 | 
							
									    ->	Member = Element
							 | 
						||
| 
								 | 
							
									    ;	!, fail
							 | 
						||
| 
								 | 
							
									    )
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdfs_collection_member(Element, Set) :-
							 | 
						||
| 
								 | 
							
									rdf_has(Set, rdf:first, Element).
							 | 
						||
| 
								 | 
							
								rdfs_collection_member(Element, Set) :-
							 | 
						||
| 
								 | 
							
									rdf_has(Set, rdf:rest, Tail), !,
							 | 
						||
| 
								 | 
							
									rdfs_collection_member(Element, Tail).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	rdfs_list_to_prolog_list(+RDFSList, -PrologList)
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Convert ann RDFS list (result from parseType=Collection) into a
							 | 
						||
| 
								 | 
							
								%	Prolog list of elements.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdfs_list_to_prolog_list(Set, []) :-
							 | 
						||
| 
								 | 
							
									rdf_equal(Set, rdf:nil), !.
							 | 
						||
| 
								 | 
							
								rdfs_list_to_prolog_list(Set, [H|T]) :-
							 | 
						||
| 
								 | 
							
									rdf_has(Set, rdf:first, H),
							 | 
						||
| 
								 | 
							
									rdf_has(Set, rdf:rest, Tail), !,
							 | 
						||
| 
								 | 
							
									rdfs_list_to_prolog_list(Tail, T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	rdfs_assert_list(+Resources, -List) is det.
							 | 
						||
| 
								 | 
							
								%%	rdfs_assert_list(+Resources, -List, +DB) is det.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Create an RDF list from the given Resources.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdfs_assert_list(Resources, List) :-
							 | 
						||
| 
								 | 
							
									rdfs_assert_list(Resources, List, user).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdfs_assert_list([], Nil, _) :-
							 | 
						||
| 
								 | 
							
									rdf_equal(rdf:nil, Nil).
							 | 
						||
| 
								 | 
							
								rdfs_assert_list([H|T], List, DB) :-
							 | 
						||
| 
								 | 
							
									rdfs_assert_list(T, Tail, DB),
							 | 
						||
| 
								 | 
							
									rdf_bnode(List),
							 | 
						||
| 
								 | 
							
									rdf_assert(List, rdf:rest, Tail, DB),
							 | 
						||
| 
								 | 
							
									rdf_assert(List, rdf:first, H, DB),
							 | 
						||
| 
								 | 
							
									rdf_assert(List, rdf:type, rdf:'List', DB).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										 /*******************************
							 | 
						||
| 
								 | 
							
										 *     SEARCH IN HIERARCHY	*
							 | 
						||
| 
								 | 
							
										 *******************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	rdfs_find(+String, +Domain, ?Properties, +Method, -Subject)
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Search all classes below Domain for a literal property with
							 | 
						||
| 
								 | 
							
								%	that matches String.  Method is one of
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%		* substring
							 | 
						||
| 
								 | 
							
								%		* word
							 | 
						||
| 
								 | 
							
								%		* prefix
							 | 
						||
| 
								 | 
							
								%		* exact
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	domain is defined by owl_satisfy from owl.pl
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Note that the rdfs:label field is handled by rdfs_label/2,
							 | 
						||
| 
								 | 
							
								%	making the URI-ref fragment name the last resort to determine
							 | 
						||
| 
								 | 
							
								%	the label.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdfs_find(String, Domain, Fields, Method, Subject) :-
							 | 
						||
| 
								 | 
							
									var(Fields), !,
							 | 
						||
| 
								 | 
							
									For =.. [Method,String],
							 | 
						||
| 
								 | 
							
									rdf_has(Subject, Field, literal(For, _)),
							 | 
						||
| 
								 | 
							
									owl_satisfies(Domain, Subject),
							 | 
						||
| 
								 | 
							
									Fields = [Field].		% report where we found it.
							 | 
						||
| 
								 | 
							
								rdfs_find(String, Domain, Fields, Method, Subject) :-
							 | 
						||
| 
								 | 
							
									globalise_list(Fields, GlobalFields),
							 | 
						||
| 
								 | 
							
									For =.. [Method,String],
							 | 
						||
| 
								 | 
							
									member(Field, GlobalFields),
							 | 
						||
| 
								 | 
							
									(   Field == resource
							 | 
						||
| 
								 | 
							
									->  rdf_subject(Subject),
							 | 
						||
| 
								 | 
							
									    rdf_match_label(Method, String, Subject)
							 | 
						||
| 
								 | 
							
									;   rdf_has(Subject, Field, literal(For, _))
							 | 
						||
| 
								 | 
							
									),
							 | 
						||
| 
								 | 
							
									owl_satisfies(Domain, Subject).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								owl_satisfies(Domain, _) :-
							 | 
						||
| 
								 | 
							
									rdf_equal(rdfs:'Resource', Domain), !.
							 | 
						||
| 
								 | 
							
													% Descriptions
							 | 
						||
| 
								 | 
							
								owl_satisfies(class(Domain), Resource) :- !,
							 | 
						||
| 
								 | 
							
									(   rdf_equal(Domain, rdfs:'Resource')
							 | 
						||
| 
								 | 
							
									->  true
							 | 
						||
| 
								 | 
							
									;   rdfs_subclass_of(Resource, Domain)
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								owl_satisfies(union_of(Domains), Resource) :- !,
							 | 
						||
| 
								 | 
							
									member(Domain, Domains),
							 | 
						||
| 
								 | 
							
									owl_satisfies(Domain, Resource), !.
							 | 
						||
| 
								 | 
							
								owl_satisfies(intersection_of(Domains), Resource) :- !,
							 | 
						||
| 
								 | 
							
									in_all_domains(Domains, Resource).
							 | 
						||
| 
								 | 
							
								owl_satisfies(complement_of(Domain), Resource) :- !,
							 | 
						||
| 
								 | 
							
									\+ owl_satisfies(Domain, Resource).
							 | 
						||
| 
								 | 
							
								owl_satisfies(one_of(List), Resource) :- !,
							 | 
						||
| 
								 | 
							
									memberchk(Resource, List).
							 | 
						||
| 
								 | 
							
													% Restrictions
							 | 
						||
| 
								 | 
							
								owl_satisfies(all_values_from(Domain), Resource) :-
							 | 
						||
| 
								 | 
							
									(   rdf_equal(Domain, rdfs:'Resource')
							 | 
						||
| 
								 | 
							
									->  true
							 | 
						||
| 
								 | 
							
									;   rdfs_individual_of(Resource, Domain)
							 | 
						||
| 
								 | 
							
									), !.
							 | 
						||
| 
								 | 
							
								owl_satisfies(some_values_from(_Domain), _Resource) :- !.
							 | 
						||
| 
								 | 
							
								owl_satisfies(has_value(Value), Resource) :-
							 | 
						||
| 
								 | 
							
									rdf_equal(Value, Resource).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								in_all_domains([], _).
							 | 
						||
| 
								 | 
							
								in_all_domains([H|T], Resource) :-
							 | 
						||
| 
								 | 
							
									owl_satisfies(H, Resource),
							 | 
						||
| 
								 | 
							
									in_all_domains(T, Resource).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								globalise_list([], []) :- !.
							 | 
						||
| 
								 | 
							
								globalise_list([H0|T0], [H|T]) :- !,
							 | 
						||
| 
								 | 
							
									globalise_list(H0, H),
							 | 
						||
| 
								 | 
							
									globalise_list(T0, T).
							 | 
						||
| 
								 | 
							
								globalise_list(X, G) :-
							 | 
						||
| 
								 | 
							
									rdf_global_id(X, G).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
							 | 
						||
| 
								 | 
							
								TOP-DOWN
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdfs_find(String, Domain, Fields, Method, Subject) :-
							 | 
						||
| 
								 | 
							
									globalise_list(Fields, GlobalFields),
							 | 
						||
| 
								 | 
							
									generate_domain(Domain, Subject),
							 | 
						||
| 
								 | 
							
									member(Field, GlobalFields),
							 | 
						||
| 
								 | 
							
									(   rdf_equal(Field, rdfs:label)
							 | 
						||
| 
								 | 
							
									->  rdfs_label(Subject, Arg)
							 | 
						||
| 
								 | 
							
									;   rdf_has(Subject, Field, literal(Arg))
							 | 
						||
| 
								 | 
							
									),
							 | 
						||
| 
								 | 
							
									rdf_match_label(Method, String, Arg).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	generate_domain(+Domain, -Resource)
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Generate all resources that satisfy some a domain specification.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								generate_domain(All, Subject) :-
							 | 
						||
| 
								 | 
							
									rdf_equal(All, rdfs:'Resource'), !,
							 | 
						||
| 
								 | 
							
									rdf_subject(Subject).
							 | 
						||
| 
								 | 
							
								generate_domain(class(Class), Subject) :- !,
							 | 
						||
| 
								 | 
							
									rdfs_subclass_of(Subject, Class).
							 | 
						||
| 
								 | 
							
								generate_domain(all_values_from(Class), Individual) :-
							 | 
						||
| 
								 | 
							
									(   rdf_equal(Class, rdfs:'Resource')
							 | 
						||
| 
								 | 
							
									->  rdf_subject(Individual)			% this is OWL-full
							 | 
						||
| 
								 | 
							
									;   rdfs_individual_of(Individual, Class)
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								generate_domain(some_values_from(Class), Individual) :- % Actually this is
							 | 
						||
| 
								 | 
							
									rdfs_individual_of(Individual, Class). 		% anything
							 | 
						||
| 
								 | 
							
								generate_domain(union_of(Domains), Individual) :-
							 | 
						||
| 
								 | 
							
									member(Domain, Domains),
							 | 
						||
| 
								 | 
							
									generate_domain(Domain, Individual).
							 | 
						||
| 
								 | 
							
								generate_domain(intersection_of(Domains), Individual) :-
							 | 
						||
| 
								 | 
							
									in_all_domains(Domains, Individual).
							 | 
						||
| 
								 | 
							
								generate_domain(one_of(Individuals), Individual) :-
							 | 
						||
| 
								 | 
							
									member(Individual, Individuals).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								in_all_domains([], _).
							 | 
						||
| 
								 | 
							
								in_all_domains([H|T], Resource) :-
							 | 
						||
| 
								 | 
							
									generate_domain(H, Resource),
							 | 
						||
| 
								 | 
							
									in_all_domains(T, Resource).
							 | 
						||
| 
								 | 
							
								- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								
							 |