Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file libMeta.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119(** Functions to manipulate metavariables. *)openLplibopenTermopenTimedopenCommon(** Logging function for unification. *)letlog=Logger.make'a'"meta""metavariables"letlog=log.ppletmeta_counter:intStdlib.ref=Stdlib.ref(-1)(** [reset_meta_counter ()] resets the counter used to produce meta keys. *)letreset_meta_counter()=Stdlib.(meta_counter:=-1)(** [fresh p ?name a n] creates a fresh metavariable of type [a] and arity [n]
with the optional name [name], and adds it to [p]. *)letfresh:problem->term->int->meta=funpan->letm={meta_key=Stdlib.(incrmeta_counter;!meta_counter);meta_type=refa;meta_arity=n;meta_value=refNone}inifLogger.log_enabled()thenlog"fresh ?%d"m.meta_key;p:={!pwithmetas=MetaSet.addm!p.metas};ifLogger.log_enabled()thenlog"%a"Print.problemp;m(** [fresh_box p a n] is the boxed counterpart of [fresh_meta]. It is
only useful in the rare cases where the type of a metavariable
contains a free term variable environment. This should only happens
when scoping the rewriting rules, use this function with care.
The metavariable is created immediately with a dummy type, and the
type becomes valid at unboxing. The boxed metavariable should be
unboxed at most once, otherwise its type may be rendered invalid in
some contexts. *)letfresh_box:problem->tbox->int->metaBindlib.box=funpan->letm=freshpmk_KindninBindlib.box_apply(funa->m.meta_type:=a;m)a(** [set p m v] sets the metavariable [m] of [p] to [v]. WARNING: No specific
check is performed, so this function may lead to cyclic terms. To use with
care. *)letset:problem->meta->tmbinder->unit=funpmv->m.meta_type:=mk_Kind;(* to save memory *)m.meta_value:=Somev;p:={!pwithmetas=MetaSet.removem!p.metas}(** [make p ctx a] creates a fresh metavariable term of type [a] in the
context [ctx], and adds it to [p]. *)letmake:problem->ctxt->term->term=funpctxa->leta,k=Ctxt.to_prodctxainletm=freshpakinmk_Meta(m,Array.of_list(List.rev_map(fun(x,_,_)->mk_Varix)ctx))(** [bmake p bctx a] is the boxed version of {!make}: it creates
a fresh {e boxed} metavariable in {e boxed} context [bctx] of {e
boxed} type [a]. It is the same as [lift (make p c b)] (provided that
[bctx] is boxed [c] and [a] is boxed [b]), but more efficient. *)letbmake:problem->bctxt->tbox->tbox=funpbctxa->leta,k=Ctxt.to_prod_boxbctxainletm=fresh_boxpakin_Meta_fullm(Array.of_list(List.rev_map(fun(x,_,_)->_Varix)bctx))(** [make_codomain p ctx a] creates a fresh metavariable term of type [Type]
in the context [ctx] extended with a fresh variable of type [a], and
updates [p] with generated metavariables. *)letmake_codomain:problem->ctxt->term->tbinder=funpctxa->letx=new_tvar"x"inbindxlift(makep((x,a,None)::ctx)mk_Type)(** [bmake_codomain p bctx a] is [make_codomain p bctx a] but on boxed
terms. *)letbmake_codomain:problem->bctxt->tbox->tbinderBindlib.box=funpbctxa->letx=new_tvar"x"inletb=bmakep((x,a,None)::bctx)_TypeinBindlib.bind_varxb(** [iter b f c t] applies the function [f] to every metavariable of [t] and,
if [x] is a variable of [t] mapped to [v] in the context [c], then to every
metavariable of [v], and to the type of every metavariable recursively if
[b] is true. *)letiter:bool->(meta->unit)->ctxt->term->unit=funbfc->(* Convert the context into a map. *)letvm=letfvm(x,_,v)=matchvwith|Somev->VarMap.addxvvm|None->vminStdlib.ref(List.fold_leftfVarMap.emptyc)inletrecitert=matchunfoldtwith|Patt_|TEnv_|Wild|TRef_|Type|Kind|Plac_|Symb_->()|Varix->beginmatchVarMap.find_optxStdlib.(!vm)with|Somev->Stdlib.(vm:=VarMap.removex!vm);iterv|None->()end|Prod(a,b)|Abst(a,b)->itera;iter(Bindlib.substbmk_Kind)|Appl(t,u)->itert;iteru|Meta(m,ts)->fm;Array.iteriterts;ifbtheniter!(m.meta_type)|LLet(a,t,u)->itera;itert;iter(Bindlib.substumk_Kind)initer(** [occurs m c t] tests whether the metavariable [m] occurs in the term [t]
when variables defined in the context [c] are unfolded. *)letoccurs:meta->ctxt->term->bool=letexceptionFoundinfunmct->letfp=ifm==pthenraiseFoundintryiterfalsefct;falsewithFound->true