This document describes the MP file format for storing merged prefixes of Petri nets. The file is textual, and contains the following information. - the total number of mp-conditions, mp-events, places and transitions (one line). - for each mp-condition (from first to last, separate line for each mp-condition): -- the number of the original place -- the occurrence-depth -- the initial marking - for each mp-event (from first to last, separate line for each mp-condition): -- the number of the original transition -- the cut-off status (0 - no, 1 - yes) -- the size of the preset -- the size of the postset -- the list of numbers of mp-conditions in the preset -- the list of numbers of mp-conditions in the postset - the maximal string length + 1 for place/transition names (on a separate line) (useful for memory allocation in the parser) - for each place (from first to last, separate line for each place): -- the name of the place - for each transition (from first to last, separate line for each place): -- the name of the transition The following C++ code implements an MP parser, and might hopefully be useful as a reference: void readMP(const char* filename){ unsigned num_mpcond,num_mpev,num_net_pl,num_net_tr; unsigned orig_node_num,odepth,init_marking; unsigned cutoff,preset_size,postset_size,mpcond_num; unsigned len; char* name; size_t name_len; unsigned line_no=1, read_fields; int read_chars; FILE* f=fopen(filename,"rb"); if(!f){ Error(cannot_open_file_inp(filename)); return; } read_fields=fscanf(f," %u%*[ \t]%u%*[ \t]%u%*[ \t]%u%*[ \t]", &num_mpcond, &num_mpev, &num_net_pl, &num_net_tr ); if(read_fields==EOF || read_fields<4) goto fail; fscanf(f,"\n%n",&read_chars); if(read_chars<1) goto fail; line_no++; this->arr_pl.destroy_all(); this->arr_tr.destroy_all(); for(unsigned i=0;inum_net_pl || odepth<1 || (init_marking && odepth!=1) ) goto fail; fscanf(f,"\n%n",&read_chars); if(read_chars<1) goto fail; line_no++; CONDITION* mpcond=new CONDITION(i+1,odepth,(typename ORIGINAL_NET::PLACE*)orig_node_num,init_marking); this->arr_pl.add(mpcond); } for(unsigned i=0;inum_net_tr || cutoff>1 || preset_size<1 ) goto fail; EVENT* mpev=new EVENT(i+1,0); mpev->orig_node=(typename ORIGINAL_NET::TRANSITION*)orig_node_num; if(cutoff){ mpev->cutoff_corr.assign_unspecified(); } this->arr_tr.add(mpev); for(unsigned j=0;j=num_mpcond) goto fail; mpev->preset.add(this->arr_pl[mpcond_num]); this->arr_pl[mpcond_num]->postset.add(mpev); } for(unsigned j=0;j=num_mpcond) goto fail; mpev->postset.add(this->arr_pl[mpcond_num]); this->arr_pl[mpcond_num]->preset.add(mpev); } fscanf(f,"\n%n",&read_chars); if(read_chars<1) goto fail; line_no++; } read_fields=fscanf(f," %u%*[ \t]",&len); if(read_fields==EOF || read_fields<1) goto fail; fscanf(f,"\n%n",&read_chars); if(read_chars<1) goto fail; line_no++; name=new char[len+2]; if(!this->net){ this->net=new ORIGINAL_NET(); } this->net->arr_pl.destroy_all(); this->net->arr_tr.destroy_all(); for(unsigned i=0;inet->arr_pl.add(pl); } for(unsigned i=0;inet->arr_tr.add(tr); } // fix the orig_node field of all mp-conditions and mp-events for(unsigned i=0;iarr_pl.numit;i++){ CONDITION* mpcond=this->arr_pl[i]; mpcond->orig_node=this->net->arr_pl[(unsigned)mpcond->orig_node-1]; } for(unsigned i=0;iarr_tr.numit;i++){ EVENT* mpev=this->arr_tr[i]; mpev->orig_node=this->net->arr_tr[(unsigned)mpev->orig_node-1]; } // calculate the initial marking for(unsigned i=0;iarr_pl.numit;i++){ CONDITION* mpcond=this->arr_pl[i]; typename ORIGINAL_NET::PLACE* pl=mpcond->orig_node; for(unsigned j=0;jinit_marking;++j){ pl->init_marking.add(new PNToken(PNToken::t_dot)); } } for(unsigned i=0;iarr_tr.numit;i++){ EVENT* mpev=this->arr_tr[i]; typename ORIGINAL_NET::TRANSITION* tr=mpev->orig_node; if(tr->preset.numit || tr->postset.numit) continue; for(unsigned j=0;jpreset.numit;j++){ typename ORIGINAL_NET::PLACE* pl=mpev->preset[j]->orig_node; tr->preset.add(pl); pl->postset.add(tr); } for(unsigned j=0;jpostset.numit;j++){ typename ORIGINAL_NET::PLACE* pl=mpev->postset[j]->orig_node; tr->postset.add(pl); pl->preset.add(tr); } } // sort places' presets and postsets for(unsigned i=0;inet->arr_pl.numit;i++){ this->net->arr_pl[i]->template sort_preset>(); this->net->arr_pl[i]->template sort_postset>(); } // sort transitions' presets and postsets for(unsigned i=0;inet->arr_tr.numit;i++){ this->net->arr_tr[i]->template sort_preset>(); this->net->arr_tr[i]->template sort_postset>(); } delete[] name; goto exit; fail: Error(syntax_error(filename,line_no)); exit: fclose(f); }