123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736(******************************************************************************)(* _ __ * The Kappa Language *)(* | |/ / * Copyright 2010-2020 CNRS - Harvard Medical School - INRIA - IRIF *)(* | ' / *********************************************************************)(* | . \ * This file is distributed under the terms of the *)(* |_|\_\ * GNU Lesser General Public License Version 3 *)(******************************************************************************)typepervasives_bool=booltype('mix,'id)e=|BIN_ALG_OPofOperator.bin_alg_op*('mix,'id)eLoc.annoted*('mix,'id)eLoc.annoted|UN_ALG_OPofOperator.un_alg_op*('mix,'id)eLoc.annoted|STATE_ALG_OPofOperator.state_alg_op|ALG_VARof'id|KAPPA_INSTANCEof'mix|TOKEN_IDof'id|CONSTofNbr.t|IFof('mix,'id)boolLoc.annoted*('mix,'id)eLoc.annoted*('mix,'id)eLoc.annoted|DIFF_TOKENof(('mix,'id)eLoc.annoted*'id)|DIFF_KAPPA_INSTANCEof(('mix,'id)eLoc.annoted*'mix)and('mix,'id)bool=|TRUE|FALSE|BIN_BOOL_OPofOperator.bin_bool_op*('mix,'id)boolLoc.annoted*('mix,'id)boolLoc.annoted|UN_BOOL_OPofOperator.un_bool_op*('mix,'id)boolLoc.annoted|COMPARE_OPofOperator.compare_op*('mix,'id)eLoc.annoted*('mix,'id)eLoc.annotedletrece_to_yojson~filenamesf_mixf_id=function|BIN_ALG_OP(op,a,b)->`List[Operator.bin_alg_op_to_jsonop;Loc.yojson_of_annoted~filenames(e_to_yojson~filenamesf_mixf_id)a;Loc.yojson_of_annoted~filenames(e_to_yojson~filenamesf_mixf_id)b;]|UN_ALG_OP(op,a)->`List[Operator.un_alg_op_to_jsonop;Loc.yojson_of_annoted~filenames(e_to_yojson~filenamesf_mixf_id)a;]|STATE_ALG_OPop->Operator.state_alg_op_to_jsonop|ALG_VARi->`List[`String"VAR";f_idi]|KAPPA_INSTANCEcc->`List[`String"MIX";f_mixcc]|TOKEN_IDi->`List[`String"TOKEN";f_idi]|CONSTn->Nbr.to_yojsonn|IF(cond,yes,no)->`List[`String"IF";Loc.yojson_of_annoted~filenames(bool_to_yojson~filenamesf_mixf_id)cond;Loc.yojson_of_annoted~filenames(e_to_yojson~filenamesf_mixf_id)yes;Loc.yojson_of_annoted~filenames(e_to_yojson~filenamesf_mixf_id)no;]|DIFF_TOKEN(expr,token)->`List[`String"DIFF_TOKEN";Loc.yojson_of_annoted~filenames(e_to_yojson~filenamesf_mixf_id)expr;f_idtoken;]|DIFF_KAPPA_INSTANCE(expr,mixture)->`List[`String"DIFF_MIXTURE";Loc.yojson_of_annoted~filenames(e_to_yojson~filenamesf_mixf_id)expr;f_mixmixture;]andbool_to_yojson~filenamesf_mixf_id=function|TRUE->`Booltrue|FALSE->`Boolfalse|UN_BOOL_OP(op,a)->`List[Operator.un_bool_op_to_jsonop;Loc.yojson_of_annoted~filenames(bool_to_yojson~filenamesf_mixf_id)a;]|BIN_BOOL_OP(op,a,b)->`List[Operator.bin_bool_op_to_jsonop;Loc.yojson_of_annoted~filenames(bool_to_yojson~filenamesf_mixf_id)a;Loc.yojson_of_annoted~filenames(bool_to_yojson~filenamesf_mixf_id)b;]|COMPARE_OP(op,a,b)->`List[Operator.compare_op_to_jsonop;Loc.yojson_of_annoted~filenames(e_to_yojson~filenamesf_mixf_id)a;Loc.yojson_of_annoted~filenames(e_to_yojson~filenamesf_mixf_id)b;]letrece_of_yojson~filenamesf_mixf_id=function|`List[`String"DIFF_MIXTURE";expr;mixture]->DIFF_KAPPA_INSTANCE(Loc.annoted_of_yojson~filenames(e_of_yojson~filenamesf_mixf_id)expr,f_mixmixture)|`List[`String"DIFF_TOKEN";expr;tok]->DIFF_TOKEN(Loc.annoted_of_yojson~filenames(e_of_yojson~filenamesf_mixf_id)expr,f_idtok)|`List[op;a;b]->BIN_ALG_OP(Operator.bin_alg_op_of_jsonop,Loc.annoted_of_yojson~filenames(e_of_yojson~filenamesf_mixf_id)a,Loc.annoted_of_yojson~filenames(e_of_yojson~filenamesf_mixf_id)b)|`List[`String"VAR";i]->ALG_VAR(f_idi)|`List[`String"TOKEN";i]->TOKEN_ID(f_idi)|`List[`String"MIX";cc]->KAPPA_INSTANCE(f_mixcc)|`List[op;a]->UN_ALG_OP(Operator.un_alg_op_of_jsonop,Loc.annoted_of_yojson~filenames(e_of_yojson~filenamesf_mixf_id)a)|`List[`String"IF";cond;yes;no]->IF(Loc.annoted_of_yojson~filenames(bool_of_yojson~filenamesf_mixf_id)cond,Loc.annoted_of_yojson~filenames(e_of_yojson~filenamesf_mixf_id)yes,Loc.annoted_of_yojson~filenames(e_of_yojson~filenamesf_mixf_id)no)|x->(trySTATE_ALG_OP(Operator.state_alg_op_of_jsonx)withYojson.Basic.Util.Type_error_->(tryCONST(Nbr.of_yojsonx)withYojson.Basic.Util.Type_error_->raise(Yojson.Basic.Util.Type_error("Invalid Alg_expr",x))))andbool_of_yojson~filenamesf_mixf_id=function|`Boolb->ifbthenTRUEelseFALSE|`List[op;a]->UN_BOOL_OP(Operator.un_bool_op_of_jsonop,Loc.annoted_of_yojson~filenames(bool_of_yojson~filenamesf_mixf_id)a)|`List[op;a;b]asx->(tryBIN_BOOL_OP(Operator.bin_bool_op_of_jsonop,Loc.annoted_of_yojson~filenames(bool_of_yojson~filenamesf_mixf_id)a,Loc.annoted_of_yojson~filenames(bool_of_yojson~filenamesf_mixf_id)b)withYojson.Basic.Util.Type_error_->(tryCOMPARE_OP(Operator.compare_op_of_jsonop,Loc.annoted_of_yojson~filenames(e_of_yojson~filenamesf_mixf_id)a,Loc.annoted_of_yojson~filenames(e_of_yojson~filenamesf_mixf_id)b)withYojson.Basic.Util.Type_error_->raise(Yojson.Basic.Util.Type_error("Incorrect bool expr",x))))|x->raise(Yojson.Basic.Util.Type_error("Incorrect bool_expr",x))letrecprintpr_mixpr_tokpr_varf=function|CONSTn->Nbr.printfn|ALG_VARlab->pr_varflab|KAPPA_INSTANCEast->pr_mixfast|TOKEN_IDtk->Format.fprintff"|%a|"pr_toktk|STATE_ALG_OPop->Operator.print_state_alg_opfop|BIN_ALG_OP(op,(a,_),(b,_))->Operator.print_bin_alg_op(printpr_mixpr_tokpr_var)a(printpr_mixpr_tokpr_var)bfop|UN_ALG_OP(op,(a,_))->Format.fprintff"%a(%a)"Operator.print_un_alg_opop(printpr_mixpr_tokpr_var)a|IF((cond,_),(yes,_),(no,_))->Format.fprintff"%a [?] %a [:] %a"(print_boolpr_mixpr_tokpr_var)cond(printpr_mixpr_tokpr_var)yes(printpr_mixpr_tokpr_var)no|DIFF_TOKEN((expr,_),tok)->Format.fprintff"diff(%a,%a)"(printpr_mixpr_tokpr_var)exprpr_toktok|DIFF_KAPPA_INSTANCE((expr,_),mixture)->Format.fprintff"diff(%a,%a)"(printpr_mixpr_tokpr_var)exprpr_mixmixtureandprint_boolpr_mixpr_tokpr_varf=function|TRUE->Format.fprintff"[true]"|FALSE->Format.fprintff"[false]"|UN_BOOL_OP(op,(a,_))->Format.fprintff"%a (%a)"Operator.print_un_bool_opop(print_boolpr_mixpr_tokpr_var)a|BIN_BOOL_OP(op,(a,_),(b,_))->Format.fprintff"(%a %a %a)"(print_boolpr_mixpr_tokpr_var)aOperator.print_bin_bool_opop(print_boolpr_mixpr_tokpr_var)b|COMPARE_OP(op,(a,_),(b,_))->Format.fprintff"(%a %a %a)"(printpr_mixpr_tokpr_var)aOperator.print_compare_opop(printpr_mixpr_tokpr_var)bletconstn=Loc.annot_with_dummy(CONSTn)letinti=const(Nbr.Ii)letfloatf=const(Nbr.Ff)letadde1e2=Loc.annot_with_dummy(BIN_ALG_OP(Operator.SUM,e1,e2))letminuse1e2=Loc.annot_with_dummy(BIN_ALG_OP(Operator.MINUS,e1,e2))letmulte1e2=Loc.annot_with_dummy(BIN_ALG_OP(Operator.MULT,e1,e2))letdive1e2=Loc.annot_with_dummy(BIN_ALG_OP(Operator.DIV,e1,e2))letpowe1e2=Loc.annot_with_dummy(BIN_ALG_OP(Operator.POW,e1,e2))letloge1=Loc.annot_with_dummy(UN_ALG_OP(Operator.LOG,e1))letlne1=(* JF: If I rememnber well *)div(loge1)(log(int10))letsine1=Loc.annot_with_dummy(UN_ALG_OP(Operator.SINUS,e1))letcose1=Loc.annot_with_dummy(UN_ALG_OP(Operator.COSINUS,e1))letuminuse1=Loc.annot_with_dummy(UN_ALG_OP(Operator.UMINUS,e1))letsqrte1=Loc.annot_with_dummy(UN_ALG_OP(Operator.SQRT,e1))letrecadd_dep((in_t,in_e,toks_d,out)asx)d=function|BIN_ALG_OP(_,a,b),_->add_dep(add_depxda)db|(UN_ALG_OP(_,a)|DIFF_TOKEN(a,_)|DIFF_KAPPA_INSTANCE(a,_)),_(* when we differentiate against a variable, the result may depend on this variable only if the variable occurs in the differntiated expression *)->add_depxda|ALG_VARj,_->let()=out.(j)<-Operator.DepSet.adddout.(j)inx|(KAPPA_INSTANCE_|CONST_),_->x|TOKEN_IDi,_->let()=toks_d.(i)<-Operator.DepSet.adddtoks_d.(i)inx|IF(cond,yes,no),_->add_dep(add_dep(add_dep_boolxdcond)dyes)dno|STATE_ALG_OPop,_->(matchopwith|Operator.EMAX_VAR|Operator.TMAX_VAR->x|Operator.TIME_VAR->Operator.DepSet.adddin_t,in_e,toks_d,out|Operator.CPUTIME|Operator.EVENT_VAR|Operator.NULL_EVENT_VAR->in_t,Operator.DepSet.adddin_e,toks_d,out)andadd_dep_boolxd=function|(TRUE|FALSE),_->x|UN_BOOL_OP(_,a),_->add_dep_boolxda|BIN_BOOL_OP(_,a,b),_->add_dep_bool(add_dep_boolxda)db|COMPARE_OP(_,a,b),_->add_dep(add_depxda)dbletrechas_mix:typea.?var_decls:('b->('c,'b)e)->(a,'b)e->pervasives_bool=fun?var_decls->function|BIN_ALG_OP(_,(a,_),(b,_))->has_mix?var_declsa||has_mix?var_declsb|UN_ALG_OP(_,(a,_))|DIFF_TOKEN((a,_),_)|DIFF_KAPPA_INSTANCE((a,_),_)->(* when we differentiate against a variable, the result may depend on this variable only if the variable occurs in the differntiated expression *)has_mix?var_declsa|STATE_ALG_OP_|CONST_->false|TOKEN_ID_|KAPPA_INSTANCE_->true|IF((cond,_),(yes,_),(no,_))->has_mix?var_declsyes||has_mix?var_declsno||bool_has_mix?var_declscond|ALG_VARi->(matchvar_declswith|None->false|Somef->has_mix?var_decls(fi))andbool_has_mix:typea.?var_decls:('b->('c,'b)e)->(a,'b)bool->pervasives_bool=fun?var_decls->function|TRUE|FALSE->false|COMPARE_OP(_,(a,_),(b,_))->has_mix?var_declsa||has_mix?var_declsb|BIN_BOOL_OP(_,(a,_),(b,_))->bool_has_mix?var_declsa||bool_has_mix?var_declsb|UN_BOOL_OP(_,(a,_))->bool_has_mix?var_declsaletrecis_constant=function|CONST_,_->true|IF(a,b,c),_->bool_is_constanta&&is_constantb&&is_constantc|BIN_ALG_OP(_,a,b),_->is_constanta&&is_constantb|(UN_ALG_OP(_,a)|DIFF_KAPPA_INSTANCE(a,_)|DIFF_TOKEN(a,_)),_->is_constanta|(ALG_VAR_|STATE_ALG_OP_|TOKEN_ID_|KAPPA_INSTANCE_),_->falseandbool_is_constant=function|(TRUE|FALSE),_->true|COMPARE_OP(_,a,b),_->is_constanta&&is_constantb|BIN_BOOL_OP(_,a,b),_->bool_is_constanta&&bool_is_constantb|UN_BOOL_OP(_,a),_->bool_is_constantaletrecis_time_homogeneous=function|CONST_,_->true|IF(a,b,c),_->bool_is_time_homogeneousa&&is_time_homogeneousb&&is_time_homogeneousc|BIN_ALG_OP(_,a,b),_->is_time_homogeneousa&&is_time_homogeneousb|(UN_ALG_OP(_,a)|DIFF_KAPPA_INSTANCE(a,_)|DIFF_TOKEN(a,_)),_->is_time_homogeneousa|(STATE_ALG_OP(Operator.EVENT_VAR|Operator.CPUTIME|Operator.NULL_EVENT_VAR|Operator.TMAX_VAR|Operator.EMAX_VAR),_)|ALG_VAR_,_|TOKEN_ID_,_|KAPPA_INSTANCE_,_->true|STATE_ALG_OPOperator.TIME_VAR,_->falseandbool_is_time_homogeneous=function|(TRUE|FALSE),_->true|COMPARE_OP(_,a,b),_->is_time_homogeneousa&&is_time_homogeneousb|BIN_BOOL_OP(_,a,b),_->bool_is_time_homogeneousa&&bool_is_time_homogeneousb|UN_BOOL_OP(_,a),_->bool_is_time_homogeneousaletrecaux_extract_ccacc=function|BIN_ALG_OP(_,a,b),_->aux_extract_cc(aux_extract_ccacca)b|(UN_ALG_OP(_,a)|DIFF_TOKEN(a,_)|DIFF_KAPPA_INSTANCE(a,_)),_->aux_extract_ccacca|(ALG_VAR_|CONST_|TOKEN_ID_|STATE_ALG_OP_),_->acc|KAPPA_INSTANCEi,_->i::acc|IF(cond,yes,no),_->aux_extract_cc(aux_extract_cc(extract_cc_boolacccond)yes)noandextract_cc_boolacc=function|(TRUE|FALSE),_->acc|BIN_BOOL_OP(_,a,b),_->extract_cc_bool(extract_cc_boolacca)b|UN_BOOL_OP(_,a),_->extract_cc_boolacca|COMPARE_OP(_,a,b),_->aux_extract_cc(aux_extract_ccacca)bletextract_connected_componentsx=aux_extract_cc[]xletextract_connected_components_boolx=extract_cc_bool[]xletsetup_alg_vars_rev_deptoksvars=letin_t=Operator.DepSet.emptyinletin_e=Operator.DepSet.emptyinlettoks_d=Array.make(NamedDecls.sizetoks)Operator.DepSet.emptyinletout=Array.make(Array.lengthvars)Operator.DepSet.emptyinTools.array_fold_lefti(funix(_,y)->add_depx(Operator.ALGi)y)(in_t,in_e,toks_d,out)varsletrecpropagate_constant~warning?max_time?max_events~updated_vars~vars=function|(BIN_ALG_OP(op,a,b),pos)asx->(match(propagate_constant~warning?max_time?max_events~updated_vars~varsa,propagate_constant~warning?max_time?max_events~updated_vars~varsb)with|(CONSTc1,_),(CONSTc2,_)->CONST(Nbr.of_bin_alg_opopc1c2),pos|((((BIN_ALG_OP_|UN_ALG_OP_|STATE_ALG_OP_|KAPPA_INSTANCE_|DIFF_TOKEN_|DIFF_KAPPA_INSTANCE_|TOKEN_ID_|ALG_VAR_|CONST_|IF_),_)asa'),(((BIN_ALG_OP_|UN_ALG_OP_|STATE_ALG_OP_|KAPPA_INSTANCE_|DIFF_TOKEN_|DIFF_KAPPA_INSTANCE_|TOKEN_ID_|ALG_VAR_|CONST_|IF_),_)asb'))->ifa==a'&&b==b'thenxelseBIN_ALG_OP(op,a',b'),pos)|(UN_ALG_OP(op,a),pos)asx->(matchpropagate_constant~warning?max_time?max_events~updated_vars~varsawith|CONSTc,_->CONST(Nbr.of_un_alg_opopc),pos|((DIFF_TOKEN_|DIFF_KAPPA_INSTANCE_|BIN_ALG_OP_|UN_ALG_OP_|STATE_ALG_OP_|KAPPA_INSTANCE_|TOKEN_ID_|ALG_VAR_|IF_),_)asa'->ifa==a'thenxelseUN_ALG_OP(op,a'),pos)|(DIFF_TOKEN(a,t),pos)asx->(matchpropagate_constant~warning?max_time?max_events~updated_vars~varsawith|CONST_,_->(* the derivative of a constant is zero *)CONSTNbr.zero,pos|((DIFF_TOKEN_|DIFF_KAPPA_INSTANCE_|BIN_ALG_OP_|UN_ALG_OP_|IF_|STATE_ALG_OP_|KAPPA_INSTANCE_|TOKEN_ID_|ALG_VAR_),_)asa'->ifa==a'thenxelseDIFF_TOKEN(a',t),pos)|(DIFF_KAPPA_INSTANCE(a,m),pos)asx->(matchpropagate_constant~warning?max_time?max_events~updated_vars~varsawith|CONST_,_->(* the derivative of a constant is zero *)CONSTNbr.zero,pos|((DIFF_TOKEN_|DIFF_KAPPA_INSTANCE_|BIN_ALG_OP_|UN_ALG_OP_|STATE_ALG_OP_|KAPPA_INSTANCE_|TOKEN_ID_|ALG_VAR_|IF_),_)asa'->ifa==a'thenxelseDIFF_KAPPA_INSTANCE(a',m),pos)|STATE_ALG_OPOperator.EMAX_VAR,pos->(CONST(matchmax_eventswith|Somen->Nbr.In|None->let()=warning~pos(funf->Format.pp_print_stringf"[Emax] constant is evaluated to infinity")inNbr.Finfinity),pos)|STATE_ALG_OPOperator.TMAX_VAR,pos->(CONST(matchmax_timewith|Somet->Nbr.Ft|None->let()=warning~pos(funf->Format.pp_print_stringf"[Tmax] constant is evaluated to infinity")inNbr.Finfinity),pos)|(STATE_ALG_OP(Operator.CPUTIME|Operator.TIME_VAR|Operator.EVENT_VAR|Operator.NULL_EVENT_VAR),_)asx->x|(ALG_VARi,pos)asx->ifList.memiupdated_varsthenxelse(matchvars.(i)with|_,(((CONST_|ALG_VAR_)asy),_)->y,pos|(_,((BIN_ALG_OP_|UN_ALG_OP_|STATE_ALG_OP_|KAPPA_INSTANCE_|TOKEN_ID_|IF_|DIFF_KAPPA_INSTANCE_|DIFF_TOKEN_),_))->x)|((KAPPA_INSTANCE_|TOKEN_ID_|CONST_),_)asx->x|IF(cond,yes,no),pos->(matchpropagate_constant_bool~warning?max_time?max_events~updated_vars~varscondwith|TRUE,_->propagate_constant~warning?max_time?max_events~updated_vars~varsyes|FALSE,_->propagate_constant~warning?max_time?max_events~updated_vars~varsno|((BIN_BOOL_OP_|COMPARE_OP_|UN_BOOL_OP_),_)ascond'->(IF(cond',propagate_constant~warning?max_time?max_events~updated_vars~varsyes,propagate_constant~warning?max_time?max_events~updated_vars~varsno),pos))andpropagate_constant_bool~warning?max_time?max_events~updated_vars~vars=function|((TRUE|FALSE),_)asx->x|UN_BOOL_OP(op,a),pos->(match(propagate_constant_bool~warning?max_time?max_events~updated_vars~varsa,op)with|(TRUE,_),Operator.NOT->FALSE,pos|(FALSE,_),Operator.NOT->TRUE,pos|(((BIN_BOOL_OP_|COMPARE_OP_|UN_BOOL_OP_),_)asa'),_->UN_BOOL_OP(op,a'),pos)|BIN_BOOL_OP(op,a,b),pos->(match(propagate_constant_bool~warning?max_time?max_events~updated_vars~varsa,op)with|(TRUE,_),Operator.OR->TRUE,pos|(FALSE,_),Operator.AND->FALSE,pos|(TRUE,_),Operator.AND|(FALSE,_),Operator.OR->propagate_constant_bool~warning?max_time?max_events~updated_vars~varsb|(((BIN_BOOL_OP_|COMPARE_OP_|UN_BOOL_OP_),_)asa'),_->(match(propagate_constant_bool~warning?max_time?max_events~updated_vars~varsb,op)with|(TRUE,_),Operator.OR->TRUE,pos|(FALSE,_),Operator.AND->FALSE,pos|(TRUE,_),Operator.AND|(FALSE,_),Operator.OR->a'|(((BIN_BOOL_OP_|COMPARE_OP_|UN_BOOL_OP_),_)asb'),_->BIN_BOOL_OP(op,a',b'),pos))|COMPARE_OP(op,a,b),pos->leta'=propagate_constant~warning?max_time?max_events~updated_vars~varsainletb'=propagate_constant~warning?max_time?max_events~updated_vars~varsbin(matcha',b'with|(CONSTn1,_),(CONSTn2,_)->ifNbr.of_compare_opopn1n2thenTRUE,poselseFALSE,pos|(((DIFF_KAPPA_INSTANCE_|DIFF_TOKEN_|BIN_ALG_OP_|UN_ALG_OP_|STATE_ALG_OP_|ALG_VAR_|KAPPA_INSTANCE_|TOKEN_ID_|CONST_|IF_),_),_)->COMPARE_OP(op,a',b'),pos)letrechas_progress_dep~only_time((in_t,_,_,deps)asvars_deps)=function|BIN_ALG_OP(_,a,b),_->has_progress_dep~only_timevars_depsa||has_progress_dep~only_timevars_depsb|(UN_ALG_OP(_,a)|DIFF_TOKEN(a,_)|DIFF_KAPPA_INSTANCE(a,_)),_->has_progress_dep~only_timevars_depsa|(KAPPA_INSTANCE_|TOKEN_ID_|CONST_),_->false|STATE_ALG_OPOperator.TIME_VAR,_->true|STATE_ALG_OPOperator.EVENT_VAR,_->notonly_time|(STATE_ALG_OP(Operator.CPUTIME|Operator.NULL_EVENT_VAR|Operator.EMAX_VAR|Operator.TMAX_VAR),_)->false|ALG_VARi,_->letrecauxj=Operator.DepSet.mem(Operator.ALGj)in_t||Operator.DepSet.exists(function|Operator.ALGk->auxk|Operator.RULE_|Operator.MODIF_->false)deps.(j)inauxi|IF(cond,yes,no),_->bool_has_progress_dep~only_timevars_depscond||has_progress_dep~only_timevars_depsyes||has_progress_dep~only_timevars_depsnoandbool_has_progress_dep~only_timevars_deps=function|(TRUE|FALSE),_->false|COMPARE_OP(_,a,b),_->has_progress_dep~only_timevars_depsa||has_progress_dep~only_timevars_depsb|BIN_BOOL_OP(_,a,b),_->bool_has_progress_dep~only_timevars_depsa||bool_has_progress_dep~only_timevars_depsb|UN_BOOL_OP(_,a),_->bool_has_progress_dep~only_timevars_depsaletrecis_equality_test_timevars_deps=function|TRUE|FALSE->false|UN_BOOL_OP(Operator.NOT,(a,_))->is_equality_test_timevars_depsa|BIN_BOOL_OP(_,(a,_),(b,_))->is_equality_test_timevars_depsa||is_equality_test_timevars_depsb|COMPARE_OP(op,a,b)->letonly_time=truein(matchopwith|Operator.EQUALwhenhas_progress_dep~only_timevars_depsa||has_progress_dep~only_timevars_depsb->true|Operator.EQUAL|Operator.SMALLER|Operator.GREATER|Operator.DIFF->false)letrecmap_on_mixturef=function|KAPPA_INSTANCEi,p->fi,p|DIFF_KAPPA_INSTANCE_,_->failwith"Alg_expr.map_on_mixture doesn't know what to do of DIFF_KAPPA_INSTANCE"|(CONST_,_)asx->x|(ALG_VAR_,_)asx->x|(TOKEN_ID_,_)asx->x|DIFF_TOKEN(a,i),p->DIFF_TOKEN(map_on_mixturefa,i),p|(STATE_ALG_OP_,_)asx->x|BIN_ALG_OP(o,x,y),p->BIN_ALG_OP(o,map_on_mixturefx,map_on_mixturefy),p|UN_ALG_OP(o,x),p->UN_ALG_OP(o,map_on_mixturefx),p|IF(b,x,y),p->IF(map_bool_on_mixturefb,map_on_mixturefx,map_on_mixturefy),pandmap_bool_on_mixturef=function|(TRUE,_)asx->x|(FALSE,_)asx->x|BIN_BOOL_OP(o,x,y),p->BIN_BOOL_OP(o,map_bool_on_mixturefx,map_bool_on_mixturefy),p|UN_BOOL_OP(o,x),p->UN_BOOL_OP(o,map_bool_on_mixturefx),p|COMPARE_OP(o,x,y),p->COMPARE_OP(o,map_on_mixturefx,map_on_mixturefy),pletrecfold_on_mixturefx=function|KAPPA_INSTANCEi,_->fxi|DIFF_KAPPA_INSTANCE_,_->failwith"Alg_expr.fold_on_mixture doesn't know what to do of DIFF_KAPPA_INSTANCE"|CONST_,_->x|ALG_VAR_,_->x|TOKEN_ID_,_->x|DIFF_TOKEN(a,_),_->fold_on_mixturefxa|STATE_ALG_OP_,_->x|BIN_ALG_OP(_,a,b),_->fold_on_mixturef(fold_on_mixturefxa)b|UN_ALG_OP(_,a),_->fold_on_mixturefxa|IF(b,u,v),_->fold_bool_on_mixturef(fold_on_mixturef(fold_on_mixturefxu)v)bandfold_bool_on_mixturefx=function|TRUE,_->x|FALSE,_->x|BIN_BOOL_OP(_,a,b),_->fold_bool_on_mixturef(fold_bool_on_mixturefxa)b|UN_BOOL_OP(_,a),_->fold_bool_on_mixturefxa|COMPARE_OP(_,a,b),_->fold_on_mixturef(fold_on_mixturefxa)bletrecequalab=matcha,bwith|(BIN_ALG_OP(opa,a1,a2),_),(BIN_ALG_OP(opb,b1,b2),_)->opa=opb&&equala1b1&&equala2b2|((BIN_ALG_OP_,_),((UN_ALG_OP_|STATE_ALG_OP_|ALG_VAR_|KAPPA_INSTANCE_|TOKEN_ID_|CONST_|IF_),_))|(((UN_ALG_OP_|STATE_ALG_OP_|ALG_VAR_|KAPPA_INSTANCE_|TOKEN_ID_|CONST_|IF_),_),(BIN_ALG_OP_,_))->false|(UN_ALG_OP(opa,a1),_),(UN_ALG_OP(opb,b1),_)->opa=opb&&equala1b1|((UN_ALG_OP_,_),((STATE_ALG_OP_|ALG_VAR_|KAPPA_INSTANCE_|TOKEN_ID_|CONST_|IF_),_))|(((STATE_ALG_OP_|ALG_VAR_|KAPPA_INSTANCE_|TOKEN_ID_|CONST_|IF_),_),(UN_ALG_OP_,_))->false|(STATE_ALG_OPopa,_),(STATE_ALG_OPopb,_)->opa=opb|((STATE_ALG_OP_,_),((ALG_VAR_|KAPPA_INSTANCE_|TOKEN_ID_|CONST_|IF_),_))|(((ALG_VAR_|KAPPA_INSTANCE_|TOKEN_ID_|CONST_|IF_),_),(STATE_ALG_OP_,_))->false|(ALG_VARid1,_),(ALG_VARid2,_)->id1=id2|(ALG_VAR_,_),((KAPPA_INSTANCE_|TOKEN_ID_|CONST_|IF_),_)|((KAPPA_INSTANCE_|TOKEN_ID_|CONST_|IF_),_),(ALG_VAR_,_)->false|(KAPPA_INSTANCEmix1,_),(KAPPA_INSTANCEmix2,_)->mix1=mix2|(KAPPA_INSTANCE_,_),((TOKEN_ID_|CONST_|IF_),_)|((TOKEN_ID_|CONST_|IF_),_),(KAPPA_INSTANCE_,_)->false|(TOKEN_IDid1,_),(TOKEN_IDid2,_)->id1=id2|(TOKEN_ID_,_),((CONST_|IF_),_)|((CONST_|IF_),_),(TOKEN_ID_,_)->false|(CONSTc1,_),(CONSTc2,_)->Nbr.is_equalc1c2|(CONST_,_),(IF_,_)|(IF_,_),(CONST_,_)->false|(IF(conda,a1,a2),_),(IF(condb,b1,b2),_)->equal_boolcondacondb&&equala1b1&&equala2b2|((DIFF_TOKEN_|DIFF_KAPPA_INSTANCE_),_),_|_,((DIFF_TOKEN_|DIFF_KAPPA_INSTANCE_),_)->assertfalseandequal_boolab=matcha,bwith|(TRUE,_),(TRUE,_)->true|(TRUE,_),((FALSE|BIN_BOOL_OP_|COMPARE_OP_|UN_BOOL_OP_),_)|((FALSE|BIN_BOOL_OP_|COMPARE_OP_|UN_BOOL_OP_),_),(TRUE,_)->false|(FALSE,_),(FALSE,_)->true|(FALSE,_),((BIN_BOOL_OP_|COMPARE_OP_|UN_BOOL_OP_),_)|((BIN_BOOL_OP_|COMPARE_OP_|UN_BOOL_OP_),_),(FALSE,_)->false|(UN_BOOL_OP(opa,a),_),(UN_BOOL_OP(opb,b),_)->opa=opb&&equal_boolab|(UN_BOOL_OP_,_),((BIN_BOOL_OP_|COMPARE_OP_),_)|((BIN_BOOL_OP_|COMPARE_OP_),_),(UN_BOOL_OP_,_)->false|(BIN_BOOL_OP(opa,a1,a2),_),(BIN_BOOL_OP(opb,b1,b2),_)->opa=opb&&equal_boola1b1&&equal_boola2b2|(BIN_BOOL_OP_,_),(COMPARE_OP_,_)|(COMPARE_OP_,_),(BIN_BOOL_OP_,_)->false|(COMPARE_OP(opa,a1,a2),_),(COMPARE_OP(opb,b1,b2),_)->opa=opb&&equala1b1&&equala2b2