in grolp/gen/ff_planner/inst_final.c [1197:1762]
void create_final_actions( void )
{
Action *a, *p, *t;
NormOperator *no;
NormEffect *ne;
int i, j, adr;
PseudoAction *pa;
PseudoActionEffect *pae;
ActionEffect *aa;
Bool false_cond;
a = gactions; p = NULL;
while ( a ) {
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];
}
/**************************NUMERIC PRECOND*************************/
if ( no->num_numeric_preconds > 0 ) {
a->numeric_preconds_comp = ( Comparator * )
calloc( no->num_numeric_preconds, sizeof( Comparator ) );
a->numeric_preconds_lh = ( ExpNode_pointer * )
calloc( no->num_numeric_preconds, sizeof( ExpNode_pointer ) );
a->numeric_preconds_rh = ( ExpNode_pointer * )
calloc( no->num_numeric_preconds, sizeof( ExpNode_pointer ) );
a->num_numeric_preconds = 0;
}
for ( i = 0; i < no->num_numeric_preconds; i++ ) {
a->numeric_preconds_comp[a->num_numeric_preconds] = no->numeric_preconds_comp[i];
a->numeric_preconds_lh[a->num_numeric_preconds] = copy_Exp( no->numeric_preconds_lh[i] );
instantiate_exp_by_action( &(a->numeric_preconds_lh[a->num_numeric_preconds]), a );
if ( !set_relevants_in_exp( &(a->numeric_preconds_lh[a->num_numeric_preconds]) ) ) break;
a->numeric_preconds_rh[a->num_numeric_preconds] = copy_Exp( no->numeric_preconds_rh[i] );
instantiate_exp_by_action( &(a->numeric_preconds_rh[a->num_numeric_preconds]), a );
if ( !set_relevants_in_exp( &(a->numeric_preconds_rh[a->num_numeric_preconds]) ) ) break;
if ( a->numeric_preconds_lh[a->num_numeric_preconds]->connective == NUMBER &&
a->numeric_preconds_rh[a->num_numeric_preconds]->connective == NUMBER ) {
/* trivial numeric precond
*/
if ( number_comparison_holds( a->numeric_preconds_comp[a->num_numeric_preconds],
a->numeric_preconds_lh[a->num_numeric_preconds]->value,
a->numeric_preconds_rh[a->num_numeric_preconds]->value ) ) {
/* true precond -> throw precond away. by not incrementing number of such.
*/
free_ExpNode( a->numeric_preconds_lh[a->num_numeric_preconds] );
free_ExpNode( a->numeric_preconds_rh[a->num_numeric_preconds] );
continue;
} else {
/* false precond -> throw action away.
*/
break;
}
}
a->num_numeric_preconds++;
}
if ( i < no->num_numeric_preconds ) {
/* a precond accesses an undefined fluent, or is false -> remove action!
*/
gnum_actions--;
if ( p ) {
p->next = a->next;
t = a;
a = a->next;
t->next = gtrash_actions;
gtrash_actions = t;
} else {
gactions = a->next;
t = a;
a = a->next;
t->next = gtrash_actions;
gtrash_actions = t;
}
continue;
}
/**************************NUMERIC PRECOND-END*************************/
/* and now for the effects
*/
if ( a->num_effects > 0 ) {
a->effects = ( ActionEffect * ) calloc( a->num_effects, sizeof( ActionEffect ) );
for ( i = 0; i < a->num_effects; i++ ) {
a->effects[i].illegal = FALSE;
a->effects[i].removed = FALSE;
}
}
a->num_effects = 0;
for ( ne = no->effects; ne; ne = ne->next ) {
aa = &(a->effects[a->num_effects]);
if ( ne->num_conditions > 0 ) {
aa->conditions = ( int * ) calloc( ne->num_conditions, sizeof( int ) );
}
aa->num_conditions = 0;
for ( i = 0; i < ne->num_conditions; i++ ) {
lp = ne->conditions[i].predicate;
for ( j = 0; j < garity[lp]; j++ ) {
largs[j] = ( ne->conditions[i].args[j] >= 0 ) ?
ne->conditions[i].args[j] : a->inst_table[DECODE_VAR( ne->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;
}
aa->conditions[aa->num_conditions++] = lindex[lp][adr];
}
if ( i < ne->num_conditions ) {/* found unreachable condition: free condition space */
free( aa->conditions );
continue;
}
/**************************NUMERIC COND*************************/
if ( ne->num_numeric_conditions > 0 ) {
aa->numeric_conditions_comp = ( Comparator * )
calloc( ne->num_numeric_conditions, sizeof( Comparator ) );
aa->numeric_conditions_lh = ( ExpNode_pointer * )
calloc( ne->num_numeric_conditions, sizeof( ExpNode_pointer ) );
aa->numeric_conditions_rh = ( ExpNode_pointer * )
calloc( ne->num_numeric_conditions, sizeof( ExpNode_pointer ) );
for ( i = 0; i < ne->num_numeric_conditions; i++ ) {
aa->numeric_conditions_lh[i] = NULL;
aa->numeric_conditions_rh[i] = NULL;
}
aa->num_numeric_conditions = 0;
}
false_cond = FALSE;
for ( i = 0; i < ne->num_numeric_conditions; i++ ) {
aa->numeric_conditions_comp[aa->num_numeric_conditions] = ne->numeric_conditions_comp[i];
aa->numeric_conditions_lh[aa->num_numeric_conditions] = copy_Exp( ne->numeric_conditions_lh[i] );
instantiate_exp_by_action( &(aa->numeric_conditions_lh[aa->num_numeric_conditions]), a );
if ( !set_relevants_in_exp( &(aa->numeric_conditions_lh[aa->num_numeric_conditions]) ) ) break;
aa->numeric_conditions_rh[aa->num_numeric_conditions] = copy_Exp( ne->numeric_conditions_rh[i] );
instantiate_exp_by_action( &(aa->numeric_conditions_rh[aa->num_numeric_conditions]), a );
if ( !set_relevants_in_exp( &(aa->numeric_conditions_rh[aa->num_numeric_conditions]) ) ) break;
if ( aa->numeric_conditions_lh[aa->num_numeric_conditions]->connective == NUMBER &&
aa->numeric_conditions_rh[aa->num_numeric_conditions]->connective == NUMBER ) {
/* trivial numeric condition
*/
if ( number_comparison_holds( aa->numeric_conditions_comp[aa->num_numeric_conditions],
aa->numeric_conditions_lh[aa->num_numeric_conditions]->value,
aa->numeric_conditions_rh[aa->num_numeric_conditions]->value ) ) {
/* true cond -> throw cond away. by not incrementing number of such.
*/
free_ExpNode( aa->numeric_conditions_lh[aa->num_numeric_conditions] );
free_ExpNode( aa->numeric_conditions_rh[aa->num_numeric_conditions] );
aa->numeric_conditions_lh[aa->num_numeric_conditions] = NULL;
aa->numeric_conditions_rh[aa->num_numeric_conditions] = NULL;
continue;
} else {
/* false cond -> throw effect away.
*/
false_cond = TRUE;
break;
}
}
aa->num_numeric_conditions++;
}
if ( i < ne->num_numeric_conditions ) {
if ( false_cond ) {
/* false numeric cond: free what's been done so far, and skip effect
*/
for ( i = 0; i <= aa->num_numeric_conditions; i++ ) {
free_ExpNode( aa->numeric_conditions_lh[i] );
free_ExpNode( aa->numeric_conditions_rh[i] );
}
free( aa->numeric_conditions_comp );
free( aa->numeric_conditions_lh );
free( aa->numeric_conditions_rh );
continue;/* next effect, without incrementing action counter */
} else {
/* numeric effect uses undefined fluent in condition -->
* THROW WHOLE ACTION AWAY! done by breaking out of the
* effects loop, which will be catched below overall
* effect handling.
*/
break;
}
}
/**************************NUMERIC COND - END*************************/
/* now create the add and del effects.
*/
if ( ne->num_adds > 0 ) {
aa->adds = ( int * ) calloc( ne->num_adds, sizeof( int ) );
}
aa->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;
}
aa->adds[aa->num_adds++] = lindex[lp][adr];
}
if ( ne->num_dels > 0 ) {
aa->dels = ( int * ) calloc( ne->num_dels, sizeof( int ) );
}
aa->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;
}
/* NO CHECK FOR ADD \CAP DEL!!!!! -> ALLOWED BY SEMANTICS!!!
*/
aa->dels[aa->num_dels++] = lindex[lp][adr];
}
if ( i < ne->num_dels ) break;
/**************************NUMERIC EFFECTS*************************/
if ( ne->num_numeric_effects > 0 ) {
aa->numeric_effects_neft = ( NumericEffectType * )
calloc( ne->num_numeric_effects, sizeof( NumericEffectType ) );
aa->numeric_effects_fl = ( int * )
calloc( ne->num_numeric_effects, sizeof( int ) );
aa->numeric_effects_rh = ( ExpNode_pointer * )
calloc( ne->num_numeric_effects, sizeof( ExpNode_pointer ) );
aa->num_numeric_effects = 0;
}
for ( i = 0; i < ne->num_numeric_effects; i++ ) {
aa->numeric_effects_neft[aa->num_numeric_effects] = ne->numeric_effects_neft[i];
lf = ne->numeric_effects_fluent[i].function;
for ( j = 0; j < gf_arity[lf]; j++ ) {
lf_args[j] = ( ne->numeric_effects_fluent[i].args[j] >= 0 ) ?
ne->numeric_effects_fluent[i].args[j] :
a->inst_table[DECODE_VAR( ne->numeric_effects_fluent[i].args[j] )];
}
adr = fluent_adress();
/* if it's -1, simply let it in --- if that effect appears, then
* action is illegal, otherwise not.
*/
aa->numeric_effects_fl[i] = lf_index[lf][adr];
if ( lf_index[lf][adr] == -1 ) aa->illegal = TRUE;
aa->numeric_effects_rh[aa->num_numeric_effects] = copy_Exp( ne->numeric_effects_rh[i] );
instantiate_exp_by_action( &(aa->numeric_effects_rh[aa->num_numeric_effects]), a );
if ( !set_relevants_in_exp( &(aa->numeric_effects_rh[aa->num_numeric_effects]) ) ) {
aa->illegal = TRUE;
}
if ( aa->illegal &&
aa->num_conditions == 0 &&
aa->num_numeric_conditions == 0 ) {
break;
}
/* that's it ???????????????? - !!
*/
aa->num_numeric_effects++;
}
if ( i < ne->num_numeric_effects ) {
/* an unconditional illegal effekt
*/
break;
}
/**************************NUMERIC EFFECTS - END*************************/
/* this effect is OK. go to next one in NormOp.
*/
a->num_effects++;
lnum_effects++;
}
if ( ne ) {
/* we get here if one effect was faulty
*/
gnum_actions--;
if ( p ) {
p->next = a->next;
t = a;
a = a->next;
t->next = gtrash_actions;
gtrash_actions = t;
} else {
gactions = a->next;
t = a;
a = a->next;
t->next = gtrash_actions;
gtrash_actions = t;
}
} else {
p = a;
a = a->next;
}
continue;
}
/**********************************second half: hard operators --> pseudo actions******************/
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];
}
/**************************NUMERIC PRECOND*************************/
if ( pa->num_numeric_preconds > 0 ) {
a->numeric_preconds_comp = ( Comparator * )
calloc( pa->num_numeric_preconds, sizeof( Comparator ) );
a->numeric_preconds_lh = ( ExpNode_pointer * )
calloc( pa->num_numeric_preconds, sizeof( ExpNode_pointer ) );
a->numeric_preconds_rh = ( ExpNode_pointer * )
calloc( pa->num_numeric_preconds, sizeof( ExpNode_pointer ) );
a->num_numeric_preconds = 0;
}
for ( i = 0; i < pa->num_numeric_preconds; i++ ) {
a->numeric_preconds_comp[a->num_numeric_preconds] = pa->numeric_preconds_comp[i];
a->numeric_preconds_lh[a->num_numeric_preconds] = copy_Exp( pa->numeric_preconds_lh[i] );
if ( !set_relevants_in_exp( &(a->numeric_preconds_lh[a->num_numeric_preconds]) ) ) break;
a->numeric_preconds_rh[a->num_numeric_preconds] = copy_Exp( pa->numeric_preconds_rh[i] );
if ( !set_relevants_in_exp( &(a->numeric_preconds_rh[a->num_numeric_preconds]) ) ) break;
a->num_numeric_preconds++;
}
if ( i < pa->num_numeric_preconds ) {
/* a precond accesses an undefined fluent -> remove action!
*/
gnum_actions--;
if ( p ) {
p->next = a->next;
t = a;
a = a->next;
t->next = gtrash_actions;
gtrash_actions = t;
} else {
gactions = a->next;
t = a;
a = a->next;
t->next = gtrash_actions;
gtrash_actions = t;
}
continue;
}
/**************************NUMERIC PRECOND-END*************************/
/* and now for the effects
*/
if ( a->num_effects > 0 ) {
a->effects = ( ActionEffect * ) calloc( a->num_effects, sizeof( ActionEffect ) );
for ( i = 0; i < a->num_effects; i++ ) {
a->effects[i].illegal = FALSE;
a->effects[i].removed = FALSE;
}
}
a->num_effects = 0;
for ( pae = pa->effects; pae; pae = pae->next ) {
aa = &(a->effects[a->num_effects]);
if ( pae->num_conditions > 0 ) {
aa->conditions = ( int * ) calloc( pae->num_conditions, sizeof( int ) );
}
aa->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;
}
aa->conditions[aa->num_conditions++] = lindex[lp][adr];
}
if ( i < pae->num_conditions ) {/* found unreachable condition: free condition space */
free( aa->conditions );
continue;
}
/**************************NUMERIC COND*************************/
if ( pae->num_numeric_conditions > 0 ) {
aa->numeric_conditions_comp = ( Comparator * )
calloc( pae->num_numeric_conditions, sizeof( Comparator ) );
aa->numeric_conditions_lh = ( ExpNode_pointer * )
calloc( pae->num_numeric_conditions, sizeof( ExpNode_pointer ) );
aa->numeric_conditions_rh = ( ExpNode_pointer * )
calloc( pae->num_numeric_conditions, sizeof( ExpNode_pointer ) );
for ( i = 0; i < pae->num_numeric_conditions; i++ ) {
aa->numeric_conditions_lh[i] = NULL;
aa->numeric_conditions_rh[i] = NULL;
}
aa->num_numeric_conditions = 0;
}
for ( i = 0; i < pae->num_numeric_conditions; i++ ) {
aa->numeric_conditions_comp[aa->num_numeric_conditions] = pae->numeric_conditions_comp[i];
aa->numeric_conditions_lh[aa->num_numeric_conditions] = copy_Exp( pae->numeric_conditions_lh[i] );
if ( !set_relevants_in_exp( &(aa->numeric_conditions_lh[aa->num_numeric_conditions]) ) ) break;
aa->numeric_conditions_rh[aa->num_numeric_conditions] = copy_Exp( pae->numeric_conditions_rh[i] );
if ( !set_relevants_in_exp( &(aa->numeric_conditions_rh[aa->num_numeric_conditions]) ) ) break;
aa->num_numeric_conditions++;
}
if ( i < pae->num_numeric_conditions ) {
/* numeric effect uses undefined fluent in condition -->
* THROW WHOLE ACTION AWAY! done by breaking out of the
* effects loop, which will be catched below overall
* effect handling.
*/
break;
}
/**************************NUMERIC COND - END*************************/
/* now create the add and del effects.
*/
if ( pae->num_adds > 0 ) {
aa->adds = ( int * ) calloc( pae->num_adds, sizeof( int ) );
}
aa->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;
}
aa->adds[aa->num_adds++] = lindex[lp][adr];
}
if ( pae->num_dels > 0 ) {
aa->dels = ( int * ) calloc( pae->num_dels, sizeof( int ) );
}
aa->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;
}
aa->dels[aa->num_dels++] = lindex[lp][adr];
}
if ( i < pae->num_dels ) break;
/**************************NUMERIC EFFECTS*************************/
if ( pae->num_numeric_effects > 0 ) {
aa->numeric_effects_neft = ( NumericEffectType * )
calloc( pae->num_numeric_effects, sizeof( NumericEffectType ) );
aa->numeric_effects_fl = ( int * )
calloc( pae->num_numeric_effects, sizeof( int ) );
aa->numeric_effects_rh = ( ExpNode_pointer * )
calloc( pae->num_numeric_effects, sizeof( ExpNode_pointer ) );
aa->num_numeric_effects = 0;
}
for ( i = 0; i < pae->num_numeric_effects; i++ ) {
aa->numeric_effects_neft[aa->num_numeric_effects] = pae->numeric_effects_neft[i];
lf = pae->numeric_effects_fluent[i].function;
for ( j = 0; j < gf_arity[lf]; j++ ) {
lf_args[j] = pae->numeric_effects_fluent[i].args[j];
if ( lf_args[j] < 0 ) {
printf("\n\nuninstantiated affected fluent in final actions! debug me.\n\n");
exit( 1 );
}
}
adr = fluent_adress();
/* if it's -1, simply let it in --- if that effect appears, then
* action is illegal, otherwise not.
*/
aa->numeric_effects_fl[i] = lf_index[lf][adr];
if ( lf_index[lf][adr] == -1 ) aa->illegal = TRUE;
aa->numeric_effects_rh[aa->num_numeric_effects] = copy_Exp( pae->numeric_effects_rh[i] );
if ( !set_relevants_in_exp( &(aa->numeric_effects_rh[aa->num_numeric_effects]) ) ) {
aa->illegal = TRUE;
}
if ( aa->illegal &&
aa->num_conditions == 0 &&
aa->num_numeric_conditions == 0 ) {
break;
}
/* that's it ???????????????? - !!
*/
aa->num_numeric_effects++;
}
if ( i < pae->num_numeric_effects ) {
/* an unconditional illegal effekt
*/
break;
}
/**************************NUMERIC EFFECTS - END*************************/
/* this effect is OK. go to next one in PseudoAction.
*/
a->num_effects++;
lnum_effects++;
}
if ( pae ) {
/* we get here if one effect was faulty
*/
gnum_actions--;
if ( p ) {
p->next = a->next;
t = a;
a = a->next;
t->next = gtrash_actions;
gtrash_actions = t;
} else {
gactions = a->next;
t = a;
a = a->next;
t->next = gtrash_actions;
gtrash_actions = t;
}
} else {
p = a;
a = a->next;
}
continue;
}/* 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.
*/
p = a;
a = a->next;
}/* endfor all actions ! */
}