liboaa.c

来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 1,973 行 · 第 1/5 页

C
1,973
字号
/****************************************************************************
 *   File    : liboaa.c
 *   Author  : Adam Cheyer, David Martin
 *   Purpose : Contains C version of library for the Open Agent Architecture
 *   Updated : 5/21/97
 *
 *   -------------------------------------------------------------------------
 *   Unpublished-rights reserved under the copyright laws of the United States.
 *
 *      This data and information is proprietary to, and a valuable trade
 *      secret of, SRI International.  It is given in confidence by SRI
 *      International. Its use, duplication, or disclosure is subject to the
 *      restrictions set forth in the License Agreement under which it has
 *      been distributed.
 *
 *   Unpublished Copyright (c) 1993-97, SRI International.
 *   "Open Agent Architecture" and "OAA" are Trademarks of SRI International.
 *   -------------------------------------------------------------------------
 *
 *
 ****************************************************************************
 * Note: internal functions use the naming convention oaa_function_name(),
 *     while public predicates use oaa_PublicPredicate().
 *****************************************************************************/
#define EXPORT_BORLAND

#ifdef IS_DLL
#define EXPORT_MSCPP __declspec(dllexport)
#else
#define EXPORT_MSCPP
#endif


/****************************************************************************
 * RCS Header
 ****************************************************************************/
#ifndef lint
/*static char *rcsid= "$Header: /home/zuma1/OAA/CVSRepository/oaa2/src/oaalib/c/src/liboaa.c,v 1.70 2005/05/02 16:04:51 agno Exp $";*/
#endif


/****************************************************************************
 *Include files
 ****************************************************************************/

#include <string.h>	/* string functions			*/
#include <stdio.h>
#include <stdlib.h>

#ifndef _WINDOWS
#include <sys/param.h>	/* used by getlocalhostname 		*/
#include <sys/time.h>   /* used by oaa_Ping			*/
#include <stdarg.h>   /* used by oaa_Ping		*/
#else
#include <time.h>   /* used by oaa_Ping			*/
#include <stdarg.h>   /* used by oaa_Ping		*/
#include <windows.h>   /* used by oaa_Ping		*/
#include <winsock.h> /* bzero, bcopy */
#endif

#include "libicl_private.h"
#include "libicl.h"	/* ICL term parsing/generating library 	*/
#include "libdb.h"	/* Database library 			*/
#include "libcom_tcp.h"	/* coms library				*/
#include "liboaa.h"	/* OAA library headers			*/
#include "dictionary.h" /* utility collection data type */
#include "testers.h"

/* Some param.h versions don't have this defined? */
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 256
#endif


/****************************************************************************
 * Global variables
 ****************************************************************************/

char* oaa_library_version_str = "[2,3,1]";

/* DEBUG */
extern ICLDatabase *commdb;

static ICLTerm  *oaa_solvables = NULL;                /* list of agent capabilities */
static int	    oaa_trace_on 	= FALSE;      /* Tracing on         */
static int	    oaa_com_trace_on 	= FALSE;  /* COM Tracing on         */
static int	    oaa_debug_on 	= FALSE;      /* Debugging on       */
static double   oaa_timeout	= 0.0;	 	      /* Idle timeout value */

/* Queue of events    */
ICLTerm  *oaa_saved_events = NULL;

static ICLDatabase *local_db = NULL;                  /* C equivalent of prolog db */

/* This list contains the terms to be printed by oaa_TraceMsg */
/*static ICLTerm* trace_messages_list = NULL;*/

static char * oaa_built_in_solvables_str =
"[solvable(oaa_trigger(_TriggerId, _Type, _Condition, _Action, _Params), [type(data)], [write(true)])]";

static ICLTerm *oaa_built_in_solvables_term = NULL;

int oaa_argc = 0;
char** oaa_argv = NULL;

/* For unique goal and trigger IDs */
static int globalCounter = 1;

/*
************************  TABLES   *****************************
* these substitute for various lists of things that are
* stored in the generic database in the prolog version.
*/

/*
 * context_table is used to store current contexts in the absence of
 * asserta and retract predicates
 */
static DICTIONARY *context_table = (DICTIONARY *)NULL;
/*
 * oaa_delay is a table to record requests for delayed solutions to particular
 * goals
 */
static DICTIONARY *oaa_delay = (DICTIONARY *)NULL;
/*
 * oaa_delay_table records the detailed results of a delayed goal
 */
