aboutsummaryrefslogtreecommitdiff
path: root/kernel/typing.ml
diff options
context:
space:
mode:
authorfilliatr1999-08-26 12:29:28 +0000
committerfilliatr1999-08-26 12:29:28 +0000
commit15ed739c91a22e91ae88d54215f6862fc1074a88 (patch)
treef79e0074d82a573edba76ff34dd161dd935e651f /kernel/typing.ml
parent844624640d335bd49bc187a135548734ea353e37 (diff)
mach -> typing; machops -> typeops
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@27 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'kernel/typing.ml')
-rw-r--r--kernel/typing.ml600
1 files changed, 600 insertions, 0 deletions
diff --git a/kernel/typing.ml b/kernel/typing.ml
new file mode 100644
index 0000000000..2311fb9992
--- /dev/null
+++ b/kernel/typing.ml
@@ -0,0 +1,600 @@
+
+(* $Id$ *)
+
+open Pp
+open Util
+open Names
+open Univ
+open Generic
+open Term
+open Reduction
+open Sign
+open Environ
+open Type_errors
+open Machops
+
+(* Fonctions temporaires pour relier la forme castée de la forme jugement *)
+
+let tjudge_of_cast env = function
+ | DOP2 (Cast, b, t) ->
+ (match whd_betadeltaiota env t with
+ | DOP0 (Sort s) -> {body=b; typ=s}
+ | DOP2 (Cast, b',t') -> anomaly "Supercast (tjudge_of_cast) [Mach]"
+ | _ -> anomaly "Not a type (tjudge_of_cast) [Mach]")
+ | _ -> anomaly "Not casted (tjudge_of_cast)"
+
+let tjudge_of_judge env j =
+ { body = j.uj_val;
+ typ = match whd_betadeltaiota env j.uj_type with
+ (* Nécessaire pour ZFC *)
+ | DOP0 (Sort s) -> s
+ | DOP0 Implicit -> anomaly "Tiens, un implicit"
+ | _ -> anomaly "Not a type (tjudge_ofjudge)" }
+
+let vect_lift = Array.mapi lift
+let vect_lift_type = Array.mapi (fun i t -> typed_app (lift i) t)
+
+(*s The machine flags.
+ [fix] indicates if we authorize general fixpoints ($\mathit{recarg} < 0$)
+ like [Acc_rec.fw].
+ [nocheck] indicates if we can skip some verifications to accelerate
+ the type inference. *)
+
+type 'a mach_flags = {
+ fix : bool;
+ nocheck : bool }
+
+(* The typing machine without information. *)
+
+let rec execute mf env cstr =
+ let u0 = universes env in
+ match kind_of_term cstr with
+ | IsMeta n ->
+ let metaty =
+ try lookup_meta n env
+ with Not_found -> error "A variable remains non instanciated"
+ in
+ (match kind_of_term metaty with
+ | IsCast (typ,kind) ->
+ ({ uj_val = cstr; uj_type = typ; uj_kind = kind}, u0)
+ | _ ->
+ let (jty,u1) = execute mf env metaty in
+ let k = hnf_constr env jty.uj_type in
+ ({ uj_val = cstr; uj_type = metaty; uj_kind = k }, u1))
+
+ | IsRel n ->
+ (relative env n, u0)
+
+ | IsVar id ->
+ (make_judge cstr (snd (lookup_var id env)), u0)
+
+ | IsAbst _ ->
+ if evaluable_abst env cstr then
+ execute mf env (abst_value env cstr)
+ else
+ error "Cannot typecheck an unevaluable abstraction"
+
+ | IsConst _ ->
+ (make_judge cstr (type_of_constant_or_existential env cstr), u0)
+
+ | IsMutInd _ ->
+ (make_judge cstr (type_of_inductive env cstr), u0)
+
+ | IsMutConstruct _ ->
+ let (typ,kind) = destCast (type_of_constructor env cstr) in
+ ({ uj_val = cstr; uj_type = typ; uj_kind = kind } , u0)
+
+ | IsMutCase (_,p,c,lf) ->
+ let (cj,u1) = execute mf env c in
+ let env1 = set_universes u1 env in
+ let (pj,u2) = execute mf env1 p in
+ let env2 = set_universes u2 env1 in
+ let (lfj,u3) = execute_array mf env2 lf in
+ let env3 = set_universes u3 env2 in
+ (type_of_case env3 pj cj lfj, u3)
+
+ | IsFix (vn,i,lar,lfi,vdef) ->
+ if (not mf.fix) && array_exists (fun n -> n < 0) vn then
+ error "General Fixpoints not allowed";
+ let (larv,vdefv,u1) = execute_fix mf env lar lfi vdef in
+ let fix = mkFix vn i larv lfi vdefv in
+ check_fix env fix;
+ (make_judge fix larv.(i), u1)
+
+ | IsCoFix (i,lar,lfi,vdef) ->
+ let (larv,vdefv,u1) = execute_fix mf env lar lfi vdef in
+ let cofix = mkCoFix i larv lfi vdefv in
+ check_cofix env cofix;
+ (make_judge cofix larv.(i), u1)
+
+ | IsSort (Prop c) ->
+ (type_of_prop_or_set c, u0)
+
+ | IsSort (Type u) ->
+ type_of_type u u0
+
+ | IsAppL a ->
+ let la = Array.length a in
+ if la = 0 then error_cant_execute CCI env cstr;
+ let hd = a.(0)
+ and tl = Array.to_list (Array.sub a 1 (la - 1)) in
+ let (j,u1) = execute mf env hd in
+ let env1 = set_universes u1 env in
+ let (jl,u2) = execute_list mf env1 tl in
+ let env2 = set_universes u2 env1 in
+ apply_rel_list env2 mf.nocheck jl j
+
+ | IsLambda (name,c1,c2) ->
+ let (j,u1) = execute mf env c1 in
+ let var = assumption_of_judgement env j in
+ let env1 = push_rel (name,var) (set_universes u1 env) in
+ let (j',u2) = execute mf env1 c2 in
+ let env2 = set_universes u2 env1 in
+ abs_rel env2 name var j'
+
+ | IsProd (name,c1,c2) ->
+ let (j,u1) = execute mf env c1 in
+ let var = assumption_of_judgement env j in
+ let env1 = push_rel (name,var) (set_universes u1 env) in
+ let (j',u2) = execute mf env1 c2 in
+ let env2 = set_universes u2 env1 in
+ gen_rel env2 name var j'
+
+ | IsCast (c,t) ->
+ let (cj,u1) = execute mf env c in
+ let env1 = set_universes u1 env in
+ let (tj,u2) = execute mf env1 t in
+ let env2 = set_universes u2 env1 in
+ (cast_rel env2 cj tj, u2)
+
+ | _ -> error_cant_execute CCI env cstr
+
+and execute_fix mf env lar lfi vdef =
+ let (larj,u1) = execute_array mf env lar in
+ let env1 = set_universes u1 env in
+ let lara = Array.map (assumption_of_judgement env1) larj in
+ let nlara =
+ List.combine (List.rev lfi) (Array.to_list (vect_lift_type lara)) in
+ let env2 =
+ List.fold_left (fun env nvar -> push_rel nvar env) env1 nlara in
+ let (vdefj,u2) = execute_array mf env2 vdef in
+ let env3 = set_universes u2 env2 in
+ let vdefv = Array.map j_val_only vdefj in
+ let u3 = type_fixpoint env3 lfi lara vdefj in
+ (lara,vdefv,u3)
+
+and execute_array mf env v =
+ let (jl,u1) = execute_list mf env (Array.to_list v) in
+ (Array.of_list jl, u1)
+
+and execute_list mf env = function
+ | [] -> ([], universes env)
+ | c::r ->
+ let (j,u') = execute mf env c in
+ let (jr,u'') = execute_list mf (set_universes u' env) r in
+ (j::jr, u'')
+
+
+(* The typed type of a judgment. *)
+
+let execute_type mf env constr =
+ let (j,_) = execute mf env constr in
+ typed_type_of_judgment env j
+
+
+(* Exported machines. First safe machines, with no general fixpoint
+ allowed (the flag [fix] is not set) and all verifications done (the
+ flag [nocheck] is not set). *)
+
+let safe_machine env constr =
+ let mf = { fix = false; nocheck = false } in
+ execute mf env constr
+
+let safe_machine_type env constr =
+ let mf = { fix = false; nocheck = false } in
+ execute_type mf env constr
+
+(* Machines with general fixpoint. *)
+
+let fix_machine env constr =
+ let mf = { fix = true; nocheck = false } in
+ execute mf env constr
+
+let fix_machine_type env constr =
+ let mf = { fix = true; nocheck = false } in
+ execute_type mf env constr
+
+(* Fast machines without any verification. *)
+
+let unsafe_machine env constr =
+ let mf = { fix = true; nocheck = true } in
+ execute mf env constr
+
+let unsafe_machine_type env constr =
+ let mf = { fix = true; nocheck = true } in
+ execute_type mf env constr
+
+
+(* ``Type of'' machines. *)
+
+let type_of env c =
+ let (j,_) = safe_machine env c in nf_betaiota env j.uj_type
+
+let type_of_type env c =
+ let tt = safe_machine_type env c in DOP0 (Sort tt.typ)
+
+let unsafe_type_of env c =
+ let (j,_) = unsafe_machine env c in nf_betaiota env j.uj_type
+
+let unsafe_type_of_type env c =
+ let tt = unsafe_machine_type env c in DOP0 (Sort tt.typ)
+
+
+(*s Machines with information. *)
+
+type information = Logic | Inf of unsafe_judgment
+
+(*i
+let implicit_judgment = {body=mkImplicit;typ=implicit_sort}
+
+let add_inf_rel (na,inf) env =
+ match inf with
+ Logic -> add_rel (na,implicit_judgment) env
+ | Inf j -> add_rel (na,tjudge_of_judge j) env
+
+
+let fw_mutind sigma fenv k =
+ let (sp,x,args) = destMutInd k in
+ let mis = mind_specif_of_mind k in
+ match mis_singl mis with
+ Some a -> Some (a,true)
+ | None ->
+ if is_info_cast_type sigma (mis_arity mis) then
+ let infK =
+ global_reference fenv (fwsp_of sp) (id_of_global (MutInd (sp,x)))
+ in Some (infK,false)
+ else None
+
+let inf_of_mind sigma fenv mind =
+ try
+ match fw_mutind sigma fenv mind with
+ Some (infK,singl) -> Inf(cast_fmachine (sigma,[]) fenv infK)
+ | None -> Logic
+ with
+ Not_found | Failure _ ->
+ anomaly "cannot convert an inductive to an finductive"
+
+let inf_mconstructor (sigma,metamap) fenv k =
+ let (sp,x,i,cl) = destMutConstruct k in
+ let mind = mkMutInd sp x cl in
+ (match fw_mutind sigma fenv mind with
+ None -> Logic
+ | Some(infi,singl) ->
+ (match mind_lamexp mind with
+ | Some clamexp ->
+ if singl
+ then Inf(cast_fmachine (sigma,[]) fenv clamexp)
+ else
+ let (infsp, infx, infcl) = destMutInd infi in
+ let infmconstructor = mkMutConstruct infsp infx i infcl in
+ let infval = subst1 infmconstructor clamexp in
+ Inf (cast_fmachine (sigma,fst metamap) fenv infval)
+ | _ -> assert false))
+
+
+exception DefinedExtraction
+
+(* when c is an evaluable constant with an extraction which
+ contains an implicit, gives the value of the c constant
+ otherwise raise DefinedExtraction
+*)
+
+let value_implicit_const sigma c cinf =
+ match c with DOPN(Const(_),_) ->
+ if evaluable_const sigma c then
+ let cv = const_value sigma cinf in
+ if is_implicit cv (* or contains_implicit sigma cv *)
+ then const_value sigma c
+ else raise DefinedExtraction
+ else raise DefinedExtraction
+ | _ -> raise DefinedExtraction
+
+let unsafe_infmachine (sigma,metamap) env fenv c =
+ let rec infexec env fenv cstr = match cstr with
+ DOP2(Cast,c,DOP0(Sort(Prop(Null)))) -> Logic
+ | DOP2(Cast,c,DOP2(Cast,_,DOP0(Sort(Prop(Null))))) -> Logic
+ | DOP2(Cast,c,_) -> infexec env fenv c
+ | DOP0(Meta n) ->
+ (match List.assoc n (snd metamap) with
+ Logic -> Logic
+ | Inf j -> Inf{uj_val=DOP0(Meta n);
+ uj_type=j.uj_val;
+ uj_kind = hnf_constr sigma j.uj_type})
+
+ | Rel n ->
+ inf_rel fenv
+ (contents_of_type sigma (snd (lookup_rel n env))) n
+
+ | VAR str ->
+ inf_var fenv
+ (contents_of_type sigma (snd(lookup_glob str env))) str
+
+ | DOPN(Const _,_) -> inf_of_const sigma (env,fenv) cstr
+
+ | DOPN(Abst _,_) ->
+ if evaluable_abst cstr then infexec env fenv (abst_value cstr)
+ else error "cannot extract from an unevaluable abstraction"
+
+ | DOP0(Sort s) -> inf_sort s
+
+ | DOPN(AppL,tl) ->
+ let c1 = (hd_vect tl)
+ and cl = tl_vect tl in
+ let funinf = infexec env fenv c1 in
+ (match funinf with Logic -> Logic
+ | Inf(j) -> let cinf = j.uj_val in
+ (* try to expand constants corresponding
+ to non extractable terms *)
+ (try if is_extraction_expanded() then
+ let valcte = value_implicit_const sigma c1 cinf
+ in infexec env fenv (whd_betaiota (appvect(valcte,cl)))
+ else raise DefinedExtraction
+ with DefinedExtraction ->
+ let argsinf = Array.map (infexec env fenv) cl
+ in it_vect inf_apply funinf argsinf))
+
+ | DOP2(Lambda,c1,DLAM(name,c2)) ->
+ let varinf = infexec env fenv c1 in
+ let bodyinf = infexec (add_rel (name,tjudge_of_cast sigma c1) env)
+ (add_inf_rel (name,varinf) fenv) c2
+ in inf_abs_rel name bodyinf varinf
+
+ | DOP2(Prod,c1,DLAM(name,c2)) ->
+ let c1inf = infexec env fenv c1 in
+ let c2inf = infexec (add_rel (name,tjudge_of_cast sigma c1) env)
+ (add_inf_rel (name,c1inf) fenv) c2
+ in inf_gen_rel name c2inf c1inf
+
+ | DOPN(MutInd _,_) -> inf_of_mind sigma fenv cstr
+
+ | DOPN(MutConstruct _,_) ->
+ inf_mconstructor (sigma,metamap) fenv cstr
+
+ | DOPN(Fix(vn,i),cl) ->
+ let lar = Array.sub cl 0 ((Array.length cl) - 1) in
+ let inflar = Array.map (infexec env fenv) lar in
+ let infAi = inflar.(i) in
+ (match infAi with
+ Logic -> Logic
+ | Inf aij ->
+ let (lfi,ldefs) = decomp_all_DLAMV_name (last_vect cl) in
+ let (new_env,new_fenv) =
+ it_vect2
+ (fun (ne,nfe) fk ak ->
+ (add_rel (fk,tjudge_of_cast sigma ak) ne,
+ let infAk = infexec ne nfe ak
+ in (add_inf_rel (fk,infAk) nfe)))
+ (env,fenv)
+ (Array.of_list (List.rev lfi)) (vect_lift lar) in
+(* a special function to localize the recursive index in the extracted term *)
+ let rec exec_def ne nfe n def =
+ (match hnf_constr sigma def with
+ DOP2(Lambda,c1,DLAM(name,c2)) ->
+ let varinf = infexec ne nfe c1 in
+ let ne' = (add_rel (name,tjudge_of_cast sigma c1) ne)
+ and nfe' = add_inf_rel (name,varinf) nfe in
+ if n = 0 then
+ let infc2 = infexec ne' nfe' c2
+ in let infdef = inf_abs_rel name infc2 varinf
+ and index =
+ if varinf = Logic then -1
+ (* the recursive call was on a non-informative term *)
+ else 0 in (infdef,index)
+ else
+ let bodyinf,countl =
+ exec_def (add_rel (name,tjudge_of_cast sigma c1) ne)
+ (add_inf_rel (name,varinf) nfe) (n-1) c2 in
+ let (infabs,abs) =
+ inf_abs_rel_count name bodyinf varinf
+ in (infabs,
+ if abs = ERASE then countl
+ else if countl<0 then countl-1
+ else countl+1)
+ | _ -> anomaly "exec_def : should be a lambda") in
+ let infdefs_ind =
+ map2_vect (exec_def new_env new_fenv) vn ldefs
+ in inf_fix sigma i aij.uj_type lfi inflar infdefs_ind)
+
+ | DOPN(CoFix i,cl) ->
+ let lar = Array.sub cl 0 ((Array.length cl) - 1) in
+ let inflar = Array.map (infexec env fenv) lar in
+ let infAi = inflar.(i) in
+ (match infAi with
+ Logic -> Logic
+ | Inf aij ->
+ let lfi,ldefs = decomp_all_DLAMV_name (last_vect cl) in
+ let (new_env,new_fenv) =
+ it_vect2 (fun (ne,nfe) fk ak ->
+ (add_rel (fk,tjudge_of_cast sigma ak) ne,
+ let infAk = infexec ne nfe ak
+ in (add_inf_rel (fk,infAk) nfe)))
+ (env,fenv)
+ (Array.of_list (List.rev lfi)) (vect_lift lar) in
+
+ let infdefs = Array.map (infexec new_env new_fenv) ldefs
+ in inf_cofix sigma i aij.uj_type lfi inflar infdefs)
+
+ | DOPN(MutCase _,_) ->
+ let (ci,p,c,lf) = destCase cstr in
+ let pinf = infexec env fenv p in
+ (match pinf with
+ Logic -> Logic
+ | Inf pj ->
+ if is_extraction_expanded() then
+ let (d,l) = whd_betadeltaiota_stack sigma c [] in
+ (match d with (DOPN(MutConstruct(_,_),_)) ->
+ let cstr' =
+ DOPN(MutCase(ci),Array.append [|p;applist(d,l)|] lf)
+ in infexec env fenv (whd_betaiota cstr')
+ | _ ->
+ let cinf = infexec env fenv c
+ and lfinf = Array.map (infexec env fenv) lf
+ in inf_mutcase fenv sigma pj ci cinf lfinf
+ )
+ else let cinf = infexec env fenv c
+ and lfinf = Array.map (infexec env fenv) lf
+ in inf_mutcase fenv sigma pj ci cinf lfinf)
+
+ | _ -> error "Cannot extract information"
+ in infexec env fenv c
+
+
+let core_infmachine meta env fenv c =
+ try unsafe_infmachine meta env fenv c
+ with (UserError _ | Failure _) -> Logic
+
+(* WITH INFORMATION *)
+(* does not check anymore that extracted terms are well-formed *)
+let judgement_infmachine meta env fenv c ct =
+ try
+ match unsafe_infmachine meta env fenv c with
+ Inf infj ->
+ let inftyp =
+ try unsafe_infmachine meta env fenv ct
+ with (UserError _ | Failure _) ->
+ (warning "Failed to extract in type"; Logic)
+ in (match inftyp with
+ Inf infjt ->
+ Inf{uj_val=infj.uj_val;
+ uj_type=infjt.uj_val;
+ uj_kind=infj.uj_kind}
+ | Logic -> Inf infj)
+ | Logic -> Logic
+ with (UserError _ | Failure _) -> (warning "Failed to extract"; Logic)
+
+let infmachine_type nocheck (sigma,metamap) env fenv constr =
+ let constr_metamap = List.map (fun (id,(c,_)) -> (id,c)) metamap in
+ let inf_metamap = List.map (fun (id,(_,i)) -> (id,i)) metamap in
+ let t = core_fmachine_type nocheck (sigma,constr_metamap) env constr in
+ let inf =
+ if is_info_type sigma t then (* Case the term is informative *)
+ let uniarc = get_uniarc () in
+ let infjt =
+ judgement_infmachine
+ (sigma,(constr_metamap,inf_metamap)) env fenv
+ t.body
+ (DOP0 (Sort t.typ)) in
+ let _ = set_uniarc uniarc in
+ infjt
+ else Logic
+
+ in hash_jpair_type
+ ({body = strip_all_casts t.body; typ = t.typ},
+ (inf_app (fun j -> {uj_val = nf_beta j.uj_val;
+ uj_type = nf_beta j.uj_type;
+ uj_kind = j.uj_kind }) inf))
+
+let infmachine nocheck (sigma,metamap) env fenv constr =
+ let constr_metamap = List.map (fun (id,(c,_)) -> (id,c)) metamap in
+ let inf_metamap = List.map (fun (id,(_,i)) -> (id,i)) metamap in
+ let j = core_fmachine nocheck (sigma,constr_metamap) env constr in
+ let inf =
+ if is_info_judge sigma j then (* Case the term is informative *)
+ let uniarc = get_uniarc () in
+ let jt = cast_fmachine (sigma,constr_metamap) env j.uj_type in
+ let infjt =
+ judgement_infmachine
+ (sigma,(constr_metamap,inf_metamap)) env fenv j.uj_val jt.uj_val in
+ let _ = set_uniarc uniarc in
+ infjt
+ else Logic
+
+ in hash_jpair
+ ({uj_val = strip_all_casts j.uj_val;
+ uj_type = strip_all_casts j.uj_type;
+ uj_kind = j.uj_kind},
+ (inf_app (fun j -> {uj_val = nf_beta j.uj_val;
+ uj_type = nf_beta j.uj_type;
+ uj_kind = j.uj_kind }) inf))
+
+
+let jsign_of_sign sigma sign =
+ sign_it
+ (fun id a (sign,fsign) ->
+ let sign' = add_sign (id,a) sign in
+ let fsign' =
+ match infmachine_type true (sigma,[]) (gLOB sign) (gLOB fsign) a.body
+ with
+ (_,Logic) -> fsign
+ | (_,Inf ft) -> add_sign (id,tjudge_of_judge ft) fsign
+ in (sign',fsign'))
+ sign (([],[]),([],[]))
+
+
+let fsign_of_sign sigma sign = snd (jsign_of_sign sigma sign)
+
+let infexemeta_type sigma metamap (env,fenv) c =
+ infmachine_type true (sigma,metamap) env fenv c
+
+let infexecute_rec_type sigma (env,fenv) c =
+ infmachine_type false (sigma,[]) env fenv c
+
+let infexecute_type sigma (sign,fsign) c =
+ infmachine_type false (sigma,[]) (gLOB sign) (gLOB fsign) c
+
+let infexemeta sigma metamap (env,fenv) c =
+ infmachine true (sigma,metamap) env fenv c
+
+let infexecute_rec sigma (env,fenv) c =
+ infmachine false (sigma,[]) env fenv c
+
+let infexecute sigma (sign,fsign) c =
+ infmachine false (sigma,[]) (gLOB sign) (gLOB fsign) c
+
+(* A adapter pour les nouveaux env
+let fvar_type sigma (sign,fsign) v =
+ let na = destVar v in
+ let varty = (snd(lookup_sign na sign))
+ in match (snd(infexemeta sigma [] (gLOB sign, gLOB fsign) varty)) with
+ Inf ft -> ft.uj_val
+ | Logic -> invalid_arg "Fvar with a non-informative type (1)!"
+
+*)
+
+(* MACHINE WITH UNIVERSES *)
+(* Il vaudrait mieux typer dans le graphe d'univers de Constraintab,
+ recuperer le graphe local, et restaurer l'acien graphe global *)
+
+let whd_instuni = function
+ DOP0(Sort(Type(u))) ->
+ let u = (if u = dummy_univ then new_univ() else u)
+ in DOP0(Sort(Type(u)))
+ | c -> c
+
+(* Instantiate universes: replace all dummy_univ by fresh universes.
+ This is already done by the machine.
+ Indtypes instantiates the universes itself, because in the case of
+ large constructor, additionnal constraints must be considered. *)
+let instantiate_universes c = strong whd_instuni c
+
+
+(* sp est le nom de la constante pour laquelle il faut que c soit bien type.
+ Cela sert a eviter un clash entre le noms d'univers de 2 modules compiles
+ independamment.
+ Au lieu de sp, Lib.cwd() serait peut-etre suffisant.
+ Cela eviterai de donner un section-path quand on veut typer. *)
+let fexecute_type_with_univ sigma sign sp c =
+ with_universes (fexecute_type sigma sign) (sp,initial_universes,c)
+
+
+let fexecute_with_univ sigma sign sp c =
+ with_universes (fexecute sigma sign) (sp,initial_universes,c)
+
+
+let infexecute_type_with_univ sigma psign sp c =
+ with_universes (infexecute_type sigma psign) (sp,initial_universes,c)
+
+
+let infexecute_with_univ sigma psign sp c =
+ with_universes (infexecute sigma psign) (sp,initial_universes,c)
+i*)