123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103(**********************************************************************)(* *)(* 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. *)(* *)(**********************************************************************)openUtilsmoduletypeT=sigincludeNfa.TmoduleNFA:Nfa.Twithtypestate=stateandtypesymbol=symbolexceptionNon_deterministicvalcreate:states:statelist->symbols:symbollist->istate:state->trans:(state*symbol*state)list->astates:statelist->texceptionStuckofstate*symbollistvaltrans:t->state->symbol->statevaltrans_hat:t->state->symbollist->statevalnfa_of:t->NFA.tvalof_nfa:NFA.t->tendmoduleMake(S:Ltsa.STATE)(L:Nfa.SYMBOL)=structmoduleNFA=Nfa.Make(S)(L)includeNFAexceptionStuckofstate*symbollistletnfa_ofa=aletof_nfaa=aexceptionNon_deterministicletcreate~states:qs~symbols:ss~istate:q0~trans:ts~astates:fs=(* Check for non-deterministic transitions *)letts'=List.fold_left(funacc(q,l,q')->ifList.mem_assoc(q,l)accthenraiseNon_deterministicelse((q,l),q')::acc)[]tsinNFA.create~states:qs~symbols:ss~istate:q0~trans:(List.map(fun((q,l),q')->(q,l,[q']))ts')~astates:fsletadd_transition((q1,s,q2)ast)a=letincompatible_trans(q1',s',q2')=State.compareq1q1'=0&&Symbol.comparess'=0&&State.compareq2q2'<>0inifList.existsincompatible_trans(transitionsa)thenraiseNon_deterministicelseNFA.add_transitiontalettransaqs=matchStates.elements(NFA.transaqs)with[]->raise(Stuck(q,[s]))|[q']->q'|_->failwith"Dfa.trans"(* should not happen *)lettrans_hataqs=matchStates.elements(NFA.trans_hataqs)with[]->raise(Stuck(q,s))|[q']->q'|_->failwith"Dfa.trans_hat"(* should not happen *)endmoduleTrans(S1:T)(S2:T)=structmoduleF=Nfa.Trans(S1.NFA)(S2.NFA)letmapfqfss1=letp=F.mapfqfs(S1.nfa_ofs1)inS2.of_nfapendmoduleProduct(S1:T)(S2:Twithtypesymbol=S1.symbolandtypeSymbols.t=S1.Symbols.tandtypeNFA.Symbols.t=S1.NFA.Symbols.t)=structmoduleS=OrderedTypeExt.Pair(S1.State)(S2.State)moduleL=S1.SymbolmoduleR=Make(S)(L)includeRmoduleP=Nfa.Product(S1.NFA)(S2.NFA)letproducts1s2=letp=P.product(S1.nfa_ofs1)(S2.nfa_ofs2)inletadd_stateqfr=R.add_state(q,P.is_init_statepq,f)rinletadd_transition(q,s,q')r=R.add_transition(q,s,q')rinR.empty(P.symbols'p)|>(P.fold_statesadd_statep)|>(P.fold_transitionsadd_transitionp)end