static DICTIONARY *oaa_delay_table = (DICTIONARY *)NULL;
/*
 * oaa_callback stores asserted callbacks.  takes the place of
 * oaa_callback/2 predicates
 */
static DICTIONARY *oaa_callback = (DICTIONARY *)NULL;
/*
 * oaa_cache stores cached solutions.  This is a alternative to asserting
 * oaa_cache(Goal,Solutions) terms in the general DB.
 */
static DICTIONARY *oaa_cache = (DICTIONARY *)NULL;
/*
 * oaa_waiting_for is used to associate event lists with unique ids
 */
static DICTIONARY *oaa_waiting_for = (DICTIONARY *)NULL;
/*
 * oaa_waiting_event stores the events themselves
 */
static DICTIONARY *oaa_waiting_event = (DICTIONARY *)NULL;

/**
 * Must be called to init oaa parameters, such as
 * argv and agrc. In the multithreaded version, starts the oaa thread.
 */
EXTERN int oaa_Init(int argc, char* argv[]) {
  oaa_argc = argc;
  oaa_argv = argv;
  return TRUE;
}

/**
 * Use unification to compare 2 terms, returning 0 for success and
 * 1 for failure. Used for qsort-like comparison.
 */
int oaa_compare_terms(void *t1, void *t2) {
  ICLTerm *term1 = (ICLTerm *)t1;
  ICLTerm *term2 = (ICLTerm *)t2;

  /* DEBUG */
  /*
    printDebug(1, "oaa_compare_terms : %s VS %s \n",
    icl_NewStringFromTerm(term1),
    icl_NewStringFromTerm(term2));
  */

  if(icl_Unify(term1, term2, NULL)) {
    return 1;
  }
  return 0;
}

/**
 * Record current contexts associated with a particular id.
 * This function is specific to the C version and replaces the
 * the predicate asserta(oaa_current_contexts(ID, Contexts)).
 */
int oaa_assert_current_contexts(ICLTerm *id, ICLTerm *contexts) {
  /*
   * if this is the first use of this function, create a dictionary
   * that uses unification to determine key equivalency
   */
  if(context_table == NULL)
    context_table = dict_new(oaa_compare_terms, (void *)icl_FreeTermSingle);
  dict_put_nonunique(context_table, (void *)icl_CopyTerm(id), (void *)contexts);
  return TRUE;
}

/**
 * Retrieve the context associated with id without removing the
 * entry from the table. This function is specific to the C version
 * and replaces the predicate oaa_current_contexts(id, Contexts).
 */
int oaa_retrieve_current_contexts(ICLTerm *id, ICLTerm **contexts) {
  if(context_table != NULL) {
    *contexts = (ICLTerm *)dict_get(context_table, (void *)id);
    if(*contexts)
      return TRUE;
  }
  return FALSE;
}

/**
 * Retrieve the nth id and contexts from the current_context table.
 * This function is specific to the C version and replaces the
 * the predicate oaa_current_contexts(Id, Contexts) i.e. when the
 * goal is called with both parameters as uninstantiated variables.
 */
int oaa_retrieve_nth_current_contexts(ICLTerm **id, ICLTerm **contexts,
                                      int n) {
  /*
   * if this is the first use of this function, create a dictionary
   * that uses unification to determine key equivalency
   */
  if(context_table != NULL) {
    if(dict_get_nth(context_table, (void **)id, (void **)contexts, n))
      return TRUE;
  }
  return FALSE;
}

/**
 * Retract all current contexts associated with a particular id.
 * This function is specific to the C version and replaces the
 * the predicate retractall(oaa_current_contexts(ID)).
 */
int oaa_retractall_current_contexts(ICLTerm *id) {
  if(context_table != NULL) {
    void **values;
    int    num_found, i;

    values = dict_remove_all(context_table, id, &num_found);
    if (values != NULL) {
      for (i=0; i<num_found; i++) {
	free((values[i]));
      }
      free(values);
      return TRUE;
    }
  }
  return FALSE;
}

/**
 * Assert the fact that the user has requested a delayed solution to
 * a particular goal.
 */
int oaa_assert_delay(ICLTerm *id, ICLTerm *user_id) {
  if(oaa_delay == NULL) {
    oaa_delay = dict_new(oaa_compare_terms, NULL);
  }
  dict_put(oaa_delay, (void *)id, (void *)user_id);
  return TRUE;
}

