예제 #1
0
int main( int argc, char *argv[] )

{
  
  /* resulting name for ops file
   */
  char ops_file[MAX_LENGTH] = "";
  /* same for fct file 
   */
  char fct_file[MAX_LENGTH] = "";
  
  /* for calls to outside programs, eg zchaff.
   */
  char command[MAX_LENGTH];
  char command2[MAX_LENGTH]; /* for trying another path */
  /* for getting their answer.
   */
  char command3[MAX_LENGTH];
  FILE *SATRES;

  /* sat solver data.
   */
  int sat;
  float sat_rtime;
  int nractions = -1;

  struct tms start, end;

  RPGlayer *t, *tpp;

  Bool goalreached;

  char c;
  int linecount;

/*   int time; */



  times ( &lstart );

  printf("\n\n");
  system("rm CNF");
  system("rm SATRES");
  printf("\n\n");
  fflush(stdout);

  /* command line treatment
   */
  if ( argc == 1 || ( argc == 2 && *++argv[0] == '?' ) ) {
    ff_usage();
    exit( 1 );
  }
  if ( !process_command_line( argc, argv ) ) {
    ff_usage();
    exit( 1 );
  }


  /* make file names
   */

  /* one input name missing
   */
  if ( !gcmd_line.ops_file_name || 
       !gcmd_line.fct_file_name ) {
    fprintf(stdout, "\nff: two input files needed\n\n");
    ff_usage();      
    exit( 1 );
  }
  /* add path info, complete file names will be stored in
   * ops_file and fct_file 
   */
  sprintf(ops_file, "%s%s", gcmd_line.path, gcmd_line.ops_file_name);
  sprintf(fct_file, "%s%s", gcmd_line.path, gcmd_line.fct_file_name);

  /* parse the input files
   */

  /* start parse & instantiation timing
   */
  times( &start );
  /* domain file (ops)
   */
  if ( gcmd_line.display_info >= 1 ) {
    printf("\nff: parsing domain file");
  } 
  /* it is important for the pddl language to define the domain before 
   * reading the problem 
   */
  load_ops_file( ops_file );
  /* problem file (facts)
   */  
  if ( gcmd_line.display_info >= 1 ) {
    printf(" ... done.\nff: parsing problem file"); 
  }
  sprintf(command3, "python addons/removeconstraints.py %s",fct_file);
  system(command3);
  sprintf(command3, "python addons/parseconstraints.py");
  system(command3);
  load_fct_file( fct_file );
  if ( gcmd_line.display_info >= 1 ) {
    printf(" ... done.\n\n");
  }

  /*
    Load token of mutex2ignore
   */
  if( gcmd_line.mutex2ignore_file_name[0] != '\0' )
    load_mutex2ignore_file( gcmd_line.mutex2ignore_file_name );

  /* This is needed to get all types.
   */
  build_orig_constant_list();

  /* last step of parsing: see if it's an ADL domain!
   */
  if ( !make_adl_domain() ) {
    printf("\nff: this is not an ADL problem!");
    printf("\n    can't be handled by this version.\n\n");
    exit( 1 );
  }


  /* now instantiate operators;
   */


  /**************************
   * first do PREPROCESSING * 
   **************************/

  /* start by collecting all strings and thereby encoding 
   * the domain in integers.
   */
  encode_domain_in_integers();

  /* inertia preprocessing, first step:
   *   - collect inertia information
   *   - split initial state into
   *        - arrays for individual predicates
   *        - arrays for all static relations
   *        - array containing non - static relations
   */
  do_inertia_preprocessing_step_1();

  /* normalize all PL1 formulae in domain description:
   * (goal, preconds and effect conditions)
   *   - simplify formula
   *   - expand quantifiers
   *   - NOTs down
   */
  normalize_all_wffs();

  /* translate negative preconds: introduce symmetric new predicate
   * NOT-p(..) (e.g., not-in(?ob) in briefcaseworld)
   */
  translate_negative_preconds();

  /* split domain in easy (disjunction of conjunctive preconds)
   * and hard (non DNF preconds) part, to apply 
   * different instantiation algorithms
   */
  split_domain();

  /***********************************************
   * PREPROCESSING FINISHED                      *
   *                                             *
   * NOW MULTIPLY PARAMETERS IN EFFECTIVE MANNER *
   ***********************************************/

  build_easy_action_templates();
  build_hard_action_templates();

  times( &end );
  TIME( gtempl_time );

  times( &start );

  /* perform reachability analysis in terms of relaxed 
   * fixpoint
   */
  perform_reachability_analysis();

  times( &end );
  TIME( greach_time );

  times( &start );

  /* collect the relevant facts and build final domain
   * and problem representations.
   */
  collect_relevant_facts_and_fluents();

  times( &end );
  TIME( grelev_time );


  /* for num2sat, SKIP LNF AND, WITH THAT, GCONN STRUCTURES!!!
   *
   * reason: LNF is not needed for the CNF encodings, and the RPG is
   *         built only once so optimizations are not time critical.
   *
   *         LNF introduces a huge overhead, and creates many variables
   *         (e.g. n^2 vs n for pre-LNF, in jugs) which would have to be
   *         filtered for the input ones, anyway.
   *
   * RPG sets off on these data structures:
   * extern Action *gactions;
   * extern int gnum_actions;
   * extern State ginitial_state;
   * extern int *glogic_goal;
   * extern int gnum_logic_goal;
   * extern Comparator *gnumeric_goal_comp;
   * extern ExpNode_pointer *gnumeric_goal_lh, *gnumeric_goal_rh;
   * extern int gnum_numeric_goal;
   */

  /* instead, do some additional pre-processing to collect all different 
   * constraints, and all different conjunctions psi of constraints.
   * needed to get a natural implementation of collecting value tuples
   * for all such constructs.
   */
  collect_relevant_constraints_and_psis();



  /* that is done. let's go.
   *
   * NOTE that keeping track of the RPG layers in here
   * isn't just a coincidence. It's made so that we can use these same 
   * functions to build another RPG if we want to, eg. one that's
   * modified to greedily estimate the variable domains instead of
   * enumerating them completely.
   */


  /* separating CNF and Hybrid CNF methods completely,
   * though they got a large overlap.
   * reason: looks nicer, and mayb at some point
   * we're gonna use a different RPG for hybrid.
   */

  /* just to avoid "might be used uninitialized" message
   */
  tpp = NULL;

  if ( gcmd_line.CNFencoding == 0 ||
       gcmd_line.CNFencoding == 1 ) {
    /* propositional CNF!
     */
    times( &start );
    gRPG = new_RPGlayer();
    t = RPG_initialize(gRPG);
    times( &end );
    TIME( gRPG_time );
    TIMECHECK;
    if ( gcmd_line.display_info ) {
      RPG_PV_statistics(t);
      fflush(stdout);
    }
    
    times( &start );
    gCNF = new_CNF();
    gCNFend = gCNF;
    gCNFnumvars = 0;
    gCNFnumclauses = 0;
    CNF_initialize(t, 
		   &gCNFend,
		   &gCNFnumvars,
		   &gCNFnumclauses);
    times( &end );
    TIME( gCNF_time );
    TIMECHECK;
    if ( gcmd_line.display_info ) {
      CNF_statistics(t, gCNF, gCNFnumvars, gCNFnumclauses);
      fflush(stdout);
    }

/* 
##########################################################################################
##########################################################################################
##########################################################################################
##########################################################################################
##########################################################################################
##########################################################################################
*/

    system("rm auxiliar.txt");
    
    goalreached = FALSE;
    while ( TRUE ) {
      times( &start );
      tpp = RPG_extend(t);
      times( &end );
      TIME( gRPG_time );
      TIMECHECK;
      if ( gcmd_line.display_info ) {
	RPG_AE_statistics(t);
	RPG_PV_statistics(tpp);
	fflush(stdout);
      }
      
      times( &start );
      CNF_extend(t, 
		 &gCNFend,
		 &gCNFnumvars,
		 &gCNFnumclauses);
      times( &end );
      TIME( gCNF_time );
      TIMECHECK;
      if ( gcmd_line.display_info ) {
	CNF_statistics(tpp, gCNF, gCNFnumvars, gCNFnumclauses); 
	fflush(stdout);
      }

      if ( !goalreached && !RPG_satisfiesgoal(tpp) ) {
	t = tpp;
	continue;
      }
      
      if ( !goalreached ) {
	if ( gcmd_line.display_info ) {
	  printf("\nGoal reached at %d!", tpp->t); 
	  fflush(stdout);
	}
	goalreached = TRUE;
      }
      
      CNF_get_goal(tpp, 
		   &gCNFend, 
		   &gCNFnumclauses);

      CNF_output(gCNF, gCNFnumvars, gCNFnumclauses, tpp->t);
      TIMECHECK;

	CNF_print_act_table(gRPG, "action-table");
	sprintf(command, "python %s/addons/addconstraints.py CNF action-table", 
		here);
	system(command);

      if ( gcmd_line.debug && gcmd_line.dCNF ) {
	CNF_print(gRPG, gCNF, gCNFnumvars, gCNFnumclauses);
	printf("\n\n");
/* 	exit( 0 ); */
      }
      if ( gcmd_line.CNFsolver == 0 ) {

	sprintf(command, "%s/solvers/minisat/MiniSat_v1.14/minisat CNF",
		num2satpath);
	sprintf(command2, "%s/solvers/minisat/MiniSat_v1.14/minisat CNF",
		here);
      }
      if ( gcmd_line.CNFsolver == 1 ) {
	sprintf(command, "%s/solvers/zchaff/zchaff CNF", num2satpath);
	sprintf(command2, "%s/solvers/zchaff/zchaff CNF", here);
      }
      if ( gcmd_line.CNFsolver == 2 ) { /* OJO: que no hagan falta dos comandos: -m y -s 2 */
	/* minisat */
	CNF_print_act_table(gRPG, "action-table");
	sprintf(command, "%s/solvers/minisat+mutex.py CNF action-table %s m", 
		num2satpath,
		gcmd_line.mutex2ignore_file_name );
	sprintf(command2, "%s/solvers/minisat+mutex.py CNF action-table %s m", 
		here,
		gcmd_line.mutex2ignore_file_name );
      }
      if ( gcmd_line.CNFsolver == 3 ) { 
	/* zchaff */
	CNF_print_act_table(gRPG, "action-table");
	sprintf(command, "%s/solvers/minisat+mutex.py CNF action-table %s z", 
		num2satpath,
		gcmd_line.mutex2ignore_file_name );
	sprintf(command2, "%s/solvers/minisat+mutex.py CNF action-table %s z", 
		here,
		gcmd_line.mutex2ignore_file_name );
      }
      if ( gcmd_line.display_info ) {
	printf("\nInvoking SAT solver, command:");
	printf("\n%s", command);
	printf("\n");
	fflush(stdout);
      }
      if( system( command ) )
	{
	  printf("failed with path %s, trying with %s\n", num2satpath, here);
	  printf("\nInvoking SAT solver, command:");
	  printf("\n%s", command2);
	  printf("\n");
	  fflush(stdout);
	  system( command2 );
	}
      if ( (SATRES = fopen( "SATRES", "r" )) == NULL ) {
	printf("\nSATRES file not present. Failure!\n\n");
	exit( 0 );
      }
      fscanf(SATRES, "%d %f\n", &sat, &sat_rtime);
      gSAT_time += sat_rtime;
      TIMECHECK;
      if ( sat ) {
	break;
      }
      fclose(SATRES);
/*       system("rm CNF"); */
/*       system("rm SATRES"); */
      
      CNF_retract_goal(tpp, 
		       &gCNFend, 
		       &gCNFnumclauses);
      
      t = tpp;
    } /* endwhile main planning loop */

    if ( gcmd_line.display_info ) {
      nractions = CNF_output_plan(SATRES, gRPG, gCNFnumvars);
      fflush(stdout);
    }
    fclose(SATRES);
/*     system("rm CNF"); */
/*     system("rm SATRES"); */
  } /* endif propositional CNF requested */





  if ( gcmd_line.CNFencoding == 2 ||
       gcmd_line.CNFencoding == 3 ) {
    /* Hybrid CNF!
     */
    times( &start );
    gRPG = new_RPGlayer();
    t = RPG_initialize(gRPG);
    times( &end );
    TIME( gRPG_time );
    TIMECHECK;
    if ( gcmd_line.display_info ) {
      RPG_PV_statistics(t);
      fflush(stdout);
    }
    
    times( &start );
    gHCNF = new_HCNF();
    gHCNFend = gHCNF;
    gHCNFnumvars = 0;
    gHCNFnumclauses = 0;
    HCNF_initialize(t, 
		    &gHCNFend,
		    &gHCNFnumvars,
		    &gHCNFnumclauses);
    times( &end );
    TIME( gCNF_time );
    TIMECHECK;
    if ( gcmd_line.display_info ) {
      HCNF_statistics(t, gHCNF, gHCNFnumvars, gHCNFnumclauses);
      fflush(stdout);
    }
    
    goalreached = FALSE;
    while ( TRUE ) {
      times( &start );
      tpp = RPG_extend(t);
      times( &end );
      TIME( gRPG_time );
      TIMECHECK;
      if ( gcmd_line.display_info ) {
	RPG_AE_statistics(t);
	RPG_PV_statistics(tpp);
	fflush(stdout);
      }
      
      times( &start );
      HCNF_extend(t, 
		  &gHCNFend,
		  &gHCNFnumvars,
		  &gHCNFnumclauses);
      times( &end );
      TIME( gCNF_time );
      TIMECHECK;
      if ( gcmd_line.display_info ) {
	HCNF_statistics(tpp, gHCNF, gHCNFnumvars, gHCNFnumclauses);
	fflush(stdout);
      }
      
      if ( !goalreached && !RPG_satisfiesgoal(tpp) ) {
	t = tpp;
	continue;
      }
      
      if ( !goalreached ) {
	if ( gcmd_line.display_info ) {
	  printf("\nGoal reached at %d!", tpp->t);
	  fflush(stdout);
	}
	goalreached = TRUE;
      }
      
      HCNF_get_goal(tpp, 
		    &gHCNFend, 
		    &gHCNFnumclauses);

      HCNF_output(gRPG, gHCNF, gHCNFnumvars, gHCNFnumclauses, tpp->t);
      TIMECHECK;
      if ( gcmd_line.debug && gcmd_line.dHCNF ) {
	HCNF_print(gRPG, gHCNF, gHCNFnumvars, gHCNFnumclauses);
	printf("\n\n");
	exit( 0 );
      }

      sprintf(command, "%s/solvers/mathsat/mathsat-3.3.1/mathsat CNF > SATRES", num2satpath);
      sprintf(command2, "%s/solvers/mathsat/mathsat-3.3.1/mathsat CNF > SATRES", here);

      if ( gcmd_line.display_info ) {
	printf("\nInvoking MATHSAT solver, command:");
	printf("\n%s", command);
	printf("\n");
	fflush(stdout);
      }
      if( system( command ) )
	{
	  printf("failed with path %s, trying with %s\n", num2satpath, here);
	  system( command2 );
	}
      if ( (SATRES = fopen( "SATRES", "r" )) == NULL ) {
	printf("\nSATRES file not present. Failure!\n\n");
	exit( 0 );
      }
      /* read in MATHSAT's output. looks like:
       * Result = 1
       * TSTP Exit Status: SAT
       *
       * # -------------------------------------------------
       * # User time   : 0.020 s
       * # System time : 0.019 s
       * # Total time  : 0.039 s
       */
      fscanf(SATRES, "Result = %d\n", &sat);
      linecount = 0;
      while ( TRUE ) {
	c = fgetc(SATRES);
	if ( c == '\n') {
	  linecount++;
	  if ( linecount == 5 ) {
	    break;
	  }
	}
      }
      fscanf(SATRES, "# Total time  : %f s\n", &sat_rtime);
      
      gSAT_time += sat_rtime;
      TIMECHECK;
      if ( sat ) {
	if ( gcmd_line.display_info ) {
	  printf("\nSAT! %f sec. Plan found.", sat_rtime);
	  fflush(stdout);
	}
	break;
      } else {
	if ( gcmd_line.display_info ) {
	  printf("\nUNSAT! %f sec. Iterate.", sat_rtime);
	  fflush(stdout);
	}
      }
      fclose(SATRES);
      system("rm CNF");
      system("rm SATRES");
      
      HCNF_retract_goal(tpp, 
			&gHCNFend, 
			&gHCNFnumclauses);
      
      t = tpp;
    } /* endwhile main planning loop */
    fclose(SATRES);
    system("rm CNF");
    system("rm SATRES");
  } /* endif hybrid CNF requested */



  if ( !tpp ) {
    printf("\ntpp NULL at plan info output?\n\n");
    exit( 1 );
  }
  if ( gcmd_line.display_info ) {
    output_planner_info(gRPG, nractions);
  }


  sprintf(command3, "python addons/timemachine.py %s",fct_file);
  system(command3);

  printf("\n\n");
  exit( 0 );

}
예제 #2
0
int main( int argc, char *argv[] )

