Soar Kernel  9.3.2 08-06-12
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Data Structures | Macros | Typedefs | Functions
reorder.cpp File Reference
#include <portability.h>
#include <stdlib.h>
#include "reorder.h"
#include "kernel.h"
#include "rhsfun.h"
#include "gdatastructs.h"
#include "production.h"
#include "mem.h"
#include "symtab.h"
#include "print.h"
#include "agent.h"
#include "init_soar.h"
#include "xml.h"
#include "soar_TraceNames.h"

Go to the source code of this file.

Data Structures

struct  saved_test_struct

Macros

#define BF_FOR_ACCEPTABLE_PREFS   8 /* cost of (. ^. <var> +) */
#define BF_FOR_ATTRIBUTES   8 /* cost of (. ^<var> .) */
#define BF_FOR_VALUES   8 /* cost of (. ^. <var>) */
#define MAX_COST   10000005 /* cost of a disconnected condition */

Typedefs

typedef struct saved_test_struct saved_test

Functions

Bool all_variables_in_rhs_value_bound (rhs_value rv, tc_number tc)
bool check_negative_relational_test_bindings (agent *thisAgent, condition *cond_list, tc_number tc)
bool check_unbound_negative_relational_test_referents (agent *thisAgent, test t, tc_number tc)
listcollect_root_variables (agent *thisAgent, condition *cond_list, tc_number tc, Bool allow_printing_warnings)
listcollect_vars_tested_by_cond_that_are_bound (agent *thisAgent, condition *cond, tc_number tc, list *starting_list)
listcollect_vars_tested_by_test_that_are_bound (agent *thisAgent, test t, tc_number tc, list *starting_list)
int64_t cost_of_adding_condition (agent *thisAgent, condition *cond, tc_number tc, list *root_vars_not_bound_yet)
void fill_in_vars_requiring_bindings (agent *thisAgent, condition *cond_list, tc_number tc)
int64_t find_lowest_cost_lookahead (agent *thisAgent, condition *candidates, condition *chosen, tc_number tc, list *root_vars_not_bound_yet)
int64_t get_cost_of_possible_multi_attribute (agent *thisAgent, Symbol *sym)
void init_reorderer (agent *thisAgent)
Bool legal_to_execute_action (action *a, tc_number tc)
void print_saved_test (agent *thisAgent, saved_test *st)
void print_saved_test_list (agent *thisAgent, saved_test *st)
void remove_isa_state_tests_for_non_roots (agent *thisAgent, condition **lhs_top, condition **, list *roots)
void remove_vars_requiring_bindings (agent *thisAgent, condition *cond_list)
Bool reorder_action_list (agent *thisAgent, action **action_list, tc_number lhs_tc)
void reorder_condition_list (agent *thisAgent, condition **top_of_conds, condition **bottom_of_conds, list *roots, tc_number tc, Bool reorder_nccs)
Bool reorder_lhs (agent *thisAgent, condition **lhs_top, condition **lhs_bottom, Bool reorder_nccs)
void reorder_simplified_conditions (agent *thisAgent, condition **top_of_conds, condition **bottom_of_conds, list *roots, tc_number bound_vars_tc_number, Bool reorder_nccs)
void restore_and_deallocate_saved_tests (agent *thisAgent, condition *conds_list, tc_number tc, saved_test *tests_to_restore)
saved_testrestore_saved_tests_to_test (agent *thisAgent, test *t, Bool is_id_field, tc_number bound_vars_tc_number, saved_test *tests_to_restore, bool neg)
byte reverse_direction_of_relational_test (agent *thisAgent, byte type)
saved_testsimplify_condition_list (agent *thisAgent, condition *conds_list)
saved_testsimplify_test (agent *thisAgent, test *t, saved_test *old_sts)
Bool symbol_is_constant_or_marked_variable (Symbol *sym, tc_number tc)
Bool test_covered_by_bound_vars (test t, tc_number tc, list *extra_vars)
Bool test_tests_for_root (test t, list *roots)

Macro Definition Documentation

#define BF_FOR_ACCEPTABLE_PREFS   8 /* cost of (. ^. <var> +) */

Definition at line 668 of file reorder.cpp.

Referenced by cost_of_adding_condition().

#define BF_FOR_ATTRIBUTES   8 /* cost of (. ^<var> .) */

Definition at line 670 of file reorder.cpp.

Referenced by cost_of_adding_condition().

#define BF_FOR_VALUES   8 /* cost of (. ^. <var>) */

Definition at line 669 of file reorder.cpp.

Referenced by cost_of_adding_condition().

#define MAX_COST   10000005 /* cost of a disconnected condition */

Typedef Documentation

typedef struct saved_test_struct saved_test

Function Documentation

Bool all_variables_in_rhs_value_bound ( rhs_value  rv,
tc_number  tc 
)

Definition at line 143 of file reorder.cpp.

References FALSE, cons_struct::first, NIL, cons_struct::rest, rhs_value_is_funcall(), rhs_value_to_funcall_list(), rhs_value_to_symbol(), variable_struct::tc_num, TRUE, symbol_union::var, and VARIABLE_SYMBOL_TYPE.

Referenced by legal_to_execute_action().

{
cons *c;
list *fl;
Symbol *sym;
/* --- function calls --- */
for (c=fl->rest; c!=NIL; c=c->rest)
if (! all_variables_in_rhs_value_bound (static_cast<char *>(c->first), tc))
return FALSE;
return TRUE;
} else {
/* --- ordinary (symbol) rhs values --- */
sym = rhs_value_to_symbol (rv);
if (sym->common.symbol_type==VARIABLE_SYMBOL_TYPE)
return (sym->var.tc_num == tc);
return TRUE;
}
}
bool check_negative_relational_test_bindings ( agent thisAgent,
condition cond_list,
tc_number  tc 
)

