This section contains descriptions of the functions, relations and actions of the Qulog library. In the interpreter you can see all their names and types by entering the command
| ?? stypes.
Many of these are Qu-Prolog primitive relations 'lifted' to QuLog by giving them appropriate type/mode declarations. Other Qu-Prolog relations and actions can be 'lifted' to the Qulog level be giving them a QuLog type declaration in your QuLog program file.
For example, if the primitives described on Section List Processing had not already been made available for use in QuLog, all you would have needed to do was include their type declarations as given in that section.
As another example, there is a Qu-Prolog primitive
for generating or testing an integer value N between given integer values From and To.
To use this in a QuLog program, add the moded type declaration
between: (integer,integer,?integer) <=
to your program file. It tells the QuLog mode/type checker that the relation is a Qu-Prolog primitive (that will be checked), and that in every use the first two arguments should be given as integers but the third integer argument may be given or may be returned as value of an unbound variable.
Actions:
Write the elements of List. If the atom nl_ appears in List it is written as a newline.You can also use sp_(N) where N is a positive integer to insert N spaces. Strings in List are displayed without the string quotes ".." unless you write them with q_("..."). The quotes are then put around the string.
mode/type writeL(![??term])Example:
| ?? writeL(["List of atoms ",[a,b], nl_,
"Set of nats ", {2,1,4,1}]).
List of atoms [a, b]
Set of nats {1, 2, 4}
with the next output on the next line. nl_ causes a new line to be output as would the string "\n". In fact any of the C string control characters, such as "\t", "\s" for tab and space respectively, can be put into a string and will have the intended effect unless the string is wrapped inside a q_ term. So we could have written the above query as:
| ?? writeL(["List of atoms ",[a,b],
"\nSet of nats ", {2,1,4,1}]).Other control term we can put in the list argument of writeL are:
sp_(n), n positive integer. It will display n spaces.
uq_(Atom), where Atom is an atom that normally needs to be quoted. It will be displayed without the single quotes.
wr_(Var), will not display Var as an underscore followed by a sequence of digits, as is normal, but will give it a name such as A, B, C when displayed and will give subsequent occurence of Var in the list to be output using the given name for Var.The following query illustrates the the use of uq_ and wr_.
| ?? writeL([uq_('Hello')," there\n",wr_(_895),sp_(2),
_895,sp_(2),wr_(_678),nl_]).
Hello there
A A B
_895 = A : Ty1
_678 = B : Ty2
success
The same as writeL but with a trailing newline.Example:
| ??writeLine([s("A list "), [a, b], sp_(2), {2, 1, 4, 1},
s(" followed by a set.")]).
A list [a, b] {1, 2, 4} followed by a set.with the next output being at the beginning of the next line.
Unifies Term with the next term denoted by the next sequence of characters typed at the terminal followed by fullstop, return.Example:
| ?? readT(X).
f(A).
X = f(A) : termNote that this read remembers the names of variables (the A above). A consequence of this, given the occurs check in unification, is that the following query fails.
| ?? readT(A).
f(A).
no
Two terms are compared according to the standard ordering, which is defined below. Items listed at the beginning come before the items listed at the end. For example, numbers are less than atoms in the standard ordering.
The following relations use the above ordering to test terms.
Succeeds if Term1 is greater thanTerm1 in the above ordering.
Succeeds if Term1 is greater than or equal to Term2 in the above ordering.
Succeeds if Term1 is less thanTerm1 in the above ordering.
Succeeds if Term1 is less than or equal to Term2 in the above ordering.
These testing predicates are used to determine various properties of the data objects, or apply constraints to the data objects.
Relations:
Succeed if Term is a non-variable of type Type.
mode/type type : (??top, !typeE(_)) <=Example:
| ?? type(a, atomic).
yes
| ?? type(a, int).
no
| ?? type([a,2], [int || atom]).
yes
Succeed if Term is ground.
mode/type ground : (??top) <=
Succeed if Term is of type Type and Type is a finite type.
mode/type isa : (?Term, !typeE(_)) <=Example: For this example we assume the following type declarations.
name ::= "Alice" | "Bob" | "Carol"
status ::= good(name) | bad(name)
| ?? isa(X, status).
X = good("Alice")
...
X = good("Bob")
...
X = good("Carol")
...
X = bad("Alice")
...
X = bad("Bob")
..
X = bad("Carol")
| ?? isa(good("Bob"), status).
yes
| ?? isa(2, nat).
no
Succeed if Term is atomic or a compound term with a ground functor.
mode/type template :(??top) <=
Succeed if Term is a relation or action term and that the modes of its arguments are correct.
mode/type ground_inputs : ??(relcall || actcall)
Succeed if L3 is the concatentation of L1 and L2
mode/type
append: ([T]?, [T]?, [T]?)<= | (![T], ![T], ?[T])<= |
(?[T], ?[T], ![T])<=
Succeed if L2 is the reverse of L1.
mode/type
reverse : (![T?], ?[T?]) <=
Succeed if L2 is L1 sorted.
mode/type
sort : (![T?], ?[T?]) <=
Succeed if X is in L.
mode/type
member : (T?, [T]?) <=
Succeed if X is in L.
mode/type
in: (?T,[T])<= | (T?,![T?])<= | (?string,[string])<= |
(?T,{T}) <=
Almost exactly the same uses as member except that it it must be given a complete list of possibly non-ground terms.
As its type indicates, in can also be used to access single character substrings of a string and ground elements of a set.
The following arithemetic functions are available.
Returns the sum of Num1 and Num2.
+ : (nat, nat) -> nat | (int, int) -> int | (num, num) -> num
Returns the difference of Num1 and Num2.
- : (int, int) -> int | (num, num) -> num
-Num1
Returns the negation of Num.
- : int -> int | num -> num
Returns the product of Num1 and Num2.
* : (nat, nat) -> nat | (int, int) -> int | (num, num) -> num
Returns the integer division of Num1 and Num2.
// : (nat, nat) -> nat | (int, int) -> int
Returns the division of Num1 and Num2.
/ : (num, num) -> num
Returns the mod of Num1 and Num2.
mod : (nat, int) -> nat | (int, int) -> int
Returns Num1 raised to the power Num2.
** : (nat, nat) -> nat | (int, nat) -> int | (num, num) -> num
Returns the bitwise right shift of Int with respect to Nat.
>>: (int, nat) -> int
Returns the bitwise left shift of Int with respect to Nat.
<<: (int, nat) -> int
Returns the bitwise AND of Int1 and Int2.
/\: (int, int) -> int
Returns the bitwise OR of Int1 and Int2.
\/: (int, int) -> int
Returns the bitwise complement of Int.
\: (int) -> int
Returns the absolute value of Num.
abs: int -> nat | num -> num
Returns the square root of Num.
sqrt: num -> num
Returns the round of Num.
round: num -> int
Returns the floor of Num.
floor: num -> int
Returns the ceiling of Num.
ceiling: num -> int
Returns PI.
pi_: () -> num
Returns E.
e_: () -> num
Returns the sin of Num.
sin: num -> num
Returns the cos of Num.
cos: num -> num
Returns the tan of Num.
tan: num -> num
Returns the arcsin of Num.
asin: num -> num
Returns the arccos of Num.
acos: num -> num
Returns the arctan of Num.
atan: num -> num
Returns the atan2 of Y and X. This returns an angle in the range (-pi, pi].
atan2: (num,num) -> num
Returns the current time.
now: () -> num
Returns the lapsed time in seconds since this qulog process was started
exec_time: () -> num
Returns the time at which this qulog process was started
start_time: () -> num
Returns a random number in [0,1).
random_num: () -> num
Returns a random number in the interval [Lower, Upper].
random_int: (int, int) -> num
Returns the union of sets S1 and S2.
union: ({T}, {T}) -> {T}
Returns the intersection of sets S1 and S2.
inter: ({T}, {T}) -> {T}
Returns the set difference of sets S1 and S2.
diff: ({T}, {T}) -> {T}
Returns the concatination of lists L1 and L2.
<> : ([T], [T]) -> [T]
Returns the concatination of strings S1 and S2.
++ : (string, string) -> string
Returns the length of the list, set, or string L.
# : [T] -> nat | {T} -> nat | string -> nat
Returns the compound term obtained by applying F to Args.
@.. : (term, [term]) -> termExample:
| ?? @..(a, [1,2]).
a(1, 2) : term@.. can also be used to split up a compound term as in the following example.
| ?? a(1,2) =? F@..Args.
F = a : atom
Args = [1, 2] : [nat]
$Name, where $ is a prefix operator.
Here Name is an atom that must have been initialised with a statement
int Name:=Integer, e.g. int count:=0 or
num Name:=Number, e.g. num savings:=678.50
in the program. It returns the current value associated with Name
which can be updated by primitive actions (see :=).
Always succeeds.
mode/type true : () <=
Always fails.
mode/type false : () <=
Succeeds if Term1 and Term2 unify.
Any function calls in each argument term are evaluated first using strict evaluation
- expression arguments evaluated first - as with every relation call.
mode/type = : (term?, term?) <=
Succeeds if N1 is greater than N2.
mode/type > : (!num, !num) <=
Succeeds if N1 is greater than or equal to N2.
mode/type >= : (!num, !num) <=
Succeeds if N1 is less than N2.
mode/type < : (!num, !num) <=
Succeeds if N1 is less than or equal to N2.
mode/type =< : (!num, !num) <=
Succeeds if X is a term and and T is a list or set of terms and X is an element of T or if X and T are both strings and X is a single character string occurring inT.
mode/type in: (T?,![T?]) <= | (?T,![T]) <= | (?T,!{T}) <= |
(?string, !string) <=
Succeeds if T is the term obtained by parsing the string Sas a Qulog term.
mode/type string2term : (!string, term?) <=
Succeeds if Name is the name of this thread
mode/type current_thread : (?atom) <=
get_active_resources(ResourceInfo)
Succeeds if ResourceInfo is the list of terms res(atom,[resource]) giving resources used by each running task in a multi-tasking agent. The atom is task name.
mode/type get_active_resources : (?term) <=
get_waiting_resources(ResourceInfo)
Succeeds if ResourceInfo is the list of terms res(atom,[resource]) giving resources needed by each waiting task in a multi-tasking agent. The atom is task name.
mode/type get_waiting_resources : (?term) <=
Adds its ground relcall argument (Belief) as a new last dynamic fact for its functor relation name R. R must have been declared as a belief.
mode/type remember : (relcall) ~>>
The same as remember except that Belief is forgotten after Secs seconds.
mode/type remember_for : (relcall, num) ~>>Alternative syntax: remember Belief for Secs
Adds its ground relcall argument (Belief) as a new first dynamic fact for its functor relation name R. R must have been declared as a belief.
mode/type rememberA : (relcall) ~>>
The same as rememberA except that Belief is forgotten after Secs seconds.
mode/type remember_for : (relcall, num) ~>>Alternative syntax: rememberA Belief for Secs
Remove the first dynamic fact matching Belief. Note that Belief may contain variables within the arguments. forget always succeeds even if there are no matching facts.
mode/type forget : (relcall) ~>>
The same as forget except that Belief is forgotten when Secs seconds has elapsed and Belief must be ground at the time of call.
mode/type forget_after : (relcall, num) ~>>Alternative syntax: forget Belief after Secs
The same as forget(Belief1) ; remember(Belief2). Belief1 and Belief2 may share variables.
Here Name is an atom that must have been initialised with a statement
int Name:=Integer, e.g. int count:=0 or
num Name:=Number, e.g. num savings:=678.50
in the program. These statements are shorthand for belief declarations and a definition using one fact of a unary relation called Name. They are respectively expanded into:
belief Name: int <=
Name(Integer)
belief Name: num <=
Name(Number)
The action Name := Expression is the same as
forget(Name(_));remember(Name(Expression)).
mode/type := : (!(?int <= ), !int) ~>> |
(!(?num <= ), !num) ~>>Name can be used as though it were a global variable. To access its value the operator $ is applied. The expression $Name evaluates to the current int or num value stored in Name, i.e. in the current Name belief.
As above, Name is an atom that must have been initialised with a statement
int Name:=Integer or num Name:=Number
in the program.The action Name +:= Expression is the same as
forget(Name(Val));remember(Name(Val+Expression)).
mode/type := : (!(?int <= ), !int) ~>> |
(!(?num <= ), !num) ~>>Example use count +:= 1 for increasing value held in count by 1.
As above, Name is an atom that must have been initialised with a statement
int Name:=Integer or num Name:=Number
in the program.The action Name -:= Expression is the same as
forget(Name(Val));remember(Name(Val-Expression)).
mode/type := : (!(?int <= ), !int) ~>> |
(!(?num <= ), !num) ~>>Example use savings -:= 67.90 for decreasing the value held in savings by 67.90.
Fork a new Qulog thread, give it the name Name, and start the thread executing Action. If Name is a variable it will be instantiated to a name given by the system. If Name is given it must not be the name of an existing thread.
mode/type fork_as : (actcall, ?atom) ~>>Alternative syntax: fork Action as Name
This is the message receive action. It will succeed it there is a message term in that threads message buffer whose message term unifies with Term and whose message handle unifies with Handle. If not the call will suspend and be repeatedly retried as new messages arrive until it succeeds. When it does succeed, the matched message will be removed from the message buffer.
mode/type from : (term?, ?handle) ~>>Alternative syntax: Term from Handle
This is the message send action. It sends Term as a message to the thread (of possibly another process on another machine) whose message address is Handle.
mode/type to : (??term, !handle) ~>>Alternative syntax: Term to Handle
Causes the executing thread to suspend for Secs seconds.
mode/type thread_sleep : (!num) ~>>
An interpreter command that can be used in teleor mode when an agent has been started using start_agent. Actions is a list of actions that agent wants the robotic interface to perform. The given actions must have been declared as discrete or durative.
mode/type actions : ([discrete || durative]) ~>>
Kill the current agent started using start_agent.
mode/type kill_agent : () ~>>
Kill the task with name Task started using start_task.
mode/type kill_task : (atom) ~>>
start_agent(Name, Handle, Convention)
Start a new agent whose name is Name. Handle is the message address of the robot interface or simulation with which the agent will interact. Convention is the percepts update convention being used. This is one of: all if the robot sends all the percepts each time it sends percepts; updates if the robot only sends changes to percepts; or user if the percept management is application specific in which case the action handle_percepts_ needs to be defined in the program.
mode/type start_agent : (atom, handle, atom) ~>>
Start a new task (as a thread) whose name is Name. TRCall is the TeleoR call to be executed in the thread.
mode/type start_task : (atom, trcall) ~>>
Table of Contents | Overview of QuLog | Getting Started | Syntax | Built-ins | Standard Operators | Index |