<?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=Magnus+Jacobsen</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=Magnus+Jacobsen"/>
	<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Special:Contributions/Magnus_Jacobsen"/>
	<updated>2026-04-11T16:57:40Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Compound_and_List_Domains&amp;diff=4846</id>
		<title>Compound and List Domains</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Compound_and_List_Domains&amp;diff=4846"/>
		<updated>2022-09-07T11:09:12Z</updated>

		<summary type="html">&lt;p&gt;Magnus Jacobsen: /* Using the Equal Sign to Unify Compound Domains */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In this tutorial we will introduce compound domains (sometimes called algebraic data structures). Compound domains are used to handle several pieces of data as a single entity. Lists is an example of compound domains. Lists are used so much that they have even received special syntactical sugaring.&lt;br /&gt;
&lt;br /&gt;
Compound and list domains are created using built-in domains and other compound and list domains. Visual Prolog help describes built-in domains: integral, real, string, symbol, char, string8, pointer, binary, boolean, object.&lt;br /&gt;
&lt;br /&gt;
==Compound Domains and Functors==&lt;br /&gt;
&lt;br /&gt;
Compound domains allow you to treat several pieces of information as a single item in such a way that you can easily pick them apart again. Consider, for instance, the date &amp;quot;October 15, 2003&amp;quot;. It consists of three pieces of information – the month, day, and year – but it is useful to treat the whole thing as a single data with a treelike structure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;        DATE&lt;br /&gt;
         /|\&lt;br /&gt;
        / | \&lt;br /&gt;
       /  |  \&lt;br /&gt;
      /   |   \&lt;br /&gt;
  October 15  2003&amp;lt;/pre&amp;gt;You can do this by declaring a domain containing the compound domain &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    date_cmp = date(string Month, unsigned Day, unsigned Year).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and then simply writing e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;D = date(&amp;quot;October&amp;quot;, 15, 2003),&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This looks like a Prolog fact, but it isn&amp;#039;t here – it is just a value, which you can handle in much the same way as a string or number. It begins with a name, usually called a functor(in this case date), followed by three arguments.&lt;br /&gt;
&lt;br /&gt;
Note carefully that a functor in Visual Prolog has nothing to do with a function in other programming languages. &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;A functor does not stand for some computation to be performed.&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; it is just a name that identifies a kind of compound value and holds its arguments together.&lt;br /&gt;
&lt;br /&gt;
The arguments of a compound value can themselves be compound. For instance, you might think of someone&amp;#039;s birthday as an information structure like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;            birthday&lt;br /&gt;
             /    \&lt;br /&gt;
            /      \&lt;br /&gt;
           /        \&lt;br /&gt;
          /          \&lt;br /&gt;
         /            \&lt;br /&gt;
   person             date&lt;br /&gt;
    /  \              / | \&lt;br /&gt;
   /    \            /  |  \&lt;br /&gt;