Definition at line 1121 of file reorder.cpp.

References add_bound_variables_in_condition(), three_field_tests_struct::attr_test, check_unbound_negative_relational_test_referents(), CONJUNCTIVE_NEGATION_CONDITION, condition_struct::data, three_field_tests_struct::id_test, condition_struct::condition_main_data_union::ncc, NEGATIVE_CONDITION, condition_struct::next, NIL, POSITIVE_CONDITION, condition_struct::condition_main_data_union::tests, ncc_info_struct::top, condition_struct::type, unmark_variables_and_free_list(), and three_field_tests_struct::value_test.

Referenced by reorder_lhs().

{
list* bound_vars = NIL; // this list necessary pop variables bound inside ncc's out of scope on return
bool ret = true;
/* --- add anything bound in a positive condition at this level --- */
/* --- recurse in to NCCs --- */
for (c=cond_list; ret && c!=NIL; c=c->next) {
add_bound_variables_in_condition (thisAgent, c, tc, &bound_vars);
}
}
/* --- find referents of non-equality tests in conjunctive tests in negated conditions ---*/
for (c=cond_list; ret && c!=NIL; c=c->next) {
}
}
// unmark anything bound on this level
unmark_variables_and_free_list (thisAgent, bound_vars);
return ret;
}
bool check_unbound_negative_relational_test_referents ( agent thisAgent,
test  t,
tc_number  tc 
)

Definition at line 1080 of file reorder.cpp.

References complex_test_from_test(), complex_test_struct::test_info_union::conjunct_list, CONJUNCTIVE_TEST, complex_test_struct::data, DISJUNCTION_TEST, cons_struct::first, GOAL_ID_TEST, IMPASSE_ID_TEST, agent_struct::name_of_production_being_reordered, NIL, print(), complex_test_struct::test_info_union::referent, cons_struct::rest, variable_struct::tc_num, test_is_blank_or_equality_test(), test_is_blank_test(), test_to_string(), complex_test_struct::type, symbol_union::var, and VARIABLE_SYMBOL_TYPE.

Referenced by check_negative_relational_test_bindings().

{
cons *c;
Symbol *referent;
// we only care about relational tests other than equality
if (test_is_blank_test(t)) return true;
if (test_is_blank_or_equality_test(t)) return true;
switch (ct->type) {
break;
// we do need to loop over conjunctive tests, however
for (c=ct->data.conjunct_list; c!=NIL; c=c->rest)
if (!check_unbound_negative_relational_test_referents (thisAgent, static_cast<test>(c->first), tc))
return false;
break;
default:
/* --- relational tests other than equality --- */
referent = ct->data.referent;
if (referent->common.symbol_type==VARIABLE_SYMBOL_TYPE) {
if (referent->var.tc_num != tc) {
print (thisAgent,
"Error: production %s has an unbound referent in negated relational test %s",
test_to_string (thisAgent, t, NULL, 0));
return false;
}
}
break;
}
return true;
}
list* collect_root_variables ( agent thisAgent,
condition cond_list,
tc_number  tc,
Bool  allow_printing_warnings 
)

Definition at line 590 of file reorder.cpp.

References add_bound_variables_in_test(), add_to_growable_string(), condition_struct::data, FALSE, cons_struct::first, free_growable_string(), three_field_tests_struct::id_test, make_blank_growable_string(), agent_struct::name_of_production_being_reordered, condition_struct::next, NIL, POSITIVE_CONDITION, print(), PRINT_WARNINGS_SYSPARAM, print_with_symbols(), cons_struct::rest, symbol_to_string(), agent_struct::sysparams, test_includes_equality_test_for_symbol(), test_includes_goal_or_impasse_id_test(), condition_struct::condition_main_data_union::tests, text_of_growable_string(), TRUE, condition_struct::type, unmark_variables_and_free_list(), three_field_tests_struct::value_test, and xml_generate_warning().

Referenced by find_compile_time_match_goal(), reorder_lhs(), and reorder_simplified_conditions().

{
list *new_vars_from_value_slot;
list *new_vars_from_id_slot;
cons *c;
condition *cond;
Bool found_goal_impasse_test;
/* --- find everthing that's in the value slot of some condition --- */
new_vars_from_value_slot = NIL;
for (cond=cond_list; cond!=NIL; cond=cond->next)
&new_vars_from_value_slot);
/* --- now see what else we can add by throwing in the id slot --- */
new_vars_from_id_slot = NIL;
for (cond=cond_list; cond!=NIL; cond=cond->next)
&new_vars_from_id_slot);
/* --- unmark everything we just marked --- */
unmark_variables_and_free_list (thisAgent, new_vars_from_value_slot);
for (c=new_vars_from_id_slot; c!=NIL; c=c->rest)
static_cast<Symbol *>(c->first)->var.tc_num = 0;
/* --- make sure each root var has some condition with goal/impasse --- */
if (allow_printing_warnings && thisAgent->sysparams[PRINT_WARNINGS_SYSPARAM]) {
for (c=new_vars_from_id_slot; c!=NIL; c=c->rest) {
found_goal_impasse_test = FALSE;
for (cond=cond_list; cond!=NIL; cond=cond->next) {
if (cond->type!=POSITIVE_CONDITION) continue;
static_cast<symbol_union *>(c->first)))
TRUE, TRUE)) {
found_goal_impasse_test = TRUE;
break;
}
}
if (! found_goal_impasse_test) {
print (thisAgent, "\nWarning: On the LHS of production %s, identifier ",
print_with_symbols (thisAgent, "%y is not connected to any goal or impasse.\n",
static_cast<Symbol *>(c->first));
// XML geneneration
add_to_growable_string(thisAgent, &gs, "Warning: On the LHS of production ");
add_to_growable_string(thisAgent, &gs, ", identifier ");
add_to_growable_string(thisAgent, &gs, symbol_to_string (thisAgent, static_cast<Symbol *>(c->first), true, 0, 0));
add_to_growable_string(thisAgent, &gs, " is not connected to any goal or impasse.");
free_growable_string(thisAgent, gs);
}
}
}
return new_vars_from_id_slot;
}
list* collect_vars_tested_by_cond_that_are_bound ( agent thisAgent,
condition cond,
tc_number  tc,
list starting_list 
)

