123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227(**********************************************************************)(* *)(* LASCAr *)(* *)(* Copyright (c) 2017-present, Jocelyn SEROT. All rights reserved. *)(* *)(* This source code is licensed under the license found in the *)(* LICENSE file in the root directory of this source tree. *)(* *)(**********************************************************************)openUtilsmoduleBVal=Valuation.Make(structtypet=boolletcompare=Pervasives.compareletto_string=functiontrue->"1"|false->"0"end)moduletypeT=sigtypestateincludeLtsa.Twithtypelabel:=BVal.tandtypestate:=stateandtypeattr:=BVal.tmoduleM:Ltsa.Twithtypestate=stateandtypelabel=BVal.tandtypeattr=BVal.texceptionInvalid_transitionoftransitionvalcreate:inps:BVal.namelist->outps:BVal.namelist->states:(state*BVal.t)list->istate:state->trans:(state*BVal.t*state)list->tvalempty:inps:BVal.namelist->outps:BVal.namelist->tvaladd_state:state*BVal.t->t->tvaladd_transition:state*BVal.t*state->t->tvaladd_itransition:state->t->tvallts_of:t->M.tvalistate:t->stateoptionvalinps:t->BVal.namelistvaloutps:t->BVal.namelistvaltrans:t->state->BVal.t->States.tvaltrans':t->state->BVal.t->statelistvalunwind:int->t->M.Tree.tvaldot_output:string->?fname:string->?options:Dot.graph_stylelist->t->unitvaldot_output_oc:string->out_channel->?options:Dot.graph_stylelist->t->unitendmoduleMake(S:Ltsa.STATE)=structmoduleM=Ltsa.Make(S)(BVal)(BVal)moduleTree=Tree.Make(structtypenode=S.ttypeedge=BVal.tletstring_of_node=S.to_stringletstring_of_edge=BVal.to_stringend)typestate=M.statetypelabel=M.labeltypeattr=BVal.tmoduleState=SmoduleLabel=BValmoduleStates=M.StatesmoduleAttr=BValmoduleAttrs=Map.Make(structtypet=stateletcompare=compareend)typetransition=M.transitiontypeitransition=M.itransitiontypet={lts:M.t;(* Internal representation, as a LTS *)ivs:BVal.namelist;(* Input variables *)ovs:BVal.namelist;(* Output variables *)}letlts_ofs=s.ltsletempty~inps:ivars~outps:ovars={lts=M.empty;ivs=ivars;ovs=ovars}letis_statesq=M.is_states.ltsqletistatess=M.istatess.ltsletistates's=M.istates's.ltsletistates=matchistates'swith[]->None|[q]->Someq|_->failwith"Moore: more than one initial state"letis_transitionst=M.is_transitions.ltstletinpss=s.ivsletoutpss=s.ovsexceptionInvalid_stateofstateexceptionInvalid_transitionoftransitionletadd_state(q,ov)s=BVal.checks.ovsov;{swithlts=M.add_state(q,ov)s.lts}letremove_stateqs={swithlts=M.remove_stateqs.lts}letadd_transition(q,iv,q')s=BVal.checks.ivsiv;{swithlts=M.add_transition(q,iv,q')s.lts}letadd_itransitionqs={swithlts=M.add_itransition([],q)s.lts}letattr_ofaq=M.attr_ofa.ltsqletcreate~inps:ivs~outps:ovs~states:qs~istate:q0~trans:ts=ifnot(List.memq0(List.mapfstqs))thenfailwith"Moore.create: the initial state is not listed in the set of states";letadd_statesqss=List.fold_left(funsq->add_stateqs)sqsinletadd_transitionstss=List.fold_left(funst->add_transitionts)stsinempty~inps:ivs~outps:ovs|>add_statesqs|>add_transitionsts|>add_itransitionq0letstatess=M.statess.ltsletstates's=M.states's.ltslettransitionss=M.transitionss.ltsletitransitionss=M.itransitionss.ltsletstring_of_state=M.string_of_stateletstring_of_label=M.string_of_labelletstring_of_attr=M.string_of_attrletis_init_statesq=M.is_init_states.ltsqletiter_statesfs=M.iter_statesfs.ltsletfold_statesfsz=M.fold_statesfs.ltszletiter_transitionsfs=M.iter_transitionsfs.ltsletfold_transitionsfsz=M.fold_transitionsfs.ltszletiter_itransitionsfs=M.iter_itransitionsfs.ltsletfold_itransitionsfsz=M.fold_itransitionsfs.ltszletfold_succssqfz=M.fold_succss.ltsqfzletfold_predssqfz=M.fold_predss.ltsqfzletiter_succssqf=M.iter_succss.ltsqfletiter_predssqf=M.iter_predss.ltsqfletsuccssq=M.succss.ltsqletpredssq=M.predss.ltsqletsuccs'sq=M.succs's.ltsqletpreds'sq=M.preds's.ltsqletsuccs_hatsq=M.succs_hats.ltsqletpreds_hatsq=M.preds_hats.ltsqletmap_statefs={swithlts=M.map_statefs.lts}letmap_attrfs={swithlts=M.map_attrfs.lts}letmap_labelfs={swithlts=M.map_labelfs.lts}letcleans={swithlts=M.cleans.lts}letunwinddeptha=matchM.unwinddeptha.ltswith[t]->t|_->failwith"Moore.unwind"(* should not happen *)letis_reachablesq=M.is_reachables.ltsqlettransaqs=M.fold_transitions(fun(q',s',q'')acc->ifS.compareq'q=0&&BVal.compares's=0thenStates.addq''accelseacc)a.ltsStates.emptylettrans'aqs=States.elements(transaqs)lettrans_hataqss=letrechqsss=matchsswith[]->qs|s::ss'->letqs'=States.fold(funqacc->States.union(transaqs)acc)qsqsinhqs'ss'inh(States.singletonq)sslettrans_hat'aqs=States.elements(trans_hataqs)letvar_nodea=letstring_of_varpfxn=pfx^ninlettxt=ListExt.to_string(string_of_var"In: ")"\\n"a.ivs^"\\n"^ListExt.to_string(string_of_var"Out: ")"\\n"a.ovsintxt,{Dot.node_shape="rect";Dot.node_style="regular"}letdot_outputname?(fname="")?(options=[])a=M.dot_outputname~fname:fname~options:options~extra_nodes:([var_nodea])a.ltsletdot_output_ocnameoc?(options=[])a=M.dot_output_ocnameoc~options:options~extra_nodes:([var_nodea])a.ltslettex_outputname?(fname="")?(listed_transitions=None)a=M.tex_outputname~fname:fname~listed_transitions:listed_transitionsa.ltsletdot_output_execsname?(fname="")?(options=[])deptha=M.dot_output_execsname~fname:fname~options:optionsdeptha.lts(* let dump a = M.dump a.lts *)end