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
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifndef lint
00041
00042 #endif
00043
00044
00045
00046
00047
00048
00049 #ifndef _WINDOWS
00050 #include <sys/param.h>
00051 #include <sys/time.h>
00052 #endif
00053
00054 #include <string.h>
00055 #include <stdio.h>
00056 #include <stdlib.h>
00057 #include <stdarg.h>
00058 #include "libicl_private.h"
00059 #include "libicl.h"
00060 #include "libdb.h"
00061 #include "libcom_tcp.h"
00062 #include "liboaa.h"
00063 #include "dictionary.h"
00064
00065
00066
00067
00068 int oaa_remove_trigger_local(char *type, ICLTerm *condition,
00069 ICLTerm *action, ICLTerm *params);
00070 int oaa_add_trigger_local(char *type, ICLTerm *condition,
00071 ICLTerm *action, ICLTerm *params);
00072
00073 EXTERN int oaa_solve_local(ICLTerm *full_goal, ICLTerm *params, ICLTerm **solutions);
00074 EXTERN ICLTerm *remove_element(ICLTerm *elt, ICLTerm *list, ICLTerm **rest);
00075 EXTERN int oaa_remove_data_local(ICLTerm *clause1, ICLTerm *params);
00076 EXTERN int oaa_add_data_local(ICLTerm *clause1, ICLTerm *params);
00077 EXTERN int oaa_Inform(ICLTerm *type_info, char *format_string, ICLTerm *args);
00078 EXTERN int icl_param_arg(char *param, ICLTerm *value, ICLTerm *paramlist,
00079 ICLTerm **result);
00080 EXTERN int icl_standardize_params(ICLTerm *Params,int KeepDefaults,ICLTerm **Standardized);
00081 EXTERN int replace_element(ICLTerm *elt, ICLTerm *old_list, ICLTerm *new,
00082 ICLTerm **new_list);
00083 EXTERN ICLTerm* valid_oaa_solvables();
00084 EXTERN int oaa_data_matches_solvables(ICLTerm *Clause, ICLTerm *Solvables, ICLTerm *Perm,
00085 ICLTerm **RealClause, ICLTerm **RealMatched);
00086 EXTERN int oaa_class(char *class);
00087 EXTERN char* new_goal_id();
00088 EXTERN int oaa_poll_until_event(ICLTerm *event, ICLTerm **solution);
00089 EXTERN int icl_replace_param_value(ICLTerm *param, ICLTerm *param_list);
00090
00091 int oaa_remove_local_trigger_by_id(ICLTerm *trigger_id);
00092 int oaa_fire_trigger(ICLTerm *term);
00093
00094
00099 int oaa_CheckTriggers(char *type, ICLTerm *condition_var, char *op) {
00100
00101
00102
00103
00104
00105 ICLTerm *action_var = icl_NewVar("Action");
00106 ICLTerm *params_var = icl_NewVar("Params");
00107 ICLTerm *trigger_id_var = icl_NewVar("TriggerId");
00108 ICLTerm *op_as_term = icl_NewTermFromString(op);
00109
00110 ICLTerm *trigger_clause =
00111 icl_NewStruct("oaa_trigger", 5, trigger_id_var,
00112 icl_NewStr(type), icl_CopyTerm(condition_var), action_var, params_var);
00113 ICLTerm *dummyvar = icl_NewVar("_");
00114 ICLTerm *results=NULL;
00115 ICLTerm *t1;
00116 ICLTerm *temp_list=NULL;
00117 int i;
00118
00119
00120 struct dyn_array local_da;
00121
00122
00123
00124 temp_list=icl_NewList(NULL);
00125 if(oaa_solve_local(trigger_clause, temp_list, &results)) {
00126 if(icl_IsList(results)) {
00127 ICLListType *reslist = icl_List(results);
00128 ICLTerm *recurrence_term = icl_NewStruct("recurrence", 1, icl_CopyTerm(dummyvar));
00129 while(icl_list_has_more_elements(reslist)) {
00130 ICLTerm *trigger = icl_list_element(reslist);
00131 ICLTerm *op_specified = NULL, *op_mask = NULL, *test = NULL;
00132 ICLTerm *result = NULL, *r_as_term = NULL, *trigger_id = NULL, *action = NULL, *params = NULL, *condition = NULL;
00133 ICLTerm *arglist = NULL;
00134 ICLTerm *new_params = NULL;
00135
00136 trigger_id = icl_NthTerm(trigger, 1);
00137 condition = icl_NthTerm(trigger, 3);
00138 action = icl_NthTerm(trigger, 4);
00139 params = icl_NthTerm(trigger, 5);
00140
00141
00142
00143
00144
00145
00146 icl_init_dyn_array(&local_da);
00147 icl_match_terms(condition, condition_var, &local_da);
00148
00149 if(STREQ(type, "task") && !icl_IsVar(condition)) {
00150 t1 = icl_NewTermFromData("from(self)", 10);
00151 oaa_Interpret(condition, t1, NULL);
00152 icl_Free(t1);
00153 }
00154
00155 if(icl_param_arg("on", dummyvar, params, &op_specified)) {
00156 op_mask = op_specified;
00157 }
00158 else {
00159 op_mask = dummyvar;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 result = remove_element(recurrence_term, params, &new_params);
00184 if(result && icl_IsStruct(result)) {
00185 char *whenTrigger;
00186 r_as_term = icl_NthTerm(result, 1);
00187
00188 whenTrigger = icl_NewStringFromTerm(r_as_term);
00189 if(!STREQ(whenTrigger, "whenever")) {
00190 int r2;
00191 if(icl_IsInt(r_as_term)) {
00192 ICLTerm *mod_params, *newrecurterm, *newtrigger;
00193 ICLTerm *emptyList = icl_NewList(NULL);
00194
00195 r2 = icl_Int(r_as_term) - 1;
00196
00197 oaa_remove_data_local(trigger, emptyList);
00198 if (r2 > 0) {
00199 newrecurterm = icl_NewStruct("recurrence", 1,
00200 icl_NewInt(r2));
00201 mod_params =
00202 icl_NewList(icl_NewCons(newrecurterm, icl_List(new_params)));
00203 newtrigger =
00204 icl_NewStruct("oaa_trigger", 5, trigger_id, icl_NewStr(type),
00205 condition, action, mod_params);
00206 oaa_add_data_local(newtrigger, emptyList);
00207 }
00208 icl_Free(emptyList);
00209 }
00210 else {
00211 oaa_remove_local_trigger_by_id(trigger_id);
00212 }
00213 }
00214 icl_stFree(whenTrigger);
00215 }
00216 else {
00217
00218 oaa_remove_local_trigger_by_id(trigger_id);
00219 }
00220
00221 arglist =
00222 icl_NewList(
00223 icl_NewCons(
00224 icl_NewStr(type),
00225 icl_NewCons(op_as_term,
00226 icl_NewCons(condition,
00227 icl_NewCons(test,
00228 icl_NewCons(action, NULL))))));
00229
00230 oaa_TraceMsg("\n %s trigger fired %s\n Action: %s\n",
00231 icl_NewStringFromTerm(action),
00232 icl_NewStringFromTerm(condition),NULL);
00233
00234 if(!STREQ(type, "comm")) {
00235 arglist = icl_NewList(icl_NewCons(
00236 icl_NewStr(type), icl_NewCons(
00237 condition, icl_NewCons(
00238 action, icl_NewCons(
00239 params, NULL)))));
00240 oaa_Inform(trigger, "trigger_fired(%s, %s, %s, %s)\n", arglist);
00241 }
00242
00243 action = icl_copy_term_nonrec(action, &local_da);
00244
00245 {
00246 ICLTerm* toFree;
00247 for (i = 0; i < local_da.count; i = i + 2) {
00248 free(local_da.item[i]);
00249 toFree = (ICLTerm*)(local_da.item[i + 1]);
00250 icl_Free(toFree);
00251 }
00252 }
00253 free(local_da.item);
00254
00255 oaa_fire_trigger(action);
00256
00257 reslist = icl_list_next_element(reslist);
00258
00259 icl_Free(action);
00260 icl_Free(result);
00261 icl_Free(new_params);
00262 }
00263 icl_Free(recurrence_term);
00264 }
00265 }
00266 icl_Free(trigger_clause);
00267 icl_Free(dummyvar);
00268 icl_Free(op_as_term);
00269 icl_Free(results);
00270 icl_Free(temp_list);
00271 return TRUE;
00272 }
00273
00274 int oaa_fire_trigger(ICLTerm *term) {
00275 ICLTerm *new_params = NULL, *me, *from_me_list;
00276 int res;
00277 if(icl_IsStruct(term)) {
00278 char* functor = icl_Functor(term);
00279 if(STREQ(functor, "oaa_Solve")) {
00280 if(icl_Arity(term) == 2) {
00281 ICLTerm *goal = icl_NthTerm(term, 1);
00282 ICLTerm *params = icl_NthTerm(term, 2);
00283 if(icl_ParamValue("block", NULL, params, NULL)) {
00284 new_params = icl_CopyTerm(params);
00285 }
00286 else {
00287 ICLTerm *t1 = icl_NewTermFromData("[block(false)]", 14);
00288 icl_append_to_list(t1, params, &new_params);
00289 icl_Free(t1);
00290 }
00291 res = oaa_Solve(goal, new_params, NULL, NULL);
00292 icl_Free(new_params);
00293 return res;
00294 }
00295 else if(icl_Arity(term) == 1) {
00296 ICLTerm *goal = icl_NthTerm(term, 1);
00297 new_params = icl_NewTermFromData("[block(false)]", 14);
00298 res = oaa_Solve(goal, new_params, NULL, NULL);
00299 icl_Free(new_params);
00300 return res;
00301 }
00302 }
00303 else if(STREQ(functor, "oaa_Interpret")) {
00304 if(icl_Arity(term) == 2) {
00305 ICLTerm *goal = icl_NthTerm(term, 1);
00306 ICLTerm *params = icl_NthTerm(term, 2);
00307 if(icl_ParamValue("from", NULL, params, NULL)) {
00308
00309 new_params = icl_CopyTerm(params);
00310 }
00311 else {
00312 oaa_Id(&me);
00313 from_me_list = icl_NewList(icl_NewCons(icl_NewStruct("from", 1,
00314 me),
00315 NULL));
00316 icl_append_to_list(from_me_list, params, &new_params);
00317 }
00318 res = oaa_Interpret(goal, new_params, NULL);
00319 icl_Free(new_params);
00320 return res;
00321 }
00322 else if(icl_Arity(term) == 1) {
00323 oaa_Id(&me);
00324 from_me_list =
00325 icl_NewList(
00326 icl_NewCons(icl_NewStruct("from", 1,
00327 icl_CopyTerm(me)),
00328 NULL));
00329 res = oaa_Interpret(term, from_me_list, NULL);
00330 icl_Free(from_me_list);
00331 icl_Free(me);
00332 return res;
00333 }
00334 }
00335 }
00336 oaa_Id(&me);
00337 from_me_list =
00338 icl_NewList(
00339 icl_NewCons(
00340 icl_NewStruct("from", 1,
00341 icl_CopyTerm(me)),
00342 NULL));
00343 res = oaa_Interpret(term, from_me_list, NULL);
00344 icl_Free(from_me_list);
00345 icl_Free(me);
00346 return res;
00347 }
00348
00349
00350
00351
00352
00353 int oaa_update_trigger(char *mode, char* type, ICLTerm* condition, ICLTerm* action,
00354 ICLTerm* in_params, ICLTerm** out_params){
00355 ICLTerm *t1 = NULL, *local_condition = NULL;
00356 ICLTerm *params = NULL, *params1 = NULL, *params2 = NULL;
00357 ICLTerm *new_addr = NULL, *addr = NULL;
00358 ICLTerm *me = NULL;
00359 ICLTerm *updaters1 = NULL, *requestees1 = NULL;
00360 ICLTerm *updaters2 = NULL, *requestees2 = NULL;
00361 ICLTerm *reflexive_true = icl_NewTermFromData("reflexive(true)", 15);
00362 ICLTerm *updaters = (ICLTerm *)NULL;
00363 ICLTerm *requestees = (ICLTerm *)NULL;
00364 ICLTerm* solvables = NULL;
00365
00366 int res = FALSE, self = FALSE;
00367
00368
00369 if (STREQ(mode, "comm") && !icl_Unify(condition, t1 = icl_NewTermFromData("event(A,B)", 10), NULL)) {
00370 local_condition = icl_NewStruct("event", 2, condition, icl_NewVar("X"));
00371 }
00372 else {
00373 local_condition = icl_CopyTerm(condition);
00374 }
00375 icl_Free(t1);
00376
00377
00378 if (icl_IsList(in_params)) {
00379 icl_standardize_params(in_params, 0, ¶ms);
00380 }
00381 else {
00382 params = icl_NewList(NULL);
00383 }
00384
00385
00386 if (!icl_param_arg("address", NULL, params, &addr)) {
00387 addr = icl_NewList(NULL);
00388 }
00389
00390
00391 if (oaa_PrimaryAddress(&me) &&
00392 icl_Member(me, addr, NULL)) {
00393
00394 icl_ListDelete(addr, me, &new_addr);
00395 t1 = icl_NewStruct("address", 1, icl_CopyTerm(addr));
00396 replace_element(t1, params,
00397 icl_NewStruct("address", 1, new_addr), ¶ms1);
00398 icl_Free(t1);
00399 self = TRUE;
00400 } else {
00401 new_addr = icl_CopyTerm(addr);
00402 params1 = icl_CopyTerm(params);
00403 }
00404
00405 if ((!addr->p) &&
00406 icl_GetParamValue(reflexive_true, params1, NULL)) {
00407 ICLTerm *write = icl_NewStr("write");
00408 ICLTerm *real_clause, *real_matched;
00409
00410 icl_ListDelete(params1, reflexive_true, ¶ms2);
00411 solvables = valid_oaa_solvables();
00412 if (oaa_data_matches_solvables(local_condition, solvables, write, &real_clause,
00413 &real_matched))
00414 self = TRUE;
00415 icl_Free(write);
00416 } else {
00417 params2 = params1;
00418 }
00419 icl_Free(reflexive_true);
00420
00421
00422 if (self) {
00423 requestees1 = icl_NewList(icl_NewCons(icl_CopyTerm(me), NULL));
00424 if (STREQ(mode, "add"))
00425 res = oaa_add_trigger_local(type, local_condition, action, params2);
00426 else if (STREQ(mode, "remove"))
00427 res = oaa_remove_trigger_local(type, local_condition, action, params2);
00428 if(res) {
00429 updaters1 = icl_NewList(icl_NewCons(icl_CopyTerm(me), NULL));
00430 } else {
00431 updaters1 = icl_NewList(NULL);
00432 }
00433 } else {
00434 requestees1 = icl_NewList(NULL);
00435 updaters1 = icl_NewList(NULL);
00436 }
00437 icl_Free(me);
00438
00439
00440
00441 if (oaa_class("leaf") && ((!addr->p) || (new_addr->p))) {
00442 ICLTerm *reply;
00443 char *goalIdStr = new_goal_id();
00444
00445
00446
00447 ICLTerm* toBeSent = icl_NewStruct("ev_update_trigger", 6,
00448 icl_NewStr(goalIdStr), icl_NewStr(mode),
00449 icl_NewStr(type), icl_CopyTerm(local_condition),
00450 icl_CopyTerm(action), params2);
00451 oaa_PostEvent(toBeSent, ICL_EMPTY);
00452
00453
00454
00455
00456 requestees2 = icl_NewList(NULL);
00457 updaters2 = icl_NewList(NULL);
00458
00459 if (!(icl_param_arg("reply", NULL, params, &reply) &&
00460 (STREQ("asynchronous", icl_Str(reply)) ||
00461 STREQ("none", icl_Str(reply)))) ) {
00462 ICLTerm *ev_reply_updated =
00463 icl_NewStruct("ev_trigger_updated", 8, icl_NewVar("G"),
00464 icl_NewStr(mode), icl_NewStr(type),
00465 icl_CopyTerm(local_condition), icl_CopyTerm(action), icl_CopyTerm(params2),
00466 icl_NewVar("Requestees"), icl_NewVar("Updaters"));
00467 oaa_poll_until_event(ev_reply_updated, NULL);
00468 icl_Free(ev_reply_updated);
00469 }
00470 icl_Free(toBeSent);
00471 }
00472 icl_Free(addr);
00473 icl_Free(new_addr);
00474
00475
00476
00477
00478
00479 icl_append_to_list(updaters1, updaters2, &updaters);
00480 icl_Free(updaters1);
00481 icl_Free(updaters2);
00482
00483
00484
00485 t1 = icl_NewStruct("get_satisfiers", 1,
00486 updaters);
00487 icl_replace_param_value(t1, params);
00488 icl_Free(t1);
00489
00490
00491
00492 icl_append_to_list(requestees1, requestees2, &requestees);
00493 icl_replace_param_value((t1 = icl_NewStruct("get_address", 1,
00494 requestees)),
00495 params);
00496 icl_Free(requestees1);
00497 icl_Free(requestees2);
00498 icl_Free(t1);
00499
00500 if (out_params) {
00501 *out_params = params;
00502 }
00503
00504 if(params2 == params1) {
00505 icl_Free(params2);
00506 }
00507 else {
00508 icl_Free(params2);
00509 icl_Free(params1);
00510 }
00511
00512 icl_Free(local_condition);
00513 icl_Free(params);
00514 return TRUE;
00515
00516 };
00517
00558 int oaa_AddTrigger(char *type, ICLTerm *condition, ICLTerm *action,
00559 ICLTerm *initial_params, ICLTerm **out_params) {
00560 return oaa_update_trigger("add", type, condition, action,
00561 initial_params, out_params);
00562 }
00563
00567 int oaa_RemoveTrigger(char *type, ICLTerm *condition,
00568 ICLTerm *action, ICLTerm *initial_params,
00569 ICLTerm **out_params) {
00570 return oaa_update_trigger("remove", type, condition, action,
00571 initial_params, out_params);
00572 }
00573
00574 int oaa_add_trigger_local(char *type, ICLTerm *condition, ICLTerm *action,
00575 ICLTerm *params)
00576 {
00577 static int cntr = 0;
00578 char trigger_id[32];
00579 int res;
00580 ICLTerm *t1;
00581 ICLTerm *trigger;
00582
00583 sprintf(trigger_id, "trg%d", cntr++);
00584
00585 t1 = icl_NewList(NULL);
00586 trigger = icl_NewStruct("oaa_trigger", 5,
00587 icl_NewStr(trigger_id),
00588 icl_NewStr(type),
00589 icl_CopyTerm(condition),
00590 icl_CopyTerm(action),
00591 icl_CopyTerm(params));
00592 res = oaa_add_data_local(trigger, t1);
00593 icl_Free(t1);
00594 icl_Free(trigger);
00595 return res;
00596 }
00597
00598 int oaa_remove_trigger_local(char *type, ICLTerm *condition, ICLTerm *action,
00599 ICLTerm *params)
00600 {
00601 int res;
00602 ICLTerm *tid_var = icl_NewVar("_trigger_id");
00603 ICLTerm *trigger_term = icl_NewStruct("oaa_trigger", 5, tid_var,
00604 icl_NewStr(type),
00605 icl_CopyTerm(condition),
00606 icl_CopyTerm(action),
00607 icl_CopyTerm(params));
00608 ICLTerm *t1;
00609
00610 t1 = icl_NewList(NULL);
00611 res = oaa_remove_data_local(trigger_term, t1);
00612 icl_Free(trigger_term);
00613 icl_Free(tid_var);
00614 icl_Free(t1);
00615
00616 return res;
00617 }
00618
00622 int oaa_remove_local_trigger_by_id(ICLTerm *trigger_id)
00623 {
00624 ICLTerm *dummyvar = icl_NewVar("_");
00625 ICLTerm *trigger_term = icl_NewStruct("oaa_trigger", 5,
00626 icl_CopyTerm(trigger_id),
00627 icl_CopyTerm(dummyvar),
00628 icl_CopyTerm(dummyvar),
00629 icl_CopyTerm(dummyvar),
00630 icl_CopyTerm(dummyvar));
00631 ICLTerm *t1;
00632
00633 t1 = icl_NewList(NULL);
00634 oaa_remove_data_local(trigger_term, t1);
00635 icl_Free(trigger_term);
00636 icl_Free(dummyvar);
00637 icl_Free(t1);
00638 return TRUE;
00639 }
00640