Embedded Foreign Language Interface
This supplement to the Fril Reference manual describes how to embed Fril as
a module in a program written in C or another high-level language.The software
is evolving and may change before a final version is released. It is provided
for educational, research or private use by an individual or organisation, and
may not be sold or included in any system used commercially without prior written
agreement from the authors. See the
Fril Resources Page for author details and the license
conditions
1. Overview
The Embedded Fril Foreign Language Interface enables Fril to be included as
a component of a larger system, allowing a program to run Fril queries by means
of a set of interface functions. This interface is a superset of the functions
defined in the Fril Technical Reference Manual (Section 16.14). The embedded
system is supplied as a linkable library :
| Operating System |
library format |
library name |
Availability |
| Windows |
dynamic link library (DLL)
(fril version 4.982)
|
FrilLib.dll |
Zip
archive |
| Solaris |
shared library
(fril version 4.983)
|
libFrilLib.so |
gzipped
tar archive
unpack with gunzip solarisFril.tar.gz
tar xvf solarisFril.tar
and move the library libFrilLib.so to an appropriate directory
|
| MacOS X |
shared library
(fril version 4.983)
|
libFril.so |
gzipped
tar archive
unpack with gunzip macosxFril.tar.gz
tar xvf macosxFril.tar
and move the library libFrilLib.so to an appropriate directory
|
| Linux |
shared library
(fril version 4.981)
|
libFril.so |
4.981
downloads |
The relevant library must be linked with the your object code to provide the
final system.
In order to call the embedded Fril system, your code must first initialise
Fril using the function initialise_fril().
Two distinct methods are then available to invoke Fril:
(a) a low level interface, which enables the program to build up a goal, call
Fril to execute it and then extract arguments which have been instantiated by
the execution. Broadly speaking, the procedure is as follows:
- initialise the interface using the function initialise_interface()
- create a goal using the functions createlist(...),
putatom(...), putint(...) etc
- inform Fril of the goal using the function putgoal(...)
- call Fril to execute the goal using the function call_fril(...)
- extract required information from the goal using the functions getatom(...),
getint(...) etc
(b) a high level interface which passes the goal as a string, similar to the
normal command line interface of a standard Fril system. Two functions are available:
- exec_fril, which should be used to execute a command
where no further information is required other than the sucees or failure
of the command
- query_fril, which can be used to bind variables.
The values of these variables can be extracted using the low level interface
functions getatom(...), getint(...)
etc.
The remainder of this document describes the interface functions, and provides
a simple example using the embedded interface.
Overview of passing arguments between Fril and the host C program
Using the low-level interface, C arguments are not passed directly to Fril
since this could restrict the argument types and create compatibility problems
on some systems. Instead, the arguments to the Fril predicate are passed via
the Fril interface as a list, and various functions are provided to access the
elements of this list.
The Fril interface provides a unique list identifier for each list, which is
created by the functions createlist and getlist. Any sub-lists are also given
unique list identifiers, and the same functions can be used to access any element
of any identified list.
Declarations for the interface functions are contained in the header file ifrilc.h.
The functions are described below using 'C' style declarations for arguments.
Declarations "int" and "float" indicate that the corresponding argument is an
integer or a real number, respectively, which is passed by value. The declarations
"int *", "float *" and "char *", indicate that the corresponding argument is
an integer, a real number or a character string, respectively, which is passed
by address.
Examples
The files
test_emb.c, count3.c,
count4.c
and count5.c
provide examples of the interface. Fril source files count3.frl
and lists.frl
are used by these examples. The header file ifrilc.h
is also required for compilation. To run the examples:
- obtain the embedded library files for your system
- compile one of the C example files listed above
- link with the embedded library (NB at least 8M of memory is recommended
for the executable code)
- run the example.
2. The Interface Functions
int initialise_fril ()
Behaviour :
initialises the Fril system, setting up knowledge base and other Fril runtime structures. This function should only be called once, before any other interface functions.
Return values
0 - error detected
1 - function completed satisfactorily
Errors
None
int exec_fril (char * buf , int(char*) outfn)
Behaviour :
exec_fril is a high level method of passing control to the Fril system,
executing a goal specified by the character string in buf. This is identical
to the string typed at the usual Fril prompt in the standard system.
Any additional characters in buf are used for input by Fril built-in predicates
that would normally read from stdin. If the Fril program attempts to read
from stdin and no more characters are available, execution will suspend
so that the buffer can be refilled (or replaced).
The second argument, outfn, is a pointer to a function which is called
by Fril when it has output i.e. when it would normally write to stdout.
Return values
1 - the goal succeeded
0 - the goal failed
-1 - Fril execution was interrupted (by an error or <break> key)
-2 - Fril has terminated - the system has executed the goal (exit 0) and cannot
restart
-3 - Fril is trying to read keyboard input (e.g. when executing the ÒrÓ built-in
predicate) but no further characters are available in the buffer
Errors
any Fril error may be produced by the executing Fril program
Notes :
NB When Fril is reading keyboard input using built-in predicates such as r, getb,
etc. it first takes characters from the buf argument. When this is exhausted,
Fril returns a value of -3. Execution can be continued by calling resume_fril(...)
with a new (or refilled) character buffer. See the file test_emb.c for an example.
int query_fril (char * buf , int(char*) outfn)
Behaviour :
query_fril is a high level method of passing control to the Fril system,
enabling arguments to be returned to the calling code. It executes a goal specified
by the character string in buf. This is identical to the argument to a
ÒwhÓ query in the usual Fril system, i.e. it consists of a term followed by one
or more goals. Variables in the term will normally be bound during execution of
the goal, and the bound values can be found using low level access functions and
the special list identifier HLGOAL with argument HLARG (defined in ifrilc.h)
Any additional characters in buf are used for input by Fril built-in predicates
that would normally read from stdin. If the Fril program attempts to read
from stdin and no more characters are available, execution will suspend
so that the buffer can be refilled (or replaced).
The second argument, outfn, is a pointer to a function which is called
by Fril when it has output i.e. when it would normally write to stdout.
Return values
1 - the goal succeeded
0 - the goal failed
-1 - Fril execution was interrupted (by an error or <break> key)
-2 - Fril has terminated - the system has executed the goal (exit 0) and cannot
restart
-3 - Fril is trying to read keyboard input (e.g. when executing the ÒrÓ built-in
predicate) but no further characters are available in the buffer
Errors
any Fril error may be produced by the executing Fril program
Notes :
NB When Fril is reading keyboard input using built-in predicates such as r, getb,
etc. it first takes characters from the buf argument. When this is exhausted,
Fril returns a value of -3. Execution can be continued by calling resume_fril(É)
with a new (or refilled) character buffer. See the filecount4.c for an example.
int resume_fril (char * buf , int(char*) outfn)
Behaviour :
resume_fril restarts execution of a query passed using exec_fril
or query_fril, which has suspended execution because
it needs input. If the query has completed execution, calling resume_fril
will force backtracking to find another solution.
Return values
1 - the goal succeeded
0 - the goal failed
-1 - Fril execution was interrupted (by an error or <break> key)
-2 - Fril has terminated - the system has executed the goal (exit 0) and cannot
restart
-3 - Fril is trying to read keyboard input (e.g. when executing the ÒrÓ built-in
predicate) but no further characters are available in the buffer
Errors
any Fril error may be produced by the executing Fril program
Notes :
NB When Fril is reading keyboard input using built-in predicates such as r, getb,
etc. it first takes characters from the buf argument. When this is exhausted,
Fril returns a value of -3. Execution can be continued by calling resume_fril(É)
again with a new (or refilled) character buffer. See the file count3.c for an
example.
int call_fril (char * buf , int(char*) outfn)
Behaviour :
call_fril is the low-level method of passing control to the Fril system.
It executes the goal specified by the most recent call to putgoal. If the goal
has already been executed, call_fril(É) forces backtracking to obtain more
solutions. If the goal suspended execution because it needed input, then execution
will restart from the point of suspension.
The argument buf is used for input by any Fril built-in predicates that
would normally read from stdin. If the Fril program attempts to read from
stdin and no more characters are available, execution will suspend so that
the buffer can be refilled (or replaced).
The second argument, outfn, is a pointer to a function which is called
by Fril when it has output i.e. when it would normally write to stdout.
Return values
1 - the goal succeeded
0 - the goal failed
-1 - Fril execution was interrupted (by an error or <break> key)
-2 - Fril has terminated - the system has executed the goal (exit 0) and cannot
restart
-3 - Fril is trying to read keyboard input (e.g. when executing the ÒrÓ built-in
predicate) but no further characters are available in the buffer
Errors
any Fril error may be produced by the executing Fril program
Notes :
NB When Fril is reading keyboard input using built-in predicates such as r, getb, etc. it first takes characters from the buf argument. When this is exhausted, Fril returns a value of -3. Execution can be continued by calling call_fril(É) again with a new (or refilled) character buffer. See the file test_emb.c for an example.
void initialise_interface ()
Behaviour :
initialise_interface initialises the embedded foreign language interface,
by clearing structures created during previous transfer of information across
the interface. This function should be called before a new goal is created. Any
list identifiers created prior to a call to initialise_interface are invalid
after the call.
Return values
none
Errors
none
int putgoal (int listid)
Behaviour :
putgoal passes a goal to the embedded Fril system, ready for execution by call_fril().
The single argument, listid, is the identifier of a list created by a call
to createlist
Return values
0 - error detected
1 - function completed satisfactorily
Errors
interface error 604: invalid listid
int getlistlen (int listid, int * val)
Behaviour :
This function is used to determine the length of the list referenced by the identifier
listid. On return, the integer val is set to the length of the list.
If the list is unterminated, val is minus the number of elements currently
known to be in the list, e.g. if listid referenced the list (a b c|X),
then val would be set to -3. Note that in the case of an unterminated list,
the length can change if additional elements are put into the list (see example
under putlistlen).
Return values
0 - error detected
1 - function completed satisfactorily
Errors
interface error 604: invalid listid
int putlistlen (int listid, int val)
Behaviour :
This function sets the length of the unterminated list referenced by the identifier
listid. The positive integer val specifies the new length of the list, which must
be at least as great as the current list length. See below for an example
Return values
0 - error detected
1 - function completed satisfactorily
Errors
interface error 602: element e requested by putlistlen, only <len> elements
in list interface
error 604: invalid listid interface
error 654: list is longer than val elements
Notes :
Error 654 arises if the list already has more than val elements. Either
it is not an unterminated list, or put functions have increased the list to a
size greater than val elements. Error 602 arises when the list is not unterminated,
and has fewer than val elements.
int getitemtype (int listid, int argnum, int val)
Behaviour :
getitemtype determines the nature of the argnumth element in the list referenced
by listid, and stores in val one of the following values:
INTF_ATOM item is an atom
INTF_INT item is an integer
INTF_FLOAT item is a real number (float)
INTF_LIST item is a list
INTF_VBLE item is an uninstantiated variable.
These values are defined in the file ifrilc.h
as follows:
#define INTF_ATOM 1
#define INTF_INT 2
#define INTF_FLOAT 3
#define INTF_LIST 4
#define INTF_VBLE 5
Return values
0 - error detected
1 - function completed satisfactorily
Errors
interface error 604: invalid listid
int getint (int listid, int argnum, int* int_ptr)
Behaviour :
getint is used to retrieve an integer from a specified position in a list.
The integer argument listid identifies a list (created by createlist
or getlist), and the integer argument argnum specifies
the argument position within the list. The third argument is a pointer to the
integer value, which is set by successful completion of this call.
Return values
0 - error detected
1 - function completed satisfactorily
Errors
interface error 602: element <argnum> requested by getint, only <len> elements in list
interface error 604: invalid listid
int getfloat (int listid, int argnum, float * float_ptr)
Behaviour :
getfloat is used to retrieve a real number (float) from a specified position
in a list. The integer argument listid identifies a list (created by createlist
or getlist), and the integer argument argnum specifies
the argument position within the list. The third argument is a pointer to the
float value, which is set by successful completion of this call.
Return values
0 - error detected
1 - function completed satisfactorily
Errors
interface error 602: element <argnum> requested by getfloat, only <len> elements in list
interface error 604: invalid listid
int getatom (int listid, int argnum, char * char_ptr)
Behaviour :
getatom is used to retrieve a string from a specified position in a list.
The integer argument listid identifies a list (created by createlist
or getlist), and the integer argument argnum specifies
the argument position within the list. The third argument is a pointer to a character
array, whose contents are set to the string by successful completion of this call.
Fril strings can be up to 128 characters long.
Return values
0 - error detected
1 - function completed satisfactorily
Errors
interface error 602: element <argnum> requested by getatom, only <len>
elements in list
interface error 604: invalid listid
int getlist (int listid, int argnum, int* newlistid)
Behaviour :
getlist is used to retrieve a list from a specified position in a higher
level list. The integer argument listid identifies a list (created by createlist
or getlist), and the integer argument argnum specifies
the argument position within the list. The third argument is a pointer to an integer,
whose value is set to the new list identifier on successful completion of this
call.
Return values
0 - error detected
1 - function completed satisfactorily
Errors
interface error 602: element <argnum> requested by getlist, only <len>
elements in list
interface error 604: invalid listid
int putint (int listid, int argnum, int int_val)
Behaviour :
putint is used to unify an integer value with the element at a specified
position in a list. The integer argument listid identifies a list (created
by createlist or getlist), and
the integer argument argnum specifies the element position within the list.
The third argument is an integer, whose value is unified with the specified list
element.
Return values
0 - error detected
1 - function completed satisfactorily
Errors
interface error 602: element <argnum> requested by putint, only <len> elements in list
interface error 604: invalid listid
int putfloat (int listid, int argnum, float float_val)
Behaviour :
putfloat is used to unify a float value with the element at a specified
position in a list. The integer argument listid identifies a list (created
by createlist or getlist), and
the integer argument argnum specifies the element position within the list.
The third argument is a float, whose value is unified with the specified list
element.
Return values
0 - error detected
1 - function completed satisfactorily
Errors
interface error 602: element <argnum> requested by putfloat, only <len> elements in list
interface error 604: invalid listid
int putatom (int listid, int argnum, char* str)
Behaviour :
putatom is used to unify a string with the element at a specified position
in a list. The integer argument listid identifies a list (created by createlist
or getlist), and the integer argument argnum specifies
the element position within the list. The third argument is a character array
(string), whose value is unified with the specified list element.
Return values
0 - error detected
1 - function completed satisfactorily
Errors
interface error 602: element <argnum> requested by putatom, only <len> elements in list
interface error 604: invalid listid
int putlist (int listid, int argnum, int newlistid)
Behaviour :
putlist is used to unify a list (identified by newlistid) with the
element at a specified position in the list identified by listid. The integer
argument listid identifies a list (created by createlist
or getlist), and the integer argument argnum specifies
the element position within the list. The third argument is a list identifier,
giving the list which is unified with the specified list element.
Return values
0 - error detected
1 - function completed satisfactorily
Errors
interface error 602: element <argnum> requested by putlist, only <len> elements in list
interface error 604: invalid listid
int createlist (int * listid, int length)
Behaviour :
createlist allows a new list of given length to be created. A new list
identifier is provided by the interface, and this can be used in subsequent calls
to the other access functions. Initially, the list consists of distinct variables,
which can be bound by the ÒputÓ functions. Specifying a length of -1 creates an
unterminated list, i.e. (H|T).
Return values
0 - error detected
1 - function completed satisfactorily
Errors
interface error 601: invalid length
int putarg (int listid1, int argnum1, int listid2, int argnum2)
Behaviour :
putarg unifies theargnum1th element of the list identified by listid1
with the argnum2'th element of the list identified by listid2 (assuming
these are both valid references). Normally both will reference Fril variables,
which share the same value on successful completion of this call.
Return values
0 - error detected
1 - function completed satisfactorily
Errors
interface error 602: element <argnum> requested by putarg, only <len> elements in list
interface error 604: invalid listid
int getversion (char* buffer)
Behaviour :
getversion fills the buffer with the version number and build date of the
embedded Fril library.
Return values
0 - error detected
1 - function completed satisfactorily
Errors
None