Definition at line 519 of file reorder.cpp.

References three_field_tests_struct::attr_test, collect_vars_tested_by_test_that_are_bound(), CONJUNCTIVE_NEGATION_CONDITION, condition_struct::data, three_field_tests_struct::id_test, condition_struct::condition_main_data_union::ncc, condition_struct::next, NIL, condition_struct::condition_main_data_union::tests, ncc_info_struct::top, condition_struct::type, and three_field_tests_struct::value_test.

Referenced by fill_in_vars_requiring_bindings().

{
/* --- conjuctive negations --- */
for (c=cond->data.ncc.top; c!=NIL; c=c->next)
(thisAgent, c, tc, starting_list);
} else {
/* --- positive, negative conditions --- */
(thisAgent, cond->data.tests.id_test, tc, starting_list);
(thisAgent, cond->data.tests.attr_test, tc, starting_list);
(thisAgent, cond->data.tests.value_test, tc, starting_list);
}
return starting_list;
}
list* collect_vars_tested_by_test_that_are_bound ( agent thisAgent,
test  t,
tc_number  tc,
list starting_list 
)

Definition at line 478 of file reorder.cpp.

References add_if_not_member(), complex_test_from_test(), complex_test_struct::test_info_union::conjunct_list, CONJUNCTIVE_TEST, complex_test_struct::data, DISJUNCTION_TEST, cons_struct::first, GOAL_ID_TEST, IMPASSE_ID_TEST, NIL, complex_test_struct::test_info_union::referent, referent_of_equality_test(), cons_struct::rest, variable_struct::tc_num, test_is_blank_or_equality_test(), test_is_blank_test(), complex_test_struct::type, symbol_union::var, and VARIABLE_SYMBOL_TYPE.

Referenced by collect_vars_tested_by_cond_that_are_bound().

{
cons *c;
Symbol *referent;
if (test_is_blank_test(t)) return starting_list;
if (referent->common.symbol_type==VARIABLE_SYMBOL_TYPE)
if (referent->var.tc_num == tc)
starting_list = add_if_not_member (thisAgent, referent, starting_list);
return starting_list;
}
switch (ct->type) {
return starting_list;
for (c=ct->data.conjunct_list; c!=NIL; c=c->rest)
(thisAgent, static_cast<char *>(c->first), tc, starting_list);
return starting_list;
default:
/* --- relational tests other than equality --- */
referent = ct->data.referent;
if (referent->common.symbol_type==VARIABLE_SYMBOL_TYPE)
if (referent->var.tc_num == tc)
starting_list = add_if_not_member (thisAgent, referent, starting_list);
return starting_list;
}
}
int64_t cost_of_adding_condition ( agent thisAgent,
condition cond,
tc_number  tc,
list root_vars_not_bound_yet 
)

Definition at line 726 of file reorder.cpp.

References three_field_tests_struct::attr_test, BF_FOR_ACCEPTABLE_PREFS, BF_FOR_ATTRIBUTES, BF_FOR_VALUES, condition_struct::data, cons_struct::first, get_cost_of_possible_multi_attribute(), three_field_tests_struct::id_test, MAX_COST, NIL, POSITIVE_CONDITION, referent_of_equality_test(), condition_struct::reorder, cons_struct::rest, symbol_is_constant_or_marked_variable(), test_covered_by_bound_vars(), condition_struct::test_for_acceptable_preference, test_is_blank_or_equality_test(), test_is_blank_test(), condition_struct::condition_main_data_union::tests, condition_struct::type, three_field_tests_struct::value_test, and reorder_info_struct::vars_requiring_bindings.

Referenced by find_lowest_cost_lookahead(), and reorder_simplified_conditions().

{
cons *c;
int64_t result;
/* --- handle the common simple case quickly up front --- */
if ((! root_vars_not_bound_yet) &&
return MAX_COST;
else
result = result * BF_FOR_ACCEPTABLE_PREFS;
else
result = result * BF_FOR_VALUES;
}
return result;
} /* --- end of common simple case --- */
if (cond->type==POSITIVE_CONDITION) {
/* --- for pos cond's, check what's bound, etc. --- */
root_vars_not_bound_yet))
return MAX_COST;
root_vars_not_bound_yet))
result = 1;
else
root_vars_not_bound_yet)) {
result = result * BF_FOR_ACCEPTABLE_PREFS;
else
result = result * BF_FOR_VALUES;
}
return result;
}
/* --- negated or NC conditions: just check whether all variables
requiring bindings are actually bound. If so, return 1, else
return MAX_COST --- */
for (c=cond->reorder.vars_requiring_bindings; c!=NIL; c=c->rest) {
if (static_cast<Symbol *>(c->first)->var.tc_num != tc) return MAX_COST;
}
return 1;
}
void fill_in_vars_requiring_bindings ( agent thisAgent,
condition cond_list,
tc_number  tc 
)

