Strawberry Prolog Help
version 6.1

How To ...

Install and Uninstall Strawberry Prolog
Obtain next versions
Move from old versions to this one
Recognize your Strawberry Prolog guide :-)

Language

Built-In predicates
Built-In predicates (Alphabetical list)
Errors and Warnings
Objects and Special Types
Strawberry Prolog Tutorial
Special files
Example programs
What is specific in Strawberry Prolog syntax?

Advanced Language Structures

Define functions and Built-in predicates
Define and use arrays
Use Global variables
Make Prolog CGI Scripts
Develop AI
Use OLE Automation - COM and ActiveX
Call Strawberry Prolog as OLE server
Work with databases through ODBC

Menus

File menu
Edit menu
Run menu
Trace menu
Options menu
Tools menu
Window menu
Help menu
Shortcuts

More ...

About the author


Install and Uninstall

Installing Strawberry Prolog

Download the file Strawberry Prolog .exe and execute it on your computer. This will install Strawberry Prolog, will enter registrations in the windows registry and will create a shortcut to Prolog.exe. After the installation you can delete the downloaded file or you can keep it for future installations.

Uninstalling Strawberry Prolog

Simply select Control Panel, Add/Remove Programs, select Strawberry Prolog and press Add/Remove.


Versions

Obtaining the Next Versions

Professional and Middle edition

What will be the next versions?

When the next versions will be ready?

Where to find?

Buying of subscription

What are the advantages of buying of subscription?


Move from old versions to this one

This is a help tool which is provided for people who have programs which work with an old version of Strawberry Prolog but do not work with this one due to some small changes which we made in the built-in predicates.

All such changes are described here. In order to correct your program start from the last version with which your program is working and make all changes to the current version.

From version 6.0 to version 6.1

In get and put replace the last argument with something like int32 or float64.

From version 2.92 to version 3.0

Some replacements:
Replace <>= with has_to.
Replace close_window with close.

Some changes:
Change window(Handle, Parent, Win_func(_), Title, X, Y, Width, Height)
with window( handle(Handle), parent(Parent), class(Win_func), title(Title), pos(X,Y), size(Width,Height)).

Change edit(Handle, Parent, Edit_func(_), Text, X, Y, Width, Height)
with edit( handle(Handle), parent(Parent), class(Edit_func), text(Text), pos(X,Y), size(Width,Height)).

Change button(Handle, Parent, Button_func(_), Text, X, Y, Width, Height)
with button( handle(Handle), parent(Parent), class(Button_func), text(Text), pos(X,Y), size(Width,Height)).

Change static(Handle, Parent, Static_func(_), Text, X, Y, Width, Height)
with static( handle(Handle), parent(Parent), class(Static_func), text(Text), pos(X,Y), size(Width,Height)).

Change for(I, A, B, Step) with for(I, A, B, step(Step)).
Change text_out(X, Y, Text) with text_out(Text, pos(X, Y)).
Change brush( Color, Type) with brush( Color, shape(Type)).
Change window_brush(Window, Color, Type) with window_brush(Window, Color, shape(Type)).
Change chronometer(T) with T is 1000*chronometer() (now "chronometer" returns seconds instead of milliseconds).

Other changes:
Now the predicate paint_rect is replaced with two predicates which are get_paint_rect and is_rect_in_paint.
Now the predicate position is replaced with two predicates which are pos and set_pos.
Now the predicate size is replaced with two predicates which are size and set_size.

If you use pos as a predicate then you have to change it because now it is a built-in predicate.

From version 2.9 to version 2.91

Changes with operators.
If you use operator as a term in the previous versions you should put it in brackets but in version 2.91 this will give you a syntax error. You should put the operator in apostrophes instead of brackets. For example, the expression X is (+) now will give a syntax error. You can write the same expression in this way: X is '+'.

Another change with the operators is that now you cannot put them in apostrophes. This means that a '+' b will give a syntax error. You should write this as a + b or as '+'(a,b). As you can see now if you want to use the prefix notation you should put the operator in apostrophes because +(a,b) is a syntax error (i.e. it is the same as + (a,b) or the space between the operator and the bracket is not important anymore).

Changes with priorities.
Now the priority of the bitwise predicates is a little bit higher. So if you use /\ or \/ or xor and if you rely too much on the priority maybe you will need to add brackets. If you have the expression X+Y\/Z then you have to change it to (X+Y)\/Z. Also X\/Y/\Z has to be changed to (X\/Y)/\Z.

Also the operators which are connected with an integer division now have a little bit lower priority. These operators are //, rem, mod, >> and <<. If you use these operators with * and / maybe you will need to put more brackets. If you have the expression X//Y*Z you have to change it to (X//Y)*Z. Also X mod Y/Z has to be changed to (X mod Y)/Z.

Look in the ADD file or in the Help/Operators to see these actual priorities.

Other changes:
The built-in predicates ++ and -- are removed. Replace ++(X) with X := X+1 and --(X) with X := X-1.

From version 2.6 to version 2.9

The message key_down has now only two arguments (the first two). Delete the third argument which was Flags. If you need the information which was carried by the argument Flags take it by the predicate message_flags.

Now, after the processing of any message, the stack is released in the same way as if the code ended with: !, fail. So, if you were using fail to clean the stack at the end of message processing, now you do not need to do this.

From version 2.3 to version 2.5

The predicates get_clipboard_data and set_clipboard_data have one extra argument. To make your old program working change:
get_clipboard_data() with get_clipboard_data(0)
set_clipboard_data(Text) with set_clipboard_data(Text, 0)

From version 1.6 to version 1.7

The key word built_in is changed. If you have it in your program you should to replace it with ***.

From version 1.2 to version 1.21

In this version the predicate for is changed. If you have for(I,A,B) in the old version it would make a loop for I from A up to B but without B. In this version the loop will be from A to B (included).

The easiest way to correct this in your old programs is to replace for(I,A,B) with for(I, A, B- 1) everywhere. Note that in this version you can write expressions in the place of A and B. Analogically if you have for(I,A,B,Step) then replace it with for(I,A,B- 1,Step) if the Step is positive and with for(I,A,B+1,Step) if the Step is negative.

Other change is in the predicates size and position. Now they have one more argument which shows which is the window that is all about. The easiest way to correct your old programs is to replace everywhere size(X,Y) with size(_,X,Y) and analogically for the position.

If you use brush(R,G,B) where R, G, B mean reed, green and blue then you have to replace it with brush(rgb(R,G,B)).

Predicate count_list is changed with function and its name is list_length

From version 1.02 to version 1.2

Many predicates now are functions and you have to change their syntax. For example is you have in your program print(S, T), then you should to replace it with S is print(T). The full list of predicates which became functions follows:

get
get_text
open
parent
print
random
rgb
scan
system_color
select_file
select_color

In version 1.2 the way in which you can define functions is changed. For example, if you wish to define function add(X,Y) and to use it like Result is add(2,2) to obtain 4 then the old definition style is:
add(Result, X, Y) :- Result is X + Y.

and the new style is:
Result is add(X,Y) :- Result is X + Y.

From version 1.0 (beta release) to version 1.0 (beta release2)

predicate / is changed with //.
predicate get_time is changed with chronometer
The argument of wait now is in seconds, not in centiseconds. Correct it by changing Time with Time/100.
The predicates get, put, get_text and set_text changed the places of their first two arguments.

The predicates bitmap and icon lost their last two arguments.

From version 0.7 to version 1.0 (beta release)

The predicates: pen, brush, window_brush, color_text, color_text_back, select_color are changed. The change is that instead of three arguments for the color now they have only one argument. Correct them by changing of Red, Green, Blue with rgb( Red, Green, Blue).


Your Guide

Recognize your Strawberry Prolog guide

This is your guide. His name is Fanfan and he will guide you around the world of Strawberry Prolog. You can go and chat with Fanfan.


Built-In predicates

Main predicates:

Control predicates
Strawberry functions
Loops predicates
Execution control
Input and Output predicates
Dialogs
Knowledge base manipulation
Direct Database Manipulation
File Manipulation:
Time
Special effects
OLE and ActiveX
E-mail control
Prolog CGI Scripts
Sockets support
SQL support

Arithmetic and special types:

Type checking and conversion predicates
Comparison
Evaluation
Standard arithmetic
Strings
Char Sets
Bitwise functions
Floating point functions

Windows and Drawing:

Windows and Controls creation
Windows and Controls use
Menu
Checkbox
Edit methods
Drawing
Fonts, colors, pens and backgrounds
Timer
Clipboard


Alphabetical list of predicates

symbols A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

symbols

+ addition
+ strings concatenation
- subtraction
. (point) sets and gets property, invokes method
* multiplication
/ division
** exponentiation
// integer division
= unify
?= unifyable
\= not unifyable
> bigger than
< less than
=:= equal
>= bigger or equal to
=< less or equal to
=\= not equal
>> shift all bits in right
<< shift all bits in left
/\ bitwise and function
\/ bitwise or function
\ bitwise not function
=.. makes functor and arguments as a list
! (cut) partially restricts the backtracking
:= assumes equal
; (or) executes the left goal and if fails or on Next Answer executes the right one
-> (if-then-else) if the most left goal succeeds then executes the next goal, if it fails then executes last goal.

A

abs returns the absolute value
add_text adds a text into edit box
animate creates an animation control
assert appends a clause to the run-time database
asserta appends a clause to the run-time database (in the beginning)
assert_in appends a clause both to the run-time database and to the source Prolog text
asserta_in appends a clause both to the run-time database and to the source (in the beginning)
arccos calculates the arccosine function
arcsin calculates the arcsine function
arctg calculates the arctangent function

B

beep produces a short beep
bezier_line draws a Bézier curve
bitmap creates a bitmap control
bitmap_image creates a bitmap object
brush sets the filling color
button creates a button control

C

call starts a goal
ceiling returns integer which is bigger than the argument
char_set gets and sets the default char set
char_set_name returns the name of the char set
charAt returns a char from its position
change_style changes the stile of a Window
check_box creates a check box control
chronometer gets time intervals in milliseconds
client_pos gets position of the window's client area
client_size gets the size of window's client area
close closes a window or a file or OLE server or a socket or MYSQL connection
color_text_back sets the text background
color_text sets the text color
const checks whether a term is a constant
convert_charset changes the char set
convert_UTF8_to_local converts from UTF-8 to 8 bit char set
copy_in_edit copies the selected text into the clipboard
cos calculates the cosine function
cosh calculates the hyperbolic cosine function
count_all_1s_in count how many instances of {1} are in N
count_successes count the successes of a goal
create_directory creates a new directory.
cursor sets the cursor to one of the standard cursors
cut partially restricts the backtracking
cut_in_edit cuts the selected text

D

delete_file deletes a file.
draw_arc draws an arc
draw_bitmap draws a bitmap image in a window
draw_chord draws a chord
draw_pie draws a pie
draw_point draws a point or takes the color of a point

E

edit creates an edit control
ellipse draws an ellipse
embed_server embeds an ActiveX control
enable_window Enables/Disables a window object
equal compares strings (with case and no case)
execute starts the execution of other program (usually *.EXE)
exp calculates the exponent function

F

fail always fails
feof checks for a end-of-file
field returns a field from a row
fill_polygon draws a polygon
find_any_1_in Find all instances of {1} in N
find_first_1_in Find the first instance of {1} in N
find_last_1_in Find the last instance of {1} in N
first_ASCII returns the ASCII code of the first symbol
float checks whether the argument is float or converts it to float
floor returns integer which is smaller than the argument
for doing a loop
ftruncate truncates a file
functor checks a functor's name and arity

G

get gets a byte, integer or float from a file
get_check_box_value gets the value of a checkbox
get_client gets a client socket of the remote host
get_clipboard_data gets the clipboard data
get_current_directory retrieves the current directory.
get_date gets current date
get_environment_arg returns a part of a string
get_file_pos returns the position of the file pointer
get_html_form returns a form field
get_program_argument returns the program argument passed from the command line
get_selected_text gets the selected text from an edit box
get_selection gets the selection text into an edit box
get_text gets the text value of a control
get_time gets current time
getenv returns the environment value
group_box creates a group box control

H

has_to unstable assignment

I

icon creates an icon control
integer checks whether the argument is integer or converts it to integer
is evaluates righthandside arithmetical expression and unifies the value with the lefthandside variable (Prolog 'assignment')

K

kill_timer kills a timer object

L

list_box creates a list box control
list_length returns the length of a list
less_than compares strings (with case and no case)
line draws a line
log calculates the natural logarithm
log10 calculates the logarithm with base ten
logoff Log off as an e-mail user
logon Log on as an e-mail user

M

max returns the maximum
menu creates a menu item
message creates a message dialog box
message_flags gets the status of the buttons
min returns the minimum
mod modulo
modify_at modifies the fact which has this consecutive number
modify_menu modifies the menu item
move_file moves a file to a new location
mysql_connect opens a connection to MYSQL server
mysql_eof checks if the end of the result is reached
mysql_fetch_row returns the next row from the MYSQL result
mysql_free_result frees the MYSQL result
mysql_num_fields returns the number of the fields from returned MYSQL result
mysql_query executes the Query on selected database on the MYSQL server
mysql_select_db selects the database from MYSQL server
mysql_store_result stores the result from the execution of a query

N

nl prints a new line
not_deeper_than temporally restricts the stack size
not Prolog negation
number checks if a term is a number

O

of that X which satisfy Y
on_the_last_step which was the fact used in the last unification
once executes a goal, but it is not re-executable
open opens a file
op defines an operator

P

paint_rect gets the rectangle which needs to be repainted
parent gets the parent window handle of the argument window
paste_in_edit pastes the selected text from the clipboard
pen gets/sets the current pen
pos gets a window's position
press_button presses a button at a given position
print converts a term to a string
print_file prints formatted file
print_string prints formatted string
printq converts a term to a string (without calculating it)
put puts a byte, integer or float in to a file

R

radio_button creates a radio button control
raise_event sends information from the sever back to the client
random generates random numbers
read reads a term using a dialog box
read_new_mail reads e-mail letters
read_sock reads a string from the socket
readf reads a string from a file
readln reads a line from a file
rect draws a rectangle
rem remainder
remove_directory removes a directory.
repeat always tries next answer
replace replace one string with another
retract retracts a clause from the run-time database
retract_at retracts the fact which has this consecutive number
retract_in retracts a clause both from the run-time database and from the source
retractall retracts all occurrences of a clause from the run-time database
rgb creates a color by its RGB value (Red, Green, Blue)
round returns integer which is round the argument
round_rect draws a round rectangle

S

s_mail sends mail (ONLY for UNIX)
scan converts a string to a term
select_color invokes an select color dialog box
select_file invokes an open/save file dialog box
select_font invokes a Select Font dialog box
send_mail send an e-mail letter
server opens an OLE server
server2 opens an OLE server which listen for events
server_socket creates a server socket
set retracts a clause and assert another one in place of it
set_at changes the fact which has this consecutive number
set_check_box_value sets the value of a checkbox
set_clipboard_data sets the clipboard data
set_content_type sets the content type
set_cookie sets a cookie on the client's browser
set_current_directory sets the current directory.
set_file_pos sets the file pointer
set_pos sets a window's position
set_selection sets the selection text into an edit box
set_size sets a window's size
set_text sets the text value of a control
set_timer creates a timer object
shell_execute opens a file by using it extension.
sign returns the sign
sin calculates the sine function
sinh calculates the hyperbolic sine function
size gets a window's size
socket returns a client socket
split splits a string using separator character
sqrt calculates the square root
static creates a static label
str_length finds the length of the given string
string_end finds ends from the given string
string_from_ASCII makes string from ASCII number
sub_string finds substrings from the given string
system_color gets system color

T

terminate terminates the program and displays a message
text_out draws a rectangle with a text
text_out_size Calculates the width of the text that would be printed
tg calculates the tangent function
tgh calculates the hyperbolic tangent function
the_head_of returns the head of the clause by its consecutive number
trace switches program execution to trace mode
tree_box creates a tree box control
true always succeeds
true_value returns one or zero

U

update_window updates the drawings in the window
url_encode encodes into the URL format

V

var checks if a term is a not-instantiated variable

W

wait waits a time interval
window creates an overlapping window
window_brush changes the window's background color
write writes a term
writeq writes a term (without calculating it)
write_sock writes the string in the socket
writef writes the string in a file

X

xor bitwise xor function

Y

yes_no opens a dialog box with a yes-no question to be answered


Errors

Error 1: Unexpected full stop.
Maybe you forgot to close an open bracket.

Error 2: Unexpected ).
Error 3: Unexpected }.
Error 4: Unexpected ].
Maybe you forgot to open this bracket.

Error 5: You wrote an empty atom.
You wrote two apostrophes with nothing between them.

Error 6: You wrote ( ) without a function.
You can write functions with zero arguments like f( ) but otherwise you cannot write these two brackets with nothing between them.

Error 7: Unexpected end of file.
The program must end with a full stop.

Error 8: Cannot put a comma after |.
Think of the | as an operator of type xfx and priority 1000. Think of the comma as an operator of type yfx with the same priority.

Error 9: Empty clause.
Maybe you accidentally wrote a single full stop without a clause.

Error 10: Incorrect binary number.
The binary number begins with 0b (here 0 is zero). It contains only the digits 0 and 1.

Error 11: Incorrect octal number.
The octal number begins with 0o (here 0 is zero and o is the small letter o). It contains only the digits from 0 to 7.

