123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127(* This file is free software, part of containers. See file "license" for more details. *)(** {1 Bijection} *)type'aiter=('a->unit)->unitmoduletypeOrderedType=sigtypetvalcompare:t->t->intendmoduletypeS=sigtypettypelefttyperightvalempty:tvalis_empty:t->boolvalequal:t->t->boolvalcompare:t->t->intvaladd:left->right->t->tvalcardinal:t->intvalmem:left->right->t->boolvalmem_left:left->t->boolvalmem_right:right->t->boolvalfind_left:left->t->rightvalfind_right:right->t->leftvalremove:left->right->t->tvalremove_left:left->t->tvalremove_right:right->t->tvallist_left:t->(left*right)listvallist_right:t->(right*left)listvaladd_iter:(left*right)iter->t->tvalof_iter:(left*right)iter->tvalto_iter:t->(left*right)itervaladd_list:(left*right)list->t->tvalof_list:(left*right)list->tvalto_list:t->(left*right)listendmoduleMake(L:OrderedType)(R:OrderedType)=structtypeleft=L.ttyperight=R.tmoduleMapL=Map.Make(L)moduleMapR=Map.Make(R)typet={left:rightMapL.t;right:leftMapR.t;}letempty={left=MapL.empty;right=MapR.empty}letcardinalm=MapL.cardinalm.leftletis_emptym=letres=MapL.is_emptym.leftinassert(res=MapR.is_emptym.right);resletequalab=MapL.equal(funab->R.compareab=0)a.leftb.leftletcompareab=MapL.compareR.comparea.leftb.leftletaddabm={left=(tryletfound=MapR.findbm.rightinifL.comparefounda<>0thenMapL.removefoundm.leftelsem.leftwithNot_found->m.left)|>MapL.addab;right=(tryletfound=MapL.findam.leftinifR.comparefoundb<>0thenMapR.removefoundm.rightelsem.rightwithNot_found->m.right)|>MapR.addba;}letfind_leftkeym=MapL.findkeym.leftletfind_rightkeym=MapR.findkeym.rightletmemleftrightm=tryR.compareright(find_leftleftm)=0withNot_found->falseletmem_leftkeym=MapL.memkeym.leftletmem_rightkeym=MapR.memkeym.rightletremoveabm=ifmemabmthen{left=MapL.removeam.left;right=MapR.removebm.right}elsemletremove_leftam=letright=tryMapR.remove(find_leftam)m.rightwithNot_found->m.rightin{right;left=MapL.removeam.left}letremove_rightbm=letleft=tryMapL.remove(find_rightbm)m.leftwithNot_found->m.leftin{left;right=MapR.removebm.right}letlist_leftm=MapL.bindingsm.leftletlist_rightm=MapR.bindingsm.rightletadd_listlm=List.fold_left(funm(a,b)->addabm)mlletof_listl=add_listlemptyletto_list=list_leftletadd_iterseqm=letm=refminseq(fun(k,v)->m:=addkv!m);!mletof_iterl=add_iterlemptyletto_itermyield=MapL.iter(funkv->yield(k,v))m.leftend