Definition at line 542 of file reorder.cpp.

References add_bound_variables_in_condition(), collect_vars_tested_by_cond_that_are_bound(), CONJUNCTIVE_NEGATION_CONDITION, condition_struct::data, condition_struct::condition_main_data_union::ncc, condition_struct::next, NIL, POSITIVE_CONDITION, condition_struct::reorder, ncc_info_struct::top, condition_struct::type, unmark_variables_and_free_list(), and reorder_info_struct::vars_requiring_bindings.

Referenced by reorder_lhs().

{
list *new_bound_vars;
/* --- add anything bound in a positive condition at this level --- */
new_bound_vars = NIL;
for (c=cond_list; c!=NIL; c=c->next)
add_bound_variables_in_condition (thisAgent, c, tc, &new_bound_vars);
/* --- scan through negated and NC cond's, fill in stuff --- */
for (c=cond_list; c!=NIL; c=c->next) {
}
unmark_variables_and_free_list (thisAgent, new_bound_vars);
}
int64_t find_lowest_cost_lookahead ( agent thisAgent,
condition candidates,
condition chosen,
tc_number  tc,
list root_vars_not_bound_yet 
)

Definition at line 797 of file reorder.cpp.

References add_bound_variables_in_condition(), cost_of_adding_condition(), MAX_COST, condition_struct::next, NIL, and unmark_variables_and_free_list().

Referenced by reorder_simplified_conditions().

{
int64_t min_cost, cost;
list *new_vars;
new_vars = NIL;
add_bound_variables_in_condition (thisAgent, chosen, tc, &new_vars);
min_cost = MAX_COST + 1;
for (c=candidates; c!=NIL; c=c->next) {
if (c==chosen) continue;
cost = cost_of_adding_condition (thisAgent, c, tc, root_vars_not_bound_yet);
if (cost < min_cost) {
min_cost = cost;
if (cost <= 1) break;
}
}
unmark_variables_and_free_list (thisAgent, new_vars);
return min_cost;
}
int64_t get_cost_of_possible_multi_attribute ( agent thisAgent,
Symbol sym 
)

Definition at line 709 of file reorder.cpp.

References agent_struct::multi_attributes, multi_attributes_struct::next, multi_attributes_struct::symbol, and multi_attributes_struct::value.

Referenced by cost_of_adding_condition().

{
while(m) {
if(m->symbol == sym) return m->value;
m = m->next;
}
return 1;
}
void init_reorderer ( agent thisAgent)

Definition at line 1218 of file reorder.cpp.

References init_memory_pool(), and agent_struct::saved_test_pool.

Referenced by init_production_utilities().

{ /* called from init_production_utilities() */
init_memory_pool (thisAgent, &thisAgent->saved_test_pool, sizeof(saved_test), "saved test");
}
Bool legal_to_execute_action ( action a,
tc_number  tc 
)
void print_saved_test ( agent thisAgent,
saved_test st 
)

Definition at line 210 of file reorder.cpp.

References print_string(), print_with_symbols(), test_to_string(), saved_test_struct::the_test, and saved_test_struct::var.

Referenced by print_saved_test_list().

{
print_with_symbols (thisAgent, " Symbol: %y Test: ", st->var);
print_string (thisAgent, test_to_string (thisAgent, st->the_test, NULL, 0));
}
void print_saved_test_list ( agent thisAgent,
saved_test st 
)

Definition at line 215 of file reorder.cpp.

References saved_test_struct::next, print(), and print_saved_test().

Referenced by restore_and_deallocate_saved_tests().

{
while (st) {
print_saved_test (thisAgent, st);
print (thisAgent, "\n");
st = st->next;
}
}
void remove_isa_state_tests_for_non_roots ( agent thisAgent,
condition **  lhs_top,
condition **  ,
list roots 
)
void remove_vars_requiring_bindings ( agent thisAgent,
condition cond_list 
)
Bool reorder_action_list ( agent thisAgent,
action **  action_list,
tc_number  lhs_tc 
)

Definition at line 85 of file reorder.cpp.

References add_all_variables_in_action(), FALSE, legal_to_execute_action(), agent_struct::name_of_production_being_reordered, action_struct::next, NIL, print(), TRUE, and unmark_variables_and_free_list().

Referenced by make_production().

