123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603(*A module for parsing SBML level 2 version 4*)exceptionBadofstringletraise_badmsg=raise(Badmsg)typesb_math_operator=(* arithmetics *)|MPlus(* a + b *)|MMinus(* a - b *)|MTimes(* a * b *)|MDivide(* a / b *)|MPower(* a ^ b *)|MRoot(* a^(1/b) *)|MAbs(* |a| *)|MExp(* e^a *)|MLn(* ln a *)|MLog(* log a,b *)|MFloor(* floor a *)|MCeiling(* ceil a *)|MFactorial(* a! *)(* relational *)|MEq(* a == b *)|MNeq(* a != b *)|MGt(* a > b *)|MLt(* a < b *)|MGeq(* a >= b *)|MLeq(* a <= b *)(* logic *)|MAnd(* a & b *)|MOr(* a | b *)|MXor(* a ^^ b *)|MNot(* !a *)(*trigonometry*)|MSin|MCos|MTan|MArcsin|MArccos|MArctan(*delay a,b - see SBML spec *)|MDelay(*user-defined functions*)|MFundefofstringtypesb_math=(* composite *)|MApplyofsb_math_operator*(sb_mathlist)|MLambdaof(stringlist)*sb_math|MPiecewiseof((string*sb_math)list)*string(* tokens *)|MFloatNumberoffloat|MIntNumberofint|MIdentifierofstring|MTime(* simulation time - see SBML spec*)|MTrue|MFalse|MNAN|MPi|MExponent|MInfinity|MNoMathtypesb_unit={unit_kind:string;unit_exponent:int;unit_scale:int;unit_multiplier:float;}typesb_function_definition={fundef_id:string;fundef_name:string;fundef_math:sb_math;}typesb_unit_definition={unitdef_id:string;unitdef_name:string;unitdef_unitlist:sb_unitlist;}typesb_compartment={compart_id:string;compart_name:string;compart_spatialDimensions:int;compart_size:float;compart_units:string;compart_outside:string;compart_constant:bool;}typesb_species_ref={specref_species:string;specref_id:string;specref_name:string;specref_stoichiometry:int;(* TODO variant stoichiometry | stoichiometryMath *)}typesb_species={species_id:string;species_name:string;species_type:string;species_compartment:string;species_initialAmount:float;species_initialConcentration:float;species_substanceUnits:string;species_hasOnlySubstanceUnits:bool;species_boundaryCondition:bool;species_constant:bool;}typesb_parameter={param_id:string;param_name:string;param_value:float;param_units:string;param_constant:bool;}typesb_kinetic_law={klaw_math:sb_math;klaw_parameters:sb_parameterlist;}typesb_reaction={react_id:string;react_name:string;react_boundaryCondition:bool;react_fast:bool;react_reactants:sb_species_reflist;react_products:sb_species_reflist;react_kineticLaw:sb_kinetic_law;}typesb_initial_assignment={ia_symbol:string;ia_math:sb_math;}typesb_algebraic_rule={ar_math:sb_math;}typesb_generic_rule={gr_variable:string;gr_math:sb_math;}typesb_rule=RateRuleofsb_generic_rule|AssignmentRuleofsb_generic_rule|AlgebraicRuleofsb_algebraic_ruletypesb_math_container={math:sb_math;}typesb_delay=Delayofsb_math_containertypesb_trigger=Triggerofsb_math_containertypesb_event_assignment={ea_variable:string;ea_math:sb_math;}typesb_event={event_id:string;event_name:string;event_useValuesFromTriggerTime:bool;event_trigger:sb_trigger;event_delay:sb_delay;event_assignments:sb_event_assignmentlist;}(*a wrapper type to deal with heterogeneous lists*)typesb_L=LFunctionDefinitionofsb_function_definition|LUnitDefinitionofsb_unit_definition|LCompartmentofsb_compartment|LSpeciesofsb_species|LReactionofsb_reaction|LParameterofsb_parameter|LInitialAssignmentofsb_initial_assignment|LRuleofsb_rule|LEventofsb_event|LEventAssignmentofsb_event_assignment|LSpecieRefofsb_species_ref|LUnitofsb_unittypesb_model={sbm_id:string;sbm_name:string;sbm_functionDefinitions:sb_function_definitionlist;sbm_unitDefinitions:sb_unit_definitionlist;sbm_compartments:sb_compartmentlist;sbm_species:sb_specieslist;sbm_reactions:sb_reactionlist;sbm_parameters:sb_parameterlist;sbm_initialAssignments:sb_initial_assignmentlist;sbm_rules:sb_rulelist;sbm_events:sb_eventlist;(*could not find test xmls for these*)(*constraints : sb_constraint list;
compartmentTypes : sb_compartment_type list;
speciesTypes : sb_species_type list;*)}letignore_inputi=ignore(Xmlm.inputi:Xmlm.signal)moduleMathML=struct(* MathML prettyprinting *)letrecmath_to_stringmath=letoperator_to_stringoper=matchoperwith|MPlus->"+"|MMinus->"-"|MTimes->"*"|MPower->"^"|MAbs->"ABS"|MExp->"EXP"|MFactorial->"FACTORIAL"|MCeiling->"CEILING"|MLt->"<"|MGt->">"|MLeq->"<="|MGeq->">="|MDelay->"DELAY"|MFundefoper->oper|_->raise_bad"can't convert unknown operator"inmatchmathwith|MApply(oper,exprlist)->"("^(operator_to_stringoper)^" "^(String.concat~sep:" "(List.map~f:math_to_stringexprlist))^")"|MLambda(bvarlist,lambda_expr)->"(LAMBDA ("^(String.concat~sep:" "bvarlist)^") "^(math_to_stringlambda_expr)^")"|MPiecewise(piecelist,otherwise)->"(PIECEWISE "^(String.concat~sep:" "(List.map~f:(funnext->let(var,varexpr)=nextin"("^(math_to_stringvarexpr)^" "^var^")")piecelist))^" "^otherwise^")"|MFloatNumberf->(string_of_floatf)|MIntNumberi->(string_of_inti)|MIdentifiers->s|MTime->"<time>"|MExponent->"e"|MNoMath->"/no math/"|_->raise_bad"can't convert unknown math expr"(* MathML parsing *)letextract_stringideptherrmsg=letrecskip_tagsidepth=ifdepth>0thenbeginignore_inputi;skip_tagsi(depth-1)endelse()inskip_tagsidepth;letresult=matchXmlm.inputiwith|`Datadat->dat|_->raise_baderrmsginskip_tagsidepth;resultletunpack_strings=matchswith|MIdentifier(str)->str|_->raise_bad"not a packed string"letunpack_symbol_typeattrs=let(_,sbmlUrl)=List.find_exn~f:(funnext->let((_,tag),_)=nextinString.equaltag"definitionURL")attrsinletsplitUrl=String.split~on:'/'sbmlUrlinList.nth_exnsplitUrl(List.lengthsplitUrl-1)letparse_bvarlisti=letrecbvarlist_iteribvarlist=matchXmlm.peekiwith|`El_start((_,"bvar"),_)->bvarlist_iteri((extract_stringi2"malformed lambda expr in bvar")::bvarlist)|`El_start((_,_),_)->bvarlist|_->raise_bad"malformed lambda expr in bvar list"inList.rev(bvarlist_iteri[])letrecparse_mathexpri=letrecmathexpr_iteriformula=matchXmlm.inputiwith|`El_start((_,"apply"),_)->letoperator=parse_operatoriinletexprlist=parse_exprlistiinmathexpr_iteri(MApply(operator,exprlist))|`El_start((_,"lambda"),_)->letbvars=parse_bvarlistiinletlambda_expr=parse_mathexpriinmathexpr_iteri(MLambda(bvars,lambda_expr))|`El_start((_,"piecewise"),_)->letpieces=parse_piecelistiinletotherwise=extract_stringi2"malformed otherwise expr"inmathexpr_iteri(MPiecewise(pieces,otherwise))|`El_start((_,"ci"),_)->mathexpr_iteri(MIdentifier(unpack_string(parse_mathexpri)))|`El_start((_,"cn"),attrs)->if(List.lengthattrs)=1thenmatchList.hd_exnattrswith|((_,"type"),"integer")->mathexpr_iteri(MIntNumber(int_of_string(unpack_string(parse_mathexpri))))|((_,"type"),"e-notation")->mathexpr_iteri(MFloatNumber(float_of_string(unpack_string(parse_mathexpri))))|((_,_),_)->raise_bad"malformed cn tag"elsemathexpr_iteri(MFloatNumber(float_of_string(unpack_string(parse_mathexpri))))|`El_start((_,"sep"),_)->mathexpr_iteri(MIdentifier((unpack_string(formula))^"e"^(unpack_string(parse_mathexpri))))|`El_start((_,"csymbol"),attrs)->ifString.equal(unpack_symbol_typeattrs)"time"thenbeginignore_inputi;mathexpr_iteri(MTime)endelseraise_bad"malformed csymbol expr"|`El_start((_,"exponentiale"),_)->mathexpr_iteri(MExponent)(* add more tokens *)|`El_start((_,tag),_)->print_endlinetag;raise_bad"unknown math tag"|`Datadat->MIdentifier(dat)|`El_end->formula|`Dtd_->assertfalseinmathexpr_iteriMNoMathandparse_operatori=letoper=matchXmlm.inputiwith|`El_start((_,"plus"),_)->MPlus|`El_start((_,"minus"),_)->MMinus|`El_start((_,"times"),_)->MTimes|`El_start((_,"power"),_)->MPower|`El_start((_,"abs"),_)->MAbs|`El_start((_,"exp"),_)->MExp|`El_start((_,"factorial"),_)->MFactorial|`El_start((_,"ceiling"),_)->MCeiling|`El_start((_,"lt"),_)->MLt|`El_start((_,"gt"),_)->MGt|`El_start((_,"leq"),_)->MLeq|`El_start((_,"geq"),_)->MGeq(* add more operators *)|`El_start((_,"csymbol"),attrs)->ifString.equal(unpack_symbol_typeattrs)"delay"thenbeginignore_inputi;MDelayendelseraise_bad"malformed csymbol expr"(* assume a user-defined function in functionDefinition*)|`El_start((_,"ci"),_)->MFundef(unpack_string(parse_mathexpri))|_->raise_bad"malformed apply expr"inignore_inputi;operandparse_exprlisti=letrecexprlist_iteriexprlist=matchXmlm.peekiwith|`El_start((_,_),_)->exprlist_iteri((parse_mathexpri)::exprlist)|`El_end->exprlist|_->raise_bad"malformed mathml in apply"inList.rev(exprlist_iteri[])andparse_piecelisti=letrecpiecelist_iteripiecelist=matchXmlm.peekiwith|`El_start((_,"piece"),_)->ignore_inputi;letpiece_var=extract_stringi1"malformed piece expr"inletpiece_expr=parse_mathexpriinignore_inputi;piecelist_iteri((piece_var,piece_expr)::piecelist)|`El_start((_,"otherwise"),_)->piecelist|_->raise_bad"malformed piecewise expr"inList.rev(piecelist_iteri[])letparse_math_i=letsbm=parse_mathexpriinignore_inputi;(*math tag end*)sbmendletparse_math=MathML.parse_mathletmath_to_string=MathML.math_to_stringmoduleSBMLParser=struct(*abstract stuff for lists and attributes*)letstore_attrsattrs=letparse_hash=Caml.Hashtbl.create10inletstore_attrattr=matchattrwith|((_,nam),value)->Caml.Hashtbl.addparse_hashnamvalueinList.iter~f:store_attrattrs;parse_hashletparse_listiassoclist=letreciter_listitemplist=matchXmlm.inputiwith|`El_start((_,tagname),attrs)->iter_listi((try((Caml.List.assoctagnameassoclist)attrsi)withCaml.Not_found->raise_badtagname)::templist)|`El_end->templist|`Data_->iter_listitemplist|`Dtd_->assertfalseiniter_listi[]letparse_recordilist_dictrecord_dict=letlist_hash=Caml.Hashtbl.create10inletrecord_hash=Caml.Hashtbl.create10inletreciter_recordi=matchXmlm.inputiwith|`El_start((_,tagname),attrs)->(if(String.compare(String.subtagname~pos:0~len:4)"list")=0then(try(Caml.Hashtbl.addlist_hashtagname(parse_listi(Caml.List.assoctagnamelist_dict)))withCaml.Not_found->raise_badtagname)else(try(Caml.Hashtbl.addrecord_hashtagname((Caml.List.assoctagnamerecord_dict)attrsi))withCaml.Not_found->raise_badtagname));iter_recordi|`El_end->()|`Data_->iter_recordi|`Dtd_->assertfalseiniter_recordi;(list_hash,record_hash)(*leaf record parsing, 'ignore_input i' is for skipping tag's end *)letparse_unitattrsi=ignore_inputi;letparse_hash=store_attrsattrsinLUnit({unit_kind=(Caml.Hashtbl.findparse_hash"kind");unit_exponent=(try(int_of_string(Caml.Hashtbl.findparse_hash"exponent"))withCaml.Not_found->1);unit_scale=(tryint_of_string(Caml.Hashtbl.findparse_hash"scale")withCaml.Not_found->0);unit_multiplier=(try(float_of_string(Caml.Hashtbl.findparse_hash"multiplier"))withCaml.Not_found->1.0)})letparse_compartmentattrsi=ignore_inputi;letparse_hash=store_attrsattrsinLCompartment({compart_id=(Caml.Hashtbl.findparse_hash"id");compart_name=(try(Caml.Hashtbl.findparse_hash"name")withCaml.Not_found->"");compart_size=(try(float_of_string(Caml.Hashtbl.findparse_hash"size"))withCaml.Not_found->0.0);compart_spatialDimensions=(try(int_of_string(Caml.Hashtbl.findparse_hash"spatialDimensions"))withCaml.Not_found->3);compart_units=(try(Caml.Hashtbl.findparse_hash"units")withCaml.Not_found->"");compart_outside=(try(Caml.Hashtbl.findparse_hash"outside")withCaml.Not_found->"");compart_constant=(try(bool_of_string(Caml.Hashtbl.findparse_hash"constant"))withCaml.Not_found->true);})letparse_speciesattrsi=ignore_inputi;letparse_hash=store_attrsattrsinLSpecies({species_id=(Caml.Hashtbl.findparse_hash"id");species_name=(try(Caml.Hashtbl.findparse_hash"name")withCaml.Not_found->"");species_type=(try(Caml.Hashtbl.findparse_hash"speciesType")withCaml.Not_found->"");species_compartment=(Caml.Hashtbl.findparse_hash"compartment");species_initialAmount=(try(float_of_string(Caml.Hashtbl.findparse_hash"initialAmount"))withCaml.Not_found->0.0);species_initialConcentration=(try(float_of_string(Caml.Hashtbl.findparse_hash"initialConcentration"))withCaml.Not_found->0.0);species_substanceUnits=(try(Caml.Hashtbl.findparse_hash"substanceUnits")withCaml.Not_found->"");species_hasOnlySubstanceUnits=(try(bool_of_string(Caml.Hashtbl.findparse_hash"hasOnlySubstanceUnits"))withCaml.Not_found->false);species_boundaryCondition=(try(bool_of_string(Caml.Hashtbl.findparse_hash"boundaryCondition"))withCaml.Not_found->false);species_constant=(try(bool_of_string(Caml.Hashtbl.findparse_hash"constant"))withCaml.Not_found->false);})letparse_spreferenceattrsi=ignore_inputi;letparse_hash=store_attrsattrsinLSpecieRef({specref_species=(Caml.Hashtbl.findparse_hash"species");specref_id=(try(Caml.Hashtbl.findparse_hash"id")withCaml.Not_found->"");specref_name=(try(Caml.Hashtbl.findparse_hash"name")withCaml.Not_found->"");specref_stoichiometry=(try(int_of_string(Caml.Hashtbl.findparse_hash"stoichiometry"))withCaml.Not_found->1)})letparse_parameterattrsi=ignore_inputi;letparse_hash=store_attrsattrsinLParameter({param_id=(try(Caml.Hashtbl.findparse_hash"id")withCaml.Not_found->raise_bad"no id for parameter");param_name=(try(Caml.Hashtbl.findparse_hash"name")withCaml.Not_found->"");param_value=(try(float_of_string(Caml.Hashtbl.findparse_hash"value"))withCaml.Not_found->0.0);param_units=(try(Caml.Hashtbl.findparse_hash"units")withCaml.Not_found->"");param_constant=(try(bool_of_string(Caml.Hashtbl.findparse_hash"constant"))withCaml.Not_found->true);})(*container record parsing*)letparse_fundefattrsi=letparse_hash=store_attrsattrsinlet(_,record_hash)=parse_recordi[][("math",parse_math)]inLFunctionDefinition({fundef_id=(Caml.Hashtbl.findparse_hash"id");fundef_name=(try(Caml.Hashtbl.findparse_hash"name")withCaml.Not_found->"");fundef_math=(try(Caml.Hashtbl.findrecord_hash"math")withCaml.Not_found->MNoMath);})letparse_unitdefattrsi=letparse_hash=store_attrsattrsinlet(_,record_hash)=parse_recordi[("listOfUnits",[("unit",parse_unit)])][]inLUnitDefinition({unitdef_id=(Caml.Hashtbl.findparse_hash"id");unitdef_name=(try(Caml.Hashtbl.findparse_hash"name")withCaml.Not_found->"");unitdef_unitlist=(try(List.rev_map~f:(functionLUnit(t)->t|_->raise_bad"unit")(Caml.Hashtbl.findrecord_hash"listOfUnits"))withCaml.Not_found->[]);})letparse_iassignmentattrsi=letparse_hash=store_attrsattrsinlet_,record_hash=parse_recordi[]["math",parse_math]inLInitialAssignment({ia_symbol=(Caml.Hashtbl.findparse_hash"symbol");ia_math=(try(Caml.Hashtbl.findrecord_hash"math")withCaml.Not_found->MNoMath);})letparse_generic_ruleattrsi=letparse_hash=store_attrsattrsinlet_,record_hash=parse_recordi[]["math",parse_math]in{gr_variable=(Caml.Hashtbl.findparse_hash"variable");gr_math=(try(Caml.Hashtbl.findrecord_hash"math")withCaml.Not_found->MNoMath);}letparse_algebraic_rule_i=let_,record_hash=parse_recordi[]["math",parse_math]inLRule(AlgebraicRule({ar_math=(try(Caml.Hashtbl.findrecord_hash"math")withCaml.Not_found->MNoMath);}))letparse_assignment_ruleattrsi=LRule(AssignmentRule(parse_generic_ruleattrsi))letparse_rate_ruleattrsi=LRule(RateRule(parse_generic_ruleattrsi))letparse_kineticlaw_i=let(list_hash,record_hash)=(parse_recordi[("listOfParameters",[("parameter",parse_parameter)])][("math",parse_math)])in{klaw_parameters=(try(List.rev_map~f:(functionLParameter(t)->t|_->raise_bad"parameter")(Caml.Hashtbl.findlist_hash"listOfParameters"))withCaml.Not_found->[]);klaw_math=(try(Caml.Hashtbl.findrecord_hash"math")withCaml.Not_found->MNoMath);}letparse_reactionattrsi=letparse_hash=store_attrsattrsinlet(list_hash,record_hash)=(parse_recordi[("listOfReactants",[("speciesReference",parse_spreference)]);("listOfProducts",[("speciesReference",parse_spreference)])][("kineticLaw",parse_kineticlaw)])inLReaction({react_id=(Caml.Hashtbl.findparse_hash"id");react_name=(try(Caml.Hashtbl.findparse_hash"name")withCaml.Not_found->"");react_boundaryCondition=(try(bool_of_string(Caml.Hashtbl.findparse_hash"reversible"))withCaml.Not_found->true);react_fast=(try(bool_of_string(Caml.Hashtbl.findparse_hash"fast"))withCaml.Not_found->false);react_reactants=(try(List.rev_map~f:(functionLSpecieRef(t)->t|_->raise_bad"malformed specieReference")(Caml.Hashtbl.findlist_hash"listOfReactants"))withCaml.Not_found->[]);react_products=(try(List.rev_map~f:(functionLSpecieRef(t)->t|_->raise_bad"malformed specieReference")(Caml.Hashtbl.findlist_hash"listOfProducts"))withCaml.Not_found->[]);react_kineticLaw=(try(Caml.Hashtbl.findrecord_hash"kineticLaw")withCaml.Not_found->{klaw_parameters=[];klaw_math=MNoMath});})letparse_eassignmentattrsi=letparse_hash=store_attrsattrsinlet_,record_hash=parse_recordi[]["math",parse_math]inLEventAssignment({ea_variable=(Caml.Hashtbl.findparse_hash"variable");ea_math=(try(Caml.Hashtbl.findrecord_hash"math")withCaml.Not_found->MNoMath);})letparse_math_container_i=let_,record_hash=parse_recordi[]["math",parse_math]in{math=(try(Caml.Hashtbl.findrecord_hash"math")withCaml.Not_found->MNoMath);}letparse_eventattrsi=letparse_hash=store_attrsattrsinlet(list_hash,record_hash)=(parse_recordi[("listOfEventAssignments",[("eventAssignment",parse_eassignment)])][("trigger",parse_math_container);("delay",parse_math_container)])inLEvent({event_id=(try(Caml.Hashtbl.findparse_hash"id")withCaml.Not_found->"");event_name=(try(Caml.Hashtbl.findparse_hash"name")withCaml.Not_found->"");event_useValuesFromTriggerTime=(try(bool_of_string(Caml.Hashtbl.findparse_hash"useValuesFromTriggerTime"))withCaml.Not_found->true);event_trigger=(tryTrigger(Caml.Hashtbl.findrecord_hash"trigger")withCaml.Not_found->raise_bad"trigger not found in event");event_delay=(tryDelay(Caml.Hashtbl.findrecord_hash"delay")withCaml.Not_found->Delay({math=MNoMath}));event_assignments=(try(List.rev_map~f:(functionLEventAssignment(t)->t|_->raise_bad"malformed eventAssignment")(Caml.Hashtbl.findlist_hash"listOfEventAssignments"))withCaml.Not_found->[]);})letparse_modelattrsi=letparse_hash=store_attrsattrsinletlist_hash,_=parse_recordi[("listOfFunctionDefinitions",[("functionDefinition",parse_fundef)]);("listOfUnitDefinitions",[("unitDefinition",parse_unitdef)]);("listOfCompartments",[("compartment",parse_compartment)]);("listOfSpecies",[("species",parse_species)]);("listOfReactions",[("reaction",parse_reaction)]);("listOfParameters",[("parameter",parse_parameter)]);("listOfInitialAssignments",[("initialAssignment",parse_iassignment)]);("listOfRules",[("assignmentRule",parse_assignment_rule);("rateRule",parse_rate_rule);("algebraicRule",parse_algebraic_rule)]);("listOfEvents",[("event",parse_event)])][]in{sbm_id=(try(Caml.Hashtbl.findparse_hash"id")withCaml.Not_found->"");sbm_name=(try(Caml.Hashtbl.findparse_hash"name")withCaml.Not_found->"");sbm_functionDefinitions=(try(List.rev_map~f:(functionLFunctionDefinition(t)->t|_->raise_bad"malformed functionDefinition")(Caml.Hashtbl.findlist_hash"listOfFunctionDefinitions"))withCaml.Not_found->[]);sbm_unitDefinitions=(try(List.rev_map~f:(functionLUnitDefinition(t)->t|_->raise_bad"malformed unitDefinition")(Caml.Hashtbl.findlist_hash"listOfUnitDefinitions"))withCaml.Not_found->[]);sbm_compartments=(try(List.rev_map~f:(functionLCompartment(t)->t|_->raise_bad"malformed compartment")(Caml.Hashtbl.findlist_hash"listOfCompartments"))withCaml.Not_found->[]);sbm_species=(try(List.rev_map~f:(functionLSpecies(t)->t|_->raise_bad"malformed species")(Caml.Hashtbl.findlist_hash"listOfSpecies"))withCaml.Not_found->[]);sbm_reactions=(try(List.rev_map~f:(functionLReaction(t)->t|_->raise_bad"malformed reaction")(Caml.Hashtbl.findlist_hash"listOfReactions"))withCaml.Not_found->[]);sbm_parameters=(try(List.rev_map~f:(functionLParameter(t)->t|_->raise_bad"malformed parameter")(Caml.Hashtbl.findlist_hash"listOfParameters"))withCaml.Not_found->[]);sbm_initialAssignments=(try(List.rev_map~f:(functionLInitialAssignment(t)->t|_->raise_bad"malformed initialAssignment")(Caml.Hashtbl.findlist_hash"listOfInitialAssignments"))withCaml.Not_found->[]);sbm_rules=(try(List.rev_map~f:(functionLRule(t)->t|_->raise_bad"malformed rule")(Caml.Hashtbl.findlist_hash"listOfRules"))withCaml.Not_found->[]);sbm_events=(try(List.rev_map~f:(functionLEvent(t)->t|_->raise_bad"malformed event")(Caml.Hashtbl.findlist_hash"listOfEvents"))withCaml.Not_found->[]);}(*reader function*)letin_sbmlichan=leti=(Xmlm.make_input~strip:true(`Channelichan))inignore_inputi;(* `Dtd *)ignore_inputi;(* smbl tag start *)letmodel=matchXmlm.inputiwith|`El_start((_,"model"),attrs)->parse_modelattrsi|_->raise_bad"malformed sbml"inignore_inputi;(* smbl tag end *)ifnot(Xmlm.eoii)thenraise_bad"sbml too long";modelendletin_sbml=SBMLParser.in_sbml