aboutsummaryrefslogtreecommitdiff
path: root/pretyping
diff options
context:
space:
mode:
authorHugo Herbelin2020-10-29 16:49:25 +0100
committerHugo Herbelin2020-10-31 20:29:48 +0100
commitf8f915df4a8e3c619a4ccb204ea16afacf983430 (patch)
tree927f5b2f370dda64c6be5f4c651fdbebd57b200f /pretyping
parent710f74901e0fd65ca677555366cae3d00686c9c8 (diff)
Closes #13278: take into account elimination constraints in small inversion.
Ideally, if equations t <= ?x were preserving subtyping that could be simpler. Currently we need however to put a rigid universe as constraint on the return predicate so that one branch does not force the return sort to be lower by unification than what another branch would have needed.
Diffstat (limited to 'pretyping')
-rw-r--r--pretyping/cases.ml17
1 files changed, 15 insertions, 2 deletions
diff --git a/pretyping/cases.ml b/pretyping/cases.ml
index 587fc32ecb..312bf4907f 100644
--- a/pretyping/cases.ml
+++ b/pretyping/cases.ml
@@ -2080,6 +2080,15 @@ let prepare_predicate_from_arsign_tycon ~program_mode env sigma loc tomatchs ars
Some (sigma', p, arsign)
with e when precatchable_exception e -> None
+let expected_elimination_sort env tomatchl =
+ List.fold_right (fun (_,tm) s ->
+ match tm with
+ | IsInd (_,IndType(indf,_),_) ->
+ (* Not a degenerated line, see coerce_to_indtype *)
+ let s' = Inductive.elim_sort (Inductive.lookup_mind_specif env (fst (fst (dest_ind_family indf)))) in
+ if Sorts.family_leq s s' then s else s'
+ | NotInd _ -> s) tomatchl Sorts.InType
+
(* Builds the predicate. If the predicate is dependent, its context is
* made of 1+nrealargs assumptions for each matched term in an inductive
* type and 1 assumption for each term not _syntactically_ in an
@@ -2130,8 +2139,12 @@ let prepare_predicate ?loc ~program_mode typing_fun env sigma tomatchs arsign ty
| Some rtntyp ->
(* We extract the signature of the arity *)
let building_arsign,envar = List.fold_right_map (push_rel_context ~hypnaming:KeepUserNameAndRenameExistingButSectionNames sigma) arsign env in
- let sigma, newt = new_sort_variable univ_flexible sigma in
- let sigma, predcclj = typing_fun (mk_tycon (mkSort newt)) envar sigma rtntyp in
+ (* We put a type constraint on the predicate so that one
+ branch type-checked first does not lead to a lower type than
+ another branch; we take into account the possible elimination
+ constraints on the predicate *)
+ let sigma, rtnsort = fresh_sort_in_family sigma (expected_elimination_sort !!env tomatchs) in
+ let sigma, predcclj = typing_fun (Some (mkSort rtnsort)) envar sigma rtntyp in
let predccl = nf_evar sigma predcclj.uj_val in
[sigma, predccl, building_arsign]
in