void remove_unused_parameters( void ) { Operator *o; Bool used[MAX_VARS]; int i, i1, i2, i3; for ( i = 0; i < gnum_operators; i++ ) { o = goperators[i]; for ( i1 = 0; i1 < MAX_VARS; i1++ ) { used[i1] = FALSE; } for ( i1 = 0; i1 < o->num_preconds; i1++ ) { for ( i2 = 0; i2 < garity[o->preconds[i1].predicate]; i2++ ) { if ( o->preconds[i1].args[i2] < 0 ) { used[DECODE_VAR( o->preconds[i1].args[i2] )] = TRUE; } } } for ( i1 = 0; i1 < o->num_adds; i1++ ) { for ( i2 = 0; i2 < garity[o->adds[i1].predicate]; i2++ ) { if ( o->adds[i1].args[i2] < 0 ) { used[DECODE_VAR( o->adds[i1].args[i2])] = TRUE; } } } for ( i1 = 0; i1 < o->num_dels; i1++ ) { for ( i2 = 0; i2 < garity[o->dels[i1].predicate]; i2++ ) { if ( o->dels[i1].args[i2] < 0 ) { used[DECODE_VAR( o->dels[i1].args[i2])] = TRUE; } } } i1 = 0; i3 = 0; while ( i1 < o->num_vars ) { if ( used[i1] ) { i1++; } else { printf("\nwarning: parameter x%d of op %s is not used. skipping it.", i3, o->name); for ( i2 = i1; i2 < o->num_vars-1; i2++ ) { o->var_types[i2] = o->var_types[i2+1]; used[i2] = used[i2+1]; } decrement_var_entries( o, i1 ); o->num_vars--; } i3++; } } }
Effect *instantiate_Effect( Effect *e ) { Effect *res = NULL, *tmp, *i; Literal *tt, *l; int j; for ( i = e; i; i = i->next ) { tmp = new_Effect(); tmp->eff_p = i->eff_p;/* july06: copy over eff prob */ for ( j = 0; j < i->num_vars; j++ ) { tmp->var_types[j] = i->var_types[j]; } tmp->num_vars = i->num_vars; tmp->conditions = instantiate_wff( i->conditions ); if ( tmp->conditions->connective == FAL ) { free_partial_Effect( tmp ); continue; } for ( l = i->effects; l; l = l->next ) { tt = new_Literal(); tt->negated = l->negated; tt->fact.predicate = l->fact.predicate; for ( j = 0; j < garity[tt->fact.predicate]; j++ ) { tt->fact.args[j] = l->fact.args[j]; if ( tt->fact.args[j] < 0 && linst_table[DECODE_VAR( tt->fact.args[j] )] != -1 ) { tt->fact.args[j] = linst_table[DECODE_VAR( tt->fact.args[j] )]; } } tt->next = tmp->effects; if ( tmp->effects ) { tmp->effects->prev = tt; } tmp->effects = tt; } tmp->next = res; if ( res ) { res->prev = tmp; } res = tmp; } return res; }
void print_Fact( Fact *f ) { int j; if ( f->predicate == -3 ) { printf("GOAL-REACHED"); return; } if ( f->predicate == -1 ) { printf("(="); for ( j=0; j<2; j++ ) { printf(" "); if ( f->args[j] >= 0 ) { printf("%s", gconstants[(f->args)[j]]); } else { printf("x%d", DECODE_VAR( f->args[j] )); } } printf(")"); return; } if ( f->predicate == -2 ) { printf("(!="); for ( j=0; j<2; j++ ) { printf(" "); if ( f->args[j] >= 0 ) { printf("%s", gconstants[(f->args)[j]]); } else { printf("x%d", DECODE_VAR( f->args[j] )); } } printf(")"); return; } printf("(%s", gpredicates[f->predicate]); for ( j=0; j<garity[f->predicate]; j++ ) { printf(" "); if ( f->args[j] >= 0 ) { printf("%s", gconstants[(f->args)[j]]); } else { printf("x%d", DECODE_VAR( f->args[j] )); } } printf(")"); }
void print_Fact_file( FILE* OUT, Fact *f ) { int j; if ( f->predicate == -3 ) { fprintf(OUT,"GOAL-REACHED"); return; } if ( f->predicate == -1 ) { fprintf(OUT,"(="); for ( j=0; j<2; j++ ) { fprintf(OUT," "); if ( f->args[j] >= 0 ) { fprintf(OUT,"%s", gconstants[(f->args)[j]]); } else { fprintf(OUT,"x%d", DECODE_VAR( f->args[j] )); } } fprintf(OUT,")"); return; } if ( f->predicate == -2 ) { fprintf(OUT,"(!="); for ( j=0; j<2; j++ ) { fprintf(OUT," "); if ( f->args[j] >= 0 ) { fprintf(OUT,"%s", gconstants[(f->args)[j]]); } else { fprintf(OUT,"x%d", DECODE_VAR( f->args[j] )); } } fprintf(OUT,")"); return; } fprintf(OUT,"(%s", gpredicates[f->predicate]); for ( j=0; j<garity[f->predicate]; j++ ) { fprintf(OUT," "); if ( f->args[j] >= 0 ) { fprintf(OUT,"%s", gconstants[(f->args)[j]]); } else { fprintf(OUT,"x%d", DECODE_VAR( f->args[j] )); } } fprintf(OUT,")"); }
void make_instantiate_numeric_effects( PseudoActionEffect *e, NumericEffect *ne ) { int m = 0, i; NumericEffect *n; for ( n = ne; n; n = n->next ) m++; e->numeric_effects_neft = ( NumericEffectType * ) calloc( m, sizeof( NumericEffectType ) ); e->numeric_effects_fluent = ( Fluent * ) calloc( m, sizeof( Fluent ) ); e->numeric_effects_rh = ( ExpNode_pointer * ) calloc( m, sizeof( ExpNode_pointer ) ); e->num_numeric_effects = m; m = 0; for ( n = ne; n; n = n->next ) { e->numeric_effects_neft[m] = n->neft; e->numeric_effects_fluent[m].function = n->fluent.function; for ( i = 0; i < gf_arity[n->fluent.function]; i++ ) { e->numeric_effects_fluent[m].args[i] = ( n->fluent.args[i] < 0 ) ? linst_table[DECODE_VAR( n->fluent.args[i] )] : n->fluent.args[i]; } e->numeric_effects_rh[m] = copy_Exp( n->rh ); instantiate_exp( &(e->numeric_effects_rh[m]) ); m++; } }
void unify_easy_inertia_preconds( int curr_inertia ) { int p, i, j, af, hh; int args[MAX_VARS]; int affected_params[MAX_VARS]; int num_affected_params = 0; if ( curr_inertia == lnum_inertia_conds ) { multiply_easy_non_constrained_op_parameters( 0 ); return; } p = lo->preconds[linertia_conds[curr_inertia]].predicate; for ( i = 0; i < garity[p]; i++ ) { args[i] = lo->preconds[linertia_conds[curr_inertia]].args[i]; if ( args[i] < 0 ) { hh = DECODE_VAR( args[i] ); if ( lo->inst_table[hh] != -1 ) { args[i] = lo->inst_table[hh]; } else { affected_params[num_affected_params++] = hh; } } } for ( i = 0; i < gnum_initial_predicate[p]; i++ ) { af = 0; for ( j = 0; j < garity[p]; j++ ) { if ( args[j] >= 0 ) { if ( args[j] != ginitial_predicate[p][i].args[j] ) { break; } else { continue; } } /* check whether that constant has the correct type for that * parameter (can be not fulfilled due to encoding of unary inertia */ if ( !gis_member[ginitial_predicate[p][i].args[j]][lo->var_types[affected_params[af]]] ) { break; } /* legal constant; set op parameter instantiation to it */ lo->inst_table[affected_params[af++]] = ginitial_predicate[p][i].args[j]; } if ( j < garity[p] ) { continue; } unify_easy_inertia_preconds( curr_inertia + 1 ); } for ( i = 0; i < num_affected_params; i++ ) { lo->inst_table[affected_params[i]] = -1; } }
void unify_easy_inertia_conditions( int curr_inertia ) { int p, i, j, af, hh; int args[MAX_VARS]; int affected_params[MAX_VARS]; int num_affected_params = 0; if ( curr_inertia == lnum_inertia_conds ) { multiply_easy_non_constrained_effect_parameters( 0 ); return; } p = le->conditions[linertia_conds[curr_inertia]].predicate; for ( i = 0; i < garity[p]; i++ ) { args[i] = le->conditions[linertia_conds[curr_inertia]].args[i]; if ( args[i] < 0 ) { hh = DECODE_VAR( args[i] ); hh -= lo->num_vars; if ( le->inst_table[hh] != -1 ) { args[i] = le->inst_table[hh]; } else { affected_params[num_affected_params++] = hh; } } } for ( i = 0; i < gnum_initial_predicate[p]; i++ ) { af = 0; for ( j = 0; j < garity[p]; j++ ) { if ( args[j] >= 0 ) { if ( args[j] != ginitial_predicate[p][i].args[j] ) { break; } else { continue; } } le->inst_table[affected_params[af++]] = ginitial_predicate[p][i].args[j]; } if ( j < garity[p] ) { continue; } unify_easy_inertia_conditions( curr_inertia + 1 ); } for ( i = 0; i < num_affected_params; i++ ) { le->inst_table[affected_params[i]] = -1; } }
void make_instantiate_literals( PseudoActionEffect *e, Literal *ll ) { int ma = 0, md = 0, i; Literal *l; for ( l = ll; l; l = l->next ) { if ( l->negated ) { md++; } else { ma++; } } e->adds = ( Fact * ) calloc( ma, sizeof( Fact ) ); e->dels = ( Fact * ) calloc( md, sizeof( Fact ) ); for ( l = ll; l; l = l->next ) { if ( l->negated ) { e->dels[e->num_dels].predicate = l->fact.predicate; for ( i = 0; i < garity[l->fact.predicate]; i++ ) { e->dels[e->num_dels].args[i] = ( l->fact.args[i] < 0 ) ? linst_table[DECODE_VAR( l->fact.args[i] )] : l->fact.args[i]; } e->num_dels++; } else { e->adds[e->num_adds].predicate = l->fact.predicate; for ( i = 0; i < garity[l->fact.predicate]; i++ ) { e->adds[e->num_adds].args[i] = ( l->fact.args[i] < 0 ) ? linst_table[DECODE_VAR( l->fact.args[i] )] : l->fact.args[i]; } e->num_adds++; } } }
void print_Fluent( Fluent *f ) { int j, ff = f->function; printf("(%s", gfunctions[ff]); for ( j=0; j<gf_arity[ff]; j++ ) { printf(" "); if ( f->args[j] >= 0 ) { printf("%s", gconstants[(f->args)[j]]); } else { printf("x%d", DECODE_VAR( f->args[j] )); } } printf(")"); }
void decrement_inferior_vars_in_literals( int var, Literal *ef ) { Literal *l; int i; for ( l = ef; l; l = l->next ) { for ( i = 0; i < garity[l->fact.predicate]; i++ ) { if ( l->fact.args[i] >= 0 ) { continue; } if ( DECODE_VAR( l->fact.args[i] ) > var ) { l->fact.args[i]++; } } } }
void decrement_inferior_vars_in_numeric_effects( int var, NumericEffect *ef ) { NumericEffect *l; int i; for ( l = ef; l; l = l->next ) { for ( i = 0; i < gf_arity[l->fluent.function]; i++ ) { if ( l->fluent.args[i] >= 0 ) { continue; } if ( DECODE_VAR( l->fluent.args[i] ) > var ) { l->fluent.args[i]++; } } decrement_inferior_vars_in_exp( var, l->rh ); } }
void perform_reachability_analysis( void ) { int size, i, j, k, adr, num, pargtype; Bool fixpoint; Facts *f; NormOperator *no; EasyTemplate *t1, *t2; NormEffect *ne; Action *tmp, *a; Bool *had_hard_template; PseudoAction *pa; PseudoActionEffect *pae; gactions = NULL; gnum_actions = 0; for ( i = 0; i < gnum_predicates; i++ ) { size = 1; for ( j = 0; j < garity[i]; j++ ) { pargtype = gpredicates_args_type[i][j]; size *= gtype_size[pargtype]; } lpos[i] = ( int_pointer ) calloc( size, sizeof( int ) ); lneg[i] = ( int_pointer ) calloc( size, sizeof( int ) ); luse[i] = ( int_pointer ) calloc( size, sizeof( int ) ); lindex[i] = ( int_pointer ) calloc( size, sizeof( int ) ); for ( j = 0; j < size; j++ ) { lpos[i][j] = 0; lneg[i][j] = 1;/* all facts but initials are poss. negative */ luse[i][j] = 0; lindex[i][j] = -1; } } had_hard_template = ( Bool * ) calloc( gnum_hard_templates, sizeof( Bool ) ); for ( i = 0; i < gnum_hard_templates; i++ ) { had_hard_template[i] = FALSE; } /* mark initial facts as possibly positive, not poss. negative */ for ( i = 0; i < gnum_predicates; i++ ) { lp = i; for ( j = 0; j < gnum_initial_predicate[i]; j++ ) { for ( k = 0; k < garity[i]; k++ ) { largs[k] = ginitial_predicate[i][j].args[k]; } adr = fact_adress(); lpos[lp][adr] = 1; lneg[lp][adr] = 0; } } /* compute fixpoint */ fixpoint = FALSE; while ( !fixpoint ) { fixpoint = TRUE; /* assign next layer of easy templates to possibly positive fixpoint */ t1 = geasy_templates; while ( t1 ) { no = t1->op; for ( i = 0; i < no->num_preconds; i++ ) { lp = no->preconds[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = ( no->preconds[i].args[j] >= 0 ) ? no->preconds[i].args[j] : t1->inst_table[DECODE_VAR( no->preconds[i].args[j] )]; } if ( !lpos[lp][fact_adress()] ) { break; } } if ( i < no->num_preconds ) { t1 = t1->next; continue; } num = 0; for ( ne = no->effects; ne; ne = ne->next ) { num++; /* currently, simply ignore effect conditions and assume * they will all be made true eventually. */ for ( i = 0; i < ne->num_adds; i++ ) { lp = ne->adds[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = ( ne->adds[i].args[j] >= 0 ) ? ne->adds[i].args[j] : t1->inst_table[DECODE_VAR( ne->adds[i].args[j] )]; } adr = fact_adress(); if ( !lpos[lp][adr] ) { /* new relevant fact! (added non initial) */ lpos[lp][adr] = 1; lneg[lp][adr] = 1; luse[lp][adr] = 1; if ( gnum_relevant_facts == MAX_RELEVANT_FACTS ) { printf("\ntoo many relevant facts! increase MAX_RELEVANT_FACTS (currently %d)\n\n", MAX_RELEVANT_FACTS); exit( 1 ); } grelevant_facts[gnum_relevant_facts].predicate = lp; for ( j = 0; j < garity[lp]; j++ ) { grelevant_facts[gnum_relevant_facts].args[j] = largs[j]; } lindex[lp][adr] = gnum_relevant_facts; gnum_relevant_facts++; fixpoint = FALSE; } } } tmp = new_Action(); tmp->norm_operator = no; for ( i = 0; i < no->num_vars; i++ ) { tmp->inst_table[i] = t1->inst_table[i]; } tmp->name = no->operator->name; tmp->num_name_vars = no->operator->number_of_real_params; make_name_inst_table_from_NormOperator( tmp, no, t1 ); tmp->next = gactions; tmp->num_effects = num; gactions = tmp; gnum_actions++; t2 = t1->next; if ( t1->next ) { t1->next->prev = t1->prev; } if ( t1->prev ) { t1->prev->next = t1->next; } else { geasy_templates = t1->next; } free_single_EasyTemplate( t1 ); t1 = t2; } /* now assign all hard templates that have not been transformed * to actions yet. */ for ( i = 0; i < gnum_hard_templates; i++ ) { if ( had_hard_template[i] ) { continue; } pa = ghard_templates[i]; for ( j = 0; j < pa->num_preconds; j++ ) { lp = pa->preconds[j].predicate; for ( k = 0; k < garity[lp]; k++ ) { largs[k] = pa->preconds[j].args[k]; } if ( !lpos[lp][fact_adress()] ) { break; } } if ( j < pa->num_preconds ) { continue; } for ( pae = pa->effects; pae; pae = pae->next ) { /* currently, simply ignore effect conditions and assume * they will all be made true eventually. */ for ( j = 0; j < pae->num_adds; j++ ) { lp = pae->adds[j].predicate; for ( k = 0; k < garity[lp]; k++ ) { largs[k] = pae->adds[j].args[k]; } adr = fact_adress(); if ( !lpos[lp][adr] ) { /* new relevant fact! (added non initial) */ lpos[lp][adr] = 1; lneg[lp][adr] = 1; luse[lp][adr] = 1; if ( gnum_relevant_facts == MAX_RELEVANT_FACTS ) { printf("\ntoo many relevant facts! increase MAX_RELEVANT_FACTS (currently %d)\n\n", MAX_RELEVANT_FACTS); exit( 1 ); } grelevant_facts[gnum_relevant_facts].predicate = lp; for ( k = 0; k < garity[lp]; k++ ) { grelevant_facts[gnum_relevant_facts].args[k] = largs[k]; } lindex[lp][adr] = gnum_relevant_facts; gnum_relevant_facts++; fixpoint = FALSE; } } } tmp = new_Action(); tmp->pseudo_action = pa; for ( j = 0; j < pa->operator->num_vars; j++ ) { tmp->inst_table[j] = pa->inst_table[j]; } tmp->name = pa->operator->name; tmp->num_name_vars = pa->operator->number_of_real_params; make_name_inst_table_from_PseudoAction( tmp, pa ); tmp->next = gactions; tmp->num_effects = pa->num_effects; gactions = tmp; gnum_actions++; had_hard_template[i] = TRUE; } } free( had_hard_template ); gnum_pp_facts = gnum_initial + gnum_relevant_facts; if ( gcmd_line.display_info == 118 ) { printf("\nreachability analysys came up with:"); printf("\n\npossibly positive facts:"); for ( f = ginitial; f; f = f->next ) { printf("\n"); print_Fact( f->fact ); } for ( i = 0; i < gnum_relevant_facts; i++ ) { printf("\n"); print_Fact( &(grelevant_facts[i]) ); } printf("\n\nthis yields these %d action templates:", gnum_actions); for ( i = 0; i < gnum_operators; i++ ) { printf("\n\noperator %s:", goperators[i]->name); for ( a = gactions; a; a = a->next ) { if ( ( a->norm_operator && a->norm_operator->operator != goperators[i] ) || ( a->pseudo_action && a->pseudo_action->operator != goperators[i] ) ) { continue; } printf("\ntemplate: "); for ( j = 0; j < goperators[i]->number_of_real_params; j++ ) { printf("%s", gconstants[a->name_inst_table[j]]); if ( j < goperators[i]->num_vars-1 ) { printf(" "); } } } } printf("\n\n"); } }
void unify_easy_inertia_preconds( int curr_inertia ) { int p, i, j, k, af, hh; int args[MAX_VARS]; int affected_params[MAX_VARS]; int num_affected_params = 0; if ( curr_inertia == lnum_inertia_conds ) { multiply_easy_non_constrained_op_parameters( 0 ); return; } p = lo->preconds[linertia_conds[curr_inertia]].predicate; for ( i = 0; i < garity[p]; i++ ) { args[i] = lo->preconds[linertia_conds[curr_inertia]].args[i]; if ( args[i] < 0 ) { hh = DECODE_VAR( args[i] ); if ( lo->inst_table[hh] != -1 ) { args[i] = lo->inst_table[hh]; } else { affected_params[num_affected_params++] = hh; } } } for ( i = 0; i < gnum_initial_predicate[p]; i++ ) { af = 0; for ( j = 0; j < garity[p]; j++ ) { if ( args[j] >= 0 ) { if ( args[j] != ginitial_predicate[p][i].args[j] ) { break; } else { continue; } } /* see if we have that constant already in instantiation; * if so, skip this inertia: op params are assumed different! */ /* if ( lused_constant[ginitial_predicate[p][i].args[j]] ) { break; } */ /* legal constant; set op parameter instantiation to it */ lo->inst_table[affected_params[af++]] = ginitial_predicate[p][i].args[j]; lused_constant[ginitial_predicate[p][i].args[j]] = TRUE; } if ( j < garity[p] ) { for ( k = 0; k < af; k++ ) { lused_constant[lo->inst_table[affected_params[k]]] = FALSE; } continue; } unify_easy_inertia_preconds( curr_inertia + 1 ); for ( j = 0; j < num_affected_params; j++ ) { lused_constant[lo->inst_table[affected_params[j]]] = FALSE; } } for ( i = 0; i < num_affected_params; i++ ) { lo->inst_table[affected_params[i]] = -1; } }
void unify_inertia_preconds( int curr_inertia ) { int p, i, j, k, af; int args[MAX_VARS]; int affected_params[MAX_VARS]; int num_affected_params = 0; if ( curr_inertia == lnum_inertia_preconds ) { multiply_parameters( 0 ); return; } /* might be possible to implement this more effective by * collecting the arg vectors for each inertia as a preprocess * and setting, when instantiating a parameter, all the occurences * in the following inertia arg vectors to the appropriate constant * value. * * affected parameters are also the same on each call for a single inertia, * so this is unnecessary recomputing. */ p = lo->preconds[linertia_preconds[curr_inertia]].predicate; for ( i = 0; i < garity[p]; i++ ) { args[i] = lo->preconds[linertia_preconds[curr_inertia]].args[i]; if ( args[i] < 0 && lo->inst_table[DECODE_VAR( args[i] )] != -1 ) { args[i] = lo->inst_table[DECODE_VAR( args[i] )]; } if ( args[i] < 0 ) { affected_params[num_affected_params++] = DECODE_VAR( args[i] ); } } for ( i = 0; i < gnum_inertia; i++ ) { if ( ginertia[i].predicate != p ) { continue; } af = 0; for ( j = 0; j < garity[p]; j++ ) { if ( args[j] >= 0 ) { if ( args[j] != ginertia[i].args[j] ) { break; } else { continue; } } /* see if we have that constant already in instantiation; * if so, skip this inertia: op params are assumed different! */ if ( lused_constant[ginertia[i].args[j]] ) { break; } /* check whether that constant has the correct type for that * parameter */ if ( !gis_member[ginertia[i].args[j]][lo->var_types[affected_params[af]]] ) { break; } /* legal constant; set op parameter instantiation to it */ lo->inst_table[affected_params[af++]] = ginertia[i].args[j]; lused_constant[ginertia[i].args[j]] = TRUE; } if ( j < garity[p] ) { for ( k = 0; k < af; k++ ) { lused_constant[lo->inst_table[affected_params[k]]] = FALSE; } continue; } unify_inertia_preconds( curr_inertia + 1 ); for ( j = 0; j < num_affected_params; j++ ) { lused_constant[lo->inst_table[affected_params[j]]] = FALSE; } } for ( i = 0; i < num_affected_params; i++ ) { lo->inst_table[affected_params[i]] = -1; } }
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 create_final_actions( void ) { Action *a; NormOperator *no; NormEffect *ne; int i, j, adr, h; PseudoAction *pa; PseudoActionEffect *pae; for ( a = gactions; a; a = a->next ) { if ( a->norm_operator ) { /* action comes from an easy template NormOp */ no = a->norm_operator; if ( no->num_preconds > 0 ) { a->preconds = ( int * ) calloc( no->num_preconds, sizeof( int ) ); } a->num_preconds = 0; for ( i = 0; i < no->num_preconds; i++ ) { lp = no->preconds[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = ( no->preconds[i].args[j] >= 0 ) ? no->preconds[i].args[j] : a->inst_table[DECODE_VAR( no->preconds[i].args[j] )]; } adr = fact_adress(); /* preconds are lpos in all cases due to reachability analysis */ if ( !lneg[lp][adr] ) { continue; } a->preconds[a->num_preconds++] = lindex[lp][adr]; } if ( a->num_effects > 0 ) { a->effects = ( ActionEffect * ) calloc( a->num_effects, sizeof( ActionEffect ) ); } a->num_effects = 0; for ( ne = no->effects; ne; ne = ne->next ) { if ( ne->num_conditions > 0 ) { a->effects[a->num_effects].conditions = ( int * ) calloc( ne->num_conditions, sizeof( int ) ); } a->effects[a->num_effects].num_conditions = 0; for ( i = 0; i < ne->num_conditions; i++ ) { lp = ne->conditions[i].predicate; h = ( lp < 0 ) ? 2 : garity[lp]; for ( j = 0; j < h; j++ ) { largs[j] = ( ne->conditions[i].args[j] >= 0 ) ? ne->conditions[i].args[j] : a->inst_table[DECODE_VAR( ne->conditions[i].args[j] )]; } if ( lp >= 0 ) { adr = fact_adress(); if ( !lpos[lp][adr] ) {/* condition not reachable: skip effect */ break; } if ( !lneg[lp][adr] ) {/* condition always true: skip it */ continue; } a->effects[a->num_effects].conditions[a->effects[a->num_effects].num_conditions++] = lindex[lp][adr]; } else { if ( lp == -2 ) { if ( largs[0] == largs[1] ) break; } else { if ( largs[0] != largs[1] ) break; } } } if ( i < ne->num_conditions ) {/* found unreachable condition: free condition space */ free( a->effects[a->num_effects].conditions ); continue; } /* now create the add and del effects. */ if ( ne->num_adds > 0 ) { a->effects[a->num_effects].adds = ( int * ) calloc( ne->num_adds, sizeof( int ) ); } a->effects[a->num_effects].num_adds = 0; for ( i = 0; i < ne->num_adds; i++ ) { lp = ne->adds[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = ( ne->adds[i].args[j] >= 0 ) ? ne->adds[i].args[j] : a->inst_table[DECODE_VAR( ne->adds[i].args[j] )]; } adr = fact_adress(); if ( !lneg[lp][adr] ) {/* effect always true: skip it */ continue; } a->effects[a->num_effects].adds[a->effects[a->num_effects].num_adds++] = lindex[lp][adr]; } if ( ne->num_dels > 0 ) { a->effects[a->num_effects].dels = ( int * ) calloc( ne->num_dels, sizeof( int ) ); } a->effects[a->num_effects].num_dels = 0; for ( i = 0; i < ne->num_dels; i++ ) { lp = ne->dels[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = ( ne->dels[i].args[j] >= 0 ) ? ne->dels[i].args[j] : a->inst_table[DECODE_VAR( ne->dels[i].args[j] )]; } adr = fact_adress(); if ( !lpos[lp][adr] ) {/* effect always false: skip it */ continue; } a->effects[a->num_effects].dels[a->effects[a->num_effects].num_dels++] = lindex[lp][adr]; } /* this effect is OK. go to next one in NormOp. */ a->num_effects++; lnum_effects++; } continue; } if ( a->pseudo_action ) { /* action is result of a PseudoAction */ pa = a->pseudo_action; if ( pa->num_preconds > 0 ) { a->preconds = ( int * ) calloc( pa->num_preconds, sizeof( int ) ); } a->num_preconds = 0; for ( i = 0; i < pa->num_preconds; i++ ) { lp = pa->preconds[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = pa->preconds[i].args[j]; } adr = fact_adress(); /* preconds are lpos in all cases due to reachability analysis */ if ( !lneg[lp][adr] ) { continue; } a->preconds[a->num_preconds++] = lindex[lp][adr]; } if ( a->num_effects > 0 ) { a->effects = ( ActionEffect * ) calloc( a->num_effects, sizeof( ActionEffect ) ); } a->num_effects = 0; for ( pae = pa->effects; pae; pae = pae->next ) { if ( pae->num_conditions > 0 ) { a->effects[a->num_effects].conditions = ( int * ) calloc( pae->num_conditions, sizeof( int ) ); } a->effects[a->num_effects].num_conditions = 0; for ( i = 0; i < pae->num_conditions; i++ ) { lp = pae->conditions[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = pae->conditions[i].args[j]; } adr = fact_adress(); if ( !lpos[lp][adr] ) {/* condition not reachable: skip effect */ break; } if ( !lneg[lp][adr] ) {/* condition always true: skip it */ continue; } a->effects[a->num_effects].conditions[a->effects[a->num_effects].num_conditions++] = lindex[lp][adr]; } if ( i < pae->num_conditions ) {/* found unreachable condition: free condition space */ free( a->effects[a->num_effects].conditions ); continue; } /* now create the add and del effects. */ if ( pae->num_adds > 0 ) { a->effects[a->num_effects].adds = ( int * ) calloc( pae->num_adds, sizeof( int ) ); } a->effects[a->num_effects].num_adds = 0; for ( i = 0; i < pae->num_adds; i++ ) { lp = pae->adds[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = pae->adds[i].args[j]; } adr = fact_adress(); if ( !lneg[lp][adr] ) {/* effect always true: skip it */ continue; } a->effects[a->num_effects].adds[a->effects[a->num_effects].num_adds++] = lindex[lp][adr]; } if ( pae->num_dels > 0 ) { a->effects[a->num_effects].dels = ( int * ) calloc( pae->num_dels, sizeof( int ) ); } a->effects[a->num_effects].num_dels = 0; for ( i = 0; i < pae->num_dels; i++ ) { lp = pae->dels[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = pae->dels[i].args[j]; } adr = fact_adress(); if ( !lpos[lp][adr] ) {/* effect always false: skip it */ continue; } a->effects[a->num_effects].dels[a->effects[a->num_effects].num_dels++] = lindex[lp][adr]; } /* this effect is OK. go to next one in PseudoAction. */ a->num_effects++; lnum_effects++; } }/* end of if clause for PseudoAction */ /* if action was neither normop, nor pseudo action determined, * then it is an artificial action due to disjunctive goal * conditions. * * these are already in final form. */ }/* endfor all actions ! */ }
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; } }
WffNode *instantiate_wff( WffNode *w ) { WffNode *res = NULL, *tmp, *i; int j, c0, c1, m, h; Bool ok; switch ( w->connective ) { case AND: m = 0; i = w->sons; while ( i ) { tmp = instantiate_wff( i ); if ( tmp->connective == FAL ) { free_WffNode( res ); return tmp; } if ( tmp->connective == TRU ) { free( tmp ); i = i->next; continue; } tmp->next = res; if ( res ) { res->prev = tmp; } res = tmp; i = i->next; m++; } if ( m == 0 ) { res = new_WffNode( TRU ); break; } if ( m == 1 ) { break; } tmp = new_WffNode( AND ); tmp->sons = res; res = tmp; break; case OR: m = 0; i = w->sons; while ( i ) { tmp = instantiate_wff( i ); if ( tmp->connective == TRU ) { free_WffNode( res ); return tmp; } if ( tmp->connective == FAL ) { free( tmp ); i = i->next; continue; } tmp->next = res; if ( res ) { res->prev = tmp; } res = tmp; i = i->next; m++; } if ( m == 0 ) { res = new_WffNode( FAL ); break; } if ( m == 1 ) { break; } tmp = new_WffNode( OR ); tmp->sons = res; res = tmp; break; case NOT: /* must be non-equality */ c0 = ( w->son->fact->args[0] < 0 ) ? linst_table[DECODE_VAR( w->son->fact->args[0] )] : w->son->fact->args[0]; c1 = ( w->son->fact->args[1] < 0 ) ? linst_table[DECODE_VAR( w->son->fact->args[1] )] : w->son->fact->args[1]; if ( c0 < 0 || c1 < 0 ) { /* ef param while checking ef conds in inst op */ res = new_WffNode( ATOM ); res->fact = new_Fact(); res->fact->predicate = -2; res->fact->args[0] = ( c0 < 0 ) ? w->son->fact->args[0] : c0; res->fact->args[1] = ( c1 < 0 ) ? w->son->fact->args[1] : c1; break; } if ( c0 != c1 ) { res = new_WffNode( TRU ); } else { res = new_WffNode( FAL ); } break; case ATOM: res = new_WffNode( ATOM ); res->fact = new_Fact(); res->fact->predicate = w->fact->predicate; ok = TRUE; for ( j = 0; j < garity[res->fact->predicate]; j++ ) { h = ( w->fact->args[j] < 0 ) ? linst_table[DECODE_VAR( w->fact->args[j] )] : w->fact->args[j]; if ( h < 0 ) { ok = FALSE; res->fact->args[j] = w->fact->args[j]; } else { res->fact->args[j] = h; } } if ( !ok ) {/* contains ef params */ break; } if ( !full_possibly_negative( res->fact ) ) { free( res->fact ); res->fact = NULL; res->connective = TRU; break; } if ( !full_possibly_positive( res->fact ) ) { free( res->fact ); res->fact = NULL; res->connective = FAL; break; } break; case TRU: case FAL: res = new_WffNode( w->connective ); break; default: printf("\n\nillegal connective %d in instantiate formula\n\n", w->connective); exit( 1 ); } return res; }
void perform_reachability_analysis( void ) { int size, i, j, k, adr, num; Bool fixpoint; Facts *f; NormOperator *no; EasyTemplate *t1, *t2; NormEffect *ne; Action *tmp, *a; Bool *had_hard_template; PseudoAction *pa; PseudoActionEffect *pae; /* * DEA - University of Brescia */ int numero, kk, kkk; WffNode *precs, *n; /* * End of DEA */ gactions = NULL; gnum_actions = 0; for ( i = 0; i < gnum_predicates; i++ ) { size = 1; for ( j = 0; j < garity[i]; j++ ) { size *= gnum_constants; } lpos[i] = ( int_pointer ) calloc( size, sizeof( int ) ); lneg[i] = ( int_pointer ) calloc( size, sizeof( int ) ); luse[i] = ( int_pointer ) calloc( size, sizeof( int ) ); lindex[i] = ( int_pointer ) calloc( size, sizeof( int ) ); for ( j = 0; j < size; j++ ) { lpos[i][j] = 0; lneg[i][j] = 1;/* all facts but initials are poss. negative */ luse[i][j] = 0; lindex[i][j] = -1; } } had_hard_template = ( Bool * ) calloc( gnum_hard_templates, sizeof( Bool ) ); for ( i = 0; i < gnum_hard_templates; i++ ) { had_hard_template[i] = FALSE; } /* mark initial facts as possibly positive, not poss. negative */ for ( i = 0; i < gnum_predicates; i++ ) { lp = i; for ( j = 0; j < gnum_initial_predicate[i]; j++ ) { for ( k = 0; k < garity[i]; k++ ) { largs[k] = ginitial_predicate[i][j].args[k]; } adr = fact_adress(); lpos[lp][adr] = 1; lneg[lp][adr] = 0; } } /* compute fixpoint */ fixpoint = FALSE; while ( !fixpoint ) { fixpoint = TRUE; /* * DEA - University of Brescia */ /*geasy_templates: action list (instantious operator) */ numero = 0; for (t1 = geasy_templates; t1; t1 = t1->next) numero++; if (gcmd_line.display_info == 121) printf ("\nLe geasy_templates sono %d, le gnum_actions %d", numero, gnum_actions); /* * End of DEA */ /* assign next layer of easy templates to possibly positive fixpoint */ t1 = geasy_templates; while ( t1 ) { no = t1->op; for ( i = 0; i < no->num_preconds; i++ ) { lp = no->preconds[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = ( no->preconds[i].args[j] >= 0 ) ? no->preconds[i].args[j] : t1->inst_table[DECODE_VAR( no->preconds[i].args[j] )]; } /* * DEA - University of Brescia */ //se questa precondizione compare anche tra gli effetti additivi, allora considerala raggiunta //ATTENZIONE: non e' esattamente corretto; questo check e' volto a gestire il caso di una precondizione over all o at end //che viene realizzata attraverso un effetto at start - senza qs check l'azione non risulta applicabile //il problema e' che qui non introduco i check su overall, end, etc: basta che una preco compaia anche tra gli effetti e la considero raggiunta //ATTENZIONE: saltare questo check se il corrispondente PlOperator e' is_odd for (kk = 0; kk < no->effects->num_adds; kk++) { int this_pred = no->effects->adds[kk].predicate; if(no->effects->num_adds>MAX_VARS) { #ifdef __MY_OUTPUT__ MSG_ERROR ( WAR_MAX_VARS ); #else printf( WAR_MAX_VARS ); #endif exit (1); } for (kkk = 0; kkk < no->effects->num_adds; kkk++) these_args[kkk] = (no->effects->adds[kk].args[kkk] >= 0) ? no->effects->adds[kk].args[kkk] : t1-> inst_table[DECODE_VAR(no->effects->adds[kk].args[kkk])]; //cerco la preco corrente tra gli effetti additivi //il predicato non coincide: provo con il prossimo effetto if (this_pred != lp) continue; //controllo tutti gli argomenti for (kkk = 0; kkk < garity[this_pred]; kkk++) //se ce n'e' almeno uno diverso, non e' lo stesso fatto if (these_args[kkk] != largs[kkk]) break; //questo if e' vero se e' lo stesso fatto: l'ho trovato quindi esco if (kkk == garity[this_pred]) break; } //se non ho fatto passare tutti gli effetti, significa che ho trovato la preco tra gli effetti additivi: considero raggiunta la preco, passa a controllare la prossima if (kk != no->effects->num_adds) continue; /* se tale preco non e' raggiunta, esci e vai a qui1 */ /* * End of DEA */ if ( !lpos[lp][fact_adress()] ) { break; } } if ( i < no->num_preconds ) { t1 = t1->next; continue; } /* * DEA - University of Brescia */ //ulteriore check: verifico che un predicato inerziale sia effettivamente presente nei fatti iniziali, altrimenti l'azione non e' applicabile //problema rilevato con Rovers/SimpleTime precs = no->operator-> preconds; if (precs->connective == AND) precs = precs->sons; for (n = precs; n; n = n->next) { //mi e' capitato di trovare un nodo not, con son predicato -1. boh? (problema:Satellite/numeric) if (n->fact == NULL) continue; /*lp=numero di predicato della preco i-esima */ lp = n->fact->predicate; /*per ciascuno degli argomenti della precondizione */ for (j = 0; j < garity[lp]; j++) { /* CONTROLLARE */ largs[j] =(n->fact->args[j] >= 0 ) ? n->fact->args[j]: t1->inst_table[DECODE_VAR (n->fact->args[j])]; } adr = fact_adress (); //CHECK1 chiesto da Ivan: se il fatto e' non inerziale e non compare tra le preconds del normoperator, da errore! //INIZIO CHECK1 if (gis_added[lp] || gis_deleted[lp]) { for (i = 0; i < no->num_preconds; i++) { /*lp=numero di predicato della preco i-esima */ lp1 = no->preconds[i].predicate; /*per ciascuno degli argomenti della precondizione */ for (j = 0; j < garity[lp1]; j++) { /* non ho colto qui perche' ci sono 2 casi, comunque mette in largs[k] il numero di ciascun oggetto */ largs1[j] = (no->preconds[i].args[j] >= 0) ? no->preconds[i].args[j] : t1-> inst_table[DECODE_VAR (no->preconds[i].args[j])]; } if ((lp == lp1) && (adr == fact_adress1 ())) break; } if (i == no->num_preconds) { if(DEBUG3) { printf ("\nAttenzione: uno dei fatti non inerziali non compare tra le preconds del normoperator!\n"); fflush (stdout); } assert (0); } } //FINE CHECK1 //se questo fatto viene aggiunto, non e' necessario verificarlo -> passo al prossimo if (gis_added[lp]) continue; //Se il fatto non e' stato raggiunto, non posso applicare l'azione: esco dal for if (!lpos[lp][fact_adress ()]) break; } //se ho fatto un break prima di finire le preco, significa che un predicato inerziale non compare nei fatti iniziali if (n != NULL) { //passo quindi ad esaminare la prossima azione t1 = t1->next; continue; } /* * End of DEA */ num = 0; for ( ne = no->effects; ne; ne = ne->next ) { num++; /* currently, simply ignore effect conditions and assume * they will all be made true eventually. */ for ( i = 0; i < ne->num_adds; i++ ) { lp = ne->adds[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = ( ne->adds[i].args[j] >= 0 ) ? ne->adds[i].args[j] : t1->inst_table[DECODE_VAR( ne->adds[i].args[j] )]; } adr = fact_adress(); if ( !lpos[lp][adr] ) { /* new relevant fact! (added non initial) */ lpos[lp][adr] = 1; lneg[lp][adr] = 1; luse[lp][adr] = 1; if ( gnum_relevant_facts == MAX_RELEVANT_FACTS ) { printf("\ntoo many relevant facts! increase MAX_RELEVANT_FACTS (currently %d)\n\n", MAX_RELEVANT_FACTS); exit( 1 ); } grelevant_facts[gnum_relevant_facts].predicate = lp; for ( j = 0; j < garity[lp]; j++ ) { grelevant_facts[gnum_relevant_facts].args[j] = largs[j]; } lindex[lp][adr] = gnum_relevant_facts; gnum_relevant_facts++; fixpoint = FALSE; } } } /* * DEA - University of Brescia */ check_time_and_length (0); /* con zero non controlla la lunghezza */ /* * End of DEA */ tmp = new_Action(); tmp->norm_operator = no; for ( i = 0; i < no->num_vars; i++ ) { tmp->inst_table[i] = t1->inst_table[i]; } tmp->name = no->operator->name; tmp->num_name_vars = no->operator->number_of_real_params; make_name_inst_table_from_NormOperator( tmp, no, t1 ); tmp->next = gactions; tmp->num_effects = num; gactions = tmp; gnum_actions++; t2 = t1->next; if ( t1->next ) { t1->next->prev = t1->prev; } if ( t1->prev ) { t1->prev->next = t1->next; } else { geasy_templates = t1->next; } free_single_EasyTemplate( t1 ); t1 = t2; } /* now assign all hard templates that have not been transformed * to actions yet. */ for ( i = 0; i < gnum_hard_templates; i++ ) { if ( had_hard_template[i] ) { continue; } pa = ghard_templates[i]; for ( j = 0; j < pa->num_preconds; j++ ) { lp = pa->preconds[j].predicate; for ( k = 0; k < garity[lp]; k++ ) { largs[k] = pa->preconds[j].args[k]; } if ( !lpos[lp][fact_adress()] ) { break; } } if ( j < pa->num_preconds ) { continue; } for ( pae = pa->effects; pae; pae = pae->next ) { /* currently, simply ignore effect conditions and assume * they will all be made true eventually. */ for ( j = 0; j < pae->num_adds; j++ ) { lp = pae->adds[j].predicate; for ( k = 0; k < garity[lp]; k++ ) { largs[k] = pae->adds[j].args[k]; } adr = fact_adress(); if ( !lpos[lp][adr] ) { /* new relevant fact! (added non initial) */ lpos[lp][adr] = 1; lneg[lp][adr] = 1; luse[lp][adr] = 1; if ( gnum_relevant_facts == MAX_RELEVANT_FACTS ) { printf("\ntoo many relevant facts! increase MAX_RELEVANT_FACTS (currently %d)\n\n", MAX_RELEVANT_FACTS); exit( 1 ); } grelevant_facts[gnum_relevant_facts].predicate = lp; for ( k = 0; k < garity[lp]; k++ ) { grelevant_facts[gnum_relevant_facts].args[k] = largs[k]; } lindex[lp][adr] = gnum_relevant_facts; gnum_relevant_facts++; fixpoint = FALSE; } } } /* * DEA - University of Brescia */ check_time_and_length (0); /* con zero non controlla la lunghezza */ /* * End of DEA */ tmp = new_Action(); tmp->pseudo_action = pa; for ( j = 0; j < pa->operator->num_vars; j++ ) { tmp->inst_table[j] = pa->inst_table[j]; } tmp->name = pa->operator->name; tmp->num_name_vars = pa->operator->number_of_real_params; make_name_inst_table_from_PseudoAction( tmp, pa ); tmp->next = gactions; tmp->num_effects = pa->num_effects; gactions = tmp; gnum_actions++; had_hard_template[i] = TRUE; } } /* * DEA - University of Brescia */ numero = 0; for (t1 = geasy_templates; t1; t1 = t1->next) numero++; if (gcmd_line.display_info == 121) printf ("\nLe geasy_templates sono %d, le gnum_actions %d", numero, gnum_actions); /* * End of DEA */ free( had_hard_template ); gnum_pp_facts = gnum_initial + gnum_relevant_facts; if ( gcmd_line.display_info == 118 ) { printf("\nreachability analysys came up with:"); printf("\n\npossibly positive facts:"); for ( f = ginitial; f; f = f->next ) { printf("\n"); print_Fact( f->fact ); } for ( i = 0; i < gnum_relevant_facts; i++ ) { printf("\n"); print_Fact( &(grelevant_facts[i]) ); } printf("\n\nthis yields these %d action templates:", gnum_actions); for ( i = 0; i < gnum_operators; i++ ) { printf("\n\noperator %s:", goperators[i]->name); for ( a = gactions; a; a = a->next ) { if ( ( a->norm_operator && a->norm_operator->operator != goperators[i] ) || ( a->pseudo_action && a->pseudo_action->operator != goperators[i] ) ) { continue; } printf("\ntemplate: "); for ( j = 0; j < goperators[i]->number_of_real_params; j++ ) { printf("%s", gconstants[a->name_inst_table[j]]); if ( j < goperators[i]->num_vars-1 ) { printf(" "); } } } } printf("\n\n"); } }
void instantiate_exp( ExpNode **n ) { int j, f, k, h; Bool ok; switch ( (*n)->connective ) { case AD: instantiate_exp( &((*n)->leftson) ); instantiate_exp( &((*n)->rightson) ); if ( (*n)->leftson->connective != NUMBER || (*n)->rightson->connective != NUMBER ) { break; } (*n)->connective = NUMBER; (*n)->value = (*n)->leftson->value + (*n)->rightson->value; free_ExpNode( (*n)->leftson ); (*n)->leftson = NULL; free_ExpNode( (*n)->rightson ); (*n)->rightson = NULL; break; case SU: instantiate_exp( &((*n)->leftson) ); instantiate_exp( &((*n)->rightson) ); if ( (*n)->leftson->connective != NUMBER || (*n)->rightson->connective != NUMBER ) { break; } (*n)->connective = NUMBER; (*n)->value = (*n)->leftson->value - (*n)->rightson->value; free_ExpNode( (*n)->leftson ); (*n)->leftson = NULL; free_ExpNode( (*n)->rightson ); (*n)->rightson = NULL; break; case MU: instantiate_exp( &((*n)->leftson) ); instantiate_exp( &((*n)->rightson) ); if ( (*n)->leftson->connective != NUMBER || (*n)->rightson->connective != NUMBER ) { break; } (*n)->connective = NUMBER; (*n)->value = (*n)->leftson->value * (*n)->rightson->value; free_ExpNode( (*n)->leftson ); (*n)->leftson = NULL; free_ExpNode( (*n)->rightson ); (*n)->rightson = NULL; break; case DI: instantiate_exp( &((*n)->leftson) ); instantiate_exp( &((*n)->rightson) ); if ( (*n)->leftson->connective != NUMBER || (*n)->rightson->connective != NUMBER ) { break; } if ( (*n)->rightson->value == 0 ) { /* kind of unclean: simply leave that in here; * we will later determine the right thing * to do with it. */ break; } (*n)->connective = NUMBER; (*n)->value = (*n)->leftson->value / (*n)->rightson->value; free_ExpNode( (*n)->leftson ); (*n)->leftson = NULL; free_ExpNode( (*n)->rightson ); (*n)->rightson = NULL; break; case MINUS: instantiate_exp( &((*n)->son) ); if ( (*n)->son->connective != NUMBER ) break; (*n)->connective = NUMBER; (*n)->value = ((float) (-1)) * (*n)->son->value; free_ExpNode( (*n)->son ); (*n)->son = NULL; break; case NUMBER: break; case FHEAD: f = (*n)->fluent->function; ok = TRUE; for ( j = 0; j < gf_arity[f]; j++ ) { h = ( (*n)->fluent->args[j] < 0 ) ? linst_table[DECODE_VAR( (*n)->fluent->args[j] )] : (*n)->fluent->args[j]; if ( h < 0 ) { ok = FALSE; } else { (*n)->fluent->args[j] = h; } } if ( !ok ) { break; } /* we handle only the case where the fluent is fully instantiated, * static, and in the initial state. */ if ( gis_changed[f] ) break; for ( j = 0; j < gnum_initial_function[f]; j++ ) { for ( k = 0; k < gf_arity[f]; k++ ) { if ( ginitial_function[f][j].fluent.args[k] != (*n)->fluent->args[k] ) break; } if ( k < gf_arity[f] ) continue; (*n)->connective = NUMBER; (*n)->value = ginitial_function[f][j].value; break; } break; default: printf("\n\ninst exp: wrong specifier %d", (*n)->connective); exit( 1 ); } }
void collect_relevant_facts( void ) { Action *a; NormOperator *no; NormEffect *ne; int i, j, adr; PseudoAction *pa; PseudoActionEffect *pae; /* mark all deleted facts; such facts, that are also pos, are relevant. */ for ( a = gactions; a; a = a->next ) { if ( a->norm_operator ) { no = a->norm_operator; for ( ne = no->effects; ne; ne = ne->next ) { for ( i = 0; i < ne->num_dels; i++ ) { lp = ne->dels[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = ( ne->dels[i].args[j] >= 0 ) ? ne->dels[i].args[j] : a->inst_table[DECODE_VAR( ne->dels[i].args[j] )]; } adr = fact_adress(); lneg[lp][adr] = 1; if ( lpos[lp][adr] && !luse[lp][adr] ) { luse[lp][adr] = 1; lindex[lp][adr] = gnum_relevant_facts; if ( gnum_relevant_facts == MAX_RELEVANT_FACTS ) { printf("\nincrease MAX_RELEVANT_FACTS! (current value: %d)\n\n", MAX_RELEVANT_FACTS); exit( 1 ); } grelevant_facts[gnum_relevant_facts].predicate = lp; for ( j = 0; j < garity[lp]; j++ ) { grelevant_facts[gnum_relevant_facts].args[j] = largs[j]; } lindex[lp][adr] = gnum_relevant_facts; gnum_relevant_facts++; } } } } else { pa = a->pseudo_action; for ( pae = pa->effects; pae; pae = pae->next ) { for ( i = 0; i < pae->num_dels; i++ ) { lp = pae->dels[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = pae->dels[i].args[j]; } adr = fact_adress(); lneg[lp][adr] = 1; if ( lpos[lp][adr] && !luse[lp][adr] ) { luse[lp][adr] = 1; lindex[lp][adr] = gnum_relevant_facts; if ( gnum_relevant_facts == MAX_RELEVANT_FACTS ) { printf("\nincrease MAX_RELEVANT_FACTS! (current value: %d)\n\n", MAX_RELEVANT_FACTS); exit( 1 ); } grelevant_facts[gnum_relevant_facts].predicate = lp; for ( j = 0; j < garity[lp]; j++ ) { grelevant_facts[gnum_relevant_facts].args[j] = largs[j]; } lindex[lp][adr] = gnum_relevant_facts; gnum_relevant_facts++; } } } } } if ( gcmd_line.display_info == 119 ) { printf("\n\nfacts selected as relevant:\n\n"); for ( i = 0; i < gnum_relevant_facts; i++ ) { printf("\n%d: ", i); print_Fact( &(grelevant_facts[i]) ); } } lnum_effects = 0; // Chih-Wei if (GpG.SearchModal != -2) create_final_goal_state(); create_final_initial_state(); create_final_actions(); if ( gcmd_line.display_info == 120 ) { printf("\n\nfinal domain representation is:\n\n"); for ( i = 0; i < gnum_operators; i++ ) { printf("\n\n------------------operator %s-----------\n\n", goperators[i]->name); for ( a = gactions; a; a = a->next ) { if ( ( !a->norm_operator && !a->pseudo_action ) || ( a->norm_operator && a->norm_operator->operator != goperators[i] ) || ( a->pseudo_action && a->pseudo_action->operator != goperators[i] ) ) { continue; } print_Action( a ); } } printf("\n\n--------------------GOAL REACHED ops-----------\n\n"); for ( a = gactions; a; a = a->next ) { if ( !a->norm_operator && !a->pseudo_action ) { print_Action( a ); } } printf("\n\nfinal initial state is:\n\n"); for ( i = 0; i < ginitial_state.num_F; i++ ) { print_ft_name( ginitial_state.F[i] ); printf("\n"); } printf("\n\nfinal goal state is:\n\n"); for ( i = 0; i < ggoal_state.num_F; i++ ) { print_ft_name( ggoal_state.F[i] ); printf("\n"); } } }
WffNode *instantiate_wff( WffNode *w ) { WffNode *res = NULL, *tmp, *i; int j, m, h; Bool ok, ct; switch ( w->connective ) { case AND: m = 0; i = w->sons; while ( i ) { tmp = instantiate_wff( i ); if ( tmp->connective == FAL ) { free_WffNode( res ); return tmp; } if ( tmp->connective == TRU ) { free( tmp ); i = i->next; continue; } tmp->next = res; if ( res ) { res->prev = tmp; } res = tmp; i = i->next; m++; } if ( m == 0 ) { res = new_WffNode( TRU ); break; } if ( m == 1 ) { break; } tmp = new_WffNode( AND ); tmp->sons = res; res = tmp; break; case OR: m = 0; i = w->sons; while ( i ) { tmp = instantiate_wff( i ); if ( tmp->connective == TRU ) { free_WffNode( res ); return tmp; } if ( tmp->connective == FAL ) { free( tmp ); i = i->next; continue; } tmp->next = res; if ( res ) { res->prev = tmp; } res = tmp; i = i->next; m++; } if ( m == 0 ) { res = new_WffNode( FAL ); break; } if ( m == 1 ) { break; } tmp = new_WffNode( OR ); tmp->sons = res; res = tmp; break; case ATOM: res = new_WffNode( ATOM ); res->fact = new_Fact(); res->fact->predicate = w->fact->predicate; ok = TRUE; for ( j = 0; j < garity[res->fact->predicate]; j++ ) { h = ( w->fact->args[j] < 0 ) ? linst_table[DECODE_VAR( w->fact->args[j] )] : w->fact->args[j]; if ( h < 0 ) { ok = FALSE; res->fact->args[j] = w->fact->args[j]; } else { res->fact->args[j] = h; } } if ( !ok ) {/* contains ef params */ break; } if ( !full_possibly_negative( res->fact ) ) { free( res->fact ); res->fact = NULL; res->connective = TRU; break; } if ( !full_possibly_positive( res->fact ) ) { free( res->fact ); res->fact = NULL; res->connective = FAL; break; } break; case COMP: res = new_WffNode( COMP ); res->comp = w->comp; res->lh = copy_Exp( w->lh ); res->rh = copy_Exp( w->rh ); instantiate_exp( &(res->lh) ); instantiate_exp( &(res->rh) ); if ( res->lh->connective != NUMBER || res->rh->connective != NUMBER ) { /* logical simplification only possible if both parts are numbers */ break; } ct = number_comparison_holds( res->comp, res->lh->value, res->rh->value ); if ( ct ) { res->connective = TRU; free_ExpNode( res->lh ); res->lh = NULL; free_ExpNode( res->rh ); res->rh = NULL; res->comp = -1; } else { res->connective = FAL; free_ExpNode( res->lh ); res->lh = NULL; free_ExpNode( res->rh ); res->rh = NULL; res->comp = -1; } break; case TRU: case FAL: res = new_WffNode( w->connective ); break; default: printf("\n\nillegal connective %d in instantiate formula\n\n", w->connective); exit( 1 ); } return res; }
Effect *instantiate_Effect( Effect *e ) { Effect *res = NULL, *tmp, *i; Literal *tt, *l; NumericEffect *ne, *ttt; int j; for ( i = e; i; i = i->next ) { tmp = new_Effect(); for ( j = 0; j < i->num_vars; j++ ) { tmp->var_types[j] = i->var_types[j]; } tmp->num_vars = i->num_vars; tmp->conditions = instantiate_wff( i->conditions ); if ( tmp->conditions->connective == FAL ) { free_partial_Effect( tmp ); continue; } for ( l = i->effects; l; l = l->next ) { tt = new_Literal(); tt->negated = l->negated; tt->fact.predicate = l->fact.predicate; for ( j = 0; j < garity[tt->fact.predicate]; j++ ) { tt->fact.args[j] = l->fact.args[j]; if ( tt->fact.args[j] < 0 && linst_table[DECODE_VAR( tt->fact.args[j] )] != -1 ) { tt->fact.args[j] = linst_table[DECODE_VAR( tt->fact.args[j] )]; } } tt->next = tmp->effects; if ( tmp->effects ) { tmp->effects->prev = tt; } tmp->effects = tt; } for ( ne = i->numeric_effects; ne; ne = ne->next ) { ttt = new_NumericEffect(); ttt->neft = ne->neft; ttt->fluent.function = ne->fluent.function; for ( j = 0; j < gf_arity[ttt->fluent.function]; j++ ) { ttt->fluent.args[j] = ne->fluent.args[j]; if ( ttt->fluent.args[j] < 0 && linst_table[DECODE_VAR( ttt->fluent.args[j] )] != -1 ) { ttt->fluent.args[j] = linst_table[DECODE_VAR( ttt->fluent.args[j] )]; } } ttt->rh = copy_Exp( ne->rh ); instantiate_exp( &(ttt->rh) ); ttt->next = tmp->numeric_effects; if ( tmp->numeric_effects ) { tmp->numeric_effects->prev = ttt; } tmp->numeric_effects = ttt; } tmp->next = res; if ( res ) { res->prev = tmp; } res = tmp; } return res; }
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 remove_unused_easy_parameters( void ) { int i, i1, i2, i3, a; NormEffect *e; Bool used[MAX_VARS]; NormOperator *o; for ( i = 0; i < gnum_easy_operators; i++ ) { o = geasy_operators[i]; for ( i1 = 0; i1 < MAX_VARS; i1++ ) { used[i1] = FALSE; } for ( i1 = 0; i1 < o->num_preconds; i1++ ) { for ( i2 = 0; i2 < garity[o->preconds[i1].predicate]; i2++ ) { if ( o->preconds[i1].args[i2] < 0 ) { used[DECODE_VAR( o->preconds[i1].args[i2] )] = TRUE; } } } for ( e = o->effects; e; e = e->next ) { 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; } } } remove_unused_easy_effect_parameters( o, e ); } i1 = 0; i3 = 0; while ( i1 < o->num_vars ) { if ( used[i1] ) { i1++; } else { o->type_removed_vars[o->num_removed_vars] = o->var_types[i1]; for ( i2 = i1; i2 < o->num_vars-1; i2++ ) { o->var_types[i2] = o->var_types[i2+1]; used[i2] = used[i2+1]; } decrement_var_entries( o, i1 ); o->num_vars--; o->removed_vars[o->num_removed_vars++] = i3; } i3++; } } }
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--; } } }