%META:TOPICINFO{author="guest" date="1061501940" format="1.0" version="1.2"}%
	+ The %TOPIC%
The %TOPIC% introduces the ==%<nop>PROLOG{...}%== tag that:
	* runs a GnuProlog query
	* replaces the tag with the run's output (you can also choose the output format)
	* you can cache the result at save time to speed viewing the page
	* you can impose a timeout to avoid runaway programs
__NOTE:__ This is a first example of:
	* an object-oriented plugin. 
	* a plugin using a TWiki:Codev/PoorManCache
	* a plugin that declares its syntax.
	* so you *need* version 1.011 or above of =[[%ATTACHURL%/Plugins.pm][Plugins.pm]]= (attached) that handles objects and syntax declarations
----
%TOC%
----
	++ Syntax
%PLUGINSYNTAX{"%TOPIC%"}%

	++ Installation
	* install GnuProlog
	* install the ==IPC::Run== Perl module (from CPAN)
	* install version 1.011 or above of ==Plugins.pm==
	* apply the attached [[%ATTACHURL%/Store-verbatim.diff][patch]] needed to avoid processing ==verbatim== tags in beforeSaveHandler 
	* unzip the ==%TOPIC%.zip== package in the twiki directory (as usual)
		* Move the =Plugins/%TOPIC%.txt*= files to the TWiki web if you like
	* check if the [[#Example_without_prompt][first example]] works

	++ Settings
	* Set DEBUG to 1 to see the command called
		* Set DEBUG = 0
	* Description of this Plugin
		* Set SHORTDESCRIPTION = GnuProlog wrapper (and example of caching at save time)
	* Default timeout for stopping long (runaway) runs
		* Set TIMEOUT = 2
		* __NOTE:__ long running programs can be cached at save time by using the ==when="save"== parameter together with a long timeout

	++ BUGS
	* __Security Issue:__ the prolog program runs not (yet) chrooted 

	++ TODO
	* run in a Safe box?
	* run under *chroot*?
	* compile a *safe* version of GnuProlog? <-- this one is better
	* allow the usage of other implementations of prolog (SWI Prolog, Sicstus, ...)

	++ Dependencies
	* ==Plugins.pm== version 1.011 or above
	* the attached [[%ATTACHURL%/Store-verbatim.diff][patch]] needed to avoid processing ==verbatim== tags in beforeSaveHandler 
	* The GnuProlog prolog/constraint solver: http://www.gnu.org/software/prolog (tested with version 1.2.16)
	* The CPAN module ==IPC::Run==

	++ Change history
	* v. 1.000 : %TWIKIWEB%.AndreaSterbini: first release

----
	++ Examples
	+++ Example without prompt
<table border="1">
<tr><th>When you type</th></tr>
<tr><td>
<verbatim>
%PROLOG{
	goal="
		member(K,['TOPIC','WEB','ATTACHDIR','WEBDIR']),
		environ(K,V),
		format('\t* ~a = ~a\n',[K,V]),
		fail" 
}%
</verbatim>
</td></tr>
<tr><th>You get</th></tr>
<tr><td>
	* TOPIC = PrologPlugin
	* WEB = Plugins
	* ATTACHDIR = /home/twiki/pub/Plugins/PrologPlugin
	* WEBDIR = /home/twiki/data/Plugins
</td></tr>
<tr><th>If correctly installed you get the same below</th></tr>
<tr><td>
%PROLOG{
	goal="
		member(K,['TOPIC','WEB','ATTACHDIR','WEBDIR']),
		environ(K,V),
		format('\t* ~a = ~a\n',[K,V]),
		fail" 
}%
</td></tr>
</table>

	+++ Example cached at save time
<table border="1">
<tr><th>When you type</th></tr>
<tr><td>
<verbatim>
<pre>
%PROLOG{
	initgoal="write('%RED%initgoal is running%ENDCOLOR%'),nl" 
	entrygoal="write('%BLUE%entrygoal is running%ENDCOLOR%'),nl" 
	querygoal="write('%GREEN%querygoal is running%ENDCOLOR%'),nl,halt" 
	when="save"}%
</pre>
</verbatim>
</td></tr>
<tr><th>You get</th></tr>
<tr><td>
<pre>
%SAVEDPROLOG{
	initgoal="write('%RED%initgoal is running%ENDCOLOR%'),nl" 
	entrygoal="write('%BLUE%entrygoal is running%ENDCOLOR%'),nl" 
	querygoal="write('%GREEN%querygoal is running%ENDCOLOR%'),nl,halt" 
	when="save" cachedval="%RED%initgoal is running%ENDCOLOR%
GNU Prolog 1.2.16
By Daniel Diaz
Copyright (C) 1999-2002 Daniel Diaz
%BLUE%entrygoal is running%ENDCOLOR%
| ?- write('%GREEN%querygoal is running%ENDCOLOR%'),nl,halt.
%GREEN%querygoal is running%ENDCOLOR%
"}%
</pre>
</td></tr>
</table>

	+++ Example of timeout expiration
<table border="1">
<tr><th>When you type</th></tr>
<tr><td>
<verbatim>
%PROLOG{
	goal="repeat,sleep(1),write(query),nl,fail" 
	format="
		<center>
		<table border='1'>
			<tr><th>stdout</th><th>stderr</th></tr>
			<tr><td><pre>$stdout&nbsp;</pre></td><td><pre>$stderr&nbsp;</pre></td></tr>
		</table>
		</center>"
	when="save"
}%
</verbatim>
</td></tr>
<tr><th>You get</th></tr>
<tr><td>
%SAVEDPROLOG{
	goal="repeat,sleep(1),write(query),nl,fail" 
	format="
		<center>
		<table border='1'>
			<tr><th>stdout</th><th>stderr</th></tr>
			<tr><td><pre>$stdout&nbsp;</pre></td><td><pre>$stderr&nbsp;</pre></td></tr>
		</table>
		</center>"
	when="save" cachedval="
		<center>
		<table border='1'>
			<tr><th>stdout</th><th>stderr</th></tr>
			<tr><td><pre>query
query
<font color='red'>Prolog process timed out after 2 seconds.</font>&nbsp;</pre></td><td><pre>&nbsp;</pre></td></tr>
		</table>
		</center>"}%
</td></tr>
</table>

	+++ Writing to an attachment
<table border="1">
<tr><th>When you type</th></tr>
<tr><td>
<verbatim>
%PROLOG{
	goal="
		tell('pippo.txt'),
		write('| la vecchia con la borsa ... |'),
		nl,
		write('| ... salta il fosso senza rincorsa. |'),
		nl,
		told" 
	dir="topic" 
	when="save"
}%
| *Content of %ATTACHURL%/pippo.txt* | 
%INCLUDE{"%ATTACHURL%/pippo.txt"}%
</verbatim>
</td></tr>
<tr><th>You get</th></tr>
<tr><td>
<pre>
%SAVEDPROLOG{
	goal="
		tell('pippo.txt'),
		write('| la vecchia con la borsa ... |'),
		nl,
		write('| ... salta il fosso senza rincorsa. |'),
		nl,
		told" 
	dir="topic" 
	when="save" cachedval=""}%
</pre>

| *Content of %ATTACHURL%/pippo.txt* | 
%INCLUDE{"%ATTACHURL%/pippo.txt"}%
</td></tr>
</table>
----
<br>-- Main.AndreaSterbini - 22 Aug 2003
%META:FILEATTACHMENT{name="Plugins.pm" attr="" comment="v. 1.011: handles objects and syntax declarations" date="1061502613" path="Plugins.pm" size="14198" user="AndreaSterbini" version="1.1"}%
%META:FILEATTACHMENT{name="Store-verbatim.diff" attr="" comment="patch to avoid verbatim in beforeSaveHandler " date="1061505018" path="Store-verbatim.diff" size="733" user="AndreaSterbini" version="1.1"}%
