Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file model.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2022 Nomadic Labs. <contact@nomadic-labs.com> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)type(_,_,_)arity=|Zero_arity:('elt,'elt,unit)arity|Succ_arity:('elt,'b,'a)arity->('elt,'elt->'b,int*'a)arityletarity_0=Zero_arityletarity_1=Succ_arityarity_0letarity_2=Succ_arityarity_1letarity_3=Succ_arityarity_2moduletypeModel_impl=sigtypearg_typevalname:Namespace.tvaltakes_saturation_reprs:boolmoduleDef(X:Costlang.S):sigtypemodel_typevalarity:(X.size,model_type,arg_type)arityvalmodel:model_typeX.reprendendmoduletypeInstantiated=sigtype'areprtypesizetypearg_typetypemodel_typevalarity:(size,model_type,arg_type)arityvalmodel:arg_type->sizereprendtype'argmodel=(moduleModel_implwithtypearg_type='arg)moduletypeApp=sigtypetvalapplied:tendmoduletypeApplied=functor(X:Costlang.S)->Appwithtypet=X.sizeX.reprtypeapplied=(moduleApplied)typepacked_model=Model:_model->packed_modeltype_t=|Abstract:{conv:'workload->'arg;model:'argmodel}->'workloadt|Aggregate:{model:'workload->applied;sub_models:packed_modellist;}->'workloadtletpp_packed_modelppf(Modelmodel)=letmoduleModel=(valmodel)inletmodulePp=Model.Def(Costlang.Pp)inFormat.fprintfppf"@[<v2>%a:@ %s@]"Namespace.ppModel.namePp.modelletppppf=function|Abstract{model;_}->Format.fprintfppf"@[<v2>Abstract@ %a@]"pp_packed_model(Modelmodel)|Aggregate{sub_models;_}->Format.fprintfppf"@[<v2>Aggregate with submodels:@ @[%a@]@]"(Format.pp_print_listpp_packed_model)sub_modelsletapply_model:'arg->'argmodel->applied=fun(typee)(elim:e)((moduleImpl):emodel)->letmoduleApplied(X:Costlang.S)=structincludeImpl.Def(X)typet=X.sizeX.reprletrecapply:typeabc.(int->cX.repr)->(c,a,b)arity->aX.repr->b->cX.repr=funconvarityfarg->matcharitywith|Zero_arity->f|Succ_arityar->letarg,rest=arginapplyconvar(X.appf(convarg))restletapplied=applyX.intaritymodelelimendin((moduleApplied):applied)moduleInstantiate(X:Costlang.S)(M:Model_impl):Instantiatedwithtype'arepr='aX.reprandtypesize=X.sizeandtypearg_type=M.arg_type=structtype'arepr='aX.reprtypesize=X.sizeincludeMincludeDef(X)letrecapply:typeabc.(int->cX.repr)->(c,a,b)arity->aX.repr->b->cX.repr=funconvarityfarg->matcharitywith|Zero_arity->f|Succ_arityar->letarg,rest=arginapplyconvar(X.appf(convarg))restletmodelelim=applyX.intaritymodelelimendletset_takes_saturation_reprs(typea)b((moduleModel):amodel):amodel=letmoduleModel'=structincludeModellettakes_saturation_reprs=bendin(moduleModel')letmake?(takes_saturation_reprs=false)~convmodel=letmodel=set_takes_saturation_reprstakes_saturation_reprsmodelinAbstract{conv;model}letmake_aggregated~model~sub_models=Aggregate{model;sub_models}letapplymodelworkload=matchmodelwith|Abstract{conv;model}->apply_model(convworkload)model|Aggregate{model;_}->modelworkloadletforce_aggregated~model=matchmodelwith|Aggregate_->model|Abstract{conv=_;model=model2}->Aggregate{model=applymodel;sub_models=[Modelmodel2]}letadd_aggregated_models:('w1->applied)->('w2->applied)->'w1*'w2->applied=funm1m2(w1,w2)->let(moduleM1)=m1w1inlet(moduleM2)=m2w2inletmoduleM(X:Costlang.S)=structtypet=X.sizeX.reprletapplied=let(moduleM1:Appwithtypet=X.sizeX.repr)=(moduleM1(X))inlet(moduleM2:Appwithtypet=X.sizeX.repr)=(moduleM2(X))inX.(M1.applied+M2.applied)endin(moduleM:Applied)letadd_modelm1m2=letm1=force_aggregated~model:m1inletm2=force_aggregated~model:m2inmatch(m1,m2)with|(Aggregate{model=m1;sub_models=l1},Aggregate{model=m2;sub_models=l2})->Aggregate{model=add_aggregated_modelsm1m2;sub_models=l1@l2}|_->assertfalse(* impossible *)letprecompose:typeab.(a->b)->bt->at=funfmodel->matchmodelwith|Abstract{conv;model}->letconvx=conv(fx)inAbstract{conv;model}|Aggregate{model;sub_models}->Aggregate{model=(funx->model(fx));sub_models}letget_free_variable_set(typea)(model:amodel)=letmoduleM=(valmodel)inletmoduleT0=Costlang.Fold_constants(Costlang.Free_variables)inletmoduleT1=Costlang.Beta_normalize(T0)inletmoduleR=M.Def(T1)inT0.prj@@T1.prjR.model(* No workload application. For [Aggregate _], only extract
the free variables of the [sub_models].
*)letget_free_variable_set_of_t=letget_free_variables_of_packed_model(Model(moduleModel):packed_model)=letmoduleM=Model.Def(Costlang.Free_variables)inM.modelinfunction|Abstract{model;_}->get_free_variables_of_packed_model(Modelmodel)|Aggregate{sub_models;_}->List.fold_left(funaccpacked_model->Free_variable.Set.unionacc@@get_free_variables_of_packed_modelpacked_model)Free_variable.Set.emptysub_modelsletget_free_variable_set_applied(typeworkload)(model:workloadt)(workload:workload)=(* If a parameter is fixed to 0 in the workload data, the application
of the workload can eliminate free variables multiplied
by the parameter.
The typical example is the intercept case where some parameters
tend to be fixed to 0. This may not work when the intercept point
is not at "zero"s.
It is unfortunate that we need to apply workload data to a model to
know which variables can be optimized out. We may be able to do it
without workload, but it seems not an easy task.
*)letapplied=applymodelworkloadinletmoduleM=(valapplied)inletmoduleT0=Costlang.Fold_constants(Costlang.Free_variables)inletmoduleT1=Costlang.Beta_normalize(T0)inletmoduleR=M(T1)inT0.prj@@T1.prjR.applied(* -------------------------------------------------------------------------- *)(* Commonly used models *)letzero=letmoduleM=structtypearg_type=unitletname=Namespace.root"zero"lettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=sizeletarity=arity_0letmodel=int0endendin(moduleM:Model_implwithtypearg_type=unit)letunknown_const1~name~const=letmoduleM=structtypearg_type=unitletname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=sizeletarity=arity_0letmodel=free~name:constendendin(moduleM:Model_implwithtypearg_type=unit)letunknown_const1_skip1~name~const=letmoduleM=structtypearg_type=int*unitletname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->sizeletarity=arity_1letmodel=lam~name:"size"@@fun(_:sizerepr)->free~name:constendendin(moduleM:Model_implwithtypearg_type=int*unit)letunknown_const1_skip2~name~const=letmoduleM=structtypearg_type=int*(int*unit)letname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->size->sizeletarity=arity_2letmodel=lam~name:"size1"@@fun(_:sizerepr)->lam~name:"size2"@@fun(_:sizerepr)->free~name:constendendin(moduleM:Model_implwithtypearg_type=int*(int*unit))letlinear~name~coeff=letmoduleM=structtypearg_type=int*unitletname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->sizeletarity=arity_1letmodel=lam~name:"size"@@funsize->free~name:coeff*sizeendendin(moduleM:Model_implwithtypearg_type=int*unit)letaffine~name~intercept~coeff=letmoduleM=structtypearg_type=int*unitletname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->sizeletarity=arity_1letmodel=lam~name:"size"@@funsize->free~name:intercept+(free~name:coeff*size)endendin(moduleM:Model_implwithtypearg_type=int*unit)letaffine_offset~name~intercept~coeff~offset=letmoduleM=structtypearg_type=int*unitletname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->sizeletarity=arity_1letmodel=lam~name:"size"@@funsize->free~name:intercept+(free~name:coeff*sat_subsize(intoffset))endendin(moduleM:Model_implwithtypearg_type=int*unit)letquadratic~name~coeff=letmoduleM=structtypearg_type=int*unitletname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->sizeletarity=arity_1letmodel=lam~name:"size"@@funsize->free~name:coeff*(size*size)endendin(moduleM:Model_implwithtypearg_type=int*unit)letnlogn~name~intercept~coeff=letmoduleM=structtypearg_type=int*unitletname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->sizeletarity=arity_1letmodel=lam~name:"size"@@funsize->free~name:intercept+(free~name:coeff*(size*log2(int1+size)))endendin(moduleM:Model_implwithtypearg_type=int*unit)letnsqrtn_const~name~intercept~coeff=letmoduleM=structtypearg_type=int*unitletname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->sizeletarity=arity_1letmodel=lam~name:"size"@@funsize->free~name:intercept+(free~name:coeff*(size*sqrtsize))endendin(moduleM:Model_implwithtypearg_type=int*unit)letlogn~name~coeff=letmoduleM=structtypearg_type=int*unitletname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->sizeletarity=arity_1letmodel=lam~name:"size"@@funsize->free~name:coeff*log2(int1+size)endendin(moduleM:Model_implwithtypearg_type=int*unit)letlinear_sum~name~intercept~coeff=letmoduleM=structtypearg_type=int*(int*unit)letname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->size->sizeletarity=arity_2letmodel=lam~name:"size1"@@funsize1->lam~name:"size2"@@funsize2->free~name:intercept+(free~name:coeff*(size1+size2))endendin(moduleM:Model_implwithtypearg_type=int*(int*unit))letlinear_sat_sub~name~intercept~coeff=letmoduleM=structtypearg_type=int*(int*unit)letname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->size->sizeletarity=arity_2letmodel=lam~name:"size1"@@funsize1->lam~name:"size2"@@funsize2->free~name:intercept+(free~name:coeff*sat_subsize1size2)endendin(moduleM:Model_implwithtypearg_type=int*(int*unit))letlinear_max~name~intercept~coeff=letmoduleM=structtypearg_type=int*(int*unit)letname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->size->sizeletarity=arity_2letmodel=lam~name:"size1"@@funsize1->lam~name:"size2"@@funsize2->free~name:intercept+(free~name:coeff*maxsize1size2)endendin(moduleM:Model_implwithtypearg_type=int*(int*unit))letlinear_min~name~intercept~coeff=letmoduleM=structtypearg_type=int*(int*unit)letname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->size->sizeletarity=arity_2letmodel=lam~name:"size1"@@funsize1->lam~name:"size2"@@funsize2->free~name:intercept+(free~name:coeff*minsize1size2)endendin(moduleM:Model_implwithtypearg_type=int*(int*unit))letlinear_min_offset~name~intercept~coeff~offset=letmoduleM=structtypearg_type=int*(int*unit)letname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->size->sizeletarity=arity_2letmodel=lam~name:"size1"@@funsize1->lam~name:"size2"@@funsize2->free~name:intercept+(free~name:coeff*sat_sub(minsize1size2)(intoffset))endendin(moduleM:Model_implwithtypearg_type=int*(int*unit))letlinear_mul~name~intercept~coeff=letmoduleM=structtypearg_type=int*(int*unit)letname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->size->sizeletarity=arity_2letmodel=lam~name:"size1"@@funsize1->lam~name:"size2"@@funsize2->free~name:intercept+(free~name:coeff*(size1*size2))endendin(moduleM:Model_implwithtypearg_type=int*(int*unit))letbilinear~name~coeff1~coeff2=letmoduleM=structtypearg_type=int*(int*unit)letname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->size->sizeletarity=arity_2letmodel=lam~name:"size1"@@funsize1->lam~name:"size2"@@funsize2->(free~name:coeff1*size1)+(free~name:coeff2*size2)endendin(moduleM:Model_implwithtypearg_type=int*(int*unit))letbilinear_affine~name~intercept~coeff1~coeff2=letmoduleM=structtypearg_type=int*(int*unit)letname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->size->sizeletarity=arity_2letmodel=lam~name:"size1"@@funsize1->lam~name:"size2"@@funsize2->free~name:intercept+(free~name:coeff1*size1)+(free~name:coeff2*size2)endendin(moduleM:Model_implwithtypearg_type=int*(int*unit))letaffine_skip1~name~intercept~coeff=letmoduleM=structtypearg_type=int*(int*unit)letname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->size->sizeletarity=arity_2letmodel=lam~name:"size1"@@fun(_size1:sizerepr)->lam~name:"size2"@@funsize2->free~name:intercept+(free~name:coeff*size2)endendin(moduleM:Model_implwithtypearg_type=int*(int*unit))letnlogm~name~intercept~coeff=letmoduleM=structtypearg_type=int*(int*unit)letname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->size->sizeletarity=arity_2letmodel=lam~name:"size1"@@funsize1->lam~name:"size2"@@funsize2->free~name:intercept+(free~name:coeff*(size1*log2(int1+size2)))endendin(moduleM:Model_implwithtypearg_type=int*(int*unit))letn_plus_logm~name~intercept~linear_coeff~log_coeff=letmoduleM=structtypearg_type=int*(int*unit)letname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->size->sizeletarity=arity_2letmodel=lam~name:"size1"@@funsize1->lam~name:"size2"@@funsize2->free~name:intercept+(free~name:linear_coeff*size1)+(free~name:log_coeff*log2(int1+size2))endendin(moduleM:Model_implwithtypearg_type=int*(int*unit))lettrilinear~name~coeff1~coeff2~coeff3=letmoduleM=structtypearg_type=int*(int*(int*unit))letname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->size->size->sizeletarity=arity_3letmodel=lam~name:"size1"@@funsize1->lam~name:"size2"@@funsize2->lam~name:"size3"@@funsize3->(free~name:coeff1*size1)+(free~name:coeff2*size2)+(free~name:coeff3*size3)endendin(moduleM:Model_implwithtypearg_type=int*(int*(int*unit)))letbreakdown~name~coeff1~coeff2~break=assert(0<=break);letmoduleM=structtypearg_type=int*unitletname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->sizeletarity=arity_1letmodel=lam~name:"size"@@funsize->(free~name:coeff1*min(intbreak)size)+(free~name:coeff2*sat_subsize(intbreak))endendin(moduleM:Model_implwithtypearg_type=int*unit)letbreakdown2~name~coeff1~coeff2~coeff3~break1~break2=assert(0<=break1&&break1<=break2);letmoduleM=structtypearg_type=int*unitletname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->sizeletarity=arity_1letmodel=lam~name:"size"@@funsize->(free~name:coeff1*min(intbreak1)size)+(free~name:coeff2*sat_sub(min(intbreak2)size)(intbreak1))+(free~name:coeff3*sat_subsize(intbreak2))endendin(moduleM:Model_implwithtypearg_type=int*unit)letbreakdown2_const~name~coeff1~coeff2~coeff3~const~break1~break2=assert(0<=break1&&break1<=break2);letmoduleM=structtypearg_type=int*unitletname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->sizeletarity=arity_1letmodel=lam~name:"size"@@funsize->(free~name:coeff1*min(intbreak1)size)+(free~name:coeff2*sat_sub(min(intbreak2)size)(intbreak1))+(free~name:coeff3*sat_subsize(intbreak2))+free~name:constendendin(moduleM:Model_implwithtypearg_type=int*unit)letbreakdown2_const_offset~name~coeff1~coeff2~coeff3~const~break1~break2~offset=assert(0<=break1&&break1<=break2);letmoduleM=structtypearg_type=int*unitletname=namelettakes_saturation_reprs=falsemoduleDef(X:Costlang.S)=structopenXtypemodel_type=size->sizeletarity=arity_1letmodel=lam~name:"size"@@funsize->let_~name:"size"(sat_subsize(intoffset))@@funsize->(free~name:coeff1*min(intbreak1)size)+(free~name:coeff2*sat_sub(min(intbreak2)size)(intbreak1))+(free~name:coeff3*sat_subsize(intbreak2))+free~name:constendendin(moduleM:Model_implwithtypearg_type=int*unit)moduletypeBinary_operation=sigmoduleDef(X:Costlang.S):sigvalop:X.sizeX.repr->X.sizeX.repr->X.sizeX.reprendendmoduleSynthesize(B:Binary_operation)(X:Model_impl)(Y:Model_implwithtypearg_type=X.arg_type)(Names:sigvalname:Namespace.tvalx_label:stringvaly_label:stringend):Model_implwithtypearg_type=X.arg_type=structtypearg_type=X.arg_typeletname=Names.name(* Use X's configuration *)lettakes_saturation_reprs=X.takes_saturation_reprsmoduleDef(C:Costlang.S)=structmoduleArgs=X.Def(Costlang.Arg_names)moduleBinOp=B.Def(C)moduleX=X.Def(C)moduleY=Y.Def(C)typemodel_type=X.model_typeletarity=X.arityletrecsynthesize:typeaargs_modelx_modely_model.(Costlang.Arg_names.size,args_model,a)arity->args_modelCostlang.Arg_names.repr->(C.size,x_model,a)arity->x_modelC.repr->(C.size,y_model,a)arity->y_modelC.repr->x_modelC.repr=funarg_arityargsarity1term1arity2term2->matcharg_aritywith|Zero_arity->(* These bindings of Zero_arity are necessary for type checking *)letZero_arity=arity1inletZero_arity=arity2inletopenCinlet_~name:Names.x_labelterm1@@funterm1->let_~name:Names.y_labelterm2@@funterm2->BinOp.opterm1term2|Succ_arityarg_arity->let(Succ_arityarity1)=arity1inlet(Succ_arityarity2)=arity2inletopenCinlam~name:(Costlang.Arg_names.arg_nameargs)@@funarg->synthesizearg_arity(Costlang.Arg_names.unwrap_sizeargs)arity1(appterm1arg)arity2(appterm2arg)letmodel=synthesizeArgs.arityArgs.modelX.arityX.modelY.arityY.modelendendletsynthesize(typea)~name~binop~x_label~x_model~y_label~y_model=let(moduleB:Binary_operation)=binopinlet((moduleX):amodel)=x_modelinlet((moduleY):amodel)=y_modelinletmoduleM=Synthesize(B)(X)(Y)(structletx_label=x_labellety_label=y_labelletname=nameend)in((moduleM):amodel)