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
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #include "soarkernel.h"
00051 #include <ctype.h>
00052 #include "soar_core_utils.h"
00053 #include "explain.h"
00054
00055 extern byte type_of_existing_impasse(Symbol * goal);
00056 extern wme *find_impasse_wme(Symbol * id, Symbol * attr);
00057 extern void find_match_goal(instantiation * inst);
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 void add_results_for_id(Symbol * id);
00076 #ifdef DONT_CALC_GDS_OR_BT
00077 static void add_named_superstate_attribute_to_grounds(instantiation * inst, char *name);
00078 #endif
00079
00080 #ifdef SINGLE_THIN_JUSTIFICATION
00081 void deallocate_inst_members_to_be_rewritten(instantiation * inst);
00082 void second_stage_chunk_instantiation(instantiation * inst);
00083 void re_fill_in_instantiation_stuff_for_modified_lhs(instantiation * inst, bool need_to_do_support_calculations);
00084
00085 #endif
00086
00087 #define add_results_if_needed(sym) \
00088 { if ((sym)->common.symbol_type==IDENTIFIER_SYMBOL_TYPE) \
00089 if ( ((sym)->id.level >= current_agent(results_match_goal_level)) && \
00090 ((sym)->id.tc_num != current_agent(results_tc_number)) ) \
00091 add_results_for_id(sym); }
00092
00093 void add_pref_to_results(preference * pref)
00094 {
00095 preference *p;
00096
00097
00098 for (p = current_agent(results); p != NIL; p = p->next_result) {
00099 if (p->id != pref->id)
00100 continue;
00101 if (p->attr != pref->attr)
00102 continue;
00103 if (p->value != pref->value)
00104 continue;
00105 if (p->type != pref->type)
00106 continue;
00107 if (preference_is_unary(pref->type))
00108 return;
00109 if (p->referent != pref->referent)
00110 continue;
00111 return;
00112 }
00113
00114 #ifdef NO_TOP_JUST
00115
00116 if (pref->match_goal_level != current_agent(results_match_goal_level)) {
00117 for (p = pref->next_clone; p != NIL; p = p->next_clone)
00118 if (p->match_goal_level == current_agent(results_match_goal_level))
00119 break;
00120 if (!p)
00121 for (p = pref->prev_clone; p != NIL; p = p->prev_clone)
00122 if (p->match_goal_level == current_agent(results_match_goal_level))
00123 break;
00124 if (!p)
00125 return;
00126 pref = p;
00127 }
00128 #else
00129
00130
00131 if (pref->inst->match_goal_level != current_agent(results_match_goal_level)) {
00132 for (p = pref->next_clone; p != NIL; p = p->next_clone)
00133 if (p->inst->match_goal_level == current_agent(results_match_goal_level))
00134 break;
00135 if (!p)
00136 for (p = pref->prev_clone; p != NIL; p = p->prev_clone)
00137 if (p->inst->match_goal_level == current_agent(results_match_goal_level))
00138 break;
00139 if (!p)
00140 return;
00141 pref = p;
00142 }
00143 #endif
00144
00145
00146 pref->next_result = current_agent(results);
00147 current_agent(results) = pref;
00148
00149
00150 add_results_if_needed(pref->value);
00151 if (preference_is_binary(pref->type))
00152 add_results_if_needed(pref->referent);
00153 }
00154
00155 void add_results_for_id(Symbol * id)
00156 {
00157 slot *s;
00158 preference *pref;
00159 wme *w;
00160
00161 id->id.tc_num = current_agent(results_tc_number);
00162
00163
00164 for (w = id->id.input_wmes; w != NIL; w = w->next)
00165 add_results_if_needed(w->value);
00166 for (s = id->id.slots; s != NIL; s = s->next) {
00167 for (pref = s->all_preferences; pref != NIL; pref = pref->all_of_slot_next)
00168 add_pref_to_results(pref);
00169 for (w = s->wmes; w != NIL; w = w->next)
00170 add_results_if_needed(w->value);
00171 }
00172
00173 for (pref = current_agent(extra_result_prefs_from_instantiation); pref != NIL; pref = pref->inst_next) {
00174 if (pref->id == id)
00175 add_pref_to_results(pref);
00176 }
00177 }
00178
00179 preference *get_results_for_instantiation(instantiation * inst)
00180 {
00181 preference *pref;
00182
00183 current_agent(results) = NIL;
00184 current_agent(results_match_goal_level) = inst->match_goal_level;
00185 current_agent(results_tc_number) = get_new_tc_number();
00186 current_agent(extra_result_prefs_from_instantiation) = inst->preferences_generated;
00187 for (pref = inst->preferences_generated; pref != NIL; pref = pref->inst_next)
00188 if ((pref->id->id.level < current_agent(results_match_goal_level)) &&
00189 (pref->id->id.tc_num != current_agent(results_tc_number))) {
00190 add_pref_to_results(pref);
00191
00192 }
00193 return current_agent(results);
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 void variablize_symbol(Symbol ** sym)
00219 {
00220 char prefix[2];
00221 Symbol *var;
00222
00223 if ((*sym)->common.symbol_type != IDENTIFIER_SYMBOL_TYPE)
00224 return;
00225 if (!current_agent(variablize_this_chunk))
00226 return;
00227
00228 if ((*sym)->id.tc_num == current_agent(variablization_tc)) {
00229
00230 var = (*sym)->id.variablization;
00231 symbol_remove_ref(*sym);
00232 *sym = var;
00233 symbol_add_ref(var);
00234 return;
00235 }
00236
00237
00238 (*sym)->id.tc_num = current_agent(variablization_tc);
00239 prefix[0] = (char) tolower((*sym)->id.name_letter);
00240 prefix[1] = 0;
00241 var = generate_new_variable(prefix);
00242 (*sym)->id.variablization = var;
00243 symbol_remove_ref(*sym);
00244 *sym = var;
00245 }
00246
00247 void variablize_test(test * t)
00248 {
00249 cons *c;
00250 complex_test *ct;
00251
00252 if (test_is_blank_test(*t))
00253 return;
00254 if (test_is_blank_or_equality_test(*t)) {
00255 variablize_symbol((Symbol **) t);
00256
00257 return;
00258 }
00259
00260 ct = complex_test_from_test(*t);
00261
00262 switch (ct->type) {
00263 case GOAL_ID_TEST:
00264 case IMPASSE_ID_TEST:
00265 case DISJUNCTION_TEST:
00266 return;
00267 case CONJUNCTIVE_TEST:
00268 for (c = ct->data.conjunct_list; c != NIL; c = c->rest)
00269 variablize_test((test *) (&(c->first)));
00270 return;
00271 default:
00272 variablize_symbol(&(ct->data.referent));
00273 return;
00274 }
00275 }
00276
00277 void variablize_condition_list(condition * cond)
00278 {
00279 for (; cond != NIL; cond = cond->next) {
00280 switch (cond->type) {
00281 case POSITIVE_CONDITION:
00282 case NEGATIVE_CONDITION:
00283 variablize_test(&(cond->data.tests.id_test));
00284 variablize_test(&(cond->data.tests.attr_test));
00285 variablize_test(&(cond->data.tests.value_test));
00286 break;
00287 case CONJUNCTIVE_NEGATION_CONDITION:
00288 variablize_condition_list(cond->data.ncc.top);
00289 break;
00290 }
00291 }
00292 }
00293
00294 action *copy_and_variablize_result_list(preference * pref)
00295 {
00296 action *a;
00297 Symbol *temp;
00298
00299 if (!pref)
00300 return NIL;
00301 allocate_with_pool(¤t_agent(action_pool), &a);
00302 a->type = MAKE_ACTION;
00303
00304 temp = pref->id;
00305 symbol_add_ref(temp);
00306 variablize_symbol(&temp);
00307 a->id = symbol_to_rhs_value(temp);
00308
00309 temp = pref->attr;
00310 symbol_add_ref(temp);
00311 variablize_symbol(&temp);
00312 a->attr = symbol_to_rhs_value(temp);
00313
00314 temp = pref->value;
00315 symbol_add_ref(temp);
00316 variablize_symbol(&temp);
00317 a->value = symbol_to_rhs_value(temp);
00318
00319 a->preference_type = pref->type;
00320
00321 if (preference_is_binary(pref->type)) {
00322 temp = pref->referent;
00323 symbol_add_ref(temp);
00324 variablize_symbol(&temp);
00325 a->referent = symbol_to_rhs_value(temp);
00326 }
00327
00328 a->next = copy_and_variablize_result_list(pref->next_result);
00329 return a;
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 void init_chunk_cond_set(chunk_cond_set * set)
00377 {
00378 int i;
00379
00380 set->all = NIL;
00381 for (i = 0; i < CHUNK_COND_HASH_TABLE_SIZE; i++)
00382 set->table[i] = NIL;
00383 }
00384
00385 chunk_cond *make_chunk_cond_for_condition(condition * cond)
00386 {
00387 chunk_cond *cc;
00388 unsigned long remainder, hv;
00389
00390 allocate_with_pool(¤t_agent(chunk_cond_pool), &cc);
00391 cc->cond = cond;
00392 cc->hash_value = hash_condition(cond);
00393 remainder = cc->hash_value;
00394 hv = 0;
00395 while (remainder) {
00396 hv ^= (remainder & masks_for_n_low_order_bits[LOG_2_CHUNK_COND_HASH_TABLE_SIZE]);
00397 remainder = remainder >> LOG_2_CHUNK_COND_HASH_TABLE_SIZE;
00398 }
00399 cc->compressed_hash_value = hv;
00400 return cc;
00401 }
00402
00403 bool add_to_chunk_cond_set(chunk_cond_set * set, chunk_cond * new_cc)
00404 {
00405 chunk_cond *old;
00406
00407 for (old = set->table[new_cc->compressed_hash_value]; old != NIL; old = old->next_in_bucket)
00408 if (old->hash_value == new_cc->hash_value)
00409 if (conditions_are_equal(old->cond, new_cc->cond))
00410 break;
00411 if (old) {
00412
00413 free_with_pool(¤t_agent(chunk_cond_pool), new_cc);
00414 return FALSE;
00415 }
00416
00417 insert_at_head_of_dll(set->all, new_cc, next, prev);
00418 insert_at_head_of_dll(set->table[new_cc->compressed_hash_value], new_cc, next_in_bucket, prev_in_bucket);
00419 return TRUE;
00420 }
00421
00422 void remove_from_chunk_cond_set(chunk_cond_set * set, chunk_cond * cc)
00423 {
00424 remove_from_dll(set->all, cc, next, prev);
00425 remove_from_dll(set->table[cc->compressed_hash_value], cc, next_in_bucket, prev_in_bucket);
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 void build_chunk_conds_for_grounds_and_add_negateds(chunk_cond ** dest_top,
00456 chunk_cond ** dest_bottom, tc_number tc_to_use)
00457 {
00458 cons *c;
00459 condition *ground;
00460 chunk_cond *cc, *first_cc, *prev_cc;
00461
00462 first_cc = NIL;
00463
00464
00465 prev_cc = NIL;
00466 while (current_agent(grounds)) {
00467 c = current_agent(grounds);
00468 current_agent(grounds) = current_agent(grounds)->rest;
00469 ground = c->first;
00470 free_cons(c);
00471
00472 allocate_with_pool(¤t_agent(chunk_cond_pool), &cc);
00473 cc->cond = ground;
00474 cc->instantiated_cond = copy_condition(cc->cond);
00475 cc->variablized_cond = copy_condition(cc->cond);
00476 if (prev_cc) {
00477 prev_cc->next = cc;
00478 cc->prev = prev_cc;
00479 cc->variablized_cond->prev = prev_cc->variablized_cond;
00480 prev_cc->variablized_cond->next = cc->variablized_cond;
00481 } else {
00482 first_cc = cc;
00483 cc->prev = NIL;
00484 cc->variablized_cond->prev = NIL;
00485 }
00486 prev_cc = cc;
00487
00488 add_cond_to_tc(ground, tc_to_use, NIL, NIL);
00489 }
00490
00491 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
00492
00493
00494
00495 if (current_agent(sysparams)[TRACE_BACKTRACING_SYSPARAM])
00496 print_string("\n\n*** Adding Grounded Negated Conditions ***\n");
00497 #endif
00498
00499 while (current_agent(negated_set).all) {
00500 cc = current_agent(negated_set).all;
00501 remove_from_chunk_cond_set(¤t_agent(negated_set), cc);
00502 if (cond_is_in_tc(cc->cond, tc_to_use)) {
00503
00504 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
00505
00506 if (current_agent(sysparams)[TRACE_BACKTRACING_SYSPARAM]) {
00507 print_string("\n-->Moving to grounds: ");
00508 print_condition(cc->cond);
00509 }
00510 #endif
00511
00512 cc->instantiated_cond = copy_condition(cc->cond);
00513 cc->variablized_cond = copy_condition(cc->cond);
00514 if (prev_cc) {
00515 prev_cc->next = cc;
00516 cc->prev = prev_cc;
00517 cc->variablized_cond->prev = prev_cc->variablized_cond;
00518 prev_cc->variablized_cond->next = cc->variablized_cond;
00519 } else {
00520 first_cc = cc;
00521 cc->prev = NIL;
00522 cc->variablized_cond->prev = NIL;
00523 }
00524 prev_cc = cc;
00525 } else {
00526
00527 free_with_pool(¤t_agent(chunk_cond_pool), cc);
00528 }
00529 }
00530
00531 if (prev_cc) {
00532 prev_cc->next = NIL;
00533 prev_cc->variablized_cond->next = NIL;
00534 } else {
00535 first_cc = NIL;
00536 }
00537
00538 *dest_top = first_cc;
00539 *dest_bottom = prev_cc;
00540 }
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551 not *get_nots_for_instantiated_conditions(list * instantiations_with_nots, tc_number tc_of_grounds)
00552 {
00553 cons *c;
00554 instantiation *inst;
00555 not *n1, *n2, *new_not, *collected_nots;
00556
00557
00558 collected_nots = NIL;
00559 while (instantiations_with_nots) {
00560 c = instantiations_with_nots;
00561 instantiations_with_nots = c->rest;
00562 inst = c->first;
00563 free_cons(c);
00564 for (n1 = inst->nots; n1 != NIL; n1 = n1->next) {
00565
00566 if (n1->s1->id.tc_num != tc_of_grounds)
00567 continue;
00568 if (n1->s2->id.tc_num != tc_of_grounds)
00569 continue;
00570
00571 for (n2 = collected_nots; n2 != NIL; n2 = n2->next) {
00572 if ((n2->s1 == n1->s1) && (n2->s2 == n1->s2))
00573 break;
00574 if ((n2->s1 == n1->s2) && (n2->s2 == n1->s1))
00575 break;
00576 }
00577 if (n2)
00578 continue;
00579
00580 allocate_with_pool(¤t_agent(not_pool), &new_not);
00581 new_not->next = collected_nots;
00582 collected_nots = new_not;
00583 new_not->s1 = n1->s1;
00584 symbol_add_ref(new_not->s1);
00585 new_not->s2 = n1->s2;
00586 symbol_add_ref(new_not->s2);
00587 }
00588 }
00589
00590 return collected_nots;
00591 }
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604 void variablize_nots_and_insert_into_conditions(not * nots, condition * conds)
00605 {
00606 not *n;
00607 Symbol *var1, *var2;
00608 test t;
00609 complex_test *ct;
00610 condition *c;
00611 bool added_it;
00612
00613
00614 if (!current_agent(variablize_this_chunk))
00615 return;
00616
00617 for (n = nots; n != NIL; n = n->next) {
00618 var1 = n->s1->id.variablization;
00619 var2 = n->s2->id.variablization;
00620
00621 allocate_with_pool(¤t_agent(complex_test_pool), &ct);
00622 t = make_test_from_complex_test(ct);
00623 ct->type = NOT_EQUAL_TEST;
00624 ct->data.referent = var2;
00625 symbol_add_ref(var2);
00626 added_it = FALSE;
00627 for (c = conds; c != NIL; c = c->next) {
00628 if (c->type != POSITIVE_CONDITION)
00629 continue;
00630 if (test_includes_equality_test_for_symbol(c->data.tests.id_test, var1)) {
00631 add_new_test_to_test(&(c->data.tests.id_test), t);
00632 added_it = TRUE;
00633 break;
00634 }
00635 if (test_includes_equality_test_for_symbol(c->data.tests.attr_test, var1)) {
00636 add_new_test_to_test(&(c->data.tests.attr_test), t);
00637 added_it = TRUE;
00638 break;
00639 }
00640 if (test_includes_equality_test_for_symbol(c->data.tests.value_test, var1)) {
00641 add_new_test_to_test(&(c->data.tests.value_test), t);
00642 added_it = TRUE;
00643 break;
00644 }
00645 }
00646 if (!added_it) {
00647 char msg[MESSAGE_SIZE];
00648 strncpy(msg, "chunk.c: Internal error: couldn't add Not test to chunk\n", MESSAGE_SIZE);
00649 msg[MESSAGE_SIZE - 1] = 0;
00650 abort_with_fatal_error(msg);
00651 }
00652 }
00653 }
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 void add_goal_or_impasse_tests(chunk_cond * all_ccs)
00669 {
00670 chunk_cond *cc;
00671 tc_number tc;
00672
00673 Symbol *id;
00674 test t;
00675 complex_test *ct;
00676
00677 tc = get_new_tc_number();
00678 for (cc = all_ccs; cc != NIL; cc = cc->next) {
00679 if (cc->instantiated_cond->type != POSITIVE_CONDITION)
00680 continue;
00681 id = referent_of_equality_test(cc->instantiated_cond->data.tests.id_test);
00682 if ((id->id.isa_goal || id->id.isa_impasse) && (id->id.tc_num != tc)) {
00683 allocate_with_pool(¤t_agent(complex_test_pool), &ct);
00684 ct->type = (char) ((id->id.isa_goal) ? GOAL_ID_TEST : IMPASSE_ID_TEST);
00685 t = make_test_from_complex_test(ct);
00686 add_new_test_to_test(&(cc->variablized_cond->data.tests.id_test), t);
00687 id->id.tc_num = tc;
00688 }
00689 }
00690 }
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 void reorder_instantiated_conditions(chunk_cond * top_cc, condition ** dest_inst_top, condition ** dest_inst_bottom)
00722 {
00723 chunk_cond *cc;
00724
00725
00726
00727
00728 for (cc = top_cc; cc != NIL; cc = cc->next) {
00729 cc->saved_prev_pointer_of_variablized_cond = cc->variablized_cond->prev;
00730 cc->variablized_cond->prev = cc->instantiated_cond;
00731 }
00732
00733
00734 for (cc = top_cc; cc != NIL; cc = cc->next) {
00735 if (cc->variablized_cond->next) {
00736 cc->instantiated_cond->next = cc->variablized_cond->next->prev;
00737 } else {
00738 cc->instantiated_cond->next = NIL;
00739 *dest_inst_bottom = cc->instantiated_cond;
00740 }
00741
00742 if (cc->saved_prev_pointer_of_variablized_cond) {
00743 cc->instantiated_cond->prev = cc->saved_prev_pointer_of_variablized_cond->prev;
00744 } else {
00745 cc->instantiated_cond->prev = NIL;
00746 *dest_inst_top = cc->instantiated_cond;
00747 }
00748 }
00749
00750
00751 for (cc = top_cc; cc != NIL; cc = cc->next) {
00752 cc->variablized_cond->prev = cc->saved_prev_pointer_of_variablized_cond;
00753 }
00754 }
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765 void make_clones_of_results(preference * results, instantiation * chunk_inst)
00766 {
00767 preference *p, *result_p;
00768
00769 chunk_inst->preferences_generated = NIL;
00770 for (result_p = results; result_p != NIL; result_p = result_p->next_result) {
00771
00772 p = make_preference(result_p->type, result_p->id, result_p->attr, result_p->value, result_p->referent);
00773 symbol_add_ref(p->id);
00774 symbol_add_ref(p->attr);
00775 symbol_add_ref(p->value);
00776 if (preference_is_binary(p->type))
00777 symbol_add_ref(p->referent);
00778
00779 p->inst = chunk_inst;
00780 insert_at_head_of_dll(chunk_inst->preferences_generated, p, inst_next, inst_prev);
00781
00782 p->next_clone = result_p;
00783 p->prev_clone = result_p->prev_clone;
00784 result_p->prev_clone = p;
00785 if (p->prev_clone)
00786 p->prev_clone->next_clone = p;
00787 }
00788 }
00789
00790
00791 Symbol *find_goal_at_goal_stack_level(goal_stack_level level)
00792 {
00793 Symbol *g;
00794
00795 for (g = current_agent(top_goal); g != NIL; g = g->id.lower_goal)
00796 if (g->id.level == level)
00797 return (g);
00798 return (NIL);
00799 }
00800
00801 Symbol *find_impasse_wme_value(Symbol * id, Symbol * attr)
00802 {
00803 wme *w;
00804
00805 for (w = id->id.impasse_wmes; w != NIL; w = w->next)
00806 if (w->attr == attr)
00807 return w->value;
00808 return NIL;
00809 }
00810
00811 #define NAME_SIZE 512
00812 #define IMPASS_NAME_SIZE 32
00813 Symbol *generate_chunk_name_sym_constant(instantiation * inst)
00814 {
00815 char name[NAME_SIZE];
00816 char impass_name[IMPASS_NAME_SIZE];
00817 Symbol *generated_name;
00818 Symbol *goal;
00819 byte impasse_type;
00820 preference *p;
00821 goal_stack_level lowest_result_level;
00822
00823 if (!current_agent(sysparams)[USE_LONG_CHUNK_NAMES])
00824 return (generate_new_sym_constant(current_agent(chunk_name_prefix), ¤t_agent(chunk_count)));
00825
00826 lowest_result_level = current_agent(top_goal)->id.level;
00827 for (p = inst->preferences_generated; p != NIL; p = p->inst_next)
00828 if (p->id->id.level > lowest_result_level)
00829 lowest_result_level = p->id->id.level;
00830
00831 goal = find_goal_at_goal_stack_level(lowest_result_level);
00832
00833 if (goal) {
00834 impasse_type = type_of_existing_impasse(goal);
00835
00836
00837
00838
00839
00840
00841
00842 switch (impasse_type) {
00843 case NONE_IMPASSE_TYPE:
00844 print("Internal error: impasse_type is NONE_IMPASSE_TYPE during chunk creation.\n");
00845 strncpy(impass_name, "unknownimpasse", IMPASS_NAME_SIZE);
00846 break;
00847 case CONSTRAINT_FAILURE_IMPASSE_TYPE:
00848 strncpy(impass_name, "cfailure", IMPASS_NAME_SIZE);
00849 break;
00850 case CONFLICT_IMPASSE_TYPE:
00851 strncpy(impass_name, "conflict", IMPASS_NAME_SIZE);
00852 break;
00853 case TIE_IMPASSE_TYPE:
00854 strncpy(impass_name, "tie", IMPASS_NAME_SIZE);
00855 break;
00856 case NO_CHANGE_IMPASSE_TYPE:
00857 {
00858 Symbol *sym;
00859
00860 if ((sym = find_impasse_wme_value(goal->id.lower_goal, current_agent(attribute_symbol))) == NIL) {
00861 #ifdef DEBUG_CHUNK_NAMES
00862 print("Internal error: Failed to find ^attribute impasse wme.\n");
00863 do_print_for_identifier(goal->id.lower_goal, 1, 0);
00864 #endif
00865 strncpy(impass_name, "unknownimpasse", IMPASS_NAME_SIZE);
00866 } else if (sym == current_agent(operator_symbol)) {
00867 strncpy(impass_name, "opnochange", IMPASS_NAME_SIZE);
00868 } else if (sym == current_agent(state_symbol)) {
00869 strncpy(impass_name, "snochange", IMPASS_NAME_SIZE);
00870 } else {
00871 #ifdef DEBUG_CHUNK_NAMES
00872 print("Internal error: ^attribute impasse wme has unexpected value.\n");
00873 #endif
00874 strncpy(impass_name, "unknownimpasse", IMPASS_NAME_SIZE);
00875 }
00876 }
00877 break;
00878 default:
00879 print("Internal error: encountered unknown impasse_type: %d.\n", impasse_type);
00880 strncpy(impass_name, "unknownimpasse", IMPASS_NAME_SIZE);
00881 break;
00882 }
00883 } else {
00884 print("Internal error: Failed to determine impasse type.\n");
00885 strncpy(impass_name, "unknownimpasse", IMPASS_NAME_SIZE);
00886 }
00887 impass_name[IMPASS_NAME_SIZE - 1] = 0;
00888
00889 snprintf(name, NAME_SIZE, "%s-%lu*d%lu*%s*%lu",
00890 current_agent(chunk_name_prefix),
00891 current_agent(chunk_count++), current_agent(d_cycle_count), impass_name, current_agent(chunks_this_d_cycle)
00892 );
00893 name[NAME_SIZE - 1] = 0;
00894
00895
00896 if (find_sym_constant(name)) {
00897 unsigned long collision_count;
00898
00899 collision_count = 1;
00900 print("Warning: generated chunk name already exists. Will find unique name.\n");
00901 do {
00902 snprintf(name, NAME_SIZE, "%s-%lu*d%lu*%s*%lu*%lu",
00903 current_agent(chunk_name_prefix),
00904 current_agent(chunk_count++),
00905 current_agent(d_cycle_count), impass_name, current_agent(chunks_this_d_cycle), collision_count++);
00906 name[NAME_SIZE - 1] = 0;
00907 } while (find_sym_constant(name));
00908 }
00909
00910 generated_name = make_sym_constant(name);
00911 return generated_name;
00912 }
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926 void chunk_instantiation(instantiation * inst, bool allow_variablization)
00927 {
00928 goal_stack_level grounds_level;
00929 preference *results, *pref;
00930 instantiation *chunk_inst;
00931 Symbol *prod_name;
00932 byte prod_type;
00933 bool print_name, print_prod;
00934
00935 condition *lhs_top, *lhs_bottom;
00936 not *nots;
00937 chunk_cond *top_cc, *bottom_cc;
00938 explain_chunk_str temp_explain_chunk;
00939
00940 #if !defined(THIN_JUSTIFICATIONS) || defined(MAKE_PRODUCTION_FOR_THIN_JUSTS)
00941 production *prod;
00942 action *rhs;
00943 #endif
00944
00945 #ifndef THIN_JUSTIFICATIONS
00946 byte rete_addition_result;
00947 #endif
00948
00949 #if !defined(NO_TIMING_STUFF) && defined(DETAILED_TIMING_STATS)
00950 struct timeval saved_start_tv;
00951 #endif
00952
00953
00954 temp_explain_chunk.conds = NULL;
00955 temp_explain_chunk.actions = NULL;
00956
00957
00958 if (!inst->match_goal)
00959 return;
00960
00961 #ifdef WATCH_PREFS_GENERATED
00962 print("\nPreferences Generated for instantiation at top of ci\n");
00963 print_instantiation_with_wmes(inst, TIMETAG_WME_TRACE);
00964 print("\n Instantiation Match Goal Level = %d", inst->match_goal_level);
00965 print("\n---------------------------------------------\n");
00966 for (pref = inst->preferences_generated; pref != NIL; pref = pref->inst_next) {
00967 watchful_print_preference(pref);
00968 print("Reference count = %d\n", pref->reference_count);
00969 }
00970 print("\n");
00971 #endif
00972
00973
00974 for (pref = inst->preferences_generated; pref != NIL; pref = pref->inst_next) {
00975 if (pref->id->id.level < inst->match_goal_level)
00976 break;
00977 }
00978 if (!pref)
00979 return;
00980
00981 #ifndef NO_TIMING_STUFF
00982 #ifdef DETAILED_TIMING_STATS
00983 start_timer(&saved_start_tv);
00984 #endif
00985 #endif
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018 #ifndef DONT_ALLOW_VARIABLIZATION
01019
01020 #ifndef SOAR_8_ONLY
01021 if (current_agent(operand2_mode) == TRUE) {
01022 #endif
01023
01024 if (current_agent(sysparams)[LEARNING_ON_SYSPARAM] == TRUE) {
01025 if (pref->id->id.level < (inst->match_goal_level - 1)) {
01026 allow_variablization = FALSE;
01027 inst->okay_to_variablize = FALSE;
01028
01029 if (current_agent(soar_verbose_flag) == TRUE)
01030 print("\n in chunk_instantiation: making justification only");
01031 }
01032
01033 else {
01034 allow_variablization = (bool) current_agent(sysparams)[LEARNING_ON_SYSPARAM];
01035 inst->okay_to_variablize = (byte) current_agent(sysparams)[LEARNING_ON_SYSPARAM];
01036
01037 if (current_agent(soar_verbose_flag) == TRUE)
01038 print("\n in chunk_instantiation: resetting allow_variablization to %s",
01039 ((allow_variablization) ? "TRUE" : "FALSE"));
01040 }
01041 }
01042
01043 #ifndef SOAR_8_ONLY
01044 }
01045 #endif
01046
01047 #else
01048
01049 inst->okay_to_variablize = FALSE;
01050
01051 #endif
01052
01053
01054
01055 results = get_results_for_instantiation(inst);
01056
01057 if (!results)
01058 goto chunking_done;
01059
01060 #ifdef OPTIMIZE_TOP_LEVEL_RESULTS
01061 {
01062 preference *the_temp_pref;
01063 bool optimize = TRUE;
01064 Symbol *top_level_goal = NIL;
01065
01066 for (the_temp_pref = inst->preferences_generated; the_temp_pref != NIL;
01067 the_temp_pref = the_temp_pref->inst_next) {
01068 if (the_temp_pref->id->id.level != 1) {
01069 optimize = FALSE;
01070 } else if (!top_level_goal && the_temp_pref->id->id.isa_goal) {
01071 top_level_goal = the_temp_pref->id;
01072 }
01073
01074 }
01075
01076 if (optimize) {
01077
01078
01079
01080
01081
01082
01083 allocate_with_pool(¤t_agent(instantiation_pool), &chunk_inst);
01084 chunk_inst->prod = NIL;
01085 chunk_inst->top_of_instantiated_conditions = NIL;
01086 chunk_inst->bottom_of_instantiated_conditions = NIL;
01087 chunk_inst->nots = NIL;
01088 chunk_inst->GDS_evaluated_already = FALSE;
01089 chunk_inst->okay_to_variablize = FALSE;
01090
01091 make_clones_of_results(results, chunk_inst);
01092 fill_in_new_instantiation_stuff(chunk_inst, FALSE);
01093
01094 for (the_temp_pref = chunk_inst->preferences_generated;
01095 the_temp_pref != NIL; the_temp_pref = the_temp_pref->inst_next) {
01096
01097
01098
01099
01100
01101 the_temp_pref->o_supported = TRUE;
01102 the_temp_pref->match_goal_level = 1;
01103 the_temp_pref->match_goal = top_level_goal;
01104
01105 }
01106
01107
01108
01109
01110 chunk_inst->match_goal = top_level_goal;
01111 chunk_inst->match_goal_level = 1;
01112 chunk_inst->in_ms = TRUE;
01113 chunk_inst->next = current_agent(newly_created_instantiations);
01114 current_agent(newly_created_instantiations) = chunk_inst;
01115
01116 goto chunking_done;
01117
01118 }
01119 }
01120 #endif
01121
01122 #ifdef WATCH_RESULTS
01123 {
01124 preference *the_temp_pref;
01125
01126 print("\nResults for instantiaition:\n");
01127 print_instantiation_with_wmes(inst, TIMETAG_WME_TRACE);
01128 print("\n---------------------------\n");
01129 for (the_temp_pref = results; the_temp_pref != NIL; the_temp_pref = the_temp_pref->next_result) {
01130 watchful_print_preference(the_temp_pref);
01131 print("References for id at top of chunk_inst = %d\n", the_temp_pref->id->common.reference_count);
01132
01133 }
01134 print("\n");
01135 }
01136 #endif
01137
01138 #ifdef WATCH_INST_CONDS
01139 print_with_symbols("\nIn chunk_instantiation.\nInst which will be chunked is: %y -- conditions:\n",
01140 inst->prod->name);
01141 print("Address %p\n", inst);
01142 print_condition_list(inst->top_of_instantiated_conditions, 2, TRUE);
01143 if (inst->top_of_instantiated_conditions == NIL) {
01144 print("There are no pointers here...\n");
01145 }
01146 #endif
01147
01148
01149 {
01150 Symbol *g;
01151 for (g = inst->match_goal->id.higher_goal; g && g->id.allow_bottom_up_chunks; g = g->id.higher_goal)
01152 g->id.allow_bottom_up_chunks = FALSE;
01153 }
01154
01155 grounds_level = (short) (inst->match_goal_level - 1);
01156
01157 current_agent(backtrace_number)++;
01158 if (current_agent(backtrace_number) == 0)
01159 current_agent(backtrace_number) = 1;
01160 current_agent(grounds_tc)++;
01161 if (current_agent(grounds_tc) == 0)
01162 current_agent(grounds_tc) = 1;
01163 current_agent(potentials_tc)++;
01164 if (current_agent(potentials_tc) == 0)
01165 current_agent(potentials_tc) = 1;
01166 current_agent(locals_tc)++;
01167 if (current_agent(locals_tc) == 0)
01168 current_agent(locals_tc) = 1;
01169 current_agent(grounds) = NIL;
01170 current_agent(positive_potentials) = NIL;
01171 current_agent(locals) = NIL;
01172 current_agent(instantiations_with_nots) = NIL;
01173
01174 #ifndef DONT_ALLOW_VARIABLIZATION
01175
01176 if (allow_variablization && (!current_agent(sysparams)[LEARNING_ALL_GOALS_SYSPARAM]))
01177 allow_variablization = inst->match_goal->id.allow_bottom_up_chunks;
01178
01179 #endif
01180
01181
01182
01183
01184 current_agent(chunk_free_flag) = FALSE;
01185
01186 current_agent(chunky_flag) = FALSE;
01187
01188 #ifndef DONT_ALLOW_VARIABLIZATION
01189
01190
01191 if (allow_variablization) {
01192
01193
01194
01195
01196
01197 if (current_agent(sysparams)[LEARNING_EXCEPT_SYSPARAM]) {
01198 if (member_of_list(inst->match_goal, current_agent(chunk_free_problem_spaces))) {
01199 allow_variablization = FALSE;
01200 current_agent(chunk_free_flag) = TRUE;
01201 }
01202 } else if (current_agent(sysparams)[LEARNING_ONLY_SYSPARAM]) {
01203 if (member_of_list(inst->match_goal, current_agent(chunky_problem_spaces))) {
01204 allow_variablization = TRUE;
01205 current_agent(chunky_flag) = TRUE;
01206 } else {
01207 allow_variablization = FALSE;
01208 current_agent(chunky_flag) = FALSE;
01209 }
01210 }
01211 }
01212
01213 current_agent(variablize_this_chunk) = allow_variablization;
01214
01215 #else
01216
01217 current_agent(variablize_this_chunk) = FALSE;
01218 #endif
01219
01220 #ifndef THIN_JUSTIFICATIONS
01221
01222
01223
01224 if (current_agent(sysparams)[EXPLAIN_SYSPARAM]) {
01225 temp_explain_chunk.conds = NULL;
01226 temp_explain_chunk.actions = NULL;
01227 temp_explain_chunk.backtrace = NULL;
01228 temp_explain_chunk.name[0] = '\0';
01229 temp_explain_chunk.all_grounds = NIL;
01230 temp_explain_chunk.next_chunk = NULL;
01231 reset_backtrace_list();
01232 }
01233 #endif
01234
01235 #ifndef NO_BACKTRACING
01236 #ifndef DONT_CALC_GDS_OR_BT
01237
01238
01239 for (pref = results; pref != NIL; pref = pref->next_result) {
01240
01241 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
01242 if (current_agent(sysparams)[TRACE_BACKTRACING_SYSPARAM]) {
01243 print_string("\nFor result preference ");
01244 print_preference(pref);
01245 print_string(" ");
01246 }
01247 #endif
01248
01249 #ifdef NO_TOP_JUST
01250 if (pref->inst)
01251 backtrace_through_instantiation(pref->inst, grounds_level, NULL, 0);
01252
01253 #else
01254 backtrace_through_instantiation(pref->inst, grounds_level, NULL, 0);
01255
01256 #endif
01257
01258 }
01259
01260 #else
01261 add_named_superstate_attribute_to_grounds(inst, "superstate");
01262 #endif
01263
01264 #endif
01265
01266 current_agent(quiescence_t_flag) = FALSE;
01267
01268 for (;;) {
01269 trace_locals(grounds_level);
01270 trace_grounded_potentials();
01271 if (!trace_ungrounded_potentials(grounds_level))
01272 break;
01273 }
01274 free_list(current_agent(positive_potentials));
01275
01276
01277 {
01278 tc_number tc_for_grounds;
01279 tc_for_grounds = get_new_tc_number();
01280 build_chunk_conds_for_grounds_and_add_negateds(&top_cc, &bottom_cc, tc_for_grounds);
01281 nots = get_nots_for_instantiated_conditions(current_agent(instantiations_with_nots), tc_for_grounds);
01282 }
01283
01284
01285
01286 #ifndef DONT_ALLOW_VARIABLIZATION
01287
01288 if (current_agent(variablize_this_chunk)) {
01289
01290 current_agent(chunks_this_d_cycle)++;
01291 prod_name = generate_chunk_name_sym_constant(inst);
01292
01293
01294 prod_type = CHUNK_PRODUCTION_TYPE;
01295 print_name = (bool) current_agent(sysparams)[TRACE_CHUNK_NAMES_SYSPARAM];
01296 print_prod = (bool) current_agent(sysparams)[TRACE_CHUNKS_SYSPARAM];
01297
01298 } else {
01299
01300 #endif
01301
01302 #ifdef THIN_JUSTIFICATIONS
01303 prod_name = generate_new_sym_constant("temp-justification-", ¤t_agent(justification_count));
01304 #else
01305 prod_name = generate_new_sym_constant("justification-", ¤t_agent(justification_count));
01306 #endif
01307
01308 prod_type = JUSTIFICATION_PRODUCTION_TYPE;
01309 print_name = (bool) current_agent(sysparams)[TRACE_JUSTIFICATION_NAMES_SYSPARAM];
01310 print_prod = (bool) current_agent(sysparams)[TRACE_JUSTIFICATIONS_SYSPARAM];
01311
01312 #ifndef DONT_ALLOW_VARIABLIZATION
01313 }
01314 #endif
01315
01316
01317 if (print_name) {
01318 if (get_printer_output_column() != 1)
01319 print("\n");
01320 print_with_symbols("Building %y", prod_name);
01321
01322 #if defined(THIN_JUSTIFICATIONS) && !defined(MAKE_PRODUCTION_FOR_THIN_JUSTS)
01323 print("...thin justification, no prod");
01324 #endif
01325
01326 }
01327
01328
01329
01330 if (!top_cc) {
01331 if (current_agent(sysparams)[PRINT_WARNINGS_SYSPARAM])
01332 print_string(" Warning: chunk has no grounds, ignoring it.");
01333 goto chunking_done;
01334 }
01335 #ifndef DONT_ALLOW_VARIABLIZATION
01336
01337
01338 if (current_agent(chunks_this_d_cycle) > (unsigned long) current_agent(sysparams)[MAX_CHUNKS_SYSPARAM]) {
01339 if (current_agent(sysparams)[PRINT_WARNINGS_SYSPARAM])
01340 print("\nWarning: reached max-chunks! Halting system.");
01341 current_agent(max_chunks_reached) = TRUE;
01342 goto chunking_done;
01343 }
01344 #endif
01345
01346
01347 lhs_top = top_cc->variablized_cond;
01348 lhs_bottom = bottom_cc->variablized_cond;
01349 reset_variable_generator(lhs_top, NIL);
01350 current_agent(variablization_tc) = get_new_tc_number();
01351 variablize_condition_list(lhs_top);
01352 variablize_nots_and_insert_into_conditions(nots, lhs_top);
01353 #if !defined(THIN_JUSTIFICATIONS) || defined(MAKE_PRODUCTION_FOR_THIN_JUSTS)
01354 rhs = copy_and_variablize_result_list(results);
01355 #endif
01356
01357
01358 add_goal_or_impasse_tests(top_cc);
01359
01360
01361 #if !defined(THIN_JUSTIFICATIONS) || defined(MAKE_PRODUCTION_FOR_THIN_JUSTS)
01362
01363 prod = make_production(prod_type, prod_name, &lhs_top, &lhs_bottom, &rhs, FALSE);
01364
01365 if (!prod) {
01366 print("\nUnable to reorder this chunk:\n ");
01367 print_condition_list(lhs_top, 2, FALSE);
01368 print("\n -->\n ");
01369 print_action_list(rhs, 3, FALSE);
01370 print("\n\n(Ignoring this chunk. Weird things could happen from now on...)\n");
01371 goto chunking_done;
01372 }
01373 #endif
01374
01375 {
01376 condition *inst_lhs_top, *inst_lhs_bottom;
01377
01378 reorder_instantiated_conditions(top_cc, &inst_lhs_top, &inst_lhs_bottom);
01379
01380
01381 if (current_agent(sysparams)[EXPLAIN_SYSPARAM])
01382 temp_explain_chunk.all_grounds = inst_lhs_top;
01383
01384 allocate_with_pool(¤t_agent(instantiation_pool), &chunk_inst);
01385
01386 #if !defined(THIN_JUSTIFICATIONS) || defined(MAKE_PRODUCTION_FOR_THIN_JUSTS)
01387 chunk_inst->prod = prod;
01388 #else
01389 chunk_inst->prod = NIL;
01390 #endif
01391
01392 chunk_inst->top_of_instantiated_conditions = inst_lhs_top;
01393
01394 #ifdef WATCH_SSCI_CONDS
01395
01396 print("\nCreating temp-justification: ");
01397
01398 if (chunk_inst->prod)
01399 print_with_symbols("%y...conditions:\n", chunk_inst->prod->name);
01400 else
01401 print("(nil) ... conditions:\n");
01402
01403 print("Address %p\n", chunk_inst);
01404 print_condition_list(chunk_inst->top_of_instantiated_conditions, 2, TRUE);
01405 if (chunk_inst->top_of_instantiated_conditions == NIL) {
01406 print("There are no pointers here...\n");
01407 }
01408 #endif
01409
01410 chunk_inst->bottom_of_instantiated_conditions = inst_lhs_bottom;
01411 chunk_inst->nots = nots;
01412 chunk_inst->GDS_evaluated_already = FALSE;
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422 if (!current_agent(sysparams)[LEARNING_ONLY_SYSPARAM]) {
01423 if ((!current_agent(variablize_this_chunk))
01424 && (current_agent(chunk_free_flag))
01425 && (!current_agent(quiescence_t_flag)))
01426 chunk_inst->okay_to_variablize = TRUE;
01427 else
01428 chunk_inst->okay_to_variablize = current_agent(variablize_this_chunk);
01429 } else {
01430 if ((!current_agent(variablize_this_chunk))
01431 && (!current_agent(chunky_flag))
01432 && (!current_agent(quiescence_t_flag)))
01433 chunk_inst->okay_to_variablize = TRUE;
01434 else
01435 chunk_inst->okay_to_variablize = current_agent(variablize_this_chunk);
01436 }
01437
01438
01439 chunk_inst->in_ms = TRUE;
01440
01441
01442 make_clones_of_results(results, chunk_inst);
01443
01444 fill_in_new_instantiation_stuff(chunk_inst, TRUE);
01445
01446 }
01447
01448 #ifdef WARN_IF_RESULT_IS_I_SUPPORTED
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464 for (pref = chunk_inst->preferences_generated; pref != NIL; pref = pref->inst_next) {
01465 if (pref->o_supported == FALSE) {
01466 print("Warning: Result is not natively o-supported. ");
01467 #ifdef THIN_JUSTIFICATIONS
01468 #ifdef ALLOW_I_SUPPORTED_SUBGOAL_RESULTS_WITH_THIN_JUSTS
01469 print("This may produce memory leaks.\n");
01470 #else
01471 print("O-support will be forced.\n");
01472 #endif
01473 #endif
01474
01475 watchful_print_preference(pref);
01476 }
01477 }
01478 #endif
01479
01480 #if defined(DONT_CALC_GDS_OR_BT) || (defined(THIN_JUSTIFICATIONS) && !defined(ALLOW_I_SUPPORTED_SUBGOAL_RESULTS_WITH_THIN_JUSTS))
01481
01482
01483
01484 for (pref = chunk_inst->preferences_generated; pref != NIL; pref = pref->inst_next)
01485
01486 pref->o_supported = TRUE;
01487
01488 #endif
01489
01490 #ifndef THIN_JUSTIFICATIONS
01491
01492
01493
01494
01495 if (current_agent(sysparams)[EXPLAIN_SYSPARAM]) {
01496 condition *new_top, *new_bottom;
01497 copy_condition_list(lhs_top, &new_top, &new_bottom);
01498 temp_explain_chunk.conds = new_top;
01499 temp_explain_chunk.actions = copy_and_variablize_result_list(results);
01500 }
01501
01502 rete_addition_result = add_production_to_rete(prod, lhs_top, chunk_inst, print_name);
01503
01504 #ifdef WATCH_CHUNK_INST
01505 if (rete_addition_result == REFRACTED_INST_MATCHED)
01506 print("\nAdded chunk/justification to rete -- result: MATCHED\n");
01507 else if (rete_addition_result == REFRACTED_INST_DID_NOT_MATCH)
01508 print("\nAdded chunk/justification to rete -- result: DID NOT MATCH\n");
01509 else
01510 print("\nAdded chunk/justification to rete -- result: DUPLICATE\n");
01511 #endif
01512
01513
01514
01515
01516 if (current_agent(sysparams)[EXPLAIN_SYSPARAM]) {
01517 if ((rete_addition_result != DUPLICATE_PRODUCTION) &&
01518 ((prod_type != JUSTIFICATION_PRODUCTION_TYPE) || (rete_addition_result != REFRACTED_INST_DID_NOT_MATCH))) {
01519 strncpy(temp_explain_chunk.name, prod_name->sc.name, PROD_NAME_SIZE);
01520 temp_explain_chunk.name[PROD_NAME_SIZE - 1] = 0;
01521 explain_add_temp_to_chunk_list(&temp_explain_chunk);
01522 } else {
01523
01524 deallocate_condition_list(temp_explain_chunk.conds);
01525 deallocate_action_list(temp_explain_chunk.actions);
01526 }
01527 }
01528
01529 deallocate_condition_list(lhs_top);
01530 {
01531 chunk_cond *cc;
01532 while (top_cc) {
01533 cc = top_cc;
01534 top_cc = cc->next;
01535 free_with_pool(¤t_agent(chunk_cond_pool), cc);
01536 }
01537 }
01538
01539 if (print_prod && (rete_addition_result != DUPLICATE_PRODUCTION)) {
01540 print_string("\n");
01541 print_production(prod, FALSE);
01542 }
01543
01544 if (rete_addition_result == DUPLICATE_PRODUCTION) {
01545 excise_production(prod, FALSE);
01546 } else if ((prod_type == JUSTIFICATION_PRODUCTION_TYPE) && (rete_addition_result == REFRACTED_INST_DID_NOT_MATCH)) {
01547 excise_production(prod, FALSE);
01548 }
01549
01550 if (rete_addition_result != REFRACTED_INST_MATCHED) {
01551
01552
01553
01554 chunk_inst->in_ms = FALSE;
01555 }
01556 #else
01557
01558
01559
01560 deallocate_condition_list(lhs_top);
01561 #ifdef DONT_CALC_GDS_OR_BT
01562
01563 deallocate_condition_list(top_cc->cond);
01564 #endif
01565 {
01566 chunk_cond *cc;
01567 while (top_cc) {
01568 cc = top_cc;
01569 top_cc = cc->next;
01570 free_with_pool(¤t_agent(chunk_cond_pool), cc);
01571 }
01572 }
01573
01574 if (print_prod) {
01575 print_string("\n -- Justification (not added to rete) -- \n");
01576 {
01577 preference *the_temp_pref;
01578
01579 print("\nResults for instantiaition:\n");
01580 print_instantiation_with_wmes(chunk_inst, FULL_WME_TRACE);
01581 print("\n---------------------------\n");
01582 for (the_temp_pref = chunk_inst->preferences_generated;
01583 the_temp_pref != NIL; the_temp_pref = the_temp_pref->inst_next) {
01584 watchful_print_preference(the_temp_pref);
01585 }
01586 print("\n");
01587 }
01588
01589 }
01590 #endif
01591
01592
01593
01594 chunk_inst->next = current_agent(newly_created_instantiations);
01595 current_agent(newly_created_instantiations) = chunk_inst;
01596
01597
01598 if (!current_agent(max_chunks_reached))
01599 #ifndef THIN_JUSTIFICATIONS
01600 chunk_instantiation(chunk_inst, current_agent(variablize_this_chunk));
01601
01602 #else
01603
01604 if (chunk_inst->isa_ssci_inst != TRUE) {
01605 chunk_inst->isa_ssci_inst = TRUE;
01606 }
01607 #ifdef WATCH_SSCI_INSTS
01608
01609 print("\nCreating an SSCI instantiation: ");
01610 if (chunk_inst->prod)
01611 print_with_symbols("%y\n", chunk_inst->prod->name);
01612 else
01613 print("(nil)\n");
01614
01615 #endif
01616
01617 #ifdef SINGLE_THIN_JUSTIFICATION
01618 second_stage_chunk_instantiation(chunk_inst);
01619
01620 #else
01621
01622
01623
01624
01625
01626
01627
01628 chunk_instantiation(chunk_inst, FALSE);
01629
01630 #endif
01631
01632 #endif
01633
01634 #ifndef NO_TIMING_STUFF
01635 #ifdef DETAILED_TIMING_STATS
01636 stop_timer(&saved_start_tv, ¤t_agent(chunking_cpu_time[current_agent(current_phase)]));
01637 #endif
01638 #endif
01639
01640 return;
01641
01642 chunking_done:{
01643 }
01644
01645 #ifndef NO_TIMING_STUFF
01646 #ifdef DETAILED_TIMING_STATS
01647 stop_timer(&saved_start_tv, ¤t_agent(chunking_cpu_time[current_agent(current_phase)]));
01648 #endif
01649 #endif
01650
01651 }
01652
01653 #ifdef SINGLE_THIN_JUSTIFICATION
01654
01655 void second_stage_chunk_instantiation(instantiation * inst)
01656 {
01657 goal_stack_level grounds_level;
01658 preference *results, *pref;
01659 bool print_name, print_prod;
01660 condition *lhs_top, *lhs_bottom;
01661 not *nots;
01662 chunk_cond *top_cc, *bottom_cc;
01663
01664
01665 if (!inst->match_goal)
01666 return;
01667
01668 #ifdef WATCH_PREFS_GENERATED
01669 print("\nPreferences Generated for instantiation at top of sscii\n");
01670 print_instantiation_with_wmes(inst, TIMETAG_WME_TRACE);
01671 print("\n Instantiation Match Goal Level = %d", inst->match_goal_level);
01672 print("\n---------------------------------------------\n");
01673 for (pref = inst->preferences_generated; pref != NIL; pref = pref->inst_next) {
01674 watchful_print_preference(pref);
01675 print("Reference count = %d\n", pref->reference_count);
01676 }
01677 print("\n");
01678 #endif
01679
01680
01681 for (pref = inst->preferences_generated; pref != NIL; pref = pref->inst_next) {
01682 if (pref->id->id.level < inst->match_goal_level)
01683 break;
01684 }
01685 if (!pref)
01686 return;
01687 inst->okay_to_variablize = FALSE;
01688
01689 results = get_results_for_instantiation(inst);
01690
01691 #ifdef WATCH_RESULTS
01692 {
01693 preference *the_temp_pref;
01694
01695 print("\nResults for instantiaition:\n");
01696 print_instantiation_with_wmes(inst, TIMETAG_WME_TRACE);
01697 print("\n---------------------------\n");
01698 for (the_temp_pref = results; the_temp_pref != NIL; the_temp_pref = the_temp_pref->next_result) {
01699 watchful_print_preference(the_temp_pref);
01700
01701 }
01702 print("\n");
01703 }
01704 #endif
01705
01706 if (!results)
01707 goto chunking_done;
01708
01709
01710 {
01711 Symbol *g;
01712 for (g = inst->match_goal->id.higher_goal; g && g->id.allow_bottom_up_chunks; g = g->id.higher_goal)
01713 g->id.allow_bottom_up_chunks = FALSE;
01714 }
01715
01716 grounds_level = inst->match_goal_level - 1;
01717
01718 current_agent(backtrace_number)++;
01719 if (current_agent(backtrace_number) == 0)
01720 current_agent(backtrace_number) = 1;
01721 current_agent(grounds_tc)++;
01722 if (current_agent(grounds_tc) == 0)
01723 current_agent(grounds_tc) = 1;
01724 current_agent(potentials_tc)++;
01725 if (current_agent(potentials_tc) == 0)
01726 current_agent(potentials_tc) = 1;
01727 current_agent(locals_tc)++;
01728 if (current_agent(locals_tc) == 0)
01729 current_agent(locals_tc) = 1;
01730 current_agent(grounds) = NIL;
01731 current_agent(positive_potentials) = NIL;
01732 current_agent(locals) = NIL;
01733 current_agent(instantiations_with_nots) = NIL;
01734
01735
01736
01737
01738 current_agent(chunk_free_flag) = FALSE;
01739
01740 current_agent(chunky_flag) = FALSE;
01741
01742 current_agent(variablize_this_chunk) = FALSE;
01743
01744 #ifndef NO_BACKTRACING
01745 #ifndef DONT_CALC_GDS_OR_BT
01746
01747
01748 for (pref = results; pref != NIL; pref = pref->next_result) {
01749
01750 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
01751 if (current_agent(sysparams)[TRACE_BACKTRACING_SYSPARAM]) {
01752 print_string("\nFor result preference ");
01753 print_preference(pref);
01754 print_string(" ");
01755 }
01756 #endif
01757
01758 if (pref->inst)
01759 backtrace_through_instantiation(pref->inst, grounds_level, NULL, 0);
01760
01761 }
01762
01763 #else
01764 add_named_superstate_attribute_to_grounds(inst, "superstate");
01765 #endif
01766
01767 #endif
01768
01769 current_agent(quiescence_t_flag) = FALSE;
01770
01771 while (TRUE) {
01772 trace_locals(grounds_level);
01773 trace_grounded_potentials();
01774 if (!trace_ungrounded_potentials(grounds_level))
01775 break;
01776 }
01777 free_list(current_agent(positive_potentials));
01778
01779
01780 {
01781 tc_number tc_for_grounds;
01782 tc_for_grounds = get_new_tc_number();
01783 build_chunk_conds_for_grounds_and_add_negateds(&top_cc, &bottom_cc, tc_for_grounds);
01784 nots = get_nots_for_instantiated_conditions(current_agent(instantiations_with_nots), tc_for_grounds);
01785 }
01786
01787
01788 #ifdef MAKE_PRODUCTION_FOR_THIN_JUSTS
01789 if (inst->prod->type != JUSTIFICATION_PRODUCTION_TYPE) {
01790 print("Warning (1)\n");
01791 }
01792 #endif
01793
01794 print_name = current_agent(sysparams)[TRACE_JUSTIFICATION_NAMES_SYSPARAM];
01795 print_prod = current_agent(sysparams)[TRACE_JUSTIFICATIONS_SYSPARAM];
01796
01797 #ifdef WATCH_SSCI_INSTS
01798
01799 print("Rebuiding ");
01800 if (inst->prod)
01801 print_with_symbols("%y\n", inst->prod->name);
01802 else
01803 print("an SSCI inst.\n");
01804
01805 #endif
01806
01807
01808 if (print_name) {
01809 if (get_printer_output_column() != 1)
01810 print("\n");
01811 print("Rebuiding ");
01812 if (inst->prod)
01813 print_with_symbols("%y\n", inst->prod->name);
01814 else
01815 print("an SSCI inst.\n");
01816
01817 }
01818
01819
01820
01821 if (!top_cc) {
01822 if (current_agent(sysparams)[PRINT_WARNINGS_SYSPARAM])
01823 print_string(" Warning: chunk has no grounds, ignoring it.");
01824
01825 }
01826
01827
01828 lhs_top = top_cc->variablized_cond;
01829 lhs_bottom = bottom_cc->variablized_cond;
01830 reset_variable_generator(lhs_top, NIL);
01831 current_agent(variablization_tc) = get_new_tc_number();
01832 variablize_condition_list(lhs_top);
01833 variablize_nots_and_insert_into_conditions(nots, lhs_top);
01834
01835
01836
01837
01838
01839
01840 add_goal_or_impasse_tests(top_cc);
01841
01842
01843
01844 {
01845 condition *inst_lhs_top, *inst_lhs_bottom;
01846
01847 reorder_instantiated_conditions(top_cc, &inst_lhs_top, &inst_lhs_bottom);
01848 deallocate_inst_members_to_be_rewritten(inst);
01849
01850
01851
01852
01853 inst->top_of_instantiated_conditions = inst_lhs_top;
01854 inst->bottom_of_instantiated_conditions = inst_lhs_bottom;
01855 inst->nots = nots;
01856
01857 #ifdef WATCH_SSCI_CONDS
01858
01859 print("Rebuiding temp-just: ");
01860 if (inst->prod)
01861 print_with_symbols("%y ... conditions:\n", inst->prod->name);
01862 else
01863 print(" (nil) ... conditions: \n");
01864 print("Address %p\n", inst);
01865 print_condition_list(inst->top_of_instantiated_conditions, 2, TRUE);
01866 if (inst->top_of_instantiated_conditions == NIL) {
01867 print("There are no pointers here...\n");
01868 }
01869 #endif
01870
01871 re_fill_in_instantiation_stuff_for_modified_lhs(inst, TRUE);
01872
01873 }
01874
01875 #ifdef WARN_IF_RESULT_IS_I_SUPPORTED
01876
01877
01878
01879
01880 for (pref = inst->preferences_generated; pref != NIL; pref = pref->inst_next) {
01881 if (pref->o_supported == FALSE) {
01882 print("Warning: Result is not natively o-supported. ");
01883
01884 #ifdef ALLOW_I_SUPPORTED_SUBGOAL_RESULTS_WITH_THIN_JUSTS
01885 print("This may produce memory leaks.\n");
01886 #else
01887 print("O-support will be forced.\n");
01888 #endif
01889
01890 watchful_print_preference(pref);
01891 }
01892 }
01893 #endif
01894
01895
01896 deallocate_condition_list(lhs_top);
01897 #ifdef DONT_CALC_GDS_OR_BT
01898
01899 deallocate_condition_list(top_cc->cond);
01900 #endif
01901
01902 {
01903 chunk_cond *cc;
01904 while (top_cc) {
01905 cc = top_cc;
01906 top_cc = cc->next;
01907 free_with_pool(¤t_agent(chunk_cond_pool), cc);
01908 }
01909 }
01910
01911
01912 second_stage_chunk_instantiation(inst);
01913
01914 chunking_done:{
01915 }
01916
01917 }
01918
01919 void deallocate_inst_members_to_be_rewritten(instantiation * inst)
01920 {
01921
01922 goal_stack_level level;
01923 condition *cond;
01924
01925 level = inst->match_goal_level;
01926
01927
01928
01929
01930
01931
01932
01933
01934 for (cond = inst->top_of_instantiated_conditions; cond != NIL; cond = cond->next)
01935 if (cond->type == POSITIVE_CONDITION) {
01936
01937 #ifdef NO_TOP_LEVEL_REFS
01938 if (level > 1) {
01939 wme_remove_ref(cond->bt.wme);
01940 }
01941 #ifdef DEBUG_NO_TOP_LEVEL_REFS
01942 else {
01943 print("NO_TOP_LEVEL_REFS(4): Not removing reference to tt =%lu ref =%lu\n",
01944 cond->bt.wme->timetag, cond->bt.wme->reference_count);
01945 }
01946 #endif
01947
01948 #else
01949 wme_remove_ref(cond->bt.wme);
01950 #endif
01951 if (cond->bt.trace) {
01952
01953 #ifdef NO_TOP_JUST
01954 if (cond->bt.trace->match_goal_level > level)
01955 cond->bt.trace = find_clone_for_level(cond->bt.trace, level);
01956 #else
01957
01958 if (cond->bt.trace->inst->match_goal_level > level)
01959 cond->bt.trace = find_clone_for_level(cond->bt.trace, level);
01960 #endif
01961
01962
01963 #ifdef NO_TOP_LEVEL_REFS
01964 if ((cond->bt.trace) && (level > 1)) {
01965 preference_remove_ref(cond->bt.trace);
01966 }
01967 #ifdef DEBUG_NO_TOP_LEVEL_REFS
01968 else {
01969 print("NO_TOP_LEVEL_REFS (5): Not removing reference to rf = %lu\n",
01970 cond->bt.trace->reference_count);
01971 print("NO_TOP_LEVEL_REFS (5): cond->bt.trace = \n");
01972 print_preference(cond->bt.trace);
01973 }
01974 #endif
01975
01976 #else
01977 if (cond->bt.trace)
01978 preference_remove_ref(cond->bt.trace);
01979 #endif
01980 }
01981
01982 }
01983
01984 {
01985 preference *pr, *p, *np;
01986
01987
01988
01989 if (inst->match_goal) {
01990 for (p = inst->match_goal->id.preferences_from_goal; p != NIL; p = np) {
01991
01992 np = p->all_of_goal_next;
01993 for (pr = inst->preferences_generated; pr != NIL; pr = pr->inst_next) {
01994 if (p == pr) {
01995
01996
01997
01998 remove_from_dll(inst->match_goal->id.preferences_from_goal,
01999 pr, all_of_goal_next, all_of_goal_prev);
02000 break;
02001 }
02002 }
02003 }
02004 }
02005 }
02006
02007
02008
02009
02010
02011
02012
02013
02014 deallocate_condition_list(inst->top_of_instantiated_conditions);
02015 deallocate_list_of_nots(inst->nots);
02016
02017 }
02018
02019
02020
02021
02022
02023 void re_fill_in_instantiation_stuff_for_modified_lhs(instantiation * inst, bool need_to_do_support_calculations)
02024 {
02025 condition *cond;
02026 preference *p;
02027 goal_stack_level level;
02028
02029 #if 0
02030 #ifdef TRY_SSCI_PROD_NIL
02031 if (inst->prod)
02032 #endif
02033 production_add_ref(inst->prod);
02034 #endif
02035
02036 find_match_goal(inst);
02037
02038 level = inst->match_goal_level;
02039
02040 #ifdef NO_TOP_JUST
02041
02042
02043
02044
02045 for (p = inst->preferences_generated; p != NIL; p = p->inst_next) {
02046 p->match_goal = inst->match_goal;
02047 p->match_goal_level = inst->match_goal_level;
02048 }
02049
02050
02051 #endif
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067 for (cond = inst->top_of_instantiated_conditions; cond != NIL; cond = cond->next)
02068 if (cond->type == POSITIVE_CONDITION) {
02069
02070
02071
02072 #ifdef NO_TOP_LEVEL_REFS
02073 if (level > 1) {
02074 wme_add_ref(cond->bt.wme);
02075 }
02076 #ifdef DEBUG_NO_TOP_LEVEL_REFS
02077 else {
02078 print("NO_TOP_LEVEL_REFS (1): Not adding reference to tt =%lu ref =%lu\n",
02079 cond->bt.wme->timetag, cond->bt.wme->reference_count);
02080 }
02081 #endif
02082
02083 #else
02084 wme_add_ref(cond->bt.wme);
02085 #endif
02086
02087
02088 if (cond->bt.trace) {
02089
02090 #ifdef NO_TOP_JUST
02091 if (cond->bt.trace->match_goal_level > level)
02092 cond->bt.trace = find_clone_for_level(cond->bt.trace, level);
02093 #else
02094
02095 if (cond->bt.trace->inst->match_goal_level > level)
02096 cond->bt.trace = find_clone_for_level(cond->bt.trace, level);
02097 #endif
02098
02099
02100 #ifdef NO_TOP_LEVEL_REFS
02101 if ((cond->bt.trace) && (level > 1)) {
02102 preference_add_ref(cond->bt.trace);
02103 }
02104 #ifdef DEBUG_NO_TOP_LEVEL_REFS
02105 else {
02106 print("NO_TOP_LEVEL_REFS (2): Not adding reference to rf = %lu\n",
02107 cond->bt.trace->reference_count);
02108 print("NO_TOP_LEVEL_REFS (2): cond->bt.trace = \n");
02109 print_preference(cond->bt.trace);
02110 }
02111 #endif
02112
02113 #else
02114 if (cond->bt.trace)
02115 preference_add_ref(cond->bt.trace);
02116 #endif
02117 }
02118
02119 }
02120
02121
02122
02123 if (inst->match_goal) {
02124 for (p = inst->preferences_generated; p != NIL; p = p->inst_next) {
02125 insert_at_head_of_dll(inst->match_goal->id.preferences_from_goal, p, all_of_goal_next, all_of_goal_prev);
02126 p->on_goal_list = TRUE;
02127 }
02128 }
02129
02130 inst->backtrace_number = 0;
02131
02132 if (current_agent(o_support_calculation_type) == 0) {
02133
02134 if (need_to_do_support_calculations)
02135 calculate_support_for_instantiation_preferences(inst);
02136 } else if (current_agent(o_support_calculation_type) == 1) {
02137 if (need_to_do_support_calculations)
02138 calculate_support_for_instantiation_preferences(inst);
02139
02140 if ((inst->prod->declared_support != DECLARED_O_SUPPORT) &&
02141 (inst->prod->declared_support != DECLARED_I_SUPPORT)) {
02142
02143
02144
02145 list *saved_flags;
02146 preference *pref;
02147 bool difference_found;
02148 saved_flags = NIL;
02149 for (pref = inst->preferences_generated; pref != NIL; pref = pref->inst_next)
02150 push((pref->o_supported ? pref : NIL), saved_flags);
02151 saved_flags = destructively_reverse_list(saved_flags);
02152 dougs_calculate_support_for_instantiation_preferences(inst);
02153 difference_found = FALSE;
02154 for (pref = inst->preferences_generated; pref != NIL; pref = pref->inst_next) {
02155 cons *c;
02156 bool b;
02157 c = saved_flags;
02158 saved_flags = c->rest;
02159 b = (c->first ? TRUE : FALSE);
02160 free_cons(c);
02161 if (pref->o_supported != b)
02162 difference_found = TRUE;
02163 pref->o_supported = b;
02164 }
02165 if (difference_found) {
02166 print_with_symbols("\n*** O-support difference found in production %y", inst->prod->name);
02167 }
02168 }
02169 } else {
02170
02171 if ((inst->prod->declared_support != DECLARED_O_SUPPORT) &&
02172 (inst->prod->declared_support != DECLARED_I_SUPPORT)) {
02173 dougs_calculate_support_for_instantiation_preferences(inst);
02174 }
02175 }
02176 }
02177
02178 #endif
02179
02180
02181
02182
02183
02184
02185
02186
02187 void init_chunker(void)
02188 {
02189 init_memory_pool(¤t_agent(chunk_cond_pool), sizeof(chunk_cond), "chunk condition");
02190 init_chunk_cond_set(¤t_agent(negated_set));
02191 }
02192
02193 #ifdef DONT_CALC_GDS_OR_BT
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215 static void add_named_superstate_attribute_to_grounds(instantiation * inst, char *name)
02216 {
02217 Symbol *target;
02218 wme *ps;
02219 slot *the_slot;
02220 condition *ps_cond;
02221
02222
02223 target = find_sym_constant(name);
02224
02225 if (!target)
02226 target = current_agent(superstate_symbol);
02227
02228 the_slot = find_slot(inst->match_goal->id.higher_goal, target);
02229
02230 if (the_slot) {
02231 ps = the_slot->wmes;
02232 } else {
02233 ps = find_impasse_wme(inst->match_goal->id.higher_goal, target);
02234 }
02235
02236 if (ps == NIL) {
02237 print("\nNo Chunks Hack: Whoops, couldn't find %s in superstate.\n", name);
02238 return;
02239 }
02240
02241
02242
02243
02244 allocate_with_pool(¤t_agent(condition_pool), &ps_cond);
02245
02246 ps_cond->prev = NIL;
02247 ps_cond->next = NIL;
02248 ps_cond->type = POSITIVE_CONDITION;
02249
02250 ps_cond->data.tests.id_test = make_equality_test(ps->id);
02251 ps_cond->data.tests.attr_test = make_equality_test(ps->attr);
02252 ps_cond->data.tests.value_test = make_equality_test(ps->value);
02253 ps_cond->test_for_acceptable_preference = ps->acceptable;
02254
02255 ps_cond->bt.wme = ps;
02256 ps_cond->bt.level = inst->match_goal_level - 1;
02257
02258 ps_cond->bt.trace = NIL;
02259 ps_cond->bt.prohibits = NIL;
02260
02261 push((ps_cond), current_agent(grounds));
02262
02263 }
02264
02265 #endif
02266