| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | /*  $Id$ | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Part of SWI-Prolog | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Author:        Jan Wielemaker | 
					
						
							|  |  |  |     E-mail:        wielemak@science.uva.nl | 
					
						
							|  |  |  |     WWW:           http://www.swi.psy.uva.nl/projects/xpce/ | 
					
						
							|  |  |  |     Copyright (C): 1985-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(prolog_xref, | 
					
						
							|  |  |  | 	  [ xref_source/1,		% +Source | 
					
						
							|  |  |  | 	    xref_called/3,		% ?Source, ?Callable, ?By | 
					
						
							|  |  |  | 	    xref_defined/3,		% ?Source. ?Callable, -How | 
					
						
							|  |  |  | 	    xref_definition_line/2,	% +How, -Line | 
					
						
							|  |  |  | 	    xref_exported/2,		% ?Source, ?Callable | 
					
						
							|  |  |  | 	    xref_module/2,		% ?Source, ?Module | 
					
						
							|  |  |  | 	    xref_op/2,			% ?Source, ?Op | 
					
						
							|  |  |  | 	    xref_clean/1,		% +Source | 
					
						
							|  |  |  | 	    xref_current_source/1,	% ?Source | 
					
						
							|  |  |  | 	    xref_done/2,		% +Source, -Time | 
					
						
							|  |  |  | 	    xref_built_in/1,		% ?Callable | 
					
						
							|  |  |  | 	    xref_expand/2,		% +Term, -Expanded | 
					
						
							|  |  |  | 	    xref_source_file/3,		% +Spec, -Path, +Source | 
					
						
							|  |  |  | 	    xref_source_file/4,		% +Spec, -Path, +Source, +Options | 
					
						
							|  |  |  | 	    xref_public_list/4,		% +Path, -Export, +Src | 
					
						
							|  |  |  | 	    xref_meta/2,		% +Goal, -Called | 
					
						
							|  |  |  | 	    xref_hook/1,		% ?Callable | 
					
						
							|  |  |  | 					% XPCE class references | 
					
						
							|  |  |  | 	    xref_used_class/2,		% ?Source, ?ClassName | 
					
						
							|  |  |  | 	    xref_defined_class/3	% ?Source, ?ClassName, -How | 
					
						
							|  |  |  | 	  ]). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | :- use_module(library(debug), [debug/3, debugging/1]). | 
					
						
							|  |  |  | :- use_module(library(lists), [append/3, member/2]). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | :- use_module(library(operators), | 
					
						
							|  |  |  | 	      [pop_operators/0, push_op/3, push_operators/1]). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | :- if(current_prolog_flag(dialect, swi)). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | :- use_module(library(shlib), [current_foreign_library/2]). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | :- endif. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | :- use_module(library(prolog_source)). | 
					
						
							|  |  |  | :- use_module(library(option)). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | :- use_module(library(error)). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | :- dynamic | 
					
						
							|  |  |  | 	called/3,			% Head, Src, From | 
					
						
							|  |  |  | 	(dynamic)/3,			% Head, Src, Line | 
					
						
							|  |  |  | 	(thread_local)/3,		% Head, Src, Line | 
					
						
							|  |  |  | 	(multifile)/3,			% Head, Src, Line | 
					
						
							|  |  |  | 	defined/3,			% Head, Src, Line | 
					
						
							|  |  |  | 	foreign/3,			% Head, Src, Line | 
					
						
							|  |  |  | 	constraint/3,			% Head, Src, Line | 
					
						
							|  |  |  | 	imported/3,			% Head, Src, From | 
					
						
							|  |  |  | 	exported/2,			% Head, Src | 
					
						
							|  |  |  | 	xmodule/2,			% Module, Src | 
					
						
							|  |  |  | 	xop/2,				% Src, Op | 
					
						
							|  |  |  | 	source/2,			% Src, Time | 
					
						
							|  |  |  | 	used_class/2,			% Name, Src | 
					
						
							|  |  |  | 	defined_class/5,		% Name, Super, Summary, Src, Line | 
					
						
							|  |  |  | 	(mode)/2.			% Mode, Src | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | :- create_prolog_flag(xref, false, [type(boolean)]). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		 /******************************* | 
					
						
							|  |  |  | 		 *	      HOOKS		* | 
					
						
							|  |  |  | 		 *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %	prolog:called_by(+Goal, -ListOfCalled) | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	If this succeeds, the cross-referencer assumes Goal may call any | 
					
						
							|  |  |  | %	of the goals in ListOfCalled. If this call fails, default | 
					
						
							|  |  |  | %	meta-goal analysis is used to determine additional called goals. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %	prolog:meta_goal(+Goal, -Pattern) | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	Define meta-predicates.  See the examples in this file for details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :- multifile | 
					
						
							|  |  |  | 	prolog:called_by/2,		% +Goal, -Called | 
					
						
							|  |  |  | 	prolog:meta_goal/2,		% +Goal, -Pattern | 
					
						
							|  |  |  | 	prolog:hook/1.			% +Callable | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :- dynamic | 
					
						
							|  |  |  | 	meta_goal/2. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | called_by(Goal, Called) :- | 
					
						
							|  |  |  | 	prolog:called_by(Goal, Called), !. | 
					
						
							|  |  |  | called_by(on_signal(_,_,New), [New+1]) :- | 
					
						
							|  |  |  | 	(   new == throw | 
					
						
							|  |  |  | 	;   new == default | 
					
						
							|  |  |  | 	), !, fail. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 		 /******************************* | 
					
						
							|  |  |  | 		 *	     BUILT-INS		* | 
					
						
							|  |  |  | 		 *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	built_in_predicate(+Callable) | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	True if Callable is a built-in | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | :- expects_dialect(swi). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | :- if(current_prolog_flag(dialect, swi)). | 
					
						
							|  |  |  | system_predicate(Goal) :- | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	functor(Goal, Name, Arity), | 
					
						
							|  |  |  | 	current_predicate(system:Name/Arity),	% avoid autoloading | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	predicate_property(system:Goal, built_in), !. | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | :-endif. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/******************************** | 
					
						
							|  |  |  | 		*            TOPLEVEL		* | 
					
						
							|  |  |  | 		********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | verbose :- | 
					
						
							|  |  |  | 	debugging(xref). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	xref_source(+Source) is det. | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Generate the cross-reference data  for   Source  if  not already | 
					
						
							|  |  |  | %	done and the source is not modified.  Checking for modifications | 
					
						
							|  |  |  | %	is only done for files. | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	@param Source	File specification or XPCE buffer | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_source(Source) :- | 
					
						
							|  |  |  | 	prolog_canonical_source(Source, Src), | 
					
						
							|  |  |  | 	(   atom(Src) | 
					
						
							|  |  |  | 	->  time_file(Src, Modified), | 
					
						
							|  |  |  | 	    source(Src, Modified) | 
					
						
							|  |  |  | 	), !. | 
					
						
							|  |  |  | xref_source(Source) :- | 
					
						
							|  |  |  | 	prolog_canonical_source(Source, Src), | 
					
						
							|  |  |  | 	xref_clean(Src), | 
					
						
							|  |  |  | 	(   atom(Src) | 
					
						
							|  |  |  | 	->  time_file(Src, Modified) | 
					
						
							|  |  |  | 	;   get_time(Modified)		% Actually should be `generation' | 
					
						
							|  |  |  | 	), | 
					
						
							|  |  |  | 	assert(source(Src, Modified)), | 
					
						
							|  |  |  | 	xref_setup(Src, In, State), | 
					
						
							|  |  |  | 	call_cleanup(collect(Src, In), xref_cleanup(State)). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | :- thread_local | 
					
						
							|  |  |  | 	xref_stream/1.			% input stream | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_setup(Src, In, state(In, Xref, [SRef|HRefs])) :- | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	prolog_open_source(Src, In), | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	asserta(xref_stream(In), SRef), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	(   current_prolog_flag(xref, Xref) | 
					
						
							|  |  |  | 	->  true | 
					
						
							|  |  |  | 	;   Xref = false | 
					
						
							|  |  |  | 	), | 
					
						
							|  |  |  | 	set_prolog_flag(xref, true), | 
					
						
							|  |  |  | 	(   verbose | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	->  HRefs = [] | 
					
						
							|  |  |  | 	;   asserta(user:message_hook(_,_,_), Ref), | 
					
						
							|  |  |  | 	    HRefs = [Ref] | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | xref_cleanup(state(In, Xref, Refs)) :- | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	prolog_close_source(In), | 
					
						
							|  |  |  | 	set_prolog_flag(xref, Xref), | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	maplist(erase, Refs). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	xref_input_stream(-Stream) is det. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	Current input stream for cross-referencer. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_input_stream(Stream) :- | 
					
						
							|  |  |  | 	xref_stream(Var), !, | 
					
						
							|  |  |  | 	Stream = Var. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | %%	xref_push_op(Source, +Prec, +Type, :Name) | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Define operators into the default source module and register | 
					
						
							|  |  |  | %	them to be undone by pop_operators/0. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_push_op(Src, P, T, N0) :- !, | 
					
						
							|  |  |  | 	(   N0 = _:_ | 
					
						
							|  |  |  | 	->  N = N0 | 
					
						
							|  |  |  | 	;   '$set_source_module'(M, M), | 
					
						
							|  |  |  | 	    N = M:N0 | 
					
						
							|  |  |  | 	), | 
					
						
							|  |  |  | 	push_op(P, T, N), | 
					
						
							|  |  |  | 	assert_op(Src, op(P,T,N)), | 
					
						
							|  |  |  | 	debug(xref, ':- ~w.', [op(P,T,N)]). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	xref_clean(+Source) is det. | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Reset the database for the given source. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_clean(Source) :- | 
					
						
							|  |  |  | 	prolog_canonical_source(Source, Src), | 
					
						
							|  |  |  | 	retractall(called(_, Src, _Origin)), | 
					
						
							|  |  |  | 	retractall(dynamic(_, Src, Line)), | 
					
						
							|  |  |  | 	retractall(multifile(_, Src, Line)), | 
					
						
							|  |  |  | 	retractall(defined(_, Src, Line)), | 
					
						
							|  |  |  | 	retractall(foreign(_, Src, Line)), | 
					
						
							|  |  |  | 	retractall(constraint(_, Src, Line)), | 
					
						
							|  |  |  | 	retractall(imported(_, Src, _From)), | 
					
						
							|  |  |  | 	retractall(exported(_, Src)), | 
					
						
							|  |  |  | 	retractall(xmodule(_, Src)), | 
					
						
							|  |  |  | 	retractall(xop(Src, _)), | 
					
						
							|  |  |  | 	retractall(source(Src, _)), | 
					
						
							|  |  |  | 	retractall(used_class(_, Src)), | 
					
						
							|  |  |  | 	retractall(defined_class(_, _, _, Src, _)), | 
					
						
							|  |  |  | 	retractall(mode(_, Src)). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		 /******************************* | 
					
						
							|  |  |  | 		 *	    READ RESULTS	* | 
					
						
							|  |  |  | 		 *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	xref_current_source(?Source) | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	Check what sources have been analysed. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_current_source(Source) :- | 
					
						
							|  |  |  | 	source(Source, _Time). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	xref_done(+Source, -Time) is det. | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Cross-reference executed at Time | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_done(Source, Time) :- | 
					
						
							|  |  |  | 	prolog_canonical_source(Source, Src), | 
					
						
							|  |  |  | 	source(Src, Time). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	xref_called(+Source, ?Called, ?By) is nondet. | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Enumerate the predicate-call relations. Predicate called by | 
					
						
							|  |  |  | %	directives have a By '<directive>'. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_called(Source, Called, By) :- | 
					
						
							|  |  |  | 	prolog_canonical_source(Source, Src), | 
					
						
							|  |  |  | 	called(Called, Src, By). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	xref_defined(+Source, +Goal, ?How) is semidet. | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Test if Goal is accessible in Source. If this is the case, How | 
					
						
							|  |  |  | %	specifies the reason why the predicate is accessible. Note that | 
					
						
							|  |  |  | %	this predicate does not deal with built-in or global predicates, | 
					
						
							|  |  |  | %	just locally defined and imported ones. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_defined(Source, Called, How) :- | 
					
						
							|  |  |  | 	prolog_canonical_source(Source, Src), | 
					
						
							|  |  |  | 	xref_defined2(How, Src, Called). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_defined2(dynamic(Line), Src, Called) :- | 
					
						
							|  |  |  | 	dynamic(Called, Src, Line). | 
					
						
							|  |  |  | xref_defined2(thread_local(Line), Src, Called) :- | 
					
						
							|  |  |  | 	thread_local(Called, Src, Line). | 
					
						
							|  |  |  | xref_defined2(multifile(Line), Src, Called) :- | 
					
						
							|  |  |  | 	multifile(Called, Src, Line). | 
					
						
							|  |  |  | xref_defined2(local(Line), Src, Called) :- | 
					
						
							|  |  |  | 	defined(Called, Src, Line). | 
					
						
							|  |  |  | xref_defined2(foreign(Line), Src, Called) :- | 
					
						
							|  |  |  | 	foreign(Called, Src, Line). | 
					
						
							|  |  |  | xref_defined2(constraint(Line), Src, Called) :- | 
					
						
							|  |  |  | 	constraint(Called, Src, Line). | 
					
						
							|  |  |  | xref_defined2(imported(From), Src, Called) :- | 
					
						
							|  |  |  | 	imported(Called, Src, From). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	xref_definition_line(+How, -Line) | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	If the 3th argument of xref_defined contains line info, return | 
					
						
							|  |  |  | %	this in Line. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_definition_line(local(Line),	 Line). | 
					
						
							|  |  |  | xref_definition_line(dynamic(Line),	 Line). | 
					
						
							|  |  |  | xref_definition_line(thread_local(Line), Line). | 
					
						
							|  |  |  | xref_definition_line(multifile(Line),	 Line). | 
					
						
							|  |  |  | xref_definition_line(constraint(Line),	 Line). | 
					
						
							|  |  |  | xref_definition_line(foreign(Line),	 Line). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_exported(Source, Called) :- | 
					
						
							|  |  |  | 	prolog_canonical_source(Source, Src), | 
					
						
							|  |  |  | 	exported(Called, Src). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	xref_module(?Source, ?Module) is nondet. | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	True if Module is defined in Source. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_module(Source, Module) :- | 
					
						
							|  |  |  | 	prolog_canonical_source(Source, Src), | 
					
						
							|  |  |  | 	xmodule(Module, Src). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	xref_op(?Source, Op) is nondet. | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Give the operators active inside the module. This is intended to | 
					
						
							|  |  |  | %	setup the environment for incremental parsing of a term from the | 
					
						
							|  |  |  | %	source-file. | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	@param Op	Term of the form op(Priority, Type, Name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_op(Source, Op) :- | 
					
						
							|  |  |  | 	prolog_canonical_source(Source, Src), | 
					
						
							|  |  |  | 	xop(Src, Op). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_built_in(Head) :- | 
					
						
							|  |  |  | 	system_predicate(Head). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_used_class(Source, Class) :- | 
					
						
							|  |  |  | 	prolog_canonical_source(Source, Src), | 
					
						
							|  |  |  | 	used_class(Class, Src). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_defined_class(Source, Class, local(Line, Super, Summary)) :- | 
					
						
							|  |  |  | 	prolog_canonical_source(Source, Src), | 
					
						
							|  |  |  | 	defined_class(Class, Super, Summary, Src, Line), | 
					
						
							|  |  |  | 	integer(Line), !. | 
					
						
							|  |  |  | xref_defined_class(Source, Class, file(File)) :- | 
					
						
							|  |  |  | 	prolog_canonical_source(Source, Src), | 
					
						
							|  |  |  | 	defined_class(Class, _, _, Src, file(File)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | collect(Src, In) :- | 
					
						
							|  |  |  | 	repeat, | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	    catch(read_source_term(Src, In, Term, TermPos), | 
					
						
							|  |  |  | 		  E, report_syntax_error(E)), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	    xref_expand(Term, T), | 
					
						
							|  |  |  | 	    (   T == end_of_file | 
					
						
							|  |  |  | 	    ->  ! | 
					
						
							|  |  |  | 	    ;   stream_position_data(line_count, TermPos, Line), | 
					
						
							|  |  |  | 		flag(xref_src_line, _, Line), | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 		catch(process(T, Src), E, print_message(error, E)), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 		fail | 
					
						
							|  |  |  | 	    ). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | %%	read_source_term(+Src, +In:stream, -Term, -TermPos) is det. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | % | 
					
						
							|  |  |  | %	Read next term  from  In.   The  cross-referencer  supports  the | 
					
						
							|  |  |  | %	comment_hook  as  also  implemented  by  the  compiler  for  the | 
					
						
							|  |  |  | %	documentation processor. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :- multifile | 
					
						
							|  |  |  | 	prolog:comment_hook/3. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | read_source_term(Src, In, Term, TermPos) :- | 
					
						
							|  |  |  | 	atom(Src), | 
					
						
							|  |  |  | 	\+ source_file(Src),		% normally loaded; no need to update | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	'$get_predicate_attribute'(prolog:comment_hook(_,_,_), | 
					
						
							|  |  |  | 				   number_of_clauses, N), | 
					
						
							|  |  |  | 	N > 0, !, | 
					
						
							|  |  |  | 	'$set_source_module'(SM, SM), | 
					
						
							|  |  |  | 	read_term(In, Term, | 
					
						
							|  |  |  | 		  [ term_position(TermPos), | 
					
						
							|  |  |  | 		    comments(Comments), | 
					
						
							|  |  |  | 		    module(SM) | 
					
						
							|  |  |  | 		  ]), | 
					
						
							|  |  |  | 	(   catch(prolog:comment_hook(Comments, TermPos, Term), E, | 
					
						
							|  |  |  | 		  print_message(error, E)) | 
					
						
							|  |  |  | 	->  true | 
					
						
							|  |  |  | 	;   true | 
					
						
							|  |  |  | 	). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | read_source_term(_, In, Term, TermPos) :- | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	'$set_source_module'(SM, SM), | 
					
						
							|  |  |  | 	read_term(In, Term, | 
					
						
							|  |  |  | 		  [ term_position(TermPos), | 
					
						
							|  |  |  | 		    module(SM) | 
					
						
							|  |  |  | 		  ]). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | report_syntax_error(E) :- | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	(   verbose | 
					
						
							|  |  |  | 	->  print_message(error, E) | 
					
						
							|  |  |  | 	;   true | 
					
						
							|  |  |  | 	), | 
					
						
							|  |  |  | 	fail. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		 /******************************* | 
					
						
							|  |  |  | 		 *	     EXPANSION		* | 
					
						
							|  |  |  | 		 *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	xref_expand(+Term, -Expanded) | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	Do the term-expansion. We have to pass require as we need it for | 
					
						
							|  |  |  | %	validation. Otherwise we do term-expansion,  handling all of the | 
					
						
							|  |  |  | %	XPCE class compiler as normal   Prolog  afterwards. CHR programs | 
					
						
							|  |  |  | %	are processed using process_chr/2  directly   from  the  source, | 
					
						
							|  |  |  | %	which is why we inhibit expansion here. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | xref_expand((:- if(Cond)), (:- if(Cond))). | 
					
						
							|  |  |  | xref_expand((:- elif(Cond)), (:- elif(Cond))). | 
					
						
							|  |  |  | xref_expand((:- else), (:- else)). | 
					
						
							|  |  |  | xref_expand((:- endif), (:- endif)). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | xref_expand((:- require(X)), | 
					
						
							|  |  |  | 	    (:- require(X))) :- !. | 
					
						
							|  |  |  | xref_expand(Term, _) :- | 
					
						
							|  |  |  | 	requires_library(Term, Lib), | 
					
						
							|  |  |  | 	ensure_loaded(user:Lib), | 
					
						
							|  |  |  | 	fail. | 
					
						
							|  |  |  | xref_expand(Term, Term) :- | 
					
						
							|  |  |  | 	chr_expandable(Term), !. | 
					
						
							|  |  |  | xref_expand('$:-'(X), '$:-'(X)) :- !,	% boot module | 
					
						
							|  |  |  | 	style_check(+dollar). | 
					
						
							|  |  |  | xref_expand(Term, T) :- | 
					
						
							|  |  |  | 	catch(expand_term(Term, Expanded), _, Expanded=Term), | 
					
						
							|  |  |  | 	(   is_list(Expanded) | 
					
						
							|  |  |  | 	->  member(T, Expanded) | 
					
						
							|  |  |  | 	;   T = Expanded | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	requires_library(+Term, -Library) | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	known expansion hooks.  Should be more dynamic! | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | requires_library((:- emacs_begin_mode(_,_,_,_,_)), library(emacs_extend)). | 
					
						
							|  |  |  | requires_library((:- draw_begin_shape(_,_,_,_)), library(pcedraw)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		 /******************************* | 
					
						
							|  |  |  | 		 *	     PROCESS		* | 
					
						
							|  |  |  | 		 *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | process(Var, _) :- | 
					
						
							|  |  |  | 	var(Var), !.			% Warn? | 
					
						
							|  |  |  | process((:- Directive), Src) :- !, | 
					
						
							|  |  |  | 	process_directive(Directive, Src), !. | 
					
						
							|  |  |  | process((?- Directive), Src) :- !, | 
					
						
							|  |  |  | 	process_directive(Directive, Src), !. | 
					
						
							|  |  |  | process((Head :- Body), Src) :- !, | 
					
						
							|  |  |  | 	assert_defined(Src, Head), | 
					
						
							|  |  |  | 	process_body(Body, Head, Src). | 
					
						
							|  |  |  | process('$source_location'(_File, _Line):Clause, Src) :- !, | 
					
						
							|  |  |  | 	process(Clause, Src). | 
					
						
							|  |  |  | process(Term, Src) :- | 
					
						
							|  |  |  | 	chr_expandable(Term), !, | 
					
						
							|  |  |  | 	process_chr(Term, Src). | 
					
						
							|  |  |  | process(M:(Head :- Body), Src) :- !, | 
					
						
							|  |  |  | 	process((M:Head :- M:Body), Src). | 
					
						
							|  |  |  | process(Head, Src) :- | 
					
						
							|  |  |  | 	assert_defined(Src, Head). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/******************************** | 
					
						
							|  |  |  | 		 *           DIRECTIVES		* | 
					
						
							|  |  |  | 		 ********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | process_directive(Var, _) :- | 
					
						
							|  |  |  | 	var(Var), !.			% error, but that isn't our business | 
					
						
							|  |  |  | process_directive((A,B), Src) :- !,	% TBD: whta about other control | 
					
						
							|  |  |  | 	process_directive(A, Src),	% structures? | 
					
						
							|  |  |  | 	process_directive(B, Src). | 
					
						
							|  |  |  | process_directive(List, Src) :- | 
					
						
							|  |  |  | 	is_list(List), !, | 
					
						
							|  |  |  | 	process_directive(consult(List), Src). | 
					
						
							|  |  |  | process_directive(use_module(Spec, Import), Src) :- | 
					
						
							|  |  |  | 	xref_public_list(Spec, Path, Public, Src), | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	assert_import(Src, Import, Public, Path, false). | 
					
						
							|  |  |  | process_directive(reexport(Spec, Import), Src) :- | 
					
						
							|  |  |  | 	xref_public_list(Spec, Path, Public, Src), | 
					
						
							|  |  |  | 	assert_import(Src, Import, Public, Path, true). | 
					
						
							|  |  |  | process_directive(reexport(Modules), Src) :- | 
					
						
							|  |  |  | 	process_use_module(Modules, Src, true). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | process_directive(use_module(Modules), Src) :- | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	process_use_module(Modules, Src, false). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | process_directive(consult(Modules), Src) :- | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	process_use_module(Modules, Src, false). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | process_directive(ensure_loaded(Modules), Src) :- | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	process_use_module(Modules, Src, false). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | process_directive(load_files(Files, _Options), Src) :- | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	process_use_module(Files, Src, false). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | process_directive(include(Files), Src) :- | 
					
						
							|  |  |  | 	process_include(Files, Src). | 
					
						
							|  |  |  | process_directive(dynamic(Dynamic), Src) :- | 
					
						
							|  |  |  | 	assert_dynamic(Src, Dynamic). | 
					
						
							|  |  |  | process_directive(thread_local(Dynamic), Src) :- | 
					
						
							|  |  |  | 	assert_thread_local(Src, Dynamic). | 
					
						
							|  |  |  | process_directive(multifile(Dynamic), Src) :- | 
					
						
							|  |  |  | 	assert_multifile(Src, Dynamic). | 
					
						
							|  |  |  | process_directive(module(Module, Export), Src) :- | 
					
						
							|  |  |  | 	assert_module(Src, Module), | 
					
						
							|  |  |  | 	assert_export(Src, Export). | 
					
						
							|  |  |  | process_directive(system_mode(on), _Src) :- !, | 
					
						
							|  |  |  | 	style_check(+dollar). | 
					
						
							|  |  |  | process_directive(pce_begin_class_definition(Name, Meta, Super, Doc), Src) :- | 
					
						
							|  |  |  | 	assert_defined_class(Src, Name, Meta, Super, Doc). | 
					
						
							|  |  |  | process_directive(pce_autoload(Name, From), Src) :- | 
					
						
							|  |  |  | 	assert_defined_class(Src, Name, imported_from(From)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | process_directive(op(P, A, N), Src) :- | 
					
						
							|  |  |  | 	xref_push_op(Src, P, A, N). | 
					
						
							|  |  |  | process_directive(style_check(X), _) :- | 
					
						
							|  |  |  | 	style_check(X). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | process_directive(encoding(Enc), _) :- | 
					
						
							|  |  |  | 	(   xref_input_stream(Stream) | 
					
						
							|  |  |  | 	->  catch(set_stream(Stream, encoding(Enc)), _, true) | 
					
						
							|  |  |  | 	;   true			% can this happen? | 
					
						
							|  |  |  | 	). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | process_directive(system_module, _) :- | 
					
						
							|  |  |  | 	style_check(+dollar). | 
					
						
							|  |  |  | process_directive(set_prolog_flag(character_escapes, Esc), _) :- | 
					
						
							|  |  |  | 	set_prolog_flag(character_escapes, Esc). | 
					
						
							|  |  |  | process_directive(pce_expansion:push_compile_operators, _) :- | 
					
						
							|  |  |  | 	'$set_source_module'(SM, SM), | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	call(pce_expansion:push_compile_operators(SM)). % call to avoid xref | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | process_directive(pce_expansion:pop_compile_operators, _) :- | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	call(pce_expansion:pop_compile_operators). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | process_directive(meta_predicate(Meta), _) :- | 
					
						
							|  |  |  | 	process_meta_predicate(Meta). | 
					
						
							|  |  |  | process_directive(arithmetic_function(FSpec), Src) :- | 
					
						
							|  |  |  | 	arith_callable(FSpec, Goal), !, | 
					
						
							|  |  |  | 	flag(xref_src_line, Line, Line), | 
					
						
							|  |  |  | 	assert_called(Src, '<directive>'(Line), Goal). | 
					
						
							|  |  |  | process_directive(format_predicate(_, Goal), Src) :- !, | 
					
						
							|  |  |  | 	flag(xref_src_line, Line, Line), | 
					
						
							|  |  |  | 	assert_called(Src, '<directive>'(Line), Goal). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | process_directive(if(Cond), Src) :- !, | 
					
						
							|  |  |  | 	flag(xref_src_line, Line, Line), | 
					
						
							|  |  |  | 	assert_called(Src, '<directive>'(Line), Cond). | 
					
						
							|  |  |  | process_directive(elif(Cond), Src) :- !, | 
					
						
							|  |  |  | 	flag(xref_src_line, Line, Line), | 
					
						
							|  |  |  | 	assert_called(Src, '<directive>'(Line), Cond). | 
					
						
							|  |  |  | process_directive(else, _) :- !. | 
					
						
							|  |  |  | process_directive(endif, _) :- !. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | process_directive(Goal, Src) :- | 
					
						
							|  |  |  | 	flag(xref_src_line, Line, Line), | 
					
						
							|  |  |  | 	process_body(Goal, '<directive>'(Line), Src). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	process_meta_predicate(+Decl) | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Create prolog:meta_goal/2 declaration from the meta-goal | 
					
						
							|  |  |  | %	declaration. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | process_meta_predicate((A,B)) :- !, | 
					
						
							|  |  |  | 	process_meta_predicate(A), | 
					
						
							|  |  |  | 	process_meta_predicate(B). | 
					
						
							|  |  |  | process_meta_predicate(Decl) :- | 
					
						
							|  |  |  | 	functor(Decl, Name, Arity), | 
					
						
							|  |  |  | 	functor(Head, Name, Arity), | 
					
						
							|  |  |  | 	meta_args(1, Arity, Decl, Head, Meta), | 
					
						
							|  |  |  | 	(   (   prolog:meta_goal(Head, _) | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	    ;   called_by(Head, _) | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	    ;   meta_goal(Head, _) | 
					
						
							|  |  |  | 	    ) | 
					
						
							|  |  |  | 	->  true | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	;   assert(meta_goal(Head, Meta)) | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | meta_args(I, Arity, _, _, []) :- | 
					
						
							|  |  |  | 	I > Arity, !. | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | meta_args(I, Arity, Decl, Head, [H|T]) :- 		% 0 | 
					
						
							|  |  |  | 	arg(I, Decl, 0), !, | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	arg(I, Head, H), | 
					
						
							|  |  |  | 	I2 is I + 1, | 
					
						
							|  |  |  | 	meta_args(I2, Arity, Decl, Head, T). | 
					
						
							|  |  |  | meta_args(I, Arity, Decl, Head, [H+A|T]) :-		% I --> H+I | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	arg(I, Decl, A), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	integer(A), A > 0, !, | 
					
						
							|  |  |  | 	arg(I, Head, H), | 
					
						
							|  |  |  | 	I2 is I + 1, | 
					
						
							|  |  |  | 	meta_args(I2, Arity, Decl, Head, T). | 
					
						
							|  |  |  | meta_args(I, Arity, Decl, Head, Meta) :- | 
					
						
							|  |  |  | 	I2 is I + 1, | 
					
						
							|  |  |  | 	meta_args(I2, Arity, Decl, Head, Meta). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	      /******************************** | 
					
						
							|  |  |  | 	      *             BODY	      * | 
					
						
							|  |  |  | 	      ********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_meta((A, B), 		[A, B]). | 
					
						
							|  |  |  | xref_meta((A; B), 		[A, B]). | 
					
						
							|  |  |  | xref_meta((A| B), 		[A, B]). | 
					
						
							|  |  |  | xref_meta((A -> B),		[A, B]). | 
					
						
							|  |  |  | xref_meta((A *-> B),		[A, B]). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | xref_meta(findall(_V,G,_L),	[G]). | 
					
						
							|  |  |  | xref_meta(findall(_V,G,_L,_T),	[G]). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | xref_meta(setof(_V, G, _L),	[G]). | 
					
						
							|  |  |  | xref_meta(bagof(_V, G, _L),	[G]). | 
					
						
							|  |  |  | xref_meta(forall(A, B),		[A, B]). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | xref_meta(maplist(G,_),		[G+1]). | 
					
						
							|  |  |  | xref_meta(maplist(G,_,_),	[G+2]). | 
					
						
							|  |  |  | xref_meta(maplist(G,_,_,_),	[G+3]). | 
					
						
							|  |  |  | xref_meta(maplist(G,_,_,_,_),	[G+4]). | 
					
						
							|  |  |  | xref_meta(map_list_to_pairs(G,_,_), [G+2]). | 
					
						
							|  |  |  | xref_meta(map_assoc(G, _),	[G+1]). | 
					
						
							|  |  |  | xref_meta(map_assoc(G, _, _),	[G+2]). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | xref_meta(checklist(G, _L),	[G+1]). | 
					
						
							|  |  |  | xref_meta(sublist(G, _, _),	[G+1]). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | xref_meta(include(G, _, _),	[G+1]). | 
					
						
							|  |  |  | xref_meta(exclude(G, _, _),	[G+1]). | 
					
						
							|  |  |  | xref_meta(partition(G, _, _, _, _),	[G+2]). | 
					
						
							|  |  |  | xref_meta(partition(G, _, _, _),[G+1]). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | xref_meta(call(G),		[G]). | 
					
						
							|  |  |  | xref_meta(call(G, _),		[G+1]). | 
					
						
							|  |  |  | xref_meta(call(G, _, _),	[G+2]). | 
					
						
							|  |  |  | xref_meta(call(G, _, _, _),	[G+3]). | 
					
						
							|  |  |  | xref_meta(call(G, _, _, _, _),	[G+4]). | 
					
						
							|  |  |  | xref_meta(not(G),		[G]). | 
					
						
							|  |  |  | xref_meta(notrace(G),		[G]). | 
					
						
							|  |  |  | xref_meta(\+(G),		[G]). | 
					
						
							|  |  |  | xref_meta(ignore(G),		[G]). | 
					
						
							|  |  |  | xref_meta(once(G),		[G]). | 
					
						
							|  |  |  | xref_meta(initialization(G),	[G]). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | xref_meta(initialization(G,_),	[G]). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | xref_meta(retract(Rule),	[G]) :- head_of(Rule, G). | 
					
						
							|  |  |  | xref_meta(clause(G, _),		[G]). | 
					
						
							|  |  |  | xref_meta(clause(G, _, _),	[G]). | 
					
						
							|  |  |  | xref_meta(phrase(G, _A),	[G+2]). | 
					
						
							|  |  |  | xref_meta(phrase(G, _A, _R),	[G+2]). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | xref_meta(phrase_from_file(G,_),[G+2]). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | xref_meta(catch(A, _, B),	[A, B]). | 
					
						
							|  |  |  | xref_meta(thread_create(A,_,_), [A]). | 
					
						
							|  |  |  | xref_meta(thread_signal(_,A),   [A]). | 
					
						
							|  |  |  | xref_meta(thread_at_exit(A),	[A]). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | xref_meta(thread_initialization(A), [A]). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | xref_meta(predsort(A,_,_),	[A+3]). | 
					
						
							|  |  |  | xref_meta(call_cleanup(A, B),	[A, B]). | 
					
						
							|  |  |  | xref_meta(call_cleanup(A, _, B),[A, B]). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | xref_meta(setup_call_cleanup(A, B, C),[A, B, C]). | 
					
						
							|  |  |  | xref_meta(setup_call_catcher_cleanup(A, B, _, C),[A, B, C]). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | xref_meta(with_mutex(_,A),	[A]). | 
					
						
							|  |  |  | xref_meta(assume(G),		[G]).	% library(debug) | 
					
						
							|  |  |  | xref_meta(assertion(G),		[G]).	% library(debug) | 
					
						
							|  |  |  | xref_meta(freeze(_, G),		[G]). | 
					
						
							|  |  |  | xref_meta(when(C, A),		[C, A]). | 
					
						
							|  |  |  | xref_meta(clause(G, _),		[G]). | 
					
						
							|  |  |  | xref_meta(clause(G, _, _),	[G]). | 
					
						
							|  |  |  | xref_meta(time(G),		[G]).	% development system | 
					
						
							|  |  |  | xref_meta(profile(G),		[G]). | 
					
						
							|  |  |  | xref_meta(at_halt(G),		[G]). | 
					
						
							|  |  |  | xref_meta(call_with_time_limit(_, G), [G]). | 
					
						
							|  |  |  | xref_meta(call_with_depth_limit(G, _, _), [G]). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | xref_meta(alarm(_, G, _),	[G]). | 
					
						
							|  |  |  | xref_meta(alarm(_, G, _, _),	[G]). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | xref_meta('$add_directive_wic'(G), [G]). | 
					
						
							|  |  |  | xref_meta(with_output_to(_, G),	[G]). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | xref_meta(if(G),		[G]). | 
					
						
							|  |  |  | xref_meta(elif(G),		[G]). | 
					
						
							|  |  |  | xref_meta(meta_options(G,_,_),	[G+1]). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					% XPCE meta-predicates | 
					
						
							|  |  |  | xref_meta(pce_global(_, new(_)), _) :- !, fail. | 
					
						
							|  |  |  | xref_meta(pce_global(_, B),     [B+1]). | 
					
						
							|  |  |  | xref_meta(ifmaintainer(G),	[G]).	% used in manual | 
					
						
							|  |  |  | xref_meta(listen(_, G),		[G]).	% library(broadcast) | 
					
						
							|  |  |  | xref_meta(listen(_, _, G),	[G]). | 
					
						
							|  |  |  | xref_meta(in_pce_thread(G),	[G]). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_meta(G, Meta) :-			% call user extensions | 
					
						
							|  |  |  | 	prolog:meta_goal(G, Meta). | 
					
						
							|  |  |  | xref_meta(G, Meta) :-			% Generated from :- meta_predicate | 
					
						
							|  |  |  | 	meta_goal(G, Meta). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	head_of(+Rule, -Head) | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Get the head for a retract call. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | head_of(Var, _) :- | 
					
						
							|  |  |  | 	var(Var), !, fail. | 
					
						
							|  |  |  | head_of((Head :- _), Head). | 
					
						
							|  |  |  | head_of(Head, Head). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	xref_hook(?Callable) | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Definition of known hooks.  Hooks  that   can  be  called in any | 
					
						
							|  |  |  | %	module are unqualified.  Other  hooks   are  qualified  with the | 
					
						
							|  |  |  | %	module where they are called. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_hook(Hook) :- | 
					
						
							|  |  |  | 	prolog:hook(Hook). | 
					
						
							|  |  |  | xref_hook(Hook) :- | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	hook(Hook). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hook(attr_portray_hook(_,_)). | 
					
						
							|  |  |  | hook(attr_unify_hook(_,_)). | 
					
						
							|  |  |  | hook(goal_expansion(_,_)). | 
					
						
							|  |  |  | hook(term_expansion(_,_)). | 
					
						
							|  |  |  | hook(resource(_,_,_)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hook(emacs_prolog_colours:goal_classification(_,_)). | 
					
						
							|  |  |  | hook(emacs_prolog_colours:term_colours(_,_)). | 
					
						
							|  |  |  | hook(emacs_prolog_colours:goal_colours(_,_)). | 
					
						
							|  |  |  | hook(emacs_prolog_colours:style(_,_)). | 
					
						
							|  |  |  | hook(emacs_prolog_colours:identify(_,_)). | 
					
						
							|  |  |  | hook(pce_principal:pce_class(_,_,_,_,_,_)). | 
					
						
							|  |  |  | hook(pce_principal:send_implementation(_,_,_)). | 
					
						
							|  |  |  | hook(pce_principal:get_implementation(_,_,_,_)). | 
					
						
							|  |  |  | hook(pce_principal:pce_lazy_get_method(_,_,_)). | 
					
						
							|  |  |  | hook(pce_principal:pce_lazy_send_method(_,_,_)). | 
					
						
							|  |  |  | hook(pce_principal:pce_uses_template(_,_)). | 
					
						
							|  |  |  | hook(prolog:locate_clauses(_,_)). | 
					
						
							|  |  |  | hook(prolog:message(_,_,_)). | 
					
						
							|  |  |  | hook(prolog:message_context(_,_,_)). | 
					
						
							|  |  |  | hook(prolog:debug_control_hook(_)). | 
					
						
							|  |  |  | hook(prolog:help_hook(_)). | 
					
						
							|  |  |  | hook(prolog:show_profile_hook(_,_)). | 
					
						
							|  |  |  | hook(prolog:general_exception(_,_)). | 
					
						
							|  |  |  | hook(prolog_edit:load). | 
					
						
							|  |  |  | hook(prolog_edit:locate(_,_,_)). | 
					
						
							|  |  |  | hook(shlib:unload_all_foreign_libraries). | 
					
						
							|  |  |  | hook(system:'$foreign_registered'(_, _)). | 
					
						
							|  |  |  | hook(user:exception(_,_,_)). | 
					
						
							|  |  |  | hook(user:file_search_path(_,_)). | 
					
						
							|  |  |  | hook(user:library_directory(_)). | 
					
						
							|  |  |  | hook(user:message_hook(_,_,_)). | 
					
						
							|  |  |  | hook(user:portray(_)). | 
					
						
							|  |  |  | hook(user:prolog_clause_name(_,_)). | 
					
						
							|  |  |  | hook(user:prolog_list_goal(_)). | 
					
						
							|  |  |  | hook(user:prolog_predicate_name(_,_)). | 
					
						
							|  |  |  | hook(user:prolog_trace_interception(_,_,_,_)). | 
					
						
							|  |  |  | hook(user:prolog_event_hook(_)). | 
					
						
							|  |  |  | hook(user:prolog_exception_hook(_,_,_,_)). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | %%	arith_callable(+Spec, -Callable) | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Translate argument of arithmetic_function/1 into a callable term | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | arith_callable(Var, _) :- | 
					
						
							|  |  |  | 	var(Var), !, fail. | 
					
						
							|  |  |  | arith_callable(Module:Spec, Module:Goal) :- !, | 
					
						
							|  |  |  | 	arith_callable(Spec, Goal). | 
					
						
							|  |  |  | arith_callable(Name/Arity, Goal) :- | 
					
						
							|  |  |  | 	PredArity is Arity + 1, | 
					
						
							|  |  |  | 	functor(Goal, Name, PredArity). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	process_body(+Body, +Origin, +Src) | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Process a callable body (body of a clause or directive). Origin | 
					
						
							|  |  |  | %	describes the origin of the call. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | process_body(Var, _, _) :- | 
					
						
							|  |  |  | 	var(Var), !. | 
					
						
							|  |  |  | process_body(Goal, Origin, Src) :- | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	called_by(Goal, Called), !, | 
					
						
							|  |  |  | 	must_be(list, Called), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	assert_called(Src, Origin, Goal), | 
					
						
							|  |  |  | 	process_called_list(Called, Origin, Src). | 
					
						
							|  |  |  | process_body(Goal, Origin, Src) :- | 
					
						
							|  |  |  | 	process_xpce_goal(Goal, Origin, Src), !. | 
					
						
							|  |  |  | process_body(load_foreign_library(File), _Origin, Src) :- | 
					
						
							|  |  |  | 	process_foreign(File, Src). | 
					
						
							|  |  |  | process_body(load_foreign_library(File, _Init), _Origin, Src) :- | 
					
						
							|  |  |  | 	process_foreign(File, Src). | 
					
						
							|  |  |  | process_body(Goal, Origin, Src) :- | 
					
						
							|  |  |  | 	xref_meta(Goal, Metas), !, | 
					
						
							|  |  |  | 	assert_called(Src, Origin, Goal), | 
					
						
							|  |  |  | 	process_called_list(Metas, Origin, Src). | 
					
						
							|  |  |  | process_body(Goal, Origin, Src) :- | 
					
						
							|  |  |  | 	asserting_goal(Goal, Rule), !, | 
					
						
							|  |  |  | 	assert_called(Src, Origin, Goal), | 
					
						
							|  |  |  | 	process_assert(Rule, Origin, Src). | 
					
						
							|  |  |  | process_body(Goal, Origin, Src) :- | 
					
						
							|  |  |  | 	assert_called(Src, Origin, Goal). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | process_called_list([], _, _). | 
					
						
							|  |  |  | process_called_list([H|T], Origin, Src) :- | 
					
						
							|  |  |  | 	process_meta(H, Origin, Src), | 
					
						
							|  |  |  | 	process_called_list(T, Origin, Src). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | process_meta(A+N, Origin, Src) :- !, | 
					
						
							|  |  |  | 	(   extend(A, N, AX) | 
					
						
							|  |  |  | 	->  process_body(AX, Origin, Src) | 
					
						
							|  |  |  | 	;   true | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | process_meta(G, Origin, Src) :- | 
					
						
							|  |  |  | 	process_body(G, Origin, Src). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extend(Var, _, _) :- | 
					
						
							|  |  |  | 	var(Var), !, fail. | 
					
						
							|  |  |  | extend(M:G, N, M:GX) :- !, | 
					
						
							|  |  |  | 	callable(G), | 
					
						
							|  |  |  | 	extend(G, N, GX). | 
					
						
							|  |  |  | extend(G, N, GX) :- | 
					
						
							|  |  |  | 	callable(G), | 
					
						
							|  |  |  | 	G =.. List, | 
					
						
							|  |  |  | 	length(Rest, N), | 
					
						
							|  |  |  | 	append(List, Rest, NList), | 
					
						
							|  |  |  | 	GX =.. NList. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | asserting_goal(assert(Rule), Rule). | 
					
						
							|  |  |  | asserting_goal(asserta(Rule), Rule). | 
					
						
							|  |  |  | asserting_goal(assertz(Rule), Rule). | 
					
						
							|  |  |  | asserting_goal(assert(Rule,_), Rule). | 
					
						
							|  |  |  | asserting_goal(asserta(Rule,_), Rule). | 
					
						
							|  |  |  | asserting_goal(assertz(Rule,_), Rule). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | process_assert(0, _, _) :- !.		% catch variables | 
					
						
							|  |  |  | process_assert((_:-Body), Origin, Src) :- !, | 
					
						
							|  |  |  | 	process_body(Body, Origin, Src). | 
					
						
							|  |  |  | process_assert(_, _, _). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		 /******************************* | 
					
						
							|  |  |  | 		 *	    XPCE STUFF		* | 
					
						
							|  |  |  | 		 *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | pce_goal(new(_,_), new(-, new)). | 
					
						
							|  |  |  | pce_goal(send(_,_), send(arg, msg)). | 
					
						
							|  |  |  | pce_goal(send_class(_,_,_), send_class(arg, arg, msg)). | 
					
						
							|  |  |  | pce_goal(get(_,_,_), get(arg, msg, -)). | 
					
						
							|  |  |  | pce_goal(get_class(_,_,_,_), get_class(arg, arg, msg, -)). | 
					
						
							|  |  |  | pce_goal(get_chain(_,_,_), get_chain(arg, msg, -)). | 
					
						
							|  |  |  | pce_goal(get_object(_,_,_), get_object(arg, msg, -)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | process_xpce_goal(G, Origin, Src) :- | 
					
						
							|  |  |  | 	pce_goal(G, Process), !, | 
					
						
							|  |  |  | 	assert_called(Src, Origin, G), | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	(   arg(I, Process, How), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	    arg(I, G, Term), | 
					
						
							|  |  |  | 	    process_xpce_arg(How, Term, Origin, Src), | 
					
						
							|  |  |  | 	    fail | 
					
						
							|  |  |  | 	;   true | 
					
						
							|  |  |  | 	). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | process_xpce_arg(new, Term, Origin, Src) :- | 
					
						
							|  |  |  | 	callable(Term), | 
					
						
							|  |  |  | 	process_new(Term, Origin, Src). | 
					
						
							|  |  |  | process_xpce_arg(arg, Term, Origin, Src) :- | 
					
						
							|  |  |  | 	compound(Term), | 
					
						
							|  |  |  | 	process_new(Term, Origin, Src). | 
					
						
							|  |  |  | process_xpce_arg(msg, Term, Origin, Src) :- | 
					
						
							|  |  |  | 	compound(Term), | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	(   arg(_, Term, Arg), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	    process_xpce_arg(arg, Arg, Origin, Src), | 
					
						
							|  |  |  | 	    fail | 
					
						
							|  |  |  | 	;   true | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | process_new(_M:_Term, _, _) :- !.	% TBD: Calls on other modules! | 
					
						
							|  |  |  | process_new(Term, Origin, Src) :- | 
					
						
							|  |  |  | 	assert_new(Src, Origin, Term), | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	(   arg(_, Term, Arg), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	    process_xpce_arg(arg, Arg, Origin, Src), | 
					
						
							|  |  |  | 	    fail | 
					
						
							|  |  |  | 	;   true | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | assert_new(_, _, Term) :- | 
					
						
							|  |  |  | 	\+ callable(Term), !. | 
					
						
							|  |  |  | assert_new(Src, Origin, Control) :- | 
					
						
							|  |  |  | 	functor(Control, Class, _), | 
					
						
							|  |  |  | 	pce_control_class(Class), !, | 
					
						
							|  |  |  | 	forall(arg(_, Control, Arg), | 
					
						
							|  |  |  | 	       assert_new(Src, Origin, Arg)). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | assert_new(Src, Origin, Term) :- | 
					
						
							|  |  |  | 	compound(Term), | 
					
						
							|  |  |  | 	arg(1, Term, Prolog), | 
					
						
							|  |  |  | 	Prolog == @(prolog), | 
					
						
							|  |  |  | 	(   Term =.. [message, _, Selector | T], | 
					
						
							|  |  |  | 	    atom(Selector) | 
					
						
							|  |  |  | 	->  Called =.. [Selector|T], | 
					
						
							|  |  |  | 	    process_body(Called, Origin, Src) | 
					
						
							|  |  |  | 	;   Term =.. [?, _, Selector | T], | 
					
						
							|  |  |  | 	    atom(Selector) | 
					
						
							|  |  |  | 	->  append(T, [_R], T2), | 
					
						
							|  |  |  | 	    Called =.. [Selector|T2], | 
					
						
							|  |  |  | 	    process_body(Called, Origin, Src) | 
					
						
							|  |  |  | 	), | 
					
						
							|  |  |  | 	fail. | 
					
						
							|  |  |  | assert_new(_, _, @(_)) :- !. | 
					
						
							|  |  |  | assert_new(Src, _, Term) :- | 
					
						
							|  |  |  | 	functor(Term, Name, _), | 
					
						
							|  |  |  | 	assert_used_class(Src, Name). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | pce_control_class(and). | 
					
						
							|  |  |  | pce_control_class(or). | 
					
						
							|  |  |  | pce_control_class(if). | 
					
						
							|  |  |  | pce_control_class(not). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 		/******************************** | 
					
						
							|  |  |  | 		*       INCLUDED MODULES	* | 
					
						
							|  |  |  | 		********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | %%	process_use_module(+Modules, +Src, +Rexport) is det. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | process_use_module(_Module:_Files, _, _) :- !.	% loaded in another module | 
					
						
							|  |  |  | process_use_module([], _, _) :- !. | 
					
						
							|  |  |  | process_use_module([H|T], Src, Reexport) :- !, | 
					
						
							|  |  |  | 	process_use_module(H, Src, Reexport), | 
					
						
							|  |  |  | 	process_use_module(T, Src, Reexport). | 
					
						
							|  |  |  | process_use_module(library(pce), Src, Reexport) :- !,	% bit special | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	xref_public_list(library(pce), Path, Public, Src), | 
					
						
							|  |  |  | 	forall(member(Import, Public), | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	       process_pce_import(Import, Src, Path, Reexport)). | 
					
						
							|  |  |  | process_use_module(File, Src, Reexport) :- | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	(   catch(xref_public_list(File, Path, Public, Src), _, fail) | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	->  assert_import(Src, Public, _, Path, Reexport), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	    (	File = library(chr)	% hacky | 
					
						
							|  |  |  | 	    ->	assert(mode(chr, Src)) | 
					
						
							|  |  |  | 	    ;	true | 
					
						
							|  |  |  | 	    ) | 
					
						
							|  |  |  | 	;   true | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | process_pce_import(Name/Arity, Src, Path, Reexport) :- | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	atom(Name), | 
					
						
							|  |  |  | 	integer(Arity), !, | 
					
						
							|  |  |  | 	functor(Term, Name, Arity), | 
					
						
							|  |  |  | 	(   \+ system_predicate(Term), | 
					
						
							|  |  |  | 	    \+ Term = pce_error(_) 	% hack!? | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	->  assert_import(Src, [Name/Arity], _, Path, Reexport) | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	;   true | 
					
						
							|  |  |  | 	). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | process_pce_import(op(P,T,N), Src, _, _) :- | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	xref_push_op(Src, P, T, N). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	xref_public_list(+File, -Path, -Public, +Src) | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							|  |  |  | %	Find File as  referenced  from  Src.   Unify  Path  with  the an | 
					
						
							|  |  |  | %	absolute path to the  referenced  source   and  Public  with the | 
					
						
							|  |  |  | %	export list of that (module) file.   Exports are produced by the | 
					
						
							|  |  |  | %	:- module/2 directive and all subsequent :- reexport directives. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | xref_public_list(File, Path, Public, Src) :- | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	xref_public_list(File, Path, Src, Public, []). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_public_list(File, Path, Src, Public, Rest) :- | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	xref_source_file(File, Path, Src), | 
					
						
							|  |  |  | 	prolog_open_source(Path, Fd),		% skips possible #! line | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	call_cleanup(read_public(Fd, Src, Public, Rest), | 
					
						
							|  |  |  | 		     prolog_close_source(Fd)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | read_public(In, File, Public, Rest) :- | 
					
						
							|  |  |  | 	read(In, (:- module(_, Export))), | 
					
						
							|  |  |  | 	append(Export, Reexport, Public), | 
					
						
							|  |  |  | 	read(In, ReexportDecl), | 
					
						
							|  |  |  | 	read_reexport(ReexportDecl, In, File, Reexport, Rest). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | read_reexport((:- reexport(Spec)), In, File, Reexport, Rest) :- !, | 
					
						
							|  |  |  | 	reexport_files(Spec, File, Reexport, Rest0), | 
					
						
							|  |  |  | 	read(In, ReexportDecl), | 
					
						
							|  |  |  | 	read_reexport(ReexportDecl, In, File, Rest0, Rest). | 
					
						
							|  |  |  | read_reexport((:- reexport(Spec, Import)), In, File, Reexport, Rest) :- !, | 
					
						
							|  |  |  | 	public_from_import(Import, Spec, File, Reexport, Rest0), | 
					
						
							|  |  |  | 	read(In, ReexportDecl), | 
					
						
							|  |  |  | 	read_reexport(ReexportDecl, In, File, Rest0, Rest). | 
					
						
							|  |  |  | read_reexport(_, _, _, Rest, Rest). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | reexport_files([], _, Public, Public) :- !. | 
					
						
							|  |  |  | reexport_files([H|T], Src, Public, Rest) :- !, | 
					
						
							|  |  |  | 	xref_public_list(H, _, Src, Public, Rest0), | 
					
						
							|  |  |  | 	reexport_files(T, Src, Rest0, Rest). | 
					
						
							|  |  |  | reexport_files(Spec, Src, Public, Rest) :- | 
					
						
							|  |  |  | 	xref_public_list(Spec, Src, Public, Rest). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public_from_import(except(Map), File, Src, Export, Rest) :- !, | 
					
						
							|  |  |  | 	xref_public_list(File, _, Public, Src), | 
					
						
							|  |  |  | 	except(Map, Public, Export, Rest). | 
					
						
							|  |  |  | public_from_import(Import, _, _, Export, Rest) :- | 
					
						
							|  |  |  | 	import_name_map(Import, Export, Rest). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | except([], Public, Export, Rest) :- | 
					
						
							|  |  |  | 	append(Public, Rest, Export). | 
					
						
							|  |  |  | except([PI0 as NewName|Map], Public, Export, Rest) :- !, | 
					
						
							|  |  |  | 	canonical_pi(PI0, PI), | 
					
						
							|  |  |  | 	map_as(Public, PI, NewName, Public2), | 
					
						
							|  |  |  | 	except(Map, Public2, Export, Rest). | 
					
						
							|  |  |  | except([PI0|Map], Public, Export, Rest) :- | 
					
						
							|  |  |  | 	canonical_pi(PI0, PI), | 
					
						
							|  |  |  | 	select(PI2, Public, Public2), | 
					
						
							|  |  |  | 	same_pi(PI, PI2), !, | 
					
						
							|  |  |  | 	except(Map, Public2, Export, Rest). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | map_as([PI|T], Repl, As, [PI2|T])  :- | 
					
						
							|  |  |  | 	same_pi(Repl, PI), !, | 
					
						
							|  |  |  | 	pi_as(PI, As, PI2). | 
					
						
							|  |  |  | map_as([H|T0], Repl, As, [H|T])  :- | 
					
						
							|  |  |  | 	map_as(T0, Repl, As, T). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | pi_as(_/Arity, Name, Name/Arity). | 
					
						
							|  |  |  | pi_as(_//Arity, Name, Name//Arity). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import_name_map([], L, L). | 
					
						
							|  |  |  | import_name_map([_/Arity as NewName|T0], [NewName/Arity|T], Tail) :- !, | 
					
						
							|  |  |  | 	import_name_map(T0, T, Tail). | 
					
						
							|  |  |  | import_name_map([_//Arity as NewName|T0], [NewName//Arity|T], Tail) :- !, | 
					
						
							|  |  |  | 	import_name_map(T0, T, Tail). | 
					
						
							|  |  |  | import_name_map([H|T0], [H|T], Tail) :- | 
					
						
							|  |  |  | 	import_name_map(T0, T, Tail). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | canonical_pi(Name//Arity0, PI) :- | 
					
						
							|  |  |  | 	integer(Arity0), !, | 
					
						
							|  |  |  | 	PI = Name/Arity, | 
					
						
							|  |  |  | 	Arity is Arity0 + 2. | 
					
						
							|  |  |  | canonical_pi(PI, PI). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | same_pi(Canonical, PI2) :- | 
					
						
							|  |  |  | 	canonical_pi(PI2, Canonical). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		 /******************************* | 
					
						
							|  |  |  | 		 *	       INCLUDE		* | 
					
						
							|  |  |  | 		 *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | process_include([], _) :- !. | 
					
						
							|  |  |  | process_include([H|T], Src) :- !, | 
					
						
							|  |  |  | 	process_include(H, Src), | 
					
						
							|  |  |  | 	process_include(T, Src). | 
					
						
							|  |  |  | process_include(File, Src) :- | 
					
						
							|  |  |  | 	catch(read_src_to_terms(File, Src, Terms), _, fail), !, | 
					
						
							|  |  |  | 	process_terms(Terms, Src). | 
					
						
							|  |  |  | process_include(_, _). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | process_terms([], _). | 
					
						
							|  |  |  | process_terms([H|T], Src) :- | 
					
						
							|  |  |  | 	process(H, Src), | 
					
						
							|  |  |  | 	process_terms(T, Src). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | read_src_to_terms(File, Src, Terms) :- | 
					
						
							|  |  |  | 	xref_source_file(File, Path, Src), | 
					
						
							|  |  |  | 	prolog_open_source(Path, Fd), | 
					
						
							|  |  |  | 	call_cleanup(read_clauses(Fd, Terms), | 
					
						
							|  |  |  | 		     prolog_close_source(Fd)). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | read_clauses(In, Terms) :- | 
					
						
							|  |  |  | 	read_clause(In, C0), | 
					
						
							|  |  |  | 	read_clauses(C0, In, Terms). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | read_clauses(end_of_file, _, []) :- !. | 
					
						
							|  |  |  | read_clauses(Term, In, [Term|T]) :- | 
					
						
							|  |  |  | 	read_clause(In, C), | 
					
						
							|  |  |  | 	read_clauses(C, In, T). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	process_foreign(+Spec, +Src) | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Process a load_foreign_library/1 call. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | process_foreign(Spec, Src) :- | 
					
						
							|  |  |  | 	current_foreign_library(Spec, Defined), | 
					
						
							|  |  |  | 	(   xmodule(Module, Src) | 
					
						
							|  |  |  | 	->  true | 
					
						
							|  |  |  | 	;   Module = user | 
					
						
							|  |  |  | 	), | 
					
						
							|  |  |  | 	process_foreign_defined(Defined, Module, Src). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | process_foreign_defined([], _, _). | 
					
						
							|  |  |  | process_foreign_defined([H|T], M, Src) :- | 
					
						
							|  |  |  | 	(   H = M:Head | 
					
						
							|  |  |  | 	->  assert_foreign(Src, Head) | 
					
						
							|  |  |  | 	;   assert_foreign(Src, H) | 
					
						
							|  |  |  | 	), | 
					
						
							|  |  |  | 	process_foreign_defined(T, M, Src). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		 /******************************* | 
					
						
							|  |  |  | 		 *	    CHR SUPPORT		* | 
					
						
							|  |  |  | 		 *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
					
						
							|  |  |  | This part of the file supports CHR. Our choice is between making special | 
					
						
							|  |  |  | hooks to make CHR expansion work and  then handle the (complex) expanded | 
					
						
							|  |  |  | code or process the  CHR  source   directly.  The  latter looks simpler, | 
					
						
							|  |  |  | though I don't like the idea  of   adding  support for libraries to this | 
					
						
							|  |  |  | module.  A  file  is  supposed  to  be  a    CHR   file  if  it  uses  a | 
					
						
							|  |  |  | use_module(library(chr) or contains a :-   constraint/1 directive. As an | 
					
						
							|  |  |  | extra bonus we get the source-locations right :-) | 
					
						
							|  |  |  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | chr_expandable((:- constraints(_))). | 
					
						
							|  |  |  | chr_expandable((constraints(_))). | 
					
						
							|  |  |  | chr_expandable((handler(_))) :- | 
					
						
							|  |  |  | 	is_chr_file. | 
					
						
							|  |  |  | chr_expandable((rules(_))) :- | 
					
						
							|  |  |  | 	is_chr_file. | 
					
						
							|  |  |  | chr_expandable(<=>(_, _)) :- | 
					
						
							|  |  |  | 	is_chr_file. | 
					
						
							|  |  |  | chr_expandable(@(_, _)) :- | 
					
						
							|  |  |  | 	is_chr_file. | 
					
						
							|  |  |  | chr_expandable(==>(_, _)) :- | 
					
						
							|  |  |  | 	is_chr_file. | 
					
						
							|  |  |  | chr_expandable(pragma(_, _)) :- | 
					
						
							|  |  |  | 	is_chr_file. | 
					
						
							|  |  |  | chr_expandable(option(_, _)) :- | 
					
						
							|  |  |  | 	is_chr_file. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | is_chr_file :- | 
					
						
							|  |  |  | 	source(Src, _), | 
					
						
							|  |  |  | 	mode(chr, Src), !. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | process_chr(@(_Name, Rule), Src) :- | 
					
						
							|  |  |  | 	process_chr(Rule, Src). | 
					
						
							|  |  |  | process_chr(pragma(Rule, _Pragma), Src) :- | 
					
						
							|  |  |  | 	process_chr(Rule, Src). | 
					
						
							|  |  |  | process_chr(<=>(Head, Body), Src) :- | 
					
						
							|  |  |  | 	chr_head(Head, Src, H), | 
					
						
							|  |  |  | 	chr_body(Body, H, Src). | 
					
						
							|  |  |  | process_chr(==>(Head, Body), Src) :- | 
					
						
							|  |  |  | 	chr_head(Head, H, Src), | 
					
						
							|  |  |  | 	chr_body(Body, H, Src). | 
					
						
							|  |  |  | process_chr((:- constraints(C)), Src) :- | 
					
						
							|  |  |  | 	process_chr(constraints(C), Src). | 
					
						
							|  |  |  | process_chr(constraints(_), Src) :- | 
					
						
							|  |  |  | 	(   mode(chr, Src) | 
					
						
							|  |  |  | 	->  true | 
					
						
							|  |  |  | 	;   assert(mode(chr, Src)) | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | chr_head(X, _, _) :- | 
					
						
							|  |  |  | 	var(X), !.			% Illegal.  Warn? | 
					
						
							|  |  |  | chr_head(\(A,B), Src, H) :- | 
					
						
							|  |  |  | 	chr_head(A, Src, H), | 
					
						
							|  |  |  | 	process_body(B, H, Src). | 
					
						
							|  |  |  | chr_head((H0,B), Src, H) :- | 
					
						
							|  |  |  | 	chr_defined(H0, Src, H), | 
					
						
							|  |  |  | 	process_body(B, H, Src). | 
					
						
							|  |  |  | chr_head(H0, Src, H) :- | 
					
						
							|  |  |  | 	chr_defined(H0, Src, H). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | chr_defined(X, _, _) :- | 
					
						
							|  |  |  | 	var(X), !. | 
					
						
							|  |  |  | chr_defined(#(C,_Id), Src, C) :- !, | 
					
						
							|  |  |  | 	assert_constraint(Src, C). | 
					
						
							|  |  |  | chr_defined(A, Src, A) :- | 
					
						
							|  |  |  | 	assert_constraint(Src, A). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | chr_body(X, From, Src) :- | 
					
						
							|  |  |  | 	var(X), !, | 
					
						
							|  |  |  | 	process_body(X, From, Src). | 
					
						
							|  |  |  | chr_body('|'(Guard, Goals), H, Src) :- !, | 
					
						
							|  |  |  | 	chr_body(Guard, H, Src), | 
					
						
							|  |  |  | 	chr_body(Goals, H, Src). | 
					
						
							|  |  |  | chr_body(G, From, Src) :- | 
					
						
							|  |  |  | 	process_body(G, From, Src). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | assert_constraint(_, Head) :- | 
					
						
							|  |  |  | 	var(Head), !. | 
					
						
							|  |  |  | assert_constraint(Src, Head) :- | 
					
						
							|  |  |  | 	constraint(Head, Src, _), !. | 
					
						
							|  |  |  | assert_constraint(Src, Head) :- | 
					
						
							|  |  |  | 	functor(Head, Name, Arity), | 
					
						
							|  |  |  | 	functor(Term, Name, Arity), | 
					
						
							|  |  |  | 	flag(xref_src_line, Line, Line), | 
					
						
							|  |  |  | 	assert(constraint(Term, Src, Line)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/******************************** | 
					
						
							|  |  |  | 		*       PHASE 1 ASSERTIONS	* | 
					
						
							|  |  |  | 		********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	assert_called(+Src, +From, +Head) | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	Assert the fact that Head is called by From in Src. We do not | 
					
						
							|  |  |  | %	assert called system predicates. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | assert_called(_, _, Var) :- | 
					
						
							|  |  |  | 	var(Var), !. | 
					
						
							|  |  |  | assert_called(Src, From, Goal) :- | 
					
						
							|  |  |  | 	var(From), !, | 
					
						
							|  |  |  | 	assert_called(Src, '<unknown>', Goal). | 
					
						
							|  |  |  | assert_called(_, _, Goal) :- | 
					
						
							|  |  |  | 	hide_called(Goal), !. | 
					
						
							|  |  |  | assert_called(Src, Origin, M:G) :- !, | 
					
						
							|  |  |  | 	(   atom(M), | 
					
						
							|  |  |  | 	    callable(G) | 
					
						
							|  |  |  | 	->  (   xmodule(M, Src) | 
					
						
							|  |  |  | 	    ->  assert_called(Src, Origin, G) | 
					
						
							|  |  |  | 	    ;   called(M:G, Src, Origin) | 
					
						
							|  |  |  | 	    ->  true | 
					
						
							|  |  |  | 	    ;   generalise(Origin, OTerm), | 
					
						
							|  |  |  | 		generalise(G, GTerm), | 
					
						
							|  |  |  | 		assert(called(M:GTerm, Src, OTerm)) | 
					
						
							|  |  |  | 	    ) | 
					
						
							|  |  |  | 	;   true                        % call to variable module | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | assert_called(_, _, Goal) :- | 
					
						
							|  |  |  | 	system_predicate(Goal), !. | 
					
						
							|  |  |  | assert_called(Src, Origin, Goal) :- | 
					
						
							|  |  |  | 	called(Goal, Src, Origin), !. | 
					
						
							|  |  |  | assert_called(Src, Origin, Goal) :- | 
					
						
							|  |  |  | 	generalise(Origin, OTerm), | 
					
						
							|  |  |  | 	generalise(Goal, Term), | 
					
						
							|  |  |  | 	assert(called(Term, Src, OTerm)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	hide_called(:Callable) | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Goals that should not turn up as being called. Hack. Eventually | 
					
						
							|  |  |  | %	we should deal with that using an XPCE plugin. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hide_called(pce_principal:send_implementation(_, _, _)). | 
					
						
							|  |  |  | hide_called(pce_principal:get_implementation(_, _, _, _)). | 
					
						
							|  |  |  | hide_called(pce_principal:pce_lazy_get_method(_,_,_)). | 
					
						
							|  |  |  | hide_called(pce_principal:pce_lazy_send_method(_,_,_)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | assert_defined(Src, Goal) :- | 
					
						
							|  |  |  | 	defined(Goal, Src, _), !. | 
					
						
							|  |  |  | assert_defined(Src, Goal) :- | 
					
						
							|  |  |  | 	generalise(Goal, Term), | 
					
						
							|  |  |  | 	flag(xref_src_line, Line, Line), | 
					
						
							|  |  |  | 	assert(defined(Term, Src, Line)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | assert_foreign(Src, Goal) :- | 
					
						
							|  |  |  | 	foreign(Goal, Src, _), !. | 
					
						
							|  |  |  | assert_foreign(Src, Goal) :- | 
					
						
							|  |  |  | 	generalise(Goal, Term), | 
					
						
							|  |  |  | 	flag(xref_src_line, Line, Line), | 
					
						
							|  |  |  | 	assert(foreign(Term, Src, Line)). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | %%	assert_import(+Src, +Import, +PublicList, +From, +Reexport) is det. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	Asserts imports into Src. Import   is  the import specification, | 
					
						
							|  |  |  | %	PublicList is the list of known  public predicates or unbound if | 
					
						
							|  |  |  | %	this need not be checked and  From   is  the file from which the | 
					
						
							|  |  |  | %	public predicates come. If  Reexport   is  =true=, re-export the | 
					
						
							|  |  |  | %	imported predicates. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	@tbd	Tighter type-checking on Import. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | assert_import(_, [], _, _, _) :- !. | 
					
						
							|  |  |  | assert_import(Src, [H|T], Public, From, Reexport) :- !, | 
					
						
							|  |  |  | 	assert_import(Src, H, Public, From, Reexport), | 
					
						
							|  |  |  | 	assert_import(Src, T, Public, From, Reexport). | 
					
						
							|  |  |  | assert_import(Src, except(Except), Public, From, Reexport) :- !, | 
					
						
							|  |  |  | 	is_list(Public), !, | 
					
						
							|  |  |  | 	except(Except, Public, Import, []), | 
					
						
							|  |  |  | 	assert_import(Src, Import, _All, From, Reexport). | 
					
						
							|  |  |  | assert_import(Src, Import as Name, Public, From, Reexport) :- !, | 
					
						
							|  |  |  | 	pi_to_head(Import, Term0), | 
					
						
							|  |  |  | 	functor(Term0, _OldName, Arity), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	functor(Term, Name, Arity), | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	(   in_public_list(Term0, Public) | 
					
						
							|  |  |  | 	->  assert(imported(Term, Src, From)), | 
					
						
							|  |  |  | 	    assert_reexport(Reexport, Src, Term) | 
					
						
							|  |  |  | 	;   flag(xref_src_line, Line, Line), | 
					
						
							|  |  |  | 	    assert_called(Src, '<directive>'(Line), Term0) | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | assert_import(Src, Import, Public, From, Reexport) :- | 
					
						
							|  |  |  | 	pi_to_head(Import, Term), !, | 
					
						
							|  |  |  | 	(   in_public_list(Term, Public) | 
					
						
							|  |  |  | 	->  assert(imported(Term, Src, From)), | 
					
						
							|  |  |  | 	    assert_reexport(Reexport, Src, Term) | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	;   flag(xref_src_line, Line, Line), | 
					
						
							|  |  |  | 	    assert_called(Src, '<directive>'(Line), Term) | 
					
						
							|  |  |  | 	). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | assert_import(Src, op(P,T,N), _, _, _) :- | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	xref_push_op(Src, P,T,N). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | in_public_list(_Head, Public) :- | 
					
						
							|  |  |  | 	var(Public), !. | 
					
						
							|  |  |  | in_public_list(Head, Public) :- | 
					
						
							|  |  |  | 	member(Export, Public), | 
					
						
							|  |  |  | 	pi_to_head(Export, Head). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | assert_reexport(false, _, _) :- !. | 
					
						
							|  |  |  | assert_reexport(true, Src, Term) :- | 
					
						
							|  |  |  | 	assert(exported(Term, Src)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %%	assert_op(+Src, +Op) is det. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	@param Op	Ground term op(Priority, Type, Name). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | assert_op(Src, op(P,T,_:N)) :- | 
					
						
							|  |  |  | 	(   xop(Src, op(P,T,N)) | 
					
						
							|  |  |  | 	->  true | 
					
						
							|  |  |  | 	;   assert(xop(Src, op(P,T,N))) | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	assert_module(+Src, +Module) | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Assert we are loading code into Module.  This is also used to | 
					
						
							|  |  |  | %	exploit local term-expansion and other rules. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | assert_module(Src, Module) :- | 
					
						
							|  |  |  | 	xmodule(Module, Src), !. | 
					
						
							|  |  |  | assert_module(Src, Module) :- | 
					
						
							|  |  |  | 	'$set_source_module'(_, Module), | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	assert(xmodule(Module, Src)). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | assert_export(_, []) :- !. | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | assert_export(Src, [H|T]) :- !, | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	assert_export(Src, H), | 
					
						
							|  |  |  | 	assert_export(Src, T). | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | assert_export(Src, PI) :- | 
					
						
							|  |  |  | 	pi_to_head(PI, Term), !, | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	assert(exported(Term, Src)). | 
					
						
							|  |  |  | assert_export(Src, op(P, A, N)) :- | 
					
						
							|  |  |  | 	xref_push_op(Src, P, A, N). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | assert_dynamic(Src, (A, B)) :- !, | 
					
						
							|  |  |  | 	assert_dynamic(Src, A), | 
					
						
							|  |  |  | 	assert_dynamic(Src, B). | 
					
						
							|  |  |  | assert_dynamic(_, _M:_Name/_Arity) :- !. % not local | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | assert_dynamic(Src, PI) :- | 
					
						
							|  |  |  | 	pi_to_head(PI, Term), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	(   thread_local(Term, Src, _)	% dynamic after thread_local has | 
					
						
							|  |  |  | 	->  true			% no effect | 
					
						
							|  |  |  | 	;   flag(xref_src_line, Line, Line), | 
					
						
							|  |  |  | 	    assert(dynamic(Term, Src, Line)) | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | assert_thread_local(Src, (A, B)) :- !, | 
					
						
							|  |  |  | 	assert_thread_local(Src, A), | 
					
						
							|  |  |  | 	assert_thread_local(Src, B). | 
					
						
							|  |  |  | assert_thread_local(_, _M:_Name/_Arity) :- !. % not local | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | assert_thread_local(Src, PI) :- | 
					
						
							|  |  |  | 	pi_to_head(PI, Term), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	flag(xref_src_line, Line, Line), | 
					
						
							|  |  |  | 	assert(thread_local(Term, Src, Line)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | assert_multifile(Src, (A, B)) :- !, | 
					
						
							|  |  |  | 	assert_multifile(Src, A), | 
					
						
							|  |  |  | 	assert_multifile(Src, B). | 
					
						
							|  |  |  | assert_multifile(_, _M:_Name/_Arity) :- !. % not local | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | assert_multifile(Src, PI) :- | 
					
						
							|  |  |  | 	pi_to_head(PI, Term), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	flag(xref_src_line, Line, Line), | 
					
						
							|  |  |  | 	assert(multifile(Term, Src, Line)). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | %%	pi_to_head(+PI, -Head) is semidet. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	Translate Name/Arity or Name//Arity to a callable term. Fails if | 
					
						
							|  |  |  | %	PI is not a predicate indicator. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | pi_to_head(Var, _) :- | 
					
						
							|  |  |  | 	var(Var), !, fail. | 
					
						
							|  |  |  | pi_to_head(Name/Arity, Term) :- | 
					
						
							|  |  |  | 	functor(Term, Name, Arity). | 
					
						
							|  |  |  | pi_to_head(Name//DCGArity, Term) :- | 
					
						
							|  |  |  | 	Arity is DCGArity+2, | 
					
						
							|  |  |  | 	functor(Term, Name, Arity). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | assert_used_class(Src, Name) :- | 
					
						
							|  |  |  | 	used_class(Name, Src), !. | 
					
						
							|  |  |  | assert_used_class(Src, Name) :- | 
					
						
							|  |  |  | 	assert(used_class(Name, Src)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | assert_defined_class(Src, Name, _Meta, _Super, _) :- | 
					
						
							|  |  |  | 	defined_class(Name, _, _, Src, _), !. | 
					
						
							|  |  |  | assert_defined_class(_, _, _, -, _) :- !. 		% :- pce_extend_class | 
					
						
							|  |  |  | assert_defined_class(Src, Name, Meta, Super, Summary) :- | 
					
						
							|  |  |  | 	flag(xref_src_line, Line, Line), | 
					
						
							|  |  |  | 	(   Summary == @(default) | 
					
						
							|  |  |  | 	->  Atom = '' | 
					
						
							|  |  |  | 	;   is_list(Summary) | 
					
						
							|  |  |  | 	->  atom_codes(Atom, Summary) | 
					
						
							|  |  |  | 	;   string(Summary) | 
					
						
							|  |  |  | 	->  atom_concat(Summary, '', Atom) | 
					
						
							|  |  |  | 	), | 
					
						
							|  |  |  | 	assert(defined_class(Name, Super, Atom, Src, Line)), | 
					
						
							|  |  |  | 	(   Meta = @(_) | 
					
						
							|  |  |  | 	->  true | 
					
						
							|  |  |  | 	;   assert_used_class(Src, Meta) | 
					
						
							|  |  |  | 	), | 
					
						
							|  |  |  | 	assert_used_class(Src, Super). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | assert_defined_class(Src, Name, imported_from(_File)) :- | 
					
						
							|  |  |  | 	defined_class(Name, _, _, Src, _), !. | 
					
						
							|  |  |  | assert_defined_class(Src, Name, imported_from(File)) :- | 
					
						
							|  |  |  | 	assert(defined_class(Name, _, '', Src, file(File))). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/******************************** | 
					
						
							|  |  |  | 		*            UTILITIES		* | 
					
						
							|  |  |  | 		********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	generalise(+Callable, -General) | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Generalise a callable term. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | generalise(Var, Var) :- | 
					
						
							|  |  |  | 	var(Var), !.			% error? | 
					
						
							|  |  |  | generalise(pce_principal:send_implementation(Id, _, _), | 
					
						
							|  |  |  | 	   pce_principal:send_implementation(Id, _, _)) :- | 
					
						
							|  |  |  | 	atom(Id), !. | 
					
						
							|  |  |  | generalise(pce_principal:get_implementation(Id, _, _, _), | 
					
						
							|  |  |  | 	   pce_principal:get_implementation(Id, _, _, _)) :- | 
					
						
							|  |  |  | 	atom(Id), !. | 
					
						
							|  |  |  | generalise('<directive>'(Line), '<directive>'(Line)) :- !. | 
					
						
							|  |  |  | generalise(Module:Goal0, Module:Goal) :- | 
					
						
							|  |  |  | 	atom(Module), !, | 
					
						
							|  |  |  | 	generalise(Goal0, Goal). | 
					
						
							|  |  |  | generalise(Term0, Term) :- | 
					
						
							|  |  |  | 	callable(Term0), | 
					
						
							|  |  |  | 	functor(Term0, Name, Arity), | 
					
						
							|  |  |  | 	functor(Term, Name, Arity). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		 /******************************* | 
					
						
							|  |  |  | 		 *	SOURCE MANAGEMENT	* | 
					
						
							|  |  |  | 		 *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
					
						
							|  |  |  | This section of the file contains   hookable  predicates to reason about | 
					
						
							|  |  |  | sources. The built-in code here  can  only   deal  with  files. The XPCE | 
					
						
							|  |  |  | library(pce_prolog_xref) provides hooks to deal with XPCE objects, so we | 
					
						
							|  |  |  | can do cross-referencing on PceEmacs edit   buffers.  Other examples for | 
					
						
							|  |  |  | hooking can be databases, (HTTP) URIs, etc. | 
					
						
							|  |  |  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :- multifile | 
					
						
							|  |  |  | 	prolog:xref_source_directory/2.		% +Source, -Dir | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	xref_source_file(+Spec, -File, +Src) is semidet. | 
					
						
							|  |  |  | %%	xref_source_file(+Spec, -File, +Src, +Options) is semidet. | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Find named source file from Spec, relative to Src. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_source_file(Plain, File, Source) :- | 
					
						
							|  |  |  | 	xref_source_file(Plain, File, Source, []). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | xref_source_file(Plain, File, Source, Options) :- | 
					
						
							|  |  |  | 	atom(Plain), | 
					
						
							|  |  |  | 	\+ is_absolute_file_name(Plain), | 
					
						
							|  |  |  | 	(   prolog:xref_source_directory(Source, Dir) | 
					
						
							|  |  |  | 	->  true | 
					
						
							|  |  |  | 	;   atom(Source), | 
					
						
							|  |  |  | 	    file_directory_name(Source, Dir) | 
					
						
							|  |  |  | 	), | 
					
						
							| 
									
										
										
										
											2010-02-28 22:26:09 +00:00
										 |  |  | 	atomic_list_concat([Dir, /, Plain], Spec), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	do_xref_source_file(Spec, File, Options), !. | 
					
						
							|  |  |  | xref_source_file(Spec, File, _, Options) :- | 
					
						
							|  |  |  | 	do_xref_source_file(Spec, File, Options), !. | 
					
						
							|  |  |  | xref_source_file(Spec, _, _, _) :- | 
					
						
							|  |  |  | 	verbose, | 
					
						
							|  |  |  | 	print_message(warning, error(existence_error(file, Spec), _)), | 
					
						
							|  |  |  | 	fail. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | do_xref_source_file(Spec, File, Options) :- | 
					
						
							|  |  |  | 	option(file_type(Type), Options, prolog), | 
					
						
							|  |  |  | 	absolute_file_name(Spec, | 
					
						
							|  |  |  | 			   [ file_type(Type), | 
					
						
							|  |  |  | 			     access(read), | 
					
						
							|  |  |  | 			     file_errors(fail) | 
					
						
							|  |  |  | 			   ], File), !. | 
					
						
							|  |  |  | 
 |