+let mk_meta ?name metasenv context ty =
+ match ty with
+ | `Typeless ->
+ let n = newmeta () in
+ let ty = NCic.Implicit (`Typeof n) in
+ let menv_entry = (n, (name, context, ty)) in
+ menv_entry :: metasenv,NCic.Meta (n, (0,NCic.Irl (List.length context))), ty
+ | `Type
+ | `Term ->
+ let context_for_ty = if ty = `Type then [] else context in
+ let n = newmeta () in
+ let ty_menv_entry = (n, (name,context_for_ty, NCic.Implicit (`Typeof n))) in
+ let m = newmeta () in
+ let ty = NCic.Meta (n, (0,NCic.Irl (List.length context_for_ty))) in
+ let menv_entry = (m, (name, context, ty)) in
+ menv_entry :: ty_menv_entry :: metasenv,
+ NCic.Meta (m, (0,NCic.Irl (List.length context))), ty
+ | `WithType ty ->
+ let n = newmeta () in
+ let len = List.length context in
+ let menv_entry = (n, (name, context, ty)) in
+ menv_entry :: metasenv, NCic.Meta (n, (0,NCic.Irl len)), ty
+;;
+
+let saturate ?(delta=0) metasenv context ty goal_arity =
+ assert (goal_arity >= 0);
+ let rec aux metasenv = function
+ | NCic.Prod (name,s,t) ->
+ let metasenv1, arg,_ =
+ mk_meta ~name:name metasenv context (`WithType s) in
+ let t, metasenv1, args, pno =
+ aux metasenv1 (NCicSubstitution.subst arg t)
+ in
+ if pno + 1 = goal_arity then
+ ty, metasenv, [], goal_arity+1
+ else
+ t, metasenv1, arg::args, pno+1
+ | ty ->
+ match NCicReduction.whd context ty ~delta with
+ | NCic.Prod _ as ty -> aux metasenv ty
+ | ty -> ty, metasenv, [], 0
+ in
+ let res, newmetasenv, arguments, _ = aux metasenv ty in
+ res, newmetasenv, arguments
+;;