OAA Interagent Communication Language (ICL)

API Reference Manual


Version 2.0




The OAA Home Page is at: http://www.ai.sri.com/~oaa


Open Agent Architecture and OAA are trademarks of SRI International.


Interagent Communication Language (ICL) API Reference

This section describes functions for constructing and parsing ICL messages, contained in library "liboaa". Familiarity with ICL syntax is assumed. This document does not refer to the semantics for ICL expressions, only the parsing functions for non-Prolog languages.

Structured message functions is the preferred way of manipulating ICL messages in languages such as C or C++, but string-based parsing functions are also provided for 1) simplified porting from OAA 1.0, and 2) for languages such as Visual Basic that don't have the capacity to manipulate structures and pointers.

A glossary is provided at the end of this document.


Alphabetical Index

ICL Structured Parsing Routines

Introduction to Structured Parsing Routines

Reading and Writing Terms

Creation/Freeing of Terms

Type-Testing and Unification

Data access

Lists

Convenience Structures


ICL String Parsing Routines

Introduction to String-based Parsing Routines

Data access and lists

Type-Testing and Unification

Quoting and Unquoting

Creation/Freeing


Glossary


Alphabetical Index


Introduction to String-based Parsing

Parsing incoming message

Incoming ICL messages may be complex, nested structures, and parsing functions allow a programmer to pull the messages apart to access the individual pieces.

String-based parsing functions rely heavily on COPYING when providing access to subpieces of a message. The copied subparts should then be icl_stFree'd when finished.

Example

/* An incoming message "add_person('Adam', 31, [male, eyes(brown)])" 
   should be parsed and processed. */

   char *func = NULL;
   char *args = NULL;

   icl_stFunctorArgs(event, &func, &args);
            func now is "add_person"
            args is "'Adam', 31, [male, eyes(brown)]"

   if (strcmp(func, "add_person") == 0) {
      char *name = NULL;
      int age = 0;
      char *attrs = NULL;

      icl_stNthElt(args, 1, &name);
      icl_stFixQuotes(name);
      age = icl_stNthArgAsInt(event, 2);
      icl_stNthArg(event, 3, &attrs);

      /* Call my local function to use the data */
      myAddPerson(name, age, attrs);

      /* Free space used by local variables */
      icl_stFree(name);
      icl_stFree(attrs);
   }

   icl_stFree(func);
   icl_stFree(args);

Loops

Please note that the use of icl_stNthElt to iterate over all elements in a list (as illustrated by the following example) is extremely inefficient! Since the string is not indexed, icl_stNthElt must itself iterate to arrive at the Nth element, so calling it in a loop is complexity O(n^2).
   BAD CODE: It works, but is Inefficient!!!

   list = strdup("[a,b,c,d,e,f]");

   /* Remove enclosing brackets from list */
   icl_stListToTerms(p);

   for (i = 1; i <= icl_stListLen(list); i++) {
      char *elt = NULL;

      icl_stNthElt(list, i, &elt);
      printf("element #", i, ": ", elt, "\n");

      icl_stFree(elt);
   }
   icl_stFree(list);

The preferred method for iteration is to use icl_stHeadTailPtr.

   The RIGHT way to iterate.

   char *list = NULL;
   char *p;

   list = strdup("[a,b,c,d,e,f]");

   p = list;
   i = 0;

   /* Remove enclosing brackets from list */
   icl_stListToTerms(p);

   /* Recurse over all elements in list
   while (p && *p) {
      char *elt = NULL;

      i++;
      icl_stHeadTailPtr(p, &elt, &p);
      printf("element #", i, ": ", elt, "\n");

      icl_stFree(elt);
   }

   icl_stFree(list);

   /* don't free p! */

Constructing messages to send

Messages can be constructed using normal string construction routines, such as sprintf or icl_stAppend(). Care should be taken that every message sent out conforms to ICL syntax, particularly regarding the use of quotation marks ("'"): Any single quote marks in a string must be doubled. e.g. "'Adam''s house'".

Example

In this example, we use icl_stDoubleQuotes to prepare some user input text (which may contain a "'" mark) for sending.
   char *event;

   /* create space for event to send */
   event = malloc(strlen(user_input) + 50);

   /* Double any quotes which may be in user input */
   sprintf(event, "process_english_sentence('%s')", 
      icl_stDoubleQuotes(user_input));

   /* Send ICL request */
   oaa_Solve(event, "[]", &answers);

   oaa_stFree(event);


icl_stFunctorArgs

Declaration

C: void icl_stFunctorArgs(char *structure, char **func, char **args);

Description

Splits a string containing a prolog-style structure into a functor and arguments.

Remarks


icl_stHeadTailPtr

Declaration

C: void icl_stHeadTailPtr(char *terms, char **aterm, char **restterms)

Description

Takes a comma-separated list of elements and returns a copy of the first element and a pointer to the rest of the list.

Remarks

Example

The following is an example of the recommended way to recurse over an ICL list of elements.
   char *list = NULL;
   char *p;

   list = strdup("[elt1, elt2, a(b(1),2)]");

   p = list;

   /* Remove enclosing brackets from list */
   icl_stListToTerms(p);

   /* Recurse over all elements in list
   while (p && *p) {
      char *elt = NULL;

      icl_stHeadTailPtr(p, &elt, &p);
      use(elt);

      icl_stFree(elt);
   }

   icl_stFree(list);

   /* don't free p! */


icl_stNthElt

Declaration

C: void icl_stNthElt(char *list, int n, char **elt);

Description

Returns the Nth element in a comma-separated list of terms

Remarks

Elt should be free'd when no longer needed.

See Also