lts_file_t aut_file_create(const char* name,lts_type_t ltstype,int segments,lts_file_t settings){ if (lts_type_get_state_length(ltstype)) { //Abort("cannot write state to AUT file"); Print(infoShort,"Ignoring state vector"); } if (lts_type_get_state_label_count(ltstype)) { Abort("cannot write state labels to AUT file"); } if (lts_type_get_edge_label_count(ltstype)!=1) { Abort("AUT files contain precisely one edge label"); } if (segments!=1) Abort("AUT files contain precisely 1 segment"); lts_file_t file=lts_file_bare(name,ltstype,1,settings,sizeof(struct lts_file_s)); file->f=fopen(name,"w"); if(file->f==NULL){ AbortCall("while opening %s",name); } file->root--; // set to -1 denoting undefined. file->states++; // set to 1, denoting one state. file->type_no=lts_type_get_edge_label_typeno(ltstype,0); lts_file_set_write_init(file,aut_write_init); lts_file_set_write_state(file,write_state); lts_file_set_write_edge(file,aut_write_edge); lts_file_set_close(file,aut_write_close); fprintf(file->f,"des(?,?,?) \n"); lts_file_complete(file); return file; }
void lts_type_serialize(lts_type_t t,stream_t ds){ DSwriteS(ds,"lts signature 1.1"); uint32_t N=lts_type_get_state_length(t); Warning(debug,"state length is %d",N); DSwriteU32(ds,N); for(uint32_t i=0;i<N;i++){ char*x=lts_type_get_state_name(t,i); if (x) DSwriteS(ds,x); else DSwriteS(ds,""); DSwriteU32(ds,lts_type_get_state_typeno(t,i)); } N=lts_type_get_state_label_count(t); Warning(debug,"%d state labels",N); DSwriteU32(ds,N); for(uint32_t i=0;i<N;i++){ char*x=lts_type_get_state_label_name(t,i); if (x) DSwriteS(ds,x); else DSwriteS(ds,""); DSwriteU32(ds,lts_type_get_state_label_typeno(t,i)); } N=lts_type_get_edge_label_count(t); Warning(debug,"%d edge labels",N); DSwriteU32(ds,N); for(uint32_t i=0;i<N;i++){ char*x=lts_type_get_edge_label_name(t,i); if (x) DSwriteS(ds,x); else DSwriteS(ds,""); DSwriteU32(ds,lts_type_get_edge_label_typeno(t,i)); Warning(debug,"edge label %d is %s : %s",i,x,lts_type_get_edge_label_type(t,i)); } N=lts_type_get_type_count(t); Warning(debug,"%d types",N); DSwriteU32(ds,N); for(uint32_t i=0;i<N;i++){ DSwriteS(ds,lts_type_get_type(t,i)); DSwriteS(ds,(char*)data_format_string(t,i)); } }
static void init_model(char *file) { Warning(info, "opening %s", file); model = GBcreateBase(); GBsetChunkMap (model, HREgreyboxTableFactory()); HREbarrier(HREglobal()); GBloadFile(model, file, &model); HREbarrier(HREglobal()); if (HREme(HREglobal())==0 && !PINS_USE_GUARDS && no_soundness_check) { Abort("Option --no-soundness-check is incompatible with --pins-guards=false"); } if (HREme(HREglobal())==0 && log_active(infoLong) && !no_matrix) { fprintf(stderr, "Dependency Matrix:\n"); GBprintDependencyMatrixCombined(stderr, model); } ltstype = GBgetLTStype(model); N = lts_type_get_state_length(ltstype); eLbls = lts_type_get_edge_label_count(ltstype); sLbls = GBgetStateLabelInfo(model) == NULL ? 0 : dm_nrows(GBgetStateLabelInfo(model)); nGrps = dm_nrows(GBgetDMInfo(model)); max_sat_levels = (N / sat_granularity) + 1; if (PINS_USE_GUARDS) { nGuards = GBgetStateLabelGroupInfo(model, GB_SL_GUARDS)->count; if (HREme(HREglobal())==0) { Warning(info, "state vector length is %d; there are %d groups and %d guards", N, nGrps, nGuards); } } else { if (HREme(HREglobal())==0) { Warning(info, "state vector length is %d; there are %d groups", N, nGrps); } } int id=GBgetMatrixID(model,"inhibit"); if (id>=0){ inhibit_matrix=GBgetMatrix(model,id); if (HREme(HREglobal())==0) { Warning(infoLong,"inhibit matrix is:"); if (log_active(infoLong)) dm_print(stderr,inhibit_matrix); } } id = GBgetMatrixID(model,LTSMIN_EDGE_TYPE_ACTION_CLASS); if (id>=0){ class_matrix=GBgetMatrix(model,id); if (HREme(HREglobal())==0) { Warning(infoLong,"inhibit class matrix is:"); if (log_active(infoLong)) dm_print(stderr,class_matrix); } } HREbarrier(HREglobal()); }
/* * Sanitizes and caches all the variable names of an lts_type_t. Should only be * called once. */ void sanitize_variables(lts_type_t ltstype) { int n_vars = lts_type_get_state_length(ltstype); sanitized_variables = (char**)RTmalloc(n_vars*sizeof(char*)); for (int i=0;i<n_vars;i++) { char *name = lts_type_get_state_name(ltstype,i); int len = strlen(name)+2; sanitized_variables[i] = (char*)RTmalloc(len); sanitize_ID(name,len,sanitized_variables[i]); Debug("Sanitizing variable %s to %s", name, sanitized_variables[i]); } }
trc_env_t * trc_create (model_t model, trc_get_state_f get, void *arg) { trc_env_t *trace = RTmalloc(sizeof(trc_env_t)); lts_type_t ltstype = GBgetLTStype (model); trace->N = lts_type_get_state_length (ltstype); trace->state_labels = lts_type_get_state_label_count (ltstype); trace->get_state = get; trace->get_state_arg = arg; trace->model = model; return trace; }
static void default_push(lts_file_t src,lts_file_t dst){ if (SYSTEM(src)->ctx != SYSTEM(dst)->ctx) Abort("cannot copy between different contexts"); int me=HREme(SYSTEM(src)->ctx); lts_type_t ltstype=lts_file_get_type(src); int N1=lts_type_get_state_length(ltstype); int N2=lts_type_get_state_label_count(ltstype); int K=lts_type_get_edge_label_count(ltstype); int do_state; if (N1){ Print(infoLong,"vector length is %d",N1); do_state=1; } else { do_state=N2?1:0; N1=1; } int src_seg; uint32_t src_state[N1]; int dst_seg; uint32_t dst_state[N1]; uint32_t edge_labels[K]; if (me==0) { Print(infoLong,"copying initial states"); int count=0; while(lts_read_init(src,&src_seg,src_state)){ count++; lts_write_init(dst,src_seg,src_state); } Print(infoLong,"%d initial state(s)",count); } for(int i=0;i<lts_file_owned_count(src);i++){ src_seg=lts_file_owned(src,i); dst_seg=lts_file_owned(src,i); if (do_state) { Print(infoLong,"copying states of segment %d",src_seg); uint32_t state_labels[N2]; while(lts_read_state(src,&src_seg,src_state,state_labels)){ lts_write_state(dst,src_seg,src_state,state_labels); } } Print(infoLong,"copying edges of segment %d",src_seg); while(lts_read_edge(src,&src_seg,src_state,&dst_seg,dst_state,edge_labels)){ lts_write_edge(dst,src_seg,src_state,dst_seg,dst_state,edge_labels); } } Print(infoLong,"done"); }
void mark_predicate (model_t m, ltsmin_expr_t e, int *dep, ltsmin_parse_env_t env) { if (!e) return; switch(e->node_type) { case BINARY_OP: mark_predicate(m,e->arg1,dep,env); mark_predicate(m,e->arg2,dep,env); break; case UNARY_OP: mark_predicate(m,e->arg1,dep,env); break; default: switch(e->token) { case PRED_TRUE: case PRED_FALSE: case PRED_NUM: case PRED_VAR: case PRED_CHUNK: break; case PRED_EQ: mark_predicate(m,e->arg1, dep,env); mark_predicate(m,e->arg2, dep,env); break; case PRED_SVAR: { lts_type_t ltstype = GBgetLTStype(m); int N = lts_type_get_state_length (ltstype); if (e->idx < N) { // state variable dep[e->idx] = 1; } else { // state label HREassert (e->idx < N + lts_type_get_state_label_count(ltstype)); matrix_t *sl = GBgetStateLabelInfo (m); HREassert (N == dm_ncols(sl)); for (int i = 0; i < N; i++) { if (dm_is_set(sl, e->idx - N, i)) dep[i] = 1; } } break; } default: LTSminLogExpr (error, "Unhandled predicate expression: ", e, env); HREabort (LTSMIN_EXIT_FAILURE); } break; } }
void lts_write(char *name,lts_t lts,string_set_t filter,int segments){ int format=lts_guess_format(name); lts_type_t ltstype=lts->ltstype; switch(format){ case LTS_IMCA: lts_write_imca(name,lts); break; case LTS_TRA: lts_write_tra(name,lts); break; case LTS_PG: lts_write_pg(name,lts); break; case LTS_DIR: if (lts_type_get_state_length(ltstype)==0 && lts_type_get_state_label_count(ltstype)==0 && lts_type_get_edge_label_count(ltstype)==1 ){ archive_t archive=arch_dir_create(name,65536,DELETE_ALL); lts_write_dir(archive,NULL,lts,segments); arch_close(&archive); break; } else // fall through default: { lts_file_t src=lts_reader(lts,segments,NULL); lts_file_t dst; if (filter==NULL){ dst=lts_file_create(name,lts->ltstype,segments,src); } else { dst=lts_file_create_filter(name,lts->ltstype,filter,segments,src); } int T=lts_type_get_type_count(lts->ltstype); for(int i=0;i<T;i++){ if (lts->values[i]) lts_file_set_table(dst,i,lts->values[i]); } lts_file_copy(src,dst); lts_file_close(src); lts_file_close(dst); break; } } }
static void pvar_slice(lts_type_t ltstype){ if (pvars==NULL) { pv_count=0; return; } int N=lts_type_get_state_length(ltstype); char *tmp=pvars; pv_count=0; while(tmp){ pv_count++; int i=0; while(tmp[i]&&tmp[i]!=' ') { i++; } if (tmp[i]) { tmp[i]=0; tmp=&tmp[i+1]; } else { tmp=NULL; } } pvar_name=RTmalloc(pv_count*sizeof(char*)); pvar_idx=RTmalloc(pv_count*sizeof(int)); tmp=pvars; Warning(info,"state length is %d",N); for(int j=0;j<N;j++) Warning(info,"state %d is %s",j, lts_type_get_state_name(ltstype,j)); for(int i=0;i<pv_count;i++){ pvar_name[i]=tmp; pvar_idx[i]=-1; for(int j=0;j<N;j++){ if (strcmp(tmp,lts_type_get_state_name(ltstype,j))!=0) continue; pvar_idx[i]=j; break; } tmp=tmp+strlen(tmp)+1; } for(int i=0;i<pv_count;i++){ Warning(info,"variable %d is %s, idx %d",i,pvar_name[i],pvar_idx[i]); } }
/* avoid rebuilding the whole tree, by storing extra info for the chunks */ static int ltsmin_expr_lookup_values(ltsmin_expr_t ltl,ltsmin_parse_env_t env,model_t model) { //return type(SVAR) idx or -1 if (!ltl) return -1; int left, right; switch(ltl->node_type) { case BINARY_OP: left = ltsmin_expr_lookup_values(ltl->arg1, env, model); right = ltsmin_expr_lookup_values(ltl->arg2, env, model); switch(ltl->token) { case PRED_EQ: if (left >= 0) { // type(SVAR) ltsmin_expr_lookup_value (ltl, ltl->arg2, left, env, model); } else if (right >= 0) { // type(SVAR) ltsmin_expr_lookup_value (ltl, ltl->arg1, right, env, model); } } return -1; case UNARY_OP: ltsmin_expr_lookup_values(ltl->arg1, env, model); return -1; default: switch(ltl->token) { case SVAR: { lts_type_t ltstype = GBgetLTStype (model); int N = lts_type_get_state_length (ltstype); if (ltl->idx < N) return lts_type_get_state_typeno (ltstype, ltl->idx); else return lts_type_get_state_label_typeno (ltstype, ltl->idx - N); } default: return -1; } } }
int main(int argc, char *argv[]){ char* files[2]; RTinitPopt(&argc,&argv,options,2,2,files,NULL,"<input> <output>","Stream based file format conversion\n\nOptions"); model_t model=GBcreateBase(); GBsetChunkMethods(model,new_string_index,NULL, (int2chunk_t)SIgetC,(chunk2int_t)SIputC,(get_count_t)SIgetCount); Warning(info,"copying %s to %s",files[0],files[1]); lts_input_t input=lts_input_open(files[0],model,0,1); if (segments==0) { segments=lts_input_segments(input); } char*input_mode=lts_input_mode(input); if (input_mode) { Warning(debug,"input was written in %s mode",input_mode); if (!strcmp(input_mode,"viv") || !strcmp(input_mode,"vsi")){ if (segments!=1) Fatal(1,error,"cannot write more than one segment"); lts_type_t ltstype=GBgetLTStype(model); int N=lts_type_get_state_length(ltstype); Warning(info,"state length is %d",N); treedbs_t dbs=TreeDBScreate(N); // we should convert the GB not and not hack the ltstype. lts_type_set_state_label_count(ltstype,0); lts_output_t output=lts_output_open(files[1],model,segments,0,1,"-ii",NULL); lts_output_set_root_idx(output,0,0); lts_enum_cb_t ecb=lts_output_begin(output,segments,segments,segments); // We should have two passes (if the file is not in BFS order then the state numbers are wrong!) // pass 1: states with labels. // pass 2: edges with labels. // Currently the viv reader illegally does two passes. N=lts_input_segments(input); uint32_t begin[N]; lts_count_t *count=lts_input_count(input); begin[0]=0; for(int i=1;i<N;i++) begin[i]=begin[i-1]+count->state[i-1]; struct dbs_ctx ctx; ctx.dbs=dbs; ctx.begin=begin; lts_input_enum(input,N,N,N,lts_enum_convert(ecb,&ctx,dbs_fold,dbs_unfold,1)); lts_output_end(output,ecb); lts_output_close(&output); uint32_t* root=lts_input_root(input); uint32_t root_no=TreeFold(dbs,(int*)root); if (root_no!=0){ Fatal(1,error,"root is %u rather than 0",root_no); } } else { Warning(info,"input mode %s not supported",input_mode); } } else if (segments==lts_input_segments(input)){ Warning(debug,"undefined input mode"); lts_output_t output=lts_output_open(files[1],model,segments,0,1,"-ii",NULL); lts_output_set_root_idx(output,lts_root_segment(input),lts_root_offset(input)); lts_enum_cb_t ecb=lts_output_begin(output,segments,segments,segments); lts_input_enum(input,segments,segments,segments,ecb); lts_output_end(output,ecb); lts_output_close(&output); } else { Warning(debug,"undefined input mode with segment conversion"); int N=lts_input_segments(input); uint64_t offset[N+1]; lts_count_t *count=lts_input_count(input); offset[0]=segments; offset[1]=0; for(int i=1;i<N;i++){ offset[i+1]=offset[i]+count->state[i-1]; } uint64_t root=offset[lts_root_segment(input)+1]+lts_root_offset(input); lts_output_t output=lts_output_open(files[1],model,segments,0,1,"-ii",NULL); lts_output_set_root_idx(output,root%segments,root/segments); lts_enum_cb_t ecb=lts_output_begin(output,segments,segments,segments); lts_input_enum(input,N,N,N,lts_enum_convert(ecb,offset,convert_div_mod,copy_seg_ofs,1)); lts_output_end(output,ecb); lts_output_close(&output); } lts_input_close(&input); return 0; }
int main(int argc, char *argv[]){ char* files[2]; HREinitBegin(argv[0]); HREaddOptions(options,"Tool for transforming labeled transition systems\n\nOptions"); lts_lib_setup(); HREinitStart(&argc,&argv,1,2,files,"<input> [<output>]"); int me=HREme(HREglobal()); int peers=HREpeers(HREglobal()); if (peers>1) Abort("parallelizing this tool is future work");(void)me; string_set_t label_set=NULL; if (label_filter!=NULL){ label_set=SSMcreateSWPset(label_filter); } switch(task){ case Undefined: Abort("task unspecified"); case LTScopy: if (files[1]==NULL) Abort("second argument required for copy."); Print(infoShort,"streaming copy from %s to %s",files[0],files[1]); lts_file_t in=lts_file_open(files[0]); lts_type_t ltstype=lts_file_get_type(in); rd_seg=lts_file_get_segments(in); if (wr_seg==0) { wr_seg=rd_seg; } else { Abort("on-the-fly changing the number of segments is future work"); } lts_file_t out; if (label_set==NULL){ out=lts_file_create(files[1],ltstype,wr_seg,in); } else { out=lts_file_create_filter(files[1],ltstype,label_set,wr_seg,in); } int N=lts_type_get_type_count(ltstype); for(int i=0;i<N;i++){ char*name=lts_type_get_type(ltstype,i); switch(lts_type_get_format(ltstype,i)){ case LTStypeDirect: case LTStypeRange: Debug("integer type %s does not use tables",name); break; case LTStypeChunk: case LTStypeEnum: Debug("creating table for type %s",name); value_table_t tmp=chunk_table_create(NULL,name); Debug("set in %s",name); lts_file_set_table(in,i,tmp); Debug("set out %s",name); lts_file_set_table(out,i,tmp); break; } } lts_file_copy(in,out); lts_file_close(out); lts_file_close(in); break; case LTSrdwr: if (files[1]==NULL) Abort("second argument required for rdwr."); Print(infoShort,"loading from %s",files[0]); lts_t lts=lts_create(); lts_read(files[0],lts); if (encode) { Print(infoShort,"single edge label encoding"); lts=lts_encode_edge(lts); } if (bfs_reorder) { Print(infoShort,"reindexing LTS in BFS order"); lts_bfs_reorder(lts); } Print(infoShort,"storing in %s",files[1]); if(wr_seg==0) wr_seg=1; lts_write(files[1],lts,label_set,wr_seg); break; case LTSindex:{ if (peers>1) Abort("parallelizing this tool is future work"); if (files[1]==NULL) Abort("second argument required for index."); Print(infoShort,"opening %s",files[0]); lts_file_t in=lts_file_open(files[0]); lts_type_t ltstype=lts_file_get_type(in); int segments=lts_file_get_segments(in); lts_file_t settings=lts_get_template(in); if (lts_file_get_edge_owner(settings)!=SourceOwned) Abort("bad edge owner"); lts_file_set_dest_mode(settings,Index); lts_file_set_init_mode(settings,Index); Print(infoShort,"creating %s",files[1]); lts_file_t out=lts_file_create(files[1],ltstype,segments,settings); int N=lts_type_get_type_count(ltstype); for(int i=0;i<N;i++){ char*name=lts_type_get_type(ltstype,i); switch(lts_type_get_format(ltstype,i)){ case LTStypeDirect: case LTStypeRange: Debug("integer type %s does not use tables",name); break; case LTStypeChunk: case LTStypeEnum: Debug("creating table for type %s",name); value_table_t tmp=chunk_table_create(NULL,name); Debug("set in %s",name); lts_file_set_table(in,i,tmp); Debug("set out %s",name); lts_file_set_table(out,i,tmp); break; } } treedbs_t db[segments]; int SV=lts_type_get_state_length(ltstype); int SL=lts_type_get_state_label_count(ltstype); int K=lts_type_get_edge_label_count(ltstype); for(int i=0;i<segments;i++){ Print(info,"loading and copying states of segment %d",i); uint32_t state[SV]; uint32_t label[SL]; db[i]=TreeDBScreate(SV); int idx=0; while(lts_read_state(in,&i,state,label)){ int tmp=TreeFold(db[i],(int*)state); if (idx!=tmp){ Abort("unexpected index %u != %u",tmp,idx); } idx++; lts_write_state(out,i,(int*)state,label); } } Print(info,"converting initial states"); { uint32_t seg; uint32_t state[SV]; while(lts_read_init(in,(int*)&seg,state)){ int idx=TreeFold(db[seg],(int*)state); lts_write_init(out,seg,&idx); } } for(int i=0;i<segments;i++){ Print(info,"converting edges of segment %d",i); uint32_t src_state[1]; uint32_t dst_seg; uint32_t dst_state[SV]; uint32_t label[K]; while(lts_read_edge(in,&i,src_state,(int*)&dst_seg,dst_state,label)){ int idx=TreeFold(db[dst_seg],(int*)dst_state); lts_write_edge(out,i,src_state,dst_seg,&idx,label); } } lts_file_close(out); lts_file_close(in); } } Print(infoShort,"done"); HREexit(LTSMIN_EXIT_SUCCESS); }
int main(int argc, char *argv[]){ char *files[2]; RTinitPopt(&argc,&argv,options,1,2,files,NULL,"<model> [<lts>]", "Perform an enumerative reachability analysis of <model>\n" "Run the TorX remote procedure call protocol on <model> (--torx).\n\n" "Options"); if (files[1]) { Warning(info,"Writing output to %s",files[1]); write_lts=1; } else { Warning(info,"No output, just counting the number of states"); write_lts=0; } if (application==RunTorX && write_lts) Fatal(1,error,"A TorX server does not write to a file"); Warning(info,"loading model from %s",files[0]); model_t model=GBcreateBase(); GBsetChunkMethods(model,new_string_index,NULL, (int2chunk_t)SIgetC,(chunk2int_t)SIputC,(get_count_t)SIgetCount); GBloadFile(model,files[0],&model); if (RTverbosity >=2) { fprintf(stderr,"Dependency Matrix:\n"); GBprintDependencyMatrix(stderr,model); } if (matrix) { GBprintDependencyMatrix(stdout,model); exit(0); } lts_type_t ltstype=GBgetLTStype(model); N=lts_type_get_state_length(ltstype); edge_info_t e_info=GBgetEdgeInfo(model); K=e_info->groups; Warning(info,"length is %d, there are %d groups",N,K); state_labels=lts_type_get_state_label_count(ltstype); edge_labels=lts_type_get_edge_label_count(ltstype); Warning(info,"There are %d state labels and %d edge labels",state_labels,edge_labels); if (state_labels&&write_lts&&!write_state) { Fatal(1,error,"Writing state labels, but not state vectors unsupported. " "Writing of state vector is enabled with the option --write-state"); } int src[N]; GBgetInitialState(model,src); Warning(info,"got initial state"); int level=0; switch(application){ case ReachVset: domain=vdom_create_default(N); visited_set=vset_create(domain,0,NULL); next_set=vset_create(domain,0,NULL); if (write_lts){ output=lts_output_open(files[1],model,1,0,1,"viv",NULL); lts_output_set_root_vec(output,(uint32_t*)src); lts_output_set_root_idx(output,0,0); output_handle=lts_output_begin(output,0,0,0); } vset_add(visited_set,src); vset_add(next_set,src); vset_t current_set=vset_create(domain,0,NULL); while (!vset_is_empty(next_set)){ if (RTverbosity >= 1) Warning(info,"level %d has %d states, explored %d states %d trans", level,(visited-explored),explored,trans); level++; vset_copy(current_set,next_set); vset_clear(next_set); vset_enum(current_set,explore_state_vector,model); } long long size; long nodes; vset_count(visited_set,&nodes,&size); Warning(info,"%lld reachable states represented symbolically with %ld nodes",size,nodes); break; case ReachTreeDBS: dbs=TreeDBScreate(N); if(TreeFold(dbs,src)!=0){ Fatal(1,error,"expected 0"); } if (write_lts){ output=lts_output_open(files[1],model,1,0,1,write_state?"vsi":"-ii",NULL); if (write_state) lts_output_set_root_vec(output,(uint32_t*)src); lts_output_set_root_idx(output,0,0); output_handle=lts_output_begin(output,0,0,0); } int limit=visited; while(explored<visited){ if (limit==explored){ if (RTverbosity >= 1) Warning(info,"level %d has %d states, explored %d states %d trans", level,(visited-explored),explored,trans); limit=visited; level++; } TreeUnfold(dbs,explored,src); explore_state_index(model,explored,src); } break; case RunTorX: { torx_struct_t context = { model, ltstype }; torx_ui(&context); return 0; } } if (write_lts){ lts_output_end(output,output_handle); Warning(info,"finishing the writing"); lts_output_close(&output); Warning(info,"state space has %d levels %d states %d transitions",level,visited,trans); } else { printf("state space has %d levels %d states %d transitions\n",level,visited,trans); } return 0; }
void CAESAR_INIT_GRAPH(void) { char *opencaesar_args, *opencaesar_prog,*ltsmin_options; int argc; char **argv; opencaesar_prog = getenv ("OPEN_CAESAR_PROG"); if (opencaesar_prog == NULL) CAESAR_ERROR ("undefined environment variable $OPEN_CAESAR_PROG"); opencaesar_args = getenv ("OPEN_CAESAR_FILE"); if (opencaesar_args == NULL) CAESAR_ERROR ("undefined environment variable $OPEN_CAESAR_FILE"); ltsmin_options = getenv ("LTSMIN_OPTIONS"); if (ltsmin_options == NULL) CAESAR_ERROR ("undefined environment variable $LTSMIN_OPTIONS"); int len=strlen(opencaesar_prog)+strlen(ltsmin_options)+strlen(opencaesar_args); char cmdline[len+6]; sprintf(cmdline,"%s %s %s",opencaesar_prog,ltsmin_options,opencaesar_args); int res=poptParseArgvString(cmdline,&argc,(void*)(&argv)); if (res){ Abort("could not parse %s: %s",opencaesar_args,poptStrerror(res)); } char *files[2]; HREinitBegin(argv[0]); HREaddOptions(options,"Options"); HREinitStart(&argc,&argv,1,1,(char**)files,"<model>"); Warning(info,"loading model from %s",files[0]); model=GBcreateBase(); GBsetChunkMethods(model,new_string_index,NULL, (int2chunk_t)SIgetC, (chunk2int_t)SIputC, (chunkatint_t)SIputCAt, (get_count_t)SIgetCount); GBloadFile(model,files[0],&model); ltstype=GBgetLTStype(model); N = lts_type_get_state_length(ltstype); K = dm_nrows(GBgetDMInfo(model)); Warning(info,"length is %d, there are %d groups",N,K); state_labels=lts_type_get_state_label_count(ltstype); edge_labels=lts_type_get_edge_label_count(ltstype); Warning(info,"There are %d state labels and %d edge labels",state_labels,edge_labels); if (edge_encode){ edge_size=edge_labels+N+state_labels; Warning(info,"encoding state information on edges"); } else { edge_size=edge_labels; Warning(info,"state information is hidden"); } CAESAR_HINT_SIZE_STATE = N*sizeof(int); CAESAR_HINT_HASH_SIZE_STATE = CAESAR_HINT_SIZE_STATE; CAESAR_HINT_SIZE_LABEL = edge_size*sizeof(int); CAESAR_HINT_HASH_SIZE_LABEL = CAESAR_HINT_SIZE_LABEL; Warning(info,"CAESAR_HINT_SIZE_STATE=%lu CAESAR_HINT_SIZE_LABEL=%lu", (unsigned long)CAESAR_HINT_SIZE_STATE,(unsigned long)CAESAR_HINT_SIZE_LABEL); }
/** * \brief Initialises the data structures for generating symbolic parity games. */ void init_spg(model_t model) { lts_type_t type = GBgetLTStype(model); var_pos = 0; var_type_no = 0; for(int i=0; i<N; i++) { //Printf(infoLong, "%d: %s (%d [%s])\n", i, lts_type_get_state_name(type, i), lts_type_get_state_typeno(type, i), lts_type_get_state_type(type, i)); #ifdef LTSMIN_PBES char* str1 = "string"; // for the PBES language module #else char* str1 = "mu"; // for the mu-calculus PINS layer #endif size_t strlen1 = strlen(str1); char* str2 = lts_type_get_state_type(type, i); size_t strlen2 = strlen(str2); if (strlen1==strlen2 && strncmp(str1, str2, strlen1)==0) { var_pos = i; var_type_no = lts_type_get_state_typeno(type, i); if (GBhaveMucalc()) { true_index = 0; // enforced by mucalc parser (mucalc-grammar.lemon / mucalc-syntax.c) false_index = 1; } else { // required for the PBES language module. true_index = pins_chunk_put (model, var_type_no, chunk_str("true")); false_index = pins_chunk_put (model, var_type_no, chunk_str("false")); } } } int p_len = 1; int proj[1] = {var_pos}; // position 0 encodes the variable variable_projection = vproj_create(domain, p_len, proj); num_vars = pins_chunk_count (model, var_type_no); // number of propositional variables if (GBhaveMucalc()) { num_vars = GBgetMucalcNodeCount(); // number of mu-calculus subformulae } Print(infoLong, "init_spg: var_type_no=%d, num_vars=%zu", var_type_no, num_vars); priority = RTmalloc(num_vars * sizeof(int)); // priority of variables player = RTmalloc(num_vars * sizeof(int)); // player of variables for(size_t i=0; i<num_vars; i++) { lts_type_t type = GBgetLTStype(model); int state_length = lts_type_get_state_length(type); // create dummy state with variable i: int state[state_length]; for(int j=0; j < state_length; j++) { state[j] = 0; } state[var_pos] = i; int label = GBgetStateLabelLong(model, PG_PRIORITY, state); // priority priority[i] = label; if (label < min_priority) { min_priority = label; } if (label > max_priority) { max_priority = label; } //Print(infoLong, " label %d (priority): %d", 0, label); label = GBgetStateLabelLong(model, PG_PLAYER, state); // player player[i] = label; //Print(infoLong, " label %d (player): %d", 1, label); } true_states = vset_create(domain, -1, NULL); false_states = vset_create(domain, -1, NULL); }
void ETFloadGreyboxModel(model_t model, const char *name) { gb_context_t ctx=(gb_context_t)RTmalloc(sizeof(struct grey_box_context)); GBsetContext(model,ctx); etf_model_t etf=etf_parse_file(name); lts_type_t ltstype=etf_type(etf); int state_length=lts_type_get_state_length(ltstype); ctx->edge_labels=lts_type_get_edge_label_count(ltstype); if (ctx->edge_labels>1) { ctx->label_idx=SIcreate(); } else { ctx->label_idx=NULL; } GBsetLTStype(model,ltstype); matrix_t* p_dm_info = (matrix_t*)RTmalloc(sizeof(matrix_t)); matrix_t* p_dm_read_info = (matrix_t*)RTmalloc(sizeof(matrix_t)); matrix_t* p_dm_write_info = (matrix_t*)RTmalloc(sizeof(matrix_t)); dm_create(p_dm_info, etf_trans_section_count(etf), state_length); dm_create(p_dm_read_info, etf_trans_section_count(etf), state_length); dm_create(p_dm_write_info, etf_trans_section_count(etf), state_length); ctx->trans_key_idx=(string_index_t*)RTmalloc(dm_nrows(p_dm_info)*sizeof(string_index_t)); ctx->trans_table=(matrix_table_t*)RTmalloc(dm_nrows(p_dm_info)*sizeof(matrix_table_t)); for(int i=0; i < dm_nrows(p_dm_info); i++) { Warning(infoLong,"parsing table %d",i); etf_rel_t trans=etf_trans_section(etf,i); int used[state_length]; int src[state_length]; int dst[state_length]; int lbl[ctx->edge_labels]; int proj[state_length]; ETFrelIterate(trans); if (!ETFrelNext(trans,src,dst,lbl)){ Abort("unexpected empty transition section"); } int len=0; for(int j=0;j<state_length;j++){ if (src[j]) { proj[len]=j; Warning(debug,"pi[%d]=%d",len,proj[len]); len++; dm_set(p_dm_info, i, j); used[j]=1; } else { used[j]=0; } } Warning(infoLong,"length is %d",len); ctx->trans_key_idx[i]=SIcreate(); ctx->trans_table[i]=MTcreate(3); int src_short[len]; int dst_short[len]; uint32_t row[3]; do { /* * If an element is non-zero, we always consider it a read. If the * value is changed for at least one transition in a group then * we also consider it a write. Note that this could be slightly * optimized by omitting those elements from read where the value * varies over all possible inputs. */ for(int k=0;k<state_length;k++) { if (src[k] != 0) { dm_set(p_dm_read_info, i, k); if (src[k] != dst[k]) dm_set(p_dm_write_info, i, k); } } for(int k=0;k<state_length;k++) { if(used[k]?(src[k]==0):(src[k]!=0)){ Abort("inconsistent section in src vector"); } } for(int k=0;k<len;k++) src_short[k]=src[proj[k]]-1; for(int k=0;k<state_length;k++) { if(used[k]?(dst[k]==0):(dst[k]!=0)){ Abort("inconsistent section in dst vector"); } } for(int k=0;k<len;k++) dst_short[k]=dst[proj[k]]-1; row[0]=(uint32_t)SIputC(ctx->trans_key_idx[i],(char*)src_short,len<<2); switch(ctx->edge_labels){ case 0: row[2]=0; break; case 1: row[2]=(uint32_t)lbl[0]; break; default: row[2]=(uint32_t)SIputC(ctx->label_idx,(char*)lbl,(ctx->edge_labels)<<2); break; } row[1]=(int32_t)SIputC(ctx->trans_key_idx[i],(char*)dst_short,len<<2); MTaddRow(ctx->trans_table[i],row); } while(ETFrelNext(trans,src,dst,lbl)); Warning(infoLong,"table %d has %d states and %d transitions", i,SIgetCount(ctx->trans_key_idx[i]),ETFrelCount(trans)); ETFrelDestroy(&trans); MTclusterBuild(ctx->trans_table[i],0,SIgetCount(ctx->trans_key_idx[i])); } GBsetDMInfo(model, p_dm_info); /* * Set these again when ETF supports read, write and copy. GBsetDMInfoRead(model, p_dm_read_info); GBsetDMInfoMustWrite(model, p_dm_write_info); GBsetSupportsCopy(model); // no may-write so we support copy. */ GBsetNextStateShort(model,etf_short); matrix_t *p_sl_info = RTmalloc(sizeof *p_sl_info); dm_create(p_sl_info, etf_map_section_count(etf), state_length); ctx->label_key_idx=(string_index_t*)RTmalloc(dm_nrows(p_sl_info)*sizeof(string_index_t)); ctx->label_data=(int**)RTmalloc(dm_nrows(p_sl_info)*sizeof(int*)); for(int i=0;i<dm_nrows(p_sl_info);i++){ Warning(infoLong,"parsing map %d",i); etf_map_t map=etf_get_map(etf,i); int used[state_length]; int state[state_length]; int value; ETFmapIterate(map); if (!ETFmapNext(map,state,&value)){ Abort("Unexpected empty map"); } int len=0; for(int j=0;j<state_length;j++){ if (state[j]) { used[len]=j; len++; dm_set(p_sl_info, i, j); } } int*proj=(int*)RTmalloc(len*sizeof(int)); for(int j=0;j<len;j++) proj[j]=used[j]; for(int j=0;j<state_length;j++) used[j]=state[j]; string_index_t key_idx=SIcreate(); int *data=(int*)RTmalloc(ETFmapCount(map)*sizeof(int)); int key[len]; do { for(int k=0;k<state_length;k++) { if(used[k]?(state[k]==0):(state[k]!=0)){ Abort("inconsistent map section"); } } for(int k=0;k<len;k++) key[k]=state[proj[k]]-1; data[SIputC(key_idx,(char*)key,len<<2)]=value; } while(ETFmapNext(map,state,&value)); ctx->label_key_idx[i]=key_idx; ctx->label_data[i]=data; } GBsetStateLabelInfo(model, p_sl_info); GBsetStateLabelShort(model,etf_state_short); GBsetTransitionInGroup(model,etf_transition_in_group); int type_count=lts_type_get_type_count(ltstype); for(int i=0;i<type_count;i++){ Warning(infoLong,"Setting values for type %d (%s)",i,lts_type_get_type(ltstype,i)); int count=etf_get_value_count(etf,i); for(int j=0;j<count;j++){ GBchunkPutAt(model,i,etf_get_value(etf,i,j),j); } } int state[state_length]; etf_get_initial(etf,state); GBsetInitialState(model,state); }
int SLTSsegmentNumber(seg_lts_t lts){ return lts->seg_no; } hre_task_queue_t SLTSgetQueue(seg_lts_t lts){ return lts->task_queue; } seg_lts_t SLTScreate(lts_type_t signature,hre_task_queue_t task_queue,seg_lts_layout_t layout){ seg_lts_t lts=RT_NEW(struct seg_lts_s); lts->sig=signature; lts->task_queue=task_queue; lts->seg_no=HREme(TQcontext(task_queue)); lts->seg_count=HREpeers(TQcontext(task_queue)); lts->state_length=lts_type_get_state_length(signature); lts->state_labels=lts_type_get_state_label_count(signature); lts->edge_labels=lts_type_get_edge_label_count(signature); lts->layout=layout; lts->vt_count=lts_type_get_type_count(signature); lts->vt=RTmalloc(lts->vt_count*sizeof(value_table_t)); for(int i=0;i<lts->vt_count;i++) { char *type_name=lts_type_get_type(signature,i); lts->vt[i]=HREcreateTable(TQcontext(task_queue),type_name); } return lts; } int SLTSstateCount(seg_lts_t lts){ return lts->state_count; }
void dve_write(const char*name,etf_model_t model){ lts_type_t ltstype=etf_type(model); int N=lts_type_get_state_length(ltstype); int K=lts_type_get_edge_label_count(ltstype); int G=etf_trans_section_count(model); // mapping section => pvar int owner[G]; // default ownership if no state variable is written to // this is so that self-transitions on state variables go in their own process int defowner[G]; // mapping variable => type int types[N]; pvar_slice(ltstype); // count of sections per pvar int g_count[pv_count+1]; for(int i=0;i<=pv_count;i++){ g_count[i]=0; } /* Analyze sections: find out which sections belong to which pvar */ // maximum value per variable int max[N]; etf_get_initial(model,max); if (pv_count) { for(int i=0;i<G;i++) { etf_rel_t trans=etf_trans_section(model,i); int status[N]; int count=analyze_rel(trans,N,K,status,max); owner[i]=-1; defowner[i]=-1; if(count==0) continue; for(int j=0;j<N;j++){ for(int k=0;k<pv_count;k++){ if (pvar_idx[k]==j){ if(status[j]&0x2){ if (owner[i]==-1){ owner[i]=k; } else { Abort("group %d belongs to two processes",i); } } else if (status[j]&0x1) { if (defowner[i]==-1) { defowner[i]=k; } else { defowner[i]=pv_count; } } } } } if (owner[i]==-1) owner[i]=defowner[i]; if (owner[i]==-1) owner[i]=pv_count; g_count[owner[i]]++; Warning(info,"group %d belongs to proc %d",i,owner[i]); } } else { for(int i=0;i<G;i++) { owner[i]=0; g_count[owner[i]]++; } } /* Analyze variables: find out what type each variable is */ // pvar with at least one nonempty section: state variable // always same owner: local variable // otherwise: global int var_owner[N]; for (int i=0;i<N;i++) { types[i]=VAR_TYPE_UNKNOWN; var_owner[i]=-1; } for (int i=0;i<pv_count;i++) { types[pvar_idx[i]] = g_count[i]?VAR_TYPE_STATE:VAR_TYPE_GLOBAL; } if (pv_count) { for (int i=0;i<G;i++) { etf_rel_t trans=etf_trans_section(model,i); int status[N]; int count=analyze_rel(trans,N,K,status,NULL); if (!count) continue; for (int j=0;j<N;j++) { if (types[j]==VAR_TYPE_STATE) continue; if (status[j]) { if (var_owner[j]==-1) { var_owner[j]=owner[i]; types[j]=VAR_TYPE_LOCAL; } else { if (var_owner[j]!=owner[i]) { types[j]=VAR_TYPE_GLOBAL; } } } } } for (int i=0;i<N;i++) { char *typename; switch(types[i]) { case VAR_TYPE_STATE: typename="state"; break; case VAR_TYPE_LOCAL: typename="local"; break; case VAR_TYPE_GLOBAL: typename="global"; break; default: typename="unknown"; break; } Warning(info,"variable %s is %s",lts_variable_name(ltstype,i),typename); } } else { for(int i=0;i<N;i++) {