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 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"); } }