Data Types
This document assumes that you have already been exposed to prolog before.
Otherwise, it may not have much sense to you.
Integer Numbers
- Decimal signed numbers, i.e.: -127 0 127 16485 and so on.
- Hexadecimal signed numbers begin with 0x or 0X, i.e.: 0xff 0Xca -0xF7 0XF8 and so on. You can use upper case or lower case.
Real Numbers
- Decimal signed numbers with fractional part, i.e.: -127.0 3.1415 and so on.
- Hexadecimal signed numbers with fractional part begin with 0x or 0X, i.e.: 0x1.0 0x1.8 and so on. You can use upper case or lower case.
Texts (or Strings)
- Texts begin with doubl quotation (") and end with doubl quotation ("), i.e.: "Hello World".
- If you need to use double quotation inside the text, prefis it with backslash (\), i.e. "Quoting \"something\" withing the text.".
- New line is denoted as "\n".
-
- Backslash itself is denoted as double backslash (\\).
Symbols (sometimes referred as "atoms")
- Symbols appear only in few other computer languages, such as Lisp or Ruby.
-
- Symbols are composed of characters, numbers and some of the special characters. For example: command write show list exit addcl0
are all symbols.
- Symbols have to begin with either character (lower or upper case) or underscore.
- Symbols are used for naming commands. For example, all mathematical operations (add sub sin cos etc.) are attached to symbols.
- Symbols can also be used as enumerated values. For example, you can use symbols to give names to months, such as: January February March and so on.
- Symbols are groupped together into directories or folders. These directories function as modules.
- Symbols are not arranged into any specific order.
Abstract Variables
- Abstract Variables do not appear main stream computer languages.
- Abstract Variables all begin with start (*), i.e.: *x *y *x1 *x2 *something *out *number and so on.
- Single star denotes anonymous abstract variable. Hence * * are 3 different variables, while *x *x are 3 identical variables.
- Initially an abstract variable has no value at all. Once abstract variable becomes a value, it can not be changed any more.
- However, if program backtracks (reverses its execution), abstract variables can loose their bindings.
Pairs
- Pairs simply combine two values in an agregated value. For example: [1 : 2] is a pair.
- Pairs are denoted using square brackets. Colon separates the two member values of the pair.
- Pairs can contain any other data. They can even contain pairs inside, i.e.: [ [ 1 : 2 ] : [ 3 : 4 ] ].
Empty Pair (or empty list)
- Empty pair is denoted using two square brackets only, i.e.: [].
- Empty pair is sometimes referred to as "empty list". Whatever the name, it is one and the same thing.
Lists (or nested pairs)
- Lists are used to group values together. For example: [1 2 3] is a list containing 3 elements.
- They are very good for implementing records. For example: [capitol "France" "Paris"] contains one symbol and two text values.
- In fact, lists are nothing more than nested pairs. In fact, [1 2 3] is exactly the same thing as [1 : [2 : [3 : []]]].
- The difference is made by the colon character. If it is not there, then it means that there is an "invisible" extra nested pair.
- This convention allows for an easy access to lists of unknown length and for making commands with unknown number of parameters.
Commands
- A command or an instruction (sometimes called "predicate" as well) is one and the same thing. It is denoted using lists.
For example: [show "Hello World"] is an instruction.
- [show "Hello World"] is also a list. It means that it in fact a nested pair: [show : ["Hello World" : []]].
- Commands are the basic building blocks of programs. You can use them to write sequences of instructions.
- Commands either work OK or fail.
- If command succeedes then the next command is called and execution continues.
- If command fails then program backtracks, i.e. goes backward, trying to find alternative solutions to previously called commands.
- If you wish to get some results from calling a command, then you should pass some abstract variables.
For example, you may wish to calculate the sum of 1 and 2 and get the result.
The appropriate command is: [sum 1 2 *result].
- Please note, that if you wish to know what to add to 1 to get 3 in result, you will place your abstract variable in different position.
[sum 1 *what 3] will substitute *what with 2, which will indicate that 1 + 2 equal 3.
- Just like in any other computer language, you can use structured commands (i.e. loops, conditions, switchest, etc.).
The difference between prolog and other languages is that there is not much difference between simple and structured commands.
Structured commands in prolog just take simple commands as parameters.
- The simplest structured command in this dialect is res. It takes any number of parameters and every parameter must be a list denoting command.
Those commands can be simple or structured themselves. They can also be unknown hoping that they become known during execution time.
- For example, to calculate the sum of 1 and 2 and showing the result on the computer screen, you will have to write: [res [sum 1 2 *result] [show *result]].
Please note, how the commands are nested and passed as parameters.
Clauses
- Clauses are prolog quivalent of procedures from other computer languages.
- Each clause is denoted as a list of commands. Its first element is clause header with formal parameters. The rest is the body, which in majority of cases contains commands.
- An easy example would be an implementation of playcommand. It will take one parameter, a midi key number, and will play it for one second with velocity = 100.
Here is the definition:
[[play *note]
[keyon 0 *note 100]
[wait 1000]
[keyoff 0 *note]
]
- Another example will implement a triplication command. [[triple *in *out] [times *in 3.0 *out]]. This clause consists of header and one command.
Interestingly, you can also use it for calculating the result of division by 3.0.