<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.visual-prolog.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=EJP</id>
	<title>wiki.visual-prolog.com - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.visual-prolog.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=EJP"/>
	<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Special:Contributions/EJP"/>
	<updated>2026-04-09T17:38:58Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Exception_Handling&amp;diff=4345</id>
		<title>Exception Handling</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Exception_Handling&amp;diff=4345"/>
		<updated>2016-11-08T16:31:20Z</updated>

		<summary type="html">&lt;p&gt;EJP: Alll, Some times&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An exception is a deviation from the expected.  What is an exception in one context may be expected in another context, and thus not an exception in that context.&lt;br /&gt;
&lt;br /&gt;
In Visual Prolog programs exceptions are used to deal with deviations from what is expected in the given context.  When a certain program part gets into a situation it cannot deal with it can &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;raise&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; an exception.  When an exception is raised the program control is transferred to the nearest &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;exception handler&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.  If the exception handler cannot handle the exception it can either raise a new exception or &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; the original exception.&lt;br /&gt;
&lt;br /&gt;
The program will terminate with an error message if there is no exception handler to transfer the control to.&lt;br /&gt;
&lt;br /&gt;
=== Introduction to exception handling  ===&lt;br /&gt;
&lt;br /&gt;
There are many concepts and entities to understand when dealing with exceptions.  This section will give an introduction by means of an example.&lt;br /&gt;
&lt;br /&gt;
A certain program needs to write some information to a file.  Therefore it has a predicate &amp;lt;vp&amp;gt;writeInfo&amp;lt;/vp&amp;gt; that can write this information.  &amp;lt;vp&amp;gt;writeInfo&amp;lt;/vp&amp;gt; calls the PFC constructor &amp;lt;vp&amp;gt;outputStream_file::create&amp;lt;/vp&amp;gt; to obtain a stream that it can write the information to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    writeInfo(Filename) :-&lt;br /&gt;
        S = outputStream_file::create(Filename),&lt;br /&gt;
        …&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But if the file already exists and is write-protected it is impossible to create the stream.&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;vp&amp;gt;outputStream_file::create&amp;lt;/vp&amp;gt; this situation is considered to be exceptional/unexpected and therefore it raises an exception.&lt;br /&gt;
&lt;br /&gt;
When an exception is raised the program control is transferred to the nearest exception handler, which can hopefully handle the situation and thus bring the program back on track again.&lt;br /&gt;
&lt;br /&gt;
In this case &amp;lt;vp&amp;gt;writeInfo&amp;lt;/vp&amp;gt; is called after the user have entered the file name in a dialog and pressed a &amp;#039;&amp;#039;&amp;#039;Save&amp;#039;&amp;#039;&amp;#039;-button.  So the handling we want is simply to tell the user that the information was not written because the file was write-protected.  The user can choose a different filename, remove the write protection, delete the file, cancel the operation entirely or something else.  But from the program&amp;#039;s point of view the exceptional situation is handled.&lt;br /&gt;
&lt;br /&gt;
To set a handler we use the {{lang2|Terms|try-catch|try-catch}} language construction:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    saveInfo(Filename) :-&lt;br /&gt;
        try&lt;br /&gt;
            writeInfo(Filename)&lt;br /&gt;
         catch TraceId do&lt;br /&gt;
              % &amp;lt;&amp;lt;handle situation&amp;gt;&amp;gt;&lt;br /&gt;
         end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code works like this:  &amp;lt;vp&amp;gt;writeInfo&amp;lt;/vp&amp;gt; is called, if it succeeds the {{lang2|Terms|try-catch|try-catch}} construction will not do more and &amp;lt;vp&amp;gt;saveInfo&amp;lt;/vp&amp;gt; will also succeed.&lt;br /&gt;
