| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | /*  Part of SWI-Prolog | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Author:        Jan Wielemaker | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  |     E-mail:        J.Wielemaker@vu.nl | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  |     WWW:           http://www.swi-prolog.org | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  |     Copyright (C): 1985-2012, University of Amsterdam | 
					
						
							|  |  |  | 			      VU University Amsterdam | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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 | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  |     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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_debug, | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | 	  [ debug/3,			% +Topic, +Format, :Args | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	    debug/1,			% +Topic | 
					
						
							|  |  |  | 	    nodebug/1,			% +Topic | 
					
						
							|  |  |  | 	    debugging/1,		% ?Topic | 
					
						
							|  |  |  | 	    debugging/2,		% ?Topic, ?Bool | 
					
						
							|  |  |  | 	    list_debug_topics/0, | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | 	    debug_message_context/1,	% (+|-)What | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	    assertion/1			% :Goal | 
					
						
							|  |  |  | 	  ]). | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | :- use_module(library(error)). | 
					
						
							|  |  |  | :- use_module(library(lists)). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | :- set_prolog_flag(generate_debug_info, false). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | :- meta_predicate | 
					
						
							|  |  |  | 	assertion(0), | 
					
						
							|  |  |  | 	debug(+,+,:). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :- multifile prolog:assertion_failed/2. | 
					
						
							|  |  |  | :- dynamic   prolog:assertion_failed/2. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*:- use_module(library(prolog_stack)).*/ % We use the autoloader if needed | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | :- if(current_prolog_flag(dialect, yap)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :- use_module(library(hacks), [stack_dump/1]). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % this is as good as I can do.  | 
					
						
							|  |  |  | backtrace(N) :- | 
					
						
							|  |  |  | 	stack_dump(N). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :- endif. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | %:- set_prolog_flag(generate_debug_info, false). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | :- dynamic | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | 	debugging/3,			% Topic, Enabled, To | 
					
						
							|  |  |  | 	debug_context/1. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | debug_context(thread). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** <module> Print debug messages and test assertions | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | This library is a replacement for  format/3 for printing debug messages. | 
					
						
							|  |  |  | Messages are assigned a _topic_. By   dynamically  enabling or disabling | 
					
						
							|  |  |  | topics the user can  select  desired   messages.  Debug  statements  are | 
					
						
							|  |  |  | removed when the code is compiled for optimization. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | See manual for details. With XPCE, you can use the call below to start a | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | graphical monitoring tool. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | == | 
					
						
							|  |  |  | ?- prolog_ide(debug_monitor). | 
					
						
							|  |  |  | == | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Using the predicate assertion/1 you  can   make  assumptions  about your | 
					
						
							|  |  |  | program explicit, trapping the debugger if the condition does not hold. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @author	Jan Wielemaker | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	debugging(+Topic) is semidet. | 
					
						
							|  |  |  | %%	debugging(-Topic) is nondet. | 
					
						
							|  |  |  | %%	debugging(?Topic, ?Bool) is nondet. | 
					
						
							|  |  |  | % | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | %	Examine debug topics. The form debugging(+Topic)  may be used to | 
					
						
							|  |  |  | %	perform more complex debugging tasks.   A typical usage skeleton | 
					
						
							|  |  |  | %	is: | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	  == | 
					
						
							|  |  |  | %		(   debugging(mytopic) | 
					
						
							|  |  |  | %		->  <perform debugging actions> | 
					
						
							|  |  |  | %		;   true | 
					
						
							|  |  |  | %		), | 
					
						
							|  |  |  | %		... | 
					
						
							|  |  |  | %	  == | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	The other two calls are intended to examine existing and enabled | 
					
						
							|  |  |  | %	debugging tokens and are typically not used in user programs. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | debugging(Topic) :- | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | 	debugging(Topic, true, _To). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | debugging(Topic, Bool) :- | 
					
						
							|  |  |  | 	debugging(Topic, Bool, _To). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | %%	debug(+Topic) is det. | 
					
						
							|  |  |  | %%	nodebug(+Topic) is det. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	Add/remove a topic from being   printed.  nodebug(_) removes all | 
					
						
							|  |  |  | %	topics. Gives a warning if the topic is not defined unless it is | 
					
						
							|  |  |  | %	used from a directive. The latter allows placing debug topics at | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | %	the start of a (load-)file without warnings. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	For debug/1, Topic can be  a  term   Topic  >  Out, where Out is | 
					
						
							|  |  |  | %	either a stream or  stream-alias  or   a  filename  (atom). This | 
					
						
							|  |  |  | %	redirects debug information on this topic to the given output. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | debug(Topic) :- | 
					
						
							|  |  |  | 	debug(Topic, true). | 
					
						
							|  |  |  | nodebug(Topic) :- | 
					
						
							|  |  |  | 	debug(Topic, false). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | debug(Spec, Val) :- | 
					
						
							|  |  |  | 	debug_target(Spec, Topic, Out), | 
					
						
							|  |  |  | 	(   (   retract(debugging(Topic, Enabled0, To0)) | 
					
						
							|  |  |  | 	    *-> update_debug(Enabled0, To0, Val, Out, Enabled, To), | 
					
						
							|  |  |  | 		assert(debugging(Topic, Enabled, To)), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 		fail | 
					
						
							|  |  |  | 	    ;   (   prolog_load_context(file, _) | 
					
						
							|  |  |  | 		->  true | 
					
						
							|  |  |  | 		;   print_message(warning, debug_no_topic(Topic)) | 
					
						
							|  |  |  | 		), | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | 		update_debug(false, [], Val, Out, Enabled, To), | 
					
						
							|  |  |  | 	        assert(debugging(Topic, Enabled, To)) | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	    ) | 
					
						
							|  |  |  | 	->  true | 
					
						
							|  |  |  | 	;   true | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | debug_target(Spec, Topic, To) :- | 
					
						
							|  |  |  | 	nonvar(Spec), | 
					
						
							|  |  |  | 	Spec = (Topic > To), !. | 
					
						
							|  |  |  | debug_target(Topic, Topic, -). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | update_debug(_, To0, true, -, true, To) :- !, | 
					
						
							|  |  |  | 	ensure_output(To0, To). | 
					
						
							|  |  |  | update_debug(true, To0, true, Out, true, Output) :- !, | 
					
						
							|  |  |  | 	append(To0, [Out], Output). | 
					
						
							|  |  |  | update_debug(false, _, true, Out, true, [Out]) :- !. | 
					
						
							|  |  |  | update_debug(_, _, false, -, false, []) :- !. | 
					
						
							|  |  |  | update_debug(true, [Out], false, Out, false, []) :- !. | 
					
						
							|  |  |  | update_debug(true, To0, false, Out, true, Output) :- !, | 
					
						
							|  |  |  | 	delete(To0, Out, Output). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ensure_output([], [user_error]) :- !. | 
					
						
							|  |  |  | ensure_output(List, List). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | %%	debug_topic(+Topic) is det. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	Declare a topic for debugging.  This can be used to find all | 
					
						
							|  |  |  | %	topics available for debugging. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | debug_topic(Topic) :- | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | 	(   debugging(Registered, _, _), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	    Registered =@= Topic | 
					
						
							|  |  |  | 	->  true | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | 	;   assert(debugging(Topic, false, [])) | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	list_debug_topics is det. | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	List currently known debug topics and their setting. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | list_debug_topics :- | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | 	format(user_error, '~*t~45|~n', "-"), | 
					
						
							|  |  |  | 	format(user_error, '~w~t ~w~35| ~w~n', | 
					
						
							|  |  |  | 	       ['Debug Topic', 'Activated', 'To']), | 
					
						
							|  |  |  | 	format(user_error, '~*t~45|~n', "-"), | 
					
						
							|  |  |  | 	(   debugging(Topic, Value, To), | 
					
						
							|  |  |  | 	    format(user_error, '~w~t ~w~35| ~w~n', [Topic, Value, To]), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	    fail | 
					
						
							|  |  |  | 	;   true | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | %%	debug_message_context(+What) is det. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	Specify additional context for debug messages.   What  is one of | 
					
						
							|  |  |  | %	+Context or -Context, and Context is  one of =thread=, =time= or | 
					
						
							|  |  |  | %	time(Format),  where  Format  is    a  format specification  for | 
					
						
							|  |  |  | %	format_time/3 (default is =|%T.%3f|=).  Initially, debug/3 shows | 
					
						
							|  |  |  | %	only thread information. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | debug_message_context(+Topic) :- !, | 
					
						
							|  |  |  | 	valid_topic(Topic, Del, Add), | 
					
						
							|  |  |  | 	retractall(debug_context(Del)), | 
					
						
							|  |  |  | 	assert(debug_context(Add)). | 
					
						
							|  |  |  | debug_message_context(-Topic) :- !, | 
					
						
							|  |  |  | 	valid_topic(Topic, Del, _), | 
					
						
							|  |  |  | 	retractall(debug_context(Del)). | 
					
						
							|  |  |  | debug_message_context(Term) :- | 
					
						
							|  |  |  | 	type_error(debug_message_context, Term). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | valid_topic(thread, thread, thread) :- !. | 
					
						
							|  |  |  | valid_topic(time, time(_), time('%T.%3f')) :- !. | 
					
						
							|  |  |  | valid_topic(time(Format), time(_), time(Format)) :- !. | 
					
						
							|  |  |  | valid_topic(X, _, _) :- | 
					
						
							|  |  |  | 	domain_error(debug_message_context, X). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	debug(+Topic, +Format, :Args) is det. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | %	Format a message if debug topic  is enabled. Similar to format/3 | 
					
						
							|  |  |  | %	to =user_error=, but only prints if   Topic is activated through | 
					
						
							|  |  |  | %	debug/1. Args is a  meta-argument  to   deal  with  goal for the | 
					
						
							|  |  |  | %	@-command.   Output   is   first    handed     to    the    hook | 
					
						
							|  |  |  | %	prolog:debug_print_hook/3.  If  this  fails,    Format+Args   is | 
					
						
							|  |  |  | %	translated  to  text   using    the   message-translation   (see | 
					
						
							|  |  |  | %	print_message/2) for the  term  debug(Format,   Args)  and  then | 
					
						
							|  |  |  | %	printed to every matching destination   (controlled  by debug/1) | 
					
						
							|  |  |  | %	using print_message_lines/3. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	The message is preceded by '% ' and terminated with a newline. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	@see	format/3. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | debug(Topic, Format, Args) :- | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | 	debugging(Topic, true, To), !, | 
					
						
							|  |  |  | 	print_debug(Topic, To, Format, Args). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | debug(_, _, _). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | %%	prolog:debug_print_hook(+Topic, +Format, +Args) is semidet. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	Hook called by debug/3.  This  hook   is  used  by the graphical | 
					
						
							|  |  |  | %	frontend that can be activated using prolog_ide/1: | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	  == | 
					
						
							|  |  |  | %	  ?- prolog_ide(debug_monitor). | 
					
						
							|  |  |  | %	  == | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | :- multifile | 
					
						
							|  |  |  | 	prolog:debug_print_hook/3. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | print_debug(Topic, _To, Format, Args) :- | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	prolog:debug_print_hook(Topic, Format, Args), !. | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | print_debug(_, [], _, _) :- !. | 
					
						
							|  |  |  | print_debug(Topic, To, Format, Args) :- | 
					
						
							|  |  |  | 	phrase('$messages':translate_message(debug(Format, Args)), Lines), | 
					
						
							|  |  |  | 	(   member(T, To), | 
					
						
							|  |  |  | 	    debug_output(T, Stream), | 
					
						
							|  |  |  | 	    print_message_lines(Stream, kind(debug(Topic)), Lines), | 
					
						
							|  |  |  | 	    fail | 
					
						
							|  |  |  | 	;   true | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | debug_output(user, user_error) :- !. | 
					
						
							|  |  |  | debug_output(Stream, Stream) :- | 
					
						
							|  |  |  | 	is_stream(Stream), !. | 
					
						
							|  |  |  | debug_output(File, Stream) :- | 
					
						
							|  |  |  | 	open(File, append, Stream, | 
					
						
							|  |  |  | 	     [ close_on_abort(false), | 
					
						
							|  |  |  | 	       alias(File), | 
					
						
							|  |  |  | 	       buffer(line) | 
					
						
							|  |  |  | 	     ]). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		 /******************************* | 
					
						
							|  |  |  | 		 *	     ASSERTION		* | 
					
						
							|  |  |  | 		 *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	assertion(:Goal) is det. | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | % | 
					
						
							|  |  |  | %	Acts similar to C assert()  macro.  It   has  no  effect if Goal | 
					
						
							|  |  |  | %	succeeds. If Goal fails or throws    an exception, the following | 
					
						
							|  |  |  | %	steps are taken: | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	  * call prolog:assertion_failed/2.  If prolog:assertion_failed/2 | 
					
						
							|  |  |  | %	    fails, then: | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	    - If this is an interactive toplevel thread, print a | 
					
						
							|  |  |  | %	      message, the stack-trace, and finally trap the debugger. | 
					
						
							|  |  |  | %	    - Otherwise, throw error(assertion_error(Reason, G),_) where | 
					
						
							|  |  |  | %	      Reason is one of =fail= or the exception raised. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | assertion(G) :- | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | 	\+ \+ catch(G, | 
					
						
							|  |  |  | 		    Error, | 
					
						
							|  |  |  | 		    assertion_failed(Error, G)), | 
					
						
							|  |  |  | 	!. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | assertion(G) :- | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | 	assertion_failed(fail, G), | 
					
						
							|  |  |  | 	assertion_failed.		% prevent last call optimization. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | assertion_failed(Reason, G) :- | 
					
						
							|  |  |  | 	prolog:assertion_failed(Reason, G), !. | 
					
						
							|  |  |  | assertion_failed(Reason, G) :- | 
					
						
							|  |  |  | 	print_message(error, assertion_failed(Reason, G)), | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	backtrace(10), | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | 	(   current_prolog_flag(break_level, _)	% interactive thread | 
					
						
							|  |  |  | 	->  trace | 
					
						
							|  |  |  | 	;   throw(error(assertion_error(Reason, G), _)) | 
					
						
							|  |  |  | 	). | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | assertion_failed. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	assume(:Goal) is det. | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	Acts similar to C assert() macro.  It has no effect of Goal | 
					
						
							|  |  |  | %	succeeds.  If Goal fails it prints a message, a stack-trace | 
					
						
							|  |  |  | %	and finally traps the debugger. | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | %	@deprecated	Use assertion/1 in new code. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		 /******************************* | 
					
						
							|  |  |  | 		 *	     EXPANSION		* | 
					
						
							|  |  |  | 		 *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :- multifile | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | 	system:goal_expansion/2. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | system:goal_expansion(debug(Topic,_,_), true) :- | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	(   current_prolog_flag(optimise, true) | 
					
						
							|  |  |  | 	->  true | 
					
						
							|  |  |  | 	;   debug_topic(Topic), | 
					
						
							|  |  |  | 	    fail | 
					
						
							|  |  |  | 	). | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | system:goal_expansion(debugging(Topic), fail) :- | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	(   current_prolog_flag(optimise, true) | 
					
						
							|  |  |  | 	->  true | 
					
						
							|  |  |  | 	;   debug_topic(Topic), | 
					
						
							|  |  |  | 	    fail | 
					
						
							|  |  |  | 	). | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | system:goal_expansion(assertion(_), Goal) :- | 
					
						
							|  |  |  | 	current_prolog_flag(optimise, true), | 
					
						
							|  |  |  | 	Goal = true. | 
					
						
							|  |  |  | system:goal_expansion(assume(_), Goal) :- | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 	print_message(informational, | 
					
						
							|  |  |  | 		      compatibility(renamed(assume/1, assertion/1))), | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | 	current_prolog_flag(optimise, true), | 
					
						
							|  |  |  | 	Goal = true. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		 /******************************* | 
					
						
							|  |  |  | 		 *	      MESSAGES		* | 
					
						
							|  |  |  | 		 *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :- multifile | 
					
						
							|  |  |  | 	prolog:message/3. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | prolog:message(assertion_failed(_, G)) --> | 
					
						
							|  |  |  | 	[ 'Assertion failed: ~q'-[G] ]. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | prolog:message(debug(Fmt, Args)) --> | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | 	show_thread_context, | 
					
						
							|  |  |  | 	show_time_context, | 
					
						
							|  |  |  | 	[ Fmt-Args ]. | 
					
						
							| 
									
										
										
										
											2008-02-12 17:03:59 +00:00
										 |  |  | prolog:message(debug_no_topic(Topic)) --> | 
					
						
							|  |  |  | 	[ '~q: no matching debug topic (yet)'-[Topic] ]. | 
					
						
							| 
									
										
										
										
											2013-01-18 14:31:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | show_thread_context --> | 
					
						
							|  |  |  | 	{ debug_context(thread), | 
					
						
							|  |  |  | 	  thread_self(Me) , | 
					
						
							|  |  |  | 	  Me \== main | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 	[ '[Thread ~w] '-[Me] ]. | 
					
						
							|  |  |  | show_thread_context --> | 
					
						
							|  |  |  | 	[]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | show_time_context --> | 
					
						
							|  |  |  | 	{ debug_context(time(Format)), | 
					
						
							|  |  |  | 	  get_time(Now), | 
					
						
							|  |  |  | 	  format_time(string(S), Format, Now) | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 	[ '[~w] '-[S] ]. | 
					
						
							|  |  |  | show_time_context --> | 
					
						
							|  |  |  | 	[]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		 /******************************* | 
					
						
							|  |  |  | 		 *	       HOOKS		* | 
					
						
							|  |  |  | 		 *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %%	prolog:assertion_failed(+Reason, +Goal) is semidet. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %	This hook is called if the Goal  of assertion/1 fails. Reason is | 
					
						
							|  |  |  | %	unified with either =fail= if Goal simply failed or an exception | 
					
						
							|  |  |  | %	call otherwise. If this hook  fails,   the  default behaviour is | 
					
						
							|  |  |  | %	activated.  If  the  hooks  throws  an   exception  it  will  be | 
					
						
							|  |  |  | %	propagated into the caller of assertion/1. |