void normalize_expressions()

in grolp/gen/ff_planner/expressions.c [476:855]


void normalize_expressions( void )

{

  Action *a, *p, *t;
  ActionEffect *e;
  int i, j, k;
  Bool eq;
  LnfExpNode *lnf;

  /* first, pre-normalize all the expressions, i.e. translate
   * divisions, and push muliplications downwards.
   */
  for ( i = 0; i < gnum_numeric_goal; i++ ) {
    if ( !translate_divisions( &(gnumeric_goal_lh[i]) ) ) {
      printf("\n\nff: division by zero in goal. no plan will solve it.\n\n");
      exit( 1 );
    }
    push_multiplications_down( &(gnumeric_goal_lh[i]) );
    if ( !translate_divisions( &(gnumeric_goal_rh[i]) ) ) {
      printf("\n\nff: division by zero in goal. no plan will solve it.\n\n");
      exit( 1 );
    }
    push_multiplications_down( &(gnumeric_goal_rh[i]) );
  }

  a = gactions; p = NULL;
  while ( a ) {
    for ( i = 0; i < a->num_numeric_preconds; i++ ) {
      if ( !translate_divisions( &(a->numeric_preconds_lh[i]) ) ) break;
      push_multiplications_down( &(a->numeric_preconds_lh[i]) );
      if ( !translate_divisions( &(a->numeric_preconds_rh[i]) ) ) break;
      push_multiplications_down( &(a->numeric_preconds_rh[i]) );
    }
    if ( i < a->num_numeric_preconds ) {
      if ( gcmd_line.display_info ) {
	printf("\nwarning: division by zero in precond of ");
	print_Action_name( a );
	printf(". skipping 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;
    }

    for ( i = 0; i < a->num_effects; i++ ) {
      e = &(a->effects[i]);

      for ( j = 0; j < e->num_numeric_conditions; j++ ) {
	if ( !translate_divisions( &(e->numeric_conditions_lh[j]) ) ) break;
	push_multiplications_down( &(e->numeric_conditions_lh[j]) );
	if ( !translate_divisions( &(e->numeric_conditions_rh[j]) ) ) break;
	push_multiplications_down( &(e->numeric_conditions_rh[j]) );
      }
      if ( j < e->num_numeric_conditions ) break;

      if ( e->illegal ) {
	continue;
      }

      for ( j = 0; j < e->num_numeric_effects; j++ ) {
	if ( !translate_divisions( &(e->numeric_effects_rh[j]) ) ) break;
	push_multiplications_down( &(e->numeric_effects_rh[j]) );
      }
      if ( j < e->num_numeric_effects ) {
	if ( gcmd_line.display_info ) {
	  printf("\nwarning: division by zero in effect rh of ");
	  print_Action_name( a );
	  printf(". marking effect as illegal.");
	}
	e->illegal = TRUE;
      }
    }
    if ( i < a->num_effects ) {
      if ( gcmd_line.display_info ) {
	printf("\nwarning: division by zero in effect cond of ");
	print_Action_name( a );
	printf(". skipping 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;
    }
    
    p = a;
    a = a->next;
  }
  if ( gmetric != NULL ) {
    if ( !translate_divisions( &gmetric ) ) {
      if ( gcmd_line.display_info ) {
	printf("\nwarning: division by zero in metric. replaced with plan length.");
      }
      free_ExpNode( gmetric );
      gmetric = NULL;
    }
    push_multiplications_down( &gmetric );
  }

  /* now, collect the normalized representations of all expressions.
   */
  for ( a = gactions; a; a = a->next ) {
    /* preconds
     */
    a->lnf_preconds_comp = ( Comparator * ) calloc( MAX_LNF_COMPS, sizeof( Comparator ) );
    a->lnf_preconds_lh = ( LnfExpNode_pointer * ) calloc( MAX_LNF_COMPS, sizeof( LnfExpNode_pointer ) );
    a->lnf_preconds_rh = ( float * ) calloc( MAX_LNF_COMPS, sizeof( float ) );
    a->num_lnf_preconds = 0;
    for ( i = 0; i < a->num_numeric_preconds; i++ ) {
      if ( a->num_lnf_preconds == MAX_LNF_COMPS ) {
	printf("\n\nincrease MAX_LNF_COMPS! currently %d\n\n", MAX_LNF_COMPS);
	exit( 1 );
      }
      eq = FALSE;
      if ( a->numeric_preconds_comp[i] == EQ ) {
	eq = TRUE;
	a->numeric_preconds_comp[i] = LEQ;
      }
      put_comp_into_normalized_locals( a->numeric_preconds_comp[i],
				       a->numeric_preconds_lh[i],
				       a->numeric_preconds_rh[i] );
      a->lnf_preconds_comp[a->num_lnf_preconds] = lcomp;
      a->lnf_preconds_lh[a->num_lnf_preconds] = new_LnfExpNode();
      lnf = a->lnf_preconds_lh[a->num_lnf_preconds];
      for ( j = 0; j < lnum_F; j++ ) {
	if ( lC[j] == 0 ) continue;
	if ( lC[j] > 0 ) {
	  lnf->pF[lnf->num_pF] = lF[j];
	  lnf->pC[lnf->num_pF++] = lC[j];
	} else {
	  lnf->nF[lnf->num_nF] = lF[j];
	  lnf->nC[lnf->num_nF++] = (-1) * lC[j];
	}
      }
      a->lnf_preconds_rh[a->num_lnf_preconds] = lc;
      a->num_lnf_preconds++;
      if ( eq ) {
	if ( a->num_lnf_preconds == MAX_LNF_COMPS ) {
	  printf("\n\nincrease MAX_LNF_COMPS! currently %d\n\n", MAX_LNF_COMPS);
	  exit( 1 );
	}
	a->numeric_preconds_comp[i] = EQ;
	put_comp_into_normalized_locals( GEQ,
					 a->numeric_preconds_lh[i],
					 a->numeric_preconds_rh[i] );
	a->lnf_preconds_comp[a->num_lnf_preconds] = lcomp;
	a->lnf_preconds_lh[a->num_lnf_preconds] = new_LnfExpNode();
	lnf = a->lnf_preconds_lh[a->num_lnf_preconds];
	for ( j = 0; j < lnum_F; j++ ) {
	  if ( lC[j] == 0 ) continue;
	  if ( lC[j] > 0 ) {
	    lnf->pF[lnf->num_pF] = lF[j];
	    lnf->pC[lnf->num_pF++] = lC[j];
	  } else {
	    lnf->nF[lnf->num_nF] = lF[j];
	    lnf->nC[lnf->num_nF++] = (-1) * lC[j];
	  }
	}
	a->lnf_preconds_rh[a->num_lnf_preconds] = lc;
	a->num_lnf_preconds++;
      }
    }

    /* effects
     */
    for ( i = 0; i < a->num_effects; i++ ) {
      e = &(a->effects[i]);

      e->lnf_conditions_comp = ( Comparator * ) calloc( MAX_LNF_COMPS, sizeof( Comparator ) );
      e->lnf_conditions_lh = ( LnfExpNode_pointer * ) calloc( MAX_LNF_COMPS, sizeof( LnfExpNode_pointer ) );
      e->lnf_conditions_rh = ( float * ) calloc( MAX_LNF_COMPS, sizeof( float ) );
      e->num_lnf_conditions = 0;
      for ( j = 0; j < e->num_numeric_conditions; j++ ) {
	if ( e->num_lnf_conditions == MAX_LNF_COMPS ) {
	  printf("\n\nincrease MAX_LNF_COMPS! currently %d\n\n", MAX_LNF_COMPS);
	  exit( 1 );
	}
	eq = FALSE;
	if ( e->numeric_conditions_comp[j] == EQ ) {
	  eq = TRUE;
	  e->numeric_conditions_comp[j] = LEQ;
	}
	put_comp_into_normalized_locals( e->numeric_conditions_comp[j],
					 e->numeric_conditions_lh[j],
					 e->numeric_conditions_rh[j] );
	e->lnf_conditions_comp[e->num_lnf_conditions] = lcomp;
	e->lnf_conditions_lh[e->num_lnf_conditions] = new_LnfExpNode();
	lnf = e->lnf_conditions_lh[e->num_lnf_conditions];
	for ( k = 0; k < lnum_F; k++ ) {
	  if ( lC[k] == 0 ) continue;
	  if ( lC[k] > 0 ) {
	    lnf->pF[lnf->num_pF] = lF[k];
	    lnf->pC[lnf->num_pF++] = lC[k];
	  } else {
	    lnf->nF[lnf->num_nF] = lF[k];
	    lnf->nC[lnf->num_nF++] = (-1) * lC[k];
	  }
	}
	e->lnf_conditions_rh[e->num_lnf_conditions] = lc;
	e->num_lnf_conditions++;
	if ( eq ) {
	  if ( e->num_lnf_conditions == MAX_LNF_COMPS ) {
	    printf("\n\nincrease MAX_LNF_COMPS! currently %d\n\n", MAX_LNF_COMPS);
	    exit( 1 );
	  }
	  e->numeric_conditions_comp[j] = EQ;
	  put_comp_into_normalized_locals( GEQ,
					   e->numeric_conditions_lh[j],
					   e->numeric_conditions_rh[j] );
	  e->lnf_conditions_comp[e->num_lnf_conditions] = lcomp;
	  e->lnf_conditions_lh[e->num_lnf_conditions] = new_LnfExpNode();
	  lnf = e->lnf_conditions_lh[e->num_lnf_conditions];
	  for ( k = 0; k < lnum_F; k++ ) {
	    if ( lC[k] == 0 ) continue;
	    if ( lC[k] > 0 ) {
	      lnf->pF[lnf->num_pF] = lF[k];
	      lnf->pC[lnf->num_pF++] = lC[k];
	    } else {
	      lnf->nF[lnf->num_nF] = lF[k];
	      lnf->nC[lnf->num_nF++] = (-1) * lC[k];
	    }
	  }
	  e->lnf_conditions_rh[e->num_lnf_conditions] = lc;
	  e->num_lnf_conditions++;
	}
      }

      if ( e->illegal ) {
	/* we do have the LNF to know whether the effect appears.
	 * if it does, then this one is illegal anyway, remembered
	 * in inst final due to undefined fl access.
	 *
	 * if it is LEGAL, then all fluents we're gonna find and
	 * collect below are relevant!!!
	 */
	continue;
      }
      
      e->lnf_effects_neft = ( NumericEffectType * ) calloc( MAX_LNF_EFFS, sizeof( NumericEffectType ) );
      e->lnf_effects_fl = ( int * ) calloc( MAX_LNF_EFFS, sizeof( int ) );
      e->lnf_effects_rh = ( LnfExpNode_pointer * ) calloc( MAX_LNF_EFFS, sizeof( LnfExpNode_pointer ) );
      e->num_lnf_effects = 0;
      for ( j = 0; j < e->num_numeric_effects; j++ ) {
	if ( e->num_lnf_effects == MAX_LNF_EFFS ) {
	  printf("\n\nincrease MAX_LNF_EFFS! currently %d\n\n", MAX_LNF_EFFS);
	  exit( 1 );
	}
	e->lnf_effects_neft[e->num_lnf_effects] = e->numeric_effects_neft[j];
	e->lnf_effects_fl[e->num_lnf_effects] = e->numeric_effects_fl[j];
	lnum_F = 0;
	lc = 0;
	if ( e->lnf_effects_neft[e->num_lnf_effects] == DECREASE ) {
	  collect_normalized_locals( e->numeric_effects_rh[j], FALSE );
	  e->lnf_effects_neft[e->num_lnf_effects] = INCREASE;
	} else {
	  collect_normalized_locals( e->numeric_effects_rh[j], TRUE );
	}
	e->lnf_effects_rh[e->num_lnf_effects] = new_LnfExpNode();
	lnf = e->lnf_effects_rh[e->num_lnf_effects];
	for ( k = 0; k < lnum_F; k++ ) {
	  if ( lC[k] == 0 ) continue;
	  if ( lC[k] > 0 ) {
	    lnf->pF[lnf->num_pF] = lF[k];
	    lnf->pC[lnf->num_pF++] = lC[k];
	  } else {
	    lnf->nF[lnf->num_nF] = lF[k];
	    lnf->nC[lnf->num_nF++] = (-1) * lC[k];
	  }
	}
	e->lnf_effects_rh[e->num_lnf_effects]->c = lc;
	e->num_lnf_effects++;
      }
    }
  }

  /* goal condition also...
   */
  glnf_goal_comp = ( Comparator * ) calloc( MAX_LNF_COMPS, sizeof( Comparator ) );
  glnf_goal_lh = ( LnfExpNode_pointer * ) calloc( MAX_LNF_COMPS, sizeof( LnfExpNode_pointer ) );
  glnf_goal_rh = ( float * ) calloc( MAX_LNF_COMPS, sizeof( float ) );
  gnum_lnf_goal = 0;
  for ( i = 0; i < gnum_numeric_goal; i++ ) {
    if ( gnum_lnf_goal == MAX_LNF_COMPS ) {
      printf("\n\nincrease MAX_LNF_COMPS! currently %d\n\n", MAX_LNF_COMPS);
      exit( 1 );
    }
    eq = FALSE;
    if ( gnumeric_goal_comp[i] == EQ ) {
      eq = TRUE;
      gnumeric_goal_comp[i] = LEQ;
    }
    put_comp_into_normalized_locals( gnumeric_goal_comp[i],
				     gnumeric_goal_lh[i],
				     gnumeric_goal_rh[i] );
    glnf_goal_comp[gnum_lnf_goal] = lcomp;
    glnf_goal_lh[gnum_lnf_goal] = new_LnfExpNode();
    lnf = glnf_goal_lh[gnum_lnf_goal];
    for ( j = 0; j < lnum_F; j++ ) {
      if ( lC[j] == 0 ) continue;
      if ( lC[j] > 0 ) {
	lnf->pF[lnf->num_pF] = lF[j];
	lnf->pC[lnf->num_pF++] = lC[j];
      } else {
	lnf->nF[lnf->num_nF] = lF[j];
	lnf->nC[lnf->num_nF++] = (-1) * lC[j];
      }
    }
    glnf_goal_rh[gnum_lnf_goal] = lc;
    gnum_lnf_goal++;
    if ( eq ) {
      if ( gnum_lnf_goal == MAX_LNF_COMPS ) {
	printf("\n\nincrease MAX_LNF_COMPS! currently %d\n\n", MAX_LNF_COMPS);
	exit( 1 );
      }
      gnumeric_goal_comp[i] = EQ;
      put_comp_into_normalized_locals( GEQ,
				       gnumeric_goal_lh[i],
				       gnumeric_goal_rh[i] );
      glnf_goal_comp[gnum_lnf_goal] = lcomp;
      glnf_goal_lh[gnum_lnf_goal] = new_LnfExpNode();
      lnf = glnf_goal_lh[gnum_lnf_goal];
      for ( j = 0; j < lnum_F; j++ ) {
	if ( lC[j] == 0 ) continue;
	if ( lC[j] > 0 ) {
	  lnf->pF[lnf->num_pF] = lF[j];
	  lnf->pC[lnf->num_pF++] = lC[j];
	} else {
	  lnf->nF[lnf->num_nF] = lF[j];
	  lnf->nC[lnf->num_nF++] = (-1) * lC[j];
	}
      }
      glnf_goal_rh[gnum_lnf_goal] = lc;
      gnum_lnf_goal++;
    }
  }
  /* metric...
   */
  lnum_F = 0;
  lc = 0;
  glnf_metric.num_pF = 0;
  glnf_metric.num_nF = 0;
  glnf_metric.c = 0;
  collect_normalized_locals( gmetric, TRUE );
  lnf = &glnf_metric;
  for ( j = 0; j < lnum_F; j++ ) {
    if ( lC[j] == 0 ) continue;
    if ( lC[j] > 0 ) {
      lnf->pF[lnf->num_pF] = lF[j];
      lnf->pC[lnf->num_pF++] = lC[j];
    } else {
      lnf->nF[lnf->num_nF] = lF[j];
      lnf->nC[lnf->num_nF++] = (-1) * lC[j];
    }
  }


}