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 + -
显示快捷键?