void create_final_initial_state( void ) { Facts *f; int i, adr; for ( f = ginitial; f; f = f->next ) { lp = f->fact->predicate; for ( i = 0; i < garity[lp]; i++ ) { largs[i] = f->fact->args[i]; } adr = fact_adress(); if ( !lneg[lp][adr] ) {/* non deleted ini */ continue; } if ( ginitial_state.num_F == MAX_STATE ) { printf("\ntoo many initial facts! increase MAX_STATE(%d)\n\n", MAX_STATE); exit( 1 ); } ginitial_state.F[ginitial_state.num_F++] = lindex[lp][adr]; } }
// void set_relevants_in_wff( WffNode **w ) int set_relevants_in_wff( WffNode **w ) /* * End of DEA */ { WffNode *i; int j, adr; switch ( (*w)->connective ) { case AND: case OR: for ( i = (*w)->sons; i; i = i->next ) { set_relevants_in_wff( &i ); } break; case ATOM: /* no equalities, as fully instantiated */ lp = (*w)->fact->predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = (*w)->fact->args[j]; } adr = fact_adress(); if ( !lneg[lp][adr] ) { (*w)->connective = TRU; free( (*w)->fact ); (*w)->fact = NULL; break; } if ( !lpos[lp][adr] ) { (*w)->connective = FAL; free( (*w)->fact ); (*w)->fact = NULL; break; } break; default: printf("\n\nwon't get here: non NOT,OR,AND in goal set relevants\n\n"); /* * DEA - University of Brescia */ exit( 1 ); /* * End of DEA */ } /* * DEA - University of Brescia */ return 0; /* * End of DEA */ }
void create_final_initial_state( void ) { Facts *f; int i, adr; for ( f = ginitial; f; f = f->next ) { lp = f->fact->predicate; for ( i = 0; i < garity[lp]; i++ ) { largs[i] = f->fact->args[i]; } adr = fact_adress(); if ( !lneg[lp][adr] ) {/* non deleted ini */ continue; } ginitial_state.F[ginitial_state.num_F++] = lindex[lp][adr]; } }
void create_final_goal_state( void ) { WffNode *w, *ww; int m, i, adr; Action *tmp; /* * DEA - University of Brescia */ // set_relevants_in_wff( &ggoal ); if (set_relevants_in_wff (&ggoal)) return; /* * End of DEA */ cleanup_wff( &ggoal ); if ( ggoal->connective == TRU ) { /* * DEA - University of Brescia */ // printf("\nff: goal can be simplified to TRUE. The empty plan solves it\n\n"); printf ("\n%s: goal can be simplified to TRUE. The empty plan solves it\n\n", NAMEPRG); /* * End of DEA */ exit( 1 ); } if ( ggoal->connective == FAL ) { /* * DEA - University of Brescia */ if (GpG.inst_duplicate_param == FALSE) printf("\n%s: create_final_goal_state(): goal can be simplified to FALSE. \n Please run %s with option '-same_objects' \n\n", NAMEPRG, NAMEPRG); else printf("\n%s: create_final_goal_state(): goal can be simplified to FALSE.\n No plan will solve it\n\n", NAMEPRG); // printf("\nff: goal can be simplified to FALSE. No plan will solve it\n\n"); /* * End of DEA */ exit( 1 ); } switch ( ggoal->connective ) { case OR: if ( gnum_relevant_facts == MAX_RELEVANT_FACTS ) { printf("\nincrease MAX_RELEVANT_FACTS! (current value: %d)\n\n", MAX_RELEVANT_FACTS); exit( 1 ); } grelevant_facts[gnum_relevant_facts].predicate = -3; gnum_relevant_facts++; for ( w = ggoal->sons; w; w = w->next ) { tmp = new_Action(); if ( w->connective == AND ) { m = 0; for ( ww = w->sons; ww; ww = ww->next ) m++; tmp->preconds = ( int * ) calloc( m, sizeof( int ) ); tmp->num_preconds = 0; for ( ww = w->sons; ww; ww = ww->next ) { lp = ww->fact->predicate; for ( i = 0; i < garity[lp]; i++ ) { largs[i] = ww->fact->args[i]; } adr = fact_adress(); tmp->preconds[tmp->num_preconds++] = lindex[lp][adr]; } } else { tmp->preconds = ( int * ) calloc( 1, sizeof( int ) ); tmp->num_preconds = 1; lp = w->fact->predicate; for ( i = 0; i < garity[lp]; i++ ) { largs[i] = w->fact->args[i]; } adr = fact_adress(); tmp->preconds[0] = lindex[lp][adr]; } tmp->effects = ( ActionEffect * ) calloc( 1, sizeof( ActionEffect ) ); tmp->num_effects = 1; tmp->effects[0].conditions = NULL; tmp->effects[0].num_conditions = 0; tmp->effects[0].dels = NULL; tmp->effects[0].num_dels = 0; tmp->effects[0].adds = ( int * ) calloc( 1, sizeof( int ) ); tmp->effects[0].adds[0] = gnum_relevant_facts - 1; tmp->effects[0].num_adds = 1; tmp->next = gactions; gactions = tmp; gnum_actions++; lnum_effects++; } ggoal_state.F[0] = gnum_relevant_facts - 1; ggoal_state.num_F = 1; break; case AND: for ( w = ggoal->sons; w; w = w->next ) { lp = w->fact->predicate; for ( i = 0; i < garity[lp]; i++ ) { largs[i] = w->fact->args[i]; } adr = fact_adress(); ggoal_state.F[ggoal_state.num_F++] = lindex[lp][adr]; } break; case ATOM: ggoal_state.num_F = 1; lp = ggoal->fact->predicate; for ( i = 0; i < garity[lp]; i++ ) { largs[i] = ggoal->fact->args[i]; } adr = fact_adress(); ggoal_state.F[0] = lindex[lp][adr]; break; default: printf("\n\nwon't get here: non ATOM,AND,OR in fully simplified goal\n\n"); exit( 1 ); } }
void collect_relevant_facts( void ) { Action *a; NormOperator *no; NormEffect *ne; int i, j, adr; PseudoAction *pa; PseudoActionEffect *pae; /* mark all deleted facts; such facts, that are also pos, are relevant. */ for ( a = gactions; a; a = a->next ) { if ( a->norm_operator ) { no = a->norm_operator; for ( ne = no->effects; ne; ne = ne->next ) { 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(); lneg[lp][adr] = 1; if ( lpos[lp][adr] && !luse[lp][adr] ) { luse[lp][adr] = 1; lindex[lp][adr] = gnum_relevant_facts; if ( gnum_relevant_facts == MAX_RELEVANT_FACTS ) { printf("\nincrease MAX_RELEVANT_FACTS! (current value: %d)\n\n", MAX_RELEVANT_FACTS); exit( 1 ); } grelevant_facts[gnum_relevant_facts].predicate = lp; for ( j = 0; j < garity[lp]; j++ ) { grelevant_facts[gnum_relevant_facts].args[j] = largs[j]; } lindex[lp][adr] = gnum_relevant_facts; gnum_relevant_facts++; } } } } else { pa = a->pseudo_action; for ( pae = pa->effects; pae; pae = pae->next ) { 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(); lneg[lp][adr] = 1; if ( lpos[lp][adr] && !luse[lp][adr] ) { luse[lp][adr] = 1; lindex[lp][adr] = gnum_relevant_facts; if ( gnum_relevant_facts == MAX_RELEVANT_FACTS ) { printf("\nincrease MAX_RELEVANT_FACTS! (current value: %d)\n\n", MAX_RELEVANT_FACTS); exit( 1 ); } grelevant_facts[gnum_relevant_facts].predicate = lp; for ( j = 0; j < garity[lp]; j++ ) { grelevant_facts[gnum_relevant_facts].args[j] = largs[j]; } lindex[lp][adr] = gnum_relevant_facts; gnum_relevant_facts++; } } } } } if ( gcmd_line.display_info == 119 ) { printf("\n\nfacts selected as relevant:\n\n"); for ( i = 0; i < gnum_relevant_facts; i++ ) { printf("\n%d: ", i); print_Fact( &(grelevant_facts[i]) ); } } lnum_effects = 0; // Chih-Wei if (GpG.SearchModal != -2) create_final_goal_state(); create_final_initial_state(); create_final_actions(); if ( gcmd_line.display_info == 120 ) { printf("\n\nfinal domain representation is:\n\n"); for ( i = 0; i < gnum_operators; i++ ) { printf("\n\n------------------operator %s-----------\n\n", goperators[i]->name); for ( a = gactions; a; a = a->next ) { if ( ( !a->norm_operator && !a->pseudo_action ) || ( a->norm_operator && a->norm_operator->operator != goperators[i] ) || ( a->pseudo_action && a->pseudo_action->operator != goperators[i] ) ) { continue; } print_Action( a ); } } printf("\n\n--------------------GOAL REACHED ops-----------\n\n"); for ( a = gactions; a; a = a->next ) { if ( !a->norm_operator && !a->pseudo_action ) { print_Action( a ); } } printf("\n\nfinal initial state is:\n\n"); for ( i = 0; i < ginitial_state.num_F; i++ ) { print_ft_name( ginitial_state.F[i] ); printf("\n"); } printf("\n\nfinal goal state is:\n\n"); for ( i = 0; i < ggoal_state.num_F; i++ ) { print_ft_name( ggoal_state.F[i] ); printf("\n"); } } }
void perform_reachability_analysis( void ) { int size, i, j, k, adr, num; Bool fixpoint; Facts *f; NormOperator *no; EasyTemplate *t1, *t2; NormEffect *ne; Action *tmp, *a; Bool *had_hard_template; PseudoAction *pa; PseudoActionEffect *pae; /* * DEA - University of Brescia */ int numero, kk, kkk; WffNode *precs, *n; /* * End of DEA */ gactions = NULL; gnum_actions = 0; for ( i = 0; i < gnum_predicates; i++ ) { size = 1; for ( j = 0; j < garity[i]; j++ ) { size *= gnum_constants; } lpos[i] = ( int_pointer ) calloc( size, sizeof( int ) ); lneg[i] = ( int_pointer ) calloc( size, sizeof( int ) ); luse[i] = ( int_pointer ) calloc( size, sizeof( int ) ); lindex[i] = ( int_pointer ) calloc( size, sizeof( int ) ); for ( j = 0; j < size; j++ ) { lpos[i][j] = 0; lneg[i][j] = 1;/* all facts but initials are poss. negative */ luse[i][j] = 0; lindex[i][j] = -1; } } had_hard_template = ( Bool * ) calloc( gnum_hard_templates, sizeof( Bool ) ); for ( i = 0; i < gnum_hard_templates; i++ ) { had_hard_template[i] = FALSE; } /* mark initial facts as possibly positive, not poss. negative */ for ( i = 0; i < gnum_predicates; i++ ) { lp = i; for ( j = 0; j < gnum_initial_predicate[i]; j++ ) { for ( k = 0; k < garity[i]; k++ ) { largs[k] = ginitial_predicate[i][j].args[k]; } adr = fact_adress(); lpos[lp][adr] = 1; lneg[lp][adr] = 0; } } /* compute fixpoint */ fixpoint = FALSE; while ( !fixpoint ) { fixpoint = TRUE; /* * DEA - University of Brescia */ /*geasy_templates: action list (instantious operator) */ numero = 0; for (t1 = geasy_templates; t1; t1 = t1->next) numero++; if (gcmd_line.display_info == 121) printf ("\nLe geasy_templates sono %d, le gnum_actions %d", numero, gnum_actions); /* * End of DEA */ /* assign next layer of easy templates to possibly positive fixpoint */ t1 = geasy_templates; while ( t1 ) { no = t1->op; 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] : t1->inst_table[DECODE_VAR( no->preconds[i].args[j] )]; } /* * DEA - University of Brescia */ //se questa precondizione compare anche tra gli effetti additivi, allora considerala raggiunta //ATTENZIONE: non e' esattamente corretto; questo check e' volto a gestire il caso di una precondizione over all o at end //che viene realizzata attraverso un effetto at start - senza qs check l'azione non risulta applicabile //il problema e' che qui non introduco i check su overall, end, etc: basta che una preco compaia anche tra gli effetti e la considero raggiunta //ATTENZIONE: saltare questo check se il corrispondente PlOperator e' is_odd for (kk = 0; kk < no->effects->num_adds; kk++) { int this_pred = no->effects->adds[kk].predicate; if(no->effects->num_adds>MAX_VARS) { #ifdef __MY_OUTPUT__ MSG_ERROR ( WAR_MAX_VARS ); #else printf( WAR_MAX_VARS ); #endif exit (1); } for (kkk = 0; kkk < no->effects->num_adds; kkk++) these_args[kkk] = (no->effects->adds[kk].args[kkk] >= 0) ? no->effects->adds[kk].args[kkk] : t1-> inst_table[DECODE_VAR(no->effects->adds[kk].args[kkk])]; //cerco la preco corrente tra gli effetti additivi //il predicato non coincide: provo con il prossimo effetto if (this_pred != lp) continue; //controllo tutti gli argomenti for (kkk = 0; kkk < garity[this_pred]; kkk++) //se ce n'e' almeno uno diverso, non e' lo stesso fatto if (these_args[kkk] != largs[kkk]) break; //questo if e' vero se e' lo stesso fatto: l'ho trovato quindi esco if (kkk == garity[this_pred]) break; } //se non ho fatto passare tutti gli effetti, significa che ho trovato la preco tra gli effetti additivi: considero raggiunta la preco, passa a controllare la prossima if (kk != no->effects->num_adds) continue; /* se tale preco non e' raggiunta, esci e vai a qui1 */ /* * End of DEA */ if ( !lpos[lp][fact_adress()] ) { break; } } if ( i < no->num_preconds ) { t1 = t1->next; continue; } /* * DEA - University of Brescia */ //ulteriore check: verifico che un predicato inerziale sia effettivamente presente nei fatti iniziali, altrimenti l'azione non e' applicabile //problema rilevato con Rovers/SimpleTime precs = no->operator-> preconds; if (precs->connective == AND) precs = precs->sons; for (n = precs; n; n = n->next) { //mi e' capitato di trovare un nodo not, con son predicato -1. boh? (problema:Satellite/numeric) if (n->fact == NULL) continue; /*lp=numero di predicato della preco i-esima */ lp = n->fact->predicate; /*per ciascuno degli argomenti della precondizione */ for (j = 0; j < garity[lp]; j++) { /* CONTROLLARE */ largs[j] =(n->fact->args[j] >= 0 ) ? n->fact->args[j]: t1->inst_table[DECODE_VAR (n->fact->args[j])]; } adr = fact_adress (); //CHECK1 chiesto da Ivan: se il fatto e' non inerziale e non compare tra le preconds del normoperator, da errore! //INIZIO CHECK1 if (gis_added[lp] || gis_deleted[lp]) { for (i = 0; i < no->num_preconds; i++) { /*lp=numero di predicato della preco i-esima */ lp1 = no->preconds[i].predicate; /*per ciascuno degli argomenti della precondizione */ for (j = 0; j < garity[lp1]; j++) { /* non ho colto qui perche' ci sono 2 casi, comunque mette in largs[k] il numero di ciascun oggetto */ largs1[j] = (no->preconds[i].args[j] >= 0) ? no->preconds[i].args[j] : t1-> inst_table[DECODE_VAR (no->preconds[i].args[j])]; } if ((lp == lp1) && (adr == fact_adress1 ())) break; } if (i == no->num_preconds) { if(DEBUG3) { printf ("\nAttenzione: uno dei fatti non inerziali non compare tra le preconds del normoperator!\n"); fflush (stdout); } assert (0); } } //FINE CHECK1 //se questo fatto viene aggiunto, non e' necessario verificarlo -> passo al prossimo if (gis_added[lp]) continue; //Se il fatto non e' stato raggiunto, non posso applicare l'azione: esco dal for if (!lpos[lp][fact_adress ()]) break; } //se ho fatto un break prima di finire le preco, significa che un predicato inerziale non compare nei fatti iniziali if (n != NULL) { //passo quindi ad esaminare la prossima azione t1 = t1->next; continue; } /* * End of DEA */ num = 0; for ( ne = no->effects; ne; ne = ne->next ) { num++; /* currently, simply ignore effect conditions and assume * they will all be made true eventually. */ 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] : t1->inst_table[DECODE_VAR( ne->adds[i].args[j] )]; } adr = fact_adress(); if ( !lpos[lp][adr] ) { /* new relevant fact! (added non initial) */ lpos[lp][adr] = 1; lneg[lp][adr] = 1; luse[lp][adr] = 1; if ( gnum_relevant_facts == MAX_RELEVANT_FACTS ) { printf("\ntoo many relevant facts! increase MAX_RELEVANT_FACTS (currently %d)\n\n", MAX_RELEVANT_FACTS); exit( 1 ); } grelevant_facts[gnum_relevant_facts].predicate = lp; for ( j = 0; j < garity[lp]; j++ ) { grelevant_facts[gnum_relevant_facts].args[j] = largs[j]; } lindex[lp][adr] = gnum_relevant_facts; gnum_relevant_facts++; fixpoint = FALSE; } } } /* * DEA - University of Brescia */ check_time_and_length (0); /* con zero non controlla la lunghezza */ /* * End of DEA */ tmp = new_Action(); tmp->norm_operator = no; for ( i = 0; i < no->num_vars; i++ ) { tmp->inst_table[i] = t1->inst_table[i]; } tmp->name = no->operator->name; tmp->num_name_vars = no->operator->number_of_real_params; make_name_inst_table_from_NormOperator( tmp, no, t1 ); tmp->next = gactions; tmp->num_effects = num; gactions = tmp; gnum_actions++; t2 = t1->next; if ( t1->next ) { t1->next->prev = t1->prev; } if ( t1->prev ) { t1->prev->next = t1->next; } else { geasy_templates = t1->next; } free_single_EasyTemplate( t1 ); t1 = t2; } /* now assign all hard templates that have not been transformed * to actions yet. */ for ( i = 0; i < gnum_hard_templates; i++ ) { if ( had_hard_template[i] ) { continue; } pa = ghard_templates[i]; for ( j = 0; j < pa->num_preconds; j++ ) { lp = pa->preconds[j].predicate; for ( k = 0; k < garity[lp]; k++ ) { largs[k] = pa->preconds[j].args[k]; } if ( !lpos[lp][fact_adress()] ) { break; } } if ( j < pa->num_preconds ) { continue; } for ( pae = pa->effects; pae; pae = pae->next ) { /* currently, simply ignore effect conditions and assume * they will all be made true eventually. */ for ( j = 0; j < pae->num_adds; j++ ) { lp = pae->adds[j].predicate; for ( k = 0; k < garity[lp]; k++ ) { largs[k] = pae->adds[j].args[k]; } adr = fact_adress(); if ( !lpos[lp][adr] ) { /* new relevant fact! (added non initial) */ lpos[lp][adr] = 1; lneg[lp][adr] = 1; luse[lp][adr] = 1; if ( gnum_relevant_facts == MAX_RELEVANT_FACTS ) { printf("\ntoo many relevant facts! increase MAX_RELEVANT_FACTS (currently %d)\n\n", MAX_RELEVANT_FACTS); exit( 1 ); } grelevant_facts[gnum_relevant_facts].predicate = lp; for ( k = 0; k < garity[lp]; k++ ) { grelevant_facts[gnum_relevant_facts].args[k] = largs[k]; } lindex[lp][adr] = gnum_relevant_facts; gnum_relevant_facts++; fixpoint = FALSE; } } } /* * DEA - University of Brescia */ check_time_and_length (0); /* con zero non controlla la lunghezza */ /* * End of DEA */ tmp = new_Action(); tmp->pseudo_action = pa; for ( j = 0; j < pa->operator->num_vars; j++ ) { tmp->inst_table[j] = pa->inst_table[j]; } tmp->name = pa->operator->name; tmp->num_name_vars = pa->operator->number_of_real_params; make_name_inst_table_from_PseudoAction( tmp, pa ); tmp->next = gactions; tmp->num_effects = pa->num_effects; gactions = tmp; gnum_actions++; had_hard_template[i] = TRUE; } } /* * DEA - University of Brescia */ numero = 0; for (t1 = geasy_templates; t1; t1 = t1->next) numero++; if (gcmd_line.display_info == 121) printf ("\nLe geasy_templates sono %d, le gnum_actions %d", numero, gnum_actions); /* * End of DEA */ free( had_hard_template ); gnum_pp_facts = gnum_initial + gnum_relevant_facts; if ( gcmd_line.display_info == 118 ) { printf("\nreachability analysys came up with:"); printf("\n\npossibly positive facts:"); for ( f = ginitial; f; f = f->next ) { printf("\n"); print_Fact( f->fact ); } for ( i = 0; i < gnum_relevant_facts; i++ ) { printf("\n"); print_Fact( &(grelevant_facts[i]) ); } printf("\n\nthis yields these %d action templates:", gnum_actions); for ( i = 0; i < gnum_operators; i++ ) { printf("\n\noperator %s:", goperators[i]->name); for ( a = gactions; a; a = a->next ) { if ( ( a->norm_operator && a->norm_operator->operator != goperators[i] ) || ( a->pseudo_action && a->pseudo_action->operator != goperators[i] ) ) { continue; } printf("\ntemplate: "); for ( j = 0; j < goperators[i]->number_of_real_params; j++ ) { printf("%s", gconstants[a->name_inst_table[j]]); if ( j < goperators[i]->num_vars-1 ) { printf(" "); } } } } printf("\n\n"); } }
void create_final_actions( void ) { Action *a; NormOperator *no; NormEffect *ne; int i, j, adr, h; PseudoAction *pa; PseudoActionEffect *pae; for ( a = gactions; a; a = a->next ) { 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]; } if ( a->num_effects > 0 ) { a->effects = ( ActionEffect * ) calloc( a->num_effects, sizeof( ActionEffect ) ); } a->num_effects = 0; for ( ne = no->effects; ne; ne = ne->next ) { if ( ne->num_conditions > 0 ) { a->effects[a->num_effects].conditions = ( int * ) calloc( ne->num_conditions, sizeof( int ) ); } a->effects[a->num_effects].num_conditions = 0; for ( i = 0; i < ne->num_conditions; i++ ) { lp = ne->conditions[i].predicate; h = ( lp < 0 ) ? 2 : garity[lp]; for ( j = 0; j < h; j++ ) { largs[j] = ( ne->conditions[i].args[j] >= 0 ) ? ne->conditions[i].args[j] : a->inst_table[DECODE_VAR( ne->conditions[i].args[j] )]; } if ( lp >= 0 ) { adr = fact_adress(); if ( !lpos[lp][adr] ) {/* condition not reachable: skip effect */ break; } if ( !lneg[lp][adr] ) {/* condition always true: skip it */ continue; } a->effects[a->num_effects].conditions[a->effects[a->num_effects].num_conditions++] = lindex[lp][adr]; } else { if ( lp == -2 ) { if ( largs[0] == largs[1] ) break; } else { if ( largs[0] != largs[1] ) break; } } } if ( i < ne->num_conditions ) {/* found unreachable condition: free condition space */ free( a->effects[a->num_effects].conditions ); continue; } /* now create the add and del effects. */ if ( ne->num_adds > 0 ) { a->effects[a->num_effects].adds = ( int * ) calloc( ne->num_adds, sizeof( int ) ); } a->effects[a->num_effects].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; } a->effects[a->num_effects].adds[a->effects[a->num_effects].num_adds++] = lindex[lp][adr]; } if ( ne->num_dels > 0 ) { a->effects[a->num_effects].dels = ( int * ) calloc( ne->num_dels, sizeof( int ) ); } a->effects[a->num_effects].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; } a->effects[a->num_effects].dels[a->effects[a->num_effects].num_dels++] = lindex[lp][adr]; } /* this effect is OK. go to next one in NormOp. */ a->num_effects++; lnum_effects++; } continue; } 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]; } if ( a->num_effects > 0 ) { a->effects = ( ActionEffect * ) calloc( a->num_effects, sizeof( ActionEffect ) ); } a->num_effects = 0; for ( pae = pa->effects; pae; pae = pae->next ) { if ( pae->num_conditions > 0 ) { a->effects[a->num_effects].conditions = ( int * ) calloc( pae->num_conditions, sizeof( int ) ); } a->effects[a->num_effects].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; } a->effects[a->num_effects].conditions[a->effects[a->num_effects].num_conditions++] = lindex[lp][adr]; } if ( i < pae->num_conditions ) {/* found unreachable condition: free condition space */ free( a->effects[a->num_effects].conditions ); continue; } /* now create the add and del effects. */ if ( pae->num_adds > 0 ) { a->effects[a->num_effects].adds = ( int * ) calloc( pae->num_adds, sizeof( int ) ); } a->effects[a->num_effects].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; } a->effects[a->num_effects].adds[a->effects[a->num_effects].num_adds++] = lindex[lp][adr]; } if ( pae->num_dels > 0 ) { a->effects[a->num_effects].dels = ( int * ) calloc( pae->num_dels, sizeof( int ) ); } a->effects[a->num_effects].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; } a->effects[a->num_effects].dels[a->effects[a->num_effects].num_dels++] = lindex[lp][adr]; } /* this effect is OK. go to next one in PseudoAction. */ a->num_effects++; lnum_effects++; } }/* 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. */ }/* endfor all actions ! */ }
void collect_relevant_facts( void ) { Action *a; Operator *o; int i, j, adr; /* mark all deleted facts; such facts, that are also pos, are relevant. */ for ( a = gactions; a; a = a->next ) { o = goperators[a->op]; for ( i = 0; i < o->num_dels; i++ ) { lp = o->dels[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = GET_CONSTANT( o->dels[i].args[j], a ); } adr = fact_adress(); lneg[lp][adr] = 1; if ( lpos[lp][adr] && !luse[lp][adr] ) { luse[lp][adr] = 1; lindex[lp][adr] = gnum_relevant_facts; if ( gnum_relevant_facts == MAX_RELEVANT_FACTS ) { printf("\nincrease MAX_RELEVANT_FACTS! (current value: %d)\n\n", MAX_RELEVANT_FACTS); exit( 1 ); } grelevant_facts[gnum_relevant_facts].predicate = lp; for ( j = 0; j < garity[lp]; j++ ) { grelevant_facts[gnum_relevant_facts].args[j] = largs[j]; } lindex[lp][adr] = gnum_relevant_facts; gnum_relevant_facts++; } } } /* now build final action instances */ for ( a = gactions; a; a = a->next ) { o = goperators[a->op]; for ( i = 0; i < o->num_preconds; i++ ) { lp = o->preconds[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = GET_CONSTANT( o->preconds[i].args[j], a ); } adr = fact_adress(); if ( !lneg[lp][adr] ) { continue; } a->preconds[a->num_preconds++] = lindex[lp][adr]; } for ( i = 0; i < o->num_adds; i++ ) { lp = o->adds[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = GET_CONSTANT( o->adds[i].args[j], a ); } adr = fact_adress(); if ( !lneg[lp][adr] ) { continue; } a->adds[a->num_adds++] = lindex[lp][adr]; } for ( i = 0; i < o->num_dels; i++ ) { lp = o->dels[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = GET_CONSTANT( o->dels[i].args[j], a ); } adr = fact_adress(); if ( !lpos[lp][adr] ) { continue; } a->dels[a->num_dels++] = lindex[lp][adr]; } } /* build final initial and goal representation */ ginitial_state.num_F = 0; for ( i = 0; i < gnum_initial; i++ ) { lp = ginitial[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = ginitial[i].args[j]; } adr = fact_adress(); if ( !lneg[lp][adr] ) { continue; } ginitial_state.F[ginitial_state.num_F++] = lindex[lp][adr]; } ggoal_state.num_F = 0; for ( i = 0; i < gnum_goal; i++ ) { lp = ggoal[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = ggoal[i].args[j]; } adr = fact_adress(); if ( !lneg[lp][adr] ) { continue; } ggoal_state.F[ggoal_state.num_F++] = lindex[lp][adr]; } if ( gcmd_line.display_info == 110 ) { printf("\n\nfinal domain representation:"); printf("\n\nall actions:"); for ( a = gactions; a; a = a->next ) { print_Action( a ); } printf("\n\ninitial_state:"); for ( i = 0; i < ginitial_state.num_F; i++ ) { printf("\n"); print_ft_name( ginitial_state.F[i] ); } printf("\n\ngoal_state:"); for ( i = 0; i < ggoal_state.num_F; i++ ) { printf("\n"); print_ft_name( ggoal_state.F[i] ); } } }
void perform_reachability_analysis( void ) { int size, i, j, adr; Bool fixpoint; ActionTemplate *t1, *t2, *t3; Operator *o; Action *tmp, *a; for ( i = 0; i < gnum_predicates; i++ ) { size = 1; for ( j = 0; j < garity[i]; j++ ) { size *= gnum_constants; } lpos[i] = ( int_pointer ) calloc( size, sizeof( int ) ); lneg[i] = ( int_pointer ) calloc( size, sizeof( int ) ); luse[i] = ( int_pointer ) calloc( size, sizeof( int ) ); lindex[i] = ( int_pointer ) calloc( size, sizeof( int ) ); for ( j = 0; j < size; j++ ) { lpos[i][j] = 0; lneg[i][j] = 0; luse[i][j] = 0; lindex[i][j] = -1; } } /* mark initial facts as possibly positive */ for ( i = 0; i < gnum_initial; i++ ) { lp = ginitial[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = ginitial[i].args[j]; } lpos[lp][fact_adress()] = 1; } /* compute fixpoint */ fixpoint = FALSE; while ( !fixpoint ) { fixpoint = TRUE; t1 = gtemplates; while ( t1 ) { o = goperators[t1->op]; for ( i = 0; i < o->num_preconds; i++ ) { lp = o->preconds[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = GET_CONSTANT( o->preconds[i].args[j], t1 ); } if ( !lpos[lp][fact_adress()] ) { break; } } if ( i < o->num_preconds ) { break; } for ( i = 0; i < o->num_adds; i++ ) { lp = o->adds[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = GET_CONSTANT( o->adds[i].args[j], t1 ); } adr = fact_adress(); if ( !lpos[lp][adr] ) { /* new relevant fact! (added non initial) */ lpos[lp][adr] = 1; lneg[lp][adr] = 1; luse[lp][adr] = 1; if ( gnum_relevant_facts == MAX_RELEVANT_FACTS ) { printf("\ntoo many relevant facts! increase MAX_RELEVANT_FACTS (currently %d)\n\n", MAX_RELEVANT_FACTS); exit( 1 ); } grelevant_facts[gnum_relevant_facts].predicate = lp; for ( j = 0; j < garity[lp]; j++ ) { grelevant_facts[gnum_relevant_facts].args[j] = largs[j]; } lindex[lp][adr] = gnum_relevant_facts; gnum_relevant_facts++; fixpoint = FALSE; } } tmp = new_Action( t1->op ); for ( i = 0; i < o->num_vars; i++ ) { tmp->inst_table[i] = t1->inst_table[i]; } tmp->next = gactions; gactions = tmp; gnum_actions++; t2 = t1; t1 = t1->next; free_single_ActionTemplate( t2 ); } gtemplates = t1; t3 = t1; if ( t1 ) t1 = t1->next; while ( t1 ) { o = goperators[t1->op]; for ( i = 0; i < o->num_preconds; i++ ) { lp = o->preconds[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = GET_CONSTANT( o->preconds[i].args[j], t1 ); } if ( !lpos[lp][fact_adress()] ) { break; } } if ( i == o->num_preconds ) { for ( i = 0; i < o->num_adds; i++ ) { lp = o->adds[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = GET_CONSTANT( o->adds[i].args[j], t1 ); } adr = fact_adress(); if ( !lpos[lp][adr] ) { /* new relevant fact! (added non initial) */ lpos[lp][adr] = 1; lneg[lp][adr] = 1; luse[lp][adr] = 1; if ( gnum_relevant_facts == MAX_RELEVANT_FACTS ) { printf("\ntoo many relevant facts! increase MAX_RELEVANT_FACTS (currently %d)\n\n", MAX_RELEVANT_FACTS); exit( 1 ); } grelevant_facts[gnum_relevant_facts].predicate = lp; for ( j = 0; j < garity[lp]; j++ ) { grelevant_facts[gnum_relevant_facts].args[j] = largs[j]; } lindex[lp][adr] = gnum_relevant_facts; gnum_relevant_facts++; fixpoint = FALSE; } } tmp = new_Action( t1->op ); for ( i = 0; i < o->num_vars; i++ ) { tmp->inst_table[i] = t1->inst_table[i]; } tmp->next = gactions; gactions = tmp; gnum_actions++; t3->next = t1->next; t2 = t1; t1 = t1->next; free_single_ActionTemplate( t2 ); } else { t3 = t3->next; t1 = t1->next; } } } gnum_pp_facts = gnum_initial + gnum_relevant_facts; if ( gcmd_line.display_info == 109 ) { printf("\nreachability analysys came up with:"); printf("\n\npossibly positive facts:"); for ( i = 0; i < gnum_initial; i++ ) { printf("\n"); print_Fact( &(ginitial[i]) ); } for ( i = 0; i < gnum_relevant_facts; i++ ) { printf("\n"); print_Fact( &(grelevant_facts[i]) ); } printf("\n\nthis yields these %d action templates:", gnum_actions); for ( i = 0; i < gnum_operators; i++ ) { printf("\n\noperator %s:", goperators[i]->name); for ( a = gactions; a; a = a->next ) { if ( a->op != i ) { continue; } printf("\ntemplate: "); for ( j = 0; j < goperators[i]->num_vars; j++ ) { printf("%s", gconstants[a->inst_table[j]]); if ( j < goperators[i]->num_vars-1 ) { printf(" "); } } } } printf("\n\n"); } /* if a goal is not possibly positive, the problem * is unsolvable. */ for ( i = 0; i < gnum_goal; i++ ) { lp = ggoal[i].predicate; for ( j = 0; j < garity[lp]; j++ ) { largs[j] = ggoal[i].args[j]; } if ( !lpos[lp][fact_adress()] ) { printf("\nproblem is unsolvable! goals can't be reached\n\n"); output_planner_info(); } } }
void perform_reachability_analysis( void ) { int size, i, j, k, adr, num, pargtype; Bool fixpoint; Facts *f; NormOperator *no; EasyTemplate *t1, *t2; NormEffect *ne; Action *tmp, *a; Bool *had_hard_template; PseudoAction *pa; PseudoActionEffect *pae; gactions = NULL; gnum_actions = 0; for ( i = 0; i < gnum_predicates; i++ ) { size = 1; for ( j = 0; j < garity[i]; j++ ) { pargtype = gpredicates_args_type[i][j]; size *= gtype_size[pargtype]; } lpos[i] = ( int_pointer ) calloc( size, sizeof( int ) ); lneg[i] = ( int_pointer ) calloc( size, sizeof( int ) ); luse[i] = ( int_pointer ) calloc( size, sizeof( int ) ); lindex[i] = ( int_pointer ) calloc( size, sizeof( int ) ); for ( j = 0; j < size; j++ ) { lpos[i][j] = 0; lneg[i][j] = 1;/* all facts but initials are poss. negative */ luse[i][j] = 0; lindex[i][j] = -1; } } had_hard_template = ( Bool * ) calloc( gnum_hard_templates, sizeof( Bool ) ); for ( i = 0; i < gnum_hard_templates; i++ ) { had_hard_template[i] = FALSE; } /* mark initial facts as possibly positive, not poss. negative */ for ( i = 0; i < gnum_predicates; i++ ) { lp = i; for ( j = 0; j < gnum_initial_predicate[i]; j++ ) { for ( k = 0; k < garity[i]; k++ ) { largs[k] = ginitial_predicate[i][j].args[k]; } adr = fact_adress(); lpos[lp][adr] = 1; lneg[lp][adr] = 0; } } /* compute fixpoint */ fixpoint = FALSE; while ( !fixpoint ) { fixpoint = TRUE; /* assign next layer of easy templates to possibly positive fixpoint */ t1 = geasy_templates; while ( t1 ) { no = t1->op; 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] : t1->inst_table[DECODE_VAR( no->preconds[i].args[j] )]; } if ( !lpos[lp][fact_adress()] ) { break; } } if ( i < no->num_preconds ) { t1 = t1->next; continue; } num = 0; for ( ne = no->effects; ne; ne = ne->next ) { num++; /* currently, simply ignore effect conditions and assume * they will all be made true eventually. */ 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] : t1->inst_table[DECODE_VAR( ne->adds[i].args[j] )]; } adr = fact_adress(); if ( !lpos[lp][adr] ) { /* new relevant fact! (added non initial) */ lpos[lp][adr] = 1; lneg[lp][adr] = 1; luse[lp][adr] = 1; if ( gnum_relevant_facts == MAX_RELEVANT_FACTS ) { printf("\ntoo many relevant facts! increase MAX_RELEVANT_FACTS (currently %d)\n\n", MAX_RELEVANT_FACTS); exit( 1 ); } grelevant_facts[gnum_relevant_facts].predicate = lp; for ( j = 0; j < garity[lp]; j++ ) { grelevant_facts[gnum_relevant_facts].args[j] = largs[j]; } lindex[lp][adr] = gnum_relevant_facts; gnum_relevant_facts++; fixpoint = FALSE; } } } tmp = new_Action(); tmp->norm_operator = no; for ( i = 0; i < no->num_vars; i++ ) { tmp->inst_table[i] = t1->inst_table[i]; } tmp->name = no->operator->name; tmp->num_name_vars = no->operator->number_of_real_params; make_name_inst_table_from_NormOperator( tmp, no, t1 ); tmp->next = gactions; tmp->num_effects = num; gactions = tmp; gnum_actions++; t2 = t1->next; if ( t1->next ) { t1->next->prev = t1->prev; } if ( t1->prev ) { t1->prev->next = t1->next; } else { geasy_templates = t1->next; } free_single_EasyTemplate( t1 ); t1 = t2; } /* now assign all hard templates that have not been transformed * to actions yet. */ for ( i = 0; i < gnum_hard_templates; i++ ) { if ( had_hard_template[i] ) { continue; } pa = ghard_templates[i]; for ( j = 0; j < pa->num_preconds; j++ ) { lp = pa->preconds[j].predicate; for ( k = 0; k < garity[lp]; k++ ) { largs[k] = pa->preconds[j].args[k]; } if ( !lpos[lp][fact_adress()] ) { break; } } if ( j < pa->num_preconds ) { continue; } for ( pae = pa->effects; pae; pae = pae->next ) { /* currently, simply ignore effect conditions and assume * they will all be made true eventually. */ for ( j = 0; j < pae->num_adds; j++ ) { lp = pae->adds[j].predicate; for ( k = 0; k < garity[lp]; k++ ) { largs[k] = pae->adds[j].args[k]; } adr = fact_adress(); if ( !lpos[lp][adr] ) { /* new relevant fact! (added non initial) */ lpos[lp][adr] = 1; lneg[lp][adr] = 1; luse[lp][adr] = 1; if ( gnum_relevant_facts == MAX_RELEVANT_FACTS ) { printf("\ntoo many relevant facts! increase MAX_RELEVANT_FACTS (currently %d)\n\n", MAX_RELEVANT_FACTS); exit( 1 ); } grelevant_facts[gnum_relevant_facts].predicate = lp; for ( k = 0; k < garity[lp]; k++ ) { grelevant_facts[gnum_relevant_facts].args[k] = largs[k]; } lindex[lp][adr] = gnum_relevant_facts; gnum_relevant_facts++; fixpoint = FALSE; } } } tmp = new_Action(); tmp->pseudo_action = pa; for ( j = 0; j < pa->operator->num_vars; j++ ) { tmp->inst_table[j] = pa->inst_table[j]; } tmp->name = pa->operator->name; tmp->num_name_vars = pa->operator->number_of_real_params; make_name_inst_table_from_PseudoAction( tmp, pa ); tmp->next = gactions; tmp->num_effects = pa->num_effects; gactions = tmp; gnum_actions++; had_hard_template[i] = TRUE; } } free( had_hard_template ); gnum_pp_facts = gnum_initial + gnum_relevant_facts; if ( gcmd_line.display_info == 118 ) { printf("\nreachability analysys came up with:"); printf("\n\npossibly positive facts:"); for ( f = ginitial; f; f = f->next ) { printf("\n"); print_Fact( f->fact ); } for ( i = 0; i < gnum_relevant_facts; i++ ) { printf("\n"); print_Fact( &(grelevant_facts[i]) ); } printf("\n\nthis yields these %d action templates:", gnum_actions); for ( i = 0; i < gnum_operators; i++ ) { printf("\n\noperator %s:", goperators[i]->name); for ( a = gactions; a; a = a->next ) { if ( ( a->norm_operator && a->norm_operator->operator != goperators[i] ) || ( a->pseudo_action && a->pseudo_action->operator != goperators[i] ) ) { continue; } printf("\ntemplate: "); for ( j = 0; j < goperators[i]->number_of_real_params; j++ ) { printf("%s", gconstants[a->name_inst_table[j]]); if ( j < goperators[i]->num_vars-1 ) { printf(" "); } } } } printf("\n\n"); } }