/**
 * Retract the fact that the user has requested a delayed solution to
 * a particular goal and return the user id.
 */
int oaa_retract_delay(ICLTerm *id, ICLTerm **user_id) {
  if(oaa_delay != NULL) {
    *user_id = (ICLTerm *)dict_remove(oaa_delay, (void *)id);
    if(*user_id)
      return TRUE;
  }
  return FALSE;
}

/**
 * Store the solution to a delayed goal.
 */
int oaa_assert_delay_table(ICLTerm *goal_id, ICLTerm *user_id,
                           ICLTerm *full_goal, ICLTerm *solve_params,
                           ICLTerm *all_params) {
  ICLTerm *value_list = icl_NewList(NULL);
  /* first make sure the table exists */
  if(oaa_delay_table == NULL) {
    oaa_delay_table = dict_new(oaa_compare_terms, (void *)icl_FreeTermSingle);
  }
  /*
   * Now make a list out of the value terms.  Lookups will be done based
   * on the user_id, so make that the key and put the rest of the terms
   * into a list
   */
  icl_AddToList(value_list, goal_id, TRUE);
  icl_AddToList(value_list, full_goal, TRUE);
  icl_AddToList(value_list, solve_params, TRUE);
  icl_AddToList(value_list, all_params, TRUE);
  /*
   * put nonunique since there may be more than one delayed solution
   * per user_id
   */
  dict_put_nonunique(oaa_delay_table, (void *)icl_CopyTerm(user_id), (void *)value_list);
  return TRUE;
}

/**
 * Remove and return the first solution found that has been
 * stored with the key, user_id.
 */
int oaa_retract_delay_table(ICLTerm **goal_id, ICLTerm *user_id,
                            ICLTerm **full_goal, ICLTerm **solve_params,
                            ICLTerm **all_params) {
  /* first make sure the table exists */
  if(oaa_delay_table != NULL) {
    ICLTerm *value_list =
      dict_remove(oaa_delay_table, (void *)user_id);
    if(value_list) {
      *goal_id = icl_NthTerm(value_list, 1);
      *full_goal = icl_NthTerm(value_list, 2);
      *solve_params = icl_NthTerm(value_list, 3);
      *all_params = icl_NthTerm(value_list, 4);
      icl_Free(value_list);
      return TRUE;
    }
  }
  return FALSE;
}

/**
 * Store a callback procedure associated with a particular id.
 */
int oaa_assert_callback(ICLTerm *id, int (*user_callback)(ICLTerm*, ICLTerm*, ICLTerm*)) {
  {
    ICLTerm *key;
    if(oaa_callback == NULL) {
      oaa_callback = dict_new(oaa_compare_terms, NULL);
    }
    if(dict_index_for_key(oaa_callback, id) >= 0) {
      key = id;
    }
    else {
      key = icl_CopyTerm(id);
    }
    dict_put(oaa_callback, key, user_callback);
  }
  CHECK_LEAKS();
  return TRUE;
}

/**
 * Retrieves the callback procedure without retracting it.
 */
int oaa_retrieve_callback(ICLTerm *id,  int (**user_callback)(ICLTerm*, ICLTerm*, ICLTerm*)) {
  if(oaa_callback != NULL) {
    *user_callback = dict_get(oaa_callback, (void*)id);
    if(*user_callback) {
      return TRUE;
    }
  }
  return FALSE;
}

/**
 * Retract the first callback associated with this id.
 */
int oaa_retract_callback(ICLTerm *id, int (*user_callback)(ICLTerm*, ICLTerm*, ICLTerm*)) {
  if(oaa_callback != NULL) {
    user_callback = dict_remove(oaa_callback, (void *)id);
    if(user_callback != NULL) {
      return TRUE;
    }
  }
  return FALSE;
}

/**
 * Retract all callbacks associated with this id.
 */
int oaa_retractall_callback(ICLTerm *id, ICLTerm **proc) {

  if(oaa_callback != NULL) {
    void **values;
    int    num_found, i;

    values = dict_remove_all(oaa_callback, id, &num_found);
    if (values != NULL) {
      *proc = (ICLTerm *)*values;	/* ?? */
      for (i=0; i<num_found; i++) {
        free((values[i]));
      }
      free(values);
      return TRUE;
    }
  }
  return FALSE;
}

/**

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?