This component provides everything required to build an agent in Delphi for use with the Open Agent Architecture framework. TAgent provides routines and methods for network communication, ICL parsing, trigger management, dynamic string handling and distributed queries.
At design time, set values for the Host, Port and QPServer32 properties. ICL services that the agent will provide should be declared in the Solvable list, and then code for each of the solvables should be added to the OnOAAEvent event. Incoming requests can be parsed using Prolog parsing routines.
At runtime, the Connect method will establish a connection with a remote OAA server agent.
Address Host KSName Port QPServer32 Solvable TraceOn TcpTraceOn varAbort
Connect Connected Disconnect SendData PostEvent Interpret Solve WriteBB WriteOnceBB WriteReplaceBB ReplaceBB RetractBB AddTrigger AddTriggerToKS
OnOAAEvent OnOAAInfo OnTcpInfo
oaaAgent (TAgent Component)
property Address: string;
Contains the IP address for the Host Server. This can be left empty, if the property Host is given, and it will be filled in during connection.
oaaAgent (TAgent Component)
property Host: string;
Contains the host where to find the Server agent.
This property should be set before calling Connect.
oaaAgent (TAgent Component)
property KSName: string;
Stores the internal name for the agent with respect to the Server agent.
This property should be set before calling Connect.
oaaAgent (TAgent Component)
property Port: u_short;
Contains the port used by the Server agent.
This property should be set before calling Connect.
oaaAgent (TAgent Component)
property QPServer32: Boolean;
If QPServer32 is true, an OAA Server agent compiled with Quintus Prolog v3.2 or later is expected. Earlier versions of Prolog expect a different data initialization when connecting.
oaaAgent (TAgent Component)
property Solvable: TStringList;
Contains a list of ICL capabilities or services that the agent proposes to provide.
oaaAgent (TAgent Component)
property TraceOn: Boolean;
If TraceOn is true, status messages will be traced through the event OnOAAInfo.
oaaAgent (TAgent Component)
property TcpTraceOn: Boolean;
If TcpTraceOn is true, all incoming and outgoing data will be traced through the event OnTcpInfo.
oaaAgent (TAgent Component)
property varAbort: Boolean
If varAbort becomes true, any pending solve events will be cancelled without waiting for the Server to return an answer. Solve returns false.
This property is runtime only.
oaaAgent (TAgent Component)
procedure Connect;
Establishes a connection, then sends the agentname, solvable list and agent language to the Server.
oaaAgent (TAgent Component)
procedure Disconnect;
Disconnects from the Server agent.
oaaAgent (TAgent Component)
procedure SendData(data: Pchar);
Sends raw data (not an event) to the Server agent.
oaaAgent (TAgent Component)
procedure PostEvent(fmt : PChar; const argsP: array of Pchar; const argsC: array of Const);
Sends an event to the Server
oaaAgent (TAgent Component)
procedure Interpret(ks: PChar; event: PChar; var answers: Pchar);
Executes an incoming event. If an event is a builtin routine, it is executed here. Otherwise, the event is passed to the OnOAAEvent event handler defined for the agent.
Builtin events are:
trace_on
trace_off
halt
solve()
oaaAgent (TAgent Component)
procedure Solve(fmt: PChar; const argsP: array of Pchar; const argsC: array of const; const params: PChar; var answers: Pchar);
Requests data or actions from distributed agents.Inputs
goal: an ICL goal to be solved/performed
params: control parameters describing how the goal should be resolved.Outputs
answers: a list of answers. Should be "[]" for failure, or a list containing the event with variables replaced with values.
example: a query "a(X)" could return "[a(1),a(2),a(3)]"Parameters
cache cache all solutions locally
level_limit(N) highest number of levels to climb for solutions
address(KS) a specific KS to solve goal
and_parallel and-parallel solve of goal list
or_parallel or-parallel solve of goal list
test(Test) only solve goal on blackboards where Test succeeds
locally.
broadcast just disseminate message, do not request results
solution_limit(N) limits number of solutions found to N. Currently only
works for 1...
time_limit(N) waits a maximum of N seconds before returning (failure
if no solution).
context(C) define a context which will be passed to all solves
resulting from your initial solve request.
oaaAgent (TAgent Component)
procedure WriteBB(item, data: Pchar);
Add information to global data stored on Blackboard Server
oaaAgent (TAgent Component)
procedure WriteOnceBB(item, data: Pchar);
Add information to global data stored on Blackboard Server at most once time (if exists, doesn't write again)
oaaAgent (TAgent Component)
procedure WriteReplaceBB(item, data: Pchar);
Add information to global data stored on Blackboard Server, replacing old information with new information.
oaaAgent (TAgent Component)
procedure ReplaceBB(item, oldData, newData: Pchar);
Change item value from Old to New.
oaaAgent (TAgent Component)
procedure RetractBB(item, data: Pchar);
Remove item from global data store on Blackboard Server.
oaaAgent (TAgent Component)
procedure AddTrigger(kind, typeOf, condition, action: Pchar);
Adds a trigger to the appropriate agentInputs
Kind: may be 'test', 'data', or 'alarm' (not 'event')
Type: may be 'when' (once), 'if' (once), 'whenever' (persistent)
Condition: test condition
Action: action to be performed if condition succeedsRemarks
add_trigger/4 does not require a KS to be specified, because the KS will always be determined automatically:
data: always installed on the Server
test: installed on appropriate agent by solvable
alarm: installed on the alarm agent
For 'event' triggers, use AddTriggerToKS()
oaaAgent (TAgent Component)
procedure AddTriggerToKS(ks, kind, typeOf, condition, action: PChar);
Adds a trigger to the specified agentInputs
Kind: may be 'test', 'event', or 'alarm' (not 'data'!)
Type: may be 'when' (once), 'if' (once), 'whenever' (persistent)
Condition: test condition
Action: action to be performed if condition succeedsRemarks
Cannot install a data trigger because data triggers always go on the Server agent, which is not a valid KS. Use AddTrigger().
oaaAgent (TAgent Component)
procedure OAAInfo(Sender : TObject; icode: TOAAInfo; data: PChar);Purpose
Send the application certain types of OAA information.
The sender parameter points to the TAgent component sending the message.
icode contains the type of information being sent, and data contains a value depending on icode, as described below:
siTcpTraceIn
This message is sent to the application only if the TcpTraceOn property is set to true.
data contains characters arriving from TCP server connection.
siTcpTraceOut
This message is sent to the application only if the TcpTraceOn property is set to true.
data contains characters sent to the TCP server connection.
siTraceOn
This message is sent to the application when a change in the state of the TraceOn property occurs.
data will contain the new state, either TRUE or FALSE.
siTraceMsg
This message is sent to the application only if the TraceOn property is set to true.
data contains a trace message describing some current OAA event.
oaaAgent (TAgent Component)
function OAAEvent(Sender : TObject; ks, func, args: PChar; var ans: PChar): Boolean;
OAAEvent occurs for an agent whenever it has been requested by the Facilitator to accomplish a task corresponding to an ICL expression listed in the solvable property for the agent.
The agent programmer should complete this event for all ICL expressions listed in the solvable property, defining the appropriate actions and return values for each.Inputs
ks The internal ID for the agent requesting the action. This
ID can be used to send back a specific message to the
agent using the "address()" parameter of the
solveOAAAGENT.SM_001 method.
func The functor corresponding to the ICL expression requested.
args The arguments corresponding to the functor of the ICL
expression.
Outputs
The ans parameter should return an answer in newly allocated memory that can be StrFree'd when no longer needed. Ans should contain the value '[]' if the request fails, and a list of answers if the predicate succeeds. For example, if func is 'parent' and args contains 'adam X', ans might return '[parent(adam, alice), parent(adam, tom)]'.Returns
True if the agent will attempt to handle the expression, returning either success or failure in the ans parameter, or False if the agent cannot handle the request at all.
oaaAgent (TAgent Component)
procedure TcpInfo(Sender : TObject; icode : TSockInfo);Purpose
Send messages about the state of the current TCP state.Inputs
Sender contains the TAgent component sending the message, and icode contains the TCP state as follows:
siInactive Resting state, no connection underway
siLookUp Looking up address for host
siConnect Trying to connect to host and port
siConnected Connection completed
siListen Trying to listen at specified socket
siRecv Data has been received on the TCP socket
siSend Data has been sent on the TCP socket
siClosed Socket has been closed
siTimedOut A timeout has occurred while trying to make a TCP
connection.
oaaAgent (TAgent Component)
Trim Remove leading and trailing spaces and other unprintables
RemoveQuotes Removes leading and trailing " and ' marks
DoubleQuotes Doubles any single quotes it finds in the string.
FormatLen Returns the length of the buffer required to contain a
formatted string
FStr Returns a new buffer pointing to a formatted string with
arguments inserted.
oaaAgent (TAgent Component)
function Trim(s: PChar): PChar;
purpose: Remove leading and trailing spaces and other unprintables
inputs: a string to trim
returns: A pointer to the result
remarks:
can be used as either a procedure or as a function
writes result in same space as original var, because we are sure the result will be the same size or smaller as original
oaaAgent (TAgent Component)
function RemoveQuotes(s: PChar): Pchar;
purpose: Removes leading and trailing " and ' marks
inputs: a string to trim
returns: A pointer to the result
remarks:
can be used as either a procedure or as a function
writes result in same space as original var, because we are sure the result will be the same size or smaller as original
oaaAgent (TAgent Component)Declaration
procedure DoubleQuotes(s: PChar; var ds: Pchar);
purpose: Doubles any single quotes it finds in the string. This is needed to guarantee the result will be a readable Prolog term.
inputs: a string
outputs: a string with single quotes doubled ' --> ''
remarks: Output will be a newly created space which should be StrFree'd
oaaAgent (TAgent Component)
function FormatLen(fmt : PChar; const args: array of PChar): Integer;
purpose: Returns the length of the buffer required to contain a formatted string
remarks: The only format arguments supported are '%s', '%c' and '%d'.
oaaAgent (TAgent Component)
function FStr(fmt : PChar; const argsP: array of Pchar; const argsC: array of const): PChar;
purpose: Returns a new buffer pointing to a formatted string with arguments inserted.
remarks:
The only format arguments supported are '%s' and '%d'.
The memory allocated by the new string should be StrFree'd afterwards.
The arguments must be passed in twice because I couldn't solve the type checking problem of calling both FormatLen and StrLFmt. Ideas?
oaaAgent (TAgent Component)Routines:
StrFreeOAAAGEN Deallocates a pchar and sets its value to nil T.S__002 StrAppendOAAAG Appends a string onto the end of a first one, adjusting ENT.S__003 the size of the resulting string if necessary.
oaaAgent (TAgent Component)
procedure StrFree(var p: Pchar);
purpose: Deallocates a pchar and sets its value to nil
inputs: p: a pointer to deallocate
remarks: Only deallocates memory at most once
oaaAgent (TAgent Component)
procedure StrAppend(var str1: PChar; str2: Pchar);
purpose: Appends a string onto the end of a first one, adjusting the size of the resulting string if necessary.
inputs:
str1: Returns the concatenated string
str2: A string to concatenate to str1
remarks: Don't forget to deallocate (StrFree) str1 when you are finished.
oaaAgent (TAgent Component)
Functor Splits a string containing a Prolog-style term into a
functor and arguments
Term Takes a (comma-separated) list of terms and returns the
first (car) and rest (cdr) of the list
NthElt Returns the Nth term in a list of terms
Argument Returns the Nth argument in a term
ListLen Returns the length of a comma-separated list of Prolog
terms
ListToTerms Converts an incoming Prolog list (in [elt1, elt2, ...]
form) into a comma-separated list of terms on which we can
use ListLen(), NthElt(), etc.
IsList Returns true if the term is a list (has functor '.' or
starts with '[')
IsVar Returns true iff term is a variable (i.e. starts with a
capital letter or a '_')
CharsToAtom Converts a Prolog string, represented as a list of ASCII
values, into an atom.
e.g. [97,98,99] --> 'abc'.
Match Returns true iff term1 and term2 match (unify without var
binding)
oaaAgent (TAgent Component)
procedure Functor(predicate: PChar; var func, args: Pchar);
purpose: Splits a string containing a Prolog-style term into a functor and arguments
inputs: predicate: In form "func(arg1, arg2, ...)"
outputs:
func: returns "func"
args: returns "arg1, arg2, ..."
remarks:
func and args will return new copies of the data, which should be StrFree'd once they are no longer needed.
If no arguments exist, the empty string is returned in args.
oaaAgent (TAgent Component)
procedure Term(terms: PChar; var aTerm, restTerms: Pchar);
purpose: Takes a (comma-separated) list of terms and returns the first (car) and rest (cdr) of the list.
inputs: terms: a list of prolog terms
outputs:
aTerm: first term in the list
restTerms: the rest of the terms
remarks:
Terms may be nested arbitrarily deep (e.g. a(b(c(d,1)), X) ).
aTerm will return a new copy of the first argument, which should be StrFree'd when finished using. restTerms will return a pointer into the list of terms.
Expressions may contain embedded arguments stored in 7-bit JIS format.
oaaAgent (TAgent Component)
procedure NthElt(list: PChar; n: Integer; var elt: Pchar);
purpose: Returns the Nth term in a list of terms
inputs:
list: a string containing a comma-separated list of terms
n: index into a list (nth term)
outputs: elt: the nth term in a list
remarks: elt will point to newly allocated space and should be StrFree'd when finished using.
oaaAgent (TAgent Component)
procedure Argument(predicate: PChar; n: Integer; var arg: Pchar);
purpose: Returns the Nth argument in a term
inputs:
predicate: a prolog-style term: e.g. func(a1, a2, a3, ...)
n: index into the term
outputs: argument: the nth argument in the term. if n=2, argument = a2
remarks: argument will point to newly allocated space and should be StrFree'd when finished using.
oaaAgent (TAgent Component)
function ListLen(list: PChar): Integer;
purpose: Returns the length of a comma-separated list of prolog terms
inputs: list: a string containing a comma-separated list of terms
returns: the number of terms in the list
oaaAgent (TAgent Component)
function ListToTerms(var s: PChar): Pchar;
purpose: Converts an incoming prolog list (in [elt1, elt2, ...] form) into a comma-separated list of terms on which we can use ListLen(), NthElt(), etc.
outputs: s: a string containing a list of terms
remarks: ListToTerms will store the result in the same space as the input, since we know the result will always be the same size or smaller.
oaaAgent (TAgent Component)
function IsList(term: PChar): Boolean;
purpose: Returns true if the term is a list (has functor '.' or starts with '[')
inputs: term: a string containing a prolog term
returns: True if the term is a list
oaaAgent (TAgent Component)
function IsVar(term: PChar): Boolean;
purpose: Returns true iff term is a variable (i.e. starts with a capital letter or a '_')
inputs: term1: a string containing a prolog term (or variable)
oaaAgent (TAgent Component)
function CharsToAtom(list: PChar; var atom: PChar): Boolean;
purpose:
Converts a Prolog string, represented as a list of ASCII values,
into an atom.
e.g. [97,98,99] --> 'abc'.
inputs: list: a string containing a Prolog list of ASCII characters.
outputs: atom: the list of ASCII characters converted into an atom (string).
remarks: atom will point to newly allocated space and should be StrFree'd when finished using.
returns: True if success, i.e. list was a valid list of only ASCII values.
oaaAgent (TAgent Component)
function Match(term1, term2: PChar): Boolean;
purpose: Returns true iff term1 and term2 match (unify without var binding)
inputs: term1: a string containing a prolog term (or variable)