<?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=Thomas+Linder+Puls</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=Thomas+Linder+Puls"/>
	<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Special:Contributions/Thomas_Linder_Puls"/>
	<updated>2026-04-11T13:47:29Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_10_Upgrade_Notes&amp;diff=5002</id>
		<title>Visual Prolog 10 Upgrade Notes</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_10_Upgrade_Notes&amp;diff=5002"/>
		<updated>2026-03-31T08:17:09Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: predicate name spelling&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document describes how to upgrade Visual Prolog 9 projects to Visual Prolog 10, for older projects you should also read the [[Visual Prolog 9 Upgrade Notes]].&lt;br /&gt;
&lt;br /&gt;
If you have problems with upgrading your projects and need additional information, you are welcome to ask questions in [http://discuss.visual-prolog.com/viewforum.php?f=2 Visual Prolog Discussion Forum].&lt;br /&gt;
&lt;br /&gt;
By default, the installation of Visual Prolog 10 will not replace any previously installed versions. It is possible to work with several versions on a single computer.&lt;br /&gt;
* The Commercial Edition will by default be installed in &amp;#039;&amp;#039;&amp;#039;C:\Program Files (x86)\Visual Prolog 10&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;C:\Program Files\Visual Prolog 10&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* The Personal Edition will by default be installed to &amp;#039;&amp;#039;&amp;#039;C:\Program Files (x86)\Visual Prolog 10PE&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;C:\Program Files\Visual Prolog 10PE&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Visual Prolog 10 projects are backward-compatible with Visual Prolog 9 projects.&lt;br /&gt;
If you are going to use different versions of Visual Prolog installed at one computer, avoid opening projects by double-clicking on vipprj files.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Notice&amp;#039;&amp;#039;&amp;#039; it is highly advisable to have a backup of a project before updating.&lt;br /&gt;
&lt;br /&gt;
=== Superfluos files ===&lt;br /&gt;
&lt;br /&gt;
The following files are superfluous and should be deleted:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;.frm&amp;#039;&amp;#039;&amp;#039; related to forms&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;.win&amp;#039;&amp;#039;&amp;#039; related to e.g. the task window&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;.ctl&amp;#039;&amp;#039;&amp;#039; related to controls&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;.dlg&amp;#039;&amp;#039;&amp;#039; related to dialogs; &amp;#039;&amp;#039;&amp;#039;except&amp;#039;&amp;#039;&amp;#039; if it corresponds to &amp;quot;aincient&amp;quot; Visual Prolog 5 resource dialog that has been &amp;quot;inherited&amp;quot; into the project.  If in doubt: the code in the corresponding &amp;#039;&amp;#039;&amp;#039;.pro&amp;#039;&amp;#039;&amp;#039; file of such a dialog will not contain a &amp;lt;vp&amp;gt;generatedInitialize&amp;lt;/vp&amp;gt; predicate.&lt;br /&gt;
&lt;br /&gt;
=== Binary memory representation ===&lt;br /&gt;
&lt;br /&gt;
Binaries have changed representation. In the old representation a binary was a pointer to the actual data, and immediately before the data the size of the binary was written. Windows API and other external APIs does not use this representation and as a consequence binaries was often had to be copied from the buffer that cntains it to another &amp;quot;buffer&amp;quot; that can hold the size infront of the data. A &amp;lt;vp&amp;gt;binary&amp;lt;/vp&amp;gt; is now represented as a pointer to a memory cell containing a pointer to a data-buffer and the size. So the size is no longer placed in a specific place relative to the actual data. With the old representation &amp;lt;vp&amp;gt;uncheckedConvert&amp;lt;/vp&amp;gt; of a binary to the &amp;lt;vp&amp;gt;pointer&amp;lt;/vp&amp;gt; domain would result in a pointer to the data. With the new representation this is no longer the case and therefore it has been made illegal to &amp;lt;vp&amp;gt;uncheckedConvert&amp;lt;/vp&amp;gt; from &amp;lt;vp&amp;gt;binary&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;pointer&amp;lt;/vp&amp;gt;, instead you must use &amp;lt;vp&amp;gt;convert&amp;lt;/vp&amp;gt; which will both in old and new representation give a pointer to the data. Alternatively, you can use the extension predicate &amp;lt;vp&amp;gt;binary::data()&amp;lt;/vp&amp;gt; instead, e.g. &amp;lt;vp&amp;gt;Pointer = MyBinary:data()&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== List comprehension ===&lt;br /&gt;
&lt;br /&gt;
In a list comprehension &amp;lt;vp&amp;gt;[ Exp || Gen ]&amp;lt;/vp&amp;gt; the &amp;lt;vp&amp;gt;Exp&amp;lt;/vp&amp;gt; must be a procedure (language reference has always required that, but the compiler has accepted &amp;lt;vp&amp;gt;determ&amp;lt;/vp&amp;gt; expressions). In cases where &amp;lt;vp&amp;gt;Exp&amp;lt;/vp&amp;gt; is determ the following rewrite can be applied &amp;lt;vp&amp;gt;[ V || Gen, V = Exp ]&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;&amp;gt;_list domains deprecated ===&lt;br /&gt;
&lt;br /&gt;
The domains &amp;lt;vp&amp;gt;integer_list&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;integer_list_list&amp;lt;/vp&amp;gt;, etc. has been deprecated. In declarations the *-form should be used, but in predicate calls like &amp;lt;vp&amp;gt;tryToTerm&amp;lt;/vp&amp;gt; it is necessary to uses the &amp;lt;vp&amp;gt;list{...}&amp;lt;/vp&amp;gt; type constructor, e.g. &amp;lt;vp&amp;gt;tryToTerm(list{integer}, String)&amp;lt;/vp&amp;gt;. An old program can require a significant amount of updates.&lt;br /&gt;
&lt;br /&gt;
=== Erroneous predicates as values ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;erroneous&amp;lt;/vp&amp;gt; predicates can now be used as a value, for example in &amp;lt;vp&amp;gt;X otherwise raise_error()&amp;lt;/vp&amp;gt;. Hereby &amp;lt;vp&amp;gt;erroneous&amp;lt;/vp&amp;gt; functions have become superfluous, and subsequently it is now illegal to declare &amp;lt;vp&amp;gt;erroneous&amp;lt;/vp&amp;gt; functions (a corresponding &amp;lt;vp&amp;gt;erroneous&amp;lt;/vp&amp;gt; predicate must be used instead).&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Visual Prolog 10 New Features]]&lt;br /&gt;
* [[Visual Prolog 9 Upgrade Notes]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Release Notes|10 Upgrade Notes]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Getting_Started&amp;diff=5001</id>
		<title>Getting Started</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Getting_Started&amp;diff=5001"/>
		<updated>2026-01-26T12:02:50Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: PDC is on com domain&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&lt;br /&gt;
No matter what prerequisites you have, it is a good idea to read the [[:Category:Tutorials|tutorials]].&lt;br /&gt;
&lt;br /&gt;
The tutorials in the [[Fundamental Visual Prolog]] section describe differences between Visual Prolog and traditional Prolog, and introduce a program that is developed in Visual Prolog.&lt;br /&gt;
&lt;br /&gt;
Other tutorials discuss the [[Ide/Environment Overview|Visual Prolog Integrated Environment]] (IDE) and various Visual Prolog language features.&lt;br /&gt;
&lt;br /&gt;
== Video Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.visual-prolog.com/video/HelloWorld/default.htm Hello World! Video Tutorial] covers basic IDE functionality&lt;br /&gt;
* [http://www.visual-prolog.com/video/IntelliSpeed/default.htm IntelliSpeed Video Tutorial] demonstrates the context sensitive keyboard accelerator and browse system.&lt;br /&gt;
&lt;br /&gt;
== Online Help System ==&lt;br /&gt;
&lt;br /&gt;
Once you are familiar with the concepts and principles, you also can use reference material from the following sections of the Help system: &lt;br /&gt;
&lt;br /&gt;
*The [[Language Reference]] that describes the syntax and semantics of the Visual Prolog language. &lt;br /&gt;
*Integrated Development Environment (IDE) Help.&lt;br /&gt;
*Prolog Foundation Classes (PFC) reference documentation. &lt;br /&gt;
&lt;br /&gt;
This Help is reference material rather than tutorial, meaning that it is not a good place to learn Visual Prolog, but it is a very good place to seek answers to specific questions.&lt;br /&gt;
&lt;br /&gt;
The Help system is available from the Integrated Development Environment.&lt;br /&gt;
&lt;br /&gt;
== Discussion forum ==&lt;br /&gt;
&lt;br /&gt;
You are also welcome to join Visual Prolog discussion forum and seek assistance or share your knowledge in the [https://discuss.visual-prolog.com Visual Prolog Discussion forums].&lt;br /&gt;
&lt;br /&gt;
You will find a lot of interesting information in the [https://discuss.visual-prolog.com/viewforum.php?f=3 Visual Prolog Tips, How To&amp;#039;s, Code Samples, etc]. And, of course, you are also invited to contribute your own tips, etc.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
You can download a number of [http://www.visual-prolog.com/link/demo.php demo examples] for Visual Prolog.&lt;br /&gt;
&lt;br /&gt;
Notice that the Microsoft Edge browser may say that the download is not safe, which is not true.  Click on the three dots and choose &amp;quot;Keep&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== PDC ==&lt;br /&gt;
&lt;br /&gt;
Visual Prolog is made by the company PDC. We invite you to visit the [https://www.pdc.com PDC homepage] to find descriptions of real-world commercial projects written entirely in Visual Prolog for:&lt;br /&gt;
&lt;br /&gt;
* Staff Planning &lt;br /&gt;
* Hospital Booking &lt;br /&gt;
* Airport Decision Support &lt;br /&gt;
* Airline Decision Support &lt;br /&gt;
* Shop Floor Scheduling&lt;br /&gt;
&lt;br /&gt;
We hope, you will enjoy Visual Prolog!&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic Information]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Getting_Started&amp;diff=5000</id>
		<title>Getting Started</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Getting_Started&amp;diff=5000"/>
		<updated>2026-01-26T11:59:48Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Download examples&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&lt;br /&gt;
No matter what prerequisites you have, it is a good idea to read the [[:Category:Tutorials|tutorials]].&lt;br /&gt;
&lt;br /&gt;
The tutorials in the [[Fundamental Visual Prolog]] section describe differences between Visual Prolog and traditional Prolog, and introduce a program that is developed in Visual Prolog.&lt;br /&gt;
&lt;br /&gt;
Other tutorials discuss the [[Ide/Environment Overview|Visual Prolog Integrated Environment]] (IDE) and various Visual Prolog language features.&lt;br /&gt;
&lt;br /&gt;
== Video Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.visual-prolog.com/video/HelloWorld/default.htm Hello World! Video Tutorial] covers basic IDE functionality&lt;br /&gt;
* [http://www.visual-prolog.com/video/IntelliSpeed/default.htm IntelliSpeed Video Tutorial] demonstrates the context sensitive keyboard accelerator and browse system.&lt;br /&gt;
&lt;br /&gt;
== Online Help System ==&lt;br /&gt;
&lt;br /&gt;
Once you are familiar with the concepts and principles, you also can use reference material from the following sections of the Help system: &lt;br /&gt;
&lt;br /&gt;
*The [[Language Reference]] that describes the syntax and semantics of the Visual Prolog language. &lt;br /&gt;
*Integrated Development Environment (IDE) Help.&lt;br /&gt;
*Prolog Foundation Classes (PFC) reference documentation. &lt;br /&gt;
&lt;br /&gt;
This Help is reference material rather than tutorial, meaning that it is not a good place to learn Visual Prolog, but it is a very good place to seek answers to specific questions.&lt;br /&gt;
&lt;br /&gt;
The Help system is available from the Integrated Development Environment.&lt;br /&gt;
&lt;br /&gt;
== Discussion forum ==&lt;br /&gt;
&lt;br /&gt;
You are also welcome to join Visual Prolog discussion forum and seek assistance or share your knowledge in the [https://discuss.visual-prolog.com Visual Prolog Discussion forums].&lt;br /&gt;
&lt;br /&gt;
You will find a lot of interesting information in the [https://discuss.visual-prolog.com/viewforum.php?f=3 Visual Prolog Tips, How To&amp;#039;s, Code Samples, etc]. And, of course, you are also invited to contribute your own tips, etc.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
You can download a number of [http://www.visual-prolog.com/link/demo.php demo examples] for Visual Prolog.&lt;br /&gt;
&lt;br /&gt;
Notice that the Microsoft Edge browser may say that the download is not safe, which is not true.  Click on the three dots and choose &amp;quot;Keep&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== PDC ==&lt;br /&gt;
&lt;br /&gt;
Visual Prolog is made by the company PDC. We invite you to visit the [https://www.pdc.dk PDC homepage] to find descriptions of real-world commercial projects written entirely in Visual Prolog for:&lt;br /&gt;
&lt;br /&gt;
* Staff Planning &lt;br /&gt;
* Hospital Booking &lt;br /&gt;
* Airport Decision Support &lt;br /&gt;
* Airline Decision Support &lt;br /&gt;
* Shop Floor Scheduling&lt;br /&gt;
&lt;br /&gt;
We hope, you will enjoy Visual Prolog!&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic Information]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Lists_and_Recursion&amp;diff=4999</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=4999"/>
		<updated>2025-10-06T13:10:33Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: format bug&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 &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;2&amp;lt;/vp&amp;gt;, and &amp;lt;vp&amp;gt;3&amp;lt;/vp&amp;gt; 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 &amp;lt;vp&amp;gt;[1, 2, 3]&amp;lt;/vp&amp;gt; is different from the list &amp;lt;vp&amp;gt;[1, 3, 2]&amp;lt;/vp&amp;gt;.&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;
== Lists Domains ==&lt;br /&gt;
&lt;br /&gt;
It &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt; is a type/domain then &amp;lt;vp&amp;gt;T*&amp;lt;/vp&amp;gt; is the domain of lists containing &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt; elements.  I.e. an asterisk after a domain means &amp;quot;List of that domain&amp;quot;.&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 &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;same&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; domain.&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;
The tail of a list is always a list; the head of a list is an element.&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;
If you take the first element from the tail of a list enough times, you will eventually get down to an empty list (&amp;lt;vp&amp;gt;[]&amp;lt;/vp&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
The empty list cannot be broken into head and tail.&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;50&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;implement main&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        write_a_list([1, 2, 3]).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    write_a_list : (integer* List).&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),&lt;br /&gt;
        stdio::nl,&lt;br /&gt;
        write_a_list(T).&lt;br /&gt;
&lt;br /&gt;
end implement main&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::runUtf8(main::run).&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;
*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 &amp;lt;vp&amp;gt;write_a_list&amp;lt;/vp&amp;gt; predicate is called from &amp;lt;vp&amp;gt;run&amp;lt;/vp&amp;gt; clause:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;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;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;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;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 an empty list, &amp;lt;vp&amp;gt;[]&amp;lt;/vp&amp;gt;, is &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
*The length of any other list is the length of its tail plus &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt;.&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 main&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    length_of : (A* List) -&amp;gt; integer Length.&lt;br /&gt;
&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement main&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    length_of([]) = 0.&lt;br /&gt;
    length_of([_ | T]) = Length :-&lt;br /&gt;
        TailLength = length_of(T),&lt;br /&gt;
        Length = TailLength + 1.&lt;br /&gt;
&lt;br /&gt;
end implement main&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    Length = main::length_of([1, 2, 3]),&lt;br /&gt;
    stdio::write(Length).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Take a look at the second clause first. Crucially, &amp;lt;vp&amp;gt;[_ | T]&amp;lt;/vp&amp;gt; will match any nonempty list, binding &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt; 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;Length = main::length_of([1, 2, 3])&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will match the second clause, with &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt; = &amp;lt;vp&amp;gt;[2, 3]&amp;lt;/vp&amp;gt;. The next step is to compute the length of &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt;. When this is done (never mind how), &amp;lt;vp&amp;gt;TailLength&amp;lt;/vp&amp;gt; will get the value &amp;lt;vp&amp;gt;2&amp;lt;/vp&amp;gt;, and the computer can then add &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; to it and bind &amp;lt;vp&amp;gt;Length&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;3&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
So how is the middle step executed? That step was to find the length of &amp;lt;vp&amp;gt;[2, 3]&amp;lt;/vp&amp;gt; by satisfying the goal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;TailLength = main::length_of([2, 3])&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In other words, &amp;lt;vp&amp;gt;length_of&amp;lt;/vp&amp;gt; calls itself recursively. This goal matches the second clause, binding&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;vp&amp;gt;[3]&amp;lt;/vp&amp;gt; in the goal to &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt; in the clause and&lt;br /&gt;
*&amp;lt;vp&amp;gt;TailLength&amp;lt;/vp&amp;gt; in the goal to &amp;lt;vp&amp;gt;Length&amp;lt;/vp&amp;gt; in the clause.&lt;br /&gt;
&lt;br /&gt;
Recall that &amp;lt;vp&amp;gt;TailLength&amp;lt;/vp&amp;gt; in the goal will not interfere with &amp;lt;vp&amp;gt;TailLength&amp;lt;/vp&amp;gt; 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 &amp;lt;vp&amp;gt;[3]&amp;lt;/vp&amp;gt;, which will be &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt;, and then add &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; to that to get the length of &amp;lt;vp&amp;gt;[2, 3]&amp;lt;/vp&amp;gt;, which will be &amp;lt;vp&amp;gt;2&amp;lt;/vp&amp;gt;. So far, so good.&lt;br /&gt;
&lt;br /&gt;
Likewise, &amp;lt;vp&amp;gt;length_of&amp;lt;/vp&amp;gt; will call itself recursively again to get the length of &amp;lt;vp&amp;gt;[3]&amp;lt;/vp&amp;gt;. The tail of &amp;lt;vp&amp;gt;[3]&amp;lt;/vp&amp;gt; is &amp;lt;vp&amp;gt;[]&amp;lt;/vp&amp;gt;, so &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt; is bound to &amp;lt;vp&amp;gt;[]&amp;lt;/vp&amp;gt;, and the problem is to get the length of &amp;lt;vp&amp;gt;[]&amp;lt;/vp&amp;gt;, then add 1 to it, giving the length of &amp;lt;vp&amp;gt;[3]&amp;lt;/vp&amp;gt;.&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;TailLength = main::length_of([])&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
matches the &amp;#039;&amp;#039;first&amp;#039;&amp;#039; clause, binding &amp;lt;vp&amp;gt;TailLength&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt;. So now the computer can add &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; to that, giving the length of &amp;lt;vp&amp;gt;[3]&amp;lt;/vp&amp;gt;, and return to the calling clause. This, in turn, will add &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; again, giving the length of &amp;lt;vp&amp;gt;[2, 3]&amp;lt;/vp&amp;gt;, and return to the clause that called it; this original clause will add &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; again, giving the length of &amp;lt;vp&amp;gt;[1, 2, 3]&amp;lt;/vp&amp;gt;.&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 suffixes 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;Length_1 = main::length_of([1, 2, 3]).&lt;br /&gt;
    TailLength_1 = main::length_of([2, 3]).&lt;br /&gt;
        TailLength_2 = main::length_of([3]).&lt;br /&gt;
            TailLength_3 = main::length_of([]).&lt;br /&gt;
            TailLength_3 = 0.&lt;br /&gt;
        Length_3 =  TailLength_3 + 1 = 1.&lt;br /&gt;
    Length_2 = Length_3 + 1 = 2.&lt;br /&gt;
Length_1 = Length_2 + 1 = 3.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that the code above can be written more compact without the use of intermediate variables like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    length_of([]) = 0.&lt;br /&gt;
    length_of([_ | T]) = length_of(T) + 1.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These clauses more or less directly states the original specification:&lt;br /&gt;
&lt;br /&gt;
*The length of an empty list, &amp;lt;vp&amp;gt;[]&amp;lt;/vp&amp;gt;, is &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
*The length of any other list is the length of its tail plus &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Tail Recursion===&lt;br /&gt;
&lt;br /&gt;
You probably noticed that &amp;lt;vp&amp;gt;length_of&amp;lt;/vp&amp;gt; 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 &amp;lt;vp&amp;gt;length_of&amp;lt;/vp&amp;gt; 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 two arguments.&lt;br /&gt;
&lt;br /&gt;
* The first is the list, which the computer will whittle away on each call until it eventually becomes empty, just as before.&lt;br /&gt;
* The second is an counter that starts out as &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt; and increments on each call.&lt;br /&gt;
&lt;br /&gt;
When the list is finally empty, you&amp;#039;ll return the counter as the list length.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class main&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    length_of : (A* List, integer Counter) -&amp;gt; integer Result.&lt;br /&gt;
&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement main&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    length_of([], Counter) = Counter.&lt;br /&gt;
    length_of([_ | T], Counter) = Result :-&lt;br /&gt;
        NewCounter = Counter + 1,&lt;br /&gt;
        Result = length_of(T, NewCounter).&lt;br /&gt;
&lt;br /&gt;
end implement main&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    Length = main::length_of([1, 2, 3], 0), /* start with Counter = 0 */&lt;br /&gt;
    stdio::write(&amp;quot;Length = &amp;quot;, Length).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This version of the &amp;lt;vp&amp;gt;length_of&amp;lt;/vp&amp;gt; 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, &amp;#039;&amp;#039;by devious means, you can often find a tail-recursive algorithm for a problem that seems to demand a different type of recursion&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 main&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    add1 : (integer* NumberList) -&amp;gt; integer* IncrList.&lt;br /&gt;
&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement main&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    add1([]) = []. % boundary condition&lt;br /&gt;
    add1([Head | Tail]) = Result :-&lt;br /&gt;
        % separate the head  from the rest of the list&lt;br /&gt;
        Head1 = Head + 1, % add 1 to the first element&lt;br /&gt;
        Tail1 = add1(Tail), % call element with the rest of the list&lt;br /&gt;
        Result = [Head1 | Tail1]. % Put the new head infront of the new tail&lt;br /&gt;
&lt;br /&gt;
end implement main&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    NewList = main::add1([1, 2, 3, 4]),&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;
Runnig the the predicate with &amp;lt;vp&amp;gt;[1, 2, 3, 4]&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;NewList = add1([1,2,3,4]).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will result in &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NewList = [2, 3, 4, 5]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tail Recursion Again ===&lt;br /&gt;
&lt;br /&gt;
Is &amp;lt;vp&amp;gt;add1&amp;lt;/vp&amp;gt; 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;lt;vp&amp;gt;Head&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;Tail&amp;lt;/vp&amp;gt;.&lt;br /&gt;
*Add &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;Head&amp;lt;/vp&amp;gt;, giving &amp;lt;vp&amp;gt;Head1&amp;lt;/vp&amp;gt;.&lt;br /&gt;
*Recursively add 1 to all the elements of &amp;lt;vp&amp;gt;Tail&amp;lt;/vp&amp;gt;, giving &amp;lt;vp&amp;gt;Tail1&amp;lt;/vp&amp;gt;.&lt;br /&gt;
*Combine &amp;lt;vp&amp;gt;Head1&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;Tail1&amp;lt;/vp&amp;gt;, 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;that is not how Prolog does it&amp;#039;&amp;#039;. In Visual Prolog, &amp;lt;vp&amp;gt;add1&amp;lt;/vp&amp;gt; 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;lt;vp&amp;gt;Head&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;Tail&amp;lt;/vp&amp;gt;.&lt;br /&gt;
*Bind the head and tail of &amp;lt;vp&amp;gt;Result&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;Head1&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;Tail1&amp;lt;/vp&amp;gt;. (&amp;lt;vp&amp;gt;Head1&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;Tail1&amp;lt;/vp&amp;gt; do not have values yet.)&lt;br /&gt;
*Add &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;Head&amp;lt;/vp&amp;gt;, giving &amp;lt;vp&amp;gt;Head1&amp;lt;/vp&amp;gt;.&lt;br /&gt;
*Recursively add &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; to all the elements of &amp;lt;vp&amp;gt;Tail&amp;lt;/vp&amp;gt;, giving &amp;lt;vp&amp;gt;Tail1&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
When this is done, &amp;lt;vp&amp;gt;Head1&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;Tail1&amp;lt;/vp&amp;gt; are &amp;#039;&amp;#039;already&amp;#039;&amp;#039; the head and tail of &amp;lt;vp&amp;gt;Result&amp;lt;/vp&amp;gt;; 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 main&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    discard_negatives : (integer*, integer* [out]).&lt;br /&gt;
&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement main&lt;br /&gt;
&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;
&lt;br /&gt;
end implement main &lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    main::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;main::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;clauses&lt;br /&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 program below, 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;main::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;class main&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    isMember : (A, A*) determ.&lt;br /&gt;
&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement main&lt;br /&gt;
&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;
&lt;br /&gt;
end implement main&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    main::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;
    or&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 program works in two ways. Consider its clauses once again:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    isMember(Name, [Name | _]) :-&lt;br /&gt;
        !.&lt;br /&gt;
    isMember(Name, [_ | Tail]) :-&lt;br /&gt;
        isMember(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;
This 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;class main&lt;br /&gt;
&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 Name [out], address Address [out], age Age [out]) multi.&lt;br /&gt;
    sumlist : (age* AgeList, age Age [out], integer Count [out]).&lt;br /&gt;
&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement main&lt;br /&gt;
&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,&lt;br /&gt;
        N = 1 + N1.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    person(&amp;quot;Sherlock Holmes&amp;quot;, &amp;quot;22B Baker Street&amp;quot;, 42).&lt;br /&gt;
    person(&amp;quot;Pete Spiers&amp;quot;, &amp;quot;Apt. 22, 21st Street&amp;quot;, 36).&lt;br /&gt;
    person(&amp;quot;Mary Darrow&amp;quot;, &amp;quot;Suite 2, Omega Home&amp;quot;, 51).&lt;br /&gt;
&lt;br /&gt;
end implement main&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    L = [Age || main::person(_, _, Age)],&lt;br /&gt;
    main::sumlist(L, Sum, N),&lt;br /&gt;
    Average = Sum / N,&lt;br /&gt;
    stdio::writef(&amp;quot;Average = %.&amp;quot;, Average).&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 || main::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 in [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;
    list = elem*.&lt;br /&gt;
    elem = l(list List); i(integer Integer); c(char Char); s(string String).&lt;br /&gt;
        % the functors are l, i, c, and s&lt;br /&gt;
&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 main&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    list = elem*.&lt;br /&gt;
    elem = l(list List); i(integer Integer); c(char Char); s(string String).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    test : ().&lt;br /&gt;
&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement main&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    append : (A*, A*, A* [out]).&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;
&lt;br /&gt;
end implement main&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    main::test().&lt;br /&gt;
&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;/*******************************************&lt;br /&gt;
* Lexer&lt;br /&gt;
*******************************************/&lt;br /&gt;
&lt;br /&gt;
class lexer&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    tokl : (string Input) -&amp;gt; string* TokenTL.&lt;br /&gt;
&lt;br /&gt;
end class lexer&lt;br /&gt;
&lt;br /&gt;
implement lexer&lt;br /&gt;
&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;
&lt;br /&gt;
end implement lexer&lt;br /&gt;
&lt;br /&gt;
/*******************************************&lt;br /&gt;
* Parser&lt;br /&gt;
*******************************************/&lt;br /&gt;
&lt;br /&gt;
class parser&lt;br /&gt;
&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;
&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;
        !,&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;
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;
&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 in 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&lt;br /&gt;
[a, b | [c, d]] or&lt;br /&gt;
[a, b, c | [d]] or&lt;br /&gt;
[a | [b | [c, d]]] or&lt;br /&gt;
[a | [b | [c | [d]]]] or&lt;br /&gt;
[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>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Lists_and_Recursion&amp;diff=4998</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=4998"/>
		<updated>2025-10-06T13:09:25Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: add goal&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 &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;2&amp;lt;/vp&amp;gt;, and &amp;lt;vp&amp;gt;3&amp;lt;/vp&amp;gt; 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 &amp;lt;vp&amp;gt;[1, 2, 3]&amp;lt;/vp&amp;gt; is different from the list &amp;lt;vp&amp;gt;[1, 3, 2]&amp;lt;/vp&amp;gt;.&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;
== Lists Domains ==&lt;br /&gt;
&lt;br /&gt;
It &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt; is a type/domain then &amp;lt;vp&amp;gt;T*&amp;lt;/vp&amp;gt; is the domain of lists containing &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt; elements.  I.e. an asterisk after a domain means &amp;quot;List of that domain&amp;quot;.&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 &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;same&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; domain.&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;
The tail of a list is always a list; the head of a list is an element.&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;
If you take the first element from the tail of a list enough times, you will eventually get down to an empty list (&amp;lt;vp&amp;gt;[]&amp;lt;/vp&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
The empty list cannot be broken into head and tail.&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;50&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;implement main&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        write_a_list([1, 2, 3]).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    write_a_list : (integer* List).&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),&lt;br /&gt;
        stdio::nl,&lt;br /&gt;
        write_a_list(T).&lt;br /&gt;
&lt;br /&gt;
end implement main&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::runUtf8(main::run).&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;
*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 &amp;lt;vp&amp;gt;write_a_list&amp;lt;/vp&amp;gt; predicate is called from &amp;lt;vp&amp;gt;run&amp;lt;/vp&amp;gt; clause:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;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;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;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;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 an empty list, &amp;lt;vp&amp;gt;[]&amp;lt;/vp&amp;gt;, is &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
*The length of any other list is the length of its tail plus &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt;.&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 main&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    length_of : (A* List) -&amp;gt; integer Length.&lt;br /&gt;
&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement main&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    length_of([]) = 0.&lt;br /&gt;
    length_of([_ | T]) = Length :-&lt;br /&gt;
        TailLength = length_of(T),&lt;br /&gt;
        Length = TailLength + 1.&lt;br /&gt;
&lt;br /&gt;
end implement main&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    Length = main::length_of([1, 2, 3]),&lt;br /&gt;
    stdio::write(Length).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Take a look at the second clause first. Crucially, &amp;lt;vp&amp;gt;[_ | T]&amp;lt;/vp&amp;gt; will match any nonempty list, binding &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt; 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;Length = main::length_of([1, 2, 3])&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will match the second clause, with &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt; = &amp;lt;vp&amp;gt;[2, 3]&amp;lt;/vp&amp;gt;. The next step is to compute the length of &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt;. When this is done (never mind how), &amp;lt;vp&amp;gt;TailLength&amp;lt;/vp&amp;gt; will get the value &amp;lt;vp&amp;gt;2&amp;lt;/vp&amp;gt;, and the computer can then add &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; to it and bind &amp;lt;vp&amp;gt;Length&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;3&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
So how is the middle step executed? That step was to find the length of &amp;lt;vp&amp;gt;[2, 3]&amp;lt;/vp&amp;gt; by satisfying the goal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;TailLength = main::length_of([2, 3])&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In other words, &amp;lt;vp&amp;gt;length_of&amp;lt;/vp&amp;gt; calls itself recursively. This goal matches the second clause, binding&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;vp&amp;gt;[3]&amp;lt;/vp&amp;gt; in the goal to &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt; in the clause and&lt;br /&gt;
*&amp;lt;vp&amp;gt;TailLength&amp;lt;/vp&amp;gt; in the goal to &amp;lt;vp&amp;gt;Length&amp;lt;/vp&amp;gt; in the clause.&lt;br /&gt;
&lt;br /&gt;
Recall that &amp;lt;vp&amp;gt;TailLength&amp;lt;/vp&amp;gt; in the goal will not interfere with &amp;lt;vp&amp;gt;TailLength&amp;lt;/vp&amp;gt; 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 &amp;lt;vp&amp;gt;[3]&amp;lt;/vp&amp;gt;, which will be &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt;, and then add &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; to that to get the length of &amp;lt;vp&amp;gt;[2, 3]&amp;lt;/vp&amp;gt;, which will be &amp;lt;vp&amp;gt;2&amp;lt;/vp&amp;gt;. So far, so good.&lt;br /&gt;
&lt;br /&gt;
Likewise, &amp;lt;vp&amp;gt;length_of&amp;lt;/vp&amp;gt; will call itself recursively again to get the length of &amp;lt;vp&amp;gt;[3]&amp;lt;/vp&amp;gt;. The tail of &amp;lt;vp&amp;gt;[3]&amp;lt;/vp&amp;gt; is &amp;lt;vp&amp;gt;[]&amp;lt;/vp&amp;gt;, so &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt; is bound to &amp;lt;vp&amp;gt;[]&amp;lt;/vp&amp;gt;, and the problem is to get the length of &amp;lt;vp&amp;gt;[]&amp;lt;/vp&amp;gt;, then add 1 to it, giving the length of &amp;lt;vp&amp;gt;[3]&amp;lt;/vp&amp;gt;.&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;TailLength = main::length_of([])&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
matches the &amp;#039;&amp;#039;first&amp;#039;&amp;#039; clause, binding &amp;lt;vp&amp;gt;TailLength&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt;. So now the computer can add &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; to that, giving the length of &amp;lt;vp&amp;gt;[3]&amp;lt;/vp&amp;gt;, and return to the calling clause. This, in turn, will add &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; again, giving the length of &amp;lt;vp&amp;gt;[2, 3]&amp;lt;/vp&amp;gt;, and return to the clause that called it; this original clause will add &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; again, giving the length of &amp;lt;vp&amp;gt;[1, 2, 3]&amp;lt;/vp&amp;gt;.&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 suffixes 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;Length_1 = main::length_of([1, 2, 3]).&lt;br /&gt;
    TailLength_1 = main::length_of([2, 3]).&lt;br /&gt;
        TailLength_2 = main::length_of([3]).&lt;br /&gt;
            TailLength_3 = main::length_of([]).&lt;br /&gt;
            TailLength_3 = 0.&lt;br /&gt;
        Length_3 =  TailLength_3 + 1 = 1.&lt;br /&gt;
    Length_2 = Length_3 + 1 = 2.&lt;br /&gt;
Length_1 = Length_2 + 1 = 3.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that the code above can be written more compact without the use of intermediate variables like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    length_of([]) = 0.&lt;br /&gt;
    length_of([_ | T]) = length_of(T) + 1.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These clauses more or less directly states the original specification:&lt;br /&gt;
&lt;br /&gt;
*The length of an empty list, &amp;lt;vp&amp;gt;[]&amp;lt;/vp&amp;gt;, is &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
*The length of any other list is the length of its tail plus &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Tail Recursion===&lt;br /&gt;
&lt;br /&gt;
You probably noticed that &amp;lt;vp&amp;gt;length_of&amp;lt;/vp&amp;gt; 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 &amp;lt;vp&amp;gt;length_of&amp;lt;/vp&amp;gt; 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 two arguments.&lt;br /&gt;
&lt;br /&gt;
* The first is the list, which the computer will whittle away on each call until it eventually becomes empty, just as before.&lt;br /&gt;
* The second is an counter that starts out as &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt; and increments on each call.&lt;br /&gt;
&lt;br /&gt;
When the list is finally empty, you&amp;#039;ll return the counter as the list length.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class main&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    length_of : (A* List, integer Counter) -&amp;gt; integer Result.&lt;br /&gt;
&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement main&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    length_of([], Counter) = Counter.&lt;br /&gt;
    length_of([_ | T], Counter) = Result :-&lt;br /&gt;
        NewCounter = Counter + 1,&lt;br /&gt;
        Result = length_of(T, NewCounter).&lt;br /&gt;
&lt;br /&gt;
end implement main&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    Length = main::length_of([1, 2, 3], 0), /* start with Counter = 0 */&lt;br /&gt;
    stdio::write(&amp;quot;Length = &amp;quot;, Length).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This version of the &amp;lt;vp&amp;gt;length_of&amp;lt;/vp&amp;gt; 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, &amp;#039;&amp;#039;by devious means, you can often find a tail-recursive algorithm for a problem that seems to demand a different type of recursion&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 main&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    add1 : (integer* NumberList) -&amp;gt; integer* IncrList.&lt;br /&gt;
&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement main&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    add1([]) = []. % boundary condition&lt;br /&gt;
    add1([Head | Tail]) = Result :-&lt;br /&gt;
        % separate the head  from the rest of the list&lt;br /&gt;
        Head1 = Head + 1, % add 1 to the first element&lt;br /&gt;
        Tail1 = add1(Tail), % call element with the rest of the list&lt;br /&gt;
        Result = [Head1 | Tail1]. % Put the new head infront of the new tail&lt;br /&gt;
&lt;br /&gt;
end implement main&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    NewList = main::add1([1, 2, 3, 4]),&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;
Runnig the the predicate with &amp;lt;vp&amp;gt;[1, 2, 3, 4]&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;NewList = add1([1,2,3,4]).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will result in &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NewList = [2, 3, 4, 5]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tail Recursion Again ===&lt;br /&gt;
&lt;br /&gt;
Is &amp;lt;vp&amp;gt;add1&amp;lt;/vp&amp;gt; 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;lt;vp&amp;gt;Head&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;Tail&amp;lt;/vp&amp;gt;.&lt;br /&gt;
*Add &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;Head&amp;lt;/vp&amp;gt;, giving &amp;lt;vp&amp;gt;Head1&amp;lt;/vp&amp;gt;.&lt;br /&gt;
*Recursively add 1 to all the elements of &amp;lt;vp&amp;gt;Tail&amp;lt;/vp&amp;gt;, giving &amp;lt;vp&amp;gt;Tail1&amp;lt;/vp&amp;gt;.&lt;br /&gt;
*Combine &amp;lt;vp&amp;gt;Head1&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;Tail1&amp;lt;/vp&amp;gt;, 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;that is not how Prolog does it&amp;#039;&amp;#039;. In Visual Prolog, &amp;lt;vp&amp;gt;add1&amp;lt;/vp&amp;gt; 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;lt;vp&amp;gt;Head&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;Tail&amp;lt;/vp&amp;gt;.&lt;br /&gt;
*Bind the head and tail of &amp;lt;vp&amp;gt;Result&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;Head1&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;Tail1&amp;lt;/vp&amp;gt;. (&amp;lt;vp&amp;gt;Head1&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;Tail1&amp;lt;/vp&amp;gt; do not have values yet.)&lt;br /&gt;
*Add &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;Head&amp;lt;/vp&amp;gt;, giving &amp;lt;vp&amp;gt;Head1&amp;lt;/vp&amp;gt;.&lt;br /&gt;
*Recursively add &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; to all the elements of &amp;lt;vp&amp;gt;Tail&amp;lt;/vp&amp;gt;, giving &amp;lt;vp&amp;gt;Tail1&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
When this is done, &amp;lt;vp&amp;gt;Head1&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;Tail1&amp;lt;/vp&amp;gt; are &amp;#039;&amp;#039;already&amp;#039;&amp;#039; the head and tail of &amp;lt;vp&amp;gt;Result&amp;lt;/vp&amp;gt;; 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 main&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    discard_negatives : (integer*, integer* [out]).&lt;br /&gt;
&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement main&lt;br /&gt;
&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;
&lt;br /&gt;
end implement main &lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    main::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;main::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;clauses&lt;br /&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 program below, 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;main::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;class main&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    isMember : (A, A*) determ.&lt;br /&gt;
&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement main&lt;br /&gt;
&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;
&lt;br /&gt;
end implement main&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    main::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;
    or&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 program works in two ways. Consider its clauses once again:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    isMember(Name, [Name | _]) :-&lt;br /&gt;
        !.&lt;br /&gt;
    isMember(Name, [_ | Tail]) :-&lt;br /&gt;
        isMember(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;
This 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;class main&lt;br /&gt;
&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 Name [out], address Address [out], age Age [out]) multi.&lt;br /&gt;
    sumlist : (age* AgeList, age Age [out], integer Count [out]).&lt;br /&gt;
&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement main&lt;br /&gt;
&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,&lt;br /&gt;
        N = 1 + N1.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    person(&amp;quot;Sherlock Holmes&amp;quot;, &amp;quot;22B Baker Street&amp;quot;, 42).&lt;br /&gt;
    person(&amp;quot;Pete Spiers&amp;quot;, &amp;quot;Apt. 22, 21st Street&amp;quot;, 36).&lt;br /&gt;
    person(&amp;quot;Mary Darrow&amp;quot;, &amp;quot;Suite 2, Omega Home&amp;quot;, 51).&lt;br /&gt;
&lt;br /&gt;
end implement main&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    L = [Age || main::person(_, _, Age)],&lt;br /&gt;
    main::sumlist(L, Sum, N),&lt;br /&gt;
    Average = Sum / N,&lt;br /&gt;
    stdio::writef(&amp;quot;Average = %.&amp;quot;, Average).&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 || main::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 in [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;
    list = elem*.&lt;br /&gt;
    elem = l(list List); i(integer Integer); c(char Char); s(string String).&lt;br /&gt;
        % the functors are l, i, c, and s&lt;br /&gt;
&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 main&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    list = elem*.&lt;br /&gt;
    elem = l(list List); i(integer Integer); c(char Char); s(string String).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    test : ().&lt;br /&gt;
&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement main&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    append : (A*, A*, A* [out]).&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;
&lt;br /&gt;
end implement main&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    main::test().&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;/*******************************************&lt;br /&gt;
* Lexer&lt;br /&gt;
*******************************************/&lt;br /&gt;
&lt;br /&gt;
class lexer&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    tokl : (string Input) -&amp;gt; string* TokenTL.&lt;br /&gt;
&lt;br /&gt;
end class lexer&lt;br /&gt;
&lt;br /&gt;
implement lexer&lt;br /&gt;
&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;
&lt;br /&gt;
end implement lexer&lt;br /&gt;
&lt;br /&gt;
/*******************************************&lt;br /&gt;
* Parser&lt;br /&gt;
*******************************************/&lt;br /&gt;
&lt;br /&gt;
class parser&lt;br /&gt;
&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;
&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;
        !,&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;
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;
&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 in 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&lt;br /&gt;
[a, b | [c, d]] or&lt;br /&gt;
[a, b, c | [d]] or&lt;br /&gt;
[a | [b | [c, d]]] or&lt;br /&gt;
[a | [b | [c | [d]]]] or&lt;br /&gt;
[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>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms/Anonymous_Predicates&amp;diff=4997</id>
		<title>Language Reference/Terms/Anonymous Predicates</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms/Anonymous_Predicates&amp;diff=4997"/>
		<updated>2025-08-22T11:05:54Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Review&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==== Anonymous Predicates ====&lt;br /&gt;
&lt;br /&gt;
An anonymous predicate is an expression that evaluates to a predicate value. The value can be bound to a variable, passed as an argument, or returned as a result, but it has no name in any class, interface, or implementation.&lt;br /&gt;
&lt;br /&gt;
Anonymous predicates have the ability to capture values from the context in which the expression occurs; this is a powerful ability that can be used to avoid a rather excessive amount of strange/unpleasant code.&lt;br /&gt;
&lt;br /&gt;
===== Syntax =====&lt;br /&gt;
&lt;br /&gt;
Anonymous predicates are terms:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;Term&amp;gt; : one of&lt;br /&gt;
    ...&lt;br /&gt;
    &amp;lt;AnonymousPredicate&amp;gt;&lt;br /&gt;
    ...&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An anonymous predicate is a nameless clause in curly brackets. Certain parts are optional, giving these forms:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;AnonymousPredicate&amp;gt; : one of&lt;br /&gt;
    { ( &amp;lt;Arg&amp;gt;-comma-sep-list ) = &amp;lt;Term&amp;gt; }&lt;br /&gt;
    { ( &amp;lt;Arg&amp;gt;-comma-sep-list ) = &amp;lt;Term&amp;gt; :- &amp;lt;Term&amp;gt; }&lt;br /&gt;
    { ( &amp;lt;Arg&amp;gt;-comma-sep-list ) :- &amp;lt;Term&amp;gt; }&lt;br /&gt;
    { = &amp;lt;Term&amp;gt; }&lt;br /&gt;
    { = &amp;lt;Term&amp;gt; :- &amp;lt;Term&amp;gt; }&lt;br /&gt;
    { :- &amp;lt;Term&amp;gt; }&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
Leaving out the argument list means &amp;quot;the required number of arguments&amp;quot; and can be used whenever the arguments are not used inside the predicate expression.&lt;br /&gt;
&lt;br /&gt;
===== Semantics =====&lt;br /&gt;
&lt;br /&gt;
An anonymous predicate expression evaluates to a predicate value.&lt;br /&gt;
Consider this code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        Inc = { (X) = X+1 },&lt;br /&gt;
        A = Inc(4),&lt;br /&gt;
        B = Inc(23),&lt;br /&gt;
        stdio::writef(&amp;quot;A = %, B = %&amp;quot;, A, B).&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Inc becomes an increment predicate, so the program will write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;A = 5, B = 24&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code in this example corresponds to this code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        Inc = inc,&lt;br /&gt;
        A = Inc(4),&lt;br /&gt;
        B = Inc(23),&lt;br /&gt;
        stdio::writef(&amp;quot;A = %, B = %&amp;quot;, A, B).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    inc : (integer X) -&amp;gt; integer R.&lt;br /&gt;
clauses&lt;br /&gt;
    inc(X) = X+1.&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Where the clause &amp;lt;vp&amp;gt;(X) = X+1&amp;lt;/vp&amp;gt; can be found in the last line; i.e., this time in a named predicate.&lt;br /&gt;
&lt;br /&gt;
Variables that are bound outside (i.e., before the occurrence of) an anonymous predicate can be used inside the anonymous predicate. The value of the variable will be captured by the anonymous predicate.&lt;br /&gt;
&lt;br /&gt;
Variables that are bound in an anonymous predicate are local variables in the anonymous predicate.&lt;br /&gt;
&lt;br /&gt;
===== Capturing context =====&lt;br /&gt;
&lt;br /&gt;
An anonymous predicate can capture context, which means that it can refer to things that are defined in its context, especially facts and variables from the clause.&lt;br /&gt;
&lt;br /&gt;
===== Capturing variables =====&lt;br /&gt;
&lt;br /&gt;
An anonymous predicate occurs in a clause, and this clause may contain variables. Those variables that are bound before the anonymous predicate is met can be used inside the anonymous predicate.&lt;br /&gt;
This code illustrates how a variable is captured:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    pred = (integer) -&amp;gt; integer.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    createAdder : (integer A) -&amp;gt; pred Adder.&lt;br /&gt;
clauses&lt;br /&gt;
    createAdder(A) = { (X) = X+A }.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        Add17 = createAdder(17),&lt;br /&gt;
        A = Add17(4),&lt;br /&gt;
        B = Add17(20),&lt;br /&gt;
        stdio::writef(&amp;quot;A = %, B = %&amp;quot;, A, B).&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
We call &amp;lt;vp&amp;gt;createAdder&amp;lt;/vp&amp;gt; with &amp;lt;vp&amp;gt;17&amp;lt;/vp&amp;gt; as argument. So in the &amp;lt;vp&amp;gt;createAdder&amp;lt;/vp&amp;gt; clause &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; is &amp;lt;vp&amp;gt;17&amp;lt;/vp&amp;gt;, and therefore the result is &amp;lt;vp&amp;gt;{ (X) = X+17 }&amp;lt;/vp&amp;gt;. We say that the anonymous predicate has captured the variable &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Since &amp;lt;vp&amp;gt;Add17&amp;lt;/vp&amp;gt; is a predicate that adds &amp;lt;vp&amp;gt;17&amp;lt;/vp&amp;gt; to its argument, the output of the code will be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;A = 21, B = 37&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Capturing ellipsis (...) =====&lt;br /&gt;
&lt;br /&gt;
An anonymous predicate can capture the ellipsis variable (i.e., &amp;lt;vp&amp;gt;...&amp;lt;/vp&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    ppp(...)  :-&lt;br /&gt;
        W = { () :- stdio::write(...) },&lt;br /&gt;
        qqq(W).&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
&amp;lt;vp&amp;gt;W&amp;lt;/vp&amp;gt; captures the ellipsis variable. &amp;lt;vp&amp;gt;qqq&amp;lt;/vp&amp;gt; receives a nullary predicate; when this predicate is invoked the captured ellipsis variable will be written to the standard output device.&lt;br /&gt;
&lt;br /&gt;
===== Capturing facts =====&lt;br /&gt;
&lt;br /&gt;
An anonymous predicate can access facts. If it is created by a class predicate it can access class facts. If it is created by an object predicate it can access both object and class facts.&lt;br /&gt;
Consider this code that captures a class fact:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class facts&lt;br /&gt;
    count : integer := 0.&lt;br /&gt;
clauses&lt;br /&gt;
    seq() = { () = count :- count := count+1 }.&lt;br /&gt;
clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        A = seq(),&lt;br /&gt;
        B = seq(),&lt;br /&gt;
        stdio::writef(&amp;quot;A1 = %, &amp;quot;, A()),&lt;br /&gt;
        stdio::writef(&amp;quot;B1 = %, &amp;quot;, B()),&lt;br /&gt;
        stdio::writef(&amp;quot;A2 = %, &amp;quot;, A()),&lt;br /&gt;
        stdio::writef(&amp;quot;B2 = %&amp;quot;, B()).&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Both &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; increment the class fact &amp;lt;vp&amp;gt;count&amp;lt;/vp&amp;gt;, so the result is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;A1 = 1, B1 = 2, A2 = 3, B2 = 4&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In object predicates we can capture object facts. So assuming that &amp;lt;vp&amp;gt;seq&amp;lt;/vp&amp;gt; is an object predicate in &amp;lt;vp&amp;gt;myClass&amp;lt;/vp&amp;gt;, this code illustrates the capture of an object fact:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    count : integer := 0.&lt;br /&gt;
clauses&lt;br /&gt;
    seq() = { () = count :- count := count+1 }.&lt;br /&gt;
clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        A = myClass::new():seq(),&lt;br /&gt;
        B = myClass::new():seq(),&lt;br /&gt;
        stdio::writef(&amp;quot;A1 = %, &amp;quot;, A()),&lt;br /&gt;
        stdio::writef(&amp;quot;B1 = %, &amp;quot;, B()),&lt;br /&gt;
        stdio::writef(&amp;quot;A2 = %, &amp;quot;, A()),&lt;br /&gt;
        stdio::writef(&amp;quot;B2 = %&amp;quot;, B()).&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
In this case &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; come from two different objects, which each have a &amp;lt;vp&amp;gt;count&amp;lt;/vp&amp;gt; fact, so the output will be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;A1 = 1, B1 = 1, A2 = 2, B2 = 2&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Technically, the class version actually does not capture anything; it merely has access to the fact. Likewise, the object version does not actually capture the fact; instead it captures &amp;lt;vp&amp;gt;This&amp;lt;/vp&amp;gt; and through &amp;lt;vp&amp;gt;This&amp;lt;/vp&amp;gt; it obtains access to the object facts.&lt;br /&gt;
&lt;br /&gt;
===== Capturing This =====&lt;br /&gt;
&lt;br /&gt;
As described above it is possible to capture &amp;lt;vp&amp;gt;This&amp;lt;/vp&amp;gt; and thereby gain access to object facts. The same mechanism gives access to calling object predicates.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    seq() = { () = count :- inc() }.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    inc() :- count := count+1.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;This&amp;lt;/vp&amp;gt; can also be used directly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    ppp() = { () = aaa::rrr(This) }.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Nesting =====&lt;br /&gt;
&lt;br /&gt;
Anonymous predicates can be nested:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        P = { (A) = { (B) = A+B } },&lt;br /&gt;
        Q = P(3300),&lt;br /&gt;
        R = P(2200),&lt;br /&gt;
        stdio::writef(&amp;quot;Q(11) = %, &amp;quot;, Q(11)),&lt;br /&gt;
        stdio::writef(&amp;quot;R(11) = %&amp;quot;, R(11)).&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
To obtain &amp;lt;vp&amp;gt;Q&amp;lt;/vp&amp;gt; we call &amp;lt;vp&amp;gt;P&amp;lt;/vp&amp;gt; with &amp;lt;vp&amp;gt;3300&amp;lt;/vp&amp;gt;, so &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; is &amp;lt;vp&amp;gt;3300&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;Q&amp;lt;/vp&amp;gt; therefore becomes &amp;lt;vp&amp;gt;{ (B) = 3300+B }&amp;lt;/vp&amp;gt;; likewise &amp;lt;vp&amp;gt;R&amp;lt;/vp&amp;gt; becomes &amp;lt;vp&amp;gt;{ (B) = 2200+B }&amp;lt;/vp&amp;gt;. So the output is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;Q(11) = 3311, R(11) = 2211&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Syntactic Sugar =====&lt;br /&gt;
&lt;br /&gt;
If you do not need the arguments they can be skipped.  &lt;br /&gt;
So this code fragment:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
P = { (_) :- succeed },&lt;br /&gt;
Q = { (_, _) = 0 },&lt;br /&gt;
R = { (_, _, _) = _ :- fail }.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
can be shortened to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
P = { :- succeed },&lt;br /&gt;
Q = { = 0 },&lt;br /&gt;
R = { = _ :- fail }.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that the arguments are completely skipped. If you write &amp;lt;vp&amp;gt;()&amp;lt;/vp&amp;gt; it means zero arguments, whereas skipping the arguments means &amp;quot;a suitable amount&amp;quot; of arguments.&lt;br /&gt;
&lt;br /&gt;
==== Examples of practical usage ====&lt;br /&gt;
&lt;br /&gt;
The examples assume that the PFC scopes &amp;lt;vp&amp;gt;core&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;std&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;stdio&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;list&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;string&amp;lt;/vp&amp;gt; are open.&lt;br /&gt;
&lt;br /&gt;
===== Dummy predicates =====&lt;br /&gt;
&lt;br /&gt;
Anonymous predicates are good for creating dummy predicate values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
ppp( { = true } ),     % do not filter (boolean)&lt;br /&gt;
qqq( { :- succeed } ), % do not filter (determ)&lt;br /&gt;
rrr( { = 17 } ).       % all rows must have height 17&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Adaptation =====&lt;br /&gt;
&lt;br /&gt;
In cases where you need a predicate and have one that is almost suitable, you can make the adaptation using an anonymous predicate.&lt;br /&gt;
&lt;br /&gt;
====== Index adaptation ======&lt;br /&gt;
&lt;br /&gt;
Consider the predicate write3:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    write3 : (function{integer, string} Indexer).&lt;br /&gt;
clauses&lt;br /&gt;
    write3(Indexer) :-&lt;br /&gt;
        foreach I = std::fromTo(0,2) do&lt;br /&gt;
            write(Indexer(I), &amp;quot;\n&amp;quot;)&lt;br /&gt;
        end foreach.&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Indexer implements an &amp;quot;array&amp;quot; of strings; &amp;lt;vp&amp;gt;write3&amp;lt;/vp&amp;gt; will write the three strings found at the indexes &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;2&amp;lt;/vp&amp;gt;. So &amp;lt;vp&amp;gt;write3&amp;lt;/vp&amp;gt; assumes that the &amp;quot;array&amp;quot; index is zero-based.&lt;br /&gt;
&lt;br /&gt;
However, the &amp;quot;array&amp;quot; we have uses a one-based index:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    myArray : (integer N) -&amp;gt; string Value.&lt;br /&gt;
clauses&lt;br /&gt;
    myArray(1) = &amp;quot;First&amp;quot; :- !.&lt;br /&gt;
    myArray(2) = &amp;quot;Second&amp;quot; :- !.&lt;br /&gt;
    myArray(3) = &amp;quot;Third&amp;quot; :- !.&lt;br /&gt;
    myArray(_) = _ :-&lt;br /&gt;
        raiseError().&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Using an anonymous predicate we can easily adapt the one-based array to the zero-based usage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;% myArray is 1-based, write3 requires 0-based&lt;br /&gt;
Arr = { (N) = myArray(N+1) },&lt;br /&gt;
write3(Arr).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So we get the expected output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;First&lt;br /&gt;
Second&lt;br /&gt;
Third&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Parameter adaptation ======&lt;br /&gt;
&lt;br /&gt;
In this code &amp;lt;vp&amp;gt;listChildren&amp;lt;/vp&amp;gt; will call a &amp;lt;vp&amp;gt;ChildWriter&amp;lt;/vp&amp;gt; predicate for each &amp;quot;C is the child of P&amp;quot;-pair:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    listChildren :&lt;br /&gt;
        (predicate{string,string} ChildWriter).&lt;br /&gt;
clauses&lt;br /&gt;
    listChildren(CW) :-&lt;br /&gt;
        CW(&amp;quot;Son1&amp;quot;, &amp;quot;Father&amp;quot;),&lt;br /&gt;
        CW(&amp;quot;Son2&amp;quot;, &amp;quot;Father&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
We will however prefer to list the &amp;quot;P is the parent of C&amp;quot; using the predicate &amp;lt;vp&amp;gt;wParent&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    wParent : (string Parent, string Child).&lt;br /&gt;
clauses&lt;br /&gt;
    wParent(P, C) :-&lt;br /&gt;
        writef(&amp;quot;% is the parent of %\n&amp;quot;, P, C).&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
&amp;lt;vp&amp;gt;wParent&amp;lt;/vp&amp;gt; takes the arguments in the opposite order, but we can easily adapt using an anonymous predicate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;Swap = { (A,B) :- wParent(B,A) },&lt;br /&gt;
listChildren(Swap).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And then the output becomes the expected:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;Father is the parent of Son1&lt;br /&gt;
Father is the parent of Son2&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can also throw away arguments, for example when calling this predicate that only needs a &amp;lt;vp&amp;gt;Child&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    wKnowParent : (string Child).&lt;br /&gt;
clauses&lt;br /&gt;
    wKnowParent(C) :-&lt;br /&gt;
        writef(&amp;quot;We know a parent of %\n&amp;quot;, C).&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
The adaptation looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;Fewer = { (C,P) :- wKnowParent(C) },&lt;br /&gt;
listChildren(Fewer).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output will be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;We know a parent of Son1&lt;br /&gt;
We know a parent of Son2&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can also supply dummy arguments:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;More = { (_,P) :- addChildren(P, 1) },&lt;br /&gt;
listChildren(More).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here &amp;lt;vp&amp;gt;addChildren&amp;lt;/vp&amp;gt; will &amp;quot;add a count of children to P&amp;quot;. Since each invocation corresponds to one child we will call &amp;lt;vp&amp;gt;addChildren&amp;lt;/vp&amp;gt; supplying &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; as a &amp;quot;dummy&amp;quot; argument. The &amp;lt;vp&amp;gt;More&amp;lt;/vp&amp;gt; is thus an adaptor that both throws away an argument and supplies a dummy argument.&lt;br /&gt;
&lt;br /&gt;
===== Filters =====&lt;br /&gt;
&lt;br /&gt;
Assume this predicate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    writeFiltered : &lt;br /&gt;
        (string L, predicate_dt{integer} Filter).&lt;br /&gt;
clauses&lt;br /&gt;
    writeFiltered(Label, Filter) :-&lt;br /&gt;
        List = [1,2,3,4,5,6,7,8,9],&lt;br /&gt;
        FilteredList = filter(List, Filter),&lt;br /&gt;
        writef(&amp;quot;%\t%\n&amp;quot;, Label, FilteredList).&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
&amp;lt;vp&amp;gt;Filter&amp;lt;/vp&amp;gt; is used to filter the list &amp;lt;vp&amp;gt;[1,2,3,4,5,6,7,8,9]&amp;lt;/vp&amp;gt;; the filtered list and the &amp;lt;vp&amp;gt;Label&amp;lt;/vp&amp;gt; are written to the standard output.&lt;br /&gt;
&lt;br /&gt;
First we use the allow-all filter:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;All = { :- succeed },&lt;br /&gt;
writeFiltered(&amp;quot;All&amp;quot;, All).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This filter simply succeeds for any element, so the output is the entire list:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;All     [1,2,3,4,5,6,7,8,9]&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is just as easy to create a filter that fails for all elements and thus allow-none:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;None = { :- fail },&lt;br /&gt;
writeFiltered(&amp;quot;None&amp;quot;, None).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output from this is the empty list:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;None    []&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can also create filters for elements greater than &amp;lt;vp&amp;gt;3&amp;lt;/vp&amp;gt; and elements divisible by &amp;lt;vp&amp;gt;3&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;GreaterThan3 = { (X) :- X &amp;gt; 3 },&lt;br /&gt;
writeFiltered(&amp;quot;&amp;gt; 3&amp;quot;, GreaterThan3),&lt;br /&gt;
Rem3 = { (X) :- 0 = X rem 3 },&lt;br /&gt;
writeFiltered(&amp;quot;Rem3&amp;quot;, Rem3).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output from this is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&amp;gt; 3     [4,5,6,7,8,9]&lt;br /&gt;
Rem3    [3,6,9]&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Sorting =====&lt;br /&gt;
&lt;br /&gt;
The list package has a sort predicate. But sometimes the default order is not what you need. Therefore the list package also has a predicate &amp;lt;vp&amp;gt;sortBy&amp;lt;/vp&amp;gt;, which sorts the elements using a programmer-defined compare operation.&lt;br /&gt;
Let us first consider string sorting, using this predicate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    writeStringsSorted :&lt;br /&gt;
        (string Label, comparator{string} Comp).&lt;br /&gt;
clauses&lt;br /&gt;
    writeStringsSorted(Label, C) :-&lt;br /&gt;
        List = [&amp;quot;John Wayne&amp;quot;, &amp;quot;Uma Thurman&amp;quot;,&lt;br /&gt;
            &amp;quot;Harrison Ford&amp;quot;, &amp;quot;Nicolas Cage&amp;quot;,&lt;br /&gt;
            &amp;quot;Elizabeth Taylor&amp;quot;, &amp;quot;Cary Grant&amp;quot;,&lt;br /&gt;
            &amp;quot;Jerry Lewis&amp;quot;, &amp;quot;Robert De Niro&amp;quot;],&lt;br /&gt;
        Sorted = sortBy(C, List),&lt;br /&gt;
        write(Label, &amp;quot;\n&amp;quot;),&lt;br /&gt;
        foreach S = list::getMember_nd(Sorted) do&lt;br /&gt;
            writef(&amp;quot;    %\n&amp;quot;, S)&lt;br /&gt;
        end foreach.&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
We can call the predicate with the &amp;quot;normal&amp;quot; comparator, and using an anonymous predicate we can easily sort it descending as well:  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;Normal = compare,&lt;br /&gt;
writeStringsSorted(&amp;quot;Normal&amp;quot;, Normal),&lt;br /&gt;
Descending = { (A,B) = compare(B,A) },&lt;br /&gt;
writeStringsSorted(&amp;quot;Descending&amp;quot;, Descending).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;Normal&lt;br /&gt;
    Cary Grant&lt;br /&gt;
    Elizabeth Taylor&lt;br /&gt;
    Harrison Ford&lt;br /&gt;
    Jerry Lewis&lt;br /&gt;
    John Wayne&lt;br /&gt;
    Nicolas Cage&lt;br /&gt;
    Robert De Niro&lt;br /&gt;
    Uma Thurman&lt;br /&gt;
Descending&lt;br /&gt;
    Uma Thurman&lt;br /&gt;
    Robert De Niro&lt;br /&gt;
    Nicolas Cage&lt;br /&gt;
    John Wayne&lt;br /&gt;
    Jerry Lewis&lt;br /&gt;
    Harrison Ford&lt;br /&gt;
    Elizabeth Taylor&lt;br /&gt;
    Cary Grant&amp;lt;/source&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
Let us also sort some more complex elements. Here a person has a first name and a last name, using this domain:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    person = p(string First, string Last).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the demonstration we will use this test predicate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    writePersonsSorted : &lt;br /&gt;
        (string Label, comparator{person} Comparator).&lt;br /&gt;
clauses&lt;br /&gt;
    writePersonsSorted(Label, C) :-&lt;br /&gt;
        List = [p(&amp;quot;John&amp;quot;,&amp;quot;Wayne&amp;quot;),&lt;br /&gt;
            p(&amp;quot;Uma&amp;quot;,&amp;quot;Thurman&amp;quot;),&lt;br /&gt;
            p(&amp;quot;Harrison&amp;quot;,&amp;quot;Ford&amp;quot;),&lt;br /&gt;
            p(&amp;quot;Nicolas&amp;quot;,&amp;quot;Cage&amp;quot;),&lt;br /&gt;
            p(&amp;quot;Elizabeth&amp;quot;,&amp;quot;Taylor&amp;quot;),&lt;br /&gt;
            p(&amp;quot;Cary&amp;quot;,&amp;quot;Grant&amp;quot;),&lt;br /&gt;
            p(&amp;quot;Jerry&amp;quot;,&amp;quot;Lewis&amp;quot;),&lt;br /&gt;
            p(&amp;quot;Robert&amp;quot;,&amp;quot;De Niro&amp;quot;)],&lt;br /&gt;
        Sorted = sortBy(C, List),&lt;br /&gt;
        write(Label, &amp;quot;\n&amp;quot;),&lt;br /&gt;
        foreach p(F,L) = list::getMember_nd(Sorted) do&lt;br /&gt;
            writef(&amp;quot;    % %\n&amp;quot;, F, L)&lt;br /&gt;
        end foreach.&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Again we can sort using the normal and a descending comparator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;Normal = compare,&lt;br /&gt;
writePersonsSorted(&amp;quot;Normal&amp;quot;, Normal),&lt;br /&gt;
Descending = { (A,B) = compare(B,A) },&lt;br /&gt;
writePersonsSorted(&amp;quot;Descending&amp;quot;, Descending).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since the &amp;lt;vp&amp;gt;compare&amp;lt;/vp&amp;gt; predicate uses left-to-right lexicographic order on the &amp;lt;vp&amp;gt;p&amp;lt;/vp&amp;gt;-functor, the result is the same as before:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;Normal&lt;br /&gt;
    Cary Grant&lt;br /&gt;
    Elizabeth Taylor&lt;br /&gt;
    Harrison Ford&lt;br /&gt;
    Jerry Lewis&lt;br /&gt;
    John Wayne&lt;br /&gt;
    Nicolas Cage&lt;br /&gt;
    Robert De Niro&lt;br /&gt;
    Uma Thurman&lt;br /&gt;
Descending&lt;br /&gt;
    Uma Thurman&lt;br /&gt;
    Robert De Niro&lt;br /&gt;
    Nicolas Cage&lt;br /&gt;
    John Wayne&lt;br /&gt;
    Jerry Lewis&lt;br /&gt;
    Harrison Ford&lt;br /&gt;
    Elizabeth Taylor&lt;br /&gt;
    Cary Grant&amp;lt;/source&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
But with the more complex domain we can create a comparator that will sort on last name:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;LN = { (p(_,L1), p(_, L2)) = compare(L1,L2) },&lt;br /&gt;
writePersonsSorted(&amp;quot;LastName&amp;quot;, LN).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is what we expect:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;LastName&lt;br /&gt;
    Nicolas Cage&lt;br /&gt;
    Robert De Niro&lt;br /&gt;
    Harrison Ford&lt;br /&gt;
    Cary Grant&lt;br /&gt;
    Jerry Lewis&lt;br /&gt;
    Elizabeth Taylor&lt;br /&gt;
    Uma Thurman&lt;br /&gt;
    John Wayne&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Capturing context (threads &amp;amp; callbacks) =====&lt;br /&gt;
&lt;br /&gt;
As mentioned a very powerful feature of anonymous predicates is the ability to capture context. The examples in this section show some ways you can use this. &lt;br /&gt;
&lt;br /&gt;
====== Background threads ======&lt;br /&gt;
&lt;br /&gt;
The routine for starting a thread takes a nullary predicate and runs it in the new thread. But you nearly always need to pass some input data to the job in the new thread.&lt;br /&gt;
This is possible in several ways, but the absolutely simplest way is to use anonymous predicates.&lt;br /&gt;
The project &amp;lt;vp&amp;gt;bgDemo&amp;lt;/vp&amp;gt; from the Visual Prolog example collection (that can be installed from the IDE) uses this method.&lt;br /&gt;
The project has a form that can start a background job and display status information from the job in a &amp;lt;vp&amp;gt;jobControl&amp;lt;/vp&amp;gt; that is added to the form.&lt;br /&gt;
A background job is a predicate that will receive a &amp;lt;vp&amp;gt;jobLog&amp;lt;/vp&amp;gt;, which it can use to report status and completion degree:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    job = (jobLog Log).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;vp&amp;gt;jobLog&amp;lt;/vp&amp;gt; looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface jobLog&lt;br /&gt;
&lt;br /&gt;
properties&lt;br /&gt;
    completion : real (i).&lt;br /&gt;
&lt;br /&gt;
properties&lt;br /&gt;
    status : string (i).&lt;br /&gt;
&lt;br /&gt;
end interface jobLog&amp;lt;/vip&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
The job can report completion degree by setting the &amp;lt;vp&amp;gt;completion&amp;lt;/vp&amp;gt; property (range &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt;). Likewise, the &amp;lt;vp&amp;gt;status&amp;lt;/vp&amp;gt; property can be used to reflect the current status of the job.&lt;br /&gt;
&lt;br /&gt;
The status and completion will be shown in the form together with a job name.&lt;br /&gt;
A job is started by calling the form&amp;#039;s &amp;lt;vp&amp;gt;addJob&amp;lt;/vp&amp;gt; predicate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    addJob(JobName, Job) :-&lt;br /&gt;
        JobCtrl = jobControl::new(This),&lt;br /&gt;
        JobCtrl:name := JobName,&lt;br /&gt;
        JobCtrl:show(),&lt;br /&gt;
        assert(jobCtrl_fact(JobCtrl)),&lt;br /&gt;
        arrange(),&lt;br /&gt;
        JobLog = jobLog::new(JobCtrl),&lt;br /&gt;
        Action = { :- Job(JobLog) },&lt;br /&gt;
        _ = thread::start(Action).&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
In this context it is the last three lines that are interesting. &amp;lt;vp&amp;gt;thread::start&amp;lt;/vp&amp;gt; takes a nullary predicate as argument, but a job is a predicate that takes a &amp;lt;vp&amp;gt;jobLog&amp;lt;/vp&amp;gt; as argument. Therefore we create an anonymous predicate &amp;lt;vp&amp;gt;Action&amp;lt;/vp&amp;gt;, which takes no arguments but invokes &amp;lt;vp&amp;gt;Job&amp;lt;/vp&amp;gt; on the &amp;lt;vp&amp;gt;JobLog&amp;lt;/vp&amp;gt;. The anonymous predicate has captured both &amp;lt;vp&amp;gt;Job&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;JobLog&amp;lt;/vp&amp;gt; from the context, and subsequently both these values are transferred to the new thread even though this thread only receives a nullary predicate.&lt;br /&gt;
&lt;br /&gt;
The jobs in the &amp;lt;vp&amp;gt;bgDemo&amp;lt;/vp&amp;gt; project are merely dummy jobs that only manipulate their &amp;lt;vp&amp;gt;jobLog&amp;lt;/vp&amp;gt;. One of them looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    job(Log, From, To) :-&lt;br /&gt;
        Log:status := &amp;quot;Step 1&amp;quot;,&lt;br /&gt;
        foreach N1 = std::fromTo(From, To) do&lt;br /&gt;
            Log:completion :=&lt;br /&gt;
                (N1-From) / (To-From) / 2,&lt;br /&gt;
            programControl::sleep(3)&lt;br /&gt;
        end foreach,&lt;br /&gt;
        Log:status := &amp;quot;Step 2&amp;quot;,&lt;br /&gt;
        foreach N2 = std::fromTo(From, To) do&lt;br /&gt;
            Log:completion :=&lt;br /&gt;
                (N2-From) / (To-From) / 2 + 0.5,&lt;br /&gt;
            programControl::sleep(3)&lt;br /&gt;
        end foreach,&lt;br /&gt;
        Log:status := &amp;quot;finished&amp;quot;.&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
It has two loops which run from &amp;lt;vp&amp;gt;From&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;To&amp;lt;/vp&amp;gt; and calculates the completion and sets it on the &amp;lt;vp&amp;gt;Log&amp;lt;/vp&amp;gt;. It also sets the status text before, between and after the loops.&lt;br /&gt;
&lt;br /&gt;
You may notice that the job does not have the proper job type, because a proper job only has one argument (the &amp;lt;vp&amp;gt;jobLog&amp;lt;/vp&amp;gt;); this job has three arguments.&lt;br /&gt;
Again it is anonymous predicates that help us. The code that adds the jobs to the form looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    onFileNew : window::menuItemListener.&lt;br /&gt;
clauses&lt;br /&gt;
    onFileNew(_Source, _MenuTag) :-&lt;br /&gt;
        JF = jobForm::display(This),&lt;br /&gt;
        Job11 = {(L) :- job1::job(L, 1, 1000)},&lt;br /&gt;
        Job12 = {(L) :- job1::job(L, 200, 600)},&lt;br /&gt;
        Job13 = {(L) :- job1::job(L, 1200, 3000)},&lt;br /&gt;
        Job14 = {(L) :- job1::job(L, 1, 1000)},&lt;br /&gt;
        JF:addJob(&amp;quot;job1.1&amp;quot;, Job11),&lt;br /&gt;
        JF:addJob(&amp;quot;job1.2&amp;quot;, Job12),&lt;br /&gt;
        JF:addJob(&amp;quot;job1.3&amp;quot;, Job13),&lt;br /&gt;
        JF:addJob(&amp;quot;job1.4&amp;quot;, Job14),&lt;br /&gt;
        ...&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
In a more realistic program, it is most likely that &amp;lt;vp&amp;gt;From&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;To&amp;lt;/vp&amp;gt; would not be constants, but rather parameters passed from some outer place. In that case these anonymous predicates would also capture variables from the context.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;jobLog&amp;lt;/vp&amp;gt; in the &amp;lt;vp&amp;gt;bgDemo&amp;lt;/vp&amp;gt; illustrates one more usage of anonymous predicates. The &amp;lt;vp&amp;gt;jobLog&amp;lt;/vp&amp;gt; passes the completion and the status information to a &amp;lt;vp&amp;gt;jobControl&amp;lt;/vp&amp;gt;. The &amp;lt;vp&amp;gt;jobControl&amp;lt;/vp&amp;gt; is a GUI control on the &amp;lt;vp&amp;gt;jobForm&amp;lt;/vp&amp;gt; capable of doing a suitable rendering of the information. This however gives a synchronization problem, because GUI controls are not thread safe and here we want to update some controls from a background thread. This can lead to conflicts, because it is the main thread that draws the controls.&lt;br /&gt;
&lt;br /&gt;
The solution is to transfer the update of the control to the GUI thread. We do this by posting actions to the control.&lt;br /&gt;
The implementation of the status update looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    status(Status) :-&lt;br /&gt;
        Action = { :- jobCtrl:status := Status },&lt;br /&gt;
        jobCtrl:postAction(Action).&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
&amp;lt;vp&amp;gt;Action&amp;lt;/vp&amp;gt; is a nullary predicate that will set the status in the &amp;lt;vp&amp;gt;jobCtrl&amp;lt;/vp&amp;gt;. We post this action to the &amp;lt;vp&amp;gt;jobCtrl&amp;lt;/vp&amp;gt;. When the &amp;lt;vp&amp;gt;jobCtrl&amp;lt;/vp&amp;gt; receives the action it invokes it and is thus updated. This way, the actual update of the control will be performed by the GUI thread.&lt;br /&gt;
This anonymous predicate not only captures the &amp;lt;vp&amp;gt;Status&amp;lt;/vp&amp;gt; variable it also captures the &amp;lt;vp&amp;gt;jobCtrl&amp;lt;/vp&amp;gt; fact.&lt;br /&gt;
&lt;br /&gt;
====== Asynchronous callbacks ======&lt;br /&gt;
&lt;br /&gt;
Assume that we send commands to a remote service. The command execution is asynchronous, so when we execute a command we also give a callback action which will be invoked when the execution of the command is finished. To execute a command we must call this predicate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    executeCommand :&lt;br /&gt;
        (command Cmd, predicate{} OnDone).&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Based on this predicate we want to create a similar predicate that can execute a list of commands. A certain command should be executed when the previous command completes.&lt;br /&gt;
We will also make our list executor asynchronous, so we supply an action that will be invoked when the entire script of commands is finished.&lt;br /&gt;
Our script executor will have the form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    executeScript :&lt;br /&gt;
        (command* Script, predicate{} OnDone).&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
If the script is empty we simply invoke the &amp;lt;vp&amp;gt;OnDone&amp;lt;/vp&amp;gt; action. &lt;br /&gt;
If the script has a command &amp;lt;vp&amp;gt;H&amp;lt;/vp&amp;gt; and a rest script &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt;, we must first execute &amp;lt;vp&amp;gt;H&amp;lt;/vp&amp;gt;, and when it is finished we must execute the rest of the script &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt;. So the &amp;lt;vp&amp;gt;OnDone&amp;lt;/vp&amp;gt; action we supply when executing &amp;lt;vp&amp;gt;H&amp;lt;/vp&amp;gt; must execute &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt;.&lt;br /&gt;
All in all, the implementation can look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    executeScript([], OnDone) :-&lt;br /&gt;
        OnDone().&lt;br /&gt;
    executeScript([H|T], OnDone) :-&lt;br /&gt;
        DoneH = { :- executeScript(T, OnDone) },&lt;br /&gt;
        executeCommand(H, DoneH).&amp;lt;/vip&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
We have used an anonymous predicate to perform the execution of the rest of the script. This anonymous predicate captures &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;OnDone&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{LanguageReferenceSubarticle|Terms/Anonymous Predicates}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains&amp;diff=4996</id>
		<title>Language Reference/Built-in entities/Domains</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains&amp;diff=4996"/>
		<updated>2025-08-21T09:13:05Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: string8 literals&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{|{{prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|[[#any|any]]&lt;br /&gt;
|Universal term type&lt;br /&gt;
|-&lt;br /&gt;
|[[#char|char]]&lt;br /&gt;
|Unicode character (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
|[[#string|string]]&lt;br /&gt;
|UTF-16 zero-terminated string&lt;br /&gt;
|-&lt;br /&gt;
|[[#string8|string8]]&lt;br /&gt;
|Zero-terminated 8-bit string typically in UTF-8 encoding&lt;br /&gt;
|-&lt;br /&gt;
|[[#symbol|symbol]]&lt;br /&gt;
|Interned UTF-16 string (global symbol table)&lt;br /&gt;
|-&lt;br /&gt;
|[[#binary|binary]]&lt;br /&gt;
|Byte sequence (non-scanned)&lt;br /&gt;
|-&lt;br /&gt;
|[[#binaryNonAtomic|binaryNonAtomic]]&lt;br /&gt;
|Byte sequence (GC-scanned; may contain pointers)&lt;br /&gt;
|-&lt;br /&gt;
|[[#integer|integer]]&lt;br /&gt;
|32-bit signed integer&lt;br /&gt;
|-&lt;br /&gt;
|[[#integer64|integer64]]&lt;br /&gt;
|64-bit signed integer&lt;br /&gt;
|-&lt;br /&gt;
|[[#integerNative|integerNative]]&lt;br /&gt;
|Platform-sized signed integer (32/64-bit)&lt;br /&gt;
|-&lt;br /&gt;
|[[#unsigned|unsigned]]&lt;br /&gt;
|32-bit unsigned integer&lt;br /&gt;
|-&lt;br /&gt;
|[[#unsigned64|unsigned64]]&lt;br /&gt;
|64-bit unsigned integer&lt;br /&gt;
|-&lt;br /&gt;
|[[#unsignedNative|unsignedNative]]&lt;br /&gt;
|Platform-sized unsigned integer (32/64-bit)&lt;br /&gt;
|-&lt;br /&gt;
|[[#real|real]]&lt;br /&gt;
|Floating-point number (64-bit)&lt;br /&gt;
|-&lt;br /&gt;
|[[#real32|real32]]&lt;br /&gt;
|Floating-point number (32-bit)&lt;br /&gt;
|-&lt;br /&gt;
|[[#pointer|pointer]]&lt;br /&gt;
|Pointer value&lt;br /&gt;
|-&lt;br /&gt;
|[[#pointerTo|pointerTo]]&lt;br /&gt;
|Pointer to a value of a given type&lt;br /&gt;
|-&lt;br /&gt;
|[[#handle|handle]]&lt;br /&gt;
|Operating system handle (e.g., Windows)&lt;br /&gt;
|-&lt;br /&gt;
|[[#boolean|boolean]]&lt;br /&gt;
|Boolean values&lt;br /&gt;
|-&lt;br /&gt;
|[[#factDB|factDB]]&lt;br /&gt;
|Descriptor of a named internal database&lt;br /&gt;
|-&lt;br /&gt;
|[[#compareResult|compareResult]]&lt;br /&gt;
|Result of a comparison&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== any ====&lt;br /&gt;
&lt;br /&gt;
Universal term type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;any&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Values of this domain can hold any term. Such a value contains a reference to the type library of the term and the term itself.&lt;br /&gt;
&lt;br /&gt;
==== char ====&lt;br /&gt;
&lt;br /&gt;
Unicode character.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;char&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Values of this domain are Unicode characters implemented as two unsigned bytes.&lt;br /&gt;
&lt;br /&gt;
Only assignment and comparison (lexicographical) are defined. The image of a character has the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;Char_image&amp;gt; :&lt;br /&gt;
      &amp;#039; Char_value &amp;#039;&lt;br /&gt;
&amp;lt;Char_value&amp;gt; :&lt;br /&gt;
      &amp;lt;Letter&amp;gt;&lt;br /&gt;
      &amp;lt;Digit&amp;gt;&lt;br /&gt;
      &amp;lt;Graphical_symbol&amp;gt;&lt;br /&gt;
      &amp;lt;Escape_seq&amp;gt;&lt;br /&gt;
&amp;lt;Escape_seq&amp;gt;:&lt;br /&gt;
      \t&lt;br /&gt;
      \n&lt;br /&gt;
      \r&lt;br /&gt;
      \\&lt;br /&gt;
      \&amp;#039;&lt;br /&gt;
      \&amp;quot;&lt;br /&gt;
      \u&amp;lt;HHHH&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the syntax above &amp;lt;vpbnf&amp;gt;&amp;lt;HHHH&amp;gt;&amp;lt;/vpbnf&amp;gt; corresponds to four hexadecimal digits. The backslash and single quote can only be represented by escape sequences.&lt;br /&gt;
&lt;br /&gt;
==== compareResult ====&lt;br /&gt;
&lt;br /&gt;
The result domain for comparisons (e.g., {{lang2|Built-in entities|compare|compare/2-&amp;gt;}}).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
   compareResult = less; equal; greater.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== string ====&lt;br /&gt;
&lt;br /&gt;
UTF-16 strings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;string&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A string is a pointer to a zero-terminated sequence of UTF-16 code units. Elements are 16-bit values; certain characters are encoded using surrogate pairs. Strings are immutable.&lt;br /&gt;
&lt;br /&gt;
In source code a string literal is one or more parts surrounded by double quotes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;StringLiteral&amp;gt;:&lt;br /&gt;
   &amp;lt;StringLiteralPart&amp;gt;-list&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;StringLiteralPart&amp;gt; :&lt;br /&gt;
   @&amp;quot; AnyCharacter-list-opt &amp;quot;&lt;br /&gt;
   &amp;quot; CharacterValue-list-opt &amp;quot;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parts starting with &amp;lt;vp&amp;gt;@&amp;lt;/vp&amp;gt; do not use escape sequences; parts without &amp;lt;vp&amp;gt;@&amp;lt;/vp&amp;gt; use the following escapes:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;\\&amp;lt;/vp&amp;gt; representing &amp;lt;vp&amp;gt;\&amp;lt;/vp&amp;gt;&lt;br /&gt;
* &amp;lt;vp&amp;gt;\t&amp;lt;/vp&amp;gt; representing a tab character&lt;br /&gt;
* &amp;lt;vp&amp;gt;\n&amp;lt;/vp&amp;gt; representing a newline character&lt;br /&gt;
* &amp;lt;vp&amp;gt;\r&amp;lt;/vp&amp;gt; representing a carriage return&lt;br /&gt;
* &amp;lt;vp&amp;gt;\&amp;#039;&amp;lt;/vp&amp;gt; representing a single quote&lt;br /&gt;
* &amp;lt;vp&amp;gt;\&amp;quot;&amp;lt;/vp&amp;gt; representing a double quote&lt;br /&gt;
* &amp;lt;vp&amp;gt;\u&amp;lt;/vp&amp;gt; followed by exactly four &amp;lt;vpbnf&amp;gt;&amp;lt;HexadecimalDigit&amp;gt;&amp;lt;/vpbnf&amp;gt; values representing the Unicode character&lt;br /&gt;
&lt;br /&gt;
Double quotes in strings must be written using the escape sequence (single quotes may be written directly or escaped).&lt;br /&gt;
&lt;br /&gt;
==== string8 ====&lt;br /&gt;
&lt;br /&gt;
A built-in domain whose elements are sequences of one-byte characters (bytes). Implemented as a pointer to a zero-terminated array of bytes.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Literals.&amp;#039;&amp;#039;&amp;#039; The same string literal syntax (`&amp;quot;...&amp;quot;`) can be used both as a &amp;lt;vp&amp;gt;string&amp;lt;/vp&amp;gt; literal and as a &amp;lt;vp&amp;gt;string8&amp;lt;/vp&amp;gt; literal, depending on context:&lt;br /&gt;
* When a &amp;lt;vp&amp;gt;string8&amp;lt;/vp&amp;gt; value is expected, the literal is compiled as UTF-8 bytes with a trailing zero&lt;br /&gt;
* When a &amp;lt;vp&amp;gt;string&amp;lt;/vp&amp;gt; value is expected, the literal is compiled as UTF-16 code units with a trailing zero&lt;br /&gt;
&lt;br /&gt;
If the context is ambiguous, disambiguate by using a typed context (e.g., a predicate parameter of type &amp;lt;vp&amp;gt;string8&amp;lt;/vp&amp;gt;) or by explicit conversion.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
predicates&lt;br /&gt;
    use8  : (string8 S8).&lt;br /&gt;
    use16 : (string  S).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    demo() :-&lt;br /&gt;
        use8(&amp;quot;Hello&amp;quot;),   % literal used as string8 (UTF-8)&lt;br /&gt;
        use16(&amp;quot;Hello&amp;quot;).  % the same literal used as string (UTF-16)&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== symbol ====&lt;br /&gt;
&lt;br /&gt;
UTF-16 strings with the same representation as &amp;lt;vp&amp;gt;string&amp;lt;/vp&amp;gt;, but also stored in a global symbol table.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;symbol&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;vp&amp;gt;symbol&amp;lt;/vp&amp;gt; is interned in a global symbol table; identical symbols share the same pointer value. Symbols are never reclaimed, so they should not be used for large, short-lived text.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;symbol&amp;lt;/vp&amp;gt; is a subtype of &amp;lt;vp&amp;gt;string&amp;lt;/vp&amp;gt;, so a symbol can be used wherever a string is expected. The opposite is not automatic; to obtain a symbol from a string, explicitly &amp;lt;vp&amp;gt;convert&amp;lt;/vp&amp;gt; to the symbol domain (or a subtype).&lt;br /&gt;
&lt;br /&gt;
Equality is efficient for &amp;lt;vp&amp;gt;symbol&amp;lt;/vp&amp;gt; values (pointer equality). Other comparisons behave like the corresponding &amp;lt;vp&amp;gt;string&amp;lt;/vp&amp;gt; operations.&lt;br /&gt;
&lt;br /&gt;
==== binary ====&lt;br /&gt;
&lt;br /&gt;
Sequence of bytes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;binary&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used for holding binary data. A value is a pointer to the byte sequence that represents the contents of the binary term.&lt;br /&gt;
&lt;br /&gt;
The length of a binary term is stored in the four bytes immediately preceding the sequence:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;TotalNumberOfBytesOccupiedByBinary = ByteLen + 4&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;lt;vp&amp;gt;ByteLen&amp;lt;/vp&amp;gt; is the length of the sequence and &amp;lt;vp&amp;gt;4&amp;lt;/vp&amp;gt; is the size field.&lt;br /&gt;
&lt;br /&gt;
Only assignment and comparison are defined.&lt;br /&gt;
&lt;br /&gt;
Two binaries are compared as follows:&lt;br /&gt;
&lt;br /&gt;
* If sizes differ, the larger size is greater&lt;br /&gt;
* Otherwise, compare bytes (as unsigned) until a difference is found; equal if sizes match and all bytes are equal&lt;br /&gt;
&lt;br /&gt;
The text syntax for binary images is determined by &amp;lt;vpbnf&amp;gt;&amp;lt;Binary&amp;gt;&amp;lt;/vpbnf&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;Binary&amp;gt; :&lt;br /&gt;
       $ [ &amp;lt;Byte_value&amp;gt;-comma-sep-list-opt ]&lt;br /&gt;
&amp;lt;Byte_value&amp;gt; :&lt;br /&gt;
      &amp;lt;Expression&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each expression must be computable at compile time and have a value in the range &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt;..&amp;amp;nbsp;&amp;lt;vp&amp;gt;255&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== binaryNonAtomic ====&lt;br /&gt;
&lt;br /&gt;
Sequence of bytes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;binaryNonAtomic&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Same as [[#binary|binary]], but may contain pointers and is scanned by the garbage collector.&lt;br /&gt;
&lt;br /&gt;
==== integer ====&lt;br /&gt;
&lt;br /&gt;
32-bit signed integer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;integer&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Values occupy 4 bytes. Arithmetic (&amp;lt;vp&amp;gt;+&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;-&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;/&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;*&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;^&amp;lt;/vp&amp;gt;), comparison, assignment, {{lang2|Built-in entities|Operators|div/2-&amp;gt;}}, {{lang2|Built-in entities|Operators|mod/2-&amp;gt;}}, {{lang2|Built-in entities|Operators|quot/2-&amp;gt;}}, and {{lang2|Built-in entities|Operators|rem/2-&amp;gt;}} are defined.&lt;br /&gt;
&lt;br /&gt;
Range: &amp;lt;vp&amp;gt;-2147483648&amp;lt;/vp&amp;gt; .. &amp;lt;vp&amp;gt;2147483647&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Literals follow &amp;lt;vpbnf&amp;gt;&amp;lt;Integer&amp;gt;&amp;lt;/vpbnf&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;Integer&amp;gt; :&lt;br /&gt;
      &amp;lt;Add_operation&amp;gt;-opt 0o &amp;lt;Oct_number&amp;gt;&lt;br /&gt;
      &amp;lt;Add_operation&amp;gt;-opt &amp;lt;Dec_number&amp;gt;&lt;br /&gt;
      &amp;lt;Add_operation&amp;gt;-opt 0x &amp;lt;Hex_number&amp;gt;&lt;br /&gt;
&amp;lt;Add_operation&amp;gt; :&lt;br /&gt;
      +&lt;br /&gt;
      -&lt;br /&gt;
&amp;lt;Oct_number&amp;gt; :&lt;br /&gt;
      &amp;lt;Oct_digit&amp;gt;-list&lt;br /&gt;
&amp;lt;Oct_digit&amp;gt; : one of&lt;br /&gt;
      0 1 2 3 4 5 6 7&lt;br /&gt;
&amp;lt;Dec_number&amp;gt; :&lt;br /&gt;
      &amp;lt;Dec_digit&amp;gt;-list&lt;br /&gt;
&amp;lt;Dec_digit&amp;gt; : one of&lt;br /&gt;
      &amp;lt;Oct_digit&amp;gt; 8 9&lt;br /&gt;
&amp;lt;Hex_number&amp;gt; :&lt;br /&gt;
      &amp;lt;Hex_digit&amp;gt;-list&lt;br /&gt;
&amp;lt;Hex_digit&amp;gt; : one of&lt;br /&gt;
      &amp;lt;Dec_digit&amp;gt; a b c d e f A B C D E F&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== integer64 ====&lt;br /&gt;
&lt;br /&gt;
64-bit signed integer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;integer64&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Values occupy 8 bytes.&lt;br /&gt;
&lt;br /&gt;
Range: &amp;lt;vp&amp;gt;-2^63 = -9223372036854775808&amp;lt;/vp&amp;gt; .. &amp;lt;vp&amp;gt;2^63-1 = 9223372036854775807&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Literals use the same syntax as &amp;lt;vpbnf&amp;gt;&amp;lt;Integer&amp;gt;&amp;lt;/vpbnf&amp;gt;. The available operations mirror those for &amp;lt;vpbnf&amp;gt;&amp;lt;Integer&amp;gt;&amp;lt;/vpbnf&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== integerNative ====&lt;br /&gt;
&lt;br /&gt;
Platform-sized signed integer (32-bit in 32-bit programs; 64-bit in 64-bit programs).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;integerNative&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== unsigned ====&lt;br /&gt;
&lt;br /&gt;
32-bit unsigned integer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;unsigned&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Values occupy 4 bytes. Arithmetic (&amp;lt;vp&amp;gt;+&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;-&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;/&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;*&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;^&amp;lt;/vp&amp;gt;), comparison, assignment, {{lang2|Built-in entities|Operators|div/2-&amp;gt;}}, {{lang2|Built-in entities|Operators|mod/2-&amp;gt;}}, {{lang2|Built-in entities|Operators|rem/2-&amp;gt;}}, and {{lang2|Built-in entities|Operators|quot/2-&amp;gt;}} are defined.&lt;br /&gt;
&lt;br /&gt;
Range: &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt; .. &amp;lt;vp&amp;gt;4294967295&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Literals use the same syntax as &amp;lt;vp&amp;gt;integer&amp;lt;/vp&amp;gt; numbers. A leading minus (&amp;lt;vpbnf&amp;gt;&amp;lt;UnaryMinus&amp;gt;&amp;lt;/vpbnf&amp;gt;) is not allowed for an &amp;lt;vp&amp;gt;unsigned&amp;lt;/vp&amp;gt; literal.&lt;br /&gt;
&lt;br /&gt;
==== unsigned64 ====&lt;br /&gt;
&lt;br /&gt;
64-bit unsigned integer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;unsigned64&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Values occupy 8 bytes.&lt;br /&gt;
&lt;br /&gt;
Range: &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt; .. &amp;lt;vp&amp;gt;2^64-1 = 18,446,744,073,709,551,615&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Literals use the same syntax as &amp;lt;vp&amp;gt;integer64&amp;lt;/vp&amp;gt; numbers. A leading minus (&amp;lt;vpbnf&amp;gt;&amp;lt;UnaryMinus&amp;gt;&amp;lt;/vpbnf&amp;gt;) is not allowed for an &amp;lt;vp&amp;gt;unsigned64&amp;lt;/vp&amp;gt; literal.&lt;br /&gt;
&lt;br /&gt;
Operations mirror those for &amp;lt;vpbnf&amp;gt;&amp;lt;Unsigned&amp;gt;&amp;lt;/vpbnf&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== unsignedNative ====&lt;br /&gt;
&lt;br /&gt;
Platform-sized unsigned integer (32-bit in 32-bit programs; 64-bit in 64-bit programs).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;unsignedNative&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== real ====&lt;br /&gt;
&lt;br /&gt;
Floating-point number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;real&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Values occupy 8 bytes. All arithmetic, comparison, and assignment operations are defined.&lt;br /&gt;
&lt;br /&gt;
Range: approximately &amp;lt;vp&amp;gt;-1.7e+308&amp;lt;/vp&amp;gt; .. &amp;lt;vp&amp;gt;1.7e+308&amp;lt;/vp&amp;gt;. Integral values are implicitly converted to &amp;lt;vp&amp;gt;real&amp;lt;/vp&amp;gt; when needed.&lt;br /&gt;
&lt;br /&gt;
Floating-point literals follow &amp;lt;vpbnf&amp;gt;&amp;lt;Real&amp;gt;&amp;lt;/vpbnf&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;Real&amp;gt; :&lt;br /&gt;
      &amp;lt;Add_operation&amp;gt;-opt &amp;lt;Fraction&amp;gt; &amp;lt;Exponent&amp;gt;-opt&lt;br /&gt;
&amp;lt;Fraction&amp;gt; :&lt;br /&gt;
      &amp;lt;Dec_number&amp;gt; &amp;lt;Fractional_part&amp;gt;-opt&lt;br /&gt;
&amp;lt;Fractional_part&amp;gt; :&lt;br /&gt;
      . &amp;lt;Dec_number&amp;gt;&lt;br /&gt;
&amp;lt;Exponent&amp;gt; :&lt;br /&gt;
      &amp;lt;Exp&amp;gt; &amp;lt;Add_operation&amp;gt;-opt &amp;lt;Dec_number&amp;gt;&lt;br /&gt;
&amp;lt;Exp&amp;gt; :&lt;br /&gt;
      e&lt;br /&gt;
      E&lt;br /&gt;
&amp;lt;Add_operation&amp;gt; :&lt;br /&gt;
      +&lt;br /&gt;
      -&lt;br /&gt;
&amp;lt;Dec_number&amp;gt; :&lt;br /&gt;
      &amp;lt;Dec_digit&amp;gt;-list&lt;br /&gt;
&amp;lt;Dec_digit&amp;gt; : one of&lt;br /&gt;
      0 1 2 3 4 5 6 7 8 9&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== real32 ====&lt;br /&gt;
&lt;br /&gt;
Floating-point number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;real32&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Values occupy 4 bytes. All arithmetic, comparison, and assignment operations are defined.&lt;br /&gt;
&lt;br /&gt;
Range: approximately &amp;lt;vp&amp;gt;-3.4e+38&amp;lt;/vp&amp;gt; .. &amp;lt;vp&amp;gt;3.4e+38&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The syntax of &amp;lt;vp&amp;gt;real32&amp;lt;/vp&amp;gt; literals is the same as for &amp;lt;vp&amp;gt;real&amp;lt;/vp&amp;gt; literals.&lt;br /&gt;
&lt;br /&gt;
==== pointer ====&lt;br /&gt;
&lt;br /&gt;
A pointer to a memory address.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;pointer&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Corresponds directly to memory addresses. Only equality comparison is defined. There is a built-in &amp;#039;&amp;#039;&amp;#039;null&amp;#039;&amp;#039;&amp;#039; constant for this type.&lt;br /&gt;
&lt;br /&gt;
==== pointerTo ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;pointerTo{Type}&amp;lt;/vp&amp;gt; represents a pointer to a value of type &amp;lt;vp&amp;gt;Type&amp;lt;/vp&amp;gt;. Conceptually (it is built-in), it can be viewed as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    pointerTo{Type} = pointerTo(Type Value).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== handle ====&lt;br /&gt;
&lt;br /&gt;
Used for Windows API calls. Values have the same size as a pointer (4 bytes on 32-bit, 8 bytes on 64-bit platforms).&lt;br /&gt;
&lt;br /&gt;
No operations are defined for this domain, and values cannot be converted to/from other domains (except via &amp;lt;vp&amp;gt;uncheckedConvert&amp;lt;/vp&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
There are built-in constants: [[#nullHandle|nullHandle]] and [[#invalidHandle|invalidHandle]].&lt;br /&gt;
&lt;br /&gt;
==== boolean ====&lt;br /&gt;
&lt;br /&gt;
Boolean values.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;boolean&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This domain is provided for convenience and is treated as a normal compound domain:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
   boolean = false; true.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== factDB ====&lt;br /&gt;
&lt;br /&gt;
Descriptors of named internal databases.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;factDB&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This domain has the following hidden meta-declaration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
   factDB = struct @factdb( named_internal_database_domain, object ).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All user-defined names of facts sections are constants of this domain. The compiler automatically builds the corresponding compound terms when needed. At runtime, the first field holds the address of the corresponding domain descriptor, and the second holds either zero (for class facts sections) or a pointer to an object (e.g., &amp;lt;vp&amp;gt;This&amp;lt;/vp&amp;gt; for object facts sections).&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{LanguageReferenceSubarticle|Built-in entities/Domains}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Constants&amp;diff=4995</id>
		<title>Language Reference/Built-in entities/Constants</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Constants&amp;diff=4995"/>
		<updated>2025-08-20T13:34:27Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Review&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{|{{prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|[[#compilation_date|compilation_date]]&lt;br /&gt;
|Compilation date&lt;br /&gt;
|-&lt;br /&gt;
|[[#compilation_time|compilation_time]]&lt;br /&gt;
|Compilation time&lt;br /&gt;
|-&lt;br /&gt;
|[[#compiler_buildDate|compiler_buildDate]]&lt;br /&gt;
|Build date of the compiler&lt;br /&gt;
|-&lt;br /&gt;
|[[#compiler_version|compiler_version]]&lt;br /&gt;
|Compiler version number&lt;br /&gt;
|-&lt;br /&gt;
|[[#maxFloatDigits|maxFloatDigits]]&lt;br /&gt;
|Maximum supported &amp;lt;vp&amp;gt;digits&amp;lt;/vp&amp;gt; for &amp;lt;vp&amp;gt;real&amp;lt;/vp&amp;gt; domains&lt;br /&gt;
|-&lt;br /&gt;
|[[#null|null]]&lt;br /&gt;
|The default NULL pointer&lt;br /&gt;
|-&lt;br /&gt;
|[[#nullHandle|nullHandle]]&lt;br /&gt;
|A constant of type handle with value 0&lt;br /&gt;
|-&lt;br /&gt;
|[[#invalidHandle|invalidHandle]]&lt;br /&gt;
|A constant of type handle with value −1 (invalid)&lt;br /&gt;
|-&lt;br /&gt;
|[[#platform_bits|platform_bits]]&lt;br /&gt;
|Bitness of the compilation platform (32 or 64)&lt;br /&gt;
|-&lt;br /&gt;
|[[#platform_name|platform_name]]&lt;br /&gt;
|Target platform name&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== compilation_date ====&lt;br /&gt;
&lt;br /&gt;
Compilation date in the format &amp;#039;&amp;#039;YYYY-MM-DD&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;compilation_date : string = &amp;quot;YYYY-MM-DD&amp;quot;.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== compilation_time ====&lt;br /&gt;
&lt;br /&gt;
Compilation time in the format &amp;#039;&amp;#039;HH:MM:SS&amp;#039;&amp;#039; (24-hour clock).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;compilation_time : string = &amp;quot;HH:MM:SS&amp;quot;.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== compiler_buildDate ====&lt;br /&gt;
&lt;br /&gt;
Build date of the compiler in the format &amp;#039;&amp;#039;YYYY-MM-DD HH:MM&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;compiler_buildDate : string = &amp;quot;YYYY-MM-DD HH:MM&amp;quot;.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== compiler_version ====&lt;br /&gt;
&lt;br /&gt;
Compiler version number (value depends on the compiler).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;compiler_version = 1100.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== maxFloatDigits ====&lt;br /&gt;
&lt;br /&gt;
Maximum supported value of &amp;lt;vp&amp;gt;digits&amp;lt;/vp&amp;gt; for &amp;lt;vp&amp;gt;real&amp;lt;/vp&amp;gt; domains.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;maxFloatDigits = 16.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== null ====&lt;br /&gt;
&lt;br /&gt;
A constant of type &amp;lt;vp&amp;gt;pointer&amp;lt;/vp&amp;gt; with the value &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;null : pointer = uncheckedConvert(pointer, 0).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;null&amp;lt;/vp&amp;gt; is also implicitly defined on all interfaces as a null pointer of the interface type. If it were defined &amp;#039;&amp;#039;&amp;#039;explicitly&amp;#039;&amp;#039;&amp;#039;, it would look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface xxx&lt;br /&gt;
...&lt;br /&gt;
constants&lt;br /&gt;
    null : xxx = uncheckedConvert(xxx, null).  % already implicitly defined&lt;br /&gt;
...&lt;br /&gt;
end interface xxx&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Example|This example shows how the constant can be used in a clause.&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface xxx&lt;br /&gt;
end interface xxx&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
clauses&lt;br /&gt;
    isNullXxx(X) :-&lt;br /&gt;
        xxx::null = X.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== nullHandle ====&lt;br /&gt;
&lt;br /&gt;
A constant of type &amp;lt;vp&amp;gt;handle&amp;lt;/vp&amp;gt; with the value &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;nullHandle : handle = uncheckedConvert(handle, 0).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== invalidHandle ====&lt;br /&gt;
&lt;br /&gt;
A constant of type &amp;lt;vp&amp;gt;handle&amp;lt;/vp&amp;gt; with the value &amp;lt;vp&amp;gt;-1&amp;lt;/vp&amp;gt; (invalid for a handle).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;invalidHandle : handle = uncheckedConvert(handle, -1).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== platform_bits ====&lt;br /&gt;
&lt;br /&gt;
Bitness of the compilation platform.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;platform_bits = 32.&lt;br /&gt;
or&lt;br /&gt;
platform_bits = 64.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== platform_name ====&lt;br /&gt;
&lt;br /&gt;
Target platform name.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;platform_name : string = &amp;quot;Windows 32bits&amp;quot;.&lt;br /&gt;
or&lt;br /&gt;
platform_name : string = &amp;quot;Windows 64bits&amp;quot;.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{LanguageReferenceSubarticle|Built-in entities/Constants}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Language_Reference/Basic_Concepts/Scoping_and_Visibility&amp;diff=4994</id>
		<title>Language Reference/Basic Concepts/Scoping and Visibility</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Language_Reference/Basic_Concepts/Scoping_and_Visibility&amp;diff=4994"/>
		<updated>2025-08-20T13:19:16Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: review&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==== Name Categories ====&lt;br /&gt;
&lt;br /&gt;
All names (identifiers) in Visual Prolog are syntactically divided into two major groups:&lt;br /&gt;
&lt;br /&gt;
* Constant names (starting with a lowercase letter)&lt;br /&gt;
* Variable names (starting with an uppercase letter or an underscore)&lt;br /&gt;
&lt;br /&gt;
Constant names (identifiers) are divided into the following categories:&lt;br /&gt;
&lt;br /&gt;
* Type names (i.e., domains and interfaces)&lt;br /&gt;
* Domain carriers (i.e., classes and interfaces)&lt;br /&gt;
* Names without parentheses (i.e., constants, fact variables of non-function type, and nullary-functors)&lt;br /&gt;
* Value-returning names of arity N (i.e., functions, functors, and fact variables of function type)&lt;br /&gt;
* Non-value-returning names of arity N (i.e., predicates, facts, and fact variables of predicate type)&lt;br /&gt;
&lt;br /&gt;
Visual Prolog requires that names do not conflict at the point of declaration; otherwise, conflicts cannot be resolved at the point of use. Declarations can only conflict if they are in the same scope, because scope qualification can resolve conflicts. A name in one category can never conflict with a name in another category, but a single declaration can place a name in several categories.&lt;br /&gt;
&lt;br /&gt;
==== Packages ====&lt;br /&gt;
&lt;br /&gt;
Packages are the basic units of code organization in Visual Prolog. They group related interfaces and classes.&lt;br /&gt;
&lt;br /&gt;
Each declaration or implementation of an interface or class in a package is placed in a separate file. Each filename matches the interface or class that it declares or implements. All package files are stored in the package directory; subpackages are stored in subdirectories of that directory.&lt;br /&gt;
&lt;br /&gt;
Packages can act as class libraries. You can include packages in your program instead of placing all used interfaces and classes directly in the program.&lt;br /&gt;
&lt;br /&gt;
How packages are structured and included in projects is described in the IDE documentation (see &amp;#039;&amp;#039;&amp;#039;Creating a Package&amp;#039;&amp;#039;&amp;#039; in &amp;#039;&amp;#039;&amp;#039;Creating New Project Items&amp;#039;&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
==== Visibility, Shadowing, and Qualification ====&lt;br /&gt;
&lt;br /&gt;
Most scoping rules were introduced above; this section completes the picture.&lt;br /&gt;
&lt;br /&gt;
An interface definition, a class declaration, and a class implementation are scopes (scopes cannot be nested). An implementation (privately) extends the scope of the corresponding class declaration. Visibility is the same &amp;#039;&amp;#039;&amp;#039;everywhere&amp;#039;&amp;#039;&amp;#039; in a scope; i.e., &amp;#039;&amp;#039;&amp;#039;no matter where&amp;#039;&amp;#039;&amp;#039; something is declared in the scope, it is visible in the &amp;#039;&amp;#039;&amp;#039;whole&amp;#039;&amp;#039;&amp;#039; scope.&lt;br /&gt;
&lt;br /&gt;
Public names from supported interfaces and super-classes are directly (i.e., without qualification) available inside a scope when their origin is unambiguous. It is illegal to use a name whose origin is ambiguous. Ambiguities in predicate calls can be removed by qualifying the predicate name with the class name (e.g., &amp;lt;vp&amp;gt;cc::p&amp;lt;/vp&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
This qualification is also used to qualify calls to object member predicates of super-classes on the &amp;#039;&amp;#039;current&amp;#039;&amp;#039; object.&lt;br /&gt;
&lt;br /&gt;
Visual Prolog has the following shadowing hierarchy:&lt;br /&gt;
&lt;br /&gt;
* Local&lt;br /&gt;
* Opened scopes and super-classes&lt;br /&gt;
&lt;br /&gt;
Opened scopes have the same status as super-classes. Local declarations shadow declarations in opened scopes. If two or more opened scopes contain conflicting declarations, you can only access them by using qualification.&lt;br /&gt;
&lt;br /&gt;
{{Example|Assume the interface &amp;lt;vp&amp;gt;ixx&amp;lt;/vp&amp;gt; and the classes &amp;lt;vp&amp;gt;aa&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;bb&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface ixx&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    p1 : ().&lt;br /&gt;
    p2 : ().&lt;br /&gt;
    p3 : ().&lt;br /&gt;
&lt;br /&gt;
end interface ixx&lt;br /&gt;
&lt;br /&gt;
%========================&lt;br /&gt;
&lt;br /&gt;
class aa : ixx&lt;br /&gt;
end class aa&lt;br /&gt;
&lt;br /&gt;
%========================&lt;br /&gt;
&lt;br /&gt;
class bb&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    p3 : ().&lt;br /&gt;
    p4 : ().&lt;br /&gt;
    p5 : ().&lt;br /&gt;
&lt;br /&gt;
end class bb&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The class &amp;lt;vp&amp;gt;aa&amp;lt;/vp&amp;gt; creates objects of type &amp;lt;vp&amp;gt;ixx&amp;lt;/vp&amp;gt;, whereas the class &amp;lt;vp&amp;gt;bb&amp;lt;/vp&amp;gt; does not create objects at all.&lt;br /&gt;
&lt;br /&gt;
In this context consider the implementation of a class &amp;lt;vp&amp;gt;cc&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement cc inherits aa&lt;br /&gt;
    open bb&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    p2(). % reimplementation of ixx::p2&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    p5 : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p5().&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    new() :-&lt;br /&gt;
        p1(), % aa::p1&lt;br /&gt;
        p2(), % cc::p2 (shadows aa::p2)&lt;br /&gt;
        aa::p2(), % aa::p2&lt;br /&gt;
        p3(), % Illegal ambiguous call: aa::p3 or bb::p3&lt;br /&gt;
        aa::p3(), % aa::p3&lt;br /&gt;
        bb::p3(), % bb::p3&lt;br /&gt;
        p4(), % bb::p4&lt;br /&gt;
        p5(). % cc::p5 (shadows bb::p5)&lt;br /&gt;
&lt;br /&gt;
end implement cc&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
Since &amp;lt;vp&amp;gt;cc&amp;lt;/vp&amp;gt; inherits &amp;lt;vp&amp;gt;aa&amp;lt;/vp&amp;gt;, all predicates in the interface &amp;lt;vp&amp;gt;ixx&amp;lt;/vp&amp;gt; are visible in &amp;lt;vp&amp;gt;cc&amp;lt;/vp&amp;gt;. Likewise, the &amp;lt;vp&amp;gt;open bb&amp;lt;/vp&amp;gt; directive makes all predicates in &amp;lt;vp&amp;gt;bb&amp;lt;/vp&amp;gt; visible in &amp;lt;vp&amp;gt;cc&amp;lt;/vp&amp;gt;.}}&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{LanguageReferenceSubarticle|Basic Concepts/Scoping &amp;amp; Visibility}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Language_Reference/Basic_Concepts/Object_System&amp;diff=4993</id>
		<title>Language Reference/Basic Concepts/Object System</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Language_Reference/Basic_Concepts/Object_System&amp;diff=4993"/>
		<updated>2025-08-20T12:26:53Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: review&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==== External View ====&lt;br /&gt;
&lt;br /&gt;
This section clarifies the class-related notions in Visual Prolog at a conceptual level. It does not discuss syntax or implementation details.&lt;br /&gt;
&lt;br /&gt;
The class concept in Visual Prolog is based on three semantic entities:&lt;br /&gt;
* objects&lt;br /&gt;
* interfaces&lt;br /&gt;
* classes&lt;br /&gt;
&lt;br /&gt;
===== Object =====&lt;br /&gt;
&lt;br /&gt;
An &amp;#039;&amp;#039;object&amp;#039;&amp;#039; is a set of named &amp;#039;&amp;#039;object member predicates&amp;#039;&amp;#039; together with a set of &amp;#039;&amp;#039;supported&amp;#039;&amp;#039; interfaces. Objects also have state, but this state can only be observed and changed through member predicates; the state is therefore &amp;#039;&amp;#039;encapsulated&amp;#039;&amp;#039; in the object.&lt;br /&gt;
&lt;br /&gt;
===== Interface =====&lt;br /&gt;
&lt;br /&gt;
An &amp;#039;&amp;#039;interface&amp;#039;&amp;#039; is an object type. It has a name and defines a set of named object predicates.&lt;br /&gt;
&lt;br /&gt;
Interfaces form a &amp;#039;&amp;#039;supports&amp;#039;&amp;#039; hierarchy (a [[wikipedia:semilattice|semi-lattice]]) rooted at the &amp;lt;vp&amp;gt;object&amp;lt;/vp&amp;gt; interface. If an object has a type denoted by some interface, it also has the types of all supported interfaces. Thus the supports hierarchy is a type hierarchy: an interface is a subtype of each interface it supports.&lt;br /&gt;
&lt;br /&gt;
===== Class =====&lt;br /&gt;
&lt;br /&gt;
A &amp;#039;&amp;#039;class&amp;#039;&amp;#039; is a named object factory; it constructs objects that correspond to a given interface. If a class constructs objects of interface &amp;lt;vp&amp;gt;iii&amp;lt;/vp&amp;gt;, then its objects are &amp;quot;&amp;lt;vp&amp;gt;iii&amp;lt;/vp&amp;gt; objects&amp;quot;. All objects constructed by the same class share the same definitions of the object member predicates, but each object has its own state; the predicate definitions belong to the class, while the state belongs to each object.&lt;br /&gt;
&lt;br /&gt;
The set of object member predicates a class &amp;#039;&amp;#039;defines&amp;#039;&amp;#039; is the &amp;#039;&amp;#039;&amp;#039;union&amp;#039;&amp;#039;&amp;#039; of the predicates &amp;#039;&amp;#039;declared&amp;#039;&amp;#039; (transitively) in its interfaces. If the same predicate is declared in multiple interfaces, the class provides &amp;#039;&amp;#039;&amp;#039;one&amp;#039;&amp;#039;&amp;#039; common definition; this is only valid if the intended semantics coincide. Interface support must be specified explicitly.&lt;br /&gt;
&lt;br /&gt;
===== Module =====&lt;br /&gt;
&lt;br /&gt;
A class need not construct objects. A class without a construction type acts as a module: it may have only class members and class state.&lt;br /&gt;
&lt;br /&gt;
===== Identity =====&lt;br /&gt;
&lt;br /&gt;
Every object is unique. Even if two objects currently have identical state, they are not identical: one can be changed without affecting the other. We never access object state directly; we access it through references, and many references may denote the same object. Classes and interfaces are also unique and identified by name (with namespace); duplicate names are not allowed within a program. Structural equality does &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; imply identity for objects, classes, or interfaces.&lt;br /&gt;
&lt;br /&gt;
==== Internal View ====&lt;br /&gt;
&lt;br /&gt;
This section complements the external view with internal aspects: how declarations and implementations are organized. From a programmatic point of view, classes are central (they contain the code). Interfaces have mainly static importance and have no direct runtime representation; objects are dynamic and exist only when the program runs.&lt;br /&gt;
&lt;br /&gt;
A class has a declaration and an implementation. The declaration states the &amp;#039;&amp;#039;public&amp;#039;&amp;#039; accessible parts of the class and of the objects it constructs; the implementation &amp;#039;&amp;#039;defines&amp;#039;&amp;#039; what the declaration introduces (predicates are implemented by clauses, by inheritance, or resolved to external libraries). A class declaration is purely declarative.&lt;br /&gt;
&lt;br /&gt;
An implementation can declare additional private entities (domains, predicates, etc.). Object state is stored as facts in the implementation; such facts are per-object, while &amp;#039;&amp;#039;class&amp;#039;&amp;#039; facts are shared across all objects of the class. Facts are declared only in implementations and are not directly accessible from outside. Implementations may also (privately) support more interfaces than stated in the declaration.&lt;br /&gt;
&lt;br /&gt;
===== Code Inheritance =====&lt;br /&gt;
&lt;br /&gt;
Code inheritance occurs only in class implementations. Visual Prolog supports multiple inheritance via an &amp;#039;&amp;#039;inherits&amp;#039;&amp;#039; section in the implementation. The classes you inherit from are &amp;#039;&amp;#039;parent&amp;#039;&amp;#039; (&amp;#039;&amp;#039;super&amp;#039;&amp;#039;) classes; the inheriting class is the &amp;#039;&amp;#039;child&amp;#039;&amp;#039; (&amp;#039;&amp;#039;sub&amp;#039;&amp;#039;) class. A child class can only access its parent classes through their public interfaces; it receives no special privileges.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{LanguageReferenceSubarticle|Basic Concepts/Object System}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Language_Reference/Basic_Concepts/Types_and_Subtypes&amp;diff=4992</id>
		<title>Language Reference/Basic Concepts/Types and Subtypes</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Language_Reference/Basic_Concepts/Types_and_Subtypes&amp;diff=4992"/>
		<updated>2025-08-20T08:47:13Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Review&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==== Types ====&lt;br /&gt;
&lt;br /&gt;
Visual Prolog types are divided into object types and value types. Objects&lt;br /&gt;
have mutable state, whereas values are immutable.&lt;br /&gt;
&lt;br /&gt;
Object types are defined by interface definitions.&lt;br /&gt;
&lt;br /&gt;
The value types include {{lang2|Domains|Integral_Domains|numerical types}}, {{lang2|Built-in_entities|string|strings}}, {{lang2|Built-in_entities|char|character types}}, and {{lang2|Domains|Compound_Domains|compound domains}} (also known as algebraic data types). Simpler forms&lt;br /&gt;
of compound domains are structure and enumeration types, whereas more&lt;br /&gt;
complex forms represent tree structures.&lt;br /&gt;
&lt;br /&gt;
==== Subtypes ====&lt;br /&gt;
&lt;br /&gt;
Types are organized in a subtype hierarchy. Subtypes provide subsumption polymorphism: any context that expects a value of some type will also accept a value of any subtype. Equivalently, values of a given type are implicitly converted to any super-type where needed; no explicit cast is required.&lt;br /&gt;
&lt;br /&gt;
Subtypes can be derived from any value type, except from algebraic data types. Types derived from algebraic data types are synonym types rather than subtypes (i.e., they denote the same type).&lt;br /&gt;
&lt;br /&gt;
The notion of subtypes relates to the notion of subsets. However, even if a type is &amp;quot;mathematically&amp;quot; a subset of another type, it is not a subtype unless declared as such.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    t1 = [1..17].&lt;br /&gt;
    t2 = [5..13].&lt;br /&gt;
    t3 = t1 [5..13].&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;t1&amp;lt;/vp&amp;gt; is an integral type whose values are the integers from &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;17&amp;lt;/vp&amp;gt; (inclusive). Likewise, &amp;lt;vp&amp;gt;t2&amp;lt;/vp&amp;gt; contains the values from &amp;lt;vp&amp;gt;5&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;13&amp;lt;/vp&amp;gt;. So &amp;lt;vp&amp;gt;t2&amp;lt;/vp&amp;gt; is a subset of &amp;lt;vp&amp;gt;t1&amp;lt;/vp&amp;gt;, but &amp;lt;vp&amp;gt;t2&amp;lt;/vp&amp;gt; is &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; a subtype of &amp;lt;vp&amp;gt;t1&amp;lt;/vp&amp;gt;. By contrast, &amp;lt;vp&amp;gt;t3&amp;lt;/vp&amp;gt; (which contains the same values as &amp;lt;vp&amp;gt;t2&amp;lt;/vp&amp;gt;) is a subtype of &amp;lt;vp&amp;gt;t1&amp;lt;/vp&amp;gt;, because it is declared to be so.&lt;br /&gt;
&lt;br /&gt;
The language contains a few implicit subtype relations; otherwise, subtype relations are stated explicitly in type definitions.&lt;br /&gt;
&lt;br /&gt;
Object types are organized in a subtype hierarchy rooted in the predefined object type &amp;lt;vp&amp;gt;object&amp;lt;/vp&amp;gt;, i.e., any object type is a subtype of &amp;lt;vp&amp;gt;object&amp;lt;/vp&amp;gt;. Object subtypes are formed by stating that one interface &amp;lt;vp&amp;gt;supports&amp;lt;/vp&amp;gt; another. If an object has an interface/object type that &amp;lt;vp&amp;gt;supports&amp;lt;/vp&amp;gt; another interface, the object also has that type and can be used as such without further changes.&lt;br /&gt;
&lt;br /&gt;
See also: {{lang2|Domains|Universal_and_Root_Types|Universal and Root Types}}&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{LanguageReferenceSubarticle|Basic Concepts/Types and Subtypes}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Language_Reference/Basic_Concepts/Scoping_and_Visibility&amp;diff=4991</id>
		<title>Language Reference/Basic Concepts/Scoping and Visibility</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Language_Reference/Basic_Concepts/Scoping_and_Visibility&amp;diff=4991"/>
		<updated>2025-08-19T15:10:15Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Header level&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==== Name Categories ====&lt;br /&gt;
&lt;br /&gt;
All names (identifiers) in Visual Prolog are syntactically divided into two major groups:&lt;br /&gt;
&lt;br /&gt;
*Constant names (starting with a lowercase letter)&lt;br /&gt;
*Variable names (starting with an uppercase letter or an underscore)&lt;br /&gt;
&lt;br /&gt;
Constant names (identifiers) are divided into the following categories:&lt;br /&gt;
&lt;br /&gt;
* Type names (i.e. domains and interfaces).&lt;br /&gt;
* Domain carriers (i.e. classes and interfaces).&lt;br /&gt;
* Names without parentheses (i.e. constants, fact variables of non-function type and nullary-functors).&lt;br /&gt;
* Value returning names of arity N (i.e. functions, functors and fact-variables of function type).&lt;br /&gt;
* Non-value-returning names of arity N (i.e. predicates, facts and fact variables of predicate type).&lt;br /&gt;
&lt;br /&gt;
Visual Prolog demands that names do not conflict at the point of declaration, because then it would be impossible to solve the conflict at point of usage. Declarations can only conflict if they are in the same scope, because qualification with scope can be used to solve the conflict. A name in one category can never be in conflict with a name in another category, but as we shall see a single declaration might place a name in several categories.&lt;br /&gt;
&lt;br /&gt;
==== Packages ====&lt;br /&gt;
&lt;br /&gt;
The basic units of code organization accepted in Visual Prolog are packages. We use packages in Visual Prolog to organize and structuring things. The use of packages ensures homogeneity in structuring principles among different projects. Packages define the standard for tool structuring and ease sharing source code among projects. &lt;br /&gt;
&lt;br /&gt;
The package is a collection of several grouped together interfaces and classes. The package provides some common name to all these interfaces and classes. Each declaration or implementation of each interface or class from a package is placed in a separate file. Each filename (of these files) coincides with the name of a class or an interface that is declared or implemented in this file. All package files are stored in the same separate package directory. (If a package contains sub-packages, then they are placed in subdirectories of the package directory.) &lt;br /&gt;
&lt;br /&gt;
The concept of packages is used for grouping together several linked interfaces and classes. Packages can play a role of some class library. Packages can be used in your program instead of direct placing all used interfaces and classes into your program.&lt;br /&gt;
&lt;br /&gt;
The accepted in Visual Prolog structure of packages and how packages should be included into projects are described in the VDE part of this help. (See &amp;#039;&amp;#039;&amp;#039;Creating a Package&amp;#039;&amp;#039;&amp;#039; in &amp;#039;&amp;#039;&amp;#039;Creating New Project Items&amp;#039;&amp;#039;&amp;#039;.)&lt;br /&gt;
&lt;br /&gt;
==== Visibility, Shadowing, and Qualification ====&lt;br /&gt;
&lt;br /&gt;
Most of the scoping rules are already mentioned above. This section will complete the picture.&lt;br /&gt;
&lt;br /&gt;
An interface definition, a class declaration and a class implementation are scopes (scopes cannot be nested). An implementation (privately) extends the scope of the corresponding class declaration. The visibility is the same &amp;#039;&amp;#039;&amp;#039;everywhere&amp;#039;&amp;#039;&amp;#039; in a scope. This does especially mean that &amp;#039;&amp;#039;&amp;#039;no matter where&amp;#039;&amp;#039;&amp;#039; in a scope something is declared, it is visible in the &amp;#039;&amp;#039;&amp;#039;whole&amp;#039;&amp;#039;&amp;#039; scope.&lt;br /&gt;
&lt;br /&gt;
Public names from supported interfaces and super-classes are directly (i.e. without qualification) available inside a scope, if it is unambiguous where they come from. It is illegal to use a name whose origin is ambiguous. All ambiguities in predicate calls can be removed by qualifying the predicate name with the class name (e.g. &amp;lt;vp&amp;gt;cc::p&amp;lt;/vp&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
This qualification is also used to qualify calls of object member predicates of super-classes on the &amp;#039;&amp;#039;current&amp;#039;&amp;#039; object.&lt;br /&gt;
&lt;br /&gt;
Visual Prolog has the following shadowing hierarchy:&lt;br /&gt;
&lt;br /&gt;
* Local&lt;br /&gt;
* Super-class &amp;amp; opened scopes&lt;br /&gt;
&lt;br /&gt;
Opened scopes have the same status as super-classes, so in the sequel we will just say super-classes.&lt;br /&gt;
&lt;br /&gt;
The hierarchy means that a local declaration will shadow a super-class declaration. But there is no shadowing between super-classes; all super-classes have equal preference. If two or more super classes contain conflicting declarations then these declarations can only be accessed by means of qualification.&lt;br /&gt;
&lt;br /&gt;
{{Example|Assume the interface &amp;lt;vp&amp;gt;ixx&amp;lt;/vp&amp;gt; and the classes &amp;lt;vp&amp;gt;aa&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;bb&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface ixx&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    p1 : ().&lt;br /&gt;
    p2 : ().&lt;br /&gt;
    p3 : ().&lt;br /&gt;
&lt;br /&gt;
end interface ixx&lt;br /&gt;
&lt;br /&gt;
%========================&lt;br /&gt;
&lt;br /&gt;
class aa : ixx&lt;br /&gt;
end class aa&lt;br /&gt;
&lt;br /&gt;
%========================&lt;br /&gt;
&lt;br /&gt;
class bb&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    p3 : ().&lt;br /&gt;
    p4 : ().&lt;br /&gt;
    p5 : ().&lt;br /&gt;
&lt;br /&gt;
end class bb&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The class &amp;lt;vp&amp;gt;aa&amp;lt;/vp&amp;gt; creates objects of type &amp;lt;vp&amp;gt;ixx&amp;lt;/vp&amp;gt;, whereas the class &amp;lt;vp&amp;gt;bb&amp;lt;/vp&amp;gt; does not create objects at all.&lt;br /&gt;
&lt;br /&gt;
In this context consider the implementation of a class &amp;lt;vp&amp;gt;cc&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement cc inherits aa&lt;br /&gt;
    open bb&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    p2(). % reimplementation of ixx::p2&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    p5 : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p5().&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    new() :-&lt;br /&gt;
        p1(), % aa::p1&lt;br /&gt;
        p2(), % cc::p2 (shadows aa::p2)&lt;br /&gt;
        aa::p2(), % aa::p2&lt;br /&gt;
        p3(), % Illegal ambiguous call: aa::p3 or bb::p3&lt;br /&gt;
        aa::p3(), % aa::p3&lt;br /&gt;
        bb::p3(), % bb::p3&lt;br /&gt;
        p4(), % bb::p4&lt;br /&gt;
        p5(). % cc::p5 (shadows bb::p5)&lt;br /&gt;
&lt;br /&gt;
end implement cc&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
Since &amp;lt;vp&amp;gt;cc&amp;lt;/vp&amp;gt; inherits &amp;lt;vp&amp;gt;aa&amp;lt;/vp&amp;gt; all the predicates in the interface &amp;lt;vp&amp;gt;ixx&amp;lt;/vp&amp;gt; are also visible in &amp;lt;vp&amp;gt;cc&amp;lt;/vp&amp;gt;.  Likewise the &amp;lt;vp&amp;gt;open bb&amp;lt;/vp&amp;gt; qualification will make all predicates in &amp;lt;vp&amp;gt;bb&amp;lt;/vp&amp;gt; visible in &amp;lt;vp&amp;gt;cc&amp;lt;/vp&amp;gt;.}}&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{LanguageReferenceSubarticle|Basic Concepts/Scoping &amp;amp; Visibility}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Language_Reference/Basic_Concepts/Scoping_and_Visibility&amp;diff=4990</id>
		<title>Language Reference/Basic Concepts/Scoping and Visibility</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Language_Reference/Basic_Concepts/Scoping_and_Visibility&amp;diff=4990"/>
		<updated>2025-08-19T15:09:56Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Header level&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==== Name Categories ====&lt;br /&gt;
&lt;br /&gt;
All names (identifiers) in Visual Prolog are syntactically divided into two major groups:&lt;br /&gt;
&lt;br /&gt;
*Constant names (starting with a lowercase letter)&lt;br /&gt;
*Variable names (starting with an uppercase letter or an underscore)&lt;br /&gt;
&lt;br /&gt;
Constant names (identifiers) are divided into the following categories:&lt;br /&gt;
&lt;br /&gt;
* Type names (i.e. domains and interfaces).&lt;br /&gt;
* Domain carriers (i.e. classes and interfaces).&lt;br /&gt;
* Names without parentheses (i.e. constants, fact variables of non-function type and nullary-functors).&lt;br /&gt;
* Value returning names of arity N (i.e. functions, functors and fact-variables of function type).&lt;br /&gt;
* Non-value-returning names of arity N (i.e. predicates, facts and fact variables of predicate type).&lt;br /&gt;
&lt;br /&gt;
Visual Prolog demands that names do not conflict at the point of declaration, because then it would be impossible to solve the conflict at point of usage. Declarations can only conflict if they are in the same scope, because qualification with scope can be used to solve the conflict. A name in one category can never be in conflict with a name in another category, but as we shall see a single declaration might place a name in several categories.&lt;br /&gt;
&lt;br /&gt;
==== Packages ====&lt;br /&gt;
&lt;br /&gt;
The basic units of code organization accepted in Visual Prolog are packages. We use packages in Visual Prolog to organize and structuring things. The use of packages ensures homogeneity in structuring principles among different projects. Packages define the standard for tool structuring and ease sharing source code among projects. &lt;br /&gt;
&lt;br /&gt;
The package is a collection of several grouped together interfaces and classes. The package provides some common name to all these interfaces and classes. Each declaration or implementation of each interface or class from a package is placed in a separate file. Each filename (of these files) coincides with the name of a class or an interface that is declared or implemented in this file. All package files are stored in the same separate package directory. (If a package contains sub-packages, then they are placed in subdirectories of the package directory.) &lt;br /&gt;
&lt;br /&gt;
The concept of packages is used for grouping together several linked interfaces and classes. Packages can play a role of some class library. Packages can be used in your program instead of direct placing all used interfaces and classes into your program.&lt;br /&gt;
&lt;br /&gt;
The accepted in Visual Prolog structure of packages and how packages should be included into projects are described in the VDE part of this help. (See &amp;#039;&amp;#039;&amp;#039;Creating a Package&amp;#039;&amp;#039;&amp;#039; in &amp;#039;&amp;#039;&amp;#039;Creating New Project Items&amp;#039;&amp;#039;&amp;#039;.)&lt;br /&gt;
&lt;br /&gt;
===== Visibility, Shadowing, and Qualification =====&lt;br /&gt;
&lt;br /&gt;
Most of the scoping rules are already mentioned above. This section will complete the picture.&lt;br /&gt;
&lt;br /&gt;
An interface definition, a class declaration and a class implementation are scopes (scopes cannot be nested). An implementation (privately) extends the scope of the corresponding class declaration. The visibility is the same &amp;#039;&amp;#039;&amp;#039;everywhere&amp;#039;&amp;#039;&amp;#039; in a scope. This does especially mean that &amp;#039;&amp;#039;&amp;#039;no matter where&amp;#039;&amp;#039;&amp;#039; in a scope something is declared, it is visible in the &amp;#039;&amp;#039;&amp;#039;whole&amp;#039;&amp;#039;&amp;#039; scope.&lt;br /&gt;
&lt;br /&gt;
Public names from supported interfaces and super-classes are directly (i.e. without qualification) available inside a scope, if it is unambiguous where they come from. It is illegal to use a name whose origin is ambiguous. All ambiguities in predicate calls can be removed by qualifying the predicate name with the class name (e.g. &amp;lt;vp&amp;gt;cc::p&amp;lt;/vp&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
This qualification is also used to qualify calls of object member predicates of super-classes on the &amp;#039;&amp;#039;current&amp;#039;&amp;#039; object.&lt;br /&gt;
&lt;br /&gt;
Visual Prolog has the following shadowing hierarchy:&lt;br /&gt;
&lt;br /&gt;
* Local&lt;br /&gt;
* Super-class &amp;amp; opened scopes&lt;br /&gt;
&lt;br /&gt;
Opened scopes have the same status as super-classes, so in the sequel we will just say super-classes.&lt;br /&gt;
&lt;br /&gt;
The hierarchy means that a local declaration will shadow a super-class declaration. But there is no shadowing between super-classes; all super-classes have equal preference. If two or more super classes contain conflicting declarations then these declarations can only be accessed by means of qualification.&lt;br /&gt;
&lt;br /&gt;
{{Example|Assume the interface &amp;lt;vp&amp;gt;ixx&amp;lt;/vp&amp;gt; and the classes &amp;lt;vp&amp;gt;aa&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;bb&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface ixx&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    p1 : ().&lt;br /&gt;
    p2 : ().&lt;br /&gt;
    p3 : ().&lt;br /&gt;
&lt;br /&gt;
end interface ixx&lt;br /&gt;
&lt;br /&gt;
%========================&lt;br /&gt;
&lt;br /&gt;
class aa : ixx&lt;br /&gt;
end class aa&lt;br /&gt;
&lt;br /&gt;
%========================&lt;br /&gt;
&lt;br /&gt;
class bb&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    p3 : ().&lt;br /&gt;
    p4 : ().&lt;br /&gt;
    p5 : ().&lt;br /&gt;
&lt;br /&gt;
end class bb&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The class &amp;lt;vp&amp;gt;aa&amp;lt;/vp&amp;gt; creates objects of type &amp;lt;vp&amp;gt;ixx&amp;lt;/vp&amp;gt;, whereas the class &amp;lt;vp&amp;gt;bb&amp;lt;/vp&amp;gt; does not create objects at all.&lt;br /&gt;
&lt;br /&gt;
In this context consider the implementation of a class &amp;lt;vp&amp;gt;cc&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement cc inherits aa&lt;br /&gt;
    open bb&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    p2(). % reimplementation of ixx::p2&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    p5 : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p5().&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    new() :-&lt;br /&gt;
        p1(), % aa::p1&lt;br /&gt;
        p2(), % cc::p2 (shadows aa::p2)&lt;br /&gt;
        aa::p2(), % aa::p2&lt;br /&gt;
        p3(), % Illegal ambiguous call: aa::p3 or bb::p3&lt;br /&gt;
        aa::p3(), % aa::p3&lt;br /&gt;
        bb::p3(), % bb::p3&lt;br /&gt;
        p4(), % bb::p4&lt;br /&gt;
        p5(). % cc::p5 (shadows bb::p5)&lt;br /&gt;
&lt;br /&gt;
end implement cc&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
Since &amp;lt;vp&amp;gt;cc&amp;lt;/vp&amp;gt; inherits &amp;lt;vp&amp;gt;aa&amp;lt;/vp&amp;gt; all the predicates in the interface &amp;lt;vp&amp;gt;ixx&amp;lt;/vp&amp;gt; are also visible in &amp;lt;vp&amp;gt;cc&amp;lt;/vp&amp;gt;.  Likewise the &amp;lt;vp&amp;gt;open bb&amp;lt;/vp&amp;gt; qualification will make all predicates in &amp;lt;vp&amp;gt;bb&amp;lt;/vp&amp;gt; visible in &amp;lt;vp&amp;gt;cc&amp;lt;/vp&amp;gt;.}}&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{LanguageReferenceSubarticle|Basic Concepts/Scoping &amp;amp; Visibility}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Language_Reference/Basic_Concepts/Scoping_and_Visibility&amp;diff=4989</id>
		<title>Language Reference/Basic Concepts/Scoping and Visibility</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Language_Reference/Basic_Concepts/Scoping_and_Visibility&amp;diff=4989"/>
		<updated>2025-08-19T15:09:42Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Header level&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==== Name Categories ====&lt;br /&gt;
&lt;br /&gt;
All names (identifiers) in Visual Prolog are syntactically divided into two major groups:&lt;br /&gt;
&lt;br /&gt;
*Constant names (starting with a lowercase letter)&lt;br /&gt;
*Variable names (starting with an uppercase letter or an underscore)&lt;br /&gt;
&lt;br /&gt;
Constant names (identifiers) are divided into the following categories:&lt;br /&gt;
&lt;br /&gt;
* Type names (i.e. domains and interfaces).&lt;br /&gt;
* Domain carriers (i.e. classes and interfaces).&lt;br /&gt;
* Names without parentheses (i.e. constants, fact variables of non-function type and nullary-functors).&lt;br /&gt;
* Value returning names of arity N (i.e. functions, functors and fact-variables of function type).&lt;br /&gt;
* Non-value-returning names of arity N (i.e. predicates, facts and fact variables of predicate type).&lt;br /&gt;
&lt;br /&gt;
Visual Prolog demands that names do not conflict at the point of declaration, because then it would be impossible to solve the conflict at point of usage. Declarations can only conflict if they are in the same scope, because qualification with scope can be used to solve the conflict. A name in one category can never be in conflict with a name in another category, but as we shall see a single declaration might place a name in several categories.&lt;br /&gt;
&lt;br /&gt;
===== Packages =====&lt;br /&gt;
&lt;br /&gt;
The basic units of code organization accepted in Visual Prolog are packages. We use packages in Visual Prolog to organize and structuring things. The use of packages ensures homogeneity in structuring principles among different projects. Packages define the standard for tool structuring and ease sharing source code among projects. &lt;br /&gt;
&lt;br /&gt;
The package is a collection of several grouped together interfaces and classes. The package provides some common name to all these interfaces and classes. Each declaration or implementation of each interface or class from a package is placed in a separate file. Each filename (of these files) coincides with the name of a class or an interface that is declared or implemented in this file. All package files are stored in the same separate package directory. (If a package contains sub-packages, then they are placed in subdirectories of the package directory.) &lt;br /&gt;
&lt;br /&gt;
The concept of packages is used for grouping together several linked interfaces and classes. Packages can play a role of some class library. Packages can be used in your program instead of direct placing all used interfaces and classes into your program.&lt;br /&gt;
&lt;br /&gt;
The accepted in Visual Prolog structure of packages and how packages should be included into projects are described in the VDE part of this help. (See &amp;#039;&amp;#039;&amp;#039;Creating a Package&amp;#039;&amp;#039;&amp;#039; in &amp;#039;&amp;#039;&amp;#039;Creating New Project Items&amp;#039;&amp;#039;&amp;#039;.)&lt;br /&gt;
&lt;br /&gt;
===== Visibility, Shadowing, and Qualification =====&lt;br /&gt;
&lt;br /&gt;
Most of the scoping rules are already mentioned above. This section will complete the picture.&lt;br /&gt;
&lt;br /&gt;
An interface definition, a class declaration and a class implementation are scopes (scopes cannot be nested). An implementation (privately) extends the scope of the corresponding class declaration. The visibility is the same &amp;#039;&amp;#039;&amp;#039;everywhere&amp;#039;&amp;#039;&amp;#039; in a scope. This does especially mean that &amp;#039;&amp;#039;&amp;#039;no matter where&amp;#039;&amp;#039;&amp;#039; in a scope something is declared, it is visible in the &amp;#039;&amp;#039;&amp;#039;whole&amp;#039;&amp;#039;&amp;#039; scope.&lt;br /&gt;
&lt;br /&gt;
Public names from supported interfaces and super-classes are directly (i.e. without qualification) available inside a scope, if it is unambiguous where they come from. It is illegal to use a name whose origin is ambiguous. All ambiguities in predicate calls can be removed by qualifying the predicate name with the class name (e.g. &amp;lt;vp&amp;gt;cc::p&amp;lt;/vp&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
This qualification is also used to qualify calls of object member predicates of super-classes on the &amp;#039;&amp;#039;current&amp;#039;&amp;#039; object.&lt;br /&gt;
&lt;br /&gt;
Visual Prolog has the following shadowing hierarchy:&lt;br /&gt;
&lt;br /&gt;
* Local&lt;br /&gt;
* Super-class &amp;amp; opened scopes&lt;br /&gt;
&lt;br /&gt;
Opened scopes have the same status as super-classes, so in the sequel we will just say super-classes.&lt;br /&gt;
&lt;br /&gt;
The hierarchy means that a local declaration will shadow a super-class declaration. But there is no shadowing between super-classes; all super-classes have equal preference. If two or more super classes contain conflicting declarations then these declarations can only be accessed by means of qualification.&lt;br /&gt;
&lt;br /&gt;
{{Example|Assume the interface &amp;lt;vp&amp;gt;ixx&amp;lt;/vp&amp;gt; and the classes &amp;lt;vp&amp;gt;aa&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;bb&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface ixx&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    p1 : ().&lt;br /&gt;
    p2 : ().&lt;br /&gt;
    p3 : ().&lt;br /&gt;
&lt;br /&gt;
end interface ixx&lt;br /&gt;
&lt;br /&gt;
%========================&lt;br /&gt;
&lt;br /&gt;
class aa : ixx&lt;br /&gt;
end class aa&lt;br /&gt;
&lt;br /&gt;
%========================&lt;br /&gt;
&lt;br /&gt;
class bb&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    p3 : ().&lt;br /&gt;
    p4 : ().&lt;br /&gt;
    p5 : ().&lt;br /&gt;
&lt;br /&gt;
end class bb&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The class &amp;lt;vp&amp;gt;aa&amp;lt;/vp&amp;gt; creates objects of type &amp;lt;vp&amp;gt;ixx&amp;lt;/vp&amp;gt;, whereas the class &amp;lt;vp&amp;gt;bb&amp;lt;/vp&amp;gt; does not create objects at all.&lt;br /&gt;
&lt;br /&gt;
In this context consider the implementation of a class &amp;lt;vp&amp;gt;cc&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement cc inherits aa&lt;br /&gt;
    open bb&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    p2(). % reimplementation of ixx::p2&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    p5 : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p5().&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    new() :-&lt;br /&gt;
        p1(), % aa::p1&lt;br /&gt;
        p2(), % cc::p2 (shadows aa::p2)&lt;br /&gt;
        aa::p2(), % aa::p2&lt;br /&gt;
        p3(), % Illegal ambiguous call: aa::p3 or bb::p3&lt;br /&gt;
        aa::p3(), % aa::p3&lt;br /&gt;
        bb::p3(), % bb::p3&lt;br /&gt;
        p4(), % bb::p4&lt;br /&gt;
        p5(). % cc::p5 (shadows bb::p5)&lt;br /&gt;
&lt;br /&gt;
end implement cc&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
Since &amp;lt;vp&amp;gt;cc&amp;lt;/vp&amp;gt; inherits &amp;lt;vp&amp;gt;aa&amp;lt;/vp&amp;gt; all the predicates in the interface &amp;lt;vp&amp;gt;ixx&amp;lt;/vp&amp;gt; are also visible in &amp;lt;vp&amp;gt;cc&amp;lt;/vp&amp;gt;.  Likewise the &amp;lt;vp&amp;gt;open bb&amp;lt;/vp&amp;gt; qualification will make all predicates in &amp;lt;vp&amp;gt;bb&amp;lt;/vp&amp;gt; visible in &amp;lt;vp&amp;gt;cc&amp;lt;/vp&amp;gt;.}}&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{LanguageReferenceSubarticle|Basic Concepts/Scoping &amp;amp; Visibility}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Language_Reference/Attributes&amp;diff=4988</id>
		<title>Language Reference/Attributes</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Language_Reference/Attributes&amp;diff=4988"/>
		<updated>2025-08-19T15:08:25Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{languageReferenceNavbar|Attributes}}&lt;br /&gt;
&lt;br /&gt;
Various definitions and declarations can be annotated with attributes. This section describes the general syntax of attributes and where they can be placed. It also describes the meaning of the specific attributes.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;Attributes&amp;gt; :&lt;br /&gt;
    [ &amp;lt;Attribute&amp;gt;-comma-sep-list ]&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;Attribute&amp;gt; : one of&lt;br /&gt;
    &amp;lt;LowerCaseIdentifier&amp;gt;&lt;br /&gt;
    &amp;lt;LowerCaseIdentifier&amp;gt; ( &amp;lt;Literal&amp;gt;-comma-sep-list )&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the literals must either be numbers or string literals.&lt;br /&gt;
&lt;br /&gt;
=== Insertion Points ===&lt;br /&gt;
&lt;br /&gt;
The attributes of interfaces, classes and implementations are right after the scope qualifications.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;InterfaceDeclaration&amp;gt; :&lt;br /&gt;
    interface &amp;lt;IinterfaceName&amp;gt;&lt;br /&gt;
        &amp;lt;ScopeQualifications&amp;gt;&lt;br /&gt;
        &amp;lt;Attributes&amp;gt;-opt&lt;br /&gt;
    &amp;lt;Sections&amp;gt;&lt;br /&gt;
end interface &amp;lt;IinterfaceName&amp;gt;-opt&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;ClassDeclaration&amp;gt; :&lt;br /&gt;
    class &amp;lt;ClassName&amp;gt; &amp;lt;ConstructionType&amp;gt;-opt&lt;br /&gt;
        &amp;lt;ScopeQualifications&amp;gt;&lt;br /&gt;
        &amp;lt;Attributes&amp;gt;-opt&lt;br /&gt;
    &amp;lt;Sections&amp;gt;&lt;br /&gt;
    end class &amp;lt;ClassName&amp;gt;-opt&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;ClassImplementation&amp;gt; :&lt;br /&gt;
   implement &amp;lt;ClassName&amp;gt;&lt;br /&gt;
        &amp;lt;ScopeQualifications&amp;gt;&lt;br /&gt;
        &amp;lt;Attributes&amp;gt;-opt&lt;br /&gt;
    &amp;lt;Sections&amp;gt;&lt;br /&gt;
    end implement &amp;lt;ClassName&amp;gt;-opt&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attributes of constants, domains, predicates, properties and facts are at the end (i.e. right before the terminating dot).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;ConstantDefinition&amp;gt;: one of&lt;br /&gt;
    &amp;lt;ConstantName&amp;gt; = &amp;lt;ConstantValue&amp;gt; &amp;lt;Attributes&amp;gt;-opt&lt;br /&gt;
    &amp;lt;ConstantName&amp;gt; : &amp;lt;TypeName&amp;gt; = &amp;lt;ConstantValue&amp;gt; &amp;lt;Attributes&amp;gt;-opt&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;DomainDefinition&amp;gt;:&lt;br /&gt;
    &amp;lt;DomainName&amp;gt; &amp;lt;FormalTypeParameterList&amp;gt;-opt = &amp;lt;TypeExpression&amp;gt; &amp;lt;Attributes&amp;gt;-opt&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;PredicateDeclaration&amp;gt; :&lt;br /&gt;
    &amp;lt;PredicateName&amp;gt; : &amp;lt;PredicateDomain&amp;gt; &amp;lt;LinkName&amp;gt;-opt &amp;lt;Attributes&amp;gt;-opt&lt;br /&gt;
    &amp;lt;PredicateName&amp;gt; : &amp;lt;PredicateDomainName&amp;gt; &amp;lt;LinkName&amp;gt;-opt &amp;lt;Attributes&amp;gt;-opt&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;PropertyDeclaration&amp;gt; :&lt;br /&gt;
    &amp;lt;PropertyName&amp;gt; : &amp;lt;PropertyType&amp;gt; &amp;lt;FlowPattern&amp;gt;-list-opt &amp;lt;Attributes&amp;gt;-opt&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;FactDeclaration&amp;gt; :&lt;br /&gt;
    &amp;lt;FactVariableDeclaration&amp;gt; &amp;lt;Attributes&amp;gt;-opt&lt;br /&gt;
    &amp;lt;FactFunctorDeclaration&amp;gt; &amp;lt;Attributes&amp;gt;-opt&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attributes of formal arguments are at the end.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;FormalArgument&amp;gt; :&lt;br /&gt;
    &amp;lt;TypeExpression&amp;gt; &amp;lt;ArgumentName&amp;gt;-opt &amp;lt;Attributes&amp;gt;-opt&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Specific Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== attribute ====&lt;br /&gt;
&lt;br /&gt;
This attribute is used on a functor domain to indicate that the functors in the domain can be used as attributes elsewhere in the program.&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
    meta =&lt;br /&gt;
        meta;&lt;br /&gt;
        metaDisplayAs(string DisplayAs) [attribute].&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
See [[Program Defined Attributes]].&lt;br /&gt;
&lt;br /&gt;
==== byVal ====&lt;br /&gt;
&lt;br /&gt;
An argument is transferred directly on the stack rather than using a pointer.  Valid for formal predicate arguments provided the &amp;lt;vp&amp;gt;language&amp;lt;/vp&amp;gt; is &amp;lt;vp&amp;gt;stdcall&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;apicall&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;c&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
    point = point(integer X, integer Y).&lt;br /&gt;
predicates&lt;br /&gt;
    externalP : (point Point [byVal]) language apicall.&lt;br /&gt;
&amp;lt;/vip&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
The attribute can also be used in combination with the &amp;lt;vp&amp;gt;out&amp;lt;/vp&amp;gt; attribute:&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
predicates&lt;br /&gt;
    externalP2 : (point Point [byVal, out]) language apicall.&lt;br /&gt;
&amp;lt;/vip&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
In that case a &amp;lt;vp&amp;gt;point&amp;lt;/vp&amp;gt; structure will be allocated before the call then a pointer to that structure is transferred handed to the external predicate which can then fill the structure with relevant data.&lt;br /&gt;
&lt;br /&gt;
==== classInitializer ====&lt;br /&gt;
&lt;br /&gt;
This attribute indicates that a predicate should be invoked as a class initializer.  It can be applied to a class predicate that does not take any arguments.  The predicate will be invoked when the initialization code invokes the &amp;lt;vp&amp;gt;runtime_api::runProgramInitialization&amp;lt;/vp&amp;gt;.  A class can have any number of class initializer which will be invoked in an undetermined order.  Notice that other classes may not have been initialized.&lt;br /&gt;
&lt;br /&gt;
The predicate &amp;lt;vp&amp;gt;xxx::initialize&amp;lt;/vp&amp;gt; is registered as a class initializer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement xxx&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    initialize : () [classInitializer].&lt;br /&gt;
clauses&lt;br /&gt;
    initialize() :-&lt;br /&gt;
        …&lt;br /&gt;
&lt;br /&gt;
end class xxx&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== constant ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;constant&amp;lt;/vp&amp;gt; attribute is used to declare fact variables that cannot be changed once they have been initialized.&lt;br /&gt;
&lt;br /&gt;
See {{lang2|Facts|Constant fact variable|Constant fact variable}}.&lt;br /&gt;
&lt;br /&gt;
==== compiletimeSetting ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;compiletimeSetting&amp;lt;/vp&amp;gt; attribute indicates that a constant should be considered a compiletime setting.  As a result the compiler will suppress warnings about always failing/succeding code and about unreachable code that may be caused by this constant.  The warning suppession is an approximation, because it a may be impossible/difficult to determine the cause of a warning.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement xxx&lt;br /&gt;
&lt;br /&gt;
constants&lt;br /&gt;
    debugOutput : boolean = false [compiletimeSetting].&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pppp(...) :-&lt;br /&gt;
        ...&lt;br /&gt;
        if true = debugOutput then&lt;br /&gt;
            % do not give a warning about unreachable code&lt;br /&gt;
            log::write(...)&lt;br /&gt;
         end if,&lt;br /&gt;
         ...&lt;br /&gt;
&lt;br /&gt;
end implement xxx&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== default ====&lt;br /&gt;
&lt;br /&gt;
It is problematic to update functor domains, if terms have been persisted in serialized form.  Because new programs cannot deal with old serializations.&lt;br /&gt;
&lt;br /&gt;
The two attributes &amp;lt;vp&amp;gt;default/1&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;retiredFunctor/1&amp;lt;/vp&amp;gt; can help dealing with this problem.&lt;br /&gt;
&lt;br /&gt;
The last arguments of a functor can have default values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
    ppp =&lt;br /&gt;
        fct(&lt;br /&gt;
            integer A,&lt;br /&gt;
            real B,&lt;br /&gt;
            ddd C,&lt;br /&gt;
            integer* New [default([])],&lt;br /&gt;
            real New2 [default(0)]&lt;br /&gt;
        ).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The default attribute does not change anything within the program; it only affects the deserialization.  If during deserialization we meet the closing parenthesis too soon we supply default values for the remaining arguments.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Notice&amp;#039;&amp;#039;&amp;#039; that this will only work for &amp;#039;&amp;#039;&amp;#039;text&amp;#039;&amp;#039;&amp;#039; deserialization.&lt;br /&gt;
&lt;br /&gt;
See also [[Functor Domain Versioning]].&lt;br /&gt;
&lt;br /&gt;
==== deprecated ====&lt;br /&gt;
&lt;br /&gt;
The declared entity is deprecated. The string literal describes how to migrate from it.  The entity still exists, but usage will cause a warning.&lt;br /&gt;
The entity will not exist in future versions of Visual Prolog.  Valid for member declarations and scopes.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    oldFashioned : (string Arg) [deprecated(&amp;quot;Use newFashion instead&amp;quot;)].&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== explicitTag ====&lt;br /&gt;
&lt;br /&gt;
This predicate can be used on a functor domain to ensure that the memory representation of all terms have a functor.  Without this attribute the compiler optimizes the representation such that some alternatives doesn&amp;#039;t have a functor in the term, and such that functors with arguments are represented as a pointer value.  The main purpose of this attribute is to ensure compatibility with foreign code.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    menu =&lt;br /&gt;
        resMenu(resid Resid);&lt;br /&gt;
        dynMenu(menuItem* SubMenu);&lt;br /&gt;
        noMenu&lt;br /&gt;
        [explicitTag].&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== formatString ====&lt;br /&gt;
&lt;br /&gt;
The argument is a format string for a subsequent ellipsis argument (i.e. &amp;lt;vp&amp;gt;...&amp;lt;/vp&amp;gt;).  Valid for one string argument of a predicate with an ellipsis argument.  The use of &amp;lt;vp&amp;gt;formatString&amp;lt;/vp&amp;gt; will make the compiler check the validity of actual arguments with respect to actual format strings (where possible).&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    writef : (string Format [formatString], ...).&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The format string can contain ordinary characters which are printed without modification, and format fields, that begins with the percent &amp;lt;vp&amp;gt;%&amp;lt;/vp&amp;gt; sign. If the percent sign is followed by some unknown character (not the format specifier) - then this character will  be printed without modifications.  To output a &amp;lt;vp&amp;gt;%&amp;lt;/vp&amp;gt; character you must write &amp;lt;vp&amp;gt;%%&amp;lt;/vp&amp;gt; in the format string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
     writef : (string Format [formatstring], ...).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The format fields specification is: &lt;br /&gt;
&lt;br /&gt;
[-][0][width][.precision][type] &lt;br /&gt;
&lt;br /&gt;
All fields are optional. &lt;br /&gt;
&lt;br /&gt;
[-] Hyphen indicates that the field is to be left justified; right justified is the default. Having no effect when width value is not set, or the number of characters in the actual value is greater than width value. &lt;br /&gt;
&lt;br /&gt;
[0] Zero before width means for values that zeros will be added until the minimum width is reached. If 0(zero) and -(hyphen) appear, the 0 is ignored &lt;br /&gt;
&lt;br /&gt;
[width] Positive decimal number specifying a minimum field size. If the number of characters in the actual value is less than width value - then the required number of space &amp;#039; &amp;#039; characters will be added before the value (or after it, if &amp;#039;-&amp;#039; field was set). No changes occurs if number of characters in the actual value is greater than the width value. &lt;br /&gt;
&lt;br /&gt;
[.precision] The point &amp;#039;.&amp;#039; with the following unsigned decimal number can specify either the precision of a floating-point image or the maximum number of characters to be printed from a string. &lt;br /&gt;
&lt;br /&gt;
[type] Specifies other format then the default for the given. For example, in the type field, you can give a specifier that says an integer will be formatted as an unsigned. The possible values are: &lt;br /&gt;
&lt;br /&gt;
:{|{{prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
| f || Format real&amp;#039;s in fixed-decimal notation (such as 123.4 or 0.004321). This is the default for real&amp;#039;s.&lt;br /&gt;
|-&lt;br /&gt;
| e || Format real&amp;#039;s in exponential notation (such as 1.234e+002 or 4.321e-003).&lt;br /&gt;
|-&lt;br /&gt;
| g || Format real&amp;#039;s in the shortest of f and e format, but always in e format if exponent of the value is less than -4 or greater than or equal to the precision. Trailing zeros are truncated.&lt;br /&gt;
|-&lt;br /&gt;
| d or D || Format as a signed decimal number.&lt;br /&gt;
|-&lt;br /&gt;
| u or U || Format as an unsigned integer.&lt;br /&gt;
|-&lt;br /&gt;
| x or X || Format as a hexadecimal number.&lt;br /&gt;
|-&lt;br /&gt;
| o or O || Format as an octal number.&lt;br /&gt;
|-&lt;br /&gt;
| c || Format as a char.&lt;br /&gt;
|-&lt;br /&gt;
| B || Format as the Visual Prolog binary type.&lt;br /&gt;
|-&lt;br /&gt;
| R || Format as a database reference number.&lt;br /&gt;
|-&lt;br /&gt;
| p || Format as the presented value.&lt;br /&gt;
|-&lt;br /&gt;
| P || Format as a procedure parameter.&lt;br /&gt;
|-&lt;br /&gt;
| s || Format as a string.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== generated ====&lt;br /&gt;
This attribute can be placed on interfaces, classes and implementation to indicate that the code is generated by some tool.  As result the compiler will issue less warnings about the code.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface iSomething supports iUnknown&lt;br /&gt;
    [generated]&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== immediate ====&lt;br /&gt;
&lt;br /&gt;
The attribute immediate enforces immediate (i.e. non-late) initialization of a fact variable:&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
facts&lt;br /&gt;
    current : integer := initializeCurrent() [immediate].&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
See also {{Lang2|Facts|Fact Variable Declarations|Fact Variable Declarations}}.&lt;br /&gt;
&lt;br /&gt;
==== in ====&lt;br /&gt;
&lt;br /&gt;
The argument is an input argument.  Valid for a formal predicate argument.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    pred : (string InputArg [in]).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== in_iterate ====&lt;br /&gt;
&lt;br /&gt;
Defines an in-iterator predicate for a domain or interface. See the description of the {{lang2|Terms|in|in}} operator.&lt;br /&gt;
&lt;br /&gt;
==== in_test ====&lt;br /&gt;
&lt;br /&gt;
Defines an in-test for a domain or interface. See the description of the {{lang2|Terms|in|in}} operator.&lt;br /&gt;
&lt;br /&gt;
==== inline ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;inline&amp;lt;/vp&amp;gt; alters the memory layout of a struct (i.e. a single alternative functor domain with an align qualification).  The purpose of the attribute is to ease interfacing to foreign languages and should normally not be used for pure Visual Prolog.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;inline&amp;lt;/vp&amp;gt; can be used in three cases:&lt;br /&gt;
&lt;br /&gt;
* inlining a struct rather than having a pointer to the struct&lt;br /&gt;
* inlining a fixed size string&lt;br /&gt;
* inlining a fixed number of bytes&lt;br /&gt;
* inlining a prolog predicate type (as a struct with two fields)&lt;br /&gt;
&lt;br /&gt;
When using &amp;lt;vp&amp;gt;inline&amp;lt;/vp&amp;gt; on struct field in another struct its data will be inlined instead of having a pointer to the struct&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    point =p(integer X, integer Y).&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    rectangle =&lt;br /&gt;
       r(&lt;br /&gt;
            point UpperLeft [inline],&lt;br /&gt;
            point LowerRight [inline]&lt;br /&gt;
        ).&amp;lt;/vip&amp;gt;&lt;br /&gt;
Since &amp;lt;vp&amp;gt;UpperLeft&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;LowerRight&amp;lt;/vp&amp;gt; are inlined the struct have the same memory layout as this one:&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    rectangle2 =&lt;br /&gt;
        r2(&lt;br /&gt;
            integer UpperLeft_X,&lt;br /&gt;
            integer UpperLeft_Y,&lt;br /&gt;
            integer LowerRight_X,&lt;br /&gt;
            integer LowerRight_Y&lt;br /&gt;
        ).&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When using &amp;lt;vp&amp;gt;inline(&amp;lt;size&amp;gt;)&amp;lt;/vp&amp;gt; on a &amp;lt;vp&amp;gt;string&amp;lt;/vp&amp;gt; or a &amp;lt;vp&amp;gt;string8&amp;lt;/vp&amp;gt; field in a struct, the struct will contain a fixed size string with &amp;lt;vp&amp;gt;&amp;lt;size&amp;gt;&amp;lt;/vp&amp;gt; characters (i.e. &amp;lt;vp&amp;gt;char&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;char8&amp;lt;/vp&amp;gt;, respectively).  The strings will be zero terminated if they are shorter than &amp;lt;vp&amp;gt;&amp;lt;size&amp;gt;&amp;lt;/vp&amp;gt;, but not if they have &amp;lt;vp&amp;gt;&amp;lt;size&amp;gt;&amp;lt;/vp&amp;gt; characters.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    device =&lt;br /&gt;
        device(&lt;br /&gt;
            integer Id,&lt;br /&gt;
            string DeviceName [inline(12)]&lt;br /&gt;
        ).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;vp&amp;gt;DeviceName&amp;lt;/vp&amp;gt; is an inlined Unicode string of length 12.&lt;br /&gt;
The struct have the same layout as:&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    device =&lt;br /&gt;
        device(&lt;br /&gt;
            integer Id,&lt;br /&gt;
            char DeviceName_01,&lt;br /&gt;
            char DeviceName_02,&lt;br /&gt;
            char DeviceName_03,&lt;br /&gt;
            char DeviceName_04,&lt;br /&gt;
            char DeviceName_05,&lt;br /&gt;
            char DeviceName_06,&lt;br /&gt;
            char DeviceName_07,&lt;br /&gt;
            char DeviceName_08,&lt;br /&gt;
            char DeviceName_09,&lt;br /&gt;
            char DeviceName_10,&lt;br /&gt;
            char DeviceName_11,&lt;br /&gt;
            char DeviceName_12&lt;br /&gt;
        ).&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
When using &amp;lt;vp&amp;gt;inline(&amp;lt;size&amp;gt;)&amp;lt;/vp&amp;gt; on the &amp;lt;vp&amp;gt;pointer&amp;lt;/vp&amp;gt; type the struct will contain &amp;lt;vp&amp;gt;&amp;lt;size&amp;gt;&amp;lt;/vp&amp;gt; bytes, and the pointer will become a pointer to that field:&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    mark =&lt;br /&gt;
        mark(&lt;br /&gt;
            integer Position,&lt;br /&gt;
            pointer Data [inline(8)]&lt;br /&gt;
        ).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;vp&amp;gt;Data&amp;lt;/vp&amp;gt; is pointer to 8 inlined bytes&lt;br /&gt;
The struct have the same layout as:&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    mark2 =&lt;br /&gt;
        mark2(&lt;br /&gt;
            integer Position,&lt;br /&gt;
            byte Data_1,&lt;br /&gt;
            byte Data_2,&lt;br /&gt;
            byte Data_3,&lt;br /&gt;
            byte Data_4,&lt;br /&gt;
            byte Data_5,&lt;br /&gt;
            byte Data_6,&lt;br /&gt;
            byte Data_7,&lt;br /&gt;
            byte Data_8&lt;br /&gt;
        ).&amp;lt;/vip&amp;gt;&lt;br /&gt;
And &amp;lt;vp&amp;gt;Data&amp;lt;/vp&amp;gt; will point to &amp;lt;vp&amp;gt;Data_1&amp;lt;/vp&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== intrinsic ====&lt;br /&gt;
&lt;br /&gt;
A declaration which has special meaning and handling in the compiler (semi-built-in).&lt;br /&gt;
&lt;br /&gt;
==== mandatoryOut ====&lt;br /&gt;
&lt;br /&gt;
Used to prevent a predicate from having optional output parameters (see {{Lang2|Terms|Optional parameters|Optional parameters}}).&lt;br /&gt;
&lt;br /&gt;
{{Example|This predicate does not have optional output paramters&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
predicates&lt;br /&gt;
    ppp : (integer X [out]) [mandatoryOut]. % The output parameter is mandatory&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== noDefaultConstructor ====&lt;br /&gt;
&lt;br /&gt;
Used for a class to indicate that it should not have an implicit default constructor, and can thus be used to a class that does not have any public constructors at all.  Valid for an object creating class declaration.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;class classWithoutPublicConstructors : myInterface&lt;br /&gt;
    open core&lt;br /&gt;
    [noDefaultConstructor]&lt;br /&gt;
...&lt;br /&gt;
end class classWithoutPublicConstructors&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== out ====&lt;br /&gt;
&lt;br /&gt;
The argument is an output argument. Valid for a formal predicate argument.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    pred : (string OutputArg [out]).&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== pack ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;[pack(n)]&amp;lt;/vp&amp;gt; attribute (where &amp;lt;vp&amp;gt;n&amp;lt;/vp&amp;gt; is a number) instructs the compiler to use &amp;lt;vp&amp;gt;n&amp;lt;/vp&amp;gt; as packing size for a functor domains.  By default the packing size is &amp;lt;vp&amp;gt;4&amp;lt;/vp&amp;gt; in 32 bit programs and &amp;lt;vp&amp;gt;8&amp;lt;/vp&amp;gt; in 64 bit programs.  This attribute is mainly intended for compatibility with C/C++ api&amp;#039;s.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
    packed = packed(integer8, pointer) [pack(2)].&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The attribute can used on a &amp;lt;vp&amp;gt;class&amp;lt;/vp&amp;gt; declaration to cover all domains in that class.&lt;br /&gt;
&lt;br /&gt;
{{Example|The domains used with the RichEdit control must all be packed with 4:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class richEdit_native&lt;br /&gt;
    open core, gui_native&lt;br /&gt;
    [pack(4)]&lt;br /&gt;
&lt;br /&gt;
% pack all domains with packing size 4&lt;br /&gt;
&lt;br /&gt;
end class richEdit_native&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== programPoint ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;programPoint&amp;lt;/vp&amp;gt;&amp;#039;s are used by the exception mechanism to indicate where exceptions are raised and continued, but the usage is not limited to that purpose.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;programPoint&amp;lt;/vp&amp;gt; attribute is used predicate or constructor declaration to indicate that it receives an extra input argument which describes the place in a program (program point) where this predicate was called. This additional argument has &amp;lt;vp&amp;gt;programPoint&amp;lt;/vp&amp;gt; type which is declared in the PFC core class like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    programPoint = programPoint(hScopeDescriptor ClassDescriptor, string PredicateName, sourceCursor Cursor).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;programPoint&amp;lt;/vp&amp;gt; attribute can be added to a predicate declaration like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    raiseAnException : (integer X) erroneous [programPoint].&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adding this attribute actually means that two predicates are declared, the one you have mentioned and an another one with name &amp;lt;vp&amp;gt;raiseAnException_explicit&amp;lt;/vp&amp;gt; which in addition to the arguments of &amp;lt;vp&amp;gt;raiseAnException&amp;lt;/vp&amp;gt; takes a &amp;lt;vp&amp;gt;programPoint&amp;lt;/vp&amp;gt; as first argument:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    raiseAnException : (integer X) erroneous.&lt;br /&gt;
    &lt;br /&gt;
predicates&lt;br /&gt;
    raiseAnException_explicit : (programPoint ProgramPoint, integer X) erroneous.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you call &amp;lt;vp&amp;gt;raiseAnException&amp;lt;/vp&amp;gt; the compiler will create a program point and call &amp;lt;vp&amp;gt;raiseAnException_explicit&amp;lt;/vp&amp;gt; instead.&lt;br /&gt;
 &lt;br /&gt;
{{example|&lt;br /&gt;
 &amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    test() :-&lt;br /&gt;
        raiseAnException(17).&amp;lt;/vip&amp;gt;&lt;br /&gt;
will actually correspond to:&lt;br /&gt;
 &amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    test() :-&lt;br /&gt;
        raiseAnException_explicit(programPoint(...), 17).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
where the program point corresponds to the point where &amp;lt;vp&amp;gt;raiseAnException&amp;lt;/vp&amp;gt; is called in the &amp;lt;vp&amp;gt;test&amp;lt;/vp&amp;gt; predicate.}}&lt;br /&gt;
&lt;br /&gt;
If you have a programPoint you can directly call the explicit predicate with it.&lt;br /&gt;
&lt;br /&gt;
{{example|&lt;br /&gt;
 &amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    raiseAnExceptio17_explicit(ProgramPoint) :-&lt;br /&gt;
        raiseAnException_explicit(ProgramPoint, 17).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Typically, as in this example, explicit predicates will call other explicit predicates with the programPoint they receive in order to use an &amp;quot;original&amp;quot; call point in a nested explicit predicate.}}&lt;br /&gt;
&lt;br /&gt;
Such code is treated in the usual way.  I.e. when calling &amp;lt;vp&amp;gt;raiseAnException&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;raiseAnException_explicit&amp;lt;/vp&amp;gt; will in both cases result in calling &amp;lt;vp&amp;gt;raiseAnException_explicit&amp;lt;/vp&amp;gt;, so this is the only predicate that needs an implementation.  In fact, it is illegal to state clauses for the non-explicit predicate that will never be called.&lt;br /&gt;
&lt;br /&gt;
There is also a built-in predicate, [[Language Reference/Built-in entities#programPoint|&amp;lt;vp&amp;gt;programPoint/0-&amp;gt;&amp;lt;/vp&amp;gt;]], which returns a &amp;lt;vp&amp;gt;programPoint&amp;lt;/vp&amp;gt; corresponding to the place where it is called.&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* A predicate declaration with &amp;lt;vp&amp;gt;programPoint&amp;lt;/vp&amp;gt; attribute actually declares two predicates.  A non-explicit and an explicit predicate.&lt;br /&gt;
* Calling the non-explicit predicate actually results in calling the explicit predicate with the call point as additional argument.&lt;br /&gt;
* Only the explicit predicate should be implemented.&lt;br /&gt;
&lt;br /&gt;
==== presenter ====&lt;br /&gt;
&lt;br /&gt;
Used to specify the presenter of a domain.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    someDomain = ... [presenter(presenter_someDomain)].&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Also used without argument to specify that an interface has a presenter.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;interface something [presenter]&lt;br /&gt;
...&lt;br /&gt;
end interface something&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
See [[Presenters]].&lt;br /&gt;
&lt;br /&gt;
==== queryable ====&lt;br /&gt;
&lt;br /&gt;
Makes an entity &amp;#039;queryable&amp;#039;, so that it is available for reflextion using the class &amp;lt;vp&amp;gt;predicateExtractor&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== retired ====&lt;br /&gt;
&lt;br /&gt;
The declared entity is retired. The string literal describes how to migrate from it.  The entity does not exist anymore.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    veryOldFashioned : (string Arg) [retired(&amp;quot;Use newFashion instead&amp;quot;)].&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== retiredFunctor ====&lt;br /&gt;
&lt;br /&gt;
Functor alternatives can be retired.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    ppp =&lt;br /&gt;
        fct(integer A, real B, ddd C) [retiredFunctor(aaa::fct_ppp)];&lt;br /&gt;
        fct2(integer A, ddd C, integer* New).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;aaa::fct_ppp&amp;lt;/vp&amp;gt; must be a predicate with this type (it can be an anonymous predicate):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    fct_ppp : (integer A, real B, ddd C) -&amp;gt; ppp NewValue.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I.e. it takes the arguments of the old functor and returns a value in the functor domain.&lt;br /&gt;
&lt;br /&gt;
In the program fct is does not exist at all, it is retired.  But in the deserialization fct terms can still be handled:  The arguments are parsed according to the types, and then the value is created by invoking &amp;lt;vp&amp;gt;aaa::fct_ppp&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This method will also work for binary serializations, provided:&lt;br /&gt;
&lt;br /&gt;
* The old domain had more than one alternative (so there are functor numbers in the serialization)&lt;br /&gt;
* New alternatives are added last (to retain functor numbers) &lt;br /&gt;
&lt;br /&gt;
It is however not recommend using binary serialization for inter-session persistence.&lt;br /&gt;
&lt;br /&gt;
See also [[Functor Domain Versioning]].&lt;br /&gt;
&lt;br /&gt;
==== sealed ====&lt;br /&gt;
&lt;br /&gt;
Used for an interface to indicate that it cannot be supported by any other interface. This allows to create more efficient codes, because the compiler provides some optimization when using the objects of such type. Valid for an object creating class declaration as a construction interface.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;interface myInterface&lt;br /&gt;
    [sealed]&lt;br /&gt;
...&lt;br /&gt;
end interface myInterface&lt;br /&gt;
&lt;br /&gt;
class myClass : myInterface&lt;br /&gt;
...&lt;br /&gt;
end class myClass&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== this ====&lt;br /&gt;
&lt;br /&gt;
Used for declaring {{lang2|Predicates|Extension Predicates|extension predicates}}.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
    extension : (unsigned V [this]).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== union ====&lt;br /&gt;
&lt;br /&gt;
Used for creating functor domains with several alternatives but no real functors.  This should only be used to mimic C/C++ union structs in low-level interfacing.  Valid for functor domain with several alternatives and alignment.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    u64var = align 4&lt;br /&gt;
        u64(unsigned64 Value64);&lt;br /&gt;
        u64_struct(unsigned Low32, unsigned High32)&lt;br /&gt;
        [union].&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== used ====&lt;br /&gt;
&lt;br /&gt;
An unused local member can be marked &amp;lt;vp&amp;gt;used&amp;lt;/vp&amp;gt; to prevent the compiler to issue a warning and remove the corresponding code. Valid for members.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    seeminglyUnused : () [used].&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms&amp;diff=4987</id>
		<title>Language Reference/Terms</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms&amp;diff=4987"/>
		<updated>2025-08-19T15:05:11Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Casing&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{languageReferenceNavbar|Terms}}&lt;br /&gt;
&lt;br /&gt;
This section describes terms and how execution/evaluation of terms and clauses proceeds.&lt;br /&gt;
&lt;br /&gt;
Semantically, there are two kinds of terms: &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;formulas&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;expressions&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
*Expressions represent values, like the number 7.&lt;br /&gt;
*Formulas represent logical statements, like &amp;quot;the number 7 is greater than the number 3&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Syntactically the two kinds have a huge overlap and therefore the syntax unites the two kinds into &amp;#039;&amp;#039;terms&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The following definition of &amp;lt;vpbnf&amp;gt;&amp;lt;Term&amp;gt;&amp;lt;/vpbnf&amp;gt; is simplified, in the sense that it includes syntactic constructions that are not legal. For example, one cannot legally write &amp;lt;vp&amp;gt;! + !&amp;lt;/vp&amp;gt;. We do however believe that using this simple syntax description in combination with intuitive understanding of language concepts, the type system, and the operator hierarchy described below is better for most purposes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;Term&amp;gt;:&lt;br /&gt;
    ( &amp;lt;Term&amp;gt; )&lt;br /&gt;
    &amp;lt;Literal&amp;gt;&lt;br /&gt;
    &amp;lt;Variable&amp;gt;&lt;br /&gt;
    &amp;lt;Identifier&amp;gt;&lt;br /&gt;
    &amp;lt;MemberAccess&amp;gt;&lt;br /&gt;
    &amp;lt;PredicateCall&amp;gt;&lt;br /&gt;
    &amp;lt;PredicateExpression&amp;gt;&lt;br /&gt;
    &amp;lt;UnaryOperator&amp;gt; &amp;lt;Term&amp;gt;&lt;br /&gt;
    &amp;lt;Term&amp;gt; &amp;lt;Operator&amp;gt; &amp;lt;Term&amp;gt;&lt;br /&gt;
    &amp;lt;Cut&amp;gt;&lt;br /&gt;
    &amp;lt;Ellipsis&amp;gt;&lt;br /&gt;
    &amp;lt;FactvariableAssignment&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Backtracking ===&lt;br /&gt;
&lt;br /&gt;
The evaluation of a Prolog program is a search for a &amp;quot;solution&amp;quot; to the goal. Each step in the search for a solution can either &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;succeed&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;fail&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;. At certain points in the program execution there are more than one possible choices for finding a solution. When such a choice point is met a so called &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;backtrack point&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; is created. A backtrack point is a recording of the program state plus a pointer to the choice that was not executed. If it turn out that the original choice could not provide the solution (i.e. if it &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;fails&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;), then the program will &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;backtrack&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; to the recorded backtrack point. Thereby restoring the program state and pursuing the other choice. The mechanism will be described and exemplified in details in the following sections.&lt;br /&gt;
&lt;br /&gt;
=== Literals ===&lt;br /&gt;
&lt;br /&gt;
Literals have {{lang2|Domains|Universal_Types|universal type}}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;Literal&amp;gt;:&lt;br /&gt;
   &amp;lt;IntegerLiteral&amp;gt;&lt;br /&gt;
   &amp;lt;RealLiteral&amp;gt;&lt;br /&gt;
   &amp;lt;CharacterLiteral&amp;gt;&lt;br /&gt;
   &amp;lt;StringLiteral&amp;gt;&lt;br /&gt;
   &amp;lt;BinaryLiteral&amp;gt;&lt;br /&gt;
   &amp;lt;ListLiteral&amp;gt;&lt;br /&gt;
   &amp;lt;CompoundDomainLiteral&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also {{lang2|Lexical Elements|Literals|Literals (in Lexical Elements)}}&lt;br /&gt;
&lt;br /&gt;
=== Variables ===&lt;br /&gt;
&lt;br /&gt;
Variables in Visual Prolog are immutable: once they are bound to a value they retain that value, but backtracking can unbind the variable again during the process of restoring a previous program state.&lt;br /&gt;
&lt;br /&gt;
A variable can thus be bound (during unification and matching), if it is already bound then it evaluates to the value that it is bound to.&lt;br /&gt;
&lt;br /&gt;
Variables are names starting with an upper-case letter or with an underscore (_), followed by a sequence of letters (both uppercase and lowercase), digits, and underscore characters (all in all called an UppercaseIdentifier):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;Variable&amp;gt;:&lt;br /&gt;
    &amp;lt;UppercaseIdentifer&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following are examples of valid variable names:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;My_first_correct_variable_name&lt;br /&gt;
_&lt;br /&gt;
_Sales_10_11_86&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
while the next two are invalid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;1stattempt&lt;br /&gt;
second_attempt&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The variable consisting of single underscore character (i.e. &amp;lt;vp&amp;gt;_&amp;lt;/vp&amp;gt;) is known as the &amp;#039;&amp;#039;anonymous variable&amp;#039;&amp;#039;. The anonymous variable is used in patterns and bindings where the corresponding value is of no interest and should be ignored.  Every occurrence of the anonymous variable is an independent anonymous variable, i.e. even though the anonymous variable is used several times in a single clause they have no relation to each other.&lt;br /&gt;
&lt;br /&gt;
If variables that starts with an underscore are not anonymous, but they are still intended for values of no interest that should be ignored.  The compiler will issue a warning if the value of such a warning is actually not ignored.&lt;br /&gt;
&lt;br /&gt;
Prolog variables are local to the clause in which it occurs. That is, if two clauses each contain a variable called &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt;, these &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt;-s are two distinct variables.&lt;br /&gt;
&lt;br /&gt;
A variable is said to be &amp;#039;&amp;#039;free&amp;#039;&amp;#039; when it is not yet associated with a term and to be &amp;#039;&amp;#039;bound&amp;#039;&amp;#039; or instantiated when it is unified with a term.&lt;br /&gt;
&lt;br /&gt;
The Visual Prolog compiler does not make a distinction between upper and lower case letters in names, except for the first letter. This means that the two variables &amp;lt;vp&amp;gt;SourceCode&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;SOURCECODE&amp;lt;/vp&amp;gt; are the same.&lt;br /&gt;
&lt;br /&gt;
=== Identifier ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;Identifier&amp;gt;: one of&lt;br /&gt;
    &amp;lt;MemberName&amp;gt;&lt;br /&gt;
    &amp;lt;GlobalScopeMembername&amp;gt;&lt;br /&gt;
    &amp;lt;ScopeQualifiedMemberName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;MemberName&amp;gt;:&lt;br /&gt;
    &amp;lt;LowerCaseIdentifier&amp;gt;&lt;br /&gt;
&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identifiers are used to refer to named entities (i.e. classes, interfaces, constants, domains, predicates, facts, ...).&lt;br /&gt;
&lt;br /&gt;
An identifier can just be a lower case identifier (i.e. a lowercase letter followed by a sequence of letters, numbers and underscore characters).&lt;br /&gt;
&lt;br /&gt;
Many entities can have the same name.  So it may be necessary or desirable to qualify the lowercase identifier the name of the particular scope of interest, or to state that the name is in the global namespace.&lt;br /&gt;
&lt;br /&gt;
{{Example| These are examples of unqualified identifiers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;integer&lt;br /&gt;
mainExe&lt;br /&gt;
myPredicate&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Global Entities Access ====&lt;br /&gt;
&lt;br /&gt;
The only global entities, which exist in Visual Prolog, are built-in domains, predicates, and constants. Global names are directly accessible in any scope. There might however exist situations where a global name is shadowed by a local or imported name. In that case the global entity can be qualified with a double colon &amp;#039;&amp;lt;vp&amp;gt;::&amp;lt;/vp&amp;gt;&amp;#039; (without a prefixed class/interface name). The double colon can be used everywhere, but the most important place is where an interface name is used as formal parameter type specifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;GlobalScopeMemberName&amp;gt;:&lt;br /&gt;
    :: &amp;lt;MemberName&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Example| The built-in domain &amp;lt;vp&amp;gt;integer&amp;lt;/vp&amp;gt; is defined in the global scope, to avoid ambiguity or stress that it is this particular domains you can use the global scope member name:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;::integer&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Class/Interface Member Access ====&lt;br /&gt;
&lt;br /&gt;
Static members of classes and interfaces are accessed by means of qualification with the class name (and optionally a namespace prefix):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;ScopeQualifiedMemberName&amp;gt;&lt;br /&gt;
    &amp;lt;NamespacePrefix&amp;gt;-opt &amp;lt;ScopeName&amp;gt; :: &amp;lt;MemberName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;NamespacePrefix&amp;gt;:&lt;br /&gt;
    &amp;lt;NamespaceIdentifier&amp;gt;-opt \&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ScopeName&amp;gt;:&lt;br /&gt;
    &amp;lt;LowercaseIdentifier&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ScopeName is the name of the class or interface that defines/declares the name.&lt;br /&gt;
&lt;br /&gt;
Namespace prefixing is explained in: {{lang2|Namespaces|Referencing names in namespaces|Referencing names in namespaces}}.&lt;br /&gt;
&lt;br /&gt;
Some names can be accessed without qualification, see {{lang2|Basic_Concepts|Scoping_&amp;amp;_Visibility|scoping &amp;amp; visibility}}.&lt;br /&gt;
&lt;br /&gt;
=== Predicate Call ===&lt;br /&gt;
&lt;br /&gt;
A predicate call have the form&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;PredicateCall&amp;gt;:&lt;br /&gt;
     &amp;lt;Term&amp;gt; ( &amp;lt;Term&amp;gt;-comma-sep-list-opt )&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first term must be an expression that evaluates to a value with predicate type.  Typically, it is either the name of a predicate in a class, or an expression that evaluates to a predicate member of an object.&lt;br /&gt;
&lt;br /&gt;
Notice that some predicates return values, whereas other predicates do not. A predicate that returns a value is an expression, and the predicate call is often referred to as a &amp;#039;&amp;#039;&amp;#039;function&amp;#039;&amp;#039;&amp;#039; call.  A predicate that does return a value is a formula.&lt;br /&gt;
&lt;br /&gt;
A predicate is invoked by applying arguments to the predicate. The predicate must have a flow-pattern that matches the free/bound state of the arguments.&lt;br /&gt;
&lt;br /&gt;
Most predicates are defined by a set of clauses, but some predicates are built into the language and some are defined externally in a DLL (perhaps in a foreign programming language).&lt;br /&gt;
&lt;br /&gt;
When a predicate is invoked by a predicate call, each clause is executed in turn until one of them &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;succeeds&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;, or there are no more clauses left to execute. If no clause succeeds the predicate &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;fails&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
If a clause succeeds and there are more relevant clauses left, a &amp;#039;&amp;#039;&amp;#039;backtrackpoint&amp;#039;&amp;#039;&amp;#039; is created to the next relevant clause.&lt;br /&gt;
&lt;br /&gt;
Thus, a predicate can &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;fail&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;succeed&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;, and even &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;succeed&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; multiple times.&lt;br /&gt;
&lt;br /&gt;
Each clause has a head and optionally a body.&lt;br /&gt;
&lt;br /&gt;
When a predicate is called the clauses are tried in turn (from top to bottom). For each clause the arguments in the head is unified with the arguments from the call. If this unification succeeds then the body of the clause (if present) is executed. The clause &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;succeeds,&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; if the match of the head &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;succeeds&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; and the body &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;succeeds&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;. Otherwise it &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;fails&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
   ppp() :- qqq(X), write(X), fail.&lt;br /&gt;
&lt;br /&gt;
   qqq(1).&lt;br /&gt;
   qqq(2).&lt;br /&gt;
   qqq(3).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt; is called it in turn calls &amp;lt;vp&amp;gt;qqq&amp;lt;/vp&amp;gt;. When &amp;lt;vp&amp;gt;qqq&amp;lt;/vp&amp;gt; is called, it first creates a backtrack point pointing to the second clause. Then the first clause is executed. Hereby the free variable &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; from &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt; is matched against the number &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt;, whereby &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; is bound to &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt; &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; (i.e. &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt;) is written and then &amp;lt;vp&amp;gt;fail&amp;lt;/vp&amp;gt; cause backtracking to the backtrackpoint. Hereby program control is set to the second clause in &amp;lt;vp&amp;gt;qqq&amp;lt;/vp&amp;gt; and the program state is set back to the state it was in when &amp;lt;vp&amp;gt;qqq&amp;lt;/vp&amp;gt; was first entered, i.e. &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; in &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt; is unbound again.&lt;br /&gt;
&lt;br /&gt;
Before the actual execution of the second clause in &amp;lt;vp&amp;gt;qqq&amp;lt;/vp&amp;gt; begins a backtrack point to the third clause is created.  The execution then proceeds as it did for &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Unification ===&lt;br /&gt;
&lt;br /&gt;
When a predicate is called the arguments from the call is &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;unified&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; with the terms in the head of each clause.&lt;br /&gt;
&lt;br /&gt;
Unification is the process of binding variables in such a way that two terms become equal, making as few bindings as possible (i.e. leaving as much as possible open for further binding).&lt;br /&gt;
&lt;br /&gt;
Variables can be bound to any kind of terms, including variables or terms containing variables.&lt;br /&gt;
&lt;br /&gt;
Unification is either possible or impossible, i.e. it can &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;succeed&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;fail&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Variables and terms to which they are unified have types, a variable can only be bound to a term of the same type as the variable, or a subtype. When two variables are bound to each other they must therefore have exactly the same type.&lt;br /&gt;
&lt;br /&gt;
Unification takes place (as mentioned) between a predicate call and the clause head. It also takes place when two terms are compared for equality.&lt;br /&gt;
&lt;br /&gt;
{{Example| Consider two terms (of the same type):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;T1 = f1(g(), X, 17, Y, 17)&lt;br /&gt;
T2 = f1(Z, Z, V, U, 43)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We will attempt to unify these two terms from left to right (i.e. a left-to-right pre-traversal).&lt;br /&gt;
&lt;br /&gt;
Both &amp;lt;vp&amp;gt;T1&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;T2&amp;lt;/vp&amp;gt; are &amp;lt;vp&amp;gt;f1/5&amp;lt;/vp&amp;gt; terms, this match. Therefore we attempt to unify each of the arguments from &amp;lt;vp&amp;gt;T1&amp;lt;/vp&amp;gt; with each correspondent argument of &amp;lt;vp&amp;gt;T2&amp;lt;/vp&amp;gt;. First we must unify &amp;lt;vp&amp;gt;Z&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;g()&amp;lt;/vp&amp;gt;, this can be unified if we bind &amp;lt;vp&amp;gt;Z&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;g()&amp;lt;/vp&amp;gt;. So far everything is fine and we have the first binding in our unifier:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;Z = g()&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next two arguments are &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;Z&amp;lt;/vp&amp;gt;, which already has been bound to &amp;lt;vp&amp;gt;g()&amp;lt;/vp&amp;gt;. These two arguments can also be unified if we also bind &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;g()&amp;lt;/vp&amp;gt;. So we now have the following contributions to our unifier:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;X = Z = g()&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we must bind &amp;lt;vp&amp;gt;V&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;17&amp;lt;/vp&amp;gt; and then we must bind &amp;lt;vp&amp;gt;Y&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;U&amp;lt;/vp&amp;gt;. So far everything unifies with the following unifier:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;X = Z = g()&lt;br /&gt;
V = 17&lt;br /&gt;
Y = U&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The two unified terms are now equivalent to these terms:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;T1 = f1(g(), g(), 17, Y, 17)&lt;br /&gt;
T2 = f1(g(), g(), 17, Y, 43)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But we have not yet unified the two last arguments, which are &amp;lt;vp&amp;gt;17&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;43&amp;lt;/vp&amp;gt;. No variable binding can make these terms equal, so all in all the unification &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;fails&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;T1&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;T2&amp;lt;/vp&amp;gt; cannot be unified.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
In the example above &amp;lt;vp&amp;gt;T1&amp;lt;/vp&amp;gt; could have been a predicate call and &amp;lt;vp&amp;gt;T2&amp;lt;/vp&amp;gt; a clause head. But they could also have been two terms that were compared with equal &amp;quot;&amp;lt;vp&amp;gt;=&amp;lt;/vp&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Matching ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Matching&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; is the same as unification except that variables can only be bound to grounded terms. A &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;grounded&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; term is a term that does not contain any unbound variables.&lt;br /&gt;
&lt;br /&gt;
It is the flow-patterns that are stated for predicates, that make it possible to use matching rather than full-blown unification.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
   ppp(Z, Z, 17).&lt;br /&gt;
   qqq() :-&lt;br /&gt;
      ppp(g(), X, 17).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unification of the &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt;-call with the &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt;-clause is possible with the following unifier:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;Z = X = g()&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt; have the flow &amp;lt;vp&amp;gt;(i,o,i)&amp;lt;/vp&amp;gt; then the unification is just a match:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;vp&amp;gt;g()&amp;lt;/vp&amp;gt; is input as the first argument, this is bound to &amp;lt;vp&amp;gt;Z&amp;lt;/vp&amp;gt;&lt;br /&gt;
*The second argument in the clause is therefore bound and can thus be output to &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt;, which therefore becomes bound to &amp;#039;&amp;#039;&amp;lt;vp&amp;gt;g()&amp;lt;/vp&amp;gt;&amp;#039;&amp;#039;.&lt;br /&gt;
*finally the third argument is &amp;lt;vp&amp;gt;17&amp;lt;/vp&amp;gt; used as input this number is simply compared to the third argument in the clause.&lt;br /&gt;
&lt;br /&gt;
It is the flow-pattern that makes it possible to predict that the clause does not need real unification.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Nested Function Calls ===&lt;br /&gt;
&lt;br /&gt;
Terms that have to be unified or matched with each other are allowed to contain sub-terms that are actually expressions or function calls that have to be evaluated before the unification/matching can be completed.&lt;br /&gt;
&lt;br /&gt;
The evaluation of such sub-terms is done on a by-need basis.&lt;br /&gt;
&lt;br /&gt;
In a predicate call all input arguments are evaluated before the predicate is called, all output arguments are variables, which does not need evaluation.&lt;br /&gt;
&lt;br /&gt;
Clause heads can also contain terms that have to be evaluated, before matching/unification can be determined.&lt;br /&gt;
&lt;br /&gt;
*all matching/unification that does not require any evaluation is performed before any evaluation is performed;&lt;br /&gt;
*then evaluation corresponding to input arguments is performed one by one left-to-right. Comparing each value to the corresponding input after each evaluation;&lt;br /&gt;
*then the clause body is evaluated;&lt;br /&gt;
*then the output arguments are evaluated (left-to-right);&lt;br /&gt;
*then the return value (if the predicate is a function) is evaluated.&lt;br /&gt;
&lt;br /&gt;
If any of these &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;fail&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; then the rest of the evaluation is not carried out.&lt;br /&gt;
&lt;br /&gt;
All in all the base principles are:&lt;br /&gt;
&lt;br /&gt;
*input after other match, before body evaluation&lt;br /&gt;
*output after body evaluation&lt;br /&gt;
*left-to-right&lt;br /&gt;
&lt;br /&gt;
=== Arguments ===&lt;br /&gt;
{{:Language Reference/Terms/Arguments}}&lt;br /&gt;
=== Fact Variable Assignment ===&lt;br /&gt;
&lt;br /&gt;
Assign operator &amp;lt;vp&amp;gt;:=&amp;lt;/vp&amp;gt; is used to assign a new value for a {{lang2|Facts|Fact_Variable_Declarations|fact variable}} &amp;lt;vpbnf&amp;gt;&amp;lt;FactVariable&amp;gt;&amp;lt;/vpbnf&amp;gt;. The &amp;lt;vpbnf&amp;gt;&amp;lt;Term&amp;gt;&amp;lt;/vpbnf&amp;gt; must be evaluated to a value of suitable type (i.e. the same type as the fact variable, or a subtype).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;FactVariableAssignment&amp;gt;:&lt;br /&gt;
    &amp;lt;FactVariable&amp;gt; := &amp;lt;Term&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Facts ===&lt;br /&gt;
&lt;br /&gt;
A fact database contains a number of fully instantiated (grounded) predicate heads corresponding to the facts from the facts section declaration. The facts can be accessed by a predicate call, using the fact name as the predicate name. The predicate call is matched against each fact in turn; succeeding with a possible backtrack point to the next fact each time the predicate call match the fact. When there are no more facts in the fact database then the predicate call fails.&lt;br /&gt;
&lt;br /&gt;
New facts can be &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;asserted&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; using the predicates {{lang2|Built-in_entities|assert|assert/1}}, {{lang2|Built-in_entities|asserta|asserta/1}}, and {{lang2|Built-in_entities|assertz|assertz/1}}. {{lang2|Built-in_entities|assert|assert/1}} is the same as {{lang2|Built-in_entities|assertz|assertz/1}} and it asserts a new fact to the end of the list of facts, whereas {{lang2|Built-in_entities|asserta|asserta/1}} asserts a new fact to the start of the list.&lt;br /&gt;
&lt;br /&gt;
Existing facts can be &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;retracted&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; with the predicate {{lang2|Built-in_entities|retract|retract/1}} and {{lang2|Built-in_entities|retractall|retractAll/1}}. {{lang2|Built-in_entities|retract|retract/1}} retracts the first fact that match the argument binding variables in the argument and leaving a backtrack point so that more facts will potentially be retracted when backtracking.&lt;br /&gt;
&lt;br /&gt;
{{lang2|Built-in_entities|retractall|retractAll/1}} retracts all facts that matches the arguments and succeeds without any binding.&lt;br /&gt;
&lt;br /&gt;
=== Operators ===&lt;br /&gt;
&lt;br /&gt;
Operators are organized in a precedence hierarchy. In the rule below operators in each group have same precedence, which is higher than those below. I.e. the power operator has higher precedence than unary minus and plus, which in turn has higher precedence than the multiplication operators, etc. Parenthesis can be used to circumvent the precedence (and for clarification).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;Operator&amp;gt;: one of&lt;br /&gt;
    &amp;lt;PowerOperator&amp;gt;&lt;br /&gt;
    &amp;lt;UnaryOperator&amp;gt;&lt;br /&gt;
    &amp;lt;MultiplicationOperator&amp;gt;&lt;br /&gt;
    &amp;lt;AdditionOperator&amp;gt;&lt;br /&gt;
    &amp;lt;OtherwiseOperator&amp;gt;&lt;br /&gt;
    &amp;lt;RelationOperator&amp;gt;&lt;br /&gt;
    &amp;lt;MustUnifyOperator&amp;gt;&lt;br /&gt;
    &amp;lt;InOperator&amp;gt;&lt;br /&gt;
    &amp;lt;AndOperator&amp;gt;&lt;br /&gt;
    &amp;lt;OrOperator&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;UnaryOperator&amp;gt;: one of&lt;br /&gt;
    - +&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All operators except the &amp;lt;vpbnf&amp;gt;&amp;lt;UnaryOperator&amp;gt;&amp;lt;/vpbnf&amp;gt;&amp;#039;s are binary.  The power operator is right associative, all other operators are left associative.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vpbnf&amp;gt;&amp;lt;RelationOperator&amp;gt;&amp;lt;/vpbnf&amp;gt;, &amp;lt;vpbnf&amp;gt;&amp;lt;MustUnifyOperator&amp;gt;&amp;lt;/vpbnf&amp;gt; and &amp;lt;vpbnf&amp;gt;&amp;lt;InOperator&amp;gt;&amp;lt;/vpbnf&amp;gt; have same precedence.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Notice&amp;#039;&amp;#039;&amp;#039; that the placement &amp;lt;vpbnf&amp;gt;&amp;lt;UnaryOperator&amp;gt;&amp;lt;/vpbnf&amp;gt; is not consistent with mathematics, where these operators are at the same level as the &amp;lt;vpbnf&amp;gt;&amp;lt;AdditionalOperator&amp;gt;&amp;lt;/vpbnf&amp;gt;&amp;#039;s.  The difference has no influence of the calculated value, but it allows writing &amp;lt;vp&amp;gt;2*-2&amp;lt;/vp&amp;gt;, where mathematics would require a parenthesis around the second operator &amp;lt;vp&amp;gt;2*(-2)&amp;lt;/vp&amp;gt;.  It also means that &amp;lt;vp&amp;gt;-2*2&amp;lt;/vp&amp;gt; is mmeans (-2)*2 where it would be &amp;lt;vp&amp;gt;-(2*2)&amp;lt;/vp&amp;gt; in mathematics (the resulting value is the same).&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vp&amp;gt;-2^2&amp;lt;/vp&amp;gt; is the same as &amp;lt;vp&amp;gt;-(2^2)&amp;lt;/vp&amp;gt; because ^ has higher precedence than unary minus.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vp&amp;gt;3^2^2&amp;lt;/vp&amp;gt; is the same as &amp;lt;vp&amp;gt;3^(2^2)&amp;lt;/vp&amp;gt; because ^ is right associative.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vp&amp;gt;-2*-3^-4+5&amp;lt;/vp&amp;gt; is the same as &amp;lt;vp&amp;gt;((-2) * (-(3 ^ (-4)))) + 5&amp;lt;/vp&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Example| The following term:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;7 + 3 * 5 * 13 + 4 + 3 = X / 6 ; A &amp;lt; 7,  p(X)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
has the same meaning as this term:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;((((7 + ((3 * 5) * 13)) + 4) + 3) = (X / 6)) ; ((A &amp;lt; 7) , p(X))&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I.e. at outermost level the term is an &amp;quot;&amp;lt;vp&amp;gt;or&amp;lt;/vp&amp;gt;&amp;quot; of two terms, the first of these is a relational (&amp;lt;vp&amp;gt;=&amp;lt;/vp&amp;gt;) term, the second is an &amp;quot;&amp;lt;vp&amp;gt;and&amp;lt;/vp&amp;gt;&amp;quot; term, etc.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Arithmetic Operators ===&lt;br /&gt;
&lt;br /&gt;
The arithmetic operators are used for arithmetic operations on numbers. They are expressions, which takes expressions as arguments. They have root types as arguments and return universal types as result. (See {{lang2|Domains|Universal_and_Root_Types|Universal and Root types}}.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;PowerOperator&amp;gt;:&lt;br /&gt;
    ^&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;MultiplicationOperator&amp;gt;: one of&lt;br /&gt;
    * / div mod quot rem&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;AdditionOperator&amp;gt;: one of&lt;br /&gt;
    +  -&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relational Operators ===&lt;br /&gt;
&lt;br /&gt;
The relational operators are formulas, which takes expressions as arguments. Given this nature they are non-associative.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;RelationOperator&amp;gt;: one of&lt;br /&gt;
  =   &amp;gt;   &amp;lt;   &amp;gt;=   &amp;lt;=   &amp;lt;&amp;gt;   &amp;gt;&amp;lt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First the left term is evaluated, then the right term is evaluated and then the results are compared.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Notice&amp;#039;&amp;#039;&amp;#039; that &amp;lt;vp&amp;gt;&amp;lt;&amp;gt;&amp;lt;/vp&amp;gt; (different) is not the dual operation of = (equal). &amp;lt;vp&amp;gt;&amp;lt;&amp;gt;&amp;lt;/vp&amp;gt; compares two values, whereas &amp;lt;vp&amp;gt;=&amp;lt;/vp&amp;gt; tries to unify two terms (in the general case at least).&lt;br /&gt;
&lt;br /&gt;
The dual to expression &amp;lt;vp&amp;gt;A = B&amp;lt;/vp&amp;gt; is &amp;lt;vp&amp;gt;not (A = B)&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Must Unify Operator ====&lt;br /&gt;
&lt;br /&gt;
The must unify operator is a procedure, which takes expressions as arguments. It is non-associative.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;MustUnifyOperator&amp;gt;:&lt;br /&gt;
  ==&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vpbnf&amp;gt;A == B&amp;lt;/vpbnf&amp;gt; unifies &amp;lt;vpbnf&amp;gt;A&amp;lt;/vpbnf&amp;gt; and &amp;lt;vpbnf&amp;gt;B&amp;lt;/vpbnf&amp;gt;; if the unification fails an exception is raised, otherwise the predicate succeeds.  Therefore &amp;lt;vpbnf&amp;gt;A == B&amp;lt;/vpbnf&amp;gt; always succeeds.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    p(L) :-&lt;br /&gt;
        [H|T] == L,&lt;br /&gt;
        ...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;vp&amp;gt;p&amp;lt;/vp&amp;gt; is a procedure. An exception will be raised if it is called with an empty list, because &amp;lt;vp&amp;gt;[H|T]&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;L&amp;lt;/vp&amp;gt; cannot unify.}}&lt;br /&gt;
&lt;br /&gt;
=== Bitwise and boolean operators ===&lt;br /&gt;
&lt;br /&gt;
The following operators for bitwise operations on &amp;lt;vp&amp;gt;unsigned&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;unsigned64&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;unsignedNative&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
A ** B % A and B&lt;br /&gt;
A ++ B % A or B&lt;br /&gt;
A -- B % A and not B&lt;br /&gt;
A ^^ B % A exclusive or B&lt;br /&gt;
~~ A % not A&lt;br /&gt;
A &amp;lt;&amp;lt; N % Shifts the bits in A N times to the left.&lt;br /&gt;
A &amp;gt;&amp;gt; N % Shifts the bits in A N times to the right.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The logical operations (&amp;lt;vp&amp;gt;**&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;++&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;^^&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;~~&amp;lt;/vp&amp;gt;) can also be used on &amp;lt;vp&amp;gt;boolean&amp;lt;/vp&amp;gt; values.&lt;br /&gt;
&lt;br /&gt;
The shift operations discard bits that is shifted out of the number, and shift-in zero bits in the opposite end.&lt;br /&gt;
&lt;br /&gt;
=== Logical Operators ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vpbnf&amp;gt;&amp;lt;AndOperator&amp;gt;&amp;lt;/vpbnf&amp;gt;(s) and &amp;lt;vpbnf&amp;gt;&amp;lt;OrOperator&amp;gt;&amp;lt;/vpbnf&amp;gt;(s) are formulas, which takes formulas as arguments. They are all left associative. The &amp;lt;vp&amp;gt;,&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;and &amp;lt;/vp&amp;gt; are synonyms and so are &amp;lt;vp&amp;gt;; &amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;or&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;AndOperator&amp;gt;: one of&lt;br /&gt;
 ,   and&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;OrOperator&amp;gt;: one of&lt;br /&gt;
  ;  or orelse&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== and (,) ====&lt;br /&gt;
&lt;br /&gt;
The evaluation of an &amp;lt;vp&amp;gt;and&amp;lt;/vp&amp;gt; term &amp;lt;vp&amp;gt;A, B&amp;lt;/vp&amp;gt; proceeds as follows. First the left sub-term &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; is evaluated. If this evaluation fails, the whole &amp;lt;vp&amp;gt;and&amp;lt;/vp&amp;gt; term fails. If &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; succeeds then the right sub-term &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; is evaluated. If this evaluation fails, the whole &amp;lt;vp&amp;gt;and&amp;lt;/vp&amp;gt; term fails, otherwise the &amp;lt;vp&amp;gt;and&amp;lt;/vp&amp;gt; term succeeds.&lt;br /&gt;
&lt;br /&gt;
Thus the second sub-term &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; is only evaluated, if the first sub-term &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; succeeds.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
   ppp() :-&lt;br /&gt;
       qqq(), rrr().&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt; is called it will first call &amp;lt;vp&amp;gt;qqq&amp;lt;/vp&amp;gt; and if &amp;lt;vp&amp;gt;qqq&amp;lt;/vp&amp;gt; succeeds, then it will call &amp;lt;vp&amp;gt;rrr&amp;lt;/vp&amp;gt;. If &amp;lt;vp&amp;gt;rrr&amp;lt;/vp&amp;gt; succeeds, then the &amp;lt;vp&amp;gt;and&amp;lt;/vp&amp;gt; term and subsequently the whole clause succeeds.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== or (;) ====&lt;br /&gt;
&lt;br /&gt;
The evaluation of an &amp;lt;vp&amp;gt;or&amp;lt;/vp&amp;gt; term &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt;; &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; proceeds as follows. First a backtrack point to the second term &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; is created and then the first term &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; is evaluated. If the evaluation of the first term succeeds, then the whole &amp;lt;vp&amp;gt;or&amp;lt;/vp&amp;gt; term succeeds and is left with a backtrack to the second term &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt;. If the evaluation of the first term fails, the backtrack point to the second term is activated.&lt;br /&gt;
&lt;br /&gt;
If the backtrack point to the second term &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; is activated (either because the first term fails, or because something later in the execution invokes the backtrack point), then the second term &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; is evaluated and the whole &amp;lt;vp&amp;gt;or&amp;lt;/vp&amp;gt; term will succeed if &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; succeeds.&lt;br /&gt;
&lt;br /&gt;
Thus an &amp;lt;vp&amp;gt;or&amp;lt;/vp&amp;gt; term can succeed with a backtrack point and the second sub-term &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; is only evaluated on backtrack.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
   ppp() :-&lt;br /&gt;
       (V = 3 or V = 7), write(V), fail.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we have used the keyword &amp;lt;vp&amp;gt;or&amp;lt;/vp&amp;gt;, but you can also use semi-colon &amp;lt;vp&amp;gt;;&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt; is called we first create a backtrack point to the term &amp;lt;vp&amp;gt;V = 7&amp;lt;/vp&amp;gt; and then we evaluate &amp;lt;vp&amp;gt;V = 3&amp;lt;/vp&amp;gt;. Thereby &amp;lt;vp&amp;gt;V&amp;lt;/vp&amp;gt; will be bound to &amp;lt;vp&amp;gt;3&amp;lt;/vp&amp;gt; we then continue to the &amp;lt;vp&amp;gt;write(V)&amp;lt;/vp&amp;gt; after &amp;lt;vp&amp;gt;3&amp;lt;/vp&amp;gt; has been written &amp;lt;vp&amp;gt;fail&amp;lt;/vp&amp;gt; is met. &amp;lt;vp&amp;gt;fail&amp;lt;/vp&amp;gt; always fails so we effectuate the backtrack point leading us to the term &amp;lt;vp&amp;gt;V = 7&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Backtracking also undo all bindings made since the backtrack point was created. In this case it means that &amp;lt;vp&amp;gt;V&amp;lt;/vp&amp;gt; is unbound.&lt;br /&gt;
&lt;br /&gt;
Then &amp;lt;vp&amp;gt;V = 7&amp;lt;/vp&amp;gt; is evaluated and &amp;lt;vp&amp;gt;V&amp;lt;/vp&amp;gt; becomes bound to &amp;lt;vp&amp;gt;7&amp;lt;/vp&amp;gt; and er continue to the term &amp;lt;vp&amp;gt;write(V)&amp;lt;/vp&amp;gt;, and then &amp;lt;vp&amp;gt;fail&amp;lt;/vp&amp;gt; is met again, this time there are no more backtrack points &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt; fails.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Using parentheses &amp;lt;vp&amp;gt;or&amp;lt;/vp&amp;gt; can be nested deeply in clauses.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
   p(X) = Y :-&lt;br /&gt;
       (X = 1, !, Z = 3 or Z = 7), Y = 2*Z.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We recommend careful usage of &amp;lt;vp&amp;gt;or&amp;lt;/vp&amp;gt;. It is mainly intended for usage in test-conditions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
   isOutside(X) :-&lt;br /&gt;
       (X &amp;lt; 10 or X &amp;gt; 90), !.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;or&amp;lt;/vp&amp;gt; is a nondeterministic construction, but &amp;lt;vp&amp;gt;orelse&amp;lt;/vp&amp;gt; can be used as a deterministic pendant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
   isOutside(X) :-&lt;br /&gt;
       X &amp;lt; 10 orelse X &amp;gt; 90.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== orelse ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;orelse&amp;lt;/vp&amp;gt; is a deterministic pendant to the nondeterministic &amp;lt;vp&amp;gt;or&amp;lt;/vp&amp;gt;.  &amp;lt;vp&amp;gt;A orelse B&amp;lt;/vp&amp;gt; will succeed if &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; succeeds or if &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; succeeds, but it will &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; leave a backtrack point to &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; if &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; succeeds.&lt;br /&gt;
&lt;br /&gt;
The evaluation of an &amp;lt;vp&amp;gt;orelse&amp;lt;/vp&amp;gt; term &amp;lt;vp&amp;gt;A orelse B&amp;lt;/vp&amp;gt; proceeds as follows: First a backtrack point to the second term &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; is created and then the first term &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; is evaluated. If the evaluation of the first term succeeds then the backtrack to the second term (and any backtrack point within it) &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; are removed again and the whole &amp;lt;vp&amp;gt;orelse&amp;lt;/vp&amp;gt; term succeeds. If the evaluation of the first term &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; fails, the backtrack point to the second term &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; is evaluated.&lt;br /&gt;
&lt;br /&gt;
So an &amp;lt;vp&amp;gt;orelse&amp;lt;/vp&amp;gt; term does not leave a backtrack point.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
   ppp(V) :-&lt;br /&gt;
       (V = 3 orelse V = 7), write(V).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whenever &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt; is called we first create a backtrack point to the term &amp;lt;vp&amp;gt;V = 7&amp;lt;/vp&amp;gt; and then we evaluate the term &amp;lt;vp&amp;gt;V = 3&amp;lt;/vp&amp;gt;, if &amp;lt;vp&amp;gt;V = 3&amp;lt;/vp&amp;gt; succeeds we remove the backtrack point to &amp;lt;vp&amp;gt;V = 7&amp;lt;/vp&amp;gt; again and then continue to &amp;lt;vp&amp;gt;write(V)&amp;lt;/vp&amp;gt;.  If &amp;lt;vp&amp;gt;V = 3&amp;lt;/vp&amp;gt; fails the backtrack point to &amp;lt;vp&amp;gt;V = 7&amp;lt;/vp&amp;gt; is effectuated.  If &amp;lt;vp&amp;gt;V = 7&amp;lt;/vp&amp;gt; succeeds we continue to &amp;lt;vp&amp;gt;write(V)&amp;lt;/vp&amp;gt;, if &amp;lt;vp&amp;gt;V = 7&amp;lt;/vp&amp;gt; fails the entire &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt; predicate will fail.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== otherwise ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;otherwise&amp;lt;/vp&amp;gt; is an expression operator; though it has control flow that makes it resemble the logical operators. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;A otherwise B&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is an expression (&amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; must be expressions).  If the evaluation of &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; succeeds by evaluating to the value VA then &amp;lt;vp&amp;gt;A otherwise B&amp;lt;/vp&amp;gt; evaluates to VA, otherwise (i.e. if the evaluation of &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; fails) then &amp;lt;vp&amp;gt;A otherwise B&amp;lt;/vp&amp;gt; will be the result of evaluating &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;otherwise&amp;lt;/vp&amp;gt; is right associative:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;A otherwise B otherwise C&lt;br /&gt;
=&amp;gt;&lt;br /&gt;
A otherwise (B otherwise C)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has lower precedence than all other expression operators, but higher than relational operators:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;V &amp;lt; A + tryGet() otherwise 9&lt;br /&gt;
=&amp;gt;&lt;br /&gt;
V &amp;lt; ((A + tryGet()) otherwise 9)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;core&amp;lt;/vp&amp;gt; have been enriched with a predicate &amp;lt;vp&amp;gt;isSome&amp;lt;/vp&amp;gt; for providing default values for &amp;lt;vp&amp;gt;core::optional&amp;lt;/vp&amp;gt; matching:&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;V = isSome(Optional) otherwise 0&amp;lt;/vip&amp;gt;&lt;br /&gt;
If &amp;lt;vp&amp;gt;Optional&amp;lt;/vp&amp;gt; have the form &amp;lt;vp&amp;gt;some(X)&amp;lt;/vp&amp;gt; then &amp;lt;vp&amp;gt;V&amp;lt;/vp&amp;gt; will get the value &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; otherwise &amp;lt;vp&amp;gt;V&amp;lt;/vp&amp;gt; will get the value &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
==== not ====&lt;br /&gt;
&lt;br /&gt;
The {{lang2|Built-in_entities|not|not/1}} takes a term as the argument. The evaluation of &amp;lt;vp&amp;gt;not(A)&amp;lt;/vp&amp;gt; first evaluates &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt;. If &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; succeeds, then &amp;lt;vp&amp;gt;not(A)&amp;lt;/vp&amp;gt; fails, if &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; fails, then &amp;lt;vp&amp;gt;not(A)&amp;lt;/vp&amp;gt; succeeds.&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;lt;vp&amp;gt;not(A)&amp;lt;/vp&amp;gt; will never bind any variables, because if &amp;lt;vp&amp;gt;not(A)&amp;lt;/vp&amp;gt; succeeds then &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; has failed, and a failed term does not bind anything. If &amp;lt;vp&amp;gt;not(A)&amp;lt;/vp&amp;gt; on the other hand fails, it cannot bind any variables either, because then the term itself failed.&lt;br /&gt;
&lt;br /&gt;
Also notice that &amp;lt;vp&amp;gt;not(A)&amp;lt;/vp&amp;gt; can never succeed with backtrack points, because if &amp;lt;vp&amp;gt;not(A)&amp;lt;/vp&amp;gt; succeeds then &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; have failed, and a failed term cannot contain any backtrack points. This in turn means that all possibilities of success in &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; have been exhausted.&lt;br /&gt;
&lt;br /&gt;
==== cut (!) ====&lt;br /&gt;
&lt;br /&gt;
Cut &amp;quot;&amp;lt;vp&amp;gt;!&amp;lt;/vp&amp;gt;&amp;quot; removes all backtrack points created since the entrance to the current predicate, this means all backtrack points to subsequent clauses, plus backtrack points in predicate calls made in the current clause before the &amp;quot;&amp;lt;vp&amp;gt;!&amp;lt;/vp&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;Cut&amp;gt;:&lt;br /&gt;
    !&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
   ppp(X) :-&lt;br /&gt;
       X &amp;gt; 7,&lt;br /&gt;
       !,&lt;br /&gt;
       write(&amp;quot;Greater than seven&amp;quot;).&lt;br /&gt;
   ppp(_X) :-&lt;br /&gt;
       write(&amp;quot;Not greater than seven&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt; is executed, there is first created a backtrack point to the second clause, and then the first clause is executed. If the test &amp;quot;&amp;lt;vp&amp;gt;X &amp;gt; 7&amp;lt;/vp&amp;gt;&amp;quot; succeeds then the cut &amp;quot;&amp;lt;vp&amp;gt;!&amp;lt;/vp&amp;gt;&amp;quot; is reached. This cut &amp;quot;&amp;lt;vp&amp;gt;!&amp;lt;/vp&amp;gt;&amp;quot; will remove the backtrack point to the second clause.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
   ppp() :-&lt;br /&gt;
       qqq(X),&lt;br /&gt;
       X &amp;gt; 7,&lt;br /&gt;
       !,&lt;br /&gt;
       write(&amp;quot;Found one&amp;quot;).&lt;br /&gt;
   ppp() :-&lt;br /&gt;
       write(&amp;quot;Did not find one&amp;quot;).&lt;br /&gt;
clauses&lt;br /&gt;
   qqq(3).&lt;br /&gt;
   qqq(12).&lt;br /&gt;
   qqq(13).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt; is executed it first creates a backtrack point to the second &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt; clause and then &amp;lt;vp&amp;gt;qqq&amp;lt;/vp&amp;gt; is called. The &amp;lt;vp&amp;gt;qqq&amp;lt;/vp&amp;gt; will create a backtrack point to the second &amp;lt;vp&amp;gt;qqq&amp;lt;/vp&amp;gt; clause and execute the first clause, thereby returning the value &amp;lt;vp&amp;gt;3&amp;lt;/vp&amp;gt;. In &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt; variable &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; is bound to this value and then compared to &amp;lt;vp&amp;gt;7&amp;lt;/vp&amp;gt;. This test fails and, therefore, the control backtracks to the second clause of &amp;lt;vp&amp;gt;qqq&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Before executing the second clause a new backtrack point to the third clause of &amp;lt;vp&amp;gt;qqq&amp;lt;/vp&amp;gt; is created and then the second clause returns &amp;lt;vp&amp;gt;12&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This time the test against &amp;lt;vp&amp;gt;7&amp;lt;/vp&amp;gt; succeeds and, therefore, the cut is executed. This cut will remove both the backtrack point left in &amp;lt;vp&amp;gt;qqq&amp;lt;/vp&amp;gt; as well as the backtrack point to the second clause of &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== cut scopes =====&lt;br /&gt;
&lt;br /&gt;
A cut scope is a scope to which the effect of a &amp;lt;vp&amp;gt;cut&amp;lt;/vp&amp;gt; is limited. Meaning that if a &amp;lt;vp&amp;gt;cut&amp;lt;/vp&amp;gt; is met within a cut scope then only backtrack points within that scope are discarded, while backtrack points outside (i.e. prior to) the cut scope remains.&lt;br /&gt;
&lt;br /&gt;
The clauses of a predicate is a cut scope. Meeting a &amp;lt;vp&amp;gt;cut&amp;lt;/vp&amp;gt; will (at most) discard the backtrack points that was created after entrance to the predicate.  Backtrack points created before entrance to the predicate will remain.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
   aaa() :- p1_nd(), qqq().&lt;br /&gt;
   qqq() :- p2_nd(), !.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;aaa&amp;lt;/vp&amp;gt; calls &amp;lt;vp&amp;gt;p1_nd&amp;lt;/vp&amp;gt;, which leaves a backtrack point, and then it calls &amp;lt;vp&amp;gt;qqq&amp;lt;/vp&amp;gt;. &amp;lt;vp&amp;gt;qqq&amp;lt;/vp&amp;gt; calls &amp;lt;vp&amp;gt;p2_nd&amp;lt;/vp&amp;gt;, which also leaves a backtrack point. Then we meet a &amp;lt;vp&amp;gt;cut&amp;lt;/vp&amp;gt;. This &amp;lt;vp&amp;gt;cut&amp;lt;/vp&amp;gt; is in the &amp;lt;vp&amp;gt;cut&amp;lt;/vp&amp;gt;-scope of the &amp;lt;vp&amp;gt;qqq&amp;lt;/vp&amp;gt; predicate, so it is only the backtrack point in &amp;lt;vp&amp;gt;p2_nd&amp;lt;/vp&amp;gt; which is discarded, the one in &amp;lt;vp&amp;gt;p1_nd&amp;lt;/vp&amp;gt; remains.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Several terms introduce cut scopes (see the respective terms: {{lang2|Terms|List_Comprehension|list comprehension}}, {{lang2|Terms|if-then-else|if-then-else}}, {{lang2|Terms|foreach|foreach}}). Here we will use &amp;lt;vp&amp;gt;if-then-else&amp;lt;/vp&amp;gt; to illustrate the effect of cut scopes.  Consider the schematic &amp;lt;vp&amp;gt;if-then-else&amp;lt;/vp&amp;gt; term:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;if Cond then T1 else T2 end if&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The condition &amp;lt;vp&amp;gt;Cond&amp;lt;/vp&amp;gt; is a cut-scope, meaning that a &amp;lt;vp&amp;gt;cut&amp;lt;/vp&amp;gt; inside &amp;lt;vp&amp;gt;Cond&amp;lt;/vp&amp;gt; will only have effect inside &amp;lt;vp&amp;gt;Cond&amp;lt;/vp&amp;gt;. &amp;lt;vp&amp;gt;Cut&amp;lt;/vp&amp;gt;s inside &amp;lt;vp&amp;gt;T1&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;T2&amp;lt;/vp&amp;gt;, on the other hand, have effect outside the &amp;lt;vp&amp;gt;if-then-else&amp;lt;/vp&amp;gt; statement.&lt;br /&gt;
&lt;br /&gt;
Consider this code fragment:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;X = getMember_nd([3,1,2]),&lt;br /&gt;
if X = getMember_nd([3,3]), ! then&lt;br /&gt;
   write(X)&lt;br /&gt;
else&lt;br /&gt;
   !&lt;br /&gt;
end if,&lt;br /&gt;
fail&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;getMember_nd&amp;lt;/vp&amp;gt; is a nondeterministic predicate. The evaluation of this code will go as follows. First &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; is bound to &amp;lt;vp&amp;gt;3&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;getMember_nd&amp;lt;/vp&amp;gt; leaves a backtrack point (so that &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; can later become &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; and then even &amp;lt;vp&amp;gt;2&amp;lt;/vp&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Then we evaluate the condition in the &amp;lt;vp&amp;gt;if-then-else&amp;lt;/vp&amp;gt; term. The first part of this condition succeeds as &amp;lt;vp&amp;gt;3&amp;lt;/vp&amp;gt; is a member of &amp;lt;vp&amp;gt;[3,3]&amp;lt;/vp&amp;gt;. The first part also leaves a backtrack point, so that it can be examined whether &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; is a member several times.&lt;br /&gt;
&lt;br /&gt;
Now we meet a &amp;lt;vp&amp;gt;cut&amp;lt;/vp&amp;gt;. This &amp;lt;vp&amp;gt;cut&amp;lt;/vp&amp;gt; is inside the condition part of an &amp;lt;vp&amp;gt;if-then-else&amp;lt;/vp&amp;gt; statement, so it only has local effect, meaning that it only discards the backtrack point in the second &amp;lt;vp&amp;gt;getMember_nd&amp;lt;/vp&amp;gt;, but leaves the backtrack point in the first &amp;lt;vp&amp;gt;getMember_nd&amp;lt;/vp&amp;gt; predicate.&lt;br /&gt;
&lt;br /&gt;
The whole condition succeeds and we enter the then-part and write out &amp;quot;&amp;lt;vp&amp;gt;3&amp;lt;/vp&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
After the &amp;lt;vp&amp;gt;if-then-else&amp;lt;/vp&amp;gt; we meet &amp;lt;vp&amp;gt;fail&amp;lt;/vp&amp;gt;, which backtracks us to the first &amp;lt;vp&amp;gt;getMember_nd&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;getMember_nd&amp;lt;/vp&amp;gt; then binds &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt;, and leaves a backtrack point (so that &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; can later become &amp;lt;vp&amp;gt;2&amp;lt;/vp&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Then we evaluate the condition in the &amp;lt;vp&amp;gt;if-then-else&amp;lt;/vp&amp;gt; term. The first part of this condition fails as &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; is not a member of &amp;lt;vp&amp;gt;[3,3]&amp;lt;/vp&amp;gt;. So we enter the &amp;lt;vp&amp;gt;else&amp;lt;/vp&amp;gt;-part.&lt;br /&gt;
&lt;br /&gt;
Here we meet a &amp;lt;vp&amp;gt;cut&amp;lt;/vp&amp;gt;. This &amp;lt;vp&amp;gt;cut&amp;lt;/vp&amp;gt; is in the &amp;lt;vp&amp;gt;else&amp;lt;/vp&amp;gt;-part of a conditional term so it has effect outside the &amp;lt;vp&amp;gt;if-then-else&amp;lt;/vp&amp;gt; term and subsequently it discards the backtrack point in the first &amp;lt;vp&amp;gt;getMember_nd&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
When we meet the &amp;lt;vp&amp;gt;fail&amp;lt;/vp&amp;gt; after the &amp;lt;vp&amp;gt;if-then-else&amp;lt;/vp&amp;gt; term there are no more backtrack points in the code and it will fail. So all in all &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; never becomes &amp;lt;vp&amp;gt;2&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== fail/0 and succeed/0 ====&lt;br /&gt;
&lt;br /&gt;
{{lang2|Built-in_entities|fail|fail/0}} and {{lang2|Built-in_entities|succeed|succeed/0}} are two built-in nullary predicates. {{lang2|Built-in_entities|fail|fail/0}} always fails and {{lang2|Built-in_entities|succeed|succeed/0}} always succeeds, besides this the predicates have no effect.&lt;br /&gt;
&lt;br /&gt;
=== in ===&lt;br /&gt;
{{:Language Reference/Terms/in}}&lt;br /&gt;
=== List Comprehension ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;ListComprehensionTerm&amp;gt; :&lt;br /&gt;
    [ &amp;lt;Term&amp;gt; || &amp;lt;Term&amp;gt; ]&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The list comprehension term is a list expression. Consider this schematic term:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;[ Exp || Gen ]&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;Gen&amp;lt;/vp&amp;gt; is (typically) a &amp;lt;vp&amp;gt;nondeterm&amp;lt;/vp&amp;gt; term. &amp;lt;vp&amp;gt;Exp&amp;lt;/vp&amp;gt; is evaluated for each solution of &amp;lt;vp&amp;gt;Gen&amp;lt;/vp&amp;gt;, and the resulting &amp;lt;vp&amp;gt;Exp&amp;lt;/vp&amp;gt;&amp;#039;s are collected in a list. The &amp;lt;vp&amp;gt;Exp&amp;lt;/vp&amp;gt; corresponding to the first solution of &amp;lt;vp&amp;gt;Gen&amp;lt;/vp&amp;gt; is the first element in the list, etc. This list is the result of the list comprehension term. &amp;lt;vp&amp;gt;Exp&amp;lt;/vp&amp;gt; must be procedure (or erroneous). Both &amp;lt;vp&amp;gt;Exp&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;Gen&amp;lt;/vp&amp;gt; are {{lang2|Terms|Cut_Scopes|cut scopes}}.&lt;br /&gt;
&lt;br /&gt;
The list comprehension (normally) reads: The list of &amp;lt;vp&amp;gt;Exp&amp;lt;/vp&amp;gt;&amp;#039;s such that &amp;lt;vp&amp;gt;Gen&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;[ X || X = getMember_nd(L), X mod 2 = 0 ]&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This reads the list of &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt;&amp;#039;s such that &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; is in &amp;lt;vp&amp;gt;L&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; is even. So this expression is the even numbers of &amp;lt;vp&amp;gt;L&amp;lt;/vp&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;[ X + 1 || X = getMember_nd(L), X mod 2 = 0 ]&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here the collected expression is more complex. This makes say the term more awkward:&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;the list of (X+1)&amp;#039;s such that ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This expression again finds the even elements in &amp;lt;vp&amp;gt;L&amp;lt;/vp&amp;gt;, but the resulting list contains all these values incremented.&lt;br /&gt;
&lt;br /&gt;
This term is completely equivalent to this term:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;[ Y || X = getMember_nd(L), X mod 2 = 0 , Y = X+1 ]&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This term is easier to say:&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;The list of Y&amp;#039;s such that (there exists an) X which is member of L, and which is even, and Y is X+1.&amp;quot;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Anonymous Predicates ===&lt;br /&gt;
{{:Language Reference/Terms/Anonymous Predicates}}&lt;br /&gt;
=== Object Member Access ===&lt;br /&gt;
Whenever we have a reference to an object, we can access the object member predicates of that object.&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;MemberAccess&amp;gt;:&lt;br /&gt;
    &amp;lt;Term&amp;gt; : &amp;lt;Identifier&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Currently, the {{lang|Terms|term}} must be a variable or a fact variable).&lt;br /&gt;
&lt;br /&gt;
The {{lang2|Lexical_Elements|Identifiers|identifier}} must have the type of the {{lang|Terms|term}}.&lt;br /&gt;
&lt;br /&gt;
Inside an implementation object member predicates can be invoked without reference to an object, because &amp;quot;&amp;lt;vp&amp;gt;This&amp;lt;/vp&amp;gt;&amp;quot; is subsumed, see {{lang2|Basic_Concepts|Scoping_&amp;amp;_Visibility|Scoping}}.&lt;br /&gt;
&lt;br /&gt;
=== Object Expressions ===&lt;br /&gt;
&lt;br /&gt;
An object expressions is an expressions that evaluates to an object.  Like anonymous predicates it can capture values from and access facts in the context it appears in.&lt;br /&gt;
&lt;br /&gt;
The syntax is like a regular class implementation without a name, but with a construction interface:&lt;br /&gt;
&lt;br /&gt;
{{Example|&amp;lt;vip&amp;gt;Object = &lt;br /&gt;
    implement : observer&lt;br /&gt;
      clauses&lt;br /&gt;
        onNext(A) :- F(toString(A)).&lt;br /&gt;
        onCompletion() :- F(&amp;quot;\n&amp;quot;).&lt;br /&gt;
    end implement&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
the &amp;lt;vp&amp;gt;implement ... end implement&amp;lt;/vp&amp;gt; part is an object expression.&lt;br /&gt;
To make object expressions a lightweight construction the keyword &amp;lt;vp&amp;gt;clauses&amp;lt;/vp&amp;gt; is implicit/optional at the beginning of the scope (unless the scope has &amp;lt;vp&amp;gt;open&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;supports&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;inherits&amp;lt;/vp&amp;gt; qualifications).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;ObjectExpression&amp;gt;: one of&lt;br /&gt;
    &amp;lt;FullObjectExpression&amp;gt;&lt;br /&gt;
    &amp;lt;SimpleObjectExpression&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;FullObjectExpression&amp;gt;:&lt;br /&gt;
    implement : &amp;lt;ConstructionType&amp;gt;&lt;br /&gt;
        &amp;lt;ScopeQualifications&amp;gt;&lt;br /&gt;
        &amp;lt;Sections&amp;gt;&lt;br /&gt;
    end implement&lt;br /&gt;
&lt;br /&gt;
&amp;lt;SimpleObjectExpression&amp;gt;:&lt;br /&gt;
    implement : &amp;lt;ConstructionType&amp;gt;&lt;br /&gt;
        &amp;lt;Clause&amp;gt;-dot-term-list-opt&lt;br /&gt;
        &amp;lt;Sections&amp;gt;&lt;br /&gt;
    end implement&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There will be exactly one constructor &amp;lt;vp&amp;gt;new\0&amp;lt;/vp&amp;gt;. Like for other objects you don&amp;#039;t need to supply an implementation if the constructor is &amp;#039;trivial&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;inherits&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;supports&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;open&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;delegate&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;resolve&amp;lt;/vp&amp;gt; works in the same way as in regular implementations.&lt;br /&gt;
&lt;br /&gt;
=== Scoping ===&lt;br /&gt;
&lt;br /&gt;
The predicates can refer to the context like anonymous predicates but can also refer to facts and inherited classes inside the object.&lt;br /&gt;
&lt;br /&gt;
Object expressions are nested within other scopes, these scopes are all visible from the object expression.  If a name is defined in more than one surrounding scope then the reference is to the closest level.  Names from named scopes can be resolved with the scope name, but names from surrounding object expressions must be resolved by means of a variable as described in the &amp;quot;This&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
=== This ===&lt;br /&gt;
&lt;br /&gt;
In a predicate in an object expression the variable &amp;lt;vp&amp;gt;This&amp;lt;/vp&amp;gt; represent the object of the object expression.  There are no predefined names for surrounding &amp;lt;vp&amp;gt;This&amp;lt;/vp&amp;gt; variables.  So if you want to refer to an outer &amp;lt;vp&amp;gt;This&amp;lt;/vp&amp;gt; you will have to put it in another variable e.g. &amp;lt;vp&amp;gt;Outer = This&amp;lt;/vp&amp;gt; and then use that variable inside the object expression.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;...&lt;br /&gt;
    Outer = This,&lt;br /&gt;
    Object = &lt;br /&gt;
        implement : observer&lt;br /&gt;
            onNext(A) :- F(Outer, toString(A))).&lt;br /&gt;
            onCompletion() :- F(Outer, &amp;quot;\n&amp;quot;)).&lt;br /&gt;
        end implement&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Polymorphism (limitation) ===&lt;br /&gt;
&lt;br /&gt;
Occasionally there will be situations where we will need a type variable.  An example would be a predicate &amp;lt;vp&amp;gt;p : () -&amp;gt; observer{A}&amp;lt;/vp&amp;gt; implemented using an object expression. Unfortunately, this is not possible until we get access to the type variables of polymorphic constructions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    p(Value) = &lt;br /&gt;
        implement : observer{A} % A is unknown/unbound&lt;br /&gt;
        facts&lt;br /&gt;
            v : A = Value. % A is unknown/unbound&lt;br /&gt;
        clauses&lt;br /&gt;
            onNext(V) :- v := V.&lt;br /&gt;
            onCompleted():- write(v).&lt;br /&gt;
        end implement.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The examples below will be based on &amp;lt;vp&amp;gt;iterator&amp;lt;/vp&amp;gt; object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface iterator&lt;br /&gt;
predicates&lt;br /&gt;
   hasNext : () determ.&lt;br /&gt;
   next : () -&amp;gt; integer.&lt;br /&gt;
end interface iterator&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which we will write using this predicate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    writeAll : (iterator It).&lt;br /&gt;
clauses&lt;br /&gt;
    writeAll(It) :-&lt;br /&gt;
        if It:hasNext() then&lt;br /&gt;
            writef(&amp;quot;%\n&amp;quot;, It:next()),&lt;br /&gt;
            writeAll(It)&lt;br /&gt;
        else&lt;br /&gt;
            write(&amp;quot;&amp;lt;&amp;lt;&amp;lt;end&amp;gt;&amp;gt;&amp;gt;\n&amp;quot;)&lt;br /&gt;
        end if.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Simple  object ====&lt;br /&gt;
&lt;br /&gt;
{{Example|We can write a simple &amp;quot;null&amp;quot; &amp;lt;vp&amp;gt;iterator&amp;lt;/vp&amp;gt; that is finished immediately.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    test1 : ().&lt;br /&gt;
clauses&lt;br /&gt;
    test1() :-&lt;br /&gt;
        It =&lt;br /&gt;
            implement : iterator&lt;br /&gt;
                hasNext() :-&lt;br /&gt;
                    fail.&lt;br /&gt;
                next() = _ :-&lt;br /&gt;
                    exception::raise_error().&lt;br /&gt;
            end implement,&lt;br /&gt;
        writeAll(It).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Calling &amp;lt;vp&amp;gt;test1&amp;lt;/vp&amp;gt; will produce&lt;br /&gt;
 &amp;lt;&amp;lt;&amp;lt;end&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
==== Own state====&lt;br /&gt;
&lt;br /&gt;
{{Example|In this example we create an iterator object that har its own fact &amp;lt;vp&amp;gt;n&amp;lt;/vp&amp;gt; which is used to count down from &amp;lt;vp&amp;gt;3&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    test2 : ().&lt;br /&gt;
clauses&lt;br /&gt;
    test2() :-&lt;br /&gt;
        It =&lt;br /&gt;
            implement : iterator&lt;br /&gt;
                hasNext() :-&lt;br /&gt;
                    n &amp;gt; 0.&lt;br /&gt;
                next() = N :-&lt;br /&gt;
                    N = n,&lt;br /&gt;
                    n := n - 1.&lt;br /&gt;
            facts&lt;br /&gt;
                n : integer := 3.&lt;br /&gt;
            end implement,&lt;br /&gt;
        writeAll(It).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Calling &amp;lt;vp&amp;gt;test2&amp;lt;/vp&amp;gt; will produce&lt;br /&gt;
  3&lt;br /&gt;
  2&lt;br /&gt;
  1&lt;br /&gt;
 &amp;lt;&amp;lt;&amp;lt;end&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
==== Capturing values ====&lt;br /&gt;
&lt;br /&gt;
{{Example|The count down object from above can be placed in its own predicate, and we can capture the value to count down &amp;lt;vp&amp;gt;From&amp;lt;/vp&amp;gt; in the context:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    countDown : (integer From) -&amp;gt; iterator It.&lt;br /&gt;
clauses&lt;br /&gt;
    countDown(From) =&lt;br /&gt;
        implement : iterator&lt;br /&gt;
            hasNext() :-&lt;br /&gt;
                n &amp;gt; 0.&lt;br /&gt;
            next() = N :-&lt;br /&gt;
                N = n,&lt;br /&gt;
                n := n - 1.&lt;br /&gt;
        facts&lt;br /&gt;
            n : integer := From.&lt;br /&gt;
        end implement.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    test3 : ().&lt;br /&gt;
clauses&lt;br /&gt;
    test3() :-&lt;br /&gt;
        It = countDown(2),&lt;br /&gt;
        writeAll(It).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Calling &amp;lt;vp&amp;gt;test3&amp;lt;/vp&amp;gt; will produce&lt;br /&gt;
  2&lt;br /&gt;
  1&lt;br /&gt;
 &amp;lt;&amp;lt;&amp;lt;end&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Example|Here &amp;lt;vp&amp;gt;map&amp;lt;/vp&amp;gt; create an iterator that maps the values returned  &amp;lt;vp&amp;gt;iterator&amp;lt;/vp&amp;gt; just like it would have modified the values of a list.  Notice how the object expression captures the variables &amp;lt;vp&amp;gt;F&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;It&amp;lt;/vp&amp;gt; and accesses them in its member predicates.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    map : (function{integer, integer} Function, iterator It) -&amp;gt; iterator Mapped.&lt;br /&gt;
clauses&lt;br /&gt;
    map(F, It) =&lt;br /&gt;
        implement : iterator&lt;br /&gt;
            hasNext() :-&lt;br /&gt;
                It:hasNext().&lt;br /&gt;
            next() = F(It:next()).&lt;br /&gt;
        end implement.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    test4 : ().&lt;br /&gt;
clauses&lt;br /&gt;
    test4() :-&lt;br /&gt;
        It1 = countDown(2),&lt;br /&gt;
        It2 = map({ (V) = V + 7 }, It1),&lt;br /&gt;
        writeAll(It2).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Calling &amp;lt;vp&amp;gt;test4&amp;lt;/vp&amp;gt; will produce&lt;br /&gt;
  9&lt;br /&gt;
  8&lt;br /&gt;
 &amp;lt;&amp;lt;&amp;lt;end&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Capturing a fact ====&lt;br /&gt;
&lt;br /&gt;
{{Example|Here the fact &amp;lt;vp&amp;gt;count&amp;lt;/vp&amp;gt; from the context is captured and manipulated from within the object expression.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class facts&lt;br /&gt;
    count : integer := 3.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    test5 : ().&lt;br /&gt;
clauses&lt;br /&gt;
    test5() :-&lt;br /&gt;
        It =&lt;br /&gt;
            implement : iterator&lt;br /&gt;
                hasNext() :-&lt;br /&gt;
                    count &amp;gt; 0.&lt;br /&gt;
                next() = N :-&lt;br /&gt;
                    N = count,&lt;br /&gt;
                    count := count - 1.&lt;br /&gt;
            end implement,&lt;br /&gt;
        writeAll(It).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Calling &amp;lt;vp&amp;gt;test5&amp;lt;/vp&amp;gt; will produce&lt;br /&gt;
  3&lt;br /&gt;
  2&lt;br /&gt;
  1&lt;br /&gt;
 &amp;lt;&amp;lt;&amp;lt;end&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== inherits ====&lt;br /&gt;
&lt;br /&gt;
{{Example|Suppose we have a class &amp;lt;vp&amp;gt;randomIterator&amp;lt;/vp&amp;gt; which generates random numbers and supports the &amp;lt;vp&amp;gt;iterator&amp;lt;/vp&amp;gt; iterator.&lt;br /&gt;
We can inherit from this iterator to create a iterator that &amp;quot;throws a dice&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    test6 : ().&lt;br /&gt;
clauses&lt;br /&gt;
    test6() :-&lt;br /&gt;
        Dice =&lt;br /&gt;
            implement : iterator inherits randomIterator&lt;br /&gt;
            clauses&lt;br /&gt;
                next() = randomIterator::next() mod 6 + 1.&lt;br /&gt;
            end implement,&lt;br /&gt;
        foreach _ = std::cIterate(5) do&lt;br /&gt;
            writef(&amp;quot;Dice : %\n&amp;quot;, Dice:next())&lt;br /&gt;
        end foreach.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By inheriting &amp;lt;vp&amp;gt;randomIterator&amp;lt;/vp&amp;gt; we get the implementation of &amp;lt;vp&amp;gt;hasNext&amp;lt;/vp&amp;gt; and only need to implement &amp;lt;vp&amp;gt;next&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Notice that it is necessary to use the &amp;lt;vp&amp;gt;clauses&amp;lt;/vp&amp;gt; keyword in this case because the class has an &amp;lt;vp&amp;gt;inherits&amp;lt;/vp&amp;gt; qualification.&lt;br /&gt;
&lt;br /&gt;
Assuming that &amp;lt;vp&amp;gt;randomIterator&amp;lt;/vp&amp;gt; will never end, we just iterate &amp;lt;vp&amp;gt;5&amp;lt;/vp&amp;gt; times.&lt;br /&gt;
&lt;br /&gt;
Calling &amp;lt;vp&amp;gt;test5&amp;lt;/vp&amp;gt; will produce (something like):&lt;br /&gt;
 Dice : 1&lt;br /&gt;
 Dice : 2&lt;br /&gt;
 Dice : 4&lt;br /&gt;
 Dice : 2&lt;br /&gt;
 Dice : 3&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Domain, Functor, and Constant Access ===&lt;br /&gt;
&lt;br /&gt;
Domains, functors, and constants are all accessed as if they are class members. Even if they are declared in an interface. This means that when they are qualified, then they are always qualified with class/interface name and a double colon.&lt;br /&gt;
&lt;br /&gt;
=== foreach ===&lt;br /&gt;
{{:Language Reference/Terms/Foreach}}&lt;br /&gt;
=== if-then-else ===&lt;br /&gt;
{{:Language Reference/Terms/If-then-else}}&lt;br /&gt;
=== try-catch-finally ===&lt;br /&gt;
{{:Language Reference/Terms/Try-catch-finally}}&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Language_Reference/Interfaces&amp;diff=4986</id>
		<title>Language Reference/Interfaces</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Language_Reference/Interfaces&amp;diff=4986"/>
		<updated>2025-06-23T11:54:10Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: /* The interface: object */ object::null&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{languageReferenceNavbar|Interfaces}}&lt;br /&gt;
&lt;br /&gt;
An interface definition defines a named object type. Interfaces can support other interfaces. See {{lang2|Interfaces|Supports_Qualification|Supports Qualification}} for further details.&lt;br /&gt;
&lt;br /&gt;
All predicates declared in an interface are object members in objects of the interface type. &lt;br /&gt;
&lt;br /&gt;
An interface is also a global scope, in which constants and domains can be defined. Thus constants and domains defined in an interface are not part of the type that the interface denotes (or of objects having this type).&lt;br /&gt;
&lt;br /&gt;
Such domains and constants can be referenced from other scopes by qualification with the interface name: &amp;lt;vp&amp;gt;interfaceName::constant&amp;lt;/vp&amp;gt;, or by using an open qualification. (See {{lang2|Interfaces|Open_Qualification|Open Qualification}}.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;InterfaceDefinition&amp;gt; :&lt;br /&gt;
   interface &amp;lt;InterfaceName&amp;gt;&lt;br /&gt;
       &amp;lt;ScopeQualifications&amp;gt;&lt;br /&gt;
   &amp;lt;Sections&amp;gt;&lt;br /&gt;
   end interface &amp;lt;IinterfaceName&amp;gt;-opt&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;InterfaceName&amp;gt; :&lt;br /&gt;
   &amp;lt;LowerCaseIdentifier&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also {{lang|Generic Interfaces and Classes|Generic Interfaces and Classes}} and {{lang|Monitors|Monitors}}.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vpbnf&amp;gt;&amp;lt;InterfaceName&amp;gt;&amp;lt;/vpbnf&amp;gt; in the end of the construction must (if present) be identical to the one in the beginning of the construction.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vpbnf&amp;gt;&amp;lt;ScopeQualifications&amp;gt;&amp;lt;/vpbnf&amp;gt; must be of the kinds:&lt;br /&gt;
&lt;br /&gt;
*{{lang2|Interfaces|Supports_Qualification|Supports Qualification}}&lt;br /&gt;
*{{lang2|Interfaces|Open_Qualification|Open Qualification}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vpbnf&amp;gt;&amp;lt;Sections&amp;gt;&amp;lt;/vpbnf&amp;gt; must be of the kinds:&lt;br /&gt;
&lt;br /&gt;
*{{lang2|Constants|Constants_Sections|ConstantsSection}}&lt;br /&gt;
*{{lang2|Domains|Domains_Sections|DomainsSection}}&lt;br /&gt;
*{{lang2|Predicates|Predicates_Sections|PredicatesSection}}&lt;br /&gt;
*{{lang2|Predicates|Predicates_from_Interface|PredicatesFromInterface}}&lt;br /&gt;
*{{lang2|Properties|Properties_Sections|PropertiesSection}}&lt;br /&gt;
*{{lang2|Directives|Conditional_Compilation|ConditionalSection}}&lt;br /&gt;
&lt;br /&gt;
All sections contained (transitively) in conditional sections must also be of those kinds.&lt;br /&gt;
&lt;br /&gt;
=== The interface: object ===&lt;br /&gt;
&lt;br /&gt;
If an interface does not explicitly support any interfaces, then it implicitly supports the build-in interface &amp;#039;&amp;#039;object.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;object&amp;#039;&amp;#039; is an empty interface, i.e. it contains no predicates etc.  The constant [[Language_Reference/Built-in_entities#null|null]] is however defined for the interface.&lt;br /&gt;
&lt;br /&gt;
The purpose of &amp;#039;&amp;#039;object&amp;#039;&amp;#039; is to be a universal base-type of all objects.&lt;br /&gt;
&lt;br /&gt;
=== Open Qualification ===&lt;br /&gt;
&lt;br /&gt;
Open qualifications are used to make references to class level entities more convenient. The open section brings the names of one scope into another scope, so that these can be referenced without qualification.&lt;br /&gt;
&lt;br /&gt;
Open has no effect on the names of object members as these can only be accessed by means of an object anyway. But names of class members, domains, functors and constants can be accessed without qualification.&lt;br /&gt;
&lt;br /&gt;
When names are brought into a scope in this way it may happen that some names becomes ambiguous (see {{lang2|Basic_Concepts|Scoping_&amp;amp;_Visibility|Scoping}}).&lt;br /&gt;
&lt;br /&gt;
Open sections have only effect in the scope in which they occur. Especially this means that an open section in a class declaration has no effect on the class implementation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;OpenQualification&amp;gt; :&lt;br /&gt;
   open &amp;lt;ScopeName&amp;gt;-comma-sep-list&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Supports Qualification ===&lt;br /&gt;
&lt;br /&gt;
Supports qualifications can only be used in {{lang2|Interfaces|Interfaces|&amp;lt;vpbnf&amp;gt;&amp;lt;InterfaceDefinition&amp;gt;&amp;lt;/vpbnf&amp;gt;}} and {{lang|Implementations|&amp;lt;vpbnf&amp;gt;&amp;lt;ClassImplementation&amp;gt;&amp;lt;/vpbnf&amp;gt;}}.&lt;br /&gt;
&lt;br /&gt;
Supports qualifications are used for two things:&lt;br /&gt;
&lt;br /&gt;
*specifying that one interface &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; extends another interface &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; and, thereby, that the object type &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; is a subtype of the object type &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt;&lt;br /&gt;
*declaring that the objects of a certain class &amp;quot;privately&amp;quot; have more object types, than the one specified as construction type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;supports&amp;lt;/vp&amp;gt; is a transitive relation: if an interface &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; &amp;lt;vp&amp;gt;supports&amp;lt;/vp&amp;gt; an interface &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;B&amp;lt;/vp&amp;gt; in turn &amp;lt;vp&amp;gt;supports&amp;lt;/vp&amp;gt; &amp;lt;vp&amp;gt;C&amp;lt;/vp&amp;gt;, then &amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt; also &amp;lt;vp&amp;gt;supports&amp;lt;/vp&amp;gt; &amp;lt;vp&amp;gt;C&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If an interface does not explicitly support any interfaces, then it implicitly supports the predefined interface &amp;#039;&amp;#039;object&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Functionally, it makes no difference whether an interface supports a certain interface more that once (directly and/or indirectly), but it might make a representational difference for the objects.&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;vp&amp;gt;supports&amp;lt;/vp&amp;gt; is used in the implementation of a class, the result is that &amp;quot;&amp;lt;vp&amp;gt;This&amp;lt;/vp&amp;gt;&amp;quot; not only can be used with the construction type, but also with any privately supported object type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;SupportsQualification&amp;gt; :&lt;br /&gt;
   supports &amp;lt;InterfaceName&amp;gt;-comma-sep-list&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vpbnf&amp;gt;&amp;lt;SupportsQualification&amp;gt;&amp;lt;/vpbnf&amp;gt; can only be used in {{lang2|Interfaces|Interfaces|&amp;lt;vpbnf&amp;gt;&amp;lt;InterfaceDefinition&amp;gt;&amp;lt;/vpbnf&amp;gt;}} and {{lang|Implementations|&amp;lt;vpbnf&amp;gt;&amp;lt;ClassImplementation&amp;gt;&amp;lt;/vpbnf&amp;gt;}}.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Notice&amp;#039;&amp;#039;&amp;#039; interfaces cannot be used together in a supports qualification, if they have conflicting predicates.&lt;br /&gt;
&lt;br /&gt;
Predicates are conflicting if they have the same name and the arity but different origin interfaces.&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;origin&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; interface of a predicate is the interface in which the predicate is literally declared, as opposed to interfaces where it is indirectly declared by a supports qualification.&lt;br /&gt;
&lt;br /&gt;
So it does not give conflicts, if the same interface is met twice or more in the supports chains.&lt;br /&gt;
&lt;br /&gt;
{{Example| Consider the following definitions and declarations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface aaa&lt;br /&gt;
predicates&lt;br /&gt;
    insert : (integer X).&lt;br /&gt;
end interface&lt;br /&gt;
&lt;br /&gt;
interface bbb&lt;br /&gt;
   supports aaa&lt;br /&gt;
predicates&lt;br /&gt;
   insert : (integer X, string Comment).&lt;br /&gt;
end interface&lt;br /&gt;
&lt;br /&gt;
interface cc&lt;br /&gt;
   supports aaa&lt;br /&gt;
predicates&lt;br /&gt;
   extract : () -&amp;gt; integer.&lt;br /&gt;
end interface&lt;br /&gt;
&lt;br /&gt;
interface dd&lt;br /&gt;
   supports aaa, bbb, cc&lt;br /&gt;
predicates &lt;br /&gt;
   extract : (string Comment) -&amp;gt; integer.&lt;br /&gt;
end interface&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is a list of all predicates found in &amp;lt;vp&amp;gt;dd&amp;lt;/vp&amp;gt; (found by a depth traversal):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
   insert : (integer).     % dd -&amp;gt; aaa&lt;br /&gt;
   insert : (integer).     % dd -&amp;gt; bbb -&amp;gt; aaa&lt;br /&gt;
   insert : (integer, string).     % dd -&amp;gt; bbb&lt;br /&gt;
   insert : (integer).     % dd -&amp;gt; cc -&amp;gt; aaa&lt;br /&gt;
   extract : () -&amp;gt; integer.     % dd -&amp;gt; cc&lt;br /&gt;
   extract: : (string) -&amp;gt; integer.     % dd&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some of the predicates are the same, so all in all, &amp;lt;vp&amp;gt;dd&amp;lt;/vp&amp;gt; will contain the following members:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
   insert : (integer).     % origin interface: aaa&lt;br /&gt;
   insert : (integer, string).     % origin interface: bbb&lt;br /&gt;
   extract : () -&amp;gt; integer.     % origin interface: cc&lt;br /&gt;
   extract : (string) -&amp;gt; integer.     % origin interface: dd&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Example| Consider the following interfaces:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface aaa&lt;br /&gt;
predicates&lt;br /&gt;
   insert : (integer X).&lt;br /&gt;
end interface&lt;br /&gt;
&lt;br /&gt;
interface bbb&lt;br /&gt;
predicates&lt;br /&gt;
   insert : (integer X).&lt;br /&gt;
end interface&lt;br /&gt;
&lt;br /&gt;
interface cc&lt;br /&gt;
   supports aaa, bbb     % conflicting interfaces&lt;br /&gt;
end interface&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The interface &amp;lt;vp&amp;gt;cc&amp;lt;/vp&amp;gt; is &amp;#039;&amp;#039;&amp;#039;illegal&amp;#039;&amp;#039;&amp;#039;, because &amp;lt;vp&amp;gt;insert/1&amp;lt;/vp&amp;gt; supported in &amp;lt;vp&amp;gt;aaa&amp;lt;/vp&amp;gt; has &amp;lt;vp&amp;gt;aaa&amp;lt;/vp&amp;gt; as origin, whereas &amp;lt;vp&amp;gt;insert/1&amp;lt;/vp&amp;gt; supported in &amp;lt;vp&amp;gt;bbb&amp;lt;/vp&amp;gt; has &amp;lt;vp&amp;gt;bbb&amp;lt;/vp&amp;gt; as origin.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Constants&amp;diff=4985</id>
		<title>Language Reference/Built-in entities/Constants</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Constants&amp;diff=4985"/>
		<updated>2025-06-23T11:50:18Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: interface::null&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{|{{prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|[[#compilation_date|compilation_date]]&lt;br /&gt;
|Compilation date.&lt;br /&gt;
|-&lt;br /&gt;
|[[#compilation_time|compilation_time]]&lt;br /&gt;
|Compilation time.&lt;br /&gt;
|-&lt;br /&gt;
|[[#compiler_buildDate|compiler_buildDate]]&lt;br /&gt;
|Build date of a compiler.&lt;br /&gt;
|-&lt;br /&gt;
|[[#compiler_version|compiler_version]]&lt;br /&gt;
|A compiler version.&lt;br /&gt;
|-&lt;br /&gt;
|[[#maxFloatDigits|maxFloatDigits]]&lt;br /&gt;
|Defines the maximal value of &amp;quot;digits&amp;quot;, which is supported by the compiler.&lt;br /&gt;
|-&lt;br /&gt;
|[[#null|null]]&lt;br /&gt;
|The default NULL pointer.&lt;br /&gt;
|-&lt;br /&gt;
|[[#nullHandle|nullHandle]]&lt;br /&gt;
|A special constant of a handle type with the zero value.&lt;br /&gt;
|-&lt;br /&gt;
|[[#invalidHandle|invalidHandle]]&lt;br /&gt;
|A special constant of a handle type with the invalid (-1) value.&lt;br /&gt;
|-&lt;br /&gt;
|[[#platform_bits|platform_bits]]&lt;br /&gt;
|Defines the digital capacity of compilation platform.&lt;br /&gt;
|-&lt;br /&gt;
|[[#platform_name|platform_name]]&lt;br /&gt;
|Defines the target platform name.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== compilation_date ====&lt;br /&gt;
&lt;br /&gt;
Compilation date. Here &amp;#039;&amp;#039;YYYY&amp;#039;&amp;#039; means the number of a year, &amp;#039;&amp;#039;MM&amp;#039;&amp;#039; means a month number, and &amp;#039;&amp;#039;DD&amp;#039;&amp;#039; means a day number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;compilation_date : string = &amp;quot;YYYY-MM-DD&amp;quot;.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== compilation_time ====&lt;br /&gt;
&lt;br /&gt;
Compilation time. Here &amp;#039;&amp;#039;HH&amp;#039;&amp;#039; means hours, &amp;#039;&amp;#039;MM&amp;#039;&amp;#039; means minutes, and &amp;#039;&amp;#039;SS &amp;#039;&amp;#039;means seconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;compilation_time : string = &amp;quot;HH:MM:SS&amp;quot;.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== compiler_buildDate ====&lt;br /&gt;
&lt;br /&gt;
Build date of the compiler.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;compiler_buildDate : string = &amp;quot;YYYY-MM-DD HH:MM&amp;quot;.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== compiler_version ====&lt;br /&gt;
&lt;br /&gt;
A compiler version. This value depends upon the compiler version.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;compiler_version = 6003.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== maxFloatDigits ====&lt;br /&gt;
&lt;br /&gt;
Defines the maximal value of &amp;quot;digits&amp;quot;, which is supported by the compiler.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;maxFloatDigits = 16.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== null ====&lt;br /&gt;
&lt;br /&gt;
A constant of type &amp;lt;vp&amp;gt;pointer&amp;lt;/vp&amp;gt; with the value &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;null : pointer = uncheckedConvert(pointer, 0).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;null&amp;lt;/vp&amp;gt; is also implicitly defined on all interfaces.  It is a null pointer of the type the interface has.  This is how it would look if the constant was defined &amp;#039;&amp;#039;&amp;#039;explicitly&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface xxx&lt;br /&gt;
...&lt;br /&gt;
constants&lt;br /&gt;
    null : xxx = uncheckedConvert(xxx, null).  % this constant is already implicitly defined&lt;br /&gt;
...&lt;br /&gt;
end interface xxx&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Example|This example shows how the constant can be used in a clause.&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface xxx&lt;br /&gt;
end interface xxx&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
clauses&lt;br /&gt;
    isNullXxx(X) :-&lt;br /&gt;
        xxx::null = X.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== nullHandle ====&lt;br /&gt;
&lt;br /&gt;
A constant of type &amp;lt;vp&amp;gt;handle&amp;lt;/vp&amp;gt; with the value &amp;lt;vp&amp;gt;0&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;nullHandle : handle = uncheckedConvert(handle, 0).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== invalidHandle ====&lt;br /&gt;
&lt;br /&gt;
A constant of type &amp;lt;vp&amp;gt;handle&amp;lt;/vp&amp;gt; with the invalid (for a handle) value &amp;lt;vp&amp;gt;-1&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;invalidHandle : handle = uncheckedConvert(handle, -1).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== platform_bits ====&lt;br /&gt;
&lt;br /&gt;
Defines the digital capacity of compilation platform.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;platform_bits = 32.&lt;br /&gt;
or&lt;br /&gt;
platform_bits = 64.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== platform_name ====&lt;br /&gt;
&lt;br /&gt;
Defines the target platform name.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;platform_name : string = &amp;quot;Windows 32bits&amp;quot;.&lt;br /&gt;
or&lt;br /&gt;
platform_name : string = &amp;quot;Windows 64bits&amp;quot;.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{LanguageReferenceSubarticle|Built-in entities/Constants}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_11_New_Features&amp;diff=4984</id>
		<title>Visual Prolog 11 New Features</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_11_New_Features&amp;diff=4984"/>
		<updated>2025-03-06T12:32:29Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: /* Language */ spelling&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Visual Prolog 11 has been extended with {{lang|Suspending Predicates|Suspending Predicates}}.&lt;br /&gt;
&lt;br /&gt;
The development system can only run on 64 bit Windows, but can still build programs for both 32 and 64 bit Windows.&lt;br /&gt;
&lt;br /&gt;
New utility &amp;quot;[[vipLaunch]]&amp;quot; for launching projects in correct IDE.  The installer is included in the Visual Prolog 11 installer, but you can also install the latest version directly here [https://www.visual-prolog.com/link/vipLaunch.php vipLaunch installer].&lt;br /&gt;
&lt;br /&gt;
Download Visual Prolog 11 [https://www.visual-prolog.com/link/examples.php?version=11 Demo Examples].&lt;br /&gt;
&lt;br /&gt;
== Build 1105 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* {{lang|Suspending Predicates|Suspending Predicates}}&lt;br /&gt;
* {{lang2|Attributes|feature|feature}} attribute, built-in predicate &amp;lt;vp&amp;gt;is_feature_available&amp;lt;/vp&amp;gt;, compiler option &amp;#039;&amp;#039;&amp;#039;/ENABLEFEature:feature_name&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Built-in predicates &amp;lt;vp&amp;gt;convertAllowNull&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;tryConvertAllowNull&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Built-in constants &amp;lt;interface&amp;gt;&amp;lt;vp&amp;gt;::null&amp;lt;/vp&amp;gt; for all interfaces&lt;br /&gt;
* Warning: explicit &amp;lt;vp&amp;gt;programmingPoint&amp;lt;/vp&amp;gt; available&lt;br /&gt;
* Embedded string8 (utf8) support (literals and conversions)&lt;br /&gt;
* Warning c665 for a fact which is always initialized with a constant and is not changed (switched off by the default)&lt;br /&gt;
* Digit separator support (syntax only) &amp;lt;vp&amp;gt;1_000_000&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;0x_1A2B_3C4D&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Support for asynchronous programming by means of suspending predicates:&lt;br /&gt;
** New: &amp;lt;vp&amp;gt;executionContext_pool&amp;lt;/vp&amp;gt; a multi threaded pool for asynchronous and background work&lt;br /&gt;
** New: &amp;lt;vp&amp;gt;executionContext_single&amp;lt;/vp&amp;gt; a single threaded worker for asynchronous work&lt;br /&gt;
** New: Suspending predicates can be executed in a GUI thread (using &amp;lt;vp&amp;gt;future::submit&amp;lt;/vp&amp;gt;)&lt;br /&gt;
** New: Diverse suspending predicate domains in &amp;lt;vp&amp;gt;core&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;asyncSocket&amp;lt;/vp&amp;gt; &amp;amp; &amp;lt;vp&amp;gt;asyncSocketListener&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: master/slave support&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;promise&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: HTTP server &amp;amp; JSON RPC &amp;amp; &amp;lt;vp&amp;gt;webSocket&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;webView2&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;watchDirectory&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Removed: &amp;lt;vp&amp;gt;continuation&amp;lt;/vp&amp;gt; class and inteface due to redundancy.&lt;br /&gt;
** Removed: &amp;lt;vp&amp;gt;threadpool&amp;lt;/vp&amp;gt; and all related classes and interfaces due to redundancy.&lt;br /&gt;
** New support class: &amp;lt;vp&amp;gt;resumable&amp;lt;/vp&amp;gt; class for internal support of suspending predicates&lt;br /&gt;
** New support classes: &amp;lt;vp&amp;gt;tp&amp;lt;/vp&amp;gt; (etc) internal win32 threadpool interface for dealing with asynchronous io, timers, syncObject waiting, etc&lt;br /&gt;
** Deprecated/removed diverse continuation based stuff&lt;br /&gt;
* MSXML import free threaded xmlhttp: including &amp;lt;vp&amp;gt;iXMLHTTPRequest3&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Predicate &amp;lt;vp&amp;gt;messageBox::displayWarningYesNo_dt&amp;lt;/vp&amp;gt; replacement for &amp;lt;vp&amp;gt;displayWarning_dt&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Deprecate &amp;lt;vp&amp;gt;messageBox::displayWarning_dt&amp;lt;/vp&amp;gt;: UX: It is reccomended to use Yes/No warnings instead of OK/Cancel&lt;br /&gt;
* Color predicates &amp;lt;vp&amp;gt;blendColor&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;darken&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;lighten&amp;lt;/vp&amp;gt; in &amp;lt;vp&amp;gt;gdiplus&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;fetchString8asString&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;useLocalTimeValue&amp;lt;/vp&amp;gt; properties on &amp;lt;vp&amp;gt;odbcConnection&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;odbcStatement&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;delayCallLimit&amp;lt;/vp&amp;gt; predicate on &amp;lt;vp&amp;gt;window&amp;lt;/vp&amp;gt; for delay calls with a MaxDelay.&lt;br /&gt;
* &amp;lt;vp&amp;gt;inputStream_binary&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;outputStream_binary&amp;lt;/vp&amp;gt; supports/allows ansi(utf8) mode.&lt;br /&gt;
* Improved &amp;lt;vp&amp;gt;outputStream&amp;lt;/vp&amp;gt; performance for &amp;lt;vp&amp;gt;messageControl&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;event0&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;event1&amp;lt;/vp&amp;gt;, ... classes: lock free threadsafe.&lt;br /&gt;
* &amp;#039;Sergoe Fluent Icons&amp;#039;/&amp;#039;Segoe MDL2 Assets&amp;#039; glyph icons in ribbonControl/commands&lt;br /&gt;
* Explorer theme is applied to &amp;lt;vp&amp;gt;treeControl&amp;lt;/vp&amp;gt; by default.&lt;br /&gt;
* &amp;lt;vp&amp;gt;monitorQueue&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;monitorQueue_length&amp;lt;/vp&amp;gt; are updated with &amp;lt;vp&amp;gt;close&amp;lt;/vp&amp;gt; functionality.  As a result the &amp;lt;vp&amp;gt;dequeue&amp;lt;/vp&amp;gt; operation has become determ.&lt;br /&gt;
* Console projects supports [https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences Console Virtual Terminal Sequences] (by off default).&lt;br /&gt;
* flag &amp;lt;vp&amp;gt;jsonRpcApi{@Context}::exceptionTraceLevel&amp;lt;/vp&amp;gt; controlling which/when exception dumps that are send to the client side.&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* Main IDE is now always 64bit&lt;br /&gt;
* [[Ide/Debugger#Debug_Adapter|Debug Adapter]] makes cross-debugging to 32bit possible&lt;br /&gt;
* Dynamic Help (based on browse information and syntax parsing results)&lt;br /&gt;
* New toolbar&lt;br /&gt;
* vipId support&lt;br /&gt;
* Use new Sergoe Fluent Icons&lt;br /&gt;
* Default SDI project includes &amp;#039;Sergoe Fluent Icons&amp;#039;/&amp;#039;Segoe MDL2 Assets&amp;#039; glyph icons the ribbonControl/commands&lt;br /&gt;
* Add variable $(node_modules)&lt;br /&gt;
* New Menu item handlers (move code expert to properties window)&lt;br /&gt;
* Alt+X converts (unicode) hex to char&lt;br /&gt;
* changes.htm and appData\doc\vip.chm handling&lt;br /&gt;
* Updated Welcome window&lt;br /&gt;
* splitterControl in welcome page&lt;br /&gt;
* Build system: pre-build command&lt;br /&gt;
* Automatic parallel obj/deb directories&lt;br /&gt;
&lt;br /&gt;
=== Debugger ===&lt;br /&gt;
&lt;br /&gt;
* Debugging now uses a [[Ide/Debugger#Debug_Adapter|Debug Adapter]]&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
* Remove superfluous webRpc demo &amp;amp; update webServiceDemo to dispose the session.&lt;br /&gt;
* The &amp;lt;vp&amp;gt;webServiceDemo&amp;lt;/vp&amp;gt; is updated to demonstrate usage of the flag &amp;lt;vp&amp;gt;jsonRpcApi{@Context}::exceptionTraceLevel&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Build 1106 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Subtype presenter problem&lt;br /&gt;
* Fix: Stack overflow exception on binary constant allocation&lt;br /&gt;
* Fix: Wrong debug info for unbound variable (functor component)&lt;br /&gt;
* Fix: Debugger/presenters: false objects&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* webView2&lt;br /&gt;
** Fix: Windows 7 and Windows 8 compatibility./li&amp;gt;&lt;br /&gt;
** Additional CompleteHandler handling (suspending predicates).&lt;br /&gt;
* Fix: &amp;lt;vp&amp;gt;ribbonControl&amp;lt;/vp&amp;gt;: Release native graphics context.&lt;br /&gt;
* odbc: add column/parameter number for results longer than the buffer.&lt;br /&gt;
* &amp;lt;vp&amp;gt;window::centerTo&amp;lt;/vp&amp;gt;: map to Windows parent (not pfc parent).&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;webView2&amp;lt;/vp&amp;gt; control show on Windows 7/8 &amp;amp; update build number&lt;br /&gt;
* show correct build number&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;comWrap&amp;lt;/vp&amp;gt;: Handle more winRT CompleteHandlers (for webView2)&lt;br /&gt;
* Fix: Runtime debugger/presenters: false objects&lt;br /&gt;
&lt;br /&gt;
== Build 1107 ==&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* New class &amp;lt;vp&amp;gt;gcUcBuffer&amp;lt;/vp&amp;gt;: for buffers that cannot be caught by false pointers.&lt;br /&gt;
* odbc: utilize &amp;lt;vp&amp;gt;gcUcBuffer&amp;lt;/vp&amp;gt; to avoid that odbc buffers are caught by false pointers.&lt;br /&gt;
* New predicate &amp;lt;vp&amp;gt;clipBoard::putFileList&amp;lt;/vp&amp;gt; for putting files on the clipboard in the pre-defined hDrop format.&lt;br /&gt;
* &amp;lt;vp&amp;gt;command&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;ribbonControl&amp;lt;/vp&amp;gt;: new responder &amp;lt;vp&amp;gt;queryBadgeState&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* Prevent &amp;lt;vp&amp;gt;vpi::processEvents&amp;lt;/vp&amp;gt; from interfering with &amp;lt;vp&amp;gt;postAction&amp;lt;/vp&amp;gt; order.&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* Personal edition supports 64 bit targets.&lt;br /&gt;
* Open external browser for registration, wiki-help and forum links.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Help -&amp;gt; Prolog Foundation Classes (PFC)&amp;#039;&amp;#039;&amp;#039; opens vip.chm.&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
Fix: MemoryProfiler wrong scaling of total graph.&lt;br /&gt;
&lt;br /&gt;
== Build 1108 ==&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* New property &amp;lt;vp&amp;gt;remoteAddress&amp;lt;/vp&amp;gt; on interface &amp;lt;vp&amp;gt;httpRequest&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* New predicate &amp;lt;vp&amp;gt;memory::mkCopy_atomic&amp;lt;/vp&amp;gt; for copying structs.&lt;br /&gt;
* New predicates &amp;lt;vp&amp;gt;formatSocketAddress&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;formatSockAddr&amp;lt;/vp&amp;gt; in class &amp;lt;vp&amp;gt;winSock2_api&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;winSock2_api&amp;lt;/vp&amp;gt; correct and simplify various domains.&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Exceptions when git is not installed.&lt;br /&gt;
&lt;br /&gt;
== Build 1110 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;match&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;case&amp;lt;/vp&amp;gt; has been reserved as keywords in next major release.&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Wrong type of parameter type in predicate &amp;lt;vp&amp;gt;winHttp_native::winHttpSetOption&amp;lt;/vp&amp;gt; declaration.&lt;br /&gt;
* Fix: Eliminate race condition for &amp;lt;vp&amp;gt;postAction&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* Deprecate &amp;lt;vp&amp;gt;time::getTickCount&amp;lt;/vp&amp;gt; in favour of &amp;lt;vp&amp;gt;performanceCounter&amp;lt;/vp&amp;gt;&amp;#039;s.&lt;br /&gt;
* Deprecate &amp;lt;vp&amp;gt;regEx::match&amp;lt;/vp&amp;gt; because &amp;lt;vp&amp;gt;match&amp;lt;/vp&amp;gt; will become a keyword.&lt;br /&gt;
&lt;br /&gt;
== Build 1111 ==&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Fix: time_api::getTimeZoneOffset hours -&amp;gt; minutes&lt;br /&gt;
* Fix: odbcStatement::free: allow to be called more than once&lt;br /&gt;
* Fix: stringFormat (gdiplus): nullary constructor must create a fresh object&lt;br /&gt;
&lt;br /&gt;
=== Debugger ===&lt;br /&gt;
&lt;br /&gt;
Fix: Dictionary loading timeout for large programs in debug adaptor&lt;br /&gt;
&lt;br /&gt;
== Build 1112 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Access violation for suspending &amp;lt;vp&amp;gt;getMember_susp_nd&amp;lt;/vp&amp;gt; predicate.&lt;br /&gt;
* Fix: Syntax error for &amp;lt;vp&amp;gt;language as&amp;lt;/vp&amp;gt; with subtype bounds&lt;br /&gt;
* Fix: 32 bit code problem for bounded polymorphism: &amp;lt;vp&amp;gt;where Key supports unsigned64&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Fix: unification of two patterns &amp;lt;vp&amp;gt;[As, [X]] = [[X], Bs] &amp;lt;/vp&amp;gt;&lt;br /&gt;
* Fix: Optional out for predicate defined by predicate domain&lt;br /&gt;
* Fix: default argument functor from domain in generic interface&lt;br /&gt;
* Fix: Problem locating correct predicate with arity (from different scopls)&lt;br /&gt;
* Fix: code generation bug for backtracking handling.&lt;br /&gt;
&lt;br /&gt;
The fixes above solves the problems mentioned in [https://discuss.visual-prolog.com/viewtopic.php?f=2&amp;amp;t=20231 Some minor details in VIP 11 build 1111].&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Fix: window::delayCall wrong handling of Id.&lt;br /&gt;
* Fix: Better presenter for core::timeout.&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
* New: More relaxed commas in parser for vipPP to auto-correct (change in vip parser)&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
See also [[Visual Prolog 11 Upgrade Notes]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Release Notes|11 New Features]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_11_New_Features&amp;diff=4983</id>
		<title>Visual Prolog 11 New Features</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_11_New_Features&amp;diff=4983"/>
		<updated>2025-03-06T12:18:12Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Remove zip/unzip&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Visual Prolog 11 has been extended with {{lang|Suspending Predicates|Suspending Predicates}}.&lt;br /&gt;
&lt;br /&gt;
The development system can only run on 64 bit Windows, but can still build programs for both 32 and 64 bit Windows.&lt;br /&gt;
&lt;br /&gt;
New utility &amp;quot;[[vipLaunch]]&amp;quot; for launching projects in correct IDE.  The installer is included in the Visual Prolog 11 installer, but you can also install the latest version directly here [https://www.visual-prolog.com/link/vipLaunch.php vipLaunch installer].&lt;br /&gt;
&lt;br /&gt;
Download Visual Prolog 11 [https://www.visual-prolog.com/link/examples.php?version=11 Demo Examples].&lt;br /&gt;
&lt;br /&gt;
== Build 1105 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* {{lang|Suspending Predicates|Suspending Predicates}}&lt;br /&gt;
* {{lang2|Attributes|feature|feature}} attribute, built-in predicate &amp;lt;vp&amp;gt;is_feature_available&amp;lt;/vp&amp;gt;, compiler option &amp;#039;&amp;#039;&amp;#039;/ENABLEFEature:feature_name&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Built-in predicates &amp;lt;vp&amp;gt;convertAllowNull&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;tryConvertAllowNull&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Built-in constants &amp;lt;interface&amp;gt;&amp;lt;vp&amp;gt;::null&amp;lt;/vp&amp;gt; for all interfaces&lt;br /&gt;
* Warning: explicit &amp;lt;vp&amp;gt;programmingPoint&amp;lt;/vp&amp;gt; available&lt;br /&gt;
* Embedded string8 (utf8) support (literals and conversions)&lt;br /&gt;
* Warning c665 for a fact which is always initialized with a constant and is not changed (switched off by the default)&lt;br /&gt;
* Digit separator support (syntax only) &amp;lt;vp&amp;gt;1_000_000&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;0x_1A2B_3C4D&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Support for asynchronous programming by means of suspending predicates:&lt;br /&gt;
** New: &amp;lt;vp&amp;gt;executionContext_pool&amp;lt;/vp&amp;gt; a multi threaded pool for asynchronous and background work&lt;br /&gt;
** New: &amp;lt;vp&amp;gt;executionContext_single&amp;lt;/vp&amp;gt; a single threaded worker for asynchronous work&lt;br /&gt;
** New: Suspending predicates can be executed in a GUI thread (using &amp;lt;vp&amp;gt;future::submit&amp;lt;/vp&amp;gt;)&lt;br /&gt;
** New: Diverse suspending predicate domains in &amp;lt;vp&amp;gt;core&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;asyncSocket&amp;lt;/vp&amp;gt; &amp;amp; &amp;lt;vp&amp;gt;asyncSocketListener&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: master/slave support&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;promise&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: HTTP server &amp;amp; JSON RPC &amp;amp; &amp;lt;vp&amp;gt;webSocket&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;webView2&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;watchDirectory&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Removed: &amp;lt;vp&amp;gt;continuation&amp;lt;/vp&amp;gt; class and inteface due to redundancy.&lt;br /&gt;
** Removed: &amp;lt;vp&amp;gt;threadpool&amp;lt;/vp&amp;gt; and all related classes and interfaces due to redundancy.&lt;br /&gt;
** New support class: &amp;lt;vp&amp;gt;resumable&amp;lt;/vp&amp;gt; class for internal support of suspending predicates&lt;br /&gt;
** New support classes: &amp;lt;vp&amp;gt;tp&amp;lt;/vp&amp;gt; (etc) internal win32 threadpool interface for dealing with asynchronous io, timers, syncObject waiting, etc&lt;br /&gt;
** Deprecated/removed diverse continuation based stuff&lt;br /&gt;
* MSXML import free threaded xmlhttp: including &amp;lt;vp&amp;gt;iXMLHTTPRequest3&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Predicate &amp;lt;vp&amp;gt;messageBox::displayWarningYesNo_dt&amp;lt;/vp&amp;gt; replacement for &amp;lt;vp&amp;gt;displayWarning_dt&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Deprecate &amp;lt;vp&amp;gt;messageBox::displayWarning_dt&amp;lt;/vp&amp;gt;: UX: It is reccomended to use Yes/No warnings instead of OK/Cancel&lt;br /&gt;
* Color predicates &amp;lt;vp&amp;gt;blendColor&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;darken&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;lighten&amp;lt;/vp&amp;gt; in &amp;lt;vp&amp;gt;gdiplus&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;fetchString8asString&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;useLocalTimeValue&amp;lt;/vp&amp;gt; properties on &amp;lt;vp&amp;gt;odbcConnection&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;odbcStatement&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;delayCallLimit&amp;lt;/vp&amp;gt; predicate on &amp;lt;vp&amp;gt;window&amp;lt;/vp&amp;gt; for delay calls with a MaxDelay.&lt;br /&gt;
* &amp;lt;vp&amp;gt;inputStream_binary&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;outputStream_binary&amp;lt;/vp&amp;gt; supports/allows ansi(utf8) mode.&lt;br /&gt;
* Improved &amp;lt;vp&amp;gt;outputStream&amp;lt;/vp&amp;gt; performance for &amp;lt;vp&amp;gt;messageControl&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;event0&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;event1&amp;lt;/vp&amp;gt;, ... classes: lock free threadsafe.&lt;br /&gt;
* &amp;#039;Sergoe Fluent Icons&amp;#039;/&amp;#039;Segoe MDL2 Assets&amp;#039; glyph icons in ribbonControl/commands&lt;br /&gt;
* Explorer theme is applied to &amp;lt;vp&amp;gt;treeControl&amp;lt;/vp&amp;gt; by default.&lt;br /&gt;
* &amp;lt;vp&amp;gt;monitorQueue&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;monitorQueue_length&amp;lt;/vp&amp;gt; are updated with &amp;lt;vp&amp;gt;close&amp;lt;/vp&amp;gt; functionality.  As a result the &amp;lt;vp&amp;gt;dequeue&amp;lt;/vp&amp;gt; operation has become determ.&lt;br /&gt;
* Console projects supports [https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences Console Virtual Terminal Sequences] (by off default).&lt;br /&gt;
* flag &amp;lt;vp&amp;gt;jsonRpcApi{@Context}::exceptionTraceLevel&amp;lt;/vp&amp;gt; controlling which/when exception dumps that are send to the client side.&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* Main IDE is now always 64bit&lt;br /&gt;
* [[Ide/Debugger#Debug_Adapter|Debug Adapter]] makes cross-debugging to 32bit possible&lt;br /&gt;
* Dynamic Help (based on browse information and syntax parsing results)&lt;br /&gt;
* New toolbar&lt;br /&gt;
* vipId support&lt;br /&gt;
* Use new Sergoe Fluent Icons&lt;br /&gt;
* Default SDI project includes &amp;#039;Sergoe Fluent Icons&amp;#039;/&amp;#039;Segoe MDL2 Assets&amp;#039; glyph icons the ribbonControl/commands&lt;br /&gt;
* Add variable $(node_modules)&lt;br /&gt;
* New Menu item handlers (move code expert to properties window)&lt;br /&gt;
* Alt+X converts (unicode) hex to char&lt;br /&gt;
* changes.htm and appData\doc\vip.chm handling&lt;br /&gt;
* Updated Welcome window&lt;br /&gt;
* splitterControl in welcome page&lt;br /&gt;
* Build system: pre-build command&lt;br /&gt;
* Automatic parallel obj/deb directories&lt;br /&gt;
&lt;br /&gt;
=== Debugger ===&lt;br /&gt;
&lt;br /&gt;
* Debugging now uses a [[Ide/Debugger#Debug_Adapter|Debug Adapter]]&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
* Remove superfluous webRpc demo &amp;amp; update webServiceDemo to dispose the session.&lt;br /&gt;
* The &amp;lt;vp&amp;gt;webServiceDemo&amp;lt;/vp&amp;gt; is updated to demonstrate usage of the flag &amp;lt;vp&amp;gt;jsonRpcApi{@Context}::exceptionTraceLevel&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Build 1106 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Subtype presenter problem&lt;br /&gt;
* Fix: Stack overflow exception on binary constant allocation&lt;br /&gt;
* Fix: Wrong debug info for unbound variable (functor component)&lt;br /&gt;
* Fix: Debugger/presenters: false objects&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* webView2&lt;br /&gt;
** Fix: Windows 7 and Windows 8 compatibility./li&amp;gt;&lt;br /&gt;
** Additional CompleteHandler handling (suspending predicates).&lt;br /&gt;
* Fix: &amp;lt;vp&amp;gt;ribbonControl&amp;lt;/vp&amp;gt;: Release native graphics context.&lt;br /&gt;
* odbc: add column/parameter number for results longer than the buffer.&lt;br /&gt;
* &amp;lt;vp&amp;gt;window::centerTo&amp;lt;/vp&amp;gt;: map to Windows parent (not pfc parent).&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;webView2&amp;lt;/vp&amp;gt; control show on Windows 7/8 &amp;amp; update build number&lt;br /&gt;
* show correct build number&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;comWrap&amp;lt;/vp&amp;gt;: Handle more winRT CompleteHandlers (for webView2)&lt;br /&gt;
* Fix: Runtime debugger/presenters: false objects&lt;br /&gt;
&lt;br /&gt;
== Build 1107 ==&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* New class &amp;lt;vp&amp;gt;gcUcBuffer&amp;lt;/vp&amp;gt;: for buffers that cannot be caught by false pointers.&lt;br /&gt;
* odbc: utilize &amp;lt;vp&amp;gt;gcUcBuffer&amp;lt;/vp&amp;gt; to avoid that odbc buffers are caught by false pointers.&lt;br /&gt;
* New predicate &amp;lt;vp&amp;gt;clipBoard::putFileList&amp;lt;/vp&amp;gt; for putting files on the clipboard in the pre-defined hDrop format.&lt;br /&gt;
* &amp;lt;vp&amp;gt;command&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;ribbonControl&amp;lt;/vp&amp;gt;: new responder &amp;lt;vp&amp;gt;queryBadgeState&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* Prevent &amp;lt;vp&amp;gt;vpi::processEvents&amp;lt;/vp&amp;gt; from interfering with &amp;lt;vp&amp;gt;postAction&amp;lt;/vp&amp;gt; order.&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* Personal edition supports 64 bit targets.&lt;br /&gt;
* Open external browser for registration, wiki-help and forum links.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Help -&amp;gt; Prolog Foundation Classes (PFC)&amp;#039;&amp;#039;&amp;#039; opens vip.chm.&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
Fix: MemoryProfiler wrong scaling of total graph.&lt;br /&gt;
&lt;br /&gt;
== Build 1108 ==&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* New property &amp;lt;vp&amp;gt;remoteAddress&amp;lt;/vp&amp;gt; on interface &amp;lt;vp&amp;gt;httpRequest&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* New predicate &amp;lt;vp&amp;gt;memory::mkCopy_atomic&amp;lt;/vp&amp;gt; for copying structs.&lt;br /&gt;
* New predicates &amp;lt;vp&amp;gt;formatSocketAddress&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;formatSockAddr&amp;lt;/vp&amp;gt; in class &amp;lt;vp&amp;gt;winSock2_api&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;winSock2_api&amp;lt;/vp&amp;gt; correct and simplify various domains.&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Exceptions when git is not installed.&lt;br /&gt;
&lt;br /&gt;
== Build 1110 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;match&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;case&amp;lt;/vp&amp;gt; has been reserved as keywords in next major release.&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Wrong type of parameter type in predicate &amp;lt;vp&amp;gt;winHttp_native::winHttpSetOption&amp;lt;/vp&amp;gt; declaration.&lt;br /&gt;
* Fix: Eliminate race condition for &amp;lt;vp&amp;gt;postAction&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* Deprecate &amp;lt;vp&amp;gt;time::getTickCount&amp;lt;/vp&amp;gt; in favour of &amp;lt;vp&amp;gt;performanceCounter&amp;lt;/vp&amp;gt;&amp;#039;s.&lt;br /&gt;
* Deprecate &amp;lt;vp&amp;gt;regEx::match&amp;lt;/vp&amp;gt; because &amp;lt;vp&amp;gt;match&amp;lt;/vp&amp;gt; will become a keyword.&lt;br /&gt;
&lt;br /&gt;
== Build 1111 ==&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Fix: time_api::getTimeZoneOffset hours -&amp;gt; minutes&lt;br /&gt;
* Fix: odbcStatement::free: allow to be called more than once&lt;br /&gt;
* Fix: stringFormat (gdiplus): nullary constructor must create a fresh object&lt;br /&gt;
&lt;br /&gt;
=== Debugger ===&lt;br /&gt;
&lt;br /&gt;
Fix: Dictionary loading timeout for large programs in debug adaptor&lt;br /&gt;
&lt;br /&gt;
== Build 1112 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Access violation for suspending &amp;lt;vp&amp;gt;getMember_susp_nd&amp;lt;/vp&amp;gt; predicate.&lt;br /&gt;
* Fix: Syntax error for &amp;lt;vp&amp;gt;language as&amp;lt;/vp&amp;gt; with subtype bounds&lt;br /&gt;
* Fix: 32 bit code problem for bounded polymorphism: &amp;lt;vp&amp;gt;where Key supports unsigned64&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Fix: unification of two patters &amp;lt;vp&amp;gt;[As, [X]] = [[X], Bs] &amp;lt;/vp&amp;gt;&lt;br /&gt;
* Fix: Optional out for predicate defined by predicate domain&lt;br /&gt;
* Fix: default argument functor from domain in generic interface&lt;br /&gt;
* Fix: Problem locating correct predicate with arity (from different scopls)&lt;br /&gt;
* Fix: code generation bug for backtracking handling.&lt;br /&gt;
&lt;br /&gt;
The fixes above solves the problems mentioned in [https://discuss.visual-prolog.com/viewtopic.php?f=2&amp;amp;t=20231 Some minor details in VIP 11 build 1111].&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Fix: window::delayCall wrong handling of Id.&lt;br /&gt;
* Fix: Better presenter for core::timeout.&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
* New: More relaxed commas in parser for vipPP to auto-correct (change in vip parser)&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
See also [[Visual Prolog 11 Upgrade Notes]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Release Notes|11 New Features]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Shadowing_PFC_files&amp;diff=4982</id>
		<title>Shadowing PFC files</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Shadowing_PFC_files&amp;diff=4982"/>
		<updated>2025-02-11T16:15:46Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: initial version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Sometimes you wan&amp;#039;t to &amp;#039;&amp;#039;&amp;#039;shadow&amp;#039;&amp;#039;&amp;#039; one or more of the official PFC files with your own files.&lt;br /&gt;
&lt;br /&gt;
Here is a way to do this in a &amp;quot;gentle&amp;quot; way.&lt;br /&gt;
&lt;br /&gt;
Let us for the example assume that I want to use my own version of the &amp;lt;vp&amp;gt;list&amp;lt;/vp&amp;gt; package.&lt;br /&gt;
&lt;br /&gt;
Before doing anything my project tree looks like this:&lt;br /&gt;
&lt;br /&gt;
[[File:Initial project tree.png|center|Initial project tree]]&lt;br /&gt;
&lt;br /&gt;
My project is named &amp;#039;&amp;#039;&amp;#039;shadow_demo&amp;#039;&amp;#039;&amp;#039; and is located in &amp;#039;&amp;#039;&amp;#039;D:\demo\projects\shadow_demo&amp;#039;&amp;#039;&amp;#039; and I want to place my shadow version of the list package inside the directory &amp;#039;&amp;#039;&amp;#039;D:\demo\shadow&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
This original files are located in the &amp;lt;vp&amp;gt;$(ProDir)\list&amp;lt;/vp&amp;gt; directory where &amp;lt;vp&amp;gt;$(ProDir)&amp;lt;/vp&amp;gt; is where where my Visual Prolog is installed.&lt;br /&gt;
&lt;br /&gt;
Notice that you can open a file explorer in this directory by selecting the &amp;lt;vp&amp;gt;$(ProDir)&amp;lt;/vp&amp;gt; node in the project tree and select &amp;#039;&amp;#039;&amp;#039;Explore ...  (Ctrl+E)&amp;#039;&amp;#039;&amp;#039; in its context menu.&lt;br /&gt;
&lt;br /&gt;
For this &amp;quot;shadow&amp;quot; method it is important that my own files are placed in the same structure as in the original &amp;#039;&amp;#039;&amp;#039;pfc&amp;#039;&amp;#039;&amp;#039; directory (including the &amp;#039;&amp;#039;&amp;#039;pfc&amp;#039;&amp;#039;&amp;#039; level). So I copy the original &amp;#039;&amp;#039;&amp;#039;list&amp;#039;&amp;#039;&amp;#039; files to my the directory &amp;#039;&amp;#039;&amp;#039;D:\demo\shadow\pfc\list&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
I want my copied files to shadow the original pfc files and therefore I add the &amp;#039;&amp;#039;&amp;#039;D:\demo\shadow&amp;#039;&amp;#039;&amp;#039; directory as an &amp;#039;&amp;#039;&amp;#039;Include Directory&amp;#039;&amp;#039;&amp;#039; in my project (it will appear with a relative path):&lt;br /&gt;
&lt;br /&gt;
[[File:Include directories shadow added.png|center|Include directories: shadow directory added]]&lt;br /&gt;
&lt;br /&gt;
It is important that the &amp;#039;&amp;#039;&amp;#039;shadow&amp;#039;&amp;#039;&amp;#039; include directory is placed &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;above&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; the &amp;lt;vp&amp;gt;$(ProDir)&amp;lt;/vp&amp;gt;, so that files found here are used instead of filed found in &amp;lt;vp&amp;gt;$(ProDir)&amp;lt;/vp&amp;gt;.  I.e. that they &amp;#039;&amp;#039;shadow&amp;#039;&amp;#039; the original pfc files.&lt;br /&gt;
&lt;br /&gt;
At this point it is important to delete the original &amp;lt;vp&amp;gt;$(ProDir)\pfc\list\list.pack&amp;lt;/vp&amp;gt; from the project otherwise you may easily end up with &amp;quot;Symbol redefinition&amp;quot; link errors:&lt;br /&gt;
&lt;br /&gt;
[[File:Symbol redefinition errors.png|center|Symbol redefinition link errors]]&lt;br /&gt;
&lt;br /&gt;
After I have deleted the &amp;lt;vp&amp;gt;$(ProDir)\pfc\list\list.pack&amp;lt;/vp&amp;gt; file from the project and rebuild the project I was met by an &amp;quot;Add required &amp;quot; dialog:&lt;br /&gt;
&lt;br /&gt;
[[File:Add required shadow list.png|center|Add required shadow list package]]&lt;br /&gt;
&lt;br /&gt;
And I added the package.  Now the project tree (actually, after closing and reopening the project in the IDE) looks like this:&lt;br /&gt;
&lt;br /&gt;
[[File:After rebuild.png|center|After rebuild (shadow appearing in project tree)]]&lt;br /&gt;
&lt;br /&gt;
The list package no longer appears in the &amp;lt;vp&amp;gt;$(ProDir)&amp;lt;/vp&amp;gt; directory.  But now I have a list package in &amp;#039;&amp;#039;&amp;#039;..\..\shadow\pfc\list&amp;#039;&amp;#039;&amp;#039; and these files will then be used instead of the original pfc files in the project.  And I can modify them as I want.&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=File:After_rebuild.png&amp;diff=4981</id>
		<title>File:After rebuild.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=File:After_rebuild.png&amp;diff=4981"/>
		<updated>2025-02-11T16:14:59Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Thomas Linder Puls uploaded a new version of File:After rebuild.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;After rebuild (shadow list appearing)&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=File:Add_required_shadow_list.png&amp;diff=4980</id>
		<title>File:Add required shadow list.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=File:Add_required_shadow_list.png&amp;diff=4980"/>
		<updated>2025-02-11T16:13:19Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Thomas Linder Puls uploaded a new version of File:Add required shadow list.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Add required shadow list package&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=File:Symbol_redefinition_errors.png&amp;diff=4979</id>
		<title>File:Symbol redefinition errors.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=File:Symbol_redefinition_errors.png&amp;diff=4979"/>
		<updated>2025-02-11T16:11:28Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Thomas Linder Puls uploaded a new version of File:Symbol redefinition errors.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Symbol redefinition errors&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=File:Include_directories_shadow_added.png&amp;diff=4978</id>
		<title>File:Include directories shadow added.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=File:Include_directories_shadow_added.png&amp;diff=4978"/>
		<updated>2025-02-11T16:09:04Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Thomas Linder Puls uploaded a new version of File:Include directories shadow added.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Include directories shadow directory added&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=File:Initial_project_tree.png&amp;diff=4977</id>
		<title>File:Initial project tree.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=File:Initial_project_tree.png&amp;diff=4977"/>
		<updated>2025-02-11T16:06:52Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Thomas Linder Puls uploaded a new version of File:Initial project tree.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Initial project tree&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=File:Include_directories_shadow_added.png&amp;diff=4976</id>
		<title>File:Include directories shadow added.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=File:Include_directories_shadow_added.png&amp;diff=4976"/>
		<updated>2025-02-11T16:01:33Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Thomas Linder Puls uploaded a new version of File:Include directories shadow added.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Include directories shadow directory added&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=File:Symbol_redefinition_errors.png&amp;diff=4975</id>
		<title>File:Symbol redefinition errors.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=File:Symbol_redefinition_errors.png&amp;diff=4975"/>
		<updated>2025-02-11T15:34:24Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Symbol redefinition errors&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=File:After_rebuild.png&amp;diff=4974</id>
		<title>File:After rebuild.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=File:After_rebuild.png&amp;diff=4974"/>
		<updated>2025-02-11T15:18:51Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;After rebuild (shadow list appearing)&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=File:Add_required_shadow_list.png&amp;diff=4973</id>
		<title>File:Add required shadow list.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=File:Add_required_shadow_list.png&amp;diff=4973"/>
		<updated>2025-02-11T15:16:51Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Add required shadow list package&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=File:Include_directories_shadow_added.png&amp;diff=4972</id>
		<title>File:Include directories shadow added.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=File:Include_directories_shadow_added.png&amp;diff=4972"/>
		<updated>2025-02-11T15:13:25Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Include directories shadow directory added&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=File:Initial_project_tree.png&amp;diff=4971</id>
		<title>File:Initial project tree.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=File:Initial_project_tree.png&amp;diff=4971"/>
		<updated>2025-02-11T15:10:02Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Initial project tree&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_11_New_Features&amp;diff=4970</id>
		<title>Visual Prolog 11 New Features</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_11_New_Features&amp;diff=4970"/>
		<updated>2025-02-03T12:07:43Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Build 1112&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Visual Prolog 11 has been extended with {{lang|Suspending Predicates|Suspending Predicates}}.&lt;br /&gt;
&lt;br /&gt;
The development system can only run on 64 bit Windows, but can still build programs for both 32 and 64 bit Windows.&lt;br /&gt;
&lt;br /&gt;
New utility &amp;quot;[[vipLaunch]]&amp;quot; for launching projects in correct IDE.  The installer is included in the Visual Prolog 11 installer, but you can also install the latest version directly here [https://www.visual-prolog.com/link/vipLaunch.php vipLaunch installer].&lt;br /&gt;
&lt;br /&gt;
Download Visual Prolog 11 [https://www.visual-prolog.com/link/examples.php?version=11 Demo Examples].&lt;br /&gt;
&lt;br /&gt;
== Build 1105 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* {{lang|Suspending Predicates|Suspending Predicates}}&lt;br /&gt;
* {{lang2|Attributes|feature|feature}} attribute, built-in predicate &amp;lt;vp&amp;gt;is_feature_available&amp;lt;/vp&amp;gt;, compiler option &amp;#039;&amp;#039;&amp;#039;/ENABLEFEature:feature_name&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Built-in predicates &amp;lt;vp&amp;gt;convertAllowNull&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;tryConvertAllowNull&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Built-in constants &amp;lt;interface&amp;gt;&amp;lt;vp&amp;gt;::null&amp;lt;/vp&amp;gt; for all interfaces&lt;br /&gt;
* Warning: explicit &amp;lt;vp&amp;gt;programmingPoint&amp;lt;/vp&amp;gt; available&lt;br /&gt;
* Embedded string8 (utf8) support (literals and conversions)&lt;br /&gt;
* Warning c665 for a fact which is always initialized with a constant and is not changed (switched off by the default)&lt;br /&gt;
* Digit separator support (syntax only) &amp;lt;vp&amp;gt;1_000_000&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;0x_1A2B_3C4D&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Support for asynchronous programming by means of suspending predicates:&lt;br /&gt;
** New: &amp;lt;vp&amp;gt;executionContext_pool&amp;lt;/vp&amp;gt; a multi threaded pool for asynchronous and background work&lt;br /&gt;
** New: &amp;lt;vp&amp;gt;executionContext_single&amp;lt;/vp&amp;gt; a single threaded worker for asynchronous work&lt;br /&gt;
** New: Suspending predicates can be executed in a GUI thread (using &amp;lt;vp&amp;gt;future::submit&amp;lt;/vp&amp;gt;)&lt;br /&gt;
** New: Diverse suspending predicate domains in &amp;lt;vp&amp;gt;core&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;asyncSocket&amp;lt;/vp&amp;gt; &amp;amp; &amp;lt;vp&amp;gt;asyncSocketListener&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: master/slave support&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;promise&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: HTTP server &amp;amp; JSON RPC &amp;amp; &amp;lt;vp&amp;gt;webSocket&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;webView2&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;watchDirectory&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Removed: &amp;lt;vp&amp;gt;continuation&amp;lt;/vp&amp;gt; class and inteface due to redundancy.&lt;br /&gt;
** Removed: &amp;lt;vp&amp;gt;threadpool&amp;lt;/vp&amp;gt; and all related classes and interfaces due to redundancy.&lt;br /&gt;
** New support class: &amp;lt;vp&amp;gt;resumable&amp;lt;/vp&amp;gt; class for internal support of suspending predicates&lt;br /&gt;
** New support classes: &amp;lt;vp&amp;gt;tp&amp;lt;/vp&amp;gt; (etc) internal win32 threadpool interface for dealing with asynchronous io, timers, syncObject waiting, etc&lt;br /&gt;
** Deprecated/removed diverse continuation based stuff&lt;br /&gt;
* MSXML import free threaded xmlhttp: including &amp;lt;vp&amp;gt;iXMLHTTPRequest3&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Predicate &amp;lt;vp&amp;gt;messageBox::displayWarningYesNo_dt&amp;lt;/vp&amp;gt; replacement for &amp;lt;vp&amp;gt;displayWarning_dt&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Deprecate &amp;lt;vp&amp;gt;messageBox::displayWarning_dt&amp;lt;/vp&amp;gt;: UX: It is reccomended to use Yes/No warnings instead of OK/Cancel&lt;br /&gt;
* Color predicates &amp;lt;vp&amp;gt;blendColor&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;darken&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;lighten&amp;lt;/vp&amp;gt; in &amp;lt;vp&amp;gt;gdiplus&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;fetchString8asString&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;useLocalTimeValue&amp;lt;/vp&amp;gt; properties on &amp;lt;vp&amp;gt;odbcConnection&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;odbcStatement&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;delayCallLimit&amp;lt;/vp&amp;gt; predicate on &amp;lt;vp&amp;gt;window&amp;lt;/vp&amp;gt; for delay calls with a MaxDelay.&lt;br /&gt;
* &amp;lt;vp&amp;gt;inputStream_binary&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;outputStream_binary&amp;lt;/vp&amp;gt; supports/allows ansi(utf8) mode.&lt;br /&gt;
* Improved &amp;lt;vp&amp;gt;outputStream&amp;lt;/vp&amp;gt; performance for &amp;lt;vp&amp;gt;messageControl&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;event0&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;event1&amp;lt;/vp&amp;gt;, ... classes: lock free threadsafe.&lt;br /&gt;
* &amp;#039;Sergoe Fluent Icons&amp;#039;/&amp;#039;Segoe MDL2 Assets&amp;#039; glyph icons in ribbonControl/commands&lt;br /&gt;
* Explorer theme is applied to &amp;lt;vp&amp;gt;treeControl&amp;lt;/vp&amp;gt; by default.&lt;br /&gt;
* &amp;lt;vp&amp;gt;monitorQueue&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;monitorQueue_length&amp;lt;/vp&amp;gt; are updated with &amp;lt;vp&amp;gt;close&amp;lt;/vp&amp;gt; functionality.  As a result the &amp;lt;vp&amp;gt;dequeue&amp;lt;/vp&amp;gt; operation has become determ.&lt;br /&gt;
* Console projects supports [https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences Console Virtual Terminal Sequences] (by off default).&lt;br /&gt;
* flag &amp;lt;vp&amp;gt;jsonRpcApi{@Context}::exceptionTraceLevel&amp;lt;/vp&amp;gt; controlling which/when exception dumps that are send to the client side.&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* Main IDE is now always 64bit&lt;br /&gt;
* [[Ide/Debugger#Debug_Adapter|Debug Adapter]] makes cross-debugging to 32bit possible&lt;br /&gt;
* Dynamic Help (based on browse information and syntax parsing results)&lt;br /&gt;
* New toolbar&lt;br /&gt;
* vipId support&lt;br /&gt;
* Use new Sergoe Fluent Icons&lt;br /&gt;
* Default SDI project includes &amp;#039;Sergoe Fluent Icons&amp;#039;/&amp;#039;Segoe MDL2 Assets&amp;#039; glyph icons the ribbonControl/commands&lt;br /&gt;
* Add variable $(node_modules)&lt;br /&gt;
* New Menu item handlers (move code expert to properties window)&lt;br /&gt;
* Alt+X converts (unicode) hex to char&lt;br /&gt;
* changes.htm and appData\doc\vip.chm handling&lt;br /&gt;
* Updated Welcome window&lt;br /&gt;
* splitterControl in welcome page&lt;br /&gt;
* Build system: pre-build command&lt;br /&gt;
* Automatic parallel obj/deb directories&lt;br /&gt;
&lt;br /&gt;
=== Debugger ===&lt;br /&gt;
&lt;br /&gt;
* Debugging now uses a [[Ide/Debugger#Debug_Adapter|Debug Adapter]]&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
* Remove superfluous webRpc demo &amp;amp; update webServiceDemo to dispose the session.&lt;br /&gt;
* The &amp;lt;vp&amp;gt;webServiceDemo&amp;lt;/vp&amp;gt; is updated to demonstrate usage of the flag &amp;lt;vp&amp;gt;jsonRpcApi{@Context}::exceptionTraceLevel&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* Add zip / unzip functionality&lt;br /&gt;
&lt;br /&gt;
== Build 1106 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Subtype presenter problem&lt;br /&gt;
* Fix: Stack overflow exception on binary constant allocation&lt;br /&gt;
* Fix: Wrong debug info for unbound variable (functor component)&lt;br /&gt;
* Fix: Debugger/presenters: false objects&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* webView2&lt;br /&gt;
** Fix: Windows 7 and Windows 8 compatibility./li&amp;gt;&lt;br /&gt;
** Additional CompleteHandler handling (suspending predicates).&lt;br /&gt;
* Fix: &amp;lt;vp&amp;gt;ribbonControl&amp;lt;/vp&amp;gt;: Release native graphics context.&lt;br /&gt;
* odbc: add column/parameter number for results longer than the buffer.&lt;br /&gt;
* &amp;lt;vp&amp;gt;window::centerTo&amp;lt;/vp&amp;gt;: map to Windows parent (not pfc parent).&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;webView2&amp;lt;/vp&amp;gt; control show on Windows 7/8 &amp;amp; update build number&lt;br /&gt;
* show correct build number&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;comWrap&amp;lt;/vp&amp;gt;: Handle more winRT CompleteHandlers (for webView2)&lt;br /&gt;
* Fix: Runtime debugger/presenters: false objects&lt;br /&gt;
&lt;br /&gt;
== Build 1107 ==&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* New class &amp;lt;vp&amp;gt;gcUcBuffer&amp;lt;/vp&amp;gt;: for buffers that cannot be caught by false pointers.&lt;br /&gt;
* odbc: utilize &amp;lt;vp&amp;gt;gcUcBuffer&amp;lt;/vp&amp;gt; to avoid that odbc buffers are caught by false pointers.&lt;br /&gt;
* New predicate &amp;lt;vp&amp;gt;clipBoard::putFileList&amp;lt;/vp&amp;gt; for putting files on the clipboard in the pre-defined hDrop format.&lt;br /&gt;
* &amp;lt;vp&amp;gt;command&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;ribbonControl&amp;lt;/vp&amp;gt;: new responder &amp;lt;vp&amp;gt;queryBadgeState&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* Prevent &amp;lt;vp&amp;gt;vpi::processEvents&amp;lt;/vp&amp;gt; from interfering with &amp;lt;vp&amp;gt;postAction&amp;lt;/vp&amp;gt; order.&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* Personal edition supports 64 bit targets.&lt;br /&gt;
* Open external browser for registration, wiki-help and forum links.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Help -&amp;gt; Prolog Foundation Classes (PFC)&amp;#039;&amp;#039;&amp;#039; opens vip.chm.&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
Fix: MemoryProfiler wrong scaling of total graph.&lt;br /&gt;
&lt;br /&gt;
== Build 1108 ==&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* New property &amp;lt;vp&amp;gt;remoteAddress&amp;lt;/vp&amp;gt; on interface &amp;lt;vp&amp;gt;httpRequest&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* New predicate &amp;lt;vp&amp;gt;memory::mkCopy_atomic&amp;lt;/vp&amp;gt; for copying structs.&lt;br /&gt;
* New predicates &amp;lt;vp&amp;gt;formatSocketAddress&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;formatSockAddr&amp;lt;/vp&amp;gt; in class &amp;lt;vp&amp;gt;winSock2_api&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;winSock2_api&amp;lt;/vp&amp;gt; correct and simplify various domains.&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Exceptions when git is not installed.&lt;br /&gt;
&lt;br /&gt;
== Build 1110 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;match&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;case&amp;lt;/vp&amp;gt; has been reserved as keywords in next major release.&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Wrong type of parameter type in predicate &amp;lt;vp&amp;gt;winHttp_native::winHttpSetOption&amp;lt;/vp&amp;gt; declaration.&lt;br /&gt;
* Fix: Eliminate race condition for &amp;lt;vp&amp;gt;postAction&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* Deprecate &amp;lt;vp&amp;gt;time::getTickCount&amp;lt;/vp&amp;gt; in favour of &amp;lt;vp&amp;gt;performanceCounter&amp;lt;/vp&amp;gt;&amp;#039;s.&lt;br /&gt;
* Deprecate &amp;lt;vp&amp;gt;regEx::match&amp;lt;/vp&amp;gt; because &amp;lt;vp&amp;gt;match&amp;lt;/vp&amp;gt; will become a keyword.&lt;br /&gt;
&lt;br /&gt;
== Build 1111 ==&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Fix: time_api::getTimeZoneOffset hours -&amp;gt; minutes&lt;br /&gt;
* Fix: odbcStatement::free: allow to be called more than once&lt;br /&gt;
* Fix: stringFormat (gdiplus): nullary constructor must create a fresh object&lt;br /&gt;
&lt;br /&gt;
=== Debugger ===&lt;br /&gt;
&lt;br /&gt;
Fix: Dictionary loading timeout for large programs in debug adaptor&lt;br /&gt;
&lt;br /&gt;
== Build 1112 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Access violation for suspending &amp;lt;vp&amp;gt;getMember_susp_nd&amp;lt;/vp&amp;gt; predicate.&lt;br /&gt;
* Fix: Syntax error for &amp;lt;vp&amp;gt;language as&amp;lt;/vp&amp;gt; with subtype bounds&lt;br /&gt;
* Fix: 32 bit code problem for bounded polymorphism: &amp;lt;vp&amp;gt;where Key supports unsigned64&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Fix: unification of two patters &amp;lt;vp&amp;gt;[As, [X]] = [[X], Bs] &amp;lt;/vp&amp;gt;&lt;br /&gt;
* Fix: Optional out for predicate defined by predicate domain&lt;br /&gt;
* Fix: default argument functor from domain in generic interface&lt;br /&gt;
* Fix: Problem locating correct predicate with arity (from different scopls)&lt;br /&gt;
* Fix: code generation bug for backtracking handling.&lt;br /&gt;
&lt;br /&gt;
The fixes above solves the problems mentioned in [https://discuss.visual-prolog.com/viewtopic.php?f=2&amp;amp;t=20231 Some minor details in VIP 11 build 1111].&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Fix: window::delayCall wrong handling of Id.&lt;br /&gt;
* Fix: Better presenter for core::timeout.&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
* New: More relaxed commas in parser for vipPP to auto-correct (change in vip parser)&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
See also [[Visual Prolog 11 Upgrade Notes]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Release Notes|11 New Features]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Thread_safety_in_Visual_Prolog&amp;diff=4969</id>
		<title>Thread safety in Visual Prolog</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Thread_safety_in_Visual_Prolog&amp;diff=4969"/>
		<updated>2024-11-05T09:45:09Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: mapM/setM&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Thread safe:&lt;br /&gt;
&lt;br /&gt;
* Access facts&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Not&amp;#039;&amp;#039;&amp;#039; thread safe:&lt;br /&gt;
&lt;br /&gt;
* GUI&lt;br /&gt;
* Streams&lt;br /&gt;
* odbcConnection/odbcStatement&lt;br /&gt;
&lt;br /&gt;
=== Facts ===&lt;br /&gt;
&lt;br /&gt;
See [[Threadsafe facts]].&lt;br /&gt;
&lt;br /&gt;
=== GUI ===&lt;br /&gt;
&lt;br /&gt;
Windows GUI is not thread safe, only the thread that runs the message pump of a window should accees that window.  In Visual Prolog all windows (except modal dialogs) belong to the thread that have executed the &amp;lt;vp&amp;gt;vpi::init&amp;lt;/vp&amp;gt; call.&lt;br /&gt;
&lt;br /&gt;
Synchronization back to the GUI thread can be done using &amp;#039;&amp;#039;&amp;#039;window::postAction&amp;#039;&amp;#039;&amp;#039;, because the posted action will be executed by the GUI thread.&lt;br /&gt;
&lt;br /&gt;
Modal dialogs run their own message pump and they are therefore owned by the thread that displays them.&lt;br /&gt;
&lt;br /&gt;
=== Streams ===&lt;br /&gt;
&lt;br /&gt;
Streams are in general not thread safe, but specific streams can be.&lt;br /&gt;
&lt;br /&gt;
From Visual Prolog 7.4 the thread on &amp;lt;vp&amp;gt;messageControl&amp;lt;/vp&amp;gt;s are thread safe.  In a GUI application stdio will thus be thread safe while it is redirected to a &amp;lt;vp&amp;gt;messageControl&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;messageForm&amp;lt;/vp&amp;gt;, but if it is redirected to some other stream it will &amp;quot;inherit&amp;quot; the thread safety from that stream.&lt;br /&gt;
&lt;br /&gt;
=== ODBC ===&lt;br /&gt;
&lt;br /&gt;
An &amp;lt;vp&amp;gt;odbcConnection&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;odbcStatement&amp;lt;/vp&amp;gt; is not thread safe, but different &amp;lt;vp&amp;gt;odbcConnection&amp;lt;/vp&amp;gt;&amp;#039;s/&amp;lt;vp&amp;gt;odbcStatement&amp;lt;/vp&amp;gt;&amp;#039;s can be accessed in parallel.&lt;br /&gt;
&lt;br /&gt;
=== mapM and setM ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;mapM&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;setM&amp;lt;/vp&amp;gt; each exist in two threadsafe versions.  Here we will just consider the mapM versions (the setM behaves completely similarly).  Most operations on red-black trees are already threadsafe.  The classes mentioned here ensures that updates are &amp;quot;sound&amp;quot;: If you set/add/delete something it will in fact be set/added/deleted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;mapM_redBlack_cas&amp;lt;/vp&amp;gt; uses &amp;lt;vp&amp;gt;compareAndSwap&amp;lt;/vp&amp;gt; (see also [https://learn.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-interlockedcompareexchange InterlockedCompareExchange]).  If two threads are updating the map simultaneously there is a chance that one of the &amp;lt;vp&amp;gt;compareAndSwap&amp;lt;/vp&amp;gt; will fail (the swap only takes place if the current tree is the same that this thread updated).  If that happens the operation will be performed once more on what is now the current tree.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;mapM_redBlack_block&amp;lt;/vp&amp;gt; uses a &amp;lt;vp&amp;gt;multiThread_native::srwLock&amp;lt;/vp&amp;gt; (see also [https://learn.microsoft.com/en-us/windows/win32/sync/slim-reader-writer--srw--locks Slim Reader/Writer (SRW) Locks]) to block threads that tries to update the map while another thread is already updating the thread.&lt;br /&gt;
&lt;br /&gt;
So in case of collisions the &amp;lt;vp&amp;gt;mapM_redBlack_cas&amp;lt;/vp&amp;gt; will use extra resources (CPU, memory allocations, etc) whereas the &amp;lt;vp&amp;gt;mapM_redBlack_block&amp;lt;/vp&amp;gt; will block a thread instead.  If there are few collision then the &amp;lt;vp&amp;gt;_cas&amp;lt;/vp&amp;gt; version will not waste much time and no threads will be blocked and involve the operating systems thread scheduling mechanism.  If there are many collisions then the &amp;lt;vp&amp;gt;_block&amp;lt;/vp&amp;gt; version will go easy on CPU, memory and instead involve the task scheduling mechanism.&lt;br /&gt;
&lt;br /&gt;
Notice that if you have really many collisions then you have a problem in any case, because then your threads will either spend resources or wait all the time. In the first case there will be a large load on you computer, in the second case the benefit you hoped for using many threads will disappear in waiting.&lt;br /&gt;
&lt;br /&gt;
[[Category:Multi-threading]]&lt;br /&gt;
[[Category:GUI]]&lt;br /&gt;
[[Category:ODBC]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Master/slave_processes&amp;diff=4968</id>
		<title>Master/slave processes</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Master/slave_processes&amp;diff=4968"/>
		<updated>2024-10-15T11:32:21Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: review&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The PFC master/slave process concept can be used for a number of reasons:&lt;br /&gt;
&lt;br /&gt;
* To make computations in parallel&lt;br /&gt;
* To isolate computations from each other&lt;br /&gt;
* To manage independent subprocesses&lt;br /&gt;
&lt;br /&gt;
=== Master/slave concepts ===&lt;br /&gt;
&lt;br /&gt;
Master/slave processes are organized hierarchically:&lt;br /&gt;
&lt;br /&gt;
* A master process can have several slave processes&lt;br /&gt;
* Each slave process has exactly one master process.&lt;br /&gt;
* A slave process can be master process of other slave processes.&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;master&amp;#039;&amp;#039;&amp;#039; process spawns and owns the &amp;#039;&amp;#039;&amp;#039;slave&amp;#039;&amp;#039;&amp;#039; processes.&lt;br /&gt;
&lt;br /&gt;
A master and slave process can communicate with each other using remote procedure calls and notifications.  All communication is serialized on pipes that are established between the master and the slave.&lt;br /&gt;
&lt;br /&gt;
The communication is (quite) transparent to the programs, in the master process the slave is represented by a proxy object; calls and notifications from the master to the slave is performed by invoking methods on the proxy object.  Likewise the master is represented by a proxy object in the slave and calls and notifications from slave to master are made on the proxy object.&lt;br /&gt;
&lt;br /&gt;
All methods are asynchronous (using an &amp;lt;vp&amp;gt;executionContext_pool&amp;lt;/vp&amp;gt; as execution context), so {{lang|Suspending Predicates|suspending predicates}} must be applied.  And synchronization to non-threadsafe structures must be used.  &amp;lt;vp&amp;gt;postAction&amp;lt;/vp&amp;gt; will have to be used to switch execution context to the GUI thread for GUI operations (and in many applications for safe access to program state).&lt;br /&gt;
&lt;br /&gt;
The master/slave process concept is illustrated by a demo project.  In the demo project the master is a builder similar to the &amp;#039;&amp;#039;&amp;#039;vipBuilder&amp;#039;&amp;#039;&amp;#039;. This master spawns a number of compiler/slave processes.&lt;br /&gt;
&lt;br /&gt;
The demo is academic in the sense that nothing is really build; the &amp;quot;compilers&amp;quot; merely simulate that they do something.&lt;br /&gt;
&lt;br /&gt;
Notice that the demo program uses the name space &amp;lt;vp&amp;gt;compiler_ms&amp;lt;/vp&amp;gt; for interfaces and classes used in the process interface.  For simplicity the name space declarations are not included in this article.&lt;br /&gt;
&lt;br /&gt;
The compiler/slave has this interface:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface slave&lt;br /&gt;
    open core&lt;br /&gt;
    [pfc\masterSlaveProcess::slave]&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    compile_rsp = compile_rsp(integer LineCount, integer Errors, durationValue CompilationTime).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    compile : (string Filename) -&amp;gt; compile_rsp CompileResult suspending.&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    setSettings : (string Settings) -&amp;gt; unit suspending.&lt;br /&gt;
&lt;br /&gt;
end interface slave&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that in this academic example the interface name is &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt;. In a real program it would be more natural to call it e.g. &amp;lt;vp&amp;gt;compiler_slave&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
We will consider the details of this interface below, currently the interesting thing is that it defines procedures &amp;lt;vp&amp;gt;compile&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;setSettings&amp;lt;/vp&amp;gt;.  Notice that they are {{lang|Suspending Predicates|suspending predicates}}.&lt;br /&gt;
&lt;br /&gt;
When the master spawn this slave it will call the &amp;lt;vp&amp;gt;setSettings&amp;lt;/vp&amp;gt; to inform the slave about settings (i.e. corresponding to the command line flags , etc of a regular compiler). And then it will call &amp;lt;vp&amp;gt;compile&amp;lt;/vp&amp;gt; on a file and when that operation completes it will (potentially) call &amp;lt;vp&amp;gt;compile&amp;lt;/vp&amp;gt; again on another file.  The master will continue this until there are no more files to compile and then it will terminate the slave.&lt;br /&gt;
&lt;br /&gt;
Actually, the master will spawn a number of slaves, so that several files can be compiled in parallel.&lt;br /&gt;
&lt;br /&gt;
The master has this interface towards the slave:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface master&lt;br /&gt;
    [pfc\masterSlaveProcess::master]&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    compilerMessage_ntf = compilerMessage_ntf(string File, integer Line, string Message).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    compilerMessage : (compilerMessage_ntf Message).&lt;br /&gt;
&lt;br /&gt;
end interface master&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This interface only contains a single notification &amp;lt;vp&amp;gt;compilerMessage&amp;lt;/vp&amp;gt; through which the compiler can notify the master with messages from the compilation, while the compilation takes place.  Notice that this predicate is not a suspending predicate, this is because notifications completely asynchronous in the sense that no result is returned to the slave and the slave does not wait for the notification to be handled.  Be aware that additional notifications and final results can arrive before other notifications has been handled.  This may lead to race conditions, and if they are not acceptable you should use a suspending predicate/function instead.&lt;br /&gt;
&lt;br /&gt;
There are restrictions on these interfaces:&lt;br /&gt;
&lt;br /&gt;
* They can contain one-input-one-output {{lang|Suspending Predicates|suspending function}}&lt;br /&gt;
* They can contain one-input notification predicates&lt;br /&gt;
* They cannot contain any other kind of predicates&lt;br /&gt;
* The input and output of the procedures and notifications must be serializable&lt;br /&gt;
&lt;br /&gt;
These two interfaces describes the master/slave process interface.&lt;br /&gt;
&lt;br /&gt;
To make the system complete the following things must be implemented:&lt;br /&gt;
&lt;br /&gt;
* A proxy class must be implemented for each of these interfaces&lt;br /&gt;
* The slave must implement the &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; interface&lt;br /&gt;
* The master must implement the &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; interface as a context to the slave proxy&lt;br /&gt;
&lt;br /&gt;
The following is also necessary, but that is handled by PFC classes:&lt;br /&gt;
&lt;br /&gt;
* The subprocess creation&lt;br /&gt;
* The creation of communication pipes&lt;br /&gt;
* The serialization/deserialization, communication and dispatching of data/messages&lt;br /&gt;
&lt;br /&gt;
The implementation of the proxy classes are quite simple as described in the next sections.&lt;br /&gt;
&lt;br /&gt;
=== slaveProcess ===&lt;br /&gt;
&lt;br /&gt;
For the master process we will need a proxy representing the slave process, the interface of this proxy looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface slaveProcess supports slave, useExe&lt;br /&gt;
&lt;br /&gt;
predicates from pfc\masterSlaveProcessSupport&lt;br /&gt;
    terminate_toRemote&lt;br /&gt;
&lt;br /&gt;
end interface slaveProcess&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It supports the &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; interface (which is the main proxy facility).  It also supports &amp;lt;vp&amp;gt;useExe&amp;lt;/vp&amp;gt; which is the PFC standard interface for subprocesses and finally it also contains the predicate &amp;lt;vp&amp;gt;terminate_toRemote&amp;lt;/vp&amp;gt; which is used internally to terminate the slave process.&lt;br /&gt;
&lt;br /&gt;
The class declaration of the &amp;lt;vp&amp;gt;slaveProcess&amp;lt;/vp&amp;gt; looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class slaveProcess : slaveProcess&lt;br /&gt;
&lt;br /&gt;
constructors&lt;br /&gt;
    new : (string SlaveProgram, master Master, string CmdLine).&lt;br /&gt;
&lt;br /&gt;
end class slaveProcess&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;Master&amp;lt;/vp&amp;gt; is the implementation of the &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; interface that the slave will communicate with.  I.e. it is the master&amp;#039;s implementation of the &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; interface.&lt;br /&gt;
&lt;br /&gt;
The implementation of the &amp;lt;vp&amp;gt;slaveProcess&amp;lt;/vp&amp;gt; looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement slaveProcess inherits slaveProcessSupport&lt;br /&gt;
    open pfc\&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    new(SlaveProgram, Master, CmdLine) :-&lt;br /&gt;
        slaveProcessSupport::new(SlaveProgram, CmdLine),&lt;br /&gt;
        register_notify(&amp;quot;compilerMessage&amp;quot;, Master:compilerMessage).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    compile(Filename) = call_toRemote(predicate_name(), Filename).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    setSettings(Settings) = call_toRemote(predicate_name(), Settings).&lt;br /&gt;
&lt;br /&gt;
end implement slaveProcess&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The implementation inherits from &amp;lt;vp&amp;gt;slaveProcessSupport&amp;lt;/vp&amp;gt; which is initialized with a &amp;quot;path&amp;quot; to the &amp;lt;vp&amp;gt;SlaveProgram&amp;lt;/vp&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
The implementation must also register all calls and notifications of the &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; interface. In this case it is just the &amp;lt;vp&amp;gt;compilerMessage&amp;lt;/vp&amp;gt; notification.&lt;br /&gt;
&lt;br /&gt;
Finally, the implementation contains a proxy method for each of the calls and notifications in the &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; interface.&lt;br /&gt;
&lt;br /&gt;
You will notice that registration as well as proxy methods is trivial code.&lt;br /&gt;
&lt;br /&gt;
=== masterProxy ===&lt;br /&gt;
&lt;br /&gt;
For the slave process we will need a proxy representing the &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; interface provided by the master. The interface of this proxy looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface masterProxy supports master&lt;br /&gt;
&lt;br /&gt;
properties from pfc\masterSlaveProcessSupport&lt;br /&gt;
    fromLoop&lt;br /&gt;
&lt;br /&gt;
end interface masterProxy&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It simply supports the &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; interface and provides a &amp;lt;vp&amp;gt;fromLoop&amp;lt;/vp&amp;gt; predicate that must be invoked to receive communication from the master.  We will return to this predicate below.&lt;br /&gt;
&lt;br /&gt;
The class declaration of the &amp;lt;vp&amp;gt;masterProxy&amp;lt;/vp&amp;gt; looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class masterProxy : masterProxy&lt;br /&gt;
&lt;br /&gt;
constructors&lt;br /&gt;
    new : (slave Slave, string MsPipe).&lt;br /&gt;
&lt;br /&gt;
end class masterProxy&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The constructor takes the implementation of the &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; interface as argument and the name of a &amp;lt;vp&amp;gt;MsPipe&amp;lt;/vp&amp;gt; to use for communication.  The implementation of the &amp;lt;vp&amp;gt;masterProxy&amp;lt;/vp&amp;gt; looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement masterProxy inherits masterProxySupport&lt;br /&gt;
    open pfc\&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    new(Slave, MsPipe) :-&lt;br /&gt;
        register_call(&amp;quot;compile&amp;quot;, Slave:compile),&lt;br /&gt;
        register_call(&amp;quot;setSettings&amp;quot;, Slave:setSettings),&lt;br /&gt;
        masterProxySupport::new(MsPipe).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    compilerMessage(Message) :-&lt;br /&gt;
        notify_wait_toRemote(predicate_name(), Message).&lt;br /&gt;
&lt;br /&gt;
end implement masterProxy&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It inherits from &amp;lt;vp&amp;gt;masterProxySupport&amp;lt;/vp&amp;gt; and contains registration of all &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; calls and notifications, and proxy implantations of all &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; calls and notifications.&lt;br /&gt;
&lt;br /&gt;
=== The master program ===&lt;br /&gt;
&lt;br /&gt;
The master program (i.e. the builder) is a console program that &lt;br /&gt;
&lt;br /&gt;
* compiles a set of files&lt;br /&gt;
* using a number of slave-compilers and &lt;br /&gt;
* writes the messages from the compilers to the console.&lt;br /&gt;
&lt;br /&gt;
Finally after all compilation is completed it will write some statistics to the console.&lt;br /&gt;
&lt;br /&gt;
This is done by the &amp;lt;vp&amp;gt;compiler::compileFiles&amp;lt;/vp&amp;gt; predicate&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class compiler : compiler&lt;br /&gt;
    open core&lt;br /&gt;
    [noDefaultConstructor]&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    compileFiles : (string SlaveProgram, string Settings, setM{string} Files, positive ProcessCount, boolean Debug)&lt;br /&gt;
        -&amp;gt; pfc\asynchronous\future{string} Result.&lt;br /&gt;
&lt;br /&gt;
end class compiler&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see the &amp;lt;vp&amp;gt;compiler&amp;lt;/vp&amp;gt; class can actually (privately) create objects of type &amp;lt;vp&amp;gt;compiler&amp;lt;/vp&amp;gt;. Each of these objects represents a compiler subprocess, but the management of these are kept privately in the implementation of the &amp;lt;vp&amp;gt;compiler&amp;lt;/vp&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;compiler&amp;lt;/vp&amp;gt; interface declares a &amp;lt;vp&amp;gt;compileFiles2&amp;lt;/vp&amp;gt; predicate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface compiler&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    compileFiles2 : (string Settings, setM{string} Files) -&amp;gt; pfc\asynchronous\future{compiler_ms\slave::compile_rsp} Result.&lt;br /&gt;
&lt;br /&gt;
end interface compiler&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see it uses a &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt;, which is an important part of submitting suspending predicates for execution.  The implementation looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement compiler&lt;br /&gt;
    supports master&lt;br /&gt;
    open core, compiler_ms\, slave, pfc\asynchronous\&lt;br /&gt;
&lt;br /&gt;
class facts&lt;br /&gt;
    cs : criticalSection := criticalSection::new(1000) [constant, immediate].&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    compileFiles(SlaveProgram, Settings, Files, ProcessCount, Debug) = R :-&lt;br /&gt;
        ProcessCount2 = math::min(list::length(Files:asList), ProcessCount),&lt;br /&gt;
        CL =&lt;br /&gt;
            [ new(SlaveProgram, D) ||&lt;br /&gt;
                C = std::cIterate(ProcessCount2),&lt;br /&gt;
                D = Debug ** toBoolean(C = 0)&lt;br /&gt;
            ],&lt;br /&gt;
        RL = [ C:compileFiles2(Settings, Files) || C in CL ],&lt;br /&gt;
        FC = future::fold(RL, plus, compilerResult_zero),&lt;br /&gt;
        R = FC:futureExtension::map(asString).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    slave : slaveProcess.&lt;br /&gt;
&lt;br /&gt;
constructors&lt;br /&gt;
    new : (string SlaveProgram, boolean Debug).&lt;br /&gt;
clauses&lt;br /&gt;
    new(SlaveProgram, Debug) :-&lt;br /&gt;
        CmdLine = if true = Debug then &amp;quot;-debug&amp;quot; else &amp;quot;&amp;quot; end if,&lt;br /&gt;
        slave := slaveProcess::new(SlaveProgram, This, CmdLine),&lt;br /&gt;
        slave:setNativeCreationFlags(multiThread_native::idle_priority_class),&lt;br /&gt;
        slave:run().&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    compileFiles2(Settings, Files) =&lt;br /&gt;
        future::submit(&lt;br /&gt;
            {  = R :-&lt;br /&gt;
                setSettings(Settings),&lt;br /&gt;
                R = doCompileFiles(Files, compilerResult_zero)&lt;br /&gt;
            }).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    setSettings : (string Settings) suspending.&lt;br /&gt;
clauses&lt;br /&gt;
    setSettings(Settings) :-&lt;br /&gt;
        _ = slave:setSettings(Settings).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    doCompileFiles : (setM{string} Files, compile_rsp Acc) -&amp;gt; compile_rsp OnCompileResult suspending.&lt;br /&gt;
clauses&lt;br /&gt;
    doCompileFiles(Files, Acc) = CompileResult :-&lt;br /&gt;
        if File = Files:tryRemoveFirst() then&lt;br /&gt;
            CR = slave:compile(File),&lt;br /&gt;
            cs:synchronize({  :- stdio::writef(&amp;quot;    %s %s\n&amp;quot;, File, CR:asString()) }),&lt;br /&gt;
            CompileResult = doCompileFiles(Files, Acc:plus(CR))&lt;br /&gt;
        else&lt;br /&gt;
            slave:terminate_toRemote(),&lt;br /&gt;
            CompileResult = Acc&lt;br /&gt;
        end if.&lt;br /&gt;
&lt;br /&gt;
constants&lt;br /&gt;
    compilerResult_zero : compile_rsp = compile_rsp(0, 0, 0).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    asString : (compile_rsp CompileResponse [this]) -&amp;gt; string.&lt;br /&gt;
clauses&lt;br /&gt;
    asString(compile_rsp(LineCount, Errors, CompilationTime)) =&lt;br /&gt;
        string::format(&amp;quot;% lines in %p % erros&amp;quot;, LineCount, duration::new(CompilationTime), Errors).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    plus : (compile_rsp A [this], compile_rsp B) -&amp;gt; compile_rsp C.&lt;br /&gt;
clauses&lt;br /&gt;
    plus(compile_rsp(AL, BL, CL), compile_rsp(AR, BR, CR)) = compile_rsp(AL + AR, BL + BR, CL + CR).&lt;br /&gt;
&lt;br /&gt;
% master&lt;br /&gt;
clauses&lt;br /&gt;
    compilerMessage(compilerMessage_ntf(File, Line, Message)) :-&lt;br /&gt;
        cs:synchronize({  :- stdio::writef(&amp;quot;        %s(%d): %s\n&amp;quot;, File, Line, Message) }).&lt;br /&gt;
&lt;br /&gt;
end implement compiler&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The asynchronous method in the master/slave concept is based on suspending predicates.  It is outside the scope of this article to go fully into details about asynchronous programming, suspending predicates and &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt;s/&amp;lt;vp&amp;gt;promise&amp;lt;/vp&amp;gt;s.&lt;br /&gt;
Here we want the main thread to wait for the result of a number of compilers it has started, and for such combined waiting and result summing, we will use &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt;s.&lt;br /&gt;
&lt;br /&gt;
The main predicate (&amp;lt;vp&amp;gt;compileFiles&amp;lt;/vp&amp;gt;) will start a number of &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; programs, and submit compilation &amp;quot;job&amp;quot; (&amp;lt;vp&amp;gt;compileFiles2&amp;lt;/vp&amp;gt;) for each of these &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt;s.  The submission of such a job is represented by a &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt; which will return the result some time in the &amp;quot;future&amp;quot;.  The results of all these &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt;s are folded into a single future, which in turn is &amp;quot;mapped&amp;quot; to a string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    compileFiles(SlaveProgram, Settings, Files, ProcessCount, Debug) = R :-&lt;br /&gt;
        ProcessCount2 = math::min(list::length(Files:asList), ProcessCount),&lt;br /&gt;
        CL =&lt;br /&gt;
            [ new(SlaveProgram, D) ||&lt;br /&gt;
                C = std::cIterate(ProcessCount2),&lt;br /&gt;
                D = Debug ** toBoolean(C = 0)&lt;br /&gt;
            ],&lt;br /&gt;
        RL = [ C:compileFiles2(Settings, Files) || C in CL ],&lt;br /&gt;
        FC = future::fold(RL, plus, compilerResult_zero),&lt;br /&gt;
        R = FC:futureExtension::map(asString).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see simple processing is a bit more complicated when futures are involved.  But predicates like &amp;lt;vp&amp;gt;future::fold&amp;lt;/vp&amp;gt; deals with a number of things: First of all it combines the results, but it also deals with asynchronous (as well as synchronous) waiting on the individual results, and in case some of the involved sub jobs completes with an exception it will also handle cancellation of the remaining sub jobs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The predicate &amp;lt;vp&amp;gt;compileFiles2&amp;lt;/vp&amp;gt; submits a compilation &amp;quot;job&amp;quot; to be executed in the default &amp;lt;vp&amp;gt;executionContext&amp;lt;/vp&amp;gt;; which in this case will be &amp;lt;vp&amp;gt;executionContext_pool::defaultPool&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    compileFiles2(Settings, Files) =&lt;br /&gt;
        future::submit(&lt;br /&gt;
            {  = R :-&lt;br /&gt;
                setSettings(Settings),&lt;br /&gt;
                R = doCompileFiles(Files, compilerResult_zero)&lt;br /&gt;
            }).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The suspending predicate &amp;lt;vp&amp;gt;doCompileFiles&amp;lt;/vp&amp;gt; contains the heart loop of the compilation. Each started compiler will be controlled with a &amp;lt;vp&amp;gt;doCompileFiles&amp;lt;/vp&amp;gt; loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
predicates&lt;br /&gt;
    doCompileFiles : (setM{string} Files, compile_rsp Acc) -&amp;gt; compile_rsp OnCompileResult suspending.&lt;br /&gt;
clauses&lt;br /&gt;
    doCompileFiles(Files, Acc) = CompileResult :-&lt;br /&gt;
        if File = Files:tryRemoveFirst() then&lt;br /&gt;
            CR = slave:compile(File),&lt;br /&gt;
            cs:synchronize({  :- stdio::writef(&amp;quot;    %s %s\n&amp;quot;, File, CR:asString()) }),&lt;br /&gt;
            CompileResult = doCompileFiles(Files, Acc:plus(CR))&lt;br /&gt;
        else&lt;br /&gt;
            slave:terminate_toRemote(),&lt;br /&gt;
            CompileResult = Acc&lt;br /&gt;
        end if.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 The loop will try to remove a &amp;lt;vp&amp;gt;File&amp;lt;/vp&amp;gt; to compile from the &amp;lt;vp&amp;gt;Files&amp;lt;/vp&amp;gt; to compile.  Since several loops will do this in parallel it is important that &amp;lt;vp&amp;gt;tryRemoveFirst&amp;lt;/vp&amp;gt; is thread safe.  In this example this is ensured by using a &amp;lt;vp&amp;gt;setM_redBlack_cas&amp;lt;/vp&amp;gt;  (i.e. a &amp;#039;&amp;#039;compare and swap&amp;#039;&amp;#039; red black set; see the &amp;lt;vp&amp;gt;main::run&amp;lt;/vp&amp;gt; implementation).&lt;br /&gt;
 &lt;br /&gt;
 If a &amp;lt;vp&amp;gt;File&amp;lt;/vp&amp;gt; can be removed from the set the &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; is asked to &amp;lt;vp&amp;gt;compile&amp;lt;/vp&amp;gt; it (asynchronous using a &amp;lt;vp&amp;gt;continuation&amp;lt;/vp&amp;gt;).  When the compilation is completed, we will write the result to stdio and loop to &amp;lt;vp&amp;gt;doCompileFiles&amp;lt;/vp&amp;gt; again.&lt;br /&gt;
 &lt;br /&gt;
 This will continue until &amp;lt;vp&amp;gt;Files&amp;lt;/vp&amp;gt; becomes empty in which case the &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; is informed to terminate (&amp;lt;vp&amp;gt;slave:terminate_toRemote()&amp;lt;/vp&amp;gt;), and the accumulated result is returned.&lt;br /&gt;
 &lt;br /&gt;
 The &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; also supports the &amp;lt;vp&amp;gt;compilerMessage&amp;lt;/vp&amp;gt; notification:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    compilerMessage(compilerMessage_ntf(File, Line, Message)) :-&lt;br /&gt;
        cs:synchronize({  :- stdio::writef(&amp;quot;        %s(%d): %s\n&amp;quot;, File, Line, Message) }).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In our case it simply writes the messages to the standard output stream.&lt;br /&gt;
 &lt;br /&gt;
=== The slave program ===&lt;br /&gt;
&lt;br /&gt;
The slave program is also a console program.  But it is very important to notice that the slave does not have a console window attached and that the console can therefore &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; be used for input/output.&lt;br /&gt;
&lt;br /&gt;
In this slave program everything interesting is packed into the implementation of &amp;lt;vp&amp;gt;theCompiler&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement theCompiler inherits masterProxy&lt;br /&gt;
    supports slave&lt;br /&gt;
    open core, compiler_ms\, master, pfc\asynchronous\&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    settings : string := &amp;quot;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    run(MsPipe) :-&lt;br /&gt;
        new(MsPipe):wait().&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    wait() :-&lt;br /&gt;
        _ = fromLoop:futureExtension::get().&lt;br /&gt;
&lt;br /&gt;
constructors&lt;br /&gt;
    new : (string MsPipe).&lt;br /&gt;
clauses&lt;br /&gt;
    new(MsPipe) :-&lt;br /&gt;
        masterProxy::new(This, MsPipe).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    compile(Filename) = compile_rsp(Lines, Errors:value, D:get()) :-&lt;br /&gt;
        T1 = time::now(),&lt;br /&gt;
        Errors = varM_integer::new(),&lt;br /&gt;
        Lines = 20 + math::random(3000),&lt;br /&gt;
        foreach I = std::cIterate(Lines) + 1 and not(executionContext::isCanceled()) do&lt;br /&gt;
            foreach _ = std::cIterate(math::random(10000)) do&lt;br /&gt;
            end foreach,&lt;br /&gt;
            R = math::random(),&lt;br /&gt;
            if R &amp;lt; 1 / 2000 then&lt;br /&gt;
                Errors:inc(),&lt;br /&gt;
                compilerMessage(compilerMessage_ntf(Filename, I, settings))&lt;br /&gt;
            end if&lt;br /&gt;
        end foreach,&lt;br /&gt;
        D = duration::new(T1, time::now()).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    setSettings(Settings) = unit :-&lt;br /&gt;
        settings := Settings.&lt;br /&gt;
&lt;br /&gt;
end implement theCompiler&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;theCompiler&amp;lt;/vp&amp;gt; implements the &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; interface which it pass as argument to the constructor of the &amp;lt;vp&amp;gt;masterProxy&amp;lt;/vp&amp;gt; object, thereby the communication and message loops are established.&lt;br /&gt;
&lt;br /&gt;
Recall that &amp;lt;vp&amp;gt;compile&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;setSettings&amp;lt;/vp&amp;gt; are suspending predicates. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;compile&amp;lt;/vp&amp;gt; performs a simple dummy simulation a compiler, by using CPU, returning messages and a final result.&lt;br /&gt;
The simulation &amp;quot;compiles&amp;quot; a random number of lines each with a certain probability to issue a compilerMessage which is notified back to the &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; (i.e. through the proxy object).&lt;br /&gt;
&lt;br /&gt;
The compilation also test for termination request from the master (i.e. &amp;lt;vp&amp;gt;not(executionContext::isCanceled())&amp;lt;/vp&amp;gt;), this test would actually only be relevant if the compilation was terminated in the middle of compilation which this example will never do.  But when compiling files from an IDE it is custom to have a &amp;quot;stop compilation&amp;quot; facility.  This facility could wait all compilers to ask for the next file to compile and terminate them there, but it could also send a terminate request to the slave, in which case the fromLoop would complete.&lt;br /&gt;
&lt;br /&gt;
In this program the main thread will simply &amp;lt;vp&amp;gt;wait&amp;lt;/vp&amp;gt;s for the termination of the &amp;lt;vp&amp;gt;fromLoop&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_for_Tyros&amp;diff=4958</id>
		<title>Visual Prolog for Tyros</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_for_Tyros&amp;diff=4958"/>
		<updated>2024-09-25T20:56:43Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: lineshift&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ambox|text= This book is about an &amp;#039;&amp;#039;&amp;#039;old&amp;#039;&amp;#039;&amp;#039; version of Visual Prolog.  We do not provide licenses for that version anymore.&lt;br /&gt;
The book may still be useful to you.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Visual Prolog for Tyros&amp;#039;&amp;#039; is a comprehensive book written by &amp;#039;&amp;#039;Eduardo Costa&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
It is a good starting point to study Visual Prolog. And it might be used by teachers for education.&lt;br /&gt;
&lt;br /&gt;
The latest edition of the book is &amp;quot;Visual Prolog 7.3 for Tyros&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The book includes a number of examples illustrating different features of Visual Prolog.&lt;br /&gt;
&lt;br /&gt;
=== Contents ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;I Savoir-faire&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
# Introduction&lt;br /&gt;
# Forms&lt;br /&gt;
# Mouse events&lt;br /&gt;
# Less Figures&lt;br /&gt;
# Horn Clauses&lt;br /&gt;
# Console Applications&lt;br /&gt;
# Grammars&lt;br /&gt;
# Painting&lt;br /&gt;
# Data types&lt;br /&gt;
# How to solve it in Prolog&lt;br /&gt;
# Facts&lt;br /&gt;
# Classes and Objects&lt;br /&gt;
# Giuseppe Peano&lt;br /&gt;
# L-Systems&lt;br /&gt;
# Games&lt;br /&gt;
# Animation&lt;br /&gt;
# Text Editor&lt;br /&gt;
# Printing&lt;br /&gt;
# Tab forms and other goodies&lt;br /&gt;
# Bugs&lt;br /&gt;
# A Data Base Manager&lt;br /&gt;
# Books and articles&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;II Artificial Intelligence&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
# Search&lt;br /&gt;
# Neural Networks&lt;br /&gt;
# Alpha Beta Pruning&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
&lt;br /&gt;
* [https://www.visual-prolog.com/download/73/books/tyros/tyros73.pdf Visual Prolog 7.3 for Tyros] (September, 2010, PDF).&lt;br /&gt;
&lt;br /&gt;
=== Examples from the book ===&lt;br /&gt;
&lt;br /&gt;
* For [https://www.visual-prolog.com/download/73/books/tyros/tyros73.zip Visual Prolog 7.3] (zip).&lt;br /&gt;
* For [https://www.visual-prolog.com/download/72/books/tyros/tyros72.zip Visual Prolog 7.2] (zip).&lt;br /&gt;
* For [https://www.visual-prolog.com/download/71/Costas-Tyros.zip Visual Prolog 7.1] (zip).&lt;br /&gt;
&lt;br /&gt;
=== Translations ===&lt;br /&gt;
&lt;br /&gt;
* [https://wikiru.visual-prolog.com/index.php?title=Visual_Prolog_for_Tyros Russian]&lt;br /&gt;
* [[Visual Prolog for Tyros in Chinese|Chinese]]&lt;br /&gt;
&lt;br /&gt;
[[ru:Visual Prolog для чайников]]&lt;br /&gt;
[[Category:Books]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=A_Beginners_Guide_to_Visual_Prolog&amp;diff=4957</id>
		<title>A Beginners Guide to Visual Prolog</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=A_Beginners_Guide_to_Visual_Prolog&amp;diff=4957"/>
		<updated>2024-09-25T20:56:01Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: notice&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
{{ambox|text=This book is about an &amp;#039;&amp;#039;&amp;#039;old&amp;#039;&amp;#039;&amp;#039; version of Visual Prolog.  We do not provide licenses for that version anymore.&lt;br /&gt;
&lt;br /&gt;
The book may still be useful to you, and the examples are in the current version of Visual Prolog}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;A Beginners&amp;#039; Guide to Visual Prolog&amp;#039;&amp;#039; is a comprehensive book for absolute beginners written by &amp;#039;&amp;#039;Thomas W. de Boer&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The book contains already published material, which is used with permision of the authors.&lt;br /&gt;
&lt;br /&gt;
The latest version of the book is devoted to Visual Prolog 7.2, but the principles are still more or less the same.&lt;br /&gt;
&lt;br /&gt;
This book is an introduction. It is meant it is for people, who know little about programming.  You should know the basics about computers and that it is possible to program them and that for a program you use a programming language. &lt;br /&gt;
&lt;br /&gt;
What when you know more? Then you should look for other sources.&lt;br /&gt;
&lt;br /&gt;
* When you are programmer and know about other languages like Visual Basic or C##, read the book [[Visual Prolog for Tyros]] by Eduardo Costa.&lt;br /&gt;
&lt;br /&gt;
* When you know about other languages and are curious about Prolog, read the basic the [[:Category:Tutorials|Tutorials]].&lt;br /&gt;
&lt;br /&gt;
* When you have experience in Prolog programming, look for details about Visual Prolog, object orientation in the [[:Category:Tutorials|Tutorials]] section of this site and Visual Prolog [[Language Reference]].&lt;br /&gt;
&lt;br /&gt;
=== Contents ===&lt;br /&gt;
&lt;br /&gt;
# The Integrated Development Environment&lt;br /&gt;
# Forms&lt;br /&gt;
# Simple user interfacing&lt;br /&gt;
# A closer look at the IDE&lt;br /&gt;
# Fundamental Prolog&lt;br /&gt;
# Data modeling in Prolog&lt;br /&gt;
# Using Forms or Dialogs and Controls: a minimal database&lt;br /&gt;
# Object oriented programming - classes and objects&lt;br /&gt;
# Declarations in Visual Prolog&lt;br /&gt;
# Recursion, lists and sorting&lt;br /&gt;
# Reading, writing, streams and files&lt;br /&gt;
# More data structures: Stacks, Queues and Trees&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Appendices&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
# Everything about Dialogs and Forms&lt;br /&gt;
# List manipulating predicates&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
* [https://www.visual-prolog.com/download/72/books/deBoer/VisualPrologBeginners.pdf A Beginners&amp;#039; Guide to Visual Prolog 7.2] (PDF format, English 279 pages).&lt;br /&gt;
&lt;br /&gt;
==== Examples from the book ====&lt;br /&gt;
* For [https://www.visual-prolog.com/download/9/books/deBoer/deBoer-BeginnersGuide-examples.zip Visual Prolog 9] (ZIP format, 280 KB).&lt;br /&gt;
* For [https://www.visual-prolog.com/download/73/books/deBoer/deBoer-BeginnersGuide-examples.zip Visual Prolog 7.3] (ZIP format, 440 KB).&lt;br /&gt;
* For [https://www.visual-prolog.com/download/72/books/deBoer/deBoer-BeginnersGuide-examples.zip Visual Prolog 7.2] (ZIP format, 437 KB).&lt;br /&gt;
&lt;br /&gt;
=== See also ===  &lt;br /&gt;
[[A Beginners Guide to Visual Prolog in Chinese]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Books]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_for_Tyros&amp;diff=4956</id>
		<title>Visual Prolog for Tyros</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_for_Tyros&amp;diff=4956"/>
		<updated>2024-09-25T20:51:40Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: notice&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ambox|text= This book is about an &amp;#039;&amp;#039;&amp;#039;old&amp;#039;&amp;#039;&amp;#039; version of Visual Prolog.  We do not provide licenses for that version anymore.&lt;br /&gt;
The book may still be useful to you.}}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Visual Prolog for Tyros&amp;#039;&amp;#039; is a comprehensive book written by &amp;#039;&amp;#039;Eduardo Costa&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
It is a good starting point to study Visual Prolog. And it might be used by teachers for education.&lt;br /&gt;
&lt;br /&gt;
The latest edition of the book is &amp;quot;Visual Prolog 7.3 for Tyros&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The book includes a number of examples illustrating different features of Visual Prolog.&lt;br /&gt;
&lt;br /&gt;
=== Contents ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;I Savoir-faire&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
# Introduction&lt;br /&gt;
# Forms&lt;br /&gt;
# Mouse events&lt;br /&gt;
# Less Figures&lt;br /&gt;
# Horn Clauses&lt;br /&gt;
# Console Applications&lt;br /&gt;
# Grammars&lt;br /&gt;
# Painting&lt;br /&gt;
# Data types&lt;br /&gt;
# How to solve it in Prolog&lt;br /&gt;
# Facts&lt;br /&gt;
# Classes and Objects&lt;br /&gt;
# Giuseppe Peano&lt;br /&gt;
# L-Systems&lt;br /&gt;
# Games&lt;br /&gt;
# Animation&lt;br /&gt;
# Text Editor&lt;br /&gt;
# Printing&lt;br /&gt;
# Tab forms and other goodies&lt;br /&gt;
# Bugs&lt;br /&gt;
# A Data Base Manager&lt;br /&gt;
# Books and articles&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;II Artificial Intelligence&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
# Search&lt;br /&gt;
# Neural Networks&lt;br /&gt;
# Alpha Beta Pruning&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
&lt;br /&gt;
* [https://www.visual-prolog.com/download/73/books/tyros/tyros73.pdf Visual Prolog 7.3 for Tyros] (September, 2010, PDF).&lt;br /&gt;
&lt;br /&gt;
=== Examples from the book ===&lt;br /&gt;
&lt;br /&gt;
* For [https://www.visual-prolog.com/download/73/books/tyros/tyros73.zip Visual Prolog 7.3] (zip).&lt;br /&gt;
* For [https://www.visual-prolog.com/download/72/books/tyros/tyros72.zip Visual Prolog 7.2] (zip).&lt;br /&gt;
* For [https://www.visual-prolog.com/download/71/Costas-Tyros.zip Visual Prolog 7.1] (zip).&lt;br /&gt;
&lt;br /&gt;
=== Translations ===&lt;br /&gt;
&lt;br /&gt;
* [https://wikiru.visual-prolog.com/index.php?title=Visual_Prolog_for_Tyros Russian]&lt;br /&gt;
* [[Visual Prolog for Tyros in Chinese|Chinese]]&lt;br /&gt;
&lt;br /&gt;
[[ru:Visual Prolog для чайников]]&lt;br /&gt;
[[Category:Books]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_Examples&amp;diff=4955</id>
		<title>Visual Prolog Examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_Examples&amp;diff=4955"/>
		<updated>2024-09-16T13:35:28Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Thomas Linder Puls moved page Visual Prolog Examples to Visual Prolog Demo Examples&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Visual Prolog Demo Examples]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_Demo_Examples&amp;diff=4954</id>
		<title>Visual Prolog Demo Examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_Demo_Examples&amp;diff=4954"/>
		<updated>2024-09-16T13:35:28Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Thomas Linder Puls moved page Visual Prolog Examples to Visual Prolog Demo Examples&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ideNavbar|IDE Projects}}&lt;br /&gt;
&lt;br /&gt;
You can download the latest Visual Prolog [https://www.vusual-prolog.com/link/demo.php demo projects].&lt;br /&gt;
&lt;br /&gt;
Notice that some demo programs may require the Commercial Edition.  The build system will inform you if that is the case.&lt;br /&gt;
&lt;br /&gt;
If you a newer Commercial Editoion you license file will contain a link to the demo programs correcponding to your version.&lt;br /&gt;
&lt;br /&gt;
For the Personal Edition you can only obtain the &amp;quot;current&amp;quot; version of demos, but you can also obtain the &amp;quot;current&amp;quot; version of the [https://www.visual-prolog.com/download.htm Personal Edition].  Older versions of the Personal Edition can be used freely, but is not otherwise supported.&lt;br /&gt;
&lt;br /&gt;
In older versions of Visual Prolog the demo projects was in the installation and could be installed from the menu entry &amp;quot;Help -&amp;gt; Install Examples ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Questions and comments to the demo examples can be given in the [https://www.visual-prolog.com/link/discuss.php discussion forum].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Visual Prolog Demo Examples ===&lt;br /&gt;
&lt;br /&gt;
{|{{prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;_BeginnersGuide/&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains updated versions of the examples in the old book [[A Beginners Guide to Visual Prolog]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;_tutorial/&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains examples corresponding to the main section of the [[:Category:Tutorials|Tutorials]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;animationControlDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;animationControl&amp;lt;/vp&amp;gt; (this control is not frequently used anymore).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;askDialogDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project use a modal dialog to ask the user a question.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;BackgroundIntelligentTransferService&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses Windows Background Intelligent Transfer Service (BITS).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;balloonTipsDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses balloon tips popping up as notifications Windows.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;bgDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project runs several background jobs in separate threads.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;buttonDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This program demonstrates how to handle OK and Cancel buttons, how to handle default buttons, how to handle button responders&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;callProcess&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| The project invokes an external process and interact with the standard output and standard input of it.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;cmdLineDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;commandLineParser&amp;lt;/vp&amp;gt; with several options.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains projects that illustrates how to use a COM component and how to implement one.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;direct2DDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project compare GDI+ graphics to &amp;quot;plain&amp;quot; GDI graphics.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;dll&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains various projects illustrating the use of DLL.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;dockingDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project iullustrates how to use &amp;quot;docking&amp;quot; to define the layout of a dialog.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;dragDropTargetOle&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project is a &amp;quot;drop target&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;dragNdropDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of drag and drop.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;editor&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates how to use the scintilla editor in a program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;formWindowDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates the use of forms.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;GDI+Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates various GDI+ features.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;genericsExample&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demostrates how to define and work with generic domains.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;guiDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates how to work with GUI.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;jsonWebToken&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates how to create and decompose JSON web tokens (jwt).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;listDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates various operations on lists.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;listViewDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;listViewControl&amp;lt;/vp&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;logDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates the use of the &amp;lt;vp&amp;gt;log&amp;lt;/vp&amp;gt; tool.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;logDemoPE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates the use of the &amp;lt;vp&amp;gt;log&amp;lt;/vp&amp;gt; tool in a Personal Edition projectl.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;masterSlave&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains projects that utilizes slave process from a master process.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;MSXML_Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the MSXML component to load an xml file which is visualized in a tree control.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;MultiThreadDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| In the example several threads produces results in the single (common for all threads) &amp;quot;queue&amp;quot;, and the primary thread reads them one by one and displays on the screen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;neuralNet&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project builds a pyramid shaped neural network. (Modern neural networks will use vector/matrix/tensor operations).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;OdbcDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrated the use of ODBC (in a GUI program).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;pictureDraw&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project draws a picture using GDI+ (&amp;lt;vp&amp;gt;gdiPlus&amp;lt;/vp&amp;gt;).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;pie&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| PIE is a Prolog Inference Engine which implements an ISO Prolog like interpreter.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;pieDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;pie&amp;lt;/vp&amp;gt; (Prolog Inference Engine) as a scripting language in the project.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;progress&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;progressControl&amp;lt;/vp&amp;gt; to illustrate progress in a program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;prologSourceBrowser&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of several types of GUI controls in a dialog that can browse in files in a directory.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;radioButtonDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates how to use single radio button group, multiple radio button groups or how to use check boxes.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;ribbonDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This demo project illustrates how to develop applications using the Ribbon and Command packages of pfc/gui.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;ribbonMdiDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This demo project illustrates use the ribbonControl in an MDI (Multiple Document Interface) program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;sandClocks&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project can solve a &amp;quot;sand clock&amp;quot; puzles.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;simpleOdbc&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of ODBC in a command line program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;socketAsync&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains a socket server and a corresponding client, both working asynchronously using suspending predicates.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;streamDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of streams.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;sudoku&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project can solve soduko&amp;#039;s using a constratint programming thechnique.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;tabControlDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;tabControl&amp;lt;/vp&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;tail&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project can follow changes to a text/log file.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;toolTipDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of tooltips.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;toyIDE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains several projecs that illustrates how a complex application can be divided into several DLL&amp;#039;s.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;treeControlDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;treeControl&amp;lt;/vp&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;useSyntaxDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the Visual Prolog parser to parse source files and then extracts literals from the syntax trees.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;validationDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates how to use control and dialog validation to validate user input in a dialog.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;vipLalrGen&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project is the source code of the Visual Prolog LALR parser generator.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;vipPP&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project is the source code of the &amp;lt;vp&amp;gt;vipPP&amp;lt;/vp&amp;gt; program that can parse and pretty print Visual Prolog source code.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;WatchDir&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses &amp;lt;vp&amp;gt;watchDir&amp;lt;/vp&amp;gt; to monitor changes in a directory.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;watchDirGui&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses &amp;lt;vp&amp;gt;watchDir&amp;lt;/vp&amp;gt; to monitor changes in a directory (in a GUI program).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;webService&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains a webServiceDemo project with a HTML test page and a corresponding Visual Prolog client program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;webView2Demo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the usage of the &amp;lt;vp&amp;gt;webView2&amp;lt;/vp&amp;gt; control (Edge browser).&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_Demo_Examples&amp;diff=4953</id>
		<title>Visual Prolog Demo Examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_Demo_Examples&amp;diff=4953"/>
		<updated>2024-09-16T13:34:42Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Discussion forum&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ideNavbar|IDE Projects}}&lt;br /&gt;
&lt;br /&gt;
You can download the latest Visual Prolog [https://www.vusual-prolog.com/link/demo.php demo projects].&lt;br /&gt;
&lt;br /&gt;
Notice that some demo programs may require the Commercial Edition.  The build system will inform you if that is the case.&lt;br /&gt;
&lt;br /&gt;
If you a newer Commercial Editoion you license file will contain a link to the demo programs correcponding to your version.&lt;br /&gt;
&lt;br /&gt;
For the Personal Edition you can only obtain the &amp;quot;current&amp;quot; version of demos, but you can also obtain the &amp;quot;current&amp;quot; version of the [https://www.visual-prolog.com/download.htm Personal Edition].  Older versions of the Personal Edition can be used freely, but is not otherwise supported.&lt;br /&gt;
&lt;br /&gt;
In older versions of Visual Prolog the demo projects was in the installation and could be installed from the menu entry &amp;quot;Help -&amp;gt; Install Examples ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Questions and comments to the demo examples can be given in the [https://www.visual-prolog.com/link/discuss.php discussion forum].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Visual Prolog Demo Examples ===&lt;br /&gt;
&lt;br /&gt;
{|{{prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;_BeginnersGuide/&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains updated versions of the examples in the old book [[A Beginners Guide to Visual Prolog]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;_tutorial/&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains examples corresponding to the main section of the [[:Category:Tutorials|Tutorials]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;animationControlDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;animationControl&amp;lt;/vp&amp;gt; (this control is not frequently used anymore).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;askDialogDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project use a modal dialog to ask the user a question.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;BackgroundIntelligentTransferService&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses Windows Background Intelligent Transfer Service (BITS).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;balloonTipsDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses balloon tips popping up as notifications Windows.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;bgDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project runs several background jobs in separate threads.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;buttonDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This program demonstrates how to handle OK and Cancel buttons, how to handle default buttons, how to handle button responders&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;callProcess&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| The project invokes an external process and interact with the standard output and standard input of it.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;cmdLineDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;commandLineParser&amp;lt;/vp&amp;gt; with several options.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains projects that illustrates how to use a COM component and how to implement one.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;direct2DDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project compare GDI+ graphics to &amp;quot;plain&amp;quot; GDI graphics.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;dll&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains various projects illustrating the use of DLL.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;dockingDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project iullustrates how to use &amp;quot;docking&amp;quot; to define the layout of a dialog.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;dragDropTargetOle&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project is a &amp;quot;drop target&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;dragNdropDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of drag and drop.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;editor&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates how to use the scintilla editor in a program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;formWindowDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates the use of forms.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;GDI+Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates various GDI+ features.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;genericsExample&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demostrates how to define and work with generic domains.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;guiDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates how to work with GUI.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;jsonWebToken&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates how to create and decompose JSON web tokens (jwt).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;listDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates various operations on lists.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;listViewDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;listViewControl&amp;lt;/vp&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;logDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates the use of the &amp;lt;vp&amp;gt;log&amp;lt;/vp&amp;gt; tool.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;logDemoPE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates the use of the &amp;lt;vp&amp;gt;log&amp;lt;/vp&amp;gt; tool in a Personal Edition projectl.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;masterSlave&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains projects that utilizes slave process from a master process.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;MSXML_Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the MSXML component to load an xml file which is visualized in a tree control.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;MultiThreadDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| In the example several threads produces results in the single (common for all threads) &amp;quot;queue&amp;quot;, and the primary thread reads them one by one and displays on the screen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;neuralNet&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project builds a pyramid shaped neural network. (Modern neural networks will use vector/matrix/tensor operations).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;OdbcDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrated the use of ODBC (in a GUI program).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;pictureDraw&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project draws a picture using GDI+ (&amp;lt;vp&amp;gt;gdiPlus&amp;lt;/vp&amp;gt;).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;pie&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| PIE is a Prolog Inference Engine which implements an ISO Prolog like interpreter.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;pieDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;pie&amp;lt;/vp&amp;gt; (Prolog Inference Engine) as a scripting language in the project.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;progress&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;progressControl&amp;lt;/vp&amp;gt; to illustrate progress in a program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;prologSourceBrowser&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of several types of GUI controls in a dialog that can browse in files in a directory.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;radioButtonDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates how to use single radio button group, multiple radio button groups or how to use check boxes.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;ribbonDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This demo project illustrates how to develop applications using the Ribbon and Command packages of pfc/gui.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;ribbonMdiDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This demo project illustrates use the ribbonControl in an MDI (Multiple Document Interface) program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;sandClocks&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project can solve a &amp;quot;sand clock&amp;quot; puzles.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;simpleOdbc&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of ODBC in a command line program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;socketAsync&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains a socket server and a corresponding client, both working asynchronously using suspending predicates.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;streamDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of streams.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;sudoku&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project can solve soduko&amp;#039;s using a constratint programming thechnique.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;tabControlDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;tabControl&amp;lt;/vp&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;tail&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project can follow changes to a text/log file.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;toolTipDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of tooltips.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;toyIDE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains several projecs that illustrates how a complex application can be divided into several DLL&amp;#039;s.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;treeControlDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;treeControl&amp;lt;/vp&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;useSyntaxDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the Visual Prolog parser to parse source files and then extracts literals from the syntax trees.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;validationDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates how to use control and dialog validation to validate user input in a dialog.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;vipLalrGen&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project is the source code of the Visual Prolog LALR parser generator.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;vipPP&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project is the source code of the &amp;lt;vp&amp;gt;vipPP&amp;lt;/vp&amp;gt; program that can parse and pretty print Visual Prolog source code.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;WatchDir&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses &amp;lt;vp&amp;gt;watchDir&amp;lt;/vp&amp;gt; to monitor changes in a directory.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;watchDirGui&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses &amp;lt;vp&amp;gt;watchDir&amp;lt;/vp&amp;gt; to monitor changes in a directory (in a GUI program).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;webService&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains a webServiceDemo project with a HTML test page and a corresponding Visual Prolog client program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;webView2Demo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the usage of the &amp;lt;vp&amp;gt;webView2&amp;lt;/vp&amp;gt; control (Edge browser).&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_Demo_Examples&amp;diff=4952</id>
		<title>Visual Prolog Demo Examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_Demo_Examples&amp;diff=4952"/>
		<updated>2024-09-16T13:32:02Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Personal Edition&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ideNavbar|IDE Projects}}&lt;br /&gt;
&lt;br /&gt;
You can download the latest Visual Prolog [https://www.vusual-prolog.com/link/demo.php demo projects].&lt;br /&gt;
&lt;br /&gt;
Notice that some demo programs may require the Commercial Edition.  The build system will inform you if that is the case.&lt;br /&gt;
&lt;br /&gt;
If you a newer Commercial Editoion you license file will contain a link to the demo programs correcponding to your version.&lt;br /&gt;
&lt;br /&gt;
For the Personal Edition you can only obtain the &amp;quot;current&amp;quot; version of demos, but you can also obtain the &amp;quot;current&amp;quot; version of the [https://www.visual-prolog.com/download.htm Personal Edition].  Older versions of the Personal Edition can be used freely, but is not otherwise supported.&lt;br /&gt;
&lt;br /&gt;
In older versions of Visual Prolog the demo projects was in the installation and could be installed from the menu entry &amp;quot;Help -&amp;gt; Install Examples ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Visual Prolog Demo Examples ===&lt;br /&gt;
&lt;br /&gt;
{|{{prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;_BeginnersGuide/&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains updated versions of the examples in the old book [[A Beginners Guide to Visual Prolog]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;_tutorial/&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains examples corresponding to the main section of the [[:Category:Tutorials|Tutorials]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;animationControlDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;animationControl&amp;lt;/vp&amp;gt; (this control is not frequently used anymore).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;askDialogDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project use a modal dialog to ask the user a question.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;BackgroundIntelligentTransferService&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses Windows Background Intelligent Transfer Service (BITS).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;balloonTipsDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses balloon tips popping up as notifications Windows.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;bgDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project runs several background jobs in separate threads.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;buttonDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This program demonstrates how to handle OK and Cancel buttons, how to handle default buttons, how to handle button responders&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;callProcess&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| The project invokes an external process and interact with the standard output and standard input of it.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;cmdLineDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;commandLineParser&amp;lt;/vp&amp;gt; with several options.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains projects that illustrates how to use a COM component and how to implement one.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;direct2DDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project compare GDI+ graphics to &amp;quot;plain&amp;quot; GDI graphics.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;dll&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains various projects illustrating the use of DLL.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;dockingDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project iullustrates how to use &amp;quot;docking&amp;quot; to define the layout of a dialog.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;dragDropTargetOle&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project is a &amp;quot;drop target&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;dragNdropDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of drag and drop.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;editor&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates how to use the scintilla editor in a program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;formWindowDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates the use of forms.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;GDI+Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates various GDI+ features.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;genericsExample&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demostrates how to define and work with generic domains.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;guiDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates how to work with GUI.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;jsonWebToken&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates how to create and decompose JSON web tokens (jwt).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;listDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates various operations on lists.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;listViewDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;listViewControl&amp;lt;/vp&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;logDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates the use of the &amp;lt;vp&amp;gt;log&amp;lt;/vp&amp;gt; tool.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;logDemoPE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates the use of the &amp;lt;vp&amp;gt;log&amp;lt;/vp&amp;gt; tool in a Personal Edition projectl.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;masterSlave&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains projects that utilizes slave process from a master process.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;MSXML_Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the MSXML component to load an xml file which is visualized in a tree control.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;MultiThreadDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| In the example several threads produces results in the single (common for all threads) &amp;quot;queue&amp;quot;, and the primary thread reads them one by one and displays on the screen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;neuralNet&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project builds a pyramid shaped neural network. (Modern neural networks will use vector/matrix/tensor operations).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;OdbcDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrated the use of ODBC (in a GUI program).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;pictureDraw&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project draws a picture using GDI+ (&amp;lt;vp&amp;gt;gdiPlus&amp;lt;/vp&amp;gt;).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;pie&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| PIE is a Prolog Inference Engine which implements an ISO Prolog like interpreter.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;pieDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;pie&amp;lt;/vp&amp;gt; (Prolog Inference Engine) as a scripting language in the project.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;progress&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;progressControl&amp;lt;/vp&amp;gt; to illustrate progress in a program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;prologSourceBrowser&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of several types of GUI controls in a dialog that can browse in files in a directory.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;radioButtonDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates how to use single radio button group, multiple radio button groups or how to use check boxes.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;ribbonDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This demo project illustrates how to develop applications using the Ribbon and Command packages of pfc/gui.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;ribbonMdiDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This demo project illustrates use the ribbonControl in an MDI (Multiple Document Interface) program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;sandClocks&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project can solve a &amp;quot;sand clock&amp;quot; puzles.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;simpleOdbc&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of ODBC in a command line program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;socketAsync&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains a socket server and a corresponding client, both working asynchronously using suspending predicates.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;streamDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of streams.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;sudoku&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project can solve soduko&amp;#039;s using a constratint programming thechnique.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;tabControlDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;tabControl&amp;lt;/vp&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;tail&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project can follow changes to a text/log file.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;toolTipDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of tooltips.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;toyIDE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains several projecs that illustrates how a complex application can be divided into several DLL&amp;#039;s.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;treeControlDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;treeControl&amp;lt;/vp&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;useSyntaxDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the Visual Prolog parser to parse source files and then extracts literals from the syntax trees.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;validationDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates how to use control and dialog validation to validate user input in a dialog.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;vipLalrGen&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project is the source code of the Visual Prolog LALR parser generator.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;vipPP&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project is the source code of the &amp;lt;vp&amp;gt;vipPP&amp;lt;/vp&amp;gt; program that can parse and pretty print Visual Prolog source code.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;WatchDir&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses &amp;lt;vp&amp;gt;watchDir&amp;lt;/vp&amp;gt; to monitor changes in a directory.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;watchDirGui&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses &amp;lt;vp&amp;gt;watchDir&amp;lt;/vp&amp;gt; to monitor changes in a directory (in a GUI program).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;webService&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains a webServiceDemo project with a HTML test page and a corresponding Visual Prolog client program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;webView2Demo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the usage of the &amp;lt;vp&amp;gt;webView2&amp;lt;/vp&amp;gt; control (Edge browser).&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_Demo_Examples&amp;diff=4951</id>
		<title>Visual Prolog Demo Examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_Demo_Examples&amp;diff=4951"/>
		<updated>2024-09-16T13:30:57Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ideNavbar|IDE Projects}}&lt;br /&gt;
&lt;br /&gt;
You can download the latest Visual Prolog [https://www.vusual-prolog.com/link/demo.php demo projects].&lt;br /&gt;
&lt;br /&gt;
Notice that some demo programs may require the Commercial Edition.  The build system will inform you if that is the case.&lt;br /&gt;
&lt;br /&gt;
If you a newer Commercial Editoion you license file will contain a link to the demo programs correcponding to your version.&lt;br /&gt;
&lt;br /&gt;
For the Personal Edition you can only obtain the &amp;quot;current&amp;quot; version of demos, but you can also obtain the &amp;quot;current&amp;quot; version of the Personal Edition&amp;quot;.  Older versions of the Personal Edition can be used freely, but is not otherwise supported.&lt;br /&gt;
&lt;br /&gt;
In older versions of Visual Prolog the demo projects was in the installation and could be installed from the menu entry &amp;quot;Help -&amp;gt; Install Examples ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Visual Prolog Demo Examples ===&lt;br /&gt;
&lt;br /&gt;
{|{{prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;_BeginnersGuide/&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains updated versions of the examples in the old book [[A Beginners Guide to Visual Prolog]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;_tutorial/&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains examples corresponding to the main section of the [[:Category:Tutorials|Tutorials]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;animationControlDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;animationControl&amp;lt;/vp&amp;gt; (this control is not frequently used anymore).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;askDialogDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project use a modal dialog to ask the user a question.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;BackgroundIntelligentTransferService&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses Windows Background Intelligent Transfer Service (BITS).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;balloonTipsDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses balloon tips popping up as notifications Windows.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;bgDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project runs several background jobs in separate threads.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;buttonDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This program demonstrates how to handle OK and Cancel buttons, how to handle default buttons, how to handle button responders&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;callProcess&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| The project invokes an external process and interact with the standard output and standard input of it.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;cmdLineDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;commandLineParser&amp;lt;/vp&amp;gt; with several options.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains projects that illustrates how to use a COM component and how to implement one.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;direct2DDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project compare GDI+ graphics to &amp;quot;plain&amp;quot; GDI graphics.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;dll&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains various projects illustrating the use of DLL.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;dockingDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project iullustrates how to use &amp;quot;docking&amp;quot; to define the layout of a dialog.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;dragDropTargetOle&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project is a &amp;quot;drop target&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;dragNdropDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of drag and drop.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;editor&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates how to use the scintilla editor in a program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;formWindowDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates the use of forms.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;GDI+Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates various GDI+ features.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;genericsExample&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demostrates how to define and work with generic domains.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;guiDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates how to work with GUI.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;jsonWebToken&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates how to create and decompose JSON web tokens (jwt).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;listDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates various operations on lists.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;listViewDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;listViewControl&amp;lt;/vp&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;logDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates the use of the &amp;lt;vp&amp;gt;log&amp;lt;/vp&amp;gt; tool.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;logDemoPE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates the use of the &amp;lt;vp&amp;gt;log&amp;lt;/vp&amp;gt; tool in a Personal Edition projectl.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;masterSlave&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains projects that utilizes slave process from a master process.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;MSXML_Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the MSXML component to load an xml file which is visualized in a tree control.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;MultiThreadDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| In the example several threads produces results in the single (common for all threads) &amp;quot;queue&amp;quot;, and the primary thread reads them one by one and displays on the screen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;neuralNet&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project builds a pyramid shaped neural network. (Modern neural networks will use vector/matrix/tensor operations).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;OdbcDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrated the use of ODBC (in a GUI program).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;pictureDraw&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project draws a picture using GDI+ (&amp;lt;vp&amp;gt;gdiPlus&amp;lt;/vp&amp;gt;).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;pie&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| PIE is a Prolog Inference Engine which implements an ISO Prolog like interpreter.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;pieDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;pie&amp;lt;/vp&amp;gt; (Prolog Inference Engine) as a scripting language in the project.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;progress&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;progressControl&amp;lt;/vp&amp;gt; to illustrate progress in a program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;prologSourceBrowser&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of several types of GUI controls in a dialog that can browse in files in a directory.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;radioButtonDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project demonstrates how to use single radio button group, multiple radio button groups or how to use check boxes.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;ribbonDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This demo project illustrates how to develop applications using the Ribbon and Command packages of pfc/gui.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;ribbonMdiDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This demo project illustrates use the ribbonControl in an MDI (Multiple Document Interface) program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;sandClocks&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project can solve a &amp;quot;sand clock&amp;quot; puzles.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;simpleOdbc&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of ODBC in a command line program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;socketAsync&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains a socket server and a corresponding client, both working asynchronously using suspending predicates.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;streamDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of streams.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;sudoku&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project can solve soduko&amp;#039;s using a constratint programming thechnique.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;tabControlDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;tabControl&amp;lt;/vp&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;tail&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project can follow changes to a text/log file.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;toolTipDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the use of tooltips.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;toyIDE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains several projecs that illustrates how a complex application can be divided into several DLL&amp;#039;s.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;treeControlDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the &amp;lt;vp&amp;gt;treeControl&amp;lt;/vp&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;useSyntaxDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses the Visual Prolog parser to parse source files and then extracts literals from the syntax trees.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;validationDemo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates how to use control and dialog validation to validate user input in a dialog.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;vipLalrGen&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project is the source code of the Visual Prolog LALR parser generator.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;vipPP&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project is the source code of the &amp;lt;vp&amp;gt;vipPP&amp;lt;/vp&amp;gt; program that can parse and pretty print Visual Prolog source code.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;WatchDir&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses &amp;lt;vp&amp;gt;watchDir&amp;lt;/vp&amp;gt; to monitor changes in a directory.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;watchDirGui&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project uses &amp;lt;vp&amp;gt;watchDir&amp;lt;/vp&amp;gt; to monitor changes in a directory (in a GUI program).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;webService&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This directory contains a webServiceDemo project with a HTML test page and a corresponding Visual Prolog client program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;webView2Demo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| This project illustrates the usage of the &amp;lt;vp&amp;gt;webView2&amp;lt;/vp&amp;gt; control (Edge browser).&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Web_Services&amp;diff=4950</id>
		<title>Web Services</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Web_Services&amp;diff=4950"/>
		<updated>2024-09-11T09:45:48Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: IISAPI removed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial describes how to create a Web Application with a HTML/JavaScript front-end that run in the users browser and a backend written in Visual Prolog.&lt;br /&gt;
&lt;br /&gt;
The emphasis is on the Visual Prolog back-end, which implement a JSON-RPC web service. The HTML/JavaScript code is mainly included to make the example self-contained and to illustrate how front-end code can interact with a Visual Prolog web service.&lt;br /&gt;
&lt;br /&gt;
It is described how the service can run as a stand-alone HTTP/HTTPS server&lt;br /&gt;
&lt;br /&gt;
Also notice that this tutorial will not consider SOAP at all.&lt;br /&gt;
&lt;br /&gt;
The tutorial corresponds to the &amp;#039;&amp;#039;&amp;#039;webService&amp;#039;&amp;#039;&amp;#039; examples.&lt;br /&gt;
&lt;br /&gt;
A web service can as described here be implemented as a stand alone server. Tt can also be implemented as an IISAPI plug-in, but we recommend using a standalone instead of using an IISAPI plug-in.&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
&lt;br /&gt;
In this section we will try to describe the overall picture of the entire application and the way it works.  What takes place is actually rather complex, but fortunately most of the complexity is handled automatically.  An understanding of the overall process including knowledge of some of the complexity will however make it easier to understand what needs to be done and why.&lt;br /&gt;
&lt;br /&gt;
The overall work flow of the example application is as follows:  The user browses (in a web browser) to the page &amp;#039;&amp;#039;&amp;#039;http:&amp;lt;nowiki /&amp;gt;//&amp;lt;server&amp;gt;/test.htm&amp;#039;&amp;#039;&amp;#039; (or &amp;#039;&amp;#039;&amp;#039;http:&amp;lt;nowiki /&amp;gt;//&amp;lt;server&amp;gt;/calendar.htm&amp;#039;&amp;#039;&amp;#039;), and the server returns the corresponding file to the browser.  The browser evaluates the contents of the file, which may result in additional requests for several cascading style scripts (css) files, JavaScript (js) files, images, etc.  Furthermore, the HTML file contains embedded JavaScript code, which will make remote procedure calls (&amp;#039;&amp;#039;&amp;#039;RPC&amp;#039;&amp;#039;&amp;#039;) to the web server.  The server will execute the corresponding procedures and return the result to the browser.  Finally, the embedded JavaScript uses the returned data to update the HTML contents of the browser.&lt;br /&gt;
&lt;br /&gt;
The communication between the client and the server is performed by means of the HTTP (or HTTPS) protocol.   So on the server side we need an HTTP server, which can both return files and implement remote procedure calls. The program in &amp;#039;&amp;#039;&amp;#039;jsonRpcService_httpApi&amp;#039;&amp;#039;&amp;#039; runs the service as a stand alone HTTP server that both handles file requests and implements the remote procedure calls.  The program in &amp;#039;&amp;#039;&amp;#039;jsonRpcService_isApi&amp;#039;&amp;#039;&amp;#039; implements the remote procedure calls as an ISAPI plug-in, the IIS (Microsoft Internet Information Services) is configured to handle the file requests and to use the ISAPI for the remote procedure calls.&lt;br /&gt;
&lt;br /&gt;
The stand alone HTTP server is implemented by means of Microsoft&amp;#039;s [http://msdn.microsoft.com/en-us/library/windows/desktop/aa364510(v=vs.85).aspx HTTP Server API], which can share ports and URL&amp;#039;s with the Internet Information Services (IIS), such that &amp;#039;&amp;#039;&amp;#039;http:&amp;lt;nowiki /&amp;gt;//&amp;lt;server&amp;gt;/file&amp;#039;&amp;#039;&amp;#039;, etc can go to our stand alone server while &amp;#039;&amp;#039;&amp;#039;http:&amp;lt;nowiki /&amp;gt;//&amp;lt;server&amp;gt;/&amp;lt;something&amp;gt;&amp;#039;&amp;#039;&amp;#039; can be handled by the IIS.&lt;br /&gt;
&lt;br /&gt;
=== JSON &amp;amp; JSON-RPC ===&lt;br /&gt;
&lt;br /&gt;
The remote procedure calls are implemented in accordance with the [http://www.jsonrpc.org/specification JSON-RPC 2.0 Specification] specification, which implies that data is encoded in [http://www.json.org/ JSON] (&amp;#039;&amp;#039;&amp;#039;J&amp;#039;&amp;#039;&amp;#039;ava&amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;cript &amp;#039;&amp;#039;&amp;#039;O&amp;#039;&amp;#039;&amp;#039;bject &amp;#039;&amp;#039;&amp;#039;N&amp;#039;&amp;#039;&amp;#039;otation) format.&lt;br /&gt;
&lt;br /&gt;
JSON syntax is a sub-set of JavaScript (hence the name): When evaluating a valid JSON text it will become a corresponding JavaScript object.  You should however &amp;#039;&amp;#039;always&amp;#039;&amp;#039; call a JSON parser instead of evaluating the text: evaluating text is a security risk, since the text could be &amp;quot;code&amp;quot; rather than &amp;quot;data&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
It is not necessary to understand the JSON format in details, because on the client side you will work with JavaScript and on the server side you will work with an object/domain representation of JSON: parsing and writing is left to standard software.&lt;br /&gt;
&lt;br /&gt;
When performing a JSON-RPC call the client sends a JSON request object, and the server will respond with a JSON response object, unless the request is a &amp;#039;&amp;#039;&amp;#039;notification&amp;#039;&amp;#039;&amp;#039;, in which case there is no response.&lt;br /&gt;
&lt;br /&gt;
Request objects have four members:&lt;br /&gt;
* &amp;lt;vp&amp;gt;jsonrpc&amp;lt;/vp&amp;gt;: A string specifying the version of the JSON-RPC protocol. MUST be exactly &amp;quot;2.0&amp;quot;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;method&amp;lt;/vp&amp;gt;: A string containing the name of the method to be invoked.&lt;br /&gt;
* &amp;lt;vp&amp;gt;params&amp;lt;/vp&amp;gt;: The method parameters (omitted if the method does not take parameters).&lt;br /&gt;
**by-position: a JSON array, containing the values in the Server expected order.&lt;br /&gt;
**by-name: a JSON object, with member names that match exactly, including case, to the method&amp;#039;s expected parameters&lt;br /&gt;
* &amp;lt;vp&amp;gt;id&amp;lt;/vp&amp;gt;: A client created string or number used to identify the request.  The &amp;lt;vp&amp;gt;id&amp;lt;/vp&amp;gt; field is omitted for notifications.&lt;br /&gt;
&lt;br /&gt;
A response object contains three members:&lt;br /&gt;
* &amp;lt;vp&amp;gt;jsonrpc&amp;lt;/vp&amp;gt; A String specifying the version of the JSON-RPC protocol. MUST be exactly &amp;quot;2.0&amp;quot;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;id&amp;lt;/vp&amp;gt; The value submitted by the client.&lt;br /&gt;
The third member is one of these:&lt;br /&gt;
* &amp;lt;vp&amp;gt;result&amp;lt;/vp&amp;gt; (implying that the call succeeded) The result of the procedure call&lt;br /&gt;
* &amp;lt;vp&amp;gt;error&amp;lt;/vp&amp;gt; (implying that the call failed) An object describing the error which occurred&lt;br /&gt;
&lt;br /&gt;
=== Client side ===&lt;br /&gt;
&lt;br /&gt;
{{Example|This code shows one way to make a procedure call on the client side:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
function httpPOST(URL, method, params) {&lt;br /&gt;
    var ReqObj = { jsonrpc: &amp;quot;2.0&amp;quot;, id: getId(), method: method, params: params };&lt;br /&gt;
    var Req = JSON.stringify(ReqObj);&lt;br /&gt;
    var xmlHttp = new XMLHttpRequest();&lt;br /&gt;
    xmlHttp.open(&amp;quot;POST&amp;quot;, URL, false);&lt;br /&gt;
    xmlHttp.setRequestHeader(&amp;#039;Content-Type&amp;#039;, &amp;#039;application/json-rpc; charset=UTF-8&amp;#039;);&lt;br /&gt;
    xmlHttp.send(Req);&lt;br /&gt;
    var resp = xmlHttp.responseText;&lt;br /&gt;
    var respObj = JSON.parse(resp);&lt;br /&gt;
    var error = respObj.error;&lt;br /&gt;
    if (error) {&lt;br /&gt;
        if (Data = error.data) {&lt;br /&gt;
            log(&amp;quot;&amp;lt;pre&amp;gt;&amp;quot; + Data +&amp;quot;&amp;lt;/pre&amp;gt;\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        log(&amp;quot;&amp;lt;p&amp;gt;error : &amp;quot;+ error.code +&amp;quot;: &amp;quot; + error.message + &amp;quot;&amp;lt;/p&amp;gt;\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        // respObj.result contains the result&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
In brief:&lt;br /&gt;
* Create a request object&lt;br /&gt;
* JSON &amp;quot;stringify&amp;quot; it&lt;br /&gt;
* POST it using an XMLHttpRequest object&lt;br /&gt;
* JSON parse the response text&lt;br /&gt;
* Check for &amp;quot;error&amp;quot; member&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
There are many other ways to make client side code, typically you will use some standard JavaScript library packages that handles errors and perform the calls asynchronously.  &amp;#039;&amp;#039;&amp;#039;calendar.htm&amp;#039;&amp;#039;&amp;#039; uses such library code, but that is outside the scope of this tutorial.&lt;br /&gt;
&lt;br /&gt;
=== Service Code ===&lt;br /&gt;
&lt;br /&gt;
In Visual Prolog JSON is represented by the domain &amp;lt;vp&amp;gt;json::jsonValue&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    jsonValue =&lt;br /&gt;
        n; % null&lt;br /&gt;
        f; % false&lt;br /&gt;
        t; % true&lt;br /&gt;
        r(real Number);&lt;br /&gt;
        s(string String);&lt;br /&gt;
        a(jsonValue* Array);&lt;br /&gt;
        o(jsonObject Object).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are only 7 kinds of JSON values: null, false, true, a number, a string, an array and an object.&lt;br /&gt;
&lt;br /&gt;
An array is a sequence of JSON values represented as a list in Visual Prolog.&lt;br /&gt;
&lt;br /&gt;
A JSON object is represented by the &amp;lt;vp&amp;gt;jsonObject&amp;lt;/vp&amp;gt; interface in Visual Prolog:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface jsonObject supports mapM{string Key, jsonValue Value}&lt;br /&gt;
...&lt;br /&gt;
end interface jsonObject&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The interface contains a number of convenience predicates/properties (which have been omitted above), but in essence a &amp;lt;vp&amp;gt;jsonObject&amp;lt;/vp&amp;gt; is simply a map from Key&amp;#039;s (names) to JSON values.&lt;br /&gt;
&lt;br /&gt;
{{Example|This code:&lt;br /&gt;
&amp;lt;vip&amp;gt;J = jsonObject::new(),&lt;br /&gt;
J:set_boolean(&amp;quot;bbb&amp;quot;, true),&lt;br /&gt;
J:set_string(&amp;quot;sss&amp;quot;, &amp;quot;The String&amp;quot;),&lt;br /&gt;
J:writeTo(stdio::outputStream),&lt;br /&gt;
stdio::nl,&lt;br /&gt;
jsonPrettyPrint::ppObject(stdio::outputStream, J)&amp;lt;/vip&amp;gt;&lt;br /&gt;
will produce this output:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;{&amp;quot;bbb&amp;quot;:true,&amp;quot;sss&amp;quot;:&amp;quot;The String&amp;quot;}&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;bbb&amp;quot; : true,&lt;br /&gt;
    &amp;quot;sss&amp;quot; : &amp;quot;The String&amp;quot;&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;vp&amp;gt;writeTo&amp;lt;/vp&amp;gt; produces a condensed JSON representation suitable interprocess communication, etc.  &amp;lt;vp&amp;gt;jsonPrettyPrint&amp;lt;/vp&amp;gt; can be used to pretty print the values (for example when debugging).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
When creating an RPC service you will have to implement an object that supports the &amp;lt;vp&amp;gt;rpcService&amp;lt;/vp&amp;gt; interface:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface testService supports rpcService&lt;br /&gt;
end interface testService&lt;br /&gt;
&lt;br /&gt;
class testService : testService&lt;br /&gt;
end class testService&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the implementation you will inherit from &amp;lt;vp&amp;gt;jsonRpcServiceSupport&amp;lt;/vp&amp;gt; which will handle the parsing, writing, etc of JSON:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;implement testService&lt;br /&gt;
    inherits jsonRpcServiceSupport&lt;br /&gt;
    open core, json&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
end implement testService&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will register your procedures in the constructor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    new() :-&lt;br /&gt;
        setProc_name(&amp;quot;hello&amp;quot;, hello),&lt;br /&gt;
        setProc_name(&amp;quot;calendar&amp;quot;, calendar).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are four kinds of procedures, with corresponding registration predicates:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;setProc_array&amp;lt;/vp&amp;gt; for registering a procedure that uses positional arguments in an array&lt;br /&gt;
* &amp;lt;vp&amp;gt;setProc_name&amp;lt;/vp&amp;gt; for registering a procedure that uses named arguments in an object&lt;br /&gt;
* &amp;lt;vp&amp;gt;setListener_array&amp;lt;/vp&amp;gt; for registering a notification listener that uses positional arguments in an array&lt;br /&gt;
* &amp;lt;vp&amp;gt;setListener_name &amp;lt;/vp&amp;gt; for registering a notification listener that uses named arguments in an object&lt;br /&gt;
&lt;br /&gt;
In the example there are two procedures &amp;quot;hello&amp;quot; and &amp;quot;calendar&amp;quot; that both uses named arguments.  The &amp;quot;hello&amp;quot; code looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;constants&lt;br /&gt;
    testService_error : jsonRpcError::serverErrorCode = jsonRpcError::serverError_last+1.&lt;br /&gt;
    % grows up from &amp;quot;last&amp;quot;, which is used for unspecified server error&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    hello : jsonProc_name.&lt;br /&gt;
clauses&lt;br /&gt;
    hello(_Context, ArgMap) = o(Result) :-&lt;br /&gt;
        Result = jsonObject::new(),&lt;br /&gt;
        Username = ArgMap:get_string(&amp;quot;username&amp;quot;),&lt;br /&gt;
        if &amp;quot;error&amp;quot; = Username then&lt;br /&gt;
            raise_serviceError(testService_error, &amp;quot;&amp;#039;error&amp;#039; is an invalid user name&amp;quot;)&lt;br /&gt;
        elseif &amp;quot;userError&amp;quot; = Username then&lt;br /&gt;
            exception::raise_user(&amp;quot;&amp;#039;%Name%&amp;#039; is an invalid user name&amp;quot;, [namedValue(&amp;quot;Name&amp;quot;, string(Username))])&lt;br /&gt;
        elseif &amp;quot;definiteUserError&amp;quot; = Username then&lt;br /&gt;
            exception::raise_definiteUser(&amp;quot;&amp;#039;%Name%&amp;#039; is an invalid user name&amp;quot;, [namedValue(&amp;quot;Name&amp;quot;, string(Username))])&lt;br /&gt;
        else&lt;br /&gt;
            Result:set_string(&amp;quot;token&amp;quot;, string::concat(&amp;quot;Hello &amp;quot;, Username))&lt;br /&gt;
        end if.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First the &amp;lt;vp&amp;gt;hello&amp;lt;/vp&amp;gt; procedure creates a &amp;lt;vp&amp;gt;jsonObject&amp;lt;/vp&amp;gt; for the &amp;lt;vp&amp;gt;Result&amp;lt;/vp&amp;gt;.  Any kind of JSON value are legal as result, but &amp;lt;vp&amp;gt;hello&amp;lt;/vp&amp;gt; is designed to return a JSON object with a &amp;lt;vp&amp;gt;&amp;quot;token&amp;quot;&amp;lt;/vp&amp;gt; member.&lt;br /&gt;
&lt;br /&gt;
Next it fetches the arguments from &amp;lt;vp&amp;gt;ArgMap&amp;lt;/vp&amp;gt;.  It expects a string argument named &amp;lt;vp&amp;gt;&amp;quot;username&amp;quot;&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;hello&amp;lt;/vp&amp;gt; uses the value of &amp;lt;vp&amp;gt;Username&amp;lt;/vp&amp;gt; to illustrate exception handling and success.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;&amp;quot;error&amp;quot;&amp;lt;/vp&amp;gt; case illustrates how you can raise &amp;quot;service errors&amp;quot;, that is errors that are specifically designed for the RPC service.  The &amp;quot;userError&amp;quot; and &amp;quot;definiteUserError&amp;quot; cases illustrates what will happen with other exceptions that occurs in the procedure call.&lt;br /&gt;
&lt;br /&gt;
Notice that the client side code should be programmed to deal with errors.  On the server side you may of course also handle specific exceptions as in any other program, and perhaps you also want to log all errors somewhere.&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;vp&amp;gt;Username&amp;lt;/vp&amp;gt; is not one of the error cases, we map &amp;quot;token&amp;quot; to a string in the &amp;lt;vp&amp;gt;Result&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Example|We recommend that your &amp;lt;vp&amp;gt;jsonProc&amp;lt;/vp&amp;gt;&amp;#039;s only deal with argument extraction and result construction, and that you keep the real functionally in a separate business layer as illustrated by this code:&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    hello : jsonProc_name.&lt;br /&gt;
clauses&lt;br /&gt;
    hello(_Context, ArgMap) = o(Result) :-&lt;br /&gt;
        Result = jsonObject::new(),&lt;br /&gt;
        Username = ArgMap:get_string(&amp;quot;username&amp;quot;),&lt;br /&gt;
        Token = businessLayer::hello(Username),  % actual functionality is in a separate business layer&lt;br /&gt;
        Result:set_string(&amp;quot;token&amp;quot;, Token).&amp;lt;/vip&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
=== Stand-alone HTTP server ===&lt;br /&gt;
&lt;br /&gt;
As illustrated by the &amp;lt;vp&amp;gt;jsonRpcService_httpApi&amp;lt;/vp&amp;gt; program the &amp;lt;vp&amp;gt;testService&amp;lt;/vp&amp;gt; (supporting the &amp;lt;vp&amp;gt;rpcService&amp;lt;/vp&amp;gt;) can be used in a stand-alone HTTP server.  It does not require much code and it is quite simple to adjust the code to specific needs.  Nevertheless the complexity is quite large.&lt;br /&gt;
&lt;br /&gt;
The server is based on Microsoft&amp;#039;s [http://msdn.microsoft.com/en-us/library/windows/desktop/aa364510(v=vs.85).aspx HTTP Server API] which cooperates well with Microsoft Internet Information Services (IIS).  In fact, it seems that IIS is built on top of the HTTP Server API (or at least that both are built on top of some common base).&lt;br /&gt;
&lt;br /&gt;
The HTTP Server api operates with the following entities:&lt;br /&gt;
* Creator/Controller Process&lt;br /&gt;
* Server Session&lt;br /&gt;
* URL groups&lt;br /&gt;
* Request queues&lt;br /&gt;
* Worker Processes&lt;br /&gt;
&lt;br /&gt;
The creator/controller process creates a server session, which defines URL groups and request queues.  The worker processes attach to the request queues and process the requests they receive.&lt;br /&gt;
&lt;br /&gt;
In the example program the creator/controller process is also the only worker process.  And it is outside the scope of this tutorial to consider more complex scenarios.&lt;br /&gt;
&lt;br /&gt;
The server session is the &amp;quot;owner&amp;quot;/&amp;quot;holder&amp;quot; of the URL groups and the request queues, which are the things we really need to consider.&lt;br /&gt;
&lt;br /&gt;
An URL group defined by a set of URL patterns of the forms:&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;http:&amp;lt;nowiki /&amp;gt;//&amp;lt;host&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;relativeURI&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;https:&amp;lt;nowiki /&amp;gt;//&amp;lt;host&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;relativeURI&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
When a request arrives at the computer a matching mechanism will match it against the URL patterns in the active URL groups, the matching will either fail or determine an URL group that covers the URL.&lt;br /&gt;
&lt;br /&gt;
Each URL group is attached to a request queue, and requests matched to a certain URL group is placed in the attached request queue. URL groups that are not attached to a request queue are inactive and does not participate in the matching.&lt;br /&gt;
&lt;br /&gt;
Worker processes dequeue requests from the request queues and handle them.  A request queue can have several URL groups attached and each URL group can have several URL patterns.  A worker process dequeuing from a certain request queue will therefore receive requests that match some URL pattern in some URL group attached to that queue.&lt;br /&gt;
&lt;br /&gt;
In the example server we create two request queues each having a single URL group attached, and each of these URL groups having one URL pattern. Effectively:&lt;br /&gt;
* &amp;lt;vp&amp;gt;reqQueue_rpc&amp;lt;/vp&amp;gt; receives requests of the form &amp;#039;&amp;#039;&amp;#039;http:&amp;lt;nowiki /&amp;gt;//localhost:5555/jsonrpc/&amp;lt;something&amp;gt;&amp;#039;&amp;#039;&amp;#039;, and&lt;br /&gt;
* &amp;lt;vp&amp;gt;reqQueue_file&amp;lt;/vp&amp;gt; receives requests of the form &amp;#039;&amp;#039;&amp;#039;http:&amp;lt;nowiki /&amp;gt;//localhost:5555/&amp;lt;something&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;reqQueue_rpc&amp;lt;/vp&amp;gt; is a &amp;lt;vp&amp;gt;requestQueue_rpc&amp;lt;/vp&amp;gt; handles RPC requests by feeding them to our &amp;lt;vp&amp;gt;testService&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;reqQueue_file&amp;lt;/vp&amp;gt; is a &amp;lt;vp&amp;gt;requestQueue_file&amp;lt;/vp&amp;gt; which uses &amp;lt;vp&amp;gt;fileMapper&amp;lt;/vp&amp;gt; to map the requests to a file name and an associated &amp;lt;vp&amp;gt;ContentType&amp;lt;/vp&amp;gt;, the &amp;lt;vp&amp;gt;requestQueue_file&amp;lt;/vp&amp;gt; will then handle the transfer of the file.&lt;br /&gt;
&lt;br /&gt;
=== Server configuration: netsh ===&lt;br /&gt;
&lt;br /&gt;
The example runs smoothly because it uses port 5555 on localhost.  Normally you will however want to run applications on port 80 for http and 443 for https, and that will cause some security problems.&lt;br /&gt;
&lt;br /&gt;
If you just change the port number and uses a public hostname you server program will get an &amp;#039;Access is denied&amp;#039; exception when trying to add the URL patterns to the URL groups.&lt;br /&gt;
&lt;br /&gt;
If you run the server &amp;quot;as Administrator&amp;quot; you will not get the access violation, but it is absolutely not advisable to run the program as administrator, because then it also have rights to do many other harmful things.&lt;br /&gt;
&lt;br /&gt;
To make the program run in normal modes you will have to reserve the URL patterns in question for the user that run the server program.&lt;br /&gt;
&lt;br /&gt;
This is done using the netsh.exe (net shell) program.  You will need to manipulate the http URL acl&amp;#039;s.  For a detailed description see [http://msdn.microsoft.com/en-us/library/windows/desktop/cc307236(v=vs.85).aspx Netsh commands for HTTP].&lt;br /&gt;
&lt;br /&gt;
{{Example|This will give an idea of what to do (in a cmd prompt):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&amp;gt;netsh http add urlacl http://www.something.com:80/ user=SMT\serviceuser&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Notice&amp;#039;&amp;#039;&amp;#039; that the cmd prompt be run &amp;quot;as Administrator&amp;quot; to make modifications.&lt;br /&gt;
If you just write &amp;quot;netsh&amp;quot; it will go into a prompt mode where change to http mode and then just write http commands&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&amp;gt;netsh&lt;br /&gt;
netsh&amp;gt;http&lt;br /&gt;
netsh http&amp;gt;add urlacl http://www.something.com:80/ user=SMT\serviceuser&lt;br /&gt;
netsh http&amp;gt;exit&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
It is possible to make the URL reservations from Visual Prolog, but in case of conflicts and problems it may be better to use the standard program netsh.&lt;br /&gt;
&lt;br /&gt;
Notice that the example program is a console program.  In an larger scale context it would seem better to create a genuine windows service.  Visual Prolog has a template project for creating services, but that subject is outside the scope of this tutorial.&lt;br /&gt;
&lt;br /&gt;
=== Existing GUI program ===&lt;br /&gt;
&lt;br /&gt;
In the &amp;#039;&amp;#039;&amp;#039;webRPC&amp;#039;&amp;#039;&amp;#039; example directory there is also a &amp;lt;vp&amp;gt;jsonRpcService_httpGUI&amp;lt;/vp&amp;gt;, which illustrated how a GUI program can act like a stand-alone Web RPC Service.  You should notice that it is not recommended to let a real service program have a GUI, but it can be quite useful if you need to let other programs interoperate with the GUI program, i.e. in a normal user login session.  It can also be used as a &amp;quot;quick and dirty&amp;quot; way to expose already existing GUI code as a Web Service (perhaps as a test before creating the real service).&lt;br /&gt;
&lt;br /&gt;
=== Multi-threading ===&lt;br /&gt;
&lt;br /&gt;
No matter how you run the web service (stand-alone with or without GUI, or as ISAPI) you should notice that the HTTP requests run in parallel in several threads. So it is important to ensure that the request handling&amp;#039;s are thread safe.  The &amp;lt;vp&amp;gt;requestQueue_rpc::synchronizer&amp;lt;/vp&amp;gt; property can be used to synchronize the execution of the RPC&amp;#039;s, the property is set to a predicate which will receive &amp;lt;vp&amp;gt;runnable&amp;lt;/vp&amp;gt;s, when the runnable is executed the actual RPC call is performed.  The runnable&amp;#039;s can for example be executed in a monitor ensuring that only one at the time is execute, or be put on a queue and executed sequentially from that or as &amp;lt;vp&amp;gt;jsonRpcService_httpGUI&amp;lt;/vp&amp;gt; does be posted to the GUI queue and thus executed by the GUI thread.&lt;br /&gt;
&lt;br /&gt;
=== Visual Prolog Client ===&lt;br /&gt;
&lt;br /&gt;
This tutorial and the mentioned examples has focused on the Visual Prolog server side, using a web browser as client side. But sometimes a Visual Prolog program may need to access a web service as client.  The example &amp;lt;vp&amp;gt;jsonRpcClient&amp;lt;/vp&amp;gt; illustrates how this can be done.  The method is quite similar to the one used in JavaScript:&lt;br /&gt;
&lt;br /&gt;
* Create a &amp;lt;vp&amp;gt;jsonRpcRequest&amp;lt;/vp&amp;gt; object, with method name and parameters&lt;br /&gt;
* JSON &amp;quot;stringify&amp;quot; it using &amp;lt;vp&amp;gt;asString&amp;lt;/vp&amp;gt;&lt;br /&gt;
* POST it using an XMLHttpRequest object (an instance of &amp;lt;vp&amp;gt;xmlHTTP&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;xmlHTTP60&amp;lt;/vp&amp;gt;)&lt;br /&gt;
* JSON parse the response text  (using &amp;lt;vp&amp;gt;jsonObject::fromString&amp;lt;/vp&amp;gt;)&lt;br /&gt;
* Check for &amp;quot;error&amp;quot; member&lt;br /&gt;
&lt;br /&gt;
In the example program you see a &amp;lt;vp&amp;gt;delayCall&amp;lt;/vp&amp;gt;, whose purpose is to allow the GUI to be updated, without this call the GUI would not update until after the RPC have completed.  The call is however irrelevant for the RPC itself.&lt;br /&gt;
&lt;br /&gt;
=== Skype HTTP/HTTPS Conflict ===&lt;br /&gt;
{{:Include/SkypeHTTPConflict}}&lt;br /&gt;
&lt;br /&gt;
=== HTTPS ===&lt;br /&gt;
&lt;br /&gt;
Finally a set if brief notes about Secure connections (SSL/TLS).&lt;br /&gt;
&lt;br /&gt;
HTTPS is the HTTP protocol used over a secure socket.  Both the IIS and the stand alone HTTP Server can use HTTPS.  To use HTTPS the server computer must have a certificate.  It is possible to create a certificate yourself, but a self created certificate is &amp;quot;untrusted&amp;quot; will therefore cause security notifications.  This is sufficient for testing and development purposes, but for real scale purposes you will have to acquire a trusted certificate.&lt;br /&gt;
&lt;br /&gt;
In brief a trusted certificate have to be obtained from a trusted provider.  The trust lies in three things:&lt;br /&gt;
* The provider is itself trusted&lt;br /&gt;
* The provider have knowledge about the &amp;quot;real identity&amp;quot; of the certificate holder (through normal purchase chains)&lt;br /&gt;
* The provider can revoke the certificate if it is misused somehow&lt;br /&gt;
&lt;br /&gt;
Notice that HTTPS by default uses port 443 (and HTTP uses port 80), and that you have to write &amp;quot;https&amp;quot; in the places where you would otherwise write &amp;quot;http&amp;quot; (e.g. &amp;#039;&amp;#039;&amp;#039;https:&amp;lt;nowiki /&amp;gt;//+:443/mypath&amp;#039;&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
For test purposes you can create self signed certificates using the power shell command &amp;quot;New-SelfSignedSertificate&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
 New-SelfSignedCertificate -DnsName &amp;quot;*.localhost.xx&amp;quot;&amp;quot; -CertStoreLocation &amp;quot;cert:\LocalMachine\My&amp;quot; -NotAfter (Get-Date).AddYears(10)&lt;br /&gt;
&lt;br /&gt;
If run &amp;quot;Manage Computer Certificates&amp;quot; you will find it in &amp;quot;Personal\Certificates&amp;quot; and if you copy it to &amp;quot;Trusted Root Certificates\Certificates&amp;quot; (it must be both places) then you computer will trust it.&lt;br /&gt;
&lt;br /&gt;
Double clicking the certificate and viewing the details will reveal the ThumbPrint which is the identifier of the certificate.&lt;br /&gt;
&lt;br /&gt;
You will use this identifier to tie the certificate to the connection.  This is done by adding an &amp;quot;sslcert&amp;quot; record with &amp;quot;netsh&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
 netsh http add sslcert hostnameport=demo.localhost.xx:443 certhash=19bde81e1b443b28fe75553cc52e0d8ba99978f1 appid={00112233-4455-6677-8899-AABBCCDDEEFF} certstorename=MY&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;certhash&amp;quot; identifies certificate (the ThumpPrint in the certificate details), the purpose of the &amp;quot;appid&amp;quot; is a unclear to me but it is in any case a GUID.&lt;br /&gt;
&lt;br /&gt;
To make test with &amp;quot;real&amp;quot; server names like &amp;quot;demo.localhost.xx&amp;quot; you can make an 127.0.0.1 entry in the &amp;quot;hosts&amp;quot; file (C:\Windows\System32\Drivers\etc\hosts):&lt;br /&gt;
 ...&lt;br /&gt;
 # localhost name resolution is handled within DNS itself.&lt;br /&gt;
 #	127.0.0.1       localhost&lt;br /&gt;
 #	::1             localhost&lt;br /&gt;
 127.0.0.1 demo.localhost.xx&lt;br /&gt;
&lt;br /&gt;
In JavaScript you can get the protocol like this:&lt;br /&gt;
&lt;br /&gt;
 // JSON RPC handling&lt;br /&gt;
 const apiUrl = window.location.protocol + &amp;#039;//&amp;#039; + window.location.host + &amp;#039;/api&amp;#039;&lt;br /&gt;
&lt;br /&gt;
For web sockets like this:&lt;br /&gt;
&lt;br /&gt;
 // webSocket handling&lt;br /&gt;
 const wsProtocol = (&amp;#039;https:&amp;#039; == window.location.protocol ? &amp;#039;wss:&amp;#039; : &amp;#039;ws:&amp;#039;)&lt;br /&gt;
 const wsUrl = wsProtocol + &amp;#039;//&amp;#039; + window.location.host + &amp;#039;/ws/&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== See also ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.json.org/ JSON]&lt;br /&gt;
* [http://www.jsonrpc.org/specification JSON-RPC 2.0 Specification]&lt;br /&gt;
* Microsoft&amp;#039;s [http://msdn.microsoft.com/en-us/library/windows/desktop/aa364510(v=vs.85).aspx HTTP Server API]&lt;br /&gt;
&lt;br /&gt;
[[Category:Internet]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_11_New_Features&amp;diff=4935</id>
		<title>Visual Prolog 11 New Features</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_11_New_Features&amp;diff=4935"/>
		<updated>2024-04-24T10:50:18Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: examples link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Visual Prolog 11 has been extended with {{lang|Suspending Predicates|Suspending Predicates}}.&lt;br /&gt;
&lt;br /&gt;
The development system can only run on 64 bit Windows, but can still build programs for both 32 and 64 bit Windows.&lt;br /&gt;
&lt;br /&gt;
New utility &amp;quot;[[vipLaunch]]&amp;quot; for launching projects in correct IDE.  The installer is included in the Visual Prolog 11 installer, but you can also install the latest version directly here [https://www.visual-prolog.com/link/vipLaunch.php vipLaunch installer].&lt;br /&gt;
&lt;br /&gt;
Download Visual Prolog 11 [https://www.visual-prolog.com/link/examples.php?version=11 Demo Examples].&lt;br /&gt;
&lt;br /&gt;
== Build 1105 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* {{lang|Suspending Predicates|Suspending Predicates}}&lt;br /&gt;
* {{lang2|Attributes|feature|feature}} attribute, built-in predicate &amp;lt;vp&amp;gt;is_feature_available&amp;lt;/vp&amp;gt;, compiler option &amp;#039;&amp;#039;&amp;#039;/ENABLEFEature:feature_name&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Built-in predicates &amp;lt;vp&amp;gt;convertAllowNull&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;tryConvertAllowNull&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Built-in constants &amp;lt;interface&amp;gt;&amp;lt;vp&amp;gt;::null&amp;lt;/vp&amp;gt; for all interfaces&lt;br /&gt;
* Warning: explicit &amp;lt;vp&amp;gt;programmingPoint&amp;lt;/vp&amp;gt; available&lt;br /&gt;
* Embedded string8 (utf8) support (literals and conversions)&lt;br /&gt;
* Warning c665 for a fact which is always initialized with a constant and is not changed (switched off by the default)&lt;br /&gt;
* Digit separator support (syntax only) &amp;lt;vp&amp;gt;1_000_000&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;0x_1A2B_3C4D&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Support for asynchronous programming by means of suspending predicates:&lt;br /&gt;
** New: &amp;lt;vp&amp;gt;executionContext_pool&amp;lt;/vp&amp;gt; a multi threaded pool for asynchronous and background work&lt;br /&gt;
** New: &amp;lt;vp&amp;gt;executionContext_single&amp;lt;/vp&amp;gt; a single threaded worker for asynchronous work&lt;br /&gt;
** New: Suspending predicates can be executed in a GUI thread (using &amp;lt;vp&amp;gt;future::submit&amp;lt;/vp&amp;gt;)&lt;br /&gt;
** New: Diverse suspending predicate domains in &amp;lt;vp&amp;gt;core&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;asyncSocket&amp;lt;/vp&amp;gt; &amp;amp; &amp;lt;vp&amp;gt;asyncSocketListener&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: master/slave support&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;promise&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: HTTP server &amp;amp; JSON RPC &amp;amp; &amp;lt;vp&amp;gt;webSocket&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;webView2&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;watchDirectory&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Removed: &amp;lt;vp&amp;gt;continuation&amp;lt;/vp&amp;gt; class and inteface due to redundancy.&lt;br /&gt;
** Removed: &amp;lt;vp&amp;gt;threadpool&amp;lt;/vp&amp;gt; and all related classes and interfaces due to redundancy.&lt;br /&gt;
** New support class: &amp;lt;vp&amp;gt;resumable&amp;lt;/vp&amp;gt; class for internal support of suspending predicates&lt;br /&gt;
** New support classes: &amp;lt;vp&amp;gt;tp&amp;lt;/vp&amp;gt; (etc) internal win32 threadpool interface for dealing with asynchronous io, timers, syncObject waiting, etc&lt;br /&gt;
** Deprecated/removed diverse continuation based stuff&lt;br /&gt;
* MSXML import free threaded xmlhttp: including &amp;lt;vp&amp;gt;iXMLHTTPRequest3&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Predicate &amp;lt;vp&amp;gt;messageBox::displayWarningYesNo_dt&amp;lt;/vp&amp;gt; replacement for &amp;lt;vp&amp;gt;displayWarning_dt&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Deprecate &amp;lt;vp&amp;gt;messageBox::displayWarning_dt&amp;lt;/vp&amp;gt;: UX: It is reccomended to use Yes/No warnings instead of OK/Cancel&lt;br /&gt;
* Color predicates &amp;lt;vp&amp;gt;blendColor&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;darken&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;lighten&amp;lt;/vp&amp;gt; in &amp;lt;vp&amp;gt;gdiplus&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;fetchString8asString&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;useLocalTimeValue&amp;lt;/vp&amp;gt; properties on &amp;lt;vp&amp;gt;odbcConnection&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;odbcStatement&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;delayCallLimit&amp;lt;/vp&amp;gt; predicate on &amp;lt;vp&amp;gt;window&amp;lt;/vp&amp;gt; for delay calls with a MaxDelay.&lt;br /&gt;
* &amp;lt;vp&amp;gt;inputStream_binary&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;outputStream_binary&amp;lt;/vp&amp;gt; supports/allows ansi(utf8) mode.&lt;br /&gt;
* Improved &amp;lt;vp&amp;gt;outputStream&amp;lt;/vp&amp;gt; performance for &amp;lt;vp&amp;gt;messageControl&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;event0&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;event1&amp;lt;/vp&amp;gt;, ... classes: lock free threadsafe.&lt;br /&gt;
* &amp;#039;Sergoe Fluent Icons&amp;#039;/&amp;#039;Segoe MDL2 Assets&amp;#039; glyph icons in ribbonControl/commands&lt;br /&gt;
* Explorer theme is applied to &amp;lt;vp&amp;gt;treeControl&amp;lt;/vp&amp;gt; by default.&lt;br /&gt;
* &amp;lt;vp&amp;gt;monitorQueue&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;monitorQueue_length&amp;lt;/vp&amp;gt; are updated with &amp;lt;vp&amp;gt;close&amp;lt;/vp&amp;gt; functionality.  As a result the &amp;lt;vp&amp;gt;dequeue&amp;lt;/vp&amp;gt; operation has become determ.&lt;br /&gt;
* Console projects supports [https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences Console Virtual Terminal Sequences] (by off default).&lt;br /&gt;
* flag &amp;lt;vp&amp;gt;jsonRpcApi{@Context}::exceptionTraceLevel&amp;lt;/vp&amp;gt; controlling which/when exception dumps that are send to the client side.&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* Main IDE is now always 64bit&lt;br /&gt;
* [[Ide/Debugger#Debug_Adapter|Debug Adapter]] makes cross-debugging to 32bit possible&lt;br /&gt;
* Dynamic Help (based on browse information and syntax parsing results)&lt;br /&gt;
* New toolbar&lt;br /&gt;
* vipId support&lt;br /&gt;
* Use new Sergoe Fluent Icons&lt;br /&gt;
* Default SDI project includes &amp;#039;Sergoe Fluent Icons&amp;#039;/&amp;#039;Segoe MDL2 Assets&amp;#039; glyph icons the ribbonControl/commands&lt;br /&gt;
* Add variable $(node_modules)&lt;br /&gt;
* New Menu item handlers (move code expert to properties window)&lt;br /&gt;
* Alt+X converts (unicode) hex to char&lt;br /&gt;
* changes.htm and appData\doc\vip.chm handling&lt;br /&gt;
* Updated Welcome window&lt;br /&gt;
* splitterControl in welcome page&lt;br /&gt;
* Build system: pre-build command&lt;br /&gt;
* Automatic parallel obj/deb directories&lt;br /&gt;
&lt;br /&gt;
=== Debugger ===&lt;br /&gt;
&lt;br /&gt;
* Debugging now uses a [[Ide/Debugger#Debug_Adapter|Debug Adapter]]&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
* Remove superfluous webRpc demo &amp;amp; update webServiceDemo to dispose the session.&lt;br /&gt;
* The &amp;lt;vp&amp;gt;webServiceDemo&amp;lt;/vp&amp;gt; is updated to demonstrate usage of the flag &amp;lt;vp&amp;gt;jsonRpcApi{@Context}::exceptionTraceLevel&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* Add zip / unzip functionality&lt;br /&gt;
&lt;br /&gt;
== Build 1106 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Subtype presenter problem&lt;br /&gt;
* Fix: Stack overflow exception on binary constant allocation&lt;br /&gt;
* Fix: Wrong debug info for unbound variable (functor component)&lt;br /&gt;
* Fix: Debugger/presenters: false objects&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* webView2&lt;br /&gt;
** Fix: Windows 7 and Windows 8 compatibility./li&amp;gt;&lt;br /&gt;
** Additional CompleteHandler handling (suspending predicates).&lt;br /&gt;
* Fix: &amp;lt;vp&amp;gt;ribbonControl&amp;lt;/vp&amp;gt;: Release native graphics context.&lt;br /&gt;
* odbc: add column/parameter number for results longer than the buffer.&lt;br /&gt;
* &amp;lt;vp&amp;gt;window::centerTo&amp;lt;/vp&amp;gt;: map to Windows parent (not pfc parent).&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;webView2&amp;lt;/vp&amp;gt; control show on Windows 7/8 &amp;amp; update build number&lt;br /&gt;
* show correct build number&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;comWrap&amp;lt;/vp&amp;gt;: Handle more winRT CompleteHandlers (for webView2)&lt;br /&gt;
* Fix: Runtime debugger/presenters: false objects&lt;br /&gt;
&lt;br /&gt;
== Build 1107 ==&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* New class &amp;lt;vp&amp;gt;gcUcBuffer&amp;lt;/vp&amp;gt;: for buffers that cannot be caught by false pointers.&lt;br /&gt;
* odbc: utilize &amp;lt;vp&amp;gt;gcUcBuffer&amp;lt;/vp&amp;gt; to avoid that odbc buffers are caught by false pointers.&lt;br /&gt;
* New predicate &amp;lt;vp&amp;gt;clipBoard::putFileList&amp;lt;/vp&amp;gt; for putting files on the clipboard in the pre-defined hDrop format.&lt;br /&gt;
* &amp;lt;vp&amp;gt;command&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;ribbonControl&amp;lt;/vp&amp;gt;: new responder &amp;lt;vp&amp;gt;queryBadgeState&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* Prevent &amp;lt;vp&amp;gt;vpi::processEvents&amp;lt;/vp&amp;gt; from interfering with &amp;lt;vp&amp;gt;postAction&amp;lt;/vp&amp;gt; order.&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* Personal edition supports 64 bit targets.&lt;br /&gt;
* Open external browser for registration, wiki-help and forum links.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Help -&amp;gt; Prolog Foundation Classes (PFC)&amp;#039;&amp;#039;&amp;#039; opens vip.chm.&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
Fix: MemoryProfiler wrong scaling of total graph.&lt;br /&gt;
&lt;br /&gt;
== Build 1108 ==&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* New property &amp;lt;vp&amp;gt;remoteAddress&amp;lt;/vp&amp;gt; on interface &amp;lt;vp&amp;gt;httpRequest&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* New predicate &amp;lt;vp&amp;gt;memory::mkCopy_atomic&amp;lt;/vp&amp;gt; for copying structs.&lt;br /&gt;
* New predicates &amp;lt;vp&amp;gt;formatSocketAddress&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;formatSockAddr&amp;lt;/vp&amp;gt; in class &amp;lt;vp&amp;gt;winSock2_api&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;winSock2_api&amp;lt;/vp&amp;gt; correct and simplify various domains.&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Exceptions when git is not installed.&lt;br /&gt;
&lt;br /&gt;
== Build 1110 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;match&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;case&amp;lt;/vp&amp;gt; has been reserved as keywords in next major release.&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Wrong type of parameter type in predicate &amp;lt;vp&amp;gt;winHttp_native::winHttpSetOption&amp;lt;/vp&amp;gt; declaration.&lt;br /&gt;
* Fix: Eliminate race condition for &amp;lt;vp&amp;gt;postAction&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* Deprecate &amp;lt;vp&amp;gt;time::getTickCount&amp;lt;/vp&amp;gt; in favour of &amp;lt;vp&amp;gt;performanceCounter&amp;lt;/vp&amp;gt;&amp;#039;s.&lt;br /&gt;
* Deprecate &amp;lt;vp&amp;gt;regEx::match&amp;lt;/vp&amp;gt; because &amp;lt;vp&amp;gt;match&amp;lt;/vp&amp;gt; will become a keyword.&lt;br /&gt;
&lt;br /&gt;
== Build 1111 ==&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Fix: time_api::getTimeZoneOffset hours -&amp;gt; minutes&lt;br /&gt;
* Fix: odbcStatement::free: allow to be called more than once&lt;br /&gt;
* Fix: stringFormat (gdiplus): nullary constructor must create a fresh object&lt;br /&gt;
&lt;br /&gt;
=== Debugger ===&lt;br /&gt;
&lt;br /&gt;
Fix: Dictionary loading timeout for large programs in debug adaptor&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
See also [[Visual Prolog 11 Upgrade Notes]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Release Notes|11 New Features]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_11_New_Features&amp;diff=4934</id>
		<title>Visual Prolog 11 New Features</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_11_New_Features&amp;diff=4934"/>
		<updated>2024-04-24T10:49:18Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Build 1111&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Visual Prolog 11 has been extended with {{lang|Suspending Predicates|Suspending Predicates}}.&lt;br /&gt;
&lt;br /&gt;
The development system can only run on 64 bit Windows, but can still build programs for both 32 and 64 bit Windows.&lt;br /&gt;
&lt;br /&gt;
New utility &amp;quot;[[vipLaunch]]&amp;quot; for launching projects in correct IDE.  The installer is included in the Visual Prolog 11 installer, but you can also install the latest version directly here [https://www.visual-prolog.com/link/vipLaunch.php vipLaunch installer].&lt;br /&gt;
&lt;br /&gt;
Download Visual Prolog 11 [https://www.visual-prolog.com/link/demo.php?version=11 Demo Examples].&lt;br /&gt;
&lt;br /&gt;
== Build 1105 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* {{lang|Suspending Predicates|Suspending Predicates}}&lt;br /&gt;
* {{lang2|Attributes|feature|feature}} attribute, built-in predicate &amp;lt;vp&amp;gt;is_feature_available&amp;lt;/vp&amp;gt;, compiler option &amp;#039;&amp;#039;&amp;#039;/ENABLEFEature:feature_name&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Built-in predicates &amp;lt;vp&amp;gt;convertAllowNull&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;tryConvertAllowNull&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Built-in constants &amp;lt;interface&amp;gt;&amp;lt;vp&amp;gt;::null&amp;lt;/vp&amp;gt; for all interfaces&lt;br /&gt;
* Warning: explicit &amp;lt;vp&amp;gt;programmingPoint&amp;lt;/vp&amp;gt; available&lt;br /&gt;
* Embedded string8 (utf8) support (literals and conversions)&lt;br /&gt;
* Warning c665 for a fact which is always initialized with a constant and is not changed (switched off by the default)&lt;br /&gt;
* Digit separator support (syntax only) &amp;lt;vp&amp;gt;1_000_000&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;0x_1A2B_3C4D&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Support for asynchronous programming by means of suspending predicates:&lt;br /&gt;
** New: &amp;lt;vp&amp;gt;executionContext_pool&amp;lt;/vp&amp;gt; a multi threaded pool for asynchronous and background work&lt;br /&gt;
** New: &amp;lt;vp&amp;gt;executionContext_single&amp;lt;/vp&amp;gt; a single threaded worker for asynchronous work&lt;br /&gt;
** New: Suspending predicates can be executed in a GUI thread (using &amp;lt;vp&amp;gt;future::submit&amp;lt;/vp&amp;gt;)&lt;br /&gt;
** New: Diverse suspending predicate domains in &amp;lt;vp&amp;gt;core&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;asyncSocket&amp;lt;/vp&amp;gt; &amp;amp; &amp;lt;vp&amp;gt;asyncSocketListener&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: master/slave support&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;promise&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: HTTP server &amp;amp; JSON RPC &amp;amp; &amp;lt;vp&amp;gt;webSocket&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;webView2&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Updated: &amp;lt;vp&amp;gt;watchDirectory&amp;lt;/vp&amp;gt;&lt;br /&gt;
** Removed: &amp;lt;vp&amp;gt;continuation&amp;lt;/vp&amp;gt; class and inteface due to redundancy.&lt;br /&gt;
** Removed: &amp;lt;vp&amp;gt;threadpool&amp;lt;/vp&amp;gt; and all related classes and interfaces due to redundancy.&lt;br /&gt;
** New support class: &amp;lt;vp&amp;gt;resumable&amp;lt;/vp&amp;gt; class for internal support of suspending predicates&lt;br /&gt;
** New support classes: &amp;lt;vp&amp;gt;tp&amp;lt;/vp&amp;gt; (etc) internal win32 threadpool interface for dealing with asynchronous io, timers, syncObject waiting, etc&lt;br /&gt;
** Deprecated/removed diverse continuation based stuff&lt;br /&gt;
* MSXML import free threaded xmlhttp: including &amp;lt;vp&amp;gt;iXMLHTTPRequest3&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Predicate &amp;lt;vp&amp;gt;messageBox::displayWarningYesNo_dt&amp;lt;/vp&amp;gt; replacement for &amp;lt;vp&amp;gt;displayWarning_dt&amp;lt;/vp&amp;gt;&lt;br /&gt;
* Deprecate &amp;lt;vp&amp;gt;messageBox::displayWarning_dt&amp;lt;/vp&amp;gt;: UX: It is reccomended to use Yes/No warnings instead of OK/Cancel&lt;br /&gt;
* Color predicates &amp;lt;vp&amp;gt;blendColor&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;darken&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;lighten&amp;lt;/vp&amp;gt; in &amp;lt;vp&amp;gt;gdiplus&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;fetchString8asString&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;useLocalTimeValue&amp;lt;/vp&amp;gt; properties on &amp;lt;vp&amp;gt;odbcConnection&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;odbcStatement&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;delayCallLimit&amp;lt;/vp&amp;gt; predicate on &amp;lt;vp&amp;gt;window&amp;lt;/vp&amp;gt; for delay calls with a MaxDelay.&lt;br /&gt;
* &amp;lt;vp&amp;gt;inputStream_binary&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;outputStream_binary&amp;lt;/vp&amp;gt; supports/allows ansi(utf8) mode.&lt;br /&gt;
* Improved &amp;lt;vp&amp;gt;outputStream&amp;lt;/vp&amp;gt; performance for &amp;lt;vp&amp;gt;messageControl&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;event0&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;event1&amp;lt;/vp&amp;gt;, ... classes: lock free threadsafe.&lt;br /&gt;
* &amp;#039;Sergoe Fluent Icons&amp;#039;/&amp;#039;Segoe MDL2 Assets&amp;#039; glyph icons in ribbonControl/commands&lt;br /&gt;
* Explorer theme is applied to &amp;lt;vp&amp;gt;treeControl&amp;lt;/vp&amp;gt; by default.&lt;br /&gt;
* &amp;lt;vp&amp;gt;monitorQueue&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;monitorQueue_length&amp;lt;/vp&amp;gt; are updated with &amp;lt;vp&amp;gt;close&amp;lt;/vp&amp;gt; functionality.  As a result the &amp;lt;vp&amp;gt;dequeue&amp;lt;/vp&amp;gt; operation has become determ.&lt;br /&gt;
* Console projects supports [https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences Console Virtual Terminal Sequences] (by off default).&lt;br /&gt;
* flag &amp;lt;vp&amp;gt;jsonRpcApi{@Context}::exceptionTraceLevel&amp;lt;/vp&amp;gt; controlling which/when exception dumps that are send to the client side.&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* Main IDE is now always 64bit&lt;br /&gt;
* [[Ide/Debugger#Debug_Adapter|Debug Adapter]] makes cross-debugging to 32bit possible&lt;br /&gt;
* Dynamic Help (based on browse information and syntax parsing results)&lt;br /&gt;
* New toolbar&lt;br /&gt;
* vipId support&lt;br /&gt;
* Use new Sergoe Fluent Icons&lt;br /&gt;
* Default SDI project includes &amp;#039;Sergoe Fluent Icons&amp;#039;/&amp;#039;Segoe MDL2 Assets&amp;#039; glyph icons the ribbonControl/commands&lt;br /&gt;
* Add variable $(node_modules)&lt;br /&gt;
* New Menu item handlers (move code expert to properties window)&lt;br /&gt;
* Alt+X converts (unicode) hex to char&lt;br /&gt;
* changes.htm and appData\doc\vip.chm handling&lt;br /&gt;
* Updated Welcome window&lt;br /&gt;
* splitterControl in welcome page&lt;br /&gt;
* Build system: pre-build command&lt;br /&gt;
* Automatic parallel obj/deb directories&lt;br /&gt;
&lt;br /&gt;
=== Debugger ===&lt;br /&gt;
&lt;br /&gt;
* Debugging now uses a [[Ide/Debugger#Debug_Adapter|Debug Adapter]]&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
* Remove superfluous webRpc demo &amp;amp; update webServiceDemo to dispose the session.&lt;br /&gt;
* The &amp;lt;vp&amp;gt;webServiceDemo&amp;lt;/vp&amp;gt; is updated to demonstrate usage of the flag &amp;lt;vp&amp;gt;jsonRpcApi{@Context}::exceptionTraceLevel&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* Add zip / unzip functionality&lt;br /&gt;
&lt;br /&gt;
== Build 1106 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Subtype presenter problem&lt;br /&gt;
* Fix: Stack overflow exception on binary constant allocation&lt;br /&gt;
* Fix: Wrong debug info for unbound variable (functor component)&lt;br /&gt;
* Fix: Debugger/presenters: false objects&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* webView2&lt;br /&gt;
** Fix: Windows 7 and Windows 8 compatibility./li&amp;gt;&lt;br /&gt;
** Additional CompleteHandler handling (suspending predicates).&lt;br /&gt;
* Fix: &amp;lt;vp&amp;gt;ribbonControl&amp;lt;/vp&amp;gt;: Release native graphics context.&lt;br /&gt;
* odbc: add column/parameter number for results longer than the buffer.&lt;br /&gt;
* &amp;lt;vp&amp;gt;window::centerTo&amp;lt;/vp&amp;gt;: map to Windows parent (not pfc parent).&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;webView2&amp;lt;/vp&amp;gt; control show on Windows 7/8 &amp;amp; update build number&lt;br /&gt;
* show correct build number&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;comWrap&amp;lt;/vp&amp;gt;: Handle more winRT CompleteHandlers (for webView2)&lt;br /&gt;
* Fix: Runtime debugger/presenters: false objects&lt;br /&gt;
&lt;br /&gt;
== Build 1107 ==&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* New class &amp;lt;vp&amp;gt;gcUcBuffer&amp;lt;/vp&amp;gt;: for buffers that cannot be caught by false pointers.&lt;br /&gt;
* odbc: utilize &amp;lt;vp&amp;gt;gcUcBuffer&amp;lt;/vp&amp;gt; to avoid that odbc buffers are caught by false pointers.&lt;br /&gt;
* New predicate &amp;lt;vp&amp;gt;clipBoard::putFileList&amp;lt;/vp&amp;gt; for putting files on the clipboard in the pre-defined hDrop format.&lt;br /&gt;
* &amp;lt;vp&amp;gt;command&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;ribbonControl&amp;lt;/vp&amp;gt;: new responder &amp;lt;vp&amp;gt;queryBadgeState&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* Prevent &amp;lt;vp&amp;gt;vpi::processEvents&amp;lt;/vp&amp;gt; from interfering with &amp;lt;vp&amp;gt;postAction&amp;lt;/vp&amp;gt; order.&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* Personal edition supports 64 bit targets.&lt;br /&gt;
* Open external browser for registration, wiki-help and forum links.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Help -&amp;gt; Prolog Foundation Classes (PFC)&amp;#039;&amp;#039;&amp;#039; opens vip.chm.&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
Fix: MemoryProfiler wrong scaling of total graph.&lt;br /&gt;
&lt;br /&gt;
== Build 1108 ==&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* New property &amp;lt;vp&amp;gt;remoteAddress&amp;lt;/vp&amp;gt; on interface &amp;lt;vp&amp;gt;httpRequest&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* New predicate &amp;lt;vp&amp;gt;memory::mkCopy_atomic&amp;lt;/vp&amp;gt; for copying structs.&lt;br /&gt;
* New predicates &amp;lt;vp&amp;gt;formatSocketAddress&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;formatSockAddr&amp;lt;/vp&amp;gt; in class &amp;lt;vp&amp;gt;winSock2_api&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* &amp;lt;vp&amp;gt;winSock2_api&amp;lt;/vp&amp;gt; correct and simplify various domains.&lt;br /&gt;
&lt;br /&gt;
=== IDE ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Exceptions when git is not installed.&lt;br /&gt;
&lt;br /&gt;
== Build 1110 ==&lt;br /&gt;
&lt;br /&gt;
=== Language ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;match&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;case&amp;lt;/vp&amp;gt; has been reserved as keywords in next major release.&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Fix: Wrong type of parameter type in predicate &amp;lt;vp&amp;gt;winHttp_native::winHttpSetOption&amp;lt;/vp&amp;gt; declaration.&lt;br /&gt;
* Fix: Eliminate race condition for &amp;lt;vp&amp;gt;postAction&amp;lt;/vp&amp;gt;.&lt;br /&gt;
* Deprecate &amp;lt;vp&amp;gt;time::getTickCount&amp;lt;/vp&amp;gt; in favour of &amp;lt;vp&amp;gt;performanceCounter&amp;lt;/vp&amp;gt;&amp;#039;s.&lt;br /&gt;
* Deprecate &amp;lt;vp&amp;gt;regEx::match&amp;lt;/vp&amp;gt; because &amp;lt;vp&amp;gt;match&amp;lt;/vp&amp;gt; will become a keyword.&lt;br /&gt;
&lt;br /&gt;
== Build 1111 ==&lt;br /&gt;
&lt;br /&gt;
=== PFC ===&lt;br /&gt;
&lt;br /&gt;
* Fix: time_api::getTimeZoneOffset hours -&amp;gt; minutes&lt;br /&gt;
* Fix: odbcStatement::free: allow to be called more than once&lt;br /&gt;
* Fix: stringFormat (gdiplus): nullary constructor must create a fresh object&lt;br /&gt;
&lt;br /&gt;
=== Debugger ===&lt;br /&gt;
&lt;br /&gt;
Fix: Dictionary loading timeout for large programs in debug adaptor&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
See also [[Visual Prolog 11 Upgrade Notes]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Release Notes|11 New Features]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_10_Upgrade_Notes&amp;diff=4933</id>
		<title>Visual Prolog 10 Upgrade Notes</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_10_Upgrade_Notes&amp;diff=4933"/>
		<updated>2024-04-18T14:16:03Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: ctrl -&amp;gt; clt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document describes how to upgrade Visual Prolog 9 projects to Visual Prolog 10, for older projects you should also read the [[Visual Prolog 9 Upgrade Notes]].&lt;br /&gt;
&lt;br /&gt;
If you have problems with upgrading your projects and need additional information, you are welcome to ask questions in [http://discuss.visual-prolog.com/viewforum.php?f=2 Visual Prolog Discussion Forum].&lt;br /&gt;
&lt;br /&gt;
By default, the installation of Visual Prolog 10 will not replace any previously installed versions. It is possible to work with several versions on a single computer.&lt;br /&gt;
* The Commercial Edition will by default be installed in &amp;#039;&amp;#039;&amp;#039;C:\Program Files (x86)\Visual Prolog 10&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;C:\Program Files\Visual Prolog 10&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* The Personal Edition will by default be installed to &amp;#039;&amp;#039;&amp;#039;C:\Program Files (x86)\Visual Prolog 10PE&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;C:\Program Files\Visual Prolog 10PE&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Visual Prolog 10 projects are backward-compatible with Visual Prolog 9 projects.&lt;br /&gt;
If you are going to use different versions of Visual Prolog installed at one computer, avoid opening projects by double-clicking on vipprj files.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Notice&amp;#039;&amp;#039;&amp;#039; it is highly advisable to have a backup of a project before updating.&lt;br /&gt;
&lt;br /&gt;
=== Superfluos files ===&lt;br /&gt;
&lt;br /&gt;
The following files are superfluous and should be deleted:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;.frm&amp;#039;&amp;#039;&amp;#039; related to forms&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;.win&amp;#039;&amp;#039;&amp;#039; related to e.g. the task window&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;.ctl&amp;#039;&amp;#039;&amp;#039; related to controls&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;.dlg&amp;#039;&amp;#039;&amp;#039; related to dialogs; &amp;#039;&amp;#039;&amp;#039;except&amp;#039;&amp;#039;&amp;#039; if it corresponds to &amp;quot;aincient&amp;quot; Visual Prolog 5 resource dialog that has been &amp;quot;inherited&amp;quot; into the project.  If in doubt: the code in the corresponding &amp;#039;&amp;#039;&amp;#039;.pro&amp;#039;&amp;#039;&amp;#039; file of such a dialog will not contain a &amp;lt;vp&amp;gt;generatedInitialize&amp;lt;/vp&amp;gt; predicate.&lt;br /&gt;
&lt;br /&gt;
=== Binary memory representation ===&lt;br /&gt;
&lt;br /&gt;
Binaries have changed representation. In the old representation a binary was a pointer to the actual data, and immediately before the data the size of the binary was written. Windows API and other external APIs does not use this representation and as a consequence binaries was often had to be copied from the buffer that cntains it to another &amp;quot;buffer&amp;quot; that can hold the size infront of the data. A &amp;lt;vp&amp;gt;binary&amp;lt;/vp&amp;gt; is now represented as a pointer to a memory cell containing a pointer to a data-buffer and the size. So the size is no longer placed in a specific place relative to the actual data. With the old representation &amp;lt;vp&amp;gt;uncheckedConvert&amp;lt;/vp&amp;gt; of a binary to the &amp;lt;vp&amp;gt;pointer&amp;lt;/vp&amp;gt; domain would result in a pointer to the data. With the new representation this is no longer the case and therefore it has been made illegal to &amp;lt;vp&amp;gt;uncheckedConvert&amp;lt;/vp&amp;gt; from &amp;lt;vp&amp;gt;binary&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;pointer&amp;lt;/vp&amp;gt;, instead you must use &amp;lt;vp&amp;gt;convert&amp;lt;/vp&amp;gt; which will both in old and new representation give a pointer to the data. Alternatively, you can use the extension predicate &amp;lt;vp&amp;gt;binary::data()&amp;lt;/vp&amp;gt; instead, e.g. &amp;lt;vp&amp;gt;Pointer = MyBinary:date()&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== List comprehension ===&lt;br /&gt;
&lt;br /&gt;
In a list comprehension &amp;lt;vp&amp;gt;[ Exp || Gen ]&amp;lt;/vp&amp;gt; the &amp;lt;vp&amp;gt;Exp&amp;lt;/vp&amp;gt; must be a procedure (language reference has always required that, but the compiler has accepted &amp;lt;vp&amp;gt;determ&amp;lt;/vp&amp;gt; expressions). In cases where &amp;lt;vp&amp;gt;Exp&amp;lt;/vp&amp;gt; is determ the following rewrite can be applied &amp;lt;vp&amp;gt;[ V || Gen, V = Exp ]&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;&amp;gt;_list domains deprecated ===&lt;br /&gt;
&lt;br /&gt;
The domains &amp;lt;vp&amp;gt;integer_list&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;integer_list_list&amp;lt;/vp&amp;gt;, etc. has been deprecated. In declarations the *-form should be used, but in predicate calls like &amp;lt;vp&amp;gt;tryToTerm&amp;lt;/vp&amp;gt; it is necessary to uses the &amp;lt;vp&amp;gt;list{...}&amp;lt;/vp&amp;gt; type constructor, e.g. &amp;lt;vp&amp;gt;tryToTerm(list{integer}, String)&amp;lt;/vp&amp;gt;. An old program can require a significant amount of updates.&lt;br /&gt;
&lt;br /&gt;
=== Erroneous predicates as values ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;erroneous&amp;lt;/vp&amp;gt; predicates can now be used as a value, for example in &amp;lt;vp&amp;gt;X otherwise raise_error()&amp;lt;/vp&amp;gt;. Hereby &amp;lt;vp&amp;gt;erroneous&amp;lt;/vp&amp;gt; functions have become superfluous, and subsequently it is now illegal to declare &amp;lt;vp&amp;gt;erroneous&amp;lt;/vp&amp;gt; functions (a corresponding &amp;lt;vp&amp;gt;erroneous&amp;lt;/vp&amp;gt; predicate must be used instead).&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Visual Prolog 10 New Features]]&lt;br /&gt;
* [[Visual Prolog 9 Upgrade Notes]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Release Notes|10 Upgrade Notes]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Language_Reference/Suspending_Predicates&amp;diff=4932</id>
		<title>Language Reference/Suspending Predicates</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Language_Reference/Suspending_Predicates&amp;diff=4932"/>
		<updated>2024-04-16T12:58:59Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: Category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{languageReferenceNavbar|Suspending Predicates}}&lt;br /&gt;
&lt;br /&gt;
The purpose of &amp;#039;&amp;#039;&amp;#039;suspending&amp;#039;&amp;#039;&amp;#039; predicates is to support asynchronous programming, parallelism, coroutines, etc.&lt;br /&gt;
&lt;br /&gt;
A suspending predicate can suspend its execution and resume it later when &amp;#039;possible&amp;#039; or &amp;#039;feasible&amp;#039;.  In an asynchronous context, a suspending predicate suspends its execution when it is waiting for an asynchronous operation to complete, allowing other operations to proceed concurrently.&lt;br /&gt;
&lt;br /&gt;
A key advantage of suspending predicates is that they do not block threads while in suspended state, thus enabling efficient utilization of resources. This feature makes them particularly useful in situations where multiple tasks are being executed concurrently.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
We want to have a loop that reads messages from a &amp;lt;vp&amp;gt;webSocket&amp;lt;/vp&amp;gt; and echoes them back to the sender.&lt;br /&gt;
Most of the time this loop would be waiting for some operation to complete; notably waiting for an incoming message.  With synchronous code this would mean that a thread would be blocked most of its lifetime, consuming the resources of a thread which doesn&amp;#039;t really do much.&lt;br /&gt;
&lt;br /&gt;
Using asynchronous programming with promises/futures, the code could look like this:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
    echoLoop_async : (webSocket WebSocket) -&amp;gt; future{unit}.&lt;br /&gt;
clauses&lt;br /&gt;
    echoLoop_async(WebSocket) =&lt;br /&gt;
        WebSocket:readMessage_async():thenDo(&lt;br /&gt;
            { (Message) = F :-&lt;br /&gt;
                if webSocket::close(Status, Reason) = Message then&lt;br /&gt;
                    if 0 &amp;lt;&amp;gt; Status then&lt;br /&gt;
                        stdio::writef(&amp;quot;Closed:% %\n&amp;quot;, Status, Reason)&lt;br /&gt;
                    end if,&lt;br /&gt;
                    F = future::newUnit()&lt;br /&gt;
                else&lt;br /&gt;
                    F =&lt;br /&gt;
                        WebSocket:writeMessage_async(Message):thenDo(&lt;br /&gt;
                            {  =&lt;br /&gt;
                                echoLoop_async(WebSocket) %&lt;br /&gt;
                            })&lt;br /&gt;
                end if&lt;br /&gt;
            }).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
Such code has several flaws, but here we will just notice that it is both difficult to write and read.&lt;br /&gt;
&lt;br /&gt;
With suspending predicates, the code can be written like this:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
    echoLoop_async : (webSocket WebSocket) suspending.&lt;br /&gt;
clauses&lt;br /&gt;
    echoLoop_async(WebSocket) :-&lt;br /&gt;
        Message = WebSocket:readMessage_async(),&lt;br /&gt;
        if webSocket::close(Status, Reason) = Message then&lt;br /&gt;
            if 0 &amp;lt;&amp;gt; Status then&lt;br /&gt;
                stdio::writef(&amp;quot;Closed:% %\n&amp;quot;, Status, Reason)&lt;br /&gt;
            end if&lt;br /&gt;
        else&lt;br /&gt;
            WebSocket:writeMessage_async(Message),&lt;br /&gt;
            echoLoop_async(WebSocket)&lt;br /&gt;
        end if.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
It is clear that this code looks exactly like synchronous code, and is therefore just as easy to read and write. But while the code looks like synchronous code the execution is quite different as described below.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Language changes ===&lt;br /&gt;
&lt;br /&gt;
The only new language entity is the keyword &amp;lt;vp&amp;gt;suspending&amp;lt;/vp&amp;gt; which is added to a predicate declaration and/or predicate domain.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
    webSocket_asyncOp = (webSocket WebSocket) suspending.&lt;br /&gt;
class predicates&lt;br /&gt;
    echoLoop_async : (webSocket WebSocket) suspending.&lt;br /&gt;
    tryCalculate : () -&amp;gt; integer Result determ suspending.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, a suspending predicate can pause its execution and resume it later when it&amp;#039;s &amp;#039;possible&amp;#039; or &amp;#039;feasible.&amp;#039; The use of quotes highlights that the programming language itself doesn&amp;#039;t specify the exact conditions for suspension or resumption. However, in certain contexts, the reasons become evident. For instance, when used for asynchronous operations, suspension occurs while waiting for those operations to finish, and execution resumes once they have completed.&lt;br /&gt;
&lt;br /&gt;
=== Suspension ===&lt;br /&gt;
&lt;br /&gt;
A suspending predicate has the ability to suspend its execution for various reasons, typically when waiting for an asynchronous operation to complete.&lt;br /&gt;
&lt;br /&gt;
The key concern with suspension is understanding what happens when execution is paused. For instance, how does it differ from blocking in a synchronous operation? In essence, when a predicate suspends, the thread that was executing its code can be utilized for other tasks. Consequently, a suspended predicate does not &amp;#039;tie up&amp;#039; a thread.&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s important to note that the execution of suspending predicates cannot be solely viewed in the context of a single thread performing a sequence of actions. Instead, a suspending predicate may consist of parts that are executed by different threads, and these threads may also perform other tasks in between executing the parts associated with a particular suspending predicate.&lt;br /&gt;
&lt;br /&gt;
=== Submitting suspending predicates ===&lt;br /&gt;
&lt;br /&gt;
Suspending predicates can seamlessly invoke other suspending predicates and non-suspending predicates.  However, there are certain limitations on calling non-suspending &amp;lt;vp&amp;gt;nondeterm&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;multi&amp;lt;/vp&amp;gt; predicates.&lt;br /&gt;
&lt;br /&gt;
When you call a non-suspending predicate, its result is immediately available when the calling thread returns from the call. In contrast, calling a suspending predicate doesn&amp;#039;t provide an immediate result because the predicate may suspend execution until an asynchronous operation is complete. Consequently, a non-suspending predicate cannot directly call a suspending one.&lt;br /&gt;
&lt;br /&gt;
Instead, suspending predicates are &amp;#039;&amp;#039;&amp;#039;submitted&amp;#039;&amp;#039;&amp;#039; for execution within a designated execution context, typically using &amp;lt;vp&amp;gt;future::submit&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;future::submit_unit&amp;lt;/vp&amp;gt;. These routines submits the suspending predicate to an &amp;lt;vp&amp;gt;executionContext&amp;lt;/vp&amp;gt; and returns a &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt; that completes with the result of the suspending predicate. As a result, when a suspending predicate is submitted for execution, the calling thread can continue to perform other tasks while the predicate is being processed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Example|Here we submit the &amp;lt;vp&amp;gt;echoLoop_async&amp;lt;/vp&amp;gt; predicate from above and wait for the completion:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
        ...&lt;br /&gt;
        Future = future::submit_unit({ :- echoLoop_async(WebSocket) }),&lt;br /&gt;
        _ = Future:get(),&lt;br /&gt;
        ...&lt;br /&gt;
&amp;lt;/vip&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
=== Await ===&lt;br /&gt;
&lt;br /&gt;
The semantics of a suspending predicate adhere to the same principles as a non-suspending predicate, with the added capability to suspend and later resume execution.&lt;br /&gt;
&lt;br /&gt;
For instance, consider a clause like this:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    p_susp() :-&lt;br /&gt;
        q_susp().&lt;br /&gt;
        r_susp().&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this scenario, the code will initially call &amp;lt;vp&amp;gt;q_susp&amp;lt;/vp&amp;gt;, and only after &amp;lt;vp&amp;gt;q_susp&amp;lt;/vp&amp;gt; has finished will &amp;lt;vp&amp;gt;r_susp&amp;lt;/vp&amp;gt; be called. During this seemingly sequential execution, the execution may suspend multiple times, but &amp;lt;vp&amp;gt;r_susp&amp;lt;/vp&amp;gt; won&amp;#039;t be invoked until &amp;lt;vp&amp;gt;q_susp&amp;lt;/vp&amp;gt; has completed.&lt;br /&gt;
&lt;br /&gt;
However, in scenarios involving asynchronous operations, it can be advantageous to initiate multiple independent operations in parallel and then wait for their completion before proceeding with the utilization of their results.&lt;br /&gt;
&lt;br /&gt;
{{Example|For example, consider this code:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    combinePages_susp() = Combined :-&lt;br /&gt;
        Page1 = fetch_susp(&amp;quot;https://.....&amp;quot;),&lt;br /&gt;
        Page2 = fetch_susp(&amp;quot;https://.....&amp;quot;),&lt;br /&gt;
        Combined = combine(Page1, Page2).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
In this code, the fetching of &amp;lt;vp&amp;gt;Page2&amp;lt;/vp&amp;gt; won&amp;#039;t commence until the fetching of &amp;lt;vp&amp;gt;Page1&amp;lt;/vp&amp;gt; has completed.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
To handle such cases, you can &amp;lt;vp&amp;gt;submit&amp;lt;/vp&amp;gt; a suspending call to the &amp;#039;background&amp;#039; and obtain a &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt; that can be &amp;lt;vp&amp;gt;await&amp;lt;/vp&amp;gt;ed. &lt;br /&gt;
&lt;br /&gt;
{{Example|Here&amp;#039;s an example based on the previous clause:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    combinePages_susp() = Combined :-&lt;br /&gt;
        Page1Future = future::submit( { = fetch_susp(&amp;quot;https://.....&amp;quot;) }),&lt;br /&gt;
        Page2 = fetch_susp(&amp;quot;https://.....&amp;quot;),&lt;br /&gt;
        Page1 = Page1Future:await(),&lt;br /&gt;
        Combined = combine(Page1, Page2).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
The first fetch is submitted to the background, and we obtain a &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt; for it. We do not create a &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt; for the second fetch because we have to wait for all fetches to complete anyway, so the last one might just as well be handled in the direct way.&lt;br /&gt;
After the fetch of &amp;lt;vp&amp;gt;Page2&amp;lt;/vp&amp;gt; has finished, we &amp;lt;vp&amp;gt;await&amp;lt;/vp&amp;gt; the completion of the fetch of &amp;lt;vp&amp;gt;Page1&amp;lt;/vp&amp;gt;. Then we combine the pages as before.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== waitSet ===&lt;br /&gt;
&lt;br /&gt;
Using the strategy outlined above, we would wait sequentially for the background operations to complete. However, this approach is suboptimal when one or more of the background operations completes with an exception. There are two key issues with this:&lt;br /&gt;
&lt;br /&gt;
* We won&amp;#039;t &amp;#039;notice&amp;#039; the exception until we &amp;lt;vp&amp;gt;await&amp;lt;/vp&amp;gt; that specific operation, which means we may need to wait on several other operations to complete before detecting the exception.&lt;br /&gt;
* We won&amp;#039;t &amp;lt;vp&amp;gt;cancel&amp;lt;/vp&amp;gt; the other operations even though their results won&amp;#039;t be used.&lt;br /&gt;
&lt;br /&gt;
To resolve these issues, we can employ a &amp;lt;vp&amp;gt;waitSet&amp;lt;/vp&amp;gt;, which is a set of &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt;s to wait for. The &amp;lt;vp&amp;gt;waitSet&amp;lt;/vp&amp;gt; itself is also a &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt; that completes when either all the &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt;s in the set have completed successfully or when one of them has completed with an exception (whichever occurs first). If an exception occurs, the &amp;lt;vp&amp;gt;waitSet&amp;lt;/vp&amp;gt; will &amp;lt;vp&amp;gt;cancel&amp;lt;/vp&amp;gt; all the remaining non-completed futures and complete itself with the same exception.&lt;br /&gt;
&lt;br /&gt;
{{Example|Here&amp;#039;s an example using a &amp;lt;vp&amp;gt;waitSet&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    combinePages_susp() = Combined :-&lt;br /&gt;
        WaitSet = waitSet::new(),&lt;br /&gt;
        Page1Future = WaitSet:submit( { = fetch_susp(&amp;quot;https://.....&amp;quot;) }),&lt;br /&gt;
        Page2Future = WaitSet:submit( { = fetch_susp(&amp;quot;https://.....&amp;quot;) }),&lt;br /&gt;
        WaitSet:await_unit(),&lt;br /&gt;
        Page1 = Page1Future:await(),&lt;br /&gt;
        Page2 = Page2Future:await(),&lt;br /&gt;
        Combined = combine(Page1, Page2).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
It&amp;#039;s worth noting that the actual waiting occurs in &amp;lt;vp&amp;gt;WaitSet:await_unit()&amp;lt;/vp&amp;gt;. If one of the operations completes with an exception, that exception will become evident at that line of code.}}&lt;br /&gt;
&lt;br /&gt;
=== Execution and cancellation contexts ===&lt;br /&gt;
&lt;br /&gt;
When suspending predicates as &amp;#039;submitted for execution&amp;#039; they will be submitted to execution in an &amp;lt;vp&amp;gt;executionContext&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
An &amp;lt;vp&amp;gt;executionContext&amp;lt;/vp&amp;gt; provides the infrastructure needed to execute suspending code. Various types of execution contexts are available:&lt;br /&gt;
&lt;br /&gt;
* Threadpools: These enable background processing and parallelism.&lt;br /&gt;
* A GUI thread: It executes the suspended parts during message handling steps.&lt;br /&gt;
* Regular threads: They enter waiting states to facilitate the resumption of suspended parts.&lt;br /&gt;
&lt;br /&gt;
However, the use of &amp;lt;vp&amp;gt;executionContext&amp;lt;/vp&amp;gt;s can give rise to certain challenges. GUI operations, for example, are typically constrained to a GUI context, while threadpools enable background processing and parallelism. This may necessitate context switching in specific situations (though the exact means for doing so may vary).&lt;br /&gt;
&lt;br /&gt;
Additionally, suspending predicates also execute within a &amp;#039;&amp;#039;&amp;#039;cancellation&amp;#039;&amp;#039;&amp;#039; context.&lt;br /&gt;
&lt;br /&gt;
Both the &amp;lt;vp&amp;gt;executionContext&amp;lt;/vp&amp;gt; and the &amp;lt;vp&amp;gt;cancellation&amp;lt;/vp&amp;gt; context of a suspending &amp;#039;task&amp;#039; can be accessed through thread-local variables. It&amp;#039;s important to note that most programmers need not directly manipulate these variables, as they are managed and utilized through library software (e.g., &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt;&amp;#039;s library).&lt;br /&gt;
&lt;br /&gt;
=== Implementation ===&lt;br /&gt;
&lt;br /&gt;
The implementation of suspending predicates is primarily designed to fulfill the specified semantics, and it is not necessary for programmers to fully understand the intricacies of the implementation. However, a brief description of the underlying implementation is provided for those interested.&lt;br /&gt;
&lt;br /&gt;
Basically, suspending predicates are transformed into &amp;#039;ordinary&amp;#039; code, and run as such.&lt;br /&gt;
&lt;br /&gt;
The transformation has three major elements:&lt;br /&gt;
&lt;br /&gt;
* Code Transformation: The code is converted into continuation-based code, where all &amp;#039;returning&amp;#039; actions are replaced by calls to a continuation. Actual returning is employed when the execution suspends and terminates.&lt;br /&gt;
* Stack to Heap: Stack-frames are converted into heap-frames, which can persist in the heap while execution is suspended and can be resumed on any thread.&lt;br /&gt;
* Backtrack Points: Backtrack points and trap points for suspending predicates are stored in the heap rather than on the run stack.&lt;br /&gt;
&lt;br /&gt;
A critical aspect of the translation scheme is that each time a suspending predicate is called, it is treated as a &amp;#039;&amp;#039;&amp;#039;final&amp;#039;&amp;#039;&amp;#039; call. Final calls are optimized to discard the current stack frame before making the call, ensuring that the new predicate&amp;#039;s stack frame replaces the current one. This means that only one frame is left on the stack, even with nested calls.&lt;br /&gt;
&lt;br /&gt;
When a predicate suspends, it returns from that call and leaves nothing on the stack.&lt;br /&gt;
&lt;br /&gt;
To manage &amp;#039;what happens next&amp;#039; when a predicate suspends and may return before completing its work, continuations are used. Continuations are predicates that represent &amp;#039;what to continue with when the current operation is done&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Continuation predicates are used to handle branching and join back to shared code. For instance, common code after conditional branches is placed into a separate continuation predicate, which is then called at the end of all branches.&lt;br /&gt;
&lt;br /&gt;
This implementation scheme below is illustrative: the actual scheme may differ for various reasons (e.g., optimization).  We will use the following naming conventions:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;&amp;lt;name&amp;gt;_susp&amp;lt;/vp&amp;gt; indicates that the predicate is suspending.  Predicates that does not end in &amp;lt;vp&amp;gt;_susp&amp;lt;/vp&amp;gt; are non-suspending.&lt;br /&gt;
* Names ending with an underscore represent &amp;quot;translated&amp;quot; predicates and built-in/internal entities.&lt;br /&gt;
&lt;br /&gt;
Let us at first disregard all data and only consider &amp;lt;vp&amp;gt;procedure&amp;lt;/vp&amp;gt;s.&lt;br /&gt;
&lt;br /&gt;
A predicate is translated into one that takes an extra continuation argument, where a &amp;lt;vp&amp;gt;continuation_&amp;lt;/vp&amp;gt; is an (object) predicate with no arguments.&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
    continuation_ = ().&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The continuation represents what happens after this predicate has done whatever it is supposed to do, i.e. how the computation &amp;#039;&amp;#039;continues&amp;#039;&amp;#039; afterwards.&lt;br /&gt;
&lt;br /&gt;
{{Example|The predicate&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
   task_susp : ()  suspending.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
is translated into a predicate &amp;lt;vp&amp;gt;task_susp_&amp;lt;/vp&amp;gt; that takes a continuation as argument instead of returning:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
   task_susp_ : (continuation_ Cont_).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
For every suspending predicate we create a heap-frame class.  Where a &amp;lt;vp&amp;gt;heapframe_&amp;lt;/vp&amp;gt; is an object with a single predicate &amp;lt;vp&amp;gt;go_&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface heapframe_&lt;br /&gt;
predicates&lt;br /&gt;
    go_ : ().&lt;br /&gt;
end interface heapframe_&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Such a class will have a constructor that receives the continuation (and any original arguments) as arguments.&lt;br /&gt;
&lt;br /&gt;
{{Example|For the predicate above we will create a class like this:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class task_susp_frm_ : heapframe_&lt;br /&gt;
constructors&lt;br /&gt;
    new : (continuation_  Cont_).&lt;br /&gt;
end class task_susp_frm_&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Now let us consider the translation of clauses.  &lt;br /&gt;
&lt;br /&gt;
{{Example|We will consider this clause&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    task_susp() :-&lt;br /&gt;
        openChannel(),&lt;br /&gt;
        fetch1_susp(),&lt;br /&gt;
        fetch2_susp(),&lt;br /&gt;
        closeChannel().&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
The code will &amp;quot;open a channel&amp;quot; by calling a non-suspending predicate &amp;lt;vp&amp;gt;openChannel&amp;lt;/vp&amp;gt;, then it will call the suspending predicate &amp;lt;vp&amp;gt;fetch1_susp&amp;lt;/vp&amp;gt;, and so forth.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The original clause will be transformed into one that takes a continuation as argument, and then constructs a heapframe object and finally invoke &amp;lt;vp&amp;gt;go_&amp;lt;/vp&amp;gt; on that predicate.&lt;br /&gt;
&lt;br /&gt;
{{Example|The clause will look like this&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    task_susp_(Cont_) :-&lt;br /&gt;
        F = task_susp_frm_::new(Cont_),&lt;br /&gt;
        F:go_().&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
Notice that the call to &amp;lt;vp&amp;gt;go_&amp;lt;/vp&amp;gt; is a final call so the stack frame for &amp;lt;vp&amp;gt;task_susp_&amp;lt;/vp&amp;gt; is replaced by the stack frame for &amp;lt;vp&amp;gt;go_&amp;lt;/vp&amp;gt;.  Leaving only one frame on the stack.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The original code of the clause will be moved to the &amp;lt;vp&amp;gt;go_&amp;lt;/vp&amp;gt; predicate and a number of &amp;lt;vp&amp;gt;continuation_&amp;lt;/vp&amp;gt; predicates.&lt;br /&gt;
&lt;br /&gt;
Each time we call a suspendable predicate we create a continuation predicate in the class and pass that as the continuation argument to the suspendable predicate (i.e. it&amp;#039;s translation).&lt;br /&gt;
&lt;br /&gt;
{{Example|For the clause above the class will look like this:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement task_susp_frm_&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    cont_ : continuation_.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    new(Cont_) :-&lt;br /&gt;
        cont_ := Cont_.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    go() :-&lt;br /&gt;
        openChannel(),&lt;br /&gt;
        fetch1_susp_(cont1_).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    cont1_ : continuation_.&lt;br /&gt;
clauses&lt;br /&gt;
    cont1_() :-&lt;br /&gt;
        fetch2_susp_(cont2_).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    cont2_ : continuation_.&lt;br /&gt;
clauses&lt;br /&gt;
    cont2_() :-&lt;br /&gt;
        closeChannel(),&lt;br /&gt;
        cont_().&lt;br /&gt;
&lt;br /&gt;
end implement task_susp_frm_&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
The overall &amp;lt;vp&amp;gt;continuation_&amp;lt;/vp&amp;gt; is stored in a fact variable, it will be invoked when the entire clause has run to the end.&lt;br /&gt;
The &amp;lt;vp&amp;gt;go_&amp;lt;/vp&amp;gt; clause first call the non-suspending predicate &amp;lt;vp&amp;gt;openChannel&amp;lt;/vp&amp;gt; and then it calls the suspending predicate &amp;lt;vp&amp;gt;fetch1_susp&amp;lt;/vp&amp;gt; or rather the translation of this predicate &amp;lt;vp&amp;gt;fetch1_susp_&amp;lt;/vp&amp;gt;.  This predicate is called with the &amp;lt;vp&amp;gt;continuation_&amp;lt;/vp&amp;gt; predicate &amp;lt;vp&amp;gt;cont1_&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&amp;lt;vp&amp;gt;cont1_&amp;lt;/vp&amp;gt; represents what happens after the call to &amp;lt;vp&amp;gt;fetch1_susp_&amp;lt;/vp&amp;gt; has finished, which is calling &amp;lt;vp&amp;gt;fetch2_susp_&amp;lt;/vp&amp;gt; (the translation of &amp;lt;vp&amp;gt;fetch2_susp&amp;lt;/vp&amp;gt;) with &amp;lt;vp&amp;gt;cont2_&amp;lt;/vp&amp;gt; as argument.&lt;br /&gt;
&amp;lt;vp&amp;gt;cont2_&amp;lt;/vp&amp;gt; represents what happens after the call to &amp;lt;vp&amp;gt;fetch2_susp_&amp;lt;/vp&amp;gt; has finished, which is calling &amp;lt;vp&amp;gt;closeChannel&amp;lt;/vp&amp;gt;.  And since the entire clause is then finished, we end &amp;lt;vp&amp;gt;cont2_&amp;lt;/vp&amp;gt; with calling &amp;lt;vp&amp;gt;cont_&amp;lt;/vp&amp;gt;, because it represents what happens after this clause.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Notice that the calls to non-suspending predicates (like &amp;lt;vp&amp;gt;openChannel&amp;lt;/vp&amp;gt;) is made in a completely normal way and that these predicates can create stack frames as they like.  However all such calls have completed before we call another suspendable predicate. So at the time we call a suspendable predicate the stack only contains the frame of the current suspendable predicate and that frame will be replaced by the new frame because the call to the new suspendable predicate is made as a final call.&lt;br /&gt;
&lt;br /&gt;
Also notice that execution cannot suspend inside a non-suspending predicate, so when suspension takes place there is only one stack frame on the stack, and when we return from that call the stack is completely vacated.&lt;br /&gt;
&lt;br /&gt;
Branching which join back to shared code cause an additional need for continuation predicates as illustrated in this example:&lt;br /&gt;
&lt;br /&gt;
{{Example|Consider this clause&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    pred_susp() :-&lt;br /&gt;
        if test() then&lt;br /&gt;
            sub_susp()&lt;br /&gt;
        else &lt;br /&gt;
            ordinary()&lt;br /&gt;
         end if,&lt;br /&gt;
         &amp;lt;common code&amp;gt;.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;vp&amp;gt;&amp;lt;common code&amp;gt;&amp;lt;/vp&amp;gt; is the continuation of both branches in the &amp;lt;vp&amp;gt;if-then-else&amp;lt;/vp&amp;gt;.  But the call to &amp;lt;vp&amp;gt;sub_susp&amp;lt;/vp&amp;gt; is a final call. So we do not come back to &amp;lt;common code&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Basically, such common code is put into a separate continuation predicate, which is then called in the end of all branches.&lt;br /&gt;
&lt;br /&gt;
{{Example|Consider this as a kind of &amp;quot;schematic middle step&amp;quot;:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    pred_susp() :-&lt;br /&gt;
        if test() then&lt;br /&gt;
            sub_susp(),&lt;br /&gt;
            contX_()&lt;br /&gt;
        else &lt;br /&gt;
            ordinary(),&lt;br /&gt;
            contX_()&lt;br /&gt;
         end if.&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
   contX_ : continuation_.&lt;br /&gt;
clauses&lt;br /&gt;
   contX_() :-&lt;br /&gt;
         &amp;lt;common code&amp;gt;.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
Given this transformation there is no longer code to execute after the &amp;lt;vp&amp;gt;if-then-else&amp;lt;/vp&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Backtracking &amp;amp; exception handling ====&lt;br /&gt;
&lt;br /&gt;
Backtracking and exception handling are managed in a similar manner in Visual Prolog. In this discussion, we&amp;#039;ll primarily focus on the handling of backtracking.&lt;br /&gt;
&lt;br /&gt;
In Visual Prolog, each thread maintains a chain of backtrack points, and there exists a thread-global pointer known as &amp;lt;vp&amp;gt;bTop_&amp;lt;/vp&amp;gt; that points to the head of this chain. Each backtrack point carries essential information needed to transfer control back to the alternative branch (the failure alternative). When a failure occurs, the system removes the first backtrack point from the chain, adjusts the &amp;lt;vp&amp;gt;bTop_&amp;lt;/vp&amp;gt; pointer to point to the next backtrack point in the chain, and restores the state based on the information stored in the backtrack point.&lt;br /&gt;
&lt;br /&gt;
The handling of &amp;#039;cut&amp;#039; (&amp;lt;vp&amp;gt;!&amp;lt;/vp&amp;gt;) involves resetting the &amp;lt;vp&amp;gt;bTop_&amp;lt;/vp&amp;gt; pointer to a specific value, which is stored in a variable at an earlier point in time. While we won&amp;#039;t delve into the intricate details of this process, it&amp;#039;s important to note that it involves operations that utilize variables within a clause. Despite the programmer not explicitly specifying the variable, the system manages it like any other variable.&lt;br /&gt;
&lt;br /&gt;
However, when dealing with suspending predicates, two specific issues arise regarding the standard handling of backtracking:&lt;br /&gt;
&lt;br /&gt;
* Backtrack Point Storage: Traditional backtrack points are stored in the stack, which conflicts with the need to entirely clear the stack in case of suspension.&lt;br /&gt;
* State Restoration: Non-deterministic (&amp;lt;vp&amp;gt;nondeterm&amp;lt;/vp/&amp;lt;vp&amp;gt;multi&amp;lt;/vp&amp;gt;) predicates maintain their state on the stack, allowing backtracking to reset to that specific stack state. However, in a suspending context, this approach is problematic since a suspending predicate may resume execution on a completely different stack.&lt;br /&gt;
&lt;br /&gt;
To address the first issue, suspending predicates allocate backtrack points in the heap instead of storing them on the stack. This ensures that they can persist even when the stack is cleared due to suspension.&lt;br /&gt;
&lt;br /&gt;
Regarding the second issue, a non-suspending backtrack point contains information about how to restore the stack and frame pointers. However, restoring the state in this manner doesn&amp;#039;t make sense for suspending predicates because they may resume execution on a different stack. Instead, a suspending backtrack point restores the stack to the location where the suspending predicates have their stack frame. This stack frame remains in the same place throughout the execution of suspendable code, except when it suspends and is later resumed in a different location (note that backtracking doesn&amp;#039;t occur while execution is suspended). Thus, during the execution of suspendable code on a particular thread and stack, a thread-global pointer is used to indicate where suspending backtrack points should restore to.&lt;br /&gt;
&lt;br /&gt;
The second issue also affects the state of suspendable nondeterministic predicates themselves. Unlike non-suspending predicates, both suspending and non-suspending backtrack points in suspendable nondeterministic predicates store their state in the heap instead of on the stack. This avoids conflicts with suspension and ensures that state can be managed effectively.&lt;br /&gt;
&lt;br /&gt;
In general, calling non-suspending &amp;lt;vp&amp;gt;nondeterm&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;multi&amp;lt;/vp&amp;gt; predicates from suspending predicates is not allowed due to the challenges in restoring backtrack points on potentially different stacks. However, it may be possible to do so in cases where it can be guaranteed that all backtracking is completed before reaching a point where a suspending predicate is called. For example, a list comprehension does not leave any backtrack points, so if all calls inside the list comprehension are non-suspending, there is no issue with calling a non-suspending nondeterministic predicate within it.&lt;br /&gt;
&lt;br /&gt;
While it may be difficult to figure out yourself whether those conditions are fulfilled, you don&amp;#039;t need to worry the compiler will tell you if there is a problem.&lt;br /&gt;
&lt;br /&gt;
As mentioned, exception handling is handled very similar to backtracking, but simpler in the sense that catch-points cannot be &amp;quot;left-behind&amp;quot; in the same way as backtrack points can. Trap-points are restored when backtracking back into the try section of a try-catch, but the problem that this cause relates to backtracking rather than to the trap-points themselves.  Also, in this case the problem is for non-suspending nondeterm/multi predicates.&lt;br /&gt;
&lt;br /&gt;
Windows will however not accept that trap-points are heap allocated.  So in on &amp;quot;low level&amp;quot; all exceptions are trapped with completely normal exception trapping code, which then delegates the exception handling to the heap stored trap points:&lt;br /&gt;
&lt;br /&gt;
{{Example|The code for this will look something like this:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
try&lt;br /&gt;
    &amp;lt;run suspending code&amp;gt;&lt;br /&gt;
catch TraceId do&lt;br /&gt;
    suspendingExceptionHandling(TraceId)&lt;br /&gt;
end try&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
Where &amp;lt;vp&amp;gt;suspendingExceptionHandling&amp;lt;/vp&amp;gt; will find the heap allocated trappoint chain and delegate the exception handling to it.}}&lt;br /&gt;
&lt;br /&gt;
==== Parameters &amp;amp; Variables ====&lt;br /&gt;
&lt;br /&gt;
Now let&amp;#039;s consider how to deal with parameters, etc.&lt;br /&gt;
&lt;br /&gt;
In Visual Prolog (i.e., for the &amp;lt;vp&amp;gt;prolog&amp;lt;/vp&amp;gt; calling convention) all function return values are transformed into output arguments. So, in the final code there is only input and output arguments, but no return values.  Output arguments are handled by passing a pointer to where the result must be stored. So, an output argument is actually a input pointer argument.&lt;br /&gt;
&lt;br /&gt;
The general principle for dealing with parameters and variables from the original code is to store them as fact variables in the heapframe object rather than on the run-stack.&lt;br /&gt;
&lt;br /&gt;
{{Example|Several of the predicates here would more naturally be functions, but to maintain focus we will make them into predicates with output variables ourselves.  We have also simplified the clause by only having one fetch, this will simplify the example without loosing any essence.&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
    task_susp : (string Server, string Result [out]) suspending.&lt;br /&gt;
clauses&lt;br /&gt;
    task_susp(Server, Result) :-&lt;br /&gt;
        openChannel(Server, Channel),&lt;br /&gt;
        fetch_susp(Channel, Result),&lt;br /&gt;
        closeChannel(Channel).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
As before the predicate is translated into one with an additional continuation argument. Furthermore, all output arguments are converted to an input pointer argument instead.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
    task_susp_ : (contination_ Cont_, string Server, pointerTo{string} ResultPtr_).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Again, we create a heapframe class with a constructor that receives all the arguments of the translated predicate.&lt;br /&gt;
&lt;br /&gt;
{{Example|The class looks like this&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class task_susp_frm_ : heapframe_&lt;br /&gt;
constructors&lt;br /&gt;
    new : (continuation_  Cont_, string Server, pointerTo{string} ResultPtr_).&lt;br /&gt;
end class task_susp_frm_&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
And the original clause is translated into one that creates a heapframe object and invoke &amp;lt;vp&amp;gt;go_&amp;lt;/vp&amp;gt; as a final call.&lt;br /&gt;
&lt;br /&gt;
{{Example|The clause will look like this&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    task_susp_(Cont_, Server, ResultPtr_) :-&lt;br /&gt;
        F = task_susp_frm_::new(Cont_, Server, ResultPtr_),&lt;br /&gt;
        F:go_().&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The heapframe class/object will contain fact variables corresponding to all parameters and variables (optimizations are not considered here).  And like before we will place the actual code in the &amp;lt;vp&amp;gt;go_&amp;lt;/vp&amp;gt; predicate and &amp;lt;vp&amp;gt;continuation_&amp;lt;/vp&amp;gt; predicates.&lt;br /&gt;
&lt;br /&gt;
{{Example|The code will look like this:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement task_susp_&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    cont_ : continuation_.&lt;br /&gt;
    channel_ : channel.&lt;br /&gt;
    resultPtr_ : ::pointerTo{::string}.&lt;br /&gt;
    server_ : ::string.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    new(Cont_, Server, ResultPtr_) :-&lt;br /&gt;
        cont_ := Cont_,&lt;br /&gt;
        server_ := Server,&lt;br /&gt;
        resultPtr_ := ResultPtr_.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    go_() :-&lt;br /&gt;
        fact_address_(channel_, ChannelPtr),&lt;br /&gt;
        openChannel(server_, ChannelPtr),&lt;br /&gt;
        fetch_susp(cont1_, channel_, resultPtr_).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    cont1_ : continuation_.&lt;br /&gt;
clauses&lt;br /&gt;
    cont1_() :-&lt;br /&gt;
        closeChannel(channel_),&lt;br /&gt;
        cont_().&lt;br /&gt;
&lt;br /&gt;
end implement task_susp_&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
There are many details around the handling of the facts that represents parameters and variables. The main principles are:&lt;br /&gt;
&lt;br /&gt;
* Input parameters and variables are represented as facts with their original type. In some places the address of such facts are needed (e.g., &amp;lt;vp&amp;gt;ChannelPtr&amp;lt;/vp&amp;gt; in the call to &amp;lt;vp&amp;gt;openChannel&amp;lt;/vp&amp;gt;).&lt;br /&gt;
* Output parameters (of the predicate itself) are received and stored as a pointerTo{...} fact. In some cases, it may be necessary to dereference the pointer (does not occur in this example).&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_11_Upgrade_Notes&amp;diff=4931</id>
		<title>Visual Prolog 11 Upgrade Notes</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_11_Upgrade_Notes&amp;diff=4931"/>
		<updated>2024-04-08T09:30:50Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: remove line shift&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document describes how to upgrade Visual Prolog 10 projects to Visual Prolog 11, for older projects you should also read the [[Visual Prolog 10 Upgrade Notes]].&lt;br /&gt;
&lt;br /&gt;
If you have problems with upgrading your projects and need additional information, you are welcome to ask questions in [http://discuss.visual-prolog.com/viewforum.php?f=2 Visual Prolog Discussion Forum].&lt;br /&gt;
&lt;br /&gt;
By default, the installation of Visual Prolog 11 will not replace any older installed versions. It is possible to work with several versions on a single computer.  See also [[vipLaunch]].&lt;br /&gt;
&lt;br /&gt;
The Commercial and Personal Edition are identical; differences in capabilities are controlled by the license used to activate the computer.&lt;br /&gt;
&lt;br /&gt;
Entities that are not available to Personal Edition usage are marked with the attribute &amp;lt;vp&amp;gt;[feature(&amp;quot;Commercial Edition&amp;quot;)]&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Visual Prolog 11 is installed &amp;#039;&amp;#039;per user&amp;#039;&amp;#039; in &amp;#039;&amp;#039;&amp;#039;...\Users\&amp;lt;user&amp;gt;\AppData\Roaming\Visual Prolog\11&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Visual Prolog 11 project files are backward-compatible with Visual Prolog 10 project files.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Notice&amp;#039;&amp;#039;&amp;#039; it is highly advisable to have a backup of a project before updating.&lt;br /&gt;
&lt;br /&gt;
When updating a project you should open the project in the new IDE and accept to remove any non-existing PFC packages.  Then build the project and accept to&lt;br /&gt;
&lt;br /&gt;
* delete all bad include directives&lt;br /&gt;
* insert new ones and &lt;br /&gt;
* add new PFC packages&lt;br /&gt;
&lt;br /&gt;
=== Superfluous Files ===&lt;br /&gt;
&lt;br /&gt;
If you haven&amp;#039;t removed the superfluous resource files then see [[Visual Prolog 10 Upgrade Notes#Superfluous_files]].&lt;br /&gt;
&lt;br /&gt;
=== match &amp;amp; case future keywords ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;match&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;case&amp;lt;/vp&amp;gt; will be keywords in future releases of Visual Prolog and you will receive warnings if you use them.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;regEx::&amp;lt;/vp&amp;gt;&amp;lt;b&amp;gt;match&amp;lt;/b&amp;gt; has been retired and renamed to &amp;lt;vp&amp;gt;regEx::matchFirst&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== gdiplus ===&lt;br /&gt;
&lt;br /&gt;
If your project initializes gdiplus, e.g. like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        _ = mainForm::display(gui::getScreenWindow()),&lt;br /&gt;
        GDIpToken = gdiplus::startup(),&lt;br /&gt;
        messageLoop::run(),&lt;br /&gt;
        gdiplus::shutdown(GDIpToken).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then simply remove the calls to &amp;lt;vp&amp;gt;gdiplus::startup&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;gdiplus::shutdown&amp;lt;/vp&amp;gt; code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        _ = mainForm::display(gui::getScreenWindow()),&lt;br /&gt;
        messageLoop::run().&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;color&amp;lt;/vp&amp;gt; class/interface has been retired, and superseded by the domain &amp;lt;vp&amp;gt;gdiplus_native::color&amp;lt;/vp&amp;gt;. In many cases you simply have to remove the call to &amp;lt;vp&amp;gt;color::create&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This line (in the &amp;#039;&amp;#039;&amp;#039;GDI+ Example&amp;#039;&amp;#039;)&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
        DarkRed = pen::createColor(color::create(gdiplus_native::darkred), penWidth, unit),&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
has been changed to:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
        DarkRed = pen::createColor(gdiplus_native::darkred, penWidth, unit),&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A little editor trick: if you use autoformatting of code (a project setting) you can just remove &amp;lt;vp&amp;gt;color::create&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
        DarkRed = pen::createColor((gdiplus_native::darkred), penWidth, unit),&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
When you save the file the superfluous parentheses will be removed automatically.  Therefore you can correct an entire file simply by replacing all occurrences of &amp;lt;vp&amp;gt;color::create&amp;lt;/vp&amp;gt; with nothing/blank.&lt;br /&gt;
&lt;br /&gt;
Furthermore, some domains have been relocated from the &amp;lt;vp&amp;gt;gdiplus&amp;lt;/vp&amp;gt; class to the &amp;lt;vp&amp;gt;gdiplus_native&amp;lt;/vp&amp;gt; class.  The &amp;quot;Fix&amp;quot; button in the error window should handle that problem automatically.  Otherwise, the IDE command &amp;#039;&amp;#039;&amp;#039;Insert -&amp;gt; Qualification Ctrl+Shift+S&amp;#039;&amp;#039;&amp;#039; can also insert or correct the qualification.&lt;br /&gt;
&lt;br /&gt;
The object predicate &amp;lt;vp&amp;gt;graphics::drawString/6&amp;lt;/vp&amp;gt; has been retired, instead you will have to choose between:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
predicates&lt;br /&gt;
    drawStringIn : (font Font, brush Brush, rectF LayoutRect, string String, stringFormat StringFormat = stringFormat::null).&lt;br /&gt;
    drawStringAt : (font Font, brush Brush, pointF Origin, string String, stringFormat StringFormat = stringFormat::null).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;graphics::drawStringIn&amp;lt;/vp&amp;gt; draws the string in the rectangle &amp;lt;vp&amp;gt;LayoutRect&amp;lt;/vp&amp;gt; or&lt;br /&gt;
* &amp;lt;vp&amp;gt;graphics::drawStringAt&amp;lt;/vp&amp;gt; draws the string at the point &amp;lt;vp&amp;gt;Origin&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== treeModel_std &amp;amp; treeNode_std ===&lt;br /&gt;
&lt;br /&gt;
If you use the &amp;lt;vp&amp;gt;treeControl&amp;lt;/vp&amp;gt; with the &amp;lt;vp&amp;gt;treeModel_std&amp;lt;/vp&amp;gt; you will have to add &amp;lt;vp&amp;gt;code::value&amp;lt;/vp&amp;gt; as argument to &amp;lt;vp&amp;gt;treeModel_std&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;treeNode_std&amp;lt;/vp&amp;gt;.  Notice that this is not necessary in clauses; only in other places (declarations, ...).&lt;br /&gt;
&lt;br /&gt;
Here illustrated with code from the &amp;lt;vp&amp;gt;dragNdropDemo&amp;lt;/vp&amp;gt; in the examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement mainForm inherits formWindow&lt;br /&gt;
    open core, vpiDomains, treeModel_std{core::value}&lt;br /&gt;
...&lt;br /&gt;
predicates&lt;br /&gt;
    onDragBegin : treeControl{treeNode_std{value}}::dragBeginResponder.&lt;br /&gt;
...&lt;br /&gt;
% This code is maintained automatically, do not update it manually. 10:41:58-23.11.2011&lt;br /&gt;
facts&lt;br /&gt;
    treeCtl : treecontrol{treeNode_std{value}}.&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that if you have deleted the form/dialog file (as described in  [[Visual Prolog 10 Upgrade Notes#Superfluos_files|superfluous Files]]) then you can (despite the warning in the comment) edit directly in the &amp;quot;auto&amp;quot;-code.&lt;br /&gt;
&lt;br /&gt;
=== codePageId ansi &amp;amp; threadAnsi ===&lt;br /&gt;
&lt;br /&gt;
The following &amp;lt;vp&amp;gt;codePageID&amp;lt;/vp&amp;gt;&amp;#039;s have been deprecated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
constants&lt;br /&gt;
    ansi : codePage = 0 [deprecated(&amp;quot;It is recommended not to use this codepage, but use an explicit encoding instead&amp;quot;)].&lt;br /&gt;
    threadAnsi : codePage = 3 [deprecated(&amp;quot;It is recommended not to use this codepage, but use an explicit encoding instead&amp;quot;)].&lt;br /&gt;
    % @short Represents the systems/threads current ANSI codePage.&lt;br /&gt;
    % It is recommended not to use this codepage but use an explicit encoding instead.&lt;br /&gt;
    % @end&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The problem with these system/user codepages is that they are often set to some regional codepage with 8 bit characters.  Files written like must be read with the same codepage, otherwise characters may become wrong or even lost.&lt;br /&gt;
&lt;br /&gt;
Some time ago (unknown when) Microsoft have introduced the possibility to use utf-8 as system/user codepage.  Using utf-8 is technically the best choice, because it &amp;quot;unites&amp;quot; all regional &amp;quot;things&amp;quot; into a single codepage. However but the transition from old regional codepages to utf-8 is &amp;quot;difficult&amp;quot;, because you will still need to read a file with the codepage that was used to write it.&lt;br /&gt;
&lt;br /&gt;
We recommend that you &amp;quot;migrate&amp;quot; text files to utf-8 (or utf-16 if you mainly use &amp;quot;special&amp;quot; characters, like chinese).  If you add a byte order mark the format becomes &amp;quot;visible&amp;quot;, but in some contexts (certain Internet contexts and using foreign applications) byte order marks in utf-8 files will not be accepted.&lt;br /&gt;
&lt;br /&gt;
=== Fallback CodePage ===&lt;br /&gt;
&lt;br /&gt;
Several text file related predicates have been equipped with a non-optional &amp;lt;vp&amp;gt;FallbackCodePage&amp;lt;/vp&amp;gt; argument.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class inputStream_file : inputStream&lt;br /&gt;
...&lt;br /&gt;
constructors&lt;br /&gt;
    openFileText : (string Filename, codePage FallbackCodePage, fileSystem_api::accessPermit Access = fileSystem_api::permitRead).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The predicate &amp;lt;vp&amp;gt;inputStream_file::openFileText&amp;lt;/vp&amp;gt; examines the file to open searching for Byte Order Marks and obvious utf-16 format.  If it is not possible to determine the codepage like that the &amp;lt;vp&amp;gt;FallbackCodePage&amp;lt;/vp&amp;gt; will be used.  Such predicates used to user the &amp;lt;vp&amp;gt;threadAnsi&amp;lt;/vp&amp;gt; codepage, but (as described above) this can lead to problems with &amp;quot;old&amp;quot; files and new settings and files written on one computer and read on another.   For this reason you must now (explicitly) decide which codepage to use if it cannot be inferred.&lt;br /&gt;
&lt;br /&gt;
=== COM component classes ===&lt;br /&gt;
&lt;br /&gt;
The import of COM components has been simplified for certain COM components.  Instead of being defined in a separate Visual Prolog class many COM components are now created by calling a predicate.&lt;br /&gt;
&lt;br /&gt;
For example, to create an XMLHTTP component you would construct object using the corresponding constructor &amp;lt;vp&amp;gt;XmlHttp = xmlhttp60::new()&amp;lt;/vp&amp;gt;, now you will instead call the predicate &amp;lt;vp&amp;gt;XmlHttp = msxml_HTTP_api::newXmlhttp60()&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== watchDirectory ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;watchDirectory&amp;lt;/vp&amp;gt; has been updated to use suspending predicates, and as result &amp;lt;vp&amp;gt;watchDirectory::start&amp;lt;/vp&amp;gt; takes an &amp;lt;vp&amp;gt;executionContext&amp;lt;/vp&amp;gt; as argument.  In most cases &amp;lt;vp&amp;gt;pfc\asynchronous\executionContext_pool::defaultPool&amp;lt;/vp&amp;gt; can be used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
            WD = watchDirectory::start(FullDir, pfc\asynchronous\executionContext_pool::defaultPool),&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Master/slave ===&lt;br /&gt;
&lt;br /&gt;
The master/slave concept has been updated to use {{lang|Suspending Predicates|suspending predicates}} instead of explicit &amp;lt;vp&amp;gt;continuation&amp;lt;/vp&amp;gt;s.  The article [[Master/slave processes]] and the corresponding demo example has been updated to reflect the changes.&lt;br /&gt;
&lt;br /&gt;
=== Web Services &amp;amp; webSockets ===&lt;br /&gt;
&lt;br /&gt;
The Web Services and &amp;lt;vp&amp;gt;webSocket&amp;lt;/vp&amp;gt;s support has been updated to use {{lang|Suspending Predicates|suspending predicates}} for asynchronous operation.  The main updates necessary to make an old program working is remove all access to &amp;lt;vp&amp;gt;threadpool&amp;lt;/vp&amp;gt;s.&lt;br /&gt;
&lt;br /&gt;
This code&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    runServer() :-&lt;br /&gt;
        ...&lt;br /&gt;
        mkService(Session, &amp;quot;File service&amp;quot;, &amp;quot;&amp;quot;, requestQueue_content::new(threadpool, demoFileService::contentMapper)),&lt;br /&gt;
        ...&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
will look like this:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    runServer() :-&lt;br /&gt;
        ...&lt;br /&gt;
        mkService(Session, &amp;quot;File service&amp;quot;, &amp;quot;&amp;quot;, requestQueue_content::new(demoFileService::contentMapper)),&lt;br /&gt;
        ...&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If necessary you can add an explicit &amp;lt;vp&amp;gt;executionContext&amp;lt;/vp&amp;gt; (&amp;lt;vp&amp;gt;Ctx&amp;lt;/vp&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    runServer() :-&lt;br /&gt;
        httpServer_api::httpInitialize(httpServer_native::http_initialize_server),&lt;br /&gt;
        Session = session::new(),&lt;br /&gt;
        Ctx = pfc\asynchronous\executionContext_pool::defaultPool,&lt;br /&gt;
        try&lt;br /&gt;
            cleanup:alsoDispose(Session),&lt;br /&gt;
            % Demo file service for html, JavaScript , images, etc to the client&lt;br /&gt;
            mkService(Session, &amp;quot;File service&amp;quot;, &amp;quot;&amp;quot;, requestQueue_content::new(demoFileService::contentMapper, Ctx)),&lt;br /&gt;
            ...&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The changes in &amp;lt;vp&amp;gt;webSocket&amp;lt;/vp&amp;gt; requires more attention.  You will have to remove &amp;lt;vp&amp;gt;continuation&amp;lt;/vp&amp;gt;s and use  {{lang|Suspending Predicates|suspending predicates}} instead.&lt;br /&gt;
&lt;br /&gt;
For example, the predicate onAttach_async must now be a suspending predicate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface webSocketService&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    onAttach_async : (httpRequest Request, webSocket WebSocket) suspending.&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The implementation of this predicate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    onAttach_async(Request, WebSocket, Continuation) :-&lt;br /&gt;
        onAttach2_async(filename::getLastDirectory(Request:path, _), WebSocket, Continuation).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 should drop the &amp;lt;vp&amp;gt;Continuation&amp;lt;/vp&amp;gt; argument:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    onAttach_async(Request, WebSocket) :-&lt;br /&gt;
        onAttach2_async(filename::getLastDirectory(Request:path, _), WebSocket).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;onAttach2_async&amp;lt;/vp&amp;gt; should also be declared as a suspending predicate (without a &amp;lt;vp&amp;gt;continuation&amp;lt;/vp&amp;gt; argument):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
predicates&lt;br /&gt;
    onAttach2_async : (string Last, webSocket WebSocket) suspending.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The interesting part is that the real functional predicates like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
    echoLoop_async : (webSocket WebSocket, continuation{unit} Continuation).&lt;br /&gt;
clauses&lt;br /&gt;
    echoLoop_async(WebSocket, Continuation) :-&lt;br /&gt;
        WebSocket:readMessage_async(&lt;br /&gt;
            Continuation:mkContinue(&lt;br /&gt;
                { (Message) :-&lt;br /&gt;
                    if webSocket::close(Status, Reason) = Message then&lt;br /&gt;
                        if 0 &amp;lt;&amp;gt; Status then&lt;br /&gt;
                            stdio::writef(&amp;quot;Closed:% %\n&amp;quot;, Status, Reason)&lt;br /&gt;
                        end if,&lt;br /&gt;
                        Continuation:success(unit)&lt;br /&gt;
                    else&lt;br /&gt;
                        if webSocket::ss(U16) = Message then&lt;br /&gt;
                            stdio::writef(&amp;quot;Message:%\n&amp;quot;, segmented_utf16::getAsString(U16))&lt;br /&gt;
                        end if,&lt;br /&gt;
                        WebSocket:writeMessage_async(Message,&lt;br /&gt;
                            Continuation:mkContinue(&lt;br /&gt;
                                {  :-&lt;br /&gt;
                                    echoLoop_async(WebSocket, Continuation) %&lt;br /&gt;
                                }))&lt;br /&gt;
                    end if&lt;br /&gt;
                })).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Should now be implemented as a suspending predicate which result in much simpler code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
    echoLoop_async : (webSocket WebSocket) suspending.&lt;br /&gt;
clauses&lt;br /&gt;
    echoLoop_async(WebSocket) :-&lt;br /&gt;
        Message = WebSocket:readMessage_async(),&lt;br /&gt;
        if webSocket::close(Status, Reason) = Message then&lt;br /&gt;
            if 0 &amp;lt;&amp;gt; Status then&lt;br /&gt;
                stdio::writef(&amp;quot;Closed:% %\n&amp;quot;, Status, Reason)&lt;br /&gt;
            end if&lt;br /&gt;
        else&lt;br /&gt;
            if webSocket::ss(U16) = Message then&lt;br /&gt;
                stdio::writef(&amp;quot;Message:%\n&amp;quot;, segmented_utf16::getAsString(U16))&lt;br /&gt;
            end if,&lt;br /&gt;
            WebSocket:writeMessage_async(Message),&lt;br /&gt;
            echoLoop_async(WebSocket)&lt;br /&gt;
        end if.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Especially, notice that this fragment of the code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    ...&lt;br /&gt;
        WebSocket:readMessage_async(&lt;br /&gt;
            Continuation:mkContinue(&lt;br /&gt;
                { (Message) :-&lt;br /&gt;
                    ...&lt;br /&gt;
                })).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simply becomes an ordinary call:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    ...&lt;br /&gt;
        Message = WebSocket:readMessage_async(),&lt;br /&gt;
        ...&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Visual Prolog 11 New Features]]&lt;br /&gt;
* [[Visual Prolog 10 Upgrade Notes]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Release Notes|11 Upgrade Notes]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_11_Upgrade_Notes&amp;diff=4930</id>
		<title>Visual Prolog 11 Upgrade Notes</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Visual_Prolog_11_Upgrade_Notes&amp;diff=4930"/>
		<updated>2024-04-08T09:29:55Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls: mach &amp;amp; case&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document describes how to upgrade Visual Prolog 10 projects to Visual Prolog 11, for older projects you should also read the [[Visual Prolog 10 Upgrade Notes]].&lt;br /&gt;
&lt;br /&gt;
If you have problems with upgrading your projects and need additional information, you are welcome to ask questions in [http://discuss.visual-prolog.com/viewforum.php?f=2 Visual Prolog Discussion Forum].&lt;br /&gt;
&lt;br /&gt;
By default, the installation of Visual Prolog 11 will not replace any older installed versions. It is possible to work with several versions on a single computer.  See also [[vipLaunch]].&lt;br /&gt;
&lt;br /&gt;
The Commercial and Personal Edition are identical; differences in capabilities are controlled by the license used to activate the computer.&lt;br /&gt;
&lt;br /&gt;
Entities that are not available to Personal Edition usage are marked with the attribute &amp;lt;vp&amp;gt;[feature(&amp;quot;Commercial Edition&amp;quot;)]&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Visual Prolog 11 is installed &amp;#039;&amp;#039;per user&amp;#039;&amp;#039; in &amp;#039;&amp;#039;&amp;#039;...\Users\&amp;lt;user&amp;gt;\AppData\Roaming\Visual Prolog\11&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Visual Prolog 11 project files are backward-compatible with Visual Prolog 10 project files.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Notice&amp;#039;&amp;#039;&amp;#039; it is highly advisable to have a backup of a project before updating.&lt;br /&gt;
&lt;br /&gt;
When updating a project you should open the project in the new IDE and accept to remove any non-existing PFC packages.  Then build the project and accept to&lt;br /&gt;
&lt;br /&gt;
* delete all bad include directives&lt;br /&gt;
* insert new ones and &lt;br /&gt;
* add new PFC packages&lt;br /&gt;
&lt;br /&gt;
=== Superfluous Files ===&lt;br /&gt;
&lt;br /&gt;
If you haven&amp;#039;t removed the superfluous resource files then see [[Visual Prolog 10 Upgrade Notes#Superfluous_files]].&lt;br /&gt;
&lt;br /&gt;
=== match &amp;amp; case future keywords ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;match&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;case&amp;lt;/vp&amp;gt; will be keywords in future releases of Visual Prolog and you will receive warnings if you use them.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;regEx::&amp;lt;/vp&amp;gt;&amp;lt;b&amp;gt;match&amp;lt;/b&amp;gt; has been retired and renamed to &amp;lt;vp&amp;gt;regEx::matchFirst&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== gdiplus ===&lt;br /&gt;
&lt;br /&gt;
If your project initializes gdiplus, e.g. like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        _ = mainForm::display(gui::getScreenWindow()),&lt;br /&gt;
        GDIpToken = gdiplus::startup(),&lt;br /&gt;
        messageLoop::run(),&lt;br /&gt;
        gdiplus::shutdown(GDIpToken).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then simply remove the calls to &amp;lt;vp&amp;gt;gdiplus::startup&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;gdiplus::shutdown&amp;lt;/vp&amp;gt; code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        _ = mainForm::display(gui::getScreenWindow()),&lt;br /&gt;
        messageLoop::run().&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;color&amp;lt;/vp&amp;gt; class/interface has been retired, and superseded by the domain &amp;lt;vp&amp;gt;gdiplus_native::color&amp;lt;/vp&amp;gt;. In many cases you simply have to remove the call to &amp;lt;vp&amp;gt;color::create&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This line (in the &amp;#039;&amp;#039;&amp;#039;GDI+ Example&amp;#039;&amp;#039;)&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
        DarkRed = pen::createColor(color::create(gdiplus_native::darkred), penWidth, unit),&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
has been changed to:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
        DarkRed = pen::createColor(gdiplus_native::darkred, penWidth, unit),&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A little editor trick: if you use autoformatting of code (a project setting) you can just remove &amp;lt;vp&amp;gt;color::create&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
        DarkRed = pen::createColor((gdiplus_native::darkred), penWidth, unit),&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
When you save the file the superfluous parentheses will be removed automatically.  Therefore you can correct an entire file simply by replacing all occurrences of &amp;lt;vp&amp;gt;color::create&amp;lt;/vp&amp;gt; with nothing/blank.&lt;br /&gt;
&lt;br /&gt;
Furthermore, some domains have been relocated from the &amp;lt;vp&amp;gt;gdiplus&amp;lt;/vp&amp;gt; class to the &amp;lt;vp&amp;gt;gdiplus_native&amp;lt;/vp&amp;gt; class.  The &amp;quot;Fix&amp;quot; button in the error window should handle that problem automatically.  Otherwise, the IDE command &amp;#039;&amp;#039;&amp;#039;Insert -&amp;gt; Qualification Ctrl+Shift+S&amp;#039;&amp;#039;&amp;#039; can also insert or correct the qualification.&lt;br /&gt;
&lt;br /&gt;
The object predicate &amp;lt;vp&amp;gt;graphics::drawString/6&amp;lt;/vp&amp;gt; has been retired, instead you will have to choose between:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
predicates&lt;br /&gt;
    drawStringIn : (font Font, brush Brush, rectF LayoutRect, string String, stringFormat StringFormat = stringFormat::null).&lt;br /&gt;
    drawStringAt : (font Font, brush Brush, pointF Origin, string String, stringFormat StringFormat = stringFormat::null).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;vp&amp;gt;graphics::drawStringIn&amp;lt;/vp&amp;gt; draws the string in the rectangle &amp;lt;vp&amp;gt;LayoutRect&amp;lt;/vp&amp;gt; or&lt;br /&gt;
* &amp;lt;vp&amp;gt;graphics::drawStringAt&amp;lt;/vp&amp;gt; draws the string at the point &amp;lt;vp&amp;gt;Origin&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== treeModel_std &amp;amp; treeNode_std ===&lt;br /&gt;
&lt;br /&gt;
If you use the &amp;lt;vp&amp;gt;treeControl&amp;lt;/vp&amp;gt; with the &amp;lt;vp&amp;gt;treeModel_std&amp;lt;/vp&amp;gt; you will have to add &amp;lt;vp&amp;gt;code::value&amp;lt;/vp&amp;gt; as argument to &amp;lt;vp&amp;gt;treeModel_std&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;treeNode_std&amp;lt;/vp&amp;gt;.  Notice that this is not necessary in clauses; only in other places (declarations, ...).&lt;br /&gt;
&lt;br /&gt;
Here illustrated with code from the &amp;lt;vp&amp;gt;dragNdropDemo&amp;lt;/vp&amp;gt; in the examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement mainForm inherits formWindow&lt;br /&gt;
    open core, vpiDomains, treeModel_std{core::value}&lt;br /&gt;
...&lt;br /&gt;
predicates&lt;br /&gt;
    onDragBegin : treeControl{treeNode_std{value}}::dragBeginResponder.&lt;br /&gt;
...&lt;br /&gt;
% This code is maintained automatically, do not update it manually. 10:41:58-23.11.2011&lt;br /&gt;
facts&lt;br /&gt;
    treeCtl : treecontrol{treeNode_std{value}}.&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that if you have deleted the form/dialog file (as described in  [[Visual Prolog 10 Upgrade Notes#Superfluos_files|superfluous Files]]) then you can (despite the warning in the comment) edit directly in the &amp;quot;auto&amp;quot;-code.&lt;br /&gt;
&lt;br /&gt;
=== codePageId ansi &amp;amp; threadAnsi ===&lt;br /&gt;
&lt;br /&gt;
The following &amp;lt;vp&amp;gt;codePageID&amp;lt;/vp&amp;gt;&amp;#039;s have been deprecated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
constants&lt;br /&gt;
    ansi : codePage = 0 [deprecated(&amp;quot;It is recommended not to use this codepage, but use an explicit encoding instead&amp;quot;)].&lt;br /&gt;
    threadAnsi : codePage = 3 [deprecated(&amp;quot;It is recommended not to use this codepage, but use an explicit encoding instead&amp;quot;)].&lt;br /&gt;
    % @short Represents the systems/threads current ANSI codePage.&lt;br /&gt;
    % It is recommended not to use this codepage but use an explicit encoding instead.&lt;br /&gt;
    % @end&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The problem with these system/user codepages is that they are often set to some regional codepage with 8 bit characters.  Files written like must be read with the same codepage, otherwise characters may become wrong or even lost.&lt;br /&gt;
&lt;br /&gt;
Some time ago (unknown when) Microsoft have introduced the possibility to use utf-8 as system/user codepage.  Using utf-8 is technically the best choice, because it &amp;quot;unites&amp;quot; all regional &amp;quot;things&amp;quot; into a single codepage. However but the transition from old regional codepages to utf-8 is &amp;quot;difficult&amp;quot;, because you will still need to read a file with the codepage that was used to write it.&lt;br /&gt;
&lt;br /&gt;
We recommend that you &amp;quot;migrate&amp;quot; text files to utf-8 (or utf-16 if you mainly use &amp;quot;special&amp;quot; characters, like chinese).  If you add a byte order mark the format becomes &amp;quot;visible&amp;quot;, but in some contexts (certain Internet contexts and using foreign applications) byte order marks in utf-8 files will not be accepted.&lt;br /&gt;
&lt;br /&gt;
=== Fallback CodePage ===&lt;br /&gt;
&lt;br /&gt;
Several text file related predicates have been equipped with a non-optional &amp;lt;vp&amp;gt;FallbackCodePage&amp;lt;/vp&amp;gt; argument.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class inputStream_file : inputStream&lt;br /&gt;
...&lt;br /&gt;
constructors&lt;br /&gt;
    openFileText : (string Filename, codePage FallbackCodePage, fileSystem_api::accessPermit Access = fileSystem_api::permitRead).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The predicate &amp;lt;vp&amp;gt;inputStream_file::openFileText&amp;lt;/vp&amp;gt; examines the file to open searching for Byte Order Marks and obvious utf-16 format.  If it is not possible to determine the codepage like that the &amp;lt;vp&amp;gt;FallbackCodePage&amp;lt;/vp&amp;gt; will be used.  Such predicates used to user the &amp;lt;vp&amp;gt;threadAnsi&amp;lt;/vp&amp;gt; codepage, but (as described above) this can lead to problems with &amp;quot;old&amp;quot; files and new settings and files written on one computer and read on another.   For this reason you must now (explicitly) decide which codepage to use if it cannot be inferred.&lt;br /&gt;
&lt;br /&gt;
=== COM component classes ===&lt;br /&gt;
&lt;br /&gt;
The import of COM components has been simplified for certain COM components.  Instead of being defined in a separate Visual Prolog class many COM components are now created by calling a predicate.&lt;br /&gt;
&lt;br /&gt;
For example, to create an XMLHTTP component you would construct object using the corresponding constructor &amp;lt;vp&amp;gt;XmlHttp = xmlhttp60::new()&amp;lt;/vp&amp;gt;, now you will instead call the predicate &amp;lt;vp&amp;gt;XmlHttp = msxml_HTTP_api::newXmlhttp60()&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== watchDirectory ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;watchDirectory&amp;lt;/vp&amp;gt; has been updated to use suspending predicates, and as result &amp;lt;vp&amp;gt;watchDirectory::start&amp;lt;/vp&amp;gt; takes an &amp;lt;vp&amp;gt;executionContext&amp;lt;/vp&amp;gt; as argument.  In most cases &amp;lt;vp&amp;gt;pfc\asynchronous\executionContext_pool::defaultPool&amp;lt;/vp&amp;gt; can be used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
            WD = watchDirectory::start(FullDir, pfc\asynchronous\executionContext_pool::defaultPool),&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Master/slave ===&lt;br /&gt;
&lt;br /&gt;
The master/slave concept has been updated to use {{lang|Suspending Predicates|suspending predicates}} instead of explicit &amp;lt;vp&amp;gt;continuation&amp;lt;/vp&amp;gt;s.  The article [[Master/slave processes]] and the corresponding demo example has been updated to reflect the changes.&lt;br /&gt;
&lt;br /&gt;
=== Web Services &amp;amp; webSockets ===&lt;br /&gt;
&lt;br /&gt;
The Web Services and &amp;lt;vp&amp;gt;webSocket&amp;lt;/vp&amp;gt;s support has been updated to use {{lang|Suspending Predicates|suspending predicates}} for asynchronous operation.  The main updates necessary to make an old program working is remove all access to &amp;lt;vp&amp;gt;threadpool&amp;lt;/vp&amp;gt;s.&lt;br /&gt;
&lt;br /&gt;
This code&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    runServer() :-&lt;br /&gt;
        ...&lt;br /&gt;
        mkService(Session, &amp;quot;File service&amp;quot;, &amp;quot;&amp;quot;, requestQueue_content::new(threadpool, demoFileService::contentMapper)),&lt;br /&gt;
        ...&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
will look like this:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    runServer() :-&lt;br /&gt;
        ...&lt;br /&gt;
        mkService(Session, &amp;quot;File service&amp;quot;, &amp;quot;&amp;quot;, requestQueue_content::new(demoFileService::contentMapper)),&lt;br /&gt;
        ...&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If necessary you can add an explicit &amp;lt;vp&amp;gt;executionContext&amp;lt;/vp&amp;gt; (&amp;lt;vp&amp;gt;Ctx&amp;lt;/vp&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    runServer() :-&lt;br /&gt;
        httpServer_api::httpInitialize(httpServer_native::http_initialize_server),&lt;br /&gt;
        Session = session::new(),&lt;br /&gt;
        Ctx = pfc\asynchronous\executionContext_pool::defaultPool,&lt;br /&gt;
        try&lt;br /&gt;
            cleanup:alsoDispose(Session),&lt;br /&gt;
            % Demo file service for html, JavaScript , images, etc to the client&lt;br /&gt;
            mkService(Session, &amp;quot;File service&amp;quot;, &amp;quot;&amp;quot;, requestQueue_content::new(demoFileService::contentMapper, Ctx)),&lt;br /&gt;
            ...&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The changes in &amp;lt;vp&amp;gt;webSocket&amp;lt;/vp&amp;gt; requires more attention.  You will have to remove &amp;lt;vp&amp;gt;continuation&amp;lt;/vp&amp;gt;s and use  {{lang|Suspending Predicates|suspending predicates}} instead.&lt;br /&gt;
&lt;br /&gt;
For example, the predicate onAttach_async must now be a suspending predicate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface webSocketService&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    onAttach_async : (httpRequest Request, webSocket WebSocket) suspending.&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The implementation of this predicate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    onAttach_async(Request, WebSocket, Continuation) :-&lt;br /&gt;
        onAttach2_async(filename::getLastDirectory(Request:path, _), WebSocket, Continuation).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 should drop the &amp;lt;vp&amp;gt;Continuation&amp;lt;/vp&amp;gt; argument:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    onAttach_async(Request, WebSocket) :-&lt;br /&gt;
        onAttach2_async(filename::getLastDirectory(Request:path, _), WebSocket).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;onAttach2_async&amp;lt;/vp&amp;gt; should also be declared as a suspending predicate (without a &amp;lt;vp&amp;gt;continuation&amp;lt;/vp&amp;gt; argument):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
predicates&lt;br /&gt;
    onAttach2_async : (string Last, webSocket WebSocket) suspending.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The interesting part is that the real functional predicates like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
    echoLoop_async : (webSocket WebSocket, continuation{unit} Continuation).&lt;br /&gt;
clauses&lt;br /&gt;
    echoLoop_async(WebSocket, Continuation) :-&lt;br /&gt;
        WebSocket:readMessage_async(&lt;br /&gt;
            Continuation:mkContinue(&lt;br /&gt;
                { (Message) :-&lt;br /&gt;
                    if webSocket::close(Status, Reason) = Message then&lt;br /&gt;
                        if 0 &amp;lt;&amp;gt; Status then&lt;br /&gt;
                            stdio::writef(&amp;quot;Closed:% %\n&amp;quot;, Status, Reason)&lt;br /&gt;
                        end if,&lt;br /&gt;
                        Continuation:success(unit)&lt;br /&gt;
                    else&lt;br /&gt;
                        if webSocket::ss(U16) = Message then&lt;br /&gt;
                            stdio::writef(&amp;quot;Message:%\n&amp;quot;, segmented_utf16::getAsString(U16))&lt;br /&gt;
                        end if,&lt;br /&gt;
                        WebSocket:writeMessage_async(Message,&lt;br /&gt;
                            Continuation:mkContinue(&lt;br /&gt;
                                {  :-&lt;br /&gt;
                                    echoLoop_async(WebSocket, Continuation) %&lt;br /&gt;
                                }))&lt;br /&gt;
                    end if&lt;br /&gt;
                })).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Should now be implemented as a suspending predicate which result in much simpler code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
    echoLoop_async : (webSocket WebSocket) suspending.&lt;br /&gt;
clauses&lt;br /&gt;
    echoLoop_async(WebSocket) :-&lt;br /&gt;
        Message = WebSocket:readMessage_async(),&lt;br /&gt;
        if webSocket::close(Status, Reason) = Message then&lt;br /&gt;
            if 0 &amp;lt;&amp;gt; Status then&lt;br /&gt;
                stdio::writef(&amp;quot;Closed:% %\n&amp;quot;, Status, Reason)&lt;br /&gt;
            end if&lt;br /&gt;
        else&lt;br /&gt;
            if webSocket::ss(U16) = Message then&lt;br /&gt;
                stdio::writef(&amp;quot;Message:%\n&amp;quot;, segmented_utf16::getAsString(U16))&lt;br /&gt;
            end if,&lt;br /&gt;
            WebSocket:writeMessage_async(Message),&lt;br /&gt;
            echoLoop_async(WebSocket)&lt;br /&gt;
        end if.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Especially, notice that this fragment of the code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    ...&lt;br /&gt;
        WebSocket:readMessage_async(&lt;br /&gt;
            Continuation:mkContinue(&lt;br /&gt;
                { (Message) :-&lt;br /&gt;
                    ...&lt;br /&gt;
                })).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simply becomes an ordinary call:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    ...&lt;br /&gt;
        Message = WebSocket:readMessage_async(),&lt;br /&gt;
        ...&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Visual Prolog 11 New Features]]&lt;br /&gt;
* [[Visual Prolog 10 Upgrade Notes]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Release Notes|11 Upgrade Notes]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
</feed>