<?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=Steve+Lympany</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=Steve+Lympany"/>
	<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Special:Contributions/Steve_Lympany"/>
	<updated>2026-04-15T21:43:42Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=3rd:HTML_drawer&amp;diff=2622</id>
		<title>3rd:HTML drawer</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=3rd:HTML_drawer&amp;diff=2622"/>
		<updated>2011-05-29T14:54:05Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Downloads */  new link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;drawHTML.DLL is a DLL is written in VIP7.3. The DLL can be linked with VIP projects - the &amp;quot;glue&amp;quot; code and examples are provided. It is used simply to draw nice text: you can control text colour and font styles using HTML tags. Text wrapping and centring are dynamic, and both can apply to different parts of the same HTML text. The main call is (you will recognise):&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;DrawHTML:drawTextInRect(WindowType,RCT,HTML,FLAGS)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Also, certain attributes can be called from your own code e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;DrawHTML:set_wrap(true),&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
A limited number of tags are understood. Some of these are standard HTML, and some are unique to the DLL.&lt;br /&gt;
==Standard HTML tags==&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;&amp;lt;/nowiki&amp;gt; &amp;#039;&amp;#039;italic&amp;#039;&amp;#039; &amp;lt;/i&amp;gt;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;&amp;lt;/nowiki&amp;gt;  &amp;#039;&amp;#039;&amp;#039;bold&amp;#039;&amp;#039;&amp;#039; &amp;lt;/b&amp;gt;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;u&amp;gt;&amp;lt;/nowiki&amp;gt;  underline &amp;lt;/u&amp;gt;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;  new line&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;sub&amp;gt;&amp;lt;/nowiki&amp;gt; subscript&amp;lt;/sub&amp;gt;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;sup&amp;gt;&amp;lt;/nowiki&amp;gt; superscript&amp;lt;/sub&amp;gt;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;par&amp;gt;&amp;lt;/nowiki&amp;gt;  also new line&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;t&amp;gt;&amp;lt;/nowiki&amp;gt;  tab&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;big&amp;gt;&amp;lt;/nowiki&amp;gt; increase font size &amp;lt;/big&amp;gt;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;small&amp;gt;&amp;lt;/nowiki&amp;gt;  decrease font size &amp;lt;/small&amp;gt;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt; &amp;lt;a ref=\&amp;quot;some text\&amp;quot;&amp;gt;hyperlink&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt;. Anchor: if the user clicks on this word, the callback will return &amp;quot;some text&amp;quot;.&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;img src=\&amp;quot;file.bmp\&amp;quot;&amp;gt;&amp;lt;/nowiki&amp;gt; draws an image.&lt;br /&gt;
==Non-standard Tags==&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;&amp;lt;/nowiki&amp;gt; centred text on &amp;lt;/c&amp;gt; ... and off&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;wr&amp;gt;&amp;lt;/nowiki&amp;gt; turn wrapping on &amp;lt;/wr&amp;gt; ... and off&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;lm=\&amp;quot;20\&amp;quot;&amp;gt;&amp;lt;/nowiki&amp;gt; left margin = 20 pixels&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;font=\&amp;quot;arial\&amp;quot;&amp;gt;&amp;lt;/nowiki&amp;gt; change font&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;color=\&amp;quot;#FF00FF\&amp;quot;&amp;gt;&amp;lt;/nowiki&amp;gt; set text colour &amp;lt;/color&amp;gt;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;hi&amp;gt;&amp;lt;/nowiki&amp;gt;text within these tags are hidden when hide=active, and displayed as normal when hide=inactive&amp;lt;/hi&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Downloads==&lt;br /&gt;
Further information and downloads can be found here:&lt;br /&gt;
http://www.acsumama.com/vip/drawhtml/index.htm&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=3rd:Tools_%26_Support&amp;diff=2619</id>
		<title>3rd:Tools &amp; Support</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=3rd:Tools_%26_Support&amp;diff=2619"/>
		<updated>2011-05-26T14:29:18Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Miscellaneous */  Web Easy&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Text Editors and Utilities ===&lt;br /&gt;
&lt;br /&gt;
* Powerful text editor (not free): [http://www.boxersoftware.com/ Boxer Text Editor]&lt;br /&gt;
* Free Text editor: [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++]&lt;br /&gt;
* Powerful editor: [http://www.textpad.com/ TextPad]&lt;br /&gt;
* Diff tool: [http://www.scootersoftware.com/ Beyond Compare]&lt;br /&gt;
* Regular Expressions tool: [http://www.ultrapico.com/Expresso.htm Expresso]&lt;br /&gt;
* Follow file changes while they happen: [http://tailforwin32.sourceforge.net/ Tail for Win32]&lt;br /&gt;
* Windows bug &amp;quot;File in use&amp;quot; - very useful [http://ccollomb.free.fr/unlocker/ Free File unlocker]&lt;br /&gt;
&lt;br /&gt;
=== Creating Help Files ===&lt;br /&gt;
&lt;br /&gt;
* CHM Editor : [http://visual-chm.wekasoft.downloadsoftware4free.com/ Visual CHM ] Cheap&lt;br /&gt;
* CHM Editor : [http://www.vizacc.com/downloads.aspx Visacc] Free.&lt;br /&gt;
* WYSIWYG HTML editor (Use Netscape &amp;#039;&amp;#039;&amp;#039;7.2&amp;#039;&amp;#039;&amp;#039;): [http://browser.netscape.com/downloads/archive/ Netscape Browser Archive] Free&lt;br /&gt;
* HTML editor: [http://www.pagebreeze.com/ PageBreeze] Cheap but look at Web Easy 8&lt;br /&gt;
&lt;br /&gt;
=== Microsoft Windows Support ===&lt;br /&gt;
&lt;br /&gt;
* Windows Problem Solving [http://winhlp.com/ Windows Problem Solver (winhlp.com)]&lt;br /&gt;
* Toolbox (free) [http://technet.microsoft.com/en-us/sysinternals/bb545027.aspx Sysinternals Utilities] (from [http://technet.microsoft.com Microsoft Technet]).  Notice especially:&lt;br /&gt;
** [http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx Process Explorer]&lt;br /&gt;
** [http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx Process Monitor]&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* Charting Tool: [http://www.pacestar.com/wizflow/index.html WizFlow]&lt;br /&gt;
* Easy Flash Editor (Swish Max2) : [http://www.swishzone.com/index.php SWiSHzone]&lt;br /&gt;
* BNF stuff : [http://www.garshol.priv.no/download/text/bnf.html BNF and EBNF] by &amp;#039;&amp;#039;Lars Marius Garshol&amp;#039;&amp;#039;&lt;br /&gt;
* BNF Stuff : [http://cui.unige.ch/db-research/Enseignement/analyseinfo/AboutBNF.html What is BNF notation?] by &amp;#039;&amp;#039;Th. Estier, CUI - University of Geneva&amp;#039;&amp;#039;&lt;br /&gt;
* Windows apps reviews : [http://www.winsupersite.com/reviews/ SuperSite Reviews] on &amp;#039;&amp;#039;Paul Thurrott&amp;#039;s SuperSite for Windows&amp;#039;&amp;#039;.&lt;br /&gt;
* Windows installer: [http://www.jrsoftware.org/isinfo.php INNOSET].&lt;br /&gt;
* Website creator: [http://www.webeasysite.com/UK/ Web Easy] Very good, and cheap&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=3rd:Tools_%26_Support&amp;diff=2618</id>
		<title>3rd:Tools &amp; Support</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=3rd:Tools_%26_Support&amp;diff=2618"/>
		<updated>2011-05-26T14:27:48Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: Reference to Web Easy&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Text Editors and Utilities ===&lt;br /&gt;
&lt;br /&gt;
* Powerful text editor (not free): [http://www.boxersoftware.com/ Boxer Text Editor]&lt;br /&gt;
* Free Text editor: [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++]&lt;br /&gt;
* Powerful editor: [http://www.textpad.com/ TextPad]&lt;br /&gt;
* Diff tool: [http://www.scootersoftware.com/ Beyond Compare]&lt;br /&gt;
* Regular Expressions tool: [http://www.ultrapico.com/Expresso.htm Expresso]&lt;br /&gt;
* Follow file changes while they happen: [http://tailforwin32.sourceforge.net/ Tail for Win32]&lt;br /&gt;
* Windows bug &amp;quot;File in use&amp;quot; - very useful [http://ccollomb.free.fr/unlocker/ Free File unlocker]&lt;br /&gt;
&lt;br /&gt;
=== Creating Help Files ===&lt;br /&gt;
&lt;br /&gt;
* CHM Editor : [http://visual-chm.wekasoft.downloadsoftware4free.com/ Visual CHM ] Cheap&lt;br /&gt;
* CHM Editor : [http://www.vizacc.com/downloads.aspx Visacc] Free.&lt;br /&gt;
* WYSIWYG HTML editor (Use Netscape &amp;#039;&amp;#039;&amp;#039;7.2&amp;#039;&amp;#039;&amp;#039;): [http://browser.netscape.com/downloads/archive/ Netscape Browser Archive] Free&lt;br /&gt;
* HTML editor: [http://www.pagebreeze.com/ PageBreeze] Cheap but look at Web Easy 8&lt;br /&gt;
&lt;br /&gt;
=== Microsoft Windows Support ===&lt;br /&gt;
&lt;br /&gt;
* Windows Problem Solving [http://winhlp.com/ Windows Problem Solver (winhlp.com)]&lt;br /&gt;
* Toolbox (free) [http://technet.microsoft.com/en-us/sysinternals/bb545027.aspx Sysinternals Utilities] (from [http://technet.microsoft.com Microsoft Technet]).  Notice especially:&lt;br /&gt;
** [http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx Process Explorer]&lt;br /&gt;
** [http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx Process Monitor]&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* Charting Tool: [http://www.pacestar.com/wizflow/index.html WizFlow]&lt;br /&gt;
* Easy Flash Editor (Swish Max2) : [http://www.swishzone.com/index.php SWiSHzone]&lt;br /&gt;
* BNF stuff : [http://www.garshol.priv.no/download/text/bnf.html BNF and EBNF] by &amp;#039;&amp;#039;Lars Marius Garshol&amp;#039;&amp;#039;&lt;br /&gt;
* BNF Stuff : [http://cui.unige.ch/db-research/Enseignement/analyseinfo/AboutBNF.html What is BNF notation?] by &amp;#039;&amp;#039;Th. Estier, CUI - University of Geneva&amp;#039;&amp;#039;&lt;br /&gt;
* Windows apps reviews : [http://www.winsupersite.com/reviews/ SuperSite Reviews] on &amp;#039;&amp;#039;Paul Thurrott&amp;#039;s SuperSite for Windows&amp;#039;&amp;#039;.&lt;br /&gt;
* Windows installer: [http://www.jrsoftware.org/isinfo.php INNOSET].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=3rd:Main_Page&amp;diff=2514</id>
		<title>3rd:Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=3rd:Main_Page&amp;diff=2514"/>
		<updated>2011-01-31T11:12:30Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: Added EDB_Class_Builder&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The namespace &amp;#039;&amp;#039;&amp;#039;3rd&amp;#039;&amp;#039;&amp;#039; is dedicated to descriptions of 3rd party packages, add-on&amp;#039;s, applications, etc, which are available to fellow programmers.&lt;br /&gt;
&lt;br /&gt;
Articles are in the &amp;#039;&amp;#039;&amp;#039;3rd&amp;#039;&amp;#039;&amp;#039; namespace if the title has this format: &amp;#039;&amp;#039;&amp;#039;3rd:&amp;lt;title&amp;gt;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
It is advantageous, if you give your package/add-on/... a &amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;, and then use &amp;#039;&amp;#039;&amp;#039;3rd:&amp;lt;name&amp;gt;&amp;#039;&amp;#039;&amp;#039; as article title.  (The name can have several words).&lt;br /&gt;
&lt;br /&gt;
Remember to write:&lt;br /&gt;
* How to obtain the package/add-on/...&lt;br /&gt;
* Which license conditions that applies&lt;br /&gt;
* Whether the package/add-on/... is free or not&lt;br /&gt;
&lt;br /&gt;
Also check-out http://www.arsaniit.com/prolog-tools&lt;br /&gt;
&lt;br /&gt;
=== Contents ===&lt;br /&gt;
&lt;br /&gt;
* [[3rd:QDBM|QDBM]] a key-&amp;gt;value database (GNU license).&lt;br /&gt;
* [[3rd:Scintilla Editor Control|Scintilla Editor Control]] custom control wraps the scintilla editor.&lt;br /&gt;
* [[3rd:SCS - Simple Client Server|SCS - Simple Client Server]] a package for creating client server solutions.&lt;br /&gt;
* [[3rd:VPcURL|VPcURL]] provides Visual Prolog bindings to the cURL library, which is a library for HTTP and FTP.&lt;br /&gt;
* [[3rd:Tools &amp;amp; Support|Tools &amp;amp; Support]] is an article about useful non-Visual Prolog tools and support sites.&lt;br /&gt;
* [[3rd:RS232|RS232]] packages for communicating via the RS232-interface of a computer.&lt;br /&gt;
* [[3rd:Fast Articifial Neural Networks (FANN)|Fast Articifial Neural Networks (FANN)]] bindings to the FANN library.&lt;br /&gt;
* [[3rd:VIC - VIP7 IDE companion|VIC - VIP7 IDE companion]] VIC provides 2 major tools, and a few little utilities, to help with the development of VIP7 projects.&lt;br /&gt;
* [[3rd:External Database class builder|EDB Class Builder]] A tool to generate a complete class using the External Database (chaindb), based on your domain structure,to include into VIP7 projects.&lt;br /&gt;
* [[3rd:PROLEDIT|PROLEDIT]] A Simple Portable Editor&lt;br /&gt;
* [[3rd:HTML drawer|drawHTML]] A DLL written in VIP7.3 to draw and print HTML. i.e. it just draws nice text, but also has a callback to allow a menu functionality.&lt;br /&gt;
* [[3rd:Layout control|Layout]] A DLL written in VIP7.3 - container control allowing one or more child controls, with hiding, resizing and different layouts&lt;br /&gt;
* [[3rd:Solution of Alphametic Puzzles|Solution of Alphametic Puzzles]] E.g. SEND + MORE = MONEY.&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=3rd:Layout_control&amp;diff=2513</id>
		<title>3rd:Layout control</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=3rd:Layout_control&amp;diff=2513"/>
		<updated>2011-01-13T20:22:17Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;quot;LAYOUT&amp;quot; is a layout control, a DLL written in VIP7.3, allowing layouts of several child controls to be displayed in a form or dialog. &amp;lt;br&amp;gt;&lt;br /&gt;
One control is displayed in one &amp;quot;pane&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
At runtime, the user can:&lt;br /&gt;
*hide/show panes&lt;br /&gt;
*reorganise pane layouts&lt;br /&gt;
*resize panes&lt;br /&gt;
*swap panes.&lt;br /&gt;
&lt;br /&gt;
It replaces &amp;lt;b&amp;gt;SplitN_Control&amp;lt;/b&amp;gt;. There is no limit to the number of panes/controls.&amp;lt;br&amp;gt;&lt;br /&gt;
To download the DLL, glue code, example, and view the details, please visit:&lt;br /&gt;
http://www.acsumama.com/VIPDeveloper/layout.htm&lt;br /&gt;
&lt;br /&gt;
[[Image:layout7.jpg]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=3rd:Layout_control&amp;diff=2512</id>
		<title>3rd:Layout control</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=3rd:Layout_control&amp;diff=2512"/>
		<updated>2011-01-13T20:19:18Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;quot;LAYOUT&amp;quot; is a layout control, a DLL written in VIP7.3, allowing layouts of several child controls to be displayed in a form or dialog. &amp;lt;br&amp;gt;&lt;br /&gt;
One control is displayed in one &amp;quot;pane&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
At runtime, the user can:&lt;br /&gt;
*hide/show panes&lt;br /&gt;
*reorganise pane layouts&lt;br /&gt;
*resize panes&lt;br /&gt;
*swap panes.&lt;br /&gt;
&lt;br /&gt;
It replaces &amp;lt;b&amp;gt;SplitN_Control&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
To download the DLL, glue code, example, and view the details, please visit:&lt;br /&gt;
http://www.acsumama.com/VIPDeveloper/layout.htm&lt;br /&gt;
&lt;br /&gt;
[[Image:layout7.jpg]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=3rd:Layout_control&amp;diff=2511</id>
		<title>3rd:Layout control</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=3rd:Layout_control&amp;diff=2511"/>
		<updated>2011-01-13T20:09:29Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A layout control, a DLL written in VIP7.3, allowing layouts of several child controls to be displayed in a form or dialog. Controls can be hidden (and reshown), resized and moved by the end-user.&amp;lt;br&amp;gt;&lt;br /&gt;
It replaces &amp;lt;b&amp;gt;SplitN_Control&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
To download the DLL, glue code, and example, please visit:&lt;br /&gt;
http://www.acsumama.com/VIPDeveloper/layout.htm&lt;br /&gt;
&lt;br /&gt;
[[Image:layout7.jpg]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=3rd:Layout_control&amp;diff=2509</id>
		<title>3rd:Layout control</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=3rd:Layout_control&amp;diff=2509"/>
		<updated>2011-01-09T19:26:16Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: New page: A layout control, a DLL written in VIP7.3, allowing layouts of several child controls to be displayed in a form or dialog. Controls can be hidden (and reshown), resized and moved by the en...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A layout control, a DLL written in VIP7.3, allowing layouts of several child controls to be displayed in a form or dialog. Controls can be hidden (and reshown), resized and moved by the end-user.&amp;lt;br&amp;gt;&lt;br /&gt;
Please visit:&lt;br /&gt;
http://www.acsumama.com/VIPDeveloper/layout.htm&lt;br /&gt;
&lt;br /&gt;
[[Image:layout7.jpg]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=File:Layout7.jpg&amp;diff=2508</id>
		<title>File:Layout7.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=File:Layout7.jpg&amp;diff=2508"/>
		<updated>2011-01-09T19:22:15Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: Screenshot of layout&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Screenshot of layout&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=3rd:Main_Page&amp;diff=2507</id>
		<title>3rd:Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=3rd:Main_Page&amp;diff=2507"/>
		<updated>2011-01-09T19:12:23Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Contents */ added Layout Control&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The namespace &amp;#039;&amp;#039;&amp;#039;3rd&amp;#039;&amp;#039;&amp;#039; is dedicated to descriptions of 3rd party packages, add-on&amp;#039;s, applications, etc, which are available to fellow programmers.&lt;br /&gt;
&lt;br /&gt;
Articles are in the &amp;#039;&amp;#039;&amp;#039;3rd&amp;#039;&amp;#039;&amp;#039; namespace if the title has this format: &amp;#039;&amp;#039;&amp;#039;3rd:&amp;lt;title&amp;gt;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
It is advantageous, if you give your package/add-on/... a &amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;, and then use &amp;#039;&amp;#039;&amp;#039;3rd:&amp;lt;name&amp;gt;&amp;#039;&amp;#039;&amp;#039; as article title.  (The name can have several words).&lt;br /&gt;
&lt;br /&gt;
Remember to write:&lt;br /&gt;
* How to obtain the package/add-on/...&lt;br /&gt;
* Which license conditions that applies&lt;br /&gt;
* Whether the package/add-on/... is free or not&lt;br /&gt;
&lt;br /&gt;
Also check-out http://www.arsaniit.com/prolog-tools&lt;br /&gt;
&lt;br /&gt;
=== Contents ===&lt;br /&gt;
&lt;br /&gt;
* [[3rd:QDBM|QDBM]] a key-&amp;gt;value database (GNU license).&lt;br /&gt;
* [[3rd:Scintilla Editor Control|Scintilla Editor Control]] custom control wraps the scintilla editor.&lt;br /&gt;
* [[3rd:SCS - Simple Client Server|SCS - Simple Client Server]] a package for creating client server solutions.&lt;br /&gt;
* [[3rd:VPcURL|VPcURL]] provides Visual Prolog bindings to the cURL library, which is a library for HTTP and FTP.&lt;br /&gt;
* [[3rd:Tools &amp;amp; Support|Tools &amp;amp; Support]] is an article about useful non-Visual Prolog tools and support sites.&lt;br /&gt;
* [[3rd:RS232|RS232]] packages for communicating via the RS232-interface of a computer.&lt;br /&gt;
* [[3rd:Fast Articifial Neural Networks (FANN)|Fast Articifial Neural Networks (FANN)]] bindings to the FANN library.&lt;br /&gt;
* [[3rd:VIC - VIP7 IDE companion|VIC - VIP7 IDE companion]] VIC provides 2 major tools, and a few little utilities, to help with the development of VIP7 projects.&lt;br /&gt;
* [[3rd:PROLEDIT|PROLEDIT]] A Simple Portable Editor&lt;br /&gt;
* [[3rd:HTML drawer|drawHTML]] A DLL written in VIP7.3 to draw and print HTML. i.e. it just draws nice text, but also has a callback to allow a menu functionality.&lt;br /&gt;
* [[3rd:Layout control|Layout]] A DLL written in VIP7.3 - container control allowing one or more child controls, with hiding, resizing and different layouts&lt;br /&gt;
* [[3rd:Solution of Alphametic Puzzles|Solution of Alphametic Puzzles]] E.g. SEND + MORE = MONEY.&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=3rd:HTML_drawer&amp;diff=2483</id>
		<title>3rd:HTML drawer</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=3rd:HTML_drawer&amp;diff=2483"/>
		<updated>2010-11-30T10:43:25Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: Description of drawHTML&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;drawHTML.DLL is a DLL is written in VIP7.3. The DLL can be linked with VIP projects - the &amp;quot;glue&amp;quot; code and examples are provided. It is used simply to draw nice text: you can control text colour and font styles using HTML tags. Text wrapping and centring are dynamic, and both can apply to different parts of the same HTML text. The main call is (you will recognise):&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;DrawHTML:drawTextInRect(WindowType,RCT,HTML,FLAGS)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Also, certain attributes can be called from your own code e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;DrawHTML:set_wrap(true),&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
A limited number of tags are understood. Some of these are standard HTML, and some are unique to the DLL.&lt;br /&gt;
==Standard HTML tags==&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;&amp;lt;/nowiki&amp;gt; &amp;#039;&amp;#039;italic&amp;#039;&amp;#039; &amp;lt;/i&amp;gt;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;&amp;lt;/nowiki&amp;gt;  &amp;#039;&amp;#039;&amp;#039;bold&amp;#039;&amp;#039;&amp;#039; &amp;lt;/b&amp;gt;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;u&amp;gt;&amp;lt;/nowiki&amp;gt;  underline &amp;lt;/u&amp;gt;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;  new line&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;sub&amp;gt;&amp;lt;/nowiki&amp;gt; subscript&amp;lt;/sub&amp;gt;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;sup&amp;gt;&amp;lt;/nowiki&amp;gt; superscript&amp;lt;/sub&amp;gt;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;par&amp;gt;&amp;lt;/nowiki&amp;gt;  also new line&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;t&amp;gt;&amp;lt;/nowiki&amp;gt;  tab&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;big&amp;gt;&amp;lt;/nowiki&amp;gt; increase font size &amp;lt;/big&amp;gt;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;small&amp;gt;&amp;lt;/nowiki&amp;gt;  decrease font size &amp;lt;/small&amp;gt;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt; &amp;lt;a ref=\&amp;quot;some text\&amp;quot;&amp;gt;hyperlink&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt;. Anchor: if the user clicks on this word, the callback will return &amp;quot;some text&amp;quot;.&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;img src=\&amp;quot;file.bmp\&amp;quot;&amp;gt;&amp;lt;/nowiki&amp;gt; draws an image.&lt;br /&gt;
==Non-standard Tags==&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;&amp;lt;/nowiki&amp;gt; centred text on &amp;lt;/c&amp;gt; ... and off&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;wr&amp;gt;&amp;lt;/nowiki&amp;gt; turn wrapping on &amp;lt;/wr&amp;gt; ... and off&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;lm=\&amp;quot;20\&amp;quot;&amp;gt;&amp;lt;/nowiki&amp;gt; left margin = 20 pixels&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;font=\&amp;quot;arial\&amp;quot;&amp;gt;&amp;lt;/nowiki&amp;gt; change font&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;color=\&amp;quot;#FF00FF\&amp;quot;&amp;gt;&amp;lt;/nowiki&amp;gt; set text colour &amp;lt;/color&amp;gt;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;&amp;lt;hi&amp;gt;&amp;lt;/nowiki&amp;gt;text within these tags are hidden when hide=active, and displayed as normal when hide=inactive&amp;lt;/hi&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Downloads==&lt;br /&gt;
Further information and downloads can be found here:&lt;br /&gt;
http://www.acsumama.com/vipDeveloper/drawHTML.htm&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=3rd:Main_Page&amp;diff=2482</id>
		<title>3rd:Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=3rd:Main_Page&amp;diff=2482"/>
		<updated>2010-11-30T10:12:30Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Contents */ Added drawHTML&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The namespace &amp;#039;&amp;#039;&amp;#039;3rd&amp;#039;&amp;#039;&amp;#039; is dedicated to descriptions of 3rd party packages, add-on&amp;#039;s, applications, etc, which are available to fellow programmers.&lt;br /&gt;
&lt;br /&gt;
Articles are in the &amp;#039;&amp;#039;&amp;#039;3rd&amp;#039;&amp;#039;&amp;#039; namespace if the title has this format: &amp;#039;&amp;#039;&amp;#039;3rd:&amp;lt;title&amp;gt;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
It is advantageous, if you give your package/add-on/... a &amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;, and then use &amp;#039;&amp;#039;&amp;#039;3rd:&amp;lt;name&amp;gt;&amp;#039;&amp;#039;&amp;#039; as article title.  (The name can have several words).&lt;br /&gt;
&lt;br /&gt;
Remember to write:&lt;br /&gt;
* How to obtain the package/add-on/...&lt;br /&gt;
* Which license conditions that applies&lt;br /&gt;
* Whether the package/add-on/... is free or not&lt;br /&gt;
&lt;br /&gt;
Also check-out http://www.arsaniit.com/prolog-tools&lt;br /&gt;
&lt;br /&gt;
=== Contents ===&lt;br /&gt;
&lt;br /&gt;
* [[3rd:QDBM|QDBM]] a key-&amp;gt;value database (GNU license).&lt;br /&gt;
* [[3rd:Scintilla Editor Control|Scintilla Editor Control]] custom control wraps the scintilla editor.&lt;br /&gt;
* [[3rd:SCS - Simple Client Server|SCS - Simple Client Server]] a package for creating client server solutions.&lt;br /&gt;
* [[3rd:VPcURL|VPcURL]] provides Visual Prolog bindings to the cURL library, which is a library for HTTP and FTP.&lt;br /&gt;
* [[3rd:Tools &amp;amp; Support|Tools &amp;amp; Support]] is an article about useful non-Visual Prolog tools and support sites.&lt;br /&gt;
* [[3rd:RS232|RS232]] packages for communicating via the RS232-interface of a computer.&lt;br /&gt;
* [[3rd:Fast Articifial Neural Networks (FANN)|Fast Articifial Neural Networks (FANN)]] bindings to the FANN library.&lt;br /&gt;
* [[3rd:VIC - VIP7 IDE companion|VIC - VIP7 IDE companion]] VIC provides 2 major tools, and a few little utilities, to help with the development of VIP7 projects.&lt;br /&gt;
* [[3rd:PROLEDIT|PROLEDIT]] A Simple Portable Editor&lt;br /&gt;
* [[3rd:HTML drawer|drawHTML]] A DLL written in VIP7.3 to draw and print HTML. i.e. it just draws nice text, but also has a callback to allow a menu functionality.&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=3rd:Tools_%26_Support&amp;diff=2446</id>
		<title>3rd:Tools &amp; Support</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=3rd:Tools_%26_Support&amp;diff=2446"/>
		<updated>2010-08-28T20:11:14Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Miscellaneous */ innoset&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Text Editors and Utilities ===&lt;br /&gt;
&lt;br /&gt;
* Powerful text editor (not free): [http://www.boxersoftware.com/ Boxer Text Editor]&lt;br /&gt;
* Free Text editor: [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++]&lt;br /&gt;
* Powerful editor: [http://www.textpad.com/ TextPad]&lt;br /&gt;
* Diff tool: [http://www.scootersoftware.com/ Beyond Compare]&lt;br /&gt;
* Regular Expressions tool: [http://www.ultrapico.com/Expresso.htm Expresso]&lt;br /&gt;
* Follow file changes while they happen: [http://tailforwin32.sourceforge.net/ Tail for Win32]&lt;br /&gt;
* Windows bug &amp;quot;File in use&amp;quot; - very useful [http://ccollomb.free.fr/unlocker/ Free File unlocker]&lt;br /&gt;
&lt;br /&gt;
=== Creating Help Files ===&lt;br /&gt;
&lt;br /&gt;
* CHM Editor : [http://visual-chm.wekasoft.downloadsoftware4free.com/ Visual CHM ] Cheap&lt;br /&gt;
* CHM Editor : [http://www.vizacc.com/downloads.aspx Visacc] Free.&lt;br /&gt;
* WYSIWYG HTML editor (Use Netscape &amp;#039;&amp;#039;&amp;#039;7.2&amp;#039;&amp;#039;&amp;#039;): [http://browser.netscape.com/downloads/archive/ Netscape Browser Archive] Free&lt;br /&gt;
* HTML editor: [http://www.pagebreeze.com/ PageBreeze] Cheap but good&lt;br /&gt;
&lt;br /&gt;
=== Microsoft Windows Support ===&lt;br /&gt;
&lt;br /&gt;
* Windows Problem Solving [http://winhlp.com/ Windows Problem Solver (winhlp.com)]&lt;br /&gt;
* Toolbox (free) [http://technet.microsoft.com/en-us/sysinternals/bb545027.aspx Sysinternals Utilities] (from [http://technet.microsoft.com Microsoft Technet]).  Notice especially:&lt;br /&gt;
** [http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx Process Explorer]&lt;br /&gt;
** [http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx Process Monitor]&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* Charting Tool: [http://www.pacestar.com/wizflow/index.html WizFlow]&lt;br /&gt;
* Easy Flash Editor (Swish Max2) : [http://www.swishzone.com/index.php SWiSHzone]&lt;br /&gt;
* BNF stuff : [http://www.garshol.priv.no/download/text/bnf.html BNF and EBNF] by &amp;#039;&amp;#039;Lars Marius Garshol&amp;#039;&amp;#039;&lt;br /&gt;
* BNF Stuff : [http://cui.unige.ch/db-research/Enseignement/analyseinfo/AboutBNF.html What is BNF notation?] by &amp;#039;&amp;#039;Th. Estier, CUI - University of Geneva&amp;#039;&amp;#039;&lt;br /&gt;
* Windows apps reviews : [http://www.winsupersite.com/reviews/ SuperSite Reviews] on &amp;#039;&amp;#039;Paul Thurrott&amp;#039;s SuperSite for Windows&amp;#039;&amp;#039;.&lt;br /&gt;
* Windows installer: [http://www.jrsoftware.org/isinfo.php INNOSET].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=3rd:Tools_%26_Support&amp;diff=2445</id>
		<title>3rd:Tools &amp; Support</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=3rd:Tools_%26_Support&amp;diff=2445"/>
		<updated>2010-08-28T20:07:29Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Miscellaneous */  add INNOTSET&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Text Editors and Utilities ===&lt;br /&gt;
&lt;br /&gt;
* Powerful text editor (not free): [http://www.boxersoftware.com/ Boxer Text Editor]&lt;br /&gt;
* Free Text editor: [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++]&lt;br /&gt;
* Powerful editor: [http://www.textpad.com/ TextPad]&lt;br /&gt;
* Diff tool: [http://www.scootersoftware.com/ Beyond Compare]&lt;br /&gt;
* Regular Expressions tool: [http://www.ultrapico.com/Expresso.htm Expresso]&lt;br /&gt;
* Follow file changes while they happen: [http://tailforwin32.sourceforge.net/ Tail for Win32]&lt;br /&gt;
* Windows bug &amp;quot;File in use&amp;quot; - very useful [http://ccollomb.free.fr/unlocker/ Free File unlocker]&lt;br /&gt;
&lt;br /&gt;
=== Creating Help Files ===&lt;br /&gt;
&lt;br /&gt;
* CHM Editor : [http://visual-chm.wekasoft.downloadsoftware4free.com/ Visual CHM ] Cheap&lt;br /&gt;
* CHM Editor : [http://www.vizacc.com/downloads.aspx Visacc] Free.&lt;br /&gt;
* WYSIWYG HTML editor (Use Netscape &amp;#039;&amp;#039;&amp;#039;7.2&amp;#039;&amp;#039;&amp;#039;): [http://browser.netscape.com/downloads/archive/ Netscape Browser Archive] Free&lt;br /&gt;
* HTML editor: [http://www.pagebreeze.com/ PageBreeze] Cheap but good&lt;br /&gt;
&lt;br /&gt;
=== Microsoft Windows Support ===&lt;br /&gt;
&lt;br /&gt;
* Windows Problem Solving [http://winhlp.com/ Windows Problem Solver (winhlp.com)]&lt;br /&gt;
* Toolbox (free) [http://technet.microsoft.com/en-us/sysinternals/bb545027.aspx Sysinternals Utilities] (from [http://technet.microsoft.com Microsoft Technet]).  Notice especially:&lt;br /&gt;
** [http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx Process Explorer]&lt;br /&gt;
** [http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx Process Monitor]&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* Charting Tool: [http://www.pacestar.com/wizflow/index.html WizFlow]&lt;br /&gt;
* Easy Flash Editor (Swish Max2) : [http://www.swishzone.com/index.php SWiSHzone]&lt;br /&gt;
* BNF stuff : [http://www.garshol.priv.no/download/text/bnf.html BNF and EBNF] by &amp;#039;&amp;#039;Lars Marius Garshol&amp;#039;&amp;#039;&lt;br /&gt;
* BNF Stuff : [http://cui.unige.ch/db-research/Enseignement/analyseinfo/AboutBNF.html What is BNF notation?] by &amp;#039;&amp;#039;Th. Estier, CUI - University of Geneva&amp;#039;&amp;#039;&lt;br /&gt;
* Windows apps reviews : [http://www.winsupersite.com/reviews/ SuperSite Reviews] on &amp;#039;&amp;#039;Paul Thurrott&amp;#039;s SuperSite for Windows&amp;#039;&amp;#039;.&lt;br /&gt;
* Windows installer: [http://www.jrsoftware.org/ INNOSET].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=3rd:Tools_%26_Support&amp;diff=2444</id>
		<title>3rd:Tools &amp; Support</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=3rd:Tools_%26_Support&amp;diff=2444"/>
		<updated>2010-08-25T10:15:18Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Text Editors and Utilities */ File unlocker&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Text Editors and Utilities ===&lt;br /&gt;
&lt;br /&gt;
* Powerful text editor (not free): [http://www.boxersoftware.com/ Boxer Text Editor]&lt;br /&gt;
* Free Text editor: [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++]&lt;br /&gt;
* Powerful editor: [http://www.textpad.com/ TextPad]&lt;br /&gt;
* Diff tool: [http://www.scootersoftware.com/ Beyond Compare]&lt;br /&gt;
* Regular Expressions tool: [http://www.ultrapico.com/Expresso.htm Expresso]&lt;br /&gt;
* Follow file changes while they happen: [http://tailforwin32.sourceforge.net/ Tail for Win32]&lt;br /&gt;
* Windows bug &amp;quot;File in use&amp;quot; - very useful [http://ccollomb.free.fr/unlocker/ Free File unlocker]&lt;br /&gt;
&lt;br /&gt;
=== Creating Help Files ===&lt;br /&gt;
&lt;br /&gt;
* CHM Editor : [http://visual-chm.wekasoft.downloadsoftware4free.com/ Visual CHM ] Cheap&lt;br /&gt;
* CHM Editor : [http://www.vizacc.com/downloads.aspx Visacc] Free.&lt;br /&gt;
* WYSIWYG HTML editor (Use Netscape &amp;#039;&amp;#039;&amp;#039;7.2&amp;#039;&amp;#039;&amp;#039;): [http://browser.netscape.com/downloads/archive/ Netscape Browser Archive] Free&lt;br /&gt;
* HTML editor: [http://www.pagebreeze.com/ PageBreeze] Cheap but good&lt;br /&gt;
&lt;br /&gt;
=== Microsoft Windows Support ===&lt;br /&gt;
&lt;br /&gt;
* Windows Problem Solving [http://winhlp.com/ Windows Problem Solver (winhlp.com)]&lt;br /&gt;
* Toolbox (free) [http://technet.microsoft.com/en-us/sysinternals/bb545027.aspx Sysinternals Utilities] (from [http://technet.microsoft.com Microsoft Technet]).  Notice especially:&lt;br /&gt;
** [http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx Process Explorer]&lt;br /&gt;
** [http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx Process Monitor]&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* Charting Tool: [http://www.pacestar.com/wizflow/index.html WizFlow]&lt;br /&gt;
* Easy Flash Editor (Swish Max2) : [http://www.swishzone.com/index.php SWiSHzone]&lt;br /&gt;
* BNF stuff : [http://www.garshol.priv.no/download/text/bnf.html BNF and EBNF] by &amp;#039;&amp;#039;Lars Marius Garshol&amp;#039;&amp;#039;&lt;br /&gt;
* BNF Stuff : [http://cui.unige.ch/db-research/Enseignement/analyseinfo/AboutBNF.html What is BNF notation?] by &amp;#039;&amp;#039;Th. Estier, CUI - University of Geneva&amp;#039;&amp;#039;&lt;br /&gt;
* Windows apps reviews : [http://www.winsupersite.com/reviews/ SuperSite Reviews] on &amp;#039;&amp;#039;Paul Thurrott&amp;#039;s SuperSite for Windows&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=2439</id>
		<title>VIP7 Construct examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=2439"/>
		<updated>2010-06-28T14:02:32Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: list::isMemberBy example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains a collection of basic examples for (mainly) the newer constructs found in VIP7.&lt;br /&gt;
&lt;br /&gt;
=== Fact variables ===&lt;br /&gt;
&lt;br /&gt;
Fact variables are the only mutable types in VIP.&lt;br /&gt;
&lt;br /&gt;
First, a reminder for ordinary facts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb_int : (integer).  % a nondeterministic fact (0 to any number of values)&lt;br /&gt;
    db_int : (integer,string) determ. % a deterministic fact (0 to 1 value)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These types of fact are asserted and retracted.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039; (fact variables)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    zz_int:integer := 0.&lt;br /&gt;
    zz_fred:integer := erroneous.&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    dom = dom(string,chaindb::ref).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    zz_dom : dom := erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        zz_int := 7,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;, zz_int), %will write &amp;quot;zz_int = 7&amp;quot;&lt;br /&gt;
        zz_int := zz_int+20,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;, zz_int), %will write &amp;quot;zz_int = 27&amp;quot;&lt;br /&gt;
        succeed.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fact variables are great for counting e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    how_many : () -&amp;gt; integer Count.&lt;br /&gt;
clauses&lt;br /&gt;
    how_many() = zz_int :-&lt;br /&gt;
        zz_int := 0,&lt;br /&gt;
        foreach some_nondeterm_fact_or_pred() do&lt;br /&gt;
            zz_int := zz_int+1&lt;br /&gt;
        end foreach.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
       stdio::write(&amp;quot;\n There are &amp;quot;, how_many(), &amp;quot; items&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lists - findall and list comprehension ===&lt;br /&gt;
&lt;br /&gt;
See [[Lists and Recursion]]&lt;br /&gt;
&amp;lt;vp&amp;gt;findall()&amp;lt;/vp&amp;gt; has been deprecated, so use the list comprehension construct.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb : (integer). %default is nondeterm for a fact&lt;br /&gt;
clauses&lt;br /&gt;
    ndb(1).&lt;br /&gt;
    ndb(2).&lt;br /&gt;
    ndb(3).&lt;br /&gt;
    ....&lt;br /&gt;
    ndb(10).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_old() :-&lt;br /&gt;
        findall(X,ndb(X),List).&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_new() :-&lt;br /&gt;
        List = [X||ndb(X)].&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X&amp;gt;6].&lt;br /&gt;
        %results in List = [7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0].&lt;br /&gt;
        %results in List = [2,4,6,8,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0, X&amp;lt;7].&lt;br /&gt;
        %results in List = [2,4,6]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        zz_int := 0,&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0, X&amp;lt;7, zz_int := zz_int+1].&lt;br /&gt;
        %results in List = [2,4,6] and zz_int = 3.&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), Y = pred2(X), Y&amp;gt;10].   %with pred2(X) = X^2.&lt;br /&gt;
        %results in List = [4,5,6,7,8,9,10]&lt;br /&gt;
        %reason - X = 3 gives Y = 9 which is &amp;lt; 10.&lt;br /&gt;
&lt;br /&gt;
    pred_other() :-&lt;br /&gt;
        L = [1,2,3,4,5,6,7,8,9,10],&lt;br /&gt;
        LIST = [ X || X = list::getMember_nd(L)].&lt;br /&gt;
        %results in List = L&lt;br /&gt;
&lt;br /&gt;
    pred_other() :-&lt;br /&gt;
        Primes = [X||X = std::fromto(1,300),&lt;br /&gt;
        L1 = [Y||Y = std::fromto(2,150)],&lt;br /&gt;
        tt(X,L1)].&lt;br /&gt;
        %results in List = prime numbers, with:&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
        tt : (integer,integer*) determ.&lt;br /&gt;
clauses&lt;br /&gt;
        tt(_X,[]) :- !.&lt;br /&gt;
        tt(X,[X|_]) :- !.&lt;br /&gt;
        tt(X,[Y|L]) :-&lt;br /&gt;
        X mod Y&amp;lt;&amp;gt;0,&lt;br /&gt;
        tt(X,L).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== if-then-else (code) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred(X,Y) = Z :-&lt;br /&gt;
        if X = 0 then&lt;br /&gt;
            Z = &amp;quot;x is zero&amp;quot;&lt;br /&gt;
        elseif X&amp;gt;0 then&lt;br /&gt;
            if pred3(Y) = true then&lt;br /&gt;
                Z = &amp;quot;x&amp;gt;0 and pred(Y) is true&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
                Z = &amp;quot;x&amp;gt;0 and pred(Y) is false&amp;quot;&lt;br /&gt;
            end if  %note, no comma here either&lt;br /&gt;
        else&lt;br /&gt;
            Z = &amp;quot;x &amp;lt;0&amp;quot;&lt;br /&gt;
        end if.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== #if #then #else (directive for conditional compilation) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;constants&lt;br /&gt;
    u64_con = 1.&lt;br /&gt;
    int_con = 2.&lt;br /&gt;
    real_con = 3.&lt;br /&gt;
&lt;br /&gt;
    compile_big_con = u64_con. %change this and then recompile.&lt;br /&gt;
&lt;br /&gt;
#if compile_big_con = u64_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : () -&amp;gt; unsigned64.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred() = U64 :-&lt;br /&gt;
            U64 = 78766.&lt;br /&gt;
&lt;br /&gt;
#elseif compile_big_con = int_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : () -&amp;gt; integer.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred() = Int :-&lt;br /&gt;
            Int = 20.&lt;br /&gt;
&lt;br /&gt;
#else&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : (real [out]).&lt;br /&gt;
    clauses&lt;br /&gt;
        pred(0.766).&lt;br /&gt;
&lt;br /&gt;
#endif&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Code construct uses     &amp;lt;vp&amp;gt;if  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;elseif  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;else&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;end if&amp;lt;/vp&amp;gt;&lt;br /&gt;
compiler directive uses &amp;lt;vp&amp;gt;#if - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#elseif - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#else&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#endif&amp;lt;/vp&amp;gt;&lt;br /&gt;
(just the &amp;quot;end if&amp;quot; is &amp;quot;different&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Trap and try/catch/finally ===&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Try-catch-finally|Try-catch-finally]]&lt;br /&gt;
Note, in [[Language Reference/Built-in entities/Predicates|Built-in entities/Predicates]]&lt;br /&gt;
suggests using &amp;lt;vp&amp;gt;try-end try&amp;lt;/vp&amp;gt; instead of &amp;lt;vp&amp;gt;trap(_,_,_)&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_all() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    call_pred_that_might_crash : (integer).&lt;br /&gt;
    call_own_exception_pred : (pointer ErrorNo).&lt;br /&gt;
    always_call_this_anyway : ().&lt;br /&gt;
clauses&lt;br /&gt;
    call_pred_that_might_crash(X) :-&lt;br /&gt;
        Y = 9/X.&lt;br /&gt;
&lt;br /&gt;
    call_own_exception_pred(ErrorNo) :-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;crashed&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
    always_call_this_anyway() :-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;finally reached&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% in this case, VIP will automatically pop up its exception dialog&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 4&amp;#039;&amp;#039;&amp;#039; - illegal - it must have a &amp;lt;vp&amp;gt;catch&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;finally&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_illegal() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Foreach ===&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Foreach|Foreach]]&lt;br /&gt;
&lt;br /&gt;
=== 64 bit numbers - history ===&lt;br /&gt;
&lt;br /&gt;
Up to VIP7.1, integer64 etc were defined as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    unsigned64 = unsigned64(unsigned32 Low, unsigned32 High).&lt;br /&gt;
    integer64 = integer64(unsigned32 Low, integer32 High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In VIP7.2 these have been renamed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    unsigned64_struct = unsigned64(unsigned Low, unsigned High).&lt;br /&gt;
    integer64_struct = integer64(unsigned Low, integer High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, for example, in VIP7.1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
     getFileProperties : (&lt;br /&gt;
        string FileName,&lt;br /&gt;
        fileSystem_api::fileAttributes Attributes,&lt;br /&gt;
        fileSystem_api::fileSize Size,&lt;br /&gt;
        core::gmtTimeValue Creation,&lt;br /&gt;
        core::gmtTimeValue LastAccess,&lt;br /&gt;
        core::gmtTimeValue LastChange)&lt;br /&gt;
        procedure (i,o,o,o,o,o).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if you needed use (and write) &amp;#039;&amp;#039;&amp;#039;fileSize&amp;#039;&amp;#039;&amp;#039; and times, you would have to have done some juggling (such as converting them to real numbers).&lt;br /&gt;
&lt;br /&gt;
To generate a 64 bit random number:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates %before VIP7.2&lt;br /&gt;
    gen64 : () -&amp;gt; unsigned64.&lt;br /&gt;
clauses&lt;br /&gt;
    gen64() = U64 :-&lt;br /&gt;
        N = 2^32,&lt;br /&gt;
        Low = math::random(N+0),&lt;br /&gt;
        High = math::random(N+0),&lt;br /&gt;
        U64 = unsigned64(Low,High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and possibly you would have needed (e.g.) &amp;#039;&amp;#039;&amp;#039;math::add&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    add : (core::unsigned64 Augend, core::unsigned64 Addend) -&amp;gt; core::unsigned64 Sum&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s now totally straightforward in VIP7.2 - just treat 64 bit numbers like any other number. You may also want these conversions - found in &amp;#039;&amp;#039;&amp;#039;core::&amp;#039;&amp;#039;&amp;#039; - for old code (this snippet is stolen from [http://discuss.visual-prolog.com/viewtopic.php?t=7927 Thomas&amp;#039; post])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    toUnsigned64 : (unsigned64_struct) -&amp;gt; unsigned64.&lt;br /&gt;
    fromUnsigned64 : (unsigned64) -&amp;gt; unsigned64_struct.&lt;br /&gt;
    toInteger64 : (integer64_struct) -&amp;gt; integer64.&lt;br /&gt;
    fromInteger64 : (integer64) -&amp;gt; integer64_struct.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And just for reference:&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#integer|integer]] range = -2^31 to +2^31-1 = -2147483648 .. 2147483647&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#unsigned|unsigned]]  range = 0 to (2^32)-1 = 4294967295&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#integer64|integer64]] range = -2^63 to 2^63&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#unsigned64|unsigned64]] range = 0 to (2^64)-1 = 18446744073709551615 ( = 1.844..E19)&lt;br /&gt;
&lt;br /&gt;
=== Polymorphic Domains ===&lt;br /&gt;
&lt;br /&gt;
See [[Objects and Polymorphism]]&lt;br /&gt;
&lt;br /&gt;
First, check out the definitions - &amp;lt;vp&amp;gt;core::tuple{}&amp;lt;/vp&amp;gt;. And while you&amp;#039;re there, just below, see &amp;lt;vp&amp;gt;core::predicate{}&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;core::function{}&amp;lt;/vp&amp;gt;, then followed by &amp;lt;vp&amp;gt;comparator{A}&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;list{A}&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The domains in class &amp;lt;vp&amp;gt;list::&amp;lt;/vp&amp;gt; are polymorphic, but you can define your own polymorphic domains. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    poly_dom{A,B} = poly_def(A,B).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you use it in your code, A and B can be any other domain.  The domain name is &amp;lt;vp&amp;gt;poly_dom{A,B}&amp;lt;/vp&amp;gt;, and you reference it you must use its whole name (not just &amp;lt;vp&amp;gt;poly_dom&amp;lt;/vp&amp;gt;) e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    joe{A,B} = poly_dom{A,B}*.&lt;br /&gt;
/* the next two lines are illegal&lt;br /&gt;
    poly_dom{A,B} = poly_def(A,B)*.&lt;br /&gt;
    poly_dom{A,A} = poly_def(A,A).&lt;br /&gt;
*/&lt;br /&gt;
    fred{A,B} = fred(poly_dom{A,B},integer).&lt;br /&gt;
&lt;br /&gt;
    maybe_silly_dom{A,B} =&lt;br /&gt;
        silly2(A,B);&lt;br /&gt;
        silly(A);&lt;br /&gt;
        pd(poly_dom{A,B});&lt;br /&gt;
        poly_dom(A,B);%IS NOT THE SAME POLY_DOM!! (notice no braces)&lt;br /&gt;
        s(string).&lt;br /&gt;
&lt;br /&gt;
    another{A} =&lt;br /&gt;
        i(integer);&lt;br /&gt;
        s(string);&lt;br /&gt;
        a(A);&lt;br /&gt;
        self(another({A}).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    zz_poly_dom:poly_dom{integer,integer} := erroneous.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_morphic_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        zz_poly_dom := poly_def(1,5),&lt;br /&gt;
        call_pd(zz_poly_dom),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        PD = poly_def(1,[&amp;quot;an example&amp;quot;,&amp;quot;or two&amp;quot;]),&lt;br /&gt;
        call_pd(PD),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        Q = [poly_def(X, Y) || X = std::fromTo(1, 4), Y = std::fromTo(1, 5)],&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,Q),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test().&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    call_pd : (poly_dom{A,B}).&lt;br /&gt;
clauses&lt;br /&gt;
    call_pd(POLY_DOM) :-&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,POLY_DOM),&lt;br /&gt;
        fail.&lt;br /&gt;
    call_pd(poly_def(A,B)) :- %note this is POLY_DEF&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,A,B),&lt;br /&gt;
        fail.&lt;br /&gt;
    call_pd(_).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Properties ===&lt;br /&gt;
&lt;br /&gt;
Properties in a class are used almost identically to fact variables, but properties can be set directly (from another class), without having to declare a public predicate to make the change.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface fred&lt;br /&gt;
    domains&lt;br /&gt;
        complete_dom = is_complete;&lt;br /&gt;
                     not_complete.&lt;br /&gt;
    properties&lt;br /&gt;
        prop_complete : complete_dom.&lt;br /&gt;
end interface fred&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;#039;&amp;#039;&amp;#039;fred.pro&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement fred&lt;br /&gt;
facts&lt;br /&gt;
    zz_complete:complete_dom := erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses %for the property&lt;br /&gt;
    prop_complete() = zz_complete. %get&lt;br /&gt;
    prop_complete(COMPLETE) :- zz_complete := COMPLETE. %set&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some other class that calls class fred:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;implement other&lt;br /&gt;
    open fred&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        Fred = fred::new(),&lt;br /&gt;
        Fred:prop_complete := is_complete,% to set the value&lt;br /&gt;
        Value = Fred:prop_complete, !. %get&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comparators and compare ===&lt;br /&gt;
&lt;br /&gt;
First, look at the definition of &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    comparator{T} = function{T, T, compareResult}.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;compareResult&amp;lt;/vp&amp;gt;&amp;#039;s definition can is found here: [[Language Reference/Built-in entities/Domains#compareResult|compareResult]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
    p_compare_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(7,2).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;greater()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
        %(because 7 &amp;gt; 2)&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(2,2).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;equal()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(&amp;quot;a&amp;quot;,&amp;quot;z&amp;quot;).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;less()&amp;#039;&amp;#039;&amp;#039;&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But you may wish to check your own domains to see which is &amp;quot;greater&amp;quot; - and of course you must define this yourself, by defining your own predicate as a &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Here is a simple domain in which only the integer parts of the variables are checked to see which is greater:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    s = s(string,integer).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    compare_it: core::comparator{s}.&lt;br /&gt;
clauses&lt;br /&gt;
    compare_it(A,B) = CompareResult :- %since this is a core::function(T,T,compareResult)&lt;br /&gt;
        A = s(_,I),&lt;br /&gt;
        B = s(_,J),&lt;br /&gt;
        if I&amp;lt;J then&lt;br /&gt;
            CompareResult = less()&lt;br /&gt;
        elseif I = J then&lt;br /&gt;
            CompareResult = equal()&lt;br /&gt;
        else&lt;br /&gt;
            CompareResult = greater()&lt;br /&gt;
        end if.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_compare_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        S1 = s(&amp;quot;abc&amp;quot;,7),&lt;br /&gt;
        S2 = s(&amp;quot;fred&amp;quot;,9),&lt;br /&gt;
        CompareResult = compare_it(S1,S2),&lt;br /&gt;
        %will give CompareResult = less, since 7&amp;lt;9.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...a bit pointless since the string part of the variables have been ignored, but it is easy to see how to expand &amp;lt;vp&amp;gt;compare_it()&amp;lt;/vp&amp;gt; to your own needs.&lt;br /&gt;
&lt;br /&gt;
=== list::sortby example using Comparator===&lt;br /&gt;
&lt;br /&gt;
list::sortby also uses Compareresult.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Say you have the following domain and fact:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	triple=triple(string,gmttimevalue,integer).&lt;br /&gt;
facts&lt;br /&gt;
	zz_triples:triple:=erroneous.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
zz_triples is populated, but it needs to be sorted by date/time. Then:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
	test():-&lt;br /&gt;
		zz_triples:=list::sortby(cp,zz_triples).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
	cp:core::comparator{triple}.&lt;br /&gt;
clauses&lt;br /&gt;
	cp(A,B)=CompareResult:-&lt;br /&gt;
		A=triple(_,ATv,_),&lt;br /&gt;
		B=triple(_,BTv,_),&lt;br /&gt;
		GMTA=gmttime::new(Atv),&lt;br /&gt;
		GMTB=gmttime::new(Btv),&lt;br /&gt;
		if GMTA:before(GMTB) then&lt;br /&gt;
			CompareResult=less&lt;br /&gt;
		else&lt;br /&gt;
			CompareResult=greater&lt;br /&gt;
		end if,!.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
	test():-&lt;br /&gt;
		zz_triples:=list::sortBy(&lt;br /&gt;
    			{(A,B)=CompareResult:-&lt;br /&gt;
				A=triple(_,ATv,_),&lt;br /&gt;
				B=triple(_,BTv,_),&lt;br /&gt;
				GMTA=gmttime::new(Atv),&lt;br /&gt;
				GMTB=gmttime::new(Btv),&lt;br /&gt;
				if GMTA:before(GMTB) then&lt;br /&gt;
					CompareResult=less&lt;br /&gt;
				else&lt;br /&gt;
					CompareResult=greater&lt;br /&gt;
				end if},&lt;br /&gt;
	           	zz_triples).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
=== list::isMemberBy example using Comparator===&lt;br /&gt;
&lt;br /&gt;
list::isMemberBy also uses Compareresult.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	intx=integer.&lt;br /&gt;
	some_struct=fred(integer*);point(pointer).&lt;br /&gt;
	dom=dom(intx,some_struct).&lt;br /&gt;
predicates&lt;br /&gt;
	test:().&lt;br /&gt;
clauses&lt;br /&gt;
	test():-&lt;br /&gt;
		Some_struct=fred([]),&lt;br /&gt;
		Dom1=dom(1,Some_struct),&lt;br /&gt;
		Dom2=dom(4,Some_struct),&lt;br /&gt;
		Dom3=dom(9,Some_struct),&lt;br /&gt;
		Dom4=dom(7,Some_struct),&lt;br /&gt;
		Doms=[Dom1,Dom2,Dom3,Dom4],&lt;br /&gt;
    		if list::isMemberBy(comp,4,Doms) then&lt;br /&gt;
    			stdio::write(&amp;quot;Dom(4,_) found&amp;quot;)&lt;br /&gt;
		else&lt;br /&gt;
			stdio::write(&amp;quot;Dom not found&amp;quot;)&lt;br /&gt;
		end if.&lt;br /&gt;
predicates&lt;br /&gt;
    comp:comparator{intx,dom}.&lt;br /&gt;
clauses&lt;br /&gt;
    comp(Intx,DOM)=equal:-&lt;br /&gt;
    	DOM=dom(Intx,_),!.&lt;br /&gt;
    comp(_,_)=greater.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
Also see&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms#Sorting http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms#Sorting]&lt;br /&gt;
&lt;br /&gt;
=== More on core::function and core::predicate ===&lt;br /&gt;
&lt;br /&gt;
Again, please check out &amp;lt;vp&amp;gt;core::function&amp;lt;/vp&amp;gt;.  &amp;lt;vp&amp;gt;core::predicate&amp;lt;/vp&amp;gt; is essentially the same, but does not return a value.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    two_times:function{integer,integer}.&lt;br /&gt;
% or    two_times: core::function{integer,integer}.&lt;br /&gt;
clauses&lt;br /&gt;
    two_times(A) = 2*A.&lt;br /&gt;
class predicates&lt;br /&gt;
    p_function : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_function() :-&lt;br /&gt;
        Z = two_times(2),&lt;br /&gt;
        %binds Z to 4&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    fred_dom{A,B} = predicate{A,B}.&lt;br /&gt;
% or    fred_dom{A,B} = core::predicate{A,B}.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    fred_pred: fred_dom{A,B}.&lt;br /&gt;
clauses&lt;br /&gt;
    fred_pred(A,B) :-&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,A,&amp;quot; &amp;quot;,B).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_pred : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_pred() :-&lt;br /&gt;
        fred_pred(&amp;quot;one&amp;quot;,2).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    add_func: function{integer,integer}.&lt;br /&gt;
clauses&lt;br /&gt;
    add_func(B) = B+1.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_function : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_function() :-&lt;br /&gt;
        X = add_func(5),&lt;br /&gt;
        %X is bound to 6&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Anonymous predicates ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;(under development)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Anonymous Predicates|Anonymous Predicates]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {() = 9},&lt;br /&gt;
        K = Anon().&lt;br /&gt;
        %results in K = 9&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = { = 88},&lt;br /&gt;
        K = Anon().&lt;br /&gt;
        %results in K = 88.&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {(A,B) = A+B},&lt;br /&gt;
        K = Anon(4,8),&lt;br /&gt;
        %results in K = 12.&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {&lt;br /&gt;
            (A,B) = C :-&lt;br /&gt;
            R = math::random(7),&lt;br /&gt;
            C = A+B+R,&lt;br /&gt;
            stdio::wRite(&amp;quot;RRRR = &amp;quot;,R)&lt;br /&gt;
            },&lt;br /&gt;
        K = Anon(4,8).&lt;br /&gt;
        %results in K = 12 + a random number &amp;lt;7&lt;br /&gt;
&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = { = f_abc(3)},&lt;br /&gt;
        K = Anon(),&lt;br /&gt;
        stdio::write(&amp;quot;\nI = { = f_abc(3)} gives &amp;quot;,K),&lt;br /&gt;
        fail.&lt;br /&gt;
    run().&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Threads ===&lt;br /&gt;
&lt;br /&gt;
To start a thread:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        _ = thread::start(fred).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred : ().&lt;br /&gt;
clauses&lt;br /&gt;
    fred() :- .....&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
fred can have no arguments, so no argument brackets are allowed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;    _ = thread::start(fred())&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is illegal. &lt;br /&gt;
&lt;br /&gt;
Using [[Language Reference/Terms/Anonymous Predicates|Anonymous Predicates]] is rather simple to pass arguments to thread:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred(X) :-&lt;br /&gt;
        _ = thread::start( { :- fred(X) } ).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred : (integer K).&lt;br /&gt;
clauses&lt;br /&gt;
    fred(K) :-&lt;br /&gt;
        ...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Examples]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2140</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2140"/>
		<updated>2010-02-16T18:35:23Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Basics */fix spelling mistake&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft provides a Speech API - SAPI - which covers both Speech Recognition and Speech Synthesis. Most of this page deals with Speech Recognition (SR). It is provided as a COM component, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2, and with a defined grammar. It is surprisingly accurate and responsive, even with a cheap microphone. Microsoft has produced SAPI recognizers for 4-5 languages including English. PDC has produced a SAPI recognizer for Danish: [http://www.pdc.dk/dk/dictus/ Dictus]. There may also be SAPI recognizers for other languages (but other than MS and PDC there don&amp;#039;t seem to be any).&lt;br /&gt;
&lt;br /&gt;
SAPI is the link between programs and Speech Recognition Engines, much like ODBC is the link between programs and SQL databases.&lt;br /&gt;
&lt;br /&gt;
Generally, the COM component is provided with Windows (but see below - [[#SAPI Availability]]).  With a copy of the DLL in your project folder, it&amp;#039;s easy to import it into your project. It is not necessary for it to be there at run time (i.e. there&amp;#039;s no need to distribute it with your app to end users).&lt;br /&gt;
&lt;br /&gt;
If you need it (see &amp;quot;availability&amp;quot; below) you can download the SDK here: [http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
*[http://msdn.microsoft.com/en-us/library/ee705648.aspx Microsoft Speech API (SAPI) 5.4 &amp;amp; 5.3]&lt;br /&gt;
&lt;br /&gt;
Also see:&lt;br /&gt;
*[[wikipedia:Microsoft Speech API]]&lt;br /&gt;
*[http://support.microsoft.com/kb/306901/ http://support.microsoft.com/kb/306901/]&lt;br /&gt;
*[http://support.microsoft.com/kb/306537/EN-US/ http://support.microsoft.com/kb/306537/EN-US/]&lt;br /&gt;
*[http://msdn.microsoft.com/en-us/library/ee431799 http://msdn.microsoft.com/en-us/library/ee431799] (good introduction)&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback predicate is called. You then extract what was spoken as a string_list, which you pass onto your own predicate to process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted?&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer.&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI SR works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SR isn&amp;#039;t great in this mode. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. Results are much better than in dictation mode. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; is expected as part of a rule.&lt;br /&gt;
&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
:&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
:&amp;lt;DICTATION&amp;gt; - for free-form dictation;&lt;br /&gt;
:&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
:&amp;lt;PHRASE&amp;gt; or &amp;lt;P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
:&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said (i.e optional);&lt;br /&gt;
:&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
:&amp;lt;WILDCARD&amp;gt; - to allow recognition of some phrases without failing due to irrelevant, or ignorable words;&lt;br /&gt;
:&amp;lt;RESOURCE&amp;gt; - to store arbitrary string	data on rules (e.g. for use by a CFG Interpreter);&lt;br /&gt;
:&amp;lt;TEXTBUFFER&amp;gt; - used for applications needing to integrate a dynamic text box or text selection with a voice command.&lt;br /&gt;
&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&lt;br /&gt;
&lt;br /&gt;
Only the &amp;lt;PHRASE&amp;gt; and &amp;lt;OPT&amp;gt; tags contain words/phrases that will be recognisable spoken words&lt;br /&gt;
&lt;br /&gt;
=== SAPI Availability/Versions ===&lt;br /&gt;
&lt;br /&gt;
*&amp;#039;&amp;#039;&amp;#039;Windows Vista and Windows 7:&amp;#039;&amp;#039;&amp;#039; SAPI 5.3 is part of Windows Vista and Windows 7, but it will only work for the languages that Microsoft supports (and Danish with PDC&amp;#039;s engine).&lt;br /&gt;
&lt;br /&gt;
*&amp;#039;&amp;#039;&amp;#039;Windows XP:&amp;#039;&amp;#039;&amp;#039; On XP you will get SAPI 5.1 with Office 2003 (but not 2007), and you can get it as part of the SDK download mentioned above. And you can get it as a installer merge module to merge into an installer you create yourself.&lt;br /&gt;
&lt;br /&gt;
*&amp;#039;&amp;#039;&amp;#039;Notes:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
** You cannot (do not!) install SAPI 5.1 on a Vista or Windows 7.&lt;br /&gt;
** A program that uses SAPI 5.1 can also (without any changes) use SAPI 5.3.&lt;br /&gt;
** The SAPI import provided by PDC is actually based on SAPI 5.3 (but it probably does not expose anything that is not also in 5.1). SAPI 5.3 is a conservative extension of SAPI 5.1. It&amp;#039;s forwards compatible: a program that works with 5.1 will also work with 5.3, but not necessarily the other way around.&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
Here are a few examples of grammars. These are the actual contents as would be stored in an XML file.&lt;br /&gt;
&lt;br /&gt;
* Example 1 - Recognises the word &amp;quot;hello&amp;quot; only.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
    &amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
    &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
    &amp;lt;/RULE&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Example 2 - All recognise the phrase &amp;quot;hello world&amp;quot;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&lt;br /&gt;
         &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Example 3 - Recognises the phrases &amp;quot;hello&amp;quot; and &amp;quot;hello world&amp;quot; (i.e &amp;quot;world&amp;quot; is optional)&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;O&amp;gt;world&amp;lt;/O&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Example 4 - Recognises &amp;quot;hello one two three&amp;quot;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;ref44&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;RULEREF NAME=&amp;quot;ref44&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;ref44&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;one&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;two&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;three&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;provide more examples&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Training ===&lt;br /&gt;
&lt;br /&gt;
Voice training is performed via the Windows Control Panel - Speech.&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2129</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2129"/>
		<updated>2010-01-29T12:12:15Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: removed section (replaced with reference)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft provides a Speech API - SAPI - which covers both Speech Recognition and Speech Synthesis. Most of this page deals with Speech Recognition (SR). It is provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2, and with a defined grammar. It is surprisingly accurate and responsive, even with a cheap microphone. Microsoft has produced SAPI recognizers for 4-5 languages including English. PDC has produced a SAPI recognizer for Danish:&lt;br /&gt;
[http://www.pdc.dk/dk/dictus/ Dictus]. There may also be SAPI recognizers for other languages (but other than MS and PDC there don&amp;#039;t seem to be any).&lt;br /&gt;
&lt;br /&gt;
SAPI is the link between programs and Speech Recognition Engines, much like ODBC is the link between programs and SQL databases.&lt;br /&gt;
&lt;br /&gt;
Generally, the COM/DLL is provided with Windows (but see below - &amp;quot;Availability&amp;quot;).  With a copy of the DLL in your project folder, it&amp;#039;s easy to import it into your project. It is not necessary for it to be there at run time (i.e. there&amp;#039;s no need to distribute it with your app to end users).&lt;br /&gt;
&lt;br /&gt;
If you need it (see &amp;quot;availability&amp;quot; below) you can download the SDK here:&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
*[http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
*[http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;Also see: &lt;br /&gt;
*[http://en.wikipedia.org/wiki/Microsoft_Speech_API http://en.wikipedia.org/wiki/Microsoft_Speech_API]&lt;br /&gt;
*[http://support.microsoft.com/kb/306901/ http://support.microsoft.com/kb/306901/]&lt;br /&gt;
*[http://support.microsoft.com/kb/306537/EN-US/ http://support.microsoft.com/kb/306537/EN-US/]&lt;br /&gt;
*[http://msdn.microsoft.com/en-us/library/ee431799 http://msdn.microsoft.com/en-us/library/ee431799] (good introduction)&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback predicate is called. You then extract what was spoken as a string_list, which you pass onto your own predicate to process. &amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted?&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI SR works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SR isn&amp;#039;t great in this mode. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. Results are much better than in dictation mode. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; is expected as part of a rule.&lt;br /&gt;
&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;DICTATION&amp;gt; - for free-form dictation;&lt;br /&gt;
&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
&amp;lt;PHRASE&amp;gt; or &amp;lt;P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said (i.e optional);&lt;br /&gt;
&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
&amp;lt;WILDCARD&amp;gt; - to allow recognition of some phrases without failing due to irrelevant, or ignorable words;&lt;br /&gt;
&amp;lt;RESOURCE&amp;gt; - to store arbitrary string	data on rules (e.g. for use by a CFG Interpreter);&lt;br /&gt;
&amp;lt;TEXTBUFFER&amp;gt; - used for applications needing to integrate a dynamic text box or text selection with a voice command.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only the &amp;lt;PHRASE&amp;gt; and &amp;lt;OPT&amp;gt; tags contain words/phrases that will be recognisable spoken words&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
=== SAPI.DLL Availability/Versions ===&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows Vista and Windows 7:&amp;lt;/b&amp;gt; SAPI 5.3 is part of Windows Vista and Windows 7, but it will only work for the languages that Microsoft supports (and Danish with PDC&amp;#039;s engine).&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows XP:&amp;lt;/b&amp;gt; On XP you will get SAPI 5.1 with Office 2003 (but not 2007), and you can get it as part of the SDK download mentioned above. And you can get it as a installer merge module to merge into an installer you create yourself.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Notes:&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
** You cannot (do not!) install SAPI 5.1 on a Vista or Windows 7.&amp;lt;br&amp;gt;&lt;br /&gt;
** A program that uses SAPI 5.1 can also (without any changes) use SAPI 5.3.&amp;lt;br&amp;gt;&lt;br /&gt;
** The SAPI import provided by PDC is actually based on SAPI 5.3 (but it probably does not expose anything that is not also in 5.1). SAPI 5.3 is a conservative extension of SAPI 5.1. It&amp;#039;s forwards compatible: a program that works with 5.1 will also work with 5.3, but not necessarily the other way around.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Here are a few examples of grammars. These are the actual contents as would be stored in an XML file.&lt;br /&gt;
&lt;br /&gt;
* Example 1 - Recognises the word &amp;quot;hello&amp;quot; only.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
   &amp;lt;/RULE&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 2 - All recognise the phrase &amp;quot;hello world&amp;quot;.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&lt;br /&gt;
         &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 3 - Recognises the phrases &amp;quot;hello&amp;quot; and &amp;quot;hello world&amp;quot; (i.e &amp;quot;world&amp;quot; is optional)&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;O&amp;gt;world&amp;lt;/O&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 4 - Recognises &amp;quot;hello one two three&amp;quot;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;ref44&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;RULEREF NAME=&amp;quot;ref44&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;ref44&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;one&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;two&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;three&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;provide more examples&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Training ===&lt;br /&gt;
&lt;br /&gt;
Voice training is performed via the Windows Control Panel - Speech.&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2128</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2128"/>
		<updated>2010-01-29T12:11:07Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Basics */ added ref&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft provides a Speech API - SAPI - which covers both Speech Recognition and Speech Synthesis. Most of this page deals with Speech Recognition (SR). It is provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2, and with a defined grammar. It is surprisingly accurate and responsive, even with a cheap microphone. Microsoft has produced SAPI recognizers for 4-5 languages including English. PDC has produced a SAPI recognizer for Danish:&lt;br /&gt;
[http://www.pdc.dk/dk/dictus/ Dictus]. There may also be SAPI recognizers for other languages (but other than MS and PDC there don&amp;#039;t seem to be any).&lt;br /&gt;
&lt;br /&gt;
SAPI is the link between programs and Speech Recognition Engines, much like ODBC is the link between programs and SQL databases.&lt;br /&gt;
&lt;br /&gt;
Generally, the COM/DLL is provided with Windows (but see below - &amp;quot;Availability&amp;quot;).  With a copy of the DLL in your project folder, it&amp;#039;s easy to import it into your project. It is not necessary for it to be there at run time (i.e. there&amp;#039;s no need to distribute it with your app to end users).&lt;br /&gt;
&lt;br /&gt;
If you need it (see &amp;quot;availability&amp;quot; below) you can download the SDK here:&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
*[http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
*[http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;Also see: &lt;br /&gt;
*[http://en.wikipedia.org/wiki/Microsoft_Speech_API http://en.wikipedia.org/wiki/Microsoft_Speech_API]&lt;br /&gt;
*[http://support.microsoft.com/kb/306901/ http://support.microsoft.com/kb/306901/]&lt;br /&gt;
*[http://support.microsoft.com/kb/306537/EN-US/ http://support.microsoft.com/kb/306537/EN-US/]&lt;br /&gt;
*[http://msdn.microsoft.com/en-us/library/ee431799 http://msdn.microsoft.com/en-us/library/ee431799] (good introduction)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback predicate is called. You then extract what was spoken as a string_list, which you pass onto your own predicate to process. &amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted?&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Extract from MS Speech SDK 5.1 Help File===&lt;br /&gt;
&amp;lt;i&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&lt;br /&gt;
The Microsoft Speech API (SAPI) is a software layer used by speech-enabled applications to communicate with Speech Recognition (SR) engines and Text-to-Speech (TTS) engines. SAPI includes an Application Programming Interface (API) and a Device Driver Interface (DDI). Applications communicate with SAPI using the API layer and speech engines communicate with SAPI using the DDI layer. &lt;br /&gt;
&lt;br /&gt;
A speech-enabled application and an SR engine do not directly communicate with each other – all communication is done using SAPI. SAPI controls a number of aspects of a speech system, such as:&lt;br /&gt;
*Controlling audio input, whether from a microphone, files, or a custom audio source; and converting audio data to a valid engine format.&lt;br /&gt;
*Loading grammar files, whether dynamically created or created from memory, URL or file; and resolving grammar imports and grammar editing.&lt;br /&gt;
*Compiling standard SAPI XML grammar format, and conversion of custom grammar formats, and parsing semantic tags in results.&lt;br /&gt;
*Sharing of recognition across multiple applications using the shared engine, as well as all marshaling between engine and applications.&lt;br /&gt;
*Returning results and other information back to the application and interacting with its message loop or other notification method. Using these methods, an engine can have a much simpler threading model than in SAPI 4, because SAPI 5 does much of the thread handling.&lt;br /&gt;
*Storing audio and serializing results for later analysis.&lt;br /&gt;
*Ensuring that applications do not cause errors – preventing applications from calling the engine with invalid parameters, and dealing with applications hanging or crashing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The SR engine performs the following tasks:&lt;br /&gt;
*Uses SAPI grammar interfaces and loads dictation.&lt;br /&gt;
*Performs recognition.&lt;br /&gt;
*Polls SAPI for information about grammar and state changes.&lt;br /&gt;
*Generates recognitions and other events to provide information to the application. &amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
The above text can also be found online, but is for SAPI5.4 :&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI SR works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SR isn&amp;#039;t great in this mode. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. Results are much better than in dictation mode. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; is expected as part of a rule.&lt;br /&gt;
&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;DICTATION&amp;gt; - for free-form dictation;&lt;br /&gt;
&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
&amp;lt;PHRASE&amp;gt; or &amp;lt;P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said (i.e optional);&lt;br /&gt;
&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
&amp;lt;WILDCARD&amp;gt; - to allow recognition of some phrases without failing due to irrelevant, or ignorable words;&lt;br /&gt;
&amp;lt;RESOURCE&amp;gt; - to store arbitrary string	data on rules (e.g. for use by a CFG Interpreter);&lt;br /&gt;
&amp;lt;TEXTBUFFER&amp;gt; - used for applications needing to integrate a dynamic text box or text selection with a voice command.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only the &amp;lt;PHRASE&amp;gt; and &amp;lt;OPT&amp;gt; tags contain words/phrases that will be recognisable spoken words&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
=== SAPI.DLL Availability/Versions ===&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows Vista and Windows 7:&amp;lt;/b&amp;gt; SAPI 5.3 is part of Windows Vista and Windows 7, but it will only work for the languages that Microsoft supports (and Danish with PDC&amp;#039;s engine).&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows XP:&amp;lt;/b&amp;gt; On XP you will get SAPI 5.1 with Office 2003 (but not 2007), and you can get it as part of the SDK download mentioned above. And you can get it as a installer merge module to merge into an installer you create yourself.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Notes:&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
** You cannot (do not!) install SAPI 5.1 on a Vista or Windows 7.&amp;lt;br&amp;gt;&lt;br /&gt;
** A program that uses SAPI 5.1 can also (without any changes) use SAPI 5.3.&amp;lt;br&amp;gt;&lt;br /&gt;
** The SAPI import provided by PDC is actually based on SAPI 5.3 (but it probably does not expose anything that is not also in 5.1). SAPI 5.3 is a conservative extension of SAPI 5.1. It&amp;#039;s forwards compatible: a program that works with 5.1 will also work with 5.3, but not necessarily the other way around.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Here are a few examples of grammars. These are the actual contents as would be stored in an XML file.&lt;br /&gt;
&lt;br /&gt;
* Example 1 - Recognises the word &amp;quot;hello&amp;quot; only.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
   &amp;lt;/RULE&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 2 - All recognise the phrase &amp;quot;hello world&amp;quot;.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&lt;br /&gt;
         &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 3 - Recognises the phrases &amp;quot;hello&amp;quot; and &amp;quot;hello world&amp;quot; (i.e &amp;quot;world&amp;quot; is optional)&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;O&amp;gt;world&amp;lt;/O&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 4 - Recognises &amp;quot;hello one two three&amp;quot;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;ref44&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;RULEREF NAME=&amp;quot;ref44&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;ref44&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;one&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;two&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;three&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;provide more examples&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Training ===&lt;br /&gt;
&lt;br /&gt;
Voice training is performed via the Windows Control Panel - Speech.&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2127</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2127"/>
		<updated>2010-01-29T12:09:47Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Extract from MS Speech SDK 5.1 Help File */ added ref&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft provides a Speech API - SAPI - which covers both Speech Recognition and Speech Synthesis. Most of this page deals with Speech Recognition (SR). It is provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2, and with a defined grammar. It is surprisingly accurate and responsive, even with a cheap microphone. Microsoft has produced SAPI recognizers for 4-5 languages including English. PDC has produced a SAPI recognizer for Danish:&lt;br /&gt;
[http://www.pdc.dk/dk/dictus/ Dictus]. There may also be SAPI recognizers for other languages (but other than MS and PDC there don&amp;#039;t seem to be any).&lt;br /&gt;
&lt;br /&gt;
SAPI is the link between programs and Speech Recognition Engines, much like ODBC is the link between programs and SQL databases.&lt;br /&gt;
&lt;br /&gt;
Generally, the COM/DLL is provided with Windows (but see below - &amp;quot;Availability&amp;quot;).  With a copy of the DLL in your project folder, it&amp;#039;s easy to import it into your project. It is not necessary for it to be there at run time (i.e. there&amp;#039;s no need to distribute it with your app to end users).&lt;br /&gt;
&lt;br /&gt;
If you need it (see &amp;quot;availability&amp;quot; below) you can download the SDK here:&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
*[http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
*[http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;Also see: &lt;br /&gt;
*[http://en.wikipedia.org/wiki/Microsoft_Speech_API http://en.wikipedia.org/wiki/Microsoft_Speech_API]&lt;br /&gt;
*[http://support.microsoft.com/kb/306901/ http://support.microsoft.com/kb/306901/]&lt;br /&gt;
*[http://support.microsoft.com/kb/306537/EN-US/ http://support.microsoft.com/kb/306537/EN-US/]&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback predicate is called. You then extract what was spoken as a string_list, which you pass onto your own predicate to process. &amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted?&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
=== Extract from MS Speech SDK 5.1 Help File===&lt;br /&gt;
&amp;lt;i&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&lt;br /&gt;
The Microsoft Speech API (SAPI) is a software layer used by speech-enabled applications to communicate with Speech Recognition (SR) engines and Text-to-Speech (TTS) engines. SAPI includes an Application Programming Interface (API) and a Device Driver Interface (DDI). Applications communicate with SAPI using the API layer and speech engines communicate with SAPI using the DDI layer. &lt;br /&gt;
&lt;br /&gt;
A speech-enabled application and an SR engine do not directly communicate with each other – all communication is done using SAPI. SAPI controls a number of aspects of a speech system, such as:&lt;br /&gt;
*Controlling audio input, whether from a microphone, files, or a custom audio source; and converting audio data to a valid engine format.&lt;br /&gt;
*Loading grammar files, whether dynamically created or created from memory, URL or file; and resolving grammar imports and grammar editing.&lt;br /&gt;
*Compiling standard SAPI XML grammar format, and conversion of custom grammar formats, and parsing semantic tags in results.&lt;br /&gt;
*Sharing of recognition across multiple applications using the shared engine, as well as all marshaling between engine and applications.&lt;br /&gt;
*Returning results and other information back to the application and interacting with its message loop or other notification method. Using these methods, an engine can have a much simpler threading model than in SAPI 4, because SAPI 5 does much of the thread handling.&lt;br /&gt;
*Storing audio and serializing results for later analysis.&lt;br /&gt;
*Ensuring that applications do not cause errors – preventing applications from calling the engine with invalid parameters, and dealing with applications hanging or crashing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The SR engine performs the following tasks:&lt;br /&gt;
*Uses SAPI grammar interfaces and loads dictation.&lt;br /&gt;
*Performs recognition.&lt;br /&gt;
*Polls SAPI for information about grammar and state changes.&lt;br /&gt;
*Generates recognitions and other events to provide information to the application. &amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
The above text can also be found online, but is for SAPI5.4 :&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI SR works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SR isn&amp;#039;t great in this mode. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. Results are much better than in dictation mode. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; is expected as part of a rule.&lt;br /&gt;
&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;DICTATION&amp;gt; - for free-form dictation;&lt;br /&gt;
&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
&amp;lt;PHRASE&amp;gt; or &amp;lt;P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said (i.e optional);&lt;br /&gt;
&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
&amp;lt;WILDCARD&amp;gt; - to allow recognition of some phrases without failing due to irrelevant, or ignorable words;&lt;br /&gt;
&amp;lt;RESOURCE&amp;gt; - to store arbitrary string	data on rules (e.g. for use by a CFG Interpreter);&lt;br /&gt;
&amp;lt;TEXTBUFFER&amp;gt; - used for applications needing to integrate a dynamic text box or text selection with a voice command.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only the &amp;lt;PHRASE&amp;gt; and &amp;lt;OPT&amp;gt; tags contain words/phrases that will be recognisable spoken words&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
=== SAPI.DLL Availability/Versions ===&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows Vista and Windows 7:&amp;lt;/b&amp;gt; SAPI 5.3 is part of Windows Vista and Windows 7, but it will only work for the languages that Microsoft supports (and Danish with PDC&amp;#039;s engine).&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows XP:&amp;lt;/b&amp;gt; On XP you will get SAPI 5.1 with Office 2003 (but not 2007), and you can get it as part of the SDK download mentioned above. And you can get it as a installer merge module to merge into an installer you create yourself.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Notes:&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
** You cannot (do not!) install SAPI 5.1 on a Vista or Windows 7.&amp;lt;br&amp;gt;&lt;br /&gt;
** A program that uses SAPI 5.1 can also (without any changes) use SAPI 5.3.&amp;lt;br&amp;gt;&lt;br /&gt;
** The SAPI import provided by PDC is actually based on SAPI 5.3 (but it probably does not expose anything that is not also in 5.1). SAPI 5.3 is a conservative extension of SAPI 5.1. It&amp;#039;s forwards compatible: a program that works with 5.1 will also work with 5.3, but not necessarily the other way around.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Here are a few examples of grammars. These are the actual contents as would be stored in an XML file.&lt;br /&gt;
&lt;br /&gt;
* Example 1 - Recognises the word &amp;quot;hello&amp;quot; only.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
   &amp;lt;/RULE&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 2 - All recognise the phrase &amp;quot;hello world&amp;quot;.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&lt;br /&gt;
         &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 3 - Recognises the phrases &amp;quot;hello&amp;quot; and &amp;quot;hello world&amp;quot; (i.e &amp;quot;world&amp;quot; is optional)&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;O&amp;gt;world&amp;lt;/O&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 4 - Recognises &amp;quot;hello one two three&amp;quot;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;ref44&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;RULEREF NAME=&amp;quot;ref44&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;ref44&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;one&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;two&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;three&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;provide more examples&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Training ===&lt;br /&gt;
&lt;br /&gt;
Voice training is performed via the Windows Control Panel - Speech.&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2126</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2126"/>
		<updated>2010-01-29T12:03:08Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: added MS SDK extract section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft provides a Speech API - SAPI - which covers both Speech Recognition and Speech Synthesis. Most of this page deals with Speech Recognition (SR). It is provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2, and with a defined grammar. It is surprisingly accurate and responsive, even with a cheap microphone. Microsoft has produced SAPI recognizers for 4-5 languages including English. PDC has produced a SAPI recognizer for Danish:&lt;br /&gt;
[http://www.pdc.dk/dk/dictus/ Dictus]. There may also be SAPI recognizers for other languages (but other than MS and PDC there don&amp;#039;t seem to be any).&lt;br /&gt;
&lt;br /&gt;
SAPI is the link between programs and Speech Recognition Engines, much like ODBC is the link between programs and SQL databases.&lt;br /&gt;
&lt;br /&gt;
Generally, the COM/DLL is provided with Windows (but see below - &amp;quot;Availability&amp;quot;).  With a copy of the DLL in your project folder, it&amp;#039;s easy to import it into your project. It is not necessary for it to be there at run time (i.e. there&amp;#039;s no need to distribute it with your app to end users).&lt;br /&gt;
&lt;br /&gt;
If you need it (see &amp;quot;availability&amp;quot; below) you can download the SDK here:&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
*[http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
*[http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;Also see: &lt;br /&gt;
*[http://en.wikipedia.org/wiki/Microsoft_Speech_API http://en.wikipedia.org/wiki/Microsoft_Speech_API]&lt;br /&gt;
*[http://support.microsoft.com/kb/306901/ http://support.microsoft.com/kb/306901/]&lt;br /&gt;
*[http://support.microsoft.com/kb/306537/EN-US/ http://support.microsoft.com/kb/306537/EN-US/]&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback predicate is called. You then extract what was spoken as a string_list, which you pass onto your own predicate to process. &amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted?&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
=== Extract from MS Speech SDK 5.1 Help File===&lt;br /&gt;
&amp;lt;i&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&lt;br /&gt;
The Microsoft Speech API (SAPI) is a software layer used by speech-enabled applications to communicate with Speech Recognition (SR) engines and Text-to-Speech (TTS) engines. SAPI includes an Application Programming Interface (API) and a Device Driver Interface (DDI). Applications communicate with SAPI using the API layer and speech engines communicate with SAPI using the DDI layer. &lt;br /&gt;
&lt;br /&gt;
A speech-enabled application and an SR engine do not directly communicate with each other – all communication is done using SAPI. SAPI controls a number of aspects of a speech system, such as:&lt;br /&gt;
*Controlling audio input, whether from a microphone, files, or a custom audio source; and converting audio data to a valid engine format.&lt;br /&gt;
*Loading grammar files, whether dynamically created or created from memory, URL or file; and resolving grammar imports and grammar editing.&lt;br /&gt;
*Compiling standard SAPI XML grammar format, and conversion of custom grammar formats, and parsing semantic tags in results.&lt;br /&gt;
*Sharing of recognition across multiple applications using the shared engine, as well as all marshaling between engine and applications.&lt;br /&gt;
*Returning results and other information back to the application and interacting with its message loop or other notification method. Using these methods, an engine can have a much simpler threading model than in SAPI 4, because SAPI 5 does much of the thread handling.&lt;br /&gt;
*Storing audio and serializing results for later analysis.&lt;br /&gt;
*Ensuring that applications do not cause errors – preventing applications from calling the engine with invalid parameters, and dealing with applications hanging or crashing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The SR engine performs the following tasks:&lt;br /&gt;
*Uses SAPI grammar interfaces and loads dictation.&lt;br /&gt;
*Performs recognition.&lt;br /&gt;
*Polls SAPI for information about grammar and state changes.&lt;br /&gt;
*Generates recognitions and other events to provide information to the application. &amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI SR works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SR isn&amp;#039;t great in this mode. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. Results are much better than in dictation mode. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; is expected as part of a rule.&lt;br /&gt;
&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;DICTATION&amp;gt; - for free-form dictation;&lt;br /&gt;
&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
&amp;lt;PHRASE&amp;gt; or &amp;lt;P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said (i.e optional);&lt;br /&gt;
&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
&amp;lt;WILDCARD&amp;gt; - to allow recognition of some phrases without failing due to irrelevant, or ignorable words;&lt;br /&gt;
&amp;lt;RESOURCE&amp;gt; - to store arbitrary string	data on rules (e.g. for use by a CFG Interpreter);&lt;br /&gt;
&amp;lt;TEXTBUFFER&amp;gt; - used for applications needing to integrate a dynamic text box or text selection with a voice command.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only the &amp;lt;PHRASE&amp;gt; and &amp;lt;OPT&amp;gt; tags contain words/phrases that will be recognisable spoken words&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
=== SAPI.DLL Availability/Versions ===&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows Vista and Windows 7:&amp;lt;/b&amp;gt; SAPI 5.3 is part of Windows Vista and Windows 7, but it will only work for the languages that Microsoft supports (and Danish with PDC&amp;#039;s engine).&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows XP:&amp;lt;/b&amp;gt; On XP you will get SAPI 5.1 with Office 2003 (but not 2007), and you can get it as part of the SDK download mentioned above. And you can get it as a installer merge module to merge into an installer you create yourself.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Notes:&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
** You cannot (do not!) install SAPI 5.1 on a Vista or Windows 7.&amp;lt;br&amp;gt;&lt;br /&gt;
** A program that uses SAPI 5.1 can also (without any changes) use SAPI 5.3.&amp;lt;br&amp;gt;&lt;br /&gt;
** The SAPI import provided by PDC is actually based on SAPI 5.3 (but it probably does not expose anything that is not also in 5.1). SAPI 5.3 is a conservative extension of SAPI 5.1. It&amp;#039;s forwards compatible: a program that works with 5.1 will also work with 5.3, but not necessarily the other way around.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Here are a few examples of grammars. These are the actual contents as would be stored in an XML file.&lt;br /&gt;
&lt;br /&gt;
* Example 1 - Recognises the word &amp;quot;hello&amp;quot; only.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
   &amp;lt;/RULE&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 2 - All recognise the phrase &amp;quot;hello world&amp;quot;.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&lt;br /&gt;
         &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 3 - Recognises the phrases &amp;quot;hello&amp;quot; and &amp;quot;hello world&amp;quot; (i.e &amp;quot;world&amp;quot; is optional)&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;O&amp;gt;world&amp;lt;/O&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 4 - Recognises &amp;quot;hello one two three&amp;quot;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;ref44&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;RULEREF NAME=&amp;quot;ref44&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;ref44&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;one&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;two&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;three&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;provide more examples&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Training ===&lt;br /&gt;
&lt;br /&gt;
Voice training is performed via the Windows Control Panel - Speech.&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2124</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2124"/>
		<updated>2010-01-25T13:22:44Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Basics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft provides a Speech API - SAPI - which covers both Speech Recognition and Speech Synthesis. Most of this page deals with Speech Recognition (SR). It is provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2, and with a defined grammar. It is surprisingly accurate and responsive, even with a cheap microphone. Microsoft has produced SAPI recognizers for 4-5 languages including English. PDC has produced a SAPI recognizer for Danish:&lt;br /&gt;
[http://www.pdc.dk/dk/dictus/ Dictus]. There may also be SAPI recognizers for other languages (but other than MS and PDC there don&amp;#039;t seem to be any).&lt;br /&gt;
&lt;br /&gt;
SAPI is the link between programs and Speech Recognition Engines, much like ODBC is the link between programs and SQL databases.&lt;br /&gt;
&lt;br /&gt;
Generally, the COM/DLL is provided with Windows (but see below - &amp;quot;Availability&amp;quot;).  With a copy of the DLL in your project folder, it&amp;#039;s easy to import it into your project. It is not necessary for it to be there at run time (i.e. there&amp;#039;s no need to distribute it with your app to end users).&lt;br /&gt;
&lt;br /&gt;
If you need it (see &amp;quot;availability&amp;quot; below) you can download the SDK here:&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;Also see: &lt;br /&gt;
*[http://en.wikipedia.org/wiki/Microsoft_Speech_API http://en.wikipedia.org/wiki/Microsoft_Speech_API]&lt;br /&gt;
*[http://support.microsoft.com/kb/306901/ http://support.microsoft.com/kb/306901/]&lt;br /&gt;
* [http://support.microsoft.com/kb/306537/EN-US/ http://support.microsoft.com/kb/306537/EN-US/]&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback predicate is called. You then extract what was spoken as a string_list, which you pass onto your own predicate to process. &amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted?&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI SR works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SR isn&amp;#039;t great in this mode. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. Results are much better than in dictation mode. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; is expected as part of a rule.&lt;br /&gt;
&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;DICTATION&amp;gt; - for free-form dictation;&lt;br /&gt;
&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
&amp;lt;PHRASE&amp;gt; or &amp;lt;P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said (i.e optional);&lt;br /&gt;
&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
&amp;lt;WILDCARD&amp;gt; - to allow recognition of some phrases without failing due to irrelevant, or ignorable words;&lt;br /&gt;
&amp;lt;RESOURCE&amp;gt; - to store arbitrary string	data on rules (e.g. for use by a CFG Interpreter);&lt;br /&gt;
&amp;lt;TEXTBUFFER&amp;gt; - used for applications needing to integrate a dynamic text box or text selection with a voice command.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only the &amp;lt;PHRASE&amp;gt; and &amp;lt;OPT&amp;gt; tags contain words/phrases that will be recognisable spoken words&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
=== SAPI.DLL Availability/Versions ===&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows Vista and Windows 7:&amp;lt;/b&amp;gt; SAPI 5.3 is part of Windows Vista and Windows 7, but it will only work for the languages that Microsoft supports (and Danish with PDC&amp;#039;s engine).&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows XP:&amp;lt;/b&amp;gt; On XP you will get SAPI 5.1 with Office 2003 (but not 2007), and you can get it as part of the SDK download mentioned above. And you can get it as a installer merge module to merge into an installer you create yourself.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Notes:&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
** You cannot (do not!) install SAPI 5.1 on a Vista or Windows 7.&amp;lt;br&amp;gt;&lt;br /&gt;
** A program that uses SAPI 5.1 can also (without any changes) use SAPI 5.3.&amp;lt;br&amp;gt;&lt;br /&gt;
** The SAPI import provided by PDC is actually based on SAPI 5.3 (but it probably does not expose anything that is not also in 5.1). SAPI 5.3 is a conservative extension of SAPI 5.1. It&amp;#039;s forwards compatible: a program that works with 5.1 will also work with 5.3, but not necessarily the other way around.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Here are a few examples of grammars. These are the actual contents as would be stored in an XML file.&lt;br /&gt;
&lt;br /&gt;
* Example 1 - Recognises the word &amp;quot;hello&amp;quot; only.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
   &amp;lt;/RULE&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 2 - All recognise the phrase &amp;quot;hello world&amp;quot;.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&lt;br /&gt;
         &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 3 - Recognises the phrases &amp;quot;hello&amp;quot; and &amp;quot;hello world&amp;quot; (i.e &amp;quot;world&amp;quot; is optional)&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;O&amp;gt;world&amp;lt;/O&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 4 - Recognises &amp;quot;hello one two three&amp;quot;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;ref44&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;RULEREF NAME=&amp;quot;ref44&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;ref44&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;one&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;two&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;three&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;provide more examples&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Training ===&lt;br /&gt;
&lt;br /&gt;
Voice training is performed via the Windows Control Panel - Speech.&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2123</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2123"/>
		<updated>2010-01-25T13:17:12Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: Added &amp;quot;training&amp;quot; section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft provides a Speech API - SAPI - which covers both Speech Recognition and Speech Synthesis. Most of this page deals with Speech Recognition (SR). It is provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2, and with a defined grammar. It is surprisingly accurate and responsive, even with a cheap microphone. Microsoft has produced SAPI recognizers for 4-5 languages including English. PDC has produced a SAPI recognizer for Danish:&lt;br /&gt;
[http://www.pdc.dk/dk/dictus/ Dictus]. There may also be SAPI recognizers for other languages (but other than MS and PDC there don&amp;#039;t seem to be any).&lt;br /&gt;
&lt;br /&gt;
SAPI is the link between programs and Speech Recognition Engines, much like ODBC is the link between programs and SQL databases.&lt;br /&gt;
&lt;br /&gt;
Generally, the COM/DLL is provided with Windows (but see below - &amp;quot;Availability&amp;quot;).  With a copy of the DLL in your project folder, it&amp;#039;s easy to import it into your project. It is not necessary for it to be there at run time (i.e. there&amp;#039;s no need to distribute it with your app to end users).&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;Also see: &lt;br /&gt;
*[http://en.wikipedia.org/wiki/Microsoft_Speech_API http://en.wikipedia.org/wiki/Microsoft_Speech_API]&lt;br /&gt;
*[http://support.microsoft.com/kb/306901/ http://support.microsoft.com/kb/306901/]&lt;br /&gt;
* [http://support.microsoft.com/kb/306537/EN-US/ http://support.microsoft.com/kb/306537/EN-US/]&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback predicate is called. You then extract what was spoken as a string_list, which you pass onto your own predicate to process. &amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted?&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI SR works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SR isn&amp;#039;t great in this mode. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. Results are much better than in dictation mode. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; is expected as part of a rule.&lt;br /&gt;
&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;DICTATION&amp;gt; - for free-form dictation;&lt;br /&gt;
&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
&amp;lt;PHRASE&amp;gt; or &amp;lt;P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said (i.e optional);&lt;br /&gt;
&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
&amp;lt;WILDCARD&amp;gt; - to allow recognition of some phrases without failing due to irrelevant, or ignorable words;&lt;br /&gt;
&amp;lt;RESOURCE&amp;gt; - to store arbitrary string	data on rules (e.g. for use by a CFG Interpreter);&lt;br /&gt;
&amp;lt;TEXTBUFFER&amp;gt; - used for applications needing to integrate a dynamic text box or text selection with a voice command.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only the &amp;lt;PHRASE&amp;gt; and &amp;lt;OPT&amp;gt; tags contain words/phrases that will be recognisable spoken words&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
=== SAPI.DLL Availability/Versions ===&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows Vista and Windows 7:&amp;lt;/b&amp;gt; SAPI 5.3 is part of Windows Vista and Windows 7, but it will only work for the languages that Microsoft supports (and Danish with PDC&amp;#039;s engine).&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows XP:&amp;lt;/b&amp;gt; On XP you will get SAPI 5.1 with Office 2003 (but not 2007), and you can get it as part of the SDK download mentioned above. And you can get it as a installer merge module to merge into an installer you create yourself.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Notes:&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
** You cannot (do not!) install SAPI 5.1 on a Vista or Windows 7.&amp;lt;br&amp;gt;&lt;br /&gt;
** A program that uses SAPI 5.1 can also (without any changes) use SAPI 5.3.&amp;lt;br&amp;gt;&lt;br /&gt;
** The SAPI import provided by PDC is actually based on SAPI 5.3 (but it probably does not expose anything that is not also in 5.1). SAPI 5.3 is a conservative extension of SAPI 5.1. It&amp;#039;s forwards compatible: a program that works with 5.1 will also work with 5.3, but not necessarily the other way around.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Here are a few examples of grammars. These are the actual contents as would be stored in an XML file.&lt;br /&gt;
&lt;br /&gt;
* Example 1 - Recognises the word &amp;quot;hello&amp;quot; only.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
   &amp;lt;/RULE&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 2 - All recognise the phrase &amp;quot;hello world&amp;quot;.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&lt;br /&gt;
         &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 3 - Recognises the phrases &amp;quot;hello&amp;quot; and &amp;quot;hello world&amp;quot; (i.e &amp;quot;world&amp;quot; is optional)&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;O&amp;gt;world&amp;lt;/O&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 4 - Recognises &amp;quot;hello one two three&amp;quot;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;ref44&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;RULEREF NAME=&amp;quot;ref44&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;ref44&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;one&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;two&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;three&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;provide more examples&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Training ===&lt;br /&gt;
&lt;br /&gt;
Voice training is performed via the Windows Control Panel - Speech.&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2122</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2122"/>
		<updated>2010-01-25T13:12:14Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Basics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft provides a Speech API - SAPI - which covers both Speech Recognition and Speech Synthesis. Most of this page deals with Speech Recognition (SR). It is provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2, and with a defined grammar. It is surprisingly accurate and responsive, even with a cheap microphone. Microsoft has produced SAPI recognizers for 4-5 languages including English. PDC has produced a SAPI recognizer for Danish:&lt;br /&gt;
[http://www.pdc.dk/dk/dictus/ Dictus]. There may also be SAPI recognizers for other languages (but other than MS and PDC there don&amp;#039;t seem to be any).&lt;br /&gt;
&lt;br /&gt;
SAPI is the link between programs and Speech Recognition Engines, much like ODBC is the link between programs and SQL databases.&lt;br /&gt;
&lt;br /&gt;
Generally, the COM/DLL is provided with Windows (but see below - &amp;quot;Availability&amp;quot;).  With a copy of the DLL in your project folder, it&amp;#039;s easy to import it into your project. It is not necessary for it to be there at run time (i.e. there&amp;#039;s no need to distribute it with your app to end users).&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;Also see: &lt;br /&gt;
*[http://en.wikipedia.org/wiki/Microsoft_Speech_API http://en.wikipedia.org/wiki/Microsoft_Speech_API]&lt;br /&gt;
*[http://support.microsoft.com/kb/306901/ http://support.microsoft.com/kb/306901/]&lt;br /&gt;
* [http://support.microsoft.com/kb/306537/EN-US/ http://support.microsoft.com/kb/306537/EN-US/]&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback predicate is called. You then extract what was spoken as a string_list, which you pass onto your own predicate to process. &amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted?&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI SR works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SR isn&amp;#039;t great in this mode. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. Results are much better than in dictation mode. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; is expected as part of a rule.&lt;br /&gt;
&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;DICTATION&amp;gt; - for free-form dictation;&lt;br /&gt;
&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
&amp;lt;PHRASE&amp;gt; or &amp;lt;P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said (i.e optional);&lt;br /&gt;
&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
&amp;lt;WILDCARD&amp;gt; - to allow recognition of some phrases without failing due to irrelevant, or ignorable words;&lt;br /&gt;
&amp;lt;RESOURCE&amp;gt; - to store arbitrary string	data on rules (e.g. for use by a CFG Interpreter);&lt;br /&gt;
&amp;lt;TEXTBUFFER&amp;gt; - used for applications needing to integrate a dynamic text box or text selection with a voice command.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only the &amp;lt;PHRASE&amp;gt; and &amp;lt;OPT&amp;gt; tags contain words/phrases that will be recognisable spoken words&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
=== SAPI.DLL Availability/Versions ===&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows Vista and Windows 7:&amp;lt;/b&amp;gt; SAPI 5.3 is part of Windows Vista and Windows 7, but it will only work for the languages that Microsoft supports (and Danish with PDC&amp;#039;s engine).&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows XP:&amp;lt;/b&amp;gt; On XP you will get SAPI 5.1 with Office 2003 (but not 2007), and you can get it as part of the SDK download mentioned above. And you can get it as a installer merge module to merge into an installer you create yourself.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Notes:&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
** You cannot (do not!) install SAPI 5.1 on a Vista or Windows 7.&amp;lt;br&amp;gt;&lt;br /&gt;
** A program that uses SAPI 5.1 can also (without any changes) use SAPI 5.3.&amp;lt;br&amp;gt;&lt;br /&gt;
** The SAPI import provided by PDC is actually based on SAPI 5.3 (but it probably does not expose anything that is not also in 5.1). SAPI 5.3 is a conservative extension of SAPI 5.1. It&amp;#039;s forwards compatible: a program that works with 5.1 will also work with 5.3, but not necessarily the other way around.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Here are a few examples of grammars. These are the actual contents as would be stored in an XML file.&lt;br /&gt;
&lt;br /&gt;
* Example 1 - Recognises the word &amp;quot;hello&amp;quot; only.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
   &amp;lt;/RULE&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 2 - All recognise the phrase &amp;quot;hello world&amp;quot;.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&lt;br /&gt;
         &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 3 - Recognises the phrases &amp;quot;hello&amp;quot; and &amp;quot;hello world&amp;quot; (i.e &amp;quot;world&amp;quot; is optional)&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;O&amp;gt;world&amp;lt;/O&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 4 - Recognises &amp;quot;hello one two three&amp;quot;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;ref44&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;RULEREF NAME=&amp;quot;ref44&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;ref44&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;one&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;two&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;three&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
* [[wikipedia:Microsoft Speech API]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2121</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2121"/>
		<updated>2010-01-25T13:08:50Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Basics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft provides a Speech API - SAPI - which covers both Speech Recognition and Speech Synthesis. Most of this page deals with Speech Recognition (SR). It is provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2, and with a defined grammar. It is surprisingly accurate and responsive, even with a cheap microphone. Microsoft has produced SAPI recognizers for 4-5 languages including English. PDC has produced a SAPI recognizer for Danish:&lt;br /&gt;
[http://www.pdc.dk/dk/dictus/ Dictus]. There may also be SAPI recognizers for other languages (but other than MS and PDC there don&amp;#039;t seem to be any).&lt;br /&gt;
&lt;br /&gt;
SAPI is the link between programs and Speech Recognition Engines, much like ODBC is the link between programs and SQL databases.&lt;br /&gt;
&lt;br /&gt;
Generally, the COM/DLL is provided with Windows (but see below - &amp;quot;Availability&amp;quot;).  With a copy of the DLL in your project folder, it&amp;#039;s easy to import it into your project. It is not necessary for it to be there at run time (i.e. there&amp;#039;s no need to distribute it with your app to end users).&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;Also see: &lt;br /&gt;
*[http://en.wikipedia.org/wiki/Microsoft_Speech_API http://en.wikipedia.org/wiki/Microsoft_Speech_API]&lt;br /&gt;
*[http://support.microsoft.com/kb/306901/ http://support.microsoft.com/kb/306901/]&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback predicate is called. You then extract what was spoken as a string_list, which you pass onto your own predicate to process. &amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted?&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI SR works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SR isn&amp;#039;t great in this mode. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. Results are much better than in dictation mode. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; is expected as part of a rule.&lt;br /&gt;
&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;DICTATION&amp;gt; - for free-form dictation;&lt;br /&gt;
&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
&amp;lt;PHRASE&amp;gt; or &amp;lt;P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said (i.e optional);&lt;br /&gt;
&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
&amp;lt;WILDCARD&amp;gt; - to allow recognition of some phrases without failing due to irrelevant, or ignorable words;&lt;br /&gt;
&amp;lt;RESOURCE&amp;gt; - to store arbitrary string	data on rules (e.g. for use by a CFG Interpreter);&lt;br /&gt;
&amp;lt;TEXTBUFFER&amp;gt; - used for applications needing to integrate a dynamic text box or text selection with a voice command.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only the &amp;lt;PHRASE&amp;gt; and &amp;lt;OPT&amp;gt; tags contain words/phrases that will be recognisable spoken words&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
=== SAPI.DLL Availability/Versions ===&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows Vista and Windows 7:&amp;lt;/b&amp;gt; SAPI 5.3 is part of Windows Vista and Windows 7, but it will only work for the languages that Microsoft supports (and Danish with PDC&amp;#039;s engine).&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows XP:&amp;lt;/b&amp;gt; On XP you will get SAPI 5.1 with Office 2003 (but not 2007), and you can get it as part of the SDK download mentioned above. And you can get it as a installer merge module to merge into an installer you create yourself.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Notes:&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
** You cannot (do not!) install SAPI 5.1 on a Vista or Windows 7.&amp;lt;br&amp;gt;&lt;br /&gt;
** A program that uses SAPI 5.1 can also (without any changes) use SAPI 5.3.&amp;lt;br&amp;gt;&lt;br /&gt;
** The SAPI import provided by PDC is actually based on SAPI 5.3 (but it probably does not expose anything that is not also in 5.1). SAPI 5.3 is a conservative extension of SAPI 5.1. It&amp;#039;s forwards compatible: a program that works with 5.1 will also work with 5.3, but not necessarily the other way around.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Here are a few examples of grammars. These are the actual contents as would be stored in an XML file.&lt;br /&gt;
&lt;br /&gt;
* Example 1 - Recognises the word &amp;quot;hello&amp;quot; only.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
   &amp;lt;/RULE&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 2 - All recognise the phrase &amp;quot;hello world&amp;quot;.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&lt;br /&gt;
         &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 3 - Recognises the phrases &amp;quot;hello&amp;quot; and &amp;quot;hello world&amp;quot; (i.e &amp;quot;world&amp;quot; is optional)&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;O&amp;gt;world&amp;lt;/O&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 4 - Recognises &amp;quot;hello one two three&amp;quot;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;ref44&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;RULEREF NAME=&amp;quot;ref44&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;ref44&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;one&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;two&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;three&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
* [[wikipedia:Microsoft Speech API]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2120</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2120"/>
		<updated>2010-01-25T12:19:53Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Basics */ added wiki link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft provides a Speech API - SAPI - which covers both Speech Recognition and Speech Synthesis. Most of this page deals with Speech Recognition (SR). It is provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2, and with a defined grammar. It is surprisingly accurate and responsive, even with a cheap microphone. Microsoft has produced SAPI recognizers for 4-5 languages including English. PDC has produced a SAPI recognizer for Danish:&lt;br /&gt;
[http://www.pdc.dk/dk/dictus/ Dictus]. There may also be SAPI recognizers for other languages (but other than MS and PDC there don&amp;#039;t seem to be any).&lt;br /&gt;
&lt;br /&gt;
SAPI is the link between programs and Speech Recognition Engines, much like ODBC is the link between programs and SQL databases.&lt;br /&gt;
&lt;br /&gt;
Generally, the COM/DLL is provided with Windows (but see below - &amp;quot;Availability&amp;quot;).  With a copy of the DLL in your project folder, it&amp;#039;s easy to import it into your project. It is not necessary for it to be there at run time (i.e. there&amp;#039;s no need to distribute it with your app to end users).&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;and &lt;br /&gt;
*[http://en.wikipedia.org/wiki/Microsoft_Speech_API http://en.wikipedia.org/wiki/Microsoft_Speech_API]&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback predicate is called. You then extract what was spoken as a string_list, which you pass onto your own predicate to process. &amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted?&amp;lt;BR&amp;gt;&lt;br /&gt;
Describe where the Speech Recognition Engine itself resides.&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI SR works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SR isn&amp;#039;t great in this mode. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. Results are much better than in dictation mode. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; is expected as part of a rule.&lt;br /&gt;
&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;DICTATION&amp;gt; - for free-form dictation;&lt;br /&gt;
&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
&amp;lt;PHRASE&amp;gt; or &amp;lt;P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said (i.e optional);&lt;br /&gt;
&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
&amp;lt;WILDCARD&amp;gt; - to allow recognition of some phrases without failing due to irrelevant, or ignorable words;&lt;br /&gt;
&amp;lt;RESOURCE&amp;gt; - to store arbitrary string	data on rules (e.g. for use by a CFG Interpreter);&lt;br /&gt;
&amp;lt;TEXTBUFFER&amp;gt; - used for applications needing to integrate a dynamic text box or text selection with a voice command.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only the &amp;lt;PHRASE&amp;gt; and &amp;lt;OPT&amp;gt; tags contain words/phrases that will be recognisable spoken words&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
=== SAPI.DLL Availability/Versions ===&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows Vista and Windows 7:&amp;lt;/b&amp;gt; SAPI 5.3 is part of Windows Vista and Windows 7, but it will only work for the languages that Microsoft supports (and Danish with PDC&amp;#039;s engine).&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows XP:&amp;lt;/b&amp;gt; On XP you will get SAPI 5.1 with Office 2003 (but not 2007), and you can get it as part of the SDK download mentioned above. And you can get it as a installer merge module to merge into an installer you create yourself.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Notes:&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
** You cannot (do not!) install SAPI 5.1 on a Vista or Windows 7.&amp;lt;br&amp;gt;&lt;br /&gt;
** A program that uses SAPI 5.1 can also (without any changes) use SAPI 5.3.&amp;lt;br&amp;gt;&lt;br /&gt;
** The SAPI import provided by PDC is actually based on SAPI 5.3 (but it probably does not expose anything that is not also in 5.1). SAPI 5.3 is a conservative extension of SAPI 5.1. It&amp;#039;s forwards compatible: a program that works with 5.1 will also work with 5.3, but not necessarily the other way around.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Here are a few examples of grammars. These are the actual contents as would be stored in an XML file.&lt;br /&gt;
&lt;br /&gt;
* Example 1 - Recognises the word &amp;quot;hello&amp;quot; only.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
   &amp;lt;/RULE&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 2 - All recognise the phrase &amp;quot;hello world&amp;quot;.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&lt;br /&gt;
         &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 3 - Recognises the phrases &amp;quot;hello&amp;quot; and &amp;quot;hello world&amp;quot; (i.e &amp;quot;world&amp;quot; is optional)&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;O&amp;gt;world&amp;lt;/O&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 4 - Recognises &amp;quot;hello one two three&amp;quot;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;ref44&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;RULEREF NAME=&amp;quot;ref44&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;ref44&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;one&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;two&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;three&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
* [[wikipedia:Microsoft Speech API]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2119</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2119"/>
		<updated>2010-01-24T22:26:26Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Dictation versus Commands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft provides a Speech API - SAPI - which covers both Speech Recognition and Speech Synthesis. Most of this page deals with Speech Recognition (SR). It is provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2, and with a defined grammar. It is surprisingly accurate and responsive, even with a cheap microphone. Microsoft has produced SAPI recognizers for 4-5 languages including English. PDC has produced a SAPI recognizer for Danish:&lt;br /&gt;
[http://www.pdc.dk/dk/dictus/ Dictus]. There may also be SAPI recognizers for other languages (but other than MS and PDC there don&amp;#039;t seem to be any).&lt;br /&gt;
&lt;br /&gt;
SAPI is the link between programs and Speech Recognition Engines, much like ODBC is the link between programs and SQL databases.&lt;br /&gt;
&lt;br /&gt;
Generally, the COM/DLL is provided with Windows (but see below - &amp;quot;Availability&amp;quot;).  With a copy of the DLL in your project folder, it&amp;#039;s easy to import it into your project. It is not necessary for it to be there at run time (i.e. there&amp;#039;s no need to distribute it with your app to end users).&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback predicate is called. You then extract what was spoken as a string_list, which you pass onto your own predicate to process. &amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted?&amp;lt;BR&amp;gt;&lt;br /&gt;
Describe where the Speech Recognition Engine itself resides.&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI SR works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SR isn&amp;#039;t great in this mode. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. Results are much better than in dictation mode. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; is expected as part of a rule.&lt;br /&gt;
&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;DICTATION&amp;gt; - for free-form dictation;&lt;br /&gt;
&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
&amp;lt;PHRASE&amp;gt; or &amp;lt;P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said (i.e optional);&lt;br /&gt;
&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
&amp;lt;WILDCARD&amp;gt; - to allow recognition of some phrases without failing due to irrelevant, or ignorable words;&lt;br /&gt;
&amp;lt;RESOURCE&amp;gt; - to store arbitrary string	data on rules (e.g. for use by a CFG Interpreter);&lt;br /&gt;
&amp;lt;TEXTBUFFER&amp;gt; - used for applications needing to integrate a dynamic text box or text selection with a voice command.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only the &amp;lt;PHRASE&amp;gt; and &amp;lt;OPT&amp;gt; tags contain words/phrases that will be recognisable spoken words&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
=== SAPI.DLL Availability/Versions ===&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows Vista and Windows 7:&amp;lt;/b&amp;gt; SAPI 5.3 is part of Windows Vista and Windows 7, but it will only work for the languages that Microsoft supports (and Danish with PDC&amp;#039;s engine).&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows XP:&amp;lt;/b&amp;gt; On XP you will get SAPI 5.1 with Office 2003 (but not 2007), and you can get it as part of the SDK download mentioned above. And you can get it as a installer merge module to merge into an installer you create yourself.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Notes:&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
** You cannot (do not!) install SAPI 5.1 on a Vista or Windows 7.&amp;lt;br&amp;gt;&lt;br /&gt;
** A program that uses SAPI 5.1 can also (without any changes) use SAPI 5.3.&amp;lt;br&amp;gt;&lt;br /&gt;
** The SAPI import provided by PDC is actually based on SAPI 5.3 (but it probably does not expose anything that is not also in 5.1). SAPI 5.3 is a conservative extension of SAPI 5.1. It&amp;#039;s forwards compatible: a program that works with 5.1 will also work with 5.3, but not necessarily the other way around.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Here are a few examples of grammars. These are the actual contents as would be stored in an XML file.&lt;br /&gt;
&lt;br /&gt;
* Example 1 - Recognises the word &amp;quot;hello&amp;quot; only.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
   &amp;lt;/RULE&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 2 - All recognise the phrase &amp;quot;hello world&amp;quot;.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&lt;br /&gt;
         &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 3 - Recognises the phrases &amp;quot;hello&amp;quot; and &amp;quot;hello world&amp;quot; (i.e &amp;quot;world&amp;quot; is optional)&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;O&amp;gt;world&amp;lt;/O&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 4 - Recognises &amp;quot;hello one two three&amp;quot;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;ref44&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;RULEREF NAME=&amp;quot;ref44&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;ref44&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;one&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;two&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;three&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
* [[wikipedia:Microsoft Speech API]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2118</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2118"/>
		<updated>2010-01-24T22:22:15Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Basics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft provides a Speech API - SAPI - which covers both Speech Recognition and Speech Synthesis. Most of this page deals with Speech Recognition (SR). It is provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2, and with a defined grammar. It is surprisingly accurate and responsive, even with a cheap microphone. Microsoft has produced SAPI recognizers for 4-5 languages including English. PDC has produced a SAPI recognizer for Danish:&lt;br /&gt;
[http://www.pdc.dk/dk/dictus/ Dictus]. There may also be SAPI recognizers for other languages (but other than MS and PDC there don&amp;#039;t seem to be any).&lt;br /&gt;
&lt;br /&gt;
SAPI is the link between programs and Speech Recognition Engines, much like ODBC is the link between programs and SQL databases.&lt;br /&gt;
&lt;br /&gt;
Generally, the COM/DLL is provided with Windows (but see below - &amp;quot;Availability&amp;quot;).  With a copy of the DLL in your project folder, it&amp;#039;s easy to import it into your project. It is not necessary for it to be there at run time (i.e. there&amp;#039;s no need to distribute it with your app to end users).&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback predicate is called. You then extract what was spoken as a string_list, which you pass onto your own predicate to process. &amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted?&amp;lt;BR&amp;gt;&lt;br /&gt;
Describe where the Speech Recognition Engine itself resides.&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI SR works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SAPI does a reasonable job. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; (free form) is expected. Results for dictation, however, aren&amp;#039;t great. Providing a grammar gives good results.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;DICTATION&amp;gt; - for free-form dictation;&lt;br /&gt;
&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
&amp;lt;PHRASE&amp;gt; or &amp;lt;P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said (i.e optional);&lt;br /&gt;
&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
&amp;lt;WILDCARD&amp;gt; - to allow recognition of some phrases without failing due to irrelevant, or ignorable words;&lt;br /&gt;
&amp;lt;RESOURCE&amp;gt; - to store arbitrary string	data on rules (e.g. for use by a CFG Interpreter);&lt;br /&gt;
&amp;lt;TEXTBUFFER&amp;gt; - used for applications needing to integrate a dynamic text box or text selection with a voice command.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only the &amp;lt;PHRASE&amp;gt; and &amp;lt;OPT&amp;gt; tags contain words/phrases that will be recognisable spoken words&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
=== SAPI.DLL Availability/Versions ===&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows Vista and Windows 7:&amp;lt;/b&amp;gt; SAPI 5.3 is part of Windows Vista and Windows 7, but it will only work for the languages that Microsoft supports (and Danish with PDC&amp;#039;s engine).&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows XP:&amp;lt;/b&amp;gt; On XP you will get SAPI 5.1 with Office 2003 (but not 2007), and you can get it as part of the SDK download mentioned above. And you can get it as a installer merge module to merge into an installer you create yourself.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Notes:&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
** You cannot (do not!) install SAPI 5.1 on a Vista or Windows 7.&amp;lt;br&amp;gt;&lt;br /&gt;
** A program that uses SAPI 5.1 can also (without any changes) use SAPI 5.3.&amp;lt;br&amp;gt;&lt;br /&gt;
** The SAPI import provided by PDC is actually based on SAPI 5.3 (but it probably does not expose anything that is not also in 5.1). SAPI 5.3 is a conservative extension of SAPI 5.1. It&amp;#039;s forwards compatible: a program that works with 5.1 will also work with 5.3, but not necessarily the other way around.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Here are a few examples of grammars. These are the actual contents as would be stored in an XML file.&lt;br /&gt;
&lt;br /&gt;
* Example 1 - Recognises the word &amp;quot;hello&amp;quot; only.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
   &amp;lt;/RULE&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 2 - All recognise the phrase &amp;quot;hello world&amp;quot;.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&lt;br /&gt;
         &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 3 - Recognises the phrases &amp;quot;hello&amp;quot; and &amp;quot;hello world&amp;quot; (i.e &amp;quot;world&amp;quot; is optional)&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;O&amp;gt;world&amp;lt;/O&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 4 - Recognises &amp;quot;hello one two three&amp;quot;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;ref44&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;RULEREF NAME=&amp;quot;ref44&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;ref44&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;one&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;two&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;three&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
* [[wikipedia:Microsoft Speech API]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2117</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2117"/>
		<updated>2010-01-24T22:17:49Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Dictation versus Commands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft provides a Speech API - SAPI - which covers both Speech Recognition and Speech Synthesis. It is provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2. It is surprisingly accurate and responsive, even with a cheap microphone. Microsoft has produced SAPI recognizers for 4-5 languages including English. PDC has produced a SAPI recognizer for Danish:&lt;br /&gt;
[http://www.pdc.dk/dk/dictus/ Dictus]. There may also be SAPI recognizers for other languages (but other than MS and PDC there don&amp;#039;t seem to be any).&lt;br /&gt;
&lt;br /&gt;
SAPI is the link between programs and Speech Recognition Engines, much like ODBC is the link between programs and SQL databases.&lt;br /&gt;
&lt;br /&gt;
Generally, the COM/DLL is provided with Windows (but see below - &amp;quot;Availability&amp;quot;).  With a copy of the DLL in your project folder, it&amp;#039;s easy to import it into your project. It is not necessary for it to be there at run time (i.e. there&amp;#039;s no need to distribute it with your app to end users).&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback predicate is called. You then extract what was spoken as a string_list, which you pass onto your own predicate to process. &amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted?&amp;lt;BR&amp;gt;&lt;br /&gt;
Describe where the Speech Recognition Engine itself resides.&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI SR works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SAPI does a reasonable job. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; (free form) is expected. Results for dictation, however, aren&amp;#039;t great. Providing a grammar gives good results.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;DICTATION&amp;gt; - for free-form dictation;&lt;br /&gt;
&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
&amp;lt;PHRASE&amp;gt; or &amp;lt;P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said (i.e optional);&lt;br /&gt;
&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
&amp;lt;WILDCARD&amp;gt; - to allow recognition of some phrases without failing due to irrelevant, or ignorable words;&lt;br /&gt;
&amp;lt;RESOURCE&amp;gt; - to store arbitrary string	data on rules (e.g. for use by a CFG Interpreter);&lt;br /&gt;
&amp;lt;TEXTBUFFER&amp;gt; - used for applications needing to integrate a dynamic text box or text selection with a voice command.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only the &amp;lt;PHRASE&amp;gt; and &amp;lt;OPT&amp;gt; tags contain words/phrases that will be recognisable spoken words&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
=== SAPI.DLL Availability/Versions ===&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows Vista and Windows 7:&amp;lt;/b&amp;gt; SAPI 5.3 is part of Windows Vista and Windows 7, but it will only work for the languages that Microsoft supports (and Danish with PDC&amp;#039;s engine).&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows XP:&amp;lt;/b&amp;gt; On XP you will get SAPI 5.1 with Office 2003 (but not 2007), and you can get it as part of the SDK download mentioned above. And you can get it as a installer merge module to merge into an installer you create yourself.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Notes:&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
** You cannot (do not!) install SAPI 5.1 on a Vista or Windows 7.&amp;lt;br&amp;gt;&lt;br /&gt;
** A program that uses SAPI 5.1 can also (without any changes) use SAPI 5.3.&amp;lt;br&amp;gt;&lt;br /&gt;
** The SAPI import provided by PDC is actually based on SAPI 5.3 (but it probably does not expose anything that is not also in 5.1). SAPI 5.3 is a conservative extension of SAPI 5.1. It&amp;#039;s forwards compatible: a program that works with 5.1 will also work with 5.3, but not necessarily the other way around.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Here are a few examples of grammars. These are the actual contents as would be stored in an XML file.&lt;br /&gt;
&lt;br /&gt;
* Example 1 - Recognises the word &amp;quot;hello&amp;quot; only.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
   &amp;lt;/RULE&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 2 - All recognise the phrase &amp;quot;hello world&amp;quot;.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&lt;br /&gt;
         &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 3 - Recognises the phrases &amp;quot;hello&amp;quot; and &amp;quot;hello world&amp;quot; (i.e &amp;quot;world&amp;quot; is optional)&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;O&amp;gt;world&amp;lt;/O&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 4 - Recognises &amp;quot;hello one two three&amp;quot;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;ref44&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;RULEREF NAME=&amp;quot;ref44&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;ref44&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;one&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;two&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;three&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
* [[wikipedia:Microsoft Speech API]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2116</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2116"/>
		<updated>2010-01-23T17:27:09Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Examples */  added some examples&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft provides a Speech API - SAPI - which covers both Speech Recognition and Speech Synthesis. It is provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2. It is surprisingly accurate and responsive, even with a cheap microphone. Microsoft has produced SAPI recognizers for 4-5 languages including English. PDC has produced a SAPI recognizer for Danish:&lt;br /&gt;
[http://www.pdc.dk/dk/dictus/ Dictus]. There may also be SAPI recognizers for other languages (but other than MS and PDC there don&amp;#039;t seem to be any).&lt;br /&gt;
&lt;br /&gt;
SAPI is the link between programs and Speech Recognition Engines, much like ODBC is the link between programs and SQL databases.&lt;br /&gt;
&lt;br /&gt;
Generally, the COM/DLL is provided with Windows (but see below - &amp;quot;Availability&amp;quot;).  With a copy of the DLL in your project folder, it&amp;#039;s easy to import it into your project. It is not necessary for it to be there at run time (i.e. there&amp;#039;s no need to distribute it with your app to end users).&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback predicate is called. You then extract what was spoken as a string_list, which you pass onto your own predicate to process. &amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted?&amp;lt;BR&amp;gt;&lt;br /&gt;
Describe where the Speech Recognition Engine itself resides.&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SAPI does a reasonable job. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; (free form) is expected.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;DICTATION&amp;gt; - for free-form dictation;&lt;br /&gt;
&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
&amp;lt;PHRASE&amp;gt; or &amp;lt;P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said (i.e optional);&lt;br /&gt;
&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
&amp;lt;WILDCARD&amp;gt; - to allow recognition of some phrases without failing due to irrelevant, or ignorable words;&lt;br /&gt;
&amp;lt;RESOURCE&amp;gt; - to store arbitrary string	data on rules (e.g. for use by a CFG Interpreter);&lt;br /&gt;
&amp;lt;TEXTBUFFER&amp;gt; - used for applications needing to integrate a dynamic text box or text selection with a voice command.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only the &amp;lt;PHRASE&amp;gt; and &amp;lt;OPT&amp;gt; tags contain words/phrases that will be recognisable spoken words&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
=== SAPI.DLL Availability/Versions ===&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows Vista and Windows 7:&amp;lt;/b&amp;gt; SAPI 5.3 is part of Windows Vista and Windows 7, but it will only work for the languages that Microsoft supports (and Danish with PDC&amp;#039;s engine).&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows XP:&amp;lt;/b&amp;gt; On XP you will get SAPI 5.1 with Office 2003 (but not 2007), and you can get it as part of the SDK download mentioned above. And you can get it as a installer merge module to merge into an installer you create yourself.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Notes:&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
** You cannot (do not!) install SAPI 5.1 on a Vista or Windows 7.&amp;lt;br&amp;gt;&lt;br /&gt;
** A program that uses SAPI 5.1 can also (without any changes) use SAPI 5.3.&amp;lt;br&amp;gt;&lt;br /&gt;
** The SAPI import provided by PDC is actually based on SAPI 5.3 (but it probably does not expose anything that is not also in 5.1). SAPI 5.3 is a conservative extension of SAPI 5.1. It&amp;#039;s forwards compatible: a program that works with 5.1 will also work with 5.3, but not necessarily the other way around.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Here are a few examples of grammars. These are the actual contents as would be stored in an XML file.&lt;br /&gt;
&lt;br /&gt;
* Example 1 - Recognises the word &amp;quot;hello&amp;quot; only.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
   &amp;lt;/RULE&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 2 - All recognise the phrase &amp;quot;hello world&amp;quot;.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello world&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&lt;br /&gt;
         &amp;lt;P&amp;gt;world&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 3 - Recognises the phrases &amp;quot;hello&amp;quot; and &amp;quot;hello world&amp;quot; (i.e &amp;quot;world&amp;quot; is optional)&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;O&amp;gt;world&amp;lt;/O&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
* Example 4 - Recognises &amp;quot;hello one two three&amp;quot;&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;DEFINE&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;ref44&amp;quot; VAL=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;ID NAME=&amp;quot;test&amp;quot; VAL=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/DEFINE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;test&amp;quot; TOPLEVEL=&amp;quot;ACTIVE&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;RULEREF NAME=&amp;quot;ref44&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
  &amp;lt;RULE NAME=&amp;quot;ref44&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;one&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;two&amp;lt;/P&amp;gt;&lt;br /&gt;
      &amp;lt;P&amp;gt;three&amp;lt;/P&amp;gt;&lt;br /&gt;
  &amp;lt;/RULE&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
* [[wikipedia:Microsoft Speech API]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2114</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2114"/>
		<updated>2010-01-23T07:22:00Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: Added &amp;quot;Availability/Versions&amp;quot; and Examples sections, plus tidy up&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft provides a Speech API - SAPI - which covers both Speech Recognition and Speech Synthesis. It is provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2. It is surprisingly accurate and responsive, even with a cheap microphone. Microsoft has produced SAPI recognizers for 4-5 languages including English. PDC has produced a SAPI recognizer for Danish:&lt;br /&gt;
[http://www.pdc.dk/dk/dictus/ Dictus]. There may also be SAPI recognizers for other languages (but other than MS and PDC there don&amp;#039;t seem to be any).&lt;br /&gt;
&lt;br /&gt;
SAPI is the link between programs and Speech Recognition Engines, much like ODBC is the link between programs and SQL databases.&lt;br /&gt;
&lt;br /&gt;
Generally, the COM/DLL is provided with Windows (but see below - &amp;quot;Availability&amp;quot;).  With a copy of the DLL in your project folder, it&amp;#039;s easy to import it into your project. It is not necessary for it to be there at run time (i.e. there&amp;#039;s no need to distribute it with your app to end users).&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback predicate is called. You then extract what was spoken as a string_list, which you pass onto your own predicate to process. &amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted?&amp;lt;BR&amp;gt;&lt;br /&gt;
Describe where the Speech Recognition Engine itself resides.&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SAPI does a reasonable job. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; (free form) is expected.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
&amp;lt;DICTATION&amp;gt; - for free-form dictation;&lt;br /&gt;
&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
&amp;lt;PHRASE&amp;gt; or &amp;lt;P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said (i.e optional);&lt;br /&gt;
&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
&amp;lt;WILDCARD&amp;gt; - to allow recognition of some phrases without failing due to irrelevant, or ignorable words;&lt;br /&gt;
&amp;lt;RESOURCE&amp;gt; - to store arbitrary string	data on rules (e.g. for use by a CFG Interpreter);&lt;br /&gt;
&amp;lt;TEXTBUFFER&amp;gt; - used for applications needing to integrate a dynamic text box or text selection with a voice command.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only the &amp;lt;PHRASE&amp;gt; and &amp;lt;OPT&amp;gt; tags contain words/phrases that will be recognisable spoken words&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
=== SAPI.DLL Availability/Versions ===&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows Vista and Windows 7:&amp;lt;/b&amp;gt; SAPI 5.3 is part of Windows Vista and Windows 7, but it will only work for the languages that Microsoft supports (and Danish with PDC&amp;#039;s engine).&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Windows XP:&amp;lt;/b&amp;gt; On XP you will get SAPI 5.1 with Office 2003 (but not 2007), and you can get it as part of the SDK download mentioned above. And you can get it as a installer merge module to merge into an installer you create yourself.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;b&amp;gt;Notes:&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
** You cannot (do not!) install SAPI 5.1 on a Vista or Windows 7.&amp;lt;br&amp;gt;&lt;br /&gt;
** A program that uses SAPI 5.1 can also (without any changes) use SAPI 5.3.&amp;lt;br&amp;gt;&lt;br /&gt;
** The SAPI import provided by PDC is actually based on SAPI 5.3 (but it probably does not expose anything that is not also in 5.1). SAPI 5.3 is a conservative extension of SAPI 5.1. It&amp;#039;s forwards compatible: a program that works with 5.1 will also work with 5.3, but not necessarily the other way around.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Here are a few examples of grammars. These are the actual contents stored in the XML file.&lt;br /&gt;
&lt;br /&gt;
# Example 1 - Recognises the word &amp;quot;hello&amp;quot; only.&lt;br /&gt;
&amp;lt;PRE&amp;gt;&lt;br /&gt;
&amp;lt;GRAMMAR&amp;gt;&lt;br /&gt;
   &amp;lt;RULE&amp;gt;&lt;br /&gt;
     &amp;lt;P&amp;gt;hello&amp;lt;/P&amp;gt;&lt;br /&gt;
   &amp;lt;/RULE&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/GRAMMAR&amp;gt;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
* [[wikipedia:Microsoft Speech API]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2113</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2113"/>
		<updated>2010-01-23T06:33:13Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Basics */ rewrite&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft provides a Speech API - SAPI - which covers both Speech Recognition and Speech Synthesis. It is provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2. It is surprisingly accurate and responsive, even with a cheap microphone. Microsoft has produced SAPI recognizers for 4-5 languages including English. PDC has produced a SAPI recognizer for Danish:&lt;br /&gt;
[http://www.pdc.dk/dk/dictus/ Dictus]. There may also be SAPI recognizers for other languages (but other than MS and PDC there don&amp;#039;t seem to be any).&lt;br /&gt;
&lt;br /&gt;
SAPI is the link between programs and Speech Recognition Engines, much like ODBC is the link between programs and SQL databases.&lt;br /&gt;
&lt;br /&gt;
Generally, the COM/DLL is provided with Windows (but see below - &amp;quot;Availability&amp;quot;).  With a copy of the DLL in your project folder, it&amp;#039;s easy to import it into your project. It is not necessary for it to be there at run time (i.e. there&amp;#039;s no need to distribute it with your app to end users).&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback predicate is called. You then extract what was spoken as a string_list, which you pass onto your own predicate to process. &amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted?&amp;lt;BR&amp;gt;&lt;br /&gt;
Describe where the Speech Recognition Engine itself resides.&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer,&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SAPI does a reasonable job. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; (free form) is expected.&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
*&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
*&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
*&amp;lt;DICTATION&amp;gt; - for free form dictation;&lt;br /&gt;
*&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
*&amp;lt;PHRASE&amp;gt; or {P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
*&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said;&lt;br /&gt;
*&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
*&amp;lt;WILDCARD&amp;gt; - &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&lt;br /&gt;
*&amp;lt;RESOURCE&amp;gt; - &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&lt;br /&gt;
*&amp;lt;TEXTBUFFER&amp;gt; - &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
* [[wikipedia:Microsoft Speech API]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=2110</id>
		<title>VIP7 Construct examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=2110"/>
		<updated>2010-01-20T13:37:13Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* list::sortby example using Comparator */ added link to language reference page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains a collection of basic examples for (mainly) the newer constructs found in VIP7.&lt;br /&gt;
&lt;br /&gt;
=== Fact variables ===&lt;br /&gt;
&lt;br /&gt;
Fact variables are the only mutable types in VIP.&lt;br /&gt;
&lt;br /&gt;
First, a reminder for ordinary facts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb_int : (integer).  % a nondeterministic fact (0 to any number of values)&lt;br /&gt;
    db_int : (integer,string) determ. % a deterministic fact (0 to 1 value)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These types of fact are asserted and retracted.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039; (fact variables)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    zz_int:integer := 0.&lt;br /&gt;
    zz_fred:integer := erroneous.&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    dom = dom(string,chaindb::ref).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    zz_dom : dom := erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        zz_int := 7,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;, zz_int), %will write &amp;quot;zz_int = 7&amp;quot;&lt;br /&gt;
        zz_int := zz_int+20,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;, zz_int), %will write &amp;quot;zz_int = 27&amp;quot;&lt;br /&gt;
        succeed.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fact variables are great for counting e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    how_many : () -&amp;gt; integer Count.&lt;br /&gt;
clauses&lt;br /&gt;
    how_many() = zz_int :-&lt;br /&gt;
        zz_int := 0,&lt;br /&gt;
        foreach some_nondeterm_fact_or_pred() do&lt;br /&gt;
            zz_int := zz_int+1&lt;br /&gt;
        end foreach.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
       stdio::write(&amp;quot;\n There are &amp;quot;, how_many(), &amp;quot; items&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lists - findall and list comprehension ===&lt;br /&gt;
&lt;br /&gt;
See [[Lists and Recursion]]&lt;br /&gt;
&amp;lt;vp&amp;gt;findall()&amp;lt;/vp&amp;gt; has been deprecated, so use the list comprehension construct.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb : (integer). %default is nondeterm for a fact&lt;br /&gt;
clauses&lt;br /&gt;
    ndb(1).&lt;br /&gt;
    ndb(2).&lt;br /&gt;
    ndb(3).&lt;br /&gt;
    ....&lt;br /&gt;
    ndb(10).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_old() :-&lt;br /&gt;
        findall(X,ndb(X),List).&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_new() :-&lt;br /&gt;
        List = [X||ndb(X)].&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X&amp;gt;6].&lt;br /&gt;
        %results in List = [7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0].&lt;br /&gt;
        %results in List = [2,4,6,8,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0, X&amp;lt;7].&lt;br /&gt;
        %results in List = [2,4,6]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        zz_int := 0,&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0, X&amp;lt;7, zz_int := zz_int+1].&lt;br /&gt;
        %results in List = [2,4,6] and zz_int = 3.&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), Y = pred2(X), Y&amp;gt;10].   %with pred2(X) = X^2.&lt;br /&gt;
        %results in List = [4,5,6,7,8,9,10]&lt;br /&gt;
        %reason - X = 3 gives Y = 9 which is &amp;lt; 10.&lt;br /&gt;
&lt;br /&gt;
    pred_other() :-&lt;br /&gt;
        L = [1,2,3,4,5,6,7,8,9,10],&lt;br /&gt;
        LIST = [ X || X = list::getMember_nd(L)].&lt;br /&gt;
        %results in List = L&lt;br /&gt;
&lt;br /&gt;
    pred_other() :-&lt;br /&gt;
        Primes = [X||X = std::fromto(1,300),&lt;br /&gt;
        L1 = [Y||Y = std::fromto(2,150)],&lt;br /&gt;
        tt(X,L1)].&lt;br /&gt;
        %results in List = prime numbers, with:&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
        tt : (integer,integer*) determ.&lt;br /&gt;
clauses&lt;br /&gt;
        tt(_X,[]) :- !.&lt;br /&gt;
        tt(X,[X|_]) :- !.&lt;br /&gt;
        tt(X,[Y|L]) :-&lt;br /&gt;
        X mod Y&amp;lt;&amp;gt;0,&lt;br /&gt;
        tt(X,L).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== if-then-else (code) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred(X,Y) = Z :-&lt;br /&gt;
        if X = 0 then&lt;br /&gt;
            Z = &amp;quot;x is zero&amp;quot;&lt;br /&gt;
        elseif X&amp;gt;0 then&lt;br /&gt;
            if pred3(Y) = true then&lt;br /&gt;
                Z = &amp;quot;x&amp;gt;0 and pred(Y) is true&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
                Z = &amp;quot;x&amp;gt;0 and pred(Y) is false&amp;quot;&lt;br /&gt;
            end if  %note, no comma here either&lt;br /&gt;
        else&lt;br /&gt;
            Z = &amp;quot;x &amp;lt;0&amp;quot;&lt;br /&gt;
        end if.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== #if #then #else (directive for conditional compilation) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;constants&lt;br /&gt;
    u64_con = 1.&lt;br /&gt;
    int_con = 2.&lt;br /&gt;
    real_con = 3.&lt;br /&gt;
&lt;br /&gt;
    compile_big_con = u64_con. %change this and then recompile.&lt;br /&gt;
&lt;br /&gt;
#if compile_big_con = u64_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : () -&amp;gt; unsigned64.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred() = U64 :-&lt;br /&gt;
            U64 = 78766.&lt;br /&gt;
&lt;br /&gt;
#elseif compile_big_con = int_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : () -&amp;gt; integer.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred() = Int :-&lt;br /&gt;
            Int = 20.&lt;br /&gt;
&lt;br /&gt;
#else&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : (real [out]).&lt;br /&gt;
    clauses&lt;br /&gt;
        pred(0.766).&lt;br /&gt;
&lt;br /&gt;
#endif&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Code construct uses     &amp;lt;vp&amp;gt;if  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;elseif  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;else&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;end if&amp;lt;/vp&amp;gt;&lt;br /&gt;
compiler directive uses &amp;lt;vp&amp;gt;#if - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#elseif - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#else&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#endif&amp;lt;/vp&amp;gt;&lt;br /&gt;
(just the &amp;quot;end if&amp;quot; is &amp;quot;different&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Trap and try/catch/finally ===&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Try-catch-finally|Try-catch-finally]]&lt;br /&gt;
Note, in [[Language Reference/Built-in entities/Predicates|Built-in entities/Predicates]]&lt;br /&gt;
suggests using &amp;lt;vp&amp;gt;try-end try&amp;lt;/vp&amp;gt; instead of &amp;lt;vp&amp;gt;trap(_,_,_)&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_all() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    call_pred_that_might_crash : (integer).&lt;br /&gt;
    call_own_exception_pred : (pointer ErrorNo).&lt;br /&gt;
    always_call_this_anyway : ().&lt;br /&gt;
clauses&lt;br /&gt;
    call_pred_that_might_crash(X) :-&lt;br /&gt;
        Y = 9/X.&lt;br /&gt;
&lt;br /&gt;
    call_own_exception_pred(ErrorNo) :-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;crashed&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
    always_call_this_anyway() :-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;finally reached&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% in this case, VIP will automatically pop up its exception dialog&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 4&amp;#039;&amp;#039;&amp;#039; - illegal - it must have a &amp;lt;vp&amp;gt;catch&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;finally&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_illegal() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Foreach ===&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Foreach|Foreach]]&lt;br /&gt;
&lt;br /&gt;
=== 64 bit numbers - history ===&lt;br /&gt;
&lt;br /&gt;
Up to VIP7.1, integer64 etc were defined as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    unsigned64 = unsigned64(unsigned32 Low, unsigned32 High).&lt;br /&gt;
    integer64 = integer64(unsigned32 Low, integer32 High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In VIP7.2 these have been renamed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    unsigned64_struct = unsigned64(unsigned Low, unsigned High).&lt;br /&gt;
    integer64_struct = integer64(unsigned Low, integer High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, for example, in VIP7.1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
     getFileProperties : (&lt;br /&gt;
        string FileName,&lt;br /&gt;
        fileSystem_api::fileAttributes Attributes,&lt;br /&gt;
        fileSystem_api::fileSize Size,&lt;br /&gt;
        core::gmtTimeValue Creation,&lt;br /&gt;
        core::gmtTimeValue LastAccess,&lt;br /&gt;
        core::gmtTimeValue LastChange)&lt;br /&gt;
        procedure (i,o,o,o,o,o).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if you needed use (and write) &amp;#039;&amp;#039;&amp;#039;fileSize&amp;#039;&amp;#039;&amp;#039; and times, you would have to have done some juggling (such as converting them to real numbers).&lt;br /&gt;
&lt;br /&gt;
To generate a 64 bit random number:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates %before VIP7.2&lt;br /&gt;
    gen64 : () -&amp;gt; unsigned64.&lt;br /&gt;
clauses&lt;br /&gt;
    gen64() = U64 :-&lt;br /&gt;
        N = 2^32,&lt;br /&gt;
        Low = math::random(N+0),&lt;br /&gt;
        High = math::random(N+0),&lt;br /&gt;
        U64 = unsigned64(Low,High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and possibly you would have needed (e.g.) &amp;#039;&amp;#039;&amp;#039;math::add&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    add : (core::unsigned64 Augend, core::unsigned64 Addend) -&amp;gt; core::unsigned64 Sum&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s now totally straightforward in VIP7.2 - just treat 64 bit numbers like any other number. You may also want these conversions - found in &amp;#039;&amp;#039;&amp;#039;core::&amp;#039;&amp;#039;&amp;#039; - for old code (this snippet is stolen from [http://discuss.visual-prolog.com/viewtopic.php?t=7927 Thomas&amp;#039; post])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    toUnsigned64 : (unsigned64_struct) -&amp;gt; unsigned64.&lt;br /&gt;
    fromUnsigned64 : (unsigned64) -&amp;gt; unsigned64_struct.&lt;br /&gt;
    toInteger64 : (integer64_struct) -&amp;gt; integer64.&lt;br /&gt;
    fromInteger64 : (integer64) -&amp;gt; integer64_struct.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And just for reference:&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#integer|integer]] range = -2^31 to +2^31-1 = -2147483648 .. 2147483647&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#unsigned|unsigned]]  range = 0 to (2^32)-1 = 4294967295&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#integer64|integer64]] range = -2^63 to 2^63&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#unsigned64|unsigned64]] range = 0 to (2^64)-1 = 18446744073709551615 ( = 1.844..E19)&lt;br /&gt;
&lt;br /&gt;
=== Polymorphic Domains ===&lt;br /&gt;
&lt;br /&gt;
See [[Objects and Polymorphism]]&lt;br /&gt;
&lt;br /&gt;
First, check out the definitions - &amp;lt;vp&amp;gt;core::tuple{}&amp;lt;/vp&amp;gt;. And while you&amp;#039;re there, just below, see &amp;lt;vp&amp;gt;core::predicate{}&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;core::function{}&amp;lt;/vp&amp;gt;, then followed by &amp;lt;vp&amp;gt;comparator{A}&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;list{A}&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The domains in class &amp;lt;vp&amp;gt;list::&amp;lt;/vp&amp;gt; are polymorphic, but you can define your own polymorphic domains. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    poly_dom{A,B} = poly_def(A,B).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you use it in your code, A and B can be any other domain.  The domain name is &amp;lt;vp&amp;gt;poly_dom{A,B}&amp;lt;/vp&amp;gt;, and you reference it you must use its whole name (not just &amp;lt;vp&amp;gt;poly_dom&amp;lt;/vp&amp;gt;) e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    joe{A,B} = poly_dom{A,B}*.&lt;br /&gt;
/* the next two lines are illegal&lt;br /&gt;
    poly_dom{A,B} = poly_def(A,B)*.&lt;br /&gt;
    poly_dom{A,A} = poly_def(A,A).&lt;br /&gt;
*/&lt;br /&gt;
    fred{A,B} = fred(poly_dom{A,B},integer).&lt;br /&gt;
&lt;br /&gt;
    maybe_silly_dom{A,B} =&lt;br /&gt;
        silly2(A,B);&lt;br /&gt;
        silly(A);&lt;br /&gt;
        pd(poly_dom{A,B});&lt;br /&gt;
        poly_dom(A,B);%IS NOT THE SAME POLY_DOM!! (notice no braces)&lt;br /&gt;
        s(string).&lt;br /&gt;
&lt;br /&gt;
    another{A} =&lt;br /&gt;
        i(integer);&lt;br /&gt;
        s(string);&lt;br /&gt;
        a(A);&lt;br /&gt;
        self(another({A}).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    zz_poly_dom:poly_dom{integer,integer} := erroneous.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_morphic_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        zz_poly_dom := poly_def(1,5),&lt;br /&gt;
        call_pd(zz_poly_dom),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        PD = poly_def(1,[&amp;quot;an example&amp;quot;,&amp;quot;or two&amp;quot;]),&lt;br /&gt;
        call_pd(PD),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        Q = [poly_def(X, Y) || X = std::fromTo(1, 4), Y = std::fromTo(1, 5)],&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,Q),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test().&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    call_pd : (poly_dom{A,B}).&lt;br /&gt;
clauses&lt;br /&gt;
    call_pd(POLY_DOM) :-&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,POLY_DOM),&lt;br /&gt;
        fail.&lt;br /&gt;
    call_pd(poly_def(A,B)) :- %note this is POLY_DEF&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,A,B),&lt;br /&gt;
        fail.&lt;br /&gt;
    call_pd(_).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Properties ===&lt;br /&gt;
&lt;br /&gt;
Properties in a class are used almost identically to fact variables, but properties can be set directly (from another class), without having to declare a public predicate to make the change.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface fred&lt;br /&gt;
    domains&lt;br /&gt;
        complete_dom = is_complete;&lt;br /&gt;
                     not_complete.&lt;br /&gt;
    properties&lt;br /&gt;
        prop_complete : complete_dom.&lt;br /&gt;
end interface fred&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;#039;&amp;#039;&amp;#039;fred.pro&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement fred&lt;br /&gt;
facts&lt;br /&gt;
    zz_complete:complete_dom := erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses %for the property&lt;br /&gt;
    prop_complete() = zz_complete. %get&lt;br /&gt;
    prop_complete(COMPLETE) :- zz_complete := COMPLETE. %set&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some other class that calls class fred:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;implement other&lt;br /&gt;
    open fred&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        Fred = fred::new(),&lt;br /&gt;
        Fred:prop_complete := is_complete,% to set the value&lt;br /&gt;
        Value = Fred:prop_complete, !. %get&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comparators and compare ===&lt;br /&gt;
&lt;br /&gt;
First, look at the definition of &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    comparator{T} = function{T, T, compareResult}.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;compareResult&amp;lt;/vp&amp;gt;&amp;#039;s definition can is found here: [[Language Reference/Built-in entities/Domains#compareResult|compareResult]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
    p_compare_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(7,2).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;greater()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
        %(because 7 &amp;gt; 2)&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(2,2).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;equal()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(&amp;quot;a&amp;quot;,&amp;quot;z&amp;quot;).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;less()&amp;#039;&amp;#039;&amp;#039;&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But you may wish to check your own domains to see which is &amp;quot;greater&amp;quot; - and of course you must define this yourself, by defining your own predicate as a &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Here is a simple domain in which only the integer parts of the variables are checked to see which is greater:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    s = s(string,integer).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    compare_it: core::comparator{s}.&lt;br /&gt;
clauses&lt;br /&gt;
    compare_it(A,B) = CompareResult :- %since this is a core::function(T,T,compareResult)&lt;br /&gt;
        A = s(_,I),&lt;br /&gt;
        B = s(_,J),&lt;br /&gt;
        if I&amp;lt;J then&lt;br /&gt;
            CompareResult = less()&lt;br /&gt;
        elseif I = J then&lt;br /&gt;
            CompareResult = equal()&lt;br /&gt;
        else&lt;br /&gt;
            CompareResult = greater()&lt;br /&gt;
        end if.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_compare_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        S1 = s(&amp;quot;abc&amp;quot;,7),&lt;br /&gt;
        S2 = s(&amp;quot;fred&amp;quot;,9),&lt;br /&gt;
        CompareResult = compare_it(S1,S2),&lt;br /&gt;
        %will give CompareResult = less, since 7&amp;lt;9.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...a bit pointless since the string part of the variables have been ignored, but it is easy to see how to expand &amp;lt;vp&amp;gt;compare_it()&amp;lt;/vp&amp;gt; to your own needs.&lt;br /&gt;
&lt;br /&gt;
=== list::sortby example using Comparator===&lt;br /&gt;
&lt;br /&gt;
list::sortby also uses Compareresult.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Say you have the following domain and fact:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	triple=triple(string,gmttimevalue,integer).&lt;br /&gt;
facts&lt;br /&gt;
	zz_triples:triple:=erroneous.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
zz_triples is populated, but it needs to be sorted by date/time. Then:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
	test():-&lt;br /&gt;
		zz_triples:=list::sortby(cp,zz_triples).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
	cp:core::comparator{triple}.&lt;br /&gt;
clauses&lt;br /&gt;
	cp(A,B)=CompareResult:-&lt;br /&gt;
		A=triple(_,ATv,_),&lt;br /&gt;
		B=triple(_,BTv,_),&lt;br /&gt;
		GMTA=gmttime::new(Atv),&lt;br /&gt;
		GMTB=gmttime::new(Btv),&lt;br /&gt;
		if GMTA:before(GMTB) then&lt;br /&gt;
			CompareResult=less&lt;br /&gt;
		else&lt;br /&gt;
			CompareResult=greater&lt;br /&gt;
		end if,!.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
	test():-&lt;br /&gt;
		zz_triples:=list::sortBy(&lt;br /&gt;
    			{(A,B)=CompareResult:-&lt;br /&gt;
				A=triple(_,ATv,_),&lt;br /&gt;
				B=triple(_,BTv,_),&lt;br /&gt;
				GMTA=gmttime::new(Atv),&lt;br /&gt;
				GMTB=gmttime::new(Btv),&lt;br /&gt;
				if GMTA:before(GMTB) then&lt;br /&gt;
					CompareResult=less&lt;br /&gt;
				else&lt;br /&gt;
					CompareResult=greater&lt;br /&gt;
				end if},&lt;br /&gt;
	           	zz_triples).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
Also see&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms#Sorting http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms#Sorting]&lt;br /&gt;
&lt;br /&gt;
=== More on core::function and core::predicate ===&lt;br /&gt;
&lt;br /&gt;
Again, please check out &amp;lt;vp&amp;gt;core::function&amp;lt;/vp&amp;gt;.  &amp;lt;vp&amp;gt;core::predicate&amp;lt;/vp&amp;gt; is essentially the same, but does not return a value.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    two_times:function{integer,integer}.&lt;br /&gt;
% or    two_times: core::function{integer,integer}.&lt;br /&gt;
clauses&lt;br /&gt;
    two_times(A) = 2*A.&lt;br /&gt;
class predicates&lt;br /&gt;
    p_function : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_function() :-&lt;br /&gt;
        Z = two_times(2),&lt;br /&gt;
        %binds Z to 4&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    fred_dom{A,B} = predicate{A,B}.&lt;br /&gt;
% or    fred_dom{A,B} = core::predicate{A,B}.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    fred_pred: fred_dom{A,B}.&lt;br /&gt;
clauses&lt;br /&gt;
    fred_pred(A,B) :-&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,A,&amp;quot; &amp;quot;,B).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_pred : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_pred() :-&lt;br /&gt;
        fred_pred(&amp;quot;one&amp;quot;,2).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    add_func: function{integer,integer}.&lt;br /&gt;
clauses&lt;br /&gt;
    add_func(B) = B+1.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_function : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_function() :-&lt;br /&gt;
        X = add_func(5),&lt;br /&gt;
        %X is bound to 6&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Anonymous predicates ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;(under development)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Anonymous Predicates|Anonymous Predicates]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {() = 9},&lt;br /&gt;
        K = Anon().&lt;br /&gt;
        %results in K = 9&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = { = 88},&lt;br /&gt;
        K = Anon().&lt;br /&gt;
        %results in K = 88.&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {(A,B) = A+B},&lt;br /&gt;
        K = Anon(4,8),&lt;br /&gt;
        %results in K = 12.&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {&lt;br /&gt;
            (A,B) = C :-&lt;br /&gt;
            R = math::random(7),&lt;br /&gt;
            C = A+B+R,&lt;br /&gt;
            stdio::wRite(&amp;quot;RRRR = &amp;quot;,R)&lt;br /&gt;
            },&lt;br /&gt;
        K = Anon(4,8).&lt;br /&gt;
        %results in K = 12 + a random number &amp;lt;7&lt;br /&gt;
&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = { = f_abc(3)},&lt;br /&gt;
        K = Anon(),&lt;br /&gt;
        stdio::write(&amp;quot;\nI = { = f_abc(3)} gives &amp;quot;,K),&lt;br /&gt;
        fail.&lt;br /&gt;
    run().&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Threads ===&lt;br /&gt;
&lt;br /&gt;
To start a thread:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        _ = thread::start(fred).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred : ().&lt;br /&gt;
clauses&lt;br /&gt;
    fred() :- .....&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
fred can have no arguments, so no argument brackets are allowed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;    _ = thread::start(fred())&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is illegal. &lt;br /&gt;
&lt;br /&gt;
Using [[Language Reference/Terms/Anonymous Predicates|Anonymous Predicates]] is rather simple to pass arguments to thread:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred(X) :-&lt;br /&gt;
        _ = thread::start( { :- fred(X) } ).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred : (integer K).&lt;br /&gt;
clauses&lt;br /&gt;
    fred(K) :-&lt;br /&gt;
        ...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Examples]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=2109</id>
		<title>VIP7 Construct examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=2109"/>
		<updated>2010-01-18T16:03:05Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* list::sortby example using Comparator */ extended format&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains a collection of basic examples for (mainly) the newer constructs found in VIP7.&lt;br /&gt;
&lt;br /&gt;
=== Fact variables ===&lt;br /&gt;
&lt;br /&gt;
Fact variables are the only mutable types in VIP.&lt;br /&gt;
&lt;br /&gt;
First, a reminder for ordinary facts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb_int : (integer).  % a nondeterministic fact (0 to any number of values)&lt;br /&gt;
    db_int : (integer,string) determ. % a deterministic fact (0 to 1 value)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These types of fact are asserted and retracted.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039; (fact variables)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    zz_int:integer := 0.&lt;br /&gt;
    zz_fred:integer := erroneous.&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    dom = dom(string,chaindb::ref).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    zz_dom : dom := erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        zz_int := 7,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;, zz_int), %will write &amp;quot;zz_int = 7&amp;quot;&lt;br /&gt;
        zz_int := zz_int+20,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;, zz_int), %will write &amp;quot;zz_int = 27&amp;quot;&lt;br /&gt;
        succeed.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fact variables are great for counting e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    how_many : () -&amp;gt; integer Count.&lt;br /&gt;
clauses&lt;br /&gt;
    how_many() = zz_int :-&lt;br /&gt;
        zz_int := 0,&lt;br /&gt;
        foreach some_nondeterm_fact_or_pred() do&lt;br /&gt;
            zz_int := zz_int+1&lt;br /&gt;
        end foreach.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
       stdio::write(&amp;quot;\n There are &amp;quot;, how_many(), &amp;quot; items&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lists - findall and list comprehension ===&lt;br /&gt;
&lt;br /&gt;
See [[Lists and Recursion]]&lt;br /&gt;
&amp;lt;vp&amp;gt;findall()&amp;lt;/vp&amp;gt; has been deprecated, so use the list comprehension construct.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb : (integer). %default is nondeterm for a fact&lt;br /&gt;
clauses&lt;br /&gt;
    ndb(1).&lt;br /&gt;
    ndb(2).&lt;br /&gt;
    ndb(3).&lt;br /&gt;
    ....&lt;br /&gt;
    ndb(10).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_old() :-&lt;br /&gt;
        findall(X,ndb(X),List).&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_new() :-&lt;br /&gt;
        List = [X||ndb(X)].&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X&amp;gt;6].&lt;br /&gt;
        %results in List = [7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0].&lt;br /&gt;
        %results in List = [2,4,6,8,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0, X&amp;lt;7].&lt;br /&gt;
        %results in List = [2,4,6]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        zz_int := 0,&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0, X&amp;lt;7, zz_int := zz_int+1].&lt;br /&gt;
        %results in List = [2,4,6] and zz_int = 3.&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), Y = pred2(X), Y&amp;gt;10].   %with pred2(X) = X^2.&lt;br /&gt;
        %results in List = [4,5,6,7,8,9,10]&lt;br /&gt;
        %reason - X = 3 gives Y = 9 which is &amp;lt; 10.&lt;br /&gt;
&lt;br /&gt;
    pred_other() :-&lt;br /&gt;
        L = [1,2,3,4,5,6,7,8,9,10],&lt;br /&gt;
        LIST = [ X || X = list::getMember_nd(L)].&lt;br /&gt;
        %results in List = L&lt;br /&gt;
&lt;br /&gt;
    pred_other() :-&lt;br /&gt;
        Primes = [X||X = std::fromto(1,300),&lt;br /&gt;
        L1 = [Y||Y = std::fromto(2,150)],&lt;br /&gt;
        tt(X,L1)].&lt;br /&gt;
        %results in List = prime numbers, with:&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
        tt : (integer,integer*) determ.&lt;br /&gt;
clauses&lt;br /&gt;
        tt(_X,[]) :- !.&lt;br /&gt;
        tt(X,[X|_]) :- !.&lt;br /&gt;
        tt(X,[Y|L]) :-&lt;br /&gt;
        X mod Y&amp;lt;&amp;gt;0,&lt;br /&gt;
        tt(X,L).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== if-then-else (code) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred(X,Y) = Z :-&lt;br /&gt;
        if X = 0 then&lt;br /&gt;
            Z = &amp;quot;x is zero&amp;quot;&lt;br /&gt;
        elseif X&amp;gt;0 then&lt;br /&gt;
            if pred3(Y) = true then&lt;br /&gt;
                Z = &amp;quot;x&amp;gt;0 and pred(Y) is true&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
                Z = &amp;quot;x&amp;gt;0 and pred(Y) is false&amp;quot;&lt;br /&gt;
            end if  %note, no comma here either&lt;br /&gt;
        else&lt;br /&gt;
            Z = &amp;quot;x &amp;lt;0&amp;quot;&lt;br /&gt;
        end if.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== #if #then #else (directive for conditional compilation) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;constants&lt;br /&gt;
    u64_con = 1.&lt;br /&gt;
    int_con = 2.&lt;br /&gt;
    real_con = 3.&lt;br /&gt;
&lt;br /&gt;
    compile_big_con = u64_con. %change this and then recompile.&lt;br /&gt;
&lt;br /&gt;
#if compile_big_con = u64_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : () -&amp;gt; unsigned64.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred() = U64 :-&lt;br /&gt;
            U64 = 78766.&lt;br /&gt;
&lt;br /&gt;
#elseif compile_big_con = int_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : () -&amp;gt; integer.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred() = Int :-&lt;br /&gt;
            Int = 20.&lt;br /&gt;
&lt;br /&gt;
#else&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : (real [out]).&lt;br /&gt;
    clauses&lt;br /&gt;
        pred(0.766).&lt;br /&gt;
&lt;br /&gt;
#endif&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Code construct uses     &amp;lt;vp&amp;gt;if  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;elseif  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;else&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;end if&amp;lt;/vp&amp;gt;&lt;br /&gt;
compiler directive uses &amp;lt;vp&amp;gt;#if - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#elseif - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#else&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#endif&amp;lt;/vp&amp;gt;&lt;br /&gt;
(just the &amp;quot;end if&amp;quot; is &amp;quot;different&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Trap and try/catch/finally ===&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Try-catch-finally|Try-catch-finally]]&lt;br /&gt;
Note, in [[Language Reference/Built-in entities/Predicates|Built-in entities/Predicates]]&lt;br /&gt;
suggests using &amp;lt;vp&amp;gt;try-end try&amp;lt;/vp&amp;gt; instead of &amp;lt;vp&amp;gt;trap(_,_,_)&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_all() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    call_pred_that_might_crash : (integer).&lt;br /&gt;
    call_own_exception_pred : (pointer ErrorNo).&lt;br /&gt;
    always_call_this_anyway : ().&lt;br /&gt;
clauses&lt;br /&gt;
    call_pred_that_might_crash(X) :-&lt;br /&gt;
        Y = 9/X.&lt;br /&gt;
&lt;br /&gt;
    call_own_exception_pred(ErrorNo) :-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;crashed&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
    always_call_this_anyway() :-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;finally reached&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% in this case, VIP will automatically pop up its exception dialog&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 4&amp;#039;&amp;#039;&amp;#039; - illegal - it must have a &amp;lt;vp&amp;gt;catch&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;finally&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_illegal() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Foreach ===&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Foreach|Foreach]]&lt;br /&gt;
&lt;br /&gt;
=== 64 bit numbers - history ===&lt;br /&gt;
&lt;br /&gt;
Up to VIP7.1, integer64 etc were defined as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    unsigned64 = unsigned64(unsigned32 Low, unsigned32 High).&lt;br /&gt;
    integer64 = integer64(unsigned32 Low, integer32 High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In VIP7.2 these have been renamed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    unsigned64_struct = unsigned64(unsigned Low, unsigned High).&lt;br /&gt;
    integer64_struct = integer64(unsigned Low, integer High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, for example, in VIP7.1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
     getFileProperties : (&lt;br /&gt;
        string FileName,&lt;br /&gt;
        fileSystem_api::fileAttributes Attributes,&lt;br /&gt;
        fileSystem_api::fileSize Size,&lt;br /&gt;
        core::gmtTimeValue Creation,&lt;br /&gt;
        core::gmtTimeValue LastAccess,&lt;br /&gt;
        core::gmtTimeValue LastChange)&lt;br /&gt;
        procedure (i,o,o,o,o,o).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if you needed use (and write) &amp;#039;&amp;#039;&amp;#039;fileSize&amp;#039;&amp;#039;&amp;#039; and times, you would have to have done some juggling (such as converting them to real numbers).&lt;br /&gt;
&lt;br /&gt;
To generate a 64 bit random number:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates %before VIP7.2&lt;br /&gt;
    gen64 : () -&amp;gt; unsigned64.&lt;br /&gt;
clauses&lt;br /&gt;
    gen64() = U64 :-&lt;br /&gt;
        N = 2^32,&lt;br /&gt;
        Low = math::random(N+0),&lt;br /&gt;
        High = math::random(N+0),&lt;br /&gt;
        U64 = unsigned64(Low,High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and possibly you would have needed (e.g.) &amp;#039;&amp;#039;&amp;#039;math::add&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    add : (core::unsigned64 Augend, core::unsigned64 Addend) -&amp;gt; core::unsigned64 Sum&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s now totally straightforward in VIP7.2 - just treat 64 bit numbers like any other number. You may also want these conversions - found in &amp;#039;&amp;#039;&amp;#039;core::&amp;#039;&amp;#039;&amp;#039; - for old code (this snippet is stolen from [http://discuss.visual-prolog.com/viewtopic.php?t=7927 Thomas&amp;#039; post])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    toUnsigned64 : (unsigned64_struct) -&amp;gt; unsigned64.&lt;br /&gt;
    fromUnsigned64 : (unsigned64) -&amp;gt; unsigned64_struct.&lt;br /&gt;
    toInteger64 : (integer64_struct) -&amp;gt; integer64.&lt;br /&gt;
    fromInteger64 : (integer64) -&amp;gt; integer64_struct.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And just for reference:&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#integer|integer]] range = -2^31 to +2^31-1 = -2147483648 .. 2147483647&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#unsigned|unsigned]]  range = 0 to (2^32)-1 = 4294967295&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#integer64|integer64]] range = -2^63 to 2^63&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#unsigned64|unsigned64]] range = 0 to (2^64)-1 = 18446744073709551615 ( = 1.844..E19)&lt;br /&gt;
&lt;br /&gt;
=== Polymorphic Domains ===&lt;br /&gt;
&lt;br /&gt;
See [[Objects and Polymorphism]]&lt;br /&gt;
&lt;br /&gt;
First, check out the definitions - &amp;lt;vp&amp;gt;core::tuple{}&amp;lt;/vp&amp;gt;. And while you&amp;#039;re there, just below, see &amp;lt;vp&amp;gt;core::predicate{}&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;core::function{}&amp;lt;/vp&amp;gt;, then followed by &amp;lt;vp&amp;gt;comparator{A}&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;list{A}&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The domains in class &amp;lt;vp&amp;gt;list::&amp;lt;/vp&amp;gt; are polymorphic, but you can define your own polymorphic domains. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    poly_dom{A,B} = poly_def(A,B).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you use it in your code, A and B can be any other domain.  The domain name is &amp;lt;vp&amp;gt;poly_dom{A,B}&amp;lt;/vp&amp;gt;, and you reference it you must use its whole name (not just &amp;lt;vp&amp;gt;poly_dom&amp;lt;/vp&amp;gt;) e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    joe{A,B} = poly_dom{A,B}*.&lt;br /&gt;
/* the next two lines are illegal&lt;br /&gt;
    poly_dom{A,B} = poly_def(A,B)*.&lt;br /&gt;
    poly_dom{A,A} = poly_def(A,A).&lt;br /&gt;
*/&lt;br /&gt;
    fred{A,B} = fred(poly_dom{A,B},integer).&lt;br /&gt;
&lt;br /&gt;
    maybe_silly_dom{A,B} =&lt;br /&gt;
        silly2(A,B);&lt;br /&gt;
        silly(A);&lt;br /&gt;
        pd(poly_dom{A,B});&lt;br /&gt;
        poly_dom(A,B);%IS NOT THE SAME POLY_DOM!! (notice no braces)&lt;br /&gt;
        s(string).&lt;br /&gt;
&lt;br /&gt;
    another{A} =&lt;br /&gt;
        i(integer);&lt;br /&gt;
        s(string);&lt;br /&gt;
        a(A);&lt;br /&gt;
        self(another({A}).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    zz_poly_dom:poly_dom{integer,integer} := erroneous.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_morphic_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        zz_poly_dom := poly_def(1,5),&lt;br /&gt;
        call_pd(zz_poly_dom),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        PD = poly_def(1,[&amp;quot;an example&amp;quot;,&amp;quot;or two&amp;quot;]),&lt;br /&gt;
        call_pd(PD),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        Q = [poly_def(X, Y) || X = std::fromTo(1, 4), Y = std::fromTo(1, 5)],&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,Q),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test().&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    call_pd : (poly_dom{A,B}).&lt;br /&gt;
clauses&lt;br /&gt;
    call_pd(POLY_DOM) :-&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,POLY_DOM),&lt;br /&gt;
        fail.&lt;br /&gt;
    call_pd(poly_def(A,B)) :- %note this is POLY_DEF&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,A,B),&lt;br /&gt;
        fail.&lt;br /&gt;
    call_pd(_).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Properties ===&lt;br /&gt;
&lt;br /&gt;
Properties in a class are used almost identically to fact variables, but properties can be set directly (from another class), without having to declare a public predicate to make the change.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface fred&lt;br /&gt;
    domains&lt;br /&gt;
        complete_dom = is_complete;&lt;br /&gt;
                     not_complete.&lt;br /&gt;
    properties&lt;br /&gt;
        prop_complete : complete_dom.&lt;br /&gt;
end interface fred&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;#039;&amp;#039;&amp;#039;fred.pro&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement fred&lt;br /&gt;
facts&lt;br /&gt;
    zz_complete:complete_dom := erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses %for the property&lt;br /&gt;
    prop_complete() = zz_complete. %get&lt;br /&gt;
    prop_complete(COMPLETE) :- zz_complete := COMPLETE. %set&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some other class that calls class fred:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;implement other&lt;br /&gt;
    open fred&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        Fred = fred::new(),&lt;br /&gt;
        Fred:prop_complete := is_complete,% to set the value&lt;br /&gt;
        Value = Fred:prop_complete, !. %get&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comparators and compare ===&lt;br /&gt;
&lt;br /&gt;
First, look at the definition of &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    comparator{T} = function{T, T, compareResult}.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;compareResult&amp;lt;/vp&amp;gt;&amp;#039;s definition can is found here: [[Language Reference/Built-in entities/Domains#compareResult|compareResult]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
    p_compare_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(7,2).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;greater()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
        %(because 7 &amp;gt; 2)&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(2,2).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;equal()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(&amp;quot;a&amp;quot;,&amp;quot;z&amp;quot;).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;less()&amp;#039;&amp;#039;&amp;#039;&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But you may wish to check your own domains to see which is &amp;quot;greater&amp;quot; - and of course you must define this yourself, by defining your own predicate as a &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Here is a simple domain in which only the integer parts of the variables are checked to see which is greater:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    s = s(string,integer).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    compare_it: core::comparator{s}.&lt;br /&gt;
clauses&lt;br /&gt;
    compare_it(A,B) = CompareResult :- %since this is a core::function(T,T,compareResult)&lt;br /&gt;
        A = s(_,I),&lt;br /&gt;
        B = s(_,J),&lt;br /&gt;
        if I&amp;lt;J then&lt;br /&gt;
            CompareResult = less()&lt;br /&gt;
        elseif I = J then&lt;br /&gt;
            CompareResult = equal()&lt;br /&gt;
        else&lt;br /&gt;
            CompareResult = greater()&lt;br /&gt;
        end if.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_compare_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        S1 = s(&amp;quot;abc&amp;quot;,7),&lt;br /&gt;
        S2 = s(&amp;quot;fred&amp;quot;,9),&lt;br /&gt;
        CompareResult = compare_it(S1,S2),&lt;br /&gt;
        %will give CompareResult = less, since 7&amp;lt;9.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...a bit pointless since the string part of the variables have been ignored, but it is easy to see how to expand &amp;lt;vp&amp;gt;compare_it()&amp;lt;/vp&amp;gt; to your own needs.&lt;br /&gt;
&lt;br /&gt;
=== list::sortby example using Comparator===&lt;br /&gt;
&lt;br /&gt;
list::sortby also uses Compareresult.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Say you have the following domain and fact:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	triple=triple(string,gmttimevalue,integer).&lt;br /&gt;
facts&lt;br /&gt;
	zz_triples:triple:=erroneous.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
zz_triples is populated, but it needs to be sorted by date/time. Then:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
	test():-&lt;br /&gt;
		zz_triples:=list::sortby(cp,zz_triples).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
	cp:core::comparator{triple}.&lt;br /&gt;
clauses&lt;br /&gt;
	cp(A,B)=CompareResult:-&lt;br /&gt;
		A=triple(_,ATv,_),&lt;br /&gt;
		B=triple(_,BTv,_),&lt;br /&gt;
		GMTA=gmttime::new(Atv),&lt;br /&gt;
		GMTB=gmttime::new(Btv),&lt;br /&gt;
		if GMTA:before(GMTB) then&lt;br /&gt;
			CompareResult=less&lt;br /&gt;
		else&lt;br /&gt;
			CompareResult=greater&lt;br /&gt;
		end if,!.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
	test():-&lt;br /&gt;
		zz_triples:=list::sortBy(&lt;br /&gt;
    			{(A,B)=CompareResult:-&lt;br /&gt;
				A=triple(_,ATv,_),&lt;br /&gt;
				B=triple(_,BTv,_),&lt;br /&gt;
				GMTA=gmttime::new(Atv),&lt;br /&gt;
				GMTB=gmttime::new(Btv),&lt;br /&gt;
				if GMTA:before(GMTB) then&lt;br /&gt;
					CompareResult=less&lt;br /&gt;
				else&lt;br /&gt;
					CompareResult=greater&lt;br /&gt;
				end if},&lt;br /&gt;
	           	zz_triples).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== More on core::function and core::predicate ===&lt;br /&gt;
&lt;br /&gt;
Again, please check out &amp;lt;vp&amp;gt;core::function&amp;lt;/vp&amp;gt;.  &amp;lt;vp&amp;gt;core::predicate&amp;lt;/vp&amp;gt; is essentially the same, but does not return a value.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    two_times:function{integer,integer}.&lt;br /&gt;
% or    two_times: core::function{integer,integer}.&lt;br /&gt;
clauses&lt;br /&gt;
    two_times(A) = 2*A.&lt;br /&gt;
class predicates&lt;br /&gt;
    p_function : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_function() :-&lt;br /&gt;
        Z = two_times(2),&lt;br /&gt;
        %binds Z to 4&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    fred_dom{A,B} = predicate{A,B}.&lt;br /&gt;
% or    fred_dom{A,B} = core::predicate{A,B}.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    fred_pred: fred_dom{A,B}.&lt;br /&gt;
clauses&lt;br /&gt;
    fred_pred(A,B) :-&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,A,&amp;quot; &amp;quot;,B).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_pred : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_pred() :-&lt;br /&gt;
        fred_pred(&amp;quot;one&amp;quot;,2).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    add_func: function{integer,integer}.&lt;br /&gt;
clauses&lt;br /&gt;
    add_func(B) = B+1.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_function : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_function() :-&lt;br /&gt;
        X = add_func(5),&lt;br /&gt;
        %X is bound to 6&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Anonymous predicates ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;(under development)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Anonymous Predicates|Anonymous Predicates]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {() = 9},&lt;br /&gt;
        K = Anon().&lt;br /&gt;
        %results in K = 9&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = { = 88},&lt;br /&gt;
        K = Anon().&lt;br /&gt;
        %results in K = 88.&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {(A,B) = A+B},&lt;br /&gt;
        K = Anon(4,8),&lt;br /&gt;
        %results in K = 12.&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {&lt;br /&gt;
            (A,B) = C :-&lt;br /&gt;
            R = math::random(7),&lt;br /&gt;
            C = A+B+R,&lt;br /&gt;
            stdio::wRite(&amp;quot;RRRR = &amp;quot;,R)&lt;br /&gt;
            },&lt;br /&gt;
        K = Anon(4,8).&lt;br /&gt;
        %results in K = 12 + a random number &amp;lt;7&lt;br /&gt;
&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = { = f_abc(3)},&lt;br /&gt;
        K = Anon(),&lt;br /&gt;
        stdio::write(&amp;quot;\nI = { = f_abc(3)} gives &amp;quot;,K),&lt;br /&gt;
        fail.&lt;br /&gt;
    run().&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Threads ===&lt;br /&gt;
&lt;br /&gt;
To start a thread:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        _ = thread::start(fred).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred : ().&lt;br /&gt;
clauses&lt;br /&gt;
    fred() :- .....&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
fred can have no arguments, so no argument brackets are allowed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;    _ = thread::start(fred())&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is illegal. &lt;br /&gt;
&lt;br /&gt;
Using [[Language Reference/Terms/Anonymous Predicates|Anonymous Predicates]] is rather simple to pass arguments to thread:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred(X) :-&lt;br /&gt;
        _ = thread::start( { :- fred(X) } ).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred : (integer K).&lt;br /&gt;
clauses&lt;br /&gt;
    fred(K) :-&lt;br /&gt;
        ...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Examples]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=2108</id>
		<title>VIP7 Construct examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=2108"/>
		<updated>2010-01-18T15:55:47Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: format list::sortby&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains a collection of basic examples for (mainly) the newer constructs found in VIP7.&lt;br /&gt;
&lt;br /&gt;
=== Fact variables ===&lt;br /&gt;
&lt;br /&gt;
Fact variables are the only mutable types in VIP.&lt;br /&gt;
&lt;br /&gt;
First, a reminder for ordinary facts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb_int : (integer).  % a nondeterministic fact (0 to any number of values)&lt;br /&gt;
    db_int : (integer,string) determ. % a deterministic fact (0 to 1 value)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These types of fact are asserted and retracted.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039; (fact variables)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    zz_int:integer := 0.&lt;br /&gt;
    zz_fred:integer := erroneous.&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    dom = dom(string,chaindb::ref).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    zz_dom : dom := erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        zz_int := 7,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;, zz_int), %will write &amp;quot;zz_int = 7&amp;quot;&lt;br /&gt;
        zz_int := zz_int+20,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;, zz_int), %will write &amp;quot;zz_int = 27&amp;quot;&lt;br /&gt;
        succeed.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fact variables are great for counting e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    how_many : () -&amp;gt; integer Count.&lt;br /&gt;
clauses&lt;br /&gt;
    how_many() = zz_int :-&lt;br /&gt;
        zz_int := 0,&lt;br /&gt;
        foreach some_nondeterm_fact_or_pred() do&lt;br /&gt;
            zz_int := zz_int+1&lt;br /&gt;
        end foreach.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
       stdio::write(&amp;quot;\n There are &amp;quot;, how_many(), &amp;quot; items&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lists - findall and list comprehension ===&lt;br /&gt;
&lt;br /&gt;
See [[Lists and Recursion]]&lt;br /&gt;
&amp;lt;vp&amp;gt;findall()&amp;lt;/vp&amp;gt; has been deprecated, so use the list comprehension construct.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb : (integer). %default is nondeterm for a fact&lt;br /&gt;
clauses&lt;br /&gt;
    ndb(1).&lt;br /&gt;
    ndb(2).&lt;br /&gt;
    ndb(3).&lt;br /&gt;
    ....&lt;br /&gt;
    ndb(10).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_old() :-&lt;br /&gt;
        findall(X,ndb(X),List).&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_new() :-&lt;br /&gt;
        List = [X||ndb(X)].&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X&amp;gt;6].&lt;br /&gt;
        %results in List = [7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0].&lt;br /&gt;
        %results in List = [2,4,6,8,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0, X&amp;lt;7].&lt;br /&gt;
        %results in List = [2,4,6]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        zz_int := 0,&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0, X&amp;lt;7, zz_int := zz_int+1].&lt;br /&gt;
        %results in List = [2,4,6] and zz_int = 3.&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), Y = pred2(X), Y&amp;gt;10].   %with pred2(X) = X^2.&lt;br /&gt;
        %results in List = [4,5,6,7,8,9,10]&lt;br /&gt;
        %reason - X = 3 gives Y = 9 which is &amp;lt; 10.&lt;br /&gt;
&lt;br /&gt;
    pred_other() :-&lt;br /&gt;
        L = [1,2,3,4,5,6,7,8,9,10],&lt;br /&gt;
        LIST = [ X || X = list::getMember_nd(L)].&lt;br /&gt;
        %results in List = L&lt;br /&gt;
&lt;br /&gt;
    pred_other() :-&lt;br /&gt;
        Primes = [X||X = std::fromto(1,300),&lt;br /&gt;
        L1 = [Y||Y = std::fromto(2,150)],&lt;br /&gt;
        tt(X,L1)].&lt;br /&gt;
        %results in List = prime numbers, with:&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
        tt : (integer,integer*) determ.&lt;br /&gt;
clauses&lt;br /&gt;
        tt(_X,[]) :- !.&lt;br /&gt;
        tt(X,[X|_]) :- !.&lt;br /&gt;
        tt(X,[Y|L]) :-&lt;br /&gt;
        X mod Y&amp;lt;&amp;gt;0,&lt;br /&gt;
        tt(X,L).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== if-then-else (code) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred(X,Y) = Z :-&lt;br /&gt;
        if X = 0 then&lt;br /&gt;
            Z = &amp;quot;x is zero&amp;quot;&lt;br /&gt;
        elseif X&amp;gt;0 then&lt;br /&gt;
            if pred3(Y) = true then&lt;br /&gt;
                Z = &amp;quot;x&amp;gt;0 and pred(Y) is true&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
                Z = &amp;quot;x&amp;gt;0 and pred(Y) is false&amp;quot;&lt;br /&gt;
            end if  %note, no comma here either&lt;br /&gt;
        else&lt;br /&gt;
            Z = &amp;quot;x &amp;lt;0&amp;quot;&lt;br /&gt;
        end if.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== #if #then #else (directive for conditional compilation) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;constants&lt;br /&gt;
    u64_con = 1.&lt;br /&gt;
    int_con = 2.&lt;br /&gt;
    real_con = 3.&lt;br /&gt;
&lt;br /&gt;
    compile_big_con = u64_con. %change this and then recompile.&lt;br /&gt;
&lt;br /&gt;
#if compile_big_con = u64_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : () -&amp;gt; unsigned64.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred() = U64 :-&lt;br /&gt;
            U64 = 78766.&lt;br /&gt;
&lt;br /&gt;
#elseif compile_big_con = int_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : () -&amp;gt; integer.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred() = Int :-&lt;br /&gt;
            Int = 20.&lt;br /&gt;
&lt;br /&gt;
#else&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : (real [out]).&lt;br /&gt;
    clauses&lt;br /&gt;
        pred(0.766).&lt;br /&gt;
&lt;br /&gt;
#endif&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Code construct uses     &amp;lt;vp&amp;gt;if  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;elseif  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;else&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;end if&amp;lt;/vp&amp;gt;&lt;br /&gt;
compiler directive uses &amp;lt;vp&amp;gt;#if - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#elseif - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#else&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#endif&amp;lt;/vp&amp;gt;&lt;br /&gt;
(just the &amp;quot;end if&amp;quot; is &amp;quot;different&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Trap and try/catch/finally ===&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Try-catch-finally|Try-catch-finally]]&lt;br /&gt;
Note, in [[Language Reference/Built-in entities/Predicates|Built-in entities/Predicates]]&lt;br /&gt;
suggests using &amp;lt;vp&amp;gt;try-end try&amp;lt;/vp&amp;gt; instead of &amp;lt;vp&amp;gt;trap(_,_,_)&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_all() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    call_pred_that_might_crash : (integer).&lt;br /&gt;
    call_own_exception_pred : (pointer ErrorNo).&lt;br /&gt;
    always_call_this_anyway : ().&lt;br /&gt;
clauses&lt;br /&gt;
    call_pred_that_might_crash(X) :-&lt;br /&gt;
        Y = 9/X.&lt;br /&gt;
&lt;br /&gt;
    call_own_exception_pred(ErrorNo) :-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;crashed&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
    always_call_this_anyway() :-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;finally reached&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% in this case, VIP will automatically pop up its exception dialog&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 4&amp;#039;&amp;#039;&amp;#039; - illegal - it must have a &amp;lt;vp&amp;gt;catch&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;finally&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_illegal() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Foreach ===&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Foreach|Foreach]]&lt;br /&gt;
&lt;br /&gt;
=== 64 bit numbers - history ===&lt;br /&gt;
&lt;br /&gt;
Up to VIP7.1, integer64 etc were defined as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    unsigned64 = unsigned64(unsigned32 Low, unsigned32 High).&lt;br /&gt;
    integer64 = integer64(unsigned32 Low, integer32 High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In VIP7.2 these have been renamed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    unsigned64_struct = unsigned64(unsigned Low, unsigned High).&lt;br /&gt;
    integer64_struct = integer64(unsigned Low, integer High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, for example, in VIP7.1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
     getFileProperties : (&lt;br /&gt;
        string FileName,&lt;br /&gt;
        fileSystem_api::fileAttributes Attributes,&lt;br /&gt;
        fileSystem_api::fileSize Size,&lt;br /&gt;
        core::gmtTimeValue Creation,&lt;br /&gt;
        core::gmtTimeValue LastAccess,&lt;br /&gt;
        core::gmtTimeValue LastChange)&lt;br /&gt;
        procedure (i,o,o,o,o,o).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if you needed use (and write) &amp;#039;&amp;#039;&amp;#039;fileSize&amp;#039;&amp;#039;&amp;#039; and times, you would have to have done some juggling (such as converting them to real numbers).&lt;br /&gt;
&lt;br /&gt;
To generate a 64 bit random number:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates %before VIP7.2&lt;br /&gt;
    gen64 : () -&amp;gt; unsigned64.&lt;br /&gt;
clauses&lt;br /&gt;
    gen64() = U64 :-&lt;br /&gt;
        N = 2^32,&lt;br /&gt;
        Low = math::random(N+0),&lt;br /&gt;
        High = math::random(N+0),&lt;br /&gt;
        U64 = unsigned64(Low,High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and possibly you would have needed (e.g.) &amp;#039;&amp;#039;&amp;#039;math::add&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    add : (core::unsigned64 Augend, core::unsigned64 Addend) -&amp;gt; core::unsigned64 Sum&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s now totally straightforward in VIP7.2 - just treat 64 bit numbers like any other number. You may also want these conversions - found in &amp;#039;&amp;#039;&amp;#039;core::&amp;#039;&amp;#039;&amp;#039; - for old code (this snippet is stolen from [http://discuss.visual-prolog.com/viewtopic.php?t=7927 Thomas&amp;#039; post])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    toUnsigned64 : (unsigned64_struct) -&amp;gt; unsigned64.&lt;br /&gt;
    fromUnsigned64 : (unsigned64) -&amp;gt; unsigned64_struct.&lt;br /&gt;
    toInteger64 : (integer64_struct) -&amp;gt; integer64.&lt;br /&gt;
    fromInteger64 : (integer64) -&amp;gt; integer64_struct.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And just for reference:&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#integer|integer]] range = -2^31 to +2^31-1 = -2147483648 .. 2147483647&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#unsigned|unsigned]]  range = 0 to (2^32)-1 = 4294967295&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#integer64|integer64]] range = -2^63 to 2^63&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#unsigned64|unsigned64]] range = 0 to (2^64)-1 = 18446744073709551615 ( = 1.844..E19)&lt;br /&gt;
&lt;br /&gt;
=== Polymorphic Domains ===&lt;br /&gt;
&lt;br /&gt;
See [[Objects and Polymorphism]]&lt;br /&gt;
&lt;br /&gt;
First, check out the definitions - &amp;lt;vp&amp;gt;core::tuple{}&amp;lt;/vp&amp;gt;. And while you&amp;#039;re there, just below, see &amp;lt;vp&amp;gt;core::predicate{}&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;core::function{}&amp;lt;/vp&amp;gt;, then followed by &amp;lt;vp&amp;gt;comparator{A}&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;list{A}&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The domains in class &amp;lt;vp&amp;gt;list::&amp;lt;/vp&amp;gt; are polymorphic, but you can define your own polymorphic domains. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    poly_dom{A,B} = poly_def(A,B).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you use it in your code, A and B can be any other domain.  The domain name is &amp;lt;vp&amp;gt;poly_dom{A,B}&amp;lt;/vp&amp;gt;, and you reference it you must use its whole name (not just &amp;lt;vp&amp;gt;poly_dom&amp;lt;/vp&amp;gt;) e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    joe{A,B} = poly_dom{A,B}*.&lt;br /&gt;
/* the next two lines are illegal&lt;br /&gt;
    poly_dom{A,B} = poly_def(A,B)*.&lt;br /&gt;
    poly_dom{A,A} = poly_def(A,A).&lt;br /&gt;
*/&lt;br /&gt;
    fred{A,B} = fred(poly_dom{A,B},integer).&lt;br /&gt;
&lt;br /&gt;
    maybe_silly_dom{A,B} =&lt;br /&gt;
        silly2(A,B);&lt;br /&gt;
        silly(A);&lt;br /&gt;
        pd(poly_dom{A,B});&lt;br /&gt;
        poly_dom(A,B);%IS NOT THE SAME POLY_DOM!! (notice no braces)&lt;br /&gt;
        s(string).&lt;br /&gt;
&lt;br /&gt;
    another{A} =&lt;br /&gt;
        i(integer);&lt;br /&gt;
        s(string);&lt;br /&gt;
        a(A);&lt;br /&gt;
        self(another({A}).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    zz_poly_dom:poly_dom{integer,integer} := erroneous.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_morphic_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        zz_poly_dom := poly_def(1,5),&lt;br /&gt;
        call_pd(zz_poly_dom),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        PD = poly_def(1,[&amp;quot;an example&amp;quot;,&amp;quot;or two&amp;quot;]),&lt;br /&gt;
        call_pd(PD),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        Q = [poly_def(X, Y) || X = std::fromTo(1, 4), Y = std::fromTo(1, 5)],&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,Q),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test().&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    call_pd : (poly_dom{A,B}).&lt;br /&gt;
clauses&lt;br /&gt;
    call_pd(POLY_DOM) :-&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,POLY_DOM),&lt;br /&gt;
        fail.&lt;br /&gt;
    call_pd(poly_def(A,B)) :- %note this is POLY_DEF&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,A,B),&lt;br /&gt;
        fail.&lt;br /&gt;
    call_pd(_).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Properties ===&lt;br /&gt;
&lt;br /&gt;
Properties in a class are used almost identically to fact variables, but properties can be set directly (from another class), without having to declare a public predicate to make the change.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface fred&lt;br /&gt;
    domains&lt;br /&gt;
        complete_dom = is_complete;&lt;br /&gt;
                     not_complete.&lt;br /&gt;
    properties&lt;br /&gt;
        prop_complete : complete_dom.&lt;br /&gt;
end interface fred&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;#039;&amp;#039;&amp;#039;fred.pro&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement fred&lt;br /&gt;
facts&lt;br /&gt;
    zz_complete:complete_dom := erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses %for the property&lt;br /&gt;
    prop_complete() = zz_complete. %get&lt;br /&gt;
    prop_complete(COMPLETE) :- zz_complete := COMPLETE. %set&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some other class that calls class fred:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;implement other&lt;br /&gt;
    open fred&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        Fred = fred::new(),&lt;br /&gt;
        Fred:prop_complete := is_complete,% to set the value&lt;br /&gt;
        Value = Fred:prop_complete, !. %get&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comparators and compare ===&lt;br /&gt;
&lt;br /&gt;
First, look at the definition of &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    comparator{T} = function{T, T, compareResult}.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;compareResult&amp;lt;/vp&amp;gt;&amp;#039;s definition can is found here: [[Language Reference/Built-in entities/Domains#compareResult|compareResult]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
    p_compare_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(7,2).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;greater()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
        %(because 7 &amp;gt; 2)&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(2,2).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;equal()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(&amp;quot;a&amp;quot;,&amp;quot;z&amp;quot;).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;less()&amp;#039;&amp;#039;&amp;#039;&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But you may wish to check your own domains to see which is &amp;quot;greater&amp;quot; - and of course you must define this yourself, by defining your own predicate as a &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Here is a simple domain in which only the integer parts of the variables are checked to see which is greater:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    s = s(string,integer).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    compare_it: core::comparator{s}.&lt;br /&gt;
clauses&lt;br /&gt;
    compare_it(A,B) = CompareResult :- %since this is a core::function(T,T,compareResult)&lt;br /&gt;
        A = s(_,I),&lt;br /&gt;
        B = s(_,J),&lt;br /&gt;
        if I&amp;lt;J then&lt;br /&gt;
            CompareResult = less()&lt;br /&gt;
        elseif I = J then&lt;br /&gt;
            CompareResult = equal()&lt;br /&gt;
        else&lt;br /&gt;
            CompareResult = greater()&lt;br /&gt;
        end if.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_compare_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        S1 = s(&amp;quot;abc&amp;quot;,7),&lt;br /&gt;
        S2 = s(&amp;quot;fred&amp;quot;,9),&lt;br /&gt;
        CompareResult = compare_it(S1,S2),&lt;br /&gt;
        %will give CompareResult = less, since 7&amp;lt;9.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...a bit pointless since the string part of the variables have been ignored, but it is easy to see how to expand &amp;lt;vp&amp;gt;compare_it()&amp;lt;/vp&amp;gt; to your own needs.&lt;br /&gt;
&lt;br /&gt;
=== list::sortby example using Comparator===&lt;br /&gt;
&lt;br /&gt;
list::sortby also uses Compareresult.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Say you have the following domain and fact:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	triple=triple(string,gmttimevalue,integer).&lt;br /&gt;
facts&lt;br /&gt;
	zz_triples:triple:=erroneous.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
zz_triples is populated, but it needs to be sorted by date/time. Then:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
	test():-&lt;br /&gt;
		zz_triples:=list::sortby(cp,zz_triples).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
	cp:core::comparator{triple}.&lt;br /&gt;
clauses&lt;br /&gt;
	cp(A,B)=CompareResult:-&lt;br /&gt;
		A=triple(_,ATv,_),&lt;br /&gt;
		B=triple(_,BTv,_),&lt;br /&gt;
		GMTA=gmttime::new(Atv),&lt;br /&gt;
		GMTB=gmttime::new(Btv),&lt;br /&gt;
		if GMTA:before(GMTB) then&lt;br /&gt;
			CompareResult=less&lt;br /&gt;
		else&lt;br /&gt;
			CompareResult=greater&lt;br /&gt;
		end if,!.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== More on core::function and core::predicate ===&lt;br /&gt;
&lt;br /&gt;
Again, please check out &amp;lt;vp&amp;gt;core::function&amp;lt;/vp&amp;gt;.  &amp;lt;vp&amp;gt;core::predicate&amp;lt;/vp&amp;gt; is essentially the same, but does not return a value.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    two_times:function{integer,integer}.&lt;br /&gt;
% or    two_times: core::function{integer,integer}.&lt;br /&gt;
clauses&lt;br /&gt;
    two_times(A) = 2*A.&lt;br /&gt;
class predicates&lt;br /&gt;
    p_function : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_function() :-&lt;br /&gt;
        Z = two_times(2),&lt;br /&gt;
        %binds Z to 4&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    fred_dom{A,B} = predicate{A,B}.&lt;br /&gt;
% or    fred_dom{A,B} = core::predicate{A,B}.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    fred_pred: fred_dom{A,B}.&lt;br /&gt;
clauses&lt;br /&gt;
    fred_pred(A,B) :-&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,A,&amp;quot; &amp;quot;,B).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_pred : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_pred() :-&lt;br /&gt;
        fred_pred(&amp;quot;one&amp;quot;,2).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    add_func: function{integer,integer}.&lt;br /&gt;
clauses&lt;br /&gt;
    add_func(B) = B+1.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_function : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_function() :-&lt;br /&gt;
        X = add_func(5),&lt;br /&gt;
        %X is bound to 6&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Anonymous predicates ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;(under development)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Anonymous Predicates|Anonymous Predicates]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {() = 9},&lt;br /&gt;
        K = Anon().&lt;br /&gt;
        %results in K = 9&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = { = 88},&lt;br /&gt;
        K = Anon().&lt;br /&gt;
        %results in K = 88.&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {(A,B) = A+B},&lt;br /&gt;
        K = Anon(4,8),&lt;br /&gt;
        %results in K = 12.&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {&lt;br /&gt;
            (A,B) = C :-&lt;br /&gt;
            R = math::random(7),&lt;br /&gt;
            C = A+B+R,&lt;br /&gt;
            stdio::wRite(&amp;quot;RRRR = &amp;quot;,R)&lt;br /&gt;
            },&lt;br /&gt;
        K = Anon(4,8).&lt;br /&gt;
        %results in K = 12 + a random number &amp;lt;7&lt;br /&gt;
&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = { = f_abc(3)},&lt;br /&gt;
        K = Anon(),&lt;br /&gt;
        stdio::write(&amp;quot;\nI = { = f_abc(3)} gives &amp;quot;,K),&lt;br /&gt;
        fail.&lt;br /&gt;
    run().&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Threads ===&lt;br /&gt;
&lt;br /&gt;
To start a thread:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        _ = thread::start(fred).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred : ().&lt;br /&gt;
clauses&lt;br /&gt;
    fred() :- .....&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
fred can have no arguments, so no argument brackets are allowed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;    _ = thread::start(fred())&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is illegal. &lt;br /&gt;
&lt;br /&gt;
Using [[Language Reference/Terms/Anonymous Predicates|Anonymous Predicates]] is rather simple to pass arguments to thread:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred(X) :-&lt;br /&gt;
        _ = thread::start( { :- fred(X) } ).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred : (integer K).&lt;br /&gt;
clauses&lt;br /&gt;
    fred(K) :-&lt;br /&gt;
        ...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Examples]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=2107</id>
		<title>VIP7 Construct examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=2107"/>
		<updated>2010-01-18T15:53:57Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: added a list::sortby example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains a collection of basic examples for (mainly) the newer constructs found in VIP7.&lt;br /&gt;
&lt;br /&gt;
=== Fact variables ===&lt;br /&gt;
&lt;br /&gt;
Fact variables are the only mutable types in VIP.&lt;br /&gt;
&lt;br /&gt;
First, a reminder for ordinary facts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb_int : (integer).  % a nondeterministic fact (0 to any number of values)&lt;br /&gt;
    db_int : (integer,string) determ. % a deterministic fact (0 to 1 value)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These types of fact are asserted and retracted.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039; (fact variables)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    zz_int:integer := 0.&lt;br /&gt;
    zz_fred:integer := erroneous.&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    dom = dom(string,chaindb::ref).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    zz_dom : dom := erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        zz_int := 7,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;, zz_int), %will write &amp;quot;zz_int = 7&amp;quot;&lt;br /&gt;
        zz_int := zz_int+20,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;, zz_int), %will write &amp;quot;zz_int = 27&amp;quot;&lt;br /&gt;
        succeed.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fact variables are great for counting e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    how_many : () -&amp;gt; integer Count.&lt;br /&gt;
clauses&lt;br /&gt;
    how_many() = zz_int :-&lt;br /&gt;
        zz_int := 0,&lt;br /&gt;
        foreach some_nondeterm_fact_or_pred() do&lt;br /&gt;
            zz_int := zz_int+1&lt;br /&gt;
        end foreach.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
       stdio::write(&amp;quot;\n There are &amp;quot;, how_many(), &amp;quot; items&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lists - findall and list comprehension ===&lt;br /&gt;
&lt;br /&gt;
See [[Lists and Recursion]]&lt;br /&gt;
&amp;lt;vp&amp;gt;findall()&amp;lt;/vp&amp;gt; has been deprecated, so use the list comprehension construct.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb : (integer). %default is nondeterm for a fact&lt;br /&gt;
clauses&lt;br /&gt;
    ndb(1).&lt;br /&gt;
    ndb(2).&lt;br /&gt;
    ndb(3).&lt;br /&gt;
    ....&lt;br /&gt;
    ndb(10).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_old() :-&lt;br /&gt;
        findall(X,ndb(X),List).&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_new() :-&lt;br /&gt;
        List = [X||ndb(X)].&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X&amp;gt;6].&lt;br /&gt;
        %results in List = [7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0].&lt;br /&gt;
        %results in List = [2,4,6,8,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0, X&amp;lt;7].&lt;br /&gt;
        %results in List = [2,4,6]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        zz_int := 0,&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0, X&amp;lt;7, zz_int := zz_int+1].&lt;br /&gt;
        %results in List = [2,4,6] and zz_int = 3.&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), Y = pred2(X), Y&amp;gt;10].   %with pred2(X) = X^2.&lt;br /&gt;
        %results in List = [4,5,6,7,8,9,10]&lt;br /&gt;
        %reason - X = 3 gives Y = 9 which is &amp;lt; 10.&lt;br /&gt;
&lt;br /&gt;
    pred_other() :-&lt;br /&gt;
        L = [1,2,3,4,5,6,7,8,9,10],&lt;br /&gt;
        LIST = [ X || X = list::getMember_nd(L)].&lt;br /&gt;
        %results in List = L&lt;br /&gt;
&lt;br /&gt;
    pred_other() :-&lt;br /&gt;
        Primes = [X||X = std::fromto(1,300),&lt;br /&gt;
        L1 = [Y||Y = std::fromto(2,150)],&lt;br /&gt;
        tt(X,L1)].&lt;br /&gt;
        %results in List = prime numbers, with:&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
        tt : (integer,integer*) determ.&lt;br /&gt;
clauses&lt;br /&gt;
        tt(_X,[]) :- !.&lt;br /&gt;
        tt(X,[X|_]) :- !.&lt;br /&gt;
        tt(X,[Y|L]) :-&lt;br /&gt;
        X mod Y&amp;lt;&amp;gt;0,&lt;br /&gt;
        tt(X,L).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== if-then-else (code) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred(X,Y) = Z :-&lt;br /&gt;
        if X = 0 then&lt;br /&gt;
            Z = &amp;quot;x is zero&amp;quot;&lt;br /&gt;
        elseif X&amp;gt;0 then&lt;br /&gt;
            if pred3(Y) = true then&lt;br /&gt;
                Z = &amp;quot;x&amp;gt;0 and pred(Y) is true&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
                Z = &amp;quot;x&amp;gt;0 and pred(Y) is false&amp;quot;&lt;br /&gt;
            end if  %note, no comma here either&lt;br /&gt;
        else&lt;br /&gt;
            Z = &amp;quot;x &amp;lt;0&amp;quot;&lt;br /&gt;
        end if.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== #if #then #else (directive for conditional compilation) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;constants&lt;br /&gt;
    u64_con = 1.&lt;br /&gt;
    int_con = 2.&lt;br /&gt;
    real_con = 3.&lt;br /&gt;
&lt;br /&gt;
    compile_big_con = u64_con. %change this and then recompile.&lt;br /&gt;
&lt;br /&gt;
#if compile_big_con = u64_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : () -&amp;gt; unsigned64.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred() = U64 :-&lt;br /&gt;
            U64 = 78766.&lt;br /&gt;
&lt;br /&gt;
#elseif compile_big_con = int_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : () -&amp;gt; integer.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred() = Int :-&lt;br /&gt;
            Int = 20.&lt;br /&gt;
&lt;br /&gt;
#else&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : (real [out]).&lt;br /&gt;
    clauses&lt;br /&gt;
        pred(0.766).&lt;br /&gt;
&lt;br /&gt;
#endif&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Code construct uses     &amp;lt;vp&amp;gt;if  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;elseif  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;else&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;end if&amp;lt;/vp&amp;gt;&lt;br /&gt;
compiler directive uses &amp;lt;vp&amp;gt;#if - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#elseif - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#else&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#endif&amp;lt;/vp&amp;gt;&lt;br /&gt;
(just the &amp;quot;end if&amp;quot; is &amp;quot;different&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Trap and try/catch/finally ===&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Try-catch-finally|Try-catch-finally]]&lt;br /&gt;
Note, in [[Language Reference/Built-in entities/Predicates|Built-in entities/Predicates]]&lt;br /&gt;
suggests using &amp;lt;vp&amp;gt;try-end try&amp;lt;/vp&amp;gt; instead of &amp;lt;vp&amp;gt;trap(_,_,_)&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_all() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    call_pred_that_might_crash : (integer).&lt;br /&gt;
    call_own_exception_pred : (pointer ErrorNo).&lt;br /&gt;
    always_call_this_anyway : ().&lt;br /&gt;
clauses&lt;br /&gt;
    call_pred_that_might_crash(X) :-&lt;br /&gt;
        Y = 9/X.&lt;br /&gt;
&lt;br /&gt;
    call_own_exception_pred(ErrorNo) :-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;crashed&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
    always_call_this_anyway() :-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;finally reached&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% in this case, VIP will automatically pop up its exception dialog&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 4&amp;#039;&amp;#039;&amp;#039; - illegal - it must have a &amp;lt;vp&amp;gt;catch&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;finally&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_illegal() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Foreach ===&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Foreach|Foreach]]&lt;br /&gt;
&lt;br /&gt;
=== 64 bit numbers - history ===&lt;br /&gt;
&lt;br /&gt;
Up to VIP7.1, integer64 etc were defined as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    unsigned64 = unsigned64(unsigned32 Low, unsigned32 High).&lt;br /&gt;
    integer64 = integer64(unsigned32 Low, integer32 High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In VIP7.2 these have been renamed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    unsigned64_struct = unsigned64(unsigned Low, unsigned High).&lt;br /&gt;
    integer64_struct = integer64(unsigned Low, integer High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, for example, in VIP7.1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
     getFileProperties : (&lt;br /&gt;
        string FileName,&lt;br /&gt;
        fileSystem_api::fileAttributes Attributes,&lt;br /&gt;
        fileSystem_api::fileSize Size,&lt;br /&gt;
        core::gmtTimeValue Creation,&lt;br /&gt;
        core::gmtTimeValue LastAccess,&lt;br /&gt;
        core::gmtTimeValue LastChange)&lt;br /&gt;
        procedure (i,o,o,o,o,o).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if you needed use (and write) &amp;#039;&amp;#039;&amp;#039;fileSize&amp;#039;&amp;#039;&amp;#039; and times, you would have to have done some juggling (such as converting them to real numbers).&lt;br /&gt;
&lt;br /&gt;
To generate a 64 bit random number:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates %before VIP7.2&lt;br /&gt;
    gen64 : () -&amp;gt; unsigned64.&lt;br /&gt;
clauses&lt;br /&gt;
    gen64() = U64 :-&lt;br /&gt;
        N = 2^32,&lt;br /&gt;
        Low = math::random(N+0),&lt;br /&gt;
        High = math::random(N+0),&lt;br /&gt;
        U64 = unsigned64(Low,High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and possibly you would have needed (e.g.) &amp;#039;&amp;#039;&amp;#039;math::add&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    add : (core::unsigned64 Augend, core::unsigned64 Addend) -&amp;gt; core::unsigned64 Sum&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s now totally straightforward in VIP7.2 - just treat 64 bit numbers like any other number. You may also want these conversions - found in &amp;#039;&amp;#039;&amp;#039;core::&amp;#039;&amp;#039;&amp;#039; - for old code (this snippet is stolen from [http://discuss.visual-prolog.com/viewtopic.php?t=7927 Thomas&amp;#039; post])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    toUnsigned64 : (unsigned64_struct) -&amp;gt; unsigned64.&lt;br /&gt;
    fromUnsigned64 : (unsigned64) -&amp;gt; unsigned64_struct.&lt;br /&gt;
    toInteger64 : (integer64_struct) -&amp;gt; integer64.&lt;br /&gt;
    fromInteger64 : (integer64) -&amp;gt; integer64_struct.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And just for reference:&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#integer|integer]] range = -2^31 to +2^31-1 = -2147483648 .. 2147483647&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#unsigned|unsigned]]  range = 0 to (2^32)-1 = 4294967295&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#integer64|integer64]] range = -2^63 to 2^63&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#unsigned64|unsigned64]] range = 0 to (2^64)-1 = 18446744073709551615 ( = 1.844..E19)&lt;br /&gt;
&lt;br /&gt;
=== Polymorphic Domains ===&lt;br /&gt;
&lt;br /&gt;
See [[Objects and Polymorphism]]&lt;br /&gt;
&lt;br /&gt;
First, check out the definitions - &amp;lt;vp&amp;gt;core::tuple{}&amp;lt;/vp&amp;gt;. And while you&amp;#039;re there, just below, see &amp;lt;vp&amp;gt;core::predicate{}&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;core::function{}&amp;lt;/vp&amp;gt;, then followed by &amp;lt;vp&amp;gt;comparator{A}&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;list{A}&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The domains in class &amp;lt;vp&amp;gt;list::&amp;lt;/vp&amp;gt; are polymorphic, but you can define your own polymorphic domains. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    poly_dom{A,B} = poly_def(A,B).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you use it in your code, A and B can be any other domain.  The domain name is &amp;lt;vp&amp;gt;poly_dom{A,B}&amp;lt;/vp&amp;gt;, and you reference it you must use its whole name (not just &amp;lt;vp&amp;gt;poly_dom&amp;lt;/vp&amp;gt;) e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    joe{A,B} = poly_dom{A,B}*.&lt;br /&gt;
/* the next two lines are illegal&lt;br /&gt;
    poly_dom{A,B} = poly_def(A,B)*.&lt;br /&gt;
    poly_dom{A,A} = poly_def(A,A).&lt;br /&gt;
*/&lt;br /&gt;
    fred{A,B} = fred(poly_dom{A,B},integer).&lt;br /&gt;
&lt;br /&gt;
    maybe_silly_dom{A,B} =&lt;br /&gt;
        silly2(A,B);&lt;br /&gt;
        silly(A);&lt;br /&gt;
        pd(poly_dom{A,B});&lt;br /&gt;
        poly_dom(A,B);%IS NOT THE SAME POLY_DOM!! (notice no braces)&lt;br /&gt;
        s(string).&lt;br /&gt;
&lt;br /&gt;
    another{A} =&lt;br /&gt;
        i(integer);&lt;br /&gt;
        s(string);&lt;br /&gt;
        a(A);&lt;br /&gt;
        self(another({A}).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    zz_poly_dom:poly_dom{integer,integer} := erroneous.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_morphic_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        zz_poly_dom := poly_def(1,5),&lt;br /&gt;
        call_pd(zz_poly_dom),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        PD = poly_def(1,[&amp;quot;an example&amp;quot;,&amp;quot;or two&amp;quot;]),&lt;br /&gt;
        call_pd(PD),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        Q = [poly_def(X, Y) || X = std::fromTo(1, 4), Y = std::fromTo(1, 5)],&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,Q),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test().&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    call_pd : (poly_dom{A,B}).&lt;br /&gt;
clauses&lt;br /&gt;
    call_pd(POLY_DOM) :-&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,POLY_DOM),&lt;br /&gt;
        fail.&lt;br /&gt;
    call_pd(poly_def(A,B)) :- %note this is POLY_DEF&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,A,B),&lt;br /&gt;
        fail.&lt;br /&gt;
    call_pd(_).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Properties ===&lt;br /&gt;
&lt;br /&gt;
Properties in a class are used almost identically to fact variables, but properties can be set directly (from another class), without having to declare a public predicate to make the change.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface fred&lt;br /&gt;
    domains&lt;br /&gt;
        complete_dom = is_complete;&lt;br /&gt;
                     not_complete.&lt;br /&gt;
    properties&lt;br /&gt;
        prop_complete : complete_dom.&lt;br /&gt;
end interface fred&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;#039;&amp;#039;&amp;#039;fred.pro&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement fred&lt;br /&gt;
facts&lt;br /&gt;
    zz_complete:complete_dom := erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses %for the property&lt;br /&gt;
    prop_complete() = zz_complete. %get&lt;br /&gt;
    prop_complete(COMPLETE) :- zz_complete := COMPLETE. %set&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some other class that calls class fred:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;implement other&lt;br /&gt;
    open fred&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        Fred = fred::new(),&lt;br /&gt;
        Fred:prop_complete := is_complete,% to set the value&lt;br /&gt;
        Value = Fred:prop_complete, !. %get&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comparators and compare ===&lt;br /&gt;
&lt;br /&gt;
First, look at the definition of &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    comparator{T} = function{T, T, compareResult}.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;compareResult&amp;lt;/vp&amp;gt;&amp;#039;s definition can is found here: [[Language Reference/Built-in entities/Domains#compareResult|compareResult]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
    p_compare_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(7,2).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;greater()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
        %(because 7 &amp;gt; 2)&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(2,2).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;equal()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(&amp;quot;a&amp;quot;,&amp;quot;z&amp;quot;).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;less()&amp;#039;&amp;#039;&amp;#039;&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But you may wish to check your own domains to see which is &amp;quot;greater&amp;quot; - and of course you must define this yourself, by defining your own predicate as a &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Here is a simple domain in which only the integer parts of the variables are checked to see which is greater:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    s = s(string,integer).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    compare_it: core::comparator{s}.&lt;br /&gt;
clauses&lt;br /&gt;
    compare_it(A,B) = CompareResult :- %since this is a core::function(T,T,compareResult)&lt;br /&gt;
        A = s(_,I),&lt;br /&gt;
        B = s(_,J),&lt;br /&gt;
        if I&amp;lt;J then&lt;br /&gt;
            CompareResult = less()&lt;br /&gt;
        elseif I = J then&lt;br /&gt;
            CompareResult = equal()&lt;br /&gt;
        else&lt;br /&gt;
            CompareResult = greater()&lt;br /&gt;
        end if.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_compare_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        S1 = s(&amp;quot;abc&amp;quot;,7),&lt;br /&gt;
        S2 = s(&amp;quot;fred&amp;quot;,9),&lt;br /&gt;
        CompareResult = compare_it(S1,S2),&lt;br /&gt;
        %will give CompareResult = less, since 7&amp;lt;9.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...a bit pointless since the string part of the variables have been ignored, but it is easy to see how to expand &amp;lt;vp&amp;gt;compare_it()&amp;lt;/vp&amp;gt; to your own needs.&lt;br /&gt;
&lt;br /&gt;
=== list::sortby example using Comparator===&lt;br /&gt;
&lt;br /&gt;
list::sortby also uses Compareresult.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Say you have the following domain and fact:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vp&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	triple=triple(string,gmttimevalue,integer).&lt;br /&gt;
facts&lt;br /&gt;
	zz_triples:triple:=erroneous.&lt;br /&gt;
&amp;lt;/vp&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
zz_triples is populated, but it needs to be sorted by date/time. Then:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
	test():-&lt;br /&gt;
		zz_triples:=list::sortby(cp,zz_triples).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
	cp:core::comparator{triple}.&lt;br /&gt;
clauses&lt;br /&gt;
	cp(A,B)=CompareResult:-&lt;br /&gt;
		A=triple(_,ATv,_),&lt;br /&gt;
		B=triple(_,BTv,_),&lt;br /&gt;
		GMTA=gmttime::new(Atv),&lt;br /&gt;
		GMTB=gmttime::new(Btv),&lt;br /&gt;
		if GMTA:before(GMTB) then&lt;br /&gt;
			CompareResult=less&lt;br /&gt;
		else&lt;br /&gt;
			CompareResult=greater&lt;br /&gt;
		end if,!.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== More on core::function and core::predicate ===&lt;br /&gt;
&lt;br /&gt;
Again, please check out &amp;lt;vp&amp;gt;core::function&amp;lt;/vp&amp;gt;.  &amp;lt;vp&amp;gt;core::predicate&amp;lt;/vp&amp;gt; is essentially the same, but does not return a value.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    two_times:function{integer,integer}.&lt;br /&gt;
% or    two_times: core::function{integer,integer}.&lt;br /&gt;
clauses&lt;br /&gt;
    two_times(A) = 2*A.&lt;br /&gt;
class predicates&lt;br /&gt;
    p_function : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_function() :-&lt;br /&gt;
        Z = two_times(2),&lt;br /&gt;
        %binds Z to 4&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    fred_dom{A,B} = predicate{A,B}.&lt;br /&gt;
% or    fred_dom{A,B} = core::predicate{A,B}.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    fred_pred: fred_dom{A,B}.&lt;br /&gt;
clauses&lt;br /&gt;
    fred_pred(A,B) :-&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,A,&amp;quot; &amp;quot;,B).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_pred : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_pred() :-&lt;br /&gt;
        fred_pred(&amp;quot;one&amp;quot;,2).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    add_func: function{integer,integer}.&lt;br /&gt;
clauses&lt;br /&gt;
    add_func(B) = B+1.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_function : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_function() :-&lt;br /&gt;
        X = add_func(5),&lt;br /&gt;
        %X is bound to 6&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Anonymous predicates ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;(under development)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Anonymous Predicates|Anonymous Predicates]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {() = 9},&lt;br /&gt;
        K = Anon().&lt;br /&gt;
        %results in K = 9&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = { = 88},&lt;br /&gt;
        K = Anon().&lt;br /&gt;
        %results in K = 88.&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {(A,B) = A+B},&lt;br /&gt;
        K = Anon(4,8),&lt;br /&gt;
        %results in K = 12.&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {&lt;br /&gt;
            (A,B) = C :-&lt;br /&gt;
            R = math::random(7),&lt;br /&gt;
            C = A+B+R,&lt;br /&gt;
            stdio::wRite(&amp;quot;RRRR = &amp;quot;,R)&lt;br /&gt;
            },&lt;br /&gt;
        K = Anon(4,8).&lt;br /&gt;
        %results in K = 12 + a random number &amp;lt;7&lt;br /&gt;
&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = { = f_abc(3)},&lt;br /&gt;
        K = Anon(),&lt;br /&gt;
        stdio::write(&amp;quot;\nI = { = f_abc(3)} gives &amp;quot;,K),&lt;br /&gt;
        fail.&lt;br /&gt;
    run().&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Threads ===&lt;br /&gt;
&lt;br /&gt;
To start a thread:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        _ = thread::start(fred).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred : ().&lt;br /&gt;
clauses&lt;br /&gt;
    fred() :- .....&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
fred can have no arguments, so no argument brackets are allowed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;    _ = thread::start(fred())&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is illegal. &lt;br /&gt;
&lt;br /&gt;
Using [[Language Reference/Terms/Anonymous Predicates|Anonymous Predicates]] is rather simple to pass arguments to thread:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred(X) :-&lt;br /&gt;
        _ = thread::start( { :- fred(X) } ).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred : (integer K).&lt;br /&gt;
clauses&lt;br /&gt;
    fred(K) :-&lt;br /&gt;
        ...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Examples]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2104</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2104"/>
		<updated>2010-01-06T10:40:24Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Basics */ SAPI.DLL placement&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft has developed (or bought, probably!) a speech engine, provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2. It is surprisingly accurate and responsive, even with a cheap microphone.&lt;br /&gt;
&lt;br /&gt;
The COM/DLL is provided with all (purportedly) copies of Windows. The file is &amp;quot;SAPI.DLL&amp;quot;, and the version used here is SAPI5.1. You should be able to locate this file on your computer, but to ensure you&amp;#039;re using SAPI5.1 you should download your own copy, and place it (SAPI.DLL) in your project&amp;#039;s EXE folder. With the DLL in your project folder, it&amp;#039;s easy to import it into your project. It should not be necessary for it to be there at run time (i.e. there&amp;#039;s no need to distribute it with your app to end users).&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback is called. You then simply extract what was said as a string_list, which you pass onto your own predicate to process. &lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer,&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SAPI does a reasonable job. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; (free form) is expected.&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
*&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
*&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
*&amp;lt;DICTATION&amp;gt; - for free form dictation;&lt;br /&gt;
*&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
*&amp;lt;PHRASE&amp;gt; or {P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
*&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said;&lt;br /&gt;
*&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
*&amp;lt;WILDCARD&amp;gt; - &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&lt;br /&gt;
*&amp;lt;RESOURCE&amp;gt; - &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&lt;br /&gt;
*&amp;lt;TEXTBUFFER&amp;gt; - &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
* [[wikipedia:Microsoft Speech API]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2102</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2102"/>
		<updated>2010-01-02T10:57:16Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: Style&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft has developed (or bought, probably!) a speech engine, provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2. It is surprisingly accurate and responsive, even with a cheap microphone.&lt;br /&gt;
&lt;br /&gt;
The COM/DLL is provided with all (purportedly) copies of Windows. The file is &amp;quot;SAPI.DLL&amp;quot;, and the version used here is SAPI5.1. You should be able to locate this file on your computer, but to ensure you&amp;#039;re using SAPI5.1 you should download your own copy, and place it (SAPI.DLL) in your project&amp;#039;s EXE folder.&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback is called. You then simply extract what was said as a string_list, which you pass onto your own predicate to process. &lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer,&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SAPI does a reasonable job. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; (free form) is expected.&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
*&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
*&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
*&amp;lt;DICTATION&amp;gt; - for free form dictation;&lt;br /&gt;
*&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
*&amp;lt;PHRASE&amp;gt; or {P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
*&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said;&lt;br /&gt;
*&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
*&amp;lt;WILDCARD&amp;gt; - &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&lt;br /&gt;
*&amp;lt;RESOURCE&amp;gt; - &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&lt;br /&gt;
*&amp;lt;TEXTBUFFER&amp;gt; - &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2101</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2101"/>
		<updated>2010-01-02T10:55:33Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: Added Section GRAMMAR FORMAT TAGS&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am still going up the learning curve here, so I am sure I will say things which are not correct.&lt;br /&gt;
&lt;br /&gt;
===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft has developed (or bought, probably!) a speech engine, provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2. It is surprisingly accurate and responsive, even with a cheap microphone.&lt;br /&gt;
&lt;br /&gt;
The COM/DLL is provided with all (purportedly) copies of Windows. The file is &amp;quot;SAPI.DLL&amp;quot;, and the version used here is SAPI5.1. You should be able to locate this file on your computer, but to ensure you&amp;#039;re using SAPI5.1 you should download your own copy, and place it (SAPI.DLL) in your project&amp;#039;s EXE folder.&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback is called. You then simply extract what was said as a string_list, which you pass onto your own predicate to process. &lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;To do - Other data can be extracted&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer,&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SAPI does a reasonable job. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; (free form) is expected.&lt;br /&gt;
===Grammar Format Tags===&lt;br /&gt;
The XML Grammar Format Tags are described the SDK Manual. Briefly these are:&lt;br /&gt;
*&amp;lt;GRAMMAR&amp;gt; - the file starts with this, and ends with &amp;lt;/GRAMMAR&amp;gt;;&lt;br /&gt;
*&amp;lt;RULE&amp;gt; - the tag for defining sentences (a list of other tags). A RULE parent must always be &amp;lt;GRAMMAR&amp;gt;;&lt;br /&gt;
*&amp;lt;DICTATION&amp;gt; - for free form dictation;&lt;br /&gt;
*&amp;lt;LIST&amp;gt; or &amp;lt;L&amp;gt; - children can be lists of PHRASEs for example;&lt;br /&gt;
*&amp;lt;PHRASE&amp;gt; or {P&amp;gt; - specifying the words to be recognised;&lt;br /&gt;
*&amp;lt;OPT&amp;gt; or &amp;lt;O&amp;gt; - specifying words that might be said;&lt;br /&gt;
*&amp;lt;RULEREF&amp;gt; - for recursively calling other RULEs;&lt;br /&gt;
*&amp;lt;WILDCARD&amp;gt; - &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&lt;br /&gt;
*&amp;lt;RESOURCE&amp;gt; - &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&lt;br /&gt;
*&amp;lt;TEXTBUFFER&amp;gt; - &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;to do&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Many of the tags can have children which are other tags, but not all, and equally some tags are restricted as to their parent tag. &amp;lt;DICTATION&amp;gt; and &amp;lt;RULEREF&amp;gt; can have no children. &amp;lt;RULE&amp;gt; can only have &amp;lt;GRAMMAR&amp;gt; as a parent. &amp;lt;GRAMMAR&amp;gt; must have one or more &amp;lt;RULE&amp;gt;s as children, and no other type (except &amp;lt;ID&amp;gt; which is discussed below).&amp;lt;BR&amp;gt;&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2100</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2100"/>
		<updated>2010-01-02T10:30:56Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Dictation versus Commands */ style&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am still going up the learning curve here, so I am sure I will say things which are not correct.&lt;br /&gt;
&lt;br /&gt;
===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft has developed (or bought, probably!) a speech engine, provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2. It is surprisingly accurate and responsive, even with a cheap microphone.&lt;br /&gt;
&lt;br /&gt;
The COM/DLL is provided with all (purportedly) copies of Windows. The file is &amp;quot;SAPI.DLL&amp;quot;, and the version used here is SAPI5.1. You should be able to locate this file on your computer, but to ensure you&amp;#039;re using SAPI5.1 you should download your own copy, and place it (SAPI.DLL) in your project&amp;#039;s EXE folder.&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;Todo - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback is called. You then simply extract what was said as a string_list, which you pass onto your own predicate to process. &lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;Todo - Other data can be extracted&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer,&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SAPI does a reasonable job. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;ToDo - is there a training mode?&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all. If you say &amp;quot;turn bed&amp;quot;, it will probably return the &amp;quot;turn red&amp;quot;, or nothing at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something slightly wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; (free form) is expected.&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2099</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2099"/>
		<updated>2010-01-02T10:23:49Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Basics */ style&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am still going up the learning curve here, so I am sure I will say things which are not correct.&lt;br /&gt;
&lt;br /&gt;
===Basics===&lt;br /&gt;
&lt;br /&gt;
Microsoft has developed (or bought, probably!) a speech engine, provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2. It is surprisingly accurate and responsive, even with a cheap microphone.&lt;br /&gt;
&lt;br /&gt;
The COM/DLL is provided with all (purportedly) copies of Windows. The file is &amp;quot;SAPI.DLL&amp;quot;, and the version used here is SAPI5.1. You should be able to locate this file on your computer, but to ensure you&amp;#039;re using SAPI5.1 you should download your own copy, and place it (SAPI.DLL) in your project&amp;#039;s EXE folder.&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en MS Download site]; you need the 68Mb file &amp;#039;&amp;#039;&amp;#039;SpeechSDK51.exe&amp;#039;&amp;#039;&amp;#039; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&lt;br /&gt;
&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/aa911607.aspx SAPI5.0 overview]&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx SAPI5.3 overview]&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;Todo - SAPI5.1 on the MS site?&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback is called. You then simply extract what was said as a string_list, which you pass onto your own predicate to process. &lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;Todo - Other data can be extracted&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. So Thomas has provided the tidied-up code here:&lt;br /&gt;
&lt;br /&gt;
* [http://discuss.visual-prolog.com/viewtopic.php?t=8206 SAPI COM glue]&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer,&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SAPI does a reasonable job. I have not yet discovered any training mode.&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. If you give it a grammar such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;turn red&amp;quot;&lt;br /&gt;
* &amp;quot;turn blue&amp;quot;&lt;br /&gt;
&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all.&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; (free form) is expected.&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2097</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2097"/>
		<updated>2010-01-01T17:53:07Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: Added small info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am still going up the learning curve here, so I am sure I will say things which are not correct. &lt;br /&gt;
===Basics===&lt;br /&gt;
Microsoft has developed (or bought, probably!) a speech engine, provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2. It is surprisingly accurate and responsive, even with a cheap microphone.&lt;br /&gt;
&lt;br /&gt;
The COM/DLL is provided with all (purportedly) copies of Windows. The file is &amp;quot;SAPI.DLL&amp;quot;, and the version used here is SAPI5.1. You should be able to locate this file on your computer, but to ensure you&amp;#039;re using SAPI5.1 you should download your own copy, and place it (SAPI.DLL) in your project&amp;#039;s EXE folder.&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en]MS Download site&amp;lt;br&amp;gt;&lt;br /&gt;
You need the 68Mb file &amp;lt;b&amp;gt;SpeechSDK51.exe&amp;lt;/b&amp;gt; near the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://msdn.microsoft.com/en-us/library/aa911607.aspx]SAPI5.0 overview&amp;lt;br&amp;gt;&lt;br /&gt;
[http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx]SAPI5.3 overview&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I&amp;#039;ll try to find the SAPI5.1 overview, but if you find it please edit it here.&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback is called. You then simply extract what was said as a string_list, which you can pass onto your own predicate. There are more things that can be extracted, but I haven&amp;#039;t got that far yet.&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. &lt;br /&gt;
So Thomas has provided the tidied-up code here:&amp;lt;br&amp;gt;&lt;br /&gt;
[http://discuss.visual-prolog.com/viewtopic.php?t=8206]SAPI COM glue&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer,&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SAPI does a reasonable job. I have not yet discovered any training mode.&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. If you give it a grammar such as&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;quot;turn red&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;quot;turn blue&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; (free form) is expected.&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2096</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2096"/>
		<updated>2010-01-01T17:49:40Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: Format change&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am still going up the learning curve here, so I am sure I will say things which are not correct. &lt;br /&gt;
===Basics===&lt;br /&gt;
Microsoft has developed (or bought, probably!) a speech engine, provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2. It is surprisingly accurate and responsive, even with a cheap microphone.&lt;br /&gt;
&lt;br /&gt;
The COM/DLL is provided with all (purportedly) copies of Windows. The file is &amp;quot;SAPI.DLL&amp;quot;, and the version used here is SAPI5.1. You should be able to locate this file on your computer, but to ensure you&amp;#039;re using SAPI5.1 you should download your own copy, and place it (SAPI.DLL) in your project&amp;#039;s EXE folder.&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en]MS Download site&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://msdn.microsoft.com/en-us/library/aa911607.aspx]SAPI5.0 overview&amp;lt;br&amp;gt;&lt;br /&gt;
[http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx]SAPI5.3 overview&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I&amp;#039;ll try to find the SAPI5.1 overview, but if you find it please edit it here.&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback is called. You then simply extract what was said as a string_list, which you can pass onto your own predicate. There are more things that can be extracted, but I haven&amp;#039;t got that far yet.&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. &lt;br /&gt;
So Thomas has provided the tidied-up code here:&amp;lt;br&amp;gt;&lt;br /&gt;
[http://discuss.visual-prolog.com/viewtopic.php?t=8206]SAPI COM glue&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer,&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SAPI does a reasonable job. I have not yet discovered any training mode.&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. If you give it a grammar such as&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;quot;turn red&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;quot;turn blue&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; (free form) is expected.&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2095</id>
		<title>Speech Recognition</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Speech_Recognition&amp;diff=2095"/>
		<updated>2010-01-01T17:43:28Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: Initial Description&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am still going up the learning curve here, so I am sure I will say things which are not correct. &lt;br /&gt;
===Basics===&lt;br /&gt;
Microsoft has developed (or bought, probably!) a speech engine, provided as a DLL, which works very nicely (thanks to Thomas and co.) with Visual Prolog 7.2. It is surprisingly accurate and responsive, even with a cheap microphone.&lt;br /&gt;
&lt;br /&gt;
The COM/DLL is provided with all (purportedly) copies of Windows. The file is &amp;quot;SAPI.DLL&amp;quot;, and the version used here is SAPI5.1. You should be able to locate this file on your computer, but to ensure you&amp;#039;re using SAPI5.1 you should download your own copy, and place it (SAPI.DLL) in your project&amp;#039;s EXE folder.&lt;br /&gt;
&lt;br /&gt;
[http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;amp;displaylang=en]MS Download site&lt;br /&gt;
&lt;br /&gt;
The SAPI overviews are here:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://msdn.microsoft.com/en-us/library/aa911607.aspx]SAPI5.1 overview&amp;lt;br&amp;gt;&lt;br /&gt;
and the SAPI5.3 overview&amp;lt;br&amp;gt;&lt;br /&gt;
[http://msdn.microsoft.com/en-us/library/ms720151(VS.85).aspx]SAPI5.3 overview&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I&amp;#039;ll try to find the SAPI5.1 overview, but if you find it please edit it here.&lt;br /&gt;
&lt;br /&gt;
When your program runs, you say something into the mic, pause, and the speech callback is called. You then simply extract what was said as a string_list, which you can pass onto your own predicate. There are more things that can be extracted, but I haven&amp;#039;t got that far yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Setting up your project===&lt;br /&gt;
When you create a new VIP project and try to generate the prolog &amp;quot;glue&amp;quot; to the SAPI COM, the code generated is not perfect. You will have noticed in the forum that this is not a trivial task, and everyone seems to write their COMs differently. &lt;br /&gt;
So Thomas has provided the tidied-up code here:&amp;lt;br&amp;gt;&lt;br /&gt;
[http://discuss.visual-prolog.com/viewtopic.php?t=8206]SAPI COM glue&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So first generate the faulty COM code using the IDE (at the point where you add the DLL to the project) so that all the folders and classes are created, and then overwrite these files with the correct code in Windows explorer,&lt;br /&gt;
&lt;br /&gt;
===Dictation versus Commands===&lt;br /&gt;
&lt;br /&gt;
Briefly, SAPI works in two modes. One is dictation - a &amp;quot;free form&amp;quot; mode for dictating letters etc. SAPI does a reasonable job. I have not yet discovered any training mode.&lt;br /&gt;
The second mode is &amp;quot;command mode&amp;quot; whereby SAPI is provided with a grammar that makes it easier for it to understand, since there is a restricted limited number of words to work with. If you give it a grammar such as&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;quot;turn red&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;quot;turn blue&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
it will totally ignore the command if you say &amp;quot;turn yellow&amp;quot; - the callback function is not called at all.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The grammar file required (if you don&amp;#039;t want dictation) is an XML file. The help file for writing an XML grammar file is provided in the download above. The rules for writing the XML file are straightforward, and for simple grammars the XML is easy to write. But if you get something wrong (even though the XML structure itself is correct), you will get an exception when your program loads and compiles it(the SAPI engine compiles the XML).&lt;br /&gt;
&lt;br /&gt;
The grammar file can have a rule saying &amp;quot;dictation&amp;quot; (free form) is expected.&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Language_Reference/Domains&amp;diff=1896</id>
		<title>Language Reference/Domains</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Language_Reference/Domains&amp;diff=1896"/>
		<updated>2009-05-16T17:52:01Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: split line&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{languageReferenceNavbar|Domains}}&lt;br /&gt;
&lt;br /&gt;
=== Domains Sections ===&lt;br /&gt;
&lt;br /&gt;
A domain section defines a set of domains in the current scope (see {{lang|Interfaces|Interface}}, {{lang2|Classes|Class Declarations|Class Declaration}}, and {{lang2|Implementations|Class_Implementations|Class Implementation}}).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;DomainsSection&amp;gt;:&lt;br /&gt;
    domains &amp;lt;DomainDefinition&amp;gt;-dot-term-list-opt&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Domain Definitions ===&lt;br /&gt;
&lt;br /&gt;
A domain definition defines a named domain in the current scope.&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;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the domain on the right hand side denotes an interface or a compound domain, then the defined domain is synonym (i.e. identical) to the type expression. Otherwise the defined domain becomes a subtype of the domain denoted by the type expression. Here a domain name &amp;lt;vpbnf&amp;gt;&amp;lt;DomainName&amp;gt;&amp;lt;/vpbnf&amp;gt; should be a {{lang2|Lexical_Elements|Identifiers|lower case identifier}}.&lt;br /&gt;
&lt;br /&gt;
There are certain places where you must use a domain name rather than a type expression:&lt;br /&gt;
&lt;br /&gt;
*as a declaration of a formal argument type;&lt;br /&gt;
*as a type of a constant or a fact variable;&lt;br /&gt;
*as a type in a list domain.&lt;br /&gt;
&lt;br /&gt;
=== Type Expressions ===&lt;br /&gt;
&lt;br /&gt;
A type expression denotes a type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;TypeExpression&amp;gt;:&lt;br /&gt;
    &amp;lt;TypeName&amp;gt;&lt;br /&gt;
    &amp;lt;CompoundDomain&amp;gt;&lt;br /&gt;
    &amp;lt;ListDomain&amp;gt;&lt;br /&gt;
    &amp;lt;PredicateDomain&amp;gt;&lt;br /&gt;
    &amp;lt;IntegralDomain&amp;gt;&lt;br /&gt;
    &amp;lt;RealDomain&amp;gt;&lt;br /&gt;
    &amp;lt;TypeVariable&amp;gt;&lt;br /&gt;
    &amp;lt;TypeApplication&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Type Names ====&lt;br /&gt;
&lt;br /&gt;
A type name is either an &amp;#039;&amp;#039;interface&amp;#039;&amp;#039; name or the name of a &amp;#039;&amp;#039;value domain&amp;#039;&amp;#039;. We use the term &amp;#039;&amp;#039;value domain&amp;#039;&amp;#039; to specify domains whose elements are {{lang2|Basic_Concepts|Types|immutable}} (unchangeable). Here we can say that objects, belonging to domains correspondent to &amp;#039;&amp;#039;interface&amp;#039;&amp;#039; names, have mutable state and terms of any other domains are immutable. So actually value types are everything except object types. A type name (obviously) denotes the type corresponding to the name of an existing domain.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;TypeName&amp;gt;:&lt;br /&gt;
    &amp;lt;InterfaceName&amp;gt;&lt;br /&gt;
    &amp;lt;DomainName&amp;gt;&lt;br /&gt;
    &amp;lt;ClassQualifiedDomainName&amp;gt;&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;
&amp;lt;vipbnf&amp;gt;&amp;lt;DomainName&amp;gt;:&lt;br /&gt;
    &amp;lt;LowercaseIdentifier&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;ClassQualifiedDomainName&amp;gt;:&lt;br /&gt;
    &amp;lt;ClassName&amp;gt;::&amp;lt;DomainName&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;ClassName&amp;gt;:&lt;br /&gt;
    &amp;lt;LowercaseIdentifier&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here &amp;lt;vpbnf&amp;gt;&amp;lt;InterfaceName&amp;gt;&amp;lt;/vpbnf&amp;gt; is an interface name, &amp;lt;vpbnf&amp;gt;&amp;lt;DomainName&amp;gt;&amp;lt;/vpbnf&amp;gt; is a value domain name, and &amp;lt;vpbnf&amp;gt;&amp;lt;ClassName&amp;gt;&amp;lt;/vpbnf&amp;gt; is a class name.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;domains newDomain1 = existingDomain. newDomain2 = myInterface.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example the domain name &amp;lt;vp&amp;gt;existingDomain&amp;lt;/vp&amp;gt; and the interface name &amp;lt;vp&amp;gt;myInterface&amp;lt;/vp&amp;gt; are used to define new domains.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Compound Domains ====&lt;br /&gt;
&lt;br /&gt;
Compound domains (also known as algebraic data types) are used to represent lists, trees, and other tree structured values. In its simple forms compound domains are used to represent structures and enumeration values. Compound domains can have a recursive definition. They can also be mutually/indirectly recursive.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;CompoundDomain&amp;gt;:&lt;br /&gt;
   &amp;lt;Alignment&amp;gt;-opt &amp;lt;FunctorAlternative&amp;gt;-semicolon-sep-list&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;Alignment&amp;gt;:&lt;br /&gt;
    align &amp;lt;IntegralConstantExpression&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here &amp;lt;vpbnf&amp;gt;&amp;lt;IntegralConstantExpression&amp;gt;&amp;lt;/vpbnf&amp;gt; is an expression, which must be compile time evaluated to an integral value.&lt;br /&gt;
&lt;br /&gt;
A compound domain declaration declares a list of functor alternatives with optional alignment. Alignment must be &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;2&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;4&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If a compound domain consists of one functor alternative, then it is considered as structure and has representation, which is binary compatible with the appropriate structure in language C.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;FunctorAlternative&amp;gt;: &lt;br /&gt;
    &amp;lt;FunctorName&amp;gt; &amp;lt;FunctorName&amp;gt; ( &amp;lt;FormalArgument&amp;gt;-comma-sep-list-opt )&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here &amp;lt;vpbnf&amp;gt;&amp;lt;FunctorName&amp;gt;&amp;lt;/vpbnf&amp;gt; is the name of a functor alternative it should be a {{lang2|Lexical_Elements|Identifiers|lower case identifier}}.&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;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here &amp;lt;vpbnf&amp;gt;&amp;lt;ArgumentName&amp;gt;&amp;lt;/vpbnf&amp;gt; can be any {{lang2|Lexical_Elements|Identifiers|upper case identifier}}. The compiler ignores it.&lt;br /&gt;
&lt;br /&gt;
Compound domains  have no subtype relations to any other domains.&lt;br /&gt;
&lt;br /&gt;
If a domain is defined as being equal to a compound domain, then these two domains are synonym types rather than subtypes. Meaning that they are just two different names for the same type.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    t1 = ff(); gg(integer, t1).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;t1&amp;lt;/vp&amp;gt; is a compound domain with two alternatives. The first alternative is the null-ary functor &amp;lt;vp&amp;gt;ff&amp;lt;/vp&amp;gt;, while the second alternative is the two-ary functor &amp;lt;vp&amp;gt;gg&amp;lt;/vp&amp;gt;, which takes an {{lang2|Built-in_entities|integer|integer}} and a term of the domain &amp;lt;vp&amp;gt;t1&amp;lt;/vp&amp;gt; itself as arguments. So the domain &amp;lt;vp&amp;gt;t1&amp;lt;/vp&amp;gt; is recursively defined.&lt;br /&gt;
&lt;br /&gt;
The following expressions are terms of the domain &amp;lt;vp&amp;gt;t1&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;ff()&lt;br /&gt;
gg(77, ff())&lt;br /&gt;
gg(33, gg(44, gg(55, ff())))&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;domains &lt;br /&gt;
    t1 = ff(); gg(t2). &lt;br /&gt;
    t2 = hh(t1, t1).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;t1&amp;lt;/vp&amp;gt; is a compound domain with two alternatives. The first alternative is the null-ary functor &amp;lt;vp&amp;gt;ff&amp;lt;/vp&amp;gt;, while the second alternative is the unary functor &amp;lt;vp&amp;gt;gg&amp;lt;/vp&amp;gt;, which takes a term of the domain &amp;lt;vp&amp;gt;t2&amp;lt;/vp&amp;gt; as argument. &amp;lt;vp&amp;gt;t2&amp;lt;/vp&amp;gt; is a compound domain with one alternative the functor &amp;lt;vp&amp;gt;hh&amp;lt;/vp&amp;gt;, which takes two &amp;lt;vp&amp;gt;t1&amp;lt;/vp&amp;gt; terms as argument. So the domains &amp;lt;vp&amp;gt;t1&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;t2&amp;lt;/vp&amp;gt; are mutually recursive.&lt;br /&gt;
&lt;br /&gt;
The following are terms in the domain &amp;lt;vp&amp;gt;t1&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;ff() &lt;br /&gt;
gg(hh(ff(), ff())) &lt;br /&gt;
gg(hh(gg(hh(ff(), ff())), ff())) &lt;br /&gt;
ggg(hh(ff(), g(hh(ff(), ff())))) &lt;br /&gt;
gg(hh(gg(hh(ff(), ff())), gg(hh(ff(), ff()))))&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&lt;br /&gt;
In this example &amp;lt;vp&amp;gt;t1&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;t2&amp;lt;/vp&amp;gt; are synonym types.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains &lt;br /&gt;
    t1 = f(); g(integer). &lt;br /&gt;
    t2 = t1.&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Normally, it is not necessary to use empty parenthesis after null-ary functors. But in a domain definition consisting only of a single null-ary functor, empty parenthesis are required to distinguish it from a synonym/subtype definition.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vp&amp;gt;t1&amp;lt;/vp&amp;gt; is a compound domain with a single null-ary functor, whereas &amp;lt;vp&amp;gt;t2&amp;lt;/vp&amp;gt; is defined to be synonym to &amp;lt;vp&amp;gt;t1&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains &lt;br /&gt;
    t1 = f(). &lt;br /&gt;
    t2 = t1.&amp;lt;/vip&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== List Domains ====&lt;br /&gt;
&lt;br /&gt;
List domains represent sequences of values of a certain domain. Thus, all elements in a &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt; list must be of type &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;ListDomain&amp;gt;:&lt;br /&gt;
    &amp;lt;TypeName&amp;gt; *&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;T*&amp;lt;/vp&amp;gt; is the type of lists of &amp;lt;vp&amp;gt;T&amp;lt;/vp&amp;gt; elements.&lt;br /&gt;
&lt;br /&gt;
The following syntax is used for lists:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;ListExpression&amp;gt;:&lt;br /&gt;
    [ &amp;lt;Term&amp;gt;-comma-sep-list-opt ]&lt;br /&gt;
    [ &amp;lt;Term&amp;gt;-comma-sep-list | &amp;lt;Tail&amp;gt; ]&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;Tail&amp;gt;:&lt;br /&gt;
    &amp;lt;Term&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here &amp;lt;vpbnf&amp;gt;&amp;lt;Tail&amp;gt;&amp;lt;/vpbnf&amp;gt; is a term which should have a value of the &amp;lt;vpbnf&amp;gt;&amp;lt;ListDomain&amp;gt;&amp;lt;/vpbnf&amp;gt; type. Each &amp;lt;vpbnf&amp;gt;&amp;lt;Term&amp;gt;&amp;lt;/vpbnf&amp;gt; should be of {{lang2|Domains|Type_Names|typeName}} type.&lt;br /&gt;
&lt;br /&gt;
Actually, lists are just compound domains with two functors: &amp;lt;vp&amp;gt;[]&amp;lt;/vp&amp;gt; denoting the empty list and the mix-fix functor &amp;lt;vp&amp;gt;[HD|TL]&amp;lt;/vp&amp;gt; denoting the list with head &amp;lt;vp&amp;gt;HD&amp;lt;/vp&amp;gt; and tail &amp;lt;vp&amp;gt;TL&amp;lt;/vp&amp;gt;. The head must be of the underlying element type, whereas the tail must be a list of relevant type.&lt;br /&gt;
&lt;br /&gt;
Lists are however syntactically sugared.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;[E1, E2, E3, ..., En | L ]&amp;lt;/vp&amp;gt; is shorthand for &amp;lt;vp&amp;gt;[E1 |[ E2 |[ ...[ En | L ]...}}]&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;[E1, E2, E3, ..., En]&amp;lt;/vp&amp;gt; is shorthand for &amp;lt;vp&amp;gt;[E1, E2, E3, ..., En |[}}&amp;lt;/vp&amp;gt;, which in turn is shorthand for &amp;lt;vp&amp;gt;[E1 |[ E2 |[ ...[ En | [] ]...}}]&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Predicate Domains ====&lt;br /&gt;
&lt;br /&gt;
Values of a predicate domain are predicates with the same &amp;quot;signature&amp;quot;, i.e. the same argument and return types, the same flow pattern and the same (or stronger) predicate mode.&lt;br /&gt;
&lt;br /&gt;
A predicate that returns a value is called a &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;function&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;, whereas a predicate that does not return a value is sometimes called an &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;ordinary&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; predicate, to stress that it is not a function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;PredicateDomain&amp;gt;:&lt;br /&gt;
   ( &amp;lt;FormalArgument&amp;gt;-comma-sep-list-opt ) &amp;lt;ReturnArgument&amp;gt;-opt &lt;br /&gt;
   &amp;lt;PredicateModeAndFlow&amp;gt;-list-opt &amp;lt;CallingConvention&amp;gt;-opt&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;FormalArgument&amp;gt;:&lt;br /&gt;
   &amp;lt;PredicateArgumentType&amp;gt; &amp;lt;VariableName&amp;gt;-opt&lt;br /&gt;
   &amp;lt;Ellipsis&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;ReturnArgument&amp;gt;:&lt;br /&gt;
    -&amp;gt; &amp;lt;FormalArgument&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;PredicateArgumentType&amp;gt;:&lt;br /&gt;
   &amp;lt;TypeName&amp;gt;&lt;br /&gt;
   &amp;lt;AnonymousIdentifier&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;VariableName&amp;gt;:&lt;br /&gt;
   &amp;lt;UpperCaseIdentifier&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Predicate domains can have &amp;lt;vpbnf&amp;gt;&amp;lt;Ellipsis&amp;gt;&amp;lt;/vpbnf&amp;gt; argument as the last &amp;lt;vpbnf&amp;gt;&amp;lt;FormalArgument&amp;gt;&amp;lt;/vpbnf&amp;gt; in the &amp;lt;vpbnf&amp;gt;&amp;lt;FormalArgument&amp;gt;-comma-sep-list&amp;lt;/vpbnf&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Predicate domains can have &amp;lt;vpbnf&amp;gt;&amp;lt;AnonymousIdentifier&amp;gt;&amp;lt;/vpbnf&amp;gt; as a {{lang2|Domains|Type_Expressions|predicateArgumentType}} to specify that the argument can be of any type.&lt;br /&gt;
&lt;br /&gt;
Currently, predicate domains with ellipsis can only be used in predicate declarations.&lt;br /&gt;
&lt;br /&gt;
Predicate domains that are used in domain definitions can at most state one flow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;PredicateModeAndFlow&amp;gt;:&lt;br /&gt;
     &amp;lt;PredicateMode&amp;gt;-opt&lt;br /&gt;
     &amp;lt;FlowPattern&amp;gt;-list-opt&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Predicate Mode =====&lt;br /&gt;
&lt;br /&gt;
The specified predicate mode applies for each member of a flow pattern list following it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;PredicateMode&amp;gt;: one of&lt;br /&gt;
   erroneous &lt;br /&gt;
   failure &lt;br /&gt;
   procedure &lt;br /&gt;
   determ &lt;br /&gt;
   multi &lt;br /&gt;
   nondeterm&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Predicate modes can be described by the following sets:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;erroneous = {} &lt;br /&gt;
failure = {Fail} &lt;br /&gt;
procedure = {Succeed} &lt;br /&gt;
determ = {Fail, Succeed} &lt;br /&gt;
multi = {Succeed, BacktrackPoint} &lt;br /&gt;
nondeterm = {Fail, Succeed, BacktrackPoint}&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;#039;&amp;#039;Fail&amp;#039;&amp;#039; is in the set it means that the predicate can fail. If &amp;#039;&amp;#039;succeed&amp;#039;&amp;#039; is in the set it means that the predicate can succeed. If &amp;#039;&amp;#039;BacktrackPoint&amp;#039;&amp;#039; is in the set it means that the predicate can return with an active backtrack point in it.&lt;br /&gt;
&lt;br /&gt;
If such a set, say &amp;lt;vp&amp;gt;failure&amp;lt;/vp&amp;gt;, is a subset of another set, say &amp;lt;vp&amp;gt;nondeterm&amp;lt;/vp&amp;gt;, then we say that the mode is stronger than the other, i.e. &amp;lt;vp&amp;gt;failure&amp;lt;/vp&amp;gt; is stronger than &amp;lt;vp&amp;gt;nondeterm&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A predicate domain actually contain all predicates (with correct type and flow), which have the mode specified or a &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;stronger&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; mode.&lt;br /&gt;
&lt;br /&gt;
It is illegal to state a predicate mode for constructors, they always have the &amp;lt;vp&amp;gt;procedure&amp;lt;/vp&amp;gt; mode.&lt;br /&gt;
&lt;br /&gt;
Omitting of a predicate mode means &amp;lt;vp&amp;gt;procedure&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Omitting of flows means that all arguments are input.&lt;br /&gt;
&lt;br /&gt;
Notice that, in difference to Visual Prolog v. 5.x, inside implementations (i.e. for a local predicates) the needed flows and modes &amp;#039;&amp;#039;&amp;#039;are NOT derived from the usages of the predicate&amp;#039;&amp;#039;&amp;#039;. Now in declarations of for local predicates omitting the predicate mode means &amp;lt;vp&amp;gt;procedure&amp;lt;/vp&amp;gt; and omitting flows means that all arguments are input.&lt;br /&gt;
&lt;br /&gt;
If inside an implementation you do not want to specify all possible flows of a predicate usage explicitly, you still can deliver this duty to the compiler. For this task inside class implementations you can use the special flow pattern &amp;lt;vp&amp;gt;anyflow&amp;lt;/vp&amp;gt;. In this case the compiler during the compilation will derive the needed flows from usages of the predicate. But if the optional preceding predicate mode is omitted before the &amp;lt;vp&amp;gt;anyflow&amp;lt;/vp&amp;gt; flow pattern, then the &amp;lt;vp&amp;gt;procedure mode&amp;lt;/vp&amp;gt; is always assumed.&lt;br /&gt;
&lt;br /&gt;
===== Flow Pattern =====&lt;br /&gt;
&lt;br /&gt;
The flow pattern defines the input/output direction of the arguments, which in combination with functor domains can be structures with parts of a single argument being input and other parts of the same argument being output.&lt;br /&gt;
&lt;br /&gt;
A flow pattern consists of a sequence of flows, each flow corresponds to an argument (fist flow to first argument, etc).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;FlowPattern&amp;gt;:&lt;br /&gt;
     ( &amp;lt;Flow&amp;gt;-comma-sep-list-opt ) AnyFlow&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;Flow&amp;gt;: one of&lt;br /&gt;
    i&lt;br /&gt;
    o &lt;br /&gt;
    &amp;lt;FunctorFlow&amp;gt;&lt;br /&gt;
    &amp;lt;ListFlow&amp;gt;&lt;br /&gt;
    &amp;lt;Ellipsis&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ellipsis flow must match an ellipsis argument and can therefore be only the last flow in the flow pattern.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;Ellipsis&amp;gt;:&lt;br /&gt;
    ...&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A functor flow &amp;lt;vpbnf&amp;gt;&amp;lt;FunctorFlow&amp;gt;&amp;lt;/vpbnf&amp;gt; states a functor and flows of each of the components of that flow. The functor must of course be in the domain of the corresponding argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;FunctorFlow&amp;gt;:&lt;br /&gt;
    &amp;lt;FunctorName&amp;gt; ( &amp;lt;Flow&amp;gt;-comma-sep-list-opt )&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A functor flow declaration cannot contain ellipsis flow.&lt;br /&gt;
&lt;br /&gt;
List flows are just like functor flows, but with the same syntactic sugaring as the list domain.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;ListFlow&amp;gt;:&lt;br /&gt;
    [ &amp;lt;Flow&amp;gt;-comma-sep-list-opt &amp;lt;ListFlowTail&amp;gt;-opt]&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;ListFlowTail&amp;gt;:&lt;br /&gt;
    | &amp;lt;Flow&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A list flow cannot contain ellipsis flow.&lt;br /&gt;
&lt;br /&gt;
When declaring a predicate the flow can be omitted. Inside an implementation (i.e. for a local predicate) the needed flows are derived from the usages of the predicate. Inside an interface or a class declaration (i.e. for a public predicate) omitting flows means that all arguments are input.&lt;br /&gt;
&lt;br /&gt;
Special flow pattern &amp;lt;vp&amp;gt;anyflow&amp;lt;/vp&amp;gt; can be stated only in declarations of local predicates (i.e. in predicate declarations inside the implementation of a class). It means that the exact flow pattern will be evaluated during the compilation. If the optional preceding predicate mode is omitted for this flow pattern, then it assumes to be a &amp;lt;vp&amp;gt;procedure&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    pp1 = (integer Argument1).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;pp1&amp;lt;/vp&amp;gt; is a predicate domain. The predicates that have type &amp;lt;vp&amp;gt;pp1&amp;lt;/vp&amp;gt; takes one {{lang2|Built-in_entities|integer|integer}} argument. Since no flow-pattern is stated the argument is input, and since no predicate mode is mentioned the predicates are &amp;lt;vp&amp;gt;procedure&amp;lt;/vp&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    pp2 = (integer Argument1) -&amp;gt; integer ReturnType.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Predicates of type &amp;lt;vp&amp;gt;pp2&amp;lt;/vp&amp;gt; take one {{lang2|Built-in_entities|integer|integer}} argument and returns a value of type {{lang2|Built-in_entities|integer|integer}}. Therefore, &amp;lt;vp&amp;gt;pp2&amp;lt;/vp&amp;gt; is actually a function domain and the predicates that have type &amp;lt;vp&amp;gt;pp2&amp;lt;/vp&amp;gt; are actually functions. Since no flow-pattern is stated the argument is input and since no predicate mode is mentioned the predicates are &amp;lt;vp&amp;gt;procedure&amp;lt;/vp&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    ppp : (integer Argument1, integer Argument2) determ (o,i) (i,o) nondeterm (o,o).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The predicate &amp;lt;vp&amp;gt;ppp&amp;lt;/vp&amp;gt; takes two {{lang2|Built-in_entities|integer|integer}} arguments. It exists in three flow variants: &amp;lt;vp&amp;gt;(o,i)&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;(i,o)&amp;lt;/vp&amp;gt;, which are &amp;lt;vp&amp;gt;determ&amp;lt;/vp&amp;gt;, and &amp;lt;vp&amp;gt;(o,o)&amp;lt;/vp&amp;gt;, which is &amp;lt;vp&amp;gt;nondeterm&amp;lt;/vp&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Calling Convention =====&lt;br /&gt;
&lt;br /&gt;
The calling convention determines how arguments, etc. are passed to the predicate, it also determines how the link name is derived from a predicate name.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;CallingConvention&amp;gt;:&lt;br /&gt;
     language &amp;lt;CallingConventionKind&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;CallingConventionKind&amp;gt;: one of&lt;br /&gt;
     c stdcall apicall prolog&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a calling convention is not stated, then the &amp;lt;vp&amp;gt;prolog&amp;lt;/vp&amp;gt; convention is assumed. The &amp;lt;vp&amp;gt;prolog&amp;lt;/vp&amp;gt; calling convention is the standard convention used for Prolog predicates.&lt;br /&gt;
&lt;br /&gt;
The calling convention &amp;lt;vp&amp;gt;c&amp;lt;/vp&amp;gt; follows the C/C++ standard calling convention. The link name of a predicate is created from the predicate name by adding a leading underscore (&amp;lt;vp&amp;gt;_&amp;lt;/vp&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
The calling convention &amp;lt;vp&amp;gt;stdcall&amp;lt;/vp&amp;gt; uses the &amp;lt;vp&amp;gt;c&amp;lt;/vp&amp;gt; link name strategy but it uses the different argument and stack handling rules. The following table shows the implementation of &amp;lt;vp&amp;gt;stdcall&amp;lt;/vp&amp;gt; calling convention:&lt;br /&gt;
&lt;br /&gt;
{|{{prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
!Feature&lt;br /&gt;
!Implementation&lt;br /&gt;
|-&lt;br /&gt;
|Argument-passing order&lt;br /&gt;
|Right to left.&lt;br /&gt;
|-&lt;br /&gt;
|Argument-passing convention&lt;br /&gt;
|By value, unless a compound domain term is passed. So it cannot be used to predicates with variable number of arguments.&lt;br /&gt;
|-&lt;br /&gt;
|Stack-maintenance responsibility&lt;br /&gt;
|Called predicate pops its own arguments from the stack.&lt;br /&gt;
|-&lt;br /&gt;
|Name-decoration convention&lt;br /&gt;
|An underscore (&amp;lt;vp&amp;gt;_&amp;lt;/vp&amp;gt;) is prefixed to the predicate name.&lt;br /&gt;
|-&lt;br /&gt;
|Case-translation convention&lt;br /&gt;
|No case translation of the predicate name is performed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The calling convention &amp;lt;vp&amp;gt;apicall&amp;lt;/vp&amp;gt; uses the same argument and stack handling rules as &amp;lt;vp&amp;gt;stdcall&amp;lt;/vp&amp;gt;, but for convenience to call MS Windows API functions &amp;lt;vp&amp;gt;apicall&amp;lt;/vp&amp;gt; uses the naming conventions that are used by most MS Windows API functions. According to &amp;lt;vp&amp;gt;apicall&amp;lt;/vp&amp;gt; naming conventions the link name of a predicate is constructed as follows:&lt;br /&gt;
&lt;br /&gt;
*an leading underscore (&amp;lt;vp&amp;gt;_&amp;lt;/vp&amp;gt;) is prefixed to the predicate name;&lt;br /&gt;
*the predicate name in which the first letter is changed in to a capital letter;&lt;br /&gt;
*the &amp;#039;&amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt;&amp;#039;, the &amp;#039;&amp;lt;vp&amp;gt;W&amp;lt;/vp&amp;gt;&amp;#039; or nothing is suffixed, if the arguments and the return type indicate an ANSI, Unicode or neutral predicate, respectively;&lt;br /&gt;
*the &amp;#039;&amp;lt;vp&amp;gt;@&amp;lt;/vp&amp;gt;&amp;#039; is suffixed;&lt;br /&gt;
*the number of bytes pushed on the call stack is suffixed.&lt;br /&gt;
&lt;br /&gt;
{{Example|&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
     predicateName : (integer, string) language apicall&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The argument types of this predicate indicates that it is a Unicode predicate (as {{lang2|Built-in_entities|string|string}} is the domain of Unicode strings). An {{lang2|Built-in_entities|integer|integer}} and a {{lang2|Built-in_entities|string|string}} each occupies 4 bytes on the call stack and, therefore, the link name becomes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;_PredicateNameW@8&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;vp&amp;gt;apicall&amp;lt;/vp&amp;gt; is used together with the &amp;quot;&amp;lt;vp&amp;gt;as&amp;lt;/vp&amp;gt;&amp;quot; construction the name stated in the &amp;quot;&amp;lt;vp&amp;gt;as&amp;lt;/vp&amp;gt;&amp;quot; construction is decorated in the same manner.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;apicall&amp;lt;/vp&amp;gt; can only be used directly in a predicate declaration, not in a predicate domain definition. In predicate domain definitions &amp;lt;vp&amp;gt;stdcall&amp;lt;/vp&amp;gt;, must be used instead.&lt;br /&gt;
&lt;br /&gt;
The following table compares implementations of &amp;lt;vp&amp;gt;c&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;apicall&amp;lt;/vp&amp;gt;, and &amp;lt;vp&amp;gt;stdcall&amp;lt;/vp&amp;gt; calling conventions (the &amp;lt;vp&amp;gt;prolog&amp;lt;/vp&amp;gt; calling convention has the special implementation, which is not discussed here):&lt;br /&gt;
&lt;br /&gt;
{|{{prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
!Keyword&lt;br /&gt;
!Stack cleanup&lt;br /&gt;
!Predicate name case-translation&lt;br /&gt;
!Link predicate name decoration convention&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;vp&amp;gt;c&amp;lt;/vp&amp;gt;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;Calling&amp;#039;&amp;#039;&amp;#039; predicate pops the arguments from the stack.&lt;br /&gt;
|None.&lt;br /&gt;
|An underscore (&amp;lt;vp&amp;gt;_&amp;lt;/vp&amp;gt;) is prefixed to the predicate name.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;vp&amp;gt;stdcall&amp;lt;/vp&amp;gt;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;Called&amp;#039;&amp;#039;&amp;#039; predicate pops its own arguments from the stack.&lt;br /&gt;
|None.&lt;br /&gt;
|An underscore (&amp;lt;vp&amp;gt;_&amp;lt;/vp&amp;gt;) is prefixed to the predicate name.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;vp&amp;gt;apicall&amp;lt;/vp&amp;gt;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;Called&amp;#039;&amp;#039;&amp;#039; predicate pops its own arguments from the stack.&lt;br /&gt;
|The first letter of the predicate name is changed to the capital letter.&lt;br /&gt;
|An underscore (&amp;lt;vp&amp;gt;_&amp;lt;/vp&amp;gt;) is prefixed to the name. The first letter is changed to the upper case. The &amp;#039;&amp;lt;vp&amp;gt;A&amp;lt;/vp&amp;gt;&amp;#039;, the &amp;#039;&amp;lt;vp&amp;gt;W&amp;lt;/vp&amp;gt;&amp;#039; or nothing is suffixed. The sign &amp;lt;vp&amp;gt;@&amp;lt;/vp&amp;gt; is suffixed. The (decimal) number of bytes in the argument list is suffixed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Visual Prolog notion of predicate domains covers both class and object members. Class members are handled straight forward, but the handling of object members requires attention. The invocation of an object predicate will get &amp;quot;back&amp;quot; in the context of the object to which the member belongs.&lt;br /&gt;
&lt;br /&gt;
{{Example| Assume the following declarations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface actionEventSource&lt;br /&gt;
domains&lt;br /&gt;
     actionListener = (actionEventSource Source) procedure (i).&lt;br /&gt;
predicates&lt;br /&gt;
     addActionListener : (actionListener Listener) procedure (i).&lt;br /&gt;
     ... end interface&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also assume a class &amp;lt;vp&amp;gt;button_class&amp;lt;/vp&amp;gt; which supports the &amp;lt;vp&amp;gt;actionEventSource&amp;lt;/vp&amp;gt;. The event is sent when the button is pressed. In &amp;lt;vp&amp;gt;myDialog_class&amp;lt;/vp&amp;gt; class, which implements a dialog, I create a button and I want to listen to its action events, so that I can react on button presses:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;implement myDialog_class &lt;br /&gt;
clauses&lt;br /&gt;
    new() :-&lt;br /&gt;
        OkButton = button_class::new(...),&lt;br /&gt;
        OkButton:addActionListener(onOk),&lt;br /&gt;
        ...&lt;br /&gt;
facts&lt;br /&gt;
    okPressed : () determ.&lt;br /&gt;
predicates&lt;br /&gt;
    onOk : actionListener.&lt;br /&gt;
clauses&lt;br /&gt;
    onOk(Source) :-&lt;br /&gt;
        assert(okPressed()).&lt;br /&gt;
end implement&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The important thing about the example is that &amp;lt;vp&amp;gt;onOk&amp;lt;/vp&amp;gt; is an object member and that, when the button is pressed, the invocation of the registered &amp;lt;vp&amp;gt;onOk&amp;lt;/vp&amp;gt; will bring us back in the object that owns &amp;lt;vp&amp;gt;onOk&amp;lt;/vp&amp;gt;. This means that we have access to the object fact &amp;lt;vp&amp;gt;okPressed&amp;lt;/vp&amp;gt;, so that we can assert it.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Format Strings =====&lt;br /&gt;
&lt;br /&gt;
A formal parameter to a predicate can be marked as format string using the attribute &amp;lt;vp&amp;gt;formatstring&amp;lt;/vp&amp;gt;. The format string can contain ordinary characters which are printed without modification, and format fields, that % begins with the percent &amp;#039;%&amp;#039; sign. If the percent sign is followed % by some unknown character (not the format specifier) - then % this character will  be printed without modifications.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
     writef : (string Format [formatstring], ...)   procedure (i,...).&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 a procedure parameter.&lt;br /&gt;
|-&lt;br /&gt;
| s || Format as a string.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Integral Domains ====&lt;br /&gt;
&lt;br /&gt;
Integral domains are used for representing integral numbers. They are divided in two main categories for signed and unsigned numbers. Integral domains can also have different representation size. The predefined domains {{lang2|Built-in_entities|integer|integer}} and {{lang2|Built-in_entities|unsigned|unsigned}} represent signed and unsigned numbers with natural representation length for the processor architecture (i.e. 32bit on a 32bit machine, etc).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;IntegralDomain&amp;gt;:&lt;br /&gt;
     &amp;lt;DomainName&amp;gt;-opt &amp;lt;IntegralDomainProperties&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a &amp;lt;vpbnf&amp;gt;&amp;lt;DomainName&amp;gt;&amp;lt;/vpbnf&amp;gt; is stated in front of the &amp;lt;vpbnf&amp;gt;&amp;lt;IntegralDomainProperties&amp;gt;&amp;lt;/vpbnf&amp;gt;, then this domain must itself be an integral domain and the resulting domain will be child-type (i.e. subtype) of this domain. In that case &amp;lt;vpbnf&amp;gt;&amp;lt;IntegralDomainProperties&amp;gt;&amp;lt;/vpbnf&amp;gt; may not violate the possibility of being a subtype, i.e. the range cannot be extended and the size cannot be changed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;IntegralDomainProperties&amp;gt;:&lt;br /&gt;
    &amp;lt;IntegralSizeDescription&amp;gt; &amp;lt;IntegralRangeDescription&amp;gt;-opt&lt;br /&gt;
    &amp;lt;IntegralRangeDescription&amp;gt; &amp;lt;IntegralSizeDescription&amp;gt;-opt&lt;br /&gt;
&lt;br /&gt;
&amp;lt;IntegralSizeDescription&amp;gt;:&lt;br /&gt;
    bitsize &amp;lt;DomainSize&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;DomainSize&amp;gt;: &lt;br /&gt;
    &amp;lt;IntegralConstantExpression&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An integral size description declares the size &amp;lt;vpbnf&amp;gt;&amp;lt;DomainSize&amp;gt;&amp;lt;/vpbnf&amp;gt; of the integral domain, measured in bits. The compiler implement such representation to the integral domain, which has no less than the specified number of bits. The value of &amp;lt;vpbnf&amp;gt;&amp;lt;DomainSize&amp;gt;&amp;lt;/vpbnf&amp;gt; should be positive and no greater than the maximal value supported by the compiler (in versions 6.x this is 32).&lt;br /&gt;
&lt;br /&gt;
If integral size description is omitted, then it will become the same as the parent domain. If there is no parent domain, it will become the natural size for the processor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;IntegralRangeDescription&amp;gt;:&lt;br /&gt;
    [ &amp;lt;MinimalBoundary&amp;gt;-opt .. &amp;lt;MaximalBoundary&amp;gt;-opt ]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;MinimalBoundary&amp;gt;:&lt;br /&gt;
    &amp;lt;IntegralConstantExpression&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;MaximalBoundary&amp;gt;: &lt;br /&gt;
    &amp;lt;IntegralConstantExpression&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An integral range description declares the minimal &amp;lt;vpbnf&amp;gt;&amp;lt;MinimalBoundary&amp;gt;&amp;lt;/vpbnf&amp;gt; and the maximal &amp;lt;vpbnf&amp;gt;&amp;lt;MaximalBoundary&amp;gt;&amp;lt;/vpbnf&amp;gt; limits for the integral domain. If a limit is omitted, then the range of the parent domain is used. If there is no parent domain, then the &amp;lt;vpbnf&amp;gt;&amp;lt;DomainSize&amp;gt;&amp;lt;/vpbnf&amp;gt; is used to determine respectively maximum or minimum value.&lt;br /&gt;
&lt;br /&gt;
Notice that the specified minimum value should not exceed the specified maximum value. That is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;MinimalBoundary&amp;gt; &amp;lt;= &amp;lt;MaximalBoundary&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also the minimal &amp;lt;vpbnf&amp;gt;&amp;lt;MinimalBoundary&amp;gt;&amp;lt;/vpbnf&amp;gt; and the maximal &amp;lt;vpbnf&amp;gt;&amp;lt;MaximalBoundary&amp;gt;&amp;lt;/vpbnf&amp;gt; limits should satisfy the limits implied by the specified bit size &amp;lt;vp&amp;gt;bitsize&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The domain bit size &amp;lt;vpbnf&amp;gt;&amp;lt;DomainSize&amp;gt;&amp;lt;/vpbnf&amp;gt; value and values of the minimal &amp;lt;vpbnf&amp;gt;&amp;lt;MinimalBoundary&amp;gt;&amp;lt;/vpbnf&amp;gt; and the maximal &amp;lt;vpbnf&amp;gt;&amp;lt;MaximalBoundary&amp;gt;&amp;lt;/vpbnf&amp;gt; limits must be calculated while compiling time.&lt;br /&gt;
&lt;br /&gt;
==== Real Domains ====&lt;br /&gt;
&lt;br /&gt;
Real domains are used to represent numbers with fractional parts (i.e. floating point numbers). Real domains can be used to represent very large and very small numbers. The built-in domain &amp;#039;&amp;#039;real&amp;#039;&amp;#039; have the natural precision for the processor architecture (or the precision given by the compiler).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;RealDomain&amp;gt;:&lt;br /&gt;
     &amp;lt;DomainName&amp;gt;-opt &amp;lt;RealDomainProperties&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a &amp;lt;vpbnf&amp;gt;&amp;lt;DomainName&amp;gt;&amp;lt;/vpbnf&amp;gt; is stated in front of the &amp;lt;vpbnf&amp;gt;&amp;lt;RealDomainProperties&amp;gt;&amp;lt;/vpbnf&amp;gt;, then this domain must itself be a real domain and the resulting domain will be a subtype of this domain. In that case &amp;lt;vpbnf&amp;gt;&amp;lt;RealDomainProperties&amp;gt;&amp;lt;/vpbnf&amp;gt; may not violate the possibility of being a subtype, i.e. the range cannot be extended and the precision cannot be increased.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;RealDomainProperties&amp;gt;: one of&lt;br /&gt;
    &amp;lt;RealPrecisionDescription&amp;gt; &amp;lt;RealRangeDescription&amp;gt;-opt&lt;br /&gt;
    &amp;lt;RealRangeDescription&amp;gt; &amp;lt;RealPrecisionDescription&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;RealPrecisionDescription&amp;gt;:&lt;br /&gt;
    digits &amp;lt;IntegralConstantExpression&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The real precision description declares precision of the real domain, measured in number of decimal digits. If precision is omitted then it will become the same as for the parent domain. If there is no parent domain, then it will be the natural precision for the processor or given by the compiler (in Visual Prolog v.6 the compiler limit is 15 digits). Precision have an upper and a lower limits given by the compiler, if the precisions larger than that limit is used the numbers will only obtain the processor (compiler) specified precision anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;RealRangeDescription&amp;gt;:&lt;br /&gt;
    [ &amp;lt;MinimalRealBoundary&amp;gt;-opt .. &amp;lt;MaximalRealBoundary&amp;gt;-opt ]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;MinimalRealBoundary&amp;gt;:&lt;br /&gt;
    &amp;lt;RealConstantExpression&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;MaximalRealBoundary&amp;gt;: &lt;br /&gt;
    &amp;lt;RealConstantExpression&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here &amp;lt;vpbnf&amp;gt;&amp;lt;RealConstantExpression&amp;gt;&amp;lt;/vpbnf&amp;gt; is an expression, which must be compile time evaluated to a floating point value. That is the real domain precision and limits must be calculated while compiling time.&lt;br /&gt;
&lt;br /&gt;
The real range description declares minimal and maximal limits for the real domain. If a limit is omitted then it will be the same as for the parent domain. If there is no parent domain then the largest possible range for the precision will be used.&lt;br /&gt;
&lt;br /&gt;
Notice that the specified minimum value should not exceed the specified maximum value. That is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;MinimalBoundary&amp;gt; &amp;lt;= &amp;lt;MaximalBoundary&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generic Domains ====&lt;br /&gt;
&lt;br /&gt;
This section contains the formal syntax for generic domains, for a more complete introduction to generics please see the section &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; Generics&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;FormalTypeParameterList&amp;gt;:&lt;br /&gt;
     &amp;lt;TypeVariable&amp;gt;-comma-sep-list-opt&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A formalTypeParameterList is a list of typeVariables&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;TypeVariable&amp;gt;:&lt;br /&gt;
    &amp;lt;UpperCaseIdentifier&amp;gt;&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;vpbnf&amp;gt;&amp;lt;TypeVariable&amp;gt;&amp;lt;/vpbnf&amp;gt; is an upper case identifier. In a domain declaration the type variable must be bound in the &amp;lt;vpbnf&amp;gt;&amp;lt;FormalTypeParameterList&amp;gt;&amp;lt;/vpbnf&amp;gt; on the left hand side of the domain definition. In a predicate declaration all free type variables are implicitly bound and scoped to that predicate declaration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vipbnf&amp;gt;&amp;lt;TypeApplication&amp;gt;:&lt;br /&gt;
     &amp;lt;TypeName&amp;gt; {&amp;lt;TypeExpression&amp;gt;-comma-sep-list-opt }&amp;lt;/vipbnf&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;vpbnf&amp;gt;&amp;lt;TypeApplication&amp;gt;&amp;lt;/vpbnf&amp;gt; is the application of a {{lang2|Domains|Type_Names|typeName}} to a list of types. The type name must be generic and the number of formal type parameters must match the number of type expressions.&lt;br /&gt;
&lt;br /&gt;
=== Universal and Root Types ===&lt;br /&gt;
&lt;br /&gt;
Visual Prolog uses some internal types, called &amp;#039;&amp;#039;root&amp;#039;&amp;#039; types and &amp;#039;&amp;#039;universal&amp;#039;&amp;#039; types.&lt;br /&gt;
&lt;br /&gt;
==== Universal Types ====&lt;br /&gt;
&lt;br /&gt;
A number literal like &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; does not have any particular type, it can be used as a value of any type that contains &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt;, including real types.&lt;br /&gt;
&lt;br /&gt;
We say that &amp;lt;vp&amp;gt;1&amp;lt;/vp&amp;gt; have a universal type. Having a universal type means that it have any type, which can represent its value.&lt;br /&gt;
&lt;br /&gt;
Arithmetic operations also return universal types.&lt;br /&gt;
&lt;br /&gt;
==== Root Types ====&lt;br /&gt;
&lt;br /&gt;
Arithmetic operations are very liberal with their operand requirements:  You can add integers of any integer domain with each other.&lt;br /&gt;
&lt;br /&gt;
We say that arithmetic operands takes root types as arguments.  The integer root type is super-type of any integer type (regardless that it is not mentioned in their declarations).  Hence any integer type can be converted to the integer root type, and, since the arithmetic operations exist for the root types, it means one of them will work on any integer domains.&lt;br /&gt;
&lt;br /&gt;
The actual number of root types and which operands exist is a matter of library facilities, and outside the scope of this document to describe.&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=1864</id>
		<title>VIP7 Construct examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=1864"/>
		<updated>2009-05-03T13:50:29Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Fact variables */ added zz_int for return value&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains a collection of basic examples for (mainly) the newer constructs found in VIP7.&lt;br /&gt;
&lt;br /&gt;
=== Fact variables ===&lt;br /&gt;
&lt;br /&gt;
Fact variables are the only mutable types in VIP.&lt;br /&gt;
&lt;br /&gt;
First, a reminder for ordinary facts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb_int : (integer).  % a nondeterministic fact (0 to any number of values)&lt;br /&gt;
    db_int : (integer,string) determ. % a deterministic fact (0 to 1 value)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These types of fact are asserted and retracted.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039; (fact variables)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    zz_int:integer := 0.&lt;br /&gt;
    zz_fred:integer := erroneous.&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    dom = dom(string,chaindb::ref).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    zz_dom : dom := erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        zz_int := 7,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;, zz_int), %will write &amp;quot;zz_int = 7&amp;quot;&lt;br /&gt;
        zz_int := zz_int+20,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;, zz_int), %will write &amp;quot;zz_int = 27&amp;quot;&lt;br /&gt;
        succeed.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fact variables are great for counting e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    how_many : () -&amp;gt; integer Count.&lt;br /&gt;
clauses&lt;br /&gt;
    how_many() = zz_int :-&lt;br /&gt;
        zz_int := 0,&lt;br /&gt;
        foreach some_nondeterm_fact_or_pred() do&lt;br /&gt;
            zz_int := zz_int+1&lt;br /&gt;
        end foreach.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
       stdio::write(&amp;quot;\n There are &amp;quot;, how_many(), &amp;quot; items&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lists - findall and list comprehension ===&lt;br /&gt;
&lt;br /&gt;
See [[Lists and Recursion]]&lt;br /&gt;
&amp;lt;vp&amp;gt;findall()&amp;lt;/vp&amp;gt; has been depricated, so use the list comprehension construct.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb : (integer). %default is nondeterm for a fact&lt;br /&gt;
clauses&lt;br /&gt;
    ndb(1).&lt;br /&gt;
    ndb(2).&lt;br /&gt;
    ndb(3).&lt;br /&gt;
    ....&lt;br /&gt;
    ndb(10).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_old() :-&lt;br /&gt;
        findall(X,ndb(X),List).&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_new() :-&lt;br /&gt;
        List = [X||ndb(X)].&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X&amp;gt;6].&lt;br /&gt;
        %results in List = [7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0].&lt;br /&gt;
        %results in List = [2,4,6,8,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0, X&amp;lt;7].&lt;br /&gt;
        %results in List = [2,4,6]&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        zz_int := 0,&lt;br /&gt;
        List = [X||ndb(X), X mod 2 = 0, X&amp;lt;7, zz_int := zz_int+1].&lt;br /&gt;
        %results in List = [2,4,6] and zz_int = 3.&lt;br /&gt;
&lt;br /&gt;
    pred_filter() :-&lt;br /&gt;
        List = [X||ndb(X), Y = pred2(X), Y&amp;gt;10].   %with pred2(X) = X^2.&lt;br /&gt;
        %results in List = [4,5,6,7,8,9,10]&lt;br /&gt;
        %reason - X = 3 gives Y = 9 which is &amp;lt; 10.&lt;br /&gt;
&lt;br /&gt;
    pred_other() :-&lt;br /&gt;
        L = [1,2,3,4,5,6,7,8,9,10],&lt;br /&gt;
        LIST = [ X || X = list::getMember_nd(L)].&lt;br /&gt;
        %results in List = L&lt;br /&gt;
&lt;br /&gt;
    pred_other() :-&lt;br /&gt;
        Primes = [X||X = std::fromto(1,300),&lt;br /&gt;
        L1 = [Y||Y = std::fromto(2,150)],&lt;br /&gt;
        tt(X,L1)].&lt;br /&gt;
        %results in List = prime numbers, with:&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
        tt : (integer,integer*) determ.&lt;br /&gt;
clauses&lt;br /&gt;
        tt(_X,[]) :- !.&lt;br /&gt;
        tt(X,[X|_]) :- !.&lt;br /&gt;
        tt(X,[Y|L]) :-&lt;br /&gt;
        X mod Y&amp;lt;&amp;gt;0,&lt;br /&gt;
        tt(X,L).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== if-then-else (code) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred(X,Y) = Z :-&lt;br /&gt;
        if X = 0 then&lt;br /&gt;
            Z = &amp;quot;x is zero&amp;quot;&lt;br /&gt;
        elseif X&amp;gt;0 then&lt;br /&gt;
            if pred3(Y) = true then&lt;br /&gt;
                Z = &amp;quot;x&amp;gt;0 and pred(Y) is true&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
                Z = &amp;quot;x&amp;gt;0 and pred(Y) is false&amp;quot;&lt;br /&gt;
            end if  %note, no comma here either&lt;br /&gt;
        else&lt;br /&gt;
            Z = &amp;quot;x &amp;lt;0&amp;quot;&lt;br /&gt;
        end if.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== #if #then #else (directive for conditional compilation) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;constants&lt;br /&gt;
    u64_con = 1.&lt;br /&gt;
    int_con = 2.&lt;br /&gt;
    real_con = 3.&lt;br /&gt;
&lt;br /&gt;
    compile_big_con = u64_con. %change this and then recompile.&lt;br /&gt;
&lt;br /&gt;
#if compile_big_con = u64_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : () -&amp;gt; unsigned64.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred() = U64 :-&lt;br /&gt;
            U64 = 78766.&lt;br /&gt;
&lt;br /&gt;
#elseif compile_big_con = int_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : () -&amp;gt; integer.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred() = Int :-&lt;br /&gt;
            Int = 20.&lt;br /&gt;
&lt;br /&gt;
#else&lt;br /&gt;
    predicates&lt;br /&gt;
        pred : (real [out]).&lt;br /&gt;
    clauses&lt;br /&gt;
        pred(0.766).&lt;br /&gt;
&lt;br /&gt;
#endif&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Code construct uses     &amp;lt;vp&amp;gt;if  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;elseif  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;else&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;end if&amp;lt;/vp&amp;gt;&lt;br /&gt;
compiler directive uses &amp;lt;vp&amp;gt;#if - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#elseif - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#else&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#endif&amp;lt;/vp&amp;gt;&lt;br /&gt;
(just the &amp;quot;end if&amp;quot; is &amp;quot;different&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Trap and try/catch/finally ===&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Try-catch-finally|Try-catch-finally]]&lt;br /&gt;
Note, in [[Language Reference/Built-in entities/Predicates|Built-in entities/Predicates]]&lt;br /&gt;
suggests using &amp;lt;vp&amp;gt;try-end try&amp;lt;/vp&amp;gt; instead of &amp;lt;vp&amp;gt;trap(_,_,_)&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_all() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    call_pred_that_might_crash : (integer).&lt;br /&gt;
    call_own_exception_pred : (pointer ErrorNo).&lt;br /&gt;
    always_call_this_anyway : ().&lt;br /&gt;
clauses&lt;br /&gt;
    call_pred_that_might_crash(X) :-&lt;br /&gt;
        Y = 9/X.&lt;br /&gt;
&lt;br /&gt;
    call_own_exception_pred(ErrorNo) :-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;crashed&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
    always_call_this_anyway() :-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;finally reached&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% in this case, VIP will automatically pop up its exception dialog&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 4&amp;#039;&amp;#039;&amp;#039; - illegal - it must have a &amp;lt;vp&amp;gt;catch&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;finally&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_illegal() :-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Foreach ===&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Foreach|Foreach]]&lt;br /&gt;
&lt;br /&gt;
=== 64 bit numbers - history ===&lt;br /&gt;
&lt;br /&gt;
Up to VIP7.1, integer64 etc were defined as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    unsigned64 = unsigned64(unsigned32 Low, unsigned32 High).&lt;br /&gt;
    integer64 = integer64(unsigned32 Low, integer32 High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In VIP7.2 these have been renamed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    unsigned64_struct = unsigned64(unsigned Low, unsigned High).&lt;br /&gt;
    integer64_struct = integer64(unsigned Low, integer High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, for example, in VIP7.1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
     getFileProperties : (&lt;br /&gt;
        string FileName,&lt;br /&gt;
        fileSystem_api::fileAttributes Attributes,&lt;br /&gt;
        fileSystem_api::fileSize Size,&lt;br /&gt;
        core::gmtTimeValue Creation,&lt;br /&gt;
        core::gmtTimeValue LastAccess,&lt;br /&gt;
        core::gmtTimeValue LastChange)&lt;br /&gt;
        procedure (i,o,o,o,o,o).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if you needed use (and write) &amp;#039;&amp;#039;&amp;#039;fileSize&amp;#039;&amp;#039;&amp;#039; and times, you would have to have done some juggling (such as converting them to real numbers).&lt;br /&gt;
&lt;br /&gt;
To generate a 64 bit random number:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates %before VIP7.2&lt;br /&gt;
    gen64 : () -&amp;gt; unsigned64.&lt;br /&gt;
clauses&lt;br /&gt;
    gen64() = U64 :-&lt;br /&gt;
        N = 2^32,&lt;br /&gt;
        Low = math::random(N+0),&lt;br /&gt;
        High = math::random(N+0),&lt;br /&gt;
        U64 = unsigned64(Low,High).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and possibly you would have needed (e.g.) &amp;#039;&amp;#039;&amp;#039;math::add&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    add : (core::unsigned64 Augend, core::unsigned64 Addend) -&amp;gt; core::unsigned64 Sum&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s now totally straightforward in VIP7.2 - just treat 64 bit numbers like any other number. You may also want these conversions - found in &amp;#039;&amp;#039;&amp;#039;core::&amp;#039;&amp;#039;&amp;#039; - for old code (this snippet is stolen from [http://discuss.visual-prolog.com/viewtopic.php?t=7927 Thomas&amp;#039; post])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    toUnsigned64 : (unsigned64_struct) -&amp;gt; unsigned64.&lt;br /&gt;
    fromUnsigned64 : (unsigned64) -&amp;gt; unsigned64_struct.&lt;br /&gt;
    toInteger64 : (integer64_struct) -&amp;gt; integer64.&lt;br /&gt;
    fromInteger64 : (integer64) -&amp;gt; integer64_struct.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And just for reference:&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#integer|integer]] range = -2^31 to +2^31-1 = -2147483648 .. 2147483647&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#unsigned|unsigned]]  range = 0 to (2^32)-1 = 4294967295&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#integer64|integer64]] range = -2^63 to 2^63&lt;br /&gt;
* [[Language Reference/Built-in_entities/Domains#unsigned64|unsigned64]] range = 0 to (2^64)-1 = 18446744073709551615 ( = 1.844..E19)&lt;br /&gt;
&lt;br /&gt;
=== Polymorphic Domains ===&lt;br /&gt;
&lt;br /&gt;
See [[Objects and Polymorphism]]&lt;br /&gt;
&lt;br /&gt;
First, check out the definitions - &amp;lt;vp&amp;gt;core::tuple{}&amp;lt;/vp&amp;gt;. And while you&amp;#039;re there, just below, see &amp;lt;vp&amp;gt;core::predicate{}&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;core::function{}&amp;lt;/vp&amp;gt;, then followed by &amp;lt;vp&amp;gt;comparator{A}&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;list{A}&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The domains in class &amp;lt;vp&amp;gt;list::&amp;lt;/vp&amp;gt; are polymorphic, but you can define your own polymorphic domains. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    poly_dom{A,B} = poly_def(A,B).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you use it in your code, A and B can be any other domain.  The domain name is &amp;lt;vp&amp;gt;poly_dom{A,B}&amp;lt;/vp&amp;gt;, and you reference it you must use its whole name (not just &amp;lt;vp&amp;gt;poly_dom&amp;lt;/vp&amp;gt;) e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    joe{A,B} = poly_dom{A,B}*.&lt;br /&gt;
/* the next two lines are illegal&lt;br /&gt;
    poly_dom{A,B} = poly_def(A,B)*.&lt;br /&gt;
    poly_dom{A,A} = poly_def(A,A).&lt;br /&gt;
*/&lt;br /&gt;
    fred{A,B} = fred(poly_dom{A,B},integer).&lt;br /&gt;
&lt;br /&gt;
    maybe_silly_dom{A,B} =&lt;br /&gt;
        silly2(A,B);&lt;br /&gt;
        silly(A);&lt;br /&gt;
        pd(poly_dom{A,B});&lt;br /&gt;
        poly_dom(A,B);%IS NOT THE SAME POLY_DOM!! (notice no braces)&lt;br /&gt;
        s(string).&lt;br /&gt;
&lt;br /&gt;
    another{A} =&lt;br /&gt;
        i(integer);&lt;br /&gt;
        s(string);&lt;br /&gt;
        a(A);&lt;br /&gt;
        self(another({A}).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    zz_poly_dom:poly_dom{integer,integer} := erroneous.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_morphic_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        zz_poly_dom := poly_def(1,5),&lt;br /&gt;
        call_pd(zz_poly_dom),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        PD = poly_def(1,[&amp;quot;an example&amp;quot;,&amp;quot;or two&amp;quot;]),&lt;br /&gt;
        call_pd(PD),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test() :-&lt;br /&gt;
        Q = [poly_def(X, Y) || X = std::fromTo(1, 4), Y = std::fromTo(1, 5)],&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,Q),&lt;br /&gt;
        fail.&lt;br /&gt;
    p_morphic_test().&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    call_pd : (poly_dom{A,B}).&lt;br /&gt;
clauses&lt;br /&gt;
    call_pd(POLY_DOM) :-&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,POLY_DOM),&lt;br /&gt;
        fail.&lt;br /&gt;
    call_pd(poly_def(A,B)) :- %note this is POLY_DEF&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,A,B),&lt;br /&gt;
        fail.&lt;br /&gt;
    call_pd(_).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Properties ===&lt;br /&gt;
&lt;br /&gt;
Properties in a class are used almost identically to fact variables, but properties can be set directly (from another class), without having to declare a public predicate to make the change.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface fred&lt;br /&gt;
    domains&lt;br /&gt;
        complete_dom = is_complete;&lt;br /&gt;
                     not_complete.&lt;br /&gt;
    properties&lt;br /&gt;
        prop_complete : complete_dom.&lt;br /&gt;
end interface fred&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;#039;&amp;#039;&amp;#039;fred.pro&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement fred&lt;br /&gt;
facts&lt;br /&gt;
    zz_complete:complete_dom := erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses %for the property&lt;br /&gt;
    prop_complete() = zz_complete. %get&lt;br /&gt;
    prop_complete(COMPLETE) :- zz_complete := COMPLETE. %set&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some other class that calls class fred:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;implement other&lt;br /&gt;
    open fred&lt;br /&gt;
clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        Fred = fred::new(),&lt;br /&gt;
        Fred:prop_complete := is_complete,% to set the value&lt;br /&gt;
        Value = Fred:prop_complete, !. %get&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comparators and compare ===&lt;br /&gt;
&lt;br /&gt;
First, look at the definition of &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    comparator{T} = function{T, T, compareResult}.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;compareResult&amp;lt;/vp&amp;gt;&amp;#039;s definition can is found here: [[Language Reference/Built-in entities/Domains#compareResult|compareResult]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
    p_compare_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(7,2).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;greater()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
        %(because 7 &amp;gt; 2)&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(2,2).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;equal()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        CompareResult = compare(&amp;quot;a&amp;quot;,&amp;quot;z&amp;quot;).&lt;br /&gt;
        %will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;less()&amp;#039;&amp;#039;&amp;#039;&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But you may wish to check your own domains to see which is &amp;quot;greater&amp;quot; - and of course you must define this yourself, by defining your own predicate as a &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Here is a simple domain in which only the integer parts of the variables are checked to see which is greater:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    s = s(string,integer).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    compare_it: core::comparator{s}.&lt;br /&gt;
clauses&lt;br /&gt;
    compare_it(A,B) = CompareResult :- %since this is a core::function(T,T,compareResult)&lt;br /&gt;
        A = s(_,I),&lt;br /&gt;
        B = s(_,J),&lt;br /&gt;
        if I&amp;lt;J then&lt;br /&gt;
            CompareResult = less()&lt;br /&gt;
        elseif I = J then&lt;br /&gt;
            CompareResult = equal()&lt;br /&gt;
        else&lt;br /&gt;
            CompareResult = greater()&lt;br /&gt;
        end if.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_compare_test : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_compare_test() :-&lt;br /&gt;
        S1 = s(&amp;quot;abc&amp;quot;,7),&lt;br /&gt;
        S2 = s(&amp;quot;fred&amp;quot;,9),&lt;br /&gt;
        CompareResult = compare_it(S1,S2),&lt;br /&gt;
        %will give CompareResult = less, since 7&amp;lt;9.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...a bit pointless since the string part of the variables have been ignored, but it is easy to see how to expand &amp;lt;vp&amp;gt;compare_it()&amp;lt;/vp&amp;gt; to your own needs.&lt;br /&gt;
&lt;br /&gt;
=== More on core::function and core::predicate ===&lt;br /&gt;
&lt;br /&gt;
Again, please check out &amp;lt;vp&amp;gt;core::function&amp;lt;/vp&amp;gt;.  &amp;lt;vp&amp;gt;core::predicate&amp;lt;/vp&amp;gt; is essentially the same, but does not return a value.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    two_times:function{integer,integer}.&lt;br /&gt;
% or    two_times: core::function{integer,integer}.&lt;br /&gt;
clauses&lt;br /&gt;
    two_times(A) = 2*A.&lt;br /&gt;
class predicates&lt;br /&gt;
    p_function : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_function() :-&lt;br /&gt;
        Z = two_times(2),&lt;br /&gt;
        %binds Z to 4&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    fred_dom{A,B} = predicate{A,B}.&lt;br /&gt;
% or    fred_dom{A,B} = core::predicate{A,B}.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    fred_pred: fred_dom{A,B}.&lt;br /&gt;
clauses&lt;br /&gt;
    fred_pred(A,B) :-&lt;br /&gt;
        stdio::write(&amp;quot;\n&amp;quot;,A,&amp;quot; &amp;quot;,B).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_pred : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_pred() :-&lt;br /&gt;
        fred_pred(&amp;quot;one&amp;quot;,2).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    add_func: function{integer,integer}.&lt;br /&gt;
clauses&lt;br /&gt;
    add_func(B) = B+1.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    p_function : ().&lt;br /&gt;
clauses&lt;br /&gt;
    p_function() :-&lt;br /&gt;
        X = add_func(5),&lt;br /&gt;
        %X is bound to 6&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Anonymous predicates ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;(under development)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
See [[Language Reference/Terms/Anonymous Predicates|Anonymous Predicates]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {() = 9},&lt;br /&gt;
        K = Anon().&lt;br /&gt;
        %results in K = 9&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = { = 88},&lt;br /&gt;
        K = Anon().&lt;br /&gt;
        %results in K = 88.&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {(A,B) = A+B},&lt;br /&gt;
        K = Anon(4,8),&lt;br /&gt;
        %results in K = 12.&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = {&lt;br /&gt;
            (A,B) = C :-&lt;br /&gt;
            R = math::random(7),&lt;br /&gt;
            C = A+B+R,&lt;br /&gt;
            stdio::wRite(&amp;quot;RRRR = &amp;quot;,R)&lt;br /&gt;
            },&lt;br /&gt;
        K = Anon(4,8).&lt;br /&gt;
        %results in K = 12 + a random number &amp;lt;7&lt;br /&gt;
&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon = { = f_abc(3)},&lt;br /&gt;
        K = Anon(),&lt;br /&gt;
        stdio::write(&amp;quot;\nI = { = f_abc(3)} gives &amp;quot;,K),&lt;br /&gt;
        fail.&lt;br /&gt;
    run().&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Threads ===&lt;br /&gt;
&lt;br /&gt;
To start a thread:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred() :-&lt;br /&gt;
        _ = thread::start(fred).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred : ().&lt;br /&gt;
clauses&lt;br /&gt;
    fred() :- .....&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
fred can have no arguments, so no argument brackets are allowed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;    _ = thread::start(fred())&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is illegal. &lt;br /&gt;
&lt;br /&gt;
Using [[Language Reference/Terms/Anonymous Predicates|Anonymous Predicates]] is rather simple to pass arguments to thread:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred(X) :-&lt;br /&gt;
        _ = thread::start( { :- fred(X) } ).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred : (integer K).&lt;br /&gt;
clauses&lt;br /&gt;
    fred(K) :-&lt;br /&gt;
        ...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Examples]]&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=1841</id>
		<title>VIP7 Construct examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=1841"/>
		<updated>2009-03-24T15:50:26Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Fact variables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains a collection of basic examples for (mainly) the newer constructs found in VIP7.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Fact variables ===&lt;br /&gt;
&lt;br /&gt;
Fact variables are the only mutable types in VIP.&lt;br /&gt;
&lt;br /&gt;
First, a reminder for ordinary facts:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb_int:(integer).  % a nondeterministic fact (0 to any number of values)&lt;br /&gt;
    db_int:(integer,string) determ. % a deterministic fact (0 to 1 value)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These types of fact are asserted and retracted.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039; (fact variables)&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    zz_int:integer:=0.&lt;br /&gt;
    zz_fred:integer:=erroneous.&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    dom=dom(string,chaindb::ref).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    zz_dom: dom :=erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
        zz_int:=7,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;,zz_int), %will write &amp;quot;zz_int=7&amp;quot;&lt;br /&gt;
        zz_int:=zz_int+20,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;,zz_int), %will write &amp;quot;zz_int=27&amp;quot;&lt;br /&gt;
        succeed.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fact variables are great for counting e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    how_many:()-&amp;gt;integer Count.&lt;br /&gt;
clauses&lt;br /&gt;
    how_many()=_:-&lt;br /&gt;
        zz_int:=0,&lt;br /&gt;
        some_nondeterm_fact_or_pred(),&lt;br /&gt;
            zz_int:=zz_int+1,&lt;br /&gt;
            fail.&lt;br /&gt;
    how_many()=zz_int.&lt;br /&gt;
clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
       stdio::write(&amp;quot;\n There are &amp;quot;,how_many(),&amp;quot; items&amp;quot;).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lists - findall and list comprehension ===&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.visual-prolog.com/index.php?title=Lists_and_Recursion Lists and Recursion]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vp&amp;gt;findall()&amp;lt;/vp&amp;gt; has been depricated, so use the list comprehension construct.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb:(integer). %default is nondeterm for a fact&lt;br /&gt;
clauses&lt;br /&gt;
    ndb(1).&lt;br /&gt;
    ndb(2).&lt;br /&gt;
    ndb(3).&lt;br /&gt;
    ....&lt;br /&gt;
    ndb(10).&lt;br /&gt;
clauses&lt;br /&gt;
    pred_old():-&lt;br /&gt;
        findall(X,ndb(X),List).&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
clauses&lt;br /&gt;
    pred_new():-&lt;br /&gt;
        List=[X||ndb(X)].&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
clauses&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        List=[X||ndb(X), X&amp;gt;6].&lt;br /&gt;
        %results in List = [7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        List=[X||ndb(X), X mod 2=0].&lt;br /&gt;
        %results in List = [2,4,6,8,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        List=[X||ndb(X), X mod 2=0, X&amp;lt;7].&lt;br /&gt;
        %results in List = [2,4,6]&lt;br /&gt;
&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        zz_int:=0,&lt;br /&gt;
        List=[X||ndb(X), X mod 2=0, X&amp;lt;7, zz_int:=zz_int+1].&lt;br /&gt;
        %results in List = [2,4,6] and zz_int=3.&lt;br /&gt;
&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        List=[X||ndb(X), Y=pred2(X), Y&amp;gt;10].   %with pred2(X)=X^2.&lt;br /&gt;
        %results in List = [4,5,6,7,8,9,10]&lt;br /&gt;
        %reason - X=3 gives Y=9 which is &amp;lt; 10.&lt;br /&gt;
&lt;br /&gt;
    pred_other():-&lt;br /&gt;
        L=[1,2,3,4,5,6,7,8,9,10],&lt;br /&gt;
        LIST=[ X || X = list::getMember_nd(L)].&lt;br /&gt;
        %results in List= L&lt;br /&gt;
&lt;br /&gt;
    pred_other():-&lt;br /&gt;
        Primes=[X||X=std::fromto(1,300),&lt;br /&gt;
		L1=[Y||Y=std::fromto(2,150)],&lt;br /&gt;
		tt(X,L1)].&lt;br /&gt;
        %results in List= prime numbers, with:&lt;br /&gt;
class predicates&lt;br /&gt;
        tt:(integer,integer*) determ.&lt;br /&gt;
clauses&lt;br /&gt;
        tt(_X,[]):-!.&lt;br /&gt;
        tt(X,[X|_]):-!.&lt;br /&gt;
        tt(X,[Y|L]):-&lt;br /&gt;
		X mod Y&amp;lt;&amp;gt;0,&lt;br /&gt;
		tt(X,L).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== if-then-else (code) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred(X,Y)=Z:-&lt;br /&gt;
        if X=0 then&lt;br /&gt;
            Z=&amp;quot;x is zero&amp;quot;&lt;br /&gt;
        elseif X&amp;gt;0 then&lt;br /&gt;
            if pred3(Y)=true then&lt;br /&gt;
                Z=&amp;quot;x&amp;gt;0 and pred(Y) is true&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
                Z=&amp;quot;x&amp;gt;0 and pred(Y) is false&amp;quot;&lt;br /&gt;
            end if  %note, no comma here either&lt;br /&gt;
        else&lt;br /&gt;
            Z=&amp;quot;x &amp;lt;0&amp;quot;&lt;br /&gt;
        end if.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== #if #then #else (directive for conditional compilation) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;constants&lt;br /&gt;
    u64_con=1.&lt;br /&gt;
    int_con=2.&lt;br /&gt;
    real_con=3.&lt;br /&gt;
&lt;br /&gt;
    compile_big_con=u64_con. %change this and then recompile.&lt;br /&gt;
&lt;br /&gt;
#if compile_big_con=u64_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred:()-&amp;gt;unsigned64.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred()=U64:-&lt;br /&gt;
            U64=78766.&lt;br /&gt;
&lt;br /&gt;
#elseif compile_big_con=int_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred:()-&amp;gt;integer.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred()=Int:-&lt;br /&gt;
            Int=20.&lt;br /&gt;
&lt;br /&gt;
#else&lt;br /&gt;
    predicates&lt;br /&gt;
        pred:(real [out]).&lt;br /&gt;
    clauses&lt;br /&gt;
        pred(0.766).&lt;br /&gt;
&lt;br /&gt;
#endif&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Code construct uses     &amp;lt;vp&amp;gt;if  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;elseif  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;else&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;end if&amp;lt;/vp&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
compiler directive uses &amp;lt;vp&amp;gt;#if - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#elseif - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#else&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#endif&amp;lt;/vp&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;(just the &amp;quot;end if&amp;quot; is &amp;quot;different&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Trap and try/catch/finally ===&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms/Try-catch-finally Try-catch-finally]&amp;lt;br&amp;gt;&lt;br /&gt;
Note, in&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Predicates Built-in entities/Predicates]&amp;lt;br&amp;gt;&lt;br /&gt;
suggests using &amp;lt;vp&amp;gt;try-end try&amp;lt;/vp&amp;gt; instead of &amp;lt;vp&amp;gt;trap(_,_,_)&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_all():-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    call_pred_that_might_crash:(integer).&lt;br /&gt;
    call_own_exception_pred:(pointer ErrorNo).&lt;br /&gt;
    always_call_this_anyway:().&lt;br /&gt;
clauses&lt;br /&gt;
    call_pred_that_might_crash(X):-&lt;br /&gt;
        Y=9/X.&lt;br /&gt;
&lt;br /&gt;
    call_own_exception_pred(ErrorNo):-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;crashed&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
    always_call_this_anyway():-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;finally reached&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some():-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% in this case, VIP will automatically pop up its exception dialog&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some():-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 4&amp;#039;&amp;#039;&amp;#039; - illegal - it must have a &amp;lt;vp&amp;gt;catch&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;finally&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_illegal():-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Foreach ===&lt;br /&gt;
See &lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms/Foreach Foreach]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== 64 bit numbers - history ===&lt;br /&gt;
Up to VIP7.1, integer64 etc were defined as:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
    unsigned64 = unsigned64(unsigned32 Low, unsigned32 High).&lt;br /&gt;
    integer64 = integer64(unsigned32 Low, integer32 High).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In VIP7.2 these have been renamed:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
    unsigned64_struct = unsigned64(unsigned Low, unsigned High).&lt;br /&gt;
    integer64_struct = integer64(unsigned Low, integer High).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, for example, in VIP7.1:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
     getFileProperties : (&lt;br /&gt;
        string FileName,&lt;br /&gt;
        fileSystem_api::fileAttributes Attributes,&lt;br /&gt;
        fileSystem_api::fileSize Size,&lt;br /&gt;
        core::gmtTimeValue Creation,&lt;br /&gt;
        core::gmtTimeValue LastAccess,&lt;br /&gt;
        core::gmtTimeValue LastChange)&lt;br /&gt;
        procedure (i,o,o,o,o,o).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
if you needed use (and write) &amp;#039;&amp;#039;&amp;#039;fileSize&amp;#039;&amp;#039;&amp;#039; and times, you would have to have done some juggling (such as converting them to real numbers). &lt;br /&gt;
&amp;lt;br&amp;gt;To generate a 64 bit random number:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates %before VIP7.2&lt;br /&gt;
    gen64:()-&amp;gt;unsigned64.&lt;br /&gt;
clauses&lt;br /&gt;
    gen64()=U64:-&lt;br /&gt;
        N= 2^32,&lt;br /&gt;
        Low=math::random(N+0),&lt;br /&gt;
        High=math::random(N+0),&lt;br /&gt;
        U64=unsigned64(Low,High).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and possibly you would have needed (e.g.) &amp;#039;&amp;#039;&amp;#039;math::add&amp;#039;&amp;#039;&amp;#039;:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
    add : (core::unsigned64 Augend, core::unsigned64 Addend) -&amp;gt; core::unsigned64 Sum&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s now totally straightforward in VIP7.2 - just treat 64 bit numbers like any other number. You may also want these conversions - found in &amp;#039;&amp;#039;&amp;#039;core::&amp;#039;&amp;#039;&amp;#039; - for old code (this snippet is stolen from [http://discuss.visual-prolog.com/viewtopic.php?t=7927 Thomas&amp;#039; post]) &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
predicates&lt;br /&gt;
    toUnsigned64 : (unsigned64_struct) -&amp;gt; unsigned64.&lt;br /&gt;
    fromUnsigned64 : (unsigned64) -&amp;gt; unsigned64_struct.&lt;br /&gt;
    toInteger64 : (integer64_struct) -&amp;gt; integer64.&lt;br /&gt;
    fromInteger64 : (integer64) -&amp;gt; integer64_struct.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
And just for reference:&amp;lt;br&amp;gt;&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#integer integer] range = -2^31 to +2^31 = -2147483648 .. 2147483647&amp;lt;br&amp;gt;&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#unsigned unsigned]  range = 0 to (2^32)-1 = 4294967295&amp;lt;br&amp;gt;&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#integer64 integer64] range = -2^63 to 2^63&amp;lt;br&amp;gt; &lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#unsigned64 unsigned64] range= 0 to (2^64)-1 = 18446744073709551615 (=1.844..E19)&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Polymorphic Domains ===&lt;br /&gt;
See [http://wiki.visual-prolog.com/index.php?title=Objects_and_Polymorphism Objects and Polymorphism]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First, check out the definitions - &amp;#039;&amp;#039;&amp;#039;core::tuple{}&amp;#039;&amp;#039;&amp;#039;. And while you&amp;#039;re there, just below, see &amp;#039;&amp;#039;&amp;#039;core::predicate{}&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;core::function{}&amp;#039;&amp;#039;&amp;#039;, then followed by &amp;#039;&amp;#039;&amp;#039;comparator{A}&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;list{A}&amp;#039;&amp;#039;&amp;#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The domains in class &amp;#039;&amp;#039;&amp;#039;list::&amp;#039;&amp;#039;&amp;#039; are polymorphic, but you can define your own polymorphic domains. Here are some examples:&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
	poly_dom{A,B}=poly_def(A,B).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
When you use it in your code, A and B can be any other domain.&amp;lt;br&amp;gt;&lt;br /&gt;
The domain name is &amp;#039;&amp;#039;&amp;#039;poly_dom{A,B}&amp;#039;&amp;#039;&amp;#039;, and you reference it you must use its whole name (not just &amp;#039;&amp;#039;&amp;#039;poly_dom&amp;#039;&amp;#039;&amp;#039;) e.g. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	joe{A,B}=poly_dom{A,B}*.	&lt;br /&gt;
/* the next two lines are illegal&lt;br /&gt;
	poly_dom{A,B}=poly_def(A,B)*.&lt;br /&gt;
	poly_dom{A,A}=poly_def(A,A).&lt;br /&gt;
*/&lt;br /&gt;
	fred{A,B}=fred(poly_dom{A,B},integer).&lt;br /&gt;
&lt;br /&gt;
	maybe_silly_dom{A,B}=silly2(A,B);&lt;br /&gt;
							silly(A);&lt;br /&gt;
							pd(poly_dom{A,B});&lt;br /&gt;
							poly_dom(A,B);%IS NOT THE SAME POLY_DOM!! (notice no braces)&lt;br /&gt;
							s(string).&lt;br /&gt;
							&lt;br /&gt;
	another{A}=i(integer);&lt;br /&gt;
				s(string);&lt;br /&gt;
				a(A);&lt;br /&gt;
				self(another({A}).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
	zz_poly_dom:poly_dom{integer,integer}:=erroneous.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
	p_morphic_test:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_morphic_test():-&lt;br /&gt;
		zz_poly_dom:=poly_def(1,5),&lt;br /&gt;
		call_pd(zz_poly_dom),&lt;br /&gt;
		fail.&lt;br /&gt;
	p_morphic_test():-&lt;br /&gt;
		PD=poly_def(1,[&amp;quot;an example&amp;quot;,&amp;quot;or two&amp;quot;]),&lt;br /&gt;
		call_pd(PD),&lt;br /&gt;
		fail.&lt;br /&gt;
	p_morphic_test():-&lt;br /&gt;
		Q= [poly_def(X, Y) || X= std::fromTo(1, 4),&lt;br /&gt;
					Y= std::fromTo(1, 5)],&lt;br /&gt;
		stdio::write(&amp;quot;\n&amp;quot;,Q),&lt;br /&gt;
		fail.&lt;br /&gt;
	p_morphic_test().&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
	call_pd:(poly_dom{A,B}).&lt;br /&gt;
clauses&lt;br /&gt;
	call_pd(POLY_DOM):-&lt;br /&gt;
		stdio::write(&amp;quot;\n&amp;quot;,POLY_DOM),&lt;br /&gt;
		fail.&lt;br /&gt;
	call_pd(poly_def(A,B)):-%note this is POLY_DEF&lt;br /&gt;
		stdio::write(&amp;quot;\n&amp;quot;,A,B),&lt;br /&gt;
		fail.&lt;br /&gt;
	call_pd(_).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Properties ===&lt;br /&gt;
&lt;br /&gt;
Properties in a class are used almost identically to fact variables, but properties can be set directly (from another class), without having to declare a public predicate to make the change.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface fred&lt;br /&gt;
    domains&lt;br /&gt;
        complete_dom=is_complete;&lt;br /&gt;
                     not_complete.&lt;br /&gt;
    properties&lt;br /&gt;
        prop_complete : complete_dom.&lt;br /&gt;
end interface fred&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;#039;&amp;#039;&amp;#039;fred.pro&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement fred&lt;br /&gt;
facts&lt;br /&gt;
    zz_complete:complete_dom:=erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses %for the property&lt;br /&gt;
    prop_complete()=zz_complete. %get&lt;br /&gt;
    prop_complete(COMPLETE):-zz_complete:=COMPLETE. %set&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some other class that calls class fred:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;implement other&lt;br /&gt;
    open fred&lt;br /&gt;
clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
        Fred=fred::new(),&lt;br /&gt;
        Fred:prop_complete:=is_complete,% to set the value&lt;br /&gt;
        Value=Fred:prop_complete,!. %get&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Comparators and compare ===&lt;br /&gt;
First, look at the definition of &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
    comparator{T} = function{T, T, compareResult}.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;compareResult&amp;#039;s&amp;#039;&amp;#039;&amp;#039; definition can is found here:&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#compareResult compareResult]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
	p_compare_test:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_compare_test():-&lt;br /&gt;
		CompareResult=compare(7,2).&lt;br /&gt;
		%will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;greater()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
		%(because 7 &amp;gt; 2)&lt;br /&gt;
	p_compare_test():-&lt;br /&gt;
		CompareResult=compare(2,2).&lt;br /&gt;
		%will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;equal()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
	p_compare_test():-&lt;br /&gt;
		CompareResult=compare(&amp;quot;a&amp;quot;,&amp;quot;z&amp;quot;).&lt;br /&gt;
		%will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;less()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But you may wish to check your own domains to see which is &amp;quot;greater&amp;quot; - and of course you must define this yourself, by defining your own predicate as a &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Here is a simple domain in which only the integer parts of the variables are checked to see which is greater:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	s=s(string,integer).&lt;br /&gt;
	&lt;br /&gt;
class predicates&lt;br /&gt;
	compare_it: core::comparator{s}.&lt;br /&gt;
clauses			&lt;br /&gt;
	compare_it(A,B)=CompareResult:-%since this is a core::function(T,T,compareResult)&lt;br /&gt;
		A=s(_,I),&lt;br /&gt;
		B=s(_,J),&lt;br /&gt;
		if I&amp;lt;J then&lt;br /&gt;
			CompareResult=less()&lt;br /&gt;
		elseif I=J then&lt;br /&gt;
			CompareResult=equal()&lt;br /&gt;
		else&lt;br /&gt;
			CompareResult=greater()&lt;br /&gt;
		end if.&lt;br /&gt;
		&lt;br /&gt;
class predicates&lt;br /&gt;
	p_compare_test:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_compare_test():-&lt;br /&gt;
		S1=s(&amp;quot;abc&amp;quot;,7),&lt;br /&gt;
		S2=s(&amp;quot;fred&amp;quot;,9),&lt;br /&gt;
		CompareResult=compare_it(S1,S2),&lt;br /&gt;
		%will give CompareResult=less, since 7&amp;lt;9.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
...a bit pointless since the string part of the variables have been ignored, but it is easy to see how to expand &amp;#039;&amp;#039;&amp;#039;compare_it()&amp;#039;&amp;#039;&amp;#039; to your own needs.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== More on core::function and core::predicate ===&lt;br /&gt;
Again, please check out &amp;#039;&amp;#039;&amp;#039;core::function&amp;#039;&amp;#039;&amp;#039;.  &amp;#039;&amp;#039;&amp;#039;core::predicate&amp;#039;&amp;#039;&amp;#039; is essentially the same, but does not return a value.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
	two_times:function{integer,integer}.&lt;br /&gt;
% or	two_times: core::function{integer,integer}.&lt;br /&gt;
clauses			&lt;br /&gt;
	two_times(A)=2*A.&lt;br /&gt;
class predicates&lt;br /&gt;
	p_function:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_function():-&lt;br /&gt;
		Z=two_times(2),&lt;br /&gt;
		%binds Z to 4&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	fred_dom{A,B}=predicate{A,B}.&lt;br /&gt;
% or	fred_dom{A,B}=core::predicate{A,B}.&lt;br /&gt;
class predicates&lt;br /&gt;
	fred_pred: fred_dom{A,B}.&lt;br /&gt;
clauses	&lt;br /&gt;
	fred_pred(A,B):-&lt;br /&gt;
		stdio::write(&amp;quot;\n&amp;quot;,A,&amp;quot; &amp;quot;,B).&lt;br /&gt;
class predicates&lt;br /&gt;
	p_pred:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_pred():-&lt;br /&gt;
		fred_pred(&amp;quot;one&amp;quot;,2).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
	add_func: function{integer,integer}.&lt;br /&gt;
clauses	&lt;br /&gt;
	add_func(B)=B+1.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
	p_function:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_function():-&lt;br /&gt;
		X=add_func(5),&lt;br /&gt;
		%X is bound to 6&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Anonymous predicates ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;(under development)&amp;#039;&amp;#039;&lt;br /&gt;
See [http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms/Anonymous_Predicates Anonymous_Predicates]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon={()=9},&lt;br /&gt;
        K=Anon().&lt;br /&gt;
        %results in K=9&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon={=88},&lt;br /&gt;
        K=Anon().&lt;br /&gt;
        %results in K=88.&lt;br /&gt;
    run():-&lt;br /&gt;
        Anon={(A,B)=A+B},&lt;br /&gt;
        K=Anon(4,8),&lt;br /&gt;
        %results in K=12.&lt;br /&gt;
    run():-&lt;br /&gt;
        Anon={&lt;br /&gt;
            (A,B)=C:-&lt;br /&gt;
            R=math::random(7),&lt;br /&gt;
            C=A+B+R,&lt;br /&gt;
            stdio::wRite(&amp;quot;RRRR=&amp;quot;,R)&lt;br /&gt;
            },&lt;br /&gt;
        K=Anon(4,8).&lt;br /&gt;
        %results in K=12 + a random number &amp;lt;7&lt;br /&gt;
&lt;br /&gt;
    run():-&lt;br /&gt;
        Anon={=f_abc(3)},&lt;br /&gt;
        K=Anon(),&lt;br /&gt;
        stdio::write(&amp;quot;\nI={=f_abc(3)} gives &amp;quot;,K),&lt;br /&gt;
        fail.&lt;br /&gt;
    run().&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Threads ===&lt;br /&gt;
&lt;br /&gt;
To start a thread:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
        _=thread::start(fred).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred:().&lt;br /&gt;
clauses&lt;br /&gt;
    fred():-.....&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
fred can have no arguments, so no argument brackets are allowed:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
    _=thread::start(fred())&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is illegal. But the thread can access data prepared before it is started.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    zz_int:integer:=erroneous.&lt;br /&gt;
clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
        zz_int:=88,&lt;br /&gt;
        _=thread::start(fred).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred:().&lt;br /&gt;
clauses&lt;br /&gt;
    fred():-&lt;br /&gt;
        K=zz_int,&lt;br /&gt;
        ...&amp;lt;/vip&amp;gt;&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=1840</id>
		<title>VIP7 Construct examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=1840"/>
		<updated>2009-03-24T15:46:28Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: Added foreach reference&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains a collection of basic examples for (mainly) the newer constructs found in VIP7.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Fact variables ===&lt;br /&gt;
&lt;br /&gt;
Fact variables are the only mutable types in VIP.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples - &amp;quot;reminder- ordinary facts&amp;quot;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb_int:(integer).  % a nondeterministic fact (0 to any number of values)&lt;br /&gt;
    db_int:(integer,string) determ. % a deterministic fact (0 to 1 value)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These types of fact are asserted and retracted.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples - &amp;quot;fact variables&amp;quot;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    zz_int:integer:=0.&lt;br /&gt;
    zz_fred:integer:=erroneous.&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    dom=dom(string,chaindb:ref).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    zz_dom:dom:=erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
        zz_int:=7,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;,zz_int), %will write &amp;quot;zz_int=7&amp;quot;&lt;br /&gt;
        zz_int:=zz_int+20,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;,zz_int), %will write &amp;quot;zz_int=27&amp;quot;&lt;br /&gt;
        succeed.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A fact variable is great for counting eg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    how_many:()-&amp;gt;integer Count.&lt;br /&gt;
clauses&lt;br /&gt;
    how_many()=_:-&lt;br /&gt;
        zz_int:=0,&lt;br /&gt;
        some_nondeterm_fact_or_pred(),&lt;br /&gt;
            zz_int:=zz_int+1,&lt;br /&gt;
            fail.&lt;br /&gt;
    how_many()=zz_int.&lt;br /&gt;
clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
       stdio::write(&amp;quot;\n There are &amp;quot;,how_many(),&amp;quot; items&amp;quot;).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lists - findall and list comprehension ===&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.visual-prolog.com/index.php?title=Lists_and_Recursion Lists and Recursion]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vp&amp;gt;findall()&amp;lt;/vp&amp;gt; has been depricated, so use the list comprehension construct.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb:(integer). %default is nondeterm for a fact&lt;br /&gt;
clauses&lt;br /&gt;
    ndb(1).&lt;br /&gt;
    ndb(2).&lt;br /&gt;
    ndb(3).&lt;br /&gt;
    ....&lt;br /&gt;
    ndb(10).&lt;br /&gt;
clauses&lt;br /&gt;
    pred_old():-&lt;br /&gt;
        findall(X,ndb(X),List).&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
clauses&lt;br /&gt;
    pred_new():-&lt;br /&gt;
        List=[X||ndb(X)].&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
clauses&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        List=[X||ndb(X), X&amp;gt;6].&lt;br /&gt;
        %results in List = [7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        List=[X||ndb(X), X mod 2=0].&lt;br /&gt;
        %results in List = [2,4,6,8,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        List=[X||ndb(X), X mod 2=0, X&amp;lt;7].&lt;br /&gt;
        %results in List = [2,4,6]&lt;br /&gt;
&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        zz_int:=0,&lt;br /&gt;
        List=[X||ndb(X), X mod 2=0, X&amp;lt;7, zz_int:=zz_int+1].&lt;br /&gt;
        %results in List = [2,4,6] and zz_int=3.&lt;br /&gt;
&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        List=[X||ndb(X), Y=pred2(X), Y&amp;gt;10].   %with pred2(X)=X^2.&lt;br /&gt;
        %results in List = [4,5,6,7,8,9,10]&lt;br /&gt;
        %reason - X=3 gives Y=9 which is &amp;lt; 10.&lt;br /&gt;
&lt;br /&gt;
    pred_other():-&lt;br /&gt;
        L=[1,2,3,4,5,6,7,8,9,10],&lt;br /&gt;
        LIST=[ X || X = list::getMember_nd(L)].&lt;br /&gt;
        %results in List= L&lt;br /&gt;
&lt;br /&gt;
    pred_other():-&lt;br /&gt;
        Primes=[X||X=std::fromto(1,300),&lt;br /&gt;
		L1=[Y||Y=std::fromto(2,150)],&lt;br /&gt;
		tt(X,L1)].&lt;br /&gt;
        %results in List= prime numbers, with:&lt;br /&gt;
class predicates&lt;br /&gt;
        tt:(integer,integer*) determ.&lt;br /&gt;
clauses&lt;br /&gt;
        tt(_X,[]):-!.&lt;br /&gt;
        tt(X,[X|_]):-!.&lt;br /&gt;
        tt(X,[Y|L]):-&lt;br /&gt;
		X mod Y&amp;lt;&amp;gt;0,&lt;br /&gt;
		tt(X,L).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== if-then-else (code) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred(X,Y)=Z:-&lt;br /&gt;
        if X=0 then&lt;br /&gt;
            Z=&amp;quot;x is zero&amp;quot;&lt;br /&gt;
        elseif X&amp;gt;0 then&lt;br /&gt;
            if pred3(Y)=true then&lt;br /&gt;
                Z=&amp;quot;x&amp;gt;0 and pred(Y) is true&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
                Z=&amp;quot;x&amp;gt;0 and pred(Y) is false&amp;quot;&lt;br /&gt;
            end if  %note, no comma here either&lt;br /&gt;
        else&lt;br /&gt;
            Z=&amp;quot;x &amp;lt;0&amp;quot;&lt;br /&gt;
        end if.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== #if #then #else (directive for conditional compilation) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;constants&lt;br /&gt;
    u64_con=1.&lt;br /&gt;
    int_con=2.&lt;br /&gt;
    real_con=3.&lt;br /&gt;
&lt;br /&gt;
    compile_big_con=u64_con. %change this and then recompile.&lt;br /&gt;
&lt;br /&gt;
#if compile_big_con=u64_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred:()-&amp;gt;unsigned64.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred()=U64:-&lt;br /&gt;
            U64=78766.&lt;br /&gt;
&lt;br /&gt;
#elseif compile_big_con=int_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred:()-&amp;gt;integer.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred()=Int:-&lt;br /&gt;
            Int=20.&lt;br /&gt;
&lt;br /&gt;
#else&lt;br /&gt;
    predicates&lt;br /&gt;
        pred:(real [out]).&lt;br /&gt;
    clauses&lt;br /&gt;
        pred(0.766).&lt;br /&gt;
&lt;br /&gt;
#endif&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Code construct uses     &amp;lt;vp&amp;gt;if  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;elseif  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;else&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;end if&amp;lt;/vp&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
compiler directive uses &amp;lt;vp&amp;gt;#if - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#elseif - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#else&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#endif&amp;lt;/vp&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;(just the &amp;quot;end if&amp;quot; is &amp;quot;different&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Trap and try/catch/finally ===&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms/Try-catch-finally Try-catch-finally]&amp;lt;br&amp;gt;&lt;br /&gt;
Note, in&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Predicates Built-in entities/Predicates]&amp;lt;br&amp;gt;&lt;br /&gt;
suggests using &amp;lt;vp&amp;gt;try-end try&amp;lt;/vp&amp;gt; instead of &amp;lt;vp&amp;gt;trap(_,_,_)&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_all():-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    call_pred_that_might_crash:(integer).&lt;br /&gt;
    call_own_exception_pred:(pointer ErrorNo).&lt;br /&gt;
    always_call_this_anyway:().&lt;br /&gt;
clauses&lt;br /&gt;
    call_pred_that_might_crash(X):-&lt;br /&gt;
        Y=9/X.&lt;br /&gt;
&lt;br /&gt;
    call_own_exception_pred(ErrorNo):-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;crashed&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
    always_call_this_anyway():-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;finally reached&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some():-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% in this case, VIP will automatically pop up its exception dialog&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some():-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 4&amp;#039;&amp;#039;&amp;#039; - illegal - it must have a &amp;lt;vp&amp;gt;catch&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;finally&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_illegal():-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Foreach ===&lt;br /&gt;
See &lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms/Foreach Foreach]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== 64 bit numbers - history ===&lt;br /&gt;
Up to VIP7.1, integer64 etc were defined as:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
    unsigned64 = unsigned64(unsigned32 Low, unsigned32 High).&lt;br /&gt;
    integer64 = integer64(unsigned32 Low, integer32 High).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In VIP7.2 these have been renamed:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
    unsigned64_struct = unsigned64(unsigned Low, unsigned High).&lt;br /&gt;
    integer64_struct = integer64(unsigned Low, integer High).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, for example, in VIP7.1:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
     getFileProperties : (&lt;br /&gt;
        string FileName,&lt;br /&gt;
        fileSystem_api::fileAttributes Attributes,&lt;br /&gt;
        fileSystem_api::fileSize Size,&lt;br /&gt;
        core::gmtTimeValue Creation,&lt;br /&gt;
        core::gmtTimeValue LastAccess,&lt;br /&gt;
        core::gmtTimeValue LastChange)&lt;br /&gt;
        procedure (i,o,o,o,o,o).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
if you needed use (and write) &amp;#039;&amp;#039;&amp;#039;fileSize&amp;#039;&amp;#039;&amp;#039; and times, you would have to have done some juggling (such as converting them to real numbers). &lt;br /&gt;
&amp;lt;br&amp;gt;To generate a 64 bit random number:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates %before VIP7.2&lt;br /&gt;
    gen64:()-&amp;gt;unsigned64.&lt;br /&gt;
clauses&lt;br /&gt;
    gen64()=U64:-&lt;br /&gt;
        N= 2^32,&lt;br /&gt;
        Low=math::random(N+0),&lt;br /&gt;
        High=math::random(N+0),&lt;br /&gt;
        U64=unsigned64(Low,High).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and possibly you would have needed (e.g.) &amp;#039;&amp;#039;&amp;#039;math::add&amp;#039;&amp;#039;&amp;#039;:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
    add : (core::unsigned64 Augend, core::unsigned64 Addend) -&amp;gt; core::unsigned64 Sum&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s now totally straightforward in VIP7.2 - just treat 64 bit numbers like any other number. You may also want these conversions - found in &amp;#039;&amp;#039;&amp;#039;core::&amp;#039;&amp;#039;&amp;#039; - for old code (this snippet is stolen from [http://discuss.visual-prolog.com/viewtopic.php?t=7927 Thomas&amp;#039; post]) &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
predicates&lt;br /&gt;
    toUnsigned64 : (unsigned64_struct) -&amp;gt; unsigned64.&lt;br /&gt;
    fromUnsigned64 : (unsigned64) -&amp;gt; unsigned64_struct.&lt;br /&gt;
    toInteger64 : (integer64_struct) -&amp;gt; integer64.&lt;br /&gt;
    fromInteger64 : (integer64) -&amp;gt; integer64_struct.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
And just for reference:&amp;lt;br&amp;gt;&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#integer integer] range = -2^31 to +2^31 = -2147483648 .. 2147483647&amp;lt;br&amp;gt;&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#unsigned unsigned]  range = 0 to (2^32)-1 = 4294967295&amp;lt;br&amp;gt;&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#integer64 integer64] range = -2^63 to 2^63&amp;lt;br&amp;gt; &lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#unsigned64 unsigned64] range= 0 to (2^64)-1 = 18446744073709551615 (=1.844..E19)&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Polymorphic Domains ===&lt;br /&gt;
See [http://wiki.visual-prolog.com/index.php?title=Objects_and_Polymorphism Objects and Polymorphism]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First, check out the definitions - &amp;#039;&amp;#039;&amp;#039;core::tuple{}&amp;#039;&amp;#039;&amp;#039;. And while you&amp;#039;re there, just below, see &amp;#039;&amp;#039;&amp;#039;core::predicate{}&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;core::function{}&amp;#039;&amp;#039;&amp;#039;, then followed by &amp;#039;&amp;#039;&amp;#039;comparator{A}&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;list{A}&amp;#039;&amp;#039;&amp;#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The domains in class &amp;#039;&amp;#039;&amp;#039;list::&amp;#039;&amp;#039;&amp;#039; are polymorphic, but you can define your own polymorphic domains. Here are some examples:&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
	poly_dom{A,B}=poly_def(A,B).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
When you use it in your code, A and B can be any other domain.&amp;lt;br&amp;gt;&lt;br /&gt;
The domain name is &amp;#039;&amp;#039;&amp;#039;poly_dom{A,B}&amp;#039;&amp;#039;&amp;#039;, and you reference it you must use its whole name (not just &amp;#039;&amp;#039;&amp;#039;poly_dom&amp;#039;&amp;#039;&amp;#039;) e.g. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	joe{A,B}=poly_dom{A,B}*.	&lt;br /&gt;
/* the next two lines are illegal&lt;br /&gt;
	poly_dom{A,B}=poly_def(A,B)*.&lt;br /&gt;
	poly_dom{A,A}=poly_def(A,A).&lt;br /&gt;
*/&lt;br /&gt;
	fred{A,B}=fred(poly_dom{A,B},integer).&lt;br /&gt;
&lt;br /&gt;
	maybe_silly_dom{A,B}=silly2(A,B);&lt;br /&gt;
							silly(A);&lt;br /&gt;
							pd(poly_dom{A,B});&lt;br /&gt;
							poly_dom(A,B);%IS NOT THE SAME POLY_DOM!! (notice no braces)&lt;br /&gt;
							s(string).&lt;br /&gt;
							&lt;br /&gt;
	another{A}=i(integer);&lt;br /&gt;
				s(string);&lt;br /&gt;
				a(A);&lt;br /&gt;
				self(another({A}).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
	zz_poly_dom:poly_dom{integer,integer}:=erroneous.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
	p_morphic_test:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_morphic_test():-&lt;br /&gt;
		zz_poly_dom:=poly_def(1,5),&lt;br /&gt;
		call_pd(zz_poly_dom),&lt;br /&gt;
		fail.&lt;br /&gt;
	p_morphic_test():-&lt;br /&gt;
		PD=poly_def(1,[&amp;quot;an example&amp;quot;,&amp;quot;or two&amp;quot;]),&lt;br /&gt;
		call_pd(PD),&lt;br /&gt;
		fail.&lt;br /&gt;
	p_morphic_test():-&lt;br /&gt;
		Q= [poly_def(X, Y) || X= std::fromTo(1, 4),&lt;br /&gt;
					Y= std::fromTo(1, 5)],&lt;br /&gt;
		stdio::write(&amp;quot;\n&amp;quot;,Q),&lt;br /&gt;
		fail.&lt;br /&gt;
	p_morphic_test().&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
	call_pd:(poly_dom{A,B}).&lt;br /&gt;
clauses&lt;br /&gt;
	call_pd(POLY_DOM):-&lt;br /&gt;
		stdio::write(&amp;quot;\n&amp;quot;,POLY_DOM),&lt;br /&gt;
		fail.&lt;br /&gt;
	call_pd(poly_def(A,B)):-%note this is POLY_DEF&lt;br /&gt;
		stdio::write(&amp;quot;\n&amp;quot;,A,B),&lt;br /&gt;
		fail.&lt;br /&gt;
	call_pd(_).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Properties ===&lt;br /&gt;
&lt;br /&gt;
Properties in a class are used almost identically to fact variables, but properties can be set directly (from another class), without having to declare a public predicate to make the change.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface fred&lt;br /&gt;
    domains&lt;br /&gt;
        complete_dom=is_complete;&lt;br /&gt;
                     not_complete.&lt;br /&gt;
    properties&lt;br /&gt;
        prop_complete : complete_dom.&lt;br /&gt;
end interface fred&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;#039;&amp;#039;&amp;#039;fred.pro&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement fred&lt;br /&gt;
facts&lt;br /&gt;
    zz_complete:complete_dom:=erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses %for the property&lt;br /&gt;
    prop_complete()=zz_complete. %get&lt;br /&gt;
    prop_complete(COMPLETE):-zz_complete:=COMPLETE. %set&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some other class that calls class fred:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;implement other&lt;br /&gt;
    open fred&lt;br /&gt;
clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
        Fred=fred::new(),&lt;br /&gt;
        Fred:prop_complete:=is_complete,% to set the value&lt;br /&gt;
        Value=Fred:prop_complete,!. %get&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Comparators and compare ===&lt;br /&gt;
First, look at the definition of &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
    comparator{T} = function{T, T, compareResult}.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;compareResult&amp;#039;s&amp;#039;&amp;#039;&amp;#039; definition can is found here:&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#compareResult compareResult]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
	p_compare_test:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_compare_test():-&lt;br /&gt;
		CompareResult=compare(7,2).&lt;br /&gt;
		%will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;greater()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
		%(because 7 &amp;gt; 2)&lt;br /&gt;
	p_compare_test():-&lt;br /&gt;
		CompareResult=compare(2,2).&lt;br /&gt;
		%will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;equal()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
	p_compare_test():-&lt;br /&gt;
		CompareResult=compare(&amp;quot;a&amp;quot;,&amp;quot;z&amp;quot;).&lt;br /&gt;
		%will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;less()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But you may wish to check your own domains to see which is &amp;quot;greater&amp;quot; - and of course you must define this yourself, by defining your own predicate as a &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Here is a simple domain in which only the integer parts of the variables are checked to see which is greater:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	s=s(string,integer).&lt;br /&gt;
	&lt;br /&gt;
class predicates&lt;br /&gt;
	compare_it: core::comparator{s}.&lt;br /&gt;
clauses			&lt;br /&gt;
	compare_it(A,B)=CompareResult:-%since this is a core::function(T,T,compareResult)&lt;br /&gt;
		A=s(_,I),&lt;br /&gt;
		B=s(_,J),&lt;br /&gt;
		if I&amp;lt;J then&lt;br /&gt;
			CompareResult=less()&lt;br /&gt;
		elseif I=J then&lt;br /&gt;
			CompareResult=equal()&lt;br /&gt;
		else&lt;br /&gt;
			CompareResult=greater()&lt;br /&gt;
		end if.&lt;br /&gt;
		&lt;br /&gt;
class predicates&lt;br /&gt;
	p_compare_test:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_compare_test():-&lt;br /&gt;
		S1=s(&amp;quot;abc&amp;quot;,7),&lt;br /&gt;
		S2=s(&amp;quot;fred&amp;quot;,9),&lt;br /&gt;
		CompareResult=compare_it(S1,S2),&lt;br /&gt;
		%will give CompareResult=less, since 7&amp;lt;9.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
...a bit pointless since the string part of the variables have been ignored, but it is easy to see how to expand &amp;#039;&amp;#039;&amp;#039;compare_it()&amp;#039;&amp;#039;&amp;#039; to your own needs.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== More on core::function and core::predicate ===&lt;br /&gt;
Again, please check out &amp;#039;&amp;#039;&amp;#039;core::function&amp;#039;&amp;#039;&amp;#039;.  &amp;#039;&amp;#039;&amp;#039;core::predicate&amp;#039;&amp;#039;&amp;#039; is essentially the same, but does not return a value.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
	two_times:function{integer,integer}.&lt;br /&gt;
% or	two_times: core::function{integer,integer}.&lt;br /&gt;
clauses			&lt;br /&gt;
	two_times(A)=2*A.&lt;br /&gt;
class predicates&lt;br /&gt;
	p_function:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_function():-&lt;br /&gt;
		Z=two_times(2),&lt;br /&gt;
		%binds Z to 4&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	fred_dom{A,B}=predicate{A,B}.&lt;br /&gt;
% or	fred_dom{A,B}=core::predicate{A,B}.&lt;br /&gt;
class predicates&lt;br /&gt;
	fred_pred: fred_dom{A,B}.&lt;br /&gt;
clauses	&lt;br /&gt;
	fred_pred(A,B):-&lt;br /&gt;
		stdio::write(&amp;quot;\n&amp;quot;,A,&amp;quot; &amp;quot;,B).&lt;br /&gt;
class predicates&lt;br /&gt;
	p_pred:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_pred():-&lt;br /&gt;
		fred_pred(&amp;quot;one&amp;quot;,2).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
	add_func: function{integer,integer}.&lt;br /&gt;
clauses	&lt;br /&gt;
	add_func(B)=B+1.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
	p_function:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_function():-&lt;br /&gt;
		X=add_func(5),&lt;br /&gt;
		%X is bound to 6&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Anonymous predicates ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;(under development)&amp;#039;&amp;#039;&lt;br /&gt;
See [http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms/Anonymous_Predicates Anonymous_Predicates]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon={()=9},&lt;br /&gt;
        K=Anon().&lt;br /&gt;
        %results in K=9&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon={=88},&lt;br /&gt;
        K=Anon().&lt;br /&gt;
        %results in K=88.&lt;br /&gt;
    run():-&lt;br /&gt;
        Anon={(A,B)=A+B},&lt;br /&gt;
        K=Anon(4,8),&lt;br /&gt;
        %results in K=12.&lt;br /&gt;
    run():-&lt;br /&gt;
        Anon={&lt;br /&gt;
            (A,B)=C:-&lt;br /&gt;
            R=math::random(7),&lt;br /&gt;
            C=A+B+R,&lt;br /&gt;
            stdio::wRite(&amp;quot;RRRR=&amp;quot;,R)&lt;br /&gt;
            },&lt;br /&gt;
        K=Anon(4,8).&lt;br /&gt;
        %results in K=12 + a random number &amp;lt;7&lt;br /&gt;
&lt;br /&gt;
    run():-&lt;br /&gt;
        Anon={=f_abc(3)},&lt;br /&gt;
        K=Anon(),&lt;br /&gt;
        stdio::write(&amp;quot;\nI={=f_abc(3)} gives &amp;quot;,K),&lt;br /&gt;
        fail.&lt;br /&gt;
    run().&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Threads ===&lt;br /&gt;
&lt;br /&gt;
To start a thread:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
        _=thread::start(fred).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred:().&lt;br /&gt;
clauses&lt;br /&gt;
    fred():-.....&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
fred can have no arguments, so no argument brackets are allowed:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
    _=thread::start(fred())&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is illegal. But the thread can access data prepared before it is started.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    zz_int:integer:=erroneous.&lt;br /&gt;
clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
        zz_int:=88,&lt;br /&gt;
        _=thread::start(fred).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred:().&lt;br /&gt;
clauses&lt;br /&gt;
    fred():-&lt;br /&gt;
        K=zz_int,&lt;br /&gt;
        ...&amp;lt;/vip&amp;gt;&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=1839</id>
		<title>VIP7 Construct examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=1839"/>
		<updated>2009-03-24T10:25:21Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* More on core::function and core::predicate */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains a collection of basic examples for (mainly) the newer constructs found in VIP7.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Fact variables ===&lt;br /&gt;
&lt;br /&gt;
Fact variables are the only mutable types in VIP.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples - &amp;quot;reminder- ordinary facts&amp;quot;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb_int:(integer).  % a nondeterministic fact (0 to any number of values)&lt;br /&gt;
    db_int:(integer,string) determ. % a deterministic fact (0 to 1 value)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These types of fact are asserted and retracted.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples - &amp;quot;fact variables&amp;quot;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    zz_int:integer:=0.&lt;br /&gt;
    zz_fred:integer:=erroneous.&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    dom=dom(string,chaindb:ref).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    zz_dom:dom:=erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
        zz_int:=7,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;,zz_int), %will write &amp;quot;zz_int=7&amp;quot;&lt;br /&gt;
        zz_int:=zz_int+20,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;,zz_int), %will write &amp;quot;zz_int=27&amp;quot;&lt;br /&gt;
        succeed.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A fact variable is great for counting eg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    how_many:()-&amp;gt;integer Count.&lt;br /&gt;
clauses&lt;br /&gt;
    how_many()=_:-&lt;br /&gt;
        zz_int:=0,&lt;br /&gt;
        some_nondeterm_fact_or_pred(),&lt;br /&gt;
            zz_int:=zz_int+1,&lt;br /&gt;
            fail.&lt;br /&gt;
    how_many()=zz_int.&lt;br /&gt;
clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
       stdio::write(&amp;quot;\n There are &amp;quot;,how_many(),&amp;quot; items&amp;quot;).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lists - findall and list comprehension ===&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.visual-prolog.com/index.php?title=Lists_and_Recursion Lists and Recursion]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vp&amp;gt;findall()&amp;lt;/vp&amp;gt; has been depricated, so use the list comprehension construct.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb:(integer). %default is nondeterm for a fact&lt;br /&gt;
clauses&lt;br /&gt;
    ndb(1).&lt;br /&gt;
    ndb(2).&lt;br /&gt;
    ndb(3).&lt;br /&gt;
    ....&lt;br /&gt;
    ndb(10).&lt;br /&gt;
clauses&lt;br /&gt;
    pred_old():-&lt;br /&gt;
        findall(X,ndb(X),List).&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
clauses&lt;br /&gt;
    pred_new():-&lt;br /&gt;
        List=[X||ndb(X)].&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
clauses&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        List=[X||ndb(X), X&amp;gt;6].&lt;br /&gt;
        %results in List = [7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        List=[X||ndb(X), X mod 2=0].&lt;br /&gt;
        %results in List = [2,4,6,8,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        List=[X||ndb(X), X mod 2=0, X&amp;lt;7].&lt;br /&gt;
        %results in List = [2,4,6]&lt;br /&gt;
&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        zz_int:=0,&lt;br /&gt;
        List=[X||ndb(X), X mod 2=0, X&amp;lt;7, zz_int:=zz_int+1].&lt;br /&gt;
        %results in List = [2,4,6] and zz_int=3.&lt;br /&gt;
&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        List=[X||ndb(X), Y=pred2(X), Y&amp;gt;10].   %with pred2(X)=X^2.&lt;br /&gt;
        %results in List = [4,5,6,7,8,9,10]&lt;br /&gt;
        %reason - X=3 gives Y=9 which is &amp;lt; 10.&lt;br /&gt;
&lt;br /&gt;
    pred_other():-&lt;br /&gt;
        L=[1,2,3,4,5,6,7,8,9,10],&lt;br /&gt;
        LIST=[ X || X = list::getMember_nd(L)].&lt;br /&gt;
        %results in List= L&lt;br /&gt;
&lt;br /&gt;
    pred_other():-&lt;br /&gt;
        Primes=[X||X=std::fromto(1,300),&lt;br /&gt;
		L1=[Y||Y=std::fromto(2,150)],&lt;br /&gt;
		tt(X,L1)].&lt;br /&gt;
        %results in List= prime numbers, with:&lt;br /&gt;
class predicates&lt;br /&gt;
        tt:(integer,integer*) determ.&lt;br /&gt;
clauses&lt;br /&gt;
        tt(_X,[]):-!.&lt;br /&gt;
        tt(X,[X|_]):-!.&lt;br /&gt;
        tt(X,[Y|L]):-&lt;br /&gt;
		X mod Y&amp;lt;&amp;gt;0,&lt;br /&gt;
		tt(X,L).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== if-then-else (code) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred(X):-&lt;br /&gt;
        if X&amp;gt;0 then&lt;br /&gt;
            stdio::write(&amp;quot;\n X&amp;gt;0&amp;quot;)  %the last line in each block has no comma&lt;br /&gt;
        else&lt;br /&gt;
            stdio::write(&amp;quot;\n X&amp;lt;=0&amp;quot;)&lt;br /&gt;
        end if.&lt;br /&gt;
&lt;br /&gt;
    pred(X):-&lt;br /&gt;
        if X&amp;gt;0 then&lt;br /&gt;
            stdio::write(&amp;quot;\n X&amp;gt;0&amp;quot;)&lt;br /&gt;
        elseif X = 0 then&lt;br /&gt;
            stdio::write(&amp;quot;\n X=0&amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
            stdio::write(&amp;quot;\n X&amp;lt;0&amp;quot;)&lt;br /&gt;
        end if.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred(X,Y)=Z:-&lt;br /&gt;
        if X=0 then&lt;br /&gt;
            Z=&amp;quot;x is zero&amp;quot;&lt;br /&gt;
        elseif X&amp;gt;0 then&lt;br /&gt;
            if pred3(Y)=true then&lt;br /&gt;
                Z=&amp;quot;x&amp;gt;0 and pred(Y) is true&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
                Z=&amp;quot;x&amp;gt;0 and pred(Y) is false&amp;quot;&lt;br /&gt;
            end if  %note, no comma here either&lt;br /&gt;
        else&lt;br /&gt;
            Z=&amp;quot;x &amp;lt;0&amp;quot;&lt;br /&gt;
        end if.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== #if #then #else (directive for conditional compilation) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;constants&lt;br /&gt;
    u64_con=1.&lt;br /&gt;
    int_con=2.&lt;br /&gt;
    real_con=3.&lt;br /&gt;
&lt;br /&gt;
    compile_big_con=u64_con. %change this and then recompile.&lt;br /&gt;
&lt;br /&gt;
#if compile_big_con=u64_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred:()-&amp;gt;unsigned64.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred()=U64:-&lt;br /&gt;
            U64=78766.&lt;br /&gt;
&lt;br /&gt;
#elseif compile_big_con=int_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred:()-&amp;gt;integer.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred()=Int:-&lt;br /&gt;
            Int=20.&lt;br /&gt;
&lt;br /&gt;
#else&lt;br /&gt;
    predicates&lt;br /&gt;
        pred:(real [out]).&lt;br /&gt;
    clauses&lt;br /&gt;
        pred(0.766).&lt;br /&gt;
&lt;br /&gt;
#endif&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Code construct uses     &amp;lt;vp&amp;gt;if  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;elseif  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;else&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;end if&amp;lt;/vp&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
compiler directive uses &amp;lt;vp&amp;gt;#if - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#elseif - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#else&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#endif&amp;lt;/vp&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;(just the &amp;quot;end if&amp;quot; is &amp;quot;different&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Trap and try/catch/finally ===&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms/Try-catch-finally Try-catch-finally]&amp;lt;br&amp;gt;&lt;br /&gt;
Note, in&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Predicates Built-in entities/Predicates]&amp;lt;br&amp;gt;&lt;br /&gt;
suggests using &amp;lt;vp&amp;gt;try-end try&amp;lt;/vp&amp;gt; instead of &amp;lt;vp&amp;gt;trap(_,_,_)&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_all():-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    call_pred_that_might_crash:(integer).&lt;br /&gt;
    call_own_exception_pred:(pointer ErrorNo).&lt;br /&gt;
    always_call_this_anyway:().&lt;br /&gt;
clauses&lt;br /&gt;
    call_pred_that_might_crash(X):-&lt;br /&gt;
        Y=9/X.&lt;br /&gt;
&lt;br /&gt;
    call_own_exception_pred(ErrorNo):-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;crashed&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
    always_call_this_anyway():-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;finally reached&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some():-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% in this case, VIP will automatically pop up its exception dialog&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some():-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 4&amp;#039;&amp;#039;&amp;#039; - illegal - it must have a &amp;lt;vp&amp;gt;catch&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;finally&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_illegal():-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== 64 bit numbers - history ===&lt;br /&gt;
Up to VIP7.1, integer64 etc were defined as:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
    unsigned64 = unsigned64(unsigned32 Low, unsigned32 High).&lt;br /&gt;
    integer64 = integer64(unsigned32 Low, integer32 High).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In VIP7.2 these have been renamed:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
    unsigned64_struct = unsigned64(unsigned Low, unsigned High).&lt;br /&gt;
    integer64_struct = integer64(unsigned Low, integer High).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, for example, in VIP7.1:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
     getFileProperties : (&lt;br /&gt;
        string FileName,&lt;br /&gt;
        fileSystem_api::fileAttributes Attributes,&lt;br /&gt;
        fileSystem_api::fileSize Size,&lt;br /&gt;
        core::gmtTimeValue Creation,&lt;br /&gt;
        core::gmtTimeValue LastAccess,&lt;br /&gt;
        core::gmtTimeValue LastChange)&lt;br /&gt;
        procedure (i,o,o,o,o,o).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
if you needed use (and write) &amp;#039;&amp;#039;&amp;#039;fileSize&amp;#039;&amp;#039;&amp;#039; and times, you would have to have done some juggling (such as converting them to real numbers). &lt;br /&gt;
&amp;lt;br&amp;gt;To generate a 64 bit random number:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates %before VIP7.2&lt;br /&gt;
    gen64:()-&amp;gt;unsigned64.&lt;br /&gt;
clauses&lt;br /&gt;
    gen64()=U64:-&lt;br /&gt;
        N= 2^32,&lt;br /&gt;
        Low=math::random(N+0),&lt;br /&gt;
        High=math::random(N+0),&lt;br /&gt;
        U64=unsigned64(Low,High).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and possibly you would have needed (e.g.) &amp;#039;&amp;#039;&amp;#039;math::add&amp;#039;&amp;#039;&amp;#039;:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
    add : (core::unsigned64 Augend, core::unsigned64 Addend) -&amp;gt; core::unsigned64 Sum&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s now totally straightforward in VIP7.2 - just treat 64 bit numbers like any other number. You may also want these conversions - found in &amp;#039;&amp;#039;&amp;#039;core::&amp;#039;&amp;#039;&amp;#039; - for old code (this snippet is stolen from [http://discuss.visual-prolog.com/viewtopic.php?t=7927 Thomas&amp;#039; post]) &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
predicates&lt;br /&gt;
    toUnsigned64 : (unsigned64_struct) -&amp;gt; unsigned64.&lt;br /&gt;
    fromUnsigned64 : (unsigned64) -&amp;gt; unsigned64_struct.&lt;br /&gt;
    toInteger64 : (integer64_struct) -&amp;gt; integer64.&lt;br /&gt;
    fromInteger64 : (integer64) -&amp;gt; integer64_struct.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
And just for reference:&amp;lt;br&amp;gt;&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#integer integer] range = -2^31 to +2^31 = -2147483648 .. 2147483647&amp;lt;br&amp;gt;&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#unsigned unsigned]  range = 0 to (2^32)-1 = 4294967295&amp;lt;br&amp;gt;&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#integer64 integer64] range = -2^63 to 2^63&amp;lt;br&amp;gt; &lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#unsigned64 unsigned64] range= 0 to (2^64)-1 = 18446744073709551615 (=1.844..E19)&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Polymorphic Domains ===&lt;br /&gt;
See [http://wiki.visual-prolog.com/index.php?title=Objects_and_Polymorphism Objects and Polymorphism]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First, check out the definitions - &amp;#039;&amp;#039;&amp;#039;core::tuple{}&amp;#039;&amp;#039;&amp;#039;. And while you&amp;#039;re there, just below, see &amp;#039;&amp;#039;&amp;#039;core::predicate{}&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;core::function{}&amp;#039;&amp;#039;&amp;#039;, then followed by &amp;#039;&amp;#039;&amp;#039;comparator{A}&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;list{A}&amp;#039;&amp;#039;&amp;#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The domains in class &amp;#039;&amp;#039;&amp;#039;list::&amp;#039;&amp;#039;&amp;#039; are polymorphic, but you can define your own polymorphic domains. Here are some examples:&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
	poly_dom{A,B}=poly_def(A,B).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
When you use it in your code, A and B can be any other domain.&amp;lt;br&amp;gt;&lt;br /&gt;
The domain name is &amp;#039;&amp;#039;&amp;#039;poly_dom{A,B}&amp;#039;&amp;#039;&amp;#039;, and you reference it you must use its whole name (not just &amp;#039;&amp;#039;&amp;#039;poly_dom&amp;#039;&amp;#039;&amp;#039;) e.g. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	joe{A,B}=poly_dom{A,B}*.	&lt;br /&gt;
/* the next two lines are illegal&lt;br /&gt;
	poly_dom{A,B}=poly_def(A,B)*.&lt;br /&gt;
	poly_dom{A,A}=poly_def(A,A).&lt;br /&gt;
*/&lt;br /&gt;
	fred{A,B}=fred(poly_dom{A,B},integer).&lt;br /&gt;
&lt;br /&gt;
	maybe_silly_dom{A,B}=silly2(A,B);&lt;br /&gt;
							silly(A);&lt;br /&gt;
							pd(poly_dom{A,B});&lt;br /&gt;
							poly_dom(A,B);%IS NOT THE SAME POLY_DOM!! (notice no braces)&lt;br /&gt;
							s(string).&lt;br /&gt;
							&lt;br /&gt;
	another{A}=i(integer);&lt;br /&gt;
				s(string);&lt;br /&gt;
				a(A);&lt;br /&gt;
				self(another({A}).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
	zz_poly_dom:poly_dom{integer,integer}:=erroneous.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
	p_morphic_test:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_morphic_test():-&lt;br /&gt;
		zz_poly_dom:=poly_def(1,5),&lt;br /&gt;
		call_pd(zz_poly_dom),&lt;br /&gt;
		fail.&lt;br /&gt;
	p_morphic_test():-&lt;br /&gt;
		PD=poly_def(1,[&amp;quot;an example&amp;quot;,&amp;quot;or two&amp;quot;]),&lt;br /&gt;
		call_pd(PD),&lt;br /&gt;
		fail.&lt;br /&gt;
	p_morphic_test():-&lt;br /&gt;
		Q= [poly_def(X, Y) || X= std::fromTo(1, 4),&lt;br /&gt;
					Y= std::fromTo(1, 5)],&lt;br /&gt;
		stdio::write(&amp;quot;\n&amp;quot;,Q),&lt;br /&gt;
		fail.&lt;br /&gt;
	p_morphic_test().&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
	call_pd:(poly_dom{A,B}).&lt;br /&gt;
clauses&lt;br /&gt;
	call_pd(POLY_DOM):-&lt;br /&gt;
		stdio::write(&amp;quot;\n&amp;quot;,POLY_DOM),&lt;br /&gt;
		fail.&lt;br /&gt;
	call_pd(poly_def(A,B)):-%note this is POLY_DEF&lt;br /&gt;
		stdio::write(&amp;quot;\n&amp;quot;,A,B),&lt;br /&gt;
		fail.&lt;br /&gt;
	call_pd(_).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Properties ===&lt;br /&gt;
&lt;br /&gt;
Properties in a class are used almost identically to fact variables, but properties can be set directly (from another class), without having to declare a public predicate to make the change.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface fred&lt;br /&gt;
    domains&lt;br /&gt;
        complete_dom=is_complete;&lt;br /&gt;
                     not_complete.&lt;br /&gt;
    properties&lt;br /&gt;
        prop_complete : complete_dom.&lt;br /&gt;
end interface fred&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;#039;&amp;#039;&amp;#039;fred.pro&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement fred&lt;br /&gt;
facts&lt;br /&gt;
    zz_complete:complete_dom:=erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses %for the property&lt;br /&gt;
    prop_complete()=zz_complete. %get&lt;br /&gt;
    prop_complete(COMPLETE):-zz_complete:=COMPLETE. %set&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some other class that calls class fred:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;implement other&lt;br /&gt;
    open fred&lt;br /&gt;
clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
        Fred=fred::new(),&lt;br /&gt;
        Fred:prop_complete:=is_complete,% to set the value&lt;br /&gt;
        Value=Fred:prop_complete,!. %get&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Comparators and compare ===&lt;br /&gt;
First, look at the definition of &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
    comparator{T} = function{T, T, compareResult}.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;compareResult&amp;#039;s&amp;#039;&amp;#039;&amp;#039; definition can is found here:&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#compareResult compareResult]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
	p_compare_test:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_compare_test():-&lt;br /&gt;
		CompareResult=compare(7,2).&lt;br /&gt;
		%will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;greater()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
		%(because 7 &amp;gt; 2)&lt;br /&gt;
	p_compare_test():-&lt;br /&gt;
		CompareResult=compare(2,2).&lt;br /&gt;
		%will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;equal()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
	p_compare_test():-&lt;br /&gt;
		CompareResult=compare(&amp;quot;a&amp;quot;,&amp;quot;z&amp;quot;).&lt;br /&gt;
		%will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;less()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But you may wish to check your own domains to see which is &amp;quot;greater&amp;quot; - and of course you must define this yourself, by defining your own predicate as a &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Here is a simple domain in which only the integer parts of the variables are checked to see which is greater:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	s=s(string,integer).&lt;br /&gt;
	&lt;br /&gt;
class predicates&lt;br /&gt;
	compare_it: core::comparator{s}.&lt;br /&gt;
clauses			&lt;br /&gt;
	compare_it(A,B)=CompareResult:-%since this is a core::function(T,T,compareResult)&lt;br /&gt;
		A=s(_,I),&lt;br /&gt;
		B=s(_,J),&lt;br /&gt;
		if I&amp;lt;J then&lt;br /&gt;
			CompareResult=less()&lt;br /&gt;
		elseif I=J then&lt;br /&gt;
			CompareResult=equal()&lt;br /&gt;
		else&lt;br /&gt;
			CompareResult=greater()&lt;br /&gt;
		end if.&lt;br /&gt;
		&lt;br /&gt;
class predicates&lt;br /&gt;
	p_compare_test:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_compare_test():-&lt;br /&gt;
		S1=s(&amp;quot;abc&amp;quot;,7),&lt;br /&gt;
		S2=s(&amp;quot;fred&amp;quot;,9),&lt;br /&gt;
		CompareResult=compare_it(S1,S2),&lt;br /&gt;
		%will give CompareResult=less, since 7&amp;lt;9.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
...a bit pointless since the string part of the variables have been ignored, but it is easy to see how to expand &amp;#039;&amp;#039;&amp;#039;compare_it()&amp;#039;&amp;#039;&amp;#039; to your own needs.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== More on core::function and core::predicate ===&lt;br /&gt;
Again, please check out &amp;#039;&amp;#039;&amp;#039;core::function&amp;#039;&amp;#039;&amp;#039;.  &amp;#039;&amp;#039;&amp;#039;core::predicate&amp;#039;&amp;#039;&amp;#039; is essentially the same, but does not return a value.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
	two_times:function{integer,integer}.&lt;br /&gt;
% or	two_times: core::function{integer,integer}.&lt;br /&gt;
clauses			&lt;br /&gt;
	two_times(A)=2*A.&lt;br /&gt;
class predicates&lt;br /&gt;
	p_function:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_function():-&lt;br /&gt;
		Z=two_times(2),&lt;br /&gt;
		%binds Z to 4&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	fred_dom{A,B}=predicate{A,B}.&lt;br /&gt;
% or	fred_dom{A,B}=core::predicate{A,B}.&lt;br /&gt;
class predicates&lt;br /&gt;
	fred_pred: fred_dom{A,B}.&lt;br /&gt;
clauses	&lt;br /&gt;
	fred_pred(A,B):-&lt;br /&gt;
		stdio::write(&amp;quot;\n&amp;quot;,A,&amp;quot; &amp;quot;,B).&lt;br /&gt;
class predicates&lt;br /&gt;
	p_pred:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_pred():-&lt;br /&gt;
		fred_pred(&amp;quot;one&amp;quot;,2).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
	add_func: function{integer,integer}.&lt;br /&gt;
clauses	&lt;br /&gt;
	add_func(B)=B+1.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
	p_function:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_function():-&lt;br /&gt;
		X=add_func(5),&lt;br /&gt;
		%X is bound to 6&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Anonymous predicates ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;(under development)&amp;#039;&amp;#039;&lt;br /&gt;
See [http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms/Anonymous_Predicates Anonymous_Predicates]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon={()=9},&lt;br /&gt;
        K=Anon().&lt;br /&gt;
        %results in K=9&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon={=88},&lt;br /&gt;
        K=Anon().&lt;br /&gt;
        %results in K=88.&lt;br /&gt;
    run():-&lt;br /&gt;
        Anon={(A,B)=A+B},&lt;br /&gt;
        K=Anon(4,8),&lt;br /&gt;
        %results in K=12.&lt;br /&gt;
    run():-&lt;br /&gt;
        Anon={&lt;br /&gt;
            (A,B)=C:-&lt;br /&gt;
            R=math::random(7),&lt;br /&gt;
            C=A+B+R,&lt;br /&gt;
            stdio::wRite(&amp;quot;RRRR=&amp;quot;,R)&lt;br /&gt;
            },&lt;br /&gt;
        K=Anon(4,8).&lt;br /&gt;
        %results in K=12 + a random number &amp;lt;7&lt;br /&gt;
&lt;br /&gt;
    run():-&lt;br /&gt;
        Anon={=f_abc(3)},&lt;br /&gt;
        K=Anon(),&lt;br /&gt;
        stdio::write(&amp;quot;\nI={=f_abc(3)} gives &amp;quot;,K),&lt;br /&gt;
        fail.&lt;br /&gt;
    run().&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Threads ===&lt;br /&gt;
&lt;br /&gt;
To start a thread:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
        _=thread::start(fred).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred:().&lt;br /&gt;
clauses&lt;br /&gt;
    fred():-.....&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
fred can have no arguments, so no argument brackets are allowed:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
    _=thread::start(fred())&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is illegal. But the thread can access data prepared before it is started.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    zz_int:integer:=erroneous.&lt;br /&gt;
clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
        zz_int:=88,&lt;br /&gt;
        _=thread::start(fred).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred:().&lt;br /&gt;
clauses&lt;br /&gt;
    fred():-&lt;br /&gt;
        K=zz_int,&lt;br /&gt;
        ...&amp;lt;/vip&amp;gt;&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=1838</id>
		<title>VIP7 Construct examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=VIP7_Construct_examples&amp;diff=1838"/>
		<updated>2009-03-24T08:38:54Z</updated>

		<summary type="html">&lt;p&gt;Steve Lympany: /* Fact variables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains a collection of basic examples for (mainly) the newer constructs found in VIP7.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Fact variables ===&lt;br /&gt;
&lt;br /&gt;
Fact variables are the only mutable types in VIP.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples - &amp;quot;reminder- ordinary facts&amp;quot;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb_int:(integer).  % a nondeterministic fact (0 to any number of values)&lt;br /&gt;
    db_int:(integer,string) determ. % a deterministic fact (0 to 1 value)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These types of fact are asserted and retracted.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples - &amp;quot;fact variables&amp;quot;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    zz_int:integer:=0.&lt;br /&gt;
    zz_fred:integer:=erroneous.&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    dom=dom(string,chaindb:ref).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    zz_dom:dom:=erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
        zz_int:=7,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;,zz_int), %will write &amp;quot;zz_int=7&amp;quot;&lt;br /&gt;
        zz_int:=zz_int+20,&lt;br /&gt;
        stdio::write(&amp;quot;\n zz_int = &amp;quot;,zz_int), %will write &amp;quot;zz_int=27&amp;quot;&lt;br /&gt;
        succeed.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A fact variable is great for counting eg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    how_many:()-&amp;gt;integer Count.&lt;br /&gt;
clauses&lt;br /&gt;
    how_many()=_:-&lt;br /&gt;
        zz_int:=0,&lt;br /&gt;
        some_nondeterm_fact_or_pred(),&lt;br /&gt;
            zz_int:=zz_int+1,&lt;br /&gt;
            fail.&lt;br /&gt;
    how_many()=zz_int.&lt;br /&gt;
clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
       stdio::write(&amp;quot;\n There are &amp;quot;,how_many(),&amp;quot; items&amp;quot;).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lists - findall and list comprehension ===&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.visual-prolog.com/index.php?title=Lists_and_Recursion Lists and Recursion]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vp&amp;gt;findall()&amp;lt;/vp&amp;gt; has been depricated, so use the list comprehension construct.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    ndb:(integer). %default is nondeterm for a fact&lt;br /&gt;
clauses&lt;br /&gt;
    ndb(1).&lt;br /&gt;
    ndb(2).&lt;br /&gt;
    ndb(3).&lt;br /&gt;
    ....&lt;br /&gt;
    ndb(10).&lt;br /&gt;
clauses&lt;br /&gt;
    pred_old():-&lt;br /&gt;
        findall(X,ndb(X),List).&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
clauses&lt;br /&gt;
    pred_new():-&lt;br /&gt;
        List=[X||ndb(X)].&lt;br /&gt;
        %results in List = [1,2,3,4,5,6,7,8,9,10]&lt;br /&gt;
clauses&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        List=[X||ndb(X), X&amp;gt;6].&lt;br /&gt;
        %results in List = [7,8,9,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        List=[X||ndb(X), X mod 2=0].&lt;br /&gt;
        %results in List = [2,4,6,8,10]&lt;br /&gt;
&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        List=[X||ndb(X), X mod 2=0, X&amp;lt;7].&lt;br /&gt;
        %results in List = [2,4,6]&lt;br /&gt;
&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        zz_int:=0,&lt;br /&gt;
        List=[X||ndb(X), X mod 2=0, X&amp;lt;7, zz_int:=zz_int+1].&lt;br /&gt;
        %results in List = [2,4,6] and zz_int=3.&lt;br /&gt;
&lt;br /&gt;
    pred_filter():-&lt;br /&gt;
        List=[X||ndb(X), Y=pred2(X), Y&amp;gt;10].   %with pred2(X)=X^2.&lt;br /&gt;
        %results in List = [4,5,6,7,8,9,10]&lt;br /&gt;
        %reason - X=3 gives Y=9 which is &amp;lt; 10.&lt;br /&gt;
&lt;br /&gt;
    pred_other():-&lt;br /&gt;
        L=[1,2,3,4,5,6,7,8,9,10],&lt;br /&gt;
        LIST=[ X || X = list::getMember_nd(L)].&lt;br /&gt;
        %results in List= L&lt;br /&gt;
&lt;br /&gt;
    pred_other():-&lt;br /&gt;
        Primes=[X||X=std::fromto(1,300),&lt;br /&gt;
		L1=[Y||Y=std::fromto(2,150)],&lt;br /&gt;
		tt(X,L1)].&lt;br /&gt;
        %results in List= prime numbers, with:&lt;br /&gt;
class predicates&lt;br /&gt;
        tt:(integer,integer*) determ.&lt;br /&gt;
clauses&lt;br /&gt;
        tt(_X,[]):-!.&lt;br /&gt;
        tt(X,[X|_]):-!.&lt;br /&gt;
        tt(X,[Y|L]):-&lt;br /&gt;
		X mod Y&amp;lt;&amp;gt;0,&lt;br /&gt;
		tt(X,L).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== if-then-else (code) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred(X):-&lt;br /&gt;
        if X&amp;gt;0 then&lt;br /&gt;
            stdio::write(&amp;quot;\n X&amp;gt;0&amp;quot;)  %the last line in each block has no comma&lt;br /&gt;
        else&lt;br /&gt;
            stdio::write(&amp;quot;\n X&amp;lt;=0&amp;quot;)&lt;br /&gt;
        end if.&lt;br /&gt;
&lt;br /&gt;
    pred(X):-&lt;br /&gt;
        if X&amp;gt;0 then&lt;br /&gt;
            stdio::write(&amp;quot;\n X&amp;gt;0&amp;quot;)&lt;br /&gt;
        elseif X = 0 then&lt;br /&gt;
            stdio::write(&amp;quot;\n X=0&amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
            stdio::write(&amp;quot;\n X&amp;lt;0&amp;quot;)&lt;br /&gt;
        end if.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    pred(X,Y)=Z:-&lt;br /&gt;
        if X=0 then&lt;br /&gt;
            Z=&amp;quot;x is zero&amp;quot;&lt;br /&gt;
        elseif X&amp;gt;0 then&lt;br /&gt;
            if pred3(Y)=true then&lt;br /&gt;
                Z=&amp;quot;x&amp;gt;0 and pred(Y) is true&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
                Z=&amp;quot;x&amp;gt;0 and pred(Y) is false&amp;quot;&lt;br /&gt;
            end if  %note, no comma here either&lt;br /&gt;
        else&lt;br /&gt;
            Z=&amp;quot;x &amp;lt;0&amp;quot;&lt;br /&gt;
        end if.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== #if #then #else (directive for conditional compilation) ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;constants&lt;br /&gt;
    u64_con=1.&lt;br /&gt;
    int_con=2.&lt;br /&gt;
    real_con=3.&lt;br /&gt;
&lt;br /&gt;
    compile_big_con=u64_con. %change this and then recompile.&lt;br /&gt;
&lt;br /&gt;
#if compile_big_con=u64_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred:()-&amp;gt;unsigned64.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred()=U64:-&lt;br /&gt;
            U64=78766.&lt;br /&gt;
&lt;br /&gt;
#elseif compile_big_con=int_con #then&lt;br /&gt;
    predicates&lt;br /&gt;
        pred:()-&amp;gt;integer.&lt;br /&gt;
    clauses&lt;br /&gt;
        pred()=Int:-&lt;br /&gt;
            Int=20.&lt;br /&gt;
&lt;br /&gt;
#else&lt;br /&gt;
    predicates&lt;br /&gt;
        pred:(real [out]).&lt;br /&gt;
    clauses&lt;br /&gt;
        pred(0.766).&lt;br /&gt;
&lt;br /&gt;
#endif&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Code construct uses     &amp;lt;vp&amp;gt;if  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;elseif  - then&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;else&amp;lt;/vp&amp;gt;,  &amp;lt;vp&amp;gt;end if&amp;lt;/vp&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
compiler directive uses &amp;lt;vp&amp;gt;#if - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#elseif - #then&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#else&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;#endif&amp;lt;/vp&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;(just the &amp;quot;end if&amp;quot; is &amp;quot;different&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Trap and try/catch/finally ===&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms/Try-catch-finally Try-catch-finally]&amp;lt;br&amp;gt;&lt;br /&gt;
Note, in&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Predicates Built-in entities/Predicates]&amp;lt;br&amp;gt;&lt;br /&gt;
suggests using &amp;lt;vp&amp;gt;try-end try&amp;lt;/vp&amp;gt; instead of &amp;lt;vp&amp;gt;trap(_,_,_)&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_all():-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    call_pred_that_might_crash:(integer).&lt;br /&gt;
    call_own_exception_pred:(pointer ErrorNo).&lt;br /&gt;
    always_call_this_anyway:().&lt;br /&gt;
clauses&lt;br /&gt;
    call_pred_that_might_crash(X):-&lt;br /&gt;
        Y=9/X.&lt;br /&gt;
&lt;br /&gt;
    call_own_exception_pred(ErrorNo):-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;crashed&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
    always_call_this_anyway():-&lt;br /&gt;
        vpiCommonDialogs::note(&amp;quot;finally reached&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some():-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        finally&lt;br /&gt;
            always_call_this_anyway()&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% in this case, VIP will automatically pop up its exception dialog&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_some():-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        catch ErrorNo do&lt;br /&gt;
            call_own_exception_pred(ErrorNo)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 4&amp;#039;&amp;#039;&amp;#039; - illegal - it must have a &amp;lt;vp&amp;gt;catch&amp;lt;/vp&amp;gt; or &amp;lt;vp&amp;gt;finally&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred_illegal():-&lt;br /&gt;
        try&lt;br /&gt;
            call_pred_that_might_crash(0)&lt;br /&gt;
        end try.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== 64 bit numbers - history ===&lt;br /&gt;
Up to VIP7.1, integer64 etc were defined as:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
    unsigned64 = unsigned64(unsigned32 Low, unsigned32 High).&lt;br /&gt;
    integer64 = integer64(unsigned32 Low, integer32 High).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In VIP7.2 these have been renamed:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
    unsigned64_struct = unsigned64(unsigned Low, unsigned High).&lt;br /&gt;
    integer64_struct = integer64(unsigned Low, integer High).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, for example, in VIP7.1:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
     getFileProperties : (&lt;br /&gt;
        string FileName,&lt;br /&gt;
        fileSystem_api::fileAttributes Attributes,&lt;br /&gt;
        fileSystem_api::fileSize Size,&lt;br /&gt;
        core::gmtTimeValue Creation,&lt;br /&gt;
        core::gmtTimeValue LastAccess,&lt;br /&gt;
        core::gmtTimeValue LastChange)&lt;br /&gt;
        procedure (i,o,o,o,o,o).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
if you needed use (and write) &amp;#039;&amp;#039;&amp;#039;fileSize&amp;#039;&amp;#039;&amp;#039; and times, you would have to have done some juggling (such as converting them to real numbers). &lt;br /&gt;
&amp;lt;br&amp;gt;To generate a 64 bit random number:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates %before VIP7.2&lt;br /&gt;
    gen64:()-&amp;gt;unsigned64.&lt;br /&gt;
clauses&lt;br /&gt;
    gen64()=U64:-&lt;br /&gt;
        N= 2^32,&lt;br /&gt;
        Low=math::random(N+0),&lt;br /&gt;
        High=math::random(N+0),&lt;br /&gt;
        U64=unsigned64(Low,High).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and possibly you would have needed (e.g.) &amp;#039;&amp;#039;&amp;#039;math::add&amp;#039;&amp;#039;&amp;#039;:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
    add : (core::unsigned64 Augend, core::unsigned64 Addend) -&amp;gt; core::unsigned64 Sum&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s now totally straightforward in VIP7.2 - just treat 64 bit numbers like any other number. You may also want these conversions - found in &amp;#039;&amp;#039;&amp;#039;core::&amp;#039;&amp;#039;&amp;#039; - for old code (this snippet is stolen from [http://discuss.visual-prolog.com/viewtopic.php?t=7927 Thomas&amp;#039; post]) &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
predicates&lt;br /&gt;
    toUnsigned64 : (unsigned64_struct) -&amp;gt; unsigned64.&lt;br /&gt;
    fromUnsigned64 : (unsigned64) -&amp;gt; unsigned64_struct.&lt;br /&gt;
    toInteger64 : (integer64_struct) -&amp;gt; integer64.&lt;br /&gt;
    fromInteger64 : (integer64) -&amp;gt; integer64_struct.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
And just for reference:&amp;lt;br&amp;gt;&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#integer integer] range = -2^31 to +2^31 = -2147483648 .. 2147483647&amp;lt;br&amp;gt;&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#unsigned unsigned]  range = 0 to (2^32)-1 = 4294967295&amp;lt;br&amp;gt;&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#integer64 integer64] range = -2^63 to 2^63&amp;lt;br&amp;gt; &lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#unsigned64 unsigned64] range= 0 to (2^64)-1 = 18446744073709551615 (=1.844..E19)&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Polymorphic Domains ===&lt;br /&gt;
See [http://wiki.visual-prolog.com/index.php?title=Objects_and_Polymorphism Objects and Polymorphism]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First, check out the definitions - &amp;#039;&amp;#039;&amp;#039;core::tuple{}&amp;#039;&amp;#039;&amp;#039;. And while you&amp;#039;re there, just below, see &amp;#039;&amp;#039;&amp;#039;core::predicate{}&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;core::function{}&amp;#039;&amp;#039;&amp;#039;, then followed by &amp;#039;&amp;#039;&amp;#039;comparator{A}&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;list{A}&amp;#039;&amp;#039;&amp;#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The domains in class &amp;#039;&amp;#039;&amp;#039;list::&amp;#039;&amp;#039;&amp;#039; are polymorphic, but you can define your own polymorphic domains. Here are some examples:&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
	poly_dom{A,B}=poly_def(A,B).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
When you use it in your code, A and B can be any other domain.&amp;lt;br&amp;gt;&lt;br /&gt;
The domain name is &amp;#039;&amp;#039;&amp;#039;poly_dom{A,B}&amp;#039;&amp;#039;&amp;#039;, and you reference it you must use its whole name (not just &amp;#039;&amp;#039;&amp;#039;poly_dom&amp;#039;&amp;#039;&amp;#039;) e.g. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	joe{A,B}=poly_dom{A,B}*.	&lt;br /&gt;
/* the next two lines are illegal&lt;br /&gt;
	poly_dom{A,B}=poly_def(A,B)*.&lt;br /&gt;
	poly_dom{A,A}=poly_def(A,A).&lt;br /&gt;
*/&lt;br /&gt;
	fred{A,B}=fred(poly_dom{A,B},integer).&lt;br /&gt;
&lt;br /&gt;
	maybe_silly_dom{A,B}=silly2(A,B);&lt;br /&gt;
							silly(A);&lt;br /&gt;
							pd(poly_dom{A,B});&lt;br /&gt;
							poly_dom(A,B);%IS NOT THE SAME POLY_DOM!! (notice no braces)&lt;br /&gt;
							s(string).&lt;br /&gt;
							&lt;br /&gt;
	another{A}=i(integer);&lt;br /&gt;
				s(string);&lt;br /&gt;
				a(A);&lt;br /&gt;
				self(another({A}).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
	zz_poly_dom:poly_dom{integer,integer}:=erroneous.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
	p_morphic_test:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_morphic_test():-&lt;br /&gt;
		zz_poly_dom:=poly_def(1,5),&lt;br /&gt;
		call_pd(zz_poly_dom),&lt;br /&gt;
		fail.&lt;br /&gt;
	p_morphic_test():-&lt;br /&gt;
		PD=poly_def(1,[&amp;quot;an example&amp;quot;,&amp;quot;or two&amp;quot;]),&lt;br /&gt;
		call_pd(PD),&lt;br /&gt;
		fail.&lt;br /&gt;
	p_morphic_test():-&lt;br /&gt;
		Q= [poly_def(X, Y) || X= std::fromTo(1, 4),&lt;br /&gt;
					Y= std::fromTo(1, 5)],&lt;br /&gt;
		stdio::write(&amp;quot;\n&amp;quot;,Q),&lt;br /&gt;
		fail.&lt;br /&gt;
	p_morphic_test().&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
	call_pd:(poly_dom{A,B}).&lt;br /&gt;
clauses&lt;br /&gt;
	call_pd(POLY_DOM):-&lt;br /&gt;
		stdio::write(&amp;quot;\n&amp;quot;,POLY_DOM),&lt;br /&gt;
		fail.&lt;br /&gt;
	call_pd(poly_def(A,B)):-%note this is POLY_DEF&lt;br /&gt;
		stdio::write(&amp;quot;\n&amp;quot;,A,B),&lt;br /&gt;
		fail.&lt;br /&gt;
	call_pd(_).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Properties ===&lt;br /&gt;
&lt;br /&gt;
Properties in a class are used almost identically to fact variables, but properties can be set directly (from another class), without having to declare a public predicate to make the change.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;interface fred&lt;br /&gt;
    domains&lt;br /&gt;
        complete_dom=is_complete;&lt;br /&gt;
                     not_complete.&lt;br /&gt;
    properties&lt;br /&gt;
        prop_complete : complete_dom.&lt;br /&gt;
end interface fred&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;#039;&amp;#039;&amp;#039;fred.pro&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement fred&lt;br /&gt;
facts&lt;br /&gt;
    zz_complete:complete_dom:=erroneous.&lt;br /&gt;
&lt;br /&gt;
clauses %for the property&lt;br /&gt;
    prop_complete()=zz_complete. %get&lt;br /&gt;
    prop_complete(COMPLETE):-zz_complete:=COMPLETE. %set&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some other class that calls class fred:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;implement other&lt;br /&gt;
    open fred&lt;br /&gt;
clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
        Fred=fred::new(),&lt;br /&gt;
        Fred:prop_complete:=is_complete,% to set the value&lt;br /&gt;
        Value=Fred:prop_complete,!. %get&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== Comparators and compare ===&lt;br /&gt;
First, look at the definition of &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
    comparator{T} = function{T, T, compareResult}.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;compareResult&amp;#039;s&amp;#039;&amp;#039;&amp;#039; definition can is found here:&lt;br /&gt;
[http://wiki.visual-prolog.com/index.php?title=Language_Reference/Built-in_entities/Domains#compareResult compareResult]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
	p_compare_test:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_compare_test():-&lt;br /&gt;
		CompareResult=compare(7,2).&lt;br /&gt;
		%will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;greater()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
		%(because 7 &amp;gt; 2)&lt;br /&gt;
	p_compare_test():-&lt;br /&gt;
		CompareResult=compare(2,2).&lt;br /&gt;
		%will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;equal()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
	p_compare_test():-&lt;br /&gt;
		CompareResult=compare(&amp;quot;a&amp;quot;,&amp;quot;z&amp;quot;).&lt;br /&gt;
		%will bind CompareResult to &amp;#039;&amp;#039;&amp;#039;less()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But you may wish to check your own domains to see which is &amp;quot;greater&amp;quot; - and of course you must define this yourself, by defining your own predicate as a &amp;#039;&amp;#039;&amp;#039;core::comparator&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Here is a simple domain in which only the integer parts of the variables are checked to see which is greater:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	s=s(string,integer).&lt;br /&gt;
	&lt;br /&gt;
class predicates&lt;br /&gt;
	compare_it: core::comparator{s}.&lt;br /&gt;
clauses			&lt;br /&gt;
	compare_it(A,B)=CompareResult:-%since this is a core::function(T,T,compareResult)&lt;br /&gt;
		A=s(_,I),&lt;br /&gt;
		B=s(_,J),&lt;br /&gt;
		if I&amp;lt;J then&lt;br /&gt;
			CompareResult=less()&lt;br /&gt;
		elseif I=J then&lt;br /&gt;
			CompareResult=equal()&lt;br /&gt;
		else&lt;br /&gt;
			CompareResult=greater()&lt;br /&gt;
		end if.&lt;br /&gt;
		&lt;br /&gt;
class predicates&lt;br /&gt;
	p_compare_test:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_compare_test():-&lt;br /&gt;
		S1=s(&amp;quot;abc&amp;quot;,7),&lt;br /&gt;
		S2=s(&amp;quot;fred&amp;quot;,9),&lt;br /&gt;
		CompareResult=compare_it(S1,S2),&lt;br /&gt;
		%will give CompareResult=less, since 7&amp;lt;9.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
...a bit pointless since the string part of the variables have been ignored, but it is easy to see how to expand &amp;#039;&amp;#039;&amp;#039;compare_it()&amp;#039;&amp;#039;&amp;#039; to your own needs.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
=== More on core::function and core::predicate ===&lt;br /&gt;
Again, please check out &amp;#039;&amp;#039;&amp;#039;core::function&amp;#039;&amp;#039;&amp;#039;.  &amp;#039;&amp;#039;&amp;#039;core::predicate&amp;#039;&amp;#039;&amp;#039; is essentially the same, but does not return a value.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
	two_times:function{integer,integer}.&lt;br /&gt;
clauses			&lt;br /&gt;
	two_times(A)=2*A.&lt;br /&gt;
class predicates&lt;br /&gt;
	p_function:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_function():-&lt;br /&gt;
		Z=two_times(2),&lt;br /&gt;
		%binds Z to 4&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
domains&lt;br /&gt;
	fred_dom{A,B}=predicate{A,B}.&lt;br /&gt;
class predicates&lt;br /&gt;
	fred_pred: fred_dom{A,B}.&lt;br /&gt;
clauses	&lt;br /&gt;
	fred_pred(A,B):-&lt;br /&gt;
		stdio::write(&amp;quot;\n&amp;quot;,A,&amp;quot; &amp;quot;,B).&lt;br /&gt;
class predicates&lt;br /&gt;
	p_function:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_function():-&lt;br /&gt;
		fred_pred(&amp;quot;one&amp;quot;,2).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example 3&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
	add_pred: function{integer,integer}.&lt;br /&gt;
clauses	&lt;br /&gt;
	add_pred(B)=B+1.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
	p_function:(). &lt;br /&gt;
clauses			&lt;br /&gt;
	p_function():-&lt;br /&gt;
		X=add_pred(5),&lt;br /&gt;
		%X is mound to 6&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Anonymous predicates ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;(under development)&amp;#039;&amp;#039;&lt;br /&gt;
See [http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms/Anonymous_Predicates Anonymous_Predicates]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon={()=9},&lt;br /&gt;
        K=Anon().&lt;br /&gt;
        %results in K=9&lt;br /&gt;
    run() :-&lt;br /&gt;
        Anon={=88},&lt;br /&gt;
        K=Anon().&lt;br /&gt;
        %results in K=88.&lt;br /&gt;
    run():-&lt;br /&gt;
        Anon={(A,B)=A+B},&lt;br /&gt;
        K=Anon(4,8),&lt;br /&gt;
        %results in K=12.&lt;br /&gt;
    run():-&lt;br /&gt;
        Anon={&lt;br /&gt;
            (A,B)=C:-&lt;br /&gt;
            R=math::random(7),&lt;br /&gt;
            C=A+B+R,&lt;br /&gt;
            stdio::wRite(&amp;quot;RRRR=&amp;quot;,R)&lt;br /&gt;
            },&lt;br /&gt;
        K=Anon(4,8).&lt;br /&gt;
        %results in K=12 + a random number &amp;lt;7&lt;br /&gt;
&lt;br /&gt;
    run():-&lt;br /&gt;
        Anon={=f_abc(3)},&lt;br /&gt;
        K=Anon(),&lt;br /&gt;
        stdio::write(&amp;quot;\nI={=f_abc(3)} gives &amp;quot;,K),&lt;br /&gt;
        fail.&lt;br /&gt;
    run().&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Threads ===&lt;br /&gt;
&lt;br /&gt;
To start a thread:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
        _=thread::start(fred).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred:().&lt;br /&gt;
clauses&lt;br /&gt;
    fred():-.....&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
fred can have no arguments, so no argument brackets are allowed:&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
    _=thread::start(fred())&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is illegal. But the thread can access data prepared before it is started.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;facts&lt;br /&gt;
    zz_int:integer:=erroneous.&lt;br /&gt;
clauses&lt;br /&gt;
    pred():-&lt;br /&gt;
        zz_int:=88,&lt;br /&gt;
        _=thread::start(fred).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    fred:().&lt;br /&gt;
clauses&lt;br /&gt;
    fred():-&lt;br /&gt;
        K=zz_int,&lt;br /&gt;
        ...&amp;lt;/vip&amp;gt;&lt;/div&gt;</summary>
		<author><name>Steve Lympany</name></author>
	</entry>
</feed>