Error 12: Incorrect symbol number (0'symbol).
The symbol number begins with 0' (zero and apostrophe). After 0' you can put any symbol but if you want to use some of the symbols " or ' or ` or \ you have to double them or put \ in front of them (like 0'"" or 0'\\ or 0'\"). You can write symbols like "new line" and "tabulator" in this way: 0'\n and 0'\t.

Error 13: Incorrect floating-point number with E but without the power.
The floating-point number begins with digits followed by a point and eventually by the letter E, after which there must be a number. For example 3.14 or 0.1e-5 or 123.0e+2 or 12e11.

Error 14: The symbol \ has to be replaced with \\ in the string.
The combination \n is accepted as the symbol "new line" so if you want to write the string \n then you have to code it as \\n.

Error 15: The operator XXX is a prefix (or of the type term) but what is expected here is something like an infix operator or a full stop.
Actually, what is expected here is an infix or a suffix operator or a comma or | or a closing bracket or a full stop.

Error 16: Instead of the atom XXX what is expected here is something like an infix operator or a full stop.
If the message is "Instead of a non-functional bracket ..." maybe you are trying to write a function like f(x) but you have put a space between f and (. Other possibility is if you have tried to write the term x op y in a prefix notation. In this case you cannot write op(x, y) because op is an infix operator but you can write 'op'(x, y), i.e. if you put the operator in apostrophes it will be accepted as an atom.

Error 17: The operator XXX is an infix (or suffix) but what is expected here is a beginning of a term.
This mean that here is expected atom or open bracket or prefix operator.

Error 18: The symbol comma is infix operatorbut but what is expected here is a beginning of a term.
This means that here is expected an atom or an open bracket or a prefix operator.

Error 19: The priority of the prefix operator XXX is lower than the priority of YYY. Use brackets to fix this error.
For example, the expression \ ?-atom will give this error because the priority of \ is higher than the priority of ?-. If you want to say '?-'('\'(atom)) write it as ?- \atom. If you want to say '\'('?-'(atom)) write it as \(?-atom), i.e. use brackets.

Error 20: The priority of the suffix operator XXX is lower than the priority of YYY. Use brackets to fix this error.
This error is symmetrical to error 19 but the problem is with a suffix instead of a prefix operator.

Error 21: The last item in an atom-operator sequence has to be an atom or an suffix operator.
The atom-operator sequence is any sequence of terms, operators, commas and | which is inside of a pair of brackets or before a full stop.

Error 22: You cannot make construction using the operators XXX and YYY. They have equal priority and their types are _fx and xf_.
Both operators cannot accept an operator with the same priority (one cannot accept from the left side and other from the right side).

Some of the operators are not defined in the ADD file. Use Help/Operators to see which ones are defined and how they are defined.


Warnings

Warning 1: There is a /* in a symbol atom.
For example, +/* will give this warning. If you want to start a comment but /* is glued to the plus put a space before /*. If you want to use +/* as a term put it in apostrophes.

Warning 2: Possibly a full stop is glued to an atom.
For example, the expression X =.. Y will give this warning because the full stop which is on the end of =.. is possibly not a part of the atom =.. . To avoid this warning do not put a space between =.. and Y or put the expression in brackets. So, if you write X=..Y or (X =.. Y) you will not have this warning.

Warning 3: The symbol 'X' cannot be in an atom.
In this version of Strawberry Prolog some of the symbols like '(' cannot be in the atoms. So, if you write 'f(a)' you will receive this warning twice and the atom 'f(a)' will be accepted as 'fa'.

Warning 4: The string XXX is not an operator.
If you want to use a symbol string as atom put it in apostrophes or define it as an operator of a type term.

Warning 5: The global variable G_XXX is used only once.
If you use one global variable only once maybe you do not need it. To avoid this warning you can declare this global variable in this way: define_sys_variables(G_XXX).

Warning 6: The predicate XXX(...) is defined in the ADD file.
You try to redefine a built-in predicate whose definition is in the ADD file. Use another name for your predicate in order to avoid the conflict with the name of the built-in predicate which already exists.

Warning 7: The predicate XXX(...) has an interrupted definition.
This warning will occur if the definition of your predicate consists of more than one clause and if you placed another clause inside the definition. For example: a(x). b(y). a(z). will give this warning. This variant is a bad programming style. In order to do it better and avoid the warning put the definition of b after the definition of a. For example: a(x). a(z). b(y).

Warning 8: The predicate XXX(...) has an interrupted definition in the ADD file.
The same as the warning 7 but here the problem is in the ADD file. Maybe the ADD file is corrupt.

Warning 9: Strange predicate XXX(...) as a head in clause YYY.
Possible error! For example, if the head is A(x) you will receive this warning. Often this warning occurs when a full stop is put instead of a comma inside a clause. For example, the clause: p(X), p(Y). will give this warning.

Warning 10: You have a clause with a variable for head.
Possible error! Such clause should be applied every time on every unification. Anyway, it will not work in this way because it will be ignored (i.e. it will not affect the execution of the program).


Objects and Special Types

These are the following types:

Integers
Floats
Strings
Objects

When is written number this mean integer or float.

Usually when somewhere you can use a special type then you can use also a global variable in the same place.


Tutorial in Strawberry Prolog

This section of the on-line help of Strawberry Prolog is designed for users who have no earlier experience with programming in Prolog. It contains short example programs in Prolog and discussions on their development and functioning. The section is an introduction to just the basic features of Prolog without being precise or exhaustive. Users who are determined to take an advanced course in Prolog are recommended the number of textbooks available. Among these is the excellent book Programming in Prologby W. F. Clocksin and C. S. Mellish .

To go through this section, place this help window and that of a running Strawberry Prolog environment side by side on the screen, and then experiment with the example programs while reading. Lines of Prolog programs, which have to be run, can be copied into some Strawberry Prolog window through the clipboard, using the Edit|Copy command of the Windows Help.

0. A preliminary note
1. Ground concepts
2. Facts
3. Questions
4. Generalization
5. Rules
6. A tracing session in Strawberry Prolog
7. Dreadful looping
8. Terms
9. Arithmetical expressions
10. Infix notation
11. Lists
12. A list processing example
13. The anonymous variable
14. Updating a Prolog database
15. Inferring negation
16. not, cut, fail

1. Ground concepts

A program in Prolog is a collection of facts and rules on how to treat facts in order to check whether some other fact is derivable from the ones in stock. Following this brief description, a Prolog program can be viewed as a kind of sophisticated database, where some of the data items are stored immediately as facts, and other data items can be acquired by applying rules. For this reason a Prolog program is often called Prolog database . This database is created by the programmer, and further processed by the Prolog interpreter (or compiler) in the course of Prolog program execution.

Program execution itself is a specific procedure of searching in the database in order to find out whether a certain (kind of) fact can be confirmed on the grounds of the facts and rules found in the program. Such facts are called goals . A successful confirmation that some goal can be inferred in a database is called satisfying a goal . All procedural behaviour on behalf of Prolog programs, e.g. input and output, relies on the specific procedure, known as backtracking , run by the Prolog interpreter during program execution , and on the occurrence of some predefined (built-in ) kinds of goals in rules. Satisfying such goals, apart from searching the database , has side effects , such as opening a file or ringing a bell.

2. Facts

In Prolog facts are understood as formal relationships between objects. The effect of the presence of a fact in a Prolog database is chiefly that the Prolog interpreter will succeed, in case this fact happens to match a goal to be satisfied.

For example, let strawberry , glory , napoleon and turkey be some objects. The facts

likes(turkey, strawberry). % 'Turkeys like strawberries.'
likes(napoleon, glory). % 'Napoleon likes glory.'

represent the formal relationship likes between these objects. In Prolog a relationship like likes is called predicate. In this example likes is a programmer-defined (user-defined) predicate. Just like every Prolog implementation, Strawberry Prolog contains built-in predicates too. Examples of their working are found below. Consider a Prolog database that consists of above facts only. That is, let the predicate likes be true for the objects turkey and strawberry , and also for the objects napoleon and glory .

To make such a database, select the File|New command from the main menu, and then enter the above facts in the newly appeared edit control. It is advisable to immediately select File|Save as... after entering the text, to specify a file for your example database to reside on disk in.

3. Questions

To make the Prolog interpreter try to satisfy some goal using this database , one must ask a question with the goal in it. In Strawberry Prolog this means to place it together with the contents of your Prolog database. The question:

?- likes(X, strawberry).

will cause the Prolog interpreter to respond:

Yes.

To see this, you need to run your program. This you can do by selecting the Run|Run (F5) command from the main menu. Just preparing your source for execution, e.g. checking it is error-free, is done by selecting Run|Compile.

This response means that the goal in this question got satisfied successfully. The reason for this is that substituting the object turkey for the variable X makes the goal likes(X, strawberry) appear exactly the same as the fact likes(turkey, strawberry) . Hence the Prolog interpreter can conclude the existence of some object X that satisfies the formal relationship likes(X, strawberry) , which is the goal above, and this object is turkey . The fact that it is turkey which, when substituted for X , brings about success, is also considered by the Prolog interpreter, when it processes the goal likes(X, strawberry) . The effect of this is that the variable X becomes instantiated to the object turkey . This can be demonstrated by asking a bit more complex question:

?- likes(X, strawberry), write(X).

Edit your initial question to make it like this. (Adding the new question to the database next to the previous one will cause both to be answered consecutively.)

Answering this question by the Prolog interpreter consists of consecutively satisfying first the goal likes(X, strawberry) , and second, in case the first goal gets satisfied successfully, the goal write(X) . Now, when the Prolog interpreter arrives at the goal write(X) , X is already instantiated to turkey . Besides, write is a built-in predicate : satisfying write(...) does not cause a database search, but causes whatever its argument, X , is instantiated to to be produced as output. So the overall effect of satisfying the goal above is(F5) :

turkey
Yes.

4. Generalization

In practice it is often desirable to concisely specify a large amount of facts of similar kind. For an example of a case, when this can be done in Prolog, consider the following Prolog statement:

likes(X, glory). % 'Everybody likes glory.'

Enter the line above into a new edit control window, to avoid getting it shadowed by other facts on likes.

This statement means that the predicate likes is true, no matter what object stands for X , provided that next to X is glory . The statement, if present in a Prolog database , makes it able to satisfy every concrete goal of the above kind. For example, now the question (you may enter it next to likes(X, glory))

?- likes(turkey, glory).

will get (F5) a Yes . Moreover, a question like

?- likes(Y, Z), write(Y), nl, write(Z).

will also be successfully satisfied in case a database contains the above statement. The output that the Prolog interpreter will produce upon the above question, may look a little strange:

_1
glory
Yes.

The cause for this can be explained by examining in greater detail how the Prolog interpreter deals with the 'general fact' likes(X, glory) . When trying to satisfy the goal likes(Y, Z) , which is the first step of answering the question above, the Prolog interpreter encounters likes(X, glory) in the database . It finds out that instantiating the variable Z to the object glory and assuming that the variables X and Y stand for the same thing, make likes(Y, Z) appear exactly the way likes(X, glory) does. Since the latter is found in the Prolog database, this is sufficient for the Prolog interpreter to regard the goal as successfully satisfied. However, X is not instantiated when the interpreter arrives at the goallikes(Y, Z). It is just assumed that X and Y stand for the same object, or, as it is adopted to speak in Prolog slang, the two variables share . Hence, there is no concrete object to instantiate Y to. So, write produces _1 - an internal name, which has little meaning to the Prolog programmer. Next, after moving to a new line, comes the object glory .

5. Rules

A Prolog database doesn't need to contain explicitly all the facts , it can produce. For example, let r be a binary predicate which is a strict linear ordering on some given finite set of objects. Suppose that some Prolog database is expected to be able to produce every fact of the kind r(a, b) , where a and b are some objects and, according to r , a precedes b . If there are n distinct objects, the number of the true facts of this kind is n(n-1)/2 . Since r is a linear ordering, r satisfies the axiom of transitivity

r(a, b)andr(b, c)implyr(a, c)for every a, b, c.

This axiom shows that a fact of the kind r(a, c) doesn't need to be stored immediately in a database, in case there exists some b such that the facts r(a, b) and r(b, c) can be produced by this database, because in this case r(a, c) can be inferred from the former two facts. This observation can easily be utilized in a Prolog database. In order to implement r , that is defined on n objects, a Prolog database needs only to contain n-1 facts of the kind r(a, b) , where object b immediately precedes object a . The rest of the n(n-1)/2 facts about r can be derived by means of a Prolog rule that implements the above axiom. In particular, for n=5 the database might look like this:

r(a1, a2).
r(a2, a3).
r(a3, a4).
r(a4, a5).
r(X, Y) :- r(X, Z), r(Z,
Y). % transitivity

Open a new Prolog-text window with the File|New Strawberry Prolog main menu command, then use the Edit|Copy Windows Help main menu command, to transfer the above lines to the new window through the clipboard.

The last line of this Prolog program is an example of a Prolog rule. What comes first in a rule is a goal which defines what facts can be expected to be confirmed by applying this rule. This goal is called head of the rule. Typically the goal contains argument places occupied by variables , as well as by concrete objects. Next in a rule comes a :- , followed by a sequence of (other) goals. This sequence is called body of the rule. A rule says that a fact of the kind specified by its head can be confirmed, provided that all the facts in the body can be confirmed.

6. A tracing session in Strawberry Prolog

Let us now trace how the Prolog interpreter will work to satisfy a goal using this database . Consider the question (add it to the new database, then just Run|Compile it) :

?- r(a2, a5).

To start tracing, select Trace|First step (Ctrl+F5), instead of Run|Run from the main menu. Next, select Trace|Proof Tree, to open a window, that will let you watch what is going on.

This question makes the interpreter try to confirm the fact r(a2, a5) . The interpreter proceeds by looking up in the database from the first line down for a fact to match with r(a2, a5) . None of the facts in the first four lines matches .

To make the interpreter get to work, press F9 (Trace|One step). What you must see is a ?-,on a separate line, followed by the body r(a2,a5),of your question.

So, (another F9) the interpreter arrives at the rule in the last line. The head of this rule matches the goalr(a2, a5) , because substituting a2 for X and a5 for Y makes it look exactly the same as this goal. So, the interpreter makes this substitution and thus reduces the goal r(a2, a5) to the conjunction of the goals r(a2, Z) and r(Z, a5) . The Proof Tree window shows these two goals. A small difference to note is that variable Z is replaced by an internally named variable. Next it tries to satisfy the goal r(a2, Z) . This goal is in red, like the one coming with the question. This is so, because it is now in the focus of the interpreter. The goal next to it, whose turn has not come yet, is in black. To satisfy this new goal, the interpreter starts another search of the database. To launch it, press F9 again. This time it finds that the fact r(a2, a3) matches the goalr(a2, Z) , because a3 can be a substitute for the variable Z . Now, to display that the goal r(a2,Z)is already satisfied, Strawberry Prolog has moved it on the left, and coloured it blue. The interpreter makes this substitution, and now the initial goal r(a2, a5) gets reduced to the conjunction of goal r(a2, a3) and r(a3, a5) , the former already satisfied. Notice, that the uninstantiated variable with an internal name has been replaced by a3 everywhere, and not just in the goal already satisfied. In order to satisfy the goal r(a3, a5) , the interpreter starts another search of the database (F9) , and, after realizing that none of the four facts in it matches the goal, arrives at the rule again. According to it, r(a3, a5) gets reduced to the conjunction of r(a3, Z) , and r(Z, a5) . Luckily, the last two goals get successfully satisfied: searching the database for a confirmation of r(a3, Z) ends (F9) at the fact r(a3, a4) and causes the interpreter to substitute a4 for Z ; this transforms r(Z, a5) into r(a4, a5) - a goal which also matches a fact contained in the database. (F9) Finally the interpreter answers

Yes.

Since this was the last goal to satisfy in order to get overall success for the goal come with the question, all red turns green.

To recapitulate, this example contains two occasions of rule application . In both of them the application of the rule starts with finding that the goal to be satisfied by rule application has the form specified in the head of the rule. The procedure of establishing this is called unification . Our example shows that distinct goals can be found appropriate to satisfy by applying the same rule. This is so, because the head of the rule contains variables (X and Y ) which act as placeholders for whatever an individual goal may happen to contain at the corresponding places. When unifying the head of the rule with either goal these variables get substituted by (or instantiated to ) the objects which stand in their places in the goal. These instantiations affect the body of the rule as well. Thus each of the two goals, that get satisfied by applying the rule , reduces to a different pair of goals. The satisfaction of every goal that commences as a result of applying the rule goes in the same way as the satisfaction of the goal that causes the rule to be applied. In other words, the Prolog interpreter works 'recursively'. Although the goals that the rule above gets applied to are both simple facts, the pairs of goals that it 'generates' are 'generalized', i.e. contain the uninstantiated variable Z . This variable is the same one in the goals r(a2, Z) and r(Z, a5) which emerges due to the first application of the rule. It is the same one in the goals r(a3, Z) and r(Z, a5) which emerge due to the second application of the rule, too. But the Z s that occur in the goals r(a2, Z) and r(a3, Z) are distinct.

Rerun the whole tracing by selecting Trace|First step again, then select Trace|Proof Tree and press F9 a few times, to see that, until instantiated, the internally named variables for Z get different numbers for their names.

The cause for this is that these Z s get allocated for the needs of distinct applications of the rule. A most significant consequence of that r(a2, Z) and r(Z, a5) share the same Z variable is that after successfully satisfying r(a2, Z) the substitution of a3 for Z affects the next-to-satisfy goal r(Z, a5) , and it ceases to be 'generalized'.

7. Dreadful endless loops

The example question above shows that this Prolog database will correctly confirm that two objects are in some relation of precedence, in case they are, according to the informal understanding of this relation. Now consider the following question:

?- r(a5, a4). % 'Whether a5 precedes a4?'

Replace ?- r(a2, a5).in your example text with this question to experiment with its working.

Of course, following the idea behind this database , it would be most desirable for the Prolog interpreter to answer (DO NOTCALL RUN|RUN HERE!)

No.

to this question. Unfortunately the interpreter never does so. The procedure it executes in order to check whether r(a5, a4) is derivable from the contents of the database runs into an infinite loop. Here is how exactly this happens. Start a new tracing session now, and make the first F9 step. First, note that none of the facts in the database matches the goal r(a5, a4) . Having realized this, the interpreter tries to satisfy the goal by applying the rule . That is, it reduces (F9) the goal r(a5, a4) to the sequence of goals r(a5, Z) and r(Z, a4) , and proceeds to satisfy the first of the two. The search for a fact to match r(a5, Z) fails too. So the rule is reached again, and r(a5, Z) gets reduced (F9) to r(a5, Z') and r(Z', Z) . Note that the name Z'(actually some internal name) for the variable Z here aims to emphasize on that the new application of the rule causes a new copy of the variable Z to be allocated . Now the interpreter has to satisfy a new goal r(a5, Z') , which is just like the previous one r(a5, Z) . Since the circumstances under which the new goal emerges differ in no detectable way for the interpreter, it proceeds to satisfy this new goal in exactly the same way (F9) . This causes the consecutive generation of a (potentially) infinite sequence of goals r(a5, Z'') , (F9,...) r(a5, Z''') , etc., i.e. an infinite loop. Fortunately, this loop does not really require the Strawberry Prolog interpreter to be stopped by 'crude force'. To let the situation develop autonomously, press F6, or select Trace|Go. This switches from stepwise to normal execution. The reason for this is that, when generating every new goal, the interpreter also stores some data on how to proceed in case the goal gets satisfied. The accumulation of this data soon consumes the whole available memory and the interpreter stops with an alarming message (Stack is full.) .

It is a good question to ask here: Could the compiler have detected and avoided the redundant loop-to-abort shown above? It is a pity, but Prolog compilers cannot do so. Forthcoming version 2.0 of Strawberry Prolog is planned to handle a loop check option to avoid many kinds of redundant loops.

So far, overcoming the undesirable behavior of the interpreter can be a reason to make a small modification of the example database. It is suitable to specify the relationship object aimmediately precedes object b , which is a special case of the relationship r, object a(merely) precedes object b , by a separate Prolog predicate named, say, c . The four facts from the database changes as follows:

c(a1, a2).
c(a2, a3).
c(a3, a4).
c(a4, a5).

To make this modification, just change r to c in the facts already part of your program.

In order to express that immediately precedes implies (merely) precedes the database can be augmented with the following rule :

r(X, Y) :- c(X, Y). % r is satisfied, provided c is.

Now consider the following modification of the transitivity rule:

r(X, Y) :- c(X, Z), r(Z, Y). % X precedes Y, provided that
% X immediately precedes some Z
% and this Z precedes Y.

Make these changes to continue following the example.

Obviously, the modified version of the rule cannot lead the interpreter into an infinite loop, at least not in the fashion of the original one. The user is encouraged to trace in detail the working of the new database on the same example goal as above, and obtain the coveted answer

No.

8. Terms

The examples above exhibit facts as relationships between abstract objects. The objects so far involved have no structure of their own. That is why they are called atoms . Prolog programs allow two more kinds of concrete primitive objects: numbers and character strings . Save that, Prolog provides a way to work with complex objects, which are called structures. Syntactically structures are recorded as terms . Here are some example of terms:

355 / 113 % 355/133 = approximately pi
unit("inch", "metre", 254 / 10000) % some data on the correspondence
% between measures of length

A term consists of a functor and a sequence of (simpler) terms, which are called its arguments . The arguments usually follow the functor, and are separated by commas and enclosed in parentheses. Atoms , numbers and character strings are the simplest kinds of terms. As it can easily be noticed, terms do not look very different from facts and goals. Moreover, even rules can be viewed as a special kind of terms. It is often convenient to think in terms of tree-like structures, like these, that correspond to the above terms:

Such structures are available in a large variety of programming languages. A feature of terms, which is rather specific to Prolog, is that one can specify terms which are not concrete objects, but, just like 'generalized' facts and goals in rules, they contain variables as their arguments, and thus represent any object of some specified shape . Some of the rules in the example Prolog database below, when applied , may cause the instantiation of variables inside terms:

nonzero(5). % 5 is a nonzero number
nonzero(15). % 15 is a nonzero number
equal_to(X, X). % every object is equal to itself
equal_to(A * X, B) :- nonzero(A), equal_to(X, B / A).
% the product of A and X is equal to B,
% provided that A is nonzero
% and X is the quotient of B and A.
% The functor of a term that is an
% arithmetical expression may stand between
% its arguments.
equal_to(0 * X, 0).
% no matter what X is,
% the product of 0 and X equals 0.

Make a new window for Prolog text in your running Strawberry Prolog environment and enter the above database.

To see this take place, consider the question (enter this question too, and press F5 to get it answered) :

?- equal_to(5 * X, 2), write(X).

that will actually make the Prolog interpreter produce a 'symbolic solution' to the equation 5x=2 . The response of Prolog to this question is

2 / 5 % the quotient of 2 and 5
Yes.

Thanks to the opportunity to recursively apply Prolog rules , the above program can produce a solution in a more complicated case too:

?- equal_to(5 * (15 * X), 25), write(X).

(Replace the previous question with this one and press F5 to execute)

The answer Prolog will give to this question is:

(25 / 5) / 15
Yes.

Employ the debugging facilities of Strawberry Prolog to trace in detail the way the above questions get answered.

9. Arithmetical expressions

The 'solution' of the equation 5.15.X=25 is purely 'symbolic': no calculations are done to simplify the expression obtained for X . This is so, because, although terms like B / A denote arithmetical expressions , Prolog treats them as mere representations of structures, and does not automatically evaluate them. Further, the predicate used to specify that a number is distinct from 0 is tailored to work just for 5 and 15 , that actually occur in the example questions . A more realistic Prolog program to symbolically solve equations needs to refer to predicates that cause their argument terms to get evaluated . These are the is predicate and the comparison predicates . Here is how a more realistic version of nonzero might look like:

nonzero(X) :- X =\= 0.

(Replace the facts on >nonzerowith this rule.)

The body of this rule contains a 'call' to the comparison operator =\=- a built-in predicate , which causes its arguments to be evaluated , in case they are arithmetical expressions , and gets successfully satisfied, in case the values obtained are distinct. In case either argument is not an arithmetical expression , =\= just fails. With this rule instead of the facts about 5 and 15 , the program database above can correctly answer a questions like:

?- equal_to(*(115, X), 250), Y is X, write(Y).

(Replace the previous question with this one and press F5 to execute)

Notice the call to the is predicate in the sequence of goals which constitute this question. This call causes the evaluation of the arithmetical expression that X is instantiated to after the success of equal_to(115 * X, 250) . The numerical value of this expression then instantiates Y . The response to this question is:

2.17391
Yes.

The number 2.17391 is the exact root of the equation 115x=250 .

10. Infix notation

As it is obvious from the above example, terms which have * and / as their functors are subject to special treatment on behalf of some built-in Prolog predicates. For the sake of convenience such terms can also be recorded in the customary infix notation , e.g. 115 * X instead of *(115, X) . Prefix notation is available, though rarely used for most terms, e. g. is(X, Y) is legal too.

11. Lists

A kind of terms that have special syntax for their so frequent use are lists . Just like in other programming languages, in Prolog lists are used to represent finite sequences of arbitrary objects. Here is an example of list:

[likes, [strawberry, X],
[glory, Y]] % example list

The simplest way to record a list in Strawberry Prolog is to write the objects it consists of, separated by commas, and enclosed in brackets. This is practicable only if the structure of the lists is clear in advance. In general a list is just expected to contain a 'first' object. This object is called the head of the list. What remains of a list, if its first object gets removed, is called the tail of a list. A list with head H and tail T can be denoted by

[H|T]

Unifying the example list with this one will result in substituting likes for H and [[strawberry, X], [glory, Y]] for T . It is often necessary to specify a few more elements of a list, starting with the first one, without specifying the whole list. To do this one can write lists like

[F, P | T] % a list with at least two elements

Unifying this list with the example list will cause F , P and T to be instantiated to likes , [strawberry, X] , and [[glory, Y]] respectively. The use of | , though indispensable, introduces lots of ambiguity in recording lists. In particular [strawberry, turkey, napoleon, glory] , [strawberry | [turkey, napoleon | [glory]]] , and even [strawberry, turkey, napoleon, glory|[]] all denote a list, which can be represented by the same tree-like structure.

The tail of a single-element list is the atom [] , that is also called the empty list .

12. A list-processing example

Let us demonstrate the use of lists by writing a still more concise Prolog database to represent the linear ordering predicate r from the example above. (You need a fresh edit control window again, because this database must not merge with others) The ordering r can be represented as the list [a1, a2, a3, a4] , where every object occurs on the left of the ones it precedes. This list can be included in the Prolog database as the fact :

r_list([a1, a2, a3, a4]).

(Enter this fact into a new window for Prolog text)

Now, in order to define the r predicate, it is enough to represent as a collection of Prolog rules the following statement:

r(a, b)holds iff the above list has the form [a1,..., a | [ak,..., b | T]]

In other words, after eventually removing several elements from the beginning of the list which satisfies r_list , it must be possible to obtain a list that has a for its head , and has b as a member of its tail . Here follow the appropriate Prolog rules:

sublist(L, L).
sublist([H | T], S) :- sublist(T, S).
member(Y, [Y | Z]).
member(Y, [W | Z]) :- member(Y, Z).
r(X, Y) :- r_list(L), sublist(L, [X | T]), member(Y, T).

(Add these lines to the data on the ordering >r)

The predicate sublist defines what it means for some list S to represent the same sequence as some other list L , save the first several members. The first line says that L is a sublist of itself. The second says that S is a sublist of a list with head H and tail T , provided that it is a sublist of the tail T . Next come the rules which define what it means for some object Y to be member of some list. The cases in which this holds are two again: Y has to be either the head of the list or a member of the tail of the list. Finally r(X, Y) holds if some sublist of the one which defines the linear ordering in question starts with X and has Y as a member of its tail.

Run this example program using the tracing facilities of Strawberry Prolog in order to see how exactly it works. For this purpose, of course, you must supply an appropriate question.

13. The anonymous variable

Note the occurrence of the variable H in the head of the rule in the second line of the definition of sublist . H occurs nowhere else in the rule. It acts just as a placeholder to ensure that the first argument of sublist has some head, no matter which exactly, and occurs nowhere else. The roles of Z in the first line of the definition of member , and that of W in the second one, are similarly inferior. In such cases, programmers in Prolog are recommended to use a special variable, which is called the anonymous variable . It is denoted by _ . Here is how using the anonymous variable changes the above Prolog program:

sublist(L, L).
sublist([_|
T], S) :- sublist(T, S).
member(Y, [Y | _]).
member(Y, [_|
Z]) :- member(Y, Z).
r(X, Y) :- r_list(L), sublist(L,
[X | T]), member(Y, T).

Make the indicated modifications in your window for Prolog text. Then run the whole thing to see that it works just the same way.

The anonymous variable matches 'whatever it encounters' during unification . Besides, two or more occurrences of the anonymous variable in the same rule need not stand for the same object.

14. Updating a Prolog database

Thinking of a Prolog program as of a database naturally reminds that databases admit updates. Strawberry Prolog contains built-in predicates , that, when 'called' have the side effect of adding and removing facts and rule from the Prolog database currently processed by the interpreter. These are the predicates assert and retract . Each of these predicates takes a single argument. The side effect of satisfying assert is adding its argument as a fact or as a rule to the end of the database, depending on what the argument is. Invoking the retract predicate causes the interpreter to search the database for the first fact or rule which matches the argument supplied to retract . If there is none, retract will fail. Otherwise the item found gets removed from the database. To see how these predicates work, consider the implementation of the linear ordering predicate r with the aid of the supplementary predicate c again. The predicates add_between and remove_between , which are defined below, can be used to update the list of facts on c and thus insert new objects at specified places in the ordering r , or remove previously inserted objects:

add_between(X, Y, Z) :- % add object X between objects Y and Z
retract(c(Y, Z)), % by removing the fact which
% Y immediately precedes Z
assert(c(Y, X)), % and adding
% that Y immediately precedes X,
assert(c(X, Z)). % and X immediately precedes Z.

remove_between(X, Y, Z) :-
retract(c(Y, X)), retract(c(X,
Z)), assert(c(Y, Z)).
% converse to add_between

15. Inferring negation

The predicate add_between which is defined above will not treat the case a new object has to be added, say, as the first one, according to the ordering r . A Prolog predicate that would do this, will first have to find out which object is first, according to r , at the time when the new one is to be added. Then this predicate will be able to assert the fact that the new object immediately precedes the one found. To determine which is the first object in r means to find an object X such that the database does contain a fact of the kind c(X, Y) , and does not contain facts of the kind c(Z, X) . In other words, the rule that is needed must look like

first(X) :- c(X, _),"c(_, X)fails".

The second 'goal' in the body of this rule ought to be successfully satisfied, in case some other goal fails. The Prolog constructs demonstrated so far are not adequate to express such a goal. All of them use the data found in the database 'positively', i.e. the more data present in the database, the bigger the chance for a goal to succeed. One may specify a goal that succeeds exactly in case some other goal fails by using the not built-in predicate . Using not , the predicate add_first(X) , which adds its only argument in the beginning of the linear ordering r , can be defined in the following way:

add_first(X) :- first(Y), assert(c(X, Y)).
first(Y) :- c(X, _), not(c(_, X)).

16. Not, 'cut', fail

The not predicate is fundamentally different from the other built-in Prolog predicates mentioned so far, because its working affects the very procedure of satisfying goals : in order to satisfy not(X) , the interpreter has to try satisfying the argument X as a goal, and declare failure if X succeeds; in case X fails, not(X) must succeed. Although not itself seems fundamental, the way it gets processed by the interpreter just described can be defined in terms of two still more fundamental built-in Prolog predicates . They are known as 'cut' and fail .

Here is an example on the role of the 'cut' predicate. As it can be seen from the examples above, a Prolog database may contain several rules with their heads matching the same goal. To satisfy one, the interpreter tries applying all the rules , starting from the topmost rule down, until some rule applies successfully. Sometimes, after successfully satisfying part of the goals which usually constitute the body of a rule, it becomes clear that the goal which caused the rule to be applied will either succeed by successfully finishing the body of the same rule, or fail no matter what other rule are available. For example, suppose that a database contains the rules

equal_to(A * X, B) :- A =:= 0, B =:= 0.
equal_to(A * X, B) :- A =/= 0, equal_to(X, B / A).

The heads of the two rules are exactly the same, and if the first rule applies for some goal successfully up to A =:= 0 , and then B =:= 0 fails, trying to apply the second rule to the same goal is no use. This can be expressed by placing a 'cut' between the two goal in the body of the first rule. For the sake of brevity 'cut' is denoted by ! :

equal_to(A * X, B) :- A =:= 0, !, B =:= 0.
equal_to(A * X, B) :- A =/= 0, equal_to(X, B / A).

Encountering ! in the body of a rule makes the Prolog interpreter give up (or 'cut') all the alternative ways not yet tried to satisfy the goal which caused this rule to be applied. (This goal is also called the cutparent.) In the example above, if A evaluates to 0 and B does not, thanks to ! , the interpreter will not attempt to apply the second rule at all. Here ! just helps save execution time. In general, the alternatives which get discarded due to ! need not be redundant, and ! can affect the very set of goals which a database will satisfy. Together with one more built-in Prolog predicate , namely fail , cut can be used to 'extract' goals from the set of those which a database must be able to satisfy. For example, the following database will confirm every individual fact of the kind likes(X, glory) , but the fact likes(strawberry, glory) :

likes(strawberry, glory) :- !, fail.
likes(X, glory).

The fail predicate, which is next to ! in the rule just above, causes the application of this rule to fail. Together with ! this rule will cause every question like likes(X, glory) where X is either uninstantiated or instantiated to strawberry to be answered No . Yet, in case X is instantiated to another object, the database will confirm that likes(X, glory) .

Having the above examples of the working of ! and fail in mind, one can easily digest the following definition of the not Prolog predicate.

not(X) :- X, !, fail. % Try satisfying X. Successful ?
% if yes, not(X) must fail, having 'cut' off
% alternative ways to succeed.
not(X). % if no, not(X) must succeed.

This definition displays a way a goal can be passed as an argument to another goal: here, the body of the rule used to define not tells the interpreter to treat X as a goal and try to satisfy it.


Special files

A Strawberry Prolog program consists of up to three files and some additional if defined:
1) a .def -file, where reserved words are defined;
2) an .add -file, where built-in predicates are declared together with some other definitions;
3) a .pro or .spj -file, where the 'very' Prolog 'program' is found;
4) additional files if they are defined in the project.

The .def - and .add -files create the context for the correct understanding of the program by the compiler (just like .h -files in C).

Compilation begins with reading the .def -file, in order to establish correspondence between the numerical identifiers of the reserved words and their string representation. The numerical identifiers of the reserved words actually correspond to line numbers in the .def -file. This way the user can modify any reserved word. It is essential to preserve the order in this file.

The next step of compilation is to read the .add -file which defines some operators and the built-in predicates. This file lets one redefine standard built-in predicates, or define new ones.

After that is the compilation of the 'very program', that is contained in the .pro or .spj -file (the difference is that .spj -file contains some settings, but the .pro -file uses the settings of the default project),

A Strawberry Prolog program must contain a .pro -file (or .spj or .txt -file). If any of the others is missing, a corresponding standard file is used in its place. These files all have the name Standard and the corresponding extensions:

Standard.def The file containing the standard reserved words.

Standard.add The file containing the declarations of the standard built-in predicates.


examples

Strawberry Prolog examples

Here you can find additional information about some examples which need additional explanation.

Applications

Lisp A simple Lisp interpreter
Base Database for a spare parts shop
Draw Menus, drawing and file operations
E-mail E-mail generator
Hanoi Towers of Hanoi

Simple demonstrations

Edit edit control demo
Sun basic drawing functions
Speed speed test
Cursor shows change of window cursor
Study demonstrates a read dialog box and assert_in
OLE demonstration of OLE Automation
Graphic demonstration graphical predicates


What is specific in the syntax

What is specific in Strawberry Prolog syntax?

This compiler supports all the features of the standard (or will support them soon) but also gives many possibilities which you have not with another Prolog compiler. Our philosophy was to give you maximal freedom and let you do as you like best. There is another philosophy, which says that if one's hands are tied, mistakes will be fewer. We do not share this thesis, and made an extension of the language which allow many constructions which other Prolog compilers would understand as syntax errors.

Here are the differences:

Operators

In Strawberry Prolog you cannot put operators in apostrophes. When one operator is in apostrophes then it will be accepted as an atom not as an operator. So, you cannot have an operator like 'A' because this atom cannot be written without apostrophes. So if you write a '+' b or +(a,b) then this will give a syntax error. The correct will be a + b and '+'(a,b) respectively. Notice that if you want to use the prefix notation then you should to put the operator in apostrophes because +(a,b) is syntax error (i.e. it is the same as + (a,b) or the space between the operator and the bracket is not important). Anyway the space between the term and the bracket is important and '+'(a,b) is not the same as '+' (a,b).

Lists and functors

In the Standard, you can write a list using square brackets '[' and ']'. For example:
[] - the empty list.
[a, b, c] - list of elements a, b, c .
[X|Y] - list with head X and tail Y .
[a, b | T] - list beginning with elements a, b and tail T .

In Strawberry Prolog you can write every of the above lists. You can write even a list like:
[ | T] - list beginning with nothing, its tail being T , same as T . Of course, this is an absolutely useless extension.

In the Standard you can write a functor with arguments like this:
f( a, b, c) .

In Strawberry Prolog you have a functor and a list of arguments. This means that you can type between ( and ) everything you can type between [ and ] . For example:
f() - f with an empty list of arguments.
f( a, b | T) - f with its argument list beginning with elements a, b and tail T .
f( | T) - f with T as its argument list.

The place of the functor can be occupied by a variable too:
X( a) - functor X (variable) with argument a .
X( | Y) - functor X (variable) with list of arguments Y (variable).

This makes extremely easy to define the operator =.. in Strawberry Prolog. Here is the definition:
X(|Y)=..[X|Y].

Remark: You must have no space between the functor and the ( . This is so both here and in the Standard.

Atoms

In Strawberry Prolog the atoms are represented as chain of constants. For example:
abc is equivalent to like_atom(a, like_atom(b , c)).

The functor like_atom is special built-in functor which do the internal representation of the atoms. You don't need to use like_atom functor unless you want to make some strange pattern (unification condition) like these:
like_atom(a, like_atom(_, c)) - which will be unifiable with every atom of three characters, the first one being a , and last one c .
like_atom(_, bc) - which will be unifiable with every atom of three characters that ends with bc .
like_atom(a, like_atom(b, _)) - which will be unifiable with every atom of three or more characters that starts with ab .

Unfortunately, you can not write a pattern that is unifiable with all the atoms with some given end.

As an example, try running the program:
?- X=c, write( like_atom(a, like_atom(b, X)) ).

Change X=c
with X=[c] , X=f(c)
and X=cd .

Internal functors

In Strawberry Prolog there are three internal functors:
like_atom(Constant, Atom), Functor( | List_of_Arguments) and [Head | Tail].

Is it possible to write a term where the functor is not an atom? For example [a](b,c). This strange construction will give you a syntax error but you still can make such a term in this way:
like_functor([a], [b,c]) or F=[a], F(b,c). The second variant is simpler but it is not a syntax construction. Anyway this is the way you can construct such term in the time of program execution.

So, in Strawberry Prolog you can use the built-in functors like_atom and like_functor in order to construct some strange terms. Also the system uses these functors in order to write these strange terms which your program accidentally constructed.

We have also one built-in constant which we use for similar purposes. This constant is like_set_const and we use it for constructions of the type: {a, b, c}. For example the empty set {} will be represented as like_functor(like_set_const, []) or as F=like_set_const, F().


Define functions and predicates

Define functions and Built-in predicates

In Strawberry Prolog you have the unique possibility to define your own functions and built-in predicates. Here you can normally ask the question: What is the difference between standard Prolog predicates and built-in predicates. Usually in the most Prolog compilers built-in predicates are called to such predicates you cannot define alone and that is why they are defined in the system. In Strawberry Prolog the situation is different, you can define your own built-in predicates. So what is the difference between built-in and standard predicates? You define built-in predicates with fixed types and fixed number of the arguments. When these predicates are executed then the types and the number of the arguments are checked and if it is not correct then an error message is displayed. Also, in the built-in predicates you can give an expression as an argument. This expression will be calculated before execution of the built-in predicate, then the predicate will be executed and the value of the expression will be given to it on the place of respective argument.

Maybe you are a little bit disappointed by such built-in predicates because you expected that they are written in another language like C and also that they are hidden somewhere in the system and you cannot see their definition. It doesn't matter that your predicate is built-in or not, if you want to make it written in C or in another language then you can do this and put it in a DLL file or in OLE server. After that you can call such a function from Strawberry Prolog. If you want to hide your predicate's definition then you can put it in Standard.add file or you can create your own ADD file to contain your built-in predicates and other often used by you Prolog source.

Well, but how to define functions and Built-in predicates in Strawberry Prolog. Here is how such definitions look like:

R is f(X1, X2, ... , Xn) :- G1, G2, ... , Gm.
*** p(X1, X2, ... , Xn) :- G1, G2, ... , Gm.

Where Xi is variable with some specifiers eventually. Here is the list of all possible types specifiers which you can use in the definition of functions and of built-in predicates:

int X - integer
float X - floating point number
str X - string
obj(X) - object
var(X) - variable
term(X) - term, i.e. no one from the above
io(X) - used for input and output
num(X) - the same as int float X
X - the same as int float str obj(var(term(X))) , i.e. calculate and don't check the type
nocalc(X) - this means that this argument should not be calculated and will be given as a term as this is with the standard Prolog predicates.

The first three specifiers are defined as prefix operators and that's why they don't need brackets. You can define one argument using several specifiers. In this case the meaning is OR, i.e. the value must be one of the specified types. The row and repetition of specifiers are not important, i.e int float X is the same as float int X or even int int float X . You cannot combine the specifier nocalc with any of the rest.

As you can see the definition of built-in predicate is the same as the definition of the standard one with the difference that you have to put the key word *** and the arguments cannot be any terms like this is in the standard predicates but they must be only variables, eventually with some specifiers. You can define one built-in predicate (or function) with more than one clause as with standard predicates but in this case in all definition clauses the number of variables (in the head) and all specifiers must be the same. For example:

*** p(X1, X2, ... , Xn) :- body_1.
.
.
.
*** p(X1, X2, ... , Xn) :- body_m.

Here if the first body fails the compiler will try to satisfy the next one and so on.

Let's see an example for defining of function and for built-in predicate:

R is add(X, Y) :- R:=X+Y.
*** my_write(X) :- beep, writeq(X), nl.

What we have defined? The new function add is actually the same as the + function which we already have. You can put it in expressions and it will calculate the expressions X and Y and after that will execute the body of the function where it will calculate the value of R. The only small difference between add and + is that the first will accept any kind of expressions for X and Y with the difference of + which accepts only integer, float and string values for them. This means that you can give two variables or terms for X and Y and add will accept them. Anyway, when the execution of the body of add starts you will receive an error message from the function + . This message will say that the arguments of + cannot be variables or terms but you will not get such a message for the function add .

If you want then you can make a type check in the add function. Let's say that we want to check whether their arguments are integer or float. Then we can define add as follows:

R is add(int float X, int float Y) :- R:=X+Y.

Now our add function is like + but only for integer and float numbers. If we try to concatenate strings with it then we will receive an error message which says that the arguments can not be strings.

The built-in predicate my_write is the same as write predicate (only one beep and one new line are small differences). If we call my_write(2+2) in our program then what will be written in the Output window? Will it be 4 as if we call write or will it be 2+2 as if we call writeq . The predicate my_write will write 4 although we use writeq in its body because the expression will be calculated before the execution of the body. If we want to make my_write like writeq then we should define it as follows:

*** my_write(nocalc(X)) :- beep, writeq(X), nl.

When defining functions and built-in predicates you can use also the operator :-- instead of :- . What is the difference? After the compilation all clauses which have the same heads are represented as a chain. Every one has a pointer to the next. So, when the program is executed if the first clause from the chain fails then the interpreter takes the next one. If you define a clause using :-- instead of :- then this clause will have a chain pointer to itself. This mean that this clause will be recalled forever (the same as if this clause was infinitely many times in the program). For example by :-- is defined the predicate repeat.

For examples of functions defined on Prolog is a good idea to look at Strawberry functions . Their definitions are in the Standard.add file.


Define and use arrays

In Strawberry Prolog you can define and use arrays as easy as in procedure languages. To define an array use the built-in predicate array. This predicate has three arguments:

array( Name, StartSize, Init )

The name can be any Prolog atom which will be used as a name of your array. Of course, you cannot use this atom as a name for other array or object. The StartSize argument has to be integer showing the size of this array at its creation. The type of the array elements will be the type of Init argument. All elements of this array will be initialized with the value of Init argument.

After defining your array you can easily use it by including in the expressions members of the type of my_array( N ) , where my_array is the atom which you choose for name of your array and N is integer expression which gives the number of the element you need. The value of N must be bigger or equal to zero and less than the size of the array, i.e. the first element of the array has index 0.

If you want to change the value of any element of the array then simply write:

my_array( N ) := V

where N is the number of the element which value you want to change and V is the new value which you want to give to this element. The creation of array and change of its elements will be stable on backtracking.

?-
array(my_array, 10, 0),
my_array(5):=13,
write(my_array(2+3)).


Global Varables

Global Variables

These are variables which are visible in the whole program, not in one clause only. Syntactically these are the variables which begin with G_.

Global variables are very convenient as illustrated in the examples. Certainly you can do without them (when you need a value somewhere in the program, then you can assert it or you can get it passing it from clause to clause as an extra argument). In 90% of the cases by global variables and by := (evaluation resistant on backtracking) you can avoid the use of assert and make your program more readable..


CGI Scripts

Strawberry Prolog CGI Scripts
(ONLY for the Professional edition)

If you want to change one static web site and to put some active content in it then you need CGI Script . Here are some typical applications of CGI Scripts , which you can see in our site made as Strawberry Prolog CGI Scripts (you can find the source of these applications in the professional edition in Prolog CGI folder):

If you like to put a registration form.
If you like to recognize your users (by cookie) and to call them by name in their own language.
If you like to visualize some automatically changeable information (like the number of the registered users)
If you like to make search in a database (of registered users for example).
If you like to put a game in your site and to give the possibility to everyone to play it through the web.
If you like to make a chat room in your site.

It is impossible to make a good site without using this technology. Of course, you can use CGI Scripts which are not made specially for your site (like counters of the page visitors). Also you can pay to a professional programmer to write the CGI Scripts which you need. All this is possible but our advice will be to make alone all the functionality which you need as Strawberry Prolog CGI Scripts . This will be an easy and pleasant work. Another possibility is to use Perl but it is easier to study Prolog than Perl and it is much easier to write a program on Prolog than on Perl.

Here is your Strawberry Prolog CGI Scripts guide which will help you to make the functionality for your site. First you need to understand what is CGI Script and how it works.

A CGI Script is a program which resides on the Web Server usually in cgi-bin directory and when the script is invoked e.g. the user has made a request which contains a CGI executable (for example http://host/cgi-bin/myCGI.pro) then the Web Server executes the program and connects its output to the user's input, so everything that the CGI will print on its standard output will be sent to the user.

Simple CGI Script :

?- set_content_type("text/html"),
write("Hello New User").

First predicate sets the content type of the page to "text/html" and in this way notifies the browser that the type of the following content will be text or html and the browser will parse it if necessary and will show it to the corresponding user. The second predicate prints into the standard output "Hello New User" so the browser will receive a page containing only that string (the result will be the same if you create a text file containing only the string " Hello New User " and try to view it through a web browser).

SUMMARY: To make a web page viewable through a Strawberry PrologCGI Scriptyou should create a file ( myCGI.pro ) and place it into the cgi-bin directory of your Web Server that contains the following:

#!./strawberry

?- set_content_type("text/html"),
write("
<put your page source here>
").

The first row of the file tells the operating system that it should pass the file as an argument to the Strawberry Prolog compiler. Page source can be in text or in HTML format. This text will be the output of your CGI Script . Of course, in this simple example the page source is static and this active page will look the same as the passive one which contains only the Page source.

IMPORTANT: In your "page source " you should replace every quotation mark with double quotation mark and every percentage mark with double percentage mark ( " -> "" and % -> %% )

Passing arguments to a CGI Script

Usually when you call CGI Script then you pass some arguments to it. For example you may want to call one CGI Script with different arguments. You can put these arguments just after the name of the program separated with a question mark. For example:

http://host/cgi-bin/myCGI.pro?name=John&password=test

in this way your CGI will receive the arguments' name with a value of "John" and password with value " test ". To get the parameters, you should use the getenv and get_html_form functions:

Query is getenv("QUERY_STRING"),
Name is get_html_form(_, "name", Query).

The Query variable will contain " name=John&password=test " and the Name variable will contain "John".

There are two ways to pass an argument to a CGI Script. The first which we described above is the GET method. In this method the arguments are visible in the address and their length is restricted up to 256 symbols. The second method for passing arguments is the POST method. By this method the fields in the HTML forms are passed.

When you submit a form then the content of the fields is passed as arguments to the CGI Script which is attached to this form. To get the arguments from a POSTmethod use the following:

Query is getenv(post),

If there are two fields in your form with the names: name and password then and if the user (web visitor) fills in these fields John and test respectively then the CGI Script which is attached to this form will receive query " name=John&password=test " and that will be the value which will receive the Query variable.

Converting a Strawberry Prolog program into a CGI Script

Suppose you have written a Strawberry Prologgame and want to place it on a Web Server, in this way many people can see it and play it. The first thing you should do is to make the layout (the " look and feel ", the HTML page) of your game. To achieve this you can use your favorite HTML Editor. Let's take for example the Tick-Tack-Toe game (take a look on it in our site). It is 3x3 table, you put " X " and the computer puts " O ", whoever makes three in a row, column or a diagonal wins. The game opens a new window with nine squares on a table. So the first thing you have to think of is to create a table (with your HTML Editor) and to put nine (blank) images in it. (Maybe you will need some GIF images too.) The next step is to remove all predicates (from the Windows game) which open (manipulate) windows, listen for the mouse click etc. You have to leave only the core of the game (the part that chooses the right move according to the position). As a Windows game your program was multi-step program (you play and the game receives your move and then it plays its next move). To make it run as a CGI Script you have to make it a single-step program (each time you have to pass the current position of the game to the CGI program together with your move and it has to return the next situation). You can keep the current position in a list for example [[f,f,f], [f,f,f], [f,f,f]] - nine empty squares, or [[x,o,x], [f,f,f], [f,f,f]] - X,O,X on the first row. You can pass this list each time you make a new move:

http://some/host/cgi-bin/Tick-Tack-Toe.pro?pos=[[f,f,f],[f,f,f],[f,f,f]]&x=1&y=2

In this way you will tell the program what is the current position (empty table) and what is your move. The program should examine the position, to choose the right move and return the HTML page to the user. According to the new position (achieved after the move) the CGI should change the images on the new HTML page. This means that it should return your HTML page but modified. In the new HTML some of the blank images should be changed with images of X and O. Also in this new HTML each blank image has to have a link to the same CGI Script with arguments the new current position and the coordinates of the cell.

In this way the game goes on. When you press on one blank image then you say to the CGI Script what is the current position and what is your move. CGI Script starts, calculates its answer, sends it to you as a HTML page. After answering the CGI Script stops and forgets about you. Of course, you can cheat the program by changing the position in the URL to [[x,x,x],[f,f,f],[f,f,f]] - which will mean that you win! That is because this CGI Script doesn't know who are you and it believes the information which you send to it. It can be done in a different way and to remember the current position but in this case it needs to support a database of all users playing the game at the moment (they can be a lot) and to recognize them (by cookie or by their IP addresses).

Your CGI program should be something like the following:

#!/path/to/the/cgi-bin/strawberry

?-
Query is getenv("QUERY_STRING"),
Pos is get_html_form(_, "pos", Query),
X is scan(get_html_form(_, "x", Query)),
Y is scan(get_html_form(_, "y", Query)),
List is scan(Pos),
choose(NewPos, List, X, Y),
view(NewPos).

choose(NewPos, OldPos, X, Y) :-
<some game logic here> .

view(NewPos) :-
set_content_type("text/html"),
write("
<your HTML page source here modified by NewPos >
").

Tracing Prolog CGI Scripts

CGI Scripts are programs which run on the server and that makes their tracing difficult. Strawberry Prolog gives you the opportunity to create and trace Prolog CGI Scripts in the Strawberry Environment and to install them on your sever only after they are ready.

When you start a CGI Script in the Strawberry Environment then it prints your web page in the Output window in HTML format. If you know HTML format that can be enough to see if your program works correctly or not. An easier way to see the result of the program is to look on it through your web browser.

How to do this?

1. Save Output window as HTML file (Press Save As when Output is active. Give html extension to the new file).
2. Open with your web browser the file that you have just created.

Now you can start tracing.
1. Clear all in the Output window (Select all and delete).
2. Run your program.
3. Delete the Yes which is at the end of the Output and eventually Compiling the file ... which is in the beginning of it.
4. Save the Output file
5. Go in your web browser and press the refresh button.

In this way you can easily trace your CGI Script . Anyway you can have some problems with the paths of the images which are included in the resulting HTML page. This paths can force you to make small changes to your program before to put it on the server. One possible decision to avoid this problem is to make two folders on your hard disk (and the same on your server). First folder called cgi-bin and the second one called Images . Save the Output in the first folder and put the images which you need in the second one. In this case the path for images will be: "../Images/".

See also:
url_encode


Develop AI

How to develop AI

AI is the main goal in Strawberry Prolog development. If you want to know more about our work in this direction then first you have to read our Definition of AI. After that go to AI folder where you will find two artificial worlds. Try to understand these worlds alone. This is important because these worlds are intelligence tests which we will use to distinguish AI from other programs. It is important for you to know how difficult are these tests.

When you finish with this preparation then you can look at the programs which pretend to be AI (they are in the same folder). Actually this programs do not cover the definition of AI because they cannot cope well even in these simple example worlds and we cannot hope that they will cope well in arbitrary world. Anyway we think that this programs are not so far from AI as it looks like.

We will give a free license of Strawberry Prolog professional edition to anyone who offers an essential improvement to the program AI 2. Actually, this means that we offer prize for the inventor of AI which is software of value estimated at $249 USD. Of course, this seems to be too small prize for such a great discovery but the reason for such stinginess is our believe that it is better if AI will never be invented.

Maybe you will be surprised by the fact that we continue to develop AI despite this believe. The reason is our conviction that the creation of AI is something unavoidable. Really, AI will decide some smaller problems like terrorism and global worming but AI will be a much bigger disaster than this problems. Now we are in the situation of the citizens of Hiroshima sixty years ago who couldn't imagine that one invention would change dramatically their lives in a few years. AI will change dramatically your life (I mean your life, not your children's or grandchildren's life). AI will affect all the humanity despite the nuclear weapons which changed the life mainly of the citizens of Hiroshima. AI is worse than the nuclear bomb because many think that it is something good but all know that the bomb is a bad thing.

This is not the next science fiction about the revolt of robots. The reason for the disaster is much simpler and it is that we will lose the need to think and to work. Maybe at the moment you do not see any danger of this. Actually, everyone dreams to become a millionaire and to stop work until the end of their life. Anyway, this will be the end of the evolution but not our end. We will continue to live but our life will be extremely boring.

The idea to make an artificial man is very old and beautiful one. The question is what we will do with the real people which we have enough. Really, the artificial man will be better than the real but this is more disadvantage than advantage.

After all this arguments maybe your enthusiasm to create AI has decreased but you cannot stop the progress and for you it will be better if you invent AI instead of someone else.

Look at the predicates for direct database manipulation which are very useful for AI applications.


Call Strawberry Prolog as OLE server

Call Strawberry Prolog as OLE server from outside

Strawberry Prolog is an OLE server and this give you the possibility to embed it in projects which are made on different language like Visual Basic or Python. Of course, you can call this server also from Strawberry Prolog.

Like a demonstration of this possibilities try the programs which are in the folder OLE / Servers. These programs demonstrate the use of Strawberry Prolog as OLE server. Actually these programs are OLE clients and OLE servers. The Server Name of Strawberry Prolog is "Strawberry.Server.1". You can use the function server in order to open SP as server from SP client program.

In order to start the server program the client has to put the program path in the program property and after this to call the method compile. When this is ready the client can use the method call in order to start evaluation of a predicate but before to call the method call the properties predicate and arguments has to be filled. The predicate must to be the name of one argument predicate from the server program. The property arguments is actually the only argument of the predicate but this argument can be a list of arguments.

If the client wants to receive a return value then the server has to put it in the G_Return variable (this global variable is defined in the ADD file). After that the client can obtain it by the property result. This property is of the type VARIANT and can contain integer, float, string or boolean (true or false) value. If you give to the variable G_Return a term then the property result will return the string in which this term is printed.

If the server program wants to raise an event to its client (i.e. to send some information back to the client) then it has to use the predicate raise_event.

If the client program wants to listen for events from the server then it has to provide a function (class) which will process these events. In order to do this with SP client, open the server with server2 function. The only event which SP server can send to its client is created by the predicate raise_event

You need the Professional edition to call Strawberry Prolog as OLE server. Actually all methods and properties exist also in the Middle and in the Light edition but in this editions the method compile works only with EXE files. This means that the server program has first to be compiled with the professional edition.

See also:
OLE and ActiveX
server
server2
raise_event
. (point)

Examples:
OLE / Servers


Work with databases through ODBC

You can use ODBC is order to work with databases. The support of ODBC is made through OLE server "ADODB.Connection". To see how it works go to the folder OLE and look at the samples db_read.pro, db_insert.pro and db_delete.pro. You will see how you can change the database source without any significant change in your program.

Yet another possibility to work with databases is the support of MySQL.

See also:
MySQL
OLE and ActiveX

Examples:
OLE / db_read.pro
OLE / db_insert.pro
OLE / db_delete.pro


File menu commands

The following commands are available through the File submenu:
New | Creates a new document. It is advisable to immediately 'Save as' the document in order to give it a name.
Open | Opens an existing document.
Open Example | The same as open but starts from the Strawberry Prolog folder.
Close | Closes an opened document.
Save | Saves an open document using the same file name.
Save As | Saves an open document to a specified file name.
Print | Prints a document.
Print Preview | Displays the document on the screen as it would appear when printed.
Print Setup | Selects a printer and a printer connection.
1, 2, ... | Opens directly the file whose name appears after the number (these files are the last four files saved).
Exit | Exits Strawberry Prolog.


Edit menu commands

The Edit submenu gives access to the following commands:
Undo | Undoes the latest editing operation, whenever possible.
Cut | Deletes data from the document and moves it to the clipboard.
Copy | Copies data from the document to the clipboard.
Paste | Pastes data from the clipboard into the document.
Paste special... | Pastes OLE data from the clipboard (OLE technology).
Select All | Select all the text in the current text window.
Find... | Opens the Find dialog box, to look for a specified string into the current window.
Find Next | Finds next occurrence (as stated in the Find dialog box). It works only if the Find dialog box has been closed.
Replace | Opens the Replace dialog box, to look for a specified string into the current window and replace it.
Insert New Object | Opens the Insert Object dialog window.
Links | Opens the Links Dialog Box (available only if you have links into your current file).
Object Properties | Displays the object properties, that depend on your computer and on the object itself.
Object <Name> | It comes directly from your computer system.


Run Menu commands

Run Menu

The Run submenu gives access to the following commands:
Compile | Compiles the program in the active window.
Run | Starts the program in the active window.
Next Answer | Makes an attempt to find next answer to the entry goal.
Loop check | Not implemented yet.


Trace Menu commands

Trace Menu

Trace menu gives access to the following commands:
First Step | Makes an initial step in answering the 'main' question.
From Next | Enables tracing to continue after answering the 'main' question once to obtain more answers.
One Step | Makes a step in executing the current goal
Step Over | Tries to satisfy the current goal without stopping to display subgoals and their working, i.e. as if it were a primitive one.
Go | Continues execution just like that of already bug-free Prolog source, i.e. without displaying current states any longer.
Trace | Breaks the program and starts tracing
Terminate | Terminates the program execution (and tracing mode as well).
Back 10 steps | Not implemented yet.
Break Point | Opens the Break Point window.
Proof Tree | Opens the Proof Tree window.


Options Menu commands

Options Menu

The Options menu offers the following commands:
Toolbar | Shows or hides the toolbar.
Status Bar | Shows or hides the status bar.
Environment | Opens the Environment dialog box.
Project | Opens the Project dialog box.
Default Project | Opens the Default Project dialog box.


Tools menu commands

The Tools submenu gives access to the following commands:
Stack window | Opens the Stack Window
Variables window | Opens the Variables Window
System List | Opens the System List Window which contains the whole Prolog database


Window Manu commands

Window menu commands

The Window submenu offers the following commands, which enable you to arrange multiple views of multiple documents in the application window:
Tile | Divides vertically the screen among the text windows currently open.
TileHorizontally | Divides horizontally the screen among the text windows currently open.
Cascade | Arranges windows so that their captions can be seen.
Arrange Icons | Arranges the icons that stand for minimized windows.
Window 1, 2, ... | Goes to a specified window.


Help menu commands

The Help menu offers the following commands to assist you using Strawberry Prolog:
Help | Shows the main index of the Help File
Contents | Shows the help contents window.
Operators | Opens the Operators window
ADD File | Opens a text window that shows the Standard.add file
About Strawberry Prolog... | Displays the version number of this application.


About the author

Name: Dimiter Dimitrov Dobrev

Sofia, Bulgaria
Telephone: +(359) (2) 979 2862
E-mail: dobrev@2-box.com

This program is made with the help of:
Angel Genov
Anton Zinoviev
Antonio Maschio
Borislav Rizov
Dimiter Georgiev
Dimitar Guelev
Plamen Sharapanov
Radoslav Nikolov
artist Konstantin Lakov

Special thanks for the support to
Prof. Dimiter Skordev


(File Open dialog box)

The following options allow you to specify which file to open:

File Name

Specifies the file you want to open. This box lists files with the extension you select in the List Files of Type field.

List Files of Type

Specifies the type of file you want to open:

Drives

Specifies the drive in which Strawberry Prolog stores the file that you want to open.

Directories

Specifies the directory in which Strawberry Prolog stores the file that you want to open.

Network

Click this button to connect to a network location, assigning it a new drive letter.


(File Save As dialog box)

The following options allow you to specify the name and location of the file you're about to save:

File Name

Specifies a file name to save a document with a different name. Strawberry Prolog adds the extension you specify in the Save File As Type box.

Drives

Specifies the drive in which you want to store the document.

Directories

Specifies the directory in which you want to store the document.

Network

Click this button to connect to a network location, assigning it a new drive letter.


(Print dialog box)

The following options allow you to specify how the document should be printed:

Printer

Displays the active printer and printer connection. Choose the Setup option to change the printer and printer connection.

Setup

Displays a Print Setup dialog box, so you can select a printer and printer connection.

Print Range

Specifies the pages you want to print:

All | Prints the entire document.
Selection | Prints the currently selected text.
Pages | Prints the range of pages you specify in the From and To fields.

Copies

Specifies the number of copies you want to print for the above page range.

Collate Copies

Prints copies in page number order, instead of separated multiple copies of each page.

Print Quality

Specifies the quality of the printing. Generally, lower quality printing takes less time to produce.


(Print Progress Dialog)

The Printing dialog box is shown during the time that Strawberry Prolog is sending output to the printer. The page number indicates the progress of the printing.

To abort printing, choose Cancel.


(Print Setup dialog box)

The following options allow you to select the destination printer and its connection.

Printer

Specifies the printer you want to use. Choose the default printer, or choose the Specific Printer option and select one of the current installed printers shown in the box. You install printers and configure ports using Control Panel.

Orientation

Specifies Portrait or Landscape.

Paper Size

Specifies the size of paper that the document is to be printed on.

Paper Source

Specifies the paper source, because some printers offer multiple trays for different paper sources.

Options

Displays a dialog box where you can make additional choices about printing, specific to the type of printer you have selected.

Network

Click this button to connect to a network location, assigning it a new drive letter.


(No Help Available)

No help is available for this message box.


(Docking Toolbar Area)

This area is provided to contain dockable toolbars, such as the default toolbar created for the application. Docking toolbars can be dragged onto or off this client area, and arrange themselves according to the space available.


(print preview toolbar)

The print preview toolbar offers you the following options:

Print

Opens the Print dialog box to start a print job.

Next Page

Previews the next printed page.

Prev Page

Previews the previous printed page.

One Page / Two Page

Previews one or two printed pages at a time.

Zoom In

Takes a closer look at the printed page.

Zoom Out

Takes a larger look at the printed page.

Close

Returns from print preview to the editing window.


(About command (Help menu))

Use this command to display the copyright notice and version number of your copy of Strawberry Prolog.


(File Exit command)

Exit command (File menu)

Use this command to end your Strawberry Prolog session. You can also use the Close command on the application Control menu. Strawberry Prolog prompts you to save documents with unsaved changes.


(Help Using Help Command)

Context Help command

Use this command to obtain help on some portion of Strawberry Prolog . When you choose the toolbar's Context Help button, the mouse pointer will change to an arrow and question mark. Then click somewhere in the Strawberry Prolog window, such as another toolbar button. The help topic will be shown for the item you clicked.


(Undo/Can't Undo command (Edit menu))

Use this command to reverse the last editing action, if possible.


(File 1, 2, 3, 4 command)

1, 2, 3, 4 command (File menu)

Use the numbers and filenames listed at the bottom of the File menu to open the last seven documents you closed. Choose the number that corresponds with the document you want to open.


(File Print command)

Print command (File menu)

Use this command to print a document. This command presents a Print dialog box, where you may specify the range of pages to be printed, the number of copies, the destination printer, and other printer setup options.


Print Preview command

Print Preview command (File menu)

Use this command to display the active document as it would appear when printed. When you choose this command, the main window will be replaced with a print preview window in which one or two pages will be displayed in their printed format. The print preview toolbar offers you options to view either one or two pages at a time; move back and forth through the document; zoom in and out of pages; and initiate a print job.


(File Print Setup command)

Print Setup command (File menu)

Use this command to select a printer and a printer connection. This command presents a Print Setup dialog box, where you specify the printer and its connection.


(Send command (File menu))

Use this command to send the active document through e-mail. This command presents a mail window with the active document attached to it. You may then fill out the To field, Subject field, and so on, and add text to the body of the message. When you are finished, you can click the Send button to send the message.


(Index command (Help menu))

Use this command to display the opening screen of help. From the opening screen, you can jump to step-by-step instructions for using Strawberry Prolog and various types of reference information.

Once you open help, you can click the Contents button whenever you want to return to the opening screen.


(Using Help command (Help menu))

Use this command for instructions about using help.


(No Help Available)

No help is available for this area of the window.


(Edit Links command)

Links command (Edit menu)

Use this command to display a Links dialog box which lets you edit links between your document and other documents.

This command is unavailable if you have no links in your document.


(Insert Object command)

Insert New Object command (Edit menu)

Inserts and embeds an object, such as a chart or an equation in a document. The application in which the object was created becomes active on the screen.

Select the object you want to insert into your document using the Insert New Object dialog box.


(Close command (Control menus))

Use this command to close the active window or dialog box.

Double-clicking a Control menu box is the same as choosing the Close command.

Note: If you have multiple windows open for a single document, the Close command on the document Control menu closes only one window at a time. You can close all windows at once with the Close command on the File menu.


(Maximize command (System menu))

Use this command to enlarge the active window to fill the available space.


(System Minimize Command)

Minimize command (application Control menu)

Use this command to reduce the Strawberry Prolog window to an icon.


(Move command (Control menu))

Use this command to display a four-headed arrow so you can move the active window or dialog box with the arrow keys.

Note: This command is unavailable if you maximize the window.


(Next Window command (document Control menu))

Use this command to switch to the next open document window. Strawberry Prolog determines which window is next according to the order in which you opened the windows.


(Previous Window command (document Control menu))

Use this command to switch to the previous open document window. Strawberry Prolog determines which window is previous according to the order in which you opened the windows.


(Restore command (Control menu))

Use this command to return the active window to its size and position before you chose the Maximize or Minimize command.


(Size command (System menu))

Use this command to display a four-headed arrow so you can size the active window with the arrow keys.

After the pointer changes to the four-headed arrow:

1.Press one of the direction keys (left, right, up, or down arrow key) to move the pointer to the border you want to move.

2.Press a direction key to move the border.

3.Press ENTER when the window is the size you want.

Note: This command is unavailable if you maximize the window.


(Switch to command (application Control menu))

Use this command to display a list of all open applications. Use this task List to switch to or close an application on the list.

Dialog Box Options

When you choose the Switch To command, you will be presented with a dialog box with the following options:

Task List

Specifies the application you want to switch to or close.

Switch To

Makes the selected application active.

End Task

Closes the selected application.

Cancel

Closes the Task List box.

Cascade

Arranges open applications so they overlap and you can see each title bar. This option does not affect applications reduced to icons.

Tile

Arranges open applications into windows that do not overlap. This option does not affect applications reduced to icons.

Arrange Icons

Arranges the icons of all minimized applications across the bottom of the screen.


(1, 2, ... command (Window menu))

Strawberry Prolog displays a list of currently open document windows at the bottom of the Window menu. A checkmark appears in front of the document name of the active window. Choose a document from this list to make its window active.


(Window Arrange Icons Command)

Use this command to arrange the icons for minimized windows at the bottom of the main window. If there is an open document window at the bottom of the main window, then some or all of the icons may not be visible because they will be underneath this d ocument window.


(Cascade command (Window menu))

Use this command to arrange multiple opened windows in an overlapped fashion.


(New command (Window menu))

Use this command to open a new window with the same contents as the active window. You can open multiple document windows to display different parts or views of a document at the same time. If you change the contents in one window, all other windows containing the same document reflect those changes. When you open a new window, it becomes the active window and is displayed on top of all other open windows.


(Tile command (Window menu))

Use this command to arrange multiple opened windows in a nonoverlapped fashion.


(Tile Horizontal command (Window menu))

Use this command to vertically arrange multiple opened windows in a nonoverlapped fashion.


(Tile Vertical command (Window menu))

Use this command to arrange multiple opened windows side by side.


(Scroll bars)

Displayed at the right and bottom edges of the document window. The scroll boxes inside the scrollbars indicate your vertical and horizontal location in the document. You can use the mouse to scroll to other parts of the document.


Copy command (Edit menu)

Use this command to copy selected data onto the clipboard. This command is unavailable if there is no data currently selected.

Copying data to the clipboard replaces the contents previously stored there.

Shortcuts

Toolbar:

Keys: CTRL+C


Cut command (Edit menu)

Use this command to remove the currently selected data from the document and put it on the clipboard. This command is unavailable if there is no data currently selected.

Cutting data to the clipboard replaces the contents previously stored there.

Shortcuts

Toolbar:

Keys: CTRL+X


Environment window

Environment dialog box

Manager

'Next' is always active
When checked, makes the Run|Next Answer (F8) command always available. This means that if no answer is received (or we received no) F8 will work like Run (F5) . Use this option to customize your keys.

'One Step' is always active
When checked, makes the Trace|One Step (F9) command always available. This means that if no steps are made F9 will work like First Step (Ctrl+F5). Use this option to customize your keys.

Automatic Words Selection This is an option of the editor. If it is set on then the mouse selection takes words only. It is difficult to start the selection from the middle of the word in this case.

Change Information Font
Opens the characters dialog window to change the font for the Information windows (the Stack window, the Variables window and the System List window of the Tool menu).

View

Large Tool Bar (appears after restart) Makes toolbar buttons large. To change this option you need to restart the Prolog Compiler.

Tool Bar is Active on Start
This changes the behavior of the tool bar on start (visible or invisible).

Status Bar is Active on Start
This changes the behavior of the status bar on start (visible or invisible).

Splash on Start
This enables the splash window at the start of the compiler. Splash window is the red square which appears for two seconds when the compiler is starting.

Proof Tree Always at the Top
This makes the Proof Tree a top-up window. It will be visible even when it is not active. If you use this option then hide the Proof Tree window by minimizing it and activate by F12 .

Automatic Scroll in Proof Tree
When you double click in the Proof Tree then you change the way it looks. In this case automatic scroll will help you because it scrolls the window but keeps the clicked subgoal static.

Syntax Color

In this page you can switch on and off the syntax coloring of the Strawberry Program Environment and you can change the colors which will be used for that.

If you don't like syntax coloring then switch off all check boxes in this page. The box "Syntax colors on file open" determine do you like the syntax coloring to be made automatically when file is opened and when it is compiled. The next two check boxes determine when you like the syntax coloring to be made in the processes of program writing. If you check "Refresh on every text change" then the syntax colors will be correct after every change but in this case the edit window can flash unpleasantly on every text change. The flashing will be stronger especially if the size of your program is bigger. If you want to avoid the flashing then check "Refresh when Enter is pressed" or even don't check any of this two boxes. In all cases you can force updating of syntax colors from the menu "Tools / Refresh Syntax Coloring (Ctrl T)".

In this window you can also change the default colors for syntax coloring and immediately to see the result of this change on the demo line. (If you don't like the result of the change then simply press the Cancel button.) To change the color of integers then select Integer in the left combo box. For quick selection you can click with the mouse on the demo line. When Integer is selected you can change its color by selecting a common color from the right combo box. If you need some exotic color which is not listed in the list then select Custom from the same list (it is on the end). When Custom is selected press the button "Change This Custom Color" and select your exotic color from the dialog box which will appear.

Other Colors

In this window you can change some colors which are used by the compiler. Click Set Default button to set all values to default. Use Change buttons to change any color. Output is the color of the output window; other colors are used in system windows like Proof Tree and Stack .


File 1, 2, 3, 4 command

1, 2, 3, ... command (File menu)

Use the numbers and filenames listed in the bottom of the File menu to open the latest six documents you closed. Choose the number that corresponds to the document you want to open.


File Close command

Close command (File menu)

Use this command to close all windows that contain the active document. Strawberry Prolog suggests you to save the changes made to your document before you close it. If you close a document without saving it, you lose all changes made since the last time you saved it. Before closing an untitled document, Strawberry Prolog displays the Save As dialog box to suggest you to name and save the document.

You can also close a document by using the Close icon on the document's window, as shown below:


File Exit command

Exit command (File menu)

Use this command to end your Strawberry Prolog session. You can also use the Close command on the application Control menu. Strawberry Prolog prompts you to save documents with unsaved changes.

Shortcuts

Mouse: Double-click the application's Control menu button.

Keys: ALT+F4


File New command

New command (File menu)

Use this command to create a new document in Strawberry Prolog. To open an existing one, use the Open command.

Shortcuts

Toolbar:

Keys: CTRL+N


File Open command

Open command (File menu)

Use this command to open an existing document in a new window. Several documents can be kept open simultaneously. Use the Window submenu, to select a document to edit, compile, or run. See Window 1, 2, ... command.

You can create new documents with the New command .

Shortcuts

Toolbar:

Keys: CTRL+O


File Print command

Print command (File menu)

Use this command to print a document. This command presents a Print dialog box , where you may specify the range of pages to be printed, the number of copies, the destination printer, and other printer setup options.

Shortcuts

Toolbar:

Keys: CTRL+P


File Print Preview command

Print Preview command (File menu)

Use this command to display the active document as it would appear when printed. When you choose this command, the main window will be replaced with a print preview window in which one or two pages will be displayed in their printed format. The print preview toolbar offers you options to view either one or two pages at a time; move back and forth through the document; zoom in and out of pages; and initiate a print job.


File Print Setup command

Print Setup command (File menu)

Use this command to select a printer and a printer connection. This command presents a Print Setup dialog box , where you specify the printer and its connection.


File Save As command

Save As command (File menu)

Use this command to save and name the active document. Strawberry Prolog displays the Save As dialog box so you can name your document.

To save a document with its existing name and directory, use the Save command .


File Save As dialog box

The following options allow you to specify the name and location of the file you're about to save:

Save in:
Select the drive and directory in which you want to store the document.

File Name:
Type a new filename and extension to save a document with a different name or in a different type.

Save as type:
Lets choose a file filter for the files you are seeing.

Moreover, other buttons are present, to ease your file treatment:
- Parent directory
- View desktop
- New folder
- List (shows files in a simple list)
- Details (shows files with all the details)


File Save command

Save command (File menu)

Use this command to save the active document under its current name and into its current directory. When you save a document for the first time, Strawberry Prolog displays the Save As dialog box so you can name your document. If you want to change name and directory of an existing document before you save it, choose the Save As command .

Shortcuts

Toolbar:

Keys: CTRL+S


Loop Check

This is a very important feature of Strawberry Prolog which we expect to be available one day.

The idea of Loop Checking is coming from the difference between declarational and procedural semantic of Prolog programs. When you write a program you think in declarational semantic. You think of the program like a set of axioms and rules and you want to obtain all answers which follow from them. Unfortunately, the Prolog Interpreter works in the procedural semantic and gives you only a part of the answers, after that it can fail in infinite loop. Our purpose is to give you the opportunity to write some declaratively correct, but procedurally incorrect programs. The loop checker will make them running correct in the declarative sense which you have put in them.

It is nice how the class of the programs which are working correctly (in the declarational sense) is maximally big. That is why we are searching for an effective algorithm which recognizes a big amount of cyclings in Prolog. The purpose is to add this algorithm to our Prolog interpreter. In this way we will obtain an interpreter of the language stronger than Prolog, because cycling in Prolog programs will work and give the expected answer.

The Loop Checker will be realized on the basis of the works of Professor Dimiter Skordev and those of the author which he made under the supervision of Professor Skordev. Users of Strawberry Prolog who are interested in this problem can read the implementor's master's thesis "Periodical Cyclings in Prolog", that is available on our web page.


Memory Options window

Settings of Project dialog box
You can set the settings of the current project (file with extension SPJ).

Default Project Settings
You can set the settings of all files with the extension PRO.

Settings

Fix First Random Number
Causes the system to generate the same pseudo-random number sequence every time. This is useful when debugging a program that use random numbers. Otherwise if the program displayed some suspicious behavior with some fixed random sequence, it possibly will not do so with another. When you play a game with random numbers this option have to be switched off. Otherwise in all games will be happening the same things.

Automatically Prolonged Stack
Enables the dynamic increasing of the stack.

Stack Full as Fail
Causes the Stack Full event to be regarded as a failure of the current goal, The use of this option can make the work of your program looking rather strange!

Use Default Memory
Use memory settings of the default project.

Use Default Font
Use font settings of the default project.

Change Window Font
Opens the characters dialog window to change the font of the text window of the project itself or to change the default window font.

Files

In this dialog box you can select files which you want to be compiled after the main program. Instead of adding files in this list you can use the directive include. Also you can change the default ADD and DEF files but be careful, after that the program may stop functioning correctly.

Break Point

Gives you the possibility to put a break point in your program and make it active or passive. This break point is on step number. This is one possibility, unique for Strawberry Prolog, that you do not have in other languages or other Prolog compilers. If you want to put a break point in the body of a clause then use the built-in predicate trace .

Memory

Size of the Stack The size of the goals stack.
Variables (in K) The total number of variables that can be allocated in K (X1024).
Linking Memory The size of Linking memory in Kb. (it is used in execution like the Stack).

Use SD buttons (Set Default) to set to default value. The start value is the value at the opening of the compiler. At the moment is the value of the current moment and Maximum is the value which cannot be exceeded.

EXE File

In this dialog you can select the attributes of the EXE file which will be generated from the project. You can choose its icon and its file name and location. Also you can add comments which will be included in the EXE file. You can choose do you like the ADD file to be included in the project. If you use the Standard.add and Standard.def files then you do not have to include it and in this way you can make the EXE file smaller.

CGI Scripts

When you debug a SGI Script in the Strawberry Prolog environment then you need to specify what it will receive with method Get and with method Post. Also if you want to debug a console program which takes its arguments from the command row then you have to specify this arguments. For more information look at Prolog CGI Scripts.


Paste command (Edit menu)

Use this command to insert a copy of the clipboard contents at the insertion point. This command is unavailable if the clipboard is empty.

Shortcuts

Toolbar:

Keys: CTRL+V


Print dialog box

The following options allow you to specify how the document should be printed:

Printer
This is the active printer and printer connection. Choose the Setup option to change the printer and printer connection.

Setup
Displays a Print Setup dialog box, so you can select a printer and printer connection.

Print Range
Specify the pages you want to print:

All Prints the entire document.
Selection Prints the currently selected text.
Pages Prints the range of pages you specify in the From and To boxes.

Copies
Specify the number of copies you want to print for the above page range.

Collate Copies
Prints copies in page number order, instead of separated multiple copies of each page.

Print Quality
Select the quality of the printing. Generally, lower quality printing takes less time to produce.


Print Preview toolbar

The print preview toolbar offers you the following options:

Print
Brings up the print dialog box, to start a print job.

Next Page
Previews the next printed page.

Prev Page
Previews the previous printed page.

One Page / Two Page
Previews one or two printed pages at a time.

Zoom In
Takes a closer look at the printed page.

Zoom Out
Takes a larger look at the printed page.

Close
Returns from the print preview to the editing window.


Print Setup dialog box

The following options allow you to select the destination printer and its connection.

Printer
Select the printer you want to use. Choose the Default Printer; or choose the Specific Printer option and select one of the current installed printers shown in the box. You install printers and configure ports using the Windows Control Panel.

Orientation
Choose Portrait or Landscape.

Paper Size
Select the size of paper that the document is to be printed on.

Paper Source
Some printers offer multiple trays for different paper sources. Specify the tray here.

Options
Displays a dialog box where you can make additional choices about printing, specific to the type of printer you have selected.

Network...
Choose this button to connect to a network location, assigning it a new drive letter.


Proof Tree

Opens a supplementary window in which program execution can be seen in progress. The main branch of the proof tree under construction for the goal being processed is displayed. The subgoals that have already been successfully satisfied appear in blue or in green . Those but partly satisfied (which are satisfying at the moment) appear in red, and the ones not yet reached appear in black.

Information in this window duplicates that in Stack window and other trace windows but it is easier to interpret.

You can change the mode of the Proof Tree window by the buttons: N, S, T, U, H, P, V.

N – show stack numbers
S – short print
T – tight print
U – underline
H – highlight
P – prefix view
V – show variables

You can click on atoms to select them. You can copy in the clipboard the selected atom with the Ctrl button. After that you can paste it by Ctrl+V in your program.

You can double click on blue atoms to see how they are satisfied. Note that the terms that instantiate variables in these branches can be seen too. If you double click a subgoal and hear sound beep, this means that this subgoal is instantiated with an axiom. If you want to receive the normal view of the Proof Tree again then double click on the last red subgoal. If you double click on a green subgoal then you will close its subtree.

You can use buttons Home, End and Insert for horizontal scrolling of this window.

Home scrolls to the beginning (the most left point).
End scrolls to the end (the most right point).
Insert scrolls to the middle.

Use also Page Up , Page Down and arrows .

Warning: The numbers of the variables in the subgoals which are in black may be not real in some sense. The reason: If this number is bigger than the maximum in the Variables window, then this is a not-instantiated variable with temporal number. The numbers of other variables are real and they are shown in the Variables window. Of course, these numbers are real but not constant because after backtracking they can change.


Shortcuts

You can use the following shortcuts:
F1 | Shows the main index of the Help File
F2 | Open... (project folder)
Ctrl+F2 | Open... (Strawberry folder)
F3 | Find next.
F4 | Clean the Output window.


Stack window

Stack

Displays the current contents of the stack. Can be used to view stack contents during stepwise execution. Nevertheless the proof tree is more convenient.

Each row of the Stack window corresponds to some atom from the tail of a rule. The Stack window contains six columns:

Column #0 counts the stack boxes. The format is Number.

Column #1 contains the number of parent box. The format is ParentNumber.

Column #2 contains the number of the atom inside the tail of its rule, and totality of the atoms in the tail of this rule. The format is Number:Totality.

Column #3 contains the number of variables in the atom and the number of variables which are in the head of the clause that has been unified with this atom. The format is vars=Variables:Variables.

Column #4 contains the number of the first variable which is in the atom. The variables which are in the head follow. So you know the numbers from column #3 and the number of the first variable and this means that you can calculate the numbers of all variables. The format is (_VarNumber).

Column #5 contains the number of the clause that has been already unified with this atom, and, next to this number, the numbers of the other clauses, that can be unified with this atom, in case of backtracking. Look at System List window in order to find which are the clauses which correspond to these numbers. The format is -> Current. Next. Next. Next..


Status Bar

The status bar is displayed at the bottom of the Strawberry Prolog window. To display or hide the status bar, use the Status Bar command in the Options menu.

The left area of the status bar describes actions of menu items as you use the arrow keys to navigate through menus. This area similarly shows messages that describe the actions of toolbar buttons as you depress them, before releasing them. If after viewing the description of the toolbar button command you wish not to execute the command, then release the mouse button while the pointer is off the toolbar button.

The right areas of the status bar has three fields.

The first one shows the line and column numbers in the format: Ln X, Col Y

The second and third indicate which of the following keys are latched down:

Indicator Description
CAP The Caps Lock key is latched down.
NUM The Num Lock key is latched down.


Toolbar

The toolbar is displayed across the top of the application window, below the menu bar. The toolbar provides quick mouse access to many tools used in Strawberry Prolog,

To hide or display the Toolbar, choose Toolbar from the Options menu (ALT, O, T).

Click To

Create a new document.

Open an existing document. Strawberry Prolog displays the Open dialog box, in which you can locate and open the desired file.

Save the active document or template with its current name. If you have not named the document, Strawberry Prolog displays the Save As dialog box.

Remove selected data from the document and store it on the clipboard.

Copy the selection to the clipboard.

Insert the contents of the clipboard at the insertion point.

Compile and execute the current file. If the compiler detects some error, during the compilation, it won't execute the program.

Compile the current file.

Build an EXE file from the active program.

Execute your program step by step. You can see the execution progress in the Proof Tree window.

Show the Proof Tree window.

Print the active document.

Preview your document before printing it.

Show the About dialog box.

Use the context Help feature. The mouse pointer will change and, pointing at some program feature or menu command, the correlated help page will be shown.

Stop program execution, in order to detect the step involved, and put a break point (Trace freature).

Stop program execution.


Variables window

Variables

Displays the current values of the variables. If a variable is linked with another one then this is displayed in format => XXX -> Term , where XXX is the number of the second variable and Term is the term which is on the end of the chain of variables.

This window can be used during stepwise execution. You can use it in combination with the proof tree which is more convenient.


View Status Bar Command

Status Bar command (Options menu)

Use this command to display and hide the Status Bar, which describes the action to be executed by the selected menu item or depressed toolbar button, and keyboard latch state. A check mark appears next to the menu item when the Status Bar is displayed.

See Status Bar for help on using the status bar.


View Toolbar command

Toolbar command (Options menu)

Use this command to display and hide the Toolbar, which includes buttons for some of the most common commands in Strawberry Prolog, such as File Open. A check mark appears next to the menu item when the Toolbar is displayed.

See Toolbar for help on using the toolbar.


BASE example

BASE

If you have a store for parts of old cars, then you need this program. It will help you to keep the store in nice condition. The program is working but where is it? It is hidden in the Base file.


Building-in a Lisp Interpreter

The file Lisp.pro contains a very simple Lisp interpreter, written in Strawberry Prolog. The version of Lisp interpreted is purely functional. It is similar to Lispkit Lisp, that is described in the book of P. Henderson Functional Programming. Application and Implementation .

The interpreter is invoked through the eval predicate, i. e.

eval(Expression,Value)

succeeds if Expression is instantiated to a Lisp expression and its value is Value .

This interpreter allows Strawberry Prolog programmers to mix functional components into their programs.

Syntax of Lisp expressions:

variable ::= Strawberry Prolog atom.
number ::= Strawberry Prolog number.
constant ::= quote( Strawberry Prolog Term ) .
atomic_expression ::= [] | number | constant | variable.
unary_operation ::= car | cdr | atom | number | null .
binary_operation ::= eq | leq | add | sub | mul | div | md | cons .
variable_list ::= [] | nonempty_variable_list
nonempty_variable_list ::= variable | nonempty_variable_list, variable
expression_list ::= expression | expression_list, expression
expression ::= atomic_expression
| unary_operation( expression )
| binary_operation ( expression , expression )
| list( expression_list )
| if_expression
| do_expression
| lambda_expression
| let_expression
| letrec_expression
| variable( expression_list )
| [ expression_list ] .
if_expression ::= if( expression , expression , expression ) .
do_expression ::= do( expression_list )
lambda_expression ::= lambda( variable_list , expression ) .
let_expression ::= let( expression , association_list ) .
letrec_expression ::= letrec( expression , association_list ) .
association_list ::= association | association_list, association.
association ::= [ variable , expression ] .

Example:

?- eval(letrec(fact(7),
[fact,lambda([x],
if(eq(x,0),
1,
mul(x,fact(sub(x,1)))
)
)]),
Value), write(Value).
causes Strawberry Prolog to write 5040 , which is the value of 7! .

Structure of the program lisp.pro :

The eval predicate is defined in terms of two other predicates: l_expr and compute. The l_expr predicate checks whether the expression given to eval is a syntactically correct Lisp program. If it is, the compute predicate evaluates it.

The compute predicate contains clauses that correspond to the different Lisp constructs implemented. It also refers to compute_list, compute_ass_list and compute_arg_list that deal with lists of (variable names and) expressions that have to be evaluated. The basic steps in computing Lisp expressions are accomplished by the value and local_value predicates, that access variable values, and by the apply_un and apply_bin predicates, that implement built-in operations.

The reserved_word, binary and unary predicates define the lists of atoms that cannot be used as variable names in Lisp programs submitted to the interpreter. These lists contain a little more built-in Lisp function names than those implemented. If you wish to implement the functions in Strawberry Prolog, just edit the lisp.pro file. If you prefer to define them in the Lisp program fragments that you submit to eval, you will need to remove their names from the lists.


CURSOR example

CURSOR

Demonstrates how to change the active window cursor.

see also Examples


DRAW

This program allows drawing simple figures using lines. There are menu options for changing the line color and width. The pictures drawn can be saved to files and restored back later

see also Examples


E-mail example

E-MAIL

This is an e-mail generator. There are two variants of this program:
First generates and sends letters.
Second one only writes them in the Output Window.

See also Examples


EDIT example

EDIT

Demonstrates creation and using of edit controls. Two edit controls appear in the client area of the window. The text in each of them can be edited, or the two texts can be exchanged by selecting menu option. You can change also the window brush.

see also Examples


GRAPHIC example

GRAPHIC

Draws random figures in the client area. Demonstrates drawing predicates, pen and brush setting and use of random numbers.

see also Examples


HANOI example

HANOI

Towers of Hanoi - solving the problem and animation.

You can change the number of the disks. For this you have to change the numDisks(5). from the source.

See also Examples


OLE example

OLE

It opens the server calculator.exe and sets and gets its property and invoke its methods.

see also Examples


SPEED example

SPEED

If you want to check how quick is this version of Strawberry Prolog you can use this program.


STUDY example

STUDY

Demonstrates the read and the assert_in predicates.

Warning: because of assert_in function this program is self-modifying
To restore the original, delete all the clauses following the comment.

See also Examples


SUN example

SUN

Demonstrates basic drawing predicates. The window processes the paint message.

see also Examples


=..
Entity: predicate

Usage:
Term =.. List

Succeeds if List is a list of the functor and all arguments of Term, in order.

Actually, =.. is defined on Prolog and here is its definition:

X(|Y)=..[X|Y].

Example:

?- f(a, b)=..X, Y=..[g, c, d], write(X), nl, write(Y), nl.


Accessing the text value of a control or window caption

get_text
Entity: function

set_text
Entity: predicate

Usage:
Text is get_text(Window)
set_text(Text , Window)

Gets/Sets the text value of a window. For the overlapping window this is the text on the Title Bar, for the edit control this is the text inside it, for the button it is the text on it and so on.

Text | string containing or receiving the text
Window | window or control handle, use _ (underscore) for default or current window

Example:

?-window( _, _, win_func(_), "set_text/get_text demo", 100, 100, 300, 200).

win_func(init):-
menu(normal, _,_,mfunc(_),"Change text").

mfunc(press):-set_text("New Text", _).


add_text
Entity: predicate

Usage:
add_text(Edit, Text)
add_text(Edit, Text, FontMask)

Adds the text Text into the edit box Edit with font FontMask.

Edit edit box object
Text the string that will be added
FontMask if you like then you can specify the font and the text color which will be used for the added text.

Examples:
?-
... ,
Red is font_mask(_,rgb(255,0,0),_,_,_,_,_,_),
add_text(Edit, "Added Text", Red).


Arithmetic predicates

Arithmetic and special types

Type checking and conversion predicates:

const checks whether a term is a constant
var checks whether a term is a not-instantiated variable
number checks whether a term is a number
integer checks whether the argument is integer or converts it to integer
float checks whether the argument is float or converts it to float
round returns integer which is round the argument
ceiling returns integer which is bigger than the argument
floor returns integer which is smaller than the argument

Comparison:

= unify
?= unifyable
\= not unifiable
> bigger than
< less than
=:= equal
>= bigger or equal to
=< less or equal to
=\= not equal

Evaluation:

is evaluates righthandside arithmetical expression and unifies the value with the lefthandside variable (Prolog 'assignment')
:= stable assignment
has_to unstable assignment

Standard arithmetic:

+ addition
- subtraction
* multiplication
/ division
** exponentiation
// integer division
mod modulo
rem remainder
abs returns the absolute value
sign returns the sign
random generates random numbers

Strings:

print converts a term to a string
printq converts a term to a string (without calculating it)
scan converts a string to a term
+ strings concatenation
sub_string finds substrings from the given string
string_end finds ends from the given string
str_length finds the length of the given string
split splits a string using separator character
equal compares strings (with case and no case)
less_than compares strings (with case and no case)
replace replace one string with another
string_from_ASCII makes string from ASCII number
first_ASCII returns the ASCII code of the first symbol
charAt returns a char from its position

Char Sets:

char_set gets and sets the default char set
char_set_name returns the name of the char set
convert_charset changes the char set
convert_UTF8_to_local converts from UTF-8 to 8 bit char set

Bitwise functions:

>> shift all bits in right
<< shift all bits in left
/\ bitwise and function
\/ bitwise or function
xor bitwise xor function
\ bitwise not function
find_first_1_in Find the first instance of {1} in N
find_last_1_in Find the last instance of {1} in N
find_any_1_in Find all instances of {1} in N
count_all_1s_in count how many instances of {1} are in N

Floating point functions:

sin calculates the sine function
cos calculates the cosine function
tg calculates the tangent function
arcsin calculates the arcsine function
arccos calculates the arccosine function
arctg calculates the arctangent function
sinh calculates the hyperbolic sine function
cosh calculates the hyperbolic cosine function
tgh calculates the hyperbolic tangent function
sqrt calculates the square root
log calculates the natural logarithm
log10 calculates the logarithm with base ten
exp calculates the exponent function


Asserting clauses in the run-time database

assert
Entity: predicate

asserta
Entity: predicate

Usage:
assert(Clause)
asserta(Clause)

Appends a clause to the run-time database. (asserta appends in the beginning)

Clause the clause to append.

Fails if Clause is not a clause.

Example:

?- assert(test(1,2)), test(X,Y), write(X), write(" "), write(Y), nl.

See also:


Asserting in the run-time database and in the program

assert_in
Entity: predicate

asserta_in
Entity: predicate

Usage:
assert_in(Clause)
asserta_in(Clause)

Asserts a clause both in the run-time database (like assert) and in the text file containing the running program. (asserta_in appends in the beginning)
Clause the clause to append.

Fails if Clause is not a clause.

Example:

?-assert_in(test(1,2)), test(X,Y), write(X), write(" "), write(Y), nl.

See also:


beep
Entity: predicate

Usage:
beep
beep(Sound)
beep(String)

Produces short beep or a system sounds which is pointed by Sound.

Sound must have on of the values:

! - System Exclamation
? - System Question
s - System Hand
i - System Asterisk
d - System Default
t - Standard beep using the computer speaker

String has to contains the name of a WAV file.

Example:

?- beep("C:\\WINDOWS\\MEDIA\\The Microsoft Sound.wav").


bezier_line
Entity: predicate

Usage:
bezier_line(X1,Y1, ... , Xn, Yn)

This function will draw a cubic Bézier curve using the points X1,Y1, ... , Xn, Yn . The Bezier line is a smooth line which is used to describe curves (for example in CorelDraw). If you want to make such a line which goes true k+1 points then you need to give 3*k+1 points to this predicate (that is, you need 2*(3*k+1) arguments). You need so many points because for every point you have to give also the vector of the touching line in the left and in the right direction. This vectors show the direction of the touching line but also their length shows how close is the curve to the touching line in this point. For example, if you gave as arguments the points p1, p2, p3, p4 then you will connect points p1 and p4 with a Bézier curve. The points p2 and p3 will describe the lines which touch our curve in p1 and p4 . More concretely the vector p1, p2 gives the direction of the touching line and its length gives how close is this curve to the touching line in p1 . It is analogous for the vector p4, p3 for the point p4 . For users who are familiar with CorelDraw this is easier. Anyway, in CorelDraw you change the position of these points by the mouse and see the result directly.

This function draws lines by using the current pen .

See also:

line
ellipse

Examples:
Music.pro


bitmap_image
Entity: function

Usage:
Bitmap is bitmap_image(Source, _)
Bitmap is bitmap_image(Source, Mask)

Creates a bitmap object from the file Source with mask file Mask. You can use later this bitmap object with the predicate draw_bitmap to draw this bitmap somewhere.

The purpose of the Mask is to make bitmap object with a transparent color in it. If you do not need transparent color in your bitmap then ignore this parameter (put _ (underline) on its place).

How to make transparent color? In your bitmap replace the color which should to be transparent with black. You have to make also a Mask bitmap. The Mask bitmap is the same but in black and white. In it the transparent color is white and all other colors are black.

How the transparent color works? First is made a logical AND between the screen and the Mask bitmap. The result is a black hole on the place where are not transparent colors (i.e. where the Mask is black). The transparent part of the image stays untouched. The second step is to make logical OR between the screen and the Source bitmap. As a result the transparent part is untouched again because it is added with Black and in the black hole appears the desired image (i.e Black OR color is equal to the same color).

Source the full path of the bitmap file
Mask the full path of the mask file

Examples:
?-
...
Bitmap is bitmap_image("image.bmp", _),
draw_bitmap( 10, 10, Bitmap, _, _).


Bitwise functions

>>, <<, /\, \/, xor, \
Entity: functions

find_first_1_in
Entity: function

find_last_1_in
Entity: function

find_any_1_in
Entity: function

count_all_1s_in
Entity: function

Usage:
R is Number >> Shift
R is Number << Shift
R is Arg1 /\ Arg2
R is Arg1 \/ Arg2
R is Arg1 xor Arg2
R is \Argument
R is find_first_1_in(N)
R is find_last_1_in(N)
R is find_any_1_in(N)
R is count_all_1s_in(N)

Bitwise functions

>> shifts right all bits
<< shift left all bits

These functions shift all bits of the Number in Shift positions (left or right). The positions which after that will be free will be set to zero.

For example 6>>2=:=1 and 6<<2=:=24.

/\ bitwise and function
\/ bitwise or function
xor bitwise xor function
\ bitwise not function

These functions make the corresponding logic operation between all bits of the arguments. For example 7/\13=:=5 because bits 1 and 4 are in 7 and in 13 but bit 8 is only in 13 like the bit 2 which is only in 7( 7=:=4+2+1, 13=:=8+4+1 and 5=:=4+1).

find_first_1_in – Find the first instance of {1} in N and return its position. If N=0 then this function fails (no answer).
find_last_1_in – Find the last instance of {1} in N and return its position. If N=0 then this function fails (no answer).
find_any_1_in – Find all instances of {1} in N and return their positions. The first answer is the first position, the second answer is the second one and so on.
count_all_1s_in – Count how many instances of {1} are in N and return their number.

These functions find some instances of {1} and count their number.


brush
Entity: predicate and function

window_brush
Entity: predicate

Usage:
brush(Color)
brush(Color, shape(Type))
Brush is brush(Color)
Brush is brush2(Color, Type)

Usage:
window_brush(Window, Color)
window_brush(Window, Color, shape(Type))

Gets/sets the current filling color.
Window | window or control handle, use _ (underscore) for default or current window
Color | integer containing a color, you can use rgb to create such integer.
Type | h Horizontal; (-) Horizontal; v Vertical; ! Vertical; x Diagonal cross; (\) Diagonal (+) Cross; (/) Diagonal;

Example:

?-window( _, _, win_func(_), "Brush Demo", 100, 100, 200, 200).

win_func(paint):-
brush(rgb(255,0,0)),
rect(0,50,200,150),
brush(rgb(0,0,255)),
rect(50,0,150,200).

See also:


call
Entity: predicate

Usage:
call(X,Y,...)

Tries consecutively the goals X , Y ... . You can use this predicate when you have to make an atomic goal from complicated one.

Example:

?- write(X of call(p(X), X>4)), nl.

p(3).
p(5).


CGI Predicates

Prolog CGI Scripts
(ONLY for Professional edition)

String2 is getenv(String1)

returns the environment value of the String1 ( QUERY_STRING, REMOTE_ADDR, HTTP_COOKIE etc.)

String is getenv(post)
returns the value of the form which is submitted using POST method

String2 is get_environment_arg(INT, String1)
returns the Int part of the String1 (all parts of String1 are separated by & or ? signs)

It is usually used to get the value of the submitted fields.

tring3 is get_html_form(INT, String1, String2)
returns the value of the INT field which has the name of String1 from the String2

The difference from get_environment_arg is that here the value is decoded. INT and String1 can be left _ which means default.

set_content_type(String)
sets the content type of the following text (for CGI ONLY) for Example "text/html", "image/jpg" etc.

set_cookie(Field, Path, Expiration)
sets a cookie on the client's browser. The Field contains something like "ID=John" The Path must contain the directory on the server on which files the cookie will be send to. For example "/" sets the cookie to all files from your server. The Expiration must contain the full date when the cookie will expire for example "Monday, 28-Feb-00 10:00:00 GMT". If the Expiration is not set the cookie will expire when the user ends the session.


change_style
Entity: predicate

Usage:
change_style(Window, XOR, AND, OR)

Changes the stile of the Window. The new stile is the old one modified by XOR, AND and OR.

XOR gives bits which have to be reversed. For example if XOR is 5 then bits 1 and 4 will be reversed.

AND gives which bits have to be zero. For example if AND is 5 then bits 1 and 4 will be set to zero.

OR gives which bits have to be one. For example if OR is 5 then bits 1 and 4 will be set to one.

Actually the result is:
New_value is ((Old_value xor XOR) /\ \AND) \/ OR


char_set
Entity: predicate

Usage:
char_set(Char_Set)

Gets and sets the default char set. All functions and predicates which work with strings use the default char set. For example, the predicate write assumes that the char set of the string is the default char set. If this is not the case the result of write can be wrong.

If Char_Set is variable then it gets the default chat set (actually gets its number which can be converted in the char set's name by the function char_set_name)

If Char_Set is the number of existing char set this predicate sets the default chat set to the one which has this number. Look at char sets table in order to see the numbers of all available char sets.

Example:

?-
char_set(0),
char_set(X),
write(char_set_name(X, l)).

See also:
char_set_name
char sets table
convert_charset
convert_UTF8_to_local

Look at the example:
char_sets.spj (in folder Examples)


char_set_name
Entity: function

Usage:
Name is char_set_name(Char_Set_Number, Type)

Returns the string which contains the name of the char set with number Char_Set_Number. If the Type is s then the short name will be returned and if it is l then the long name will be returned.

Example:

?- Name is char_set_name(2, l), write(Name).

See also:
char sets table
convert_charset
convert_UTF8_to_local

Look at the example:
char_sets.spj (in folder Examples)


Char Sets

Char Sets Table

The following char sets are supported from Strawberry Prolog:
 | Long char set name | Short name
0. | Unicode (UTF-8) | UTF-8
1. | Cyrillic (Windows-1251) | Windows-1251
2. | Western European (Windows-1252) | Windows-1252
3. | Greek (Windows-1253) | Windows-1253
4. | Turkish (Windows-1254) | Windows-1254
5. | Hebrew (Windows-1255) | Windows-1255
6. | Arabic (Windows-1256) | Windows-1256
7. | Baltic (Windows-1257) | Windows-1257
8. | Vietnamese (Windows-1258) | Windows-1258
9. | Thai (Windows-874) | Windows-874
10. | Central European (Windows-1250) | Windows-1250
11. | Western European (ISO) | ISO_8859-1
12. | Central European (ISO) | ISO_8859-2
13. | Latin 3 (ISO) | ISO_8859-3
14. | Baltic (ISO) | ISO_8859-4
15. | Cyrillic (ISO) | ISO_8859-5
16. | Arabic (ASMO 708) | ISO_8859-6
17. | Greek (ISO) | ISO_8859-7
18. | Hebrew (ISO-Visual) | ISO_8859-8
19. | Turkish (ISO) | ISO_8859-9
20. | Baltic (DOS) | cp775
21. | Western European (DOS) | cp850
22. | Central European (DOS) | cp852
23. | Turkish (DOS) | cp857
24. | Cyrillic (DOS) | cp866
25. | Greek, Modern (DOS) | cp869
26. | Cyrillic (KOI8-R) | koi8r

You can convert from one char set to another by the function convert_charset.

See also:
char_set_name
convert_charset
convert_UTF8_to_local

Look at the example:
char_sets.spj (in folder Examples)


charAt
Entity: function

Usage:
Char is charAt(Source, Pos)

Returns a char from the string Source at the position Pos (zero based). Fails if there is no such symbol.

Actually this function returns not a character but a string with length one. (Such strings we use to represent characters in Strawberry Prolog.)

Source the source string
Pos the zero based position

Examples:
?- Char is charAt("Hello", 1),
write(Char). % e


check_box
Entity: predicate

Usage:
check_box( )
check_box(Arg1, ... , ArgN)

Creates a check box control.

Put inside the brackets only these arguments which you need. All other arguments will be set by default. The arguments may be any of the following (the order is not important).
handle(Handle) | handle to this check box.
parent(Parent) | handle to the parent window.
class(Check_func) | predicate which will receive the messages from this check box.
text(Text) | the text which is on the check box
pos(X,Y) | coordinates of upper left corner
size(Width, Height) | size of the check box
checked | flag (default off)
grayed | flag (default off)

Look at check box methods:

R is get_check_box_value(Check_Box)
set_check_box_value(Check_Box, Value)

See also:
window
get_check_box_value

Look at the example:
Check Box.spj (in folder Examples)


chronometer
Entity: predicate and function

Usage:
chronometer( Time )
Time is chronometer( )

Gets time intervals in milliseconds between two calls of chronometer . If you call twice chronometer predicate then the second time it will return the time which is past between these two calls.

Example:

?- chronometer(_), do_something, chronometer(T), write(T).

do_something.

This example returns the time in milliseconds in which the do_something predicate was working.

Examples:

Speed.pro


client

client_size
Entity: predicate

client_pos
Entity: predicate

Usage:
client_size(Win, Width, Height) will return in variables (Width, Height) the difference between the right-bottom and the left-top corners of the client area of the window Win.
client_pos(Win, X, Y) will return in variables (X, Y) the left-top corner of the client area of the window Win.

Gets the size or the position of the client area of the window Win (Use _ for Win to point the current window).

Example:

win_func(mouse_wheel(Delta, X, Y)):-
client_pos(_,A,B),
draw_point(X-A, Y-B, rgb(255, 0, 0)).

See also:
size and position
Messages

Look at the example:
Fractals.pro (in folder Programs)


close
Entity: predicate

Usage:
close(Object)

Closes any type of object. You can use this predicate in order to close Window, OLE server, File, DLL, Socket or MySQL connection.

Closing an one object is the same as its killing because the object will not exist after closing. Actually its pointer will be still valid but it will point to a dead object. You can look in Tools / Objects in order to see the status of all current objects.

See also:
window
server


color

rgb
Entity: predicate and function

Usage:
rgb(Color, Red, Green, Blue)
Color is rgb(Red, Green, Blue)

Creates a color in Color by Red, Green and Blue. The variables Red, Green and Blue have to be between 0 and 255.

The Color is an integer and in hexadecimal looks in this way: 0xbbggrr, where

rr is hexadecimaly Red,
gg is hexadecimaly Green and
bb is hexadecimaly Blue.

If you use the predicate rgb then you can give it an integer for Color and will receive its components in Red, Green and Blue.

See also:
draw_point


color_text
Entity: predicate

color_text_back
Entity: predicate

Usage:
color_text(Window, Color)
color_text_back(Window, Color)

Gets/sets the foreground/background color for text output. Use this predicate with windows and edit controls.
Window | window or control handle, use _ (underscore) for default or current window.
Color | integer containing a color, you can use rgb to create such integer.

Example:

?-window( _, _, win_func(_), "Edit control demo", 100, 100, 200, 200).

win_func(init):-
window_brush(_, rgb(0, 0, 255)), % blue
edit(E1, _, edit_func(_), "Start Value", 10, 10, 100, 50).

edit_func(init) :-
color_text(_, rgb(0, 255, 0)), % green
color_text_back(_, rgb(255, 0, 0)). % red

See also:


Compare

Comparison

There are two types of predicates for comparison. These are predicates for unification comparison and predicates for arithmetic comparison.

Unification comparison. This predicates are written in Prolog and you can see their definitions in the Standard.add file.

X=Y unify X and Y
this predicate succeeds if X and Y are unifyable and unify them.

X?=Y are X and Y unifyable
this predicate succeeds if X and Y are unifyable but don't unify them.

X\=Y not unifyable
this predicate succeeds if X and Y are not unifyable.

Arithmetic comparison. These predicates are built-in and they calculate the value of the expressions X and Y and then compare these values. With these predicates you can compare integer and float numbers. Also you can compare two strings. You cannot compare a string with a number.

> bigger than
< less than
=:= equal
>= bigger or equal to
=< less or equal to
=\= not equal

When you compare integer have in mind that when one integer is bigger than 2147483647 (two billion and something) then it is accepted as negative. This comes from the 32 bit representation of the integer.

When you compare strings then smaller will be that one which is first in the alphabetical order. One symbol is before another if it is first in the ASCII table. If one string is a beginning of another then the shorter one is smaller.

For no case comparing of strings you have two more predicates: equal and less_than. Look for them in Strings.


convert_charset
Entity: function

Usage:
String is convert_charset(Start_String, From, To, Error, Default_Char)

This function changes the char set of the string Start_String from the char set From to the char set To. Here From and To are integers which contain the numbers of char sets. You can select these numbers from this table. The return string is the result of this conversion. Parameter Error is for the error code and Default_Char gives the character which will be used to replace the errors.

If you do not need parameters Error and Default_Char then replace them with _ (Anonymous variable). In such case the project default character will be used for Default_Char and you will lose the error code returned in the variable Error.

The code of the errors which appear in the time of conversion will be returned in the variable Error. This code can be 0 (no errors), 1 (cannot fit in the new set), 2 (Start_String is not in the set From) or 3 (both errors 1 and 2).

If after the conversion some of the characters of the Start_String cannot fit in the char set To then this is error 1.

If some of the characters of the Start_String are not in the set From (or if From is 0 (Unicode) and Start_String is not a correct Unicode string) then this is error 2.

If From is equal to To then Start_String is returned and there is not any check for error 2.

Example:

?-
read(String, "Write something in Russian", s), % let the project char set will be Unicode
write(String), nl,
Russian is convert_charset(String, 0, 1, _, _),
Greek is convert_charset(Russian, 3, 0, _, _),
write(Greek), nl. % changes the Russian (Cyrillic) letters with Greek letters

See also:
char sets table
char_set_name
convert_UTF8_to_local

Look at the example:
char_sets.spj (in folder Examples)


convert_UTF8_to_local
Entity: function

Usage:
Return is convert_UTF8_to_local(String, Type)

This function converts the string String from UTF-8 to 8 bit char set (if it can find proper char set). The number of the new char set will be returned in the variable Type. If the string is converted then this number is between 1 and 10 (i.e. will be one of the Windows char sets). If the string is not correct Unicode string then this number will be minus one. If the function cannot find char set which contains all symbols from the string then it returns the same string which is in UTF-8 format and in Type returns 0 (which is the number of UTF-8). If all symbols are in US ASCII then Type will stay free variable. (In this case the string can be considered as in any char set because US ASCII is subset to all char sets). If you check Type=2 then this will be true if the returned string is in char set 2 or in US ASCII. If you check Type=:=2 then this will be true only if the returned string is in the char set 2.

The return string is correct and no symbol in it is replaced with '?'. If convert_UTF8_to_local cannot find 8 bit char set which contains all symbols from the string then it returns the same string without change.

When one char set will be recognised?

If the string fit to char set 2 (Western European) then it will be converted to this char set for sure.

If the string is not in the char set 2 but is in char set 1 (Cyrillic) then it will be converted to the char set 1 for sure.

If the string contains some special symbol which is special for some of the char sets from 3 to 10 and if the string can be converted to this char set then it will be for sure. For example if the string contains a Greek letter and if the string fits in char set 3 (Greek) then it will be converted to char set 3 for sure.

Example:

?- Name is char_set_name(2, l), write(Name).

See also:
char sets table
char_set_name
convert_charset

Look at the example:
char_sets.spj (in folder Examples)


Clipboard Operations

copy_in_edit
paste_in_edit
cut_in_edit
Entity: predicate

Usage:
copy_in_edit(Edit)
paste_in_edit(Edit)
cut_in_edit(Edit)

copy_in_edit copies the selected text from an edit box into the clipboard
paste_in_edit pastes the clipboard text into an edit box
cut_in_edit copies (into the clipboard) and deletes the selected text from an edit box

Edit edit box object.

Use this predicates to transfer data between the selected text in your edit box and the clipboard. (The operational system supports a memory buffer for transferring data between different applications. Its name is Clipboard. When you do copy and paste in any program you actually use this buffer).


count_successes
Entity: function

Usage:
N is count_successes(Goal)

Here Goal has to be an atomic goal. After the execution of this function the returned value N will contain the number of the times Goal succeeded. If Goal succeeds infinitely many times then this function will go in an infinite loop.

Example:

?-
read(X,"Say how many times"),
write(count_successes(p(X))),
nl.

p(X):-
for(I,1,X),
write("*").


Creating a bitmap control

bitmap
Entity: predicate

Usage:
bitmap( )
bitmap(Arg1, ... , ArgN)

Creates a bitmap control.

Put inside the brackets only these arguments which you need. All other arguments will be set by default. The arguments may be any of the following (the order is not important).
handle(Handle) | handle to this bitmap control.
parent(Parent) | handle to the parent window.
class(Bitmap_func) | predicate which will receive the messages from this bitmap control.
file(File) | the file which contains the bitmap
pos(X,Y) | coordinates of upper left corner

Example:

?-window( title("Bitmap control demo") ).

win_func(init):-
bitmap( pos(50, 50) ).

See also:

window


Creating a button control

button
Entity: predicate

Usage:
button( )
button(Arg1, ... , ArgN)

Creates a button control.

Put inside the brackets only these arguments which you need. All other arguments will be set by default. The arguments may be any of the following (the order is not important).
handle(Handle) | handle to this button.
parent(Parent) | handle to the parent window.
class(But_func) | predicate which will receive the messages from this button.
text(Text) | the text which is on the button
pos(X,Y) | coordinates of upper left corner
size(Width, Height) | size of the button
grayed | flag (default off)

Example:

?-window( title("Button demo"), size(200, 200) ).

win_func(init):-
button( class(bfunc), text("button"), pos(20,20), size(80,50) ).

bfunc(press):-message("Message", "Button pressed.", i).

See also:

window


Creating a static label

static
Entity: predicate

Usage:
static( )
static(Arg1, ... , ArgN)

Creates a static label.

Put inside the brackets only these arguments which you need. All other arguments will be set by default. The arguments may be any of the following (the order is not important).
handle(Handle) | handle to this static label.
parent(Parent) | handle to the parent window.
class(Static_func) | predicate which will receive the messages from this static label.
text(Text) | the text which is on the static label
pos(X,Y) | coordinates of upper left corner
size(Width, Height) | size of the static label
grayed | flag (default off)

Example:

?-window( title("Static Label demo")).

win_func(init):-
static( text("Static Label"), size(100, 20)).

See also:

window


Creating an animate control

animate
Entity: predicate

Usage:
animate( )
animate(Arg1, ... , ArgN)

Creates an animation control.

Put inside the brackets only these arguments which you need. All other arguments will be set by default. The arguments may be any of the following (the order is not important).
handle(Handle) | handle to this animation control.
parent(Parent) | handle to the parent window.
class(Animate_func) | predicate which will receive the messages from this animation control.
file(File) | the file which contains the animation. This is a string containing a path to an AVI file. Unfortunately not all AVI files are suitable for animation controls. This is because of some restrictions in MS Windows. Most of the AVI files which you can find will not work with animation control. For creating proper AVI file use Video for Windows SDK.
pos(X,Y) | coordinates of upper left corner

Example:

?-window( title("Animation control demo") ).

win_func(init):-
animate( file("res/Dillo.avi"), pos(50, 50) ).

See also:

window


Creating an edit control

edit
Entity: predicate

Usage:
edit( )
edit(Arg1, ... , ArgN)

Creates an edit control.

Put inside the brackets only these arguments which you need. All other arguments will be set by default. The arguments may be any of the following (the order is not important).
handle(Handle) | handle to this edit control.
parent(Parent) | handle to the parent window.
class(Edit_func) | predicate which will receive the messages from this edit control.
text(Text) | the text which is set at the beginning
pos(X,Y) | coordinates of upper left corner
size(Width, Height) | size of the edit control
border | flag (default on)
multiline | flag (default off)
readonly | flag (default off)

Example:

?-window( title("Edit control demo"), size(200, 200)).

win_func(init):-
window_brush(_, rgb(0, 0, 255)), % blue
edit( class(edit_func), text("Start Value"), pos(10, 10), size(100, 100), multiline).

edit_func(init) :-
color_text(_, rgb(0, 255, 0)), % green
color_text_back(_, rgb(255, 0, 0)). % red

See also:

window


Creating an icon control

icon
Entity: predicate

Usage:
icon( )
icon(Arg1, ... , ArgN)

Creates an icon control.

Put inside the brackets only these arguments which you need. All other arguments will be set by default. The arguments may be any of the following (the order is not important).
handle(Handle) | handle to this icon control.
parent(Parent) | handle to the parent window.
class(Icon_func) | predicate which will receive the messages from this icon control.
file(File) | the file which contains the icon
pos(X,Y) | coordinates of upper left corner

Example:

?-window( title("Icon control demo") ).

win_func(init):-
icon( pos(50, 50) ).

See also:

window


Creating an overlapping window

window
Entity: predicate

Usage:
window( )
window(Arg1, ... , ArgN)

Creates an overlapping window.

Put inside the brackets only these arguments which you need. All other arguments will be set by default. The arguments may be any of the following (the order is not important).
handle(Handle) | handle to this window.
parent(Parent) | handle to the parent window.
class(Win_func) | predicate which will receive window messages
title(Title) | the window title
pos(X,Y) | coordinates of upper left corner
size(Width, Height) | size of the window
icon(Icon) | set icon to the window
cursor(Cursor) | set cursor to the window
backgr(Backgr) | set backgr to the window
minimized, maximized, normal | flags for the window status (the default status is normal)
clean_before_paint, paint_indirectly | flags for the way the window is painted
h_scroll, v_scroll | if you need to add scroll bars
title, sys_menu, border, thick_frame | other window flags. These flags are default on. Try to switch them off with "not"
double_clicks | this flag you have to set on if you want the window to receive the message "double_click".

Example:

?-window( title("Line demo"), size(220, 240), not(sys_menu) ).

win_func(paint):-line(0,0,200,200), line(0,200,200,0).

See also:

button


Creating menu elements

menu
Entity: predicate

Usage:
menu( )
menu(Arg1, ... , ArgN)

Creates corresponding menu entry.

Put inside the brackets only these arguments which you need. All other arguments will be set by default. The arguments may be any of the following (the order is not important).
handle(Handle) | handle to this menu entry.
parent(Parent) | handle to the parent window.
action(Menu_func) | predicate which will receive messages from this menu entry.
text(Text) | the menu entry text
normal, pop_up, separator | flags for the menu entry type.
checked, grayed, right | flags for the menu entry type.

Example:

?-window( title("menu demo") ).

win_func(init):-
menu(pop_up, action(m_popup), text("Pop_up") ),
menu(normal, action(m_item), text("MenuItem") ).

m_item(press):-message("Message", "menu item selected", i).

m_popup(init):-
menu(normal, action(s1), text("SubItem1") ),
menu(separator),
menu(normal, action(s2), text("SubItem2") ).

s1(press):-message("Message","SubItem1 selected", !).

s2(press):-message("Message","SubItem2 selected", n).

See also:


cursor
Entity: predicate

Usage:
cursor(CursorType)

Sets the cursor to one of the standard cursors.

CursorType can be one of the following constants:

? Standard arrow and small hourglass
s Standard arrow
c Crosshair
t Text I-beam
o Slashed circle
x Four-pointed arrow
n Double-pointed arrow pointing northeast and southwest
d Double-pointed arrow pointing north and south
u Double-pointed arrow pointing northwest and southeast
! Double-pointed arrow pointing west and east
v Vertical arrow
w Hourglass


cut

!
cut
Entity: predicate

Usage:
!
cut(Depth)

cut(1) is the same as !
cut(0) is the same as true
cut(0.5) cuts less than !
cut(2) cuts more than !

In Prolog the functions and predicates are multi-valued and can return more than one answer. Anyway, sometimes we need only the first answer and we want to take rid of the rest of them. For this purpose we use the predicate cut. The parameter Depth specifies which answers will be cut.

Let us have the clause:

head :-
q1, q2, …, qn, cut(Depth), s1, s2, … , sk.

The cut predicate will affect only the predicates which are before it. So, it will not affect the predicates s1, s2, … , sk. If the Depth is 0.5 we will receive only the first answer of the conjunction q1, q2, …, qn but we will receive all possible answers of the head. If the Depth is 1 all other answers of the head will be cut. If the Depth is bigger than 1 the cut will affect also the predicates and heads which are higher in the proof tree.

In the second example the Depth parameter of cut is 2.5 instead of 1.5 because in the definition of -> (if-then-else) predicate there is included one call predicate which increases the depth by one. Look at Standard.add file to see the definition of -> (if-then-else). For the same reason the depth in the example db_read.pro is 3 instead of 2.

Example:
?-
do(X), write(X), nl, fail.

do(X):-
X is sub_string("abcd", _, 2),
cut(0.5). % try this with 0, 1 and 3
do(X):-
X="end".

Example:
?-
X="", do(X), write(X), nl.

do(X):-
repeat,
read(Y, "Enter DATA", s),
X:=X+Y,
(not(yes_no("", "Do you have more data", ?))->
cut(2.5), fail
),
fail.
do(_).

See also:
once

Examples:
OLE / db_read.pro


Default Window

When you are proceeding a window message then the default window is the window that receives the message. If you are not proceeding a message then default window is the last used window.


Direct Database Manipulation

on_the_last_step
Entity: function

the_head_of
set_at
retract_at
modify_at
Entity: predicates

Usage:
R is on_the_last_step(Flag)
the_head_of(Number, Head)
set_at(Number, Fact)
retract_at(Number)
modify_at(Number, Position, New_Value)

Direct Database Manipulation

This predicates are very useful for AI applications.

When you make unification with a fact in your database you don't know which exactly is this fact. You can check the variables of the goal to understand something about this fact but you cannot understand everything (especially if the fact is a more general case than the goal). The following function will help you to understand the consecutive number of this fact in the database.

Number is on_the_last_step(Flag)

You have to call this function immediately after the unification in which you are interested. Number will be the consecutive number of the fact (or clause) in the program used in the last unification.

The Flag can have one of the following values:

a - the function will succeed in All cases.

e - the function will succeed only if on the last step the unification was made between Exactly equal goal and fact (equal up to renaming of variables). For example exactly equal are the goal p(X, f(Y)) and the fact p(A, f(B)) or p(_, f(_)).

s - the function will succeed only if on the last step the unification was made between Similar goal and fact (equal up to substitution of some variables with other variables or special types). For example similar but not exactly equal are the goal p(X, f(Y)) and the fact p(A, f(A)) or p(1, f("String")) but it is not similar to the facts p(X, f(a)) and p(X, Y).

If you know the consecutive number of one fact (for example from on_the_last_step function) and if you want to receive this fact then use:

the_head_of(Number, Head)

where Number is the consecutive number in the database and Head will return the fact which is on that number. If it is not a fact but a clause then the head of this clause will be returned.

You can modify a fact in your database by knowing its consecutive number. For this you can use the following predicates:

set_at(Number, Fact)
retract_at(Number)
modify_at(Number, Position, New_Value)

retract_at will retract the fact (or clause) which has consecutive number Number.
set_at will do more. It will retract the fact on this position and will assert in the same place the fact Fact.
With modify_at you can change one fact without retracting it. You have to specify the Number of the fact, the Position of the variable which you want to change and the new value with which to modify.

The old and the new values of the modified variable have to be a special type. This mean that you cannot change a free variable with number and vice versa but you can change integer with a string.

Position of the modified variable is the zero based index of the position of this variable in the fact. For example, in the fact p(a, X, f(X,Z) , b, 7, Y, Z) X has position zero, Z has position one and Y has position three. The position two is occupied by a variable which value is 7 and this is the only variable in this fact which may to be modified because other are free.

The predicate modify_at is very efficient and is very convenient for work with large databases.

The following example prints all facts which are similar to p(X, f(Y)) in the database:

?-
p(X, f(Y)),
R is on_the_last_step(s), % try with "a" and with "e"
write(R), nl,
the_head_of(R, X),
writeq(X), nl,
fail.

p(A, f(A)).
p(A, f(B)).
p(X, f(a)).

The following example increments the value of the first (position 0) argument of all predicates similar to p(N, 5) (and unifyable with it). Look at System List (in menu Tools) to see the result of the execution of this example.

?-
p(N, 5),
R is on_the_last_step(s), % try with "a" and with "e"
write(R), nl,
modify_at(R, 0, N+1),
fail.

p(1, 5). % OK
p(2, 5). % OK
p(A, 5). % A is not a special type
p(X, X). % X is not a special type
p(1, 6). % this is not unifyable with p(N, 5)

Look at the example:
AI 2.spj (in folder AI)


draw_bitmap
Entity: predicate

Usage:
draw_bitmap(X, Y, Bitmap, _, _)
draw_bitmap(X, Y, Bitmap, Xs, Ys) - this usage is not working at the moment

Draws a Bitmap image at a specified point (X, Y).

X x co-ordinate of the point
Y y co-ordinate of the point
Bitmap a bitmap object
Xs x co-ordinate of the new size - this is not working at the moment
Ys y co-ordinate of the new size - this is not working at the moment

Examples:
?-
...
Bitmap is bitmap_image("image.bmp", _),
draw_bitmap( 10, 10, Bitmap, _, _).

See also:
bitmap_image


draw_point
Entity: predicate

Usage:
draw_point(X, Y, Color)

Draws a point or takes the color of a point which is at co-ordinates (X, Y).

X | x co-ordinate of the point
Y | y co-ordinate of the point
Color | if Color is integer then sets the color of the point (X, Y) to this color if Color is free variable then takes the color of the point (X, Y) and puts its value in the variable Color.

Examples:
?-
...
draw_point(10, 10, rgb(0, 0, 0)),
draw_point(10, 10, Take_Color),
write("The color of this point is " + Take_Color).

See also:
rgb

Examples:
draw_point.pro


e-mail

E-mail predicates

Strawberry Prolog supports e-mail predicates.

For UNIX use the predicate:

s_mail(To, Name, Email, Subject, Mail) which sends Mail to recipient To , from Name with Email . (ONLY for UNIX)

To use e-mail predicates with MS Windows you need to install your Windows Messaging System (Inbox ). You have to configure your own profile in it. The name of this profile will be used to log in the messaging system by the predicate logon(Profile, Password) . The variable Profile has to be instantiated with a string which contains the name of your profile that you configured in the Inbox. If your profile is configured with password then the variable Password should contain it (as a string). If you do not set up a password then the variable Password can be the empty string ( "" ). When the predicate logon will be executed then you will be asked for the password of your e-mail account (this will not happen if you set your e-mail account password in the Inbox).

How to install Microsoft Exchange.

To log out from the messaging system use the predicate logoff .

To send e-mail use send_mail(Address, Subject, Mail) . Here all three variables have to be instantiated with strings. The Address has to contain the e-mail address of the recipient or a name from the address book. The Subject has to contain the subject of your e-mail. The Mail have to contain the text of your e-mail.

To read new e-mail use read_new_mail(From, Subject, Mail) . Here all three variables have to be not-instantiated and they will be instantiated with strings. The From will contain the e-mail address of the sender of the e-mail. The Subject will contain the subject of the e-mail. The Mail will contain the text of the e-mail. After execution of this predicate the message will be marked as read. If there are not any new messages the predicate will fail.

Examples:

E-mail


ellipse
Entity: predicate

draw_chord
Entity: predicate

draw_pie
Entity: predicate

draw_arc
Entity: predicate

Usage:
ellipse(X1, Y1, X2, Y2)

Draws an ellipse bounded by the rectangle with the upper left corner ( X1,Y1 ) and the lower right corner ( X2,Y2 ). The border line is drawn using the current pen , and the ellipse is filled using the current brush .

Usage:
draw_chord(X1, Y1, X2, Y2, Px, Py, Qx, Qy)

Usage:
draw_pie(X1, Y1, X2, Y2, Px, Py, Qx, Qy)

Usage:
draw_arc(X1, Y1, X2, Y2, Px, Py, Qx, Qy)

These predicates draw a chord, a pie and an arc respectively. First four arguments give ellipse bounded by the rectangle with the upper left corner ( X1,Y1 ) and the lower right corner ( X2,Y2 ). The next four arguments give two radial's endpoints ( P and Q ). If the P and Q are the same then an ellipse will be drawn. If you want the other part of the figure (not the one drawn) then replace P and Q . The border line is drawn using the current pen , and the figure is filled (only for chord and pie ) using the current brush.

All these predicates fail if any of their arguments is not a number.

Example:

?-window(_, _, win_func(_), "Ellipse demo", 100, 100, 200, 200).

win_func(paint):-ellipse(0,0,200,200).

See also:


embed_server
Entity: predicate

Usage:
embed_server( )
embed_server(Arg1, ... , ArgN)

Creates an embeded ActiveX control.

Put inside the brackets only these arguments which you need. All other arguments will be set by default. The arguments may be any of the following (the order is not important).
handle(Handle) | handle to this ActiveX control.
parent(Parent) | handle to the parent window.
class(Events_func) | predicate which will proceed the events from the ActiveX server
pos(X,Y) | coordinates of upper left corner
size(Width, Height) | size of the ActiveX control
server(Server) | Server Object or Server Name or Server Class ID
cp(ConnectionPoint) | The name of the connection point which events you want to receive. Use _ if you want to receive the events from all connection points.

This predicate is similar to the predicate button but it embeds ActiveX object instead of a button.

If you have OLE server (ActiveX object) which is created by the function server you can use the predicate embed_server in order to embed this OLE server in a window. In this case, the Server has to be a server object. If you use arguments Events_func and ConnectionPoint you will change the values which were set at the time of creation by server function.

This use of the predicate embed_server is shown in the sample Media Player.spj.

If you have not created OLE server yet you can create it and embed it in a window by the predicate embed_server. In this case the arguments Server, Events_func and ConnectionPoint are similar to the arguments of server function.

This use of the predicate embed_server is shown in the sample IE.spj.

See also:
OLE and ActiveX
server, close
. (point)
raise_event
window

Examples:
Media Player.spj
IE.spj
OLE


enable_window
Entity: predicate

Usage:
enable_window(Window, Mode)

Enables/Disables a window object

Window window object
Mode 1 - enabled, 0 - disabled

Examples:
?-
window( Win, _, win_func(_), "Enable Demo", 100, 100, 300, 200),
enable_window(Win, 0).


execute
Entity: predicate

Usage:
execute(Program)

Starts the execution of another extern program (usually *.EXE)

Program have to be a string containing a command line, i.e. path, file name and optionally program parameters.

Examples:

?- execute("C:\MSOffice\Winword\Winword.exe ").
?- execute("C:\MSOffice\Winword\Winword.exe Document.doc").


file I/O

writef
Entity: predicate

readf
Entity: function

readln
Entity: function

feof
Entity: predicate

Usage:
writef(FILE, String)
writes the String in the FILE .

Usage:
String is readf(FILE)
read the String from the FILE .

Usage:
Line is readln(FILE)
reads a Line from the FILE .

Usage:
feof(FILE)
checks for a end-of-file.

See also:


file manipulation

set_current_directory
Entity: predicate

get_current_directory
Entity: function

create_directory
Entity: predicate

remove_directory
Entity: predicate

delete_file
Entity: predicate

move_file
Entity: predicate

Usage:
set_current_directory(Dir)

sets the current directory. If Dir is free variable than the directory of the running program is set, i.e. the directory of the PRO or SPJ file.

Usage:
Dir is get_current_directory()

retrieves the current directory.

Usage:
create_directory(Dir)

creates a new directory.

Usage:
remove_directory(Dir)

removes a directory.

Usage:
delete_file(File)

deletes a file.

Usage:
move_file(File1, File2)

Moves the file File1 into the file File2

File1 string representing the path to a real file that will be moved
File2 string representing the path to the new file name

See also:


findall
Entity: predicate

Usage:
findall(X, Goal, Xlist)

Here X can be any term (usually variable) and G has to be an atomic goal (usually including X ). After the execution of this predicate in Xlist will be a list of the values for X in all successes of Goal . The difference between of and findall predicates is that the first one ( of ) succeeds as many times as Goal succeeds and every time it returns one value for X . The second one ( findall ) succeeds exactly once and returns in Xlist the list of all values for X . The length of this list is equal to the number of the successes of Goal (and also of of ).

Example:

?- findall(X, p(X), Xlist), write(Xlist).

p(a).
p(b).
p(c).


first_ASCII
Entity: function

Usage:
R is first_ASCII(String)

Here String has to be string. This function returns an integer whose value is equal to the ASCII code of the first character of the string. If the symbol is not in the ASCII table its code is bigger than 127 and the result of this function will depend on the default char set.

Note. Symbols which are in the ASCII table have codes from 0 to 127 and these codes are the same for all char sets. So, for these symbols the default char set is not important.

If the default char set is Unicode first_ASCII will return the Unicode number of the first symbol.

If the default char set is not Unicode first_ASCII will return integer between 0 and 255 whose value is equal to the code of this symbol in the default char set.


Floating point functions

R is sin(X) calculates the sine function
R is cos(X) calculates the cosine function
R is tg(X) calculates the tangent function
R is arcsin(X) calculates the arcsine function
R is arccos(X) calculates the arccosine function
R is arctg(X) calculates the arctangent function
R is sinh(X) calculates the hyperbolic sine function
R is cosh(X) calculates the hyperbolic cosine function
R is tgh(X) calculates the hyperbolic tangent function
R is sqrt(X) calculates the square root
R is log(X) calculates the natural logarithm
R is log10(X) calculates the logarithm with base ten
R is exp(X) calculates the exponent function


for
Entity: predicate

Usage:
for( I, A, B),
for( I, A, B, step(Step))

Makes a loop in which the value of I is moving between A and B with step Step. If Step is missing then the default step is one.

I starts from A and it last value is =< B if step is positive and is >= B if step is negative.

Example:

?- for( I, 10, 1, step(-1)), write(I), write(" "), fail.

This example will write:

10 9 8 7 6 5 4 3 2 1 No

See also:

repeat


ftruncate
Entity: predicate
(ONLY for Professional edition in UNIX/Linux)

Usage:
ftruncate(File, Size)

Truncates the file File to the specified size Size

File a string representing a path to a specified file
Size the new size of the file

Examples:
?-
ftruncate("test.txt", 1024).


functor predicate

functor
Entity: predicate

Usage:
functor(Term, F, A)

Extracts or checks functor's name and arity
Term | term of the form f(....)
F | unifies with the functor name f as atom
A | a number which unifies with functors arity

See also:


select_file

get
Entity: function

put
Entity: predicate

Usage:
What is get(File, Length)

Serializes variable What, using the file with handle File from which getting several bytes (how much depend of Length).

Usage:
put(What, File, Length)

Serializes variable What, using the file with handle File in which putting several bytes (how much depend of Length).

If Length is int8 then gets/puts one byte (the value has to be between 0 and 255).
If Length is int16 then gets/puts two bytes (the value has to be between 0 and 65,535).
If Length is int32 then gets/puts four bytes.
If Length is int64 then gets/puts eight bytes.
If Length is float32 then gets/puts four bytes in float format.
If Length is float64 then gets/puts eight bytes in float format.

Remark: The use of get and put will move the file position (you can change its value by the predicate set_file_pos).

See also:


get_check_box_value
Entity: function

set_check_box_value
Entity: predicate

Usage:
Mode is get_check_box_value(ChBox)
set_check_box_value(ChBox, Mode)

Gets/Sets the value of a checkbox

ChBox checkbox object
Mode checkbox value (1 - checked, 0 - not checked)

Examples:
?- set_check_box_value(ChBox, 1),
Mode is get_check_box_value(ChBox).

See also:
check_box


get_client
Entity: function

Usage:
ClSock is get_client(SrvSock)

Returns a client socket of the remote host which has made a connection to the server socket SrvSock

SrvSock server socket object

Examples:
?- SrvSock is server_socket("localhost", 8080),
...
ClSock is get_client(SrvSock)

See also:
server_socket


get_date
Entity: predicate

Usage:
get_date( Day / Month / Year )

Gets current date. The arguments have to be not-instantiated (to receive the date) or to contain a date information to be compared with the current date.

Example:

?- get_date(Day/Month/Year), Str is "Today is " + print(Day), write(Str), nl.

or:

?- get_date(Date), write("Today is "), write(Date), nl.

Look at examples:

E-mail


get_program_argument
Entity: function
(ONLY for Professional edition).

Usage:
Arg is get_program_argument(N)

Gets the N-th argument passed to the executing program (N=0 is the program name (strawberry) , N=1 is the prolog file (test.pro), N=2 is the first argument passed to the prolog file, etc). Fails if there is no such argument

N - an integer number representing the corresponding
argument passed to the prolog program

Examples:

./strawberry test.pro "First Arg" "Second Arg"

?- Arg is get_program_argument(2),
write(Arg). % First Arg


get_selected_text
Entity: function

Usage:
Text is get_selected_text(Edit)

Returns the selected text from an edit box

Edit edit box object

Examples:
?-
...
set_selection(Edit, 10, 35),
Text is get_selected_text(Edit),
write(Text).


get_selection
Entity: predicate

set_selection
Entity: predicate

Usage:
get_selection(Edit, From, To)
set_selection(Edit, From, To)

Gets/Sets the selected text into an edit box

From the starting position of the selected text
To the ending position of the selected text

Examples:
?-
...
set_selection(Edit, 10, 35),
get_selection(Edit, From, To),


get_time
Entity: predicate

Usage:
get_time( Hour : Minute / Second)
get_time( Hour : Minute / Second | Milliseconds)

Gets current time. The arguments have to be not-instantiated (to receive the time) or to contain a time information to be compared with the current time.

Example:

?- repeat, get_time(H:M/0), Str is "It is sharply " + print(H) + ":" + print(M), write(Str), nl.

This example waits for sharp time to strike (zero seconds) and then prints it in a message in Output window and stops.


group_box
Entity: predicate

Usage:
group_box( )
group_box(Arg1, ... , ArgN)

Creates a group box.

Put inside the brackets only these arguments which you need. All other arguments will be set by default. The arguments may be any of the following (the order is not important).
handle(Handle) | handle to this group box.
parent(Parent) | handle to the parent window.
class(But_func) | predicate which will receive the messages from this group box.
text(Text) | the text which is on the group box
pos(X,Y) | coordinates of upper left corner
size(Width, Height) | size of the group box
grayed | flag (default off)

Look at group box methods:

This class has not any methods.

See also:
window

Look at the example:
Group Box.spj (in folder Examples)


How to install Microsoft Exchange

(for Windows 98 you need Microsoft OutLook - it is a part of Microsoft Office and also it can be taken separately, The Microsoft OutLook Express which is going standard with Windows 98 is not sufficient.)

1. Click the Add/Remove Programs option in Control Panel, and then click the Windows Setup tab.
2. In the Components list, click Microsoft Exchange, and then click the Details button.
3. In the Microsoft Exchange dialog box, click Internet Mail, and then click OK.

Having installed Internet Mail you must add it as an information service to a Microsoft Exchange profile.

II. How to add it as an information service to a Microsoft Exchange Profile and configure it

1. Double-click the Mail and Fax icon in Control Panel, then click a profile.
2. In the Services dialog box, click the Add button.
3. In the Add Service to Profile dialog box, click Internet Mail, and then click OK.
4. Type your full name and your electronic mail name in the Personal Information box which appears on the screen.
5. Type the following information in the Mailbox Information box:
- Internet Mail Server
- Account Name
- Account Password (if you miss the Password the system will ask you to enter your password when you want to log on)
6. Click the Advanced Options button if the POP3 server is different from the SMTP server.
In the Advanced Options dialog box type the name of the SMTP server used to send outbound messages and click OK. If you have a DNS server you can type a domain name. Otherwise you must type an IP address.
7. In the General property sheet, click the Message Format button to specify the character sets and the format of the outgoing messages.
8. Click the Connection tab and define whether the computer connects to the Internet server through a LAN connection or a modem connection.

If this information proves to be insufficient it is recommended to use quoted book: "Windows 95 Resource Kit"


I/O predicates

write
Entity: predicate

writeq
Entity: predicate

nl
Entity: predicate and constant

Usage:
write(X)

Calculates the expression X and writes the result to the standard output.

Usage:
writeq(X)

Writes quoted term X to the standard output. X is not calculated even if it is an expression.

Usage:
nl
S is nl

As predicate prints a new line (carriage return). As constant returns the string "\n" (i.e. the new line string).

See also:


is
Entity: predicate

:=
Entity: predicate

has_to
Entity: predicate

Usage:
X is Y
X := Y
X has_to Y

The predicates is, := (colon equal) and has_to (unstable assignment) calculate the expression Y and bound it with the variable X. The predicates := and has_to can also be used to set the value of elements of array (example: array(N) := Y) or to set properties of OLE server (example: Server.property := Y).

Where is the difference?
The evaluation := (colon equal) is the simplest one. It simply throws out the old value of the variable X and sets its new value to the value of the expression Y. The effect of this evaluation will remain after backtracking (i.e. it is stable on backtracking). So := works in the same way as the normal evaluation which you have in common programming languages like C and Basic. This evaluation is not typical for Prolog where you usually make calculations with backtracking. Anyway, this predicate is useful because it gives you the possibility to keep some values after the backtracking (usually you keep these values in global variables or in arrays).

More typical for Prolog are the evaluations is and has_to because after the backtracking they will return the previous value of X. This will give you the possibility to make calculations with backtracking. Usually in one Prolog program you are looking for the answer by searching in the tree of all possible answers (name of this tree is the SLD tree). When you find answer in the SLD tree you will like to see only this answer and the effect of the program to be the same as if it found this answer directly without wandering in the SLD tree. So, if you make calculations you will like to see only the result of these calculations which were made on the right path. All calculations which were made on the wrong (backtracking) paths should be ignored. So this will be the effect if you use the evaluation is or has_to.

The difference between is and has_to is that is requires from X to be free variable in order to bind it with the value of Y. On the contrary, has_to does not need this because it will ignore the old value of X and will replace it with the value of Y (in the same way as := is doing). Anyway, has_to is different from := because after backtracking has_to will restore the old value of X district from :=, which will not do anything on backtracking.

How does has_to set property of OLE server. First, it calls the method GET in order to get the old value of the property. After that, it calls method SET in order to set the new value. After that, on backtracking, it calls the method SET again in order to restore the old value.

The evaluation has_to is typical for Strawberry Prolog. It is in some sense between is and :=. In some sense has_to is more powerful than is because it can change the old value of the variable X. For example, if you want to make a counter which is restored after backtracking you cannot use is because C is C+1 will fail but C has_to C+1 will work as a counter whose value is restored after backtracking. A good example of the use of has_to is the Sudoku.pro game where has_to is used in order to generate the Sudoku task.

Which one of these three evaluations to use?
If you don't know which one or if it doesn't matter which one use the predicate is. This is the most typical Prolog evaluation and very often it gives the result that the program works despite the fact that we do not know why. In other programming languages you cannot make a program which works accidentally but in Prolog it is possible and this is the main advantage of this language.

Example for has_to (Try to replace has_to with := and with is.)

?- s(X), X=a, s(X), X has_to b, s(X), fail.

s(X).

s(X) :- write(X), nl, fail.


line
Entity: predicate

fill_polygon
Entity: predicate

Usage:
line(X1, Y1, X2, Y2, ... , Xn, Yn)

Draws a line from X1,Y1 to Xn,Yn using the current pen .

fill_polygon(X1, Y1, X2, Y2, ... , Xn, Yn)

Draws a polygon using the points from X1,Y1 to Xn,Yn with the current pen and fills it with the current brush.

All these predicates fail if any of their arguments is not a number.

Example:

?-window( _, _, win_func(_), "Line demo", 100, 100, 300, 300).

win_func(paint):-
pen(2,rgb(255,0,0)),
brush(rgb(0,0,255)),
fill_polygon(0,0,200,200,0,100+100),
line(0,0,200,0,200,100+100).

See also:


list_box
Entity: predicate

Usage:
list_box(Handle, Parent, List_func, Lable, X, Y, Width, Height)

Creates a list box control.
Handle | handle. Use _ if you don't need it.
Parent | handle of the parent window. Use _ for default.
List_func | predicate which will receive edit messages
Lable | the label of the firs column
X,Y | coordinates of upper left corner
Width, Height | size of the window

Look at list box methods:

R is get_list_text(List_Box, Position)
R is get_list_length(List_Box)
R is get_list_selected(List_Box)
insert_list_item(List_Box, Position, Text, Icon)
delete_list_item(List_Box, Position)
clean_the_list(List_Box)
set_list_icons(List_Box, Type, Icon1, Icon2, ...)
add_list_column(List_Box, Where, Label, Wide)
set_list_label(List_Box, Where, Position, Text)

change_style
You can use this predicate to change the stile of your List_Box. The information which you need for this is how bits in the style are connect to list box features.

Here is the list of important bits:
4 | single selection | set
0x200 | in place edit |
0x4000 | column header |

bits 1 and 2 are responsible for view style:
0 | Icon |
1 | Report | set
2 | Small |
3 | List |

in place edit
If you want to support in place edit then you should to set this style (it is not set by default) and to proceed the message edit(Item, Text). This message is send when some one tries to edit the label of some of the list items and contain the handle of the edited item and the new text. The following example shows how this can be done:

?-
window( _, _, win_func(_), "List Demo", 100, 50, 370, 420).

win_func(init) :-
list_box(G_List_Box, _, list_func, "Name", 10, 10, 150, 350),
change_style(G_List_Box, 0, 0, 0x200),
insert_list_item(G_List_Box, end, "First", _).

list_func(edit(Item,Text)):-
yes_no("List Demo","Are you sure that you want to change this text.", ?),
set_list_label(G_List_Box, Item, 0, Text).

See also:
list box methods
window

Look at the example:
List Box.spj (in folder Examples)


List Box Methods

get_list_text, get_list_length, get_list_selected
Entity: functions

insert_list_item, delete_list_item,
clean_the_list, set_list_icons,
add_list_column, set_list_label
Entity: predicates

Usage:
R is get_list_text(List_Box, Position)
R is get_list_length(List_Box)
R is get_list_selected(List_Box)
insert_list_item(List_Box, Position, Text, Icon)
delete_list_item(List_Box, Position)
clean_the_list(List_Box)
set_list_icons(List_Box, Type, Icon1, Icon2, ...)
add_list_column(List_Box, Where, Label, Wide)
set_list_label(List_Box, Where, Position, Text)

List Box

In all list box functions and predicates you have to specify (in List_Box) which list box have to be used.

Text is get_list_text(List_Box, Position)
Returns the text which is at the position Position.

Number is get_list_length(List_Box)
Returns the number of items which are in List_Box.

Position is get_list_selected(List_Box)
Returns the position of the selected item in List_Box. If there is not any item selected then this function fails.

insert_list_item(List_Box, Position, Text, Icon)
Inserts item at Position with label Text and icon Icon.

Position has to be an integer number or "end".

The Icon has to be the number of the icon in the list of icons (look at set_list_icons). Of course, the argument Icon will have sense only if you provided a list of icons. If you don't want any icon then you can leave this argument a free variable (_).

delete_list_item(List_Box, Position)
Deletes the item which are on the position Position.

clean_the_list(List_Box)
Deletes all items in the List_Box.

set_list_icons(List_Box, Type, Icon1, Icon2, ...)
Attach to the List_Box a list of icons. The list box needs two lists of icons to put them at the items (with small and with big size). Type can be "b" or "s". The first mean that follows a list of big icons (32X32). The second mean that follows a list of small icons (16X16). Icon1, Icon2, ... have to be strings containing file names of ICO files.

After list of icons is attached you can use its icons in predicates like insert_list_item where Icon is the number of icon in this list.

add_list_column(List_Box, Where, Label, Wide)
When the list box is in Report view (which is the default one) then you can see columns with text. As default you see only one column which is with the names and icons of the items but using this predicate you can add more columns. Here Where is the number of the new column (from left to right). Label is a string with column label. Wide is integer which gives the wide of the column.

set_list_label(List_Box, Where, Position, Text)
When you have new column (look at add_list_column) then you will like to put some information in it. For this you need this predicate. Here Where is the number of the column, Position is the number of the item in front of which you want the text to be placed and the Text is a string containing the text.

Look at the example:
List Box.spj (in folder Examples)


list_length
Entity: function

Usage:
N is list_length(List)

Here List has to be a Prolog list, i.e. normal list ending with the empty list. This function calculates and returns the number of the elements of List .

Example:

?- N is list_length([1,2,3]), write(N), nl.


Main predicates

Control predicates:

op defines an operator
true always succeeds
fail always fails
once executes a goal, but it is not re-executable
call starts a goal
! (cut) partially restricts the backtracking
; (or) executes the left goal and if fails or on Next Answer executes the right one
-> (if-then-else) if the most left goal succeeds then executes the next goal, if it fails then executes last goal.
not Prolog negation
functor checks a functor's name and arity
findall makes a list of all success

Strawberry functions:

of that X which satisfy Y
count_successes count the successes of a goal
function if then else function if-then-else
list_length returns the length of a list
true_value returns one or zero
min returns the minimum
max returns the maximum

Loops predicates:

repeat always tries to get one more answer
for doing a loop

Execution control:

trace switches program execution to trace mode
terminate terminates the program and displays a message
execute starts the execution of other program (usually *.EXE)
shell_execute opens a file by using it extension.
not_deeper_than temporally restricts the stack size

Input and Output predicates:

read reads a term using a dialog box
write writes a term
writeq writes a term (without calculating it)
nl prints a new line
print_file prints formatted file
print_string prints formatted string

Dialogs:

message creates a message dialog box
yes_no opens a dialog box with a yes-no question to be answered

Knowledge base manipulation:

assert appends a clause to the run-time database
assert_in appends a clause both to the run-time database and to the source
asserta appends a clause to the run-time database (in the beginning)
asserta_in appends a clause both to the run-time database and to the source (in the beginning)
retract retracts a clause from the run-time database
retract_in retracts a clause both from the run-time database and from the source
retractall retracts all occurrences of a clause from the run-time database
set retracts a clause and assert another one in place of it

Direct Database Manipulation:

on_the_last_step which was the fact used in the last unification
the_head_of returns the head of the clause by its consecutive number
set_at changes the fact which has this consecutive number
retract_at retracts the fact which has this consecutive number
modify_at modifies the fact which has this consecutive number

File Manipulation:

open opens a file
close closes a file
writef writes the string in a file
readf reads a string from a file
readln reads a line from a file
feof checks for a end-of-file
set_current_directory sets the current directory.
get_current_directory retrieves the current directory.
create_directory creates a new directory.
remove_directory removes a directory.
delete_file deletes a file.
move_file moves a file to a new location
ftruncate truncates a file
get gets a byte, integer or float from a file
put puts a byte, integer or float in to a file
set_file_pos sets the file pointer
get_file_pos returns the position of the file pointer
select_file invokes an open/save file dialog box

Time:

chronometer gets time intervals in milliseconds
get_time gets current time
get_date gets current date
wait waits time interval

Special effects:

=.. makes functor and arguments as a list
beep produces a short beep
cursor sets the cursor to one of the standard cursors

OLE and ActiveX:

server opens an OLE server
server2 opens an OLE server which listen for events
close close OLE server
. (point) sets and gets property, invokes method
embed_server embeds an ActiveX control
raise_event sends information from the sever back to the client

E-mail control:

logon Log on as an e-mail user
logoff Log off as an e-mail user
send_mail send an e-mail letter
read_new_mail reads e-mail letters
s_mail sends mail (ONLY for UNIX)

Prolog CGI Scripts

getenv returns the environment value
get_environment_arg returns a part of a string
get_html_form returns a form field
set_content_type sets the content type
set_cookie sets a cookie on the client's browser
get_program_argument returns the program argument passed from the command line
url_encode encodes into the URL format

Sockets support

socket returns a client socket
read_sock reads a string from the socket
write_sock writes the string in the socket
get_client gets a client socket of the remote host
server_socket creates a server socket

SQL support

mysql_connect opens a connection to MYSQL server
mysql_select_db selects the database from MYSQL server
mysql_query executes the Query on selected database on the MYSQL server
mysql_store_result stores the result from the execution of a query
mysql_fetch_row returns the next row from the MYSQL result
mysql_num_fields returns the number of the fields from returned MYSQL result
field returns a field from a row
mysql_free_result frees the MYSQL result
mysql_eof checks if the end of the result is reached
close closes the MYSQL connection


Message dialog box

message
Entity: predicate

Usage:
message(Title, Text, Icon)

Invokes an application modal dialog box with a single OK button.
Title | the title of the dialog box window
Text | the text inside the window (usually some information to be displayed)
Icon | one of the predefined message icons

Example:

?-
message("Message(..) test", "Sample Message", !),
write("OK"), nl.

See also:


message_flags
Entity: predicate and constant

Usage:
message_flags(Flag)
Flags is message_flags

This predicate is to be used with the messages like key_down, mouse_click, mouse_move and mouse_wheel. With this predicate you can check what was the status of the left, middle and right mouse button and on Ctrl, Alt and Shift buttons on the keyboard at the moment the message was sent.

For mouse buttons the argument Flag has to be:
left, middle or right.

For keyboard buttons it has to be:
shift, alt or ctrl.

For messages key_down and key_up the argument Flag has to be:
function (i.e. functional key)
before (for the previous state of the key - pressed or not)
state (for the transition state of the key)

If you use message_flags as a constant its value will be a number which represents all these flags.

Example:

win_func(mouse_move(X, Y)):-
message_flags(left),
beep.

See also:
Messages

Look at the example:
Fractals.pro (in folder Programs)


Message icons

! - Asterisk

? - Question

s - Stop

i - Information

n - no icon

These icons are displayed along with the text in the message dialogs such as yes_no and message .


Messages

When a user interface element (window, control, menu) is created, a special predicate must be defined to handle incoming messages.

The first argument of such a predicate is a message name. Presently this can be one of the following:
init sent upon window creation. It is sent before the first paint message. The init message is useful for creation of menus and buttons.
paint the window has to be redrawn. This message is sent every time some part of the window's client area needs to be redrawn. See also paint_rect.
close someone tries to close the window. If the window's function does not process this message or fails while processing the window will close, otherwise it will not close (sample Sun.spj).
size(X, Y) the window changed its size and the new size of its client area is X, Y.
char(Char, Repetition) this message is sent when a character is pressed in the window focus (i.e. when the window is topmost). It has two parameters: Char is a string with length one which only character is the one pressed. Repetition is integer which says how many times this char was pressed (if you keep the button down then Repetition can be bigger than one). If you want to catch a special key like the arrows then use the message key_down.
key_down(CharCode, Repetition) this message is sent when a key is pressed in the window focus (i.e. when the window is topmost). It has two parameters: CharCode is an integer which is equal to the code of the pressed key. Repetition is integer which says how many times this key was pressed (if you keep the button down then Repetition can be bigger than one). See also message_flags.
key_up(CharCode) The same as key_down message with the difference that it is sent when the key is released. Also key_up does not have a Repetition parameter.
mouse_click(X, Y)
mouse_click_up(X, Y)
r_mouse_click(X, Y)
r_mouse_click_up(X, Y)
mouse clicked at coordinates X, Y inside the client area. There are four messages, respectively for left and right mouse button and for down and up click. Here r_ stands for right button and _up stands for releasing the key. See also message_flags.
mouse_move(X, Y) The mouse is moved and the new coordinates are X, Y (in the client area). See also message_flags.
mouse_wheel(Delta, X, Y) The mouse wheel is rotated on Delta steps. This message is sent to the window which has the focus even if the mouse cursor is out of the client area of the window. X and Y are the current coordinates of the mouse cursor (in the screen). Coordinates X, Y are given toward to the upper left corner of the screen. Use the predicate client if you want to transfer screen coordinates to the coordinates in the client area. See also message_flags.
scroll(Direction, Type, Val) this message is sent to the window when its scroll bar is moved. The argument Direction is horizontal or vertical. The argument Type is line, page, thumb_track or thumb_moved_to. The argument Val is -1 or 1 if Type is line or page, otherwise it is the new position.
scroll(Type, Val, NewPos) this message is sent to the slider control when it is moved. The argument Type is line, page, thumb_track or thumb_moved_to. The argument Val is -1 or 1 if Type is line or page, otherwise it is the new position. The argument NewPos always is the new position.
press this message is sent to a button or to menu item when it was pressed.
end send after the end of the timer's period. See also set_timer.
edit(Item, Text) this message is sent to a list box or to a tree box when some one edited a label in this box. If you want to accept the changes made by the user then the predicate processing this message should to made this change. For this purpose it receives the new Text and the Item which is changed. This message can be send only if you set to the box the style "in place edit". See also list_box and tree_box.
selected(Item)
unselected(Item)
focused(Item)
unfocused(Item) 		these messages are sent to a list box when some item is selected or unselected or when it receives or loses the focus.

Note: if you do not want to process the messages to some given window, a predicate with no clauses for it should be declared as the window's function (e.g. fail(_) ).

Note: after the processing of any message the stack is released in the same way as if the code was ended with: !, fail.

See also:
window
paint_rect
message_flags
client
set_timer
list_box
tree_box

Look at the example:
Fractals.pro (in folder Programs)


min
Entity: function

max
Entity: function

Usage:
R is min(X, Y)
R is max(X, Y)

Here X and Y have to be expressions which value is integer or float. The function min will return the value of X if it is smaller or equal to the value of Y otherwise it will return the value of Y . Analogous the function max will return the value of X if it is bigger or equal to the value of Y otherwise it will return the value of Y .

Example:

?- N is max(1,2+2), write(N), nl.


modify_menu
Entity: predicate

Usage:
modify_menu( Menu, N, Status, String )

Here Menu has to be the menu object which you want to modify. If it is _ (underline) then the default (last created) menu is modified. Here N must be an integer expression which gives the number of the menu item which has to be modified (one for the first, two for the second and so on). If you want to change the status of this menu item then the parameter Status has to be one of the following words: normal , checked or grayed . If you want to leave the status the same then put underline in the place of Status . If you want to change the text sting of the menu item then put the new string in String . If you want to leave it the same then put underline in the place of String .

Look at the example Checkers.pro


negation

not
Entity: predicate

Usage:
not(X1, ... Xn)

Prolog negation: Fails if the goal X1, ... Xn succeeds.

If not succeed then this does not mean that the goal is false but only that it does not follow from the rules and the facts which are in the program.

Actually, not can be defined on Prolog and here is one possible definition for this predicate:

not(X) :- X, !, fail.
not(X).

With not are defined many other predicates. For example:

X\=Y :- not(X=Y).

See also

standard control predicates


not_deeper_than
Entity: predicate

Usage:
not_deeper_than(Deep), goal.

Restricts the stack size. If the stack size at the moment of execution of not_deeper_than(Deep) is S then the stack is restricted by S+Deep. All answers and branches of the Proof Tree which fill the stack more than S+Deep will be cut. This mean that will be given only that answers of goal which need less than Deep steps (of course, here we don't count the steps which you lose in backtracking).

You can use this predicate for goals which are cycling. For example, when you prove theorems.

Example:

?- not_deeper_than(10), p(X), write(X), nl.

p(f(X)) :- p(X).
p(a).

This program will search for answers of goal which have a proof tree with less than ten knots.


of
Entity: function

Usage:
R is X of Goal

Here X can be any term (usually variable) and Goal has to be an atomic goal (usually including X ). When you call this function then it calls the Goal and if it succeeds the return value will be the term with which X is bounded after this success. The function X of Y will succeed as many time as Y does.

Example:

?- write(X of p(X)), nl, fail.

p(a).
p(b).
p(c).


op
Entity: predicate

Usage:
op(Priority, Type, Operator)

Operator definition.
Priority | Priority of the operator. Smaller numbers specify higher priority.
Type | Type of the operator.
Operator | Operator sign

Operator types:
fx, fy | prefix unary (the argument follows) e.g. minus X as -X
xf, yf | suffix unary (after the argument) e.g. factorial N as N!
xfx, yfy, xfy, yfx | infix binary (between the arguments) e.g. X+Y, X=Y

x and y letters specify associativity:

x the main operator in the operand must be of higher priority than this operator
y the main operator in the operand must be of higher or equal priority than this operator

Thus yfx denotes an operator which will be evaluated from left to right (such as - or / ), and xfy denotes an operator which will be evaluated from right to left (such as ; ), and xfx denotes an operator which is not associative (it can be placed only between arguments with the main operators of higher priority) such operators are > , < and yfy denotes an operator which is right and left associative (such as + or * ).

If you want to use an operator in the source then it should be defined as an axiom which is before the row where you want to use it or you can put the op operator in the body of a clause but in the second case this definition will take effect only after that this clause is executed.

The list of defined operators is available in Help/Operators. The operators are defined after compilation or after syntax colouring.

There are special types fxx, xxf, xfxx and xxfxx which can be used only for operators whose priority is lower than the priority of comma (i.e. with priority number bigger than 1000). Here xx shows that the operator expects a list of terms separated by commas instead of a single argument.

The operator :- is of type xfxx and that is why the expression H:-A, B will be read as ':-'(H, A, B) not as ':-'(H, [A, B] ) as if it was of type xfx. The expression H:-A will be read as ':-'(H, A) no matter whether the type of :- was xfxx or xfx.

The operator ?- is of type fxx and that is why the expression ?-A, B will be read as '?-'(A, B) not as '?-'( [A, B] ) as if it was of type fx. The expression ?-A will be read as '?-'(A) no matter whether the type of ?- was fxx or fx.

The operator ; is of type xxfyy and that is why the expression A; B will be read as ';'( [A], [B] ) not as ';'(A, B) as if it was of type yfx. The expression A, B; C, D will be read as ';'( [A, B], [C, D] ) no matter whether the type of ; was xxfyy or xfy.


open file

open
Entity: function

close
Entity: predicate

Usage:
FILE is open(FileName, Mode)
close(FILE)

Opens/closes a file
close can be used to close a file or OLE server or a socket or MYSQL connection
FILE | variable to accept file handle
FileName | file name with the path
Mode | the mode can be: "w" - writing (erases the old file), "w+"- writing (over the old file), "r" - reading, "r+"- reading and writing, "a" - appending (creates a new file if it does not exist), "a+"- appending (the file must exist), "b" - binary (cannot be used alone, add it on the end like "rb")

See also:


paint_rect
Entity: predicate

Usage:
paint_rect(X1, Y1, X2, Y2)

This predicate is for use with the message paint. With this predicate you can check which is the rectangle which needs to be repainted. In this way you can optimise the processing of message paint and to repaint only this part of the window which needs to be repainted instead of repainting the entire window's client area.

If arguments are not instantiated paint_rect(X1, Y1, X2, Y2) will return in variables (X1, Y1, X2, Y2) left-top and right-bottom corners of the smallest rectangle which includes the area which needs to be repainted.

If arguments are instantiated then paint_rect(X1, Y1, X2, Y2) will make a check if the rectangle (X1, Y1, X2, Y2) overlaps with the area which needs to be repainted (this will give you the possibility to determine more precisely this area).

Example:

win_func(paint):-
paint_rect(X1, Y1, X2, Y2),
rect(X1, Y1, X2, Y2).

See also:
Messages

Look at the example:
Fractals.pro (in folder Programs)


parent
Entity: function

Usage:
P is parent(W)

Returns the parent window of W in P. Succeeds if W is a valid window handle. You can use the anonymous variable as argument to specify the default window.

See also:


pen
Entity: predicate and function

Usage:
pen(PenWidth, Color)
Pen is pen(PenWidth, Color)

Gets/sets the current pen color and line width.
PenWidth | line width in pixels (put zero for transparent pen).
Color | integer containing a color, you can use rgb to create such integer.

If some of the arguments are not-instantiated variables, they take the current values. Otherwise their values are set.

Example:

?-window( _, _, win_func(_), "Pen Demo", 100, 100, 200, 200).

win_func(paint):-
pen(1, rgb(255,0,0)),
line(0,0,200,200),
pen(5, rgb(0,0,255)),
line(0,200,200,0).

See also:


. (point)
Entity: operator

Usage:
X is Server.Property
Server.Property := Value
R is Server.Method(Arg1, ... , Argn)
Server.Method(Arg1, ... , Argn)

Use the operator point in order to get and to set properties and to invoke methods.

The first argument of the point has to be object of type server. Use the function server to obtain such object. The second argument of the point has to be a property name or a method name followed by the arguments of the method.

The name of the property or of the method can be given as an atom or as a string. For example, in order to call the method Method it does not matter whether you use Server.'Method'() or Server."Method"() but anyway, we recommend to use atoms because this will make your program more readable. Also, if the name of the method begins with a small letter we can miss apostrophes. For example, Server.'method'() and Server.method() are the same.

If you want to get property this can be done by the operator point. You can put in any expression Server.Property where Server is object of type server and Property is the atom or the string which contains the name of one of the properties of this server. You may look for the names of these properties in the Object Browser.

If you want to set property then it is easy again. Simply type this:

Server.Property := Value

Here Value has to be this value which you want to set to this property. Here as you see := can be used to set property. Of course, this operation is stable on backtracking.

If you want to invoke method then use Server.Method as function or as predicate. What to use (function or the predicate) depends on that do you need the return value of this method.

R is Server.Method(Arg1, ... , Argn)
Server.Method(Arg1, ... , Argn)

Here Server has to be object of type server and Method has to be the atom or the string which contains the name of one of the methods of this server. You can take this name from the Object Browser.

The arguments has to be from the types which this method needs. By default any type is VARIANT. If you want to use input/output argument (i.e. pointer to VARIANT) then put io functor in front of your variable argument (like this: io(X) ). The type VARIANT is standard for OLE and will be OK in the most cases but if you do not want to use it then you can specify another type explicitly (like this: int4(123) ). For such specification you can use one specifier from the following list:

int2
int4
float4
float8
str
dispatch_interface

You can combine any of this specifiers with io (like this: int4(io(X)) which mean that this argument is a pointer to four byte integer). The specifier io has to be closer to the variable than int4. If you change their places then you will receive an error.

Example:

?-
S is server("Server.Name"),
S.'Property':=21,
write(S.'Property'), nl, % writes 21
S.'Method'(A, io(B), int2(C), float4(io(D)) ),
% A : VARIANT
% B : Pointer to VARIANT
% C : Two byte integer
% D : Pointer to four byte float
close(S).

See also:
OLE and ActiveX
Strawberry Prolog as OLE server
server, close
embed_server
raise_event

Examples:
Word.spj
OLE.spj
OLE


Predicate If-then-else

->
Entity: predicate and function

Usage:
A1, ... , An -> B1, ... , Bm else C1, ... . Ck
A1, ... , An -> B1, ... , Bm
R is (G1, ... , Gn -> X else Y)

Predicate:

Usage:
A1, ... , An -> B1, ... , Bm else C1, ... . Ck
A1, ... , An -> B1, ... , Bm

The predicate -> (if-then-else) executes first the left goal A1, ... , An and if it succeeds then executes the middle goal - B1, ... , Bm , if it fails then executes the right goal - C1, ... , Ck . If the right goal is missing then this is the same as if it was the empty goal. In this predicate you can write ; instead of else . This is for compatibility with other Prolog compilers.

If you write:

?-a->b->c;d;e.

then the last ; will be accepted not as a part of if-then-else but as an operator or .

If you want to create more complicated expression with many if-then-else operators in it - then use round brackets - ( and ) .

Like this:

?-a-> (b->c;d);e.

Be careful, in this case, to leave a space between -> and ; and ( , otherwise you can obtain the error No sense .

Look also at the function -> (if-then-else) .

Example:

?-
yes_no("1","",?) ->
(yes_no("2","",?) ->
write(a), nl
else
write(b), nl
)
else (yes_no("3","",?) ->
write(c), nl
else
write(d), nl
).

Function:

Usage:
R is (G1, ... , Gn -> X else Y)

If you use -> as a function then G1, ... , Gn have to be an atomic goals and X and Y have to be any expressions. If the goal G1, ... , Gn succeeds then this function returns the value of the expression X, otherwise returns the value of the expression Y.

Example:

?- write(yes_no("Say","one or two",?)-> 1 else 2).


Predicate OR

;
Entity: predicate

Usage:
A1, ... , An; B1, ... , Bm

The predicate ; (or) executes first the left goal A1, ... , An and if it fails or on Next Answer executes the right B1, ... , Bm .

Remark:
The priority of ; (or) is smaller then the priority of comma.

Remark:
In if-then-else predicate you can use ; instead of else (for compatibility with other Prolog compilers).

Example:

?-
read(X),
(X<2 ; X>3). % true outside from the interval from two to three


press_button
Entity: predicate

Usage:
press_button(W, X, Y)

Presses a button at the coordinates X,Y in the window W (if this window exists and there is a button in it at these coordinates).

See also:


print_file
Entity: predicate and function

print_string
Entity: predicate and function

Usage:
print_file(Formatting_File_Name, Arg1, Arg2, ...)
Result is print_file(Formatting_File_Name, Arg1, Arg2, ...)
print_string(Formatting_String, Arg1, Arg2, ...)
Result is print_string(Formatting_String, Arg1, Arg2, ...)

These predicates (functions) are unique for Strawberry Prolog. If you know the language C then you will notice that these predicates work similarly to the function printf but they are much more powerful than printf. The first argument of these predicates is the formatting string (or file). This string will be worked out after being modified by the arguments. All arguments are strings or numbers.

We will describe the function print_string. The predicate print_string does the same but the result is printed in the standard output instead to be returned as a result. The function and the predicate print_file do the same as print_string but the first argument is not the formatting string but the name of a file which contains this string.

The formatting string is usually in HTML format (or the file is HTML file). That is why the formatting words look like tags. Here is the list of all formatting words and a description on how they affect the output.

<i:Argument>
 Insert - This tag will be replaced with the argument with number Argument. For example <i:2> will be replaced with Arg2.
<x:Argument>
<y:Argument>
 Insert parameters in the link - These tags are the same as Insert, but they are more convenient for inserting parameters into links because they put the symbols ? and & when necessary.

For example: The result of <a href="/home.pro<x:1><y:2><y:3>"> will be <a href="/home.pro?a=1&b=2&c=3"> if Arg1, Arg2 and Arg3 are "a=1", "b=2" and "c=3".

<v:Argument:String>
<e:Argument:Number>
<l:Argument:Number>
<b:Argument:Number>
<p:Argument:Position>
<m:Argument:Mask=Value>
<o:Argument:Condition>
 These tags show the beginning of the area which will be worked out only under certain condition. The end of this area could be represented with the tag <v:Argument> or with the other condition tag with the same Argument. You can nest such areas and to use the tag <i:Argument> inside them.

If you want the opposite condition, use the symbol ^. For example: <^v:Argument> is the opposite of <v:Argument>.

If you want to write a hexadecimal number, use the symbols 0x. For example: <e:1:0x2a> is the same as <e:1:42>.

<v:Argument:String>
 Variant - the area is worked out if the Argument is equal to the String. (Do not put quotes around the string in the tag)
<e:Argument:Number>
 Equal - the same as Variant, but it works only with numbers instead of Strings. For example: <e:1:zero> will return an error, while <v:1:zero> will work fine.
<l:Argument:Number>
 Less than - the area is worked out if the Argument is a number which is less than Number.
<b:Argument:Number>
 Bigger than - the area is worked out if the Argument is a number which is bigger than Number.
<p:Argument:Position>
 Bit Position - the area is worked out if the bit is true. This bit which is at position Position in the number which is in Argument. Here the Position must be between 1 and 64.
<m:Argument:Mask=Value>
 Bit Mask - the area is worked out if the bits of Argument that are defined with a Mask are equal to Value. For example: If Arg1 is 0x10 or 0x110 then <m:1:0x11=0x10> is true but <m:1:0x11=0x11> is not true.
<o:Argument:Condition>
 Boolean Condition - the area is worked out if some Boolean condition is satisfied between the previous tags with the same Argument. The Condition can be one of the following words: some or all.

The text after the tag <o:5:all> is worked out if all tags from the types v, e, l, b, p, m with argument 5 which are before <o:5:all> gave conditions which are true.

Instead the words some and all you can use the words or and and. The opposite condition to all is some not or not all. For example: <o:1:all> is the same as <^o:1:some not>.

The condition some is true if one of the previous conditions is true and its opposite condition is default. For example: <o:1:default> is the same as <^o:1:some>.

Look at the second example below.

<r:Argument>
 Replace - shows the beginning of an area in which the string Argument will be replaced with the string which is in the next argument (i.e. Argument+1 string). The end of area can be shown as <r:>. You cannot nest the replace areas but you can combine them with Insert and Variant tags.
<t:
 Tag - This will be replaced with <. For example if you want to work out <i:1> then you have to insert in the formatting string <t:i:1>.

Example 1:

?- print_string("<r:1> Text <i:3> <r:>", "Text", "Nonsense", "Text").

In output: Nonsense Text

Example 2:

?- print_string("
<b:1:-2><l:1:10><o:1:all> -2 < <i:1> < 10 <v:1>
<^e:1:0><o:1:some> and <i:1> not zero
<o:1:default>This will not be printed <v:1>", -1).

In output: -2 < -1 < 10
and -1 not zero

Look at the example:
print_file.spj (in folder Examples)


radio_button
Entity: predicate

Usage:
radio_button( )
radio_button(Arg1, ... , ArgN)

Creates a radio button control.

Put inside the brackets only these arguments which you need. All other arguments will be set by default. The arguments may be any of the following (the order is not important).
handle(Handle) | handle to this radio button.
parent(Parent) | handle to the parent window.
class(Radio_func) | predicate which will receive the messages from this radio button.
text(Text) | the text which is on the radio button
pos(X,Y) | coordinates of upper left corner
size(Width, Height) | size of the radio button
checked | flag (default off)
grayed | flag (default off)

Look at radio button methods:

R is get_check_box_value(Radio_Button)
set_check_box_value(Radio_Button, Value)

See also:
window

Look at the example:
Radio Buttons.spj (in folder Examples)


raise_event
Entity: predicate and function

Usage:
raise_event(A, B, C)
Result is raise_event(A, B, C)

The communication between the client and the server is normally initiated by the client because he is the master and the server is the slave. The client (the master) calls methods from the server and gets and sets its properties. Anyway, sometimes it is convenient the communication to be initiated by the server. This can be done by the server events. Of course, the server can send such events but there is no guarantee that the client is listening for them. If the client proceeds an event he can return a result to the server. In this way, the server will send information to the client and will receive some information back from him.

The only event which SP server can send to its client is crated by the predicate raise_event. This event looks in the following way: event(A, B, C). Here event is the name of the event and A, B, C are its three arguments. The number of arguments is exactly three. If you need more than three arguments you have to find some way around.

The arguments A, B, C of the event are of type VARIANT so you can use them for different types of data including string, integer and float. It is the same with the Result.

If you want to know the names of the connection points Strawberry Prolog Server has only one connection point and its name is "_IStrawberrySvrEvents".

See also:
Strawberry Prolog as OLE server
server

Examples:
add_server.spj
OLE / Servers


random
Entity: function

Usage:
Return is random(Interval)

Generates in Return a random number between 0 and Interval ( 0 <=Return<Interval ).


I/O predicates

read
Entity: predicate

Usage:
read(Term)
read(Term, String)
read(Term, String, Flag)

reads a term in Term using a standard dialog box. String is displayed in the Title Bar, default value is "Write a term". If Flag is s then reads strings (you do not need to write double quotes). If Flag is t then reads terms (this is the default value).

See also:


rect
Entity: predicate

round_rect
Entity: predicate

Usage:
rect(X1,Y1,X2,Y2)
round_rect(X1,Y1,X2,Y2,Ex,Ey)

Draws a rectangle with coordinates X1,Y1, X2,Y2 using the current pen , and fills it with the current brush . In round_rect the arguments Ex and Ey give the size of the ellipse which is used to make the corners round.

If Ex and Ey are zero then round_rect will be the same as rect . On the other hand if Ex and Ey are too big then round_rect will become ellipse.

Example:

?-window(_, _, win_func(_), "Rectangle demo", 100, 100, 200, 200).

win_func(paint):-
rect(50,50,150,150), round_rect(70,70,130,130,10,10).

See also:


replace
Entity: function

Usage:
R is replace(In, What, With)

Here In, What and With have to be string expressions. This function returns a string which is obtained by replacing in In all occurrence of What with With.


Retract predicates

retract
Entity: predicate

retract_in
Entity: predicate

retractall
Entity: predicate

Usage:
retract(Clause)

Retracts the first clause which is unifiable with Clause .
Clause the clause to retract.

Fails if there is no clause which is unifiable with Clause .

Usage:
retract_in(Clause)

Retracts the first clause which is unifiable with Clause both in the run-time database (like retract) and in the text file containing the running program.
Clause the clause to retract.

Fails if there is no clause which is unifiable with Clause.

Usage:
retractall(Clause)

Retracts all clauses which are unifiable with Clause .
Clause the clause to retract.

Succeeds always.

Example:

?-retract_in(test(X)), write(X), nl, !, test(Y), write(Y), nl, fail.

test(1).
test(2).
test(3).

Run this example four times (press four times F5 ).

See also:


select_color
Entity: function

Usage:
ColorReturn is select_color(ParentWindow, ColorStart)

Invokes a standard select color dialog box using ParentWindow for parent window and ColorStart for start color (selected in the beginning). The new selected color is returned in ColorReturn .
ColorReturn | variable to receive the selected color
ParentWindow | Parent window for the dialog box. Use _ for default.
ColorStart | integer containing a color, you can use rgb to create such integer.

Example:

?-
Color is select_color(_, 0), % 0 is black, 0xffffff is white
brush(Color),
window(_, _, win_func(_), "select_color demo", 100, 100, 200, 200).

win_func(paint) :- ellipse(50,50,150,150).

See also:

rgb


select_file
Entity: function

Usage:
Name is select_file(Type, Title, Filter)

Invokes a standard file dialog box.
Name | variable to receive the file name
Type | type of the dialog box: o = open s = save
Title | dialog box title
Filter | filter to display in file types field

Example:

?-
Name is select_file(o, _, "All files (*.*)\0*.*\0 Some files (*.sm)\0*.sm\0"),
write(Name), nl.

See also:


select_font
Entity: predicate and function

Usage:
select_font(Window, Font, Colour, FaceName, Height)
Font is select_font(Window, Colour, FaceName, Height)

Invokes a standard font dialog box. You can use Font and Colour for its initialisation. Font and Colour also will receive the value of your selection. The name of the font and its size will be returned in the arguments FaceName and Height. Note that the size which you selected in dialog box is not exactly equal to Height but it is proportional to it.
Window | parent window, use _ for default
Font | Variable to receive the selected font. You can use it for initialisation of the dialog box.
Colour | Variable to receive the selected colour. You can use it for initialisation of the dialog box.
FaceName | Variable to receive the name of selected font.
Height | Variable to receive the size of selected font.

Look at examples:

Select Font.spj


server
Entity: function

Usage:
Server is server(ServerName)
Server is server2(ServerName, Events_func, ConnectionPoint)

Opens an OLE server and returns in Server an object of type server which is associated with it. If you want to listen for the events which will come from this server provide Events_func which will proceed these events. If you want to filter the stream of all incoming events you can provide the name of the connection point whose events you want to be proceeded.

ServerName | Server Name (such as "Strawberry.Server.1") or Server Class ID (such as "{ECD21404-C8F2-4202-BDFD-DBCBC7A5063C}")
Events_func | The name of the class which will proceed the events from the server. Use _ or the function server if you do not want to listen for events.
ConnectionPoint | The name of the connection point whose events you want to receive. Use _ if you want to receive the events from all connection points.

If you use _ for ConnectionPoint you can use the global variable G_Connection_Point to take the name of the connection point which is sending the event. If the server has more than one connection point it is better to listen for only one of them because most events are sent to all connection points and if you listen to all of them these events will be duplicated. The servers which have more than one connection point usually have a new and old interface supported in the new and in the old connection point.

When you process events you have to bear in mind that your program will receive the names of the events as atoms. When you call method then you can use atom or string for its name but for events you can use only atoms. For example, in order to call the method Method it will be the same if you use Server.'Method'() or Server."Method"() but if you wait for the event Event then you have to use Events_func::'Event' instead of Events_func::"Event".

Example:
?-
Server is server2("Strawberry.Server.1", on_event, "_IStrawberrySvrEvents"),
wait(10),
close(Server).
on_event::Event( | Arguments):-
write(G_Connection_Point), nl,
write(Event( | Arguments)), nl.

See also:
OLE and ActiveX
Strawberry Prolog as OLE server
close
. (point)
embed_server
raise_event

Examples:
Merlin.spj
Media Player.spj
IE.spj
OLE
OLE / Servers


server_socket
Entity: function

Usage:
SrvSock is server_socket(Host, Port)

Creates and returns a server socket on host Host and on port Port, fails if the socket can not be created

Host the host name (ex. localhost, 127.0.0.1 etc)
Port the port number (ex. 80)

Examples:
?- SrvSock is server_socket("localhost", 8080).

See also:
get_client


set
Entity: predicate

Usage:
set(Pred(Arg1, ... , ArgN))

Retracts all axioms which have predicate symbol Pred and asserts the axiom Pred(Arg1, ... , ArgN) .
Pred | predicate symbol.
Arg1, ... , ArgN | some list of arguments.

Succeeds always.

Example:

?- test(X), write(X), nl, set(test(2)), test(Y), write(Y), nl.

test(1).

See also:


set_clipboard_data
Entity: predicate

get_clipboard_data
Entity: function

Usage:
Text is get_clipboard_data(char_set)
set_clipboard_data(Text, char_set)

Sets/Gets the clipboard data

Use this predicates to transfer data with the clipboard. (The operational system supports a memory buffer for transferring data between different applications. Its name is Clipboard. When you do copy and paste in any program you actually use this buffer).
char_set - integer which is a number of a char set.

The parameter char_set is used to improve the work with Windows 98/Me and with the old applications which were made for Windows 98/Me. Actually, set_clipboard_data sets the text on clipboard in two formats:

The first one is the Unicode format. This format is used from the new applications and on this format parameter char_set has no effect.

The second format is the text format and it will be with this char set which number is in the parameter char_set. So this parameter has to be grater than zero in order to represent text char set. If parameter char_set is zero then it is ignored.

Analogically the function get_clipboard_data returns the text which is stored in the clipboard in Unicode format. If there is no text in Unicode format then it returns the text which is stored in text format. In this case get_clipboard_data function assumes that the char set of this text is that which is given in the parameter char_set. So this parameter is used when the data is stored in the clipboard by old applications which do not support Unicode.

If you do not need the parameter char_set then make it zero. In this case the current char set will be used for the text format if it is not Unicode. If the current char set is Unicode then chat set 2 will be used.

Examples:
?- set_clipboard_data("Test Clipboard", 0),
Str is get_clipboard_data(0),
write(Str).


select_file

set_file_pos
Entity: predicate

get_file_pos
Entity: function

Usage:
set_file_pos(FILE, Position, Flag)

Sets the FILE pointer to the Position from the Flag (Flag=end, Flag=begin)

Usage:
Position is get_file_pos(FILE, Flag)

Returns the position of the FILE pointer from the Flag (Flag=end, Flag= current, Flag= begin)

See also:


set_timer
Entity: function

kill_timer
Entity: predicate

Usage:
Timer is set_timer(Window, Period, Func)
kill_timer(Window, Timer)

Creates/Kills a timer object. This is a generator of periodic events. At every Period seconds this object will generate the end message and will send it to the function Func. The timer has to be assigned to a certain window object Window.

If kill_timer cannot close the timer (maybe because it is closed) then it fails.

Window the window object that the timer will be assigned to
Period the interval of time on which the timer event will be raised (in seconds, use float or integer to specify this period)
Func the event handler
Timer the timer object

Examples:
?-
...
G_Timer is set_timer(_, 5, time_func).

time_func(end) :-
write("Time event"), nl,
kill_timer(G_Timer).


shell_execute
Entity: predicate

Usage:
shell_execute(File)
shell_execute(File, Action)

Opens a File by using of its default extension and performs on it the specified Action . Instead of File you can specify a folder.

The default Action is "open". This is the same as if you double click on the file icon. Other possible Actionsare "print" and "explore".

Examples:

?- shell_execute("Document.doc").
?- shell_execute("Page.html ", "print").
?- shell_execute("C:\Program Files\Strawberry Prolog ", "explore").


size and position

size
Entity: predicate

set_size
Entity: predicate

pos
Entity: predicate

set_pos
Entity: predicate

Usage:
size(Win, Width, Height)
set_size(Win, Width, Height)

Gets or sets the size of the window Win (Use _ for Win to point the current window, use screen for Win to point the screen).

Usage:
pos(Win, X, Y)
set_pos(Win, X, Y)

Gets or sets the position of the window Win (Use _ for Win to point the current window).

See also:
client
window
button


socket

Sockets
(ONLY for Professional edition)

Socket is socket(Server, Port)
returns a client socket on the server "Server" and on port "Port" (ONLY for UNIX)

Server have to be string and Port have to be integer.

String is read_sock(Socket)
reads a String from the Socket.

write_sock(Socket, String)
writes the String in the Socket.


split
Entity: function

Usage:
Part is split(Sting, Separator, Number)

This function splits the String using Separator like a splitting character. The Number gives which part has to be the returned value. For example if Number is zero then Part will be the first part before the first symbol Separator, if Number is one then Part will be the first part after the first symbol Separator and so on. If Separator divides String on N+1 parts (i.e. you can find it N times in the String) and if N<Number then split fails.

Remark: If Number is 0 then split will never fail. In this case it will return some beginning of the String. If Separator is not in the String then split will return the whole string.

Example:

?-
read(S, "Give me a sentence: ", s),
makeList(S, L, 0),
write( L ), nl.

makeList(S, [H|T], Pos):-
H is split(S, " ", Pos), !,
Pos2 is Pos + 1,
makeList(S, T, Pos2).
makeList(S, [], Pos).


SQL

MYSQL
(ONLY for Professional edition)

Connection is mysql_connect(Host, UserName, Password)
opens a connection to MYSQL server on Host using UserName and Password.

mysql_select_db(Connection, DB_Name)
selects the database DB_Name from MYSQL server

mysql_query(Connection, Query)
executes the Query on selected database on the MYSQL server (For example "select * from Table")

Result is mysql_store_result(Connection)
stores the Result from the execution of the Query (ONLY for "select" queries)

mysql_fetch_row(Row, Result)
returns the next Row from the MYSQL Result.

Number is mysql_num_fields(Result)
returns the Number of the fields from returned MYSQL Result.

Field is field(Row, INT)
returns the INT field from the Row.

mysql_free_result(Result)
frees the MYSQL Result.

Number is mysql_num_fields(Connection)
returns the number of the fields returned from executing of a query.

mysql_eof(Result)
checks if the end of the result returned from a query is reached.

close(Connection)
closes the MYSQL Connection.


Standard arithmetic

+ addition
- subtraction
* multiplication
/ division
** exponentiation
// integer division
mod modulo
rem remainder
abs returns the absolute value
sign returns the sign


Standard control predicates

true | always succeeds
fail | always fails
once(Goal) | executes a goal, but it is not re-executable (don't give the second answer)
repeat | always tries to find next answer


string_from_ASCII
Entity: function
Warning: In the Light edition this function is not working with Unicode.

Usage:
S is string_from_ASCII(Char)

Here Char has to be integer expression. This function returns a string with length one which only character is that which ASCII number is Char.


Strings

S is S1 + S2 strings concatenation
R is str_length(S) finds the length of the given string
equal(S1, S2) compares strings with case (the same as =:= )
equal(S1, S2, no_case) compares strings (with no case)
less_than(S1, S2) compares strings with case (the same as < )
less_than(S1, S2, no_case) compares strings (with no case)

For comparing strings you can use also the arithmetic compare predicates. For them look at Comparison


sub_string
string_end
Entity: functions and predicates

Usage:
Sub is sub_string( String, Start, Length )
End is string_end( String, Start, Length )

sub_string( Sub, String, Start, Length )
string_end( End, String, Start, Length )
sub_string_no( Sub, String, Start, Length )
string_end_no( End, String, Start, Length )

The function sub_string returns the substring of String that starts from position Start and has length Length. The variable String has to be instantiated with a string, other variables can be not-instantiated. So, in the general case the function sub_string returns many answers.

The function string_end is the same as sub_string with that difference that it returns only these substrings which are ends.

The predicates are the same as the functions with that difference that you can use them to search for a concrete substring (when the argument Sub (End) is instantiated with a concrete substring). If you want to search without case use the modifications sub_string_no and string_end_no.

By putting data in some of the variables Sub , Start and Length and leaving the others not-instantiated, you can use the predicate sub_string in six various ways:

1. If all variables are instantiated then it checks if the string Sub is substring of String which starts from Start and having length Length . If in this case Length is not instantiated then it receives the length of Sub .

2. If only Sub is instantiated then predicate works as Find . It search for occurrence of Sub in String . Once found, it returns its start position in Start . By backtracking this predicate returns all such start positions (the Sub can occur several times in String ). In Length this predicate returns the length of Sub . If Length is instantiated then checks if the length of Sub is equal to Length .

3. If only Sub is not instantiated then instantiates it with the substring of String which starts from Start and having length Length .

4. If Sub , Start and Length are not-instantiated then returns in them a substring with its start position and length. By backtracking this predicate returns all substrings of String with their start positions and lengths (look at the example).

5. If Sub and Start are not-instantiated, but Length is instantiated then returns in Sub and Start a substring with its start position which has length Length . By backtracking this predicate returns all substrings of String which have length Length .

6. If Sub and Length are not-instantiated, but Start is instantiated then returns in Sub and Length a substring with its length which has start position Start . By backtracking this predicate returns all substrings of String which have start position Start .

Example:

?- sub_string(Sub, "Sub String", Start, Length), write([Sub, Start, Length]), nl, fail.


system_color
Entity: function

Usage:
Color is system_color(Object)

Gets the color of the Object in Color .

Object can be one of the following words:

window for default window color
menu for default menu color
dialog for the dialog face color

Example:

?-
brush(system_color(window)),
window(_, _, win_func(_), "system_color demo", 100, 100, 200, 200).

win_func(paint) :- ellipse(50,50,150,150).


term_to_string

print
Entity: function

printq
Entity: function

scan
Entity: function

Usage:
S is print(T)
S is printq(T)
T is scan(S)

Converts term T to string S or vice-versa. The the argument must be not-instantiated variable.

The difference between print and printq is that if T is an expression then print first calculates it and then converts the result in a string. In the opposite, printq will convert T in a string without calculating it.

For example print(2+2) will return the string "4", while printq(2+2) will return the string "2+2".


terminate
Entity: predicate

Usage:
terminate(Message)

Terminates the execution and writes a message in the Output window.

After this software termination of the program you can force the Interpreter to look for other answers by pressing New Answer (F8 ). Nevertheless the program will not continue from the place where it was stopped. The reason is that the mechanism of backtracking will search for other answers and this one which was terminated would not be found. It is easier to understand this if you imagine that after every terminate(X) there is one fail .

The message which will be written in the Output window depends on the parameter Message .

i) If Message is not-instantiated then the standard message will be displayed: "Software termination."
ii) If Message is a string then this string will be displayed.
iii) If Message is a term then this term will be written.


text_out
Entity: predicate

text_out_size
Entity: function

Usage:
text_out(Text)
text_out(Text, pos(X, Y))
R is text_out_size(Text)

text_out – Draws a rectangle with coordinates X, Y in the default window, with text Text using the current window color_text and color_text_back. The font which will be used is that which is set by the last use of the font command. If pos is not specified then the new text is added after the text printed by the last text_out.

text_out_size – Calculates the width of the text that would be printed by text_out.

See also:


trace
Entity: predicate

Usage:
trace

Stops the execution and switches in to trace mode. By this predicate you can put breakpoints in your program.


tree_box
Entity: predicate

Usage:
tree_box(Handle, Parent, Tree_func, _, X, Y, Width, Height)

Creates a list box control.
Handle | handle. Use _ if you don't need it.
Parent | handle of the parent window. Use _ for default.
Tree_func | predicate which will receive edit messages
X,Y | coordinates of upper left corner
Width, Height | size of the window

Look at tree box methods:

L is get_tree_length(Tree_Box)
S is get_tree_selected(Tree_Box)
R is tree_parent(Tree_Box, Item)
R is tree_child(Tree_Box, Item)
R is tree_next_brother(Tree_Box, Item)
insert_tree_item(Tree_Box, Item_Handle, Parent, After,
Text, Icon1, Icon2)
delete_tree_item(Tree_Box, Item)
get_tree_item(Tree_Box, Item, Text, Icon1, Icon2)
set_tree_item(Tree_Box, Item, Text, Icon1, Icon2)
clean_the_tree(Tree_Box)
set_tree_icons(Tree_Box, Icon1, Icon2, ...)

change_style
You can use this predicate to change the stile of your Tree_Box. The information which you need for this is how bits in the style are connect to list box features.

Here is the list of important bits:
1 | buttons (for opening of the item with children) | set
2 | lines (connecting items) | set
4 | root lines | set
8 | in place edit |

in place edit
If you want to support in place edit then you should to set this style (it is not set by default) and to proceed the message edit(Item, Text). This message is send when some one tries to edit the label of some of the tree items and contain the handle of the edited item and the new text. The following example shows how this can be done:

?-
window( _, _, win_func(_), "Tree Demo", 100, 50, 370, 420).

win_func(init) :-
tree_box(G_Tree_Box, _, tree_func, _, 10, 10, 150, 350),
change_style(G_Tree_Box, 0, 0, 8),
insert_tree_item(G_Tree_Box, _, root, first, "First", _, _).

tree_func(edit(Item,Text)):-
yes_no("Tree Demo","Are you sure that you want to change this text.", ?),
set_tree_item(G_Tree_Box, Item, Text, _, _).

See also:
tree box methods
window

Look at the example:
Tree Box.spj (in folder Examples)


Tree Box Methods

get_tree_length, get_tree_selected,
tree_parent, tree_child, tree_next_brother
Entity: functions

insert_tree_item, delete_tree_item,
get_tree_item, set_tree_item,
clean_the_tree, set_tree_icons
Entity: predicates

Usage:
L is get_tree_length(Tree_Box)
S is get_tree_selected(Tree_Box)
R is tree_parent(Tree_Box, Item)
R is tree_child(Tree_Box, Item)
R is tree_next_brother(Tree_Box, Item)
insert_tree_item(Tree_Box, Item_Handle, Parent, After,
Text, Icon1, Icon2)
delete_tree_item(Tree_Box, Item)
get_tree_item(Tree_Box, Item, Text, Icon1, Icon2)
set_tree_item(Tree_Box, Item, Text, Icon1, Icon2)
clean_the_tree(Tree_Box)
set_tree_icons(Tree_Box, Icon1, Icon2, ...)

Tree Box

In all tree box functions and predicates you have to specify (in Tree_Box) which tree box have to be used. Everywhere Item is the handle of the tree item which has to be used. For Item you have to use "root", "last" or the value returned by some tree function.

Number is get_tree_length(Tree_Box)
Returns the number of items which are in Tree_Box.

Item is get_tree_selected(Tree_Box)
Returns the position of the selected item in Tree_Box. If there is not any item selected then this function fails.

Parent is tree_parent(Tree_Box, Item)
Returns a handle of the item which is parent of Item. If it has not parent then "root" will be returned.

Child is tree_child(Tree_Box, Item)
Returns a handle of the item which is the first child of Item.

Brother is tree_next_brother(Tree_Box, Item)
Returns a handle of the item which is the next child of the same parent as Item. If this is the last child of the same parent then this function will fail.

insert_tree_item(Tree_Box, Item_Handle, Parent, After, Text, Icon1, Icon2)
Inserts item at position which is determined by the handles of the items Parent and After with label Text and icons Icon1 and Icon2. The first icon is for not selected state and the second is for the selected state. Icon1and Icon2 have to be numbers from the list added by set_tree_icons. The handle of the new item will be returned in the variable Item_Handle.

delete_tree_item(Tree_Box, Item)
Deletes the item which has handle Item.

get_tree_item(Tree_Box, Item, Text, Icon1, Icon2)
Takes the item with handle Item and returns in the variables Text, Icon1and Icon2 the text and the numbers of the icons which are for not selected and for the selected states.

set_tree_item(Tree_Box, Item, Text, Icon1, Icon2)
Takes the item with handle Item and changes its text with Text and icons with Icon1and Icon2 (which are for not selected and for the selected states). Icon1and Icon2 have to be numbers from the list added by set_tree_icons.

clean_the_tree(Tree_Box)
Deletes all items in the Tree_Box.

set_tree_icons(Tree_Box, Icon1, Icon2, ...)
Attach to the Tree_Box a list of icons. The tree box needs this list of icons to put them at the tree items. Icon1, Icon2, ... have to be strings containing file names of ICO files.

Look at the example:
Tree Box.spj (in folder Examples)


true_value
Entity: function

Usage:
R is true_value(Goal)

Here Goal has to be an atomic goal. If Goal succeeds then this function returns 1, otherwise it returns 0.

Example:

?- N is true_value(1<2)+true_value(2=2), write(N), nl.


Type checking predicates

number(X) | succeeds if X is a number
const(X) | succeeds if X is instantiated with a constant (single letter or single character)
var(X) | succeeds if X is a not-instantiated variable
integer(X) R is integer(X) | checks whether X is an integer or converts it to integer
float(X) R is float(X) | checks whether X is a float or converts it to float
R is round(X) | returns in R an integer rounded from X
R is ceiling(X) | returns in R the first integer which is bigger than X
R is floor(X) | returns in R , the last integer which is smaller than X


update_window
Entity: predicate

Usage:
update_window(Window)

Updates the drawing on the window client area (by sending the message paint to the window's function). Variable Window has to contain the handle of this window. You can use the anonymous variable as argument to specify the default window.

See also:

window


url_encode
Entity: function
(ONLY for the Professional edition)

Usage:
EncText is url_encode(Text)

Encodes the input string (Text) into the URL format e.g. each symbol which ASCII number is outside the range [A-z0-9_-] is converted ot its hex representation (32 -> %20 - space key)

Text the input string

This function is typically used in CGI scripts.

Examples:
?- EncText is url_encode("a a"),
write(EncText). % a%20a


wait
Entity: predicate

Usage:
wait( Time )

Waits for Time seconds. Time may be integer or float but it must be instantiated.

Example:

?- chronometer(_), wait(0.5), chronometer(Time), write(Time), nl.

This example returns the time in milliseconds in which the wait(0.5) predicate was working, i.e. it will return 500..

Examples:

CURSOR


Windows and Drawing

Windows and Controls creation:

window creates an overlapping window
edit creates an edit control
button creates a button control
check_box creates a check box control
radio_button creates a radio button control
static creates a static label
group_box creates a group box control
bitmap creates a bitmap control
icon creates an icon control
animate creates an animation control
list_box creates a list box control
Methods of the list box
tree_box creates a tree box control
Methods of the tree box
embed_server embeds an ActiveX control

Windows and Controls use:

parent gets the parent window handle of the argument window
update_window updates the drawings in the window
get_text gets the text value of a control (window)
set_text sets the text value of a control (window)
size gets a window's size
set_size sets a window's size
pos gets a window's position
set_pos sets a window's position
client_size gets the size of window's client area
client_pos gets position of the window's client area
press_button presses button at given position
change_style changes the stile of a Window
enable_window Enables/Disables a window object
paint_rect gets the rectangle which needs to be repainted
message_flags gets the status of the buttons

Menu:

menu creates a menu item
modify_menu modifies the menu item

Checkbox:

get_check_box_value gets the value of a checkbox
set_check_box_value sets the value of a checkbox

Edit methods:

add_text adds a text into edit box
get_selected_text gets the selected text from an edit box
get_selection gets the selection text into an edit box
set_selection sets the selection text into an edit box
copy_in_edit copies the selected text into the clipboard
paste_in_edit pastes the selected text from the clipboard
cut_in_edit cuts the selected text

Drawing:

line draws a line
fill_polygon draws a polygon
bezier_line draws a Bézier curve
ellipse draws an ellipse
draw_chord draws a chord
draw_pie draws a pie
draw_arc draws an arc
rect draws a rectangle
round_rect draws a round rectangle
text_out draws a rectangle with a text
text_out Calculates the width of the text that would be printed
bitmap_image creates a bitmap object
draw_bitmap draws a bitmap image in a window
draw_point draws a point or takes the color of a point

Fonts, colors, pens and backgrounds:

pen gets/sets the current pen
brush sets the filling color
color_text sets the text color
color_text_back sets the text background
window_brush sets a window's background color
system_color gets system color
rgb creates a color by its RGB value (Red, Green, Blue)
select_color invokes a Select Color dialog box
select_font invokes a Select Font dialog box

Timer:

set_timer creates a timer object
kill_timer kills a timer object

Clipboard:

get_clipboard_data gets the clipboard data
set_clipboard_data sets the clipboard data


yes_no dialog box

yes_no
Entity: predicate

Usage:
yes_no( Title, Text, Icon)

Invokes an application modal dialog box with buttons "Yes" and "No"
Title | the title of the dialog box window
Text | the text inside the window (usually the question to be answered)
Icon | one of the predefined message icons

Fails if "No" is pressed succeeds otherwise.

Example:

?-
yes_no("yes_no(..) test", "Succeed?",?),
write("Succeeded!"), nl.

See also:

message


Arithmetic: the is predicate and the comparison predicates

This version of Strawberry Prolog has integer arithmetic only. Nevertheless we describe all the arithmetic within plans here. Just do expect to find that part of it is not available yet.

Arithmetical expressions are built up using

· the following infix binary operators :

+, -, *, /, rem, mod, **, >>, <<, /\, \/

They stand for addition , substraction , multiplication , division , remainder , modulo , bit-shifts leftward and rightward , and bitwise andand or , respectively.

· the following unary operators

(unary minus) -, \

They stand for negation and bitwise complement , respecively.

Ordinary (prefix) syntax is the only option for

abs(Number) absolute value
atan(Number) arctangent
ceiling(Number) smallest integer not smaller than Number
cos(Number) cosine
exp(Number) eNumber
sign(Number) -1 , 0 or 1 for negative, zero, or positive Number
float(Number) explicit conversion to floating point
floor(Float) largest integer not greater than Number
log(Number) natural logarithm
sin(Number) sine
truncate(Float) the integer with the greatest absolute value,

not greater than that of Float , and signed like Float

round(Float) the integer nearest to 'Float

Trigonometrical functions admit arguments in radians , atan produces result in radians too.

There are two cases, in which arithmetical expressions get evaluated . One case comes with the is operator

X is Expression

causes the evaluation of Expression and instantiating variable X to the result. The other case are the occurrences of the comparison predicates:

Number1 =:= Number2 Number1 equal to Number2
Number1 =\= Number2 Number1 not equal to Number2
Number1 < Number2 Number1 greater than Number2
Number1 > Number2 Number1 less than Number2
Number1 <= Number2 Number2 not less than Number1
Number1 >= Number2 Number2 not greater than Number1

Both arguments of these predicates are expected to be arithmetical expressions and get evaluated before comparison takes place.


Atoms

An atom in Strawberry Prolog is either an arbitrary series of letters, digits, and/or underscores, that begins with a lowercase letter, or a series of characters from the set

# $ * + - . / : < = > ? @ ^ ~ \ ,

or the special atom [] , or a series of arbitrary characters in single quotes ('). Within single quotes a single quote is written double, e. g. 'can''t do'.

Note, that the uppercase letter or underscore that the name of a variable begins with is all that makes the difference between a variable and an atom.


Built-in predicates overview

The built-in predicates in Strawberry Prolog provide a one-step way to implement things that are either impossible or just too inefficient to program in the language itself.

Side effects

The built-in predicates in Strawberry Prolog also provide the facility to program actions other than just the working of the interpreter as a database engine. These actions have effect on the outer world, relative to Strawberry Prolog, and are not subject to 'undoing' in the way, say, variable instantiation is. That is why built-in predicates are often said causing side effects .


Character strings

Character strings are arbitrary series of characters, enclosed in double quotes "" . Anything, including newline characters, is allowed and treated literally in character strings, but double quote " itself. A double quote can be represented by a couple of double quotes, e.g.:

"Here is a double quote: "" in a string"


Fact

A clause that is not a rule , and stands for the immediate confirmation of that some (kind of) goals are satisfiable.

See Overall structure of Strawberry Prolog 'programs' and section Facts from the Tutorial for examples.


Lists

Lists are the kind of structures available to Prolog programmers for the representation of finite sequences of arbitrary terms. A list that represents the sequence of terms t1,t2,...,tn is usually denoted as [t1,t2,...,tn] . To represent the sequence that contains no terms at all, one can use the empty list , which is denoted by [] .

A list that has at least one element has a head and a tail . Consider [t1,t2,...,tn] again. The element t1 is called the head of this list. The list [t2,...,tn] , that can be obtained by removing t1 from the given one, is called the tail of this list. In particular, the tail of a single-element list, say [t] , is the empty list [] .

When the complete structure of some list is either not available, or irrelevant , the list can be denoted in a way that specifies just its having a head and a tail like this: [H|T] . For instance, unifying this list and [t1,t2,t3,...,tn] will result in instantiating H to t1 and T to [t2,t3,...,tn] , provided that H and T are both uninstantiated. One may also specify a list with some fixed number of initial elements and an arbitrary tail by writing [t1,t2,t3,...,tn |T] . In general, one can write one list in a variety of equivalent ways, e.g. the list [t1,t2,t3,t4] can be written as [t1,t2|[t3|[t4]]] , or even as [t1|[t2|[t3|[t4|[]]]]] , which, although extremely artificial, still conforms Prolog syntax.

Consult Strawberry Prolog Specials for some implementation-specific details on lists.


Numbers

This version of Strawberry Prolog admits long integer numbers only , i.e. integers within the range from -2147483648 to 2147483647 . Be careful with integer constants. Ones that do not represent numbers in the specified range will silently be taken for other numbers within this range. See arithmetical expressions and comparison predicates for more information on numbers.


Overall structure of Strawberry Prolog `programs'

Overall structure of Strawberry Prolog 'programs'

'... Prolog is not a wholly procedural language.' That is why the word program , although fit to bring about some intuition, and for this reason used in the tutorial text, does not strictly apply to Prolog source. Rigor of Standard prescribes whatever is submitted to a Prolog interpreter (or compiler) to be called Prolog text .

Prolog text that Strawberry Prolog admits is syntactically a series of terms , each followed by a . , and whitespace (to provide some difference from other uses of . ).

Rules are terms that have :- as their functor . Recall that the functor of a term may be placed among its arguments , if it is an operator. The left-hand side argument of a rule is the head of the rule.

In Strawberry Prolog :- is defined as an operator that admits an arbitrary sequence of arguments on its right-hand side. This sequence of terms on the right-hand side of a rule is the body of the rule. Terms in the sequence that makes the body of a rule are separated by commas.

Questions are terms that have ?- as their functor. In Strawberry Prolog ?- is an operator that admits an arbitrary sequence of arguments on its right-hand side.

Terms with their functor neither ?- nor :- are what the Tutorial calls facts .

Rules and facts are the kinds of clause that Strawberry Prolog admits. Although within the scope of Strawberry Prolog implementer's plans, directives are out of the scope of this version of the On-line Help.

Clauses are the data-like and passive part of Prolog text in Strawberry Prolog. When compiling text, the Strawberry Prolog interpreter consumes them to assemble a Prolog database . After this it processes the questions in the order of their occurrence in the text, regardless to how they are distributed among clauses.

Changes of the contents of the database caused by the interpreter's work on every question are available to next-to-process questions.


Preliminary Note

Experts in Prolog, who may venture to read this document, are asked to admit that an amount of abuse of terminology found herein is just a harmless step back from the implementor-influenced trend to formalize uniformly elements of the Prolog language that have diverse origins in practice. Furthermore, some elements of Prolog presented here are specific to Strawberry Prolog, and can happen to work differently in other implementations. For the rest of this document the word 'Prolog' is to be read as an abbreviation for Strawberry Prolog.


Prolog (run-time) database

The collection of all facts and rules available at some moment of execution time.

See Overall structure of Strawberry Prolog 'programs' and Prolog text execution .


Prolog Text Execution

Here is a detailed general outline of the procedure that the Prolog interpreter runs to execute Prolog Text.

The input to this procedure is a single goalcome, say, as the body of a question . The output is an answer Yes or No to 'whether the goal is satisfiable', and, if a Yes , a substitution of terms for the variables that occur in the goal.

Basically, the interpreter satisfies goals by searching for facts and rules in the run-time database , that can be used for this purpose. A goal may get satisfied and resatisfied several times within the work on some parent goal. Every new time when a goal is to be satisfied, some part of the database gets skipped by the corresponding search, because the rules and facts in it have already been given their turn in earlier times.

To describe how this takes place precisely, it is useful to have in mind a work-state of execution. This work-state contains every goal that is , at the current point of time, subject to resatisfaction , together with a pointer into the database . This pointer separates the part of the database still subject to search from the part already processed. The work-state as a whole is a sequence of goal-and-pointer pairs. The initial work-state is the one with the single goal available and a pointer to the first item of the database.

The procedure consists of basically two kinds of steps, called forward steps and backward steps , and some control on taking them.

A forward step for a given goal corresponds to either a fact or a rule in the Prolog database with its head successfully unifiable with the goal. Performing a forward step means that:

1. The interpreter allocates all the variables that occur in the fact or rule in question.
2. Next it unifies the fact, or the head of the rule, if a rule is the case, with the goal, letting the variables that get substituted by this unification to be instantiated to these substitutes. Note that variables that come with the goal, and are not newly allocated, can get instantiated at this point too.
3. If the database item that triggers the forward step is a fact, the above completes the step as a successful one. If this item happens to be a rule, the sequence of goals that are the body of the rule is processed to try to satisfy the goals themselves by applying the entire backtracking procedure on each of them, with all the instantiations so far made in effect. This is done by attaching their conjunction to the beginning of the work-state with a pointer to the first item of the database.

Performing a backward step , that is needed in case some forward steps are still needed, though made impossible by the choices of the database items to work with, is undoing the above actions, that constitute a forward step.

Now the control over forward and backward steps is as follows:

The topmost goal-and-pointer is extracted from the work-state. A forward step is made with the goal selected and the first item from the run-time database that is at the pointer position or lower, and successfully unifies with the goal. If this item happens to be a rule, its body takes the topmost position in the new work-state together with a pointer to the beginning of the run-time database, as stated above. In both cases a pointer into the database, pointing to the item just next to the one extracted, gets stored. Informally, the above are the actions taken to initiate the application of a rule, or to find an appropriate fact.

The above control step is repeated as long as possible. With the case of rules in mind, where body-goals take place in the work-state, and when having reached its top, get processed by corresponding forward steps, one can imagine how a complex goal gets processed by a series of successful forward steps.

Normally, there are also failures to satisfy a goal. The work-state represents failure as an attempt to find an item in the database to launch a forward step, when the pointer component of the topmost element of the work-state points to the very end of the database, i.e. no more choices of facts and rules are available. Then the interpreter makes a backward step by undoing the forward step for the latest successfully satisfied goal, and places it, together with the pointer into the database that was stored upon its forward step, on top of the work-state. As this pointer points just next to the run-time database item that launched that forward step, the new work-state dictates an attempt to resatisfy the same goal using the same database without the items already proven not successful.

Remark: The above can be viewed as just a case of the more general backtracking procedure as described in the literature on programming.


Question

A Prolog text statement of the form

?- sequence_of_goals.

Answering a question on behalf of Strawberry Prolog means trying to satisfy the goals in the sequence jointly. Goals get satisfied in the order of their occurrence in the sequence. In the course of satisfying the goals some goal may fail to get satisfied, and backtracking may take place.

After parsing the text submitted, Strawberry Prolog extracts the questions contained therein, and answers them in the order of their occurrence.

See Overall structure of Strawberry Prolog 'programs' and section Questions from the Tutorial for examples.


Rule

A clause of the form

head :- tail.

where head is a goal , and tail is the sequence of goals, separated by commas, that the rule says head is reducible to.

See Overall structure of Strawberry Prolog 'programs' and Prolog text execution .


Terms

Terms in Strawberry Prolog are defined as follows:

Atoms , numbers , character strings and variables are terms. Let f be an atom . Let t1 , ... , tn be terms. Then f(t1,...,tn) is a term too. The atom f is called the functor of this term, and t1 , ... , tn are called its arguments.

The last clause of the definition above presents the most universally available notation for terms. Terms whose functor is declared as operator, admit the functor between, or after their arguments too . This is called infix notation of terms. For example, arithmetical expressions admit both notations, e.g. +(2,X) is the same as 2 + X .


The anonymous variable

The name of every anonymous variable is _ .

The anonymous variable is an element of Prolog that is similar to a variable in almost every way. As presumable, all the occurrences of the name of an ordinary variable stand for the same variable within one clause. On the contrary, every occurrence of _denotes a distinct variable .

Example:

?- X=[_,_], X=[a,b], write(X).

will succeed, even though the two occurrences of _ seem to dictate instantiating _ to distinct terms. The output of write will be

[a,b]

Some of the use of the anonymous variable is to fill in places, where anything is welcome , not burdening the mind of the Prolog programmer with an otherwise useless name for an ordinary variable. Sometimes, when the term welcome is also irrelevant, the anonymous variable is also the best choice, because the collection of anonymous variables resembles a single one that is 'immune to instantiation'.


Unification

Unification is a procedure to establish whether two terms , that eventually contain uninstantiated variables , can be made identical by eventually substituting appropriate (other) terms for some of these uninstantiated variables, and, if they can, to find these appropriate substitutes.

Examples:

· Terms f(g(X),Y,Z) and f(g(Y),a,f(Y)) unify successfully. The substitute for both X and Y is a , and that for Z is f(a) .

· Terms f(a,X) and f(X,b) will not unify.

· Terms f(Egg,Hen) and f(egg(Hen),hen(Egg)) will not unify.

Sometimes unification is called matching . Strictly speaking, matching differs from unification in that one of the terms is more pattern-like, i.e. variables to be substituted are expected to occur there. The other term, thatmatches the pattern or not , is expected to contain the substitutes.

In a goal, successful unification causes uninstantiated variables to get instantiated to the substitute terms found by unification.

To avoid misunderstanding of unification , one must keep in mind that:

Þ Variables in terms to be unified may have the same name, yet be distinct. For example, goal(Variable, f)) , Variable uninstantiated, will successfully unify with the head of rule

goal(g, Variable) :- write(Variable).

The call to write will cause f to appear as output.

Þ Unification processes terms as if all the earlier instantiated variables that terms may happen to contain were substituted by the corresponding (other) terms. For example, the last goal in the question,

?- X = f(Y), Z = g(f(a)), g(X) = Z.

will actually make the interpreter try to unify g(f(Y)) and g(f(a)) .

Þ The variables that occur uninstantiated in terms to be unified, and eventually get instantiated after unification, need not belong to the context of the clause , that launched unification. For example, trying to satisfy goal(f(Y),g(f(a)) by applying the rule

goal(X, Z) :- X = Z, Y = b, write(Y).

will succeed by causing both a to instantiate Y from the goal and b to instantiate Y from the body of the rule.

Þ In Strawberry Prolog occur check is always on. That is, instantiating a variable to a term that contains the variable is impossible. Although instantiating, e.g. X to f(X) , may seem tempting and even sound from a somewhat more abstract viewpoint, Strawberry Prolog sticks to the inductive definition of term, and it is violated by the outcome f(f(f(...))) of this sort of 'successful unification'.


Variables

Variables in Prolog are a means to name terms that become known at run-time.

A variable's name starts with a capital letter or _ , followed by an arbitrary sequence of letters, digits and _ s. The variable, whose name is just _ , has a special role in Prolog. It is called the anonymous variable.

A variable gets allocated, when the clause (fact or rule) it occurs in is about to be applied. A variable does not get deallocated after successfully satisfying the goals that comprise the successful application of this clause. Rather, it gets deallocated when the application of the clause it got allocated in is cancelled in order, to e.g. resatisfy the goal that launched it, by a backward step.

From its allocation a variable is available for instantiation , i.e. for assigning it a term to stand for. The same variable can be instantiated and then uninstantiated unlimitedly many times. This is so because, after its allocation, the variable in general becomes part of terms, that get passed to subgoals, given rise by the application of the clause which caused the variable to get allocated. Here forward steps and backward steps can cause instantiation and uninstantiation both of locally allocated variables and earlier allocated ones.

A variable loses its value , i.e. gets uninstantiated again, only after backward steps on a clause that caused it to get a value - get instantiated. Note that, a loss of value, and not of allocation, is what happens. The backward step doesn't need to be on the clause that caused allocation.

It is sometimes possible for one variable to get instantiated to a term that consists of just another variable. This case of unification is remarkable for its violating the branch-replaces-leaf intuition for the effect of instantiation on the tree representations of terms. The definition of sharing of the two variables has been adopted, because whatever in the future instantiates one of the two, immediately does so with the other.


What are the advantages

What are the advantages of buying of subscriotion?

1. You will receive all Professional Edition versions 2.x and 3.x including version 4.0 immediately after they are released.

2. If you buy a subscription for the Professional edition now then you obtain the right to buy with it also 200 shares at 50 cents per share (look at shares.html in our site). This means that for $349 USD ( $249 for the license and $100 for shares) you can obtain 200 shares and license for versions 1.x, 2.x professional editions and version 3.0.

3. You obtain technical support by e-mail and we will try to remove immediately all the problems in the compiler that hamper your work.

4. You will help for development of Strawberry Prolog. We admire any help. You can help with money by buying of shares or with ideas and bug reports. Also you can help by creating of powerful programs on Strawberry Prolog platform. You can take the source code of Strawberry Prolog and to make your own improvements on it.


Buying a subscriotion

You can buy a subscription for Strawberry Prolog which includes the current version and all future versions including 4.0 . When you bought a subscription you will receive a personal password which can be used to download all future versions including 4.0 . The cost for this subscription for the moment is only $249 USD for the Professional edition and $98 USD for the Middle edition. Also you can use the student discount which we offer.

If you want to buy a subscription for Strawberry Prolog , please send a check or money order to the author . or pay directly by your credit card in our download center (dobrev.com/passwords.html ). When we receive your order in 24 hours we will send back to you an e-mail with your personal password and later we will send to you a letter with your license. You will need the password to copy from our web page the versions 2.x, 3.x professional (or middle) editions and the version 4.0.


OLE

OLE and ActiveX

Strawberry Prolog supports OLE Automation - COM and ActiveX. This enables you to command standard programs like MS Word or Excel using your Strawberry Prolog program. This will open opportunities to incorporate such programs into your Prolog program.

Use the function server in order to open OLE server. You can embed OLE server (ActiveX object) in your window by the predicate embed_server. In order to invoke methods and get and set properties use the operator point. You can listen for events which come back from the server. In order to do this open the server with server2 function. Also, on Strawberry Prolog you can write a server program which can send events back to its client by raise_event predicate.

If you want to command another program (server) then you have to know its commands (methods and properties). You can use the tool Object Browser (from menu Tools). With the help of this tool you can see all OLE servers which are installed on your computer. Also you can see their methods and properties. You can use any other description of this server (interface) provided by the authors of the server.

Keep in mind that some programs do not support OLE Automation (are not written as servers) and cannot be ruled from outside.

The support of OLE Automation is not an absolutely new opportunity because you already have it in Visual Basic, Delphi and Visual C++. However, Prolog (especially Strawberry Prolog) has definite advantages over other program environments and they are:

1. Basic is suitable only for short programs but when the program becomes longer it gets messy.

2. Delphi and Visual C++ are known as environments for professionals not only because you can create professional work using them but also because you need so much time to study through them that it is worth taking it on only if this is your profession.

See also:
Strawberry Prolog as OLE server
server, close
. (point)
embed_server
raise_event

Examples:
Word.spj
Chart.pro
OLE
OLE / Servers


Professional and Middle edition

The Professional Edition of Strawberry Prolog is our higher edition which includes all facilities and tools. The main advantage of the Professional edition comparing the Middle one is the possibilities to create Prolog CGI scripts and to build EXE files. These EXE files are very small but they need an installation of the Light Edition of Strawberry Prolog for work. This cannot be a problem because this edition is very small in size and it is free.

Professional edition of Strawberry Prolog is not freeware. If you want a password for it then you have to buy a license. We offer a subscription for all versions including 4.0. Now the price for this is $249 USD and we offer a student discount which is $119 USD.

The Middle Edition of Strawberry Prolog have complete functionality except creating of Prolog CGI scripts and EXE files. Like the Professional edition it is not freeware. You have to buy a subscription for it (which include all versions including 4.0). There will be a second possibility to obtain the middle edition. We will give it as a shareware for one month evaluation period together with the CD of some computer magazines. If you obtain the Middle edition from computer magazine then you have right to use it only for one month and only this version which is on the CD.

Now the price for subscription for the Middle edition is $98 USD and we offer a student discount which is $49 USD.

The Light Edition of Strawberry Prolog is free but to download and use its last version you have to open an e-mail box at SecondBox.net. This is free e-mail box through which you will forget what SPAM was! This is more than just a free service. You will make money of it rather than to pay for it.

If you do not want to open Second Box address then you can download the previous version of Strawberry Prolog Light absolutely free and without any registration.


Student Discount

We offer student discount. for Professional and Middle editions. The price with the discount is $119 USD for the Professional edition and is $49 USD for the Middle edition.

You have the right to use this discount if you study in school, college or university. Also you have right to use this discount if you are not profit organization or if you live in country with lower living standard. For such country we can not accept any one from the following list:

Australia
Canada
European Union
Israel
Japan
New Zealand
South Africa
Switzerland
USA


Type String

String is any text which is surrounded with double quotes ( " ) or with symbol `.

If you want to put in the string a quotation mark then you have to put instead of it two quotation marks ( "" ) or \". In this way the compiler will understand that you want one quotation mark in the string instead to end it.

If the string is surrounded with the symbol ` then you have not problem to put inside a quotation mark ( " ) or \". In this case if you put "" then this will be exactly two symbols ". To surround the string with the symbol ` instead of " is very convenient when you want to generate HTML file and you have a lot of " inside.

If the string is surrounded with the symbol ` then analogous you have to put instead of ` two symbols ` or \`.

If you want to put in the string special symbol then you have to put instead of it a sequence which starts with \. Here is the table of this special symbols and respective sequences:

\\ \
\" "
\` `
\n new line
\t tab

If you put in your string a line break then the effect will be the same if you wrote \n. If you want to go on a new line without putting line break in the string then you can use \. If you place \ before the line break then this line break symbol will be not included in the string. The following three commands are equivalent:

write("First Line\nSecond Line")

write("First Line
Second Line")

write("\
First Line
Second \
Line")

If you write string using write predicate then special symbols will be printed directly. If you use the writeq predicate then all special symbols will be replaced with the respective sequence (which start with \).

To work with strings use the built-in predicates and functions.


What will be?

What Will Be the Next Versions?

The versions 0.5, 0.6 and 0.7 were a very early editions of Strawberry Prolog and we did not recommend them for serious work. They are free for use and distribution (including business purposes), like 1.0.

This version 1.0 is the first version which is good enough even for professionals. This will be the last absolutely free version. In our opinion it is already the best Prolog compiler in the world!

Versions after 1.0 will be in three editions, Light, Middle and Professional. The Light edition will be freeware. The professional and middle editions will be available for the ones who made subscription for Strawberry Prolog. This subscription includes the current version and all future versions including 4.0 . When you bought a subscription you will receive a personal password which can be used to download all future versions including 4.0 . The cost for this subscription for the moment is only $249 USD for the Professional edition and $98 USD for the Middle edition (look at buy a subscription ).


When will be ready

When the Next Versions Will Be Ready?

Version 0.5 was distributed by Internet on September 13, 1996.
Version 0.6 was distributed by Internet on February 21, 1997.
Version 0.7 was distributed by Internet on December 18, 1997.
Version 1.0 (beta release) was distributed by Internet on May 28, 1998.
Version 1.0 (beta release2) was distributed by Internet on September 15, 1998.
Version 1.0 was distributed by Internet on November 19, 1998.
Version 1.01 was distributed by Internet on December 21, 1998.
Version 1.02 was distributed by Internet on April 26, 1999.
Version 1.1 was distributed by Internet on December 22, 1999.
Version 1.2 was distributed by Internet on March 28, 2000.
Version 1.21 was distributed by Internet on May 15, 2000.
Version 1.22 was distributed by Internet on July 8, 2000.
Version 1.23 was distributed by Internet on September 7, 2000.
Version 1.5 was distributed by Internet on November 22, 2000.
Version 1.6 was distributed by Internet on March 19, 2001.
Version 1.7 was distributed by Internet on April 25, 2001.
Version 1.8 was distributed by "PC Magazine - Bulgaria" in June, 2001.
Version 1.9 was distributed by Internet on September 17, 2001.
Version 2.0 was distributed by Internet on December 21, 2001.
Version 2.1 was distributed by Internet on April 25, 2002.
Version 2.3 was distributed by Internet on September 16, 2002.
Version 2.5 was distributed by Internet on May 14, 2004.
Version 2.6 was distributed by Internet on June 7, 2006.
Version 2.9 was distributed by Internet on December 24, 2006.
Version 2.91 was distributed by Internet on February 5, 2007.
Version 2.92 was distributed by Internet on April 25, 2007.
Version 3.0 Beta was distributed by Internet on December 20, 2008.
Version 3.0 Beta 2 was distributed by Internet on October 3, 2013.
Version 3.0 Beta 3 was distributed by Internet on November 2, 2013.
Version 3.0 Beta 4 was distributed by Internet on December 10, 2013.
Version 3.1 A was distributed by Internet on January 25, 2019.
Version 3.1 B was distributed by Internet on February 20, 2019.
Version 3.1 C was distributed by Internet on February 28, 2019.
Version 3.1 D was distributed by Internet on May 4, 2019.
Version 3.1 E was distributed by Internet on May 16, 2019.
Version 4.0 was distributed by Internet on January 3, 2020.
Version 5.0 was distributed by Internet on January 20, 2020.
Version 5.1 was distributed by Internet on March 25, 2020.
Version 6.0 was distributed by Internet on July 3, 2023.

Version 6.1 was distributed by Internet on August 23, 2023.


Where to Find?

Search by Internet on one of the address:

http://www.dobrev.com (this page is hosted in USA)

or in the computer magazines listed in the page:

http://www.dobrev.com/middle.html

If you want to receive e-mail messages when the new versions of Strawberry Prolog are released, please, type your e-mail address in the download center of our web site. You will receive two or three e-mails per year on new version releases.

If you want to stop receiving such information then you can easily unsubscribe from the same place.