liboaa.c

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

C
1,973
字号
  ICLTerm *declared_solvables = NULL;
  /* If the agent's name is read from the command line */
  char    *host = (char *)NULL;
  int      result = TRUE;
  int      isClient = TRUE;

  /* Determine whether connection is server or client type */
  isClient = isClientConnection(ConnectionId);
  if (!isClient) {
    printf("oaa_Register: server type\n");
    return FALSE;
  }

  /* Make sure there's a valid connection id */
  if (!ConnectionId || !*ConnectionId ||
      !com_GetInfo(ConnectionId,
                   (t1 = icl_NewStruct("status",
                                       1,
                                       icl_NewStr("connected"))), NULL)){

    printf("oaa_Register: No Connection\n");
    icl_Free(t1);
    return FALSE;
  }

  /* DEBUG */
  /*db_PrintDB(commdb);*/

  icl_Free(t1);

  // Check if handshaking has already occurred.
  // The internal logic of com_getInfo() does not
  // seem to work if the final parameter is NULL.
  t1 = icl_NewStruct("other_name", 1, icl_NewVar("_"));
  if (!com_GetInfo(ConnectionId, t1, &t2)) {
    oaa_handshake(ConnectionId, AgentName, Params);
  }
  icl_Free(t1);
  icl_Free(t2);

  /* Register local host */
  host = getlocalhostname();
  if (host != NULL) {
    ICLTerm *agent_host = NULL;
    ICLTerm *agent_listener = NULL;
    ICLTerm *myAddress = NULL;
    ICLTerm *myListenAddress = NULL;
    ICLTerm *named_address = NULL;
    ICLTerm* tempTerm = NULL;
    oaa_Address("parent", NULL, &myAddress);
    oaa_Address("client_listener", NULL, &myListenAddress);

    agent_host     = icl_NewStruct("agent_host", 3,
			         icl_CopyTerm(icl_NthTerm(myAddress,1)),
			         icl_NewStr(AgentName), icl_NewStr(host));
    if (isClient) {
      tempTerm = icl_NewTermFromData("[address(parent)]", 17);
      oaa_AddData(agent_host, tempTerm, NULL);

      // add agent_listener fact if I am a direct-connect client
      if (!STREQ(icl_Str(icl_NthTerm(myListenAddress,1)), "no_address")) {
        agent_listener = icl_NewStruct("agent_listener", 2,
                                       icl_CopyTerm(icl_NthTerm(myAddress,1)),
                                       icl_CopyTerm(icl_NthTerm(myListenAddress,1)));
        oaa_AddData(agent_listener, tempTerm, NULL);
        icl_Free(agent_listener);
        named_address = icl_NewStruct("name", 1, icl_NewStr(AgentName));

        agent_listener = icl_NewStruct("agent_listener", 2,
                                       icl_CopyTerm(named_address),
                                       icl_CopyTerm(icl_NthTerm(myListenAddress,1)));
        oaa_AddData(agent_listener, tempTerm, NULL);
        icl_Free(agent_listener);
      }
    }

    else{
      tempTerm = icl_NewTermFromData("[address(self)]", 15);
      oaa_AddData(agent_host, tempTerm, NULL);
    }
    icl_Free(tempTerm);
    icl_Free(agent_host);
    icl_Free(myAddress);
    icl_Free(myListenAddress);
    icl_Free(named_address);
  }

  t1 = icl_NewTermFromData("[if_exists(overwrite)]", 22);
  t2 = icl_NewList(NULL);
  t3 = icl_NewList(NULL);
  oaa_Declare(Solvables, t2, t2, t1, &declared_solvables);

  icl_Free(t1);
  icl_Free(t2);
  icl_Free(t3);
  icl_Free(declared_solvables);
  icl_stFree(host);

  return result;

} // end of oaa_Register



/**
 * Changes the agent's 'open' status to 'ready', indicating that the
 * agent is now ready to receive message.
 * If requested, prints 'Ready' to standard out.
 */
EXPORT_MSCPP
void EXPORT_BORLAND
oaa_Ready(int ShouldPrint)
{
  char *name = NULL;

  /* If client, send ready message to Facilitator */
  if (!oaa_class("root") && (name = oaa_name_string())) {
    ICLTerm* toBePosted = icl_NewStruct("ev_ready", 1, icl_NewStr(name));
    oaa_PostEvent(toBePosted, ICL_EMPTY);
    icl_Free(toBePosted);
  }
  if(name != NULL) {
    icl_stFree(name);
  }

  if (ShouldPrint)
    printf("Ready.\n");
}



