1 Getting Started

This section describes how to set up the required environment variables and briefly describes how to run the interpreter. At the moment it is not possible to generate an executable QuLog application that can be launched independently of the interpreter. This will be possible. However, the intepreter can be used to launch a multi-threaded message communicating application that can be left to its own devices.

1.1 Environment Variables

The root directory of the QuLog tree contains the files PROFILE_CMDS that can be used to define the required environment variables.

1.2 Data Areas

Because Qulog is currently implemented in QuProlog it has the same data areas as QuProlog and the sizes of these areas can be modified in the same way as for QuProlog - see the QuProlog manual.

1.3 Running the Interpreter

qulog is the name of the Qulog interpreter. From a Unix shell, Qulog is started by typing:

qulog

or

qulog -A name

where name is a name for this QuLog process that will be registered with a Pedro server running on the same host. You need to use this option if you want to be able to receive and/or send messages to other processes that have similarly registered a different name with this Pedro server.

If the Pedro server is running on a different host identified by domain or IP address Host, launch QuLog using

qulog -N Host -A name

For example

qulog -N leo.itee.uq.edu.au -A keith_agent

When the interpreter is ready it will prompt you with

| ??

At this point, an expression query, a relation query or an action command, followed by a FULLSTOP NEWLINE, or NEWLINE NEWLINE, can be entered. The interpreter will check that the query or command is syntactically and type correct and that modes of use are correct. It will either display an error message or print out a response to the query or command.

A CONTROL-D will exit the interpreter whenever you get the prompt.

CONTROL-C will interrupt an evaluation and allow you to abort the interpreter (enter e in response to the interrupt prompt), or to terminate the current query and any forked action threads (enter r in response to the interrupt prompt), giving you the | ?? query prompt again. There are other response options, displayed if you enter ? in response to the interrupt prompt.

If the query is an expression then the result of the expression evaluation will be displayed followed by its minimal type.

Example:

| ?? 2+sin(pi_()/4).

2.70711 : num

| ?? cos.

cos : (num)->num

The second expression is just the name of a primitive function and the value is that function. However its type is usefully displayed.

If you enter a relation query then either 'no' will be displayed to indicate there are no solutions to the query or bindings for variables of the query with their minimal types will be displayed separated by lines of fullstops. If you entered a command any output from the command will be displayed followed by 'success' or 'fail' depending upon whether the command ultimately succeeded or failed.

When there are multiple solutions to a relation query the first five (if there are that many) are displayed separated by lines containing ...

Example:
| ?? X in [4,0,3,4].


X = 4 : nat
...
X = 0 : nat
...
X = 3 : nat
...
X = 4 : nat

| ?? % New prompt indicates all sols have been given

If there are five or more solutions the interpreter waits for input from the user before displaying more. The two usual responses are:

NEWLINE - no more solutions are required; or

..NEWLINE - asking for up to 5 more solutions.

Example, showing a second use of 'in':

| ?? S in "Apple".


S = "A" : string
...
S = "p" : string
...
S = "p" : string
...
S = "l" : string
...
S = "e" : string
.. % Request for more answers if there are any
no more solutions
% Above displayed only after .. input and there are no more answers

| ?? X in {6,2,3,0,3,7,4}.
% {6,2,3,0,3,7,4} is a set so second 3 ignored, third use of 'in'


X = 0 : nat % Answers displayed in value order
...
X = 2 : nat
...
X = 3 : nat
...
X = 4 : nat
...
X = 6 : nat
.. % Request to display up to 5 more answers
X = 7 : nat

| ?? % Prompt for next query indicating no more answers

If you feel that the interpreter is giving back too many, or too few answers for a particular problem you can control this in two ways. The first is to prefix the query by the number of solutions you would like displayed at a time, followed by a ?, followed by the query. Also, instead of simply using a .. to ask for more solutions you can change the number of solutions to be displayed for this query to positive integer k by entering ..k.

Example:

| ?? 1 ? X in [1,2,1,4,2]. % Answers 1 at a time


