in grolp/gen/ff_planner/search.c [1936:2216]
Bool result_to_dest( State *dest, State *source, int op )
{
static Bool first_call = TRUE;
static Bool *in_source, *in_dest, *in_del, *true_ef, *assigned;
static int *del, num_del;
int i, j, ef, fl;
float val, source_val;
Comparator comp;
Bool one_appeared = FALSE;
if ( first_call ) {
in_source = ( Bool * ) calloc( gnum_ft_conn, sizeof( Bool ) );
in_dest = ( Bool * ) calloc( gnum_ft_conn, sizeof( Bool ) );
in_del = ( Bool * ) calloc( gnum_ft_conn, sizeof( Bool ) );
true_ef = ( Bool * ) calloc( gnum_ef_conn, sizeof( Bool ) );
assigned = ( Bool * ) calloc( gnum_fl_conn, sizeof( Bool ) );
del = ( int * ) calloc( gnum_ft_conn, sizeof( int ) );
for ( i = 0; i < gnum_ft_conn; i++ ) {
in_source[i] = FALSE;
in_dest[i] = FALSE;
in_del[i] = FALSE;
}
for ( i = 0; i < gnum_ef_conn; i++ ) {
true_ef[i] = FALSE;
}
for ( i = 0; i < gnum_fl_conn; i++ ) {
assigned[i] = FALSE;
}
first_call = FALSE;
}
/* setup true facts for effect cond evaluation
*/
for ( i = 0; i < source->num_F; i++ ) {
in_source[source->F[i]] = TRUE;
}
/* evaluate effect conditions and setup deleted facts
*/
num_del = 0;
for ( i = 0; i < gop_conn[op].num_E; i++ ) {
ef = gop_conn[op].E[i];
/* logic cond true?
*/
for ( j = 0; j < gef_conn[ef].num_PC; j++ ) {
if ( !in_source[gef_conn[ef].PC[j]] ) break;
}
if ( j < gef_conn[ef].num_PC ) continue;
/* numeric cond true?
*/
for ( j = 0; j < gef_conn[ef].num_f_PC; j++ ) {
fl = gef_conn[ef].f_PC_fl[j];
val = gef_conn[ef].f_PC_c[j];
comp = gef_conn[ef].f_PC_comp[j];
if ( !determine_source_val( source, fl, &source_val ) ) {
/* condition access to an undefined fluent!
*/
for ( i = 0; i < num_del; i++ ) {
in_del[del[i]] = FALSE;
}
for ( i = 0; i < gop_conn[op].num_E; i++ ) {
true_ef[i] = FALSE;
}
for ( i = 0; i < source->num_F; i++ ) {
in_source[source->F[i]] = FALSE;
}
return FALSE;
}
if ( !number_comparison_holds( comp, source_val, val ) ) break;
}
if ( j < gef_conn[ef].num_f_PC ) continue;
if ( gef_conn[ef].illegal ) {
/* effect always affects an undefined fluent, as we found out
* earlier
*/
for ( i = 0; i < source->num_F; i++ ) {
in_source[source->F[i]] = FALSE;
}
for ( i = 0; i < num_del; i++ ) {
in_del[del[i]] = FALSE;
}
for ( i = 0; i < gop_conn[op].num_E; i++ ) {
true_ef[i] = FALSE;
}
return FALSE;
}
true_ef[i] = TRUE;
one_appeared = TRUE;
for ( j = 0; j < gef_conn[ef].num_D; j++ ) {
if ( in_del[gef_conn[ef].D[j]] ) continue;
in_del[gef_conn[ef].D[j]] = TRUE;
del[num_del++] = gef_conn[ef].D[j];
}
}
if ( !one_appeared ) {
/* no effect appeared which means that the action is either useless
* here or its preconds are even not fulfilled (the latter
* shouldn't happen by get_A but well....)
*/
for ( i = 0; i < source->num_F; i++ ) {
in_source[source->F[i]] = FALSE;
}
for ( i = 0; i < num_del; i++ ) {
in_del[del[i]] = FALSE;
}
for ( i = 0; i < gop_conn[op].num_E; i++ ) {
true_ef[i] = FALSE;
}
return FALSE;
}
/* first, see about the numeric effects - those might render
* the op illegal here. start by copying numeric info.
*/
for ( i = 0; i < gnum_fl_conn; i++ ) {
dest->f_D[i] = source->f_D[i];
dest->f_V[i] = source->f_V[i];
}
/* illegal is an op if the result is not well-defined,
* or if it affects an undefined fluent.
*/
for ( i = 0; i < gop_conn[op].num_E; i++ ) {
if ( !true_ef[i] ) continue;
ef = gop_conn[op].E[i];
for ( j = 0; j < gef_conn[ef].num_AS; j++ ) {
fl = gef_conn[ef].AS_fl[j];
if ( gef_conn[ef].AS_fl_[j] == -1 ) {
val = gef_conn[ef].AS_c[j];
} else {
if ( !determine_source_val( source, gef_conn[ef].AS_fl_[j], &val ) ) {
/* effect rh makes use of undefined fluent!
*/
for ( i = 0; i < gnum_fl_conn; i++ ) {
assigned[i] = FALSE;
}
for ( i = 0; i < source->num_F; i++ ) {
in_source[source->F[i]] = FALSE;
}
for ( i = 0; i < num_del; i++ ) {
in_del[del[i]] = FALSE;
}
for ( i = 0; i < gop_conn[op].num_E; i++ ) {
true_ef[i] = FALSE;
}
return FALSE;
}
val += gef_conn[ef].AS_c[j];
}
if ( assigned[fl] &&
val != dest->f_V[fl] ) {
/* two different values assigned --> result not well-defined --> illegal!
*/
for ( i = 0; i < gnum_fl_conn; i++ ) {
assigned[i] = FALSE;
}
for ( i = 0; i < source->num_F; i++ ) {
in_source[source->F[i]] = FALSE;
}
for ( i = 0; i < num_del; i++ ) {
in_del[del[i]] = FALSE;
}
for ( i = 0; i < gop_conn[op].num_E; i++ ) {
true_ef[i] = FALSE;
}
return FALSE;
}
dest->f_D[fl] = TRUE;
dest->f_V[fl] = val;
assigned[fl] = TRUE;
}
for ( j = 0; j < gef_conn[ef].num_IN; j++ ) {
fl = gef_conn[ef].IN_fl[j];
if ( assigned[fl] ||
!source->f_D[fl]) {
/* assign and increase --> result not well-defined --> illegal!
* affects an undefined fluent --> illegal!
*/
for ( i = 0; i < gnum_fl_conn; i++ ) {
assigned[i] = FALSE;
}
for ( i = 0; i < source->num_F; i++ ) {
in_source[source->F[i]] = FALSE;
}
for ( i = 0; i < num_del; i++ ) {
in_del[del[i]] = FALSE;
}
for ( i = 0; i < gop_conn[op].num_E; i++ ) {
true_ef[i] = FALSE;
}
return FALSE;
}
if ( gef_conn[ef].IN_fl_[j] == -1 ) {
val = gef_conn[ef].IN_c[j];
} else {
if ( !determine_source_val( source, gef_conn[ef].IN_fl_[j], &val ) ) {
/* effect rh makes use of undefined fluent!
*/
for ( i = 0; i < gnum_fl_conn; i++ ) {
assigned[i] = FALSE;
}
for ( i = 0; i < source->num_F; i++ ) {
in_source[source->F[i]] = FALSE;
}
for ( i = 0; i < num_del; i++ ) {
in_del[del[i]] = FALSE;
}
for ( i = 0; i < gop_conn[op].num_E; i++ ) {
true_ef[i] = FALSE;
}
return FALSE;
}
val += gef_conn[ef].IN_c[j];
}
dest->f_V[fl] += val;
}
}
/* put all non-deleted facts from source into dest.
* need not check for put-in facts here,
* as initial state is made doubles-free, and invariant keeps
* true through the transition procedure
*/
dest->num_F = 0;
for ( i = 0; i < source->num_F; i++ ) {
if ( in_del[source->F[i]] ) {
continue;
}
/* no derived facts! Those must be derived anew.
*/
if ( gft_conn[source->F[i]].axiom_added ) {
continue;
}
dest->F[dest->num_F++] = source->F[i];
in_dest[source->F[i]] = TRUE;
}
/* now add all fullfilled effect adds to dest; each fact at most once!
*/
for ( i = 0; i < gop_conn[op].num_E; i++ ) {
if ( !true_ef[i] ) continue;
ef = gop_conn[op].E[i];
for ( j = 0; j < gef_conn[ef].num_A; j++ ) {
if ( in_dest[gef_conn[ef].A[j]] ) {
continue;
}
dest->F[dest->num_F++] = gef_conn[ef].A[j];
in_dest[gef_conn[ef].A[j]] = TRUE;
}
}
/* apply derived predicates til fixpoint.
*/
do_axiom_update( dest );
/* unset infos
*/
for ( i = 0; i < source->num_F; i++ ) {
in_source[source->F[i]] = FALSE;
}
for ( i = 0; i < dest->num_F; i++ ) {
in_dest[dest->F[i]] = FALSE;
}
for ( i = 0; i < num_del; i++ ) {
in_del[del[i]] = FALSE;
}
for ( i = 0; i < gop_conn[op].num_E; i++ ) {
true_ef[i] = FALSE;
}
for ( i = 0; i < gnum_fl_conn; i++ ) {
assigned[i] = FALSE;
}
return TRUE;
}