/*****************************************************************************
 * Classifying and Manipulating ICL expressions
 *****************************************************************************/

/**
 * Test whether an expression is an ICL built-in goal.
 * <p><b>Remarks:</b></p>
 * <ul>
 *   <li>icl_BuiltIn differs significantly from the Quintus Prolog predicate
 *     built_in, in that here we do not include basic constructors such
 *     as ',' and ';'.</li>
 *   <li>oaa_Interpret/2 must be defined for every goal for which
 *     icl_BuiltIn succeeds.</li>
 * </ul>
 */
EXPORT_MSCPP
int EXPORT_BORLAND
icl_BuiltIn(ICLTerm *goal)
{
  int isStruct = icl_IsStruct(goal);

  if (isStruct) {
    char *s = icl_Str(goal);
    int arity = icl_NumTerms(goal);
    return (
     ((arity == 2) && STREQ(s, "="))
     || ((arity == 2) && STREQ(s, "=="))
     || ((arity == 2) && STREQ(s, "\\=="))
     || ((arity == 2) && STREQ(s, "=<"))
     || ((arity == 2) && STREQ(s, ">="))
     || ((arity == 2) && STREQ(s, "<"))
     || ((arity == 2) && STREQ(s, ">"))
     || ((arity == 2) && STREQ(s, "member"))
     || ((arity == 2) && STREQ(s, "memberchk"))
     || ((arity == 3) && STREQ(s, "findall"))
     || ((arity == 3) && STREQ(s, "icl_ConsistentParams"))
     );
  }
  else return FALSE;
}


/**
 * Test whether an expression is an ICL compound goal.
 */
int
icl_compound_goal(ICLTerm *goal)
{
  char *s = NULL;

  s = icl_Str(goal);

  return ((s != NULL) &&
          (
           STREQ(s, ":") ||
           STREQ(s, "::") ||
           STREQ(s, "\\+") ||
           STREQ(s, "->") ||
           STREQ(s, ":") ||
           STREQ(s, ",") ||
           STREQ(s, ";")
           )
          );
}

/**
 * Test whether an expression is an ICL basic (non-compound) goal;
 * that is, just a functor with 0 or more arguments.
 * <p><b>Remarks:</b></p>
 * <ul>
 *   <li>Basic goals include built-in's as well as solvables.</li>
 *   <li>This is a syntactic test; that is, we're not checking whether the
 *     Goal is a declared solvable.</li>
 * </ul>
 */
EXPORT_MSCPP
int EXPORT_BORLAND
icl_BasicGoal(ICLTerm *goal)
{
  return (icl_IsStruct(goal) && !icl_compound_goal(goal));
}



/**
 * Assemble, disassemble, or match against the top-level components
 * of an ICL goal.
 * <p><b>Remarks:</b></p>
 * <ul>
 *   <li>The top-level structure of an ICL goal is Address:Goal::Params,
 *     with Address and Params BOTH OPTIONAL.  Thus, every ICL goal
 *     either explicitly or implicitly includes all three components.</li>
 *   <li>This may be used with any ICL goal, basic or compound.</li>
 *   <li>When P is missing, its value is returned or matched as [].  When A is
 *     missing, its value is returned or matched as 'unknown'.</li>
 * </ul>
 * <p><b>Note:</b> This function allocates memory for the three
 * return values.</p>
 */
EXPORT_MSCPP
int EXPORT_BORLAND
icl_GoalComponents(ICLTerm* fullgoal, ICLTerm** address,
		   ICLTerm** goal, ICLTerm** param)
{
  int res = FALSE;
  if (icl_IsStruct(fullgoal)&&(STREQ(icl_Str(fullgoal),"::"))) {
    /* Full goal a::g:p */
    if (icl_IsStruct(icl_NthTerm(fullgoal, 1)) &&
	(STREQ(icl_Str(icl_NthTerm(fullgoal, 1)),"::"))) {
      *address =  icl_CopyTerm(icl_NthTerm(icl_NthTerm(fullgoal, 1),1));
      *goal =  icl_CopyTerm(icl_NthTerm(icl_NthTerm(fullgoal, 1),2));
      *param = icl_CopyTerm(icl_NthTerm(fullgoal, 2));
      res = TRUE;
    }else{
      /* Simple goal goal::param */
      *address = icl_NewStr("unknown");
      *goal =  icl_CopyTerm(icl_NthTerm(fullgoal, 1));
      *param = icl_CopyTerm(icl_NthTerm(fullgoal, 2));
      res = TRUE;
    }
  }else {
    if (icl_IsStruct(fullgoal)&&(STREQ(icl_Str(fullgoal),":"))) {
      *address = icl_CopyTerm(icl_NthTerm(fullgoal, 1));
      *goal = icl_CopyTerm(icl_NthTerm(fullgoal, 2));
      *param = icl_NewList(NULL);
      res = TRUE;
    } else {
      *address = icl_NewStr("unknown");
      *goal = icl_CopyTerm(fullgoal);
      *param = icl_NewList(NULL);
      res = TRUE;
    }
  }
  return res;
}

