725 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
		
		
			
		
	
	
			725 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| 
								 | 
							
								/*  $Id$
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Part of SWI-Prolog
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Author:        Jan Wielemaker
							 | 
						||
| 
								 | 
							
								    E-mail:        wielemak@science.uva.nl
							 | 
						||
| 
								 | 
							
								    WWW:           http://www.swi-prolog.org
							 | 
						||
| 
								 | 
							
								    Copyright (C): 2002-2006, 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(rdf_parser,
							 | 
						||
| 
								 | 
							
									  [ xml_to_plrdf/3,		% +XMLTerm, -RDFTerm, +Options
							 | 
						||
| 
								 | 
							
									    element_to_plrdf/3,		% +ContentList, -RDFTerm, +Options
							 | 
						||
| 
								 | 
							
									    rdf_name_space/1
							 | 
						||
| 
								 | 
							
									  ]).
							 | 
						||
| 
								 | 
							
								:- use_module(rewrite).
							 | 
						||
| 
								 | 
							
								:- use_module(library(sgml)).		% xml_name/1
							 | 
						||
| 
								 | 
							
								:- use_module(library(lists)).
							 | 
						||
| 
								 | 
							
								:- use_module(library(url)).
							 | 
						||
| 
								 | 
							
								:- use_module(library(utf8)).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:- op(500, fx, \?).			% Optional (attrs)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								term_expansion(F, T) :- rew_term_expansion(F, T).
							 | 
						||
| 
								 | 
							
								goal_expansion(F, T) :- rew_goal_expansion(F, T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:- multifile rdf_name_space/1.
							 | 
						||
| 
								 | 
							
								:- dynamic   rdf_name_space/1.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	rdf_name_space(?URL) is nondet.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	True if URL must be handled  as rdf: Determines special handling
							 | 
						||
| 
								 | 
							
								%	of rdf:about, rdf:resource, etc.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdf_name_space('http://www.w3.org/1999/02/22-rdf-syntax-ns#').
							 | 
						||
| 
								 | 
							
								rdf_name_space('http://www.w3.org/TR/REC-rdf-syntax').
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	xml_to_plrdf(+RDFElementOrObject, -RDFTerm, +Options)
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Translate an XML (using namespaces) term into an Prolog term
							 | 
						||
| 
								 | 
							
								%	representing the RDF data.  This term can then be fed into
							 | 
						||
| 
								 | 
							
								%	rdf_triples/[2,3] to create a list of RDF triples.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	if `BaseURI' == [], local URI's are not globalised.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								xml_to_plrdf(Element, RDF, Options) :-
							 | 
						||
| 
								 | 
							
									is_list(Element), !,
							 | 
						||
| 
								 | 
							
									rewrite(\xml_content_objects(RDF, Options), Element).
							 | 
						||
| 
								 | 
							
								xml_to_plrdf(Element, RDF, Options) :-
							 | 
						||
| 
								 | 
							
									rewrite(\xml_objects(RDF, Options), Element).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	element_to_plrdf(+DOM, -RDFTerm, +Options)
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Rewrite a single XML element.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								element_to_plrdf(Element, RDF, Options) :-
							 | 
						||
| 
								 | 
							
									rewrite(\nodeElementList(RDF, Options), [Element]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								xml_objects(Objects, Options0) ::=
							 | 
						||
| 
								 | 
							
									E0,
							 | 
						||
| 
								 | 
							
									{ modify_state(E0, Options0, E, Options), !,
							 | 
						||
| 
								 | 
							
									  rewrite(\xml_objects(Objects, Options), E)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								xml_objects(Objects, Options) ::=
							 | 
						||
| 
								 | 
							
									element((\rdf('RDF'), !),
							 | 
						||
| 
								 | 
							
										_,
							 | 
						||
| 
								 | 
							
										\nodeElementList(Objects, Options)),
							 | 
						||
| 
								 | 
							
									!.
							 | 
						||
| 
								 | 
							
								xml_objects(Objects, Options) ::=
							 | 
						||
| 
								 | 
							
									element(_, _, \xml_content_objects(Objects, Options)).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								xml_content_objects([], _) ::=
							 | 
						||
| 
								 | 
							
									[].
							 | 
						||
| 
								 | 
							
								xml_content_objects([H|T], Options) ::=
							 | 
						||
| 
								 | 
							
									[ \xml_objects(H, Options)
							 | 
						||
| 
								 | 
							
									| \xml_content_objects(T, Options)
							 | 
						||
| 
								 | 
							
									].
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								nodeElementList([], _Options) ::=
							 | 
						||
| 
								 | 
							
									[], !.
							 | 
						||
| 
								 | 
							
								nodeElementList(L, Options) ::=
							 | 
						||
| 
								 | 
							
									[ (\ws, !)
							 | 
						||
| 
								 | 
							
									| \nodeElementList(L, Options)
							 | 
						||
| 
								 | 
							
									].
							 | 
						||
| 
								 | 
							
								nodeElementList([H|T], Options) ::=
							 | 
						||
| 
								 | 
							
									[ \nodeElementOrError(H, Options)
							 | 
						||
| 
								 | 
							
									| \nodeElementList(T, Options)
							 | 
						||
| 
								 | 
							
									].
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								nodeElementOrError(H, Options) ::=
							 | 
						||
| 
								 | 
							
									\nodeElement(H, Options), !.
							 | 
						||
| 
								 | 
							
								nodeElementOrError(unparsed(Data), _Options) ::=
							 | 
						||
| 
								 | 
							
									Data.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								nodeElement(container(Type, Id, Elements), Options) ::=
							 | 
						||
| 
								 | 
							
									\container(Type, Id, Elements, Options), !. 	% compatibility
							 | 
						||
| 
								 | 
							
								nodeElement(description(Type, About, BagID, Properties), Options) ::=
							 | 
						||
| 
								 | 
							
									\description(Type, About, BagID, Properties, Options).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										 /*******************************
							 | 
						||
| 
								 | 
							
										 *	    DESCRIPTION		*
							 | 
						||
| 
								 | 
							
										 *******************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								description(Type, About, BagID, Properties, Options0) ::=
							 | 
						||
| 
								 | 
							
									E0,
							 | 
						||
| 
								 | 
							
									{ modify_state(E0, Options0, E, Options), !,
							 | 
						||
| 
								 | 
							
									  rewrite(\description(Type, About, BagID, Properties, Options), E)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								description(description, About, BagID, Properties, Options) ::=
							 | 
						||
| 
								 | 
							
									element(\rdf('Description'),
							 | 
						||
| 
								 | 
							
										\attrs([ \?idAboutAttr(About, Options),
							 | 
						||
| 
								 | 
							
											 \?bagIdAttr(BagID, Options)
							 | 
						||
| 
								 | 
							
										       | \propAttrs(PropAttrs, Options)
							 | 
						||
| 
								 | 
							
										       ]),
							 | 
						||
| 
								 | 
							
										\propertyElts(PropElts, Options)),
							 | 
						||
| 
								 | 
							
									{ !, append(PropAttrs, PropElts, Properties)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								description(Type, About, BagID, Properties, Options) ::=
							 | 
						||
| 
								 | 
							
									element(Type,
							 | 
						||
| 
								 | 
							
										\attrs([ \?idAboutAttr(About, Options),
							 | 
						||
| 
								 | 
							
											 \?bagIdAttr(BagID, Options)
							 | 
						||
| 
								 | 
							
										       | \propAttrs(PropAttrs, Options)
							 | 
						||
| 
								 | 
							
										       ]),
							 | 
						||
| 
								 | 
							
										\propertyElts(PropElts, Options)),
							 | 
						||
| 
								 | 
							
									{ append(PropAttrs, PropElts, Properties)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
								propAttrs([], _) ::=
							 | 
						||
| 
								 | 
							
									[], !.
							 | 
						||
| 
								 | 
							
								propAttrs([H|T], Options) ::=
							 | 
						||
| 
								 | 
							
									[ \propAttr(H, Options)
							 | 
						||
| 
								 | 
							
									| \propAttrs(T, Options)
							 | 
						||
| 
								 | 
							
									].
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								propAttr(rdf:type = URI, Options) ::=
							 | 
						||
| 
								 | 
							
									\rdf_or_unqualified(type) = \uri(URI, Options), !.
							 | 
						||
| 
								 | 
							
								propAttr(Name = Literal, Options) ::=
							 | 
						||
| 
								 | 
							
									Name = Value,
							 | 
						||
| 
								 | 
							
									{ mkliteral(Value, Literal, Options)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								propertyElts([], _) ::=
							 | 
						||
| 
								 | 
							
									[], !.
							 | 
						||
| 
								 | 
							
								propertyElts(Elts, Options) ::=
							 | 
						||
| 
								 | 
							
									[ (\ws, !)
							 | 
						||
| 
								 | 
							
									| \propertyElts(Elts, Options)
							 | 
						||
| 
								 | 
							
									].
							 | 
						||
| 
								 | 
							
								propertyElts([H|T], Options) ::=
							 | 
						||
| 
								 | 
							
									[ \propertyElt(H, Options)
							 | 
						||
| 
								 | 
							
									| \propertyElts(T, Options)
							 | 
						||
| 
								 | 
							
									].
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								propertyElt(E, Options) ::=
							 | 
						||
| 
								 | 
							
									\propertyElt(Id, Name, Value, Options),
							 | 
						||
| 
								 | 
							
									{ mkprop(Name, Value, Prop),
							 | 
						||
| 
								 | 
							
									  (   var(Id)
							 | 
						||
| 
								 | 
							
									  ->  E = Prop
							 | 
						||
| 
								 | 
							
									  ;   E = id(Id, Prop)
							 | 
						||
| 
								 | 
							
									  )
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								mkprop(NS:Local, Value, rdf:Local = Value) :-
							 | 
						||
| 
								 | 
							
									rdf_name_space(NS), !.
							 | 
						||
| 
								 | 
							
								mkprop(Name, Value, Name = Value).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								propertyElt(Id, Name, Value, Options0) ::=
							 | 
						||
| 
								 | 
							
									E0,
							 | 
						||
| 
								 | 
							
									{ modify_state(E0, Options0, E, Options), !,
							 | 
						||
| 
								 | 
							
									  rewrite(\propertyElt(Id, Name, Value, Options), E)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
													% 5.14 emptyPropertyElt
							 | 
						||
| 
								 | 
							
								propertyElt(Id, Name, Value, Options) ::=
							 | 
						||
| 
								 | 
							
									element(Name, A, \all_ws),
							 | 
						||
| 
								 | 
							
									{ !,
							 | 
						||
| 
								 | 
							
									  rewrite(\emptyPropertyElt(Id, Value, Options), A)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								propertyElt(_, Name, description(description, Id, _, Properties), Options) ::=
							 | 
						||
| 
								 | 
							
									element(Name,
							 | 
						||
| 
								 | 
							
										\attrs([ \parseResource,
							 | 
						||
| 
								 | 
							
											 \?idAboutAttr(Id, Options)
							 | 
						||
| 
								 | 
							
										       ]),
							 | 
						||
| 
								 | 
							
										\propertyElts(Properties, Options)),
							 | 
						||
| 
								 | 
							
									!.
							 | 
						||
| 
								 | 
							
								propertyElt(_, Name, Literal, Options) ::=
							 | 
						||
| 
								 | 
							
									element(Name,
							 | 
						||
| 
								 | 
							
										\attrs([ \parseLiteral
							 | 
						||
| 
								 | 
							
										       ]),
							 | 
						||
| 
								 | 
							
										Content),
							 | 
						||
| 
								 | 
							
									{ !,
							 | 
						||
| 
								 | 
							
									  literal_value(Content, Literal, Options)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								propertyElt(Id, Name, collection(Elements), Options) ::=
							 | 
						||
| 
								 | 
							
									element(Name,
							 | 
						||
| 
								 | 
							
										\attrs([ \parseCollection,
							 | 
						||
| 
								 | 
							
											 \?idAttr(Id, Options)
							 | 
						||
| 
								 | 
							
										       ]),
							 | 
						||
| 
								 | 
							
										\nodeElementList(Elements, Options)).
							 | 
						||
| 
								 | 
							
								propertyElt(Id, Name, Literal, Options) ::=
							 | 
						||
| 
								 | 
							
									element(Name,
							 | 
						||
| 
								 | 
							
										\attrs([ \typeAttr(Type, Options),
							 | 
						||
| 
								 | 
							
											 \?idAttr(Id, Options)
							 | 
						||
| 
								 | 
							
										       ]),
							 | 
						||
| 
								 | 
							
										Content),
							 | 
						||
| 
								 | 
							
									{ typed_literal(Type, Content, Literal, Options)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								propertyElt(Id, Name, Literal, Options) ::=
							 | 
						||
| 
								 | 
							
									element(Name,
							 | 
						||
| 
								 | 
							
										\attrs([ \?idAttr(Id, Options)
							 | 
						||
| 
								 | 
							
										       ]),
							 | 
						||
| 
								 | 
							
										[ Value ]),
							 | 
						||
| 
								 | 
							
									{ atom(Value), !,
							 | 
						||
| 
								 | 
							
									  mkliteral(Value, Literal, Options)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								propertyElt(Id, Name, Value, Options) ::=
							 | 
						||
| 
								 | 
							
									element(Name,
							 | 
						||
| 
								 | 
							
										\attrs([ \?idAttr(Id, Options)
							 | 
						||
| 
								 | 
							
										       ]),
							 | 
						||
| 
								 | 
							
										\an_rdf_object(Value, Options)), !.
							 | 
						||
| 
								 | 
							
								propertyElt(Id, Name, unparsed(Value), Options) ::=
							 | 
						||
| 
								 | 
							
									element(Name,
							 | 
						||
| 
								 | 
							
										\attrs([ \?idAttr(Id, Options)
							 | 
						||
| 
								 | 
							
										       ]),
							 | 
						||
| 
								 | 
							
										Value).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								emptyPropertyElt(Id, Literal, Options) ::=
							 | 
						||
| 
								 | 
							
									\attrs([ \?idAttr(Id, Options),
							 | 
						||
| 
								 | 
							
										 \?parseLiteral
							 | 
						||
| 
								 | 
							
									       | \noMoreAttrs
							 | 
						||
| 
								 | 
							
									       ]),
							 | 
						||
| 
								 | 
							
									{ !,
							 | 
						||
| 
								 | 
							
									  mkliteral('', Literal, Options)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								emptyPropertyElt(Id,
							 | 
						||
| 
								 | 
							
										 description(description, About, BagID, Properties),
							 | 
						||
| 
								 | 
							
										 Options) ::=
							 | 
						||
| 
								 | 
							
									\attrs([ \?idAttr(Id, Options),
							 | 
						||
| 
								 | 
							
										 \?aboutResourceEmptyElt(About, Options),
							 | 
						||
| 
								 | 
							
										 \?bagIdAttr(BagID, Options),
							 | 
						||
| 
								 | 
							
										 \?parseResource
							 | 
						||
| 
								 | 
							
									       | \propAttrs(Properties, Options)
							 | 
						||
| 
								 | 
							
									       ]), !.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								aboutResourceEmptyElt(about(URI), Options) ::=
							 | 
						||
| 
								 | 
							
									\resourceAttr(URI, Options), !.
							 | 
						||
| 
								 | 
							
								aboutResourceEmptyElt(node(URI), _Options) ::=
							 | 
						||
| 
								 | 
							
									\nodeIDAttr(URI).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	literal_value(+In, -Value, +Options)
							 | 
						||
| 
								 | 
							
								%	
							 | 
						||
| 
								 | 
							
								%	Create the literal value for rdf:parseType="Literal" attributes.
							 | 
						||
| 
								 | 
							
								%	The content is the Prolog XML DOM tree for the literal.
							 | 
						||
| 
								 | 
							
								%	
							 | 
						||
| 
								 | 
							
								%	@tbd	Note that the specs demand a canonical textual representation
							 | 
						||
| 
								 | 
							
								%		of the XML data as a Unicode string.  For now the user can
							 | 
						||
| 
								 | 
							
								%		achieve this using the convert_typed_literal hook.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								literal_value(Value, literal(type(rdf:'XMLLiteral', Value)), _).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	mkliteral(+Atom, -Object, +Options)
							 | 
						||
| 
								 | 
							
								%	
							 | 
						||
| 
								 | 
							
								%	Translate attribute value Atom into an RDF object using the
							 | 
						||
| 
								 | 
							
								%	lang(Lang) option from Options.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								mkliteral(Text, literal(Val), Options) :-
							 | 
						||
| 
								 | 
							
									atom(Text),
							 | 
						||
| 
								 | 
							
									(   memberchk(lang(Lang), Options),
							 | 
						||
| 
								 | 
							
									    Lang \== ''
							 | 
						||
| 
								 | 
							
									->  Val = lang(Lang, Text)
							 | 
						||
| 
								 | 
							
									;   Val = Text
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	typed_literal(+Type, +Content, -Literal, +Options)
							 | 
						||
| 
								 | 
							
								%	
							 | 
						||
| 
								 | 
							
								%	Handle a literal attribute with rdf:datatype=Type qualifier. NB:
							 | 
						||
| 
								 | 
							
								%	possibly  it  is  faster  to  use  a  global  variable  for  the
							 | 
						||
| 
								 | 
							
								%	conversion hook.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typed_literal(Type, Content, literal(Object), Options) :-
							 | 
						||
| 
								 | 
							
									memberchk(convert_typed_literal(Convert), Options), !,
							 | 
						||
| 
								 | 
							
									(   catch(call(Convert, Type, Content, Object), E, true)
							 | 
						||
| 
								 | 
							
									->  (   var(E)
							 | 
						||
| 
								 | 
							
									    ->	true
							 | 
						||
| 
								 | 
							
									    ;	Object = E
							 | 
						||
| 
								 | 
							
									    )
							 | 
						||
| 
								 | 
							
									;   Object = error(cannot_convert(Type, Content), _)
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								typed_literal(Type, [Text], literal(type(Type, Text)), _Options) :- !.
							 | 
						||
| 
								 | 
							
								typed_literal(Type, Content, literal(type(Type, Content)), _Options).
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								idAboutAttr(id(Id), Options) ::=
							 | 
						||
| 
								 | 
							
									\idAttr(Id, Options), !.
							 | 
						||
| 
								 | 
							
								idAboutAttr(about(About), Options) ::=
							 | 
						||
| 
								 | 
							
									\aboutAttr(About, Options), !.
							 | 
						||
| 
								 | 
							
								idAboutAttr(node(About), _Options) ::=
							 | 
						||
| 
								 | 
							
									\nodeIDAttr(About), !.
							 | 
						||
| 
								 | 
							
								idAboutAttr(AboutEach, Options) ::=
							 | 
						||
| 
								 | 
							
									\aboutEachAttr(AboutEach, Options).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	an_rdf_object(-Object, +OptionsURI)
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Deals with an object, but there may be spaces around.  I'm still
							 | 
						||
| 
								 | 
							
								%	not sure where to deal with these.  Best is to ask the XML parser
							 | 
						||
| 
								 | 
							
								%	to get rid of them, So most likely this code will change if this
							 | 
						||
| 
								 | 
							
								%	happens.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								an_rdf_object(Object, Options) ::=
							 | 
						||
| 
								 | 
							
									[ \nodeElement(Object, Options)
							 | 
						||
| 
								 | 
							
									], !.
							 | 
						||
| 
								 | 
							
								an_rdf_object(Object, Options) ::=
							 | 
						||
| 
								 | 
							
									[ (\ws, !)
							 | 
						||
| 
								 | 
							
									| \an_rdf_object(Object, Options)
							 | 
						||
| 
								 | 
							
									].
							 | 
						||
| 
								 | 
							
								an_rdf_object(Object, Options) ::=
							 | 
						||
| 
								 | 
							
									[ \nodeElement(Object, Options),
							 | 
						||
| 
								 | 
							
									  \ws
							 | 
						||
| 
								 | 
							
									], !.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ws ::=
							 | 
						||
| 
								 | 
							
									A,
							 | 
						||
| 
								 | 
							
									{ atom(A),
							 | 
						||
| 
								 | 
							
									  atom_chars(A, Chars),
							 | 
						||
| 
								 | 
							
									  all_blank(Chars), !
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								ws ::=
							 | 
						||
| 
								 | 
							
									pi(_).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								all_ws ::=
							 | 
						||
| 
								 | 
							
									[], !.
							 | 
						||
| 
								 | 
							
								all_ws ::=
							 | 
						||
| 
								 | 
							
									[\ws | \all_ws].
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								all_blank([]).
							 | 
						||
| 
								 | 
							
								all_blank([H|T]) :-
							 | 
						||
| 
								 | 
							
									char_type(H, space),		% SWI-Prolog specific
							 | 
						||
| 
								 | 
							
									all_blank(T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										 /*******************************
							 | 
						||
| 
								 | 
							
										 *	   RDF ATTRIBUTES	*
							 | 
						||
| 
								 | 
							
										 *******************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								idAttr(Id, Options) ::=
							 | 
						||
| 
								 | 
							
									\rdf_or_unqualified('ID') = \uniqueid(Id, Options).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								bagIdAttr(Id, Options) ::=
							 | 
						||
| 
								 | 
							
									\rdf_or_unqualified(bagID) = \globalid(Id, Options).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								aboutAttr(About, Options) ::=
							 | 
						||
| 
								 | 
							
									\rdf_or_unqualified(about) = \uri(About, Options).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								nodeIDAttr(About) ::=
							 | 
						||
| 
								 | 
							
									\rdf_or_unqualified(nodeID) = About.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%	Not allowed in current RDF!
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								aboutEachAttr(each(AboutEach), Options) ::=
							 | 
						||
| 
								 | 
							
									\rdf_or_unqualified(aboutEach) = \uri(AboutEach, Options), !.
							 | 
						||
| 
								 | 
							
								aboutEachAttr(prefix(Prefix), Options) ::=
							 | 
						||
| 
								 | 
							
									\rdf_or_unqualified(aboutEachPrefix) = \uri(Prefix, Options), !.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								resourceAttr(URI, Options) ::=
							 | 
						||
| 
								 | 
							
									\rdf_or_unqualified(resource) = \uri(URI, Options).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typeAttr(Type, Options) ::=
							 | 
						||
| 
								 | 
							
									\rdf_or_unqualified(datatype) = \uri(Type, Options).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uri(URI, Options) ::=
							 | 
						||
| 
								 | 
							
									A,
							 | 
						||
| 
								 | 
							
									{   memberchk(base_uri(Base), Options),
							 | 
						||
| 
								 | 
							
									    Base \== []
							 | 
						||
| 
								 | 
							
									->  canonical_uri(A, Base, URI)
							 | 
						||
| 
								 | 
							
									;   sub_atom(A, 0, _, _, #)
							 | 
						||
| 
								 | 
							
									->  sub_atom(A, 1, _, 0, URI)
							 | 
						||
| 
								 | 
							
									;   url_iri(A, URI)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								globalid(Id, Options) ::=
							 | 
						||
| 
								 | 
							
									A,
							 | 
						||
| 
								 | 
							
									{   make_globalid(A, Options, Id)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uniqueid(Id, Options) ::=
							 | 
						||
| 
								 | 
							
									A,
							 | 
						||
| 
								 | 
							
									{   unique_xml_name(A),
							 | 
						||
| 
								 | 
							
									    make_globalid(A, Options, Id)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								unique_xml_name(Name) :-
							 | 
						||
| 
								 | 
							
									(   xml_name(Name)
							 | 
						||
| 
								 | 
							
									->  true
							 | 
						||
| 
								 | 
							
									;   print_message(warning, rdf(not_a_name(Name)))
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								make_globalid(In, Options, Id) :-
							 | 
						||
| 
								 | 
							
									(   memberchk(base_uri(Base), Options),
							 | 
						||
| 
								 | 
							
									    Base \== []
							 | 
						||
| 
								 | 
							
									->  (   is_absolute_url(In)
							 | 
						||
| 
								 | 
							
									    ->	url_iri(In, Id)
							 | 
						||
| 
								 | 
							
									    ;	concat_atom([Base, In], #, Id0),
							 | 
						||
| 
								 | 
							
										url_iri(Id0, Id)
							 | 
						||
| 
								 | 
							
									    )
							 | 
						||
| 
								 | 
							
									;   sub_atom(In, 0, _, _, #)
							 | 
						||
| 
								 | 
							
									->  sub_atom(In, 1, _, 0, Id)
							 | 
						||
| 
								 | 
							
									;   url_iri(In, Id)
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	canonical_uri(+In, +Base, -Absolute)
							 | 
						||
| 
								 | 
							
								%	
							 | 
						||
| 
								 | 
							
								%	Make the URI absolute and decode special sequences. For the last
							 | 
						||
| 
								 | 
							
								%	clause, which is the correct order?
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								canonical_uri('', Base, Base) :- !.	% '' expands to xml:base
							 | 
						||
| 
								 | 
							
								canonical_uri(URI0, [], URI) :- !,	% do not use one
							 | 
						||
| 
								 | 
							
									url_iri(URI0, URI).
							 | 
						||
| 
								 | 
							
								canonical_uri(URI, Base, Global) :-	% use our generic library
							 | 
						||
| 
								 | 
							
									global_url(URI, Base, Global0),
							 | 
						||
| 
								 | 
							
									url_iri(Global0, Global).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										 /*******************************
							 | 
						||
| 
								 | 
							
										 *	     CONTAINERS		*
							 | 
						||
| 
								 | 
							
										 *******************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
							 | 
						||
| 
								 | 
							
								Note that containers are no longer part   of  the definition. We'll keep
							 | 
						||
| 
								 | 
							
								the code and call it conditionally if we must.
							 | 
						||
| 
								 | 
							
								- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								container(_, _, _, _) ::=
							 | 
						||
| 
								 | 
							
									_,
							 | 
						||
| 
								 | 
							
									{ \+ current_prolog_flag(rdf_container, true),
							 | 
						||
| 
								 | 
							
									  !, fail
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								container(Type, Id, Elements, Options0) ::=
							 | 
						||
| 
								 | 
							
									E0,
							 | 
						||
| 
								 | 
							
									{ modify_state(E0, Options0, E, Options), !,
							 | 
						||
| 
								 | 
							
									  rewrite(\container(Type, Id, Elements, Options), E)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								container(Type, Id, Elements, Options) ::=
							 | 
						||
| 
								 | 
							
									element(\containertype(Type),
							 | 
						||
| 
								 | 
							
										\attrs([ \?idAttr(Id, Options)
							 | 
						||
| 
								 | 
							
										       | \memberAttrs(Elements)
							 | 
						||
| 
								 | 
							
										       ]),
							 | 
						||
| 
								 | 
							
										[]), !.
							 | 
						||
| 
								 | 
							
								container(Type, Id, Elements, Options) ::=
							 | 
						||
| 
								 | 
							
									element(\containertype(Type),
							 | 
						||
| 
								 | 
							
										\attrs([ \?idAttr(Id, Options)
							 | 
						||
| 
								 | 
							
										       ]),
							 | 
						||
| 
								 | 
							
										\memberElts(Elements, Options)).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								containertype(Type) ::=
							 | 
						||
| 
								 | 
							
									\rdf(Type),
							 | 
						||
| 
								 | 
							
									{ containertype(Type)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								containertype('Bag').
							 | 
						||
| 
								 | 
							
								containertype('Seq').
							 | 
						||
| 
								 | 
							
								containertype('Alt').
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								memberElts([], _) ::=
							 | 
						||
| 
								 | 
							
									[].
							 | 
						||
| 
								 | 
							
								memberElts([H|T], Options) ::=
							 | 
						||
| 
								 | 
							
									[ \memberElt(H, Options)
							 | 
						||
| 
								 | 
							
									| \memberElts(T, Options)
							 | 
						||
| 
								 | 
							
									].
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								memberElt(LI, Options) ::=
							 | 
						||
| 
								 | 
							
									\referencedItem(LI, Options).
							 | 
						||
| 
								 | 
							
								memberElt(LI, Options) ::=
							 | 
						||
| 
								 | 
							
									\inlineItem(LI, Options).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								referencedItem(LI, Options0) ::=
							 | 
						||
| 
								 | 
							
									E0,
							 | 
						||
| 
								 | 
							
									{ modify_state(E0, Options0, E, Options), !,
							 | 
						||
| 
								 | 
							
									  rewrite(\referencedItem(LI, Options), E)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								referencedItem(LI, Options) ::=
							 | 
						||
| 
								 | 
							
									element(\rdf_or_unqualified(li),
							 | 
						||
| 
								 | 
							
										[ \resourceAttr(LI, Options) ],
							 | 
						||
| 
								 | 
							
										[]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inlineItem(Item, Options0) ::=
							 | 
						||
| 
								 | 
							
									E0,
							 | 
						||
| 
								 | 
							
									{ modify_state(E0, Options0, E, Options), !,
							 | 
						||
| 
								 | 
							
									  rewrite(\inlineItem(Item, Options), E)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								inlineItem(Literal, Options) ::=
							 | 
						||
| 
								 | 
							
									element(\rdf_or_unqualified(li),
							 | 
						||
| 
								 | 
							
										[ \parseLiteral ],
							 | 
						||
| 
								 | 
							
										Value),
							 | 
						||
| 
								 | 
							
									literal_value(Value, Literal, Options).
							 | 
						||
| 
								 | 
							
								inlineItem(description(description, _, _, Properties), Options) ::=
							 | 
						||
| 
								 | 
							
									element(\rdf_or_unqualified(li),
							 | 
						||
| 
								 | 
							
										[ \parseResource ],
							 | 
						||
| 
								 | 
							
										\propertyElts(Properties, Options)).
							 | 
						||
| 
								 | 
							
								inlineItem(LI, Options) ::=
							 | 
						||
| 
								 | 
							
									element(\rdf_or_unqualified(li),
							 | 
						||
| 
								 | 
							
										[],
							 | 
						||
| 
								 | 
							
										[\nodeElement(LI, Options)]), !.	% inlined object
							 | 
						||
| 
								 | 
							
								inlineItem(Literal, Options) ::=
							 | 
						||
| 
								 | 
							
									element(\rdf_or_unqualified(li),
							 | 
						||
| 
								 | 
							
										[],
							 | 
						||
| 
								 | 
							
										[Text]),
							 | 
						||
| 
								 | 
							
									{ mkliteral(Text, Literal, Options)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								memberAttrs([]) ::=
							 | 
						||
| 
								 | 
							
									[].
							 | 
						||
| 
								 | 
							
								memberAttrs([H|T]) ::=
							 | 
						||
| 
								 | 
							
									[ \memberAttr(H)
							 | 
						||
| 
								 | 
							
									| \memberAttrs(T)
							 | 
						||
| 
								 | 
							
									].
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								memberAttr(li(Id, Value)) ::=		% Id should be _<n>
							 | 
						||
| 
								 | 
							
									\rdf(Id) = Value.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								parseLiteral    ::= \rdf_or_unqualified(parseType) = 'Literal'.
							 | 
						||
| 
								 | 
							
								parseResource   ::= \rdf_or_unqualified(parseType) = 'Resource'.
							 | 
						||
| 
								 | 
							
								parseCollection ::= \rdf_or_unqualified(parseType) = 'Collection'.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										 /*******************************
							 | 
						||
| 
								 | 
							
										 *	     PRIMITIVES		*
							 | 
						||
| 
								 | 
							
										 *******************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdf(Tag) ::=
							 | 
						||
| 
								 | 
							
									NS:Tag,
							 | 
						||
| 
								 | 
							
									{ rdf_name_space(NS), !
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rdf_or_unqualified(Tag) ::=
							 | 
						||
| 
								 | 
							
									Tag.
							 | 
						||
| 
								 | 
							
								rdf_or_unqualified(Tag) ::=
							 | 
						||
| 
								 | 
							
									NS:Tag,
							 | 
						||
| 
								 | 
							
									{ rdf_name_space(NS), !
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										 /*******************************
							 | 
						||
| 
								 | 
							
										 *	       BASICS		*
							 | 
						||
| 
								 | 
							
										 *******************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								attrs(Bag) ::=
							 | 
						||
| 
								 | 
							
									L0,
							 | 
						||
| 
								 | 
							
									{ do_attrs(Bag, L0)
							 | 
						||
| 
								 | 
							
									}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								do_attrs([], _) :- !.
							 | 
						||
| 
								 | 
							
								do_attrs([\?H|T], L0) :- !,		% optional
							 | 
						||
| 
								 | 
							
									(   select(X, L0, L),
							 | 
						||
| 
								 | 
							
									    rewrite(\H, X)
							 | 
						||
| 
								 | 
							
									->  true
							 | 
						||
| 
								 | 
							
									;   L = L0
							 | 
						||
| 
								 | 
							
									),
							 | 
						||
| 
								 | 
							
									do_attrs(T, L).
							 | 
						||
| 
								 | 
							
								do_attrs([H|T], L0) :-
							 | 
						||
| 
								 | 
							
									select(X, L0, L),
							 | 
						||
| 
								 | 
							
									rewrite(H, X), !,
							 | 
						||
| 
								 | 
							
									do_attrs(T, L).
							 | 
						||
| 
								 | 
							
								do_attrs(C, L) :-
							 | 
						||
| 
								 | 
							
									rewrite(C, L).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%	\noMoreAttrs
							 | 
						||
| 
								 | 
							
								%	
							 | 
						||
| 
								 | 
							
								%	Check attribute-list is empty.  Reserved xml: attributes are
							 | 
						||
| 
								 | 
							
								%	excluded from this test.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								noMoreAttrs ::=
							 | 
						||
| 
								 | 
							
									[], !.
							 | 
						||
| 
								 | 
							
								noMoreAttrs ::=
							 | 
						||
| 
								 | 
							
									[ xml:_=_
							 | 
						||
| 
								 | 
							
									| \noMoreAttrs
							 | 
						||
| 
								 | 
							
									].
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	modify_state(+Element0, +Options0, -Element, -Options)
							 | 
						||
| 
								 | 
							
								%	
							 | 
						||
| 
								 | 
							
								%	If Element0 contains xml:base = Base, strip it from the
							 | 
						||
| 
								 | 
							
								%	attributes list and update base_uri(_) in the Options
							 | 
						||
| 
								 | 
							
								%	
							 | 
						||
| 
								 | 
							
								%	It Element0 contains xml:lang = Lang, strip it from the
							 | 
						||
| 
								 | 
							
								%	attributes list and update lang(_) in the Options
							 | 
						||
| 
								 | 
							
								%	
							 | 
						||
| 
								 | 
							
								%	Remove all xmlns=_, xmlns:_=_ and xml:_=_.  Only succeed
							 | 
						||
| 
								 | 
							
								%	if something changed.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								modify_state(E0, O0, E, O) :-
							 | 
						||
| 
								 | 
							
									modify_states([base, lang, xmlns], M, E0, O0, E, O),
							 | 
						||
| 
								 | 
							
									M \== [].
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								modify_states([], [], E, O, E, O).
							 | 
						||
| 
								 | 
							
								modify_states([How|TH0], [How|TH], E0, O0, E, O) :-
							 | 
						||
| 
								 | 
							
									modify_state(How, E0, O0, E1, O1), !,
							 | 
						||
| 
								 | 
							
									modify_states(TH0, TH, E1, O1, E, O).
							 | 
						||
| 
								 | 
							
								modify_states([_|TH0], TH, E0, O0, E, O) :-
							 | 
						||
| 
								 | 
							
									modify_states(TH0, TH, E0, O0, E, O).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								modify_state(base,
							 | 
						||
| 
								 | 
							
									     element(Name, Attrs0, Content), Options0,
							 | 
						||
| 
								 | 
							
									     element(Name, Attrs, Content),  Options) :-
							 | 
						||
| 
								 | 
							
									select(xml:base=Base1, Attrs0, Attrs), !,
							 | 
						||
| 
								 | 
							
									(   select(base_uri(Base0), Options0, Options1)
							 | 
						||
| 
								 | 
							
									->  true
							 | 
						||
| 
								 | 
							
									;   Base0 = [],
							 | 
						||
| 
								 | 
							
									    Options1 = Options0
							 | 
						||
| 
								 | 
							
									),
							 | 
						||
| 
								 | 
							
									remove_fragment(Base1, Base2),
							 | 
						||
| 
								 | 
							
									canonical_uri(Base2, Base0, Base),
							 | 
						||
| 
								 | 
							
									Options = [base_uri(Base)|Options1].
							 | 
						||
| 
								 | 
							
								modify_state(lang, element(Name, Attrs0, Content), Options0,
							 | 
						||
| 
								 | 
							
									     element(Name, Attrs, Content),  Options) :-
							 | 
						||
| 
								 | 
							
									select(xml:lang=Lang, Attrs0, Attrs),
							 | 
						||
| 
								 | 
							
									\+ memberchk(ignore_lang(true), Options0), !,
							 | 
						||
| 
								 | 
							
									delete(Options0, lang(_), Options1),
							 | 
						||
| 
								 | 
							
									(   Lang == ''
							 | 
						||
| 
								 | 
							
									->  Options = Options1
							 | 
						||
| 
								 | 
							
									;   Options = [lang(Lang)|Options1]
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								modify_state(xmlns,
							 | 
						||
| 
								 | 
							
									     element(Name, Attrs0, Content), Options,
							 | 
						||
| 
								 | 
							
									     element(Name, Attrs, Content), Options) :-
							 | 
						||
| 
								 | 
							
									clean_xmlns_attr(Attrs0, Attrs),
							 | 
						||
| 
								 | 
							
									Attrs \== Attrs0.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								clean_xmlns_attr([], []).
							 | 
						||
| 
								 | 
							
								clean_xmlns_attr([H=_|T0], T) :-
							 | 
						||
| 
								 | 
							
									xml_attr(H), !,
							 | 
						||
| 
								 | 
							
									clean_xmlns_attr(T0, T).
							 | 
						||
| 
								 | 
							
								clean_xmlns_attr([H|T0], [H|T]) :-
							 | 
						||
| 
								 | 
							
									clean_xmlns_attr(T0, T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								xml_attr(xmlns).
							 | 
						||
| 
								 | 
							
								xml_attr(xmlns:_).
							 | 
						||
| 
								 | 
							
								xml_attr(xml:_).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	remove_fragment(+URI, -WithoutFragment)
							 | 
						||
| 
								 | 
							
								%	
							 | 
						||
| 
								 | 
							
								%	When handling xml:base, we must delete the possible fragment.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								remove_fragment(URI, Plain) :-
							 | 
						||
| 
								 | 
							
									sub_atom(URI, B, _, _, #), !,
							 | 
						||
| 
								 | 
							
									sub_atom(URI, 0, B, _, Plain).
							 | 
						||
| 
								 | 
							
								remove_fragment(URI, URI).
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										 /*******************************
							 | 
						||
| 
								 | 
							
										 *     HELP PCE-EMACS A BIT	*
							 | 
						||
| 
								 | 
							
										 *******************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:- multifile
							 | 
						||
| 
								 | 
							
									emacs_prolog_colours:term_colours/2,
							 | 
						||
| 
								 | 
							
									emacs_prolog_colours:goal_classification/2.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								expand(c(X), _, X) :- !.
							 | 
						||
| 
								 | 
							
								expand(In,   Pattern, Colours) :-
							 | 
						||
| 
								 | 
							
									compound(In), !,
							 | 
						||
| 
								 | 
							
									In =.. [F|Args],
							 | 
						||
| 
								 | 
							
									expand_list(Args, PatternArgs, ColourArgs),
							 | 
						||
| 
								 | 
							
									Pattern =.. [F|PatternArgs],
							 | 
						||
| 
								 | 
							
									Colours = functor(F) - ColourArgs.
							 | 
						||
| 
								 | 
							
								expand(X, X, classify).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								expand_list([], [], []).
							 | 
						||
| 
								 | 
							
								expand_list([H|T], [PH|PT], [CH|CT]) :-
							 | 
						||
| 
								 | 
							
									expand(H, PH, CH),
							 | 
						||
| 
								 | 
							
									expand_list(T, PT, CT).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:- discontiguous
							 | 
						||
| 
								 | 
							
									term_expansion/2.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								term_expansion(term_colours(C),
							 | 
						||
| 
								 | 
							
									       emacs_prolog_colours:term_colours(Pattern, Colours)) :-
							 | 
						||
| 
								 | 
							
									expand(C, Pattern, Colours).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								term_colours((c(head(+(1))) ::= c(match), {c(body)})).
							 | 
						||
| 
								 | 
							
								term_colours((c(head(+(1))) ::= c(match))).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								emacs_prolog_colours:goal_classification(\_, expanded).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:- dynamic
							 | 
						||
| 
								 | 
							
									prolog:meta_goal/2.
							 | 
						||
| 
								 | 
							
								:- multifile
							 | 
						||
| 
								 | 
							
									prolog:meta_goal/2,
							 | 
						||
| 
								 | 
							
									prolog:called_by/2.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								prolog:meta_goal(rewrite(A, _), [A]).
							 | 
						||
| 
								 | 
							
								prolog:meta_goal(\A,		[A+1]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								prolog:called_by(attrs(Attrs, _Term), Called) :-
							 | 
						||
| 
								 | 
							
									findall(G+1, sub_term(\?G, Attrs), Called, Tail),
							 | 
						||
| 
								 | 
							
									findall(G+1, sub_term(\G, Attrs), Tail).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 |