&amp;quot;Per&amp;quot; &amp;quot;Schultze&amp;quot;  &amp;quot;Apr&amp;quot; 14 1960&amp;lt;/pre&amp;gt;In Prolog you would write this as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;birthday(person(&amp;quot;Per&amp;quot;, &amp;quot;Schultze&amp;quot;), date(&amp;quot;Apr&amp;quot;,14,1960)).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, there are two sub-parts in the compound birthday value: the argument  person(&amp;quot;Per&amp;quot;, &amp;quot;Schultze&amp;quot;) and the argument date(&amp;quot;Apr&amp;quot;, 14, 1960). The functors of these values are  person and date.&lt;br /&gt;
&lt;br /&gt;
==Unification of Compound Domains==&lt;br /&gt;
&lt;br /&gt;
A compound value can unify either with a simple variable or with a compound value that matches it(perhaps containing variables as parts of its internal structure). This means you can use a compound value to pass the whole collection of items as a single value, and then use unification to pick them apart. For example, &amp;lt;vp&amp;gt;date(&amp;quot;April&amp;quot;, 14, 1960)&amp;lt;/vp&amp;gt; matches &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; and binds &amp;lt;vp&amp;gt;X&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;date(&amp;quot;April&amp;quot;,14,1960)&amp;lt;/vp&amp;gt;. Also &amp;lt;vp&amp;gt;date(&amp;quot;April&amp;quot;, 14, 1960)&amp;lt;/vp&amp;gt; matches &amp;lt;vp&amp;gt;date(Mo, Da, Yr)&amp;lt;/vp&amp;gt; and binds &amp;lt;vp&amp;gt;Mo&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;&amp;quot;April&amp;quot;&amp;lt;/vp&amp;gt;, &amp;lt;vp&amp;gt;Da&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;14&amp;lt;/vp&amp;gt;, and &amp;lt;vp&amp;gt;Yr&amp;lt;/vp&amp;gt; to &amp;lt;vp&amp;gt;1960&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Using the Equal Sign to Unify Compound Domains===&lt;br /&gt;
&lt;br /&gt;
Visual Prolog performs unification in two places. The first is when a call or goal matches the head of a clause. The second is across the &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;equal&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;(=) sign, which is actually an infix predicate(a predicate that is located &amp;#039;&amp;#039;between&amp;#039;&amp;#039; its arguments rather than &amp;#039;&amp;#039;before&amp;#039;&amp;#039; them).&lt;br /&gt;
&lt;br /&gt;
Visual Prolog will make the necessary bindings to unify the values on both sides of the &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;equal&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; sign. This is useful for finding the values of arguments within a compound value. For example, the following code excerpt tests if two people have the same last name, then gives the second person the same address as the first.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class my&lt;br /&gt;
    domains&lt;br /&gt;
        person = person(name, address).&lt;br /&gt;
        name = name(string First, string Last).&lt;br /&gt;
        address = addr(street, string City, string State).&lt;br /&gt;
        street = street(integer Number, string Street_name).&lt;br /&gt;
&lt;br /&gt;
    predicates&lt;br /&gt;
        run :().&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement my&lt;br /&gt;
    clauses&lt;br /&gt;
        run():-&lt;br /&gt;
            console::init(),&lt;br /&gt;
            P1 =  person(name(&amp;quot;Jim&amp;quot;, &amp;quot;Smith&amp;quot;),&lt;br /&gt;
                addr(street(5, &amp;quot;1st st&amp;quot;), &amp;quot;igo&amp;quot;, &amp;quot;CA&amp;quot;)),&lt;br /&gt;
            P1 = person(name(_, &amp;quot;Smith&amp;quot;), Address),&lt;br /&gt;
            P2 = person(name(&amp;quot;Jane&amp;quot;, &amp;quot;Smith&amp;quot;), Address),&lt;br /&gt;
            !,&lt;br /&gt;
            stdio::write(&amp;quot;P1 = &amp;quot;, P1, &amp;quot;\n&amp;quot;),&lt;br /&gt;
            stdio::write(&amp;quot;P2 = &amp;quot;, P2, &amp;quot;\n&amp;quot;)&lt;br /&gt;
            or&lt;br /&gt;
            stdio::write(&amp;quot;No solution&amp;quot;).&lt;br /&gt;
end implement&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    my::run.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Treating Several Items as One==&lt;br /&gt;
&lt;br /&gt;
Compound values can be regarded and treated as single values in your Prolog clauses, which greatly simplifies programming. Consider, for example, the fact&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;owns(&amp;quot;John&amp;quot;, book(&amp;quot;From Here to Eternity&amp;quot;, &amp;quot;James Jones&amp;quot;)).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in which you state that John owns the book &amp;quot;From Here to Eternity&amp;quot;, written by &amp;quot;James Jones&amp;quot;. Likewise, you could write&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;owns(&amp;quot;John&amp;quot;, horse(&amp;quot;Blacky&amp;quot;)).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which can be interpreted as&lt;br /&gt;
&lt;br /&gt;
John owns a horse named Blacky.&lt;br /&gt;
&lt;br /&gt;
The compound values in these two examples are&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;book(&amp;quot;From Here to Eternity&amp;quot;, &amp;quot;James Jones&amp;quot;)).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;horse(&amp;quot;Blacky&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you had instead written two facts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;owns(&amp;quot;John&amp;quot;, &amp;quot;From Here to Eternity&amp;quot;).&lt;br /&gt;
owns(&amp;quot;John&amp;quot;, &amp;quot;Blacky&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you would not have been able to decide whether Blacky was the title of a book or the name of a horse. On the other hand, you can use the first component of a compound value – the functor – to distinguish between different kinds of values. This example used the functors book and horse to indicate the difference between the values.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Remember&amp;#039;&amp;#039;&amp;#039;: Compound values consist of a functor and the arguments belonging to that functor, as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;functor(argument1, argument2, ..., argumentN)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===An Example Using Compound Domains===&lt;br /&gt;
&lt;br /&gt;
An important feature of compound domains allows you to easily pass a group of values as one argument. Consider a case where you are keeping a telephone database. In your database, you want to include your friends&amp;#039; and family members&amp;#039; birthdays. Here is a section of code you might have come up with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;predicates&lt;br /&gt;
    phone_list :(string First, string Last, string Phone, string Month, intege Day, integer Year) determ.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    phone_list(&amp;quot;Ed&amp;quot;, &amp;quot;Willis&amp;quot;, &amp;quot;422-0208&amp;quot;, &amp;quot;aug&amp;quot;, 3, 1955).&lt;br /&gt;
    phone_list(&amp;quot;Chris&amp;quot;, &amp;quot;Grahm&amp;quot;, &amp;quot;433-9906&amp;quot;, &amp;quot;may&amp;quot;, 12, 1962).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examine the data, noticing the six arguments in the fact phone_list; five of these arguments can be broken down into two compound domains, like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;       person                birthday&lt;br /&gt;
        /   \                /  |  \&lt;br /&gt;
       /     \              /   |   \&lt;br /&gt;
First Name  Last Name    Month Day Year&amp;lt;/pre&amp;gt;It might be more useful to represent your facts so that they reflect these compound domains. Going back a step, you can see that person is a relationship, and the first and last names are the arguments. Also, birthday is a relationship with three arguments: month, day, and year. The Prolog representation of these relationships is&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;owns(&amp;quot;John&amp;quot;, &amp;quot;From Here to Eternity&amp;quot;).&lt;br /&gt;
owns(&amp;quot;John&amp;quot;, &amp;quot;Blacky&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can now rewrite your small database to include these compound domains as part of your database.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    name = person(string First, string Last).&lt;br /&gt;
    birthday = b_date(string Month, integer Day, integer Year).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    phone_list : (name Name, string Ph_num, birthday Birthday) determ.&lt;br /&gt;
clauses&lt;br /&gt;
    phone_list(person(&amp;quot;Ed&amp;quot;, &amp;quot;Willis&amp;quot;), &amp;quot;422-0208&amp;quot;, b_date(&amp;quot;aug&amp;quot;, 3, 1955)).&lt;br /&gt;
    phone_list(person(&amp;quot;Chris&amp;quot;, &amp;quot;Grahm&amp;quot;), &amp;quot;433-9906&amp;quot;, b_date(&amp;quot;may&amp;quot;, 12, 1962)).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this program, two compound &amp;#039;&amp;#039;&amp;#039;domains&amp;#039;&amp;#039;&amp;#039; declarations were introduced. We go into more detail about these compound data structures later in this chapter. For now, we will concentrate on the benefits of using such compound domains.&lt;br /&gt;
&lt;br /&gt;
The phone_list predicate now contains three arguments, as opposed to the previous six. Sometimes breaking up your data into compound values will clarify your program and might help process the data.&lt;br /&gt;
&lt;br /&gt;
Now add some rules to program. Suppose you want to create a list of people whose birthdays are in the current month. Here is the program code to accomplish this task; this program uses the standard predicate date to get the current date from the computer&amp;#039;s internal clock. Predicate date will return the current year, month, and day from your computer&amp;#039;s clock.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class my&lt;br /&gt;
    domains&lt;br /&gt;
        name = person(string First, string Last).&lt;br /&gt;
        birthday = b_date(string Month, integer Day, integer Year).&lt;br /&gt;
    predicates&lt;br /&gt;
        phone_list : (name Name [out], string Ph_num [out], birthday Birthday [out]) multi.&lt;br /&gt;
        get_months_birthdays : ().&lt;br /&gt;
        convert_month : (string Name, integer Num [out]) determ.&lt;br /&gt;
        check_birthday_month : (integer Month_num, birthday Birthday) determ.&lt;br /&gt;
        write_person : (name Name).&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement my&lt;br /&gt;
    clauses&lt;br /&gt;
        get_months_birthdays() :-&lt;br /&gt;
            stdio::write(&amp;quot;****** This Month&amp;#039;s Birthday List *****\n&amp;quot;),&lt;br /&gt;
            stdio::write(&amp;quot; First Name\t\t Last Name\n&amp;quot;),&lt;br /&gt;
            stdio::write(&amp;quot;***********************************\n&amp;quot;),&lt;br /&gt;
            Now = time::now(),&lt;br /&gt;
            Now:getDate(_, ThisMonth, _),&lt;br /&gt;
            phone_list(Person, _, Date),&lt;br /&gt;
            check_birthday_month(ThisMonth, Date),&lt;br /&gt;
            write_person(Person),&lt;br /&gt;
            fail.&lt;br /&gt;
        get_months_birthdays() :-&lt;br /&gt;
            stdio::write(&amp;quot;\n Press any key to continue:\n&amp;quot;),&lt;br /&gt;
            _ = console::readChar().&lt;br /&gt;
&lt;br /&gt;
    clauses&lt;br /&gt;
        write_person(person(FirstName, LastName)) :-&lt;br /&gt;
            stdio::write(&amp;quot;  &amp;quot;, FirstName, &amp;quot;\t\t &amp;quot;,  LastName, &amp;quot;\n&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
    clauses&lt;br /&gt;
        check_birthday_month(Mon, b_date(Month, _, _)) :-&lt;br /&gt;
            convert_month(Month, Month1),&lt;br /&gt;
            Mon = Month1.&lt;br /&gt;
&lt;br /&gt;
    clauses&lt;br /&gt;
        phone_list(person(&amp;quot;Ed&amp;quot;, &amp;quot;Willis&amp;quot;), &amp;quot;11-1111&amp;quot;, b_date(&amp;quot;Jan&amp;quot;, 3, 1955)).&lt;br /&gt;
        phone_list(person(&amp;quot;Benjamin&amp;quot;, &amp;quot;Thomas&amp;quot;), &amp;quot;222-2222&amp;quot;, b_date(&amp;quot;Feb&amp;quot;, 5, 1965)).&lt;br /&gt;
        phone_list(person(&amp;quot;Ray&amp;quot;, &amp;quot;William&amp;quot;), &amp;quot;333-3333&amp;quot;, b_date(&amp;quot;Mar&amp;quot;, 3, 1955)).&lt;br /&gt;
        phone_list(person(&amp;quot;Tomas&amp;quot;, &amp;quot;Alfred&amp;quot;), &amp;quot;444-4444&amp;quot;, b_date(&amp;quot;Apr&amp;quot;, 29, 1975)).&lt;br /&gt;
        phone_list(person(&amp;quot;Chris&amp;quot;, &amp;quot;Gralm&amp;quot;), &amp;quot;555-5555&amp;quot;, b_date(&amp;quot;May&amp;quot;, 12, 1975)).&lt;br /&gt;
        phone_list(person(&amp;quot;Dastin&amp;quot;, &amp;quot;Robert&amp;quot;), &amp;quot;666-6666&amp;quot;, b_date(&amp;quot;Jun&amp;quot;, 17, 1975)).&lt;br /&gt;
        phone_list(person(&amp;quot;Anna&amp;quot;, &amp;quot;Friend&amp;quot;), &amp;quot;777-7777&amp;quot;, b_date(&amp;quot;Jul&amp;quot;, 2, 1975)).&lt;br /&gt;
        phone_list(person(&amp;quot;Naomi&amp;quot;, &amp;quot;Friend&amp;quot;), &amp;quot;888-8888&amp;quot;, b_date(&amp;quot;Aug&amp;quot;, 10, 1975)).&lt;br /&gt;
        phone_list(person(&amp;quot;Christina&amp;quot;, &amp;quot;Lynn&amp;quot;), &amp;quot;999-9999&amp;quot;, b_date(&amp;quot;Sep&amp;quot;, 25, 1975)).&lt;br /&gt;
        phone_list(person(&amp;quot;Kathy&amp;quot;, &amp;quot;Ann&amp;quot;), &amp;quot;110-1010&amp;quot;, b_date(&amp;quot;Oct&amp;quot;, 20, 1975)).&lt;br /&gt;
        phone_list(person(&amp;quot;Elizabeth&amp;quot;, &amp;quot;Ann&amp;quot;), &amp;quot;110-1111&amp;quot;, b_date(&amp;quot;Nov&amp;quot;, 9, 1975)).&lt;br /&gt;
        phone_list(person(&amp;quot;Aaron&amp;quot;, &amp;quot;Friend&amp;quot;), &amp;quot;110-1212&amp;quot;, b_date(&amp;quot;Dec&amp;quot;, 31, 1975)).&lt;br /&gt;
        phone_list(person(&amp;quot;Jenifer&amp;quot;, &amp;quot;Faitlin&amp;quot;), &amp;quot;888-8888&amp;quot;, b_date(&amp;quot;Aug&amp;quot;, 14, 1975)).&lt;br /&gt;
&lt;br /&gt;
    clauses&lt;br /&gt;
        convert_month(&amp;quot;Jan&amp;quot;, 1).&lt;br /&gt;
        convert_month(&amp;quot;Feb&amp;quot;, 2).&lt;br /&gt;
        convert_month(&amp;quot;Mar&amp;quot;, 3).&lt;br /&gt;
        convert_month(&amp;quot;Apr&amp;quot;, 4).&lt;br /&gt;
        convert_month(&amp;quot;May&amp;quot;, 5).&lt;br /&gt;
        convert_month(&amp;quot;Jun&amp;quot;, 6).&lt;br /&gt;
        convert_month(&amp;quot;Jul&amp;quot;, 7).&lt;br /&gt;
        convert_month(&amp;quot;Aug&amp;quot;, 8).&lt;br /&gt;
        convert_month(&amp;quot;Sep&amp;quot;, 9).&lt;br /&gt;
        convert_month(&amp;quot;Oct&amp;quot;, 10).&lt;br /&gt;
        convert_month(&amp;quot;Nov&amp;quot;, 11).&lt;br /&gt;
        convert_month(&amp;quot;Dec&amp;quot;, 12).&lt;br /&gt;
end implement&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    my::get_months_birthdays().&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
How do compound domains help in this program? This should be easy to see when you examine the code. Most of the processing goes on in the get_months_birthdays predicate.&lt;br /&gt;
&lt;br /&gt;
*First, the program makes a window to display the results.&lt;br /&gt;
&lt;br /&gt;
*After this, it writes a header in the window to help interpret the results.&lt;br /&gt;
&lt;br /&gt;
*Next, in get_months_birthdays, the program uses the built-in predicate date to obtain the current month.&lt;br /&gt;
&lt;br /&gt;
*After this, the program is all set to search the database and list the people who were born in the current month. The first thing to do is find the first person in the database. The call phone_list(Person, _, Date) binds the person&amp;#039;s first and last names to the variable Person by binding the entire functor person to Person. It also binds the person&amp;#039;s birthday to the variable Date.&amp;lt;br /&amp;gt;&lt;br /&gt;
Notice that you only need to use one variable to store a person&amp;#039;s complete name, and one variable to hold the birthday. This is the power of using compound domains.&lt;br /&gt;
&lt;br /&gt;
*Your program can now pass around a person&amp;#039;s birthday simply by passing on the variable Date. This happens in the next subgoal, where the program passes the current month(represented by an integer) and the birthday(of the person it is processing) to the predicate check_birthday_month.&lt;br /&gt;
&lt;br /&gt;
*Look closely at what happens. Visual Prolog calls the predicate check_birthday_month with two variables: The first variable is bound to an integer, and the second is bound to a birthday term. In the head of the rule that defines check_birthday_month, the first argument, This_month, is matched with the variable Mon. The second argument, Date, is matched against b_date(Month, _,_).&amp;lt;br /&amp;gt;&lt;br /&gt;
Since all you are concerned with is the month of a person&amp;#039;s birthday, you have used the anonymous variable for both the day and the year of birth.&lt;br /&gt;
&lt;br /&gt;
*The predicate check_birthday_month first converts the string for the month into an integer value. Once this is done, Visual Prolog can compare the value of the current month with the value of the person&amp;#039;s birthday month. If this comparison succeeds, then the subgoal check_birthday_month succeeds, and processing can continue. If the comparison fails(the person currently being processed was not born in the current month), Visual Prolog begins to backtrack to look for another solution to the problem.&lt;br /&gt;
&lt;br /&gt;
*The next subgoal to process is write_person. The person currently being processed has a birthday this month, so it is OK to print that person&amp;#039;s name in the report. After printing the information, the clause fails, which forces backtracking.&lt;br /&gt;
&lt;br /&gt;
*&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Backtracking always goes up to the most recent non-deterministic call and tries to re-satisfy that call.&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; In this program, the last non-deterministic call processed is the call to phone_list. It is here that the program looks up another person to be processed. If there are no more people in the database to process, the current clause fails; Visual Prolog then attempts to satisfy this call by looking further down in the database. Since there is another clause that defines get_months_birthdays, Visual Prolog tries to satisfy the call to get_months_birthdays by satisfying the subgoals to this other clause.&lt;br /&gt;
&lt;br /&gt;
==Declaring Compound Domains==&lt;br /&gt;
&lt;br /&gt;
In this section, we show you how instances of compound domains are defined. After compiling a program that contains the following relationships:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;owns(&amp;quot;John&amp;quot;, book(&amp;quot;From Here to Eternity&amp;quot;, &amp;quot;James Jones&amp;quot;)).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;owns(&amp;quot;John&amp;quot;, horse(&amp;quot;Blacky&amp;quot;)).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you could query the system with this goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;owns(&amp;quot;John&amp;quot;, X))&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The variable X can be bound to a different type: a book, a horse, or perhaps other types you define. Because of your definition of the owns predicate, you can no longer employ the old predicate declaration of owns:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;owns :(string, string).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second argument no longer refers to the string domain. Instead, you must formulate a new declaration to the predicate, such as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;owns :(name, articles).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can describe the articles domain in the domains section as shown here:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    articles = book(string Title, string Author);&lt;br /&gt;
            horse(string Name).&lt;br /&gt;
        /* Articles are books or horses */&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The semicolon is read as &amp;#039;&amp;#039;or&amp;#039;&amp;#039;. In this case, two alternatives are possible: A book can be identified by its title and author, or a horse can be identified by its name. The domains title, author, and name are all of the standard domain string.&lt;br /&gt;
&lt;br /&gt;
More alternatives can easily be added to the domains declaration. For example, articles could also include a boat, a house, or a bankbook. For a boat, you can make do with a functor that has no arguments attached to it. On the other hand, you might want to give a bank balance as a figure within the bankbook. The domains declaration of  articles is therefore extended to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    articles = book(string Title, string Author);&lt;br /&gt;
            horse(string Name); boat; bankbook(real Balance).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is a full program that shows how compound domains from the domain articles can be used in facts that define the predicate owns.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class my&lt;br /&gt;
    domains&lt;br /&gt;
        articles =&lt;br /&gt;
            book(string Title, string Author) ;&lt;br /&gt;
            horse(string Name) ; boat ; bankbook(real Balance).&lt;br /&gt;
    predicates&lt;br /&gt;
        owns :(string Name, articles) nondeterm(i,o) determ(i,i).&lt;br /&gt;
end class&lt;br /&gt;
&lt;br /&gt;
implement my&lt;br /&gt;
    clauses&lt;br /&gt;
        owns(&amp;quot;John&amp;quot;, book(&amp;quot;A friend of the family&amp;quot;, &amp;quot;Irwin Shaw&amp;quot;)).&lt;br /&gt;
        owns(&amp;quot;John&amp;quot;, horse(&amp;quot;Blacky&amp;quot;)).&lt;br /&gt;
        owns(&amp;quot;John&amp;quot;, boat).&lt;br /&gt;
        owns(&amp;quot;John&amp;quot;, bankbook(1000)).&lt;br /&gt;
end implement&lt;br /&gt;
&lt;br /&gt;
goal&lt;br /&gt;
    console::init(),&lt;br /&gt;
    my::owns(&amp;quot;John&amp;quot;, Thing),&lt;br /&gt;
    stdio::write(&amp;quot;Thing: &amp;quot;, Thing, &amp;quot;\n&amp;quot;),&lt;br /&gt;
    fail&lt;br /&gt;
    ;&lt;br /&gt;
    stdio::write(&amp;quot;The end.&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now load the program into Visual Development Environment and run it in window. Visual Prolog responds with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;Thing: book(&amp;quot;A friend of the family&amp;quot;,&amp;quot;Irwin Shaw&amp;quot;)&lt;br /&gt;
Thing: horse(&amp;quot;Blacky&amp;quot;)&lt;br /&gt;
Thing: boat()&lt;br /&gt;
Thing: bankbook(1000)&lt;br /&gt;
The end.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Writing Domain Declarations: a Summary===&lt;br /&gt;
&lt;br /&gt;
This is a generic representation of how to write compound domain declarations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domain = alternative1(D, D, ...);&lt;br /&gt;
               alternative2(D, D, ...);&lt;br /&gt;
...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, alternative1 and  alternative2 are arbitrary(but different) functors. The notation(D, D, ...) represents a list of domain names that are either declared elsewhere or are one of the standard domain types(such as string, integer, real, etc).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
*The alternatives are separated by semicolons.&lt;br /&gt;
&lt;br /&gt;
*Every alternative consists of a functor and, possibly, a list of domains for the corresponding arguments.&lt;br /&gt;
&lt;br /&gt;
*If the functor has no arguments, you can write it as alternativeN or alternativeN( ) in your programs.&lt;br /&gt;
&lt;br /&gt;
===Multi-Level Compound Domains===&lt;br /&gt;
&lt;br /&gt;
Visual Prolog allows you to construct compound domains on several levels. For example, in&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;book(&amp;quot;The Ugly Duckling&amp;quot;, &amp;quot;Andersen&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
instead of using the author&amp;#039;s last name, you could use a new structure that describes the author in more detail, including both the author&amp;#039;s first and last names. By calling the functor for the resulting new compound domain author, you can change the description of the book to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;book(&amp;quot;The Ugly Duckling&amp;quot;, author(&amp;quot;Hans Christian&amp;quot;, &amp;quot;Andersen&amp;quot;)).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the old domain declaration&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;book(string Title, string Author).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the second argument of the book functor is Author that can only include a single name, so it is no longer sufficient. You must now specify that an author is also a compound domain made up of the author&amp;#039;s first and last name. You do this with the domain definition:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;author = author(string First_name, string Last_name).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which leads to the following declarations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    articles = book(string Title, author Author); ...&lt;br /&gt;
        /* First level */&lt;br /&gt;
    author = author(string First_name, string Last_name).&lt;br /&gt;
        /* Second level */&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When using compound domains on different levels in this way, it is often helpful to draw a &amp;quot;tree&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;       book&lt;br /&gt;
       /  \&lt;br /&gt;
      /    \&lt;br /&gt;
  title   author&lt;br /&gt;
           /   \&lt;br /&gt;
          /     \&lt;br /&gt;
   First_name  Last_name&amp;lt;/pre&amp;gt;A domain declaration describes only one level of the tree at a time, and not the whole tree. For instance, a book can&amp;#039;t be defined with the following domain declaration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;/* Not allowed */&lt;br /&gt;
book = book(string Title, author(string First_name, string Last_name)).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Compound Mixed-Domain Declarations==&lt;br /&gt;
&lt;br /&gt;
In this section, we discuss three different types of domain declarations you can add to your programs. These declarations allow you to use predicates that&lt;br /&gt;
&lt;br /&gt;
*take an argument, more than one type of more than one possible type&lt;br /&gt;
&lt;br /&gt;
*take a variable number of arguments, each of a specified type&lt;br /&gt;
&lt;br /&gt;
*take a variable number of arguments, some of which might be of more than one possible type&lt;br /&gt;
&lt;br /&gt;
===Multiple-Type Arguments===&lt;br /&gt;
&lt;br /&gt;
To allow a Visual Prolog predicate to accept an argument that gives information of different types, you must add a functor declaration. In the following example, the your_age clause will accept an argument of type age, which can be a string, a real, or an integer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    age = i(integer); r(real); s(string).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    your_age :(age).&lt;br /&gt;
clauses&lt;br /&gt;
    your_age(i(Age)) :- stdio::write(Age).&lt;br /&gt;
    your_age(r(Age)) :- stdio::write(Age).&lt;br /&gt;
    your_age(s(Age)) :- stdio::write(Age).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Visual Prolog does not allow the following domain declaration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;/* Not permitted. */&lt;br /&gt;
domains&lt;br /&gt;
    age = integer; real; string.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Lists===&lt;br /&gt;
&lt;br /&gt;
Suppose you are keeping track of the different classes a professor might teach. You might produce the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;class predicates&lt;br /&gt;
    teacher :(string First_name, string Last_name, string Class) determ.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    teacher(&amp;quot;Ed&amp;quot;, &amp;quot;Willis&amp;quot;, &amp;quot;english1&amp;quot;).&lt;br /&gt;
    teacher(&amp;quot;Ed&amp;quot;, &amp;quot;Willis&amp;quot;, &amp;quot;math1&amp;quot;).&lt;br /&gt;
    teacher(&amp;quot;Ed&amp;quot;, &amp;quot;Willis&amp;quot;, &amp;quot;history1&amp;quot;).&lt;br /&gt;
    teacher(&amp;quot;Mary&amp;quot;, &amp;quot;Maker&amp;quot;, &amp;quot;history2&amp;quot;).&lt;br /&gt;
    teacher(&amp;quot;Mary&amp;quot;, &amp;quot;Maker&amp;quot;, &amp;quot;math2&amp;quot;).&lt;br /&gt;
    teacher(&amp;quot;Chris&amp;quot;, &amp;quot;Grahm&amp;quot;, &amp;quot;geometry&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, you need to repeat the teacher&amp;#039;s name for each class he or she teaches. For each class, you need to add another fact to the database. Although this is perfectly OK in this situation, you might find a school where there are hundreds of classes; this type of data structure would get a little tedious. Here, it would be helpful if you could create an argument to a predicate that could take on one &amp;#039;&amp;#039;or more&amp;#039;&amp;#039; values.&lt;br /&gt;
&lt;br /&gt;
A list in Prolog does just that. In the following code, the argument class is declared to be of a list type. We show here how a list is represented in Prolog.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    classes = string*.   /* declare a list domain */&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    teacher :(string First_name,  string Last_name,  classes Classes) determ.&lt;br /&gt;
clauses&lt;br /&gt;
    teacher(&amp;quot;Ed&amp;quot;, &amp;quot;Willis&amp;quot;, [&amp;quot;english1&amp;quot;, &amp;quot;math1&amp;quot;, &amp;quot;history1&amp;quot;]).&lt;br /&gt;
    teacher(&amp;quot;Mary&amp;quot;, &amp;quot;Maker&amp;quot;, [&amp;quot;history2&amp;quot;, &amp;quot;math2&amp;quot;]).&lt;br /&gt;
    teacher(&amp;quot;Chris&amp;quot;, &amp;quot;Grahm&amp;quot;, [&amp;quot;geometry&amp;quot;]).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, the code is more concise and easier to read than in the preceding one. Notice the domains declaration. The asterisk(*) means that classes is a list of strings. You can just as easily declare a list of integers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    integer_list = integer*.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you declare a domain, it is easy to use it; just place it as an argument to a predicate declared in the predicates section. Here is an example of using an integer list:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    integer_list = integer*.&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    test_scores :&lt;br /&gt;
        (string First_name,&lt;br /&gt;
          string Last_name,&lt;br /&gt;
          integer_list Test_Scores)&lt;br /&gt;
          determ.&lt;br /&gt;
clauses&lt;br /&gt;
    test_scores(&amp;quot;Lisa&amp;quot;, &amp;quot;Lavender&amp;quot;, [86, 91, 75]).&lt;br /&gt;
    test_scores(&amp;quot;Libby&amp;quot;, &amp;quot;Dazzner&amp;quot;, [79, 75]).&lt;br /&gt;
    test_scores(&amp;quot;Jeff&amp;quot;, &amp;quot;Zheutlin&amp;quot;, []).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the case of &amp;#039;&amp;#039;Jeff Zheutlin&amp;#039;&amp;#039;, notice that a list doesn&amp;#039;t need to contain any elements at all.&lt;br /&gt;
&lt;br /&gt;
One more example shows how one can use lists to describe the family-tree.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;domains&lt;br /&gt;
    tree_list = tree*.&lt;br /&gt;
    tree = tree(string Text, tree_list TreeList).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    family :(tree) determ.&lt;br /&gt;
clauses&lt;br /&gt;
    family(tree(&amp;quot;Grandmother&amp;quot;,&lt;br /&gt;
            [tree(&amp;quot;John&amp;quot;,&lt;br /&gt;
                [tree(&amp;quot;Eric&amp;quot;, []),&lt;br /&gt;
                 tree(&amp;quot;Mark&amp;quot;, []),&lt;br /&gt;
                 tree(&amp;quot;Leonard&amp;quot;, []) ] ),&lt;br /&gt;
             tree(&amp;quot;Ellen&amp;quot;, [])&lt;br /&gt;
            ]&lt;br /&gt;
        )).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
&lt;br /&gt;
These are the important points covered in this tutorial:&lt;br /&gt;
&lt;br /&gt;
*A Visual Prolog program can contain many types of values: simple and compound, standard and user-defined.&lt;br /&gt;
&lt;br /&gt;
*Simple values are numbers, strings, etc.&lt;br /&gt;
&lt;br /&gt;
*&amp;#039;&amp;#039;Compound domains&amp;#039;&amp;#039; allow you to treat several pieces of information as a single item. A compound domain consists of a name(known as a functor) and one or more arguments. You can define a domain with several alternative functors.&lt;br /&gt;
&lt;br /&gt;
*A functor in Visual Prolog is not the same thing as a function in other programming languages. &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;A functor does not stand for some computation to be performed.&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; It is just a name that identifies a kind of a compound domain and holds its arguments together.&lt;br /&gt;
&lt;br /&gt;
*Compound values can be regarded and treated as single values; you use the functor to distinguish between different kinds of compound values. Visual Prolog allows you to construct compound values on several levels; the arguments of a compound value can also be compound values. With compound mixed domain declarations, you can use predicates that:&lt;br /&gt;
&lt;br /&gt;
*take an argument of more than one possible type(functor declaration).&lt;br /&gt;
&lt;br /&gt;
*take a variable number of arguments, each of a specified type(list declaration).&lt;br /&gt;
&lt;br /&gt;
*take a variable number of arguments, some of which might be of more than one possible type.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[ru:Cоставные Домены и Списки]]&lt;br /&gt;
[[Category:Data types and handling]]&lt;/div&gt;</summary>
		<author><name>Magnus Jacobsen</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Lists_and_Recursion&amp;diff=4845</id>
		<title>Lists and Recursion</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Lists_and_Recursion&amp;diff=4845"/>
		<updated>2022-09-05T13:42:34Z</updated>

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