{
list *new_bound_vars;
action *remaining_actions;
action *first_action, *last_action;
action *a, *prev_a;
Bool result_flag;
new_bound_vars = NIL;
remaining_actions = *action_list;
first_action = NIL;
last_action = NIL;
while (remaining_actions) {
/* --- scan through remaining_actions, look for one that's legal --- */
prev_a = NIL;
a = remaining_actions;
while (TRUE) {
if (!a) break; /* looked at all candidates, but none were legal */
if (legal_to_execute_action (a, lhs_tc)) break;
prev_a = a;
a = a->next;
}
if (!a) break;
/* --- move action a from remaining_actions to reordered list --- */
if (prev_a) prev_a->next = a->next; else remaining_actions = a->next;
a->next = NIL;
if (last_action) last_action->next = a; else first_action = a;
last_action = a;
/* --- add new variables from a to new_bound_vars --- */
add_all_variables_in_action (thisAgent, a, lhs_tc, &new_bound_vars);
}
if (remaining_actions) {
/* --- there are remaining_actions but none can be legally added --- */
print (thisAgent, "Error: production %s has a bad RHS--\n",
print (thisAgent, " Either it creates structure not connected to anything\n");
print (thisAgent, " else in WM, or it tries to pass an unbound variable as\n");
print (thisAgent, " an argument to a function.\n");
/* --- reconstruct list of all actions --- */
if (last_action)
last_action->next = remaining_actions;
else
first_action = remaining_actions;
result_flag = FALSE;
} else {
result_flag = TRUE;
}
/* --- unmark variables that we just marked --- */
unmark_variables_and_free_list (thisAgent, new_bound_vars);
/* --- return final result --- */
*action_list = first_action;
return result_flag;
}
void reorder_condition_list ( agent thisAgent,
condition **  top_of_conds,
condition **  bottom_of_conds,
list roots,
tc_number  tc,
Bool  reorder_nccs 
)

Definition at line 990 of file reorder.cpp.

References reorder_simplified_conditions(), restore_and_deallocate_saved_tests(), and simplify_condition_list().

Referenced by reorder_lhs(), and reorder_simplified_conditions().

{
saved_test *saved_tests;
saved_tests = simplify_condition_list (thisAgent, *top_of_conds);
reorder_simplified_conditions (thisAgent, top_of_conds, bottom_of_conds, roots, tc,
reorder_nccs);
restore_and_deallocate_saved_tests (thisAgent, *top_of_conds, tc, saved_tests);
}
Bool reorder_lhs ( agent thisAgent,
condition **  lhs_top,
condition **  lhs_bottom,
Bool  reorder_nccs 
)

Definition at line 1175 of file reorder.cpp.

References add_bound_variables_in_test(), check_negative_relational_test_bindings(), collect_root_variables(), condition_struct::data, FALSE, fill_in_vars_requiring_bindings(), free_list(), get_new_tc_number(), three_field_tests_struct::id_test, agent_struct::name_of_production_being_reordered, condition_struct::next, NIL, POSITIVE_CONDITION, print(), remove_isa_state_tests_for_non_roots(), remove_vars_requiring_bindings(), reorder_condition_list(), test_includes_goal_or_impasse_id_test(), condition_struct::condition_main_data_union::tests, TRUE, and condition_struct::type.

Referenced by make_production().

{
list *roots;
tc = get_new_tc_number (thisAgent);
/* don't mark any variables, since nothing is bound outside the LHS */
roots = collect_root_variables (thisAgent, *lhs_top, tc, TRUE);
/* SBH/MVP 6-24-94 Fix to include only root "STATE" test in the LHS of a chunk.*/
if (roots) remove_isa_state_tests_for_non_roots(thisAgent, lhs_top,lhs_bottom,roots);
/* MVP 6-8-94 - fix provided by Bob */
if (!roots) {
condition *cond;
for (cond = *lhs_top; cond!=NIL; cond=cond->next) {
if ((cond->type == POSITIVE_CONDITION) &&
TRUE, FALSE))) {
add_bound_variables_in_test (thisAgent, cond->data.tests.id_test, tc, &roots);
if (roots) break;
}
}
}
if (!roots) {
print (thisAgent, "Error: in production %s,\n", thisAgent->name_of_production_being_reordered);
print (thisAgent, " The LHS has no roots.\n");
/* hmmm... most people aren't going to understand this error message */
return FALSE;
}
fill_in_vars_requiring_bindings (thisAgent, *lhs_top, tc);
reorder_condition_list (thisAgent, lhs_top, lhs_bottom, roots, tc, reorder_nccs);
remove_vars_requiring_bindings (thisAgent, *lhs_top);
free_list (thisAgent, roots);
return check_negative_relational_test_bindings (thisAgent, *lhs_top, get_new_tc_number (thisAgent));
}
void reorder_simplified_conditions ( agent thisAgent,
condition **  top_of_conds,
condition **  bottom_of_conds,
list roots,
tc_number  bound_vars_tc_number,
Bool  reorder_nccs 
)

Definition at line 838 of file reorder.cpp.

References add_bound_variables_in_condition(), add_to_growable_string(), ncc_info_struct::bottom, canonical_cond_greater(), collect_root_variables(), CONJUNCTIVE_NEGATION_CONDITION, cost_of_adding_condition(), condition_struct::data, find_lowest_cost_lookahead(), cons_struct::first, free_growable_string(), free_list(), insert_at_head_of_dll, make_blank_growable_string(), MAX_COST, agent_struct::name_of_production_being_reordered, condition_struct::condition_main_data_union::ncc, saved_test_struct::next, condition_struct::next, reorder_info_struct::next_min_cost, NIL, POSITIVE_CONDITION, print(), PRINT_WARNINGS_SYSPARAM, remove_from_dll, condition_struct::reorder, reorder_condition_list(), cons_struct::rest, agent_struct::sysparams, text_of_growable_string(), ncc_info_struct::top, TRUE, condition_struct::type, unmark_variables_and_free_list(), and xml_generate_warning().

Referenced by reorder_condition_list().

