Skip to content

Commit b96e757

Browse files
authored
Merge pull request #908 from JasonGross/coq-8.16+quotation-better-universes
Use a more systematic mangling of universe names
2 parents 0532e37 + 8bd85e5 commit b96e757

File tree

2 files changed

+86
-135
lines changed

2 files changed

+86
-135
lines changed

quotation/theories/CommonUtils.v

Lines changed: 77 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -223,71 +223,6 @@ Module WithTemplate.
223223
end.
224224
End with_monad.
225225

226-
#[local] Definition CacheT T : Type := term * list term * UniverseMap.t term -> T * (term * list term * UniverseMap.t term).
227-
#[local] Instance CacheT_Monad : Monad CacheT
228-
:= {| ret A v := fun st => (v, st)
229-
; bind A B v f := fun st => let '(v, st) := v st in f v st |}.
230-
#[local] Definition init_cache_and_run (lProp_t lSProp_t lSet_t : term) (default_univ : term) (available_univs : list term) {T} : CacheT T -> T
231-
:= fun f
232-
=> fst
233-
(f (default_univ,
234-
available_univs,
235-
UniverseMap.add
236-
Universe.lProp lProp_t
237-
(UniverseMap.add
238-
Universe.lSProp lSProp_t
239-
(UniverseMap.add
240-
(Universe.of_levels (inr Level.lzero)) lSet_t
241-
(UniverseMap.empty _))))).
242-
#[local] Definition lookupU (u : Universe.t) : CacheT term
243-
:= fun '((default_univ, fresh_univs, map) as st)
244-
=> match UniverseMap.find u map, fresh_univs with
245-
| Some t, _ => (t, st)
246-
| None, nil => (default_univ, st)
247-
| None, t :: fresh_univs
248-
=> (t, (default_univ, fresh_univs, UniverseMap.add u t map))
249-
end.
250-
251-
#[local]
252-
Definition tmRelaxSortsCached (in_domain : bool) (do_replace_U : Universe.t -> bool) (lProp_t lSProp_t lSet_t : term) (default_univ : term) (available_univs : list term) (t : term) : term
253-
:= init_cache_and_run
254-
lProp_t lSProp_t lSet_t default_univ available_univs
255-
(tmRelaxSortsM
256-
in_domain
257-
(fun u => if do_replace_U u
258-
then lookupU u
259-
else ret (tSort u))
260-
t).
261-
262-
Polymorphic Inductive list_of_types@{u} : Type@{u+1} := nil | cons (x : Type@{u}) (xs : list_of_types).
263-
Declare Scope list_of_types_scope.
264-
Delimit Scope list_of_types_scope with list_of_types.
265-
Bind Scope list_of_types_scope with list_of_types.
266-
267-
Infix "::" := cons : list_of_types_scope.
268-
Notation "[ ]" := nil : list_of_types_scope.
269-
Notation "[ x ]" := (cons x nil) : list_of_types_scope.
270-
Notation "[ x ; y ; .. ; z ]" := (cons x (cons y .. (cons z nil) ..)) : list_of_types_scope.
271-
272-
Polymorphic Definition types_monad_map@{l b a t u} {T} {M : Monad@{t u} T} {B : Type@{b}} (f : Type@{a} -> T B)
273-
:= fix types_monad_map (l : list_of_types@{l}) : T (list B)
274-
:= match l with
275-
| []%list_of_types => ret []%list
276-
| (x :: xs)%list_of_types
277-
=> fx <- f x;;
278-
fxs <- types_monad_map xs;;
279-
ret (fx :: fxs)%list
280-
end.
281-
282-
#[local] Polymorphic Definition tmRelaxSortsQuote@{uP uSP uS uD uL t u _high} (in_domain : bool) (do_replace_U : Universe.t -> bool) (available_univs : list_of_types@{uL}) (t : term) : TemplateMonad@{t u} term
283-
:= lProp_t <- @tmQuote Type@{_high} Type@{uP};;
284-
lSProp_t <- @tmQuote Type@{_high} Type@{uSP};;
285-
lSet_t <- @tmQuote Type@{_high} Type@{uS};;
286-
default_univ <- @tmQuote Type@{_high} Type@{uD};;
287-
available_univs <- types_monad_map@{uL _high _ _ _} tmQuote available_univs;;
288-
ret (tmRelaxSortsCached in_domain do_replace_U lProp_t lSProp_t lSet_t default_univ available_univs t).
289-
290-
291226
#[local] Definition is_set (s : Universe.t) : bool
292227
:= match option_map Level.is_set (Universe.get_is_level s) with
293228
| Some true => true
@@ -306,77 +241,91 @@ Module WithTemplate.
306241
| _ => false
307242
end.
308243

309-
Polymorphic Definition tmRetypeMagicRelaxSetInCodomain@{U a b t u _high} {A : Type@{a}} (B : Type@{b}) (x : A) : TemplateMonad@{t u} B
244+
Definition tmRelaxSet (in_domain : bool) (prefix : string) (t : term) : term
245+
:= tmRelaxSortsM
246+
(M:=fun T => T) in_domain
247+
(fun u => tSort (if is_set u then Universe.of_levels (inr (Level.Level (prefix ++ "._Set.0")%bs)) else u))
248+
t.
249+
250+
Module Import PrefixUniverse.
251+
Module Level.
252+
Definition prefix_with (prefix : string) (l : Level.t) : Level.t
253+
:= match l with
254+
| Level.lzero | Level.Var _ => l
255+
| Level.Level u => Level.Level (prefix ++ "." ++ u)%bs
256+
end.
257+
End Level.
258+
259+
Module LevelExprSet.
260+
Module Raw.
261+
Definition prefix_with (prefix : string) (l : LevelExprSet.Raw.t) : LevelExprSet.Raw.t
262+
:= List.map (fun '(l, n) => (Level.prefix_with prefix l, n)) l.
263+
End Raw.
264+
Lemma prefix_with_Ok {prefix : string} {l : LevelExprSet.Raw.t} (pf : LevelExprSet.Raw.Ok l) : LevelExprSet.Raw.Ok (Raw.prefix_with prefix l).
265+
Proof.
266+
hnf in *; cbv [Raw.prefix_with] in *; cbn in *.
267+
induction l as [|[l n] ls IH]; cbn in *; [ reflexivity | ].
268+
apply Bool.andb_true_iff in pf; destruct pf as [pf1 pf2].
269+
rewrite IH, Bool.andb_true_r by assumption.
270+
clear IH pf2.
271+
destruct ls as [|[l' n'] ls]; cbn in *; [ reflexivity | ].
272+
destruct l, l'; cbn in *; try assumption.
273+
induction prefix as [|?? IH];
274+
cbn in *; try assumption.
275+
rewrite ByteCompareSpec.compare_eq_refl; assumption.
276+
Qed.
277+
Definition prefix_with (prefix : string) (l : LevelExprSet.t) : LevelExprSet.t
278+
:= @LevelExprSet.Mkt (Raw.prefix_with prefix (@LevelExprSet.this l)) (prefix_with_Ok (@LevelExprSet.is_ok l)).
279+
Lemma is_empty_prefix_with {prefix} {l} : LevelExprSet.is_empty (prefix_with prefix l) = LevelExprSet.is_empty l.
280+
Proof.
281+
destruct l as [l pf]; cbn.
282+
cbv [LevelExprSet.is_empty prefix_with LevelExprSet.Raw.is_empty]; cbn.
283+
destruct l; cbn; reflexivity.
284+
Qed.
285+
End LevelExprSet.
286+
287+
Module nonEmptyLevelExprSet.
288+
Definition prefix_with (prefix : string) (l : nonEmptyLevelExprSet) : nonEmptyLevelExprSet
289+
:= {| t_set := LevelExprSet.prefix_with prefix l.(t_set)
290+
; t_ne := eq_trans LevelExprSet.is_empty_prefix_with l.(t_ne) |}.
291+
End nonEmptyLevelExprSet.
292+
293+
Module LevelAlgExpr := nonEmptyLevelExprSet.
294+
295+
Module Universe.
296+
Definition prefix_with (prefix : string) (u : Universe.t) : Universe.t
297+
:= match u with
298+
| Universe.lProp | Universe.lSProp => u
299+
| Universe.lType u => Universe.lType (LevelAlgExpr.prefix_with prefix u)
300+
end.
301+
End Universe.
302+
End PrefixUniverse.
303+
304+
Definition tmRelaxOnlyType (in_domain : bool) (prefix : string) (t : term) : term
305+
:= tmRelaxSortsM
306+
(M:=fun T => T) in_domain
307+
(fun u => tSort (PrefixUniverse.Universe.prefix_with prefix u))
308+
t.
309+
310+
Polymorphic Definition tmRetypeMagicRelaxSetInCodomain@{a b t u} (prefix : string) {A : Type@{a}} (B : Type@{b}) (x : A) : TemplateMonad@{t u} B
310311
:= qx <- tmQuote x;;
311-
qx <- tmRelaxSortsQuote@{U U U U _high t u _high} false is_set [] qx;;
312+
let qx := tmRelaxSet false prefix qx in
312313
tmUnquoteTyped B qx.
313-
Polymorphic Definition tmRetypeRelaxSetInCodomain@{U a t u _high} {A : Type@{a}} (x : A) : TemplateMonad@{t u} A
314-
:= tmRetypeMagicRelaxSetInCodomain@{U a a t u _high} A x.
314+
Polymorphic Definition tmRetypeRelaxSetInCodomain@{a t u} (prefix : string) {A : Type@{a}} (x : A) : TemplateMonad@{t u} A
315+
:= tmRetypeMagicRelaxSetInCodomain@{a a t u} prefix A x.
315316

316-
Local Notation many_Types_2 tail := (Type :: Type :: Type :: Type :: tail)%list_of_types (only parsing).
317-
Local Notation many_Types_3 tail := (many_Types_2 (many_Types_2 tail)) (only parsing).
318-
Local Notation many_Types_4 tail := (many_Types_3 (many_Types_3 tail)) (only parsing).
319-
Local Notation many_Types_5 tail := (many_Types_4 (many_Types_4 tail)) (only parsing).
320-
Local Notation many_Types := (many_Types_5 nil) (only parsing).
321-
322-
Polymorphic Definition tmRetypeMagicRelaxOnlyType0@{U a b t u _high} {A : Type@{a}} (B : Type@{b}) (x : A) : TemplateMonad@{t u} B
317+
Polymorphic Definition tmRetypeMagicRelaxOnlyType@{a b t u} (prefix : string) {A : Type@{a}} (B : Type@{b}) (x : A) : TemplateMonad@{t u} B
323318
:= qx <- tmQuote x;;
324-
qx <- tmRelaxSortsQuote@{U U U U _high t u _high} true is_only_type [] qx;;
319+
let qx := tmRelaxOnlyType true prefix qx in
325320
tmUnquoteTyped B qx.
326-
Polymorphic Definition tmRetypeRelaxOnlyType0@{U a t u _high} {A : Type@{a}} (x : A) : TemplateMonad@{t u} A
327-
:= tmRetypeMagicRelaxOnlyType0@{U a a t u _high} A x.
328-
329-
Polymorphic Definition tmRetypeMagicRelaxOnlyType {A : Type} (B : Type) (x : A) : TemplateMonad B
330-
:= qx <- tmQuote x;;
331-
qx <- tmRelaxSortsQuote true is_only_type many_Types qx;;
332-
tmUnquoteTyped B qx.
333-
Polymorphic Definition tmRetypeRelaxOnlyType {A} (x : A) : TemplateMonad A
334-
:= tmRetypeMagicRelaxOnlyType A x.
321+
Polymorphic Definition tmRetypeRelaxOnlyType@{a t u} (prefix : string) {A : Type@{a}} (x : A) : TemplateMonad@{t u} A
322+
:= tmRetypeMagicRelaxOnlyType@{a a t u} prefix A x.
335323

336324
(* Hack around https://github.com/MetaCoq/metacoq/issues/853 *)
337-
Polymorphic Definition tmRetypeAroundMetaCoqBug853_0 (t : typed_term) : TemplateMonad typed_term
338-
:= let '{| my_projT1 := ty ; my_projT2 := v |} := t in
339-
ty <- tmRetypeRelaxOnlyType0 ty;;
340-
v <- tmRetypeMagicRelaxOnlyType0 ty v;;
341-
ret {| my_projT1 := ty ; my_projT2 := v |}.
342-
343-
Polymorphic Definition tmRetypeAroundMetaCoqBug853_gen (t : typed_term) : TemplateMonad typed_term
325+
Definition tmRetypeAroundMetaCoqBug853 (prefix : string) (t : typed_term) : TemplateMonad typed_term
344326
:= let '{| my_projT1 := ty ; my_projT2 := v |} := t in
345-
ty <- tmRetypeRelaxOnlyType ty;;
346-
v <- tmRetypeMagicRelaxOnlyType ty v;;
327+
ty <- tmRetypeRelaxOnlyType prefix ty;;
328+
v <- tmRetypeMagicRelaxOnlyType prefix ty v;;
347329
ret {| my_projT1 := ty ; my_projT2 := v |}.
348-
349-
(* Hack around https://github.com/MetaCoq/metacoq/pull/876#issuecomment-1487743822 *)
350-
Monomorphic Variant exn : Set := GenericError.
351-
352-
Polymorphic Variant option_try@{u} (A : Type@{u}) : Type@{max(Set, u)} := my_Value (val : A) | my_Error (err : exn).
353-
354-
Arguments my_Value {A} val.
355-
Arguments my_Error {A} _.
356-
Polymorphic Class tmCheckSuccessHelper@{t u} {A : Type@{t}} (run : TemplateMonad@{t u} A) := tmCheckSuccess_ret : unit.
357-
#[global] Hint Extern 0 (tmCheckSuccessHelper ?run) => run_template_program run (fun v => exact tt) : typeclass_instances.
358-
Polymorphic Definition tmCheckSuccess@{t u} {A : Type@{t}} (run : TemplateMonad@{t u} A) : TemplateMonad@{t u} bool
359-
:= tmBind (tmInferInstance None (tmCheckSuccessHelper run))
360-
(fun inst => match inst with
361-
| my_Some _ => tmReturn true
362-
| my_None => tmReturn false
363-
end).
364-
Polymorphic Definition tmTryWorseButNoAnomaly@{t u} {A : Type@{t}} (run : TemplateMonad@{t u} A) : TemplateMonad@{t u} (option_try@{t} A)
365-
:= succeeds <- tmCheckSuccess run;;
366-
if succeeds:bool
367-
then v <- run;; ret (my_Value v)
368-
else ret (my_Error GenericError).
369-
370-
Definition tmRetypeAroundMetaCoqBug853 (t : typed_term) : TemplateMonad typed_term
371-
:= Eval cbv [List.fold_right] in
372-
List.fold_right
373-
(fun tmRetype acc
374-
=> res <- tmTryWorseButNoAnomaly (tmRetype t);;
375-
match res with
376-
| my_Value v => ret v
377-
| my_Error _ => acc
378-
end)
379-
(tmRetypeAroundMetaCoqBug853_gen t)
380-
[tmRetypeAroundMetaCoqBug853_0; tmRetypeAroundMetaCoqBug853_gen].
381330
End WithTemplate.
382331
Export WithTemplate (transparentify, tmQuoteToGlobalReference, tmRetypeRelaxSetInCodomain, tmRetypeRelaxOnlyType, tmRetypeMagicRelaxSetInCodomain, tmRetypeMagicRelaxOnlyType, tmObj_magic, tmRetype, tmExtractBaseModPathFromMod, tmRetypeAroundMetaCoqBug853).

quotation/theories/ToTemplate/Init.v

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,9 @@ Ltac unfold_quotation_of _ :=
424424
| change (@quotation_of A (transparentify t)) ]
425425
end.
426426

427-
Polymorphic Definition tmPrepareMakeQuotationOfConstants@{U t u u' _T _above_u _above_u'} {debug:debug_opt} (work_aronud_coq_bug_17303 : bool) (include_submodule : list ident -> bool) (include_supermodule : list ident -> list ident -> bool) (base : modpath) (cs : list global_reference) : TemplateMonad@{t u} (list (string * typed_term@{u'}))
427+
(* for universe adjustment with [tmDeclareQuotationOfModule], [tmMakeQuotationOfModule] *)
428+
#[export] Unset MetaCoq Strict Unquote Universe Mode.
429+
Polymorphic Definition tmPrepareMakeQuotationOfConstants@{U t u u' _T _above_u _above_u'} {debug:debug_opt} (work_around_coq_bug_17303 : bool) (include_submodule : list ident -> bool) (include_supermodule : list ident -> list ident -> bool) (base : modpath) (cs : list global_reference) : TemplateMonad@{t u} (list (string * typed_term@{u'}))
428430
:= let warn_bad_ctx c ctx :=
429431
(_ <- tmMsg "tmPrepareMakeQuotationOfModule: cannot handle polymorphism";;
430432
_ <- tmPrint c;;
@@ -442,7 +444,7 @@ Polymorphic Definition tmPrepareMakeQuotationOfConstants@{U t u u' _T _above_u _
442444
_ <- tmDebugPrint r;;
443445
tmReturn []) in
444446
let make_qname '(mp, name)
445-
(* ideally we'd replace _ with __ so that there can't be any collision, but the utility functions aren't written and we don't need it in practice *)
447+
(* ideally we'd replace _ with __ so that there can't be any collision, but the utility functions aren't written and we don't need it in practice *)
446448
:= option_map
447449
(fun n => "q" ++ n)%bs
448450
match split_common_prefix base mp with
@@ -488,7 +490,7 @@ Polymorphic Definition tmPrepareMakeQuotationOfConstants@{U t u u' _T _above_u _
488490
_ <- tmDebugMsg "tmPrepareMakeQuotationOfConstants: tmUnquote";;
489491
'{| my_projT1 := cty ; my_projT2 := cv |} <- tmUnquote c;;
490492
_ <- tmDebugMsg "tmPrepareMakeQuotationOfConstants: tmUnquote done";;
491-
tmReturn [(qname, if work_aronud_coq_bug_17303
493+
tmReturn [(qname, if work_around_coq_bug_17303
492494
then {| my_projT1 := term ; my_projT2 := c |}
493495
else {| my_projT1 := @quotation_of cty cv ; my_projT2 := c |})]
494496
end
@@ -507,7 +509,7 @@ Polymorphic Definition tmPrepareMakeQuotationOfConstants@{U t u u' _T _above_u _
507509
_ <- tmDebugMsg "tmPrepareMakeQuotationOfConstants: tmUnquote";;
508510
'{| my_projT1 := cty ; my_projT2 := cv |} <- tmUnquote c;;
509511
_ <- tmDebugMsg "tmPrepareMakeQuotationOfConstants: tmUnquote done";;
510-
let tmcty := tmRetypeRelaxSetInCodomain@{U t t u _above_u} cty in
512+
let tmcty := tmRetypeRelaxSetInCodomain@{t t u} qname cty in
511513
_ <- tmDebugPrint tmcty;;
512514
cty <- tmcty;;
513515
let tmcv := tmObj_magic (B:=cty) cv in
@@ -524,19 +526,19 @@ Polymorphic Definition tmPrepareMakeQuotationOfConstants@{U t u u' _T _above_u _
524526
ret ps.
525527

526528
(* N.B. We need to kludge around COQBUG(https://github.com/coq/coq/issues/17303) in Kernames :-( *)
527-
Polymorphic Definition tmMakeQuotationOfConstants_gen@{U d t u u' _T _above_u _above_u' _above_gr} {debug:debug_opt} (work_aronud_coq_bug_17303 : bool) (include_submodule : list ident -> bool) (include_supermodule : list ident -> list ident -> bool) (existing_instance : option hint_locality) (base : modpath) (cs : list global_reference) (tmDoWithDefinition : ident -> forall A : Type@{d}, A -> TemplateMonad A) : TemplateMonad unit
529+
Polymorphic Definition tmMakeQuotationOfConstants_gen@{U d t u u' _T _above_u _above_u' _above_gr} {debug:debug_opt} (work_around_coq_bug_17303 : bool) (include_submodule : list ident -> bool) (include_supermodule : list ident -> list ident -> bool) (existing_instance : option hint_locality) (base : modpath) (cs : list global_reference) (tmDoWithDefinition : ident -> forall A : Type@{d}, A -> TemplateMonad A) : TemplateMonad unit
528530
:= let tmDebugMsg s := (if debug
529531
then tmMsg s
530532
else tmReturn tt) in
531533
let tmDebugPrint {T : Type@{_T}} (v : T)
532534
:= (if debug
533535
then tmPrint v
534536
else tmReturn tt) in
535-
ps <- tmPrepareMakeQuotationOfConstants@{U t u u' _T _above_u _above_u'} work_aronud_coq_bug_17303 include_submodule include_supermodule base cs;;
537+
ps <- tmPrepareMakeQuotationOfConstants@{U t u u' _T _above_u _above_u'} work_around_coq_bug_17303 include_submodule include_supermodule base cs;;
536538
_ <- tmDebugMsg "tmMakeQuotationOfConstants_gen: defining module constants";;
537539
ps <- monad_map@{_ _ _above_gr _above_u'}
538540
(fun '(name, tyv)
539-
=> let tmTyv := tmRetypeAroundMetaCoqBug853 tyv in
541+
=> let tmTyv := tmRetypeAroundMetaCoqBug853 name tyv in
540542
_ <- tmDebugPrint tmTyv;;
541543
'{| my_projT1 := ty ; my_projT2 := v |} <- tmTyv;;
542544
tmDef_name <- tmEval cbv (@tmDoWithDefinition (name:string));;

0 commit comments

Comments
 (0)