{

  /* resulting name for ops file
   */
  char ops_file[MAX_LENGTH] = "";
  /* same for fct file 
   */
  char fct_file[MAX_LENGTH] = "";
  
  struct tms start, end;

  State current_start, current_end;
  int i, j;
  Bool found_plan;


  times ( &lstart );


  /* command line treatment
   */
  if ( argc == 1 || ( argc == 2 && *++argv[0] == '?' ) ) {
    ff_usage();
    exit( 1 );
  }
  if ( !process_command_line( argc, argv ) ) {
    ff_usage();
    exit( 1 );
  }


  /* make file names
   */

  /* one input name missing
   */
  if ( !gcmd_line.ops_file_name || 
       !gcmd_line.fct_file_name ) {
    fprintf(stdout, "\nff: two input files needed\n\n");
    ff_usage();      
    exit( 1 );
  }
  /* add path info, complete file names will be stored in
   * ops_file and fct_file 
   */
  sprintf(ops_file, "%s%s", gcmd_line.path, gcmd_line.ops_file_name);
  sprintf(fct_file, "%s%s", gcmd_line.path, gcmd_line.fct_file_name);


  /* parse the input files
   */

  /* start parse & instantiation timing
   */
  times( &start );
  /* domain file (ops)
   */
  if ( gcmd_line.display_info >= 1 ) {
    printf("\nff: parsing domain file");
  } 
  /* it is important for the pddl language to define the domain before 
   * reading the problem 
   */
  load_ops_file( ops_file );
  /* problem file (facts)
   */  
  if ( gcmd_line.display_info >= 1 ) {
    printf(" ... done.\nff: parsing problem file"); 
  }
  load_fct_file( fct_file );
  if ( gcmd_line.display_info >= 1 ) {
    printf(" ... done.\n\n");
  }

  /* This is needed to get all types.
   */
  build_orig_constant_list();

  /* last step of parsing: see if it's an ADL domain!
   */
  if ( !make_adl_domain() ) {
    printf("\nff: this is not an ADL problem!");
    printf("\n    can't be handled by this version.\n\n");
    exit( 1 );
  }


  /* now instantiate operators;
   */


  /**************************
   * first do PREPROCESSING * 
   **************************/


  /* start by collecting all strings and thereby encoding 
   * the domain in integers.
   */
  encode_domain_in_integers();

  /* inertia preprocessing, first step:
   *   - collect inertia information
   *   - split initial state into
   *        _ arrays for individual predicates
   *        - arrays for all static relations
   *        - array containing non - static relations
   */
  do_inertia_preprocessing_step_1();

  /* normalize all PL1 formulae in domain description:
   * (goal, preconds and effect conditions)
   *   - simplify formula
   *   - expand quantifiers
   *   - NOTs down
   */
  normalize_all_wffs();

  /* translate negative preconds: introduce symmetric new predicate
   * NOT-p(..) (e.g., not-in(?ob) in briefcaseworld)
   */
  translate_negative_preconds();

  /* split domain in easy (disjunction of conjunctive preconds)
   * and hard (non DNF preconds) part, to apply 
   * different instantiation algorithms
   */
  split_domain();


  /***********************************************
   * PREPROCESSING FINISHED                      *
   *                                             *
   * NOW MULTIPLY PARAMETERS IN EFFECTIVE MANNER *
   ***********************************************/

  build_easy_action_templates();
  build_hard_action_templates();

  times( &end );
  TIME( gtempl_time );

  times( &start );

  /* perform reachability analysis in terms of relaxed 
   * fixpoint
   */
  perform_reachability_analysis();

  times( &end );
  TIME( greach_time );

  times( &start );

  /* collect the relevant facts and build final domain
   * and problem representations.
   */
  collect_relevant_facts();

  times( &end );
  TIME( grelev_time );

  times( &start );

  /* now build globally accessable connectivity graph
   */
  build_connectivity_graph();

  times( &end );
  TIME( gconn_time );
  

  /***********************************************************
   * we are finally through with preprocessing and can worry *
   * bout finding a plan instead.                            *
   ***********************************************************/

  times( &start );

  /* another quick preprocess: approximate goal orderings and split
   * goal set into sequence of smaller sets, the goal agenda
   */
  compute_goal_agenda();

  /* make space in plan states info, and relax
   */
  for ( i = 0; i < MAX_PLAN_LENGTH + 1; i++ ) {
    make_state( &(gplan_states[i]), gnum_ft_conn );
    gplan_states[i].max_F = gnum_ft_conn;
  }
  make_state( &current_start, gnum_ft_conn );
  current_start.max_F = gnum_ft_conn;
  make_state( &current_end, gnum_ft_conn );
  current_end.max_F = gnum_ft_conn;
  initialize_relax();


  source_to_dest( &(gplan_states[0]), &ginitial_state );

  source_to_dest( &current_start, &ginitial_state );
  source_to_dest( &current_end, &(ggoal_agenda[0]) );

  for ( i = 0; i < gnum_goal_agenda; i++ ) {
    if ( !do_enforced_hill_climbing( &current_start, &current_end ) ) {
      break;
    }
    source_to_dest( &current_start, &(gplan_states[gnum_plan_ops]) );
    if ( i < gnum_goal_agenda - 1 ) {
      for ( j = 0; j < ggoal_agenda[i+1].num_F; j++ ) {
	current_end.F[current_end.num_F++] = ggoal_agenda[i+1].F[j];
      }
    }
  }
  found_plan = ( i == gnum_goal_agenda ) ? TRUE : FALSE;

  if ( !found_plan ) {
    printf("\n\nEnforced Hill-climbing failed !");
    printf("\nswitching to Best-first Search now.\n");
    found_plan = do_best_first_search();
  }

  times( &end );
  TIME( gsearch_time );

  if ( found_plan ) {
    print_plan();
  }

  output_planner_info();

  printf("\n\n");
  exit( 0 );

}
예제 #3
0
int main( int argc, char *argv[] ) {
    /* resulting name for ops file
     */
    char ops_file[MAX_LENGTH] = "";

    /* same for fct file
     */
    char fct_file[MAX_LENGTH] = "";

    /* name for additional goal file
     */
    char mul_file[MAX_LENGTH] = "";

    struct timeb start, end;

    State current_start, current_end;
    int i, j;
    Bool found_plan;

    Bool found_plan_for_multiple_purpose;

    /*times ( &lstart );*/
    ftime(&lstart);

    /* command line treatment*/
    if ( argc == 1 || ( argc == 2 && *++argv[0] == '?' ) ) {
        ff_usage();
        exit( 1 );
    }
    if ( !process_command_line( argc, argv ) ) {
        ff_usage();
        exit( 1 );
    }

    /* make file names
     */

    /* one input name missing
     */
    if ( !gcmd_line.ops_file_name ||
            !gcmd_line.fct_file_name ||
            !gcmd_line.mul_file_name ) {

        fprintf(stdout, "\nmul-fip : three input files needed\n");
        ff_usage();
        exit( 1 );
    }
    /* add path info, complete file names will be stored in
     * ops_file and fct_file
     */
    sprintf(ops_file, "%s%s", gcmd_line.path, gcmd_line.ops_file_name);
    sprintf(fct_file, "%s%s", gcmd_line.path, gcmd_line.fct_file_name);
    sprintf(mul_file, "%s%s", gcmd_line.path, gcmd_line.mul_file_name);

    /* parse the input files
     */
    /* start parse & instantiation timing*/
    /*times( &start );*/
    ftime(&start);
    /* domain file (ops)
     */

    /* it is important for the pddl language to define the domain before
     * reading the problem  */
    load_ops_file( ops_file );
    /* problem file (facts) */
    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: parsing problem file.\n");
    }

    load_fct_file( fct_file );

    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: original purpose fact file done.\n");
    }

    load_mul_file( mul_file );

    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: multiple purpose fact file done.\n");
    }

    /* This is needed to get all types.*/
    /* modified by jovi: adding supprot for addtional constant */
    build_orig_constant_list();

    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: build_orig_constant_list() done.\n");
    }

    /* last step of parsing: see if it's an ADL domain!
     */
    if ( !make_adl_domain() ) {
        printf("\nmul-fip: this is not an ADL problem!");
        printf("\n\tcan't be handled by this version.\n\n");
        exit( 1 );
    }
    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: make_adl_domain() done.\n");
    }

    /* now instantiate operators;
     */
    /*JC: initialize the array*/
    gInvActs = (StateActionPair*)calloc(MAX_INVALID_ACTIONS, sizeof(StateActionPair));

    /**************************
     * first do PREPROCESSING *
     **************************/

    /* start by collecting all strings and thereby encoding
     * the domain in integers.
     */
    encode_domain_in_integers();

    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: encode_domain_in_integers() done.\n");
    }
    /* inertia preprocessing, first step:
     *   - collect inertia information
     *   - split initial state into
     *        _ arrays for individual predicates
     *        - arrays for all static relations
     *        - array containing non - static relations
     */
    do_inertia_preprocessing_step_1();
    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: do_inertia_preprocessing_step_1() done.\n");
    }

    /* normalize all PL1 formulae in domain description:
     * (goal, preconds and effect conditions)
     *   - simplify formula
     *   - expand quantifiers
     *   - NOTs down
     */
    normalize_all_wffs();

    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: normalize_all_wffs() done.\n");
    }

    /* translate negative preconds: introduce symmetric new predicate
     * NOT-p(..) (e.g., not-in(?ob) in briefcaseworld)
     */
    translate_negative_preconds();
    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: translate_negative_preconds() done.\n");
    }

    /* split domain in easy (disjunction of conjunctive preconds)
     * and hard (non DNF preconds) part, to apply
     * different instantiation algorithms
     */
    split_domain();
    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: split_domain() done.\n");
    }

    /***********************************************
     * PREPROCESSING FINISHED                      *
     *                                             *
     * NOW MULTIPLY PARAMETERS IN EFFECTIVE MANNER *
     ***********************************************/

    /*jovi: updated for multiple purpose */
    build_easy_action_templates();
    build_hard_action_templates();

    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: build_easy_action_template() done.\n");
    }

    /*times( &end );*/
    ftime(&end);
    TIME( gtempl_time );

    /*times( &start );*/
    ftime(&start);

    /* perform reachability analysis in terms of relaxed  fixpoint */
    perform_reachability_analysis();

    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: perform_reachability_analysis() done.\n");
    }

    /*times( &end );*/
    ftime(&end);
    TIME( greach_time );

    /*times( &start );*/
    ftime(&start);

    /* collect the relevant facts and build final domain
     * and problem representations.*/
    collect_relevant_facts();
    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: collect_relevant_facts.\n");
    }
    /*times( &end );*/
    ftime(&end);
    TIME( grelev_time );

    /*times( &start );*/
    ftime(&start);

    /* now build globally accessable connectivity graph */
    build_connectivity_graph();
    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: build_connectivity_graph().\n");
    }

    /*times( &end );*/
    ftime(&end);
    TIME( gconn_time );


    /***********************************************************
     * we are finally through with preprocessing and can worry *
     * bout finding a plan instead.                            *
     ***********************************************************/
    ftime(&mystart);
    /*times( &start );*/
    ftime(&start);

    /* another quick preprocess: approximate goal orderings and split
     * goal set into sequence of smaller sets, the goal agenda
     */
    compute_goal_agenda();
    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: compute_goal_agenda().\n");
    }
    /*debugit(&ginitial_state);*/
    /* make space in plan states info, and relax
     * make sapce is initialize the space for gplan_states and
     * initialzie the variable
     */
    for ( i = 0; i < MAX_PLAN_LENGTH + 1; i++ ) {
        make_state( &(gplan_states[i]), gnum_ft_conn );
        gplan_states[i].max_F = gnum_ft_conn;
    }

    make_state( &current_start, gnum_ft_conn );
    current_start.max_F = gnum_ft_conn;
    make_state( &current_end, gnum_ft_conn );
    current_end.max_F = gnum_ft_conn;
    initialize_relax();

    /* need to read the agenda paper */
    source_to_dest( &(gplan_states[0]), &ginitial_state );
    source_to_dest( &current_start, &ginitial_state );
    source_to_dest( &current_end, &(ggoal_agenda[0]) );

    for ( i = 0; i < gnum_goal_agenda; i++ ) {
        /* JC add a hashtable creating in do_enforced_hill_climbling*/
        if (!do_enforced_hill_climbing(&current_start, &current_end)) {
            if (gcmd_line.display_info >= 1) {
                printf("\nDebugInfo: do_enforced_hill_climbling() exit .\n");
            }
            break;
        }
        source_to_dest( &current_start, &(gplan_states[gnum_plan_ops]) );
        if ( i < gnum_goal_agenda - 1 ) {
            for ( j = 0; j < ggoal_agenda[i+1].num_F; j++ ) {
                current_end.F[current_end.num_F++] = ggoal_agenda[i+1].F[j];
            }
        }
    }

    found_plan = ( i == gnum_goal_agenda ) ? TRUE : FALSE;

    if ( !found_plan ) {
        printf("\nDebugInfo: switching to Best-first Search now.\n");
        reset_ff_states();
        found_plan = do_best_first_search();
    }


    if ( gcmd_line.display_info >= 1 ) {
        printf("\n************************************************\n");
        printf("\n*  mul-fip: fip plan finished for single goal. *\n");
        printf("\n************************************************\n");
    }
    print_plan();

    if ( !found_plan ) {
        /*print_plan();*/
        /* D action add to group */
        build_action_group();

        gfipPlan.num_sons = 0;
        gfipPlan.action = -1;

        print_plan();

        /*put the ultimate goal to the solved set*/
        StateActionPair *g = new_StateActionPair();
        make_state(&g->state, gnum_ft_conn);
        g->state.max_F = gnum_ft_conn;
        source_to_dest(&g->state, &ggoal_state);
        g->state.num_L = 1;
        g->state.L[0] = 10000000; /*make it the biggest*/
        add_solved_state(g);
        /*ugly, but work*/

        convert_ff_plan_to_fip_plan( &gfipPlan );

        solve_unsolved_states();

        if(!gsolved_states) {
            printf("No solutions are found! The problem is unsolvable.\n");
            exit(0);
        } else if(g_is_strong) {
            StateActionPair *ptr = gsolved_states;
            Bool valid = FALSE;
            while(ptr) {
                if(ptr->state.num_L == 1 && ptr->state.L[0] == 1) {
                    valid = TRUE;
                    break;
                }
                ptr = ptr->next;
            }
            if(!valid) {
                printf("The initial state is a dead-end! The problem is unsolvable.\n");
                exit(0);
            }
        }

        printf("##########################################\n");
        printf("#####   PROCEDURE-LIKE CODE   ############\n");
        printf("##########################################\n");
        /* print_fip_plan_1( is_solved_state(&ginitial_state) , &gfipPlan, 1); */

        /* times( &end ); */
        ftime(&end);
        TIME( gsearch_time );

        /* myend = clock(); */
        ftime(&myend);

        /* printf("my cac is %7.3f\n", 1.0*(myend.millitm - mystart.millitm)/1000.0); */
        print_fip_plan_2();

        if(to_print_state)
            print_all_states();
        /* print_fip_plan_3( &gfipPlan, 0 ); */
    }
    printf("The total searching time is %7.3f\n", (myend.time - mystart.time) + (myend.millitm - mystart.millitm)/1000.0);

    output_planner_info();




    /********************************************
     * Multiple Purpose Planning                *
     ********************************************/

    if ( gcmd_line.display_info >= 1 ) {
        printf("\n************************************************\n");
        printf("\n*  mul-fip: multiple purpose planning          *\n");
        printf("\n************************************************\n");
    }

    set_global_variables_for_multiple_purpose();

    ftime(&start);
    update_reachability_analysis_for_multiple_purpose ();
    ftime(&end);
    TIME( gadd_reach_time );

    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: update_reachability_analysis_for_multiple_purpose() finished\n");
    }

    ftime(&start);
    update_relevant_facts_for_multiple_purpose ();
    ftime(&end);
    TIME( gadd_relev_time );

    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: update_relevant_facts_for_multiple_purpose() finished\n");
    }

    ftime(&start);
    update_connectivity_graph_for_multiple_purpose();
    ftime(&end);
    TIME( gadd_conn_time );

    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: update_connectivity_graph_for_multiple_purpose() finished\n");
    }

    compute_goal_agenda_for_multiple_purpose ();

    if ( gcmd_line.display_info >= 1 ) {
        printf("\nDebugInfo: compute_goal_agenda_for_multiple_purpose() finished\n");
    }

    for ( i = 0; i < MAX_PLAN_LENGTH + 1; i++ ) {
        make_state( &(gadd_plan_states[i]), gnum_ft_conn );
        gadd_plan_states[i].max_F = gnum_ft_conn;
    }

    source_to_dest( &current_end, &(gadd_goal_agenda[0]) );

    for ( i = 0; i < gadd_num_goal_agenda; i++ ) {
        /* JC add a hashtable creating in do_enforced_hill_climbling*/
        if ( !do_enforced_hill_climbing_for_multiple_purpose ( &current_start, &current_end ) ) {
            break;
        }
        source_to_dest( &current_start, &(gplan_states[gnum_plan_ops]) );
        if ( i < gnum_goal_agenda - 1 ) {
            for ( j = 0; j < ggoal_agenda[i+1].num_F; j++ ) {
                current_end.F[current_end.num_F++] = ggoal_agenda[i+1].F[j];
            }
        }
    }

    found_plan_for_multiple_purpose = ( i == gadd_num_goal_agenda ) ? TRUE : FALSE;



    if ( !found_plan_for_multiple_purpose ) {
        printf("\n\nEnforced Hill-climbing failed !");
        printf("\nswitching to Best-first Search now.\n");
        reset_ff_states_for_multiple_purpose();
        found_plan_for_multiple_purpose = do_best_first_search_for_multiple_purpose();
    }

    if ( gcmd_line.display_info >= 1 ) {
        printf("\n************************************************\n");
        printf("\n*  mul-fip: fip plan finished for multiple goal. *\n");
        printf("\n************************************************\n");
    }

    print_plan();

    if ( !found_plan_for_multiple_purpose ) {
        /*print_plan();*/
        /* D action add to group */
        build_action_group();

        gfipPlan.num_sons = 0;
        gfipPlan.action = -1;

        print_plan();

        /*put the ultimate goal to the solved set*/
        StateActionPair *g = new_StateActionPair();
        make_state(&g->state, gnum_ft_conn);
        g->state.max_F = gnum_ft_conn;
        source_to_dest(&g->state, &ggoal_state);
        g->state.num_L = 1;
        g->state.L[0] = 10000000; /*make it the biggest*/
        add_solved_state(g);
        /*ugly, but work*/

        convert_ff_plan_to_fip_plan( &gfipPlan );

        solve_unsolved_states();

        if(!gsolved_states) {
            printf("No solutions are found! The problem is unsolvable.\n");
            exit(0);
        } else if(g_is_strong) {
            StateActionPair *ptr = gsolved_states;
            Bool valid = FALSE;
            while(ptr) {
                if(ptr->state.num_L == 1 && ptr->state.L[0] == 1) {
                    valid = TRUE;
                    break;
                }
                ptr = ptr->next;
            }
            if(!valid) {
                printf("The initial state is a dead-end! The problem is unsolvable.\n");
                exit(0);
            }
        }

        printf("##########################################\n");
        printf("#####   PROCEDURE-LIKE CODE   ############\n");
        printf("##########################################\n");
        /* print_fip_plan_1( is_solved_state(&ginitial_state) , &gfipPlan, 1); */

        /* times( &end ); */
        ftime(&end);
        TIME( gsearch_time );

        /* myend = clock(); */
        ftime(&myend);

        /* printf("my cac is %7.3f\n", 1.0*(myend.millitm - mystart.millitm)/1000.0); */
        print_fip_plan_2();

        if(to_print_state)
            print_all_states();
        /* print_fip_plan_3( &gfipPlan, 0 ); */
    }
    /*****************************************************************************************/

    output_planner_info();

    printf("\n\n");
    exit( 0 );

}