void decrement_var_entries( Operator *o, int start ) { int st = ENCODE_VAR( start ), i, j; for ( i = 0; i < o->num_preconds; i++ ) { for ( j = 0; j < garity[o->preconds[i].predicate]; j++ ) { if ( o->preconds[i].args[j] < st ) { o->preconds[i].args[j]++; } } } for ( i = 0; i < o->num_adds; i++ ) { for ( j = 0; j < garity[o->adds[i].predicate]; j++ ) { if ( o->adds[i].args[j] < st ) { o->adds[i].args[j]++; } } } for ( i = 0; i < o->num_dels; i++ ) { for ( j = 0; j < garity[o->dels[i].predicate]; j++ ) { if ( o->dels[i].args[j] < st ) { o->dels[i].args[j]++; } } } }
void decrement_var_entries( NormOperator *o, int start ) { int st = ENCODE_VAR( start ), i, j, a; NormEffect *e; for ( i = 0; i < o->num_preconds; i++ ) { for ( j = 0; j < garity[o->preconds[i].predicate]; j++ ) { if ( o->preconds[i].args[j] < st ) { o->preconds[i].args[j]++; } } } for ( e = o->effects; e; e = e->next ) { for ( i = 0; i < e->num_conditions; i++ ) { a = ( e->conditions[i].predicate < 0 ) ? 2 : garity[e->conditions[i].predicate]; for ( j = 0; j < a; j++ ) { if ( e->conditions[i].args[j] < st ) { e->conditions[i].args[j]++; } } } for ( i = 0; i < e->num_adds; i++ ) { for ( j = 0; j < garity[e->adds[i].predicate]; j++ ) { if ( e->adds[i].args[j] < st ) { e->adds[i].args[j]++; } } } for ( i = 0; i < e->num_dels; i++ ) { for ( j = 0; j < garity[e->dels[i].predicate]; j++ ) { if ( e->dels[i].args[j] < st ) { e->dels[i].args[j]++; } } } } }
void multiply_easy_non_constrained_effect_parameters( int curr_parameter ) { int t, n, i, j, k, p, par; NormEffect *tmp; Bool rem; if ( curr_parameter == lnum_multiply_parameters ) { /* create new effect, adjusting conds to inst, and * partially instantiating effects; * * add result to lres */ tmp = new_NormEffect2( le ); /* instantiate param occurences */ for ( i = 0; i < le->num_vars; i++ ) { par = lo->num_vars + i; /* numerical part */ for ( j = 0; j < tmp->num_numeric_conditions; j++ ) { replace_var_with_const_in_exp( &(tmp->numeric_conditions_lh[j]), par, le->inst_table[i] ); } for ( j = 0; j < tmp->num_numeric_conditions; j++ ) { replace_var_with_const_in_exp( &(tmp->numeric_conditions_rh[j]), par, le->inst_table[i] ); } /* was that already enough to get numbers? if yes, * see whether comparison holds or not. */ j = 0; while ( j < tmp->num_numeric_conditions ) { if ( tmp->numeric_conditions_lh[j]->connective == NUMBER && tmp->numeric_conditions_rh[j]->connective == NUMBER ) { if ( number_comparison_holds( tmp->numeric_conditions_comp[j], tmp->numeric_conditions_lh[j]->value, tmp->numeric_conditions_rh[j]->value ) ) { free_ExpNode( tmp->numeric_conditions_lh[j] ); free_ExpNode( tmp->numeric_conditions_rh[j] ); for ( k = j; k < tmp->num_numeric_conditions-1; k++ ) { tmp->numeric_conditions_comp[k] = tmp->numeric_conditions_comp[k+1]; tmp->numeric_conditions_lh[k] = tmp->numeric_conditions_lh[k+1]; tmp->numeric_conditions_rh[k] = tmp->numeric_conditions_rh[k+1]; } tmp->num_numeric_conditions--; } else { free_NormEffect( tmp ); return; } } else { j++; } } for ( j = 0; j < tmp->num_numeric_effects; j++ ) { for ( k = 0; k < gf_arity[tmp->numeric_effects_fluent[j].function]; k++ ) { if ( tmp->numeric_effects_fluent[j].args[k] == ENCODE_VAR( par ) ) { tmp->numeric_effects_fluent[j].args[k] = le->inst_table[i]; } } } for ( j = 0; j < tmp->num_numeric_effects; j++ ) { replace_var_with_const_in_exp( &(tmp->numeric_effects_rh[j]), par, le->inst_table[i] ); } /* logical part */ for ( j = 0; j < tmp->num_conditions; j++ ) { for ( k = 0; k < garity[tmp->conditions[j].predicate]; k++ ) { if ( tmp->conditions[j].args[k] == ENCODE_VAR( par ) ) { tmp->conditions[j].args[k] = le->inst_table[i]; } } } for ( j = 0; j < tmp->num_adds; j++ ) { for ( k = 0; k < garity[tmp->adds[j].predicate]; k++ ) { if ( tmp->adds[j].args[k] == ENCODE_VAR( par ) ) { tmp->adds[j].args[k] = le->inst_table[i]; } } } for ( j = 0; j < tmp->num_dels; j++ ) { for ( k = 0; k < garity[tmp->dels[j].predicate]; k++ ) { if ( tmp->dels[j].args[k] == ENCODE_VAR( par ) ) { tmp->dels[j].args[k] = le->inst_table[i]; } } } } /* adjust conditions */ i = 0; while ( i < tmp->num_conditions ) { rem = FALSE; p = tmp->conditions[i].predicate; if ( !gis_added[p] && !gis_deleted[p] ) { for ( j = 0; j < garity[p]; j++ ) { if ( tmp->conditions[i].args[j] < 0 && DECODE_VAR( tmp->conditions[i].args[j] < lo->num_vars ) ) { break; } } if ( j == garity[p] ) { /* inertia that constrain only effect params have been unified, * are therefore TRUE */ rem = TRUE; } } if ( rem ) { for ( j = i; j < tmp->num_conditions - 1; j++ ) { tmp->conditions[j].predicate = tmp->conditions[j+1].predicate; for ( k = 0; k < garity[tmp->conditions[j+1].predicate]; k++ ) { tmp->conditions[j].args[k] = tmp->conditions[j+1].args[k]; } } tmp->num_conditions--; } else { i++; } } /* add result to lres */ if ( lres ) { lres->prev = tmp; } tmp->next = lres; lres = tmp; return; } t = le->var_types[lmultiply_parameters[curr_parameter]]; n = gtype_size[t]; for ( i = 0; i < n; i++ ) { le->inst_table[lmultiply_parameters[curr_parameter]] = gtype_consts[t][i]; multiply_easy_non_constrained_effect_parameters( curr_parameter + 1 ); } le->inst_table[lmultiply_parameters[curr_parameter]] = -1; }
void multiply_easy_effect_parameters( void ) { int i, j, k, l, p, par; NormEffect *e; for ( i = 0; i < gnum_easy_operators; i++ ) { lo = geasy_operators[i]; lres = NULL; for ( e = lo->effects; e; e = e->next ) { le = e; lnum_inertia_conds = 0; for ( j = 0; j < e->num_conditions; j++ ) { for ( k = 0; k < garity[e->conditions[j].predicate]; k++ ) { if ( e->conditions[j].args[k] < 0 && DECODE_VAR( e->conditions[j].args[k] ) < lo->num_vars ) { break; } } if ( k < garity[e->conditions[j].predicate] ) { /* only consider inertia constraining effect parameters */ continue; } if ( !gis_added[e->conditions[j].predicate] && !gis_deleted[e->conditions[j].predicate] ) { linertia_conds[lnum_inertia_conds++] = j; } } lnum_multiply_parameters = 0; for ( j = 0; j < e->num_vars; j++ ) { par = lo->num_vars + j; for ( k = 0; k < lnum_inertia_conds; k++ ) { p = e->conditions[linertia_conds[k]].predicate; for ( l = 0; l < garity[p]; l++ ) { if ( e->conditions[linertia_conds[k]].args[l] == ENCODE_VAR( par ) ) { break; } } if ( l < garity[p] ) { break; } } if ( k < lnum_inertia_conds ) { continue; } lmultiply_parameters[lnum_multiply_parameters++] = j; } unify_easy_inertia_conditions( 0 ); } free_NormEffect( lo->effects ); lo->effects = lres; } }
void encode_easy_unaries_as_types( void ) { NormOperator *o; int i1, i, j, k, l, new_T, p, a; TypeArray T; int num_T; NormEffect *e; int intersected_type, var; for ( i1 = 0; i1 < gnum_easy_operators; i1++ ) { o = geasy_operators[i1]; for ( i = 0; i < o->num_vars; i++ ) { T[0] = o->var_types[i]; num_T = 1; j = 0; while ( j < o->num_preconds ) { p = o->preconds[j].predicate; if ( ( (new_T = gtype_to_predicate[p]) != -1 ) && ( o->preconds[j].args[0] == ENCODE_VAR( i ) ) ) { if ( num_T == MAX_TYPE_INTERSECTIONS ) { printf("\nincrease MAX_TYPE_INTERSECTIONS (currently %d)\n\n", MAX_TYPE_INTERSECTIONS); exit( 1 ); } /* insert new type number into ordered array T; * ---- all type numbers in T are different: * new nr. is of inferred type - can't be type declared for param * precondition facts occur at most once - doubles are removed * during cleanup */ for ( k = 0; k < num_T; k++ ) { if ( new_T < T[k] ) { break; } } for ( l = num_T; l > k; l-- ) { T[l] = T[l-1]; } T[k] = new_T; num_T++; /* now remove superfluous precondition */ for ( k = j; k < o->num_preconds-1; k++ ) { o->preconds[k].predicate = o->preconds[k+1].predicate; for ( l = 0; l < garity[o->preconds[k].predicate]; l++ ) { o->preconds[k].args[l] = o->preconds[k+1].args[l]; } } o->num_preconds--; } else { j++; } } /* if we did not hit any unary inertia concerning this parameter * in the preconds, skip parameter and go to next one */ if ( num_T == 1 ) { continue; } /* now we have the ordered array of types to intersect for param i * of op o in array T of size num_T; * if there already is this intersected type, set type of this * param to its number, otherwise create the new intersected type. */ if ( (intersected_type = find_intersected_type( T, num_T )) != -1 ) { /* type already there */ o->var_types[i] = intersected_type; continue; } /* create new type */ o->var_types[i] = create_intersected_type( T, num_T ); } for ( e = o->effects; e; e = e->next ) { for ( i = 0; i < e->num_vars; i++ ) { T[0] = e->var_types[i]; var = o->num_vars + i; num_T = 1; j = 0; while ( j < e->num_conditions ) { p = e->conditions[j].predicate; if ( p < 0 ) { j++; continue; } if ( ( (new_T = gtype_to_predicate[p]) != -1 ) && ( e->conditions[j].args[0] == ENCODE_VAR( var ) ) ) { if ( num_T == MAX_TYPE_INTERSECTIONS ) { printf("\nincrease MAX_TYPE_INTERSECTIONS (currently %d)\n\n", MAX_TYPE_INTERSECTIONS); exit( 1 ); } for ( k = 0; k < num_T; k++ ) { if ( new_T < T[k] ) { break; } } for ( l = num_T; l > k; l-- ) { T[l] = T[l-1]; } T[k] = new_T; num_T++; for ( k = j; k < e->num_conditions-1; k++ ) { e->conditions[k].predicate = e->conditions[k+1].predicate; a = ( e->conditions[k].predicate < 0 ) ? 2 : garity[e->conditions[k].predicate]; for ( l = 0; l < a; l++ ) { e->conditions[k].args[l] = e->conditions[k+1].args[l]; } } e->num_conditions--; } else { j++; } } if ( num_T == 1 ) { continue; } if ( (intersected_type = find_intersected_type( T, num_T )) != -1 ) { e->var_types[i] = intersected_type; continue; } e->var_types[i] = create_intersected_type( T, num_T ); } } } handle_empty_easy_parameters(); }
void multiply_easy_op_parameters( void ) { int i, j, k, l, p; NormOperator *o; geasy_templates = NULL; gnum_easy_templates = 0; for ( i = 0; i < gnum_easy_operators; i++ ) { lo = geasy_operators[i]; lnum_inertia_conds = 0; for ( j = 0; j < lo->num_preconds; j++ ) { if ( !gis_added[lo->preconds[j].predicate] && !gis_deleted[lo->preconds[j].predicate] ) { linertia_conds[lnum_inertia_conds++] = j; } } lnum_multiply_parameters = 0; for ( j = 0; j < lo->num_vars; j++ ) { for ( k = 0; k < lnum_inertia_conds; k++ ) { p = lo->preconds[linertia_conds[k]].predicate; for ( l = 0; l < garity[p]; l++ ) { if ( lo->preconds[linertia_conds[k]].args[l] == ENCODE_VAR( j ) ) { break; } } if ( l < garity[p] ) { break; } } if ( k < lnum_inertia_conds ) { continue; } lmultiply_parameters[lnum_multiply_parameters++] = j; } unify_easy_inertia_preconds( 0 ); } /* now remove inertia preconditions from operator schemata */ for ( i = 0; i < gnum_easy_operators; i++ ) { o = geasy_operators[i]; j = 0; while ( j < o->num_preconds ) { if ( !gis_added[o->preconds[j].predicate] && !gis_deleted[o->preconds[j].predicate] ) { for ( k = j; k < o->num_preconds - 1; k++ ) { o->preconds[k].predicate = o->preconds[k+1].predicate; for ( l = 0; l < garity[o->preconds[k].predicate]; l++ ) { o->preconds[k].args[l] = o->preconds[k+1].args[l]; } } o->num_preconds--; } else { j++; } } } }
void cleanup_hard_domain( void ) { int i, j, k, par; Operator *o; Effect *e; /* so far, only unused parameters removal */ for ( i = 0; i < gnum_hard_operators; i++ ) { o = ghard_operators[i]; j = 0; while ( j < o->num_vars ) { if ( var_used_in_wff( ENCODE_VAR( j ), o->preconds ) ) { j++; continue; } for ( e = o->effects; e; e = e->next ) { if ( var_used_in_wff( ENCODE_VAR( j ), e->conditions ) ) { break; } if ( var_used_in_literals( ENCODE_VAR( j ), e->effects ) ) { break; } } if ( e ) { j++; continue; } o->removed[j] = TRUE; j++; } for ( e = o->effects; e; e = e->next ) { j = 0; while ( j < e->num_vars ) { par = o->num_vars + j; if ( var_used_in_wff( ENCODE_VAR( par ), e->conditions ) ) { j++; continue; } if ( var_used_in_literals( ENCODE_VAR( par ), e->effects ) ) { j++; continue; } if ( e->var_names[j] ) { free( e->var_names[j] ); } for ( k = j; k < e->num_vars - 1; k++ ) { e->var_names[k] = e->var_names[k+1]; e->var_names[k] = e->var_names[k+1]; } e->num_vars--; decrement_inferior_vars( par, e->conditions ); decrement_inferior_vars_in_literals( par, e->effects ); } } } }
void remove_unused_easy_effect_parameters( NormOperator *o, NormEffect *e ) { Bool used[MAX_VARS]; int i1, i2, i, j, v, a; for ( i1 = 0; i1 < MAX_VARS; i1++ ) { used[i1] = FALSE; } for ( i1 = 0; i1 < e->num_conditions; i1++ ) { a = garity[e->conditions[i1].predicate]; for ( i2 = 0; i2 < a; i2++ ) { if ( e->conditions[i1].args[i2] < 0 ) { used[DECODE_VAR( e->conditions[i1].args[i2])] = TRUE; } } } for ( i1 = 0; i1 < e->num_adds; i1++ ) { for ( i2 = 0; i2 < garity[e->adds[i1].predicate]; i2++ ) { if ( e->adds[i1].args[i2] < 0 ) { used[DECODE_VAR( e->adds[i1].args[i2])] = TRUE; } } } for ( i1 = 0; i1 < e->num_dels; i1++ ) { for ( i2 = 0; i2 < garity[e->dels[i1].predicate]; i2++ ) { if ( e->dels[i1].args[i2] < 0 ) { used[DECODE_VAR( e->dels[i1].args[i2])] = TRUE; } } } i1 = 0; while ( i1 < e->num_vars ) { v = o->num_vars+i1; if ( used[v] ) { i1++; } else { for ( i2 = i1; i2 < e->num_vars-1; i2++ ) { e->var_types[i2] = e->var_types[i2+1]; used[o->num_vars+i2] = used[o->num_vars+i2+1]; } /* now decrement var entrys higher than o->num_vars+i1 */ for ( i = 0; i < e->num_conditions; i++ ) { a = garity[e->conditions[i].predicate]; for ( j = 0; j < a; j++ ) { if ( e->conditions[i].args[j] < ENCODE_VAR( v ) ) { e->conditions[i].args[j]++; } } } for ( i = 0; i < e->num_adds; i++ ) { for ( j = 0; j < garity[e->adds[i].predicate]; j++ ) { if ( e->adds[i].args[j] < ENCODE_VAR( v ) ) { e->adds[i].args[j]++; } } } for ( i = 0; i < e->num_dels; i++ ) { for ( j = 0; j < garity[e->dels[i].predicate]; j++ ) { if ( e->dels[i].args[j] < ENCODE_VAR( v ) ) { e->dels[i].args[j]++; } } } e->num_vars--; } } }
void multiply_easy_non_constrained_effect_parameters( int curr_parameter ) { int t, n, i, j, k, p, par; NormEffect *tmp; Bool rem; if ( curr_parameter == lnum_multiply_parameters ) { /* create new effect, adjusting conds to inst, and * partially instantiating effects; * * add result to lres */ tmp = new_NormEffect2( le ); /* instantiate param occurences */ for ( i = 0; i < le->num_vars; i++ ) { par = lo->num_vars + i; for ( j = 0; j < tmp->num_conditions; j++ ) { for ( k = 0; k < garity[tmp->conditions[j].predicate]; k++ ) { if ( tmp->conditions[j].args[k] == ENCODE_VAR( par ) ) { tmp->conditions[j].args[k] = le->inst_table[i]; } } } for ( j = 0; j < tmp->num_adds; j++ ) { for ( k = 0; k < garity[tmp->adds[j].predicate]; k++ ) { if ( tmp->adds[j].args[k] == ENCODE_VAR( par ) ) { tmp->adds[j].args[k] = le->inst_table[i]; } } } for ( j = 0; j < tmp->num_dels; j++ ) { for ( k = 0; k < garity[tmp->dels[j].predicate]; k++ ) { if ( tmp->dels[j].args[k] == ENCODE_VAR( par ) ) { tmp->dels[j].args[k] = le->inst_table[i]; } } } } /* adjust conditions */ i = 0; while ( i < tmp->num_conditions ) { rem = FALSE; p = tmp->conditions[i].predicate; if ( !gis_added[p] && !gis_deleted[p] ) { for ( j = 0; j < garity[p]; j++ ) { if ( tmp->conditions[i].args[j] < 0 && DECODE_VAR( tmp->conditions[i].args[j] < lo->num_vars ) ) { break; } } if ( j == garity[p] ) { /* inertia that constrain only effect params have been unified, * are therefore TRUE */ rem = TRUE; } } if ( rem ) { for ( j = i; j < tmp->num_conditions - 1; j++ ) { tmp->conditions[j].predicate = tmp->conditions[j+1].predicate; for ( k = 0; k < garity[tmp->conditions[j+1].predicate]; k++ ) { tmp->conditions[j].args[k] = tmp->conditions[j+1].args[k]; } } tmp->num_conditions--; } else { i++; } } /* add result to lres */ if ( lres ) { lres->prev = tmp; } tmp->next = lres; lres = tmp; return; } t = le->var_types[lmultiply_parameters[curr_parameter]]; n = gtype_size[t]; for ( i = 0; i < n; i++ ) { le->inst_table[lmultiply_parameters[curr_parameter]] = gtype_consts[t][i]; multiply_easy_non_constrained_effect_parameters( curr_parameter + 1 ); } le->inst_table[lmultiply_parameters[curr_parameter]] = -1; }
void build_action_templates( void ) { int i, j, k, l, p; ActionTemplate *t; Operator *o; for ( i = 0; i < gnum_operators; i++ ) { lo = goperators[i]; lo_num = i; for ( j = 0; j < gnum_constants; j++ ) { lused_constant[j] = FALSE; } lnum_inertia_preconds = 0; for ( j = 0; j < lo->num_preconds; j++ ) { if ( !gis_added[lo->preconds[j].predicate] && !gis_deleted[lo->preconds[j].predicate] ) { linertia_preconds[lnum_inertia_preconds++] = j; } } lnum_multiply_parameters = 0; for ( j = 0; j < lo->num_vars; j++ ) { for ( k = 0; k < lnum_inertia_preconds; k++ ) { p = lo->preconds[linertia_preconds[k]].predicate; for ( l = 0; l < garity[p]; l++ ) { if ( lo->preconds[linertia_preconds[k]].args[l] == ENCODE_VAR( j ) ) { break; } } if ( l < garity[p] ) { break; } } if ( k < lnum_inertia_preconds ) { continue; } lmultiply_parameters[lnum_multiply_parameters++] = j; } unify_inertia_preconds( 0 ); } if ( gcmd_line.display_info == 107 ) { printf("\n\naction templates:"); for ( i = 0; i < gnum_operators; i++ ) { printf("\n\noperator %s:", goperators[i]->name); for ( t = gtemplates; t; t = t->next ) { if ( t->op != i ) { continue; } printf("\ninst: "); for ( j = 0; j < goperators[i]->num_vars; j++ ) { if ( t->inst_table[j] < 0 ) { printf("\nuninstantiated param in template! debug me, please\n\n"); exit( 1 ); } printf("x%d = %s", j, gconstants[t->inst_table[j]]); if ( j < goperators[i]->num_vars - 1 ) { printf(", "); } } } } } /* now remove inertia preconditions from operator schemata */ for ( i = 0; i < gnum_operators; i++ ) { o = goperators[i]; j = 0; while ( j < o->num_preconds ) { if ( !gis_added[o->preconds[j].predicate] && !gis_deleted[o->preconds[j].predicate] ) { for ( k = j; k < o->num_preconds - 1; k++ ) { o->preconds[k].predicate = o->preconds[k+1].predicate; for ( l = 0; l < garity[o->preconds[k].predicate]; l++ ) { o->preconds[k].args[l] = o->preconds[k+1].args[l]; } } o->num_preconds--; } else { j++; } } } if ( gcmd_line.display_info == 108 ) { printf("\n\ninertia free operators are:"); for ( i = 0; i < gnum_operators; i++ ) { print_Operator( goperators[i] ); } printf("\n\n"); } }
void make_Fact( Fact *f, PlNode *n, Operator *o ) { int m, i; TokenList *t; if ( !n->atom ) { printf("\nillegal (empty) atom used in domain. check input files\n\n"); exit( 1 ); } if ( strcmp( n->atom->item, EQ_STR ) == SAME ) { f->predicate = -1; } else { f->predicate = position_in_predicates_table( n->atom->item ); if ( f->predicate == -1 ) { printf("\nundeclared predicate %s used in domain definition\n\n", n->atom->item); exit( 1 ); } } m = 0; for ( t = n->atom->next; t; t = t->next ) { if ( t->item[0] == '?' ) { if ( !o ) { printf("\natom in initial or goal state uses variable\n\n"); exit( 1 ); } for ( i=0; i<o->num_vars; i++ ) { if ( o->var_names[i] == t->item || strcmp( o->var_names[i], t->item ) == SAME ) { break; } } if ( i == o->num_vars ) { printf("\nunknown variable %s in literal %s (op %s). check input files\n\n", t->item, n->atom->item, o->name); exit( 1 ); } if ( f->predicate != -1 && o->var_types[i] != gpredicates_args_type[f->predicate][m] && !is_subtype( o->var_types[i], gpredicates_args_type[f->predicate][m] ) ) { printf("\ntype of var %s of op %s doesnt match type of arg %d of predicate %s\n\n", o->var_names[i], o->name, m, gpredicates[f->predicate]); exit( 1 ); } f->args[m] = ENCODE_VAR( i ); } else { if ( (f->args[m] = position_in_constants_table( t->item )) == -1 ) { printf("\nunknown constant %s in literal %s. check input files\n\n", t->item, n->atom->item); exit( 1 ); } } m++; } if ( f->predicate == -1 ) { if ( m != 2 ) { printf("\nfound eq - predicate with %d arguments. check input files\n\n", m); exit( 1 ); } } else { if ( m != garity[f->predicate] ) { printf("\npredicate %s is declared to have %d arguments. check input files\n\n", gpredicates[f->predicate], garity[f->predicate]); exit( 1 ); } } }
void encode_unary_inertia_as_types( void ) { Operator *o; int i1, i, j, k, l, new_T, p; TypeArray T; int num_T; int intersected_type; for ( i = 0; i < MAX_TYPES; i++ ) { gnum_intersected_types[i] = -1; } for ( i1 = 0; i1 < gnum_operators; i1++ ) { o = goperators[i1]; for ( i = 0; i < o->num_vars; i++ ) { T[0] = o->var_types[i]; num_T = 1; j = 0; while ( j < o->num_preconds ) { p = o->preconds[j].predicate; if ( ( (new_T = gtype_to_predicate[p]) != -1 ) && ( o->preconds[j].args[0] == ENCODE_VAR( i ) ) ) { if ( num_T == MAX_TYPE_INTERSECTIONS ) { printf("\nincrease MAX_TYPE_INTERSECTIONS (currently %d)\n\n", MAX_TYPE_INTERSECTIONS); exit( 1 ); } /* insert new type number into ordered array T; * ---- all type numbers in T are different: * new nr. is of inferred type - can't be type declared for param * precondition facts occur at most once - doubles are removed * during cleanup */ for ( k = 0; k < num_T; k++ ) { if ( new_T < T[k] ) { break; } } for ( l = num_T; l > k; l-- ) { T[l] = T[l-1]; } T[k] = new_T; num_T++; /* now remove superfluous precondition */ for ( k = j; k < o->num_preconds-1; k++ ) { o->preconds[k].predicate = o->preconds[k+1].predicate; for ( l = 0; l < garity[o->preconds[k].predicate]; l++ ) { o->preconds[k].args[l] = o->preconds[k+1].args[l]; } } o->num_preconds--; } else { j++; } } /* if we did not hit any unary inertia concerning this parameter * in the preconds, skip parameter and go to next one */ if ( num_T == 1 ) { continue; } /* now we have the ordered array of types to intersect for param i * of op o in array T of size num_T; * if there already is this intersected type, set type of this * param to its number, otherwise create the new intersected type. */ if ( (intersected_type = find_intersected_type( T, num_T )) != -1 ) { /* type already there */ o->var_types[i] = intersected_type; continue; } /* have to create new type */ if ( gnum_types == MAX_TYPES ) { printf("\ntoo many (inferred and intersected) types! increase MAX_TYPES (currently %d)\n\n", MAX_TYPES); exit( 1 ); } gtype_names[gnum_types] = NULL; gtype_size[gnum_types] = 0; for ( j = 0; j < MAX_CONSTANTS; j++ ) { gis_member[j][gnum_types] = FALSE; } for ( j = 0; j < num_T; j++ ) { gintersected_types[gnum_types][j] = T[j]; } gnum_intersected_types[gnum_types] = num_T; intersected_type = gnum_types; o->var_types[i] = intersected_type; gnum_types++; for ( j = 0; j < gtype_size[T[0]]; j++ ) { for ( k = 1; k < num_T; k++ ) { if ( !gis_member[gtype_consts[T[0]][j]][T[k]] ) { break; } } if ( k < num_T ) { continue; } /* add constant to new type */ if ( gtype_size[intersected_type] == MAX_TYPE ) { printf("\ntoo many consts in type %s! increase MAX_TYPE (currently %d)\n\n", gtype_names[intersected_type], MAX_TYPE); exit( 1 ); } gtype_consts[intersected_type][gtype_size[intersected_type]++] = gtype_consts[T[0]][j]; gis_member[gtype_consts[T[0]][j]][intersected_type] = TRUE; } /* now verify if the intersected type equals one of the types that we intersected. * this is the case, iff one of the types in T has the same size as intersected_type */ for ( j = 0; j < num_T; j++ ) { if ( gtype_size[intersected_type] != gtype_size[T[j]] ) { continue; } /* type T[j] contains exactly the constants that we need! * * remove intersected type from table! */ gtype_size[intersected_type] = 0; for ( k = 0; k < MAX_CONSTANTS; k++ ) { gis_member[k][intersected_type] = FALSE; } gnum_intersected_types[intersected_type] = -1; gnum_types--; o->var_types[i] = T[j]; break; } } } }