&lt;br /&gt;
But in the write-protected case &amp;lt;vp&amp;gt;outputStream_file::create&amp;lt;/vp&amp;gt; will raise an exception and therefore the following will take place:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;vp&amp;gt;TraceId&amp;lt;/vp&amp;gt; will be bound to the (so called) &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;trace id&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;, which is a handle to information about the exception (described in more details below)&lt;br /&gt;
# The handler code (i.e. the code between &amp;lt;vp&amp;gt;do&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;end try&amp;lt;/vp&amp;gt;) is evaluated&lt;br /&gt;
# The result of the handler code will be the result of the {{lang2|Terms|try-catch|try-catch}} construction, and thus of &amp;lt;vp&amp;gt;saveInfo&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
So for the &amp;quot;write-protected&amp;quot; exception the handler code should write a message to the user.&lt;br /&gt;
&lt;br /&gt;
If it is another kind of exception the handler will have to do something different.  Especially, it may be an exception that the handler does not know how to handle.  In this case the best thing the handler code can do is to continue the exception as an &amp;#039;&amp;#039;unknown&amp;#039;&amp;#039; exception (i.e. unknown to the handler).&lt;br /&gt;
&lt;br /&gt;
When an exception is continued it consists of the original exception plus some continue information.  If it has been continued by several handlers it will contain a lot of continue information in addition to the original exception information.  The exception information describes a trace from the point of raise through all the handlers.  The &amp;lt;vp&amp;gt;TraceId&amp;lt;/vp&amp;gt; variable that is bound in the {{lang2|Terms|try-catch|try-catch}} construction gives access information about the entire trace (hence the name).&lt;br /&gt;
&lt;br /&gt;
As mentioned above the program will terminate with en error message, if an exception is raised and no handler can be found.  Therefore programs normally setup an outermost default exception handler.  &amp;lt;vp&amp;gt;mainExe::run&amp;lt;/vp&amp;gt; setup such a handler in a console program this is the fall-back handler.  In a GUI program there is also a default hander in the GUI event loop which will catch exceptions arising from the handling of an event.&lt;br /&gt;
&lt;br /&gt;
All in all, the lifecycle of an exception is as follows:&lt;br /&gt;
&lt;br /&gt;
* It is raised&lt;br /&gt;
* It is caught and continued&lt;br /&gt;
* It is caught and continued&lt;br /&gt;
* …&lt;br /&gt;
* It is caught and handled (or the program terminates with an error message)&lt;br /&gt;
&lt;br /&gt;
Each time the exception is caught the trace so far can be examined.  When the exception is raised and each time it is continued extra information can be added to the exception trace.  If nothing else handles an exception it will (normally) be handled by the fallback/default handler of the program.&lt;br /&gt;
&lt;br /&gt;
=== Defining an exception ===&lt;br /&gt;
&lt;br /&gt;
An exception is a value of the type &amp;lt;vp&amp;gt;core::exception&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    exception =  exception(string ClassName, string ExceptionName, string Description).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I.e. an exception is a functor term that contains three pieces of information:&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;vp&amp;gt;ClassName&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The name of the class that defines the exception&lt;br /&gt;
; &amp;lt;vp&amp;gt;ExceptionName&amp;lt;/vp&amp;gt;&lt;br /&gt;
: Then name of the exception typically the name of a constant in the program&lt;br /&gt;
; &amp;lt;vp&amp;gt;Description&amp;lt;/vp&amp;gt;&lt;br /&gt;
: A description of the exception&lt;br /&gt;
&lt;br /&gt;
{{example| The &amp;lt;vp&amp;gt;cannotCreate&amp;lt;/vp&amp;gt; exception from the example above is declared in the class &amp;lt;vp&amp;gt;fileSystem_api&amp;lt;/vp&amp;gt; like this:&lt;br /&gt;
&amp;lt;vip&amp;gt;class fileSystem_api&lt;br /&gt;
…&lt;br /&gt;
constants&lt;br /&gt;
    cannotCreate : exception = exception(class_name(), constant_name(), &amp;quot;Cannot create or open the specified file&amp;quot;).&lt;br /&gt;
…&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Language_Reference/Built-in_entities/Predicates#class_name|&amp;lt;vp&amp;gt;class_name/0-&amp;gt;&amp;lt;/vp&amp;gt;]] and [[Language_Reference/Built-in_entities/Predicates#class_name|&amp;lt;vp&amp;gt;constant_name/0-&amp;gt;&amp;lt;/vp&amp;gt;]] are built-in predicate that returns the name if the class/constant in which the call occurs.  So the line above is equivalent to this:&lt;br /&gt;
&amp;lt;vip&amp;gt;class fileSystem_api&lt;br /&gt;
…&lt;br /&gt;
constants&lt;br /&gt;
    cannotCreate : exception = exception(&amp;quot;fileSystem_api&amp;quot;, &amp;quot;cannotCreate&amp;quot;, &amp;quot;Cannot create or open the specified file&amp;quot;).&lt;br /&gt;
…&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Many/most programmers will never need to define exceptions, because in many/most cases the exceptions to use are already defined.  An exception definition is only needed when the exception must be distinguished from other kinds of exceptions, such that exception handlers can deal specially with that kind of exception.  Typically exception definitions are only necessary for exceptions that are raised by library software.  In most cases programmers will raise the exception &amp;lt;vp&amp;gt;internal_error&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Raising an exception ===&lt;br /&gt;
&lt;br /&gt;
There are many predicates that explicitly raises exceptions, but most of them does it by calling a predicate in &amp;lt;vp&amp;gt;exception&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class exception&lt;br /&gt;
…&lt;br /&gt;
predicates&lt;br /&gt;
    raise_exception : (exception Exception, ...) erroneous [programPoint].&lt;br /&gt;
    raiseDetailes : (exception Exception, namedValue* ExtraInfo) erroneous [programPoint].&lt;br /&gt;
    raise_definiteUser : (exception Exception, string Msg, namedValue* ExtraInfo) erroneous [programPoint].&lt;br /&gt;
    ...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In all cases the &amp;lt;vp&amp;gt;Exception&amp;lt;/vp&amp;gt; is the exception to raise and the rest of the arguments provides additional information about the exception.  See also [[Language Reference/Predicates#programPoint|programPoint in Language Reference]] for information about the programPoint attribute.&lt;br /&gt;
&lt;br /&gt;
{{example|The &amp;lt;vp&amp;gt;cannotCreate&amp;lt;/vp&amp;gt; exception from above is raised by the predicate &amp;lt;vp&amp;gt;fileSystem_api::raise_cannotCreate&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;fileSystem_api::raise_cannotCreate_explicit&amp;lt;/vp&amp;gt;. The code  looks like this:&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    raise_cannotCreate_explicit(ProgramPoint, FileName, LastError) :-&lt;br /&gt;
        Desc = getLastErrorDescription(LastError),&lt;br /&gt;
        Msg = string::format(&amp;quot;Cannot create or open &amp;#039;%%%s&amp;#039;\nError = 0x%08x\n%%%s&amp;quot;,&lt;br /&gt;
            fileSystem_fileName_parameter, LastError, errorDescription_parameter),&lt;br /&gt;
        raise_definiteUser_explicit(ProgramPoint, cannotCreate, Msg,&lt;br /&gt;
            [namedValue(fileSystem_fileName_parameter, string(FileName)),&lt;br /&gt;
            namedValue(fileSystem_path_parameter, string(directory::getCurrentDirectory())),&lt;br /&gt;
            namedValue(errorCode_parameter, unsigned(LastError)),&lt;br /&gt;
            namedValue(errorDescription_parameter, string(Desc))]).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;raise_cannotCreate_explicit&amp;lt;/vp&amp;gt; is called with the &amp;lt;vp&amp;gt;ProgramPoint&amp;lt;/vp&amp;gt; of the raising predicate, the &amp;lt;vp&amp;gt;FileName&amp;lt;/vp&amp;gt; and the windows error code &amp;lt;vp&amp;gt;LastError&amp;lt;/vp&amp;gt; that the relevant low level Windows API predicate caused.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;exception::getLastErrorDescription&amp;lt;/vp&amp;gt; obtains the description corresponding to &amp;lt;vp&amp;gt;LastError&amp;lt;/vp&amp;gt; from Windows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;exception::raise_definiteUser_explict&amp;lt;/vp&amp;gt; is then used to raise the &amp;lt;vp&amp;gt;cannotCreate&amp;lt;/vp&amp;gt; exception with the four pieces of extra information.  The destinction between &amp;#039;&amp;#039;errors&amp;#039;&amp;#039;, &amp;#039;&amp;#039;user errors&amp;#039;&amp;#039; and &amp;#039;&amp;#039;definite user errors&amp;#039;&amp;#039; are described below.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
It is very common to create helper predicates like  &amp;lt;vp&amp;gt;fileSystem_api::raise_cannotCreate&amp;lt;/vp&amp;gt; to do the actual raising rather that calling one of the predicates in &amp;lt;vp&amp;gt;exception&amp;lt;/vp&amp;gt; directly from the code that needs to raise the exception.  That way it is certain that the extra info for this particular exception is handled in the same way in all cases.&lt;br /&gt;
&lt;br /&gt;
Normally, the helper raise predicate is created by the same programmer that declares the exception.  And as mentioned above this is normally only programmers that create library software.&lt;br /&gt;
&lt;br /&gt;
Application programmers will in most cases raise exceptions by calling appropriate raiser predicates, typically the some defined in &amp;lt;vp&amp;gt;exception&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Catching and handling exceptions ===&lt;br /&gt;
&lt;br /&gt;
Exceptions are caught with the {{lang2|Terms|try-catch|try-catch}} construction:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;try &amp;lt;Body&amp;gt; catch &amp;lt;TraceId&amp;gt; do &amp;lt;Handler&amp;gt; end try&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;vpbnf&amp;gt;&amp;lt;Body&amp;gt;&amp;lt;/vpbnf&amp;gt; terminates with an exception &amp;lt;vpbnf&amp;gt;&amp;lt;TraceId&amp;gt;&amp;lt;/vpbnf&amp;gt; is bound to the &amp;#039;&amp;#039;trace id&amp;#039;&amp;#039; and then &amp;lt;vpbnf&amp;gt;&amp;lt;Handler&amp;gt;&amp;lt;/vpbnf&amp;gt; is evaluated.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vpbnf&amp;gt;&amp;lt;TraceId&amp;gt;&amp;lt;/vpbnf&amp;gt; is used to obtain information about the exception trace.  This information can be used for at least two things:&lt;br /&gt;
&lt;br /&gt;
* Determine which kind of exception that is caught, so that it can be decided if and how to handle it&lt;br /&gt;
* Obtain additional information to write to the user, in a log or use for something else&lt;br /&gt;
&lt;br /&gt;
As explained above it is very common that an exception is continued one or more times after it has been raised, so an exception contains a complete &amp;#039;&amp;#039;trace&amp;#039;&amp;#039; of entries (raise, continue, continue, ---).  Subsequently, you will need to search the trace to see if a certain exception is among the entries.  This is done by calling &amp;lt;vp&amp;gt;exception::tryGetDescriptor&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    tryGetDescriptor : (traceId TraceID, exception Exception) -&amp;gt; descriptor Descriptor determ.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exception trace corresponding to &amp;lt;vp&amp;gt;TraceId&amp;lt;/vp&amp;gt; is searched for an exception of the kind &amp;lt;vp&amp;gt;Exception&amp;lt;/vp&amp;gt;.  If there is such an entry in the trace (raised or continued) the corresponding exception descriptor is returned in &amp;lt;vp&amp;gt;Descriptor&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The predicate fails if such an exception is not in the exception trace.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;Descriptor&amp;lt;/vp&amp;gt; contains the extra information about that particular entry in the exception trace:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    descriptor = descriptor(programPointDescriptor ProgramPoint, exception Exception, &lt;br /&gt;
        kind Kind, namedValue* ExtraInfo, gmtTimeValue GMTTime, unsigned ThreadId).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;ProgramPoint&amp;lt;/vp&amp;gt;&lt;br /&gt;
: A readable representation of the &amp;lt;vp&amp;gt;programPoint&amp;lt;/vp&amp;gt; where the exception was raised/continued.&lt;br /&gt;
&amp;lt;vp&amp;gt;Exception&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The &amp;lt;vp&amp;gt;exception&amp;lt;/vp&amp;gt; in question&lt;br /&gt;
&amp;lt;vp&amp;gt;Kind&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The entry kind (&amp;lt;vp&amp;gt;raise&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;continue&amp;lt;/vp&amp;gt;)&lt;br /&gt;
&amp;lt;vp&amp;gt;ExtraInfo&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The extra information provided with this entry in the trace&lt;br /&gt;
&amp;lt;vp&amp;gt;GMTTime&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The time this exception trace entry was raised/continued&lt;br /&gt;
&amp;lt;vp&amp;gt;ExceptionDescription&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The exception description of this entry (this information is also present in &amp;lt;vp&amp;gt;ExceptionInfo&amp;lt;/vp&amp;gt;)&lt;br /&gt;
&amp;lt;vp&amp;gt;ThreadId&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The thread id of the thread that raised/continued this entry&lt;br /&gt;
&lt;br /&gt;
Much of this information is mainly interesting if the exception is not handled.  The information that is most interesting when handling an exception is:&lt;br /&gt;
&lt;br /&gt;
* The exception has been determined to be the one we expected&lt;br /&gt;
* The &amp;lt;vp&amp;gt;ExtraInfo&amp;lt;/vp&amp;gt; for this entry is available for use in messages, etc&lt;br /&gt;
&lt;br /&gt;
The predicate &amp;lt;vp&amp;gt;exception::tryGetExtraInfo&amp;lt;/vp&amp;gt; is convenient for obtaining extra information:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    tryGetExtraInfo : (descriptor Descriptor, string Name) -&amp;gt; value Value determ.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;Descriptor&amp;lt;/vp&amp;gt;&lt;br /&gt;
: Is the description whose extra info we want to get something from.&lt;br /&gt;
&amp;lt;vp&amp;gt;Name&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The name of the extra info parameter we want to obtain.&lt;br /&gt;
&amp;lt;vp&amp;gt;Value&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The value that the mentioned parameter has.&lt;br /&gt;
&lt;br /&gt;
{{example| Code for catching and handling the &amp;lt;vp&amp;gt;fileSystem_api::cannotCreate&amp;lt;/vp&amp;gt; exception can look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    saveInfo(Filename) :-&lt;br /&gt;
        try&lt;br /&gt;
            writeInfo(Filename)&lt;br /&gt;
         catch TraceId do&lt;br /&gt;
              if D = exception::tryGetDescriptor(TraceId, fileSystem_api::cannotCreate) then&lt;br /&gt;
                stdio::write(&amp;quot;Cannot write to the file: &amp;quot;, Filename),&lt;br /&gt;
                if string(Description) = exception::tryGetExtraInfo(D, exception::errorDescription_parameter) then&lt;br /&gt;
                    stdio::writef(&amp;quot;; %&amp;quot;, Description)&lt;br /&gt;
                end if,&lt;br /&gt;
                stdio::write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
            else&lt;br /&gt;
                exception::continue_unknown(TraceId, &amp;quot;Filename = &amp;quot;, Filename)&lt;br /&gt;
            end if&lt;br /&gt;
         end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code here don&amp;#039;t need to obtain the &amp;lt;vp&amp;gt;fileSystem_exception::fileName_parameter&amp;lt;/vp&amp;gt;, because the file name is already known in the &amp;lt;vp&amp;gt;Filename&amp;lt;/vp&amp;gt; variable.&lt;br /&gt;
&lt;br /&gt;
But we can obtain Window&amp;#039;s description of the problem querying for &amp;lt;vp&amp;gt;common_exception::errorDescription_parameter&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039; the exception as unknown if it is not a &amp;lt;vp&amp;gt;cannotCreate&amp;lt;/vp&amp;gt; exception.  For the continue call we add the filename as additional information.  &amp;lt;vp&amp;gt;common_exception::continue_unknown&amp;lt;/vp&amp;gt; will create a string of the extra arguments and add it as an &amp;lt;vp&amp;gt;common_exception::errorArguments_parameter&amp;lt;/vp&amp;gt;.  Such information is mainly for use in the default exception handler to be discussed below.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Exception dumps ===&lt;br /&gt;
&lt;br /&gt;
The class &amp;lt;vp&amp;gt;exceptionDump&amp;lt;/vp&amp;gt; contains predicates for dumping exception traces to &amp;lt;vp&amp;gt;stdio&amp;lt;/vp&amp;gt;, some other &amp;lt;vp&amp;gt;outputStream&amp;lt;/vp&amp;gt; or a &amp;lt;vp&amp;gt;string&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
An exception dump contains three major pieces of information:&lt;br /&gt;
&lt;br /&gt;
* A dump of the call stack (with file names and line numbers) from the point where the exception was raised&lt;br /&gt;
* A dump of the exception-trace with all the information from the exception descriptors&lt;br /&gt;
* Information about the operating system that the program ran on&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;exceptionDump&amp;lt;/vp&amp;gt; have predicates both for dumping exception traces both from a &amp;lt;vp&amp;gt;traceId&amp;lt;/vp&amp;gt; and from a &amp;lt;vp&amp;gt;traceInfo&amp;lt;/vp&amp;gt; obtained with &amp;lt;vp&amp;gt;exception::getTraceInfo&amp;lt;/vp&amp;gt; (see [[#Serializing exceptions]] below).&lt;br /&gt;
&lt;br /&gt;
Dumps for a certain program are in general only useful to the programmers of that program; the users of the program will find dumps cryptic and rather uninteresting.  I.e. the purpose of dumps is to give the programmer means for improving the program.&lt;br /&gt;
&lt;br /&gt;
=== Default handling ===&lt;br /&gt;
&lt;br /&gt;
A program should handle all exceptions, because if an exception is continued or raised at a point where there is no handler the program will terminate with a rather bad error message.  The error message is bad because most exception handling is done in PFC; the language itself knows nothing about exception traces and the like.&lt;br /&gt;
&lt;br /&gt;
To be sure that all exceptions are handled it is normal to set up a default (or fallback) exception handler.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;mainExe::run&amp;lt;/vp&amp;gt; (and &amp;lt;vp&amp;gt;mainExe::runCom&amp;lt;/vp&amp;gt;) which is normally called in the goal setup such a default exception handler: It runs the &amp;lt;vp&amp;gt;main::run&amp;lt;/vp&amp;gt; predicate inside a {{lang2|Terms|try-catch|try-catch}} construction that will handle any exception.&lt;br /&gt;
&lt;br /&gt;
The handler in &amp;lt;vp&amp;gt;mainExe::run&amp;lt;/vp&amp;gt; (and &amp;lt;vp&amp;gt;mainExe::runCom&amp;lt;/vp&amp;gt;) dumps the entire exception trace to output stream in &amp;lt;vp&amp;gt;stdio&amp;lt;/vp&amp;gt;.  And then the program will terminate.  The idea is that:&lt;br /&gt;
&lt;br /&gt;
* Perhaps the user can see something from the dump (which may for example say that &amp;#039;&amp;#039;access is denied&amp;#039;&amp;#039; to &amp;#039;&amp;#039;xxx.txt&amp;#039;&amp;#039;)&lt;br /&gt;
* Alternatively, the developer of the program may use the dump to improve the program&lt;br /&gt;
&lt;br /&gt;
In addition to the handler in &amp;lt;vp&amp;gt;mainExe::run&amp;lt;/vp&amp;gt; a GUI program also set a default handler in the event loop.  This handler is set by calling &amp;lt;vp&amp;gt;applicationWindow::setErrorResponder&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    errorResponder = (applicationWindow Source, exception::traceId TraceId).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    setErrorResponder : (errorResponder Responder).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default the error responder &amp;lt;vp&amp;gt;errorPresentationDialog::present&amp;lt;/vp&amp;gt; is used.  The functioning of the &amp;lt;pv&amp;gt;errorPresentationDialog&amp;lt;/vp&amp;gt; is closely related to a categorization of exceptions described in the next section.&lt;br /&gt;
&lt;br /&gt;
PFC place exceptions in three major categories based on who is (believed to be) responsible:&lt;br /&gt;
&lt;br /&gt;
; Internal errors&lt;br /&gt;
: An exceptional state which the programmer is responsible to deal with&lt;br /&gt;
; User exception&lt;br /&gt;
: An exception which can perhaps be solved by the end user of the program, but which may also call for a programmer solution.  User exceptions carries a message for the end user of the program.&lt;br /&gt;
; Definite user errors&lt;br /&gt;
: An exception which is definitely one the end user should deal with, because the programmer cannot do anything about it anyway&lt;br /&gt;
&lt;br /&gt;
You may notice that &amp;quot;error&amp;quot; is used to signal that a person is (believed to be) responsible for the problem, where as &amp;quot;exception&amp;quot; also covers situations with looser relation to specific persons (such as a network failure).&lt;br /&gt;
&lt;br /&gt;
==== Internal errors ====&lt;br /&gt;
&lt;br /&gt;
Internal errors are caused and/or should be prevented by the programmer of the program.&lt;br /&gt;
&lt;br /&gt;
{{Example| A predicate takes two lists as argument and pair the elements of the lists.  So the lists are expected to have the same length.  If the lists have different lengths it is appropriate to raise an &amp;lt;vp&amp;gt;internal_error&amp;lt;/vp&amp;gt;, because it is clearly the responsibility of the programmer to ensure that the lists have same length; the end-user of the program can at most influence this indirectly.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== User exceptions ====&lt;br /&gt;
&lt;br /&gt;
User exceptions typically deal with problems related to external resources such as files, network, databases, web servers, etc.  Often the user will become wiser by being informed about the problem and often the user may even solve the problem.&lt;br /&gt;
&lt;br /&gt;
{{Example|  The read-only file problem discussed above is a typical example of a user exception.  It is the user rather than the programmer that can solve the problem with the read-only file.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
A user exception is distinguished by having extra information in a field with name &amp;lt;vp&amp;gt;common_exception::userMessage_parameter&amp;lt;/vp&amp;gt;.  This extra info should be a message with relevance for an end user of the program.  The message can reference other extra info parameters using the format %PARAM.  The preferred way to raise user exceptions is by means of the predicate &amp;lt;vp&amp;gt;exception::raise_user&amp;lt;/vp&amp;gt;.  Likewise you can continue exceptions with a user message using &amp;lt;vp&amp;gt;exception::continue_user&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Example| This predicate will raise a &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;user&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;lt;vp&amp;gt;fileSystem_api::cannotCreate&amp;lt;/vp&amp;gt; exception&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    raise_cannotCreate : (string Filename) erroneous.&lt;br /&gt;
clauses&lt;br /&gt;
    raise_cannotCreate(Filename) :-&lt;br /&gt;
        exception::raise_user(fileSystem_api::cannotCreate,&lt;br /&gt;
            &amp;quot;It is not possible to create the file %Filename&amp;quot;,&lt;br /&gt;
            [namedValue(&amp;quot;Filename&amp;quot;, string(Filename))]).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The use of &amp;lt;vp&amp;gt;&amp;quot;%Filename&amp;quot;&amp;lt;/vp&amp;gt; in the message corresponds to the extra info &amp;lt;vp&amp;gt;&amp;quot;Filename&amp;quot;&amp;lt;/vp&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The predicate &amp;lt;vp&amp;gt;exceptionDump::tryGetUserMessage&amp;lt;/vp&amp;gt; will return a user message from a &amp;lt;vp&amp;gt;traceId&amp;lt;/vp&amp;gt; if possible.  The message will consist of all user messages from the entire trace and will have parameters substituted.&lt;br /&gt;
&lt;br /&gt;
{{Example|  Given &amp;lt;vp&amp;gt;raise_cannotCreate&amp;lt;/vp&amp;gt; from above and calling &amp;lt;vp&amp;gt;test&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    test() :-&lt;br /&gt;
        try&lt;br /&gt;
            raise_cannotCreate(&amp;quot;test.xxx&amp;quot;)&lt;br /&gt;
         catch TraceId do&lt;br /&gt;
            if UserMsg = exceptionDump::tryGetUserMessage(TraceId) then&lt;br /&gt;
                stdio::write(UserMsg)&lt;br /&gt;
            end if&lt;br /&gt;
         end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following message is written to &amp;lt;vp&amp;gt;stdio&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;It is not possible to create the file test.xxx&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Definite user errors ====&lt;br /&gt;
&lt;br /&gt;
Definite user errors are exceptions that are solely the responsibility of the user of the program.  For example wrong use of the program.&lt;br /&gt;
&lt;br /&gt;
{{Example| A program can write out some information, but only if the user has specified which information to write.  So if the user invoke the functionality without having specified which information to write, it is appropriate to raise a definite user error.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
A definite user exception is distinguished by adding &amp;lt;vp&amp;gt;true&amp;lt;/vp&amp;gt; as extra info for the parameter &amp;lt;vp&amp;gt;exception::definiteUserError_parameter&amp;lt;/vp&amp;gt;.  The preferred way to do this is by using the predicates:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;exception::raise_definiteUser&amp;lt;/vp&amp;gt;&lt;br /&gt;
* &amp;lt;vp&amp;gt;exception::continue_definiteUser&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The use of these predicates is the same as the user of &amp;lt;vp&amp;gt;common_exception::raise_user&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;common_exception::continue_user&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
An exception trace is considered a definite user error if one (or more) entries in the trace carries the &amp;lt;vp&amp;gt;exception::definiteUserError_parameter&amp;lt;/vp&amp;gt;.  The predicate &amp;lt;vp&amp;gt;exception::isDefiniteUserError&amp;lt;/vp&amp;gt; will succeed for definite user errors.&lt;br /&gt;
&lt;br /&gt;
=== Serializing exceptions ===&lt;br /&gt;
&lt;br /&gt;
In some situations the best way to handle  an exception is by sending all the information about the exception somewhere else.  A server might for example want to send the information to the client program that caused the exception, because then there is a user that can take action.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;vp&amp;gt;traceId&amp;lt;/vp&amp;gt; only have a meaning in the process that has created it, but the predicate &amp;lt;vp&amp;gt;exception::getTraceInfo&amp;lt;/vp&amp;gt; can create a &amp;lt;vp&amp;gt;traceInfo&amp;lt;/vp&amp;gt; structure (&amp;lt;vp&amp;gt;TraceInfo&amp;lt;/vp&amp;gt;) from the &amp;lt;vp&amp;gt;traceId TraceId&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    getTraceInfo : (traceId TraceId) -&amp;gt; traceInfo TraceInfo.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Such a structure is a functor structure that can be serialized/deserialized with &amp;lt;vp&amp;gt;toString&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;toTerm&amp;lt;/vp&amp;gt;; &amp;lt;vp&amp;gt;write&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;read&amp;lt;/vp&amp;gt;; nested in a fact database using &amp;lt;vp&amp;gt;save&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;consult&amp;lt;/vp&amp;gt;; etc.&lt;br /&gt;
&lt;br /&gt;
==== Packed Exceptions ====&lt;br /&gt;
&lt;br /&gt;
Sometimes, e.g., in a client/server application, you catch an exception on the server which you want to handle on the client. In that case you can serialize the exception on the server send it to the client and reraise it as a packed exception.&lt;br /&gt;
&lt;br /&gt;
On the server&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
try&lt;br /&gt;
   ...&lt;br /&gt;
catch E do&lt;br /&gt;
   sendExceptionToClient(exception::getTraceInfo())&lt;br /&gt;
end try,&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the client&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
Rtn = remoteCall(...),&lt;br /&gt;
if error(TraceInfo) = Rtn then&lt;br /&gt;
    exception::raise_packed(TraceInfo, &amp;quot;remoteCall returned an exception&amp;quot;)&lt;br /&gt;
end if&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The predicate &amp;lt;vp&amp;gt;raise_packed&amp;lt;/vp&amp;gt; works like a &amp;lt;vp&amp;gt;continue_unknown&amp;lt;/vp&amp;gt; but continues a serialized exception instead of normal exception. It is meant to be used when the exception stem from another program and thus only is available in serialized form.&lt;br /&gt;
&lt;br /&gt;
=== The error presentation dialog  ===&lt;br /&gt;
&lt;br /&gt;
The error presentation dialog (in the class &amp;lt;vp&amp;gt;errorPresentationDialog&amp;lt;/vp&amp;gt;) is by default used by the default exception handling in a GUI program.  Its behavior is closely related to the classification of exceptions described above, as described by these two rules:&lt;br /&gt;
&lt;br /&gt;
* If the exception trace carries a user message, this message will be presented to the user.&lt;br /&gt;
* If the exception trace is not a definite user error, there will be information for the programmer&lt;br /&gt;
&lt;br /&gt;
So if the exception is an internal error there will only be information for the programmer; if it is a user exception there will both be information for the user and for the programmer; and if it is a user error there will only be information for the user.&lt;br /&gt;
&lt;br /&gt;
If there is information to the programmer the exception dialog will have a details/less details button that can show/hide the programmer information.  It will also have a &amp;quot;report error&amp;quot; button, which by default will copy the information to the clipboard so that the user can easily send it to the programmer.&lt;br /&gt;
&lt;br /&gt;
[[Image:ErrorPresentationDialogDefault.png]]&lt;br /&gt;
&lt;br /&gt;
The dialog is customizable by means of various properties:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;properties&lt;br /&gt;
    title : string. % := &amp;quot;Error&amp;quot;.&lt;br /&gt;
    callBackBtnText : string. % := &amp;quot;&amp;amp;Copy&amp;quot;.&lt;br /&gt;
    dontCallBackBtnText : string. % := &amp;quot;&amp;amp;OK&amp;quot;.&lt;br /&gt;
    showDetailsBtnText : string. % := &amp;quot;Show &amp;amp;Details&amp;quot;.&lt;br /&gt;
    hideDetailsBtnText : string. % := &amp;quot;Hide &amp;amp;Details&amp;quot;.&lt;br /&gt;
    closeApplicationBtnText : string. % := &amp;quot;Close &amp;amp;Application&amp;quot;.&lt;br /&gt;
    commentTextPromt : string. % := &amp;quot;Please describe what you were doing when the error occured:&amp;quot;&lt;br /&gt;
    internalErrorMessage : string. %  := &amp;quot;An internal error has occurred.\nPlease send a bug report to your vendor.&amp;quot;.&lt;br /&gt;
    feedbackMessage : string. %  := &amp;quot;Please send your feedback.&amp;quot;.&lt;br /&gt;
    definiteUserErrorIcon : vpiDomains::resid.&lt;br /&gt;
    userErrorIcon : vpiDomains::resid.&lt;br /&gt;
    internalErrorIcon : vpiDomains::resid.&lt;br /&gt;
    reportErrorDelegate : reportErrorDelegate.&lt;br /&gt;
    extraInfoWriter : writer.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All texts and labels are controlled by properties.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;extraInfoWriter&amp;lt;/vp&amp;gt; is a callback that can be set to include extra info for the programmer.  This information will both be presented in the details window and reported back to the programmer if the user press the &amp;quot;report error&amp;quot; button (i.e. the button which is by default labeled &amp;#039;&amp;#039;&amp;#039;Copy&amp;#039;&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;extraInfoWriter&amp;lt;/vp&amp;gt; callback predicate must have this type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    writer = (outputStream Stream).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The dialog will invoke the predicate and then it should simply write extra information to the received stream.&lt;br /&gt;
&lt;br /&gt;
{{Example| The Visual Prolog IDE uses the &amp;lt;vp&amp;gt;extraInfoWriter&amp;lt;/vp&amp;gt; to write version information, information about the open project and information about the last actions carried out in the IDE.  This information will help the programmers to analyze the problem.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The action performed by the &amp;quot;report error&amp;quot; button is customizable using the property &amp;lt;vp&amp;gt;reportErrorDelegate&amp;lt;/vp&amp;gt;, which is a callback predicate of this type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    reportErrorDelegate = (window Parent, string Comment, optional{exception::traceInfo} TraceInfo, string ExtraInfo).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;vp&amp;gt;Parent&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The error presentation dialog which can be used as parent for additional dialogs.&lt;br /&gt;
; &amp;lt;vp&amp;gt;Comment&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The users comment from the comment box.&lt;br /&gt;
; &amp;lt;vp&amp;gt;TraceInfo&amp;lt;/vp&amp;gt;&lt;br /&gt;
: If the dialog is invoked on an exception the trace info is here, if it is invoked for feedback this value is &amp;lt;vp&amp;gt;none&amp;lt;/vp&amp;gt;&lt;br /&gt;
; &amp;lt;vp&amp;gt;ExtraInfo&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The extra info written by the &amp;lt;vp&amp;gt;extraInfoWriter&amp;lt;/vp&amp;gt; callback&lt;br /&gt;
&lt;br /&gt;
{{Example| In the Visual Prolog IDE the &amp;lt;vp&amp;gt;reportErrorDelegate&amp;lt;/vp&amp;gt; will send the exception information to a WEB service which will insert the notification in a database.  The notifications in the database will then be used to improve the IDE.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>EJP</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Exception_Handling&amp;diff=4344</id>
		<title>Exception Handling</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Exception_Handling&amp;diff=4344"/>
		<updated>2016-11-08T16:07:46Z</updated>

		<summary type="html">&lt;p&gt;EJP: Typo (I to In)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An exception is a deviation from the expected.  What is an exception in one context may be expected in another context, and thus not an exception in that context.&lt;br /&gt;
&lt;br /&gt;
In Visual Prolog programs exceptions are used to deal with deviations from what is expected in the given context.  When a certain program part gets into a situation it cannot deal with it can &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;raise&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; an exception.  When an exception is raised the program control is transferred to the nearest &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;exception handler&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.  If the exception handler cannot handle the exception it can either raise a new exception or &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; the original exception.&lt;br /&gt;
&lt;br /&gt;
The program will terminate with an error message if there is no exception handler to transfer the control to.&lt;br /&gt;
&lt;br /&gt;
=== Introduction to exception handling  ===&lt;br /&gt;
&lt;br /&gt;
There are many concepts and entities to understand when dealing with exceptions.  This section will give an introduction by means of an example.&lt;br /&gt;
&lt;br /&gt;
A certain program needs to write some information to a file.  Therefore it has a predicate &amp;lt;vp&amp;gt;writeInfo&amp;lt;/vp&amp;gt; that can write this information.  &amp;lt;vp&amp;gt;writeInfo&amp;lt;/vp&amp;gt; calls the PFC constructor &amp;lt;vp&amp;gt;outputStream_file::create&amp;lt;/vp&amp;gt; to obtain a stream that it can write the information to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    writeInfo(Filename) :-&lt;br /&gt;
        S = outputStream_file::create(Filename),&lt;br /&gt;
        …&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But if the file already exists and is write-protected it is impossible to create the stream.&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;vp&amp;gt;outputStream_file::create&amp;lt;/vp&amp;gt; this situation is considered to be exceptional/unexpected and therefore it raises an exception.&lt;br /&gt;
&lt;br /&gt;
When an exception is raised the program control is transferred to the nearest exception handler, which can hopefully handle the situation and thus bring the program back on track again.&lt;br /&gt;
&lt;br /&gt;
In this case &amp;lt;vp&amp;gt;writeInfo&amp;lt;/vp&amp;gt; is called after the user have entered the file name in a dialog and pressed a &amp;#039;&amp;#039;&amp;#039;Save&amp;#039;&amp;#039;&amp;#039;-button.  So the handling we want is simply to tell the user that the information was not written because the file was write-protected.  The user can choose a different filename, remove the write protection, delete the file, cancel the operation entirely or something else.  But from the program&amp;#039;s point of view the exceptional situation is handled.&lt;br /&gt;
&lt;br /&gt;
To set a handler we use the {{lang2|Terms|try-catch|try-catch}} language construction:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    saveInfo(Filename) :-&lt;br /&gt;
        try&lt;br /&gt;
            writeInfo(Filename)&lt;br /&gt;
         catch TraceId do&lt;br /&gt;
              % &amp;lt;&amp;lt;handle situation&amp;gt;&amp;gt;&lt;br /&gt;
         end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code works like this:  &amp;lt;vp&amp;gt;writeInfo&amp;lt;/vp&amp;gt; is called, if it succeeds the {{lang2|Terms|try-catch|try-catch}} construction will not do more and &amp;lt;vp&amp;gt;saveInfo&amp;lt;/vp&amp;gt; will also succeed.&lt;br /&gt;
&lt;br /&gt;
But in the write-protected case &amp;lt;vp&amp;gt;outputStream_file::create&amp;lt;/vp&amp;gt; will raise an exception and therefore the following will take place:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;vp&amp;gt;TraceId&amp;lt;/vp&amp;gt; will be bound to the (so called) &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;trace id&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;, which is a handle to information about the exception (described in more details below)&lt;br /&gt;
# The handler code (i.e. the code between &amp;lt;vp&amp;gt;do&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;end try&amp;lt;/vp&amp;gt;) is evaluated&lt;br /&gt;
# The result of the handler code will be the result of the {{lang2|Terms|try-catch|try-catch}} construction, and thus of &amp;lt;vp&amp;gt;saveInfo&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
So for the &amp;quot;write-protected&amp;quot; exception the handler code should write a message to the user.&lt;br /&gt;
&lt;br /&gt;
If it is another kind of exception the handler will have to do something different.  Especially, it may be an exception that the handler does not know how to handle.  In this case the best thing the handler code can do is to continue the exception as an &amp;#039;&amp;#039;unknown&amp;#039;&amp;#039; exception (i.e. unknown to the handler).&lt;br /&gt;
&lt;br /&gt;
When an exception is continued it consists of the original exception plus some continue information.  If it has been continued by several handlers it will contain a lot of continue information in addition to the original exception information.  The exception information describes a trace from the point of raise through all the handlers.  The &amp;lt;vp&amp;gt;TraceId&amp;lt;/vp&amp;gt; variable that is bound in the {{lang2|Terms|try-catch|try-catch}} construction gives access information about the entire trace (hence the name).&lt;br /&gt;
&lt;br /&gt;
As mentioned above the program will terminate with en error message, if an exception is raised and no handler can be found.  Therefore programs normally setup an outermost default exception handler.  &amp;lt;vp&amp;gt;mainExe::run&amp;lt;/vp&amp;gt; setup such a handler in a console program this is the fall-back handler.  In a GUI program there is also a default hander in the GUI event loop which will catch exceptions arising from the handling of an event.&lt;br /&gt;
&lt;br /&gt;
All in all, the lifecycle of an exception is as follows:&lt;br /&gt;
&lt;br /&gt;
* It is raised&lt;br /&gt;
* It is caught and continued&lt;br /&gt;
* It is caught and continued&lt;br /&gt;
* …&lt;br /&gt;
* It is caught and handled (or the program terminates with an error message)&lt;br /&gt;
&lt;br /&gt;
Each time the exception is caught the trace so far can be examined.  When the exception is raised and each time it is continued extra information can be added to the exception trace.  If nothing else handles an exception it will (normally) be handled by the fallback/default handler of the program.&lt;br /&gt;
&lt;br /&gt;
=== Defining an exception ===&lt;br /&gt;
&lt;br /&gt;
An exception is a value of the type &amp;lt;vp&amp;gt;core::exception&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    exception =  exception(string ClassName, string ExceptionName, string Description).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I.e. an exception is a functor term that contains three pieces of information:&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;vp&amp;gt;ClassName&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The name of the class that defines the exception&lt;br /&gt;
; &amp;lt;vp&amp;gt;ExceptionName&amp;lt;/vp&amp;gt;&lt;br /&gt;
: Then name of the exception typically the name of a constant in the program&lt;br /&gt;
; &amp;lt;vp&amp;gt;Description&amp;lt;/vp&amp;gt;&lt;br /&gt;
: A description of the exception&lt;br /&gt;
&lt;br /&gt;
{{example| The &amp;lt;vp&amp;gt;cannotCreate&amp;lt;/vp&amp;gt; exception from the example above is declared in the class &amp;lt;vp&amp;gt;fileSystem_api&amp;lt;/vp&amp;gt; like this:&lt;br /&gt;
&amp;lt;vip&amp;gt;class fileSystem_api&lt;br /&gt;
…&lt;br /&gt;
constants&lt;br /&gt;
    cannotCreate : exception = exception(class_name(), constant_name(), &amp;quot;Cannot create or open the specified file&amp;quot;).&lt;br /&gt;
…&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Language_Reference/Built-in_entities/Predicates#class_name|&amp;lt;vp&amp;gt;class_name/0-&amp;gt;&amp;lt;/vp&amp;gt;]] and [[Language_Reference/Built-in_entities/Predicates#class_name|&amp;lt;vp&amp;gt;constant_name/0-&amp;gt;&amp;lt;/vp&amp;gt;]] are built-in predicate that returns the name if the class/constant in which the call occurs.  So the line above is equivalent to this:&lt;br /&gt;
&amp;lt;vip&amp;gt;class fileSystem_api&lt;br /&gt;
…&lt;br /&gt;
constants&lt;br /&gt;
    cannotCreate : exception = exception(&amp;quot;fileSystem_api&amp;quot;, &amp;quot;cannotCreate&amp;quot;, &amp;quot;Cannot create or open the specified file&amp;quot;).&lt;br /&gt;
…&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Many/most programmers will never need to define exceptions, because in many/most cases the exceptions to use are already defined.  An exception definition is only needed when the exception must be distinguished from other kinds of exceptions, such that exception handlers can deal specially with that kind of exception.  Typically exception definitions are only necessary for exceptions that are raised by library software.  In most cases programmers will raise the exception &amp;lt;vp&amp;gt;internal_error&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Raising an exception ===&lt;br /&gt;
&lt;br /&gt;
There are many predicates that explicitly raises exceptions, but most of them does it by calling a predicate in &amp;lt;vp&amp;gt;exception&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class exception&lt;br /&gt;
…&lt;br /&gt;
predicates&lt;br /&gt;
    raise_exception : (exception Exception, ...) erroneous [programPoint].&lt;br /&gt;
    raiseDetailes : (exception Exception, namedValue* ExtraInfo) erroneous [programPoint].&lt;br /&gt;
    raise_definiteUser : (exception Exception, string Msg, namedValue* ExtraInfo) erroneous [programPoint].&lt;br /&gt;
    ...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In alll cases the &amp;lt;vp&amp;gt;Exception&amp;lt;/vp&amp;gt; is the exception to raise and the rest of the arguments provides additional information about the exception.  See also [[Language Reference/Predicates#programPoint|programPoint in Language Reference]] for information about the programPoint attribute.&lt;br /&gt;
&lt;br /&gt;
{{example|The &amp;lt;vp&amp;gt;cannotCreate&amp;lt;/vp&amp;gt; exception from above is raised by the predicate &amp;lt;vp&amp;gt;fileSystem_api::raise_cannotCreate&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;fileSystem_api::raise_cannotCreate_explicit&amp;lt;/vp&amp;gt;. The code  looks like this:&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    raise_cannotCreate_explicit(ProgramPoint, FileName, LastError) :-&lt;br /&gt;
        Desc = getLastErrorDescription(LastError),&lt;br /&gt;
        Msg = string::format(&amp;quot;Cannot create or open &amp;#039;%%%s&amp;#039;\nError = 0x%08x\n%%%s&amp;quot;,&lt;br /&gt;
            fileSystem_fileName_parameter, LastError, errorDescription_parameter),&lt;br /&gt;
        raise_definiteUser_explicit(ProgramPoint, cannotCreate, Msg,&lt;br /&gt;
            [namedValue(fileSystem_fileName_parameter, string(FileName)),&lt;br /&gt;
            namedValue(fileSystem_path_parameter, string(directory::getCurrentDirectory())),&lt;br /&gt;
            namedValue(errorCode_parameter, unsigned(LastError)),&lt;br /&gt;
            namedValue(errorDescription_parameter, string(Desc))]).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;raise_cannotCreate_explicit&amp;lt;/vp&amp;gt; is called with the &amp;lt;vp&amp;gt;ProgramPoint&amp;lt;/vp&amp;gt; of the raising predicate, the &amp;lt;vp&amp;gt;FileName&amp;lt;/vp&amp;gt; and the windows error code &amp;lt;vp&amp;gt;LastError&amp;lt;/vp&amp;gt; that the relevant low level Windows API predicate caused.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;exception::getLastErrorDescription&amp;lt;/vp&amp;gt; obtains the description corresponding to &amp;lt;vp&amp;gt;LastError&amp;lt;/vp&amp;gt; from Windows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;exception::raise_definiteUser_explict&amp;lt;/vp&amp;gt; is then used to raise the &amp;lt;vp&amp;gt;cannotCreate&amp;lt;/vp&amp;gt; exception with the four pieces of extra information.  The destinction between &amp;#039;&amp;#039;errors&amp;#039;&amp;#039;, &amp;#039;&amp;#039;user errors&amp;#039;&amp;#039; and &amp;#039;&amp;#039;definite user errors&amp;#039;&amp;#039; are described below.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
It is very common to create helper predicates like  &amp;lt;vp&amp;gt;fileSystem_api::raise_cannotCreate&amp;lt;/vp&amp;gt; to do the actual raising rather that calling one of the predicates in &amp;lt;vp&amp;gt;exception&amp;lt;/vp&amp;gt; directly from the code that needs to raise the exception.  That way it is certain that the extra info for this particular exception is handled in the same way in all cases.&lt;br /&gt;
&lt;br /&gt;
Normally, the helper raise predicate is created by the same programmer that declares the exception.  And as mentioned above this is normally only programmers that create library software.&lt;br /&gt;
&lt;br /&gt;
Application programmers will in most cases raise exceptions by calling appropriate raiser predicates, typically the some defined in &amp;lt;vp&amp;gt;exception&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Catching and handling exceptions ===&lt;br /&gt;
&lt;br /&gt;
Exceptions are caught with the {{lang2|Terms|try-catch|try-catch}} construction:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;try &amp;lt;Body&amp;gt; catch &amp;lt;TraceId&amp;gt; do &amp;lt;Handler&amp;gt; end try&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;vpbnf&amp;gt;&amp;lt;Body&amp;gt;&amp;lt;/vpbnf&amp;gt; terminates with an exception &amp;lt;vpbnf&amp;gt;&amp;lt;TraceId&amp;gt;&amp;lt;/vpbnf&amp;gt; is bound to the &amp;#039;&amp;#039;trace id&amp;#039;&amp;#039; and then &amp;lt;vpbnf&amp;gt;&amp;lt;Handler&amp;gt;&amp;lt;/vpbnf&amp;gt; is evaluated.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vpbnf&amp;gt;&amp;lt;TraceId&amp;gt;&amp;lt;/vpbnf&amp;gt; is used to obtain information about the exception trace.  This information can be used for at least two things:&lt;br /&gt;
&lt;br /&gt;
* Determine which kind of exception that is caught, so that it can be decided if and how to handle it&lt;br /&gt;
* Obtain additional information to write to the user, in a log or use for something else&lt;br /&gt;
&lt;br /&gt;
As explained above it is very common that an exception is continued one or more times after it has been raised, so an exception contains a complete &amp;#039;&amp;#039;trace&amp;#039;&amp;#039; of entries (raise, continue, continue, ---).  Subsequently, you will need to search the trace to see if a certain exception is among the entries.  This is done by calling &amp;lt;vp&amp;gt;exception::tryGetDescriptor&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    tryGetDescriptor : (traceId TraceID, exception Exception) -&amp;gt; descriptor Descriptor determ.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exception trace corresponding to &amp;lt;vp&amp;gt;TraceId&amp;lt;/vp&amp;gt; is searched for an exception of the kind &amp;lt;vp&amp;gt;Exception&amp;lt;/vp&amp;gt;.  If there is such an entry in the trace (raised or continued) the corresponding exception descriptor is returned in &amp;lt;vp&amp;gt;Descriptor&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The predicate fails if such an exception is not in the exception trace.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;Descriptor&amp;lt;/vp&amp;gt; contains the extra information about that particular entry in the exception trace:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    descriptor = descriptor(programPointDescriptor ProgramPoint, exception Exception, &lt;br /&gt;
        kind Kind, namedValue* ExtraInfo, gmtTimeValue GMTTime, unsigned ThreadId).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;ProgramPoint&amp;lt;/vp&amp;gt;&lt;br /&gt;
: A readable representation of the &amp;lt;vp&amp;gt;programPoint&amp;lt;/vp&amp;gt; where the exception was raised/continued.&lt;br /&gt;
&amp;lt;vp&amp;gt;Exception&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The &amp;lt;vp&amp;gt;exception&amp;lt;/vp&amp;gt; in question&lt;br /&gt;
&amp;lt;vp&amp;gt;Kind&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The entry kind (&amp;lt;vp&amp;gt;raise&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;continue&amp;lt;/vp&amp;gt;)&lt;br /&gt;
&amp;lt;vp&amp;gt;ExtraInfo&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The extra information provided with this entry in the trace&lt;br /&gt;
&amp;lt;vp&amp;gt;GMTTime&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The time this exception trace entry was raised/continued&lt;br /&gt;
&amp;lt;vp&amp;gt;ExceptionDescription&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The exception description of this entry (this information is also present in &amp;lt;vp&amp;gt;ExceptionInfo&amp;lt;/vp&amp;gt;)&lt;br /&gt;
&amp;lt;vp&amp;gt;ThreadId&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The thread id of the thread that raised/continued this entry&lt;br /&gt;
&lt;br /&gt;
Much of this information is mainly interesting if the exception is not handled.  The information that is most interesting when handling an exception is:&lt;br /&gt;
&lt;br /&gt;
* The exception has been determined to be the one we expected&lt;br /&gt;
* The &amp;lt;vp&amp;gt;ExtraInfo&amp;lt;/vp&amp;gt; for this entry is available for use in messages, etc&lt;br /&gt;
&lt;br /&gt;
The predicate &amp;lt;vp&amp;gt;exception::tryGetExtraInfo&amp;lt;/vp&amp;gt; is convenient for obtaining extra information:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    tryGetExtraInfo : (descriptor Descriptor, string Name) -&amp;gt; value Value determ.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;Descriptor&amp;lt;/vp&amp;gt;&lt;br /&gt;
: Is the description whose extra info we want to get something from.&lt;br /&gt;
&amp;lt;vp&amp;gt;Name&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The name of the extra info parameter we want to obtain.&lt;br /&gt;
&amp;lt;vp&amp;gt;Value&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The value that the mentioned parameter has.&lt;br /&gt;
&lt;br /&gt;
{{example| Code for catching and handling the &amp;lt;vp&amp;gt;fileSystem_api::cannotCreate&amp;lt;/vp&amp;gt; exception can look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    saveInfo(Filename) :-&lt;br /&gt;
        try&lt;br /&gt;
            writeInfo(Filename)&lt;br /&gt;
         catch TraceId do&lt;br /&gt;
              if D = exception::tryGetDescriptor(TraceId, fileSystem_api::cannotCreate) then&lt;br /&gt;
                stdio::write(&amp;quot;Cannot write to the file: &amp;quot;, Filename),&lt;br /&gt;
                if string(Description) = exception::tryGetExtraInfo(D, exception::errorDescription_parameter) then&lt;br /&gt;
                    stdio::writef(&amp;quot;; %&amp;quot;, Description)&lt;br /&gt;
                end if,&lt;br /&gt;
                stdio::write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
            else&lt;br /&gt;
                exception::continue_unknown(TraceId, &amp;quot;Filename = &amp;quot;, Filename)&lt;br /&gt;
            end if&lt;br /&gt;
         end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code here don&amp;#039;t need to obtain the &amp;lt;vp&amp;gt;fileSystem_exception::fileName_parameter&amp;lt;/vp&amp;gt;, because the file name is already known in the &amp;lt;vp&amp;gt;Filename&amp;lt;/vp&amp;gt; variable.&lt;br /&gt;
&lt;br /&gt;
But we can obtain Window&amp;#039;s description of the problem querying for &amp;lt;vp&amp;gt;common_exception::errorDescription_parameter&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039; the exception as unknown if it is not a &amp;lt;vp&amp;gt;cannotCreate&amp;lt;/vp&amp;gt; exception.  For the continue call we add the filename as additional information.  &amp;lt;vp&amp;gt;common_exception::continue_unknown&amp;lt;/vp&amp;gt; will create a string of the extra arguments and add it as an &amp;lt;vp&amp;gt;common_exception::errorArguments_parameter&amp;lt;/vp&amp;gt;.  Such information is mainly for use in the default exception handler to be discussed below.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Exception dumps ===&lt;br /&gt;
&lt;br /&gt;
The class &amp;lt;vp&amp;gt;exceptionDump&amp;lt;/vp&amp;gt; contains predicates for dumping exception traces to &amp;lt;vp&amp;gt;stdio&amp;lt;/vp&amp;gt;, some other &amp;lt;vp&amp;gt;outputStream&amp;lt;/vp&amp;gt; or a &amp;lt;vp&amp;gt;string&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
An exception dump contains three major pieces of information:&lt;br /&gt;
&lt;br /&gt;
* A dump of the call stack (with file names and line numbers) from the point where the exception was raised&lt;br /&gt;
* A dump of the exception-trace with all the information from the exception descriptors&lt;br /&gt;
* Information about the operating system that the program ran on&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;exceptionDump&amp;lt;/vp&amp;gt; have predicates both for dumping exception traces both from a &amp;lt;vp&amp;gt;traceId&amp;lt;/vp&amp;gt; and from a &amp;lt;vp&amp;gt;traceInfo&amp;lt;/vp&amp;gt; obtained with &amp;lt;vp&amp;gt;exception::getTraceInfo&amp;lt;/vp&amp;gt; (see [[#Serializing exceptions]] below).&lt;br /&gt;
&lt;br /&gt;
Dumps for a certain program are in general only useful to the programmers of that program; the users of the program will find dumps cryptic and rather uninteresting.  I.e. the purpose of dumps is to give the programmer means for improving the program.&lt;br /&gt;
&lt;br /&gt;
=== Default handling ===&lt;br /&gt;
&lt;br /&gt;
A program should handle all exceptions, because if an exception is continued or raised at a point where there is no handler the program will terminate with a rather bad error message.  The error message is bad because most exception handling is done in PFC; the language itself knows nothing about exception traces and the like.&lt;br /&gt;
&lt;br /&gt;
To be sure that all exceptions are handled it is normal to set up a default (or fallback) exception handler.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;mainExe::run&amp;lt;/vp&amp;gt; (and &amp;lt;vp&amp;gt;mainExe::runCom&amp;lt;/vp&amp;gt;) which is normally called in the goal setup such a default exception handler: It runs the &amp;lt;vp&amp;gt;main::run&amp;lt;/vp&amp;gt; predicate inside a {{lang2|Terms|try-catch|try-catch}} construction that will handle any exception.&lt;br /&gt;
&lt;br /&gt;
The handler in &amp;lt;vp&amp;gt;mainExe::run&amp;lt;/vp&amp;gt; (and &amp;lt;vp&amp;gt;mainExe::runCom&amp;lt;/vp&amp;gt;) dumps the entire exception trace to output stream in &amp;lt;vp&amp;gt;stdio&amp;lt;/vp&amp;gt;.  And then the program will terminate.  The idea is that:&lt;br /&gt;
&lt;br /&gt;
* Perhaps the user can see something from the dump (which may for example say that &amp;#039;&amp;#039;access is denied&amp;#039;&amp;#039; to &amp;#039;&amp;#039;xxx.txt&amp;#039;&amp;#039;)&lt;br /&gt;
* Alternatively, the developer of the program may use the dump to improve the program&lt;br /&gt;
&lt;br /&gt;
In addition to the handler in &amp;lt;vp&amp;gt;mainExe::run&amp;lt;/vp&amp;gt; a GUI program also set a default handler in the event loop.  This handler is set by calling &amp;lt;vp&amp;gt;applicationWindow::setErrorResponder&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    errorResponder = (applicationWindow Source, exception::traceId TraceId).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    setErrorResponder : (errorResponder Responder).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default the error responder &amp;lt;vp&amp;gt;errorPresentationDialog::present&amp;lt;/vp&amp;gt; is used.  The functioning of the &amp;lt;pv&amp;gt;errorPresentationDialog&amp;lt;/vp&amp;gt; is closely related to a categorization of exceptions described in the next section.&lt;br /&gt;
&lt;br /&gt;
PFC place exceptions in three major categories based on who is (believed to be) responsible:&lt;br /&gt;
&lt;br /&gt;
; Internal errors&lt;br /&gt;
: An exceptional state which the programmer is responsible to deal with&lt;br /&gt;
; User exception&lt;br /&gt;
: An exception which can perhaps be solved by the end user of the program, but which may also call for a programmer solution.  User exceptions carries a message for the end user of the program.&lt;br /&gt;
; Definite user errors&lt;br /&gt;
: An exception which is definitely one the end user should deal with, because the programmer cannot do anything about it anyway&lt;br /&gt;
&lt;br /&gt;
You may notice that &amp;quot;error&amp;quot; is used to signal that a person is (believed to be) responsible for the problem, where as &amp;quot;exception&amp;quot; also covers situations with looser relation to specific persons (such as a network failure).&lt;br /&gt;
&lt;br /&gt;
==== Internal errors ====&lt;br /&gt;
&lt;br /&gt;
Internal errors are caused and/or should be prevented by the programmer of the program.&lt;br /&gt;
&lt;br /&gt;
{{Example| A predicate takes two lists as argument and pair the elements of the lists.  So the lists are expected to have the same length.  If the lists have different lengths it is appropriate to raise an &amp;lt;vp&amp;gt;internal_error&amp;lt;/vp&amp;gt;, because it is clearly the responsibility of the programmer to ensure that the lists have same length; the end-user of the program can at most influence this indirectly.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== User exceptions ====&lt;br /&gt;
&lt;br /&gt;
User exceptions typically deal with problems related to external resources such as files, network, databases, web servers, etc.  Often the user will become wiser by being informed about the problem and often the user may even solve the problem.&lt;br /&gt;
&lt;br /&gt;
{{Example|  The read-only file problem discussed above is a typical example of a user exception.  It is the user rather than the programmer that can solve the problem with the read-only file.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
A user exception is distinguished by having extra information in a field with name &amp;lt;vp&amp;gt;common_exception::userMessage_parameter&amp;lt;/vp&amp;gt;.  This extra info should be a message with relevance for an end user of the program.  The message can reference other extra info parameters using the format %PARAM.  The preferred way to raise user exceptions is by means of the predicate &amp;lt;vp&amp;gt;exception::raise_user&amp;lt;/vp&amp;gt;.  Likewise you can continue exceptions with a user message using &amp;lt;vp&amp;gt;exception::continue_user&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Example| This predicate will raise a &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;user&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;lt;vp&amp;gt;fileSystem_api::cannotCreate&amp;lt;/vp&amp;gt; exception&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    raise_cannotCreate : (string Filename) erroneous.&lt;br /&gt;
clauses&lt;br /&gt;
    raise_cannotCreate(Filename) :-&lt;br /&gt;
        exception::raise_user(fileSystem_api::cannotCreate,&lt;br /&gt;
            &amp;quot;It is not possible to create the file %Filename&amp;quot;,&lt;br /&gt;
            [namedValue(&amp;quot;Filename&amp;quot;, string(Filename))]).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The use of &amp;lt;vp&amp;gt;&amp;quot;%Filename&amp;quot;&amp;lt;/vp&amp;gt; in the message corresponds to the extra info &amp;lt;vp&amp;gt;&amp;quot;Filename&amp;quot;&amp;lt;/vp&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The predicate &amp;lt;vp&amp;gt;exceptionDump::tryGetUserMessage&amp;lt;/vp&amp;gt; will return a user message from a &amp;lt;vp&amp;gt;traceId&amp;lt;/vp&amp;gt; if possible.  The message will consist of all user messages from the entire trace and will have parameters substituted.&lt;br /&gt;
&lt;br /&gt;
{{Example|  Given &amp;lt;vp&amp;gt;raise_cannotCreate&amp;lt;/vp&amp;gt; from above and calling &amp;lt;vp&amp;gt;test&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    test() :-&lt;br /&gt;
        try&lt;br /&gt;
            raise_cannotCreate(&amp;quot;test.xxx&amp;quot;)&lt;br /&gt;
         catch TraceId do&lt;br /&gt;
            if UserMsg = exceptionDump::tryGetUserMessage(TraceId) then&lt;br /&gt;
                stdio::write(UserMsg)&lt;br /&gt;
            end if&lt;br /&gt;
         end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following message is written to &amp;lt;vp&amp;gt;stdio&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;It is not possible to create the file test.xxx&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Definite user errors ====&lt;br /&gt;
&lt;br /&gt;
Definite user errors are exceptions that are solely the responsibility of the user of the program.  For example wrong use of the program.&lt;br /&gt;
&lt;br /&gt;
{{Example| A program can write out some information, but only if the user has specified which information to write.  So if the user invoke the functionality without having specified which information to write, it is appropriate to raise a definite user error.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
A definite user exception is distinguished by adding &amp;lt;vp&amp;gt;true&amp;lt;/vp&amp;gt; as extra info for the parameter &amp;lt;vp&amp;gt;exception::definiteUserError_parameter&amp;lt;/vp&amp;gt;.  The preferred way to do this is by using the predicates:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;exception::raise_definiteUser&amp;lt;/vp&amp;gt;&lt;br /&gt;
* &amp;lt;vp&amp;gt;exception::continue_definiteUser&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The use of these predicates is the same as the user of &amp;lt;vp&amp;gt;common_exception::raise_user&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;common_exception::continue_user&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
An exception trace is considered a definite user error if one (or more) entries in the trace carries the &amp;lt;vp&amp;gt;exception::definiteUserError_parameter&amp;lt;/vp&amp;gt;.  The predicate &amp;lt;vp&amp;gt;exception::isDefiniteUserError&amp;lt;/vp&amp;gt; will succeed for definite user errors.&lt;br /&gt;
&lt;br /&gt;
=== Serializing exceptions ===&lt;br /&gt;
&lt;br /&gt;
In some situations the best way to handle  an exception is by sending all the information about the exception somewhere else.  A server might for example want to send the information to the client program that caused the exception, because then there is a user that can take action.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;vp&amp;gt;traceId&amp;lt;/vp&amp;gt; only have a meaning in the process that has created it, but the predicate &amp;lt;vp&amp;gt;exception::getTraceInfo&amp;lt;/vp&amp;gt; can create a &amp;lt;vp&amp;gt;traceInfo&amp;lt;/vp&amp;gt; structure (&amp;lt;vp&amp;gt;TraceInfo&amp;lt;/vp&amp;gt;) from the &amp;lt;vp&amp;gt;traceId TraceId&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    getTraceInfo : (traceId TraceId) -&amp;gt; traceInfo TraceInfo.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Such a structure is a functor structure that can be serialized/deserialized with &amp;lt;vp&amp;gt;toString&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;toTerm&amp;lt;/vp&amp;gt;; &amp;lt;vp&amp;gt;write&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;read&amp;lt;/vp&amp;gt;; nested in a fact database using &amp;lt;vp&amp;gt;save&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;consult&amp;lt;/vp&amp;gt;; etc.&lt;br /&gt;
&lt;br /&gt;
==== Packed Exceptions ====&lt;br /&gt;
&lt;br /&gt;
Some times, e.g., in a client/server application, you catch an exception on the server which you want to handle on the client. In that case you can serialize the exception on the server send it to the client and reraise it as a packed exception.&lt;br /&gt;
&lt;br /&gt;
On the server&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
try&lt;br /&gt;
   ...&lt;br /&gt;
catch E do&lt;br /&gt;
   sendExceptionToClient(exception::getTraceInfo())&lt;br /&gt;
end try,&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the client&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
Rtn = remoteCall(...),&lt;br /&gt;
if error(TraceInfo) = Rtn then&lt;br /&gt;
    exception::raise_packed(TraceInfo, &amp;quot;remoteCall returned an exception&amp;quot;)&lt;br /&gt;
end if&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The predicate &amp;lt;vp&amp;gt;raise_packed&amp;lt;/vp&amp;gt; works like a &amp;lt;vp&amp;gt;continue_unknown&amp;lt;/vp&amp;gt; but continues a serialized exception instead of normal exception. It is meant to be used when the exception stem from another program and thus only is available in serialized form.&lt;br /&gt;
&lt;br /&gt;
=== The error presentation dialog  ===&lt;br /&gt;
&lt;br /&gt;
The error presentation dialog (in the class &amp;lt;vp&amp;gt;errorPresentationDialog&amp;lt;/vp&amp;gt;) is by default used by the default exception handling in a GUI program.  Its behavior is closely related to the classification of exceptions described above, as described by these two rules:&lt;br /&gt;
&lt;br /&gt;
* If the exception trace carries a user message, this message will be presented to the user.&lt;br /&gt;
* If the exception trace is not a definite user error, there will be information for the programmer&lt;br /&gt;
&lt;br /&gt;
So if the exception is an internal error there will only be information for the programmer; if it is a user exception there will both be information for the user and for the programmer; and if it is a user error there will only be information for the user.&lt;br /&gt;
&lt;br /&gt;
If there is information to the programmer the exception dialog will have a details/less details button that can show/hide the programmer information.  It will also have a &amp;quot;report error&amp;quot; button, which by default will copy the information to the clipboard so that the user can easily send it to the programmer.&lt;br /&gt;
&lt;br /&gt;
[[Image:ErrorPresentationDialogDefault.png]]&lt;br /&gt;
&lt;br /&gt;
The dialog is customizable by means of various properties:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;properties&lt;br /&gt;
    title : string. % := &amp;quot;Error&amp;quot;.&lt;br /&gt;
    callBackBtnText : string. % := &amp;quot;&amp;amp;Copy&amp;quot;.&lt;br /&gt;
    dontCallBackBtnText : string. % := &amp;quot;&amp;amp;OK&amp;quot;.&lt;br /&gt;
    showDetailsBtnText : string. % := &amp;quot;Show &amp;amp;Details&amp;quot;.&lt;br /&gt;
    hideDetailsBtnText : string. % := &amp;quot;Hide &amp;amp;Details&amp;quot;.&lt;br /&gt;
    closeApplicationBtnText : string. % := &amp;quot;Close &amp;amp;Application&amp;quot;.&lt;br /&gt;
    commentTextPromt : string. % := &amp;quot;Please describe what you were doing when the error occured:&amp;quot;&lt;br /&gt;
    internalErrorMessage : string. %  := &amp;quot;An internal error has occurred.\nPlease send a bug report to your vendor.&amp;quot;.&lt;br /&gt;
    feedbackMessage : string. %  := &amp;quot;Please send your feedback.&amp;quot;.&lt;br /&gt;
    definiteUserErrorIcon : vpiDomains::resid.&lt;br /&gt;
    userErrorIcon : vpiDomains::resid.&lt;br /&gt;
    internalErrorIcon : vpiDomains::resid.&lt;br /&gt;
    reportErrorDelegate : reportErrorDelegate.&lt;br /&gt;
    extraInfoWriter : writer.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All texts and labels are controlled by properties.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;extraInfoWriter&amp;lt;/vp&amp;gt; is a callback that can be set to include extra info for the programmer.  This information will both be presented in the details window and reported back to the programmer if the user press the &amp;quot;report error&amp;quot; button (i.e. the button which is by default labeled &amp;#039;&amp;#039;&amp;#039;Copy&amp;#039;&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;extraInfoWriter&amp;lt;/vp&amp;gt; callback predicate must have this type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    writer = (outputStream Stream).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The dialog will invoke the predicate and then it should simply write extra information to the received stream.&lt;br /&gt;
&lt;br /&gt;
{{Example| The Visual Prolog IDE uses the &amp;lt;vp&amp;gt;extraInfoWriter&amp;lt;/vp&amp;gt; to write version information, information about the open project and information about the last actions carried out in the IDE.  This information will help the programmers to analyze the problem.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The action performed by the &amp;quot;report error&amp;quot; button is customizable using the property &amp;lt;vp&amp;gt;reportErrorDelegate&amp;lt;/vp&amp;gt;, which is a callback predicate of this type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    reportErrorDelegate = (window Parent, string Comment, optional{exception::traceInfo} TraceInfo, string ExtraInfo).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;vp&amp;gt;Parent&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The error presentation dialog which can be used as parent for additional dialogs.&lt;br /&gt;
; &amp;lt;vp&amp;gt;Comment&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The users comment from the comment box.&lt;br /&gt;
; &amp;lt;vp&amp;gt;TraceInfo&amp;lt;/vp&amp;gt;&lt;br /&gt;
: If the dialog is invoked on an exception the trace info is here, if it is invoked for feedback this value is &amp;lt;vp&amp;gt;none&amp;lt;/vp&amp;gt;&lt;br /&gt;
; &amp;lt;vp&amp;gt;ExtraInfo&amp;lt;/vp&amp;gt;&lt;br /&gt;
: The extra info written by the &amp;lt;vp&amp;gt;extraInfoWriter&amp;lt;/vp&amp;gt; callback&lt;br /&gt;
&lt;br /&gt;
{{Example| In the Visual Prolog IDE the &amp;lt;vp&amp;gt;reportErrorDelegate&amp;lt;/vp&amp;gt; will send the exception information to a WEB service which will insert the notification in a database.  The notifications in the database will then be used to improve the IDE.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>EJP</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Lists_and_Recursion&amp;diff=4334</id>
		<title>Lists and Recursion</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Lists_and_Recursion&amp;diff=4334"/>
		<updated>2016-11-03T10:26:24Z</updated>

		<summary type="html">&lt;p&gt;EJP: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;List processing – handling sequences of elements – is a powerful technique in Prolog. In this tutorial, we explain what lists are and how to declare them, and then give several examples that show how you might use list processing in your own applications. We also define two well known Prolog predicates – member and append – while looking at list processing from both a recursive and a procedural standpoint.&lt;br /&gt;
&lt;br /&gt;
After that, we introduce findall, a Visual Prolog standard predicate that enables you to find and collect all solutions to a single goal. We round out this tutorial with a discussion of compound lists – combinations of different types of elements – and an example of parsing by difference lists.&lt;br /&gt;
&lt;br /&gt;
==What Is a List?==&lt;br /&gt;
&lt;br /&gt;
In Prolog, &amp;#039;&amp;#039;a list&amp;#039;&amp;#039; is an object that contains an arbitrary number of other objects within it. Lists correspond roughly to arrays in other languages, but, unlike an array, a list does not require you to declare how big it will be before you use it.&lt;br /&gt;
&lt;br /&gt;
A list that contains the numbers 1, 2, and 3 is written as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;[ 1, 2, 3 ]&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The order of the elements in this list matters:&lt;br /&gt;
&lt;br /&gt;
*Number &amp;quot;1&amp;quot; is the first element,&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;2&amp;quot; - the second,&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;3&amp;quot; - the third.&lt;br /&gt;
&lt;br /&gt;
The list [ 1, 2, 3 ] is different from the list [ 1, 3, 2 ].&lt;br /&gt;
&lt;br /&gt;
Each item contained in the list is known as an element. To form a list data structure, you separate the elements of a list with commas and then enclose them in square brackets. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;[&amp;quot;dog&amp;quot;, &amp;quot;cat&amp;quot;, &amp;quot;canary&amp;quot;]&lt;br /&gt;
[&amp;quot;valerie ann&amp;quot;, &amp;quot;jennifer caitlin&amp;quot;, &amp;quot;benjamin thomas&amp;quot;]&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The same element can be present in the list several times, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;[ 1, 2, 1, 3, 1 ]&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Declaring Lists ==&lt;br /&gt;
&lt;br /&gt;
To declare the domain for a list of integers, you use the domains declaration, like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    integer_list = integer*.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The asterisk means &amp;quot;list of&amp;quot;; that is, integer* means &amp;quot;list of integers.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Note that the word &amp;#039;&amp;#039;&amp;quot;list&amp;quot;&amp;#039;&amp;#039; has no special meaning in Visual Prolog. You could equally well have called your list domain &amp;#039;&amp;#039;zanzibar&amp;#039;&amp;#039;. It is the asterisk, not the name that signifies a list domain.&lt;br /&gt;
&lt;br /&gt;
The elements in a list can be anything, including other lists. However, all elements in a list must belong to the same domain, and in addition to the declaration of the list domain, there must be a &amp;#039;&amp;#039;&amp;#039;domains&amp;#039;&amp;#039;&amp;#039; declaration for the elements:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    element_list = elements*.&lt;br /&gt;
    elements = ....&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; must be defined to a single domain type (for example, integer, real, or symbol) or to a set of alternatives marked with different functors. Visual Prolog does not allow you to mix standard types in a list. For example, the following declarations would not properly indicate a list made up of integers, reals, and symbols:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;element_list = elements*.&lt;br /&gt;
elements =&lt;br /&gt;
    integer; % Incorrect&lt;br /&gt;
    real;&lt;br /&gt;
    symbol.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The way to declare a list made up of integers, reals, and symbols is to define a single domain comprising all three types, with functors to show which type a particular element belongs to. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;element_list = elements*.&lt;br /&gt;
elements =&lt;br /&gt;
    i(integer);&lt;br /&gt;
    r(real);&lt;br /&gt;
    s(symbol). % the functors are i, r, and s&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(For more information about this, refer to &amp;quot;Compound Lists&amp;quot; later in this tutorial.)&lt;br /&gt;
&lt;br /&gt;
== Heads and Tails ==&lt;br /&gt;
&lt;br /&gt;
A list is really a recursive compound object. It consists of two parts: the head, of a list, which is the first element, and the tail, which is a list comprising all the subsequent elements.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;The tail of a list is always a list; the head of a list is an element.&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
For example,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;the head of [a, b, c] is a&lt;br /&gt;
the tail of [a, b, c] is [b, c]&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What happens when you get down to a one-element list? The answer is that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;the head of [c] is c&lt;br /&gt;
the tail of [c] is []&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;If you take the first element from the tail of a list enough times, you will eventually get down to an empty list (&amp;#039;&amp;#039;&amp;#039;[ ]&amp;#039;&amp;#039;&amp;#039;).&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;The empty list cannot be broken into head and tail.&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
This means that, conceptually, lists have a tree structure just like other compound objects. The tree structure of [a, b, c, d] is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;    list&lt;br /&gt;
   /    \&lt;br /&gt;
  a    list&lt;br /&gt;
      /    \&lt;br /&gt;
     b    list&lt;br /&gt;
         /    \&lt;br /&gt;
        c    list&lt;br /&gt;
            /    \&lt;br /&gt;
           d      []&amp;lt;/pre&amp;gt;Further, a one-element list such as [a] is not the same as the element that it contains, because [a] is really the compound data structure shown here:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;    list&lt;br /&gt;
   /    \&lt;br /&gt;
  a     []&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==List Processing==&lt;br /&gt;
&lt;br /&gt;
Prolog provides a way to make a head and a tail of a list explicit. Instead of separating elements with commas, you can separate the head and tail with a vertical bar (|). For instance,&lt;br /&gt;
&amp;lt;vip&amp;gt;[a, b, c]&amp;lt;/vip&amp;gt;&lt;br /&gt;
is equivalent to&lt;br /&gt;
&amp;lt;vip&amp;gt;[ a | [b, c] ]&amp;lt;/vip&amp;gt;&lt;br /&gt;
which continuing the process is equivalent to &lt;br /&gt;
&amp;lt;vip&amp;gt;[ a | [ b | [ c ] ] ]&amp;lt;/vip&amp;gt;&lt;br /&gt;
which is equivalent to&lt;br /&gt;
&amp;lt;vip&amp;gt;[ a | [ b | [ c | [] ] ] ]&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can even use both kinds of separators in the same list, provided the vertical bar is the last separator. So, if you really want to, you can write [a, b, c, d] as [a, b|[c, d]].&lt;br /&gt;
&lt;br /&gt;
Table 1 gives more examples.&lt;br /&gt;
{|cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+&amp;#039;&amp;#039;&amp;#039;Table 1: Heads and Tails of Lists&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
! List&lt;br /&gt;
! Head&lt;br /&gt;
! Tail&lt;br /&gt;
|-&lt;br /&gt;
| [&amp;#039;a&amp;#039;, &amp;#039;b&amp;#039;, &amp;#039;c&amp;#039;]&lt;br /&gt;
| &amp;#039;a&amp;#039;&lt;br /&gt;
| [&amp;#039;b&amp;#039;, &amp;#039;c&amp;#039;]&lt;br /&gt;
|-&lt;br /&gt;
| [ &amp;#039;a&amp;#039; ]&lt;br /&gt;
| &amp;#039;a&amp;#039;&lt;br /&gt;
| [] &lt;br /&gt;
|-&lt;br /&gt;
| []&lt;br /&gt;
| does not exist&lt;br /&gt;
| does not exist&lt;br /&gt;
|-&lt;br /&gt;
| [[1, 2, 3], [2, 3, 4], []]&lt;br /&gt;
| [1, 2, 3]&lt;br /&gt;
| [[2, 3, 4], []]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Table 2 gives several examples of list unification.&lt;br /&gt;
&lt;br /&gt;
{|cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+&amp;#039;&amp;#039;&amp;#039;Table 2: Unification of Lists&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
!List 1&lt;br /&gt;
!List 2&lt;br /&gt;
!Variable Binding&lt;br /&gt;
|-&lt;br /&gt;
|[X, Y, Z]&lt;br /&gt;
|[egbert, eats, icecream]&lt;br /&gt;
|X=egbert, Y=eats, Z=icecream&lt;br /&gt;
|-&lt;br /&gt;
|[7]&lt;br /&gt;
|[X &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; Y] &lt;br /&gt;
|X=7, Y=[]&lt;br /&gt;
|-&lt;br /&gt;
|[1, 2, 3, 4]&lt;br /&gt;
|[X, Y &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; Z]&lt;br /&gt;
|X=1, Y=2, Z=[3,4]&lt;br /&gt;
|-&lt;br /&gt;
|[1, 2]&lt;br /&gt;
|[3 &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; X]&lt;br /&gt;
|fail&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Using Lists==&lt;br /&gt;
&lt;br /&gt;
Because a list is really a recursive compound data structure, you need recursive algorithms to process it. The most basic way to process a list is to work through it, doing something to each element until you reach the end.&lt;br /&gt;
&lt;br /&gt;
An algorithm of this kind usually needs two clauses. One of them says what to do with an ordinary list (one that can be divided into a head and a tail). The other says what to do with an empty list.&lt;br /&gt;
&lt;br /&gt;
===Writing Lists===&lt;br /&gt;
&lt;br /&gt;
For example, if you just want to print out the elements of the list, here is what you do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class my&lt;br /&gt;
    predicates&lt;br /&gt;
        write_a_list : (integer*).&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement my&lt;br /&gt;
    clauses&lt;br /&gt;
        write_a_list([]).&lt;br /&gt;
            /* If the list is empty, do nothing more. */&lt;br /&gt;
        write_a_list([H|T]):-&lt;br /&gt;
            /* Match the head to H and the tail to T, then... */&lt;br /&gt;
            stdio::write(H),stdio::nl,&lt;br /&gt;
            write_a_list(T).&lt;br /&gt;
end implement&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    my::write_a_list([1, 2, 3]).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here are the two write_a_list clauses described in natural language:&lt;br /&gt;
&lt;br /&gt;
*To write an empty list, do nothing.&lt;br /&gt;
&lt;br /&gt;
*Otherwise, to write a list, write its head (which is a single element), then write its tail (a list).&lt;br /&gt;
&lt;br /&gt;
The first time through, the goal is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;my::write_a_list([1, 2, 3]).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This matches the second clause, with H=1 and T=[2, 3]; this writes 1 and then calls write_a_list recursively with the tail of the list:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;my::write_a_list([2, 3]).&lt;br /&gt;
        /* This is write_a_list(T). */&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This recursive call matches the second clause, this time with H=2 and T=[3], so it writes 2 and again calls write_a_list recursively:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;my::write_a_list([3]).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, which clause will this goal match? Recall that, even though the list [3] has only one element; it does have a head and tail; the head is 3 and the tail is []. So, again the goal matches the second clause, with H=3 and T=[]. Hence, 3 is written and write_a_list is called recursively like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;my::write_a_list([]).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you see why this program needs the first clause. The second clause will not match this goal because [] cannot be divided into head and tail. So, if the first clause were not there, the goal would fail. As it is, the first clause matches and the goal succeeds without doing anything further.&lt;br /&gt;
&lt;br /&gt;
===Counting List Elements===&lt;br /&gt;
&lt;br /&gt;
Now consider how you might find out how many elements are in a list. What is the length of a list, anyway? Here is a simple logical definition:&lt;br /&gt;
&lt;br /&gt;
The length of [] is 0.&amp;lt;br /&amp;gt;&lt;br /&gt;
The length of any other list is 1 plus the length of its tail.&lt;br /&gt;
&lt;br /&gt;
Can you implement this? In Prolog it is very easy. It takes just two clauses:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class my&lt;br /&gt;
    predicates&lt;br /&gt;
        length_of : (A*, integer) procedure(i,o).&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement my&lt;br /&gt;
    clauses&lt;br /&gt;
        length_of([], 0).&lt;br /&gt;
        length_of([_|T], L):-&lt;br /&gt;
            length_of(T, TailLength),&lt;br /&gt;
            L = TailLength + 1.&lt;br /&gt;
end implement&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    my::length_of([1, 2, 3], L),&lt;br /&gt;
    stdio::write(L).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Take a look at the second clause first. Crucially, [_|T] will match any nonempty list, binding T to the tail of the list. The value of the head is unimportant; as long as it exists, it can be counted it as one element.&lt;br /&gt;
&lt;br /&gt;
So the goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;my::length_of([1, 2, 3], L)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will match the second clause, with T=[2, 3]. The next step is to compute the length of T. When this is done (never mind how), TailLength will get the value 2, and the computer can then add 1 to it and bind L to 3.So how is the middle step executed? That step was to find the length of [2, 3] by satisfying the goal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;my::length_of([2, 3], TailLength)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In other words, length_of calls itself recursively. This goal matches the second clause, binding&lt;br /&gt;
&lt;br /&gt;
*[3] in the goal to T in the clause and&lt;br /&gt;
&lt;br /&gt;
*TailLength in the goal to L in the clause.&lt;br /&gt;
&lt;br /&gt;
Recall that TailLength in the goal will not interfere with TailLength in the clause, because &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;each recursive invocation of a clause has its own set of variables&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
So now the problem is to find the length of [3], which will be 1, and then add 1 to that to get the length of [2, 3], which will be 2. So far, so good.&lt;br /&gt;
&lt;br /&gt;
Likewise, length_of will call itself recursively again to get the length of [3]. The tail of [3] is [], so T is bound to [], and the problem is to get the length of [], then add 1 to it, giving the length of [3].&lt;br /&gt;
&lt;br /&gt;
This time it&amp;#039;s easy. The goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;my::length_of([], TailLength)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
matches the &amp;#039;&amp;#039;first&amp;#039;&amp;#039; clause, binding TailLength to 0. So now the computer can add 1 to that, giving the length of [3], and return to the calling clause. This, in turn, will add 1 again, giving the length of [2, 3], and return to the clause that called it; this original clause will add 1 again, giving the length of [1, 2, 3].&lt;br /&gt;
&lt;br /&gt;
Confused yet? We hope not. In the following brief illustration we&amp;#039;ll summarize the calls. We&amp;#039;ve used subscripts to indicate that similarly named variables in different clauses – or different invocations of the same clause – are distinct. Please notice that you do not need to implement such predicate in your own code, you can use &amp;#039;&amp;#039;&amp;#039;list::length&amp;#039;&amp;#039;&amp;#039; predicate from PFC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;my::length_of([1, 2, 3], L1).&lt;br /&gt;
my::length_of([2, 3], L2).&lt;br /&gt;
my::length_of([3], L3).&lt;br /&gt;
my::length_of([], 0).&lt;br /&gt;
L3 =  0+1 = 1.&lt;br /&gt;
L2 = L3+1 = 2.&lt;br /&gt;
L1 = L2+1 = 3.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tail Recursion===&lt;br /&gt;
&lt;br /&gt;
You probably noticed that length_of is not, and can&amp;#039;t be, tail-recursive, because the recursive call is not the last step in its clause. Can you create a tail-recursive list-length predicate? Yes, but it will take some effort.&lt;br /&gt;
&lt;br /&gt;
The problem with length_of is that you can&amp;#039;t compute the length of a list until you&amp;#039;ve already computed the length of the tail. It turns out there&amp;#039;s a way around this. You&amp;#039;ll need a list-length predicate with three arguments.&lt;br /&gt;
&lt;br /&gt;
*One is the list, which the computer will whittle away on each call until it eventually becomes empty, just as before.&lt;br /&gt;
&lt;br /&gt;
*Another is a free argument that will ultimately contain the result (the length).&lt;br /&gt;
&lt;br /&gt;
*The third is a counter that starts out as 0 and increments on each call.&lt;br /&gt;
&lt;br /&gt;
When the list is finally empty, you&amp;#039;ll unify the counter with the (up to then) unbound result.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class my&lt;br /&gt;
    predicates&lt;br /&gt;
        length_of : (A*, integer, integer)&lt;br /&gt;
            procedure(i,o,i).&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement my&lt;br /&gt;
    clauses&lt;br /&gt;
        length_of([], Result, Result).&lt;br /&gt;
        length_of([_|T], Result, Counter):-&lt;br /&gt;
            NewCounter = Counter + 1,&lt;br /&gt;
            length_of(T, Result, NewCounter).&lt;br /&gt;
end implement&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    my::length_of([1, 2, 3], L, 0), /* start with Counter = 0 */&lt;br /&gt;
    stdio::write(&amp;quot; L = &amp;quot;, L).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This version of the length_of predicate is more complicated, and in many ways less logical, than the previous one. We&amp;#039;ve presented it merely to show you that, by devious means, &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;you can often find a tail-recursive algorithm for a problem that seems to demand a different type of recursion&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== Another Example – Modifying the List ===&lt;br /&gt;
&lt;br /&gt;
Sometimes you want to take a list and create another list from it. You do this by working through the list element by element, replacing each element with a computed value. For example, here is a program that takes a list of numbers and adds 1 to each of them:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class my&lt;br /&gt;
    predicates&lt;br /&gt;
        add1 : (integer*, integer*) procedure(i,o).&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement my&lt;br /&gt;
    clauses&lt;br /&gt;
        add1([], []).&lt;br /&gt;
            /* boundary condition */&lt;br /&gt;
        add1([Head|Tail],[Head1|Tail1]):-&lt;br /&gt;
            /* separate the head */&lt;br /&gt;
            /* from the rest of the list */&lt;br /&gt;
            Head1 = Head+1,&lt;br /&gt;
            /* add 1 to the first element */&lt;br /&gt;
            add1(Tail, Tail1).&lt;br /&gt;
            /* call element with the rest of the list */&lt;br /&gt;
end implement&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    my::add1([1,2,3,4], NewList),&lt;br /&gt;
    stdio::write(NewList)).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To paraphrase this in natural language:&lt;br /&gt;
&lt;br /&gt;
To add 1 to all the elements of the empty list,&amp;lt;br /&amp;gt;&lt;br /&gt;
just produce another empty list.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
To add 1 to all the elements of any other list,&amp;lt;br /&amp;gt;&lt;br /&gt;
add 1 to the head and make it the head of the result, and then&amp;lt;br /&amp;gt;&lt;br /&gt;
add 1 to each element of the tail and make that the tail of the result.&lt;br /&gt;
&lt;br /&gt;
Load the program, and run the goal with the specified goal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;add1([1,2,3,4], NewList).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The goal will return&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code language=&amp;quot;text&amp;quot;&amp;gt;NewList=[2,3,4,5]&lt;br /&gt;
1 Solution&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tail Recursion Again ===&lt;br /&gt;
&lt;br /&gt;
Is add1 tail-recursive? If you&amp;#039;re accustomed to using Lisp or Pascal, you might think it isn&amp;#039;t, because you think of it as performing the following operations:&lt;br /&gt;
&lt;br /&gt;
*Split the list into &amp;#039;&amp;#039;Head&amp;#039;&amp;#039; and &amp;#039;&amp;#039;Tail&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
*Add 1 to &amp;#039;&amp;#039;Head&amp;#039;&amp;#039;, giving &amp;#039;&amp;#039;Head1&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
*Recursively add 1 to all the elements of &amp;#039;&amp;#039;Tail&amp;#039;&amp;#039;, giving &amp;#039;&amp;#039;Tail1&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
*Combine &amp;#039;&amp;#039;Head1&amp;#039;&amp;#039; and &amp;#039;&amp;#039;Tail1&amp;#039;&amp;#039;, giving the resulting list.&lt;br /&gt;
&lt;br /&gt;
This isn&amp;#039;t tail-recursive, because the recursive call is not the last step.&lt;br /&gt;
&lt;br /&gt;
But – and this is important – &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;that is not how Prolog does it&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;. In Visual Prolog, add1 is tail-recursive, because its steps are really the following:&lt;br /&gt;
&lt;br /&gt;
*Bind the head and tail of the original list to &amp;#039;&amp;#039;Head&amp;#039;&amp;#039; and &amp;#039;&amp;#039;Tail&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
*Bind the head and tail of the result to &amp;#039;&amp;#039;Head1&amp;#039;&amp;#039; and &amp;#039;&amp;#039;Tail1&amp;#039;&amp;#039;. (&amp;#039;&amp;#039;Head1&amp;#039;&amp;#039; and &amp;#039;&amp;#039;Tail1&amp;#039;&amp;#039; do not have values yet.)&lt;br /&gt;
&lt;br /&gt;
*Add 1 to &amp;#039;&amp;#039;Head&amp;#039;&amp;#039;, giving &amp;#039;&amp;#039;Head1&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
*Recursively add 1 to all the elements of &amp;#039;&amp;#039;Tail&amp;#039;&amp;#039;, giving &amp;#039;&amp;#039;Tail1&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
When this is done, &amp;#039;&amp;#039;Head1&amp;#039;&amp;#039; and &amp;#039;&amp;#039;Tail1&amp;#039;&amp;#039; are &amp;#039;&amp;#039;already&amp;#039;&amp;#039; the head and tail of the result; there is no separate operation of combining them. So the recursive call really is the last step.&lt;br /&gt;
&lt;br /&gt;
=== More on Modifying Lists ===&lt;br /&gt;
&lt;br /&gt;
Of course, you don&amp;#039;t actually need to put in a replacement for every element. Here&amp;#039;s a program that scans a list of numbers and copies it, leaving out the negative numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class my&lt;br /&gt;
    predicates&lt;br /&gt;
        discard_negatives : (integer*, integer*) procedure(i,o).&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement my&lt;br /&gt;
    clauses&lt;br /&gt;
        discard_negatives([], []).&lt;br /&gt;
        discard_negatives([H|T], ProcessedTail):-&lt;br /&gt;
            H &amp;lt; 0,&lt;br /&gt;
            !,    /* If H is negative, just skip it */&lt;br /&gt;
            discard_negatives(T, ProcessedTail).&lt;br /&gt;
        discard_negatives([H|T], [H|ProcessedTail]):-&lt;br /&gt;
            discard_negatives(T, ProcessedTail).&lt;br /&gt;
end implement&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    my::discard_negatives ([2, -45, 3, 468], X),&lt;br /&gt;
    stdio::write(X).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, the goal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;my::discard_negatives([2, -45, 3, 468], X)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gives&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;X=[2, 3, 468].&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And here&amp;#039;s a predicate that copies the elements of a list, making each element occur twice:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;doubletalk([], []).&lt;br /&gt;
doubletalk([H|T], [H, H|DoubledTail]) :-&lt;br /&gt;
    doubletalk(T, DoubledTail).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===List Membership===&lt;br /&gt;
&lt;br /&gt;
Suppose you have a list with the names &amp;#039;&amp;#039;John&amp;#039;&amp;#039;, &amp;#039;&amp;#039;Leonard&amp;#039;&amp;#039;, &amp;#039;&amp;#039;Eric&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;Frank&amp;#039;&amp;#039; and would like to use Visual Prolog to investigate if a given name is in this list. In other words, you must express the relation &amp;quot;membership&amp;quot; between two arguments: a name and a list of names. This corresponds to the predicate&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;isMember : (name, name*).&lt;br /&gt;
    /* &amp;quot;name&amp;quot; is a member of &amp;quot;name*&amp;quot; */&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the e01.pro program, the first clause investigates the head of the list. If the head of the list is equal to the name you&amp;#039;re searching for, then you can conclude that Name is a member of the list. Since the tail of the list is of no interest, it is indicated by the anonymous variable. Thanks to this first clause, the goal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;my::isMember(&amp;quot;john&amp;quot;, [&amp;quot;john&amp;quot;, &amp;quot;leonard&amp;quot;, &amp;quot;eric&amp;quot;, &amp;quot;frank&amp;quot;])&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is satisfied.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;/* Program e01.pro */&lt;br /&gt;
class my&lt;br /&gt;
    predicates&lt;br /&gt;
       isMember : (A, A*) determ.&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement my&lt;br /&gt;
    clauses&lt;br /&gt;
       isMember(Name, [Name|_]) :-&lt;br /&gt;
          !.&lt;br /&gt;
       isMember(Name, [_|Tail]):-&lt;br /&gt;
          isMember(Name,Tail).&lt;br /&gt;
end implement&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
   console::init(),&lt;br /&gt;
   my::isMember(&amp;quot;john&amp;quot;, [&amp;quot;john&amp;quot;, &amp;quot;leonard&amp;quot;, &amp;quot;eric&amp;quot;, &amp;quot;frank&amp;quot;]),&lt;br /&gt;
   !,&lt;br /&gt;
   stdio::write(&amp;quot;Success&amp;quot;)&lt;br /&gt;
   ;&lt;br /&gt;
   stdio::write(&amp;quot;No solution&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the head of the list is not equal to Name, you need to investigate whether Name can be found in the tail of the list.&lt;br /&gt;
&lt;br /&gt;
In English:&lt;br /&gt;
&lt;br /&gt;
Name is a member of the list if Name is the first element of the list, or&amp;lt;br /&amp;gt;&lt;br /&gt;
Name is a member of the list if Name is a member of the tail.&lt;br /&gt;
&lt;br /&gt;
The second clause of isMember relates to this relationship. In Visual Prolog:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;isMember(Name, [_|Tail]) :-&lt;br /&gt;
    isMember(Name, Tail).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Appending One List to Another: Declarative and Procedural Programming===&lt;br /&gt;
&lt;br /&gt;
As given, the member predicate of the e01.pro program works in two ways. Consider its clauses once again:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;member(Name, [Name|_]).&lt;br /&gt;
member(Name, [_|Tail]) :-&lt;br /&gt;
    member(Name, Tail).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can look at these clauses from two different points of view: declarative and procedural.&lt;br /&gt;
&lt;br /&gt;
*From a declarative viewpoint, the clauses say:Name is a member of a list if the head is equal to Name;&amp;lt;br /&amp;gt;&lt;br /&gt;
if not, Name is a member of the list if it is a member of the tail.&lt;br /&gt;
&lt;br /&gt;
*From a procedural viewpoint, the two clauses could be interpreted as saying:To find a member of a list, find its head;&amp;lt;br /&amp;gt;&lt;br /&gt;
otherwise, find a member of its tail.&lt;br /&gt;
&lt;br /&gt;
These two points of view correspond to the goals&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;member(2, [1, 2, 3, 4]).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;member(X, [1, 2, 3, 4]).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In effect, the first goal asks Visual Prolog to check whether something is true; the second asks Visual Prolog to find all members of the list [1,2,3,4]. Don&amp;#039;t be confused by this. The member predicate is the same in both cases, but its behavior may be viewed from different angles.&lt;br /&gt;
&lt;br /&gt;
=== Recursion from a Procedural Viewpoint ===&lt;br /&gt;
&lt;br /&gt;
The beauty of Prolog is that, often, when you construct the clauses for a predicate from one point of view, they&amp;#039;ll work from the other. To see this duality, in this next example you&amp;#039;ll construct a predicate to append one list to another. You&amp;#039;ll define the predicate append with three arguments:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;append(List1, List2, List3).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This combines List1 and List2 to form List3. Once again you are using recursion (this time from a procedural point of view).&lt;br /&gt;
&lt;br /&gt;
If List1 is empty, the result of appending &amp;#039;&amp;#039; Lis&amp;#039;&amp;#039;t&amp;#039;&amp;#039;1&amp;#039;&amp;#039; and List2 will be the same as List2. In Prolog:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;append([], List2, List2).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If List1 is not empty, you can combine List1 and List2 to form &amp;#039;&amp;#039;List3&amp;#039;&amp;#039; by making the head of List1 the head of List3. (In the following code, the variable H is used as the head of both List1 and List3.) The tail of List3 is L3, which is composed of the rest of List1 (namely, L1) and all of List2. In Prolog:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;append([H|L1], List2, [H|L3]) :-&lt;br /&gt;
   append(L1, List2, L3).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The append predicate operates as follows: While List1 is not empty, the recursive rule transfers one element at a time to List3. When List1 is empty, the first clause ensures that List2 hooks onto the back of List3.&lt;br /&gt;
&lt;br /&gt;
=== One Predicate Can Have Different Uses ===&lt;br /&gt;
&lt;br /&gt;
Looking at append from a declarative point of view, you have defined a relation between three lists. This relation also holds if List1 and List3 are known but List2 isn&amp;#039;t. However, it also holds true if only List3 is known. For example, to find which two lists could be appended to form a known list, you could use a goal of the form&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;append(L1, L2, [1, 2, 4]).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this goal, Visual Prolog will find these solutions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;1L1=[], L2=[1,2,4]&lt;br /&gt;
L1=[1], L2=[2,4]L1=[1,2], L2=[4]L1=[1,2,4], L2=[]4 Solutions&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use append to find which list you could append to [3,4] to form the list [1,2,3,4]. Try giving the goal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;append(L1, [3,4], [1,2,3,4]).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Visual Prolog finds the solution&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;L1=[1,2].&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This append predicate has defined a relation between an &amp;#039;&amp;#039; input set&amp;#039;&amp;#039; and an &amp;#039;&amp;#039;output set&amp;#039;&amp;#039; in such a way that the relation applies both ways. Given that relation, you can ask&lt;br /&gt;
&lt;br /&gt;
Which output corresponds to this given input?&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
Which input corresponds to this given output?&lt;br /&gt;
&lt;br /&gt;
The status of the arguments to a given predicate when you call that predicate is referred to as a &amp;#039;&amp;#039;flow pattern&amp;#039;&amp;#039;. An argument that is bound or instantiated at the time of the call is an input argument, signified by (i); a free argument is an output argument, signified by (o).&lt;br /&gt;
&lt;br /&gt;
The append predicate has the ability to handle any flow pattern you provide. However, not all predicates have the capability of being called with different flow patterns. When a Prolog clause is able to handle multiple flow patterns, it is known as an invertible clause. Many of list predicate can be found in the &amp;#039;&amp;#039;&amp;#039;list&amp;#039;&amp;#039;&amp;#039; class.&lt;br /&gt;
&lt;br /&gt;
==Finding All the Solutions at Once==&lt;br /&gt;
&lt;br /&gt;
Backtracking and recursion are two ways to perform repetitive processes. Recursion won out because, unlike backtracking, it can pass information (through arguments) from one recursive call to the next. Because of this, a recursive procedure can keep track of partial results or counters as it goes along.&lt;br /&gt;
&lt;br /&gt;
But there&amp;#039;s one thing backtracking can do that recursion can&amp;#039;t do – namely, find all the alternative solutions to a goal. So you may find yourself in a quandary: You need all the solutions to a goal, but you need them all at once, as part of a single compound data structure. What do you do?&lt;br /&gt;
&lt;br /&gt;
Fortunately, Visual Prolog provides a way out of this impasse. The built-in construction list comprehension takes a goal as one of its arguments and collects all of the solutions to that goal into an output single list. list comprehension takes two arguments:&lt;br /&gt;
&lt;br /&gt;
*The first argument, VarName, specifies which argument in the specified predicate is to be collected into a list.&lt;br /&gt;
&lt;br /&gt;
*The second, mypredicate, indicates the predicate from which the values will be collected.&lt;br /&gt;
&lt;br /&gt;
*The output ListParam, is a variable that holds the list of values collected through backtracking.&lt;br /&gt;
&lt;br /&gt;
The e02.pro program uses list comprehension to print the average age of a group of people.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;        /* Program e02.pro */&lt;br /&gt;
class my&lt;br /&gt;
domains&lt;br /&gt;
    name = string.&lt;br /&gt;
    address = string.&lt;br /&gt;
    age = integer.&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    person : (name, address, age)&lt;br /&gt;
        nondeterm anyflow.&lt;br /&gt;
    sumlist : (age*, age, integer)&lt;br /&gt;
        procedure(i,o,o).&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement my&lt;br /&gt;
clauses&lt;br /&gt;
    sumlist([],0,0).&lt;br /&gt;
    sumlist([H|T], Sum, N):-&lt;br /&gt;
        sumlist(T, S1, N1),&lt;br /&gt;
        Sum=H+S1, N=1+N1.&lt;br /&gt;
    person(&amp;quot;Sherlock Holmes&amp;quot;,&lt;br /&gt;
        &amp;quot;22B Baker Street&amp;quot;, 42).&lt;br /&gt;
    person(&amp;quot;Pete Spiers&amp;quot;,&lt;br /&gt;
        &amp;quot;Apt. 22, 21st Street&amp;quot;, 36).&lt;br /&gt;
    person(&amp;quot;Mary Darrow&amp;quot;,&lt;br /&gt;
        &amp;quot;Suite 2, Omega Home&amp;quot;, 51).&lt;br /&gt;
end implement&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    L = [ Age || my::person(_, _, Age)],&lt;br /&gt;
    my::sumlist(L, Sum, N),&lt;br /&gt;
    Ave = Sum/N,&lt;br /&gt;
    stdio::write(&amp;quot;Average=&amp;quot;, Ave, &amp;quot;. &amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The list comprehension clause in this program creates a list L, which is a collection of all the ages obtained from the predicate person. If you wanted to collect a list of all the people who are 42 years old, you could give the following subgoal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;List = [ Who || my::person(Who, _, 42) ]&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following code will create the list of positive items:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;List = [ X || X = list::getMember_nd([2,-8,-3,6]), X &amp;gt; 0]&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Compound Lists==&lt;br /&gt;
&lt;br /&gt;
A list of integers can be simply declared as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;integer*&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The same is true for a list of real numbers, a list of symbols, or a list of strings.&lt;br /&gt;
&lt;br /&gt;
However, it is often valuable to store a combination of different types of elements within a list, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;[2, 3, 5.12, [&amp;quot;food&amp;quot;, &amp;quot;goo&amp;quot;], &amp;quot;new&amp;quot;] % Not correct Visual Prolog&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Compound lists&amp;#039;&amp;#039; are lists that contain more than one type of element. You need special declarations to handle lists of multiple-type elements, because Visual Prolog requires that all elements in a list belong to the &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;same&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; domain. The way to create a list in Prolog that stores these different types of elements is to use functors, because a domain can contain &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;more than one&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; data type as arguments to functors.&lt;br /&gt;
&lt;br /&gt;
The following is an example of a domain declaration for a list that can contain an integer, a character, a string, or a list of any of these:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    llist = l(list); i(integer); c(char); s(string).&lt;br /&gt;
        % the functors are l, i, c, and s&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The list&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;[ 2, 9, [&amp;quot;food&amp;quot;, &amp;quot;goo&amp;quot;], &amp;quot;new&amp;quot; ] % Not correct Visual Prolog&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
would be written in Visual Prolog as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;[i(2), i(9), l([s(&amp;quot;food&amp;quot;), s(&amp;quot;goo&amp;quot;)]), s(&amp;quot;new&amp;quot;)] % Correct Visual Prolog&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following example of append shows how to use this domain declaration in a typical list-manipulation program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class my&lt;br /&gt;
    domains&lt;br /&gt;
        llist = l(list); i(integer); c(char); s(string).&lt;br /&gt;
    predicates&lt;br /&gt;
        test : ().&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement my&lt;br /&gt;
    class predicates&lt;br /&gt;
        append : (A*,A*,A*) procedure (i,i,o).&lt;br /&gt;
    clauses&lt;br /&gt;
        append([], L, L).&lt;br /&gt;
        append([X|L1], L2, [X|L3]):-&lt;br /&gt;
            append(L1, L2, L3).&lt;br /&gt;
&lt;br /&gt;
    clauses&lt;br /&gt;
        test() :-&lt;br /&gt;
            append([s(&amp;quot;likes&amp;quot;), l([s(&amp;quot;bill&amp;quot;), s(&amp;quot;mary&amp;quot;)])], [s(&amp;quot;bill&amp;quot;), s(&amp;quot;sue&amp;quot;)], Ans),&lt;br /&gt;
            stdio::write(&amp;quot;FIRST LIST: &amp;quot;, Ans,&amp;quot;\n\n&amp;quot;),&lt;br /&gt;
            append([l([s(&amp;quot;This&amp;quot;), s(&amp;quot;is&amp;quot;),s(&amp;quot;a&amp;quot;),s(&amp;quot;list&amp;quot;)]), s(&amp;quot;bee&amp;quot;)], [c(&amp;#039;c&amp;#039;)], Ans2),&lt;br /&gt;
            stdio::write(&amp;quot;SECOND LIST: &amp;quot;, Ans2, &amp;quot;\n\n&amp;quot;).&lt;br /&gt;
end implement&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Parsing by Difference Lists ==&lt;br /&gt;
&lt;br /&gt;
The ch07e10.pro program demonstrates [[wikipedia:parsing|parsing]] by &amp;#039;&amp;#039;difference lists&amp;#039;&amp;#039;. The process of parsing by difference lists works by reducing the problem; in this example we transform a string of input into a Prolog structure that can be used or evaluated later.&lt;br /&gt;
&lt;br /&gt;
The parser in this example is for a very primitive computer language. Although this example is very advanced for this point in the tutorial, we decided to put it here because parsing is one of the areas where Visual Prolog is very powerful. If you do not feel ready for this topic, you can skip this example and continue reading the tutorial without any loss of continuity.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;#include @&amp;quot;pfc\list\list.ph&amp;quot;&lt;br /&gt;
#include @&amp;quot;pfc\string\string.ph&amp;quot;&lt;br /&gt;
#include @&amp;quot;pfc\application\exe\exe.ph&amp;quot;&lt;br /&gt;
#include @&amp;quot;pfc\console\console.ph&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*******************************************&lt;br /&gt;
* Lexer&lt;br /&gt;
*******************************************/&lt;br /&gt;
class lexer&lt;br /&gt;
    predicates&lt;br /&gt;
        tokl : (string Input) -&amp;gt; string* TokenTL.&lt;br /&gt;
end class lexer&lt;br /&gt;
&lt;br /&gt;
implement lexer&lt;br /&gt;
    clauses&lt;br /&gt;
        tokl(Input) = [Tok|tokl(Rest)] :-&lt;br /&gt;
            string::fronttoken(Input, Tok, Rest),&lt;br /&gt;
            !.&lt;br /&gt;
        tokl(_) = [].&lt;br /&gt;
end implement&lt;br /&gt;
&lt;br /&gt;
/*******************************************&lt;br /&gt;
* Parser&lt;br /&gt;
*******************************************/&lt;br /&gt;
class parser&lt;br /&gt;
    domains&lt;br /&gt;
        program = statement*.&lt;br /&gt;
&lt;br /&gt;
    domains&lt;br /&gt;
        statement =&lt;br /&gt;
            if_Then_Else(expression Condition, statement ThenPart, statement ElsePart);&lt;br /&gt;
            if_Then(expression Condition, statement ThenPart);&lt;br /&gt;
            while(expression Condition, statement Body);&lt;br /&gt;
            assign(id Variable, expression Expression).&lt;br /&gt;
&lt;br /&gt;
    domains&lt;br /&gt;
        expression =&lt;br /&gt;
            plus(expression, expression);&lt;br /&gt;
            minus(expression, expression);&lt;br /&gt;
            var(id);&lt;br /&gt;
            int(integer).&lt;br /&gt;
&lt;br /&gt;
    domains&lt;br /&gt;
       id = string.&lt;br /&gt;
&lt;br /&gt;
    predicates&lt;br /&gt;
        program : (string* TL) -&amp;gt; program ProgramTree determ.&lt;br /&gt;
&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement parser&lt;br /&gt;
    clauses&lt;br /&gt;
        program(TL) =  Prog :-&lt;br /&gt;
            Prog = statement_list(TL, TL0),&lt;br /&gt;
            [] = TL0.&lt;br /&gt;
&lt;br /&gt;
    class predicates&lt;br /&gt;
        statement_list : (string* TL1, string* TL0 [out]) -&amp;gt; program Program determ.&lt;br /&gt;
    clauses&lt;br /&gt;
        statement_list([], []) = [] :-&lt;br /&gt;
            !.&lt;br /&gt;
        statement_list(TL1, TL0) = [Statement|Program] :-&lt;br /&gt;
            Statement = statement(TL1, TL2),&lt;br /&gt;
            TL2=[&amp;quot;;&amp;quot;|TL3],&lt;br /&gt;
            Program = statement_list(TL3, TL0).&lt;br /&gt;
&lt;br /&gt;
    class predicates&lt;br /&gt;
        statement : (string* TL1, string* TL0 [out]) -&amp;gt; statement Statement determ.&lt;br /&gt;
    clauses&lt;br /&gt;
        statement([&amp;quot;if&amp;quot;|TL1], TL0) = if_then_else(Condition, ThenPart, ElsePart) :-&lt;br /&gt;
            Condition = expression(TL1, TL2),&lt;br /&gt;
            TL2=[&amp;quot;then&amp;quot;|TL3],&lt;br /&gt;
            ThenPart = statement(TL3, TL4),&lt;br /&gt;
            TL4=[&amp;quot;else&amp;quot;|TL5],!,&lt;br /&gt;
            ElsePart = statement(TL5, TL6),&lt;br /&gt;
            TL6=[&amp;quot;fi&amp;quot;|TL0].&lt;br /&gt;
&lt;br /&gt;
        statement([&amp;quot;if&amp;quot;|TL1], TL0) = if_then(Condition, Statement) :-&lt;br /&gt;
            !,&lt;br /&gt;
            Condition = expression(TL1, TL2),&lt;br /&gt;
            TL2=[&amp;quot;then&amp;quot;|TL3],&lt;br /&gt;
            Statement = statement(TL3, TL4),&lt;br /&gt;
            TL4=[&amp;quot;fi&amp;quot;|TL0].&lt;br /&gt;
&lt;br /&gt;
        statement([&amp;quot;do&amp;quot;|TL1], TL0) = while(Condition, Statement) :-&lt;br /&gt;
            !,&lt;br /&gt;
            Statement = statement(TL1, TL2),&lt;br /&gt;
            TL2=[&amp;quot;while&amp;quot;|TL3],&lt;br /&gt;
            Condition = expression(TL3, TL0).&lt;br /&gt;
&lt;br /&gt;
        statement([ID|TL1], TL0) = assign(Id,Exp) :-&lt;br /&gt;
            string::isname(ID),&lt;br /&gt;
            TL1=[&amp;quot;=&amp;quot;|TL2],&lt;br /&gt;
            Exp = expression(TL2, TL0).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    class predicates&lt;br /&gt;
        expression : (string* TL1, string* TL0 [out]) -&amp;gt; expression Expression determ.&lt;br /&gt;
    clauses&lt;br /&gt;
        expression(TL1, TL0) = Exp:-&lt;br /&gt;
            PreTerm = term(TL1, TL2),&lt;br /&gt;
            Exp = termTail(TL2, TL0, PreTerm).&lt;br /&gt;
&lt;br /&gt;
    class predicates&lt;br /&gt;
        termTail : (string* TL1, string* TL0 [out], expression PreExpr) -&amp;gt; expression Expr determ.&lt;br /&gt;
    clauses&lt;br /&gt;
        termTail([&amp;quot;+&amp;quot;|TL1], TL0, Exp1) = Exp :-&lt;br /&gt;
            !,&lt;br /&gt;
            Exp2 = term(TL1, TL2),&lt;br /&gt;
            Exp = termTail(TL2, TL0, plus(Exp1, Exp2)).&lt;br /&gt;
&lt;br /&gt;
        termTail([&amp;quot;-&amp;quot;|TL1], TL0, Exp1) = Exp :-&lt;br /&gt;
            !,&lt;br /&gt;
            Exp2 = term(TL1, TL2),&lt;br /&gt;
            Exp = termTail(TL2, TL0, minus(Exp1, Exp2)).&lt;br /&gt;
&lt;br /&gt;
        termTail(TL, TL, Exp) = Exp.&lt;br /&gt;
&lt;br /&gt;
    class predicates&lt;br /&gt;
        term : (string* TL1, string* TL0 [out]) -&amp;gt; expression Expression  determ.&lt;br /&gt;
    clauses&lt;br /&gt;
        term([Int|Rest], Rest) = int(I) :-&lt;br /&gt;
            try&lt;br /&gt;
                I = toTerm(Int)&lt;br /&gt;
            catch _ do&lt;br /&gt;
                fail&lt;br /&gt;
            end try,&lt;br /&gt;
            !.&lt;br /&gt;
&lt;br /&gt;
        term([Id|Rest], Rest) = var(Id) :-&lt;br /&gt;
            string::isName(Id).&lt;br /&gt;
end implement parser&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    TokenTL = lexer::tokl(&amp;quot;b=2; if b then a=1 else a=2 fi; do a=a-1 while a;&amp;quot;),&lt;br /&gt;
    if ProgramTree = parser::program(TokenTL) then&lt;br /&gt;
        foreach Stmt = list::getMember_nd(ProgramTree) do&lt;br /&gt;
            stdio::write(Stmt, &amp;quot;\n&amp;quot;)&lt;br /&gt;
        end foreach&lt;br /&gt;
    else&lt;br /&gt;
        stdio::write(&amp;quot;Parse error\n&amp;quot;)&lt;br /&gt;
    end if.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program will write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;assign(&amp;quot;b&amp;quot;,int(2))&lt;br /&gt;
if_then_else(var(&amp;quot;b&amp;quot;),assign(&amp;quot;a&amp;quot;,int(1)),assign(&amp;quot;a&amp;quot;,int(2)))&lt;br /&gt;
while(var(&amp;quot;a&amp;quot;),assign(&amp;quot;a&amp;quot;,minus(var(&amp;quot;a&amp;quot;),int(1))))&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The transformation in this example is divided into two stages: scanning and parsing. The tokl predicate is the scanner; it accepts a string and converts it into a list of tokens. In this example the input text is a Pascal-like program made up of Pascal-like statements. This programming language only understands certain statements: IF THEN ELSE, IF THEN, DO WHILE, and ASSIGNMENT. Statements are made up of expressions and other statements. Expressions are addition, subtraction, variables, and integers.&lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s how this example works:&lt;br /&gt;
&lt;br /&gt;
*The &amp;#039;&amp;#039;&amp;#039;program&amp;#039;&amp;#039;&amp;#039; predicate takes a list of tokens call the &amp;#039;&amp;#039;&amp;#039;statement_list&amp;#039;&amp;#039;&amp;#039; predicate on that list.  And then is test that all tokens was used in the parse process.&lt;br /&gt;
*The predicate &amp;#039;&amp;#039;&amp;#039;statement_list&amp;#039;&amp;#039;&amp;#039; takes a list of tokens and tests if the tokens can be divided up into individual statements, each ending with a semicolon.&lt;br /&gt;
*The predicate &amp;#039;&amp;#039;&amp;#039;statement&amp;#039;&amp;#039;&amp;#039; tests if the first tokens of the token list make up a legal statement. If so, the statement is returned in a structure and the remaining tokens are returned back to &amp;#039;&amp;#039;&amp;#039;statement_list&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
*The four clauses of the &amp;#039;&amp;#039;&amp;#039;statement&amp;#039;&amp;#039;&amp;#039; correspond to the four types of statements the parser understands.&lt;br /&gt;
**If the first &amp;#039;&amp;#039;&amp;#039;statement&amp;#039;&amp;#039;&amp;#039; clause is unable to transform the list of tokens into an &amp;#039;&amp;#039;IF THEN ELSE&amp;#039;&amp;#039; statement, the clause fails and backtracks to the next &amp;#039;&amp;#039;&amp;#039;statement&amp;#039;&amp;#039;&amp;#039; clause.&lt;br /&gt;
**The second clause tries to transform the list of tokens into an &amp;#039;&amp;#039;IF THEN&amp;#039;&amp;#039; statement.&lt;br /&gt;
**If that clause fails, the next clause tries to transform the list of tokens into a &amp;#039;&amp;#039;DO WHILE&amp;#039;&amp;#039; statement.&lt;br /&gt;
**And if all the first three &amp;#039;&amp;#039;&amp;#039;statement&amp;#039;&amp;#039;&amp;#039; clauses fail, the last clause for that predicate tests if the statement does assignment. This clause tests for assignment by testing if the first term is a symbol, the second term is &amp;quot;=&amp;quot;, and the next terms make up a simple math expression.&lt;br /&gt;
*The &amp;#039;&amp;#039;&amp;#039;expression&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;term&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;termTail&amp;#039;&amp;#039;&amp;#039; predicates work in simailar ways, by testing if the first terms are expressions and – if so – returning the remainder of the terms and an expression structure back to &amp;#039;&amp;#039;&amp;#039;statement&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
&lt;br /&gt;
These are the important points covered in this tutorial:&lt;br /&gt;
&lt;br /&gt;
*&amp;#039;&amp;#039;Lists&amp;#039;&amp;#039; can contain an arbitrary number of elements; you declare them by adding an asterisk at the end of a previously defined domain.&lt;br /&gt;
&lt;br /&gt;
*A list is a recursive compound object that consists of a head and a tail. The head is the first element and the tail is the rest of the list (without the first element). The tail of a list is always a list; the head of a list is an element. A list can contain zero or more elements; the empty list is written [].&lt;br /&gt;
&lt;br /&gt;
*The elements in a list can be anything, including other lists; all elements in a list must belong to the same domain. The domain declaration for the elements must be of this form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
   element_list = elements*.&lt;br /&gt;
   elements = ....&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where elements = one of the standard domains (integer, real, etc.) or a set of alternatives marked with different functors (int(integer); rl(real); smb(symbol); etc.). You can only mix types in a list in Visual Prolog by enclosing them in compound objects/functors.&lt;br /&gt;
&lt;br /&gt;
*You can use separators (commas, [, and |) to make the head and tail of a list explicit; for example, the list&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;[a, b, c, d]&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
can be written as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;[a|[b, c, d]] or[a, b|[c, d]] or[a, b, c|[d]] or[a|[b|[c, d]]] or[a|[b|[c|[d]]]] or even[a|[b|[c|[d|[]]]]]&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*List processing consists of recursively removing the head of the list (and usually doing something with it) until the list is an empty list.&lt;br /&gt;
&lt;br /&gt;
*The list predicates can be found in the &amp;#039;&amp;#039;&amp;#039;list&amp;#039;&amp;#039;&amp;#039; class.&lt;br /&gt;
&lt;br /&gt;
*Visual Prolog provides a built-in construction,  list comprehension, which takes a goal as one of its arguments and collects all of the solutions to that goal into a single list. It has the syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;Result = [ Argument || myPredicate(Argument) ]&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Because Visual Prolog requires that all elements in a list belong to the same domain, you use functors to create a list that stores different types of elements.&lt;br /&gt;
&lt;br /&gt;
*The process of &amp;#039;&amp;#039;parsing by difference lists&amp;#039;&amp;#039; works by reducing the problem; the example in this tutorial transforms a string of input into a Prolog structure that can be used or evaluated later.&lt;br /&gt;
&lt;br /&gt;
[[ru:Списки и рекурсия]]&lt;br /&gt;
[[Category:Data types and handling]]&lt;/div&gt;</summary>
		<author><name>EJP</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Fundamental_Visual_Prolog_-_the_Data_Layer&amp;diff=4329</id>
		<title>Fundamental Visual Prolog - the Data Layer</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Fundamental_Visual_Prolog_-_the_Data_Layer&amp;diff=4329"/>
		<updated>2016-11-03T09:40:04Z</updated>

		<summary type="html">&lt;p&gt;EJP: Updated familyDL and familyData code snippets.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{FundamentalPrologNavbar}}&lt;br /&gt;
&lt;br /&gt;
In this tutorial, we will continue with the &amp;#039;&amp;#039;&amp;#039;family&amp;#039;&amp;#039;&amp;#039; example, where we would introduce one more layer - the Data layer - to handle the problem more efficiently. This tutorial will give you all the sophistication that is required to handle complex situations.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Download&amp;#039;&amp;#039;&amp;#039; source files of the example project used in this tutorial:&lt;br /&gt;
&lt;br /&gt;
* Visual Prolog 7.4 and 7.3 install examples in the IDE:&lt;br /&gt;
*:&amp;#039;&amp;#039;&amp;#039;Help -&amp;gt; Install Examples...&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* [http://download.pdc.dk/vip/72/tutorial/family4.zip Visual Prolog 7.2 version].&lt;br /&gt;
* [http://download.pdc.dk/vip/71/tutorial/family4.zip Visual Prolog 7.1 version].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Concepts==&lt;br /&gt;
&lt;br /&gt;
There is a Chinese proverb that goes like this: &amp;quot;Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime&amp;quot;. There is a lesson in programming there. It is often better to substitute data (&amp;#039;&amp;#039;a fish&amp;#039;&amp;#039;) with a method (&amp;#039;&amp;#039;the procedure of fishing&amp;#039;&amp;#039;) that can lead to the data.&lt;br /&gt;
&lt;br /&gt;
This concept can be extended further a bit more. For example, if before teaching the person fishing directly, the man is taught the principles of getting food from nature, then the person has a much better chance of getting food for his family.&lt;br /&gt;
&lt;br /&gt;
But here is a caveat: explaining things using analogies can be a bit problematic, because, when you stretch an analogy too far, it breaks! In the above example, if you give the fisherman one more layer&amp;#039;&amp;#039;,&amp;#039;&amp;#039; then he may die of starvation before he can harvest the fruits of his fine education!&lt;br /&gt;
&lt;br /&gt;
This manner of daisy-chaining together a set of activities to achieve the end goal can be done in programming also. But then, this has to be done intelligently, as per the demands posed by the complexity of the software problem you are trying to handle. Though it can be said that more the &amp;#039;&amp;#039;layers&amp;#039;&amp;#039; that are introduced, better is the control on reaching the eventual goal; one needs to setup the layers after careful foresight.&lt;br /&gt;
&lt;br /&gt;
If you see the pattern that had evolved in through the entire &amp;#039;&amp;#039;&amp;#039;family&amp;#039;&amp;#039;&amp;#039; series of tutorials (Fundamental Visual Prolog, Fundamental Visual Prolog - GUI,  Fundamental Visual Prolog - the Business Logical Layer), you would notice the same thing: more and more refined layers were introduced that finely controlled the behavior of the program. At the same time, there were no unnecessary layers - if it were so, it would have only increased the complexity and cumbersomeness of the program.&lt;br /&gt;
&lt;br /&gt;
In this tutorial, we will introduce the Data layer. The core of the data layer is nothing but a class, and objects of that class would be used to access and set the actual data. In the earlier tutorial, please note that the Business Logical Layer (BLL) handled the data also. This time, the BLL would be handling &amp;#039;&amp;#039;only&amp;#039;&amp;#039; the logic.&lt;br /&gt;
&lt;br /&gt;
==The Program==&lt;br /&gt;
&lt;br /&gt;
But first of all, let us understand the various parts of the program with the help of the supplied  family4.zip file. In this tutorial, we are not presenting the code that is needed (else this tutorial will become too lengthy). All the code is present in the example for the tutorial. You can read the code from the IDE, when you load the project there. Some partial code is, however, present here, for quick reference.&lt;br /&gt;
&lt;br /&gt;
When you load the project (&amp;#039;&amp;#039;&amp;#039;family4&amp;#039;&amp;#039;&amp;#039;) in the Visual Prolog IDE, you will notice four separate packages as seen below:&lt;br /&gt;
&lt;br /&gt;
:[[Image:FundamentalVisualPrologData_01.png|Visual Prolog Project window]]&lt;br /&gt;
&lt;br /&gt;
These packages are the FamilyBLL, FamilyData&amp;#039;&amp;#039;,&amp;#039;&amp;#039; FamilyDL and TaskWindow packages. The last package (i.e. TaskWindow) is automatically created by the IDE, when you create the project. The method to create the other packages was explained in a previous tutorial.&lt;br /&gt;
&lt;br /&gt;
The project was created in a similar fashion that was explained in a previous tutorial. There are no surprises there. But here is a bit of explanation of something new.&lt;br /&gt;
&lt;br /&gt;
There is one more dialog that is introduced in the &amp;#039;&amp;#039;&amp;#039;TaskWindow&amp;#039;&amp;#039;&amp;#039; package as compared to the previous tutorial. This is the &amp;#039;&amp;#039;&amp;#039;NewPersonDialog&amp;#039;&amp;#039;&amp;#039;, which is shown below. (We&amp;#039;ve already included this dialog in the project. However, the explanation below pretends that you are creating this dialog on your own in the project.)&lt;br /&gt;
&lt;br /&gt;
:[[Image:FundamentalVisualPrologData_02.png|New Person Dialog]]&lt;br /&gt;
&lt;br /&gt;
This dialog is a modeless dialog, which is used to collect the information of a new person that is to be inserted into the current database. As you can see in the above image, there is a text-edit field (idc_name) for collecting the name, a radio button series (idc_male and idc_female) for finding the gender, and two further text edit fields (idc_parent1 and idc_parent2) to find the parents of the person being added into the database. A modeless dialog is one, which can remain open and active, without interfering in the workings of other parts of the GUI.&lt;br /&gt;
&lt;br /&gt;
There is no difference between a &amp;#039;&amp;#039;modal&amp;#039;&amp;#039; and &amp;#039;&amp;#039;modeless&amp;#039;&amp;#039; dialog when it is being created. However, when you set its attributes you must be careful to specify that it is indeed a modeless one, as shown below:&lt;br /&gt;
&lt;br /&gt;
:[[Image:FundamentalVisualPrologData_04.png|Specifying]]&lt;br /&gt;
&lt;br /&gt;
Now just creating such a dialog is not of any use if there is no way by which the dialog can be invoked from TaskWindow. Hence we need to insert a new menu item in that and associate an event handler with that menu item. Once we create the appropriate menu item, the code wizard will allow us to create a handler into which we can fill in the requisite code. The image is shown below:&lt;br /&gt;
&lt;br /&gt;
:[[Image:FundamentalVisualPrologData_03.png|Creating a handler in the Dialog and Window Expert (TaskWindow)]]&lt;br /&gt;
&lt;br /&gt;
Please note that in an earlier tutorial (Fundamental Visual Prolog - GUI), we had shown how to create an event handler for a menu-item using the above code wizard.&lt;br /&gt;
&lt;br /&gt;
==Modeless Dialog: Conceptual Issues==&lt;br /&gt;
&lt;br /&gt;
This program uses a modeless dialog in order to insert information regarding new persons into the &amp;#039;&amp;#039;&amp;#039;family&amp;#039;&amp;#039;&amp;#039; database. As indicated in an earlier tutorial, coding for the events happening from a modeless dialog can sometimes be tricky. This can be understood if you know exactly why a modal dialog works the way it does. In a modal dialog, the operating system suspends events happening from all other GUI parts of the same application and concentrates only on those that emerge from the modal dialog. The logic required to be handled by the programmer at that point in time becomes quite simple, as the programmer is quite sure that there are no untoward events that are happening simultaneously in other parts of the same program.&lt;br /&gt;
&lt;br /&gt;
On the other hand, when a modeless dialog is in use, the program is receptive to events even from parts of the program &amp;#039;&amp;#039;along with&amp;#039;&amp;#039; those occurring from within the said dialog. The permutations and combinations of event handling required need to be carefully thought through by the programmer. For example, the program could open a database, and then have a &amp;#039;&amp;#039;modeless&amp;#039;&amp;#039; dialog opened, which worked on the database. It would throw an error, when the dialog is put to use if in the background the database was closed without shutting down the dialog. Unless, of course, you had anticipated such a course of events and programmed for such situations.&lt;br /&gt;
&lt;br /&gt;
If you see the source code that handles the events happening from this dialog in NewPersonDialog.pro, you would see that the code carefully catches a lot of error situations. It even has an integrity checker that attempts to trace what may cause a piece of code to cause an error.&lt;br /&gt;
&lt;br /&gt;
Predicates that may lead to errors during runtime are called from within a &amp;lt;vp&amp;gt;try&amp;lt;/vp&amp;gt;-construction. For example, see the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    onControlOK(_Ctrl, _CtrlType, _CtrlWin, _CtrlInfo) = handled(0) :-&lt;br /&gt;
        Name = vpi::winGetText(vpi::winGetCtlHandle(thisWin, idc_name)),&lt;br /&gt;
        Name  &amp;quot;&amp;quot;,&lt;br /&gt;
        MaleBool = vpi::winIsChecked(vpi::winGetCtlHandle(thisWin, idc_male)),&lt;br /&gt;
        Gender = maleFlagToGender(MaleBool),&lt;br /&gt;
        OptParent1 = optParent(idc_parent1),&lt;br /&gt;
        OptParent2 = optParent(idc_parent2),&lt;br /&gt;
        try&lt;br /&gt;
            bl:addPerson(Name, Gender, OptParent1, OptParent2)&lt;br /&gt;
        catch TraceId do&lt;br /&gt;
            integrityHandler(TraceId))&lt;br /&gt;
        end try,&lt;br /&gt;
        !,&lt;br /&gt;
        stdIO::write(&amp;quot;Inserted &amp;quot;, Name, &amp;quot;\n&amp;quot;).&lt;br /&gt;
    onControlOK(_Ctrl, _CtrlType, _CtrlWin, _CtrlInfo) = handled(0).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above code snippet, the programmer is not sure whether the addition of a person into the database is really possible (because it is not allowed to add an existing person). Thus the &amp;lt;vp&amp;gt;addPerson&amp;lt;/vp&amp;gt; is not called directly, but inside a &amp;lt;vp&amp;gt;try&amp;lt;/vp&amp;gt;-construction. The &amp;lt;vp&amp;gt;try&amp;lt;/vp&amp;gt;-construction has three components ; the first is the code to be called to do the actual work at that point in the code, the second is the a variable (i.e. &amp;lt;vp&amp;gt;TraceId&amp;lt;/vp&amp;gt;) bound to a &amp;lt;vp&amp;gt;traceId&amp;lt;/vp&amp;gt; which is used to access information about the exception, and the third is the code that is called when the first part terminates with an exception. That component can be used by the programmer to bring the program safely back into control.&lt;br /&gt;
&lt;br /&gt;
==The FamilyData Package==&lt;br /&gt;
&lt;br /&gt;
In this example, we&amp;#039;ll create one FamilyData package, which has all the required code for handling the domains that are needed by the program. The same domains would be available to the &amp;#039;&amp;#039;&amp;#039;BLL&amp;#039;&amp;#039;&amp;#039; (Business Logic Layer), when it communicates with the data layer.&lt;br /&gt;
&lt;br /&gt;
In this class, we&amp;#039;ll write the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class familyData&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    gender = female; male.&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    person = string.&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    optionalPerson =&lt;br /&gt;
        noPerson;&lt;br /&gt;
        person(person Person).&lt;br /&gt;
&lt;br /&gt;
end class familyData&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you notice, the above class contains the domain definitions that are to be shared between multiple classes. Thus, the purpose of this package is to act as a meeting place between the &amp;#039;&amp;#039;Data Layer&amp;#039;&amp;#039; and the &amp;#039;&amp;#039;Business Layer&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
==Interfaces==&lt;br /&gt;
&lt;br /&gt;
The layer&amp;#039;&amp;#039;,&amp;#039;&amp;#039; which will handle the data, will be via objects created from a class in the FamilyDL package. However, before we get to the actual contents of that package, we need to understand a concept called an interface&amp;#039;&amp;#039;.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
An interface can be looked upon as a statement of intention on what to expect in the objects that would adhere to the said interface. It is written in a separate file using the IDE and it can contain predicates that can be expected to be found in the objects of a class.&lt;br /&gt;
&lt;br /&gt;
An interface can also be used for some more definitions that are not explained in this tutorial. You can learn about those advance usage in a future tutorial.&lt;br /&gt;
&lt;br /&gt;
The reason for writing the intentions separately into a different interface is an elegant one: A class can be written to adhere to the declarations found in an interface. The interface gives an abstract definition of the functionality provided by the objects of the class. The definition is &amp;quot;abstract&amp;quot; because it only expresses some of the functionality of the objects. In short, a class can declaratively state that its objects would be behaving in accordance to the interface.&lt;br /&gt;
&lt;br /&gt;
Several classes can implement the same interface; each of them providing a specific, concrete (i.e. non-abstract) implementation of the abstraction. This reduces the burden of code maintenance tremendously. Later on, when more sophistication is to be introduced in the same program, the programmer/s can work on these interfaces and then work their way from there methodically.&lt;br /&gt;
&lt;br /&gt;
==The FamilyDL Package==&lt;br /&gt;
&lt;br /&gt;
This example also contains another package called the FamilyDL package. This package contains the main class, whose objects would handle the actual data.&lt;br /&gt;
&lt;br /&gt;
This package contains an interface - the familydl interface. The main purpose of this interface is to define the predicates that are provided by the data layer to the business logic layer. As such it plays a major role in the data layer. This interface will be based on domains from the FamilyData package.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface familyDL&lt;br /&gt;
    open core, familyData&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    person_nd : (person Name [out]) nondeterm.&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    gender : (person Name) -&amp;gt; gender Gender.&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    parent_nd : (person Person, person Parent [out]) nondeterm.&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    addPerson : (person Person, gender Gender).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    addParent : (person Person, person Parent).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    personExists : (person Person) determ.&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    save : ().&lt;br /&gt;
&lt;br /&gt;
end interface familyDL&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above code, the open keyword is used to indicate that the declarations in both the core and the familyData packages are used in this interface.&lt;br /&gt;
&lt;br /&gt;
The package contains two classes: family_exception and family_factfile. Most of the work will be done by family_factfile&amp;#039;&amp;#039;.&amp;#039;&amp;#039; That file will contain the code, which brings in the fish (if one were to again use the metaphor of the Chinese proverb mentioned in the beginning of this tutorial). It systematically builds up the database that is used by the program, and, while doing, so checks for any error situation that may happen. In case there is an error, it would use predicates from the family_exception class to systematically signal the error.&lt;br /&gt;
&lt;br /&gt;
==Code for the familyDL Package==&lt;br /&gt;
&lt;br /&gt;
The familyDL package has one interface file familydl.i, which code was given earlier. The package also contains two .pro files containing the implementations of two .cl (class) files. The two classes in this package are familydl_exception and familydl_factfile. The code for familydl_factfile can be examined from the family4.zip file that can be downloaded separately for this tutorial. The predicates in that file are for handling the data, and we have covered that in our earlier tutorial.&lt;br /&gt;
&lt;br /&gt;
The code for familydl_exception is also not presented here in this tutorial. Please read it from the family4.zip file. The predicates contain support utility predicates that are used to show correct error messages, when incorrect data and/or errors (known as exceptions in computerese) are caught by the program. Many of these error situations happen without the control of the programmer (for example, a drive door being open is an exception that cannot be predicted), but sometimes, it is required to make an error happen. That means, the programmer deliberately raises an error (to use some computer jargon here). Thus the error utility predicates start with the term &amp;#039;&amp;#039;&amp;#039;raise_&amp;#039;&amp;#039;&amp;#039; as you may notice in the code.&lt;br /&gt;
&lt;br /&gt;
Note that familydl_exception does not contain the logic for handling the exceptions themselves. They are utility predicates that allow the program show the correct error dialog, when exceptions are to happen.&lt;br /&gt;
&lt;br /&gt;
Here is an example how these raise_ predicates are deliberately invoked by the programmer to signal an error situation.&lt;br /&gt;
&lt;br /&gt;
In the familydl_factfile.pro you would find a predicate for adding a parent. In the clause body, it first goes through two checks to see if both the Person as well as the Parent of the Person are existing. If anyone of them does not exist, then &amp;#039;&amp;#039;&amp;#039;familyDL_exception::raise_personAlreadyExists&amp;#039;&amp;#039;&amp;#039; is called. This raises the exception and the program would display a special error dialog at that point. Fortunately, that particular error dialog does not need to be constructed by the programmer. The dialog creation work is done by the libraries of Visual Prolog when it links your program. You would not be creating a separate error dialog the way we did for other dialogs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;%note: the following is only partial&lt;br /&gt;
%      code from familydl_factfile.pro&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    addParent(Person, Parent) :-&lt;br /&gt;
        check_personExists(Person),&lt;br /&gt;
        check_personExists(Parent),&lt;br /&gt;
        assertz(parent_fct(Person, Parent)).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    personExists(Person) :-&lt;br /&gt;
        person_fct(Person, _),&lt;br /&gt;
        !.&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    check_personDoesNotExist : (string Person).&lt;br /&gt;
clauses&lt;br /&gt;
    check_personDoesNotExist(Person) :-&lt;br /&gt;
        personExists(Person),&lt;br /&gt;
        !,&lt;br /&gt;
        familyDL_exception::raise_personAlreadyExists(Person).&lt;br /&gt;
    check_personDoesNotExist(_).&lt;br /&gt;
&lt;br /&gt;
...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Code for the familyBLL Package==&lt;br /&gt;
&lt;br /&gt;
The code for the &amp;#039;&amp;#039;&amp;#039;familyBL.i&amp;#039;&amp;#039;&amp;#039; interface file is given below. This is quite similar to the interface for the business layer that was developed for the previous tutorial. But there are important differences: the domains have been shifted out of this package and are now commonly shared between the Data Layer and the Business Layer. This is an obvious move, because in the previous tutorial we had kept both the Business Layer and the Data Layer as one piece of code. When we separate these two layers, we would still need some common point through which these two layers can talk to one another, and the obvious decision would be to make the domains used by them common to each other.&lt;br /&gt;
&lt;br /&gt;
The second change that can be noticed is that the predicates do not have multiple-flows. Each predicate does exactly one thing with the parameters that it handles. This makes the program move &amp;#039;&amp;#039;away&amp;#039;&amp;#039; from traditional Prolog and it becomes similar to programs written in other languages. Often, this strategy yields better results because it makes it easier to understand the program when one reads the source code. However, the former method of having multiple-flows does result in shorter source code and is often preferred by programmers who came in after using traditional Prolog.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface familyBL&lt;br /&gt;
    open core, familyData&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    personWithFather_nd : (person Person, person Father)&lt;br /&gt;
        nondeterm (o,o).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    personWithGrandfather_nd : (person Person, person GrandFather)&lt;br /&gt;
        nondeterm (o,o).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    ancestor_nd : (person Person, person Ancestor)&lt;br /&gt;
        nondeterm (i,o).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    addPerson : (person Person, gender Gender, optionalPerson Parent1, optionalPerson Parent2).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    save : ().&lt;br /&gt;
end interface familyBL&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The source code for the &amp;#039;&amp;#039;&amp;#039;familyBL&amp;#039;&amp;#039;&amp;#039; class is not presented here. You may read it once you load the code from the supplied example into your IDE. There should be no surprises there. It does the same activities that were carried out in the business layer of the previous tutorial (Fundamental Visual Prolog - the Business Logical Layer). However, there are two important differences: wherever data accessing or setting of data is needed, predicates from the familyDL class are used. Also, the predicates of this class check the validity of information and raise exceptions in the case logical errors are found.&lt;br /&gt;
&lt;br /&gt;
The package contains one more class: &amp;#039;&amp;#039;&amp;#039;familyBL_exception&amp;#039;&amp;#039;&amp;#039;. This class is similar to the one that we found in the Data Layer. But this time, it contains utility predicates that are used to raise exceptions, when the Business Layer predicates are at work.&lt;br /&gt;
&lt;br /&gt;
==Features of a Data Layer==&lt;br /&gt;
&lt;br /&gt;
The main feature of a Data layer, is that it implements a set of predicates collectively referred to as data accessors in object-oriented languages. A &amp;#039;&amp;#039;Data accessor&amp;#039;&amp;#039; decouples data access from the underlying implementation. In simpler terms, you would use predicates to &amp;#039;&amp;#039;set&amp;#039;&amp;#039; and &amp;#039;&amp;#039;get&amp;#039;&amp;#039; the data used by the program. The actual data would remain private and inaccessible from the outside.&lt;br /&gt;
&lt;br /&gt;
Data accessors can also provide a uniform interface to access attributes of the data, while leaving the concrete organization of the attributes hidden.&lt;br /&gt;
&lt;br /&gt;
The advantage of using &amp;#039;&amp;#039;data accessors&amp;#039;&amp;#039; is that algorithms implemented in other areas of the program can be written independent of the knowledge regarding the exact data structure that was used in the Data layer.&lt;br /&gt;
&lt;br /&gt;
There are hardly any pitfalls to this approach, but whatever they are, these pitfalls must be understood. The main one is that two sophisticated levels of understanding have to be reached by the programmer when writing the Data layer&amp;#039;&amp;#039;.&amp;#039;&amp;#039; One would be to determine the internal data structures that will remain private within the Data layer. (The kind of thinking, required to develop data structures, was discussed in the Fundamental Visual Prolog tutorial  regarding functors). But after that, the programmer will also have to spend time designing efficient &amp;#039;&amp;#039;data accessor&amp;#039;&amp;#039; predicates so that other layers can mate smoothly with the &amp;#039;&amp;#039;Data layer&amp;#039;&amp;#039;. Incorrect design of the &amp;#039;&amp;#039;data accessor&amp;#039;&amp;#039; predicates can often create a lot of headache, when a team of programmers is at work. Especially, when the program is required to move from a simple one to a more complex one.&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we used a strategy of &amp;quot;&amp;#039;&amp;#039;teach the program fishing and not give it fish&amp;#039;&amp;#039;&amp;quot; in our program. This is nothing but modularizing of the source code of the software intelligently so that code maintenance and extension of the code becomes extremely simple. We split the erstwhile Business Layer of the previous tutorial into two parts: one contained pure business logic and the other one handled just the data. This allows us to extend the program later on and replace just the data layer with other forms of data handling techniques (such as through data retrieved via an ODBC protocol, or via the Internet, etc.) This tutorial also covered exception handling and we discovered, how easy it is to write our own exception raising predicates, and use those to display intelligent error messages to the user.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
[[Category:Fundamental Visual Prolog Tutorial]]&lt;/div&gt;</summary>
		<author><name>EJP</name></author>
	</entry>
</feed>