void create_final_actions()

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 ! */

}