{
condition *remaining_conds; /* header of dll */
condition *first_cond, *last_cond;
condition *cond, *next_cond;
condition *min_cost_conds, *chosen;
int64_t cost = 0;
int64_t min_cost = 0;
list *new_vars;
remaining_conds = *top_of_conds;
first_cond = NIL;
last_cond = NIL;
new_vars = NIL;
/* repeat: scan through remaining_conds
rate each one
if tie, call lookahead routine
add min-cost item to conds
*/
while (remaining_conds) {
/* --- find min-cost set --- */
min_cost_conds = NIL;
min_cost = 0;
for (cond=remaining_conds; cond!=NIL; cond=cond->next) {
cost = cost_of_adding_condition (thisAgent, cond, bound_vars_tc_number, roots);
if ((! min_cost_conds) || (cost < min_cost)) {
min_cost = cost;
min_cost_conds = cond;
} else if (cost==min_cost) {
cond->reorder.next_min_cost = min_cost_conds;
min_cost_conds = cond;
}
/* if (min_cost <= 1) break; This optimization needs to be removed,
otherwise the tie set is not created.
Without the tie set we can't check the
canonical order. */
}
/* --- if min_cost==MAX_COST, print error message --- */
if ((min_cost==MAX_COST) &&
print (thisAgent, "Warning: in production %s,\n",
print (thisAgent, " The LHS conditions are not all connected.\n");
/* BUGBUG I'm not sure whether this can ever happen. */
// XML geneneration
add_to_growable_string(thisAgent, &gs, "Warning: in production ");
add_to_growable_string(thisAgent, &gs, "\n The LHS conditions are not all connected.");
free_growable_string(thisAgent, gs);
}
/* --- if more than one min-cost item, and cost>1, do lookahead --- */
if ((min_cost > 1) && (min_cost_conds->reorder.next_min_cost)) {
min_cost = MAX_COST + 1;
for (cond=min_cost_conds, next_cond = cond->reorder.next_min_cost;
cond!=NIL;
cond=next_cond, next_cond=(cond?cond->reorder.next_min_cost:NIL)) {
cost = find_lowest_cost_lookahead (thisAgent, remaining_conds, cond,
bound_vars_tc_number, roots);
if (cost < min_cost) {
min_cost = cost;
min_cost_conds = cond;
} else {
/*******************************************************************
These code segments find the condition in the tie set with the smallest
value in the canonical order. This ensures that productions with the
same set of conditions are ordered the same. Except if the variables
are assigned differently.
*********************************************************************/
if (cost == min_cost && cond->type == POSITIVE_CONDITION) {
if (canonical_cond_greater(min_cost_conds,cond)) {
min_cost = cost;
min_cost_conds = cond;
}
}
}
/*******************************************************************/
}
}
/*******************************************************************/
if (min_cost == 1 && (min_cost_conds->reorder.next_min_cost)) {
for (cond=min_cost_conds; cond!=NIL; cond=cond->reorder.next_min_cost) {
if (cond->type == POSITIVE_CONDITION &&
min_cost_conds->type == POSITIVE_CONDITION &&
canonical_cond_greater(min_cost_conds,cond))
{
min_cost = cost;
min_cost_conds = cond;
}
else if (cond->type != POSITIVE_CONDITION &&
min_cost_conds->type == POSITIVE_CONDITION)
{
min_cost = cost;
min_cost_conds = cond;
}
}
}
/*******************************************************************/
/* --- install the first item in the min-cost set --- */
chosen = min_cost_conds;
remove_from_dll (remaining_conds, chosen, next, prev);
if (!first_cond) first_cond = chosen;
/* Note: args look weird on the next line, because we're really
inserting the chosen item at the *end* of the list */
insert_at_head_of_dll (last_cond, chosen, prev, next);
/* --- if a conjunctive negation, recursively reorder its conditions --- */
if ((chosen->type==CONJUNCTIVE_NEGATION_CONDITION) && reorder_nccs) {
list *ncc_roots;
ncc_roots = collect_root_variables (thisAgent, chosen->data.ncc.top,
bound_vars_tc_number, TRUE);
reorder_condition_list (thisAgent, &(chosen->data.ncc.top),
&(chosen->data.ncc.bottom),
ncc_roots,
bound_vars_tc_number,
reorder_nccs);
free_list (thisAgent, ncc_roots);
}
/* --- update set of bound variables for newly added condition --- */
add_bound_variables_in_condition (thisAgent, chosen, bound_vars_tc_number, &new_vars);
/* --- if all roots are bound, set roots=NIL: don't need 'em anymore --- */
if (roots) {
cons *c;
for (c=roots; c!=NIL; c=c->rest)
if (static_cast<Symbol *>(c->first)->var.tc_num != bound_vars_tc_number)
break;
if (!c) roots=NIL;
}
} /* end of while (remaining_conds) */
unmark_variables_and_free_list (thisAgent, new_vars);
*top_of_conds = first_cond;
*bottom_of_conds = last_cond;
}
void restore_and_deallocate_saved_tests ( agent thisAgent,
condition conds_list,
tc_number  tc,
saved_test tests_to_restore 
)

Definition at line 403 of file reorder.cpp.

References add_bound_variables_in_test(), add_to_growable_string(), three_field_tests_struct::attr_test, CONJUNCTIVE_NEGATION_CONDITION, condition_struct::data, FALSE, free_growable_string(), three_field_tests_struct::id_test, make_blank_growable_string(), agent_struct::name_of_production_being_reordered, NEGATIVE_CONDITION, condition_struct::next, NIL, POSITIVE_CONDITION, print(), print_saved_test_list(), PRINT_WARNINGS_SYSPARAM, restore_saved_tests_to_test(), agent_struct::sysparams, condition_struct::condition_main_data_union::tests, text_of_growable_string(), TRUE, condition_struct::type, unmark_variables_and_free_list(), three_field_tests_struct::value_test, and xml_generate_warning().

Referenced by reorder_condition_list().

{
condition *cond;
list *new_vars;
new_vars = NIL;
for (cond=conds_list; cond!=NIL; cond=cond->next) {
#ifdef CONSIDER_NEGATIVE
if (cond->type==CONJUNCTIVE_NEGATION_CONDITION) continue;
#else
if (cond->type!=POSITIVE_CONDITION) continue;
#endif
bool neg = cond->type == NEGATIVE_CONDITION;
tests_to_restore = restore_saved_tests_to_test
(thisAgent, (&cond->data.tests.id_test), TRUE, tc, tests_to_restore, neg);
add_bound_variables_in_test (thisAgent, cond->data.tests.id_test, tc, &new_vars);
tests_to_restore = restore_saved_tests_to_test
(thisAgent, (&cond->data.tests.attr_test), FALSE, tc, tests_to_restore, neg);
add_bound_variables_in_test (thisAgent, cond->data.tests.attr_test, tc, &new_vars);
tests_to_restore = restore_saved_tests_to_test
(thisAgent, (&cond->data.tests.value_test), FALSE, tc, tests_to_restore, neg);
add_bound_variables_in_test (thisAgent, cond->data.tests.value_test, tc, &new_vars);
}
if (tests_to_restore) {
print (thisAgent, "\nWarning: in production %s,\n",
print (thisAgent, " ignoring test(s) whose referent is unbound:\n");
print_saved_test_list (thisAgent, tests_to_restore);
// TODO: XML tagged output -- how to create this string?
// KJC TODO: need a tagged output version of print_saved_test_list
// XML generation
add_to_growable_string(thisAgent, &gs, "Warning: in production ");
add_to_growable_string(thisAgent, &gs, "\n ignoring test(s) whose referent is unbound:");
//TODO: fill in XML print_saved_test_list. Possibile methods include:
// 1) write a version which adds to a growable string
// 2) write a version which generates XML tags/attributes, so we get "typed" output for this warning
// i.e. "<warning><string value="beginning of message"></string><test att="val"></test><string value="rest of message"></string></warning>
free_growable_string(thisAgent, gs);
}
/* ought to deallocate the saved tests, but who cares */
}
unmark_variables_and_free_list (thisAgent, new_vars);
}
saved_test* restore_saved_tests_to_test ( agent thisAgent,
test t,
Bool  is_id_field,
tc_number  bound_vars_tc_number,
saved_test tests_to_restore,
bool  neg 
)

Definition at line 342 of file reorder.cpp.

References add_new_test_to_test_if_not_already_there(), complex_test_from_test(), complex_test_struct::data, DISJUNCTION_TEST, FALSE, GOAL_ID_TEST, IMPASSE_ID_TEST, saved_test_struct::next, NIL, complex_test_struct::test_info_union::referent, reverse_direction_of_relational_test(), agent_struct::saved_test_pool, symbol_is_constant_or_marked_variable(), symbol_remove_ref(), test_includes_equality_test_for_symbol(), saved_test_struct::the_test, TRUE, complex_test_struct::type, and saved_test_struct::var.

Referenced by restore_and_deallocate_saved_tests().

{
saved_test *st, *prev_st, *next_st;
Bool added_it;
Symbol *referent;
prev_st = NIL;
st = tests_to_restore;
while (st) {
next_st = st->next;
added_it = FALSE;
switch (ct->type) {
if (! is_id_field) break; /* goal/impasse tests only go in id fields */
/* ... otherwise fall through to the next case below ... */
added_it = TRUE;
}
break;
default: /* --- st->test is a relational test other than equality --- */
referent = ct->data.referent;
bound_vars_tc_number) ||
(st->var == referent)) {
added_it = TRUE;
}
} else if (test_includes_equality_test_for_symbol (*t, referent)) {
bound_vars_tc_number) ||
(st->var == referent)) {
ct->data.referent = st->var;
st->var = referent;
added_it = TRUE;
}
}
break;
} /* end of switch statement */
if (added_it) {
if (prev_st) prev_st->next = next_st; else tests_to_restore = next_st;
symbol_remove_ref (thisAgent, st->var);
free_with_pool (&thisAgent->saved_test_pool, st);
} else {
prev_st = st;
}
st = next_st;
} /* end of while (st) */
return tests_to_restore;
}
byte reverse_direction_of_relational_test ( agent thisAgent,
byte  type 
)

