value_table_t HREcreateTable(hre_context_t ctx,const char* name){ if (HREpeers(ctx)==1) return chunk_table_create(ctx,(char*)name); value_table_t vt=VTcreateBase((char*)name,sizeof(struct value_table_s)); VTdestroySet(vt,destroy); VTputChunkSet(vt,put_chunk); VTputAtChunkSet(vt,put_at_chunk); VTgetChunkSet(vt,get_chunk); VTgetCountSet(vt,get_count); vt->index=SIcreate(); vt->ctx=ctx; vt->msg_pending=0; uint32_t request_tag=HREactionCreate(ctx,1,CHUNK_BUFFER_SIZE,request_action,vt); uint32_t answer_tag=HREactionCreate(ctx,0,CHUNK_BUFFER_SIZE,answer_action,vt); vt->msg=HREnewMessage(ctx,CHUNK_BUFFER_SIZE); if (HREme(ctx)==0){ vt->msg->tag=answer_tag; vt->msg->comm=0; } else { vt->msg->tag=request_tag; vt->msg->comm=1; } vt->msg->source=HREme(ctx); vt->msg->target=0; vt->msg->ready=hre_ready_decr; vt->msg->ready_ctx=&vt->msg_pending; HREbarrier(ctx); return vt; }
static value_index_t put_chunk(value_table_t vt,chunk item){ if (HREme(vt->ctx)==0) { return SIputC(vt->index,item.data,item.len); } int res=SIlookupC(vt->index,item.data,item.len); if (res==SI_INDEX_FAILED) { Debug("looking up chunk %s",item.data); if (vt->msg_pending) { Debug("waiting for msg (%x/%d) %s",vt->msg_pending,vt->msg_pending,vt->msg->buffer+4); HREyieldWhile(vt->ctx,&vt->msg_pending); } Debug("preparing message"); vt->task=-1; int32_t tmp=-1; if (item.len>MAX_CHUNK_SIZE) Abort("chunk length %d exceeds maximum (%d).",item.len,MAX_CHUNK_SIZE); memcpy(vt->msg->buffer,&tmp,4); memcpy(vt->msg->buffer+4,item.data,item.len); vt->msg->tail=item.len+4; vt->task_pending=1; vt->msg_pending=1; HREpostSend(vt->msg); Debug("waiting for result"); HREyieldWhile(vt->ctx,&vt->task_pending); res=vt->task; SIputCAt(vt->index,item.data,item.len,res); Debug("got %d",res); } return res; }
static void spg_solve_popt(poptContext con, enum poptCallbackReason reason, const struct poptOption * opt, const char * arg, void * data) { (void)con; (void)opt; (void)arg; (void)data; switch (reason) { case POPT_CALLBACK_REASON_PRE: Abort("unexpected call to spg_solve_popt"); case POPT_CALLBACK_REASON_POST: { int res; res = linear_search(ATTR, attr_str); if (res < 0) { Print(lerror, "Unknown attractor strategy %s", attr_str); HREexitUsage(HRE_EXIT_FAILURE); } else if (HREme(HREglobal())==0) { Print(info, "Attractor strategy is %s", attr_str); } attr_strategy = res; return; } case POPT_CALLBACK_REASON_OPTION: Abort("unexpected call to spg_solve_popt"); } }
static void* thread_main(void*arg){ hre_context_t context=(hre_context_t)arg; HREprocessSet(context); HREglobalSet(context); set_label("%s(%2d/%2d)",HREappName(),HREme(context),HREpeers(context)); Debug("calling main..."); int argc=1; char *argv[2]={strdup(HREpathName()),NULL}; main(argc,argv); return NULL; }
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()); }
static void queue_recv(hre_context_t ctx,hre_msg_t msg){ int me=HREme(ctx); if (me==(int)msg->source) { Abort("receive complete on local message"); } else { Debug("receive complete"); // Complete send remotely. /* there are two reasons for not executing msgReady: 1. the sender must be sent a signal to unblock in case it's waiting. 2. the callback may refer to memory that is not visible in this process. (multi-process only) */ queue_put(ctx,msg,msg->source); } }
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"); }
static void put_at_chunk(value_table_t vt,chunk item,value_index_t index){ SIputCAt(vt->index,item.data,item.len,index); if (HREme(vt->ctx)!=0) { Debug("validating at owner chunk %s at %u",item.data, index); if (vt->msg_pending) { Debug("waiting for msg (%x/%d) %s",vt->msg_pending,vt->msg_pending,vt->msg->buffer+4); HREyieldWhile(vt->ctx,&vt->msg_pending); } Debug("preparing message"); int32_t tmp = -2 - index; if (item.len>MAX_CHUNK_SIZE) Abort("chunk length %d exceeds maximum (%d).",item.len,MAX_CHUNK_SIZE); memcpy(vt->msg->buffer,&tmp,4); memcpy(vt->msg->buffer+4,item.data,item.len); vt->msg->tail=item.len+4; vt->msg_pending=1; HREpostSend(vt->msg); } }
static chunk get_chunk(value_table_t vt,value_index_t idx){ int len; char* data=SIgetC(vt->index,idx,&len); if (data==NULL) { if (HREme(vt->ctx)==0) Abort("chunk %d does not exist",idx); Debug("looking up index %d",idx); if (vt->msg_pending) HREyieldWhile(vt->ctx,&vt->msg_pending); vt->task=idx; memcpy(vt->msg->buffer,&idx,4); vt->msg->tail=4; vt->task_pending=1; vt->msg_pending=1; HREpostSend(vt->msg); HREyieldWhile(vt->ctx,&vt->task_pending); data=SIgetC(vt->index,idx,&len); data[len]=0; Debug("got %s (%d)",data,vt->msg_pending); } return chunk_ld(len,data); }
static void queue_while(hre_context_t ctx,int*condition){ int me=HREme(ctx); hre_msg_t msg=NULL; int max_comm=array_size(HREcommManager(ctx)); int comm; for(;;){ pthread_mutex_lock(&ctx->queues[me].lock); Debug("scanning queue %d below %d",me,max_comm); for(comm=0;comm<max_comm;comm++){ msg=hre_get_msg(&ctx->queues[me].comm[comm]); if (msg) break; } while(!msg && *condition) { Debug("blocking %d",*condition); pthread_cond_wait(&ctx->queues[me].cond, &ctx->queues[me].lock); Debug("scanning queue %d below %d",me,max_comm); for(comm=0;comm<max_comm;comm++){ msg=hre_get_msg(&ctx->queues[me].comm[comm]); if (msg) break; } } pthread_mutex_unlock(&ctx->queues[me].lock); if (!msg) break; /* Messages are put in the queue with the sending context. They have to be processed with respect to the receiving context. */ msg->context=ctx; if (me==(int)msg->target) { Debug("delivering message %p",msg); // Message is sent to us. HREdeliverMessage(msg); } else { Debug("completed message %p",msg); // Message is being returned to us. HREmsgReady(msg); } } }
int lts_file_owned(lts_file_t lts,int nth){ int me=HREme(SYSTEM(lts)->ctx); int peers=HREpeers(SYSTEM(lts)->ctx); return me+peers*nth; }
int lts_file_owned_count(lts_file_t lts){ int me=HREme(SYSTEM(lts)->ctx); int peers=HREpeers(SYSTEM(lts)->ctx); int N=SYSTEM(lts)->segments; return (N+peers-me-1)/peers; }
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); }
return lts->seg_count; } 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){
void HREprintUsage(){ if (HREme(HREglobal()) == 0) poptPrintUsage(optCon,stdout,0); }
int TQwait(hre_task_queue_t queue){ if (HREpeers(queue->ctx)==1) return 0; Debug("enter wait"); queue->wait_cancelled=0; queue->status=Dirty; queue->mode=Immediate; TaskFlush(queue); struct term_msg* msg_in=&queue->term_in; struct term_msg* msg_out=(struct term_msg*)queue->msg->buffer; if (HREme(queue->ctx)==0) { queue->status=Dirty; int round=0; while(queue->status!=Terminated) { queue->wait_pending=queue->recv_pending; HREyieldWhile(queue->ctx,&queue->wait_pending); if (queue->wait_cancelled){ Debug("wait cancelled 1"); queue->status=Active; queue->mode=Lazy; return 1; // wait has been cancelled. } switch(queue->status){ case Idle: case Dirty: if (msg_in->status==Terminated){ msg_in->status=Dirty; queue->status=Terminated; break; } if (queue->send_pending) { HREyieldWhile(queue->ctx,&queue->send_pending); if (queue->wait_cancelled){ Debug("wait cancelled 2"); queue->status=Active; queue->mode=Lazy; return 1; // wait has been cancelled. } } if (queue->status==Idle && msg_in->status==Idle && msg_in->sent==msg_in->recv){ msg_out->status=Terminated; Debug("termination detected in %d rounds",round); queue->send_pending=1; queue->recv_pending=1; HREpostSend(queue->msg); break; } queue->status=Idle; msg_out->status=Idle; msg_out->sent=queue->sent; msg_out->recv=queue->recv; queue->status=Idle; round++; Debug("starting detection round %d",round); queue->send_pending=1; queue->recv_pending=1; HREpostSend(queue->msg); break; case Active: Abort("should not be active in this loop") case Terminated: Abort("should not be terminated in this loop") default: Abort("missing case"); } } queue->status=Active; } else {
void HREprintHelp(){ if (HREme(HREglobal()) == 0) poptPrintHelp(optCon,stdout,0); }
static void reach_popt(poptContext con, enum poptCallbackReason reason, const struct poptOption * opt, const char * arg, void * data) { (void)con; (void)opt; (void)arg; (void)data; switch (reason) { case POPT_CALLBACK_REASON_PRE: Abort("unexpected call to reach_popt"); case POPT_CALLBACK_REASON_POST: { int res; res = linear_search(ORDER, order); if (res < 0) { Warning(lerror, "unknown exploration order %s", order); HREexitUsage(LTSMIN_EXIT_FAILURE); } else if (HREme(HREglobal())==0) { Warning(info, "Exploration order is %s", order); } strategy = res; res = linear_search(SATURATION, saturation); if (res < 0) { Warning(lerror, "unknown saturation strategy %s", saturation); HREexitUsage(LTSMIN_EXIT_FAILURE); } else if (HREme(HREglobal())==0) { Warning(info, "Saturation strategy is %s", saturation); } sat_strategy = res; res = linear_search(GUIDED, guidance); if (res < 0) { Warning(lerror, "unknown guided search strategy %s", guidance); HREexitUsage(LTSMIN_EXIT_FAILURE); } else if (HREme(HREglobal())==0) { Warning(info, "Guided search strategy is %s", guidance); } guide_strategy = res; if (trc_output != NULL && !dlk_detect && act_detect == NULL && HREme(HREglobal())==0) Warning(info, "Ignoring trace output"); if (inv_bin_par == 1 && inv_par == 0) { Warning(lerror, "--inv-bin-par requires --inv-par"); HREexitUsage(LTSMIN_EXIT_FAILURE); } return; } case POPT_CALLBACK_REASON_OPTION: IF_LONG(invariant_long) { num_inv++; inv_detect = (char**) RTrealloc(inv_detect, sizeof(char*) * num_inv); inv_detect[num_inv - 1] = (char*) RTmalloc(strlen(arg) + 1); memcpy(inv_detect[num_inv - 1], arg, strlen(arg) + 1); } IF_LONG(ctl_star_long) { num_ctl_star++; ctl_star_formulas = (char**) RTrealloc(ctl_star_formulas, sizeof(char*) * num_ctl_star); ctl_star_formulas[num_ctl_star - 1] = (char*) RTmalloc(strlen(arg) + 1); memcpy(ctl_star_formulas[num_ctl_star - 1], arg, strlen(arg) + 1); } IF_LONG(ctl_long) { num_ctl++; ctl_formulas = (char**) RTrealloc(ctl_formulas, sizeof(char*) * num_ctl); ctl_formulas[num_ctl - 1] = (char*) RTmalloc(strlen(arg) + 1); memcpy(ctl_formulas[num_ctl - 1], arg, strlen(arg) + 1); } IF_LONG(ltl_long) { num_ltl++; ltl_formulas = (char**) RTrealloc(ltl_formulas, sizeof(char*) * num_ltl); ltl_formulas[num_ltl - 1] = (char*) RTmalloc(strlen(arg) + 1); memcpy(ltl_formulas[num_ltl - 1], arg, strlen(arg) + 1); } IF_LONG(mu_long) { num_mu++; mu_formulas = (char**) RTrealloc(mu_formulas, sizeof(char*) * num_mu); mu_formulas[num_mu - 1] = (char*) RTmalloc(strlen(arg) + 1); memcpy(mu_formulas[num_mu - 1], arg, strlen(arg) + 1); } return; } }
static void init_domain(vset_implementation_t impl) { domain = vdom_create_domain(N, impl); for (int i = 0; i < dm_ncols(GBgetDMInfo(model)); i++) { vdom_set_name(domain, i, lts_type_get_state_name(ltstype, i)); } group_next = (vrel_t*)RTmalloc(nGrps * sizeof(vrel_t)); group_explored = (vset_t*)RTmalloc(nGrps * sizeof(vset_t)); group_tmp = (vset_t*)RTmalloc(nGrps * sizeof(vset_t)); r_projs = (ci_list **)RTmalloc(sizeof(ci_list *[nGrps])); w_projs = (ci_list **)RTmalloc(sizeof(ci_list *[nGrps])); l_projs = (ci_list **)RTmalloc(sizeof(ci_list *[sLbls])); label_false = (vset_t*)RTmalloc(sLbls * sizeof(vset_t)); label_true = (vset_t*)RTmalloc(sLbls * sizeof(vset_t)); label_tmp = (vset_t*)RTmalloc(sLbls * sizeof(vset_t)); if (!vdom_separates_rw(domain) && !PINS_USE_GUARDS) { read_matrix = GBgetDMInfo(model); write_matrix = GBgetDMInfo(model); Warning(info, "Using GBgetTransitionsShort as next-state function"); transitions_short = GBgetTransitionsShort; } else if (!vdom_separates_rw(domain) && PINS_USE_GUARDS) { read_matrix = GBgetMatrix(model, GBgetMatrixID(model, LTSMIN_MATRIX_ACTIONS_READS)); write_matrix = GBgetDMInfo(model); Warning(info, "Using GBgetActionsShort as next-state function"); transitions_short = GBgetActionsShort; } else if (vdom_separates_rw(domain) && !PINS_USE_GUARDS) { read_matrix = GBgetDMInfoRead(model); write_matrix = GBgetDMInfoMayWrite(model); Warning(info, "Using GBgetTransitionsShortR2W as next-state function"); transitions_short = GBgetTransitionsShortR2W; } else { // vdom_separates_rw(domain) && PINS_USE_GUARDS read_matrix = GBgetMatrix(model, GBgetMatrixID(model, LTSMIN_MATRIX_ACTIONS_READS)); write_matrix = GBgetDMInfoMayWrite(model); Warning(info, "Using GBgetActionsShortR2W as next-state function"); transitions_short = GBgetActionsShortR2W; } if (PINS_USE_GUARDS) { if (no_soundness_check) { Warning(info, "Guard-splitting: not checking soundness of the specification, this may result in an incorrect state space!"); } else { Warning(info, "Guard-splitting: checking soundness of specification, this may be slow!"); } } r_projs = (ci_list **) dm_rows_to_idx_table (read_matrix); w_projs = (ci_list **) dm_rows_to_idx_table (write_matrix); for(int i = 0; i < nGrps; i++) { if (HREme(HREglobal())==0) { if (vdom_separates_rw(domain)) { group_next[i] = vrel_create_rw (domain, r_projs[i]->count, r_projs[i]->data, w_projs[i]->count, w_projs[i]->data); } else { group_next[i] = vrel_create (domain, r_projs[i]->count, r_projs[i]->data); } group_explored[i] = vset_create (domain, r_projs[i]->count, r_projs[i]->data); group_tmp[i] = vset_create (domain, r_projs[i]->count, r_projs[i]->data); if (inhibit_matrix != NULL) { inhibit_class_count = dm_nrows(inhibit_matrix); class_enabled = (vset_t*)RTmalloc(inhibit_class_count * sizeof(vset_t)); for(int i=0; i<inhibit_class_count; i++) { class_enabled[i] = vset_create(domain, -1, NULL); } } } } l_projs = (ci_list **) dm_rows_to_idx_table (GBgetStateLabelInfo(model)); for (int i = 0; i < sLbls; i++) { /* Indeed, we skip unused state labels, but allocate memory for pointers * (to vset_t's). Is this bad? Maybe a hashmap is worse. */ if (bitvector_is_set(&state_label_used, i)) { if (HREme(HREglobal()) == 0) { label_false[i] = vset_create(domain, l_projs[i]->count, l_projs[i]->data); label_true[i] = vset_create(domain, l_projs[i]->count, l_projs[i]->data); label_tmp[i] = vset_create(domain, l_projs[i]->count, l_projs[i]->data); } } else { label_false[i] = NULL; label_true[i] = NULL; label_tmp[i] = NULL; } } inv_set = (vset_t *) RTmalloc(sizeof(vset_t[num_inv])); for (int i = 0; i < num_inv; i++) { inv_set[i] = vset_create (domain, inv_proj[i]->count, inv_proj[i]->data); inv_info_prepare (inv_expr[i], inv_parse_env[i], i); } }