/****************************************************************************
 * Permissions and parameter lists
 *
 * These procedures are used in processing solvables permissions, and
 * parameter lists of all kinds (including those used with solvables,
 * those contained in events, and those used in calls to various
 * library procedures).
 *
 * All permissions and many parameters have default values.
 *
 * Permissions and parameters lists have a standard form, as defined by
 * the predicates below.  To save bandwidth and promote readability, a
 * "perm" or "param" list in standard form OMITS default values.  For
 * easier processing (e.g., comparing/merging param lists), boolean
 * params in standard form always include a single argument 'true' or
 * 'false'.
 *
 * In definitions of solvables and calls to documented library
 * procedures, it's OK to include default params in a Params list, if
 * desired.  For boolean params, when the intended value is 'true', it's
 * OK just to specify the functor, for example, instead of
 * cache(true), it's OK just to include 'cache'.
 *
 *
 ***************************************************************************/

/**
 * Standardizes a permissions list, removing defaults if requested.
 * Normally there's no need to keep the default value of a param,
 * but there are exceptional situations.  If KeepDefaults is true,
 * default values are kept.
 */
int
icl_standardize_perms(ICLTerm *Perms, int KeepDefaults, ICLTerm **Standardized)
{

  if (icl_IsList(Perms)) {
    ICLListType *args = NULL;
    ICLListType *newArgs = NULL;
    ICLListType *endp = NULL;
    ICLTerm *standard = NULL;

    args = icl_List(Perms);
    while (args) {
      icl_perm_standard_form(args->elt, &standard);
      if (KeepDefaults || !icl_perm_default(standard, NULL)) {
        /* Keep: add to result list */
        if (!newArgs) {
          newArgs = icl_NewCons(standard, NULL);
          endp = newArgs;
        }
        else {
          endp->next = icl_NewCons(standard, NULL);
          endp = endp->next;
        }
      }
      else icl_Free(standard);

      args = args->next;
    }
    *Standardized = icl_NewList(newArgs);
    return TRUE;
  }
  else return FALSE;
}


/**
 * Returns a copy of perm in standard permission form.
 */
/*
 * remarks: call --> call(true)
 */
void
icl_perm_standard_form(ICLTerm *perm, ICLTerm **Standard)
{
  if (icl_IsStr(perm))
    *Standard = icl_NewStruct(icl_Str(perm), 1, icl_NewStr("true"));
  else *Standard = icl_CopyTerm(perm);
}


/**
 * Returns the list of default permissions.
 * May be used with icl_ParamValue() to test or lookup an element
 */
ICLTerm * perm_default_list()
{
  static ICLTerm *perm_defaults = NULL;

  /* check to see if first time or somehow invalidated */
  if (!icl_IsValid(perm_defaults)) {
    perm_defaults =
      icl_NewTermFromString("[call(true),read(false),write(false)]");
    return perm_defaults;
  }
  else return perm_defaults;
}


/**
 * Returns true if perm unifies with a default permission.
 * result may be NULL (test only) or can return the result
 * of the unification.
 */
int
icl_perm_default(ICLTerm *perm, ICLTerm **result)
{
  return (icl_IsStruct(perm) && (icl_NumTerms(perm) == 1) &&
          icl_ParamValue(icl_Str(perm), icl_NthTerm(perm, 1),
                         perm_default_list(), result));
}


/**
 * Standardizes a permissions list, removing defaults if requested.
 * Normally there's no need to keep the default value of a param,
 * but there are exceptional situations.  If KeepDefaults is true,
 * default values are kept.
 * Standardized is all newly allocated stuff.
 */
int
icl_standardize_params(ICLTerm *Params,int KeepDefaults,ICLTerm **Standardized)
{
  if (icl_IsList(Params)) {
    ICLListType *args = NULL;
    ICLListType *newArgs = NULL;
    ICLListType *endp = NULL;

⌨️ 快捷键说明

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