00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #define EXPORT_BORLAND
00032
00033 #ifdef IS_DLL
00034 #define EXPORT_MSCPP __declspec(dllexport)
00035 #else
00036 #define EXPORT_MSCPP
00037 #endif
00038
00039
00040
00041
00042
00043 #ifndef lint
00044
00045 #endif
00046
00047
00048
00049
00050
00051
00052 #include <string.h>
00053 #include <stdio.h>
00054 #include <stdlib.h>
00055
00056 #ifndef _WINDOWS
00057 #include <sys/param.h>
00058 #include <sys/time.h>
00059 #include <stdarg.h>
00060 #else
00061 #include <time.h>
00062 #include <stdarg.h>
00063 #include <windows.h>
00064 #include <winsock.h>
00065 #endif
00066
00067 #include "libicl_private.h"
00068 #include "libicl.h"
00069 #include "libdb.h"
00070 #include "libcom_tcp.h"
00071 #include "liboaa.h"
00072 #include "dictionary.h"
00073 #include "testers.h"
00074
00075
00076 #ifndef MAXHOSTNAMELEN
00077 #define MAXHOSTNAMELEN 256
00078 #endif
00079
00080
00081 int oaa_SeqNumLessThan(int a, int b);
00082
00083
00084
00085
00086
00087 char const* oaa_library_version_str = "[2,3,2]";
00088
00089
00090 extern ICLDatabase *commdb;
00091
00092 static ICLTerm *oaa_solvables = NULL;
00093 static int oaa_trace_on = FALSE;
00094 static int oaa_com_trace_on = FALSE;
00095 static int oaa_debug_on = FALSE;
00096 static double oaa_timeout = 0.0;
00097
00098
00099 ICLTerm *oaa_saved_events = NULL;
00100
00101 static ICLDatabase *local_db = NULL;
00102
00103
00104
00105
00106 static char * oaa_built_in_solvables_str =
00107 "[solvable(oaa_trigger(_TriggerId, _Type, _Condition, _Action, _Params), [type(data)], [write(true)])]";
00108
00109 static ICLTerm *oaa_built_in_solvables_term = NULL;
00110
00111 static ICLTerm* oaa_outSeqNum_matcher = NULL;
00112
00113 static ICLTerm* oaa_lastSeenSeqNum_matcher = NULL;
00114
00115 int oaa_argc = 0;
00116 char** oaa_argv = NULL;
00117
00118
00119 static int globalCounter = 1;
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 static DICTIONARY *context_table = (DICTIONARY *)NULL;
00132
00133
00134
00135
00136 static DICTIONARY *oaa_delay = (DICTIONARY *)NULL;
00137
00138
00139
00140 static DICTIONARY *oaa_delay_table = (DICTIONARY *)NULL;
00141
00142
00143
00144
00145 static DICTIONARY *oaa_callback = (DICTIONARY *)NULL;
00146
00147
00148
00149
00150 static DICTIONARY *oaa_cache = (DICTIONARY *)NULL;
00151
00152
00153
00154 static DICTIONARY *oaa_waiting_for = (DICTIONARY *)NULL;
00155
00156
00157
00158 static DICTIONARY *oaa_waiting_event = (DICTIONARY *)NULL;
00159
00164 EXTERN int oaa_Init(int argc, char* argv[]) {
00165 oaa_argc = argc;
00166 oaa_argv = argv;
00167 return TRUE;
00168 }
00169
00170 static ICLTerm* getEvSolvedGoal(ICLTerm* goal)
00171 {
00172 static int useVar = -1;
00173 ICLTerm* resolved;
00174 if(useVar == -1) {
00175 if(oaa_ResolveVariable("return_goal_with_solutions", &resolved)) {
00176 if(resolved && icl_IsStr(resolved) && strcmp("true", icl_Str(resolved))) {
00177 useVar = 0;
00178 }
00179 else {
00180 useVar = 1;
00181 }
00182 icl_Free(resolved);
00183 }
00184 else {
00185 useVar = 1;
00186 }
00187 }
00188
00189 if(useVar) {
00190 return icl_NewVar("_");
00191 }
00192 else {
00193 return icl_CopyTerm(goal);
00194 }
00195 }
00196
00201 int oaa_compare_terms(void *t1, void *t2) {
00202 ICLTerm *term1 = (ICLTerm *)t1;
00203 ICLTerm *term2 = (ICLTerm *)t2;
00204
00205
00206
00207
00208
00209
00210
00211
00212 if(icl_Unify(term1, term2, NULL)) {
00213 return 1;
00214 }
00215 return 0;
00216 }
00217
00223 int oaa_assert_current_contexts(ICLTerm *id, ICLTerm *contexts) {
00224
00225
00226
00227
00228 if(context_table == NULL)
00229 context_table = dict_new(oaa_compare_terms, (void *)icl_FreeTermSingle);
00230 dict_put_nonunique(context_table, (void *)icl_CopyTerm(id), (void *)contexts);
00231 return TRUE;
00232 }
00233
00239 int oaa_retrieve_current_contexts(ICLTerm *id, ICLTerm **contexts) {
00240 if(context_table != NULL) {
00241 *contexts = (ICLTerm *)dict_get(context_table, (void *)id);
00242 if(*contexts)
00243 return TRUE;
00244 }
00245 return FALSE;
00246 }
00247
00254 int oaa_retrieve_nth_current_contexts(ICLTerm **id, ICLTerm **contexts,
00255 int n) {
00256
00257
00258
00259
00260 if(context_table != NULL) {
00261 if(dict_get_nth(context_table, (void **)id, (void **)contexts, n))
00262 return TRUE;
00263 }
00264 return FALSE;
00265 }
00266
00272 int oaa_retractall_current_contexts(ICLTerm *id) {
00273 if(context_table != NULL) {
00274 void **values;
00275 int num_found, i;
00276
00277 values = dict_remove_all(context_table, id, &num_found);
00278 if (values != NULL) {
00279 for (i=0; i<num_found; i++) {
00280 free((values[i]));
00281 }
00282 free(values);
00283 return TRUE;
00284 }
00285 }
00286 return FALSE;
00287 }
00288
00293 int oaa_assert_delay(ICLTerm *id, ICLTerm *user_id) {
00294 if(oaa_delay == NULL) {
00295 oaa_delay = dict_new(oaa_compare_terms, NULL);
00296 }
00297 dict_put(oaa_delay, (void *)id, (void *)user_id);
00298 return TRUE;
00299 }
00300
00305 int oaa_retract_delay(ICLTerm *id, ICLTerm **user_id) {
00306 if(oaa_delay != NULL) {
00307 *user_id = (ICLTerm *)dict_remove(oaa_delay, (void *)id);
00308 if(*user_id)
00309 return TRUE;
00310 }
00311 return FALSE;
00312 }
00313
00317 int oaa_assert_delay_table(ICLTerm *goal_id, ICLTerm *user_id,
00318 ICLTerm *full_goal, ICLTerm *solve_params,
00319 ICLTerm *all_params) {
00320 ICLTerm *value_list = icl_NewList(NULL);
00321
00322 if(oaa_delay_table == NULL) {
00323 oaa_delay_table = dict_new(oaa_compare_terms, (void *)icl_FreeTermSingle);
00324 }
00325
00326
00327
00328
00329
00330 icl_AddToList(value_list, goal_id, TRUE);
00331 icl_AddToList(value_list, full_goal, TRUE);
00332 icl_AddToList(value_list, solve_params, TRUE);
00333 icl_AddToList(value_list, all_params, TRUE);
00334
00335
00336
00337
00338 dict_put_nonunique(oaa_delay_table, (void *)icl_CopyTerm(user_id), (void *)value_list);
00339 return TRUE;
00340 }
00341
00346 int oaa_retract_delay_table(ICLTerm **goal_id, ICLTerm *user_id,
00347 ICLTerm **full_goal, ICLTerm **solve_params,
00348 ICLTerm **all_params) {
00349
00350 if(oaa_delay_table != NULL) {
00351 ICLTerm *value_list =
00352 dict_remove(oaa_delay_table, (void *)user_id);
00353 if(value_list) {
00354 *goal_id = icl_CopyTerm(icl_NthTerm(value_list, 1));
00355 *full_goal = icl_CopyTerm(icl_NthTerm(value_list, 2));
00356 *solve_params = icl_CopyTerm(icl_NthTerm(value_list, 3));
00357 *all_params = icl_CopyTerm(icl_NthTerm(value_list, 4));
00358 icl_Free(value_list);
00359 return TRUE;
00360 }
00361 }
00362 return FALSE;
00363 }
00364
00368 int oaa_assert_callback(ICLTerm *id, int (*user_callback)(ICLTerm*, ICLTerm*, ICLTerm*)) {
00369 {
00370 ICLTerm *key;
00371 if(oaa_callback == NULL) {
00372 oaa_callback = dict_new(oaa_compare_terms, NULL);
00373 }
00374 if(dict_index_for_key(oaa_callback, id) >= 0) {
00375 key = id;
00376 }
00377 else {
00378 key = icl_CopyTerm(id);
00379 }
00380 dict_put(oaa_callback, key, user_callback);
00381 }
00382 CHECK_LEAKS();
00383 return TRUE;
00384 }
00385
00389 int oaa_retrieve_callback(ICLTerm *id, int (**user_callback)(ICLTerm*, ICLTerm*, ICLTerm*)) {
00390 if(oaa_callback != NULL) {
00391 *user_callback = dict_get(oaa_callback, (void*)id);
00392 if(*user_callback) {
00393 return TRUE;
00394 }
00395 }
00396 return FALSE;
00397 }
00398
00402 int oaa_retract_callback(ICLTerm *id, int (*user_callback)(ICLTerm*, ICLTerm*, ICLTerm*)) {
00403 if(oaa_callback != NULL) {
00404 user_callback = dict_remove(oaa_callback, (void *)id);
00405 if(user_callback != NULL) {
00406 return TRUE;
00407 }
00408 }
00409 return FALSE;
00410 }
00411
00415 int oaa_retractall_callback(ICLTerm *id, ICLTerm **proc) {
00416
00417 if(oaa_callback != NULL) {
00418 void **values;
00419 int num_found, i;
00420
00421 values = dict_remove_all(oaa_callback, id, &num_found);
00422 if (values != NULL) {
00423 *proc = (ICLTerm *)*values;
00424 for (i=0; i<num_found; i++) {
00425 free((values[i]));
00426 }
00427 free(values);
00428 return TRUE;
00429 }
00430 }
00431 return FALSE;
00432 }
00433
00437 int oaa_assert_cache(ICLTerm *goal, ICLTerm *solutions) {
00438 if(oaa_cache == NULL) {
00439 oaa_cache = dict_new(oaa_compare_terms, (void *)icl_FreeTermSingle);
00440 }
00441 dict_put_nonunique(oaa_cache, (void *)icl_CopyTerm(goal), (void *)solutions);
00442 return TRUE;
00443 }
00444
00448 int oaa_retrieve_cache(ICLTerm *goal, ICLTerm **solutions) {
00449 if(oaa_cache != NULL) {
00450 *solutions = (ICLTerm *)dict_get(oaa_cache, (void *)goal);
00451 if(*solutions != NULL) {
00452 return TRUE;
00453 }
00454 }
00455 return FALSE;
00456 }
00457
00462 int oaa_retractall_cache(ICLTerm *goal) {
00463
00464 if(oaa_cache != NULL) {
00465 int num_found = 0;
00466 int i = 0;
00467 void **values = dict_remove_all(oaa_cache, goal, &num_found);
00468
00469 if (values != NULL) {
00470 for (i=0; i<num_found; i++) {
00471 free((values[i]));
00472 }
00473 free(values);
00474 return TRUE;
00475 }
00476 }
00477 return FALSE;
00478 }
00479
00483 int oaa_retrieve_all_cache(ICLTerm *goal, ICLTerm **solutions) {
00484 int i = 0, n = 0, inited = FALSE, res = FALSE;
00485 if(oaa_cache != NULL) {
00486
00487 for(i=0, n=oaa_cache->size; i<n; i++) {
00488 ICLTerm *test_goal = oaa_cache->key[i];
00489
00490 if(!(oaa_cache->compar)((void *)goal, (void *)test_goal)) {
00491 ICLTerm *tmpsoln = oaa_cache->value[i];
00492
00493 if(inited)
00494 icl_AddToList(*solutions, tmpsoln, TRUE);
00495 else {
00496 *solutions = icl_NewList(icl_NewCons(tmpsoln, NULL));
00497 inited = TRUE;
00498 }
00499 res = TRUE;
00500 }
00501 }
00502 }
00503 return res;
00504 }
00505
00509 int oaa_retract_cache(ICLTerm *goal, ICLTerm **solutions) {
00510 if(oaa_cache != NULL) {
00511 *solutions = (ICLTerm *)dict_remove(oaa_cache, (void *)goal);
00512 if(*solutions != NULL) {
00513 return TRUE;
00514 }
00515 }
00516 return FALSE;
00517 }
00518
00522 int oaa_assert_waiting_for(ICLTerm *id, ICLTerm *event_list) {
00523 if(oaa_waiting_for == NULL)
00524 oaa_waiting_for = dict_new(oaa_compare_terms, (void *)icl_FreeTermSingle);
00525 dict_put(oaa_waiting_for, (void *)icl_CopyTerm(id), (void *)event_list);
00526 return TRUE;
00527 }
00528
00532 int oaa_retrieve_waiting_for(ICLTerm *id, ICLTerm **event_list) {
00533 if(oaa_waiting_for != NULL) {
00534 *event_list = (ICLTerm *)dict_get(oaa_waiting_for, (void *)id);
00535 if(*event_list != NULL) {
00536 return TRUE;
00537 }
00538 }
00539 return FALSE;
00540 }
00541
00545 int oaa_retrieve_all_waiting_for(ICLTerm *id, ICLTerm **event_list) {
00546 int res = FALSE, inited = FALSE, i = 0, n = 0;
00547 if(oaa_waiting_for != NULL) {
00548 for(i=0, n=oaa_waiting_for->size; i<n; i++) {
00549 ICLTerm *test_id = oaa_waiting_for->key[i];
00550
00551 if((oaa_waiting_for->compar)((void *)id, (void *)test_id)) {
00552 ICLTerm *tmpel = oaa_waiting_for->value[i];
00553
00554 if(inited) {
00555 icl_AppendCopy(*event_list, tmpel);
00556 }
00557 else {
00558 *event_list = icl_CopyTerm(tmpel);
00559 inited = TRUE;
00560 }
00561 res = TRUE;
00562 }
00563 }
00564 }
00565 return res;
00566 }
00567
00568
00572 int oaa_retract_waiting_for(ICLTerm *id, ICLTerm **event_list) {
00573 if(oaa_waiting_for != NULL) {
00574 *event_list = (ICLTerm *)dict_remove(oaa_waiting_for, (void *)id);
00575 if(*event_list != NULL) {
00576 return TRUE;
00577 }
00578 }
00579 return FALSE;
00580 }
00581
00585 int oaa_assert_waiting_event(ICLTerm *event){
00586 if(oaa_waiting_event == NULL) {
00587 oaa_waiting_event = dict_new(oaa_compare_terms, (void *)icl_FreeTermSingle);
00588 }
00589
00590 dict_put(oaa_waiting_event, (void *)icl_CopyTerm(event), (void *)icl_CopyTerm(event));
00591 return TRUE;
00592 }
00593
00597 int oaa_retrieve_all_waiting_events(ICLTerm **event_list) {
00598 int i = 0, n = 0;
00599 *event_list = icl_NewList(NULL);
00600 if(oaa_waiting_event != NULL) {
00601 for(i=0, n=oaa_waiting_event->size; i<n; i++) {
00602 ICLTerm *event = oaa_waiting_event->value[i];
00603
00604 icl_AddToList(*event_list, icl_CopyTerm(event), TRUE);
00605 }
00606 }
00607 return TRUE;
00608 }
00609
00610
00614 int oaa_retract_waiting_event(ICLTerm *event) {
00615 ICLTerm *retracted = NULL;
00616 if(oaa_waiting_event != NULL) {
00617 retracted = (ICLTerm *)dict_remove(oaa_waiting_event, (void *)event);
00618 if(retracted != NULL) {
00619 icl_Free(retracted);
00620 return TRUE;
00621 }
00622 }
00623 return FALSE;
00624 }
00625
00629 ICLTerm * oaa_built_in_solvables()
00630 {
00631 if (oaa_built_in_solvables_term == NULL) {
00632 oaa_built_in_solvables_term =
00633 icl_NewTermFromString(oaa_built_in_solvables_str);
00634 }
00635
00636 return oaa_built_in_solvables_term;
00637 }
00638
00639
00640
00641
00642
00643
00644 EXTERN void icl_param_standard_form(ICLTerm *param, ICLListType **SList);
00645 EXTERN int icl_param_default(ICLTerm *param, ICLTerm **result);
00646 EXTERN void icl_perm_standard_form(ICLTerm *perm, ICLTerm **Standard);
00647 EXTERN int icl_perm_default(ICLTerm *perm, ICLTerm **result);
00648 EXTERN int icl_address_to_id(ICLTerm* inFullAddress, ICLTerm** result);
00649 EXTERN int icl_standardize_address(ICLTerm *Addr, ICLTerm **StandardAddr);
00650 EXTERN int icl_standardize_solvables(ICLTerm *ShorthandSolvables, ICLTerm **StandardSolvables);
00651 EXTERN int icl_readable_solvables(ICLTerm *StandardSolvables, ICLTerm **ShorthandSolvables);
00652 EXTERN int icl_readable_solvable(ICLTerm *StandardSolvable, ICLTerm **ShorthandSolvable);
00653 EXTERN int oaa_goal_in_solvables(ICLTerm *Goal, ICLTerm *Solvables, ICLTerm **MatchedSolvable);
00654 EXTERN int oaa_call_callback(char* callback_id, ICLTerm *goal, ICLTerm *params, ICLTerm* solutions);
00655 EXTERN int oaa_sort_and_get_event(ICLTerm *EventList, int LowestPriority, ICLTerm **Event, ICLTerm **Params);
00656 EXTERN int oaa_extract_event(ICLTerm *raw_event, ICLTerm **content, ICLTerm **params);
00657
00658 EXTERN int oaa_class(char *class);
00659 EXTERN char *oaa_name_string(void);
00660 EXTERN int oaa_Id(ICLTerm **Id);
00661 EXTERN ICLTerm *perm_default_list();
00662 EXTERN ICLTerm *param_default_list();
00663 EXTERN int oaa_priority_compare(ICLTerm *Elt1, ICLTerm *Elt2);
00664 EXTERN int oaa_extract_event_param(ICLTerm *event, char *param,
00665 ICLTerm **result);
00666 EXTERN int oaa_choose_event(int LowestPriority, ICLTerm *EventList,
00667 ICLTerm **Event);
00668 EXTERN int oaa_read_all_events(double TimeOut, ICLListType **Events,
00669 int *FlushPriority);
00670 EXTERN int oaa_select_event(double timeout, ICLTerm **event);
00671 EXTERN int oaa_flush_events(ICLTerm **original_events, int flush_priority);
00672 EXTERN int oaa_data_in_solvables(ICLTerm *Clause, ICLTerm *Solvables,
00673 ICLTerm *Perm, ICLTerm **MatchedSolvable);
00674 EXTERN int oaa_distribute_perms(ICLTerm *solvables, ICLTerm *common_perms,
00675 ICLTerm **new_solvables);
00676 EXTERN int oaa_distribute_params(ICLTerm *solvables, ICLTerm *common_params,
00677 ICLTerm **new_solvables);
00678
00679 EXTERN int oaa_declare_aux(char *mode, ICLTerm *solvables, ICLTerm *params,
00680 ICLTerm **declared_solvables);
00681 EXTERN int icl_standardize_addressee(ICLTerm *Addr, ICLTerm **StandardAddr);
00682 EXTERN int oaa_address_to_comm_id(ICLTerm *inAddress, char **commId);
00683 EXTERN char* new_goal_id();
00684 EXTERN char* new_trigger_id();
00685 EXTERN int select_elements(ICLTerm *list, int (*test_function)(ICLTerm*),
00686 ICLTerm** result);
00687 EXTERN int oaa_handle_user_event(ICLTerm *event, ICLTerm *params,
00688 ICLTerm **solutions);
00689 EXTERN int oaa_exec_event(ICLTerm *goal, ICLTerm *params, ICLTerm **solutions);
00690 EXTERN int oaa_cont_solve(ICLTerm* goal_id, ICLTerm *goal,
00691 ICLTerm *global_params, ICLTerm **solutions,
00692 ICLTerm **out_params);
00693 EXTERN ICLTerm *remove_element(ICLTerm *elt, ICLTerm *list, ICLTerm **rest);
00694 EXTERN int oaa_cont_poll_until_all_events(ICLTerm *event_list, ICLTerm *event,
00695 ICLTerm *params, int priority,
00696 ICLTerm **solutions);
00697 EXTERN int oaa_handle_ev_update_data(ICLTerm *goal, ICLTerm *params);
00698
00699 EXTERN int oaa_ComTraceMsg(char *format_string, ...);
00700 EXTERN int oaa_flush_notification(ICLTerm *raw_event);
00701 EXTERN int oaa_event_param(ICLTerm *event, ICLTerm *param);
00702 EXTERN int oaa_get_flush_notify(ICLTerm *event, ICLTerm **notify_event);
00703 EXTERN int oaa_translate_incoming_event(ICLTerm *raw_event_in, ICLTerm **raw_event_out);
00704 EXTERN int oaa_unwrap_event(ICLTerm *in_event, char **connection_id, ICLTerm **out_event);
00705 EXTERN int oaa_from_param(ICLTerm *event);
00706 EXTERN int oaa_content_fac_id(ICLTerm *content, ICLTerm **id);
00707 EXTERN int oaa_is_parent_fac_id(char *connection_id, ICLTerm **id);
00708 EXTERN int oaa_is_oaa_id(char *connection_id, ICLTerm **id);
00709 EXTERN int oaa_remove_data_owned_by(ICLTerm *id);
00710 EXTERN int oaa_handle_ev_update_trigger(ICLTerm *goal, ICLTerm *params);
00711 EXTERN int oaa_handle_ev_solve(ICLTerm *goal, ICLTerm *params, ICLTerm **solutions);
00712 EXTERN int oaa_handle_ev_solved(ICLTerm *goal, ICLTerm *params);
00713 EXTERN int oaa_add_data_local(ICLTerm *clause1, ICLTerm *params);
00714 EXTERN int oaa_remove_data_local(ICLTerm *clause1, ICLTerm *params);
00715 EXTERN int oaa_replace_data_local(ICLTerm *clause1_in, ICLTerm *params);
00716 EXTERN int oaa_Inform(ICLTerm *type_info, char *format_string, ICLTerm *args);
00717 EXTERN int oaa_solve_local(ICLTerm *full_goal, ICLTerm *params, ICLTerm **solutions);
00718 EXTERN int oaa_turn_on_debug();
00719 EXTERN int oaa_turn_off_debug();
00720 EXTERN int predicate_skeleton(ICLTerm *goal, ICLTerm **skeleton);
00721 EXTERN int oaa_is_waiting_for(ICLTerm *event);
00722 EXTERN int oaa_translate_outgoing_event(ICLTerm *event, ICLTerm *dest_id, char* commId,
00723 ICLTerm **new_event);
00724 EXTERN int oaa_poll_until_event(ICLTerm *event, ICLTerm **solution);
00725 EXTERN int oaa_declare_local(char *mode, ICLTerm *solvable0, ICLTerm *params,
00726 ICLTerm **returned_solvables);
00727 EXTERN int solvables_to_be_added(ICLTerm *solvables, ICLTerm *current,
00728 ICLTerm **ok_solvables);
00729 EXTERN int solvables_to_be_removed(ICLTerm *solvables, ICLTerm *current,
00730 ICLTerm **ok_solvables);
00731 EXTERN int oaa_remove_solvables_data(ICLTerm *solvables);
00732 EXTERN int icl_subtract(ICLTerm *list1, ICLTerm *list2, ICLTerm **result);
00733 EXTERN int replace_element(ICLTerm *elt, ICLTerm *old_list, ICLTerm *new,
00734 ICLTerm **new_list);
00735 EXTERN int oaa_update(char *mode, ICLTerm *clause, ICLTerm *initial_params,
00736 ICLTerm **out_params);
00737 EXTERN int oaa_retractall(ICLTerm *clause, ICLTerm *owner, ICLTerm *callback);
00738 EXTERN int retract_all(ICLTerm *clause);
00739 EXTERN int oaa_data_owner(ICLTerm *params, ICLTerm **owner);
00740 EXTERN int oaa_asserta(ICLTerm *clause, ICLTerm *owner, ICLTerm *callback);
00741 EXTERN int oaa_assertz(ICLTerm *clause, ICLTerm *owner, ICLTerm *callback);
00742 EXTERN int oaa_retract(ICLTerm *clause, ICLTerm *owner, ICLTerm *callback);
00743 EXTERN int oaa_replace_all(ICLTerm *clause1, ICLTerm *clause2, ICLTerm *owner,
00744 ICLTerm *callback);
00745 EXTERN int oaa_poll_until_event_priority(ICLTerm *event, int priority,
00746 ICLTerm **solutions);
00747 EXTERN int oaa_poll_until_all_events(ICLTerm *event_list, int priority,
00748 ICLTerm **solutions);
00749 EXTERN int oaa_grab_waiting_event(ICLTerm *event_list, ICLTerm **event);
00750 EXTERN int replace_all(ICLTerm *clause1, ICLTerm *clause2);
00751
00752
00753 static int ensure_direct_connection(ICLTerm *AgentAddress, char **ConnectionId);
00754 static int isClientConnection(char *ConnectionId);
00755 static char* new_direct_connection_id(void);
00756 static int oaa_cont_solve_direct(ICLTerm* goal_id,
00757 ICLTerm *goal,
00758 ICLTerm *SingleAgentAddress,
00759 ICLTerm *global_params,
00760 ICLTerm **solutions,
00761 ICLTerm **out_params);
00762 static int oaa_cont_plan(ICLTerm* goal_id,
00763 ICLTerm *templateGoal,
00764 ICLTerm *actualGoal,
00765 ICLTerm *global_params,
00766 ICLTerm **solutions,
00767 ICLTerm **out_params);
00768 static int oaa_get_single_address_from_plan(ICLTerm *ev_planned_term,
00769 ICLTerm **SingleAgentAddress);
00770 static int oaa_handshake(char *ConnectionId, char *InitialAgentName, ICLTerm *Params);
00771
00772
00773
00774
00775
00776
00780 char *getlocalhostname(void) {
00781 char buf[MAXHOSTNAMELEN + 1];
00782 if (gethostname(buf, MAXHOSTNAMELEN) == 0) {
00783 return(strdup(buf));
00784 }
00785 else return(NULL);
00786 }
00787
00788
00822 EXPORT_MSCPP
00823 int EXPORT_BORLAND
00824 oaa_Register(char *ConnectionId, char *AgentName, ICLTerm *Solvables)
00825 {
00826 ICLTerm *Params = NULL;
00827 ICLTerm *t1 = NULL;
00828 ICLTerm *t2 = NULL;
00829 ICLTerm *t3 = NULL;
00830 ICLTerm *declared_solvables = NULL;
00831
00832 char *host = (char *)NULL;
00833 int result = TRUE;
00834 int isClient = TRUE;
00835
00836
00837 isClient = isClientConnection(ConnectionId);
00838 if (!isClient) {
00839 printf("oaa_Register: server type\n");
00840 return FALSE;
00841 }
00842
00843
00844 if (!ConnectionId || !*ConnectionId ||
00845 !com_GetInfo(ConnectionId,
00846 (t1 = icl_NewStruct("status",
00847 1,
00848 icl_NewStr("connected"))), NULL)){
00849
00850 printf("oaa_Register: No Connection\n");
00851 icl_Free(t1);
00852 return FALSE;
00853 }
00854
00855
00856
00857
00858 icl_Free(t1);
00859
00860
00861
00862
00863 t1 = icl_NewStruct("other_name", 1, icl_NewVar("_"));
00864 if (!com_GetInfo(ConnectionId, t1, &t2)) {
00865 oaa_handshake(ConnectionId, AgentName, Params);
00866 }
00867 icl_Free(t1);
00868 icl_Free(t2);
00869
00870
00871 host = getlocalhostname();
00872 if (host != NULL) {
00873 ICLTerm *agent_host = NULL;
00874 ICLTerm *agent_listener = NULL;
00875 ICLTerm *myAddress = NULL;
00876 ICLTerm *myListenAddress = NULL;
00877 ICLTerm *named_address = NULL;
00878 ICLTerm* tempTerm = NULL;
00879 oaa_Address("parent", NULL, &myAddress);
00880 oaa_Address("client_listener", NULL, &myListenAddress);
00881
00882 agent_host = icl_NewStruct("agent_host", 3,
00883 icl_CopyTerm(icl_NthTerm(myAddress,1)),
00884 icl_NewStr(AgentName), icl_NewStr(host));
00885 if (isClient) {
00886 tempTerm = icl_NewTermFromData("[address(parent)]", 17);
00887 oaa_AddData(agent_host, tempTerm, NULL);
00888
00889
00890 if (!STREQ(icl_Str(icl_NthTerm(myListenAddress,1)), "no_address")) {
00891 agent_listener = icl_NewStruct("agent_listener", 2,
00892 icl_CopyTerm(icl_NthTerm(myAddress,1)),
00893 icl_CopyTerm(icl_NthTerm(myListenAddress,1)));
00894 oaa_AddData(agent_listener, tempTerm, NULL);
00895 icl_Free(agent_listener);
00896 named_address = icl_NewStruct("name", 1, icl_NewStr(AgentName));
00897
00898 agent_listener = icl_NewStruct("agent_listener", 2,
00899 icl_CopyTerm(named_address),
00900 icl_CopyTerm(icl_NthTerm(myListenAddress,1)));
00901 oaa_AddData(agent_listener, tempTerm, NULL);
00902 icl_Free(agent_listener);
00903 }
00904 }
00905
00906 else{
00907 tempTerm = icl_NewTermFromData("[address(self)]", 15);
00908 oaa_AddData(agent_host, tempTerm, NULL);
00909 }
00910 icl_Free(tempTerm);
00911 icl_Free(agent_host);
00912 icl_Free(myAddress);
00913 icl_Free(myListenAddress);
00914 icl_Free(named_address);
00915 }
00916
00917 t1 = icl_NewTermFromData("[if_exists(overwrite)]", 22);
00918 t2 = icl_NewList(NULL);
00919 t3 = icl_NewList(NULL);
00920 oaa_Declare(Solvables, t2, t2, t1, &declared_solvables);
00921
00922 icl_Free(t1);
00923 icl_Free(t2);
00924 icl_Free(t3);
00925 icl_Free(declared_solvables);
00926 icl_stFree(host);
00927
00928 return result;
00929
00930 }
00931
00932
00933
00939 EXPORT_MSCPP
00940 void EXPORT_BORLAND
00941 oaa_Ready(int ShouldPrint)
00942 {
00943 char *name = NULL;
00944
00945
00946 if (!oaa_class("root") && (name = oaa_name_string())) {
00947 ICLTerm* toBePosted = icl_NewStruct("ev_ready", 1, icl_NewStr(name));
00948 oaa_PostEvent(toBePosted, ICL_EMPTY);
00949 icl_Free(toBePosted);
00950 }
00951 if(name != NULL) {
00952 icl_stFree(name);
00953 }
00954
00955 if (ShouldPrint)
00956 printf("Ready.\n");
00957 }
00958
00959
00960
00961
00962
00963
00964
00976 EXPORT_MSCPP
00977 int EXPORT_BORLAND
00978 icl_BuiltIn(ICLTerm *goal)
00979 {
00980 int isStruct = icl_IsStruct(goal);
00981
00982 if (isStruct) {
00983 char *s = icl_Str(goal);
00984 int arity = icl_NumTerms(goal);
00985 return (
00986 ((arity == 2) && STREQ(s, "="))
00987 || ((arity == 2) && STREQ(s, "=="))
00988 || ((arity == 2) && STREQ(s, "\\=="))
00989 || ((arity == 2) && STREQ(s, "=<"))
00990 || ((arity == 2) && STREQ(s, ">="))
00991 || ((arity == 2) && STREQ(s, "<"))
00992 || ((arity == 2) && STREQ(s, ">"))
00993 || ((arity == 2) && STREQ(s, "member"))
00994 || ((arity == 2) && STREQ(s, "memberchk"))
00995 || ((arity == 3) && STREQ(s, "findall"))
00996 || ((arity == 3) && STREQ(s, "icl_ConsistentParams"))
00997 );
00998 }
00999 else return FALSE;
01000 }
01001
01002
01006 int
01007 icl_compound_goal(ICLTerm *goal)
01008 {
01009 char *s = NULL;
01010
01011 s = icl_Str(goal);
01012
01013 return ((s != NULL) &&
01014 (
01015 STREQ(s, ":") ||
01016 STREQ(s, "::") ||
01017 STREQ(s, "\\+") ||
01018 STREQ(s, "->") ||
01019 STREQ(s, ":") ||
01020 STREQ(s, ",") ||
01021 STREQ(s, ";")
01022 )
01023 );
01024 }
01025
01036 EXPORT_MSCPP
01037 int EXPORT_BORLAND
01038 icl_BasicGoal(ICLTerm *goal)
01039 {
01040 return (icl_IsStruct(goal) && !icl_compound_goal(goal));
01041 }
01042
01043
01044
01060 EXPORT_MSCPP
01061 int EXPORT_BORLAND
01062 icl_GoalComponents(ICLTerm* fullgoal, ICLTerm** address,
01063 ICLTerm** goal, ICLTerm** param)
01064 {
01065 int res = FALSE;
01066 if (icl_IsStruct(fullgoal)&&(STREQ(icl_Str(fullgoal),"::"))) {
01067
01068 if (icl_IsStruct(icl_NthTerm(fullgoal, 1)) &&
01069 (STREQ(icl_Str(icl_NthTerm(fullgoal, 1)),"::"))) {
01070 *address = icl_CopyTerm(icl_NthTerm(icl_NthTerm(fullgoal, 1),1));
01071 *goal = icl_CopyTerm(icl_NthTerm(icl_NthTerm(fullgoal, 1),2));
01072 *param = icl_CopyTerm(icl_NthTerm(fullgoal, 2));
01073 res = TRUE;
01074 }else{
01075
01076 *address = icl_NewStr("unknown");
01077 *goal = icl_CopyTerm(icl_NthTerm(fullgoal, 1));
01078 *param = icl_CopyTerm(icl_NthTerm(fullgoal, 2));
01079 res = TRUE;
01080 }
01081 }else {
01082 if (icl_IsStruct(fullgoal)&&(STREQ(icl_Str(fullgoal),":"))) {
01083 *address = icl_CopyTerm(icl_NthTerm(fullgoal, 1));
01084 *goal = icl_CopyTerm(icl_NthTerm(fullgoal, 2));
01085 *param = icl_NewList(NULL);
01086 res = TRUE;
01087 } else {
01088 *address = icl_NewStr("unknown");
01089 *goal = icl_CopyTerm(fullgoal);
01090 *param = icl_NewList(NULL);
01091 res = TRUE;
01092 }
01093 }
01094 return res;
01095 }
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01129 int
01130 icl_standardize_perms(ICLTerm *Perms, int KeepDefaults, ICLTerm **Standardized)
01131 {
01132
01133 if (icl_IsList(Perms)) {
01134 ICLListType *args = NULL;
01135 ICLListType *newArgs = NULL;
01136 ICLListType *endp = NULL;
01137 ICLTerm *standard = NULL;
01138
01139 args = icl_List(Perms);
01140 while (args) {
01141 icl_perm_standard_form(args->elt, &standard);
01142 if (KeepDefaults || !icl_perm_default(standard, NULL)) {
01143
01144 if (!newArgs) {
01145 newArgs = icl_NewCons(standard, NULL);
01146 endp = newArgs;
01147 }
01148 else {
01149 endp->next = icl_NewCons(standard, NULL);
01150 endp = endp->next;
01151 }
01152 }
01153 else icl_Free(standard);
01154
01155 args = args->next;
01156 }
01157 *Standardized = icl_NewList(newArgs);
01158 return TRUE;
01159 }
01160 else return FALSE;
01161 }
01162
01163
01167
01168
01169
01170 void
01171 icl_perm_standard_form(ICLTerm *perm, ICLTerm **Standard)
01172 {
01173 if (icl_IsStr(perm))
01174 *Standard = icl_NewStruct(icl_Str(perm), 1, icl_NewStr("true"));
01175 else *Standard = icl_CopyTerm(perm);
01176 }
01177
01178
01183 ICLTerm * perm_default_list()
01184 {
01185 static ICLTerm *perm_defaults = NULL;
01186
01187
01188 if (!icl_IsValid(perm_defaults)) {
01189 perm_defaults =
01190 icl_NewTermFromString("[call(true),read(false),write(false)]");
01191 return perm_defaults;
01192 }
01193 else return perm_defaults;
01194 }
01195
01196
01202 int
01203 icl_perm_default(ICLTerm *perm, ICLTerm **result)
01204 {
01205 return (icl_IsStruct(perm) && (icl_NumTerms(perm) == 1) &&
01206 icl_ParamValue(icl_Str(perm), icl_NthTerm(perm, 1),
01207 perm_default_list(), result));
01208 }
01209
01210
01218 int
01219 icl_standardize_params(ICLTerm *Params,int KeepDefaults,ICLTerm **Standardized)
01220 {
01221 if (icl_IsList(Params)) {
01222 ICLListType *args = NULL;
01223 ICLListType *newArgs = NULL;
01224 ICLListType *endp = NULL;
01225 ICLListType *slist = NULL;
01226 ICLListType *next = NULL;
01227
01228 args = icl_List(Params);
01229 while (args) {
01230
01231 icl_param_standard_form(args->elt, &slist);
01232
01233 while (slist) {
01234 if (KeepDefaults || !icl_param_default(slist->elt,NULL)) {
01235
01236 if (!newArgs) {
01237 newArgs = icl_NewCons(slist->elt, NULL);
01238 endp = newArgs;
01239 }
01240 else {
01241 endp->next = icl_NewCons(slist->elt, NULL);
01242 endp = endp->next;
01243 }
01244 }
01245
01246
01247
01248 next = slist->next;
01249 free(slist);
01250 slist = next;
01251 }
01252 args = args->next;
01253 }
01254 *Standardized = icl_NewList(newArgs);
01255 return TRUE;
01256 }
01257 else {
01258 *Standardized = NULL;
01259 return FALSE;
01260 }
01261 }
01262
01263
01268 ICLTerm * param_default_list()
01269 {
01270 static ICLTerm *param_defaults = NULL;
01271
01272
01273 if (!icl_IsValid(param_defaults)) {
01274 param_defaults =
01275 icl_NewTermFromString("[from(unknown),priority(5),utility(5),if_exists(append),type(procedure),callback(app_do_event),private(false),single_value(false),unique_values(false),rules_ok(false),bookkeeping(true),persistent(false),at_beginning(false),do_all(false),reflexive(true),parallel_ok(true),reply(true),block(true),cache(false),flush_events(false),recurrence(when)]");
01276 return param_defaults;
01277 }
01278 else return param_defaults;
01279 }
01280
01281
01285 void
01286 icl_param_standard_form(ICLTerm *param, ICLListType **SList)
01287 {
01288 int isStruct = icl_IsStruct(param);
01289 int arity = icl_NumTerms(param);
01290 if (isStruct && (arity == 1) && STREQ(icl_Str(param), "block")) {
01291 *SList = icl_NewCons(icl_NewStruct("blocking", 1, icl_CopyTerm(icl_NthTerm(param, 1))),NULL);
01292 }
01293 else if (isStruct && (arity == 1) && STREQ(icl_Str(param), "reply") &&
01294 STREQ(icl_Str(icl_NthTerm(param, 1)), "false")) {
01295 *SList = icl_NewCons(icl_NewStruct("reply", 1, icl_NewStr("none")),NULL);
01296 }
01297 else if (isStruct && (arity == 1) && STREQ(icl_Str(param), "broadcast") &&
01298 STREQ(icl_Str(icl_NthTerm(param, 1)), "false")) {
01299 *SList = icl_NewCons(icl_NewStruct("reply", 1, icl_NewStr("true")),NULL);
01300 }
01301 else if ((arity == 0) && STREQ(icl_Str(param), "broadcast")) {
01302 *SList = icl_NewCons(icl_NewStruct("reply", 1, icl_NewStr("none")),NULL);
01303 }
01304 else if (isStruct && (arity == 1) && STREQ(icl_Str(param), "address")) {
01305 ICLTerm *newAddr;
01306 icl_standardize_address(icl_NthTerm(param, 1), &newAddr);
01307 *SList = icl_NewCons(icl_NewStruct("address", 1, newAddr),NULL);
01308 }
01309 else if (isStruct && (arity == 1) && STREQ(icl_Str(param), "strategy") &&
01310 STREQ(icl_Str(icl_NthTerm(param, 1)), "query")) {
01311 *SList = icl_NewCons(icl_NewStruct("parallel_ok", 1, icl_NewStr("true")),
01312 NULL);
01313 }
01314 else if (isStruct && (arity == 1) && STREQ(icl_Str(param), "strategy") &&
01315 STREQ(icl_Str(icl_NthTerm(param, 1)), "action")) {
01316 *SList = icl_NewCons(icl_NewStruct("parallel_ok", 1, icl_NewStr("false")),
01317 icl_NewCons(icl_NewStruct("solution_limit", 1, icl_NewInt(1)),NULL));
01318 }
01319 else if (isStruct && (arity == 1) && STREQ(icl_Str(param), "strategy") &&
01320 STREQ(icl_Str(icl_NthTerm(param, 1)), "inform")) {
01321 *SList = icl_NewCons(icl_NewStruct("parallel_ok", 1, icl_NewStr("true")),
01322 icl_NewCons(icl_NewStruct("reply", 1, icl_NewStr("none")),NULL));
01323 }
01324 else if (icl_IsStr(param)) {
01325 *SList = icl_NewCons(icl_NewStruct(icl_Str(param), 1, icl_NewStr("true")),
01326 NULL);
01327 }
01328 else {
01329 *SList = icl_NewCons(icl_CopyTerm(param), NULL);
01330 }
01331 }
01332
01333
01339 int
01340 icl_param_default(ICLTerm *param, ICLTerm **result)
01341 {
01342 return (icl_IsStruct(param) && (icl_NumTerms(param) == 1) &&
01343 icl_ParamValue(icl_Str(param), icl_NthTerm(param, 1),
01344 param_default_list(), result));
01345 }
01346
01353 int icl_param_arg(char *param, ICLTerm *value, ICLTerm *paramlist,
01354 ICLTerm **result) {
01355 ICLTerm *bigresult;
01356 int res = FALSE;
01357 if(icl_ParamValue(param, value, paramlist, &bigresult)) {
01358 res = TRUE;
01359 if (bigresult) {
01360 *result = icl_CopyTerm(icl_NthTerm(bigresult, 1));
01361 icl_Free(bigresult);
01362 }
01363 }
01364 return res;
01365 }
01366
01379 EXPORT_MSCPP
01380 int EXPORT_BORLAND
01381 icl_GetParamValue(ICLTerm *Param, ICLTerm *ParamList, ICLTerm **Result)
01382 {
01383 int res = FALSE;
01384
01385 if (icl_IsStruct(Param) && (icl_NumTerms(Param) == 1) &&
01386 icl_IsList(ParamList)) {
01387 ICLTerm *p;
01388
01389 if (icl_ParamValue(icl_Str(Param), NULL, ParamList, &p)) {
01390 res = icl_Unify(Param, p, Result);
01391 icl_Free(p);
01392 } else
01393
01394 if (icl_ParamValue(icl_Str(Param), NULL, param_default_list(), &p)) {
01395 res = icl_Unify(Param, p, Result);
01396 icl_Free(p);
01397 }
01398
01399 return res;
01400 }
01401 else {
01402 return FALSE;
01403 }
01404 }
01405
01419 EXPORT_MSCPP
01420 int EXPORT_BORLAND
01421 icl_GetPermValue(ICLTerm *Perm, ICLTerm *PermList, ICLTerm **Result)
01422 {
01423 int res = FALSE;
01424 if (icl_IsStruct(Perm) && (icl_NumTerms(Perm) == 1) &&
01425 icl_IsList(PermList)) {
01426 ICLTerm *p;
01427
01428 if (icl_ParamValue(icl_Str(Perm), NULL, PermList, &p)) {
01429 res = icl_Unify(Perm, p, Result);
01430 icl_Free(p);
01431 } else
01432
01433 if (icl_ParamValue(icl_Str(Perm), NULL, perm_default_list(), &p)) {
01434 res = icl_Unify(Perm, p, Result);
01435 icl_Free(p);
01436 }
01437
01438 return res;
01439 }
01440 else return FALSE;
01441 }
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01514 int icl_name(ICLTerm *term)
01515 {
01516 if (icl_IsStr(term)) {
01517 char *s = icl_Str(term);
01518
01519 return (!(STREQ(s,"self") ||
01520 STREQ(s,"parent") ||
01521 STREQ(s,"facilitator")));
01522 }
01523 else return FALSE;
01524 }
01525
01526
01531 int icl_true_id(ICLTerm *term, ICLTerm **Id)
01532 {
01533 int res = TRUE;
01534
01535 if (icl_IsInt(term))
01536 *Id = icl_CopyTerm(term);
01537 else
01538
01539 if (icl_IsStr(term)) {
01540
01541 if STREQ(icl_Str(term), "self") {
01542 res = oaa_PrimaryAddress(Id);
01543 }
01544 else
01545 if (STREQ(icl_Str(term), "parent") ||
01546 STREQ(icl_Str(term), "facilitator")) {
01547 ICLTerm *fid, *t1;
01548
01549 res = com_GetInfo("parent",
01550 (t1 = icl_NewStruct("fac_id",
01551 1,
01552 icl_NewVar("FId"))),
01553 &fid);
01554
01555 icl_Free(t1);
01556 if (res) {
01557 *Id = icl_CopyTerm(icl_NthTerm(fid, 1));
01558 icl_Free(fid);
01559 }
01560 }
01561 else res = FALSE;
01562 }
01563 else res = FALSE;
01564
01565 return res;
01566 }
01567
01568
01574 int
01575 icl_standardize_addressee(ICLTerm *Addr, ICLTerm **StandardAddr)
01576 {
01577 ICLTerm *tempRequest = icl_NewTermFromData("other_address(A)",16);
01578 ICLTerm *result = NULL;
01579 ICLTerm *fid = NULL;
01580 ICLTerm *t1;
01581 int freeResult = FALSE;
01582 int returnValue = 0;
01583
01584
01585 if (icl_IsStr(Addr) && (STREQ(icl_Str(Addr),"self"))) {
01586 oaa_PrimaryAddress(&result);
01587
01588 freeResult = TRUE;
01589 }else
01590
01591 if (icl_IsStr(Addr) && (STREQ(icl_Str(Addr),"parent"))) {
01592 com_GetInfo("parent", tempRequest, &fid);
01593 if (fid != NULL) {
01594 result = icl_CopyTerm(icl_NthTerm(fid, 1));
01595
01596 freeResult = TRUE;
01597 icl_Free(fid);
01598 }
01599 }else
01600
01601
01602 if (icl_IsStr(Addr) && (STREQ(icl_Str(Addr),"facilitator"))) {
01603 com_GetInfo("parent", tempRequest, &fid);
01604 if (fid != NULL) {
01605 result = icl_CopyTerm(icl_NthTerm(fid, 1));
01606
01607 freeResult = TRUE;
01608 icl_Free(fid);
01609 }
01610 }else
01611
01612
01613 if (icl_IsStruct(Addr) && (STREQ(icl_Str(Addr),"tcp")) &&
01614 (icl_NumTerms(Addr)==2)) {
01615 result = Addr;
01616
01617 freeResult = FALSE;
01618 }else
01619
01620
01621 if (icl_IsStruct(Addr) && STREQ(icl_Str(Addr),"addr")) {
01622 ICLTerm *res, *fid;
01623 int arity = icl_NumTerms(Addr);
01624
01625 if (com_GetInfo("parent",
01626 (t1 = icl_NewStruct("addr",
01627 1,
01628 icl_NewVar("Addr"))),
01629 &res)) {
01630
01631 icl_Free(t1);
01632 if ((arity == 1) && icl_Unify(Addr, res, NULL)) {
01633 if (com_GetInfo("parent",
01634 (t1 = icl_NewStruct("fac_id",
01635 1,
01636 icl_NewVar("FId"))),
01637 &fid)) {
01638
01639 result = icl_CopyTerm(icl_NthTerm(fid, 1));
01640
01641 freeResult = TRUE;
01642 icl_Free(fid);
01643 icl_Free(t1);
01644 }
01645 }
01646 else {
01647 icl_Free(t1);
01648 }
01649
01650 if ((arity == 2) && icl_Unify(icl_NthTerm(Addr,1),
01651 icl_NthTerm(res,1), NULL)) {
01652 result = icl_NthTerm(Addr, 2);
01653
01654 freeResult = FALSE;
01655 }
01656 icl_Free(res);
01657 }
01658 icl_Free(t1);
01659
01660 if ((!result) && (icl_NumTerms(Addr) == 2)) {
01661 result = Addr;
01662
01663 freeResult = FALSE;
01664 }
01665 }
01666
01667
01668
01669 else if (icl_IsStruct(Addr) && STREQ(icl_Str(Addr),"name")) {
01670 if (icl_name(icl_NthTerm(Addr, 1)))
01671 result = Addr;
01672
01673 freeResult = FALSE;
01674 }
01675 else if (icl_name(Addr)) {
01676 result = icl_NewStruct("name", 1, icl_CopyTerm(Addr));
01677
01678 freeResult = TRUE;
01679 printf("WARNING (liboaa.c): addressee name, in address/1 param, should be "
01680 "specified as:\n name(%s)\n", icl_Str(Addr));
01681 }
01682 else if (!icl_true_id(Addr, &result)) {
01683 printf("WARNING (liboaa.c): Illegal addressee, in address/1 param, discarded:\n ");
01684 icl_WriteTerm(Addr);
01685 printf("\n");
01686 icl_Free(result);
01687
01688 freeResult = FALSE;
01689 }
01690
01691 if (result)
01692 *StandardAddr = icl_CopyTerm(result);
01693
01694 returnValue = (result != NULL) ? 1 : 0;
01695
01696 if (freeResult) {
01697 icl_Free(result);
01698 }
01699
01700 icl_Free(tempRequest);
01701
01702 return (returnValue);
01703 }
01704
01705
01706
01712 int
01713 icl_standardize_address(ICLTerm *Addr, ICLTerm **StandardAddr)
01714 {
01715 ICLListType *args = NULL, *newArgs = NULL, *endp = NULL;
01716 ICLTerm *elt = NULL, *standard = NULL;
01717
01718 if (!icl_IsList(Addr))
01719 elt = Addr;
01720 else
01721 args = icl_List(Addr);
01722
01723 while (args || elt) {
01724
01725 if (!elt) elt = args->elt;
01726
01727 if (icl_standardize_addressee(elt, &standard)) {
01728
01729 if (!newArgs) {
01730 newArgs = icl_NewCons(standard, NULL);
01731 endp = newArgs;
01732 }
01733 else {
01734 endp->next = icl_NewCons(standard, NULL);
01735 endp = endp->next;
01736 }
01737 }
01738
01739 if (args)
01740 args = args->next;
01741 elt = NULL;
01742 }
01743 if (args)
01744 *StandardAddr = icl_NewList(newArgs);
01745 else {
01746 *StandardAddr = newArgs->elt;
01747
01748
01749 if (newArgs->next == (ICLListType *)NULL)
01750 free(newArgs);
01751 else {
01752 ICLListType *list = newArgs->next, *next;
01753
01754 free(newArgs);
01755 while (list) {
01756 icl_Free(list->elt);
01757 next = list->next;
01758 free(list);
01759 list = next;
01760 }
01761 }
01762 }
01763
01764 return TRUE;
01765 }
01766
01767
01768
01769
01811
01812
01813
01814
01815
01816 EXPORT_MSCPP
01817 int EXPORT_BORLAND
01818 icl_ConvertSolvables(int toStandard,
01819 ICLTerm *ShorthandSolvables, ICLTerm **StandardSolvables)
01820 {
01821 if (toStandard) {
01822 return icl_standardize_solvables(ShorthandSolvables, StandardSolvables);
01823 }
01824 else {
01825 return icl_readable_solvables(ShorthandSolvables, StandardSolvables);
01826 }
01827 }
01828
01829 int
01830 icl_standardize_solvable(ICLTerm *Shorthand,
01831 ICLTerm **Standard)
01832 {
01833 int isStruct = icl_IsStruct(Shorthand);
01834 int arity = icl_NumTerms(Shorthand);
01835 int res = TRUE;
01836 ICLTerm *tmp;
01837 ICLTerm *perms, *params;
01838
01839 *Standard = NULL;
01840
01841
01842 if (isStruct && STREQ(icl_Str(Shorthand), "solvable")) {
01843 ICLTerm *goal = icl_NthTerm(Shorthand, 1);
01844
01845 if (arity > 1) {
01846 icl_standardize_params(icl_NthTerm(Shorthand, 2), FALSE, ¶ms);
01847 }
01848 else {
01849 params = icl_NewList(NULL);
01850 }
01851
01852 if (arity == 3) {
01853 icl_standardize_perms(icl_NthTerm(Shorthand, 3), FALSE, &perms);
01854 }
01855 else {
01856 perms = icl_NewList(NULL);
01857 }
01858
01859
01860 if (icl_IsStruct(goal) && (icl_NumTerms(goal) == 2) &&
01861 STREQ(icl_Str(goal), ":-")) {
01862
01863 ICLTerm *g = icl_CopyTerm(icl_NthTerm(goal, 1));
01864 icl_AddToList(params,
01865 icl_NewStruct("test", 1,
01866 icl_CopyTerm(icl_NthTerm(goal, 2))), FALSE);
01867
01868 tmp = icl_NewStruct("solvable", 3, g, params, perms);
01869 res = icl_standardize_solvable(tmp, Standard);
01870 icl_Free(tmp);
01871 }
01872 else {
01873 *Standard = icl_NewStruct("solvable", 3,
01874 icl_CopyTerm(icl_NthTerm(Shorthand, 1)), params, perms);
01875 }
01876 }
01877 else if (isStruct && (arity == 2) && STREQ(icl_Str(Shorthand), ":-")) {
01878
01879 ICLTerm *goal = icl_NthTerm(Shorthand, 1);
01880
01881 *Standard =
01882 icl_NewStruct("solvable", 3, icl_CopyTerm(icl_NthTerm(goal, 1)),
01883 icl_NewList(icl_NewCons(icl_CopyTerm(icl_NthTerm(goal, 2)), NULL)),
01884 icl_NewList(NULL));
01885 }
01886 else {
01887 *Standard = icl_NewStruct("solvable", 3, icl_CopyTerm(Shorthand),
01888 icl_NewList(NULL), icl_NewList(NULL));
01889 }
01890 return res;
01891 }
01892
01896 int
01897 icl_standardize_solvables(ICLTerm *ShorthandSolvables,
01898 ICLTerm **StandardSolvables)
01899 {
01900
01901 if (icl_IsList(ShorthandSolvables)) {
01902 ICLListType *args, *newArgs = NULL, *endp = NULL;
01903 ICLTerm *standard = NULL;
01904
01905 args = icl_List(ShorthandSolvables);
01906 while (args) {
01907 if (icl_standardize_solvable(args->elt, &standard)) {
01908
01909 if (!newArgs) {
01910 newArgs = icl_NewCons(standard, NULL);
01911 endp = newArgs;
01912 }
01913 else {
01914 endp->next = icl_NewCons(standard, NULL);
01915 endp = endp->next;
01916 }
01917 }
01918
01919 args = args->next;
01920 }
01921 *StandardSolvables = icl_NewList(newArgs);
01922
01923 return TRUE;
01924 }
01925 return FALSE;
01926 }
01927
01931
01932
01933
01934
01935
01936
01937
01938 int
01939 icl_readable_solvable(ICLTerm *StandardSolvable,
01940 ICLTerm **ShorthandSolvable)
01941 {
01942 int isStruct = icl_IsStruct(StandardSolvable);
01943 int arity = icl_NumTerms(StandardSolvable);
01944
01945 if (isStruct && (arity == 3) &&
01946 STREQ(icl_Str(StandardSolvable),"solvable")) {
01947 ICLTerm *params = icl_NthTerm(StandardSolvable, 2);
01948 ICLTerm *perms = icl_NthTerm(StandardSolvable, 2);
01949
01950 if (icl_IsList(perms) && (icl_NumTerms(perms) == 0)) {
01951 if (icl_IsList(params) && (icl_NumTerms(params) == 0))
01952 *ShorthandSolvable = icl_CopyTerm(icl_NthTerm(StandardSolvable,1));
01953 else
01954 *ShorthandSolvable = icl_NewStruct("solvable", 2,
01955 icl_CopyTerm(icl_NthTerm(StandardSolvable,1)),
01956 icl_CopyTerm(icl_NthTerm(StandardSolvable,2)));
01957 }
01958 else
01959 *ShorthandSolvable = icl_CopyTerm(StandardSolvable);
01960 }
01961 else
01962 *ShorthandSolvable = icl_CopyTerm(StandardSolvable);
01963 return TRUE;
01964 }
01965
01966
01971 int
01972 icl_readable_solvables(ICLTerm *StandardSolvables,
01973 ICLTerm **ShorthandSolvables)
01974 {
01975 if (icl_IsList(StandardSolvables)) {
01976 ICLListType *args, *newArgs = NULL, *endp = NULL;
01977 ICLTerm *shortsolve = NULL;
01978
01979 args = icl_List(StandardSolvables);
01980 while (args) {
01981
01982 if (icl_readable_solvable(args->elt, &shortsolve)) {
01983
01984 if (!newArgs) {
01985 newArgs = icl_NewCons(shortsolve, NULL);
01986 endp = newArgs;
01987 }
01988 else {
01989 endp->next = icl_NewCons(shortsolve, NULL);
01990 endp = endp->next;
01991 }
01992 }
01993
01994 args = args->next;
01995 }
01996 *ShorthandSolvables = icl_NewList(newArgs);
01997 return TRUE;
01998 }
01999 else return FALSE;
02000 }
02001
02002
02003
02018 int
02019 icl_minimally_instantiate_solvable(ICLTerm *Shorthand,
02020 ICLTerm **Minimal)
02021 {
02022 int isStruct = icl_IsStruct(Shorthand);
02023 int arity = icl_NumTerms(Shorthand);
02024 int res = TRUE;
02025 ICLTerm *perms, *params;
02026
02027
02028
02029 if (isStruct && STREQ(icl_Str(Shorthand), "solvable")) {
02030 ICLTerm *goal = icl_NthTerm(Shorthand, 1);
02031 ICLTerm *g;
02032
02033 params = icl_NewVar("Params");
02034 perms = icl_NewVar("Perms");
02035
02036
02037 if (icl_IsStruct(goal) && (icl_NumTerms(goal) == 2) &&
02038 STREQ(icl_Str(goal), ":-")) {
02039
02040 g = icl_CopyTerm(icl_NthTerm(goal, 1));
02041 }
02042 else
02043 g = icl_CopyTerm(goal);
02044 *Minimal = icl_NewStruct("solvable", 3, g, params, perms);
02045 }
02046 else
02047
02048
02049 if (isStruct && (arity == 2) && STREQ(icl_Str(Shorthand), ":-")) {
02050 ICLTerm *goal = icl_NthTerm(Shorthand, 1);
02051
02052 *Minimal = icl_NewStruct("solvable", 3, icl_CopyTerm(icl_NthTerm(goal, 1)),
02053 icl_NewVar("Params"), icl_NewVar("Perms"));
02054 }
02055 else
02056 *Minimal = icl_NewStruct("solvable", 3, icl_CopyTerm(Shorthand),
02057 icl_NewVar("Params"), icl_NewVar("Perms"));
02058
02059 return res;
02060 }
02061
02062
02063
02067 int
02068 icl_minimally_instantiate_solvables(ICLTerm *ShorthandSolvables,
02069 ICLTerm **MinimalSolvables)
02070 {
02071 if (icl_IsList(ShorthandSolvables)) {
02072 ICLListType *args, *newArgs = NULL, *endp = NULL;
02073 ICLTerm *minimal = NULL;
02074
02075 args = icl_List(ShorthandSolvables);
02076 while (args) {
02077
02078 if (icl_minimally_instantiate_solvable(args->elt, &minimal)) {
02079
02080 if (!newArgs) {
02081 newArgs = icl_NewCons(minimal, NULL);
02082 endp = newArgs;
02083 }
02084 else {
02085 endp->next = icl_NewCons(minimal, NULL);
02086 endp = endp->next;
02087 }
02088 }
02089
02090 args = args->next;
02091 }
02092 *MinimalSolvables = icl_NewList(newArgs);
02093 return TRUE;
02094 }
02095 else return FALSE;
02096 }
02097
02098
02136 int
02137 oaa_goal_matches_solvables(ICLTerm *Goal, ICLTerm *Solvables,
02138 ICLTerm **RealGoal, ICLTerm **RealMatched)
02139 {
02140
02141 ICLTerm *Matched = NULL;
02142 ICLTerm *allSolvables = NULL;
02143 ICLTerm *t1;
02144 int result = TRUE;
02145
02146 icl_Union(oaa_built_in_solvables(), Solvables, &allSolvables);
02147
02148
02149
02150
02151
02152
02153
02154
02155 CHECK_LEAKS();
02156 if (oaa_goal_in_solvables(Goal, allSolvables, &Matched)) {
02157
02158 ICLTerm *Params = icl_NthTerm(Matched, 2);
02159 ICLTerm *Value = NULL;
02160
02161 icl_Free(allSolvables);
02162
02163 t1 = icl_NewStruct("synonym",
02164 2,
02165 icl_CopyTerm(Goal),
02166 icl_NewVar("SynGoal"));
02167 if (icl_GetParamValue(t1, Params, &Value)) {
02168 result = oaa_goal_matches_solvables(icl_NthTerm(Value, 2),
02169 Solvables,
02170 RealGoal,
02171 RealMatched);
02172 icl_Free(Matched);
02173 icl_Free(Value);
02174 }
02175 else {
02176 *RealGoal = icl_CopyTerm(Goal);
02177 *RealMatched = Matched;
02178
02179 }
02180 icl_Free(t1);
02181 }
02182 else {
02183 icl_Free(allSolvables);
02184 result = FALSE;
02185 }
02186
02187 return result;
02188 }
02189
02203 int
02204 oaa_goal_in_solvables(ICLTerm *Goal, ICLTerm *Solvables,
02205 ICLTerm **MatchedSolvable)
02206 {
02207 int result = TRUE;
02208 int done = FALSE;
02209
02210 if (icl_IsList(Solvables)) {
02211 ICLListType *args = NULL;
02212
02213 args = icl_List(Solvables);
02214 while (args && !done) {
02215
02216 ICLTerm *G1 = icl_NthTerm(args->elt, 1);
02217 ICLTerm *Params = icl_NthTerm(args->elt, 2);
02218 ICLTerm *t1, *t2;
02219
02220 if (icl_Unify(Goal, G1, NULL)) {
02221 t1 = icl_NewStruct("synonym",
02222 2,
02223 icl_CopyTerm(Goal),
02224 icl_NewVar("SynGoal"));
02225 if (icl_GetParamValue(t1, Params, NULL)) {
02226 done = TRUE;
02227 *MatchedSolvable = icl_CopyTerm(args->elt);
02228 icl_Free(t1);
02229 }
02230 else
02231
02232 icl_Free(t1);
02233
02234
02235 if (icl_GetPermValue((t1 = icl_NewTermFromData("call(true)",10)),
02236 Params,
02237 NULL)) {
02238 ICLTerm *Test;
02239 ICLTerm *WholeTest;
02240
02241
02242 t2 = icl_NewStruct("test",
02243 1,
02244 icl_NewVar("T"));
02245 if (icl_GetPermValue(t2,
02246 Params,
02247 &Test)) {
02248
02249
02250
02251 WholeTest = icl_NewGroup(
02252 '(',
02253 ",",
02254 icl_NewCons(
02255 icl_NewStruct("=",
02256 2,
02257 icl_CopyTerm(G1),
02258 icl_CopyTerm(Goal)),
02259 icl_NewCons(icl_CopyTerm(Test), NULL)));
02260
02261
02262
02263
02264 done = oaa_Interpret(WholeTest, ICL_EMPTY, NULL);
02265
02266 if (done) {
02267 *MatchedSolvable = icl_CopyTerm(args->elt);
02268 }
02269
02270 icl_Free(Test);
02271 icl_Free(WholeTest);
02272 } else {
02273 done = TRUE;
02274 *MatchedSolvable = icl_CopyTerm(args->elt);
02275 }
02276 icl_Free(t2);
02277 }
02278 icl_Free(t1);
02279 }
02280 args = args->next;
02281 }
02282
02283 if (!done && !args) {
02284 result = FALSE;
02285 }
02286 }
02287 else {
02288 result = FALSE;
02289 }
02290 return result;
02291 }
02292
02293
02321 int
02322 oaa_data_matches_solvables(ICLTerm *Clause, ICLTerm *Solvables, ICLTerm *Perm,
02323 ICLTerm **RealClause, ICLTerm **RealMatched)
02324 {
02325
02326 ICLTerm *Matched = NULL;
02327 ICLTerm *Head = NULL, *Body = NULL;
02328 ICLTerm *t1;
02329 int result = TRUE;
02330
02331 if (oaa_data_in_solvables(Clause, oaa_built_in_solvables(),Perm,&Matched) ||
02332 oaa_data_in_solvables(Clause, Solvables,Perm,&Matched)) {
02333
02334
02335 ICLTerm *Params = icl_NthTerm(Matched, 2);
02336 ICLTerm *Value = NULL;
02337
02338 if (icl_IsStruct(Clause) && STREQ(icl_Functor(Clause), ":-")) {
02339 Head = icl_NthTerm(Clause, 1);
02340 Body = icl_NthTerm(Clause, 2);
02341 }
02342 else {
02343 Head = Clause;
02344 }
02345
02346
02347 t1 = icl_NewStruct("synonym",
02348 2,
02349 icl_CopyTerm(Head),
02350 icl_NewVar("SynHead"));
02351 if (icl_GetParamValue(t1, Params, &Value)) {
02352 ICLTerm *SynClause;
02353
02354 if (Body) {
02355 SynClause = icl_NewStruct(":-", 2,
02356 icl_CopyTerm(icl_NthTerm(Value, 2)),
02357 icl_CopyTerm(Body));
02358 }
02359 else {
02360 SynClause = icl_CopyTerm(icl_NthTerm(Value, 2));
02361 }
02362
02363 result = oaa_data_matches_solvables(SynClause,
02364 Solvables,
02365 Perm,
02366 RealClause,
02367 RealMatched);
02368 icl_Free(SynClause);
02369 icl_Free(Matched);
02370 icl_Free(Value);
02371 }
02372 else {
02373 *RealClause = icl_CopyTerm(Clause);
02374 *RealMatched = Matched;
02375
02376 }
02377 icl_Free(t1);
02378 }
02379 else {
02380 result = FALSE;
02381 }
02382
02383 return result;
02384 }
02385
02386
02387
02397 int
02398 oaa_data_in_solvables(ICLTerm *Clause, ICLTerm *Solvables, ICLTerm *Perm,
02399 ICLTerm **MatchedSolvable)
02400 {
02401 int result = TRUE;
02402 int done = FALSE;
02403
02404 if (icl_IsList(Solvables)) {
02405 ICLListType *args = NULL;
02406 ICLTerm *Head = NULL, *Body = NULL;
02407
02408 if (icl_IsStruct(Clause) && STREQ(icl_Functor(Clause), ":-")) {
02409 Head = icl_NthTerm(Clause, 1);
02410 Body = icl_NthTerm(Clause, 2);
02411 }
02412 else {
02413 Head = Clause;
02414 }
02415
02416 args = icl_List(Solvables);
02417 while (args && !done) {
02418
02419
02420 ICLTerm *G1 = icl_NthTerm(args->elt, 1);
02421 ICLTerm *Params = icl_NthTerm(args->elt, 2);
02422 ICLTerm *Perms = icl_NthTerm(args->elt, 3);
02423
02424 if (icl_Unify(Head, G1, NULL)) {
02425 ICLTerm *t1;
02426
02427 if (icl_GetParamValue((t1 = icl_NewStruct("synonym",
02428 2,
02429 icl_CopyTerm(Head),
02430 icl_NewVar("_RealHead"))),
02431 Params, NULL)) {
02432 done = TRUE;
02433 *MatchedSolvable = icl_CopyTerm(args->elt);
02434 }
02435 else {
02436 ICLTerm *t2;
02437
02438 t2 = icl_NewTermFromData("type(data)",10);
02439 done = icl_GetParamValue(t2, Params, NULL);
02440 icl_Free(t2);
02441 if (done && Body) {
02442 t2 = icl_NewTermFromData("rules_ok(true)",14);
02443 done = icl_GetParamValue(t2,Params, NULL);
02444 icl_Free(t2);
02445 }
02446 if (done) {
02447 if(STREQ(icl_Str(Perm), "write")) {
02448 t2 = icl_NewTermFromData("write(true)",11);
02449 done = icl_GetPermValue(t2, Perms, NULL);
02450 icl_Free(t2);
02451 }
02452 else {
02453 t2 = icl_NewTermFromData("read(true)",10);
02454 done = icl_GetPermValue(t2, Perms, NULL);
02455 icl_Free(t2);
02456 }
02457 }
02458 if (done) {
02459 *MatchedSolvable = icl_CopyTerm(args->elt);
02460 }
02461 }
02462 icl_Free(t1);
02463 }
02464 args = args->next;
02465 }
02466
02467
02468 if (!done && !args) {
02469 result = FALSE;
02470 }
02471 }
02472 else {
02473 result = FALSE;
02474 }
02475
02476 return result;
02477 }
02478
02479
02480
02481
02482
02483
02484
02491 EXPORT_MSCPP
02492 void EXPORT_BORLAND
02493 oaa_MainLoop(int ShouldPrint)
02494 {
02495 ICLTerm *Event, *Params;
02496 oaa_Ready(ShouldPrint);
02497
02498 while (TRUE) {
02499 oaa_GetEvent(&Event, &Params, 0);
02500 CHECK_LEAKS();
02501 oaa_ProcessEvent(Event, Params);
02502 CHECK_LEAKS();
02503 icl_Free(Event);
02504 icl_Free(Params);
02505 }
02506 }
02507
02508
02516 EXPORT_MSCPP
02517 void EXPORT_BORLAND
02518 oaa_ProcessAllEvents()
02519 {
02520 ICLTerm *Event = NULL, *Params = NULL;
02521 oaa_GetEvent(&Event, &Params, 0);
02522 oaa_ProcessEvent(Event, Params);
02523 icl_Free(Event);
02524 icl_Free(Params);
02525 }
02526
02527
02528 static char* oaa_getConnectionIdFromParams(ICLTerm *params)
02529 {
02530 ICLTerm* connId;
02531 char* toReturn;
02532 if(!icl_ParamValue("connection_id", NULL, params, &connId)) {
02533 char* paramString = icl_NewStringFromTerm(params);
02534 fprintf(stderr, "No connection_id in: %s", paramString);
02535 icl_stFree(paramString);
02536 return NULL;
02537 }
02538 toReturn = strdup(icl_Str(icl_NthTerm(connId, 1)));
02539 icl_Free(connId);
02540 return toReturn;
02541 }
02542
02543 static void oaa_got_heartbeat(char* connection)
02544 {
02545 GTimeVal now;
02546 ICLTerm* hb;
02547
02548 g_get_current_time(&now);
02549 hb = icl_NewStruct("last_heartbeat", 1, icl_NewInt(now.tv_sec));
02550 com_UpdateInfo(connection, hb);
02551 icl_Free(hb);
02552 }
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568 static void oaa_send_heartbeat_reply(char* conn)
02569 {
02570 ICLTerm* reply = icl_NewStruct("event", 2, icl_NewStr("ev_heartbeat_reply"), icl_NewList(NULL));
02571 com_SendTerm(conn, reply);
02572 }
02573
02574 static void oaa_resend_unacked(char* connId)
02575 {
02576 ICLTerm* unackedMatcher = icl_NewStruct("unacked", 1, icl_NewVar("_"));
02577 ICLTerm* unacked;
02578 if(com_GetInfo(connId, unackedMatcher, &unacked)) {
02579 ICLListType* toSend;
02580 for(toSend = icl_List(unacked); toSend; toSend = icl_ListNext(toSend)) {
02581 com_SendTerm(connId, icl_ListElt(toSend));
02582 }
02583 icl_Free(unacked);
02584 }
02585
02586 icl_Free(unackedMatcher);
02587 }
02588
02589 static void oaa_handle_reconnect_handshake(ICLTerm* reconnectEvent)
02590 {
02591 char* connId = icl_Str(icl_NthTerm(reconnectEvent, 1));
02592 char* name = icl_Str(icl_NthTerm(reconnectEvent, 2));
02593 ICLTerm* reconnectTerm = icl_CopyTerm(icl_NthTerm(reconnectEvent, 3));
02594 ICLTerm* addressTerm = icl_CopyTerm(icl_NthTerm(reconnectEvent, 4));
02595 ICLTerm* nameTerm = icl_CopyTerm(icl_NthTerm(reconnectEvent, 5));
02596 ICLTerm* params = icl_NewList(NULL);
02597 icl_AddToList(params, reconnectTerm, FALSE);
02598 icl_AddToList(params, addressTerm, FALSE);
02599 icl_AddToList(params, nameTerm, FALSE);
02600
02601 if(oaa_handshake(connId, name, params)) {
02602 oaa_resend_unacked(connId);
02603 }
02604 icl_Free(params);
02605 }
02606
02613 EXPORT_MSCPP
02614 void EXPORT_BORLAND
02615 oaa_ProcessEvent(ICLTerm *Event, ICLTerm *Params)
02616 {
02617 if (icl_IsStr(Event) && STREQ(icl_Str(Event),"timeout")) {
02618 oaa_CheckTriggers("task", NULL, NULL);
02619
02620
02621
02622
02623 oaa_call_callback("app_idle", (ICLTerm *)NULL, (ICLTerm *)NULL, (ICLTerm *)NULL);
02624 }
02625 if(icl_IsStr(Event) && STREQ(icl_Str(Event), "ev_heartbeat")) {
02626 char* conn = oaa_getConnectionIdFromParams(Params);
02627 oaa_send_heartbeat_reply(conn);
02628 oaa_got_heartbeat(conn);
02629 free(conn);
02630 }
02631 else if(icl_IsStr(Event) && STREQ(icl_Str(Event), "ev_heartbeat_reply")) {
02632 char* conn = oaa_getConnectionIdFromParams(Params);
02633 oaa_got_heartbeat(conn);
02634 free(conn);
02635 }
02636 else if(icl_IsStruct(Event) && STREQ(icl_Str(Event), "ev_reconnected_needs_handshake")) {
02637 oaa_handle_reconnect_handshake(Event);
02638 }
02639 else {
02640
02641 ICLTerm *solutions = NULL;
02642 oaa_Interpret(Event, Params, &solutions);
02643 if(solutions != NULL) {
02644 icl_Free(solutions);
02645 }
02646
02647
02648
02649 }
02650 }
02651
02652
02656 EXPORT_MSCPP
02657 void EXPORT_BORLAND
02658 oaa_SetTimeout(double NSecs)
02659 {
02660 if (NSecs < 0)
02661 oaa_timeout = 0.0;
02662 else oaa_timeout = NSecs;
02663
02664
02665 }
02666
02667
02684 EXPORT_MSCPP
02685 void EXPORT_BORLAND
02686 oaa_GetEvent(ICLTerm **Event, ICLTerm **Params, int LowestPriority)
02687 {
02688
02689 double TimeoutSecs = 0;
02690 int FlushPriority = 0;
02691 ICLTerm *MoreEvents = icl_NewList(NULL);
02692 #ifdef UNNEEDED_DEBUG
02693 char *debugString = NULL;
02694 #endif
02695
02696 *Event = NULL;
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706 if(icl_ListLen(oaa_saved_events) > 0) {
02707 TimeoutSecs = 0.01;
02708
02709 }
02710 else {
02711 TimeoutSecs = oaa_timeout;
02712 }
02713 oaa_read_all_events(TimeoutSecs, (ICLListType **)&(MoreEvents->p),
02714 &FlushPriority);
02715 CHECK_LEAKS();
02716
02717 #ifdef UNNEEDED_DEBUG
02718 {
02719 char* debugString = icl_NewStringFromTerm(MoreEvents);
02720 debugPrint(1, "%s:%i MoreEvents %s\n", __PRETTY_FUNCTION__, __LINE__, debugString);
02721 icl_stFree(debugString);
02722 }
02723 #endif
02724
02725
02726
02727
02728
02729
02730 if (oaa_saved_events) {
02731 oaa_flush_events(&oaa_saved_events, FlushPriority);
02732 icl_AppendCopy(oaa_saved_events, MoreEvents);
02733 }
02734 CHECK_LEAKS();
02735
02736
02737
02738
02739 if (!oaa_sort_and_get_event(oaa_saved_events, LowestPriority,
02740 Event, Params)){
02741 icl_Free(*Event);
02742 *Event = icl_NewStr("timeout");
02743 *Params = icl_CopyTerm(ICL_EMPTY);
02744 }
02745 else {
02746 ICLTerm *t1;
02747
02748 t1 = icl_NewStruct("event",
02749 2,
02750 icl_CopyTerm(*Event),
02751 icl_CopyTerm(*Params));
02752 oaa_CheckTriggers("comm", t1, "receive");
02753 icl_Free(t1);
02754 }
02755 icl_Free(MoreEvents);
02756 CHECK_LEAKS();
02757
02758 }
02759
02760
02768 int oaa_sort_and_get_event(ICLTerm *EventList, int LowestPriority,
02769 ICLTerm **Event, ICLTerm **Params)
02770 {
02771
02772 ICLTerm *RawEvent;
02773
02774 icl_SortList(EventList, oaa_priority_compare);
02775
02776 if (oaa_choose_event(LowestPriority, EventList, &RawEvent)) {
02777 oaa_extract_event(RawEvent, Event, Params);
02778 icl_Free(RawEvent);
02779 return TRUE;
02780 }
02781 else return FALSE;
02782 }
02783
02784
02788 int oaa_priority_compare(ICLTerm *Elt1, ICLTerm *Elt2)
02789 {
02790 ICLTerm *param1, *param2;
02791 int p1 = 0, p2 = 0;
02792
02793 oaa_extract_event_param(Elt1, "priority", ¶m1);
02794 oaa_extract_event_param(Elt2, "priority", ¶m2);
02795
02796 if (icl_IsInt(param1))
02797 p1 = icl_Int(param1);
02798 else p1 = 5;
02799 if (icl_IsInt(param2))
02800 p2 = icl_Int(param2);
02801 else p2 = 5;
02802
02803 icl_Free(param1);
02804 icl_Free(param2);
02805
02806 return p1 >= p2;
02807 }
02808
02809
02815 int oaa_choose_event(int LowestPriority, ICLTerm *EventList, ICLTerm **Event) {
02816
02817 if (EventList) {
02818 ICLListType *list = icl_List(EventList);
02819 ICLListType *prev = list;
02820 ICLTerm *p = NULL;
02821 ICLTerm *pAsStruct = NULL;
02822 int found = FALSE;
02823
02824 if (Event) {
02825 *Event = NULL;
02826 }
02827
02828 while (list && (list->elt != NULL) && !found) {
02829 oaa_extract_event_param(list->elt, "priority", &pAsStruct);
02830 if (pAsStruct) {
02831 p = icl_NthTerm(pAsStruct,1);
02832 }
02833
02834 if (icl_IsInt(p) && (icl_Int(p) > LowestPriority)) {
02835 if (Event) {
02836 *Event = icl_CopyTerm(list->elt);
02837 }
02838 found = TRUE;
02839 icl_Free(pAsStruct);
02840
02841
02842 if (list == prev) {
02843 EventList->p = list->next;
02844 icl_Free(list->elt);
02845 free(list);
02846 return TRUE;
02847 }
02848 else {
02849 prev->next = list->next;
02850 icl_Free(list->elt);
02851 free(list);
02852 return TRUE;
02853 }
02854 }
02855 if (pAsStruct) {
02856 icl_Free(pAsStruct);
02857 }
02858
02859 prev = list;
02860 list = list->next;
02861 }
02862
02863
02864
02865
02866 return found;
02867 }
02868 return FALSE;
02869 }
02870
02885 int oaa_read_all_events(double TimeOut, ICLListType **Events,
02886 int *FlushPriority)
02887 {
02888 ICLTerm *e = NULL, *ok_event = NULL, *param = NULL, *paramAsStruct = NULL;
02889 ICLListType *RestEvents = NULL;
02890 int RestFlushPriority = 0, p;
02891
02892 CHECK_LEAKS();
02893 if(oaa_select_event(TimeOut, &e) == FALSE) {
02894 if(e != NULL) {
02895 icl_Free(e);
02896 }
02897 *Events = NULL;
02898 *FlushPriority = 0;
02899 CHECK_LEAKS();
02900 return FALSE;
02901 }
02902 CHECK_LEAKS();
02903
02904
02905
02906 if(icl_IsStr(e) && STREQ(icl_Str(e), "timeout")) {
02907 *Events = NULL;
02908 *FlushPriority = 0;
02909 CHECK_LEAKS();
02910 return FALSE;
02911 } else {
02912
02913
02914
02915
02916
02917 CHECK_LEAKS();
02918
02919
02920 CHECK_LEAKS();
02921 if(oaa_ValidateEvent(e, &ok_event)) {
02922
02923
02924
02925
02926 if (oaa_com_trace_on) {
02927 char *debugStr;
02928 CHECK_LEAKS();
02929 debugStr = icl_NewStringFromTerm(ok_event);
02930 oaa_ComTraceMsg("\n[COM received]:\n %s\n", debugStr,NULL);
02931 icl_stFree(debugStr);
02932 }
02933
02934 icl_Free(e);
02935
02936 oaa_extract_event_param(ok_event, "priority", ¶mAsStruct);
02937 if (paramAsStruct) {
02938 param = icl_NthTerm(paramAsStruct,1);
02939 }
02940
02941 if(icl_IsInt(param)) {
02942 p = icl_Int(param);
02943 }
02944 else {
02945 p = 0;
02946 }
02947
02948 CHECK_LEAKS();
02949
02950
02951 if(p < RestFlushPriority) {
02952 CHECK_LEAKS();
02953
02954 oaa_flush_notification(ok_event);
02955 *FlushPriority = RestFlushPriority;
02956 *Events = RestEvents;
02957 icl_Free(ok_event);
02958 CHECK_LEAKS();
02959 }
02960 else {
02961 ICLTerm *flushevents;
02962 CHECK_LEAKS();
02963 flushevents = icl_NewTermFromData("flush_events(true)",18);
02964
02965 *Events = icl_NewCons(ok_event, RestEvents);
02966 CHECK_LEAKS();
02967
02968
02969
02970 if(oaa_event_param(ok_event, flushevents)) {
02971 *FlushPriority = p;
02972 }
02973 else {
02974 *FlushPriority = RestFlushPriority;
02975 }
02976 icl_Free(flushevents);
02977 CHECK_LEAKS();
02978 }
02979 icl_Free(paramAsStruct);
02980 CHECK_LEAKS();
02981 } else {
02982
02983 printf("Invalid event\n");
02984 *Events = RestEvents;
02985 if(ok_event != NULL) {
02986 icl_Free(ok_event);
02987 }
02988 icl_Free(e);
02989 CHECK_LEAKS();
02990 }
02991 }
02992 CHECK_LEAKS();
02993 return FALSE;
02994 }
02995
03005 int oaa_ValidateEvent(ICLTerm *E, ICLTerm **OkEvent)
03006 {
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020 *OkEvent = icl_CopyTerm(E);
03021 return TRUE;
03022 }
03023
03027 int oaa_flush_events(ICLTerm **original_events, int flush_priority)
03028 {
03029 ICLListType *eventlist;
03030 ICLTerm* events = NULL;
03031
03032
03033
03034
03035
03036
03037
03038
03039 events = *original_events;
03040
03041 *original_events = icl_NewList(NULL);
03042
03043 eventlist = icl_List(events);
03044 while(icl_ListHasMoreElements(eventlist)) {
03045 ICLTerm *event = icl_ListElement(eventlist);
03046 ICLTerm *param = NULL, *paramAsStruct = NULL;
03047 int p=0;
03048
03049 oaa_extract_event_param(event, "priority", ¶mAsStruct);
03050 if (paramAsStruct) {
03051 param = icl_NthTerm(paramAsStruct,1);
03052 }
03053
03054 if(icl_IsInt(param)) {
03055 p = icl_Int(param);
03056 }
03057 if(p < flush_priority) {
03058 oaa_flush_notification(event);
03059 }
03060 else {
03061 icl_AddToList(*original_events, icl_CopyTerm(event), TRUE);
03062 }
03063 eventlist = icl_ListNextElement(eventlist);
03064 icl_Free(paramAsStruct);
03065 }
03066 icl_Free(events);
03067 return TRUE;
03068 }
03069
03075 int oaa_flush_notification(ICLTerm *raw_event)
03076 {
03077 ICLTerm *event, *params, *notify_event;
03078
03079 oaa_extract_event(raw_event, &event, ¶ms);
03080 if(oaa_get_flush_notify(event, ¬ify_event)) {
03081 ICLTerm *emptyParams = icl_NewList(NULL);
03082 oaa_PostEvent(notify_event, emptyParams);
03083 icl_Free(emptyParams);
03084 }
03085 icl_Free(event);
03086 icl_Free(params);
03087 icl_Free(notify_event);
03088 return TRUE;
03089 }
03090
03096 int oaa_get_flush_notify(ICLTerm *event, ICLTerm **notify_event)
03097 {
03098
03099 int result = FALSE;
03100 *notify_event = NULL;
03101
03102 if(icl_IsStr(event)) {
03103
03104 char *functor = icl_Functor(event);
03105 if(STREQ(functor, "ev_solve")) {
03106 ICLTerm *id = icl_NthTerm(event, 1);
03107 ICLTerm *goal = icl_NthTerm(event, 2);
03108 ICLTerm *params = icl_NthTerm(event, 3);
03109 ICLTerm *reply_none = icl_NewTermFromData("reply(none)",11);
03110 if(!icl_GetParamValue(reply_none, params, NULL)) {
03111 ICLTerm *my_id;
03112 result = oaa_PrimaryAddress(&my_id);
03113 if(result) {
03114
03115 *notify_event = icl_NewStruct("ev_solved", 5,
03116 icl_CopyTerm(id),
03117 icl_CopyTerm(id),
03118 my_id,
03119 getEvSolvedGoal(goal),
03120 icl_CopyTerm(params),
03121 icl_NewList(NULL));
03122 }
03123 }
03124 icl_Free(reply_none);
03125 }
03126 }
03127 return result;
03128 }
03129
03130 static void oaa_acked(char* connId, int ackNum)
03131 {
03132 ICLTerm* unackedMatcher = icl_NewStruct("unacked", 1, icl_NewVar("_"));
03133 ICLTerm* unackedTerm;
03134 ICLTerm* unackedList;
03135 ICLTerm* nextUnackedTerm = icl_NewStruct("unacked", 1, icl_NewList(NULL));
03136 ICLTerm* remainder = icl_NthTerm(nextUnackedTerm, 1);
03137 ICLListType* listElt;
03138 ICLTerm* sequenceMatcher = icl_NewStruct("sequence", 1, icl_NewVar("_"));
03139 ICLTerm* sequenceTerm;
03140
03141 if(!com_GetInfo(connId, unackedMatcher, &unackedTerm)) {
03142 goto cleanup;
03143 }
03144 unackedList = icl_NthTerm(unackedTerm, 1);
03145 for(listElt = icl_List(unackedList); listElt != NULL; listElt = icl_ListNext(listElt)) {
03146 if(icl_Member(sequenceMatcher, icl_NthTerm(icl_ListElt(listElt), 2), &sequenceTerm)) {
03147 int eltSeqNum = icl_Int(icl_NthTerm(sequenceTerm, 1));
03148 if(oaa_SeqNumLessThan(ackNum, eltSeqNum)) {
03149 break;
03150 }
03151 }
03152 icl_Free(sequenceTerm);
03153 }
03154 for(; listElt != NULL; listElt = icl_ListNext(listElt)) {
03155 icl_AddToList(remainder, icl_CopyTerm(icl_ListElt(listElt)), TRUE);
03156 }
03157 icl_Free(unackedTerm);
03158
03159 com_UpdateInfo(connId, nextUnackedTerm);
03160
03161 cleanup:
03162 icl_Free(nextUnackedTerm);
03163 icl_Free(unackedMatcher);
03164 icl_Free(sequenceMatcher);
03165 }
03166
03167 static void oaa_record_outgoing_event(char* connId, ICLTerm* event)
03168 {
03169 ICLTerm* unackedMatcher = icl_NewStruct("unacked", 1, icl_NewVar("_"));
03170 ICLTerm* unackedTerm;
03171 ICLTerm* unackedList;
03172
03173 if(!com_GetInfo(connId, unackedMatcher, &unackedTerm)) {
03174 unackedTerm = icl_NewStruct("unacked", 1, icl_NewList(NULL));
03175 }
03176 unackedList = icl_NthTerm(unackedTerm, 1);
03177 icl_AddToList(unackedList, icl_CopyTerm(event), TRUE);
03178 com_UpdateInfo(connId, unackedTerm);
03179 icl_Free(unackedTerm);
03180 icl_Free(unackedMatcher);
03181 }
03182
03183 static void oaa_update_seq_num(ICLTerm* event)
03184 {
03185 char* connId;
03186 if(!icl_IsStruct(event) || icl_NumTerms(event) != 2 || !STREQ(icl_Functor(event), "event")) {
03187 return;
03188 }
03189 else {
03190 ICLTerm* eventParams = icl_NthTerm(event, 2);
03191 ICLTerm* connMatcher = icl_NewStruct("connection_id", 1, icl_NewVar("_"));
03192 ICLTerm* sequenceMatcher = icl_NewStruct("sequence", 1, icl_NewVar("_"));
03193 ICLTerm* sequenceTerm;
03194 ICLTerm* connTerm;
03195
03196 if(!icl_Member(connMatcher, eventParams, &connTerm)) {
03197 goto cleanup;
03198 }
03199 connId = icl_Str(icl_NthTerm(connTerm, 1));
03200
03201 if(icl_Member(sequenceMatcher, eventParams, &sequenceTerm)) {
03202 ICLTerm* otherSequenceTerm = icl_NewStruct("other_sequence", 1, icl_CopyTerm(icl_NthTerm(sequenceTerm, 1)));
03203 com_UpdateInfo(connId, otherSequenceTerm);
03204 icl_Free(otherSequenceTerm);
03205 icl_Free(sequenceTerm);
03206 }
03207 icl_Free(connTerm);
03208
03209 cleanup:
03210 icl_Free(connMatcher);
03211 icl_Free(sequenceMatcher);
03212 }
03213 }
03214
03215 static void oaa_update_last_acked(ICLTerm* event)
03216 {
03217 char* connId;
03218 if(!icl_IsStruct(event) || icl_NumTerms(event) != 2 || !STREQ(icl_Functor(event), "event")) {
03219 return;
03220 }
03221 else {
03222 ICLTerm* eventParams = icl_NthTerm(event, 2);
03223 ICLTerm* connMatcher = icl_NewStruct("connection_id", 1, icl_NewVar("_"));
03224 ICLTerm* ackMatcher = icl_NewStruct("ack", 1, icl_NewVar("_"));
03225 ICLTerm* ackTerm;
03226 ICLTerm* connTerm;
03227
03228 if(!icl_Member(connMatcher, eventParams, &connTerm)) {
03229 goto cleanup;
03230 }
03231 connId = icl_Str(icl_NthTerm(connTerm, 1));
03232
03233 if(icl_Member(ackMatcher, eventParams, &ackTerm)) {
03234 ICLTerm* otherAckTerm = icl_NewStruct("other_acked", 1, icl_CopyTerm(icl_NthTerm(ackTerm, 1)));
03235 com_UpdateInfo(connId, otherAckTerm);
03236 oaa_acked(connId, icl_Int(icl_NthTerm(ackTerm, 1)));
03237 icl_Free(otherAckTerm);
03238 icl_Free(ackTerm);
03239 }
03240 icl_Free(connTerm);
03241
03242 cleanup:
03243 icl_Free(connMatcher);
03244 icl_Free(ackMatcher);
03245 }
03246 }
03247
03248
03258 int oaa_select_event(double timeout, ICLTerm **event)
03259 {
03260 ICLTerm *in_event = NULL;
03261 ICLTerm *translated_event = NULL;
03262 char *connection_id;
03263
03264 int selected = FALSE;
03265
03266 selected = com_SelectEventFromAllIds(timeout, &in_event);
03267 CHECK_LEAKS();
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277 if(selected) {
03278 #ifdef FACILITATOR_OK
03279 oaa_translate_incoming_event(in_event, &translated_event);
03280 #else
03281 translated_event = in_event;
03282 #endif
03283
03284 oaa_unwrap_event(translated_event, &connection_id, event);
03285 oaa_update_seq_num(*event);
03286 oaa_update_last_acked(*event);
03287 icl_stFree(connection_id);
03288
03289
03290
03291
03292
03293
03294
03295
03296 }
03297
03298
03299
03300 #ifdef FACILITATOR_OK
03301 icl_Free(in_event);
03302 #endif
03303 icl_Free(translated_event);
03304 CHECK_LEAKS();
03305 return selected;
03306 }
03307
03308
03327
03328 int oaa_unwrap_event(ICLTerm *in_event,
03329 char **connection_id,
03330 ICLTerm **out_event)
03331 {
03332 ICLTerm *content, *new_params;
03333 char *errfmt =
03334 "%s: incoming event from an unrecognized connection (%s):\n %s\n";
03335
03336
03337 if(icl_IsStr(in_event) && STREQ(icl_Str(in_event), "timeout")) {
03338 *connection_id = strdup("unknown");
03339 *out_event = icl_CopyTerm(in_event);
03340 return TRUE;
03341 }
03342
03343
03344 *connection_id = com_GetDefaultConnectionId();
03345
03346
03347
03348
03349
03350 if(icl_IsStruct(in_event)) {
03351 char *functor = icl_Functor(in_event);
03352
03353 if(STREQ(functor, "term")) {
03354
03355
03356
03357 if(icl_NumTerms(in_event) == 1) {
03358 if (strlen(*connection_id) < strlen("unknown")) {
03359 icl_stFree(*connection_id);
03360 *connection_id = strdup("unknown");
03361 }
03362 else {
03363 strcpy(*connection_id, "unknown");
03364 }
03365 *out_event = icl_CopyTerm(icl_NthTerm(in_event, 1));
03366 }
03367 else if(icl_NumTerms(in_event) == 2) {
03368
03369
03370 ICLTerm *res;
03371 ICLTerm *connection = icl_NthTerm(in_event, 1);
03372 ICLTerm *event = icl_NthTerm(in_event, 2);
03373 ICLTerm *params = icl_NthTerm(event, 2);
03374 ICLTerm *cid;
03375 ICLTerm *t1;
03376
03377 content = icl_NthTerm(event, 1);
03378 t1 = icl_NewStruct("connection", 1, connection);
03379 if(!com_GetInfo(*connection_id, t1, &res)) {
03380 char *debug1 = icl_NewStringFromTerm(connection);
03381 char *debug2 = icl_NewStringFromTerm(icl_NthTerm(in_event, 2));
03382 fprintf(stderr, errfmt, "INTERNAL ERROR",
03383 debug1, debug2);
03384 *connection_id = strdup("unknown");
03385 icl_stFree(debug1);
03386 icl_stFree(debug2);
03387 }
03388 icl_Free(t1);
03389 icl_Free(res);
03390
03391
03392
03393
03394
03395 if(oaa_from_param(*out_event)) {
03396 new_params = icl_CopyTerm(params);
03397 }
03398 else {
03399 ICLTerm *id, *from_id;
03400 if(oaa_content_fac_id(content, &id)) {
03401 }
03402 else if(oaa_is_parent_fac_id(*connection_id, &id)) {
03403 }
03404 else if(oaa_is_oaa_id(*connection_id, &id)) {
03405 }
03406 else {
03407 id = icl_NewStr("unknown");
03408 }
03409 from_id = icl_NewStruct("from", 1, id);
03410 new_params = icl_NewList(icl_NewCons(from_id, icl_ListCopy(params)));
03411 }
03412 cid = icl_NewStruct("connection_id", 1,
03413 icl_NewStr(*connection_id));
03414 icl_AddToList(new_params, cid, FALSE);
03415 *out_event = icl_NewStruct("event", 2, icl_CopyTerm(content), new_params);
03416 }
03417 }
03418 else {
03419 if (strlen(*connection_id) < strlen("unknown")) {
03420 icl_stFree(*connection_id);
03421 *connection_id = strdup("unknown");
03422 }
03423 else {
03424 strcpy(*connection_id, "unknown");
03425 }
03426 }
03427 }
03428 return TRUE;
03429 }
03430
03431
03432
03433
03434 int oaa_from_param(ICLTerm *event)
03435 {
03436 ICLTerm *from = icl_NewStruct("from", 1, icl_NewVar("_"));
03437
03438 if(oaa_event_param(event, from)) {
03439 icl_Free(from);
03440 return TRUE;
03441 }
03442
03443 icl_Free(from);
03444 return FALSE;
03445 }
03446
03447
03448
03449
03450 int oaa_content_fac_id(ICLTerm *content, ICLTerm **id)
03451 {
03452 if(icl_IsStruct(content)) {
03453 char *functor = icl_Functor(content);
03454 if(STREQ(functor, "ev_connected")) {
03455
03456 ICLTerm *res = NULL;
03457 ICLTerm *fac_id = icl_NewStruct("fac_id", 1, icl_NewVar("Id"));
03458 ICLTerm *infolist = icl_NthTerm(content, 1);
03459 if(icl_GetParamValue(fac_id, infolist, &res)) {
03460 *id = res;
03461 icl_Free(fac_id);
03462 return TRUE;
03463 }
03464 icl_Free(fac_id);
03465 }
03466 }
03467 return FALSE;
03468 }
03469
03470
03471
03472
03473 int oaa_is_parent_fac_id(char *connection_id, ICLTerm **id)
03474 {
03475 ICLTerm *res = NULL;
03476 ICLTerm *fac_id = icl_NewStruct("fac_id", 1, icl_NewVar("Id"));
03477 if(STREQ(connection_id, "parent"))
03478 if(com_GetInfo(connection_id, fac_id, &res)) {
03479 *id = res;
03480 icl_Free(fac_id);
03481 return TRUE;
03482 }
03483 icl_Free(fac_id);
03484 return FALSE;
03485 }
03486
03487
03488
03489
03490 int oaa_is_oaa_id(char *connection_id, ICLTerm **id)
03491 {
03492 ICLTerm *res = NULL;
03493 ICLTerm *oaa_id = icl_NewStruct("oaa_id", 1, icl_NewVar("Id"));
03494
03495 if(com_GetInfo(connection_id, oaa_id, &res)) {
03496 *id = res;
03497 icl_Free(oaa_id);
03498 return TRUE;
03499 }
03500
03501 icl_Free(oaa_id);
03502 return FALSE;
03503 }
03504
03505
03506
03507
03508
03509
03510
03511
03512
03513 int oaa_translate_incoming_event(ICLTerm *raw_event_in,
03514 ICLTerm **raw_event_out)
03515 {
03516 #ifdef FACILITATOR_OK
03517
03518 ICLTerm *event_in, *contents;
03519 if(icl_IsStruct(raw_event_in) &&
03520 STREQ(icl_Functor(raw_event_in), "term")) {
03521 if((icl_IsStruct(event_in = icl_NthTerm(raw_event_in, 2))) &&
03522 (strcmp(icl_Functor(event_in), "event") == 0) &&
03523 (contents = icl_NthTerm(event_in, 1)) &&
03524 (icl_IsStruct(contents)) &&
03525 (strcmp(icl_Functor(contents), "ev_connect") == 0)) {
03526
03527 ICLTerm *params = icl_NthTerm(event_in, 2);
03528 ICLTerm *arglist = icl_NewList(icl_Arguments(contents));
03529
03530 ICLTerm *event_out =
03531 icl_NewStruct("event", 2,
03532 icl_NewStructFromList("ev_connected", arglist),
03533 params);
03534 *raw_event_out =
03535 icl_NewStruct("term", 2, icl_NthTerm(raw_event_in, 1), event_out);
03536 return;
03537 }
03538 } else {
03539
03540
03541 }
03542 #endif
03543 *raw_event_out = icl_CopyTerm(raw_event_in);
03544 return TRUE;
03545 }
03546
03552 int oaa_extract_event(ICLTerm *raw_event, ICLTerm **content, ICLTerm **params)
03553
03554 {
03555
03556 if(icl_IsStruct(raw_event)) {
03557 char *functor = icl_Functor(raw_event);
03558
03559 if(STREQ(functor, "event")) {
03560 *content = icl_CopyTerm(icl_NthTerm(raw_event, 1));
03561 *params = icl_CopyTerm(icl_NthTerm(raw_event, 2));
03562 return TRUE;
03563 }
03564
03565 }
03566 *content = *params = NULL;
03567 return TRUE;
03568 }
03569
03570
03578 int oaa_event_param(ICLTerm *event, ICLTerm *param) {
03579 if(icl_IsStruct(event) &&
03580 STREQ(icl_Functor(event), "event") &&
03581 (icl_NumTerms(event) == 2)) {
03582
03583 ICLTerm *params = icl_NthTerm(event, 2);
03584 return icl_ParamValue(icl_Str(param), NULL, params, NULL);
03585 }
03586 return FALSE;
03587 }
03588
03595 int oaa_extract_event_param(ICLTerm *event, char *param, ICLTerm **result) {
03596 int res = FALSE;
03597
03598 if(icl_IsStruct(event) &&
03599 STREQ(icl_Functor(event), "event") &&
03600 (icl_NumTerms(event) == 2)) {
03601 ICLTerm* paramAsTerm = icl_NewStruct(param, 1, icl_NewVar("_"));
03602 ICLTerm *params = icl_NthTerm(event, 2);
03603 res = icl_GetParamValue(paramAsTerm, params, result);
03604 icl_Free(paramAsTerm);
03605 return res;
03606 }
03607 return res;
03608 }
03609
03620 int oaa_Interpret(ICLTerm *goal, ICLTerm *params, ICLTerm **solutions) {
03621 char *goalstr;
03622 if(icl_IsVar(goal)) {
03623 return FALSE;
03624 }
03625 if(icl_IsStr(goal)) {
03626 if(STREQ((goalstr = icl_Str(goal)), "true")) {
03627 return TRUE;
03628 }
03629 if(STREQ(goalstr, "fail")) {
03630 return FALSE;
03631 }
03632 if(STREQ(goalstr, "false")) {
03633 return FALSE;
03634 }
03635 }
03636 if(icl_IsGroup(goal)) {
03637 char *startC=NULL, *sep;
03638 ICLListType *goal_list = icl_List(goal);
03639 icl_GetGroupChars(goal, startC, &sep);
03640
03641
03642
03643
03644 switch(*sep) {
03645 case ',':
03646 while(icl_ListHasMoreElements(goal_list)) {
03647 ICLTerm *subgoal =
03648 icl_ListElement(icl_ListNextElement(goal_list));
03649 if(!oaa_Interpret(subgoal, params, solutions))
03650 return FALSE;
03651 }
03652 return TRUE;
03653 case ';':
03654 while(icl_ListHasMoreElements(goal_list)) {
03655 ICLTerm *subgoal =
03656 icl_ListElement(icl_ListNextElement(goal_list));
03657 if(oaa_Interpret(subgoal, params, solutions))
03658 return TRUE;
03659 }
03660 return FALSE;
03661 }
03662 }
03663 if(icl_IsStruct(goal) &&
03664 STREQ(icl_Functor(goal), "findall")) {
03665
03666
03667
03668 }
03669 if(icl_BuiltIn(goal)) {
03670
03671
03672 return FALSE;
03673 }
03674 else {
03675 return oaa_exec_event(goal, params, solutions);
03676 }
03677 }
03678
03684 int oaa_exec_event(ICLTerm *goal, ICLTerm *params, ICLTerm **solutions) {
03685 char *goalstr = icl_Str(goal);
03686 int res = FALSE;
03687 int arity = icl_NumTerms(goal);
03688 if(STREQ(goalstr, "ev_trace_on")) {
03689 oaa_trace_on = TRUE;
03690 printf("\nTrace on.\n");
03691 res = TRUE;
03692 }
03693 else if(STREQ(goalstr, "ev_trace_off")) {
03694 oaa_trace_on = FALSE;
03695 printf("\nTrace off.\n");
03696 res = TRUE;
03697 }
03698 else if(STREQ(goalstr, "ev_com_trace_on")) {
03699 oaa_com_trace_on = TRUE;
03700 printf("\nCOMMUNICATION PROTOCOL trace on.\n");
03701 res = TRUE;
03702 }
03703 else if(STREQ(goalstr, "ev_com_trace_off")) {
03704 oaa_com_trace_on = FALSE;
03705 printf("\nCOMMUNICATION PROTOCOL trace off.\n");
03706 res = TRUE;
03707 }
03708 else if(STREQ(goalstr, "ev_debug_on")) {
03709 oaa_debug_on = TRUE;
03710 printf("\nDebug on.\n");
03711 res = TRUE;
03712 }
03713 else if(STREQ(goalstr, "ev_debug_off")) {
03714 oaa_debug_on = FALSE;
03715 printf("\nDebug off.\n");
03716 res = TRUE;
03717 }
03718 else if(STREQ(goalstr, "ev_set_timeout")) {
03719 oaa_timeout = icl_Int(icl_NthTerm(goal, 1));
03720 printf("\nTimeout set to %f.\n", oaa_timeout);
03721 res = TRUE;
03722 }
03723 else if(STREQ(goalstr, "ev_set_timeout")) {
03724 oaa_timeout = icl_Int(icl_NthTerm(goal, 1));
03725 printf("\nTimeout set to %f.\n", oaa_timeout);
03726 res = TRUE;
03727 }
03728 else if (STREQ(goalstr, "ev_agent_disconnected")) {
03729 ICLTerm *lid = icl_CopyTerm(icl_NthTerm(goal, 1));
03730
03731 oaa_remove_data_owned_by(lid);
03732 icl_Free(lid);
03733 res = TRUE;
03734 }
03735 else if (STREQ(goalstr, "ev_halt")) {
03736
03737 ICLTerm *tmpArgs = icl_NewList(NULL);
03738
03739 printf("\nDisconnecting...\n");
03740 com_Disconnect("parent");
03741 oaa_call_callback("app_done", NULL, tmpArgs, NULL);
03742 icl_Free(tmpArgs);
03743 exit(0);
03744 }
03745 else if(STREQ(goalstr, "ev_update_data") && (arity == 4)) {
03746
03747
03748 res = oaa_handle_ev_update_data(goal, params);
03749 }
03750 else if(STREQ(goalstr, "ev_update_trigger") &&
03751 (arity == 6)) {
03752 res = oaa_handle_ev_update_trigger(goal, params);
03753 }
03754 else if(STREQ(goalstr, "ev_solve") && (arity == 3)) {
03755 res = oaa_handle_ev_solve(goal, params, solutions);
03756 }
03757 else if(STREQ(goalstr, "ev_solved") && (arity == 6)) {
03758 res = oaa_handle_ev_solved(goal, params);
03759 }
03760 else
03761
03762
03763
03764 if(STREQ(goalstr, "oaa_Solve") && (arity == 2)) {
03765 res = oaa_Solve(icl_NthTerm(goal,1), icl_NthTerm(goal,2), NULL, solutions);
03766 }
03767 else
03768
03769
03770
03771 if(STREQ(goalstr, "oaa_PostEvent") && (arity == 2)) {
03772 res = oaa_PostEvent(icl_NthTerm(goal,1), icl_NthTerm(goal,2));
03773 }
03774 else
03775
03776
03777
03778 if(STREQ(goalstr, "oaa_AddData") && (arity == 2)) {
03779 res = oaa_AddData(icl_NthTerm(goal,1), icl_NthTerm(goal,2), NULL);
03780 }
03781 else
03782
03783
03784
03785 if(STREQ(goalstr, "oaa_AddTrigger") && (arity == 4)) {
03786 res = oaa_AddTrigger(icl_Str(icl_NthTerm(goal,1)), icl_NthTerm(goal,2),
03787 icl_NthTerm(goal,3), icl_NthTerm(goal,4), NULL);
03788 }
03789 else
03790 {
03791 res = oaa_handle_user_event(goal, params, solutions);
03792 }
03793 return res;
03794 }
03795
03796
03797
03798
03799 int oaa_handle_ev_update_data(ICLTerm *goal, ICLTerm *params)
03800 {
03801 ICLTerm *agent_id = NULL, *updaters = NULL, *requestees = NULL, *all_params = NULL;
03802 ICLTerm *mode = NULL, *id = NULL, *clause = NULL, *term_params = NULL;
03803 ICLTerm *t1 = NULL;
03804 int result = 0;
03805 char *modestr = NULL;
03806
03807 mode = icl_NthTerm(goal, 2);
03808 id = icl_NthTerm(goal, 1);
03809 clause = icl_NthTerm(goal, 3);
03810 term_params = icl_NthTerm(goal, 4);
03811 modestr = icl_Str(mode);
03812 all_params = NULL;
03813
03814 oaa_PrimaryAddress(&agent_id);
03815 requestees = icl_NewList(icl_NewCons(agent_id,NULL));
03816 icl_append_to_list(term_params, params, &all_params);
03817 if(!all_params) {
03818 all_params = icl_NewList(NULL);
03819 }
03820
03821
03822
03823
03824 if(STREQ(modestr, "add")) {
03825 result = oaa_add_data_local(clause, all_params);
03826 }
03827 else if(STREQ(modestr, "remove")) {
03828 result = oaa_remove_data_local(clause, all_params);
03829 }
03830 else if(STREQ(modestr, "replace")) {
03831 result = oaa_replace_data_local(clause, all_params);
03832 }
03833 else {
03834 result = FALSE;
03835 }
03836 t1 = icl_NewTermFromData("reply(none)",11);
03837 if(!icl_GetParamValue(t1, params, NULL)) {
03838 ICLTerm *new_term;
03839 ICLTerm *emptyList;
03840 if(result) {
03841 updaters = icl_NewList(icl_NewCons(agent_id, NULL));
03842 }
03843 else {
03844 updaters = icl_NewList(NULL);
03845 }
03846 new_term =
03847 icl_NewStruct("ev_data_updated", 6,
03848 icl_CopyTerm(id),
03849 icl_CopyTerm(mode),
03850 icl_CopyTerm(clause),
03851 icl_CopyTerm(params),
03852 requestees,
03853 updaters);
03854 emptyList = icl_NewList(NULL);
03855 oaa_PostEvent(new_term, emptyList);
03856 icl_Free(new_term);
03857 icl_Free(emptyList);
03858 }
03859 icl_Free(t1);
03860 icl_Free(requestees);
03861 icl_Free(updaters);
03862 icl_Free(all_params);
03863 return TRUE;
03864 }
03865
03866
03867
03868
03869 int oaa_handle_ev_update_trigger(ICLTerm *goal, ICLTerm *params)
03870 {
03871 ICLTerm *id = icl_NthTerm(goal, 1);
03872 ICLTerm *mode = icl_NthTerm(goal, 2);
03873 char *type = icl_Str(icl_NthTerm(goal, 3));
03874 ICLTerm *condition = icl_NthTerm(goal, 4);
03875 ICLTerm *action = icl_NthTerm(goal, 5);
03876 ICLTerm *trig_params = icl_NthTerm(goal, 6);
03877 ICLTerm *agent_id, *new_term, *updaters, *all_params;
03878 ICLTerm *t1 = NULL;
03879 ICLTerm *emptyList = NULL;
03880 char *modestr = icl_Str(mode);
03881 int result = FALSE;
03882 oaa_PrimaryAddress(&agent_id);
03883 all_params = NULL;
03884 icl_append_to_list(trig_params, params, &all_params);
03885 if(!all_params) {
03886 all_params = NULL;
03887 }
03888
03889
03890
03891
03892
03893 if (STREQ(modestr, "add")) {
03894 result = oaa_add_trigger_local(type, condition, action, all_params);
03895 }
03896 else if (STREQ(modestr, "remove")) {
03897 result = oaa_remove_trigger_local(type, condition, action, all_params);
03898 }
03899 else {
03900 result = FALSE;
03901 }
03902
03903 if (!icl_GetParamValue((t1 = icl_NewTermFromData("reply(none)",11)),
03904 params, NULL)) {
03905 if (result) {
03906 updaters = icl_NewList(icl_NewCons(agent_id, NULL));
03907 }
03908 else {
03909 updaters = icl_NewList(NULL);
03910 }
03911 new_term = icl_NewStruct("ev_trigger_updated", 8,
03912 icl_CopyTerm(id),
03913 icl_CopyTerm(mode),
03914 icl_NewStr(type),
03915 icl_CopyTerm(condition),
03916 icl_CopyTerm(action),
03917 icl_CopyTerm(params),
03918 icl_CopyTerm(updaters),
03919 icl_CopyTerm(updaters));
03920 emptyList = icl_NewList(NULL);
03921 oaa_PostEvent(new_term, emptyList);
03922 icl_Free(emptyList);
03923 icl_Free(new_term);
03924 icl_Free(updaters);
03925 }
03926 icl_Free(t1);
03927 icl_Free(all_params);
03928
03929
03930
03931
03932
03933 return TRUE;
03934 }
03935
03936
03937
03938
03939
03940 int oaa_find_all_contexts(ICLTerm *params, ICLTerm **contexts) {
03941 ICLTerm *context, *test;
03942 ICLListType *p;
03943 if(!icl_IsList(params))
03944 return FALSE;
03945 test = icl_NewStruct("context", 1, icl_NewVar("X"));
03946 p = icl_List(params);
03947 *contexts = NULL;
03948 while(p) {
03949 if(icl_Unify(test, p->elt, &context)) {
03950 if(*contexts == NULL) {
03951 *contexts = icl_NewList(NULL);
03952 }
03953 icl_AddToList(*contexts, context, TRUE);
03954 }
03955 p = p->next;
03956 }
03957 if(*contexts == NULL) {
03958 *contexts = icl_NewList(NULL);
03959 }
03960 icl_Free(test);
03961 return TRUE;
03962 }
03963
03964
03965
03966
03967 int oaa_handle_ev_solved(ICLTerm *goal, ICLTerm *params) {
03968 ICLTerm *local_params = icl_NthTerm(goal, 5);
03969 ICLTerm *local_callback = NULL;
03970 char* local_callback_id;
03971 int res;
03972 ICLTerm* request_for_callback = icl_NewTermFromData("callback(X)",11);
03973 (void)params;
03974
03975 if (icl_GetParamValue(request_for_callback, local_params, &local_callback)) {
03976 local_callback_id = icl_Str(icl_NthTerm(local_callback,1));
03977 }
03978 else {
03979 local_callback_id = "app_do_event";
03980 }
03981
03982 icl_Free(request_for_callback);
03983 res = oaa_call_callback(local_callback_id, goal, local_params, NULL);
03984 icl_Free(local_callback);
03985 return res;
03986 }
03987
03988
03989
03990
03991 int oaa_handle_ev_solve(ICLTerm *goal, ICLTerm *params, ICLTerm **solutions) {
03992 ICLTerm *id = icl_NthTerm(goal, 1);
03993 ICLTerm *full_goal = icl_NthTerm(goal, 2);
03994 ICLTerm *solve_params = icl_NthTerm(goal, 3);
03995 ICLTerm *goal_params, *contexts;
03996 ICLTerm *tmp1, *tmp2, *user_id;
03997 ICLTerm *t1 = NULL;
03998 ICLTerm *t2 = NULL;
03999 ICLTerm *inherited_params;
04000 ICLTerm *all_params;
04001
04002 if(!oaa_class("leaf"))
04003 return FALSE;
04004
04005 inherited_params = NULL;
04006 all_params = NULL;
04007 icl_GoalComponents(full_goal, &tmp1, &tmp2, &goal_params);
04008 icl_Free(tmp1);
04009 icl_Free(tmp2);
04010
04011
04012
04013
04014
04015 icl_append_to_list(solve_params, params, &inherited_params);
04016 icl_append_to_list(goal_params, inherited_params, &all_params);
04017 icl_Free(goal_params);
04018
04019
04020 oaa_find_all_contexts(all_params, &contexts);
04021 oaa_assert_current_contexts(id, contexts);
04022
04023
04024
04025
04026
04027
04028
04029
04030 *solutions = icl_NewList(NULL);
04031 oaa_solve_local(full_goal, inherited_params, solutions);
04032
04033 #ifdef UNNEEDED_DEBUG
04034 oaa_TraceMsg("\nSolutions found for %s:\n %s\n",
04035 icl_NewStringFromTerm(full_goal),
04036 icl_NewStringFromTerm(*solutions),NULL);
04037 #endif
04038
04039
04040
04041
04042
04043
04044 if(oaa_retract_delay(id, &user_id)) {
04045 oaa_assert_delay_table(icl_CopyTerm(id), icl_CopyTerm(user_id), icl_CopyTerm(full_goal), icl_CopyTerm(solve_params), icl_CopyTerm(all_params));
04046 } else {
04047 ICLTerm* request = icl_NewTermFromData("reply(none)",11);
04048 ICLTerm* post_params = NULL;
04049 int no_reply = icl_GetParamValue(request, all_params, NULL);
04050 ICLTerm *from_ks = NULL;
04051 oaa_PrimaryAddress(&from_ks);
04052
04053 if (!no_reply && !STREQ(icl_Str(from_ks), "unknown")) {
04054 ICLTerm *new_event =
04055 icl_NewStruct("ev_solved", 6,
04056 icl_CopyTerm(id),
04057 icl_NewList(icl_NewCons(icl_CopyTerm(from_ks), NULL)),
04058 icl_NewList(icl_NewCons(icl_CopyTerm(from_ks), NULL)),
04059 getEvSolvedGoal(full_goal),
04060 icl_CopyTerm(solve_params),
04061 icl_CopyTerm(*solutions));
04062
04063
04064
04065
04066
04067 post_params = icl_NewList(NULL);
04068
04069
04070 t1 = icl_NewStruct("connection_id", 1, icl_NewVar("_"));
04071 if (icl_GetParamValue(t1, params, &t2)) {
04072 icl_AddToList(post_params, icl_CopyTerm(t2), FALSE);
04073 }
04074 icl_Free(t1);
04075 if (t2 != NULL) {
04076 icl_Free(t2);
04077 }
04078
04079 oaa_PostEvent(new_event, post_params);
04080 icl_Free(new_event);
04081 icl_Free(post_params);
04082 }
04083 if(from_ks != NULL) {
04084 icl_Free(from_ks);
04085 }
04086 icl_Free(request);
04087 }
04088 oaa_retractall_current_contexts(id);
04089
04090 icl_Free(inherited_params);
04091 icl_Free(all_params);
04092
04093 return TRUE;
04094
04095 }
04096
04097 ICLTerm *valid_oaa_solvables() {
04098 if(oaa_solvables == NULL) {
04099 oaa_solvables = icl_NewList(NULL);
04100 return oaa_solvables;
04101 }
04102 else {
04103 return oaa_solvables;
04104 }
04105 }
04106
04107 static char* CALLBACK_PARAM = "callback(CB)";
04108
04109
04110
04111
04112 int oaa_handle_user_event(ICLTerm *event, ICLTerm *params, ICLTerm **solutions) {
04113 ICLTerm *goal = NULL, *matched = NULL;
04114 ICLTerm *solvables = valid_oaa_solvables();
04115 int res = FALSE;
04116 oaa_turn_on_debug();
04117
04118 oaa_goal_matches_solvables(event, solvables, &goal, &matched);
04119
04120 if (matched && icl_IsStruct(matched) &&
04121 STREQ(icl_Functor(matched), "solvable")) {
04122
04123 int (*callback_proc)(ICLTerm*, ICLTerm*, ICLTerm*)=NULL;
04124
04125 ICLTerm* solv_params = icl_NthTerm(matched, 2);
04126 ICLTerm* tempRequest = icl_NewTermFromData(CALLBACK_PARAM, strlen(CALLBACK_PARAM));
04127 ICLTerm* cb = NULL;
04128 icl_GetParamValue(tempRequest, solv_params, &cb);
04129 icl_Free(tempRequest);
04130
04131
04132 if (cb) {
04133 oaa_GetCallback(icl_Str(icl_NthTerm(cb,1)), &callback_proc);
04134 icl_Free(cb);
04135 }
04136
04137 if (callback_proc) {
04138 callback_proc(event, params, *solutions);
04139 }
04140 oaa_turn_off_debug();
04141 res = TRUE;
04142 }
04143 if(goal) {
04144 icl_Free(goal);
04145 }
04146 if(matched) {
04147 icl_Free(matched);
04148 }
04149 return res;
04150 }
04151
04152
04153
04154
04155
04156
04157 int passes_tests(ICLTerm *params)
04158 {
04159 ICLTerm *test;
04160 ICLTerm *results;
04161 ICLTerm *t1;
04162 int returnValue = TRUE;
04163
04164 if (oaa_class("leaf")) {
04165 t1 = icl_NewStruct("test", 1, icl_NewVar("Test"));
04166 if (icl_GetParamValue(t1, params, &test)) {
04167 ICLTerm *emptyList = icl_NewList(NULL);
04168 returnValue = oaa_Solve(test, emptyList, &results, NULL);
04169 icl_Free(emptyList);
04170 icl_Free(results);
04171 }
04172 else {
04173 returnValue = TRUE;
04174 }
04175 icl_Free(t1);
04176 }
04177 else if(oaa_class("root") || oaa_class("node")) {
04178
04179
04180
04181
04182 t1 = icl_NewStruct("test", 1, icl_NewVar("Test"));
04183 if(icl_GetParamValue(t1, params, &test)) {
04184 ICLTerm *emptyList = icl_NewList(NULL);
04185 (void)oaa_solve_local(test, emptyList, &results);
04186 icl_Free(emptyList);
04187 icl_Free(results);
04188 }
04189 else {
04190 returnValue = FALSE;
04191 }
04192
04193 icl_Free(t1);
04194 }
04195 return returnValue;
04196 }
04197
04203 int oaa_DelaySolution(ICLTerm *id) {
04204 ICLTerm *goal_id, *tmp;
04205
04206
04207
04208 if(oaa_retrieve_nth_current_contexts(&goal_id, &tmp, 0)) {
04209 oaa_assert_delay(goal_id, id);
04210 return TRUE;
04211 }
04212 return FALSE;
04213 }
04214
04219 int oaa_ReturnDelayedSolutions(ICLTerm *id, ICLTerm *solution_list)
04220 {
04221 ICLTerm *goal_id, *goal, *solve_params, *all_params;
04222 ICLTerm *solutions = icl_NewList(NULL);
04223 ICLTerm *from_ks;
04224
04225 if(oaa_retract_delay_table(&goal_id, id, &goal, &solve_params,
04226 &all_params)) {
04227 ICLTerm *t1;
04228
04229 t1 = icl_NewTermFromData("reply(none)",11);
04230 if(!icl_GetParamValue(t1, all_params, NULL)) {
04231 ICLListType *slist;
04232
04233 if(!oaa_PrimaryAddress(&from_ks)) {
04234 from_ks = icl_NewStr("unknown");
04235 }
04236
04237
04238 slist = icl_List(solution_list);
04239
04240 while(icl_ListHasMoreElements(slist)) {
04241 ICLTerm *soln = icl_ListElement(slist);
04242
04243 if(icl_Unify(goal, soln, NULL)) {
04244 icl_AddToList(solutions, icl_CopyTerm(soln), TRUE);
04245 }
04246 slist = icl_ListNextElement(slist);
04247 }
04248
04249 if(icl_NumTerms(solutions) > 0) {
04250 ICLTerm* requestees = icl_NewList(NULL);
04251 ICLTerm* responders;
04252 ICLTerm *eventToPost;
04253 icl_AddToList(requestees, icl_CopyTerm(from_ks), 1);
04254 responders = icl_CopyTerm(requestees);
04255 eventToPost = icl_NewStruct("ev_solved", 6, icl_CopyTerm(goal_id),
04256 requestees, responders, getEvSolvedGoal(goal), icl_CopyTerm(solve_params),
04257 solutions);
04258 (void)oaa_PostEvent(eventToPost, NULL);
04259 icl_Free(goal_id);
04260 icl_Free(goal);
04261 icl_Free(solve_params);
04262 icl_Free(all_params);
04263 icl_Free(from_ks);
04264 icl_Free(eventToPost);
04265 }
04266 else {
04267 icl_Free(goal_id);
04268 icl_Free(goal);
04269 icl_Free(solve_params);
04270 icl_Free(all_params);
04271 icl_Free(from_ks);
04272 icl_Free(t1);
04273 return FALSE;
04274 }
04275 } else {
04276 icl_Free(t1);
04277 return FALSE;
04278 }
04279 icl_Free(t1);
04280 }
04281 else
04282 {
04283 return FALSE;
04284 }
04285 return TRUE;
04286 }
04287
04305
04306
04307
04308
04309
04310
04311
04312
04313
04314
04315
04316
04317
04318 int oaa_AddDelayedContextParams(ICLTerm *id, ICLTerm *params,
04319 ICLTerm **new_params)
04320 {
04321 ICLTerm *goal_id, *goal, *solve_params, *all_params;
04322 ICLTerm *contexts = icl_NewList(NULL);
04323
04324 if (oaa_retract_delay_table(&goal_id, id, &goal,
04325 &solve_params, &all_params)) {
04326 ICLListType *allparamlist = icl_List(all_params);
04327
04328 while (icl_ListHasMoreElements(allparamlist)) {
04329 ICLTerm *param = icl_ListElement(allparamlist);
04330 ICLTerm *context;
04331 ICLTerm *t1;
04332
04333 t1 = icl_NewStruct("context", 1, icl_NewVar("C"));
04334 if (icl_Unify(t1, param, &context))
04335 icl_AddToList(contexts, context, TRUE);
04336
04337 allparamlist = icl_ListNextElement(allparamlist);
04338 icl_Free(t1);
04339 }
04340 if (icl_NumTerms(contexts) > 0) {
04341 icl_append_to_list(contexts, params, new_params);
04342 return TRUE;
04343 }
04344 }
04345 return FALSE;
04346 }
04347
04348
04349
04350
04351
04352 int oaa_address_to_comm_id(ICLTerm *inAddress, char **commId)
04353 {
04354 ICLTerm* tempRequest;
04355 int res;
04356
04357 tempRequest = icl_NewStruct("other_address", 1, icl_CopyTerm(inAddress));
04358 res = com_GetConnectionFromInfo(tempRequest, commId);
04359 icl_Free(tempRequest);
04360 return res;
04361 }
04362
04381 int oaa_PostEvent(ICLTerm *contents, ICLTerm *params)
04382 {
04383 ICLTerm *send_event;
04384 ICLTerm *destvar = icl_NewVar("Dest"), *dest;
04385 ICLTerm *dest_id, *trans_event, *arglist;
04386 ICLTerm *t1 = (ICLTerm *)NULL, *t2 = (ICLTerm *)NULL;
04387 char *comm_id = NULL;
04388
04389
04390
04391 t1 = icl_NewStruct("priority", 1, icl_NewVar("_"));
04392 t2 = icl_NewStruct("from", 1, icl_NewVar("_"));
04393
04394 if (memberchk(t1, params) || memberchk(t2, params)) {
04395
04396 send_event = icl_NewStruct("event", 2, icl_CopyTerm(contents),
04397 icl_CopyTerm(params));
04398 }
04399 else {
04400 send_event = icl_NewStruct("event", 2, icl_CopyTerm(contents),
04401 icl_NewList(NULL));
04402 }
04403 icl_Free(t1);
04404 icl_Free(t2);
04405
04406
04407 t1 = icl_NewStruct("connection_id", 1, icl_NewVar("_"));
04408 if (icl_GetParamValue(t1, params, &t2)) {
04409 comm_id = strdup(icl_Str(icl_NthTerm(t2,1)));
04410 }
04411 icl_Free(t1);
04412 icl_Free(t2);
04413
04414
04415 t1 = icl_NewStruct("address", 1, icl_CopyTerm(destvar));
04416 if (!icl_GetParamValue(t1, params, &dest)) {
04417 dest = icl_NewStr("parent");
04418 }
04419 icl_Free(t1);
04420
04421 icl_standardize_addressee(dest, &dest_id);
04422
04423 arglist = icl_NewList(NULL);
04424 icl_AddToList(arglist, dest, FALSE);
04425
04426 #ifdef UNNEEDED_DEBUG
04427 oaa_ComTraceMsg("\n[COM send to %s]:\n %s\n",
04428 icl_NewStringFromTerm(dest_id),
04429 icl_NewStringFromTerm(arglist), NULL);
04430 #endif //UNNEEDED_DEBUG
04431 if (comm_id == NULL) {
04432 oaa_address_to_comm_id(dest_id, &comm_id);
04433 }
04434 oaa_translate_outgoing_event(send_event, dest_id, comm_id, &trans_event);
04435 icl_AddToList(arglist, trans_event, TRUE);
04436 oaa_record_outgoing_event(comm_id, trans_event);
04437
04438
04439 com_SendTerm(comm_id, trans_event);
04440 icl_stFree(comm_id);
04441
04442
04443
04444
04445 oaa_CheckTriggers("comm", send_event, "send");
04446 icl_Free(destvar);
04447 icl_Free(dest_id);
04448 icl_Free(send_event);
04449 icl_Free(arglist);
04450 return TRUE;
04451 }
04452
04453 int oaa_convert_id_to_comm_id(ICLTerm *id, ICLTerm **cid)
04454 {
04455 char *connid;
04456 int res = FALSE;
04457 ICLTerm *fid = icl_NewStruct("fac_id", 1, icl_NewVar("FId"));
04458 ICLTerm *oid = icl_NewStruct("oaa_id", 1, icl_NewVar("FId"));
04459 (void)id;
04460
04461
04462
04463
04464
04465
04466
04467
04468 if(com_GetConnectionId(&connid, fid) ||
04469 com_GetConnectionId(&connid, oid)) {
04470 *cid = icl_NewStr(connid);
04471 res = TRUE;
04472 }
04473 icl_Free(fid);
04474 icl_Free(oid);
04475 return res;
04476 }
04477
04487 int oaa_translate_outgoing_event(ICLTerm *event, ICLTerm *dest_id, char* commId,
04488 ICLTerm **new_event) {
04489 ICLTerm *contents;
04490 ICLTerm *params;
04491 int nextOutSeqNum;
04492 int lastSeenSeqNum;
04493 ICLTerm *lastOutSeqNumTerm = NULL;
04494 ICLTerm *lastSeenSeqNumTerm = NULL;
04495 ICLTerm *ackTerm = NULL;
04496 ICLTerm *seqNumTerm = NULL;
04497 (void)dest_id;
04498
04499 if(!oaa_outSeqNum_matcher) {
04500 oaa_outSeqNum_matcher = icl_NewStruct("sequence", 1, icl_NewVar("_"));
04501 }
04502 if(!oaa_lastSeenSeqNum_matcher) {
04503 oaa_lastSeenSeqNum_matcher = icl_NewStruct("ack", 1, icl_NewVar("_"));
04504 }
04505
04506 com_GetInfo(commId, oaa_outSeqNum_matcher, &lastOutSeqNumTerm);
04507 if(lastOutSeqNumTerm) {
04508 nextOutSeqNum = icl_Int(icl_NthTerm(lastOutSeqNumTerm, 1)) + 1;
04509 seqNumTerm = icl_NewStruct("sequence", 1, icl_NewInt(nextOutSeqNum));
04510 com_UpdateInfo(commId, seqNumTerm);
04511 icl_Free(lastOutSeqNumTerm);
04512 }
04513
04514 com_GetInfo(commId, oaa_lastSeenSeqNum_matcher, &lastSeenSeqNumTerm);
04515 if(lastSeenSeqNumTerm) {
04516 lastSeenSeqNum = icl_Int(icl_NthTerm(lastSeenSeqNumTerm, 1));
04517 ackTerm = icl_NewStruct("ack", 1, icl_NewInt(lastSeenSeqNum));
04518 icl_Free(lastSeenSeqNumTerm);
04519 }
04520
04521
04522
04523
04524
04525
04526 if(icl_IsStruct(event) &&
04527 STREQ(icl_Functor(event), "event")) {
04528 if(icl_IsStruct(contents = icl_NthTerm(event, 1)) &&
04529 (STREQ(icl_Functor(contents), "ev_connect") ||
04530 STREQ(icl_Functor(contents), "ev_connected"))) {
04531 *new_event = icl_CopyTerm(event);
04532 params = icl_NthTerm(*new_event, 2);
04533 if(!STREQ(icl_Functor(contents), "ev_connected")) {
04534 if(seqNumTerm) {
04535 icl_AddToList(params, seqNumTerm, FALSE);
04536 }
04537 }
04538 if(ackTerm) {
04539 icl_AddToList(params, ackTerm, FALSE);
04540 }
04541 return TRUE;
04542 } else {
04543
04544
04545
04546
04547
04548
04549
04550
04551 }
04552 }
04553 #if 0
04554
04555
04556
04557 *new_event = event;
04558 #endif
04559
04560
04561
04562
04563
04564 *new_event = icl_CopyTerm(event);
04565 params = icl_NthTerm(*new_event, 2);
04566 if(seqNumTerm) {
04567 icl_AddToList(params, seqNumTerm, FALSE);
04568 }
04569 if(ackTerm) {
04570 icl_AddToList(params, ackTerm, FALSE);
04571 }
04572 return TRUE;
04573 }
04574
04575
04576
04577
04578
04579
04580 int oaa_LibraryVersion(ICLTerm** version) {
04581 int result = FALSE;
04582 ICLTerm* myVersionAsTerm =
04583 icl_NewStruct("version", 1, icl_NewStr(oaa_library_version_str));
04584 result = icl_Unify(*version, myVersionAsTerm, version);
04585 icl_Free(myVersionAsTerm);
04586 return result;
04587 }
04588
04593 int oaa_Version(ICLTerm *agent_id, ICLTerm **language, ICLTerm **version) {
04594 ICLTerm *true_id;
04595 ICLTerm *true_id_var = icl_NewVar("TrueId");
04596 ICLTerm *version_var = icl_NewVar("Version");
04597 ICLTerm *language_var = icl_NewVar("Language");
04598 ICLTerm *oaa_id_query = icl_NewStruct("oaa_id", 1, true_id_var);
04599 ICLTerm *fac_id_query = icl_NewStruct("fac_id", 1, true_id_var);
04600 ICLTerm *agent_language_query = icl_NewStruct("agent_language", 1,
04601 true_id_var);
04602 ICLTerm *agent_version_query = icl_NewStruct("agent_version", 1,
04603 version_var);
04604 char *comm_id_str;
04605
04606 if (icl_true_id(agent_id, &true_id)) {
04607
04608 if (oaa_PrimaryAddress(&true_id) &&
04609 oaa_LibraryVersion(version)) {
04610 *language = icl_NewStr("c");
04611 } else if ((com_GetConnectionId(&comm_id_str, oaa_id_query) ||
04612 com_GetConnectionId(&comm_id_str, fac_id_query)) &&
04613 (com_GetInfo(comm_id_str, agent_language_query, language) ||
04614 (*language = icl_NewStr("unknown"))) &&
04615 (com_GetInfo(comm_id_str, agent_version_query, version) ||
04616 (*version = icl_NewStr("unknown")))) {
04617 } else if (oaa_class("leaf") || oaa_class("node")) {
04618 ICLTerm *agent_version_term =
04619 icl_NewStruct("agent_version", 3, true_id,
04620 language_var, version_var);
04621 ICLTerm *paramlist = icl_NewTermFromData("[address(parent)]",17);
04622 ICLTerm *result, *result_list;
04623
04624 if (oaa_Solve(agent_version_term, paramlist, NULL, &result_list)) {
04625 if (icl_IsList(result_list) &&
04626 (result = icl_NthTerm(result_list, 1)) &&
04627 icl_IsStruct(result) &&
04628 (icl_NumTerms(result) == 3)) {
04629 *language = icl_NthTerm(result, 2);
04630 *version = icl_NthTerm(result, 3);
04631 }
04632 }
04633 icl_Free(paramlist);
04634 icl_Free(agent_version_term);
04635 } else {
04636 *language = icl_NewStr("prolog");
04637 *version = icl_NewStr("1.0");
04638 }
04639 } else {
04640 *language = icl_NewStr("prolog");
04641 *version = icl_NewStr("1.0");
04642 }
04643
04644 icl_Free(oaa_id_query);
04645 icl_Free(fac_id_query);
04646 icl_Free(agent_language_query);
04647 icl_Free(agent_version_query);
04648 icl_Free(true_id_var);
04649 icl_Free(version_var);
04650 icl_Free(language_var);
04651 return TRUE;
04652 }
04653
04657 int oaa_CanSolve(ICLTerm *goal, ICLTerm **kslist)
04658 {
04659 ICLTerm *kslist_var = icl_NewVar("KSList");
04660 ICLTerm *can_solve_query = icl_NewStruct("can_solve", 2, goal, kslist_var);
04661 ICLTerm *paramlist = icl_NewTermFromData("[address(parent)]",17);
04662 int res = FALSE;
04663
04664 if(oaa_Solve(can_solve_query, paramlist, NULL, kslist))
04665 res = TRUE;
04666 icl_Free(can_solve_query);
04667 icl_Free(paramlist);
04668 return res;
04669 }
04670
04679 int oaa_Ping(ICLTerm *agent_addr, double time_limit,
04680 double *total_response_time) {
04681 int res = FALSE;
04682 if(time_limit >= 0.0) {
04683 #ifndef _WINDOWS
04684 double t0, t1;
04685 struct timeval tv0, tv1;
04686 #endif
04687 ICLTerm *trueterm = icl_NewStr("true");
04688 ICLTerm *tlfloat = icl_NewFloat(time_limit);
04689 ICLTerm *addrterm = icl_NewStruct("address", 1, agent_addr);
04690 ICLTerm *tlterm = icl_NewStruct("time_limit", 1, tlfloat);
04691 ICLTerm *paramlist = icl_NewList(NULL);
04692 ICLTerm *result;
04693
04694 icl_AddToList(paramlist, addrterm, TRUE);
04695 icl_AddToList(paramlist, tlterm, TRUE);
04696 #ifndef _WINDOWS
04697 gettimeofday(&tv0, (void *)0);
04698 #endif
04699 if(oaa_Solve(trueterm, paramlist, &result, NULL)) {
04700 #ifndef _WINDOWS
04701 gettimeofday(&tv1, (void *)0);
04702 t0 = tv0.tv_sec*1000.0 + tv0.tv_usec;
04703 t1 = tv1.tv_sec*1000.0 + tv1.tv_usec;
04704 *total_response_time = (t1 - t0)*0.001;
04705 #endif
04706 res = TRUE;
04707 }
04708 icl_Free(trueterm);
04709 icl_Free(paramlist);
04710 }
04711 return res;
04712 }
04713
04714
04715
04716
04759
04760
04761
04762
04763
04764
04765 int oaa_Declare(ICLTerm *solvable, ICLTerm *initial_common_perms,
04766 ICLTerm *initial_common_params, ICLTerm *initial_params,
04767 ICLTerm **declared_solvables)
04768 {
04769 int res = FALSE;
04770 ICLTerm *solvable_list, *solvables, *common_perms;
04771 ICLTerm *common_params, *params, *solvables1, *new_solvables;
04772 int res1 = 0;
04773 int res2 = 0;
04774 int res3 = 0;
04775 int res4 = 0;
04776 int res5 = 0;
04777 int res6 = 0;
04778 int res7 = 0;
04779
04780 if (icl_IsList(solvable)) {
04781 solvable_list = solvable;
04782 }
04783 else {
04784 solvable_list = icl_NewList(icl_NewCons(icl_CopyTerm(solvable), NULL));
04785 }
04786
04787 res2 = icl_standardize_perms(initial_common_perms, FALSE, &common_perms);
04788 res3 = icl_standardize_params(initial_common_params, FALSE, &common_params);
04789 res4 = icl_standardize_params(initial_params, FALSE, ¶ms);
04790
04791 res1 = icl_ConvertSolvables(TRUE, solvable_list, &solvables);
04792 if(res1) {
04793 res5 = oaa_distribute_perms(solvables, common_perms, &solvables1);
04794 }
04795 if(res5) {
04796 res6 = oaa_distribute_params(solvables1, common_params, &new_solvables);
04797 }
04798 if(res6 && res4) {
04799 res7 = oaa_declare_aux("add", new_solvables, params, declared_solvables);
04800 }
04801
04802 if (res1 && res2 && res3 && res4 && res5 && res6 && res7) {
04803 res = TRUE;
04804 }
04805
04806 if(solvable_list != solvable) {
04807 icl_Free(solvable_list);
04808 }
04809 icl_Free(solvables);
04810 icl_Free(solvables1);
04811 icl_Free(new_solvables);
04812 icl_Free(params);
04813 icl_Free(common_perms);
04814 icl_Free(common_params);
04815
04816 return res;
04817 }
04818
04819
04823 int oaa_DeclareData(ICLTerm *solv, ICLTerm *params,
04824 ICLTerm **declared_solvs) {
04825 int res = FALSE;
04826 if(!icl_IsList(solv)) {
04827 ICLTerm *solvlist = icl_NewList(icl_NewCons(solv, (ICLListType *)NULL));
04828 if(oaa_DeclareData(solvlist, params, declared_solvs))
04829 res = TRUE;
04830 } else if(!res) {
04831 ICLTerm *common_perms =
04832 icl_NewTermFromData("[write(true)]",13);
04833 ICLTerm *common_params =
04834 icl_NewTermFromData("[type(data)]",12);
04835 if(oaa_Declare(solv, common_perms, common_params,
04836 params, declared_solvs))
04837 res = TRUE;
04838 }
04839 return res;
04840 }
04841
04856 int oaa_Undeclare(ICLTerm *solvable, ICLTerm *initial_params,
04857 ICLTerm **undeclared_solvables) {
04858 int res = FALSE;
04859 ICLTerm *solvable_list, *solvables, *params;
04860
04861 if(icl_IsList(solvable))
04862 solvable_list = solvable;
04863 else
04864 solvable_list = icl_NewList(icl_NewCons(solvable, (ICLListType *)NULL));
04865 if(icl_minimally_instantiate_solvables(solvable_list, &solvables) &&
04866 icl_standardize_params(initial_params, FALSE, ¶ms) &&
04867 oaa_declare_aux("remove", solvables, params, undeclared_solvables))
04868 res = TRUE;
04869 return res;
04870 }
04871
04872
04892 int oaa_Redeclare(ICLTerm *initial_solvable, ICLTerm *initial_new_solvable,
04893 ICLTerm *initial_params) {
04894 ICLTerm *solvable, *new_solvable, *solvable_list, *new_solvable_list;
04895 ICLTerm *params, *with_new_solvable, *redeclared_solvables;
04896 ICLTerm *init_solv_list =
04897 icl_NewList(icl_NewCons(initial_solvable, (ICLListType *)NULL));
04898 ICLTerm *init_new_solv_list =
04899 icl_NewList(icl_NewCons(initial_new_solvable, (ICLListType *)NULL));
04900 int res = FALSE;
04901 if(icl_minimally_instantiate_solvables(init_solv_list, &solvable_list) &&
04902 icl_ConvertSolvables(TRUE, init_new_solv_list, &new_solvable_list) &&
04903 icl_standardize_params(initial_params, FALSE, ¶ms) &&
04904 icl_IsList(solvable_list)) {
04905 solvable = icl_NthTerm(solvable_list, 1);
04906 if(icl_IsList(new_solvable_list)) {
04907 new_solvable = icl_NthTerm(new_solvable_list, 1);
04908 with_new_solvable = icl_NewStruct("with", 1, new_solvable);
04909 icl_AddToList(params, with_new_solvable, FALSE);
04910 if(oaa_declare_aux("replace", solvable,
04911 params, &redeclared_solvables) &&
04912 icl_IsList(redeclared_solvables) &&
04913 redeclared_solvables->p) {
04914 res = TRUE;
04915 }
04916
04917 }
04918 }
04919 icl_Free(init_solv_list);
04920 icl_Free(init_new_solv_list);
04921 return res;
04922 }
04923
04931 int select_elements(ICLTerm *list, int (*test_function)(ICLTerm*), ICLTerm** result){
04932
04933 if (list && icl_IsList(list)) {
04934 ICLListType *local_list = NULL, *newArgs = NULL, *endp = NULL;
04935
04936 local_list = icl_List(list);
04937 while (local_list) {
04938
04939 if (test_function(local_list->elt)) {
04940
04941 if (!newArgs) {
04942 newArgs = icl_NewCons(icl_CopyTerm(local_list->elt), NULL);
04943 endp = newArgs;
04944 }
04945 else {
04946 endp->next = icl_NewCons(icl_CopyTerm(local_list->elt), NULL);
04947 endp = endp->next;
04948 }
04949 }
04950
04951 local_list = local_list->next;
04952 }
04953 *result = icl_NewList(newArgs);
04954
04955 return TRUE;
04956 }
04957
04958 return FALSE;
04959 }
04960
04961
04962
04963
04964
04965
04966
04967
04968
04969
04970
04971
04972
04973
04974
04975
04976
04977
04978
04979 int oaa_declare_aux(char *mode, ICLTerm *solvables, ICLTerm *params,
04980 ICLTerm **declared_solvables)
04981 {
04982
04983 ICLTerm *fac_id_query = icl_NewTermFromData("fac_id(ParentId)",16);
04984 ICLTerm *result = (ICLTerm *)NULL;
04985 ICLTerm *dec_solv_var = icl_NewVar("DeclaredSolvables");
04986 int res = FALSE;
04987
04988
04989
04990
04991
04992 if (com_GetInfo("parent", fac_id_query, &result)) {
04993
04994 ICLTerm *parentidlist =
04995 icl_NewList(icl_NewCons(icl_CopyTerm(icl_NthTerm(result, 1)),
04996 (ICLListType *)NULL));
04997 ICLTerm *address_query = icl_NewStruct("address", 1, parentidlist);
04998
04999 icl_Free(result);
05000 if (icl_GetParamValue(address_query, params, &result)) {
05001 ICLTerm *emptyList = icl_NewList(NULL);
05002
05003 ICLTerm *post = icl_NewStruct("ev_post_declare", 3,
05004 icl_NewStr(mode),
05005 icl_CopyTerm(solvables),
05006 icl_CopyTerm(params));
05007 ICLTerm *ev_reply_declared = icl_NewStruct("ev_reply_declared", 4,
05008 icl_NewStr(mode),
05009 icl_CopyTerm(solvables),
05010 icl_CopyTerm(params),
05011 icl_CopyTerm(dec_solv_var));
05012
05013 if (oaa_PostEvent(post, emptyList) &&
05014 oaa_poll_until_event(ev_reply_declared, NULL)) {
05015 res = TRUE;
05016 }
05017 icl_Free(emptyList);
05018 icl_Free(post);
05019 icl_Free(ev_reply_declared);
05020 icl_Free(result);
05021 }
05022 icl_Free(address_query);
05023 }
05024
05025 if (!res) {
05026
05027
05028
05029 ICLTerm *me;
05030 ICLTerm *addr_query = icl_NewStruct("address", 1, icl_NewVar("Addr"));
05031 int res1, res2, res3;
05032
05033 oaa_PrimaryAddress(&me);
05034
05035 res1 = icl_GetParamValue(addr_query, params, &result);
05036 res2 = icl_Unify(me, icl_NthTerm(result, 1), NULL);
05037 res3 = oaa_declare_local(mode, solvables, params, declared_solvables);
05038 if ((!res1 || res2) && res3) {
05039
05040
05041
05042
05043
05044 if (((!oaa_class("leaf")) && (*declared_solvables)->p)) {
05045 #if 0
05046
05047 ICLTerm *my_name;
05048 ICLTerm *event, *param_list;
05049 oaa_Name(&my_name);
05050 event =
05051 icl_NewStruct("ev_register_solvables", 1, icl_NewStr(mode),
05052 dec_solv_var, my_name, params);
05053 param_list = icl_NewList(icl_NewCons(icl_NewStruct("from", 1, me),
05054 NULL));
05055
05056
05057 #endif
05058 } else {
05059
05060
05061
05062 ICLTerm *public_solvables;
05063 CHECK_LEAKS();
05064 select_elements(*declared_solvables, oaa_is_public_solvable,
05065 &public_solvables);
05066 CHECK_LEAKS();
05067 if (oaa_class("leaf") && public_solvables->p) {
05068 ICLTerm *tempRequest = icl_NewTermFromData("oaa_name(MyName)",16);
05069 if(res1) {
05070 icl_Free(result);
05071 }
05072 CHECK_LEAKS();
05073 com_GetInfo("parent", tempRequest, &result);
05074 CHECK_LEAKS();
05075
05076 if(result && icl_IsStruct(result)) {
05077 ICLTerm *my_name_c = icl_CopyTerm(icl_NthTerm(result, 1));
05078 ICLTerm *event =
05079 icl_NewStruct("ev_register_solvables", 4, icl_NewStr(mode),
05080 public_solvables, my_name_c, icl_CopyTerm(params));
05081 ICLTerm *postParams = icl_NewList(NULL);
05082 CHECK_LEAKS();
05083 oaa_PostEvent(event, postParams);
05084 CHECK_LEAKS();
05085 icl_Free(postParams);
05086 icl_Free(result);
05087 icl_Free(event);
05088 }
05089 else {
05090 icl_Free(public_solvables);
05091 }
05092 icl_Free(tempRequest);
05093 }
05094 else {
05095 icl_Free(public_solvables);
05096 }
05097 }
05098 res = TRUE;
05099 }
05100 icl_Free(me);
05101 icl_Free(addr_query);
05102 }
05103 icl_Free(fac_id_query);
05104 icl_Free(dec_solv_var);
05105 return res;
05106 }
05107
05108
05109
05110
05111
05112 int oaa_public_solvable(ICLTerm *solvable)
05113 {
05114 ICLTerm *tmpres, *params;
05115 ICLTerm *param = icl_NewTermFromData("private(false)",14);
05116
05117 if (icl_IsStruct(solvable) &&
05118 (icl_NumTerms(solvable) == 3) &&
05119 (params = icl_NthTerm(solvable, 2)) &&
05120 icl_GetParamValue(param, params, &tmpres)) {
05121
05122 icl_Free(param);
05123 return TRUE;
05124 }
05125
05126 icl_Free(param);
05127 return FALSE;
05128 }
05129
05130
05131
05132
05133 int oaa_data_solvable(ICLTerm *solvable)
05134 {
05135 ICLTerm *tmpres, *params;
05136 ICLTerm *param = icl_NewTermFromData("type(data)",10);
05137
05138 if (icl_IsStruct(solvable) &&
05139 (icl_NumTerms(solvable) == 3) &&
05140 (params = icl_NthTerm(solvable, 2)) &&
05141 icl_GetParamValue(param, params, &tmpres)) {
05142
05143 icl_Free(param);
05144 return TRUE;
05145 }
05146
05147 icl_Free(param);
05148 return FALSE;
05149 }
05150
05151
05152
05153
05154
05155
05156
05157
05158
05159
05160
05161
05162
05163
05164
05165
05166
05167
05168
05169
05170 int oaa_declare_local(char *mode, ICLTerm *solvable0, ICLTerm *params,
05171 ICLTerm **returned_solvables) {
05172 ICLTerm *current_solvables;
05173 ICLTerm *db_solvables, *solvables;
05174 ICLTerm *all_solvables = NULL;
05175 int res = FALSE;
05176
05177 if (!icl_IsList(solvable0)) {
05178 solvables = icl_NewList(icl_NewCons(solvable0, NULL));
05179 }
05180 else {
05181 solvables = solvable0;
05182 }
05183
05184 if (STREQ(mode, "add")) {
05185
05186 ICLTerm *initial_solvables = solvables;
05187 ICLTerm *declared_solvables = NULL;
05188 ICLTerm *ifexistsfalse = icl_NewTermFromString("if_exists(overwrite)");
05189
05190 if (icl_GetParamValue(ifexistsfalse, params, NULL)) {
05191 current_solvables = icl_NewList(NULL);
05192 }
05193 else {
05194 current_solvables = valid_oaa_solvables();
05195 }
05196 icl_Free(ifexistsfalse);
05197
05198
05199
05200
05201
05202
05203 solvables_to_be_added(initial_solvables, current_solvables, &declared_solvables);
05204
05205
05206
05207
05208 select_elements(declared_solvables, oaa_is_data_solvable, &db_solvables);
05209
05210
05211
05212
05213 icl_append_to_list(current_solvables, declared_solvables, &all_solvables);
05214 if(oaa_solvables != NULL) {
05215 icl_Free(oaa_solvables);
05216 }
05217 oaa_solvables = all_solvables;
05218 if(oaa_solvables == NULL) {
05219 oaa_solvables = icl_NewList(NULL);
05220 }
05221 if (returned_solvables != NULL) {
05222 *returned_solvables = declared_solvables;
05223 }
05224 else {
05225 icl_Free(declared_solvables);
05226 }
05227
05228 icl_Free(current_solvables);
05229 icl_Free(db_solvables);
05230 res = TRUE;
05231 }
05232 else if (STREQ(mode, "remove")) {
05233 ICLTerm *removed_solvables, *new;
05234 ICLTerm *current = valid_oaa_solvables();
05235
05236
05237
05238
05239 solvables_to_be_removed(solvables, current, &removed_solvables);
05240
05241
05242
05243 select_elements(removed_solvables, oaa_is_data_solvable, &db_solvables);
05244 oaa_remove_solvables_data(db_solvables);
05245
05246
05247
05248 icl_subtract(current, removed_solvables, &new);
05249 if(oaa_solvables != NULL) {
05250 icl_Free(oaa_solvables);
05251 }
05252 oaa_solvables = new;
05253 if(oaa_solvables == NULL) {
05254 oaa_solvables = icl_NewList(NULL);
05255 }
05256 *returned_solvables = removed_solvables;
05257 icl_Free(db_solvables);
05258 res = TRUE;
05259 }
05260 else if (STREQ(mode, "replace") &&
05261 (icl_NumTerms(solvables) == 1)) {
05262
05263 ICLTerm *new_solvable, *result, *current, *new;
05264 ICLTerm *solvable = icl_NthTerm(solvables, 1);
05265 ICLTerm *t1;
05266
05267 if (icl_Member((t1 = icl_NewTermFromString("with(NewSolvable)")),
05268 icl_CopyTerm(params), &result)) {
05269 new_solvable = icl_CopyTerm(icl_NthTerm(result, 1));
05270 icl_Free(result);
05271
05272
05273
05274 current = valid_oaa_solvables();
05275 if (icl_Member(solvable, current, NULL)) {
05276
05277
05278
05279 if (oaa_data_solvable(solvable))
05280 oaa_remove_solvables_data(solvables);
05281
05282
05283
05284 replace_element(solvable, current, new_solvable, &new);
05285 if(oaa_solvables != NULL) {
05286 icl_Free(oaa_solvables);
05287 }
05288 oaa_solvables = new;
05289 if(oaa_solvables == NULL) {
05290 oaa_solvables = icl_NewList(NULL);
05291 }
05292 *returned_solvables = solvables;
05293 res = TRUE;
05294 }
05295 }
05296 icl_Free(t1);
05297
05298 if (!res) {
05299 ICLTerm *goal;
05300 if (icl_IsStruct(solvable) &&
05301 STREQ(icl_Functor(solvable), "solvable") &&
05302 (goal = icl_NthTerm(solvable, 1))) {
05303 printf("WARNING: Ignoring attempt to replace a non-existent solvable:\n %s\n",
05304 icl_NewStringFromTerm(goal));
05305 }
05306 *returned_solvables = icl_NewList(NULL);
05307 res = TRUE;
05308 }
05309 }
05310 return res;
05311 }
05312
05317 int icl_subtract(ICLTerm *list1, ICLTerm *list2, ICLTerm **result) {
05318 *result = icl_NewList(NULL);
05319 if(icl_IsList(list1) && icl_IsList(list2)) {
05320 ICLListType *iterator = icl_List(list1);
05321 while(icl_ListHasMoreElements(iterator)) {
05322 ICLTerm *el = icl_ListElement(iterator);
05323 if(!icl_Member(el, list2, NULL)) {
05324 icl_AddToList(*result, el, TRUE);
05325 }
05326 iterator = icl_ListNextElement(iterator);
05327 }
05328 return TRUE;
05329 }
05330 return FALSE;
05331 }
05332
05338
05339
05340
05341
05342
05343 int oaa_distribute_params(ICLTerm *solvables, ICLTerm *common_params,
05344 ICLTerm **new_solvables) {
05345 *new_solvables = icl_NewList(NULL);
05346 if(icl_IsList(solvables)) {
05347 ICLListType *solvable_list = icl_List(solvables);
05348 while(icl_ListHasMoreElements(solvable_list)) {
05349 ICLTerm *solvable = icl_ListElement(solvable_list);
05350
05351 if(icl_IsStruct(solvable) &&
05352 STREQ(icl_Functor(solvable), "solvable") &&
05353 (icl_NumTerms(solvable) == 3)) {
05354
05355 ICLTerm *goal = icl_NthTerm(solvable, 1);
05356 ICLTerm *params = icl_NthTerm(solvable, 2);
05357 ICLTerm *perms = icl_NthTerm(solvable, 3);
05358 ICLTerm *new_params, *new_solvable;
05359 icl_Union(params, common_params, &new_params);
05360
05361 new_solvable = icl_NewStruct("solvable", 3, icl_CopyTerm(goal),
05362 new_params, icl_CopyTerm(perms));
05363 icl_AddToList(*new_solvables, new_solvable, TRUE);
05364 }
05365 solvable_list = icl_ListNextElement(solvable_list);
05366 }
05367 return TRUE;
05368 }
05369 return FALSE;
05370 }
05371
05372 int oaa_distribute_perms(ICLTerm *solvables, ICLTerm *common_perms,
05373 ICLTerm **new_solvables) {
05374
05375 *new_solvables = icl_NewList(NULL);
05376 if(icl_IsList(solvables)) {
05377 ICLListType *solvable_list = icl_List(solvables);
05378 while(icl_ListHasMoreElements(solvable_list)) {
05379 ICLTerm *solvable = icl_ListElement(solvable_list);
05380
05381 if(icl_IsStruct(solvable) &&
05382 STREQ(icl_Functor(solvable), "solvable") &&
05383 (icl_NumTerms(solvable) == 3)) {
05384 ICLTerm *goal = icl_NthTerm(solvable, 1);
05385 ICLTerm *params = icl_NthTerm(solvable, 2);
05386 ICLTerm *perms = icl_NthTerm(solvable, 3);
05387 ICLTerm *new_perms, *new_solvable;
05388 icl_Union(perms, common_perms, &new_perms);
05389
05390 new_solvable = icl_NewStruct("solvable", 3, icl_CopyTerm(goal),
05391 icl_CopyTerm(params), new_perms);
05392 icl_AddToList(*new_solvables, new_solvable, TRUE);
05393 }
05394 solvable_list = icl_ListNextElement(solvable_list);
05395 }
05396 return TRUE;
05397 }
05398 return FALSE;
05399 }
05400
05401
05406
05407
05408
05409
05410
05411 int solvables_to_be_added(ICLTerm *solvables, ICLTerm *current,
05412 ICLTerm **ok_solvables) {
05413 *ok_solvables = icl_NewList(NULL);
05414 if(icl_IsList(solvables)) {
05415 ICLListType *solvable_list = icl_List(solvables);
05416 while(icl_ListHasMoreElements(solvable_list)) {
05417 ICLTerm *solvable = icl_ListElement(solvable_list);
05418 if(icl_IsStruct(solvable) &&
05419 STREQ(icl_Functor(solvable), "solvable") &&
05420 (icl_NumTerms(solvable) == 3)) {
05421 ICLTerm *goal = icl_NthTerm(solvable, 1);
05422 if(icl_Member(goal, current, NULL)) {
05423
05424 char *debugString = icl_NewStringFromTerm(goal);
05425 printf("WARNING: Ignoring attempt to declare an already"
05426 " existing solvable:\n %s", debugString);
05427 icl_stFree(debugString);
05428 continue;
05429 }
05430 icl_AddToList(*ok_solvables, icl_CopyTerm(solvable), TRUE);
05431 }
05432 solvable_list = icl_ListNextElement(solvable_list);
05433 }
05434 }
05435 return TRUE;
05436 }
05437
05442
05443
05444
05445
05446
05447
05448 int solvables_to_be_removed(ICLTerm *solvables, ICLTerm *current,
05449 ICLTerm **ok_solvables) {
05450 *ok_solvables = icl_NewList(NULL);
05451 if(icl_IsList(solvables)) {
05452 ICLListType *solvable_list = icl_List(solvables);
05453 while(icl_ListHasMoreElements(solvable_list)) {
05454 ICLTerm *solvable = icl_ListElement(solvable_list);
05455 if(icl_IsStruct(solvable) &&
05456 STREQ(icl_Functor(solvable), "solvable") &&
05457 (icl_NumTerms(solvable) == 3)) {
05458 ICLTerm *goal = icl_NthTerm(solvable, 1);
05459 if(!icl_Member(goal, current, NULL)) {
05460 printf("WARNING: Ignoring attempt to remove a "
05461 "non-existent solvable:\n %s",
05462 icl_NewStringFromTerm(goal));
05463 continue;
05464 }
05465 icl_AddToList(*ok_solvables, solvable, TRUE);
05466 }
05467 solvable_list = icl_ListNextElement(solvable_list);
05468 }
05469 }
05470 return TRUE;
05471 }
05472
05473
05474
05475
05476
05477
05478
05517 int oaa_AddData(ICLTerm *clause, ICLTerm *in_params, ICLTerm **out_params) {
05518 return oaa_update("add", clause, in_params, out_params);
05519 }
05520
05521
05522
05523
05524
05525
05526
05527
05528
05529
05530
05531
05532
05533
05534
05535
05536
05537
05538
05539
05540
05541
05542
05543
05544
05545
05546
05547
05548
05549
05550
05551
05552
05553
05554
05555 int oaa_RemoveData(ICLTerm *clause, ICLTerm *in_params, ICLTerm **out_params) {
05556 return oaa_update("remove", clause, in_params, out_params);
05557 }
05558
05602 int oaa_ReplaceData(ICLTerm *clause1, ICLTerm *clause2,
05603 ICLTerm *in_params, ICLTerm **out_params) {
05604 ICLTerm *new_param_list = icl_NewList(icl_List(in_params));
05605 icl_AddToList(new_param_list, icl_NewStruct("with", 1, clause2), FALSE);
05606 return oaa_update("replace", clause1, new_param_list, out_params);
05607 }
05608
05614 int icl_replace_param_value(ICLTerm *param, ICLTerm *param_list) {
05615 int res = FALSE;
05616 if (icl_IsStruct(param) &&
05617 (icl_NumTerms(param) == 1) &&
05618 icl_IsList(param_list)) {
05619 ICLListType *plist = icl_List(param_list);
05620 while(icl_ListHasMoreElements(plist)) {
05621 ICLTerm *p = icl_ListElement(plist);
05622 ICLTerm *result;
05623 if(icl_Unify(param, p, &result)) {
05624 plist->elt = result;
05625 icl_Free(p);
05626 res = TRUE;
05627 break;
05628 }
05629 plist = icl_ListNextElement(plist);
05630 }
05631 }
05632 return res;
05633 }
05634
05643 int oaa_update(char *mode, ICLTerm *clause, ICLTerm *initial_params,
05644 ICLTerm **out_params)
05645 {
05646 ICLTerm *params = NULL, *addr = NULL, *me = NULL;
05647 ICLTerm *new_addr = NULL, *params1 = NULL, *params2 = NULL, *solvables = NULL;
05648 ICLTerm *updaters1 = NULL, *updaters2 = NULL, *updaters = NULL;
05649 ICLTerm *requestees1 = NULL, *requestees2 = NULL, *requestees = NULL;
05650 ICLTerm *t1 = NULL;
05651 int self = FALSE, res = FALSE;
05652 ICLTerm *reflexive_true = icl_NewTermFromString("reflexive(true)");
05653
05654 icl_standardize_params(initial_params, FALSE, ¶ms);
05655
05656
05657 if (!icl_param_arg("address", NULL, params, &addr)) {
05658 addr = icl_NewList(NULL);
05659 }
05660
05661
05662 if (oaa_PrimaryAddress(&me) &&
05663 icl_Member(me, addr, NULL)) {
05664
05665 icl_ListDelete(addr, me, &new_addr);
05666 t1 = icl_NewStruct("address", 1, icl_CopyTerm(addr));
05667 replace_element(t1, params,
05668 icl_NewStruct("address", 1, new_addr), ¶ms1);
05669 icl_Free(t1);
05670 self = TRUE;
05671 } else {
05672 new_addr = icl_CopyTerm(addr);
05673 params1 = icl_CopyTerm(params);
05674 }
05675
05676 if ((!addr->p) &&
05677 icl_GetParamValue(reflexive_true, params1, NULL)) {
05678 ICLTerm *write = icl_NewTermFromString("write");
05679 ICLTerm *real_clause, *real_matched;
05680
05681 icl_ListDelete(params1, reflexive_true, ¶ms2);
05682 solvables = valid_oaa_solvables();
05683 if (oaa_data_matches_solvables(clause, solvables, write, &real_clause,
05684 &real_matched))
05685 self = TRUE;
05686 icl_Free(write);
05687 } else {
05688 params2 = params1;
05689 }
05690 icl_Free(reflexive_true);
05691
05692
05693 if (self) {
05694 requestees1 = icl_NewList(icl_NewCons(icl_CopyTerm(me), NULL));
05695 if (STREQ(mode, "add")) {
05696 res = oaa_add_data_local(clause, params2);
05697 }
05698 else if (STREQ(mode, "replace")) {
05699 res = oaa_replace_data_local(clause, params2);
05700 }
05701 else if (STREQ(mode, "remove")) {
05702 res = oaa_remove_data_local(clause, params2);
05703 }
05704 if(res) {
05705 updaters1 = icl_NewList(icl_NewCons(icl_CopyTerm(me), NULL));
05706 } else {
05707 updaters1 = icl_NewList(NULL);
05708 }
05709 } else {
05710 requestees1 = icl_NewList(NULL);
05711 updaters1 = icl_NewList(NULL);
05712 }
05713 icl_Free(me);
05714
05715
05716
05717 if (oaa_class("leaf") &&
05718 ((!addr->p) || (new_addr->p))) {
05719
05720 ICLTerm *reply;
05721 char *goalIdStr = new_goal_id();
05722
05723
05724
05725 ICLTerm* toBeSent = icl_NewStruct("ev_update_data", 4,
05726 icl_NewStr(goalIdStr),
05727 icl_NewStr(mode), icl_CopyTerm(clause),
05728 icl_CopyTerm(params2));
05729 oaa_PostEvent(toBeSent, ICL_EMPTY);
05730 icl_Free(toBeSent);
05731 icl_stFree(goalIdStr);
05732
05733
05734
05735 if ( !(icl_param_arg("reply", NULL, params, &reply) &&
05736 (STREQ("asynchronous", icl_Str(reply)) ||
05737 STREQ("none", icl_Str(reply)))) ) {
05738 ICLTerm *ev_reply_updated =
05739 icl_NewStruct("ev_data_updated", 6, icl_NewVar("G"), icl_NewStr(mode),
05740 icl_CopyTerm(clause), icl_CopyTerm(params2),
05741 icl_NewVar("Requestees"), icl_NewVar("Updaters"));
05742 oaa_poll_until_event(ev_reply_updated, NULL);
05743 icl_Free(ev_reply_updated);
05744 }
05745 }
05746 icl_Free(addr);
05747 icl_Free(new_addr);
05748
05749 requestees2 = icl_NewList(NULL);
05750 updaters2 = icl_NewList(NULL);
05751
05752
05753
05754
05755
05756 icl_append_to_list(updaters1, updaters2, &updaters);
05757 icl_Free(updaters1);
05758 icl_Free(updaters2);
05759
05760
05761
05762 t1 = icl_NewStruct("get_satisfiers", 1, updaters);
05763 icl_replace_param_value(t1, params);
05764 icl_Free(t1);
05765
05766
05767
05768 icl_append_to_list(requestees1, requestees2, &requestees);
05769 t1 = icl_NewStruct("get_address", 1, requestees);
05770 icl_replace_param_value(t1, params);
05771 icl_Free(requestees1);
05772 icl_Free(requestees2);
05773 icl_Free(t1);
05774 if(params2 == params1) {
05775 icl_Free(params2);
05776 }
05777 else {
05778 icl_Free(params2);
05779 icl_Free(params1);
05780 }
05781
05782 if (out_params != NULL) {
05783 *out_params = params;
05784 }
05785 else {
05786 icl_Free(params);
05787 }
05788
05789 return TRUE;
05790 }
05791
05792
05793
05794
05795
05796
05797
05798
05799
05800 int asserta(ICLTerm *clause)
05801 {
05802 int res;
05803 ICLTerm *t1;
05804
05805 if(!db_IsValid(local_db))
05806 local_db = db_NewDB();
05807 res =
05808 db_Assert(local_db, clause,
05809 (t1 = icl_NewTermFromString("[at_beginning(true)]")));
05810 icl_Free(t1);
05811 return res;
05812 }
05813
05814 int assertz(ICLTerm *clause)
05815 {
05816 int res;
05817 ICLTerm *t1;
05818
05819 if(!db_IsValid(local_db))
05820 local_db = db_NewDB();
05821 res =
05822 db_Assert(local_db, clause,
05823 (t1 = icl_NewTermFromString("[at_beginning(false)]")));
05824 icl_Free(t1);
05825 return res;
05826 }
05827
05828 int retract(ICLTerm *clause) {
05829 if(!db_IsValid(local_db))
05830 local_db = db_NewDB();
05831 return db_Retract(local_db, clause, ICL_EMPTY);
05832 }
05833
05834
05835
05836
05837
05838
05839 static int db_ref_number = 0;
05840
05841
05842
05843
05844 static DICTIONARY *oaa_db_ref = (DICTIONARY *)NULL;
05845
05846
05847 int asserta_ref(ICLTerm *clause, ICLTerm **ref) {
05848 *ref = icl_NewInt(db_ref_number++);
05849 if(!oaa_db_ref)
05850 oaa_db_ref = dict_new(oaa_compare_terms, (void *)icl_FreeTermSingle);
05851 dict_put(oaa_db_ref, (void *)icl_CopyTerm(clause), (void *)*ref);
05852 return asserta(clause);
05853 }
05854
05855 int assertz_ref(ICLTerm *clause, ICLTerm **ref) {
05856 *ref = icl_NewInt(db_ref_number++);
05857 if(!oaa_db_ref)
05858 oaa_db_ref = dict_new(oaa_compare_terms, (void *)icl_FreeTermSingle);
05859 dict_put(oaa_db_ref, (void *)icl_CopyTerm(clause), (void *)*ref);
05860 return assertz(clause);
05861 }
05862
05863 int ref_for_clause(ICLTerm *clause, ICLTerm **ref) {
05864 int result = FALSE;
05865 if(oaa_db_ref) {
05866 *ref = (ICLTerm *)dict_get(oaa_db_ref, (void *)clause);
05867 if (*ref)
05868 result = TRUE;
05869 }
05870 return result;
05871 }
05872
05873 int erase_ref(ICLTerm *clause, ICLTerm *ref) {
05874 if(oaa_db_ref) {
05875 ICLTerm *val = (ICLTerm *)dict_get(oaa_db_ref, clause);
05876 while(val != NULL) {
05877 if(icl_Unify(val, ref, NULL)) {
05878 dict_remove_specific(oaa_db_ref, clause, ref);
05879 return TRUE;
05880 }
05881 val = (ICLTerm *)dict_get(oaa_db_ref, clause);
05882 }
05883 }
05884 return TRUE;
05885 }
05886
05887
05896 int oaa_add_data_local(ICLTerm *clause1, ICLTerm *params)
05897 {
05898 ICLTerm *clause = NULL, *matched = NULL;
05899 ICLTerm *head = NULL, *body = NULL;
05900 ICLTerm *pred = NULL, *decl_params = NULL, *all_params = NULL;
05901 ICLTerm *callback = NULL, *result = NULL;
05902 ICLTerm *t1 = NULL, *t2 = NULL;
05903 ICLTerm *dummyvar = NULL, *single_value_true = NULL;
05904 ICLTerm *solvables = valid_oaa_solvables();
05905 ICLTerm *permRequest = icl_NewStr("write");
05906
05907 oaa_data_matches_solvables(clause1, solvables,
05908 permRequest,
05909 &clause, &matched);
05910 icl_Free(permRequest);
05911
05912 if (icl_IsStruct(matched) &&
05913 (icl_NumTerms(matched) == 3) &&
05914 STREQ(icl_Functor(matched), "solvable")) {
05915
05916 pred = icl_NthTerm(matched, 1);
05917 decl_params = icl_NthTerm(matched, 2);
05918 } else {
05919 return FALSE;
05920 }
05921 if (icl_IsStruct(clause) &&
05922 STREQ(icl_Functor(clause), ":-") &&
05923 (icl_NumTerms(clause) == 2)) {
05924
05925 head = icl_NthTerm(clause, 1);
05926 body = icl_NthTerm(clause, 2);
05927 } else {
05928 head = clause;
05929 body = ICL_TRUE;
05930 }
05931 icl_append_to_list(params, decl_params, &all_params);
05932
05933
05934
05935 dummyvar = icl_NewVar("dummy");
05936 t1 = icl_NewStruct("callback", 1, icl_CopyTerm(dummyvar));
05937
05938 if (! icl_GetParamValue(t1, all_params, &callback)) {
05939
05940 callback = icl_NewVar("Callback");
05941 }
05942 icl_Free(t1);
05943
05944
05945 single_value_true = icl_NewTermFromString("single_value(true)");
05946 if (icl_GetParamValue(single_value_true, all_params, &result)) {
05947 if (!icl_ParamValue("bookkeeping", ICL_FALSE, decl_params, NULL)) {
05948 oaa_retractall(pred, dummyvar, callback);
05949 }
05950 else {
05951 retract_all(pred);
05952 }
05953 }
05954
05955 icl_Free(dummyvar);
05956 icl_Free(single_value_true);
05957
05958
05959 t1 = icl_NewTermFromString("unique_values(true)");
05960 if (db_Solve(local_db, pred, ICL_EMPTY, NULL) &&
05961 icl_GetParamValue(t1, all_params, NULL)) {
05962 icl_Free(all_params);
05963 icl_Free(t1);
05964 return TRUE;
05965 }
05966 icl_Free(t1);
05967
05968 t1 = icl_NewTermFromString("bookkeeping(true)");
05969 if (icl_GetParamValue(t1, decl_params, NULL)) {
05970 ICLTerm *owner;
05971
05972 icl_Free(t1);
05973 oaa_data_owner(params, &owner);
05974 if(icl_GetParamValue((t1 = icl_NewTermFromString("at_beginning(true)")),
05975 all_params, NULL)) {
05976 oaa_asserta(clause, owner, callback);
05977 }
05978 else {
05979 oaa_assertz(clause, owner, callback);
05980 }
05981 icl_Free(t1);
05982 } else {
05983 if (icl_GetParamValue((t2 = icl_NewTermFromString("at_beginning(true)")),
05984 all_params, NULL)) {
05985 asserta(clause);
05986 }
05987 else {
05988 assertz(clause);
05989 }
05990 }
05991 icl_Free(t1);
05992 icl_Free(t2);
05993 icl_Free(all_params);
05994 oaa_CheckTriggers("data", head, "add");
05995 return TRUE;
05996 }
05997
06004 int oaa_remove_data_local(ICLTerm *clause1, ICLTerm *params)
06005 {
06006 ICLTerm *matched = NULL;
06007 ICLTerm *clause, *decl_params;
06008 ICLTerm *head, *body, *all_params, *callback;
06009 ICLTerm *local_solvables = valid_oaa_solvables();
06010 ICLTerm *permRequest = icl_NewStr("write");
06011 ICLTerm *t1 = (ICLTerm *)NULL, *t2 = (ICLTerm *)NULL;
06012
06013 oaa_data_matches_solvables(clause1, local_solvables,
06014 permRequest,
06015 &clause, &matched);
06016 icl_Free(permRequest);
06017 if(matched && icl_IsStruct(matched) &&
06018 (icl_NumTerms(matched) == 3) &&
06019 STREQ(icl_Functor(matched), "solvable")) {
06020 decl_params = icl_NthTerm(matched, 2);
06021 } else {
06022 return FALSE;
06023 }
06024 if(icl_IsStruct(clause) &&
06025 STREQ(icl_Functor(clause), ":-") &&
06026 (icl_NumTerms(clause) == 2)) {
06027 head = icl_NthTerm(clause, 1);
06028 body = icl_NthTerm(clause, 2);
06029 } else {
06030 head = clause;
06031 body = ICL_TRUE;
06032 }
06033 icl_append_to_list(params, decl_params, &all_params);
06034 if(!icl_param_arg("callback", NULL, all_params, &callback)) {
06035
06036 callback = icl_NewVar("Callback");
06037 }
06038
06039 t1 = icl_NewTermFromString("bookkeeping(true)");
06040 if (icl_GetParamValue(t1, decl_params, NULL)) {
06041 ICLTerm *owner;
06042
06043 if (!icl_param_arg("owner", NULL, params, &owner)) {
06044 owner = icl_NewVar("Owner");
06045 }
06046 if (icl_ParamValue("do_all", ICL_TRUE, all_params, NULL)) {
06047 oaa_retractall(clause, owner, callback);
06048 }
06049 else {
06050 oaa_retract(clause, owner, callback);
06051 }
06052 }
06053 else {
06054 t2 = icl_NewTermFromString("do_all(true)");
06055 if (icl_GetParamValue(t2, all_params, NULL)) {
06056 retract_all(clause);
06057 }
06058 else {
06059 retract(clause);
06060 }
06061 }
06062 icl_Free(t1);
06063 icl_Free(t2);
06064 icl_Free(all_params);
06065 oaa_CheckTriggers("data", head, "remove");
06066 return TRUE;
06067 }
06068
06077 int oaa_replace_data_local(ICLTerm *clause1_in, ICLTerm *params) {
06078 ICLTerm *clause2_in, *result = (ICLTerm *)NULL, *clause1, *clause2;
06079 ICLTerm *decl_params = NULL;
06080 ICLTerm *all_params;
06081 ICLTerm *head, *body, *matched;
06082 ICLTerm *solvables = valid_oaa_solvables();
06083 ICLTerm *dummyvar = icl_NewVar("dummy");
06084 ICLTerm *callback = NULL;
06085 ICLTerm *owner = NULL;
06086 ICLTerm *t1;
06087
06088 if (icl_Member((t1 = icl_NewStruct("with", 1, dummyvar)), params,
06089 &result)) {
06090 clause2_in = icl_CopyTerm(icl_NthTerm(result, 1));
06091 icl_Free(result);
06092 }
06093 else {
06094 icl_Free(t1);
06095 return FALSE;
06096 }
06097 icl_Free(t1);
06098
06099 print_dictionary(oaa_db_ref);
06100
06101 oaa_data_matches_solvables(clause1_in, solvables,
06102 (t1 = icl_NewStr("write")),
06103 &clause1, &matched);
06104 icl_Free(t1);
06105
06106 oaa_data_matches_solvables(clause2_in, solvables,
06107 (t1 = icl_NewStr("write")),
06108 &clause2, &result);
06109 icl_Free(t1);
06110
06111 if(icl_IsStruct(matched) &&
06112 (icl_NumTerms(matched) == 3) &&
06113 STREQ(icl_Functor(matched), "solvable")) {
06114 decl_params = icl_CopyTerm(icl_NthTerm(matched, 2));
06115 } else {
06116 return FALSE;
06117 }
06118 if(icl_IsStruct(clause1) &&
06119 STREQ(icl_Functor(clause1), ":-") &&
06120 (icl_NumTerms(clause1) == 2)) {
06121 head = icl_NthTerm(clause1, 1);
06122 body = icl_NthTerm(clause1, 2);
06123 } else {
06124 head = clause1;
06125 body = ICL_TRUE;
06126 }
06127
06128 icl_append_to_list(params, decl_params, &all_params);
06129 icl_param_arg("callback", dummyvar, all_params, &callback);
06130
06131
06132 if (callback==NULL) {
06133 callback = icl_NewVar("Callback");
06134 }
06135
06136 if(!icl_ParamValue("bookkeeping",ICL_FALSE, decl_params, NULL)) {
06137 oaa_data_owner(params, &owner);
06138 if(icl_ParamValue("do_all", ICL_TRUE, params, NULL)) {
06139 oaa_replace_all(clause1, clause2, owner, callback);
06140 }
06141 else {
06142 if (oaa_retract(clause1, owner, callback)) {
06143 if(icl_ParamValue("at_beginning", ICL_TRUE, all_params, NULL)) {
06144 oaa_asserta(clause2, owner, callback);
06145 }
06146 else {
06147 oaa_assertz(clause2, owner, callback);
06148 }
06149 }
06150 }
06151 } else {
06152 if(icl_ParamValue("do_all", ICL_TRUE, params, NULL)) {
06153 replace_all(clause1, clause2);
06154 }
06155 else {
06156 if (retract(clause1)) {
06157 if(icl_ParamValue("at_beginning", ICL_TRUE, all_params, NULL)) {
06158 asserta(clause2);
06159 }
06160 else {
06161 assertz(clause2);
06162 }
06163 }
06164 }
06165 }
06166 oaa_CheckTriggers("data", clause1, "remove");
06167 oaa_CheckTriggers("data", clause2, "add");
06168
06169 icl_Free(head);
06170 icl_Free(body);
06171 icl_Free(clause1);
06172 icl_Free(result);
06173 icl_Free(decl_params);
06174 icl_Free(all_params);
06175 icl_Free(owner);
06176 return TRUE;
06177 }
06178
06184 int retract_all(ICLTerm *clause)
06185 {
06186 ICLTerm *t1;
06187
06188 if(!db_IsValid(local_db))
06189 local_db = db_NewDB();
06190 db_Retract(local_db, clause,
06191 (t1 = icl_NewTermFromString("[do_all(true)]")));
06192 icl_Free(t1);
06193 return TRUE;
06194 }
06195
06200 int replace_all(ICLTerm *clause1, ICLTerm *clause2)
06201 {
06202 ICLTerm *t1;
06203
06204 if(!db_IsValid(local_db))
06205 local_db = db_NewDB();
06206 db_Retract(local_db, clause1,
06207 (t1 = icl_NewTermFromString("[do_all(true)]")));
06208 db_Assert(local_db, clause2, ICL_EMPTY);
06209 icl_Free(t1);
06210 return TRUE;
06211 }
06212
06216 int oaa_data_owner(ICLTerm *params, ICLTerm **owner) {
06217 ICLTerm *dummyvar = icl_NewVar("_");
06218 if(icl_param_arg("owner", dummyvar, params, owner))
06219 return TRUE;
06220 else if(icl_param_arg("from", dummyvar, params, owner))
06221 return TRUE;
06222 else if(oaa_PrimaryAddress(owner))
06223 return TRUE;
06224 *owner = icl_NewStr("unknown");
06225 return TRUE;
06226 }
06227
06231 int oaa_Id(ICLTerm **my_id) {
06232 ICLTerm *result, *t1;
06233
06234 if(com_GetInfo("parent",
06235 (t1 = icl_NewTermFromString("oaa_id(MyId)")),
06236 &result)) {
06237
06238 *my_id = icl_CopyTerm(icl_NthTerm(result, 1));
06239 icl_Free(result);
06240 icl_Free(t1);
06241 return TRUE;
06242 } else {
06243 char *conn_id;
06244 ICLTerm *type_server = icl_NewTermFromString("type(server)");
06245
06246 icl_Free(t1);
06247 if(com_GetConnectionId(&conn_id, type_server) &&
06248 com_GetInfo(conn_id,
06249 (t1 = icl_NewTermFromString("oaa_id(MyId)")),
06250 &result)) {
06251 *my_id = icl_CopyTerm(icl_NthTerm(result, 1));
06252 icl_Free(result);
06253 icl_Free(t1);
06254 icl_Free(type_server);
06255 return TRUE;
06256 }
06257 }
06258 icl_Free(t1);
06259 return FALSE;
06260 }
06261
06271
06272
06273
06274 int oaa_Address(char* connectionId, ICLTerm* Type, ICLTerm **myAddress)
06275 {
06276 (void)Type;
06277 *myAddress = icl_NewList(NULL);
06278
06279 if (connectionId != NULL) {
06280 if (!com_Connected(connectionId)) {
06281 printWarning(1, "Address requested for connection %s but no such "
06282 "connection exists",connectionId);
06283 icl_AddToList(*myAddress, icl_NewStr("no_address"), FALSE);
06284 } else {
06285 ICLTerm *t1, *tempTerm = NULL;
06286
06287 com_GetInfo(connectionId,
06288 (t1 = icl_NewTermFromString("oaa_address(MyAddress)")),
06289 &tempTerm);
06290 icl_AddToList(*myAddress, icl_CopyTerm(icl_NthTerm(tempTerm, 1)), FALSE);
06291 icl_Free(t1);
06292 icl_Free(tempTerm);
06293 return TRUE;
06294 }
06295 }
06296 else {
06297
06298
06299
06300
06301
06302 int index;
06303 ICLTerm* validConnections = NULL;
06304
06305 com_GetAllValidConnections(&validConnections);
06306
06307 if (validConnections != NULL) {
06308 ICLTerm* requestInfo = icl_NewTermFromString("oaa_address(MyAddress)");
06309
06310
06311
06312
06313
06314 char* connectionIdAsString = NULL;
06315
06316 for (index = 1; index <=icl_ListLen(validConnections) ; index ++) {
06317 ICLTerm* tempTerm = NULL;
06318 connectionIdAsString = icl_Str(icl_NthTerm(validConnections, index));
06319
06320
06321
06322
06323 com_GetInfo(connectionIdAsString, requestInfo, &tempTerm);
06324 icl_AddToList(*myAddress, icl_CopyTerm(icl_NthTerm(tempTerm, 1)),
06325 TRUE);
06326 icl_Free(tempTerm);
06327 }
06328 icl_Free(validConnections);
06329 icl_Free(requestInfo);
06330 return TRUE;
06331 }
06332 }
06333 return FALSE;
06334 }
06335
06339 int oaa_PrimaryAddress(ICLTerm** primaryAddress)
06340 {
06341 if (com_Connected("parent")) {
06342 ICLTerm* tempResult = NULL;
06343 ICLTerm* requestInfo = icl_NewTermFromString("oaa_address(MyAddress)");
06344
06345 com_GetInfo("parent", requestInfo, &tempResult);
06346 *primaryAddress = icl_CopyTerm(icl_NthTerm(tempResult,1));
06347 icl_Free(tempResult);
06348 icl_Free(requestInfo);
06349 return TRUE;
06350 }
06351 else {
06352 printf("liboaa.c::oaa_PrimaryAddress: not connected\n");
06353 }
06354 return FALSE;
06355 }
06356
06360 int oaa_PrimaryId(ICLTerm** primaryId) {
06361 ICLTerm* tempAddress = NULL;
06362
06363 if (oaa_PrimaryAddress(&tempAddress)) {
06364
06365 int returnValue = icl_address_to_id(tempAddress, primaryId);
06366 icl_Free(tempAddress);
06367 return returnValue;
06368 }
06369 return FALSE;
06370 }
06371
06372
06373
06374
06375
06376 int icl_address_to_id(ICLTerm* inFullAddress, ICLTerm** result) {
06377 int success = FALSE;
06378 ICLTerm *tempTerm = icl_NewTermFromString("addr(FacAddr, Id)");
06379 if (icl_Unify(inFullAddress, tempTerm, NULL)) {
06380 *result = icl_CopyTerm(icl_NthTerm(inFullAddress, 2));
06381 success = TRUE;
06382 }
06383 icl_Free(tempTerm);
06384 return success;
06385 }
06386
06390 int oaa_Name(ICLTerm **my_name) {
06391 ICLTerm *result, *t1;
06392
06393 if (com_GetInfo("parent",
06394 (t1 = icl_NewTermFromString("oaa_name(MyName)")),
06395 &result)) {
06396
06397 *my_name = icl_CopyTerm(icl_NthTerm(result, 1));
06398 icl_Free(result);
06399 icl_Free(t1);
06400 return TRUE;
06401 } else {
06402
06403 char *conn_id;
06404 ICLTerm *type_server = icl_NewTermFromString("type(server)");
06405
06406 icl_Free(t1);
06407 if (com_GetConnectionId(&conn_id, type_server) &&
06408 com_GetInfo(conn_id,
06409 (t1 = icl_NewTermFromString("oaa_name(MyName)")),
06410 &result)) {
06411
06412 *my_name = icl_CopyTerm(icl_NthTerm(result, 1));
06413 icl_Free(result);
06414 icl_Free(t1);
06415 return TRUE;
06416 }
06417 icl_Free(t1);
06418 }
06419 return FALSE;
06420 }
06421
06422 char *oaa_name_string()
06423 {
06424 ICLTerm *name;
06425
06426 if (oaa_Name(&name)) {
06427
06428 char *nameStr = strdup(icl_Str(name));
06429 icl_Free(name);
06430 return nameStr;
06431 }
06432 else
06433 return NULL;
06434 }
06435
06436
06440 int oaa_class(char *class) {
06441 int res = FALSE;
06442
06443 if(STREQ(class, "leaf") &&
06444 !com_Connected("fac_listener"))
06445 res = TRUE;
06446 else if(STREQ(class, "node") &&
06447 com_Connected("fac_listener") &&
06448 com_Connected("parent"))
06449 res = TRUE;
06450 else if(STREQ(class, "root") &&
06451 com_Connected("fac_listener") &&
06452 !com_Connected("parent"))
06453 res = TRUE;
06454
06455 return res;
06456 }
06457
06458
06459
06460
06461
06462
06463
06464
06465
06466
06467
06468
06469
06470
06471 int oaa_asserta(ICLTerm *clause, ICLTerm *owner, ICLTerm *callback)
06472 {
06473 ICLTerm *ref, *now, *t1;
06474 #ifndef _WINDOWS
06475 struct timeval tv;
06476 #else
06477 time_t ltime;;
06478 #endif
06479 (void)callback;
06480
06481 asserta_ref(clause, &ref);
06482
06483
06484 #ifndef _WINDOWS
06485 gettimeofday(&tv, (void *)0);
06486 now = icl_NewFloat(tv.tv_sec*1000.0 + tv.tv_usec);
06487 #else
06488 time( <ime );
06489 now = icl_NewFloat(ltime*1000.0);
06490 #endif
06491 asserta(icl_NewStruct("oaa_data_ref", 3, ref, owner, now));
06492 oaa_call_callback("app_on_data_change", (t1 = icl_NewStruct("add", 1, clause)), NULL, NULL);
06493 icl_Free(t1);
06494 return TRUE;
06495 }
06496
06497 int oaa_assertz(ICLTerm *clause, ICLTerm *owner, ICLTerm *callback)
06498 {
06499 ICLTerm *ref, *now, *t1;
06500 #ifndef _WINDOWS
06501 struct timeval tv;
06502 #else
06503 time_t ltime;;
06504 #endif
06505 (void)callback;
06506
06507
06508
06509 assertz_ref(clause, &ref);
06510
06511 #ifndef _WINDOWS
06512 gettimeofday(&tv, (void *)0);
06513 now = icl_NewFloat(tv.tv_sec*1000.0 + tv.tv_usec);
06514 #else
06515 time( <ime );
06516 now = icl_NewFloat(ltime*1000.0);
06517 #endif
06518 asserta(icl_NewStruct("oaa_data_ref", 3, ref, owner, now));
06519 oaa_call_callback("app_on_data_change", (t1 = icl_NewStruct("add", 1, icl_CopyTerm(clause))),NULL,NULL);
06520 icl_Free(t1);
06521 return TRUE;
06522 }
06523
06524 int oaa_retract(ICLTerm *clause, ICLTerm *owner, ICLTerm *callback)
06525 {
06526 ICLTerm *ref, *t1;
06527 (void)callback;
06528
06529 if (ref_for_clause(clause, &ref)) {
06530 t1 = icl_NewStruct("oaa_data_ref", 3, ref, icl_CopyTerm(owner),
06531 icl_NewVar("_"));
06532 if (retract(t1)) {
06533 erase_ref(clause, ref);
06534 icl_Free(t1);
06535
06536 t1 = icl_NewStruct("remove", 1, icl_CopyTerm(clause));
06537 oaa_call_callback("app_on_data_change", t1, NULL, NULL);
06538 icl_Free(t1);
06539 retract(clause);
06540 return TRUE;
06541 }
06542 icl_Free(t1);
06543 }
06544 return FALSE;
06545 }
06546
06547 int oaa_retractall(ICLTerm *clause, ICLTerm *owner, ICLTerm *callback)
06548 {
06549 while (oaa_retract(clause, owner, callback));
06550 return TRUE;
06551 }
06552
06553 int oaa_replace_all(ICLTerm *clause1, ICLTerm *clause2, ICLTerm *owner,
06554 ICLTerm *callback) {
06555 ICLTerm *dummyvar = icl_NewVar("_old_owner");
06556
06557 while(oaa_retract(clause1, dummyvar, callback))
06558 oaa_assertz(clause2, owner, callback);
06559 icl_Free(dummyvar);
06560 return TRUE;
06561 }
06562
06563
06564
06565
06566
06567 static int oaaSolveRec = 0;
06706 int oaa_Solve(ICLTerm *goal, ICLTerm *initial_params, ICLTerm **out_params,
06707 ICLTerm **solutions) {
06708 int compound, res = FALSE;
06709 ICLTerm *params=NULL, *new_params = NULL, *id = NULL, *contexts = NULL, *t1 = NULL;
06710 ICLTerm *tmp_params = NULL;
06711 ++oaaSolveRec;
06712
06713 icl_standardize_params(initial_params, FALSE, ¶ms);
06714
06715 #ifdef UNNEEDED_DEBUG
06716 arglist = (icl_NewList(
06717 icl_NewCons(
06718 icl_CopyTerm(goal),
06719 icl_NewCons(icl_CopyTerm(params),NULL))));
06720 {
06721 char *debugStr = icl_NewStringFromTerm(arglist);
06722 oaa_TraceMsg("\n\nStarting oaa_Solve request:\n %s\n", debugStr,NULL);
06723 icl_stFree(debugStr);
06724 icl_Free(arglist);
06725 }
06726 #endif
06727
06728
06729 t1 = icl_NewTermFromString("cache(true)");
06730 if (icl_GetParamValue(t1, params, NULL) &&
06731 icl_compound_goal(goal)) {
06732 char *debugStr = icl_NewStringFromTerm(goal);
06733
06734 printf("%s: %s (%s)\n Goal: %s\n", "Warning",
06735 "Ignoring 'cache' parameter", "cannot be used with compound goal",
06736 debugStr);
06737 icl_stFree(debugStr);
06738 compound = TRUE;
06739 }
06740 else {
06741 compound = FALSE;
06742 }
06743 icl_Free(t1);
06744
06745
06746
06747 t1 = icl_NewTermFromString("reply(true)");
06748 if (icl_GetParamValue(t1, params, NULL) &&
06749 oaa_retrieve_nth_current_contexts(&id, &contexts, 0)) {
06750 icl_append_to_list(contexts, params, &new_params);
06751 }
06752 else {
06753 new_params = params;
06754 }
06755 icl_Free(t1);
06756
06757
06758
06759
06760
06761
06762 t1 = icl_NewTermFromString("cache(true)");
06763 if (icl_GetParamValue(t1, new_params, NULL) &&
06764 !compound &&
06765 oaa_InCache(goal, solutions)) {
06766
06767 #ifdef UNNEEDED_DEBUG
06768 {
06769 char *debugStr = icl_NewStringFromTerm(*solutions);
06770 oaa_TraceMsg("\n\nSolutions found in cache:\n %s.\n",
06771 debugStr,NULL);
06772 icl_stFree(debugStr);
06773 }
06774 #endif
06775 icl_Free(t1);
06776 res = TRUE;
06777 }
06778 else {
06779
06780 ICLTerm *me;
06781 int meRes;
06782
06783
06784
06785
06786
06787
06788
06789
06790 icl_Free(t1);
06791 meRes = oaa_PrimaryAddress(&me);
06792 if(meRes == FALSE) {
06793 fprintf(stderr, "oaa_Solve: could not get my address--not connected?\n");
06794 --oaaSolveRec;
06795 return FALSE;
06796 }
06797 t1 = icl_NewStruct("address", 1, me);
06798 if (meRes && icl_GetParamValue(t1, params, NULL)) {
06799 icl_Free(t1);
06800 res = oaa_solve_local(goal, new_params, solutions);
06801 }
06802 else {
06803 char* newId = new_goal_id();
06804 ICLTerm* local_goal_id = icl_NewStr(newId);
06805
06806
06807
06808
06809
06810
06811
06812 icl_Free(t1);
06813 icl_stFree(newId);
06814
06815
06816
06817
06818
06819
06820
06821
06822
06823 res = oaa_cont_solve(local_goal_id,
06824 goal,
06825 new_params,
06826 solutions,
06827 &tmp_params);
06828
06829
06830
06831
06832
06833
06834
06835
06836
06837 icl_Free(local_goal_id);
06838 if (res) {
06839 if(new_params != NULL) {
06840 if(new_params == params) {
06841
06842
06843
06844
06845
06846
06847
06848 icl_Free(params);
06849 }
06850 else {
06851 icl_Free(params);
06852 icl_Free(new_params);
06853 }
06854 }
06855 new_params = tmp_params;
06856
06857 #ifdef UNNEEDED_DEBUG
06858 t1 = icl_NewTermFromString("reply(none)");
06859 if (icl_GetParamValue(t1, new_params, NULL)){
06860
06861 }
06862 else {
06863
06864
06865 }
06866 icl_Free(t1);
06867 #endif
06868
06869 t1 = icl_NewTermFromString("cache(true)");
06870 if (icl_GetParamValue(t1, new_params, NULL) &&
06871 (*solutions)->p) {
06872 oaa_AddToCache(goal, *solutions);
06873
06874 }
06875 icl_Free(t1);
06876 }
06877
06878 if (out_params && new_params) {
06879 *out_params = icl_CopyTerm(new_params);
06880 }
06881
06882 icl_Free(local_goal_id);
06883 }
06884 }
06885 if (new_params == tmp_params) {
06886 new_params = NULL;
06887 }
06888 if(tmp_params != NULL) {
06889 icl_Free(tmp_params);
06890 }
06891 if ((new_params != params)) {
06892 icl_Free(new_params);
06893 icl_Free(params);
06894 }
06895 else {
06896 icl_Free(params);
06897 }
06898 --oaaSolveRec;
06899 return res;
06900 }
06901
06902 int oaa_solve_local(ICLTerm *full_goal, ICLTerm *params, ICLTerm **solutions)
06903 {
06904
06905 ICLTerm *tmp=NULL;
06906 ICLTerm *goal_params=NULL;
06907 ICLTerm *solvables=NULL;
06908 ICLTerm *goal1=NULL;
06909 ICLTerm *goal=NULL;
06910 ICLTerm *new_params=NULL;
06911 ICLTerm *t1 = NULL;
06912 ICLTerm *matched=NULL;
06913 ICLTerm *all_params = NULL;
06914 int res = FALSE;
06915
06916
06917
06918 icl_GoalComponents(full_goal, &tmp, &goal1, &goal_params);
06919 solvables = valid_oaa_solvables();
06920
06921 {
06922
06923 }
06924
06925
06926 if (!(icl_compound_goal(goal1) || icl_BuiltIn(goal1))) {
06927 oaa_goal_matches_solvables(goal1, solvables, &goal, &matched);
06928 }
06929
06930
06931 if (goal == NULL) {
06932 if(!*solutions) {
06933 *solutions = icl_NewList(NULL);
06934 }
06935 }
06936 else {
06937
06938
06939
06940
06941 icl_append_to_list(goal_params, params, &all_params);
06942
06943
06944
06945
06946
06947 if (passes_tests(all_params)) {
06948 ICLTerm* tempTerm=NULL;
06949 ICLTerm* solvParams = icl_NthTerm(matched, 2);
06950 ICLTerm *empty_list = icl_NewList(NULL);
06951
06952 t1 = icl_NewTermFromString("test(_)");
06953 icl_ListDelete(all_params, t1, &new_params);
06954 icl_Free(t1);
06955
06956
06957 tempTerm = icl_NewTermFromString("type(data)");
06958 if (icl_GetParamValue(tempTerm, solvParams, NULL)) {
06959 res = db_Solve(local_db, goal, empty_list, solutions);
06960 }
06961 else {
06962 res = oaa_Interpret(goal, new_params, solutions);
06963 }
06964
06965 icl_Free(empty_list);
06966 icl_Free(tempTerm);
06967
06968
06969
06970
06971 } else {
06972
06973 }
06974
06975
06976
06977
06978
06979
06980 icl_Free(all_params);
06981 icl_Free(goal);
06982 }
06983 icl_Free(tmp);
06984 icl_Free(goal1);
06985 icl_Free(goal_params);
06986 icl_Free(matched);
06987 icl_Free(new_params);
06988 return res;
06989 }
06990
06995 int oaa_cont_solve(ICLTerm *goal_id, ICLTerm *goal, ICLTerm *global_params,
06996 ICLTerm **solutions, ICLTerm **out_params) {
06997
06998 int answer = FALSE;
06999 ICLTerm *anAddress = NULL;
07000 ICLTerm *fullGoal = NULL;
07001 ICLTerm *actualGoal = NULL;
07002 ICLTerm *new_global_params = NULL;
07003 int freeFullGoal = FALSE;
07004 static ICLTerm *full_goal_struct = NULL;
07005 static ICLTerm *addr_struct = NULL;
07006 static ICLTerm *d_c_struct = NULL;
07007
07008 if (!icl_IsValid(full_goal_struct)) {
07009 full_goal_struct = icl_NewTermFromData("full_goal(_)", 12);
07010 addr_struct = icl_NewTermFromData("address(AnAddress)", 18);
07011 d_c_struct = icl_NewTermFromData("direct_connect(true)", 20);
07012 }
07013
07014 if (icl_GetParamValue(full_goal_struct, global_params, &fullGoal)) {
07015 actualGoal = icl_NthTerm(fullGoal,1);
07016
07017
07018 icl_ListDelete(global_params, full_goal_struct, &new_global_params);
07019 freeFullGoal = TRUE;
07020 }
07021 else {
07022 actualGoal = goal;
07023 new_global_params = global_params;
07024 freeFullGoal = FALSE;
07025 }
07026
07027 if (icl_GetParamValue(addr_struct, global_params, &anAddress)
07028 && icl_GetParamValue(d_c_struct, global_params, NULL)) {
07029
07030 ICLTerm *addr = icl_NthTerm(anAddress,1);
07031
07032
07033
07034
07035
07036 answer = oaa_cont_solve_direct(goal_id, actualGoal, addr, new_global_params,
07037 solutions, out_params);
07038 }
07039 else if (!icl_GetParamValue(addr_struct, global_params, NULL)
07040 && icl_GetParamValue(d_c_struct, global_params, NULL)) {
07041
07042
07043
07044
07045
07046
07047 answer = oaa_cont_plan(goal_id, goal, actualGoal, new_global_params,
07048 solutions, out_params);
07049 }
07050 else {
07051
07052
07053
07054
07055
07056
07057 answer = oaa_cont_solve_direct(goal_id, actualGoal, NULL, new_global_params,
07058 solutions, out_params);
07059 }
07060
07061 icl_Free(anAddress);
07062 if (freeFullGoal) {
07063 icl_Free(fullGoal);
07064 icl_Free(new_global_params);
07065 }
07066 return answer;
07067 }
07068
07069
07070
07071
07072
07073
07074
07075
07076
07081 int oaa_InCache(ICLTerm *goal, ICLTerm **solutions) {
07082
07083
07084 return oaa_retrieve_all_cache(goal, solutions);
07085 }
07086
07091 int oaa_AddToCache(ICLTerm *goal, ICLTerm *solutions) {
07092 ICLListType *slist = NULL;
07093
07094 if(icl_IsList(solutions)) {
07095 slist = icl_List(solutions);
07096 }
07097 while(icl_ListHasMoreElements(slist)) {
07098 ICLTerm *soln = icl_ListElement(slist);
07099 oaa_assert_cache(goal, soln);
07100 slist = icl_ListNextElement(slist);
07101 }
07102 return TRUE;
07103 }
07104
07108 int oaa_ClearCache() {
07109 ICLTerm *dummyvar = icl_NewVar("_");
07110 ICLTerm *allcache = icl_NewStruct("oaa_cache", 2, dummyvar, dummyvar);
07111 oaa_retractall_cache(allcache);
07112 icl_Free(allcache);
07113 icl_Free(dummyvar);
07114 return TRUE;
07115 }
07116
07124 int oaa_poll_until_event(ICLTerm *event, ICLTerm **solution) {
07125 ICLTerm *pterm;
07126 int p;
07127 static ICLTerm *temp_term = NULL;
07128 int answer;
07129
07130 if (!icl_IsValid(temp_term)) {
07131 temp_term = icl_NewTermFromData("priority(P)",11);
07132 }
07133 icl_param_default(temp_term, &pterm);
07134 p = icl_Int(icl_NthTerm(pterm,1));
07135 icl_Free(pterm);
07136 answer = oaa_poll_until_event_priority(event, p, solution);
07137 return answer;
07138 }
07139
07140 int oaa_poll_until_event_priority(ICLTerm *event, int priority,
07141 ICLTerm **solutions) {
07142 int res;
07143 ICLTerm *event_list = icl_NewList(icl_NewCons(icl_CopyTerm(event), NULL));
07144
07145
07146 if (solutions) {
07147
07148 ICLTerm* local_solutions = icl_NewList(NULL);
07149 res = oaa_poll_until_all_events(event_list, priority, &local_solutions);
07150
07151
07152
07153
07154 if (local_solutions && (icl_NumTerms(local_solutions)>0)) {
07155 *solutions = icl_CopyTerm(icl_NthTerm(local_solutions, 1));
07156 }
07157 icl_Free(local_solutions);
07158 }
07159 else {
07160 res = oaa_poll_until_all_events(event_list, priority, NULL);
07161 }
07162 icl_Free(event_list);
07163 return res;
07164 }
07165
07170
07171
07172
07173
07174 int oaa_poll_until_all_events(ICLTerm *event_list, int priority,
07175 ICLTerm **solutions) {
07176 ICLTerm *event = (ICLTerm *)NULL, *params = (ICLTerm *)NULL;
07177 ICLTerm *dummyvar = icl_NewVar("_");
07178 int res = FALSE;
07179
07180
07181
07182
07183
07184
07185 if(solutions != NULL) {
07186 if(*solutions == NULL) {
07187 *solutions = icl_NewList(NULL);
07188 }
07189 }
07190
07191 if(!event_list->p) {
07192 return TRUE;
07193 }
07194
07195 while(!res) {
07196 int otherres = 0;
07197
07198
07199
07200
07201 event = NULL;
07202 otherres = oaa_grab_waiting_event(event_list, &event);
07203 CHECK_LEAKS();
07204 if(!otherres) {
07205 oaa_GetEvent(&event, ¶ms, 0);
07206 CHECK_LEAKS();
07207 }
07208 CHECK_LEAKS();
07209
07210
07211
07212
07213 CHECK_LEAKS();
07214 if (STREQ(icl_Str(event), "timeout")) {
07215 if (oaa_CheckTriggers("task", dummyvar, "_")) {
07216 ICLTerm *tmpArgs = icl_NewList(NULL);
07217 oaa_call_callback("oaa_AppIdle", dummyvar, tmpArgs, NULL);
07218 icl_Free(tmpArgs);
07219 }
07220 }
07221 else {
07222 CHECK_LEAKS();
07223 oaa_cont_poll_until_all_events(event_list, event, params,
07224 priority, solutions);
07225 CHECK_LEAKS();
07226 res = TRUE;
07227 }
07228 icl_Free(event);
07229 icl_Free(params);
07230 }
07231 icl_Free(dummyvar);
07232 return res;
07233 }
07234
07235
07236
07237
07238
07239
07240
07241 int oaa_cont_poll_until_all_events(ICLTerm *event_list, ICLTerm *event,
07242 ICLTerm *params, int priority,
07243 ICLTerm **solutions) {
07244 static int cntr = 0;
07245 char buf[128];
07246 ICLTerm *new_event_list, *wait_id, *tmp_event_list;
07247
07248
07249
07250 ICLTerm *removed_from_list = NULL;
07251
07252 CHECK_LEAKS();
07253 removed_from_list = remove_element(event, event_list, &new_event_list);
07254
07255
07256
07257
07258
07259
07260
07261
07262
07263
07264
07265
07266
07267
07268
07269
07270
07271
07272
07273
07274
07275 CHECK_LEAKS();
07276
07277
07278
07279 if (removed_from_list) {
07280 if (solutions) {
07281 if(*solutions == NULL) {
07282 *solutions = icl_NewList(NULL);
07283 }
07284 icl_AddToList(*solutions, icl_CopyTerm(event), TRUE);
07285 }
07286 icl_Free(new_event_list);
07287
07288 return TRUE;
07289 }
07290 else {
07291
07292
07293
07294
07295
07296
07297 if(oaa_is_waiting_for(event)) {
07298 oaa_assert_waiting_event(event);
07299 }
07300 else {
07301
07302 sprintf(buf, "wait%d", cntr);
07303 ++cntr;
07304 wait_id = icl_NewStr(buf);
07305 oaa_assert_waiting_for(wait_id, event_list);
07306 oaa_ProcessEvent(event, params);
07307
07308 oaa_retract_waiting_for(wait_id, &tmp_event_list);
07309 }
07310 return oaa_poll_until_all_events(event_list, priority, solutions);
07311 }
07312 return FALSE;
07313 }
07314
07315
07316
07317
07318
07319
07320
07325 int oaa_RegisterCallback(char* callback_id, int (*callback_proc)(ICLTerm*, ICLTerm*, ICLTerm*)) {
07326 ICLTerm* callbackId;
07327
07328
07329 if (strcmp(callback_id, "oaa_AppDoEvent") == 0) {
07330 callback_id = "app_do_event";
07331 }
07332 else if (strcmp(callback_id, "oaa_AppIdle") == 0) {
07333 callback_id = "app_idle";
07334 }
07335 else if (strcmp(callback_id, "oaa_AppDone") == 0) {
07336 callback_id = "app_done";
07337 }
07338
07339 callbackId = icl_NewStr(callback_id);
07340
07341
07342
07343
07344
07345 oaa_assert_callback(callbackId, callback_proc);
07346 CHECK_LEAKS();
07347 icl_Free(callbackId);
07348 CHECK_LEAKS();
07349 return TRUE;
07350 }
07351
07352 int oaa_GetCallback(char* callback_id, int (**callback_proc)(ICLTerm*, ICLTerm*, ICLTerm*)) {
07353 ICLTerm* tempTerm = icl_NewStr(callback_id);
07354 int result = oaa_retrieve_callback(tempTerm, callback_proc);
07355 icl_Free(tempTerm);
07356 return result;
07357 }
07358
07359 int oaa_call_callback(char* callback_id, ICLTerm *goal, ICLTerm* params, ICLTerm* solutions) {
07360 char* goalStr;
07361
07362 int (*callback_proc)(ICLTerm*, ICLTerm*, ICLTerm*)=NULL;
07363
07364 oaa_GetCallback(callback_id, &callback_proc);
07365
07366 if (callback_proc) {
07367 goalStr = icl_NewStringFromTerm(goal);
07368 icl_stFree(goalStr);
07369 return callback_proc(goal, params, solutions);
07370 }
07371 else if(goal != NULL && strcmp("oaa_AppIdle",callback_id)) {
07372 goalStr = icl_NewStringFromTerm(goal);
07373 printf("oaa_call_callback no callback for id %s and goal %s from term pointer %p\n", callback_id, goalStr, goal);
07374 icl_stFree(goalStr);
07375 }
07376 return FALSE;
07377 }
07378
07379
07380
07381
07382
07383
07384
07385
07386
07387 char* new_goal_id()
07388 {
07389
07390
07391 char *res = NULL;
07392 static char *idStr = NULL;
07393 ICLTerm *myPrimId = NULL;
07394 char temp[255];
07395
07396 if (idStr == NULL) {
07397 if (oaa_PrimaryId(&myPrimId)) {
07398 idStr = icl_NewStringFromTerm(myPrimId);
07399 icl_Free(myPrimId);
07400 }
07401 }
07402 sprintf(temp, "g_%s%d", idStr, globalCounter++);
07403 res = strdup(temp);
07404
07405 if(idStr == NULL) {
07406 printf("liboaa.c::new_goal_id() Warning: No result\n");
07407 }
07408
07409 return res;
07410 }
07411
07412
07413
07414
07415
07416 char* new_trigger_id() {
07417 char *res = NULL;
07418
07419 ICLTerm *myPrimId = NULL;
07420 if (oaa_PrimaryId(&myPrimId)) {
07421 char temp [255];
07422 sprintf(temp, "t_%s%d", icl_NewStringFromTerm(myPrimId),globalCounter++);
07423 res = strdup(temp);
07424 icl_Free(myPrimId);
07425 }
07426 return res;
07427 }
07428
07429
07430
07431
07432
07436 int oaa_TraceMsg(char *format_string, ...) {
07437 if (oaa_trace_on) {
07438 char buf[1000];
07439 va_list ptr;
07440 va_start(ptr,format_string);
07441 vsprintf(buf,format_string,ptr);
07442 printf("%s\n", buf);
07443 va_end(ptr);
07444 }
07445 return TRUE;
07446 }
07447
07451 int oaa_ComTraceMsg(char *format_string, ...) {
07452 if (oaa_com_trace_on){
07453 char buf[10000];
07454 va_list ptr;
07455 va_start(ptr,format_string);
07456 vsprintf(buf,format_string,ptr);
07457 printf("%s\n", buf);
07458 va_end(ptr);
07459 }
07460 return TRUE;
07461 }
07462
07463
07464
07465
07466
07467
07468 int oaa_turn_on_debug() {
07469 if(oaa_debug_on) {
07470
07471
07472
07473
07474 }
07475 return TRUE;
07476 }
07477
07478
07479
07480
07481
07482 int oaa_turn_off_debug() {
07483 if(oaa_debug_on) {
07484
07485
07486
07487
07488 }
07489 return TRUE;
07490 }
07491
07492
07493
07494
07499 int oaa_Inform(ICLTerm *type_info, char *format_string, ICLTerm *args) {
07500
07501 #ifdef OAA_INFORM
07502
07503 char result[512];
07504 int res = FALSE;
07505 (void)type_info;
07506 (void)format_string;
07507 (void)args;
07508 if(oaa_TraceMsg(format_string, args) &&
07509 oaa_class("leaf")) {
07510 if(icl_IsList(args)) {
07511 ICLListType *plist = icl_List(args);
07512 va_list ap;
07513
07514
07515 va_start(ap);
07516 while(icl_ListHasMoreElements(plist)) {
07517 char *term_string = icl_Str(icl_ListElement(plist));
07518 va_arg(ap, char *) = term_string;
07519 plist = icl_ListNextElement(plist);
07520 }
07521 va_end(ap);
07522 vsprintf(result, format_string, ap);
07523 res = oaa_Solve(icl_NewStruct("inform", 2, type_info,
07524 icl_NewStr(result)),
07525 icl_NewList(
07526 icl_NewCons(
07527 icl_NewTermFromString("strategy(inform)"),
07528 NULL)));
07529 }
07530 }
07531 return res;
07532
07533 #endif
07534
07535 (void)type_info;
07536 (void)format_string;
07537 (void)args;
07538 return FALSE;
07539 }
07540
07541
07542
07543
07544
07545
07546
07547
07548
07549
07550
07551
07552
07553
07554
07555
07556
07557
07558
07559
07560
07561
07562
07563
07564
07565
07566
07567
07568
07569
07570
07571
07572
07573
07574
07575
07576
07577
07578
07579
07580
07581
07582
07583
07584
07585
07586
07587
07588
07589
07590
07591
07592
07593
07594
07595
07596
07601 int oaa_is_waiting_for(ICLTerm *event)
07602 {
07603 int result;
07604 ICLTerm *event_list = NULL;
07605 ICLTerm *dummyvar = icl_NewVar("_");
07606
07607 oaa_retrieve_all_waiting_for(dummyvar, &event_list);
07608 icl_Free(dummyvar);
07609
07610 if(icl_Member(event, event_list, NULL))
07611 result = TRUE;
07612 else
07613 result = FALSE;
07614
07615 icl_Free(event_list);
07616 return(result);
07617 }
07618
07623 int oaa_grab_waiting_event(ICLTerm *event_list, ICLTerm **event)
07624 {
07625 ICLTerm *test_events, *an_event, *unified_event;
07626 ICLListType *elist;
07627 int returnValue = FALSE;
07628
07629 oaa_retrieve_all_waiting_events(&test_events);
07630 elist = icl_List(test_events);
07631
07632 while(icl_ListHasMoreElements(elist)) {
07633 an_event = icl_ListElement(elist);
07634 elist = icl_ListNextElement(elist);
07635
07636 if(icl_Member(an_event, event_list, &unified_event)) {
07637 oaa_retract_waiting_event(unified_event);
07638 *event = unified_event;
07639 returnValue = TRUE;
07640 break;
07641 }
07642 }
07643 icl_Free(test_events);
07644 return returnValue;
07645 }
07646
07647
07648
07649
07655 int oaa_remove_solvables_data(ICLTerm *solvables) {
07656 int res = FALSE;
07657 if(icl_IsList(solvables)) {
07658 ICLListType *slist = icl_List(solvables);
07659 ICLTerm *dummyvar = icl_NewVar("_");
07660 ICLTerm *type_data = icl_NewTermFromString("type(data)");
07661 ICLTerm *synonym = icl_NewStruct("synonym", 2, dummyvar, dummyvar);
07662 while(icl_ListHasMoreElements(slist)) {
07663 ICLTerm *solvable = icl_ListElement(slist);
07664 res = FALSE;
07665 if(icl_IsStruct(solvable) &&
07666 (icl_Arity(solvable) == 3)) {
07667
07668 ICLTerm *goal = icl_NthTerm(solvable, 1);
07669 ICLTerm *params = icl_NthTerm(solvable, 2);
07670 ICLTerm *t1;
07671
07672 if (icl_GetParamValue(type_data, params, NULL) &&
07673 (!icl_GetParamValue(synonym, params, NULL))) {
07674
07675
07676
07677
07678 ICLTerm *skeleton;
07679 predicate_skeleton(goal, &skeleton);
07680 if (oaa_remove_data_local(skeleton,
07681 (t1 = icl_NewTermFromString(
07682 "[do_all(true)]"))))
07683 res = TRUE;
07684 else
07685 printf(
07686 "%s: Problem in removing all data form solvable: %s\n",
07687 "! ERROR", icl_NewStringFromTerm(goal));
07688 icl_Free(t1);
07689 }
07690 }
07691 slist = icl_ListNextElement(slist);
07692 }
07693 icl_Free(synonym);
07694 icl_Free(dummyvar);
07695 icl_Free(type_data);
07696 }
07697 return res;
07698 }
07699
07700 int oaa_remove_data_owned_by(ICLTerm *id)
07701 {
07702 ICLTerm *solvables = valid_oaa_solvables();
07703 ICLTerm *built_ins = oaa_built_in_solvables();
07704 ICLTerm *all_solvables=NULL;
07705 ICLListType *slist = NULL;
07706 ICLTerm *type_data = icl_NewTermFromString("type(data)");
07707 ICLTerm *persistent_true = icl_NewTermFromString("persistent(true)");
07708 ICLTerm *dummyvar = icl_NewVar("_");
07709 ICLTerm *synonym = icl_NewStruct("synonym", 2, icl_CopyTerm(dummyvar), icl_CopyTerm(dummyvar));
07710 int res= FALSE;
07711
07712 icl_append_to_list(built_ins, solvables, &all_solvables);
07713 slist = icl_List(all_solvables);
07714 while(icl_ListHasMoreElements(slist)) {
07715 ICLTerm *solvable = icl_ListElement(slist);
07716 res = FALSE;
07717 if(icl_IsStruct(solvable) &&
07718 (icl_Arity(solvable) == 3)) {
07719 ICLTerm *goal = icl_NthTerm(solvable, 1);
07720 ICLTerm *params = icl_NthTerm(solvable, 2);
07721 if(icl_GetParamValue(type_data, params, NULL) &&
07722 !icl_GetParamValue(persistent_true, params, NULL) &&
07723 !icl_GetParamValue(synonym, params, NULL)) {
07724
07725
07726
07727
07728 ICLTerm *skeleton=NULL;
07729 ICLTerm *rparams =
07730 icl_NewList(icl_NewCons(icl_NewStruct("owner", 1, icl_CopyTerm(id)),
07731 icl_NewCons(icl_NewTermFromString("do_all(true)"), NULL)));
07732 predicate_skeleton(goal, &skeleton);
07733 if (oaa_remove_data_local(skeleton, rparams)) {
07734 res = TRUE;
07735 }
07736 else {
07737 char *debugStr = icl_NewStringFromTerm(goal);
07738 printf("%s: Problem in removing all data form solvable: %s\n",
07739 "! ERROR", debugStr);
07740 icl_stFree(debugStr);
07741 }
07742 icl_Free(rparams);
07743 }
07744 }
07745 slist = icl_ListNextElement(slist);
07746 }
07747 icl_Free(synonym);
07748 icl_Free(dummyvar);
07749 icl_Free(persistent_true);
07750 icl_Free(type_data);
07751 return res;
07752 }
07753
07754
07755
07756
07757
07758
07759
07760
07761
07762
07763
07764
07765
07766
07767
07768
07769
07770
07771
07772
07773
07774
07775
07776
07777
07778
07779
07780
07781
07782
07783
07784
07785
07786
07787
07788
07789
07790
07791
07792
07793
07794
07795 int predicate_skeleton(ICLTerm *goal, ICLTerm **skeleton) {
07796 if(icl_IsStruct(goal)) {
07797 ICLTerm *dummyvar = icl_NewVar("_");
07798 char *functor = icl_Functor(goal);
07799 int arity = icl_Arity(goal);
07800 ICLTerm *arglist = icl_NewList(NULL);
07801 int i;
07802 for(i=0; i<arity; i++) {
07803 icl_AddToList(arglist, icl_CopyTerm(dummyvar), TRUE);
07804 }
07805 *skeleton = icl_NewStructFromList(functor, arglist);
07806 icl_Free(dummyvar);
07807 return TRUE;
07808 }
07809 return FALSE;
07810 }
07811
07812
07813
07814
07815
07816
07817
07818
07819
07820
07821
07822
07823
07824
07831 ICLTerm* remove_element(ICLTerm *elt, ICLTerm *list, ICLTerm **rest) {
07832 ICLTerm* removed = NULL;
07833 ICLListType *elist = icl_List(list);
07834 *rest = icl_NewList(NULL);
07835 while(icl_ListHasMoreElements(elist)) {
07836 ICLTerm *test = icl_ListElement(elist);
07837
07838
07839
07840
07841
07842
07843
07844
07845 if(icl_Unify(elt, test, NULL)) {
07846 removed = test;
07847 }
07848 else {
07849 icl_AddToList(*rest, icl_CopyTerm(test), TRUE);
07850 }
07851 elist = icl_ListNextElement(elist);
07852 }
07853 return removed;
07854 }
07855
07861 int replace_element(ICLTerm *elt, ICLTerm *old_list, ICLTerm *new_elt,
07862 ICLTerm **new_list)
07863 {
07864 int res = FALSE;
07865 ICLListType *elist = icl_List(old_list);
07866 (void)new_elt;
07867 *new_list = icl_NewList(NULL);
07868 while(icl_ListHasMoreElements(elist)) {
07869 ICLTerm *unified, *test = icl_ListElement(elist);
07870 if(icl_Unify(elt, test, &unified)) {
07871 icl_AddToList(unified, icl_CopyTerm(*new_list), TRUE);
07872 res = TRUE;
07873 } else {
07874 icl_AddToList(test, icl_CopyTerm(*new_list), TRUE);
07875 }
07876 elist = icl_ListNextElement(elist);
07877 }
07878 return res;
07879 }
07880
07881
07882
07883
07884
07885
07886
07887 static int ensure_direct_connection(ICLTerm *AgentAddress, char **ConnectionId) {
07888 int answer = FALSE;
07889 ICLTerm *other_address = icl_NewStruct("other_address", 1, icl_CopyTerm(AgentAddress));
07890 answer = com_GetConnectionId(ConnectionId, other_address);
07891 if (!answer) {
07892 ICLTerm *goal = icl_NewStruct("agent_listener", 2,
07893 icl_CopyTerm(AgentAddress),
07894 icl_NewVar("X"));
07895
07896 ICLTerm *solveParams = icl_NewTermFromData("[address(parent)]", 17);
07897 ICLTerm *solutions = icl_NewList(NULL);
07898 ICLTerm *myName = NULL;
07899 char *myNameString = NULL;
07900 ICLTerm *ConnectAddress = NULL;
07901 ICLTerm *connectParams = icl_NewList(NULL);
07902 icl_AddToList(connectParams, icl_NewStruct("resolve_vars", 1, icl_NewStr("false")), TRUE);
07903 icl_AddToList(connectParams, icl_CopyTerm(other_address), TRUE);
07904 oaa_Solve(goal, solveParams, NULL, &solutions);
07905 ConnectAddress = icl_CopyTerm(icl_NthTerm(icl_NthTerm(icl_NthTerm(solutions,1),2),1));
07906 if (ConnectAddress == NULL) {
07907 icl_Free(connectParams);
07908 icl_Free(ConnectAddress);
07909 icl_Free(goal);
07910 icl_Free(connectParams);
07911 icl_Free(solutions);
07912 icl_Free(solveParams);
07913 answer = FALSE;
07914 }
07915 else {
07916 *ConnectionId = new_direct_connection_id();
07917
07918 oaa_Name(&myName);
07919 myNameString = icl_NewStringFromTerm(myName);
07920 answer = oaa_Connect(*ConnectionId, ConnectAddress, myNameString, connectParams);
07921
07922 icl_Free(goal);
07923 icl_Free(solveParams);
07924 icl_Free(solutions);
07925 icl_Free(myName);
07926 icl_stFree(myNameString);
07927 icl_Free(ConnectAddress);
07928 icl_Free(connectParams);
07929 }
07930 CHECK_LEAKS();
07931 }
07932 icl_Free(other_address);
07933 CHECK_LEAKS();
07934 return answer;
07935 }
07936
07937
07938
07939
07940
07941 static int isClientConnection(char *ConnectionId) {
07942 ICLTerm *t2 = NULL;
07943 ICLTerm *type = NULL;
07944 int answer = TRUE;
07945
07946 t2 = icl_NewStruct("type", 1, icl_NewVar("T"));
07947 if (com_GetInfo(ConnectionId, t2, &type)) {
07948 answer = STREQ(icl_Str(type), "client");
07949 }
07950 icl_Free(type);
07951 icl_Free(t2);
07952 return answer;
07953 }
07954
07964 EXPORT_MSCPP
07965 int EXPORT_BORLAND
07966 memberchk(ICLTerm *Param, ICLTerm *ParamList) {
07967 int res = FALSE;
07968
07969
07970 if ((Param == NULL) ||
07971 (ParamList == NULL) ||
07972 (icl_ListLen(ParamList) == 0)) {
07973 return FALSE;
07974 }
07975
07976 if (icl_IsStruct(Param) && (icl_NumTerms(Param) == 1) &&
07977 icl_IsList(ParamList)) {
07978 ICLTerm *p;
07979 if (icl_ParamValue(icl_Str(Param), NULL, ParamList, &p)) {
07980 res = icl_Unify(Param, p, NULL);
07981 icl_Free(p);
07982 }
07983 return res;
07984 }
07985 else {
07986 return FALSE;
07987 }
07988 }
07989
07990
07991
07992
07993
07994 static char* new_direct_connection_id() {
07995 static int counter = 1;
07996 char temp[255];
07997 sprintf(temp, "direct%d", counter++);
07998 return strdup(temp);
07999 }
08000
08007 EXPORT_MSCPP
08008 int EXPORT_BORLAND
08009 oaa_Connect(char *ConnectionId, ICLTerm *Address, char *InitialAgentName, ICLTerm *Params) {
08010
08011 if (comConnectFormat(ConnectionId, Params, Address, COM_BEST_FORMAT) <= 0) {
08012 return FALSE;
08013 }
08014
08015 if(!oaa_handshake(ConnectionId, InitialAgentName, Params)) {
08016 return FALSE;
08017 }
08018
08019 return TRUE;
08020
08021 }
08022
08023
08024
08025
08026 static int oaa_cont_solve_direct(ICLTerm* goal_id,
08027 ICLTerm *goal,
08028 ICLTerm *SingleAgentAddress,
08029 ICLTerm *global_params,
08030 ICLTerm **solutions,
08031 ICLTerm **out_params) {
08032 ICLTerm *tmp1 = NULL;
08033 ICLTerm *tmp2 = NULL;
08034 ICLTerm *params = NULL;
08035 ICLTerm *requestees = NULL;
08036 ICLTerm *solvers = NULL;
08037 ICLTerm *solved_params = NULL;
08038 ICLTerm *dummyvar = icl_NewVar("_");
08039 ICLTerm *t1 = (ICLTerm *)NULL, *t2 = (ICLTerm *)NULL, *t3 = (ICLTerm *)NULL;
08040 ICLTerm *all_params = NULL;
08041 int res = FALSE;
08042
08043 ICLTerm *conn_id = NULL;
08044 ICLTerm *post_params = icl_NewList(NULL);
08045 char *ConnectionId = NULL;
08046
08047 int direct_connect_used = FALSE;
08048 static ICLTerm *get_direct_connect_used_true = NULL;
08049 static ICLTerm *get_direct_connect_used_false = NULL;
08050
08051 if (!icl_IsValid(get_direct_connect_used_true)) {
08052 get_direct_connect_used_true
08053 = icl_NewTermFromData("get_direct_connect_used(true)",29);
08054 get_direct_connect_used_false
08055 = icl_NewTermFromData("get_direct_connect_used(false)",30);
08056 }
08057
08058
08059
08060
08061
08062 if((SingleAgentAddress != NULL) &&
08063 ensure_direct_connection(SingleAgentAddress, &ConnectionId)) {
08064 direct_connect_used = TRUE;
08065 icl_AddToList(global_params, icl_CopyTerm(SingleAgentAddress), FALSE);
08066 conn_id = icl_NewStruct("connection_id", 1, icl_NewStr(ConnectionId));
08067 icl_AddToList(post_params, conn_id, FALSE);
08068
08069 }
08070 t1 = icl_NewStruct("ev_solve", 3,
08071 icl_CopyTerm(goal_id),
08072 icl_CopyTerm(goal),
08073 icl_CopyTerm(global_params));
08074
08075 oaa_PostEvent(t1, post_params);
08076 icl_Free(t1);
08077
08078 icl_GoalComponents(goal, &tmp1, &tmp2, ¶ms);
08079 icl_append_to_list(params, global_params, &all_params);
08080
08081 icl_Free(tmp1);
08082 icl_Free(tmp2);
08083 icl_Free(params);
08084
08085 t1 = icl_NewTermFromData("reply(false)",12);
08086 t2 = icl_NewTermFromData("reply(none)",11);
08087 t3 = icl_NewTermFromData("blocking(false)",15);
08088
08089 if (icl_GetParamValue(t1, all_params, NULL) ||
08090 icl_GetParamValue(t2, all_params, NULL) ||
08091 icl_GetParamValue(t3, all_params, NULL)) {
08092
08093 if (solutions) {
08094 *solutions = icl_CopyTerm(goal);
08095 }
08096 requestees = icl_NewList(NULL);
08097 solvers = icl_NewList(NULL);
08098 }
08099 else {
08100
08101 ICLTerm *result;
08102 ICLTerm *ev_reply_solved_term;
08103 ev_reply_solved_term = icl_NewStruct("ev_solved", 6,
08104 icl_CopyTerm(goal_id),
08105 icl_CopyTerm(dummyvar),
08106 icl_CopyTerm(dummyvar),
08107 icl_CopyTerm(dummyvar),
08108 icl_CopyTerm(dummyvar),
08109 icl_CopyTerm(dummyvar));
08110
08111
08112
08113
08114
08115
08116
08117 if (oaa_poll_until_event(ev_reply_solved_term, &result)) {
08118 if (icl_IsStruct(result) && (icl_Arity(result) == 6)) {
08119 requestees = icl_CopyTerm(icl_NthTerm(result, 2));
08120 solvers = icl_CopyTerm(icl_NthTerm(result, 3));
08121 solved_params = icl_CopyTerm(icl_NthTerm(result, 5));
08122 if(*solutions != NULL) {
08123 icl_Free(*solutions);
08124 }
08125 *solutions = icl_CopyTerm(icl_NthTerm(result, 6));
08126 icl_Free(result);
08127 if (icl_ListLen(*solutions)>0) {
08128 res = TRUE;
08129 }
08130 if (!icl_Unify(global_params, solved_params, NULL)) {
08131 char *debugStr = icl_NewStringFromTerm(solved_params);
08132 printf("%s: %s %s\n %s: %s\n", "WARNING",
08133 "Params in solved event don't unify",
08134 "with original params", "SolvedParams",
08135 debugStr);
08136 icl_stFree(debugStr);
08137 }
08138 }
08139 }
08140 icl_Free(ev_reply_solved_term);
08141 }
08142 icl_Free(t1); icl_Free(t2); icl_Free(t3);
08143
08144 if (res) {
08145
08146 if (out_params) {
08147 *out_params = icl_CopyTerm(global_params);
08148 t1 = icl_NewStruct("get_satisfiers", 1, icl_CopyTerm(solvers));
08149 icl_replace_param_value(t1, *out_params);
08150 icl_Free(t1);
08151
08152
08153 t1 = icl_NewStruct("get_address", 1, icl_CopyTerm(requestees));
08154 icl_replace_param_value(t1, *out_params);
08155 icl_Free(t1);
08156
08157
08158 if (direct_connect_used) {
08159 icl_replace_param_value(get_direct_connect_used_true,*out_params);
08160 }
08161 else {
08162 icl_replace_param_value(get_direct_connect_used_false,*out_params);
08163 }
08164 }
08165 }
08166 icl_Free(solved_params);
08167 icl_Free(solvers);
08168 icl_Free(requestees);
08169 icl_Free(dummyvar);
08170 icl_Free(all_params);
08171 icl_Free(post_params);
08172 icl_stFree(ConnectionId);
08173 return res;
08174
08175 }
08176
08177
08178
08179
08180 static int oaa_cont_plan(ICLTerm *goal_id,
08181 ICLTerm *templateGoal,
08182 ICLTerm *actualGoal,
08183 ICLTerm *global_params,
08184 ICLTerm **solutions,
08185 ICLTerm **out_params) {
08186 int answer = FALSE;
08187 ICLTerm *result = NULL;
08188 ICLTerm *ev_reply_planned_term = NULL;
08189 ICLTerm *t1 = NULL;
08190 ICLTerm *t2 = NULL;
08191 ICLTerm *t3 = NULL;
08192 ICLTerm *SingleAgentAddress = NULL;
08193
08194 t1 = icl_NewStruct("ev_plan", 3,
08195 icl_CopyTerm(goal_id),
08196 icl_CopyTerm(templateGoal),
08197 icl_CopyTerm(global_params));
08198 t2 = icl_NewStruct("connection_id", 1, icl_NewStr("parent"));
08199 t3 = icl_NewList(NULL);
08200 icl_AddToList(t3,t2,TRUE);
08201
08202 oaa_PostEvent(t1, t3);
08203
08204 ev_reply_planned_term = icl_NewStruct("ev_planned", 4,
08205 icl_NewVar("_"),
08206 icl_CopyTerm(templateGoal),
08207 icl_NewVar("_"),
08208 icl_NewVar("_"));
08209
08210 oaa_poll_until_event(ev_reply_planned_term, &result);
08211
08212
08213 if (oaa_get_single_address_from_plan(result, &SingleAgentAddress)) {
08214 answer = oaa_cont_solve_direct(goal_id, actualGoal, SingleAgentAddress, global_params, solutions, out_params);
08215 }
08216 else {
08217
08218 answer = oaa_cont_solve_direct(goal_id, actualGoal, NULL, global_params, solutions, out_params);
08219 }
08220
08221 icl_Free(SingleAgentAddress);
08222 icl_Free(ev_reply_planned_term);
08223 icl_Free(t1);
08224 icl_Free(t3);
08225 icl_Free(result);
08226
08227 return answer;
08228
08229 }
08230
08241 EXPORT_MSCPP
08242 int EXPORT_BORLAND
08243 oaa_Disconnect(char* ConnectionId, ICLTerm *Params) {
08244
08245
08246 (void)Params;
08247
08248 return com_Disconnect(ConnectionId);
08249 }
08250
08251
08252
08253
08254 static int oaa_get_single_address_from_plan(ICLTerm *ev_planned_term,
08255 ICLTerm **SingleAgentAddress) {
08256 ICLTerm *AgentAddressList = icl_NthTerm(icl_NthTerm(ev_planned_term, 4), 1);
08257 int answer = FALSE;
08258 *SingleAgentAddress = NULL;
08259
08260 if (AgentAddressList != NULL &&
08261 icl_IsList(AgentAddressList) &&
08262 icl_ListLen(AgentAddressList) == 1) {
08263 *SingleAgentAddress = icl_CopyTerm(icl_NthTerm(AgentAddressList, 1));
08264 answer = TRUE;
08265 if(!icl_IsValid(ev_planned_term) ||
08266 !icl_IsValid(AgentAddressList) ||
08267 !icl_IsValid(*SingleAgentAddress)) {
08268 ev_planned_term = NULL;
08269 ev_planned_term->magic_cookie = 0;
08270 }
08271 }
08272
08273 return answer;
08274
08275 }
08276
08277
08278
08279
08280
08281 static int oaa_handshake(char *ConnectionId, char *InitialAgentName, ICLTerm *Params) {
08282 int isClient = TRUE;
08283 ICLTerm *ConnEvent = NULL;
08284 ICLTerm *EventTerm = NULL;
08285 ICLTerm* agent_name_cmdline = NULL;
08286 ICLTerm *myId = NULL;
08287 ICLTerm *t1 = NULL;
08288 char *AgentName = NULL;
08289 char buf[1000];
08290 int result = TRUE;
08291 ICLTerm* usePassword = NULL;
08292 ICLTerm* passwordTerm = NULL;
08293 char* password = NULL;
08294 ICLTerm* reconnectMatcher = icl_NewStruct("reconnect", 1, icl_NewVar("true"));
08295 int isReconnect = FALSE;
08296 (void)Params;
08297
08298 memset(buf, 0, 1000);
08299
08300
08301 if (oaa_saved_events==NULL) {
08302 oaa_saved_events = icl_NewList(NULL);
08303 }
08304
08305
08306 isClient = isClientConnection(ConnectionId);
08307 isReconnect = icl_Member(reconnectMatcher, Params, NULL);
08308 icl_Free(reconnectMatcher);
08309
08310
08311
08312
08313 oaa_ResolveVariable("-oaa_name", &agent_name_cmdline);
08314 if(agent_name_cmdline) {
08315 AgentName = icl_NewStringFromTerm(agent_name_cmdline);
08316 }
08317 else {
08318 AgentName = strdup(InitialAgentName);
08319 }
08320
08321 icl_stFixQuotes(AgentName);
08322
08323 com_AddInfo(ConnectionId,
08324 (t1 = icl_NewStruct("oaa_name",
08325 1,
08326 icl_NewStr(AgentName))));
08327 icl_Free(t1);
08328
08329 if (isClient) {
08330 ICLTerm* ev_connect;
08331
08332 if(!db_IsValid(local_db))
08333 local_db = db_NewDB();
08334
08335 oaa_ResolveVariable("use_password", &usePassword);
08336
08337 if(usePassword != NULL) {
08338 if(icl_IsStr(usePassword) &&
08339 (strlen(icl_Str(usePassword)) == 4) &&
08340 (strncmp(icl_Str(usePassword), "true", 4) == 0)) {
08341 oaa_ResolveVariable("client_password", &passwordTerm);
08342 if(passwordTerm != NULL) {
08343 password = icl_NewStringFromTerm(passwordTerm);
08344 }
08345 else {
08346 password = strdup("_");
08347 }
08348 }
08349 }
08350
08351
08352
08353
08354
08355
08356
08357
08358
08359 if(password != NULL) {
08360 sprintf(buf, "event(ev_connect([other_name('%s'),"
08361 "other_language(c),other_type(client),"
08362 "other_version(%s),password(%s)]),[])",
08363 AgentName, oaa_library_version_str, password);
08364 icl_stFree(password);
08365 }
08366 else {
08367 sprintf(buf, "event(ev_connect([other_name('%s'),"
08368 "other_language(c),other_type(client),"
08369 "other_version(%s)]),[])",
08370 AgentName, oaa_library_version_str);
08371 }
08372 ev_connect = icl_NewTermFromString(buf);
08373 if(isReconnect) {
08374 ICLTerm* connectParams = icl_NthTerm(icl_NthTerm(ev_connect, 1), 1);
08375 ICLTerm* reconnectTerm;
08376 ICLTerm* nameTerm;
08377 ICLTerm* addressTerm;
08378 ICLTerm* reconnectMatcher = icl_NewStruct("reconnect", 1, icl_NewVar("_"));
08379 ICLTerm* nameMatcher = icl_NewStruct("other_name", 1, icl_NewVar("_"));
08380 ICLTerm* addressMatcher = icl_NewStruct("other_address", 1, icl_NewVar("_"));
08381 if(!icl_Member(reconnectMatcher, Params, &reconnectTerm)) {
08382 fprintf(stderr, "Reconnecting handshake requires reconnect(_) in Params, but none found");
08383 }
08384 else {
08385 icl_AddToList(connectParams, reconnectTerm, FALSE);
08386 }
08387 if(!icl_Member(nameMatcher, Params, &nameTerm)) {
08388 fprintf(stderr, "Reconnecting handshake requires other_name(_) in Params, but none found");
08389 }
08390 else {
08391 icl_AddToList(connectParams, nameTerm, FALSE);
08392 }
08393 if(!icl_Member(addressMatcher, Params, &addressTerm)) {
08394 fprintf(stderr, "Reconnecting handshake requires other_addres(_) in Params, but none found");
08395 }
08396 else {
08397 icl_AddToList(connectParams, addressTerm, FALSE);
08398 }
08399 }
08400 com_SendTerm(ConnectionId, ev_connect);
08401 icl_Free(ev_connect);
08402
08403
08404
08405 com_GetEventFromConnection(ConnectionId, 0.0, &EventTerm);
08406
08407 ConnEvent = icl_NthTerm(icl_NthTerm(EventTerm, 1), 1);
08408
08409 t1 = icl_NewStruct("ev_connected",
08410 1,
08411 icl_NewVar("FacInfoList"));
08412 if(icl_Unify(ConnEvent, t1, NULL)) {
08413 if(icl_IsStruct((icl_NthTerm(ConnEvent, 1)))) {
08414 ICLTerm* resStruct = icl_NthTerm(ConnEvent, 1);
08415 char* functor = icl_Functor(resStruct);
08416 if(functor != NULL) {
08417 if((strlen(functor) == 9) &&
08418 (strncmp(functor, "exception", 9) == 0)) {
08419 char* exceptionData = icl_NewStringFromTerm(icl_NthTerm(resStruct, 1));
08420 fprintf(stderr, "Exception in oaa_handlshake: %s\n", exceptionData);
08421 icl_stFree(exceptionData);
08422 result = FALSE;
08423 }
08424 }
08425 }
08426
08427 if(result != FALSE) {
08428 com_UpdateInfo(ConnectionId, icl_NthTerm(ConnEvent, 1));
08429 }
08430 }
08431 else {
08432 printf("oaa_handshake no ev_connected\n");
08433 result = FALSE;
08434 }
08435
08436 icl_Free(t1);
08437 icl_Free(EventTerm);
08438 }
08439 else {
08440
08441
08442
08443
08444
08445 com_AddInfo(ConnectionId,
08446 (t1 = icl_NewStruct("oaa_name",
08447 1,
08448 icl_NewStr(AgentName))));
08449 icl_Free(t1);
08450
08451
08452
08453 com_AddInfo(ConnectionId,
08454 (t1 = icl_NewStruct("oaa_id", 1, icl_NewInt(0))));
08455 icl_Free(t1);
08456
08457 result = oaa_PrimaryAddress(&myId);
08458
08459
08460
08461
08462
08463
08464
08465
08466
08467
08468
08469
08470 }
08471 icl_stFree(agent_name_cmdline);
08472 icl_stFree(AgentName);
08473 return result;
08474 }
08475
08482 EXPORT_MSCPP
08483 int EXPORT_BORLAND
08484 oaa_SetupCommunication(char *InitialAgentName) {
08485 ICLTerm *RequestedAddress = NULL;
08486 ICLTerm* var;
08487 char *requestedAddressString;
08488
08489 var = icl_NewVar("_");
08490 if (!oaa_Connect("parent", var, InitialAgentName, ICL_EMPTY)) {
08491 icl_Free(var);
08492 return FALSE;
08493 }
08494 icl_Free(var);
08495
08496 oaa_ResolveVariable("oaa_listen", &RequestedAddress);
08497 requestedAddressString = getenv("OAA_LISTEN");
08498 if (requestedAddressString) {
08499 RequestedAddress = icl_NewTermFromString(requestedAddressString);
08500 }
08501 oaa_ResolveVariable("-oaa_listen", &RequestedAddress);
08502
08503 if (RequestedAddress != NULL) {
08504 if (com_ListenAt("client_listener", NULL, RequestedAddress)) {
08505 char *tmp = icl_NewStringFromTerm(RequestedAddress);
08506 printf("Agent listening at %s\n", tmp);
08507 icl_stFree(tmp);
08508 }
08509 else {
08510 printf("Unable to open a client listener connection;");
08511 printf(" continuing without it\n");
08512 }
08513 icl_Free(RequestedAddress);
08514 }
08515 return TRUE;
08516 }
08517
08518 int oaa_SeqNumLessThan(int a, int b)
08519 {
08520 if(a < b) {
08521 return (b - a) <= (2147483647 / 3);
08522 }
08523 else {
08524 return (a - b) >= ((2147483647 / 3) * 2);
08525 }
08526 }
08527
08538 int oaa_version_atleast(int major, int minor, int level, ICLTerm* toCheck)
08539 {
08540 int size;
08541 if(!icl_IsList(toCheck)) {
08542 return FALSE;
08543 }
08544
08545 size = icl_NumTerms(toCheck);
08546 if(size > 0) {
08547 ICLTerm* majorTerm = icl_NthTerm(toCheck, 1);
08548 int majorCheck = icl_Int(majorTerm);
08549 if(majorCheck > major) {
08550 return TRUE;
08551 }
08552 else if(majorCheck < major) {
08553 return FALSE;
08554 }
08555 else if(size > 1) {
08556 ICLTerm* minorTerm = icl_NthTerm(toCheck, 2);
08557 int minorCheck = icl_Int(minorTerm);
08558 if(minorCheck > minor) {
08559 return TRUE;
08560 }
08561 else if(minorCheck < minor) {
08562 return FALSE;
08563 }
08564 else if(size > 2) {
08565 ICLTerm* levelTerm = icl_NthTerm(toCheck, 3);
08566 int levelCheck = icl_Int(levelTerm);
08567 if(levelCheck >= level) {
08568 return TRUE;
08569 }
08570 else {
08571 return FALSE;
08572 }
08573 }
08574 }
08575 else {
08576 return minor < 0;
08577 }
08578 }
08579 return FALSE;
08580 }
08581
08582 EXPORT_MSCPP
08583 int EXPORT_BORLAND
08584 oaa_SupportsSequenceNumbers(char* connectionId)
08585 {
08586 ICLTerm* otherVersionTerm;
08587 ICLTerm* toMatch = icl_NewStruct("other_version", 1, icl_NewVar("_"));
08588 ICLTerm* versionList;
08589 int result = FALSE;
08590 if(!com_GetInfo(connectionId, toMatch, &otherVersionTerm)) {
08591 goto finally;
08592 }
08593
08594 versionList = icl_NthTerm(otherVersionTerm, 1);
08595 result = oaa_version_atleast(2, 3, 3, versionList);
08596
08597 finally:
08598 icl_Free(toMatch);
08599 icl_Free(otherVersionTerm);
08600 return result;
08601 }
08602
08603
08604