Definition at line 323 of file reorder.cpp.

References abort_with_fatal_error(), BUFFER_MSG_SIZE, GREATER_OR_EQUAL_TEST, GREATER_TEST, LESS_OR_EQUAL_TEST, LESS_TEST, NOT_EQUAL_TEST, and SAME_TYPE_TEST.

Referenced by restore_saved_tests_to_test().

{
switch (type) {
case LESS_TEST: return GREATER_TEST;
case GREATER_TEST: return LESS_TEST;
default:
{ char msg[BUFFER_MSG_SIZE];
strncpy (msg,
"Internal error: arg to reverse_direction_of_relational_test\n", BUFFER_MSG_SIZE);
msg[BUFFER_MSG_SIZE - 1] = 0; /* ensure null termination */
abort_with_fatal_error(thisAgent, msg);
}
}
return 0; /* unreachable, but without it, gcc -Wall warns here */
}
saved_test* simplify_condition_list ( agent thisAgent,
condition conds_list 
)

Definition at line 303 of file reorder.cpp.

References three_field_tests_struct::attr_test, CONJUNCTIVE_NEGATION_CONDITION, condition_struct::data, three_field_tests_struct::id_test, condition_struct::next, NIL, POSITIVE_CONDITION, simplify_test(), condition_struct::condition_main_data_union::tests, condition_struct::type, and three_field_tests_struct::value_test.