X = 1 : nat
.. 2 % Switch to sols 2 at a time
X = 2 : nat
...
X = 1 : nat
.. % Request for the next 2 sols
X = 4 : nat
...
X = 2 : nat
.. % Request for the next 2 sols
no more solutions

| ??

You can also change the default number of solutions that are displayed for any query to a positive number n, say 3, using the command:

| ?? set_num_answers 3.

success

Sometimes you might have a relation query that contains many variables but you might only be interested in the bindings for some of the variables. This can be accomplished by listing the variables for which you want to see the answer bindings, separated from the query by a ?.

Example:

| ?? L1, L2 ? append(L1, L3, [1,2,3,4,5,6]) & append(L4, L2, L3)
& 2 = #L4.
% Expressions such as #L4, length of L4, can be used in = tests


L1 = [] : [Ty1]
% A type variable Ty1 as [] is empty list of any type
L2 = [3, 4, 5, 6] : [nat]
% [nat] is type expression for a list of nats (non-neg ints)
...
L1 = [1] : [nat]
L2 = [4, 5, 6] : [nat]
...
L1 = [1, 2] : [nat]
L2 = [5, 6] : [nat]
...
L1 = [1, 2, 3] : [nat]
L2 = [6] : [nat]
...
L1 = [1, 2, 3, 4] : [nat]
L2 = [] : [Ty1]

The two ideas above can be combined as in the following example.

| ?? 2 L1, L2 ? append(L1, L3, [1,2,3,4,5,6]) & append(L4, L2, L3)
& 2 = #L4.


L1 = [] : [Ty1]
L2 = [3, 4, 5, 6] : [nat]
...
L1 = [1] : [nat]
L2 = [4, 5, 6] : [nat]

Equivalently you can express the above query using an existential quantification on L3, L3.

| ?? 2 ? exists L3, L4 append(L1, L3, [1,2,3,4,5,6]) &
append(L4, L2, L3) & 2 = #L4.

The existential quantification is needed if you want all the answers as a list.

| ?? [(L1,L2) :: exists L3, L4 append(L1, L3, [1,2,3,4,5,6]) &
append(L4, L2, L3) & 2 = #L4].


[([],[3,4,5,6]), ([1],[4,5,6]), ([1,2],[5,6]), ([1,2,3],[6]),
([1,2,3,4],[])]:[([nat],[nat])]
% Value type is a list of pairs of lists of nats

We can re-express the last list expression query more succinctly using the list concatenation operator <> for splitting of a list using the special non-determinsitic match operator =? that requires its left hand side to be, or to evlaluate to a ground term. <> may also be used for concatenating complete lists or ground or non-ground terms.

| ?? [(L1,L2) :: exists L4 [1,2,3,4,5,6] =? L1 <> L4?2=#L4 <> L2]

Using this non-deterministic list pattern matching we do not need the L3 variable, and the constraint that L4 must contain two elements becomes a constraint

2=#L4

expressed inside the <> pattern expression attached to the variable L4, preceded by a ?.

If you have constructed a program file prog1.qlg of QuLog type definitions, type declarations for relations, function and actions and their rules, you can bring all those into the interpreter using the command

| ?? consult prog1.

success

You may get syntax and mode errors signalled in which case none of the program file is consulted. There will be at least one QuLog examples file with the QuLog distribution that you installed. You can consult and query one of these files. For example, there may be a file qlexamples.qlg in qulog/examples/introduction. If you launch QuLog from inside this directory you can load all its definitions using:

| ?? consult qlexamples.

You can see all the relation and function rules you currently have in the interpreter using:

| ?? show.

or specific ones using:

| ?? show child_of, person, fact, new_child.

Notice the variable names of the consulted file will be used.

You can see all the type definitions and declarations using:

| ?? types.

You can see all the system type definitions and the type declarations for the primitive relations, functions and actions using:

| ?? stypes.

A displayed type declaration may be accompanied by a brief description of the primitive. You can also show the type declarations for specific relations by giving their names, separated by commas, after either the types or stypes command.


Table of Contents Overview of QuLog Getting Started Syntax Built-ins Standard Operators Index