123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106(* This file is free software, part of Zipperposition. See file "license" for more details. *)(** {1 De Bruijn environments} *)type'at={size:int;stack:'aoptionlist;}letempty={size=0;stack=[];}letis_emptyenv=env.size=0letmakesize={size;stack=CCList.range0size|>List.map(fun_->None);}letsingletonx={size=1;stack=[Somex];}letpushenvx={size=env.size+1;stack=(Somex)::env.stack;}letpush_l_same_orderenvl=List.fold_right(funxe->pushex)lenvletpush_l_revenvl=List.fold_leftpushenvlletpush_noneenv={size=env.size+1;stack=None::env.stack;}letrecpush_none_multipleenvn=ifn<=0thenenvelsepush_none(push_none_multipleenv(n-1))letsizeenv=env.sizeletpopenv=matchenv.stackwith|[]->raise(Invalid_argument"Env.pop: empty env")|_::tl->{size=env.size-1;stack=tl;}letrecpop_manyenvn=matchnwith|0->env|_->pop_many(popenv)(n-1)letfindenvn=assert(n>=0);ifn<env.sizethenList.nthenv.stacknelseNoneletfind_exnenvn=ifn<env.sizethenmatchList.nthenv.stacknwith|None->failwith"DBEnv.find_exn"|Somex->xelsefailwith"DBEnv.find_exn"letmemenvn=ifn<env.sizethenList.nthenv.stackn<>Noneelsefalseletsetenvnx=ifn<0||n>=env.sizethenraise(Invalid_argument"DBEnv.set");{envwithstack=CCList.set_at_idxn(Somex)env.stack;}letnum_bindingsdb=letreccountaccl=matchlwith|[]->acc|None::l'->countaccl'|Some_::l'->count(1+acc)l'incount0db.stackletmapfdb=letstack=List.map(function|None->None|Somex->Some(fx))db.stackin{dbwithstack;}letfilterifdb=letstack=CCList.foldi(funaccio->matchowith|Somexwhenfix->Somex::acc|_->None::acc)[]db.stack|>List.revin{dbwithstack;}letof_listl=letmax=List.fold_left(funacc(b,_)->maxaccb)~-1linletenv=make(max+1)inList.fold_left(funenv(db,v)->setenvdbv)envlletto_liste=e.stackletto_list_ie=List.mapi(funix->CCOpt.map(CCPair.makei)x)e.stackletpppp_xoute=letpp_itemout=function|None->CCFormat.stringout"_"|Somex->Format.fprintfout"[@[%a@]]"pp_xxinFormat.fprintfout"@[<hv2>%a@]"(Util.pp_list~sep:","pp_item)e.stackletto_stringppx=CCFormat.to_string(ppppx)