Referenced by reorder_condition_list().

{
saved_test *sts;
sts = NIL;
for (c=conds_list; c!=NIL; c=c->next) {
//#define CONSIDER_NEGATIVE 1
#ifdef CONSIDER_NEGATIVE
#else
#endif
sts = simplify_test (thisAgent, &(c->data.tests.id_test), sts);
sts = simplify_test (thisAgent, &(c->data.tests.attr_test), sts);
sts = simplify_test (thisAgent, &(c->data.tests.value_test), sts);
}
}
return sts;
}
saved_test* simplify_test ( agent thisAgent,
test t,
saved_test old_sts 
)

Definition at line 223 of file reorder.cpp.

References allocate_cons(), complex_test_from_test(), complex_test_struct::test_info_union::conjunct_list, CONJUNCTIVE_TEST, complex_test_struct::data, cons_struct::first, free_cons(), generate_new_variable(), make_equality_test_without_adding_reference(), saved_test_struct::next, NIL, referent_of_equality_test(), cons_struct::rest, agent_struct::saved_test_pool, symbol_add_ref(), test_is_blank_or_equality_test(), test_is_blank_test(), saved_test_struct::the_test, complex_test_struct::type, and saved_test_struct::var.

Referenced by simplify_condition_list().

{
test New, subtest;
saved_test *saved;
Symbol *var, *sym;
cons *c, *prev_c, *next_c;
if (test_is_blank_test(*t)) {
sym = generate_new_variable (thisAgent, "dummy-");
return old_sts;
}
return old_sts;
}
switch (ct->type) {
/* --- look at subtests for an equality test --- */
sym = NIL;
for (c=ct->data.conjunct_list; c!=NIL; c=c->rest) {
subtest = static_cast<char *>(c->first);
sym = referent_of_equality_test(subtest);
}
/* --- if no equality test was found, generate a variable for it --- */
if (!sym) {
sym = generate_new_variable (thisAgent, "dummy-");
allocate_cons (thisAgent, &c);
c->first = New;
}
/* --- scan through, create saved_test for subtests except equality --- */
prev_c = NIL;
while (c) {
next_c = c->rest;
subtest = static_cast<char *>(c->first);
/* --- create saved_test, splice this cons out of conjunct_list --- */
allocate_with_pool (thisAgent, &thisAgent->saved_test_pool, &saved);
saved->next = old_sts;
old_sts = saved;
saved->var = sym;
saved->the_test = subtest;
if (prev_c)
prev_c->rest = next_c;
else
ct->data.conjunct_list = next_c;
free_cons (thisAgent, c);
} else {
prev_c = c;
}
c = next_c;
}
break;
default:
/* --- goal/impasse, disjunction, and non-equality relational tests --- */
var = generate_new_variable (thisAgent, "dummy-");
allocate_with_pool (thisAgent, &thisAgent->saved_test_pool, &saved);
saved->next = old_sts;
old_sts = saved;
saved->var = var;
saved->the_test = *t;
*t = New;
break;
}
return old_sts;
}
Bool symbol_is_constant_or_marked_variable ( Symbol sym,
tc_number  tc 
)
inline

Definition at line 53 of file reorder.cpp.

References common, and VARIABLE_SYMBOL_TYPE.

Referenced by cost_of_adding_condition(), restore_saved_tests_to_test(), and test_covered_by_bound_vars().

{
return ( ((sym)->common.symbol_type!=VARIABLE_SYMBOL_TYPE) ||
((sym)->var.tc_num == (tc)) );
}
Bool test_covered_by_bound_vars ( test  t,
tc_number  tc,
list extra_vars 
)
Bool test_tests_for_root ( test  t,
list roots 
)

Definition at line 1010 of file reorder.cpp.

References complex_test_from_test(), complex_test_struct::test_info_union::conjunct_list, CONJUNCTIVE_TEST, complex_test_struct::data, DISJUNCTION_TEST, FALSE, cons_struct::first, GOAL_ID_TEST, IMPASSE_ID_TEST, member_of_list(), NIL, complex_test_struct::test_info_union::referent, referent_of_equality_test(), cons_struct::rest, test_is_blank_or_equality_test(), test_is_blank_test(), TRUE, complex_test_struct::type, and VARIABLE_SYMBOL_TYPE.

Referenced by remove_isa_state_tests_for_non_roots().

{
cons *c;
Symbol *referent;
/* Gather variables from test. */
if (test_is_blank_test(t)) return FALSE;
if ((referent->common.symbol_type==VARIABLE_SYMBOL_TYPE) &&
member_of_list(referent,roots)) return TRUE;
return FALSE;
}
switch (ct->type) {
return FALSE;
break;
for (c=ct->data.conjunct_list; c!=NIL; c=c->rest)
if (test_tests_for_root(static_cast<char *>(c->first), roots)) return TRUE;
return FALSE;
break;
default:
/* --- relational tests other than equality --- */
referent = ct->data.referent;
if ((referent->common.symbol_type==VARIABLE_SYMBOL_TYPE) &&
member_of_list(referent,roots)) return TRUE;
return FALSE;
break;
}
}