aboutsummaryrefslogtreecommitdiff
path: root/pretyping
diff options
context:
space:
mode:
Diffstat (limited to 'pretyping')
-rw-r--r--pretyping/cbv.ml50
-rw-r--r--pretyping/cbv.mli3
-rw-r--r--pretyping/constr_matching.ml15
-rw-r--r--pretyping/detyping.ml14
-rw-r--r--pretyping/evarconv.ml28
-rw-r--r--pretyping/evardefine.ml83
-rw-r--r--pretyping/evardefine.mli5
-rw-r--r--pretyping/evarsolve.ml11
-rw-r--r--pretyping/globEnv.ml3
-rw-r--r--pretyping/glob_ops.ml12
-rw-r--r--pretyping/glob_term.ml1
-rw-r--r--pretyping/heads.ml2
-rw-r--r--pretyping/indrec.ml4
-rw-r--r--pretyping/keys.ml4
-rw-r--r--pretyping/nativenorm.ml20
-rw-r--r--pretyping/pattern.ml1
-rw-r--r--pretyping/patternops.ml26
-rw-r--r--pretyping/pretype_errors.ml1
-rw-r--r--pretyping/pretyping.ml68
-rw-r--r--pretyping/pretyping.mli1
-rw-r--r--pretyping/pretyping.mllib2
-rw-r--r--pretyping/recordops.ml31
-rw-r--r--pretyping/recordops.mli11
-rw-r--r--pretyping/reductionops.ml77
-rw-r--r--pretyping/reductionops.mli29
-rw-r--r--pretyping/retyping.ml9
-rw-r--r--pretyping/retyping.mli4
-rw-r--r--pretyping/tacred.ml282
-rw-r--r--pretyping/typing.ml24
-rw-r--r--pretyping/unification.ml16
-rw-r--r--pretyping/vnorm.ml38
31 files changed, 567 insertions, 308 deletions
diff --git a/pretyping/cbv.ml b/pretyping/cbv.ml
index b713d7812e..2c7b689c04 100644
--- a/pretyping/cbv.ml
+++ b/pretyping/cbv.ml
@@ -52,7 +52,8 @@ type cbv_value =
| FIXP of fixpoint * cbv_value subs * cbv_value array
| COFIXP of cofixpoint * cbv_value subs * cbv_value array
| CONSTR of constructor Univ.puniverses * cbv_value array
- | PRIMITIVE of CPrimitives.t * constr * cbv_value array
+ | PRIMITIVE of CPrimitives.t * pconstant * cbv_value array
+ | ARRAY of Univ.Instance.t * cbv_value Parray.t * cbv_value
(* type of terms with a hole. This hole can appear only under App or Case.
* TOP means the term is considered without context
@@ -98,6 +99,8 @@ let rec shift_value n = function
CONSTR (c, Array.map (shift_value n) args)
| PRIMITIVE(op,c,args) ->
PRIMITIVE(op,c,Array.map (shift_value n) args)
+ | ARRAY (u,t,ty) ->
+ ARRAY(u, Parray.map (shift_value n) t, shift_value n ty)
let shift_value n v =
if Int.equal n 0 then v else shift_value n v
@@ -170,7 +173,7 @@ let strip_appl head stack =
| COFIXP (cofix,env,app) -> (COFIXP(cofix,env,[||]), stack_app app stack)
| CONSTR (c,app) -> (CONSTR(c,[||]), stack_app app stack)
| PRIMITIVE(op,c,app) -> (PRIMITIVE(op,c,[||]), stack_app app stack)
- | VAL _ | STACK _ | CBN _ | LAM _ -> (head, stack)
+ | VAL _ | STACK _ | CBN _ | LAM _ | ARRAY _ -> (head, stack)
(* Tests if fixpoint reduction is possible. *)
@@ -209,6 +212,7 @@ module VNativeEntries =
type elem = cbv_value
type args = cbv_value array
type evd = unit
+ type uinstance = Univ.Instance.t
let get = Array.get
@@ -228,6 +232,11 @@ module VNativeEntries =
| _ -> raise Primred.NativeDestKO)
| _ -> raise Primred.NativeDestKO
+ let get_parray () e =
+ match e with
+ | ARRAY(_u,t,_ty) -> t
+ | _ -> raise Primred.NativeDestKO
+
let mkInt env i = VAL(0, mkInt i)
let mkFloat env f = VAL(0, mkFloat f)
@@ -327,6 +336,9 @@ module VNativeEntries =
let (_pNormal,_nNormal,_pSubn,_nSubn,_pZero,_nZero,_pInf,_nInf,nan) =
get_f_class_constructors env in
CONSTR(Univ.in_punivs nan, [||])
+
+ let mkArray env u t ty =
+ ARRAY (u,t,ty)
end
module VredNative = RedNative(VNativeEntries)
@@ -368,7 +380,10 @@ and reify_value = function (* reduction under binders *)
| CONSTR (c,args) ->
mkApp(mkConstructU c, Array.map reify_value args)
| PRIMITIVE(op,c,args) ->
- mkApp(c, Array.map reify_value args)
+ mkApp(mkConstU c, Array.map reify_value args)
+ | ARRAY (u,t,ty) ->
+ let t, def = Parray.to_array t in
+ mkArray(u, Array.map reify_value t, reify_value def, reify_value ty)
and apply_env env t =
match kind t with
@@ -458,6 +473,15 @@ let rec norm_head info env t stack =
| CoFix cofix -> (COFIXP(cofix,env,[||]), stack)
| Construct c -> (CONSTR(c, [||]), stack)
+ | Array(u,t,def,ty) ->
+ let ty = cbv_stack_term info TOP env ty in
+ let len = Array.length t in
+ let t =
+ Parray.init (Uint63.of_int len)
+ (fun i -> cbv_stack_term info TOP env t.(i))
+ (cbv_stack_term info TOP env def) in
+ (ARRAY (u,t,ty), stack)
+
(* neutral cases *)
| (Sort _ | Meta _ | Ind _ | Int _ | Float _) -> (VAL(0, t), stack)
| Prod _ -> (CBN(t,env), stack)
@@ -468,7 +492,12 @@ and norm_head_ref k info env stack normt t =
| Declarations.Def body ->
if get_debug_cbv () then Feedback.msg_debug Pp.(str "Unfolding " ++ debug_pr_key normt);
strip_appl (shift_value k body) stack
- | Declarations.Primitive op -> (PRIMITIVE(op,t,[||]),stack)
+ | Declarations.Primitive op ->
+ let c = match normt with
+ | ConstKey c -> c
+ | RelKey _ | VarKey _ -> assert false
+ in
+ (PRIMITIVE(op,c,[||]),stack)
| Declarations.OpaqueDef _ | Declarations.Undef _ ->
if get_debug_cbv () then Feedback.msg_debug Pp.(str "Not unfolding " ++ debug_pr_key normt);
(VAL(0,make_constr_ref k normt t),stack)
@@ -538,7 +567,7 @@ and cbv_stack_value info env = function
| (CONSTR(c,[||]), APP(appl,TOP)) -> CONSTR(c,appl)
(* primitive apply to arguments *)
- | (PRIMITIVE(op,c,[||]), APP(appl,stk)) ->
+ | (PRIMITIVE(op,(_,u as c),[||]), APP(appl,stk)) ->
let nargs = CPrimitives.arity op in
let len = Array.length appl in
if nargs <= len then
@@ -549,7 +578,7 @@ and cbv_stack_value info env = function
if nargs < len then
stack_app (Array.sub appl nargs (len - nargs)) stk
else stk in
- match VredNative.red_prim info.env () op args with
+ match VredNative.red_prim info.env () op u args with
| Some (CONSTR (c, args)) ->
(* args must be moved to the stack to allow future reductions *)
cbv_stack_value info env (CONSTR(c, [||]), stack_app args stk)
@@ -585,7 +614,7 @@ and cbv_value_cache info ref =
let v = cbv_stack_term info TOP (subs_id 0) body in
Declarations.Def v
with
- | Environ.NotEvaluableConst (Environ.IsPrimitive op) -> Declarations.Primitive op
+ | Environ.NotEvaluableConst (Environ.IsPrimitive (_u,op)) -> Declarations.Primitive op
| Not_found | Environ.NotEvaluableConst _ -> Declarations.Undef None
in
KeyTable.add info.tab ref v; v
@@ -643,7 +672,12 @@ and cbv_norm_value info = function (* reduction under binders *)
| CONSTR (c,args) ->
mkApp(mkConstructU c, Array.map (cbv_norm_value info) args)
| PRIMITIVE(op,c,args) ->
- mkApp(c,Array.map (cbv_norm_value info) args)
+ mkApp(mkConstU c,Array.map (cbv_norm_value info) args)
+ | ARRAY (u,t,ty) ->
+ let ty = cbv_norm_value info ty in
+ let t, def = Parray.to_array t in
+ let def = cbv_norm_value info def in
+ mkArray(u, Array.map (cbv_norm_value info) t, def, ty)
(* with profiling *)
let cbv_norm infos constr =
diff --git a/pretyping/cbv.mli b/pretyping/cbv.mli
index d7804edf6d..409f4c0f70 100644
--- a/pretyping/cbv.mli
+++ b/pretyping/cbv.mli
@@ -36,7 +36,8 @@ type cbv_value =
| FIXP of fixpoint * cbv_value subs * cbv_value array
| COFIXP of cofixpoint * cbv_value subs * cbv_value array
| CONSTR of constructor Univ.puniverses * cbv_value array
- | PRIMITIVE of CPrimitives.t * Constr.t * cbv_value array
+ | PRIMITIVE of CPrimitives.t * pconstant * cbv_value array
+ | ARRAY of Univ.Instance.t * cbv_value Parray.t * cbv_value
and cbv_stack =
| TOP
diff --git a/pretyping/constr_matching.ml b/pretyping/constr_matching.ml
index 656739657d..419eeaa92a 100644
--- a/pretyping/constr_matching.ml
+++ b/pretyping/constr_matching.ml
@@ -406,10 +406,16 @@ let matches_core env sigma allow_bound_rels
| PEvar (c1,args1), Evar (c2,args2) when Evar.equal c1 c2 ->
List.fold_left2 (sorec ctx env) subst args1 args2
| PInt i1, Int i2 when Uint63.equal i1 i2 -> subst
+
| PFloat f1, Float f2 when Float64.equal f1 f2 -> subst
+
+ | PArray(pt,pdef,pty), Array(_u,t,def,ty)
+ when Array.length pt = Array.length t ->
+ sorec ctx env (sorec ctx env (Array.fold_left2 (sorec ctx env) subst pt t) pdef def) pty ty
+
| (PRef _ | PVar _ | PRel _ | PApp _ | PProj _ | PLambda _
| PProd _ | PLetIn _ | PSort _ | PIf _ | PCase _
- | PFix _ | PCoFix _| PEvar _ | PInt _ | PFloat _), _ -> raise PatternMatchingFailure
+ | PFix _ | PCoFix _| PEvar _ | PInt _ | PFloat _ | PArray _), _ -> raise PatternMatchingFailure
in
sorec [] env ((Id.Map.empty,Id.Set.empty), Id.Map.empty) pat c
@@ -527,6 +533,13 @@ let sub_match ?(closed=true) env sigma pat c =
aux env term mk_ctx next
with Retyping.RetypeError _ -> next ()
end
+ | Array(u, t, def, ty) ->
+ let next_mk_ctx = function
+ | def :: ty :: l -> mk_ctx (mkArray(u, Array.of_list l, def, ty))
+ | _ -> assert false
+ in
+ let sub = (env,def) :: (env,ty) :: subargs env t in
+ try_aux sub next_mk_ctx next
| Construct _|Ind _|Evar _|Const _|Rel _|Meta _|Var _|Sort _|Int _|Float _ ->
next ()
in
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index 02c04c2300..7fcb0795bd 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -809,6 +809,12 @@ and detype_r d flags avoid env sigma t =
| CoFix (n,recdef) -> detype_cofix (detype d) flags avoid env sigma n recdef
| Int i -> GInt i
| Float f -> GFloat f
+ | Array(u,t,def,ty) ->
+ let t = Array.map (detype d flags avoid env sigma) t in
+ let def = detype d flags avoid env sigma def in
+ let ty = detype d flags avoid env sigma ty in
+ let u = detype_instance sigma u in
+ GArray(u, t, def, ty)
and detype_eqns d flags avoid env sigma ci computable constructs consnargsl bl =
try
@@ -1096,6 +1102,14 @@ let rec subst_glob_constr env subst = DAst.map (function
let k' = smartmap_cast_type (subst_glob_constr env subst) k in
if r1' == r1 && k' == k then raw else GCast (r1',k')
+ | GArray (u,t,def,ty) as raw ->
+ let def' = subst_glob_constr env subst def
+ and t' = Array.Smart.map (subst_glob_constr env subst) t
+ and ty' = subst_glob_constr env subst ty
+ in
+ if def' == def && t' == t && ty' == ty then raw else
+ GArray(u,t',def',ty')
+
)
(* Utilities to transform kernel cases to simple pattern-matching problem *)
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index 0206d4e70d..2feae8cc25 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -130,7 +130,7 @@ let flex_kind_of_term flags env evd c sk =
| Evar ev ->
if is_frozen flags ev then Rigid
else Flexible ev
- | Lambda _ | Prod _ | Sort _ | Ind _ | Construct _ | CoFix _ | Int _ | Float _ -> Rigid
+ | Lambda _ | Prod _ | Sort _ | Ind _ | Construct _ | CoFix _ | Int _ | Float _ | Array _ -> Rigid
| Meta _ -> Rigid
| Fix _ -> Rigid (* happens when the fixpoint is partially applied *)
| Cast _ | App _ | Case _ -> assert false
@@ -212,7 +212,7 @@ let occur_rigidly flags env evd (evk,_) t =
(match aux c with
| Rigid b -> Rigid b
| _ -> Reducible)
- | Meta _ | Fix _ | CoFix _ | Int _ | Float _ -> Reducible
+ | Meta _ | Fix _ | CoFix _ | Int _ | Float _ | Array _ -> Reducible
in
match aux t with
| Rigid b -> b
@@ -898,7 +898,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
only if necessary) or the second argument is potentially
usable as a canonical projection or canonical value *)
let rec is_unnamed (hd, args) = match EConstr.kind i hd with
- | (Var _|Construct _|Ind _|Const _|Prod _|Sort _|Int _ |Float _) ->
+ | (Var _|Construct _|Ind _|Const _|Prod _|Sort _|Int _ |Float _|Array _) ->
Stack.not_purely_applicative args
| (CoFix _|Meta _|Rel _)-> true
| Evar _ -> Stack.not_purely_applicative args
@@ -1019,7 +1019,8 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
| Ind _, Ind _
| Construct _, Construct _
| Int _, Int _
- | Float _, Float _ ->
+ | Float _, Float _
+ | Array _, Array _ ->
rigids env evd sk1 term1 sk2 term2
| Evar (sp1,al1), Evar (sp2,al2) -> (* Frozen evars *)
@@ -1064,9 +1065,9 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
|Some (sk1',sk2'), Success i' -> evar_conv_x flags env i' CONV (Stack.zip i' (term1,sk1')) (Stack.zip i' (term2,sk2'))
end
- | (Ind _ | Sort _ | Prod _ | CoFix _ | Fix _ | Rel _ | Var _ | Const _ | Int _ | Float _ | Evar _ | Lambda _), _ ->
+ | (Ind _ | Sort _ | Prod _ | CoFix _ | Fix _ | Rel _ | Var _ | Const _ | Int _ | Float _ | Array _ | Evar _ | Lambda _), _ ->
UnifFailure (evd,NotSameHead)
- | _, (Ind _ | Sort _ | Prod _ | CoFix _ | Fix _ | Rel _ | Var _ | Const _ | Int _ | Evar _ | Lambda _) ->
+ | _, (Ind _ | Sort _ | Prod _ | CoFix _ | Fix _ | Rel _ | Var _ | Const _ | Int _ | Array _ | Evar _ | Lambda _) ->
UnifFailure (evd,NotSameHead)
| Case _, _ -> UnifFailure (evd,NotSameHead)
| Proj _, _ -> UnifFailure (evd,NotSameHead)
@@ -1333,6 +1334,12 @@ let thin_evars env sigma sign c =
let c' = applyrec (env,0) c in
(!sigma, c')
+exception NotFoundInstance of exn
+let () = CErrors.register_handler (function
+ | NotFoundInstance e ->
+ Some Pp.(str "Failed to instantiate evar: " ++ CErrors.print e)
+ | _ -> None)
+
let second_order_matching flags env_rhs evd (evk,args) (test,argoccs) rhs =
try
let evi = Evd.find_undefined evd evk in
@@ -1410,11 +1417,10 @@ let second_order_matching flags env_rhs evd (evk,args) (test,argoccs) rhs =
refresh_universes ~status:Evd.univ_flexible (Some true)
env_evar_unf evd evty
else evd, evty in
- let (evd, ev) = new_evar_instance sign evd evty ~filter instance in
- let evk = fst (destEvar evd ev) in
+ let (evd, evk) = new_pure_evar sign evd evty ~filter in
evsref := (evk,evty,inst,prefer_abstraction)::!evsref;
fixed := Evar.Set.add evk !fixed;
- evd, ev
+ evd, mkEvar (evk, instance)
in
let evd, rhs' = apply_on_subterm env_rhs evd fixed set_var test c rhs in
if debug_ho_unification () then
@@ -1478,7 +1484,9 @@ let second_order_matching flags env_rhs evd (evk,args) (test,argoccs) rhs =
List.exists (fun c -> isVarId evd id (EConstr.of_constr c)) l ->
instantiate_evar evar_unify flags env_rhs evd ev vid
| _ -> evd)
- with e -> user_err (Pp.str "Cannot find an instance")
+ with e when CErrors.noncritical e ->
+ let e, info = Exninfo.capture e in
+ Exninfo.iraise (NotFoundInstance e, info)
else
((if debug_ho_unification () then
let evi = Evd.find evd evk in
diff --git a/pretyping/evardefine.ml b/pretyping/evardefine.ml
index 71edcaa231..f33030d6a4 100644
--- a/pretyping/evardefine.ml
+++ b/pretyping/evardefine.ml
@@ -180,26 +180,71 @@ let define_evar_as_sort env evd (ev,args) =
constraint on its domain and codomain. If the input constraint is
an evar instantiate it with the product of 2 new evars. *)
+let rec presplit env sigma c =
+ let c = Reductionops.whd_all env sigma c in
+ match EConstr.kind sigma c with
+ | App (h,args) when isEvar sigma h ->
+ let sigma, lam = define_evar_as_lambda env sigma (destEvar sigma h) in
+ (* XXX could be just whd_all -> no recursion? *)
+ presplit env sigma (mkApp (lam, args))
+ | _ -> sigma, c
+
let split_tycon ?loc env evd tycon =
- let rec real_split evd c =
- let t = Reductionops.whd_all env evd c in
- match EConstr.kind evd t with
- | Prod (na,dom,rng) -> evd, (na, dom, rng)
- | Evar ev (* ev is undefined because of whd_all *) ->
- let (evd',prod) = define_evar_as_product env evd ev in
- let (na,dom,rng) = destProd evd prod in
- let anon = {na with binder_name = Anonymous} in
- evd',(anon, dom, rng)
- | App (c,args) when isEvar evd c ->
- let (evd',lam) = define_evar_as_lambda env evd (destEvar evd c) in
- real_split evd' (mkApp (lam,args))
- | _ -> error_not_product ?loc env evd c
- in
- match tycon with
- | None -> evd,(make_annot Anonymous Relevant,None,None)
- | Some c ->
- let evd', (n, dom, rng) = real_split evd c in
- evd', (n, mk_tycon dom, mk_tycon rng)
+ match tycon with
+ | None -> evd,(make_annot Anonymous Relevant,None,None)
+ | Some c ->
+ let evd, c = presplit env evd c in
+ let evd, na, dom, rng = match EConstr.kind evd c with
+ | Prod (na,dom,rng) -> evd, na, dom, rng
+ | Evar ev ->
+ let (evd,prod) = define_evar_as_product env evd ev in
+ let (na,dom,rng) = destProd evd prod in
+ let anon = {na with binder_name = Anonymous} in
+ evd, anon, dom, rng
+ | _ ->
+ (* XXX no error to allow later coercion? Not sure if possible with funclass *)
+ error_not_product ?loc env evd c
+ in
+ evd, (na, mk_tycon dom, mk_tycon rng)
+
+
+let define_pure_evar_as_array env sigma evk =
+ let evi = Evd.find_undefined sigma evk in
+ let evenv = evar_env env evi in
+ let evksrc = evar_source evk sigma in
+ let src = subterm_source evk ~where:Domain evksrc in
+ let sigma, (ty,u) = new_type_evar evenv sigma univ_flexible ~src ~filter:(evar_filter evi) in
+ let concl = Reductionops.whd_all evenv sigma evi.evar_concl in
+ let s = destSort sigma concl in
+ (* array@{u} ty : Type@{u} <= Type@{s} *)
+ let sigma = Evd.set_leq_sort env sigma u (ESorts.kind sigma s) in
+ let u = Option.get (Univ.Universe.level (Sorts.univ_of_sort u)) in
+ let ar = Typeops.type_of_array env (Univ.Instance.of_array [|u|]) in
+ let sigma = Evd.define evk (mkApp (EConstr.of_constr ar, [| ty |])) sigma in
+ sigma
+
+let is_array_const env sigma c =
+ match EConstr.kind sigma c with
+ | Const (cst,_) ->
+ (match env.Environ.retroknowledge.Retroknowledge.retro_array with
+ | None -> false
+ | Some cst' -> Constant.equal cst cst')
+ | _ -> false
+
+let split_as_array env sigma0 = function
+ | None -> sigma0, None
+ | Some c ->
+ let sigma, c = presplit env sigma0 c in
+ match EConstr.kind sigma c with
+ | App (h,[|ty|]) when is_array_const env sigma h -> sigma, Some ty
+ | Evar ev ->
+ let sigma = define_pure_evar_as_array env sigma (fst ev) in
+ let ty = match EConstr.kind sigma c with
+ | App (_,[|ty|]) -> ty
+ | _ -> assert false
+ in
+ sigma, Some ty
+ | _ -> sigma0, None
let valcon_of_tycon x = x
let lift_tycon n = Option.map (lift n)
diff --git a/pretyping/evardefine.mli b/pretyping/evardefine.mli
index a4169c2298..e5c3f8baa1 100644
--- a/pretyping/evardefine.mli
+++ b/pretyping/evardefine.mli
@@ -35,6 +35,11 @@ val split_tycon :
?loc:Loc.t -> env -> evar_map -> type_constraint ->
evar_map * (Name.t Context.binder_annot * type_constraint * type_constraint)
+val split_as_array : env -> evar_map -> type_constraint ->
+ evar_map * type_constraint
+(** If the constraint can be made to look like [array A] return [A],
+ otherwise return [None] (this makes later coercion possible). *)
+
val valcon_of_tycon : type_constraint -> val_constraint
val lift_tycon : int -> type_constraint -> type_constraint
diff --git a/pretyping/evarsolve.ml b/pretyping/evarsolve.ml
index 348d7c0b2f..79839099f7 100644
--- a/pretyping/evarsolve.ml
+++ b/pretyping/evarsolve.ml
@@ -698,10 +698,9 @@ let make_projectable_subst aliases sigma evi args =
*)
let define_evar_from_virtual_equation define_fun env evd src t_in_env ty_t_in_sign sign filter inst_in_env =
- let (evd, evar_in_env) = new_evar_instance sign evd ty_t_in_sign ~filter ~src inst_in_env in
+ let (evd, evk) = new_pure_evar sign evd ty_t_in_sign ~filter ~src in
let t_in_env = whd_evar evd t_in_env in
- let (evk, _) = destEvar evd evar_in_env in
- let evd = define_fun env evd None (destEvar evd evar_in_env) t_in_env in
+ let evd = define_fun env evd None (evk, inst_in_env) t_in_env in
let ctxt = named_context_of_val sign in
let inst_in_sign = inst_of_vars (Filter.filter_list filter ctxt) in
let evar_in_sign = mkEvar (evk, inst_in_sign) in
@@ -770,9 +769,9 @@ let materialize_evar define_fun env evd k (evk1,args1) ty_in_env =
define_evar_from_virtual_equation define_fun env evd src ty_in_env
ty_t_in_sign sign2 filter2 inst2_in_env in
let (evd, ev2_in_sign) =
- new_evar_instance sign2 evd ev2ty_in_sign ~filter:filter2 ~src inst2_in_sign in
- let ev2_in_env = (fst (destEvar evd ev2_in_sign), inst2_in_env) in
- (evd, ev2_in_sign, ev2_in_env)
+ new_pure_evar sign2 evd ev2ty_in_sign ~filter:filter2 ~src in
+ let ev2_in_env = (ev2_in_sign, inst2_in_env) in
+ (evd, mkEvar (ev2_in_sign, inst2_in_sign), ev2_in_env)
let restrict_upon_filter evd evk p args =
let oldfullfilter = evar_filter (Evd.find_undefined evd evk) in
diff --git a/pretyping/globEnv.ml b/pretyping/globEnv.ml
index 05abb86f46..81a62a7048 100644
--- a/pretyping/globEnv.ml
+++ b/pretyping/globEnv.ml
@@ -110,7 +110,8 @@ let new_evar env sigma ?src ?naming typ =
let instance = rel_list (nb_rel env.renamed_env) inst_vars in
let (subst, _, sign) = Lazy.force env.extra in
let typ' = csubst_subst subst typ in
- new_evar_instance sign sigma typ' ?src ?naming instance
+ let (sigma, evk) = new_pure_evar sign sigma typ' ?src ?naming in
+ (sigma, mkEvar (evk, instance))
let new_type_evar env sigma ~src =
let sigma, s = Evd.new_sort_variable Evd.univ_flexible_alg sigma in
diff --git a/pretyping/glob_ops.ml b/pretyping/glob_ops.ml
index 342175a512..5bd26be823 100644
--- a/pretyping/glob_ops.ml
+++ b/pretyping/glob_ops.ml
@@ -168,9 +168,12 @@ let mk_glob_constr_eq f c1 c2 = match DAst.get c1, DAst.get c2 with
f c1 c2 && cast_type_eq f t1 t2
| GInt i1, GInt i2 -> Uint63.equal i1 i2
| GFloat f1, GFloat f2 -> Float64.equal f1 f2
+ | GArray (u1, t1, def1, ty1), GArray (u2, t2, def2, ty2) ->
+ Array.equal f t1 t2 && f def1 def2 && f ty1 ty2 &&
+ Option.equal (List.equal glob_level_eq) u1 u2
| (GRef _ | GVar _ | GEvar _ | GPatVar _ | GApp _ | GLambda _ | GProd _ | GLetIn _ |
GCases _ | GLetTuple _ | GIf _ | GRec _ | GSort _ | GHole _ | GCast _ |
- GInt _ | GFloat _), _ -> false
+ GInt _ | GFloat _ | GArray _), _ -> false
let rec glob_constr_eq c = mk_glob_constr_eq glob_constr_eq c
@@ -231,6 +234,11 @@ let map_glob_constr_left_to_right f = DAst.map (function
let comp1 = f c in
let comp2 = map_cast_type f k in
GCast (comp1,comp2)
+ | GArray (u,t,def,ty) ->
+ let comp1 = Array.map_left f t in
+ let comp2 = f def in
+ let comp3 = f ty in
+ GArray (u,comp1,comp2,comp3)
| (GVar _ | GSort _ | GHole _ | GRef _ | GEvar _ | GPatVar _ | GInt _ | GFloat _) as x -> x
)
@@ -263,6 +271,7 @@ let fold_glob_constr f acc = DAst.with_val (function
let acc = match k with
| CastConv t | CastVM t | CastNative t -> f acc t | CastCoerce -> acc in
f acc c
+ | GArray (_u,t,def,ty) -> f (f (Array.fold_left f acc t) def) ty
| (GSort _ | GHole _ | GRef _ | GEvar _ | GPatVar _ | GInt _ | GFloat _) -> acc
)
let fold_return_type_with_binders f g v acc (na,tyopt) =
@@ -305,6 +314,7 @@ let fold_glob_constr_with_binders g f v acc = DAst.(with_val (function
let acc = match k with
| CastConv t | CastVM t | CastNative t -> f v acc t | CastCoerce -> acc in
f v acc c
+ | GArray (_u, t, def, ty) -> f v (f v (Array.fold_left (f v) acc t) def) ty
| (GSort _ | GHole _ | GRef _ | GEvar _ | GPatVar _ | GInt _ | GFloat _) -> acc))
let iter_glob_constr f = fold_glob_constr (fun () -> f) ()
diff --git a/pretyping/glob_term.ml b/pretyping/glob_term.ml
index bccc30ad62..526eac6f1e 100644
--- a/pretyping/glob_term.ml
+++ b/pretyping/glob_term.ml
@@ -92,6 +92,7 @@ type 'a glob_constr_r =
| GCast of 'a glob_constr_g * 'a glob_constr_g cast_type
| GInt of Uint63.t
| GFloat of Float64.t
+ | GArray of glob_level list option * 'a glob_constr_g array * 'a glob_constr_g * 'a glob_constr_g
and 'a glob_constr_g = ('a glob_constr_r, 'a) DAst.t
and 'a glob_decl_g = Name.t * binding_kind * 'a glob_constr_g option * 'a glob_constr_g
diff --git a/pretyping/heads.ml b/pretyping/heads.ml
index 98cfbf7fa7..d1ac0862ed 100644
--- a/pretyping/heads.ml
+++ b/pretyping/heads.ml
@@ -79,7 +79,7 @@ and kind_of_head env t =
| Proj (p,c) -> RigidHead RigidOther
| Case (_,_,_,c,_) -> aux k [] c true
- | Int _ | Float _ -> ConstructorHead
+ | Int _ | Float _ | Array _ -> ConstructorHead
| Fix ((i,j),_) ->
let n = i.(j) in
try aux k [] (List.nth l n) true
diff --git a/pretyping/indrec.ml b/pretyping/indrec.ml
index 0e7fac35f1..5be8f9f83c 100644
--- a/pretyping/indrec.ml
+++ b/pretyping/indrec.ml
@@ -207,7 +207,7 @@ let type_rec_branch is_rec dep env sigma (vargs,depPvect,decP) tyi cs recargs =
| ra::rest ->
(match dest_recarg ra with
| Mrec (_,j) when is_rec -> (depPvect.(j),rest)
- | Imbr _ -> (None,rest)
+ | Nested _ -> (None,rest)
| _ -> (None, rest))
in
(match optionpos with
@@ -280,7 +280,7 @@ let make_rec_branch_arg env sigma (nparrec,fvect,decF) f cstr recargs =
let optionpos =
match dest_recarg recarg with
| Norec -> None
- | Imbr _ -> None
+ | Nested _ -> None
| Mrec (_,i) -> fvect.(i)
in
(match optionpos with
diff --git a/pretyping/keys.ml b/pretyping/keys.ml
index 1e4f2f2340..7a7099c195 100644
--- a/pretyping/keys.ml
+++ b/pretyping/keys.ml
@@ -27,6 +27,7 @@ type key =
| KRel
| KInt
| KFloat
+ | KArray
module KeyOrdered = struct
type t = key
@@ -44,6 +45,7 @@ module KeyOrdered = struct
| KRel -> 7
| KInt -> 8
| KFloat -> 9
+ | KArray -> 10
let compare gr1 gr2 =
match gr1, gr2 with
@@ -138,6 +140,7 @@ let constr_key kind c =
| LetIn _ -> KLet
| Int _ -> KInt
| Float _ -> KFloat
+ | Array _ -> KArray
in Some (aux c)
with Not_found -> None
@@ -155,6 +158,7 @@ let pr_key pr_global = function
| KRel -> str"Rel"
| KInt -> str"Int"
| KFloat -> str"Float"
+ | KArray -> str"Array"
let pr_keyset pr_global v =
prlist_with_sep spc (pr_key pr_global) (Keyset.elements v)
diff --git a/pretyping/nativenorm.ml b/pretyping/nativenorm.ml
index 89bd7e196f..3f68e3c78f 100644
--- a/pretyping/nativenorm.ml
+++ b/pretyping/nativenorm.ml
@@ -214,6 +214,7 @@ let rec nf_val env sigma v typ =
| Vconst n -> construct_of_constr_const env sigma n typ
| Vint64 i -> i |> Uint63.of_int64 |> mkInt
| Vfloat64 f -> f |> Float64.of_float |> mkFloat
+ | Varray t -> nf_array env sigma t typ
| Vblock b ->
let capp,ctyp = construct_of_constr_block env sigma (block_tag b) typ in
let args = nf_bargs env sigma b ctyp in
@@ -317,13 +318,12 @@ and nf_atom_type env sigma atom =
| Avar id ->
mkVar id, Typeops.type_of_variable env id
| Acase(ans,accu,p,bs) ->
- let () = if Typeops.should_invert_case env ans.asw_ci then
- (* TODO implement case inversion readback (properly reducing
- it is a problem for the kernel) *)
- CErrors.user_err Pp.(str "Native compute readback of case inversion not implemented.")
- in
let a,ta = nf_accu_type env sigma accu in
let ((mind,_),u as ind),allargs = find_rectype_a env ta in
+ let iv = if Typeops.should_invert_case env ans.asw_ci then
+ CaseInvert {univs=u; args=allargs}
+ else NoInvert
+ in
let (mib,mip) = Inductive.lookup_mind_specif env (fst ind) in
let nparams = mib.mind_nparams in
let params,realargs = Array.chop nparams allargs in
@@ -343,7 +343,7 @@ and nf_atom_type env sigma atom =
in
let branchs = Array.mapi mkbranch bsw in
let tcase = build_case_type p realargs a in
- mkCase(ans.asw_ci, p, NoInvert, a, branchs), tcase
+ mkCase(ans.asw_ci, p, iv, a, branchs), tcase
| Afix(tt,ft,rp,s) ->
let tt = Array.map (fun t -> nf_type_sort env sigma t) tt in
let tt = Array.map fst tt and rt = Array.map snd tt in
@@ -442,6 +442,14 @@ and nf_evar env sigma evk args =
evar node *)
mkEvar (evk, List.rev args), ty
+and nf_array env sigma t typ =
+ let ty, allargs = app_type env typ in
+ let typ_elem = allargs.(0) in
+ let t, vdef = Parray.to_array t in
+ let t = Array.map (fun v -> nf_val env sigma v typ_elem) t in
+ let u = snd (destConst ty) in
+ mkArray(u, t, nf_val env sigma vdef typ_elem, typ_elem)
+
let evars_of_evar_map sigma =
{ Nativelambda.evars_val = Evd.existential_opt_value0 sigma;
Nativelambda.evars_metas = Evd.meta_type0 sigma }
diff --git a/pretyping/pattern.ml b/pretyping/pattern.ml
index 1dfb8b2cd1..f6d61f4892 100644
--- a/pretyping/pattern.ml
+++ b/pretyping/pattern.ml
@@ -41,6 +41,7 @@ type constr_pattern =
| PCoFix of int * (Name.t array * constr_pattern array * constr_pattern array)
| PInt of Uint63.t
| PFloat of Float64.t
+ | PArray of constr_pattern array * constr_pattern * constr_pattern
(** Nota : in a [PCase], the array of branches might be shorter than
expected, denoting the use of a final "_ => _" branch *)
diff --git a/pretyping/patternops.ml b/pretyping/patternops.ml
index 4aedeb43e3..8c3d624f0f 100644
--- a/pretyping/patternops.ml
+++ b/pretyping/patternops.ml
@@ -64,10 +64,13 @@ let rec constr_pattern_eq p1 p2 = match p1, p2 with
Uint63.equal i1 i2
| PFloat f1, PFloat f2 ->
Float64.equal f1 f2
+| PArray (t1, def1, ty1), PArray (t2, def2, ty2) ->
+ Array.equal constr_pattern_eq t1 t2 && constr_pattern_eq def1 def2
+ && constr_pattern_eq ty1 ty2
| (PRef _ | PVar _ | PEvar _ | PRel _ | PApp _ | PSoApp _
| PLambda _ | PProd _ | PLetIn _ | PSort _ | PMeta _
| PIf _ | PCase _ | PFix _ | PCoFix _ | PProj _ | PInt _
- | PFloat _), _ -> false
+ | PFloat _ | PArray _), _ -> false
(** FIXME: fixpoint and cofixpoint should be relativized to pattern *)
and pattern_eq (i1, j1, p1) (i2, j2, p2) =
@@ -93,6 +96,8 @@ let rec occur_meta_pattern = function
(occur_meta_pattern p) ||
(occur_meta_pattern c) ||
(List.exists (fun (_,_,p) -> occur_meta_pattern p) br)
+ | PArray (t,def,ty) ->
+ Array.exists occur_meta_pattern t || occur_meta_pattern def || occur_meta_pattern ty
| PMeta _ | PSoApp _ -> true
| PEvar _ | PVar _ | PRef _ | PRel _ | PSort _ | PFix _ | PCoFix _
| PInt _ | PFloat _ -> false
@@ -121,6 +126,8 @@ let rec occurn_pattern n = function
Array.exists (occurn_pattern n) tl || Array.exists (occurn_pattern (n+Array.length tl)) bl
| PCoFix (_,(_,tl,bl)) ->
Array.exists (occurn_pattern n) tl || Array.exists (occurn_pattern (n+Array.length tl)) bl
+ | PArray (t,def,ty) ->
+ Array.exists (occurn_pattern n) t || occurn_pattern n def || occurn_pattern n ty
let noccurn_pattern n c = not (occurn_pattern n c)
@@ -139,7 +146,8 @@ let rec head_pattern_bound t =
-> raise BoundPattern
(* Perhaps they were arguments, but we don't beta-reduce *)
| PLambda _ -> raise BoundPattern
- | PCoFix _ | PInt _ | PFloat _ -> anomaly ~label:"head_pattern_bound" (Pp.str "not a type.")
+ | PCoFix _ | PInt _ | PFloat _ | PArray _ ->
+ anomaly ~label:"head_pattern_bound" (Pp.str "not a type.")
let head_of_constr_reference sigma c = match EConstr.kind sigma c with
| Const (sp,_) -> GlobRef.ConstRef sp
@@ -217,7 +225,10 @@ let pattern_of_constr env sigma t =
PCoFix (ln,(Array.map binder_name lna,Array.map (pattern_of_constr env) tl,
Array.map (pattern_of_constr env') bl))
| Int i -> PInt i
- | Float f -> PFloat f in
+ | Float f -> PFloat f
+ | Array (_u, t, def, ty) ->
+ PArray (Array.map (pattern_of_constr env) t, pattern_of_constr env def, pattern_of_constr env ty)
+ in
pattern_of_constr env t
(* To process patterns, we need a translation without typing at all. *)
@@ -238,6 +249,7 @@ let map_pattern_with_binders g f l = function
| PCoFix (ln,(lna,tl,bl)) ->
let l' = Array.fold_left (fun l na -> g na l) l lna in
PCoFix (ln,(lna,Array.map (f l) tl,Array.map (f l') bl))
+ | PArray (t,def,ty) -> PArray (Array.map (f l) t, f l def, f l ty)
(* Non recursive *)
| (PVar _ | PEvar _ | PRel _ | PRef _ | PSort _ | PMeta _ | PInt _
| PFloat _ as x) -> x
@@ -359,6 +371,12 @@ let rec subst_pattern env sigma subst pat =
let bl' = Array.Smart.map (subst_pattern env sigma subst) bl in
if bl' == bl && tl' == tl then pat
else PCoFix (ln,(lna,tl',bl'))
+ | PArray (t,def,ty) ->
+ let t' = Array.Smart.map (subst_pattern env sigma subst) t in
+ let def' = subst_pattern env sigma subst def in
+ let ty' = subst_pattern env sigma subst ty in
+ if def' == def && t' == t && ty' == ty then pat
+ else PArray (t',def',ty')
let mkPLetIn na b t c = PLetIn(na,b,t,c)
let mkPProd na t u = PProd(na,t,u)
@@ -502,7 +520,7 @@ let rec pat_of_raw metas vars = DAst.with_loc_val (fun ?loc -> function
| GInt i -> PInt i
| GFloat f -> PFloat f
- | GPatVar _ | GIf _ | GLetTuple _ | GCases _ | GEvar _ ->
+ | GPatVar _ | GIf _ | GLetTuple _ | GCases _ | GEvar _ | GArray _ ->
err ?loc (Pp.str "Non supported pattern."))
and pat_of_glob_in_context metas vars decls c =
diff --git a/pretyping/pretype_errors.ml b/pretyping/pretype_errors.ml
index 414663c826..207ffc7b86 100644
--- a/pretyping/pretype_errors.ml
+++ b/pretyping/pretype_errors.ml
@@ -66,6 +66,7 @@ exception PretypeError of env * Evd.evar_map * pretype_error
let precatchable_exception = function
| CErrors.UserError _ | TypeError _ | PretypeError _
+ | Reductionops.AnomalyInConversion _
| Nametab.GlobalizationError _ -> true
| _ -> false
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index e4403d5bf4..b9825b6a92 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -508,6 +508,7 @@ type pretyper = {
pretype_cast : pretyper -> glob_constr * glob_constr cast_type -> unsafe_judgment pretype_fun;
pretype_int : pretyper -> Uint63.t -> unsafe_judgment pretype_fun;
pretype_float : pretyper -> Float64.t -> unsafe_judgment pretype_fun;
+ pretype_array : pretyper -> glob_level list option * glob_constr array * glob_constr * glob_constr -> unsafe_judgment pretype_fun;
pretype_type : pretyper -> glob_constr -> unsafe_type_judgment pretype_fun;
}
@@ -549,6 +550,8 @@ let eval_pretyper self ~program_mode ~poly resolve_tc tycon env sigma t =
self.pretype_int self n ?loc ~program_mode ~poly resolve_tc tycon env sigma
| GFloat f ->
self.pretype_float self f ?loc ~program_mode ~poly resolve_tc tycon env sigma
+ | GArray (u,t,def,ty) ->
+ self.pretype_array self (u,t,def,ty) ?loc ~program_mode ~poly resolve_tc tycon env sigma
let eval_type_pretyper self ~program_mode ~poly resolve_tc tycon env sigma t =
self.pretype_type self t ~program_mode ~poly resolve_tc tycon env sigma
@@ -1196,24 +1199,6 @@ struct
sigma, { uj_val = v; uj_type = tval }
in discard_trace @@ inh_conv_coerce_to_tycon ?loc ~program_mode resolve_tc env sigma cj tycon
- let pretype_int self i =
- fun ?loc ~program_mode ~poly resolve_tc tycon env sigma ->
- let resj =
- try Typing.judge_of_int !!env i
- with Invalid_argument _ ->
- user_err ?loc ~hdr:"pretype" (str "Type of int63 should be registered first.")
- in
- discard_trace @@ inh_conv_coerce_to_tycon ?loc ~program_mode resolve_tc env sigma resj tycon
-
- let pretype_float self f =
- fun ?loc ~program_mode ~poly resolve_tc tycon env sigma ->
- let resj =
- try Typing.judge_of_float !!env f
- with Invalid_argument _ ->
- user_err ?loc ~hdr:"pretype" (str "Type of float should be registered first.")
- in
- discard_trace @@ inh_conv_coerce_to_tycon ?loc ~program_mode resolve_tc env sigma resj tycon
-
(* [pretype_type valcon env sigma c] coerces [c] into a type *)
let pretype_type self c ?loc ~program_mode ~poly resolve_tc valcon (env : GlobEnv.t) sigma = match DAst.get c with
| GHole (knd, naming, None) ->
@@ -1255,6 +1240,52 @@ let pretype_type self c ?loc ~program_mode ~poly resolve_tc valcon (env : GlobEn
?loc:(loc_of_glob_constr c) !!env sigma tj.utj_val v
end
+ let pretype_int self i =
+ fun ?loc ~program_mode ~poly resolve_tc tycon env sigma ->
+ let resj =
+ try Typing.judge_of_int !!env i
+ with Invalid_argument _ ->
+ user_err ?loc ~hdr:"pretype" (str "Type of int63 should be registered first.")
+ in
+ discard_trace @@ inh_conv_coerce_to_tycon ?loc ~program_mode resolve_tc env sigma resj tycon
+
+ let pretype_float self f =
+ fun ?loc ~program_mode ~poly resolve_tc tycon env sigma ->
+ let resj =
+ try Typing.judge_of_float !!env f
+ with Invalid_argument _ ->
+ user_err ?loc ~hdr:"pretype" (str "Type of float should be registered first.")
+ in
+ discard_trace @@ inh_conv_coerce_to_tycon ?loc ~program_mode resolve_tc env sigma resj tycon
+
+ let pretype_array self (u,t,def,ty) =
+ fun ?loc ~program_mode ~poly resolve_tc tycon env sigma ->
+ let sigma, tycon' = split_as_array !!env sigma tycon in
+ let sigma, jty = eval_type_pretyper self ~program_mode ~poly resolve_tc tycon' env sigma ty in
+ (* XXX not sure if we need to be this complex, I wrote this while
+ being confused by broken universe substitutions *)
+ let sigma, u = match Univ.Universe.level (Sorts.univ_of_sort jty.utj_type) with
+ | Some u ->
+ let sigma = Evd.make_nonalgebraic_variable sigma u in
+ sigma, u
+ | None ->
+ let sigma, u = Evd.new_univ_level_variable UState.univ_flexible sigma in
+ let sigma = Evd.set_leq_sort !!env sigma jty.utj_type
+ (Sorts.sort_of_univ (Univ.Universe.make u))
+ in
+ sigma, u
+ in
+ let sigma, jdef = eval_pretyper self ~program_mode ~poly resolve_tc (mk_tycon jty.utj_val) env sigma def in
+ let pretype_elem = eval_pretyper self ~program_mode ~poly resolve_tc (mk_tycon jty.utj_val) env in
+ let sigma, jt = Array.fold_left_map pretype_elem sigma t in
+ let u = Univ.Instance.of_array [| u |] in
+ let ta = EConstr.of_constr @@ Typeops.type_of_array !!env u in
+ let j = {
+ uj_val = EConstr.mkArray(EInstance.make u, Array.map (fun j -> j.uj_val) jt, jdef.uj_val, jty.utj_val);
+ uj_type = EConstr.mkApp(ta,[|jdef.uj_type|])
+ } in
+ discard_trace @@ inh_conv_coerce_to_tycon ?loc ~program_mode resolve_tc env sigma j tycon
+
end
(* [pretype tycon env sigma lvar lmeta cstr] attempts to type [cstr] *)
@@ -1281,6 +1312,7 @@ let default_pretyper =
pretype_cast = pretype_cast;
pretype_int = pretype_int;
pretype_float = pretype_float;
+ pretype_array = pretype_array;
pretype_type = pretype_type;
}
diff --git a/pretyping/pretyping.mli b/pretyping/pretyping.mli
index 8be7b1477b..c03374c59f 100644
--- a/pretyping/pretyping.mli
+++ b/pretyping/pretyping.mli
@@ -163,6 +163,7 @@ type pretyper = {
pretype_cast : pretyper -> glob_constr * glob_constr cast_type -> unsafe_judgment pretype_fun;
pretype_int : pretyper -> Uint63.t -> unsafe_judgment pretype_fun;
pretype_float : pretyper -> Float64.t -> unsafe_judgment pretype_fun;
+ pretype_array : pretyper -> glob_level list option * glob_constr array * glob_constr * glob_constr -> unsafe_judgment pretype_fun;
pretype_type : pretyper -> glob_constr -> unsafe_type_judgment pretype_fun;
}
(** Type of pretyping algorithms in open-recursion style. A typical way to
diff --git a/pretyping/pretyping.mllib b/pretyping/pretyping.mllib
index 07154d4e03..c31ecc135c 100644
--- a/pretyping/pretyping.mllib
+++ b/pretyping/pretyping.mllib
@@ -1,8 +1,8 @@
Geninterp
Locus
Locusops
-Pretype_errors
Reductionops
+Pretype_errors
Inductiveops
Arguments_renaming
Retyping
diff --git a/pretyping/recordops.ml b/pretyping/recordops.ml
index a8e934d3c6..e6e5ad8dd4 100644
--- a/pretyping/recordops.ml
+++ b/pretyping/recordops.ml
@@ -54,34 +54,29 @@ let structure_table =
let projection_table =
Summary.ref (Cmap.empty : struc_typ Cmap.t) ~name:"record-projs"
-(* TODO: could be unify struc_typ and struc_tuple ? *)
-
-type struc_tuple =
- constructor * proj_kind list * Constant.t option list
-
-let register_structure env (id,kl,projs) =
- let open Declarations in
- let ind = fst id in
- let mib, mip = Inductive.lookup_mind_specif env ind in
- let n = mib.mind_nparams in
- let struc =
- { s_CONST = id; s_EXPECTEDPARAM = n; s_PROJ = projs; s_PROJKIND = kl } in
+let register_structure ({ s_CONST = (ind,_); s_PROJ = projs; } as struc) =
structure_table := Indmap.add ind struc !structure_table;
projection_table :=
List.fold_right (Option.fold_right (fun proj -> Cmap.add proj struc))
projs !projection_table
-let subst_structure subst (id, kl, projs as obj) =
+let subst_structure subst struc =
let projs' =
(* invariant: struc.s_PROJ is an evaluable reference. Thus we can take *)
(* the first component of subst_con. *)
List.Smart.map
(Option.Smart.map (subst_constant subst))
- projs
+ struc.s_PROJ
in
- let id' = Globnames.subst_constructor subst id in
- if projs' == projs && id' == id then obj else
- (id',kl,projs')
+ let id' = Globnames.subst_constructor subst struc.s_CONST in
+ if projs' == struc.s_PROJ && id' == struc.s_CONST
+ then struc
+ else { struc with s_CONST = id'; s_PROJ = projs' }
+
+let rebuild_structure env struc =
+ let mib = Environ.lookup_mind (fst (fst struc.s_CONST)) env in
+ let npars = mib.Declarations.mind_nparams in
+ { struc with s_EXPECTEDPARAM = npars }
let lookup_structure indsp = Indmap.find indsp !structure_table
@@ -185,7 +180,7 @@ let rec cs_pattern_of_constr env t =
| Rel n -> Default_cs, Some n, []
| Prod (_,a,b) when Vars.noccurn 1 b -> Prod_cs, None, [a; Vars.lift (-1) b]
| Proj (p, c) ->
- let { Environ.uj_type = ty } = Typeops.infer env c in
+ let ty = Retyping.get_type_of_constr env c in
let _, params = Inductive.find_rectype env ty in
Const_cs (GlobRef.ConstRef (Projection.constant p)), None, params @ [c]
| Sort s -> Sort_cs (Sorts.family s), None, []
diff --git a/pretyping/recordops.mli b/pretyping/recordops.mli
index 955a4e7aae..3be60d5e62 100644
--- a/pretyping/recordops.mli
+++ b/pretyping/recordops.mli
@@ -27,13 +27,12 @@ type struc_typ = {
s_CONST : constructor;
s_EXPECTEDPARAM : int;
s_PROJKIND : proj_kind list;
- s_PROJ : Constant.t option list }
-
-type struc_tuple =
- constructor * proj_kind list * Constant.t option list
+ s_PROJ : Constant.t option list;
+}
-val register_structure : Environ.env -> struc_tuple -> unit
-val subst_structure : Mod_subst.substitution -> struc_tuple -> struc_tuple
+val register_structure : struc_typ -> unit
+val subst_structure : Mod_subst.substitution -> struc_typ -> struc_typ
+val rebuild_structure : Environ.env -> struc_typ -> struc_typ
(** [lookup_structure isp] returns the struc_typ associated to the
inductive path [isp] if it corresponds to a structure, otherwise
diff --git a/pretyping/reductionops.ml b/pretyping/reductionops.ml
index 18a0637efa..fdc770dba6 100644
--- a/pretyping/reductionops.ml
+++ b/pretyping/reductionops.ml
@@ -422,8 +422,8 @@ struct
let get_next_primitive_args kargs stk =
let rec nargs = function
| [] -> 0
- | CPrimitives.Kwhnf :: _ -> 0
- | _ :: s -> 1 + nargs s
+ | (CPrimitives.Kwhnf | CPrimitives.Karg) :: _ -> 0
+ | CPrimitives.Kparam :: s -> 1 + nargs s
in
let n = nargs kargs in
(List.skipn (n+1) kargs, strip_n_app n stk)
@@ -436,15 +436,11 @@ type state = constr * constr Stack.t
type reduction_function = env -> evar_map -> constr -> constr
type e_reduction_function = env -> evar_map -> constr -> evar_map * constr
-type contextual_stack_reduction_function =
+type stack_reduction_function =
env -> evar_map -> constr -> constr * constr list
-type stack_reduction_function = contextual_stack_reduction_function
-type local_stack_reduction_function =
- evar_map -> constr -> constr * constr list
type state_reduction_function =
env -> evar_map -> state -> state
-type local_state_reduction_function = evar_map -> state -> state
let pr_state env sigma (tm,sk) =
let open Pp in
@@ -572,14 +568,6 @@ let reduce_and_refold_fix recfun env sigma fix sk =
(fun _ (t,sk') -> recfun (t,sk'))
[] sigma raw_answer sk
-let fix_recarg ((recindices,bodynum),_) stack =
- assert (0 <= bodynum && bodynum < Array.length recindices);
- let recargnum = Array.get recindices bodynum in
- try
- Some (recargnum, Stack.nth stack recargnum)
- with Not_found ->
- None
-
open Primred
module CNativeEntries =
@@ -588,6 +576,7 @@ struct
type elem = EConstr.t
type args = EConstr.t array
type evd = evar_map
+ type uinstance = EConstr.EInstance.t
let get = Array.get
@@ -601,6 +590,11 @@ struct
| Float f -> f
| _ -> raise Primred.NativeDestKO
+ let get_parray evd e =
+ match EConstr.kind evd e with
+ | Array(_u,t,def,_ty) -> Parray.of_array t def
+ | _ -> raise Not_found
+
let mkInt env i =
mkInt i
@@ -611,12 +605,12 @@ struct
let (ct,cf) = get_bool_constructors env in
mkConstruct (if b then ct else cf)
- let mkCarry env b e =
- let int_ty = mkConst @@ get_int_type env in
- let (c0,c1) = get_carry_constructors env in
- mkApp (mkConstruct (if b then c1 else c0),[|int_ty;e|])
+ let mkCarry env b e =
+ let int_ty = mkConst @@ get_int_type env in
+ let (c0,c1) = get_carry_constructors env in
+ mkApp (mkConstruct (if b then c1 else c0),[|int_ty;e|])
- let mkIntPair env e1 e2 =
+ let mkIntPair env e1 e2 =
let int_ty = mkConst @@ get_int_type env in
let c = get_pair_constructor env in
mkApp(mkConstruct c, [|int_ty;int_ty;e1;e2|])
@@ -699,6 +693,11 @@ struct
let (_pNormal,_nNormal,_pSubn,_nSubn,_pZero,_nZero,_pInf,_nInf,nan) =
get_f_class_constructors env in
mkConstruct nan
+
+ let mkArray env u t ty =
+ let (t,def) = Parray.to_array t in
+ mkArray(u,t,def,ty)
+
end
module CredNative = RedNative(CNativeEntries)
@@ -767,7 +766,7 @@ let rec whd_state_gen flags env sigma =
let body = EConstr.of_constr body in
whrec (body, stack)
end
- | exception NotEvaluableConst (IsPrimitive p) when Stack.check_native_args p stack ->
+ | exception NotEvaluableConst (IsPrimitive (u,p)) when Stack.check_native_args p stack ->
let kargs = CPrimitives.kind p in
let (kargs,o) = Stack.get_next_primitive_args kargs stack in
(* Should not fail thanks to [check_native_args] *)
@@ -841,9 +840,9 @@ let rec whd_state_gen flags env sigma =
|_ -> fold ()
else fold ()
- | Int _ | Float _ ->
+ | Int _ | Float _ | Array _ ->
begin match Stack.strip_app stack with
- | (_, Stack.Primitive(p,kn,rargs,kargs)::s) ->
+ | (_, Stack.Primitive(p,(_, u as kn),rargs,kargs)::s) ->
let more_to_reduce = List.exists (fun k -> CPrimitives.Kwhnf = k) kargs in
if more_to_reduce then
let (kargs,o) = Stack.get_next_primitive_args kargs s in
@@ -858,10 +857,11 @@ let rec whd_state_gen flags env sigma =
with List.IndexOutOfRange -> (args,[]) (* FIXME probably useless *)
in
let args = Array.of_list (Option.get (Stack.list_of_app_stack (rargs @ Stack.append_app [|x|] args))) in
- begin match CredNative.red_prim env sigma p args with
- | Some t -> whrec (t,s)
- | None -> ((mkApp (mkConstU kn, args), s))
- end
+ let s = extra_args @ s in
+ begin match CredNative.red_prim env sigma p u args with
+ | Some t -> whrec (t,s)
+ | None -> ((mkApp (mkConstU kn, args), s))
+ end
| _ -> fold ()
end
@@ -942,7 +942,7 @@ let local_whd_state_gen flags _env sigma =
else s
| Rel _ | Var _ | Sort _ | Prod _ | LetIn _ | Const _ | Ind _ | Proj _
- | Int _ | Float _ -> s
+ | Int _ | Float _ | Array _ -> s
in
whrec
@@ -1085,12 +1085,25 @@ let pb_equal = function
| Reduction.CUMUL -> Reduction.CONV
| Reduction.CONV -> Reduction.CONV
+(* NOTE: We absorb anomalies happening in the conversion tactic, which
+ is a bit ugly. This is mostly due to efficiency both in tactics and
+ in the conversion machinery itself. It is not uncommon for a tactic
+ to send some ill-typed term to the engine.
+
+ We would usually say that a tactic that converts ill-typed terms is
+ buggy, but fixing the tactic could have a very large runtime cost
+ *)
+exception AnomalyInConversion of exn
+
+let _ = CErrors.register_handler (function
+ | AnomalyInConversion e ->
+ Some Pp.(str "Conversion test raised an anomaly:" ++
+ spc () ++ CErrors.print e)
+ | _ -> None)
+
let report_anomaly (e, info) =
let e =
- if is_anomaly e then
- let msg = Pp.(str "Conversion test raised an anomaly:" ++
- spc () ++ CErrors.print e) in
- UserError (None, msg)
+ if is_anomaly e then AnomalyInConversion e
else e
in
Exninfo.iraise (e, info)
diff --git a/pretyping/reductionops.mli b/pretyping/reductionops.mli
index 58fff49faa..0f288cdd46 100644
--- a/pretyping/reductionops.mli
+++ b/pretyping/reductionops.mli
@@ -23,6 +23,7 @@ val debug_RAKAM : unit -> bool
module CredNative : Primred.RedNative with
type elem = EConstr.t and type args = EConstr.t array and type evd = Evd.evar_map
+ and type uinstance = EInstance.t
(** Machinery to customize the behavior of the reduction *)
module ReductionBehaviour : sig
@@ -111,15 +112,11 @@ type reduction_function = env -> evar_map -> constr -> constr
type e_reduction_function = env -> evar_map -> constr -> evar_map * constr
-type contextual_stack_reduction_function =
+type stack_reduction_function =
env -> evar_map -> constr -> constr * constr list
-type stack_reduction_function = contextual_stack_reduction_function
-type local_stack_reduction_function =
- evar_map -> constr -> constr * constr list
type state_reduction_function =
env -> evar_map -> state -> state
-type local_state_reduction_function = evar_map -> state -> state
val pr_state : env -> evar_map -> state -> Pp.t
@@ -129,11 +126,6 @@ val strong_with_flags :
(CClosure.RedFlags.reds -> reduction_function) ->
(CClosure.RedFlags.reds -> reduction_function)
val strong : reduction_function -> reduction_function
-(*i
-val stack_reduction_of_reduction :
- 'a reduction_function -> 'a state_reduction_function
-i*)
-val stacklam : (state -> 'a) -> constr list -> evar_map -> constr -> constr Stack.t -> 'a
val whd_state_gen :
CClosure.RedFlags.reds -> Environ.env -> Evd.evar_map -> state -> state
@@ -166,13 +158,13 @@ val whd_allnolet : reduction_function
val whd_betalet : reduction_function
(** Removes cast and put into applicative form *)
-val whd_nored_stack : contextual_stack_reduction_function
-val whd_beta_stack : contextual_stack_reduction_function
-val whd_betaiota_stack : contextual_stack_reduction_function
-val whd_betaiotazeta_stack : contextual_stack_reduction_function
-val whd_all_stack : contextual_stack_reduction_function
-val whd_allnolet_stack : contextual_stack_reduction_function
-val whd_betalet_stack : contextual_stack_reduction_function
+val whd_nored_stack : stack_reduction_function
+val whd_beta_stack : stack_reduction_function
+val whd_betaiota_stack : stack_reduction_function
+val whd_betaiotazeta_stack : stack_reduction_function
+val whd_all_stack : stack_reduction_function
+val whd_allnolet_stack : stack_reduction_function
+val whd_betalet_stack : stack_reduction_function
val whd_nored_state : state_reduction_function
val whd_beta_state : state_reduction_function
@@ -241,7 +233,6 @@ val is_arity : env -> evar_map -> constr -> bool
val is_sort : env -> evar_map -> types -> bool
val contract_fix : evar_map -> fixpoint -> constr
-val fix_recarg : ('a, 'a) pfixpoint -> 'b Stack.t -> (int * 'b) option
(** {6 Querying the kernel conversion oracle: opaque/transparent constants } *)
val is_transparent : Environ.env -> Constant.t tableKey -> bool
@@ -292,3 +283,5 @@ val whd_betaiota_deltazeta_for_iota_state :
(** {6 Meta-related reduction functions } *)
val meta_instance : env -> evar_map -> constr freelisted -> constr
val nf_meta : env -> evar_map -> constr -> constr
+
+exception AnomalyInConversion of exn
diff --git a/pretyping/retyping.ml b/pretyping/retyping.ml
index bb518bc2f9..4bd22e76cb 100644
--- a/pretyping/retyping.ml
+++ b/pretyping/retyping.ml
@@ -157,6 +157,9 @@ let retype ?(polyprop=true) sigma =
| Sort _ | Prod _ -> mkSort (sort_of env cstr)
| Int _ -> EConstr.of_constr (Typeops.type_of_int env)
| Float _ -> EConstr.of_constr (Typeops.type_of_float env)
+ | Array(u, _, _, ty) ->
+ let arr = EConstr.of_constr @@ Typeops.type_of_array env (EInstance.kind sigma u) in
+ mkApp(arr, [|ty|])
and sort_of env t =
match EConstr.kind sigma t with
@@ -257,6 +260,9 @@ let get_type_of ?(polyprop=true) ?(lax=false) env sigma c =
(* Makes an unsafe judgment from a constr *)
let get_judgment_of env evc c = { uj_val = c; uj_type = get_type_of env evc c }
+let get_type_of_constr ?polyprop ?lax env ?(uctx=UState.from_env env) c =
+ EConstr.Unsafe.to_constr (get_type_of ?polyprop ?lax env (Evd.from_ctx uctx) (EConstr.of_constr c))
+
(* Returns sorts of a context *)
let sorts_of_context env evc ctxt =
let rec aux = function
@@ -301,8 +307,7 @@ let relevance_of_term env sigma c =
| Fix ((_,i),(lna,_,_)) -> (lna.(i)).binder_relevance
| CoFix (i,(lna,_,_)) -> (lna.(i)).binder_relevance
| Proj (p, _) -> Relevanceops.relevance_of_projection env p
- | Int _ | Float _ -> Sorts.Relevant
-
+ | Int _ | Float _ | Array _ -> Sorts.Relevant
| Meta _ | Evar _ -> Sorts.Relevant
in
diff --git a/pretyping/retyping.mli b/pretyping/retyping.mli
index 16bc251c2a..2e19ffdfcd 100644
--- a/pretyping/retyping.mli
+++ b/pretyping/retyping.mli
@@ -30,6 +30,10 @@ exception RetypeError of retype_error
val get_type_of :
?polyprop:bool -> ?lax:bool -> env -> evar_map -> constr -> types
+(** No-evar version of [get_type_of] *)
+val get_type_of_constr : ?polyprop:bool -> ?lax:bool
+ -> env -> ?uctx:UState.t -> Constr.t -> Constr.types
+
val get_sort_of :
?polyprop:bool -> env -> evar_map -> types -> Sorts.t
diff --git a/pretyping/tacred.ml b/pretyping/tacred.ml
index baa32565f6..e4b5dc1edf 100644
--- a/pretyping/tacred.ml
+++ b/pretyping/tacred.ml
@@ -358,30 +358,6 @@ let reference_eval env sigma = function
let x = Name default_dependent_ident
-let make_elim_fun (names,(nbfix,lv,n)) u largs =
- let lu = List.firstn n largs in
- let p = List.length lv in
- let lyi = List.map fst lv in
- let la =
- List.map_i (fun q aq ->
- (* k from the comment is q+1 *)
- try mkRel (p+1-(List.index Int.equal (n-q) lyi))
- with Not_found -> aq)
- 0 (List.map (Vars.lift p) lu)
- in
- fun i ->
- match names.(i) with
- | None -> None
- | Some (minargs,ref) ->
- let body = applist (mkEvalRef ref u, la) in
- let g =
- List.fold_left_i (fun q (* j = n+1-q *) c (ij,tij) ->
- let subst = List.map (Vars.lift (-q)) (List.firstn (n-ij) la) in
- let tij' = Vars.substl (List.rev subst) tij in
- let x = make_annot x Sorts.Relevant in (* TODO relevance *)
- mkLambda (x,tij',c)) 1 body (List.rev lv)
- in Some (minargs,g)
-
(* [f] is convertible to [Fix(recindices,bodynum),bodyvect)]:
do so that the reduction uses this extra information *)
@@ -467,16 +443,6 @@ let substl_checking_arity env subst sigma c =
type fix_reduction_result = NotReducible | Reduced of (constr * constr list)
-let reduce_fix whdfun sigma fix stack =
- match fix_recarg fix (Stack.append_app_list stack Stack.empty) with
- | None -> NotReducible
- | Some (recargnum,recarg) ->
- let (recarg'hd,_ as recarg') = whdfun sigma recarg in
- let stack' = List.assign stack recargnum (applist recarg') in
- (match EConstr.kind sigma recarg'hd with
- | Construct _ -> Reduced (contract_fix sigma fix, stack')
- | _ -> NotReducible)
-
let contract_fix_use_function env sigma f
((recindices,bodynum),(_names,_types,bodies as typedbodies)) =
let nbodies = Array.length recindices in
@@ -484,22 +450,6 @@ let contract_fix_use_function env sigma f
let lbodies = List.init nbodies make_Fi in
substl_checking_arity env (List.rev lbodies) sigma (nf_beta env sigma bodies.(bodynum))
-let reduce_fix_use_function env sigma f whfun fix stack =
- match fix_recarg fix (Stack.append_app_list stack Stack.empty) with
- | None -> NotReducible
- | Some (recargnum,recarg) ->
- let (recarg'hd,_ as recarg') =
- if EConstr.isRel sigma recarg then
- (* The recarg cannot be a local def, no worry about the right env *)
- (recarg, [])
- else
- whfun recarg in
- let stack' = List.assign stack recargnum (applist recarg') in
- (match EConstr.kind sigma recarg'hd with
- | Construct _ ->
- Reduced (contract_fix_use_function env sigma f fix,stack')
- | _ -> NotReducible)
-
let contract_cofix_use_function env sigma f
(bodynum,(_names,_,bodies as typedbodies)) =
let nbodies = Array.length bodies in
@@ -574,34 +524,23 @@ let match_eval_ref_value env sigma constr stack =
env |> lookup_rel n |> RelDecl.get_value |> Option.map (lift n)
| _ -> None
-let special_red_case env sigma whfun (ci, p, iv, c, lf) =
- let rec redrec s =
- let (constr, cargs) = whfun s in
- match match_eval_ref env sigma constr cargs with
- | Some (ref, u) ->
- (match reference_opt_value env sigma ref u with
- | None -> raise Redelimination
- | Some gvalue ->
- if reducible_mind_case sigma gvalue then
- reduce_mind_case_use_function constr env sigma
- {mP=p; mconstr=gvalue; mcargs=cargs;
- mci=ci; mlf=lf}
- else
- redrec (applist(gvalue, cargs)))
- | None ->
- if reducible_mind_case sigma constr then
- reduce_mind_case sigma
- {mP=p; mconstr=constr; mcargs=cargs;
- mci=ci; mlf=lf}
- else
- raise Redelimination
- in
- redrec c
+let push_app sigma (hd, stk as p) = match EConstr.kind sigma hd with
+| App (hd, args) ->
+ (hd, Array.fold_right (fun x accu -> x :: accu) args stk)
+| _ -> p
let recargs = function
| EvalVar _ | EvalRel _ | EvalEvar _ -> None
| EvalConst c -> ReductionBehaviour.get (GlobRef.ConstRef c)
+let fix_recarg ((recindices,bodynum),_) stack =
+ assert (0 <= bodynum && bodynum < Array.length recindices);
+ let recargnum = Array.get recindices bodynum in
+ try
+ Some (recargnum, List.nth stack recargnum)
+ with Failure _ ->
+ None
+
let reduce_projection env sigma p ~npars (recarg'hd,stack') stack =
(match EConstr.kind sigma recarg'hd with
| Construct _ ->
@@ -609,24 +548,9 @@ let reduce_projection env sigma p ~npars (recarg'hd,stack') stack =
Reduced (List.nth stack' proj_narg, stack)
| _ -> NotReducible)
-let reduce_proj env sigma whfun whfun' c =
- let rec redrec s =
- match EConstr.kind sigma s with
- | Proj (proj, c) ->
- let c' = try redrec c with Redelimination -> c in
- let constr, cargs = whfun c' in
- (match EConstr.kind sigma constr with
- | Construct _ ->
- let proj_narg = Projection.npars proj + Projection.arg proj in
- List.nth cargs proj_narg
- | _ -> raise Redelimination)
- | Case (n,p,iv,c,brs) ->
- let c' = redrec c in
- let p = (n,p,iv,c',brs) in
- (try special_red_case env sigma whfun' p
- with Redelimination -> mkCase p)
- | _ -> raise Redelimination
- in redrec c
+let rec beta_applist sigma accu c stk = match EConstr.kind sigma c, stk with
+| Lambda (_, _, c), arg :: stk -> beta_applist sigma (arg :: accu) c stk
+| _ -> substl accu c, stk
let whd_nothing_for_iota env sigma s =
let rec whrec (x, stack as s) =
@@ -650,17 +574,17 @@ let whd_nothing_for_iota env sigma s =
(match constant_opt_value_in env (const, u) with
| Some body -> whrec (EConstr.of_constr body, stack)
| None -> s)
- | LetIn (_,b,_,c) -> stacklam whrec [b] sigma c stack
+ | LetIn (_,b,_,c) -> whrec (beta_applist sigma [b] c stack)
| Cast (c,_,_) -> whrec (c, stack)
- | App (f,cl) -> whrec (f, Stack.append_app cl stack)
+ | App (f,cl) -> whrec (f, Array.fold_right (fun c accu -> c :: accu) cl stack)
| Lambda (na,t,c) ->
- (match Stack.decomp stack with
- | Some (a,m) -> stacklam whrec [a] sigma c m
+ (match stack with
+ | a :: stack -> whrec (beta_applist sigma [a] c stack)
| _ -> s)
| x -> s
in
- EConstr.decompose_app sigma (Stack.zip sigma (whrec (s,Stack.empty)))
+ whrec s
(* [red_elim_const] contracts iota/fix/cofix redexes hidden behind
constants by keeping the name of the constants in the recursive calls;
@@ -703,21 +627,17 @@ let rec red_elim_const env sigma ref u largs =
try match reference_eval env sigma ref with
| EliminationCases n when nargs >= n ->
let c = reference_value env sigma ref u in
- let c', lrest = whd_nothing_for_iota env sigma (applist(c,largs)) in
- let whfun = whd_simpl_stack env sigma in
- (special_red_case env sigma whfun (EConstr.destCase sigma c'), lrest), nocase
+ let c', lrest = whd_nothing_for_iota env sigma (c, largs) in
+ (special_red_case env sigma (EConstr.destCase sigma c'), lrest), nocase
| EliminationProj n when nargs >= n ->
let c = reference_value env sigma ref u in
- let c', lrest = whd_nothing_for_iota env sigma (applist(c,largs)) in
- let whfun = whd_construct_stack env sigma in
- let whfun' = whd_simpl_stack env sigma in
- (reduce_proj env sigma whfun whfun' c', lrest), nocase
+ let c', lrest = whd_nothing_for_iota env sigma (c, largs) in
+ (reduce_proj env sigma c', lrest), nocase
| EliminationFix (min,minfxargs,infos) when nargs >= min ->
let c = reference_value env sigma ref u in
- let d, lrest = whd_nothing_for_iota env sigma (applist(c,largs)) in
- let f = make_elim_fun ([|Some (minfxargs,ref)|],infos) u largs in
- let whfun = whd_construct_stack env sigma in
- (match reduce_fix_use_function env sigma f whfun (destFix sigma d) lrest with
+ let d, lrest = whd_nothing_for_iota env sigma (c, largs) in
+ let f = ([|Some (minfxargs,ref)|],infos), u, largs in
+ (match reduce_fix_use_function env sigma f (destFix sigma d) lrest with
| NotReducible -> raise Redelimination
| Reduced (c,rest) -> (nf_beta env sigma c, rest), nocase)
| EliminationMutualFix (min,refgoal,refinfos) when nargs >= min ->
@@ -729,10 +649,9 @@ let rec red_elim_const env sigma ref u largs =
let c', lrest = whd_betalet_stack env sigma (applist(c,args)) in
descend (destEvalRefU sigma c') lrest in
let (_, midargs as s) = descend (ref,u) largs in
- let d, lrest = whd_nothing_for_iota env sigma (applist s) in
- let f = make_elim_fun refinfos u midargs in
- let whfun = whd_construct_stack env sigma in
- (match reduce_fix_use_function env sigma f whfun (destFix sigma d) lrest with
+ let d, lrest = whd_nothing_for_iota env sigma s in
+ let f = refinfos, u, midargs in
+ (match reduce_fix_use_function env sigma f (destFix sigma d) lrest with
| NotReducible -> raise Redelimination
| Reduced (c,rest) -> (nf_beta env sigma c, rest), nocase)
| NotAnElimination when unfold_nonelim ->
@@ -755,32 +674,30 @@ and reduce_params env sigma stack l =
| _ -> raise Redelimination)
stack l
-
(* reduce to whd normal form or to an applied constant that does not hide
a reducible iota/fix/cofix redex (the "simpl" tactic) *)
and whd_simpl_stack env sigma =
let open ReductionBehaviour in
let rec redrec s =
- let (x, stack) = decompose_app_vect sigma s in
- let stack = Array.to_list stack in
- let s' = (x, stack) in
+ let s' = push_app sigma s in
+ let (x, stack) = s' in
match EConstr.kind sigma x with
| Lambda (na,t,c) ->
(match stack with
| [] -> s'
- | a :: rest -> redrec (beta_applist sigma (x, stack)))
- | LetIn (n,b,t,c) -> redrec (applist (Vars.substl [b] c, stack))
- | App (f,cl) -> redrec (applist(f, (Array.to_list cl)@stack))
- | Cast (c,_,_) -> redrec (applist(c, stack))
+ | a :: rest -> redrec (beta_applist sigma [a] c rest))
+ | LetIn (n,b,t,c) -> redrec (Vars.substl [b] c, stack)
+ | App (f,cl) -> assert false (* see push_app above *)
+ | Cast (c,_,_) -> redrec (c, stack)
| Case (ci,p,iv,c,lf) ->
(try
- redrec (applist(special_red_case env sigma redrec (ci,p,iv,c,lf), stack))
+ redrec (special_red_case env sigma (ci,p,iv,c,lf), stack)
with
Redelimination -> s')
| Fix fix ->
- (try match reduce_fix (whd_construct_stack env) sigma fix stack with
- | Reduced s' -> redrec (applist s')
+ (try match reduce_fix env sigma fix stack with
+ | Reduced s' -> redrec s'
| NotReducible -> s'
with Redelimination -> s')
@@ -800,11 +717,11 @@ and whd_simpl_stack env sigma =
(match reduce_projection env sigma p ~npars
(whd_construct_stack env sigma c) stack
with
- | Reduced s' -> redrec (applist s')
+ | Reduced s' -> redrec s'
| NotReducible -> s')
| _ ->
match reduce_projection env sigma p ~npars (whd_construct_stack env sigma c) stack with
- | Reduced s' -> redrec (applist s')
+ | Reduced s' -> redrec s'
| NotReducible -> s')
else s'
with Redelimination -> s')
@@ -814,7 +731,7 @@ and whd_simpl_stack env sigma =
| Some (ref, u) ->
(try
let sapp, nocase = red_elim_const env sigma ref u stack in
- let hd, _ as s'' = redrec (applist(sapp)) in
+ let hd, _ as s'' = redrec sapp in
let rec is_case x = match EConstr.kind sigma x with
| Lambda (_,_, x) | LetIn (_,_,_, x) | Cast (x, _,_) -> is_case x
| App (hd, _) -> is_case hd
@@ -827,10 +744,102 @@ and whd_simpl_stack env sigma =
in
redrec
+and reduce_fix env sigma fix stack =
+ match fix_recarg fix stack with
+ | None -> NotReducible
+ | Some (recargnum,recarg) ->
+ let (recarg'hd,_ as recarg') = whd_construct_stack env sigma recarg in
+ let stack' = List.assign stack recargnum (applist recarg') in
+ (match EConstr.kind sigma recarg'hd with
+ | Construct _ -> Reduced (contract_fix sigma fix, stack')
+ | _ -> NotReducible)
+
+and reduce_fix_use_function env sigma f fix stack =
+ match fix_recarg fix stack with
+ | None -> NotReducible
+ | Some (recargnum,recarg) ->
+ let (recarg'hd,_ as recarg') =
+ if EConstr.isRel sigma recarg then
+ (* The recarg cannot be a local def, no worry about the right env *)
+ (recarg, [])
+ else
+ whd_construct_stack env sigma recarg in
+ let stack' = List.assign stack recargnum (applist recarg') in
+ (match EConstr.kind sigma recarg'hd with
+ | Construct _ ->
+ let (names, (nbfix, lv, n)), u, largs = f in
+ let lu = List.firstn n largs in
+ let p = List.length lv in
+ let lyi = List.map fst lv in
+ let la =
+ List.map_i (fun q aq ->
+ (* k from the comment is q+1 *)
+ try mkRel (p+1-(List.index Int.equal (n-q) lyi))
+ with Not_found -> Vars.lift p aq)
+ 0 lu
+ in
+ let f i = match names.(i) with
+ | None -> None
+ | Some (minargs,ref) ->
+ let body = applist (mkEvalRef ref u, la) in
+ let g =
+ List.fold_left_i (fun q (* j = n+1-q *) c (ij,tij) ->
+ let subst = List.map (Vars.lift (-q)) (List.firstn (n-ij) la) in
+ let tij' = Vars.substl (List.rev subst) tij in
+ let x = make_annot x Sorts.Relevant in (* TODO relevance *)
+ mkLambda (x,tij',c)) 1 body (List.rev lv)
+ in Some (minargs,g)
+ in
+ Reduced (contract_fix_use_function env sigma f fix,stack')
+ | _ -> NotReducible)
+
+and reduce_proj env sigma c =
+ let rec redrec s =
+ match EConstr.kind sigma s with
+ | Proj (proj, c) ->
+ let c' = try redrec c with Redelimination -> c in
+ let constr, cargs = whd_construct_stack env sigma c' in
+ (match EConstr.kind sigma constr with
+ | Construct _ ->
+ let proj_narg = Projection.npars proj + Projection.arg proj in
+ List.nth cargs proj_narg
+ | _ -> raise Redelimination)
+ | Case (n,p,iv,c,brs) ->
+ let c' = redrec c in
+ let p = (n,p,iv,c',brs) in
+ (try special_red_case env sigma p
+ with Redelimination -> mkCase p)
+ | _ -> raise Redelimination
+ in redrec c
+
+and special_red_case env sigma (ci, p, iv, c, lf) =
+ let rec redrec s =
+ let (constr, cargs) = whd_simpl_stack env sigma s in
+ match match_eval_ref env sigma constr cargs with
+ | Some (ref, u) ->
+ (match reference_opt_value env sigma ref u with
+ | None -> raise Redelimination
+ | Some gvalue ->
+ if reducible_mind_case sigma gvalue then
+ reduce_mind_case_use_function constr env sigma
+ {mP=p; mconstr=gvalue; mcargs=cargs;
+ mci=ci; mlf=lf}
+ else
+ redrec (gvalue, cargs))
+ | None ->
+ if reducible_mind_case sigma constr then
+ reduce_mind_case sigma
+ {mP=p; mconstr=constr; mcargs=cargs;
+ mci=ci; mlf=lf}
+ else
+ raise Redelimination
+ in
+ redrec (push_app sigma (c, []))
+
(* reduce until finding an applied constructor or fail *)
and whd_construct_stack env sigma s =
- let (constr, cargs as s') = whd_simpl_stack env sigma s in
+ let (constr, cargs as s') = whd_simpl_stack env sigma (s, []) in
if reducible_mind_case sigma constr then s'
else match match_eval_ref env sigma constr cargs with
| Some (ref, u) ->
@@ -855,13 +864,13 @@ let try_red_product env sigma c =
| App (f,l) ->
(match EConstr.kind sigma f with
| Fix fix ->
- let stack = Stack.append_app l Stack.empty in
- (match fix_recarg fix stack with
+ (match fix_recarg fix (Array.to_list l) with
| None -> raise Redelimination
| Some (recargnum,recarg) ->
let recarg' = redrec env recarg in
- let stack' = Stack.assign stack recargnum recarg' in
- simpfun (Stack.zip sigma (f,stack')))
+ let l = Array.copy l in
+ let () = Array.set l recargnum recarg' in
+ simpfun (mkApp (f, l)))
| _ -> simpfun (mkApp (redrec env f, l)))
| Cast (c,_,_) -> redrec env c
| Prod (x,a,b) ->
@@ -973,19 +982,19 @@ let whd_simpl_orelse_delta_but_fix env sigma c =
if List.length stack <= npars then
(* Do not show the eta-expanded form *)
s'
- else redrec (applist (c, stack))
- | _ -> redrec (applist(c, stack)))
+ else redrec (c, stack)
+ | _ -> redrec (c, stack))
| None -> s'
in
let simpfun = clos_norm_flags betaiota env sigma in
simpfun (applist (redrec c))
-let hnf_constr = whd_simpl_orelse_delta_but_fix
+let hnf_constr env sigma c = whd_simpl_orelse_delta_but_fix env sigma (c, [])
(* The "simpl" reduction tactic *)
let whd_simpl env sigma c =
- applist (whd_simpl_stack env sigma c)
+ applist (whd_simpl_stack env sigma (c, []))
let simpl env sigma c = strong whd_simpl env sigma c
@@ -1267,11 +1276,10 @@ let one_step_reduce env sigma c =
| Cast (c,_,_) -> redrec (c,stack)
| Case (ci,p,iv,c,lf) ->
(try
- (special_red_case env sigma (whd_simpl_stack env sigma)
- (ci,p,iv,c,lf), stack)
+ (special_red_case env sigma (ci,p,iv,c,lf), stack)
with Redelimination -> raise NotStepReducible)
| Fix fix ->
- (try match reduce_fix (whd_construct_stack env) sigma fix stack with
+ (try match reduce_fix env sigma fix stack with
| Reduced s' -> s'
| NotReducible -> raise NotStepReducible
with Redelimination -> raise NotStepReducible)
diff --git a/pretyping/typing.ml b/pretyping/typing.ml
index b4a1153731..756ccd3438 100644
--- a/pretyping/typing.ml
+++ b/pretyping/typing.ml
@@ -332,6 +332,23 @@ let judge_of_int env v =
let judge_of_float env v =
Environ.on_judgment EConstr.of_constr (judge_of_float env v)
+let judge_of_array env sigma u tj defj tyj =
+ let ulev = match Univ.Instance.to_array u with
+ | [|u|] -> u
+ | _ -> assert false
+ in
+ let sigma = Evd.set_leq_sort env sigma tyj.utj_type
+ (Sorts.sort_of_univ (Univ.Universe.make ulev))
+ in
+ let check_one sigma j = Evarconv.unify_leq_delay env sigma j.uj_type tyj.utj_val in
+ let sigma = check_one sigma defj in
+ let sigma = Array.fold_left check_one sigma tj in
+ let arr = EConstr.of_constr @@ type_of_array env u in
+ let j = make_judge (mkArray(EInstance.make u, Array.map j_val tj, defj.uj_val, tyj.utj_val))
+ (mkApp (arr, [|tyj.utj_val|]))
+ in
+ sigma, j
+
(* cstr must be in n.f. w.r.t. evars and execute returns a judgement
where both the term and type are in n.f. *)
let rec execute env sigma cstr =
@@ -455,6 +472,13 @@ let rec execute env sigma cstr =
| Float f ->
sigma, judge_of_float env f
+ | Array(u,t,def,ty) ->
+ let sigma, tyj = execute env sigma ty in
+ let sigma, tyj = type_judgment env sigma tyj in
+ let sigma, defj = execute env sigma def in
+ let sigma, tj = execute_array env sigma t in
+ judge_of_array env sigma (EInstance.kind sigma u) tj defj tyj
+
and execute_recdef env sigma (names,lar,vdef) =
let sigma, larj = execute_array env sigma lar in
let sigma, lara = Array.fold_left_map (assumption_of_judgment env) sigma larj in
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index ef58f41489..a26c981cb9 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -564,7 +564,7 @@ let is_rigid_head sigma flags t =
match EConstr.kind sigma t with
| Const (cst,u) -> not (TransparentState.is_transparent_constant flags.modulo_delta cst)
| Ind (i,u) -> true
- | Construct _ | Int _ | Float _ -> true
+ | Construct _ | Int _ | Float _ | Array _ -> true
| Fix _ | CoFix _ -> true
| Rel _ | Var _ | Meta _ | Evar _ | Sort _ | Cast (_, _, _) | Prod _
| Lambda _ | LetIn _ | App (_, _) | Case (_, _, _, _, _)
@@ -659,7 +659,7 @@ let rec is_neutral env sigma ts t =
| Evar _ | Meta _ -> true
| Case (_, p, _, c, _) -> is_neutral env sigma ts c
| Proj (p, c) -> is_neutral env sigma ts c
- | Lambda _ | LetIn _ | Construct _ | CoFix _ | Int _ | Float _ -> false
+ | Lambda _ | LetIn _ | Construct _ | CoFix _ | Int _ | Float _ | Array _ -> false
| Sort _ | Cast (_, _, _) | Prod (_, _, _) | Ind _ -> false (* Really? *)
| Fix _ -> false (* This is an approximation *)
| App _ -> assert false
@@ -1819,6 +1819,15 @@ let w_unify_to_subterm env evd ?(flags=default_unify_flags ()) (op,cl) =
with ex when precatchable_exception ex ->
matchrec c)
+ | Array(_u,t,def,ty) ->
+ (try
+ matchrec def
+ with ex when precatchable_exception ex ->
+ try
+ matchrec ty
+ with ex when precatchable_exception ex ->
+ iter_fail matchrec t)
+
| Cast (_, _, _) (* Is this expected? *)
| Rel _ | Var _ | Meta _ | Evar _ | Sort _ | Const _ | Ind _
| Construct _ | Int _ | Float _ -> user_err Pp.(str "Match_subterm")))
@@ -1887,6 +1896,9 @@ let w_unify_to_subterm_all env evd ?(flags=default_unify_flags ()) (op,cl) =
| Lambda (_,t,c) ->
bind (matchrec t) (matchrec c)
+ | Array(_u,t,def,ty) ->
+ bind (bind (bind_iter matchrec t) (matchrec def)) (matchrec ty)
+
| Cast (_, _, _) -> fail "Match_subterm" (* Is this expected? *)
| Rel _ | Var _ | Meta _ | Evar _ | Sort _ | Const _ | Ind _
diff --git a/pretyping/vnorm.ml b/pretyping/vnorm.ml
index efe1efd74e..e5fa9bada1 100644
--- a/pretyping/vnorm.ml
+++ b/pretyping/vnorm.ml
@@ -170,6 +170,7 @@ and nf_whd env sigma whd typ =
mkApp(capp,args)
| Vint64 i -> i |> Uint63.of_int64 |> mkInt
| Vfloat64 f -> f |> Float64.of_float |> mkFloat
+ | Varray t -> nf_array env sigma t typ
| Vatom_stk(Aid idkey, stk) ->
constr_type_of_idkey env sigma idkey stk
| Vatom_stk(Aind ((mi,i) as ind), stk) ->
@@ -261,12 +262,6 @@ and nf_stk ?from:(from=0) env sigma c t stk =
nf_stk env sigma (mkApp(fa,[|c|])) (subst1 c codom) stk
| Zswitch sw :: stk ->
assert (from = 0) ;
- let ci = sw.sw_annot.Vmvalues.ci in
- let () = if Typeops.should_invert_case env ci then
- (* TODO implement case inversion readback (properly reducing
- it is a problem for the kernel) *)
- CErrors.user_err Pp.(str "VM compute readback of case inversion not implemented.")
- in
let ((mind,_ as ind), u), allargs = find_rectype_a env t in
let (mib,mip) = Inductive.lookup_mind_specif env ind in
let nparams = mib.mind_nparams in
@@ -274,7 +269,7 @@ and nf_stk ?from:(from=0) env sigma c t stk =
let nparamdecls = Context.Rel.length (Inductive.inductive_paramdecls (mib,u)) in
let pT =
hnf_prod_applist_assum env nparamdecls (type_of_ind env (ind,u)) (Array.to_list params) in
- let p = nf_predicate env sigma (ind,u) mip params (type_of_switch sw) pT in
+ let p, relevance = nf_predicate env sigma (ind,u) mip params (type_of_switch sw) pT in
(* Calcul du type des branches *)
let btypes = build_branches_type env sigma ind mib mip u params p in
(* calcul des branches *)
@@ -286,7 +281,12 @@ and nf_stk ?from:(from=0) env sigma c t stk =
in
let branchs = Array.mapi mkbranch bsw in
let tcase = build_case_type p realargs c in
- nf_stk env sigma (mkCase(ci, p, NoInvert, c, branchs)) tcase stk
+ let ci = Inductiveops.make_case_info env ind relevance RegularStyle in
+ let iv = if Typeops.should_invert_case env ci then
+ CaseInvert {univs=u; args=allargs}
+ else NoInvert
+ in
+ nf_stk env sigma (mkCase(ci, p, iv, c, branchs)) tcase stk
| Zproj p :: stk ->
assert (from = 0) ;
let p' = Projection.make p true in
@@ -296,17 +296,17 @@ and nf_stk ?from:(from=0) env sigma c t stk =
and nf_predicate env sigma ind mip params v pT =
match kind (whd_allnolet env pT) with
| LetIn (name,b,t,pT) ->
- let body =
+ let body, rel =
nf_predicate (push_rel (LocalDef (name,b,t)) env) sigma ind mip params v pT in
- mkLetIn (name,b,t,body)
+ mkLetIn (name,b,t,body), rel
| Prod (name,dom,codom) -> begin
match whd_val v with
| Vfun f ->
let k = nb_rel env in
let vb = reduce_fun k f in
- let body =
+ let body, rel =
nf_predicate (push_rel (LocalAssum (name,dom)) env) sigma ind mip params vb codom in
- mkLambda(name,dom,body)
+ mkLambda(name,dom,body), rel
| _ -> assert false
end
| _ ->
@@ -321,8 +321,10 @@ and nf_predicate env sigma ind mip params v pT =
let dom = mkApp(mkIndU ind,Array.append params rargs) in
let r = Inductive.relevance_of_inductive env (fst ind) in
let name = make_annot name r in
- let body = nf_vtype (push_rel (LocalAssum (name,dom)) env) sigma vb in
- mkLambda(name,dom,body)
+ let env = push_rel (LocalAssum (name,dom)) env in
+ let body = nf_vtype env sigma vb in
+ let rel = Retyping.relevance_of_type env sigma (EConstr.of_constr body) in
+ mkLambda(name,dom,body), rel
| _ -> assert false
and nf_args env sigma vargs ?from:(f=0) t =
@@ -399,6 +401,14 @@ and nf_cofix env sigma cf =
let cfb = Util.Array.map2 (fun v t -> nf_val env sigma v t) vb cft in
mkCoFix (init,(names,cft,cfb))
+and nf_array env sigma t typ =
+ let ty, allargs = decompose_appvect (whd_all env typ) in
+ let typ_elem = allargs.(0) in
+ let t, vdef = Parray.to_array t in
+ let t = Array.map (fun v -> nf_val env sigma v typ_elem) t in
+ let u = snd (destConst ty) in
+ mkArray(u, t, nf_val env sigma vdef typ_elem, typ_elem)
+
let cbv_vm env sigma c t =
if Termops.occur_meta sigma c then
CErrors.user_err Pp.(str "vm_compute does not support metas.");