123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666(* This file is free software, part of Zipperposition. See file "license" for more details. *)(** {1 Types} *)moduleT=InnerTermtypet=T.ttypety=ttypebuiltin=TType|Prop|Term|Rat|Int|Realletbuiltin_conv=function|TType->Builtin.tType|Prop->Builtin.prop|Term->Builtin.term|Rat->Builtin.ty_rat|Int->Builtin.ty_int|Real->Builtin.ty_realletpp_builtinoutb=Builtin.ppout(builtin_convb)typeview=|Builtinofbuiltin|VaroftHVar.t|DBofint|AppofID.t*tlist(** parametrized type *)|Funoftlist*t(** Function type (left to right, no left-nesting) *)|Foralloft(** explicit quantification using De Bruijn index *)letviewt=matchT.viewtwith|T.Varv->Varv|T.DBi->DBi|T.Bind(Binder.ForallTy,varty,t')->assert(T.equalvartyT.tType);Forallt'|T.Consts->App(s,[])|T.App(f,l)->beginmatchT.viewfwith|T.Constid->App(id,l)|_->CCFormat.printf"wrong:@[%a@]@."T.ppt;assertfalseend|T.AppBuiltin(Builtin.Arrow,[_])->assertfalse|T.AppBuiltin(Builtin.Arrow,(ret::l))->Fun(l,ret)|T.AppBuiltin(Builtin.Prop,[])->BuiltinProp|T.AppBuiltin(Builtin.TType,[])->BuiltinTType|T.AppBuiltin(Builtin.Term,[])->BuiltinTerm|T.AppBuiltin(Builtin.TyInt,[])->BuiltinInt|T.AppBuiltin(Builtin.TyRat,[])->BuiltinRat|T.AppBuiltin(Builtin.TyReal,[])->BuiltinReal|_->assertfalselethash=T.hashletequal=T.equalletcompare=T.comparelethash_mod_alpha=T.hash_mod_alphalet[@inline]is_tTypety=matchT.viewtywithT.AppBuiltin(Builtin.TType,[])->true|_->falselet[@inline]is_varty=matchT.viewtywithT.Var_->true|_->falselet[@inline]is_bvarty=matchT.viewtywithT.DB_->true|_->falselet[@inline]is_appty=matchT.viewtywithT.App_->true|_->falselet[@inline]is_constty=matchT.viewtywithT.Const_->true|_->falselet[@inline]is_funty=matchT.viewtywith|T.AppBuiltin(Builtin.Arrow,_)->true|_->falselet[@inline]is_forallty=matchT.viewtywithT.Bind(Binder.ForallTy,_,_)->true|_->falselet[@inline]is_propty=matchT.viewtywithT.AppBuiltin(Builtin.Prop,[])->true|_->falseletas_var_exnty=matchviewtywith|Varv->v|_->invalid_arg"as_var_exn"lettType=T.tTypeletprop=T.builtin~ty:tTypeBuiltin.Propletterm=T.builtin~ty:tTypeBuiltin.Termletint=T.builtin~ty:tTypeBuiltin.TyIntletrat=T.builtin~ty:tTypeBuiltin.TyRatletreal=T.builtin~ty:tTypeBuiltin.TyRealletbuiltin=function|TType->tType|Prop->prop|Term->term|Int->int|Rat->rat|Real->realletvar=T.varletvar_of_inti=T.var(HVar.make~ty:tTypei)letarrow=T.arrowletappsl=letty_s=arrow(List.map(fun_->T.tType)l)T.tTypeinT.app~ty:T.tType(T.const~ty:ty_ss)lletconsts=T.const~ty:T.tTypesletbvari=T.bvar~ty:T.tTypeiletforallty=T.bind~ty:T.tType~varty:T.tTypeBinder.forall_tytyletrecforall_nnty=ifn=0thentyelseforall(forall_n(n-1)ty)letforall_fvarsvarsty=ifvars=[]thentyelse(List.fold_right(funvty->assert(is_tType(HVar.tyv));letbody=T.DB.from_varty~var:(varv)inforallbody)varsty)let(==>)=arrowlet[@inline]of_term_unsafet=tlet[@inline]of_terms_unsafel=llet[@inline]cast_var_unsafev=v(** {2 Definitions} *)typedef=|Def_uninofint(* number of type variables *)|Def_dataofint*tylist(* data type with number of variables and cstors *)exceptionPayload_defofdefletdefid=ID.payload_findid~f:(function|Payload_defd->Somed|_->None)letdef_exnid=matchdefidwith|Somed->d|None->raiseNot_foundletset_defidd=ID.set_payloadid(Payload_defd)(** {2 Containers} *)moduleSet=T.SetmoduleMap=T.MapmoduleTbl=T.TblmoduleSeq=structletvars=T.Seq.varsletsub=T.Seq.subtermsletsymbols=T.Seq.symbolsletadd_set=T.Seq.add_setletmax_var=T.Seq.max_varletmin_var=T.Seq.min_varlethas_bools_onlyt=T.Seq.subtermst|>Iter.for_all(funty->is_funty||is_propty)endmoduleVarMap=T.VarMapmoduleVarSet=T.VarSetmoduleVarTbl=T.VarTblletvars_setsett=VarSet.add_iterset(Seq.varst)letvarst=vars_setVarSet.emptyt|>VarSet.elementsletclose_forallty=letvars=varstyinT.bind_vars~ty:tTypeBinder.ForallTyvarstytypearity_result=|Arityofint*int|NoArityletarityty=(* n_forall: number of forall traversed so far *)letrectraversen_forallty=matchviewtywith|Fun(l,ty')->assert(not(is_funty'));Arity(n_forall,List.lengthl)|Forallty'->traverse(n_forall+1)ty'|Var_->NoArity|Builtin_->Arity(n_forall,0)|DB_|App_->Arity(n_forall,0)intraverse0tyletrecexpected_argsty=matchviewtywith|Fun(args,ret)->args@expected_argsret|Forallty'->expected_argsty'|DB_|Var_|Builtin_|App_->[]letexpected_ty_varst=T.expected_ty_varstletneeds_argsty=expected_ty_varsty>0||expected_argsty<>[]letorderty:int=letrecauxty=matchviewtywith|Forallty->auxty|Fun(l,ret)->List.fold_left(funoarg->maxo(1+auxarg))(auxret)l|App(_,l)->List.fold_left(funoarg->maxo(auxarg))0l|Var_|DB_|Builtin_->0inmax1(auxty)(* never less than 1 *)letcontains_propt=Seq.subt|>Iter.existsis_propletis_ground=T.is_groundletsize=T.sizeletrecdepthty=matchviewtywith|Builtin_|Var_|DB_->1|App(_,l)->1+depth_ll|Forallty'->1+depthty'|Fun(l,ret)->1+max(depthret)(depth_ll)anddepth_ll=List.fold_left(fundt->maxd(deptht))0lletopen_fun=T.open_funletopen_poly_fun=T.open_poly_funletreturnsty=T.returnstyletreturns_propty=is_prop(returnsty)letreturns_tTypety=is_tType(returnsty)exceptionApplyErrorofstringlet()=Printexc.register_printer(function|ApplyErrormsg->Some(Util.err_spf"@[<2>Type.ApplyError:@ %s@]"msg)|_->None)leterr_apply_msg=raise(ApplyErrormsg)leterr_applyf_msg=CCFormat.ksprintfmsg~f:err_apply_(* apply a type to arguments. *)letapplyty0args0=letrecauxtyargsenv=matchT.viewty,argswith|_,[]->T.DB.evalenvty|T.AppBuiltin(Builtin.Arrow,(ret::exp_args)),_::_->(* match expected types with actual types *)aux_lretexp_argsargsenv|T.Bind(Binder.ForallTy,_,ty'),arg::args'->letarg=T.DB.evalenvarginauxty'args'(DBEnv.pushenvarg)|T.DB_,_->letty=T.DB.evalenvtyinauxtyargsenv|_->err_applyf_"@[<2>Type.apply:@ expected quantified or function type,@ but got @[%a@] @[(args: %a)@]"T.pp_zfty(CCList.ppT.pp)argsandaux_lty_retexp_argsargsenv=matchexp_args,argswith|[],[]->T.DB.evalenvty_ret|_,[]->T.DB.evalenv(arrowexp_argsty_ret)|[],_->beginmatchT.view(T.DB.evalenvty_ret)with|T.AppBuiltin(Builtin.Arrow,(ty_ret'::exp_args'))->(* [ty_ret = exp_args' -> ty_ret'], continue applying *)aux_lty_ret'exp_args'argsenv|_->err_applyf_"@[<2>Type.apply:@ unexpected arguments [@[%a@]]@]"(Util.pp_listT.pp_zf)argsend|exp::exp_args',a::args'->(* expected type: [exp]; [a]: actual value, whose type must match [exp] *)letexp'=T.DB.evalenvexpinifT.equalexp'(T.ty_exna)thenaux_lty_retexp_args'args'envelseerr_applyf_"@[<2>Type.apply:@ wrong argument type,@ expected `@[_ : %a@]`@ \
but got `@[%a : %a@]`@ when applying `%a` to@ [@[%a@]]@ in env [%a]@]"T.pp_zfexp'T.pp_zfaT.pp_zf(T.ty_exna)T.pp_zfty0(Util.pp_listT.pp_zf)args0(DBEnv.ppT.pp_zf)envinauxty0args0DBEnv.emptyletapply1tya=applyty[a]letapply_unsafe=applyletis_unifiable=T.type_is_unifiabletypeprint_hook=int->(CCFormat.t->t->unit)->CCFormat.t->t->boolmoduleTPTP=structleti=termleto=propletint=intletrat=ratletreal=const(ID.make"$real")typeprint_hook=int->(CCFormat.t->t->unit)->CCFormat.t->t->boolletrecpp_tstp_recdepthoutt=matchviewtwith|BuiltinProp->CCFormat.stringout"$o"|BuiltinTType->CCFormat.stringout"$tType"|BuiltinTerm->CCFormat.stringout"$i"|BuiltinInt->CCFormat.stringout"$int"|BuiltinRat->CCFormat.stringout"$rat"|BuiltinReal->CCFormat.stringout"$real"|Varv->Format.fprintfout"X%d"(HVar.idv)|DBi->Format.fprintfout"Tb%d"(depth-i-1)|App(p,[])->ID.pp_tstpoutp|App(p,args)->Format.fprintfout"@[<2>%a(%a)@]"ID.pp_tstpp(Util.pp_list(pp_tstp_recdepth))args|Fun(args,ret)->Format.fprintfout"%a > %a"(pp_ldepth)args(pp_tstp_recdepth)ret|Forallty'->Format.fprintfout"!>[Tb%d:$tType]: %a"depth(pp_inner(depth+1))ty'andpp_innerdepthoutt=matchviewtwith|Fun_->Format.fprintfout"(@[%a@])"(pp_tstp_recdepth)t|_->pp_tstp_recdepthouttandpp_ldepthoutl=matchlwith|[]->assertfalse|[ty]->pp_innerdepthoutty|_->Format.fprintfout"(@[%a@])"(Util.pp_list~sep:" * "(pp_tstp_recdepth))l;assertfalseletppoutt=pp_tstp_rec0outtletpp_depth?hooks:_depthoutt=pp_tstp_recdepthouttletrecpp_ho_depthdepthoutt=matchviewtwith|BuiltinProp->CCFormat.stringout"$o"|BuiltinTType->CCFormat.stringout"$tType"|BuiltinTerm->CCFormat.stringout"$i"|BuiltinInt->CCFormat.stringout"$int"|BuiltinRat->CCFormat.stringout"$rat"|BuiltinReal->CCFormat.stringout"$real"|Varv->Format.fprintfout"X%d"(HVar.idv)|DBi->Format.fprintfout"Tb%d"(depth-i-1)|App(p,[])->ID.pp_tstpoutp|App(p,args)->Format.fprintfout"@[<2>%a @@ %a @]"ID.pp_tstpp(Util.pp_list~sep:" @ "(pp_innerdepth))args|Fun(args,ret)->Format.fprintfout"%a > %a"(pp_ldepth)args(pp_innerdepth)ret|Forallty'->Format.fprintfout"!>[Tb%d:$tType]: %a"depth(pp_inner(depth+1))ty'andpp_innerdepthoutt=matchviewtwith|Fun_|App(_,_::_)->Format.fprintfout"(@[%a@])"(pp_ho_depthdepth)t|_->pp_ho_depthdepthouttandpp_ldepthoutl=matchlwith|[]->assertfalse|[ty]->pp_innerdepthoutty|_->Format.fprintfout"@[%a@]"(Util.pp_list~sep:" > "(pp_innerdepth))lletpp_ho?(depth=0)outt=pp_ho_depthdepthouttletpp_typed_varoutv=matchview(HVar.tyv)with(* | Builtin Term -> HVar.pp out v implicit *)|_->Format.fprintfout"@[%a : %a@]"HVar.pp_tstpv(pp_ho~depth:0)(HVar.tyv)letto_string=CCFormat.to_stringppendletpp_typed_var_gen~pp_tyoutv=matchview(HVar.tyv)with|BuiltinTType->Format.fprintfout"A%d"(HVar.idv)|BuiltinTerm->HVar.ppoutv|BuiltinInt->Format.fprintfout"I%d"(HVar.idv)|BuiltinRat->Format.fprintfout"Q%d"(HVar.idv)|BuiltinProp->Format.fprintfout"P%d"(HVar.idv)|Forall_|Fun_->Format.fprintfout"(@[F%d:%a@])"(HVar.idv)pp_ty(HVar.tyv)|_->Format.fprintfout"(@[%a:%a@])"HVar.ppvpp_ty(HVar.tyv)moduleZF=structletpp=T.pp_zfletto_string=CCFormat.to_stringppletpp_typed_varoutv=pp_typed_var_gen~pp_ty:ppoutvend(** {2 IO} *)letrecpp_recdepthoutt=matchviewtwith|Builtinb->pp_builtinoutb|Varv->letty=HVar.tyvinifis_tTypetythenFormat.fprintfout"A%d"(HVar.idv)elseHVar.ppoutv|DBi->Format.fprintfout"T%i"(depth-i-1)|App(p,[])->ID.ppoutp|App(p,args)->Format.fprintfout"@[<2>%a %a@]"ID.ppp(Util.pp_list~sep:" "(pp_inner_appdepth))args|Fun(args,ret)->Format.fprintfout"@[%a →@ %a@]"(Util.pp_list~sep:" → "(pp_inner_fundepth))args(pp_recdepth)ret|Forallty'->Format.fprintfout"@[Π T%i.@ %a@]"depth(pp_inner_fun(depth+1))ty'andpp_inner_fundepthoutt=matchviewtwith|Fun_->Format.fprintfout"(@[%a@])"(pp_recdepth)t|_->pp_recdepthouttandpp_inner_appdepthoutt=matchviewtwith|Fun_|App(_,_::_)->Format.fprintfout"(@[%a@])"(pp_recdepth)t|_->pp_recdepthouttletpp_depth?hooks:_depthoutt=pp_recdepthouttletppoutt=pp_rec0outtletpp_surroundedoutt=(pp_inner_app0)outtletto_string=CCFormat.to_stringppletpp_in=function|Output_format.O_zf->ZF.pp|Output_format.O_tptp->TPTP.pp_ho~depth:0|Output_format.O_normal->pp|Output_format.O_none->CCFormat.silent(* keep synchro with {!InnerTerm.pp_var} *)letpp_typed_varoutv=pp_typed_var_gen~pp_ty:ppoutvletmangle(ty:t):string=letadd_idbufid=lets=ID.nameid|>CCString.filter(function'#'|'_'->false|_->true)inBuffer.add_stringbufsinletrecauxbuft=matchviewtwith|BuiltinTType->Buffer.add_stringbuf"ty"|BuiltinInt->Buffer.add_stringbuf"int"|BuiltinRat->Buffer.add_stringbuf"rat"|BuiltinReal->Buffer.add_stringbuf"real"|BuiltinProp->Buffer.add_stringbuf"prop"|BuiltinTerm->Buffer.add_stringbuf"i"|Var_->Buffer.add_stringbuf"_"|DBi->Printf.bprintfbuf"A%d"i|App(f,[])->add_idbuff|App(f,l)->add_idbuff;List.iter(funsub->Buffer.add_charbuf'_';auxbufsub)l|Fun(args,ret)->List.iter(funsub->auxbufsub;Buffer.add_stringbuf"_to_")args;auxbufret;|Forallf->Printf.bprintfbuf"pi_%a"auxfinletbuf=Buffer.create32inauxbufty;Buffer.contentsbufletpp_mangleoutty=CCFormat.stringout(manglety)(** {2 Conversions} *)moduleConv=structmodulePT=TypedSTerm(* context used to map free variables to free variables *)typectx={mutablevars:(PT.t,tHVar.t)Var.Subst.t;mutablen:int;(* counter for free vars *)mutablehvars:PT.tVar.tVarMap.t;mutablebvars_to_db:intVarMap.t;mutablemax_vars:intoptionref;}letcreate()={vars=Var.Subst.empty;n=0;hvars=VarMap.empty;bvars_to_db=VarMap.empty;max_vars=refNone}letenter_bvarctxv=letret_handle=VarMap.find_optvctx.bvars_to_dbinletnew_map=VarMap.map(funx->x+1)ctx.bvars_to_dbinctx.bvars_to_db<-VarMap.addv0new_map;ret_handleletexit_bvar~handlectxv=letnew_map=VarMap.map(funx->x-1)ctx.bvars_to_dbinifCCOpt.is_somehandlethen(ctx.bvars_to_db<-VarMap.addv(CCOpt.get_exnhandle)new_map)elsectx.bvars_to_db<-new_mapletfind_bvarctxv=VarMap.find_optvctx.bvars_to_dbletcopyt={twithvars=t.vars;}letclearctx=ctx.vars<-Var.Subst.empty;ctx.n<-0;()letfresh_ty_varctx=letn=ctx.ninctx.n<-n+1;HVar.make~ty:tTypenletset_maxvarctxi=ctx.max_vars:=Some(i+1);ctx.n<-i+1letget_maxvarctx=CCOpt.get_or~default:0(!(ctx.max_vars))letincr_maxvarctx=set_maxvarctx(get_maxvarctx+1)exceptionErrorofTypedSTerm.tlet()=Printexc.register_printer(function|Errort->Some(Util.err_spf"@[<2>Type.Conv.Error on `@[%a@]`@]"PT.ppt)|_->None)letof_simple_term_exnctxt=letrecauxdepthv2dbt=matchPT.viewtwith|PT.Varv->beginmatchVar.Subst.findv2dbvwith|Somei->(* i was the level when [v] was bound, [depth] is the current
level, therefore there are [depth-i] binders in between *)bvar(depth-i-1)|None->var(aux_varv)end|PT.AppBuiltin(Builtin.Wildcard,[])->(* make a fresh variable, but do not remember it *)var(fresh_ty_varctx)|PT.Constid->constid|PT.AppBuiltin(Builtin.Arrow,ret::args)->letret=auxdepthv2dbretinassert(not(is_funret||is_forallret));letargs=List.map(auxdepthv2db)argsinarrowargsret|PT.AppBuiltin(Builtin.Term,[])->term|PT.AppBuiltin(Builtin.Prop,[])->prop|PT.AppBuiltin(Builtin.TType,[])->tType|PT.AppBuiltin(Builtin.TyInt,[])->int|PT.AppBuiltin(Builtin.TyRat,[])->rat|PT.AppBuiltin(Builtin.TyReal,[])->real|PT.App(f,l)->beginmatchPT.viewfwith|PT.Consthd->letl=List.map(auxdepthv2db)linapphdl|_->raise(Errort)end|PT.Bind(Binder.ForallTy,v,t')->letv2db=Var.Subst.addv2dbvdepthinlett'=aux(depth+1)v2dbt'inforallt'|PT.Record_->failwith"cannot convert record-type into type"|PT.Meta(_,{contents=Somety'},_)->auxdepthv2dbty'|PT.Bind_|PT.AppBuiltin_|PT.Meta_|PT.Ite_|PT.Match_|PT.Let_|PT.Multiset_->raise(Errort)andaux_varv=matchVar.Subst.findctx.varsvwith|Somev->v|None->(* free variable *)letv'=fresh_ty_varctxinctx.vars<-Var.Subst.addctx.varsvv';v'inaux0Var.Subst.emptytletvar_of_simple_termctxv=matchVar.Subst.findctx.varsvwith|Somev'->v'|None->letty=of_simple_term_exnctx(Var.tyv)inletv'=HVar.make~tyctx.ninctx.n<-ctx.n+1;ctx.vars<-Var.Subst.addctx.varsvv';v'letof_simple_termctxt=trySome(of_simple_term_exnctxt)withError_->Noneletrecto_simple_term?(env=DBEnv.empty)ctxt=letrecauxenvt=matchviewtwith|BuiltinProp->PT.builtin~ty:PT.tTypeBuiltin.Prop|BuiltinTType->PT.builtin~ty:PT.tTypeBuiltin.TType|BuiltinTerm->PT.builtin~ty:PT.tTypeBuiltin.Term|BuiltinInt->PT.builtin~ty:PT.tTypeBuiltin.TyInt|BuiltinRat->PT.builtin~ty:PT.tTypeBuiltin.TyRat|BuiltinReal->PT.builtin~ty:PT.tTypeBuiltin.TyReal|Varv->letv=aux_varvinPT.varv|DBi->PT.var(DBEnv.find_exnenvi)|App(s,l)->(* s : type -> type -> ... -> type *)letty_s=PT.Ty.fun_(List.map(fun_->PT.tType)l)PT.tTypeinPT.app~ty:PT.tType(PT.const~ty:ty_ss)(List.map(auxenv)l)|Fun(args,ret)->letargs=List.map(auxenv)argsinletret=auxenvretinPT.Ty.fun_argsret|Forallt'->letv=Var.of_string~ty:PT.tType(CCFormat.sprintf"V%d"(DBEnv.sizeenv))inlett'=aux(DBEnv.pushenvv)t'inPT.bind~ty:PT.tTypeBinder.forall_tyvt'andaux_varv=var_to_simple_var~prefix:"A"ctxvinauxenvtandvar_to_simple_var?(prefix="A")ctxv=tryVarMap.findvctx.hvarswithNot_found->letv'=Var.of_string~ty:(to_simple_termctx(HVar.tyv))(CCFormat.sprintf"%s%d"prefix(HVar.idv))inctx.hvars<-VarMap.addvv'ctx.hvars;v'endletrebuild_rec?(env=[])(t:t):t=letrecauxenvt=matchT.tytwith|T.NoType->assert(t==tType);t|T.HasTypety->beginmatchviewtwith|Varv->var(HVar.cast~tyv)|DBi->assert(ifi>=0&&i<List.lengthenvthentrueelse(Format.printf"%d not in %a@."i(CCFormat.Dump.listpp)env;false));assert(ifequalty(List.nthenvi)thentrueelse(Format.printf"%a:%a or %a@."pptpptypp(List.nthenvi);false));bvari|App(f,l)->appf(List.map(auxenv)l)|Fun(args,ret)->arrow(List.map(auxenv)args)(auxenvret)|Builtinb->builtinb|Forallbody->letbody'=aux(tType::env)bodyinforallbody'endinauxenvtletunsafe_eval_dbenvt:t=ifCCList.is_emptyenvthentelse(letenv=List.fold_right(funtyenv->DBEnv.pushenvty)envDBEnv.emptyinof_term_unsafe(T.DB.evalenvt))