void get_mneed()

in grolp/gen/ff_planner/relax.c [1557:1721]


void get_mneed( int fl, Bool *minusinfty, float *val )

{

  int ef, pc, i, fl_, c, in, g, as;
  float val_, mneed_;
  Bool minusinfty_;

  /* this counts the number of hits; 0 --> mneed is -infty
   */
  c = 0;
  /* check through the actions, i.e. effects. I suppose this could be made
   * *a lot* faster by checking through the PC information of the fl;
   * additionally, we'd need fast access to the art. fluents that fl 
   * participates in.
   */
  for ( ef = 0; ef < gnum_ef_conn; ef++ ) {
    /* the preconds must be supported above their required value.
     */
    for ( pc = 0;  pc < gef_conn[ef].num_f_PC; pc++ ) {
      /* constraint here is gef_conn[ef].f_PC_fl[pc] >= [>] gef_conn[ef].f_PC_c[pc]
       * where lh side can be lnf expression.
       */
      fl_ = gef_conn[ef].f_PC_fl[pc];
      if ( fl_ < 0 ) continue;
      if ( fl_ == fl ) {
	c++;
	val_ = gef_conn[ef].f_PC_c[pc];
	if ( c == 1 || val_ > *val ) {
	  *val = val_;
	}
	continue;
      }
      if ( !gfl_conn[fl_].artificial ) continue;
      for ( i = 0; i < gfl_conn[fl_].num_lnf; i++ ) {
	if ( gfl_conn[fl_].lnf_F[i] == fl ) {
	  /* might be that the expression can't be supported --
	   * if one of the fluents is undefined.
	   */
	  if ( supv( &val_, fl, fl_, gef_conn[ef].f_PC_c[pc] ) ) {
	    c++;
	    if ( c == 1 || val_ > *val ) {
	      *val = val_;
	    }
	  }
	  break;
	}
      }
    }

    /* the += effs must be supported above 0.
     */
    for ( in = 0; in < gef_conn[ef].num_IN; in++ ) {
      /* += eff here is gef_conn[ef].IN_fl[in] += gef_conn[ef].IN_fl_[in] + 
       *                                          gef_conn[ef].IN_c[in]
       * where gef_conn[ef].IN_fl_[in] can be lnf expression.
       */
      /* relevance...
       */
      if ( !gfl_conn[gef_conn[ef].IN_fl[in]].relevant ) {
	continue;
      }
      fl_ = gef_conn[ef].IN_fl_[in];
      if ( fl_ < 0 ) continue;
      if ( fl_ == fl ) {
	c++;
	val_ = (-1) * gef_conn[ef].IN_c[in];
	if ( c == 1 || val_ > *val ) {
	  *val = val_;
	}
	continue;
      }
      if ( !gfl_conn[fl_].artificial ) continue;
      for ( i = 0; i < gfl_conn[fl_].num_lnf; i++ ) {
	if ( gfl_conn[fl_].lnf_F[i] == fl ) {
	  if ( supv( &val_, fl, fl_, (-1) * gef_conn[ef].IN_c[in] ) ) {
	    c++;
	    if ( c == 1 || val_ > *val ) {
	      *val = val_;
	    }
	  }
	  break;
	}
      }
    }

    /* the := effs must be supported above the mneed value of the affected
     * varuable..
     */
    for ( as = 0; as < gef_conn[ef].num_AS; as++ ) {
      /* := eff here is gef_conn[ef].AS_fl[as] := gef_conn[ef].AS_fl_[as] + 
       *                                          gef_conn[ef].AS_c[as]
       * where gef_conn[ef].AS_fl_[as] can be lnf expression.
       */
      /* relevance...
       */
      if ( !gfl_conn[gef_conn[ef].AS_fl[as]].relevant ) {
	continue;
      }
      /* after this, -infty handling is actually superfluous... or so I'd suppose...
       */
      fl_ = gef_conn[ef].AS_fl_[as];
      if ( fl_ < 0 ) continue;
      if ( fl_ == fl ) {
	get_mneed( gef_conn[ef].AS_fl[as], &minusinfty_, &mneed_ );
	if ( !minusinfty_ ) {
	  c++;
	  val_ = mneed_ - gef_conn[ef].AS_c[as];
	  if ( c == 1 || val_ > *val ) {
	    *val = val_;
	  }
	}
	continue;
      }
      if ( !gfl_conn[fl_].artificial ) continue;
      for ( i = 0; i < gfl_conn[fl_].num_lnf; i++ ) {
	if ( gfl_conn[fl_].lnf_F[i] == fl ) {
	  get_mneed( gef_conn[ef].AS_fl[as], &minusinfty_, &mneed_ );
	  if ( !minusinfty_ ) {
	    if ( supv( &val_, fl, fl_, mneed_ - gef_conn[ef].AS_c[as] ) ) {
	      c++;
	      if ( c == 1 || val_ > *val ) {
		*val = val_;
	      }
	    }
	    break;
	  }
	}
      }
    }

  }/* end of ef loop */

  /* check through the numerical goals.
   */
  for ( g = 0; g < gnum_fnumeric_goal; g++ ) {
    /* constraint here is gfnumeric_goal_fl[g] >= [>] gfnumeric_goal_c[g]
     * where lh side can be lnf expression.
     */
    fl_ = gfnumeric_goal_fl[g];
    if ( fl_ < 0 ) continue;
    if ( fl_ == fl ) {
      c++;
      val_ = gfnumeric_goal_c[g];
      if ( c == 1 || val_ > *val ) {
	*val = val_;
      }
    }
    if ( !gfl_conn[fl_].artificial ) continue;
    for ( i = 0; i < gfl_conn[fl_].num_lnf; i++ ) {
      if ( gfl_conn[fl_].lnf_F[i] == fl ) {
	if ( supv( &val_, fl, fl_, gfnumeric_goal_c[g] ) ) {
	  c++;
	  if ( c == 1 || val_ > *val ) {
	    *val = val_;
	  }
	}
	break;
      }
    }
  }

  *minusinfty = ( c == 0 ) ? TRUE : FALSE;

}