Skip to content

Commit 25e00fa

Browse files
committed
accumulate: abstract univ instances correctly
1 parent df6157a commit 25e00fa

File tree

5 files changed

+56
-19
lines changed

5 files changed

+56
-19
lines changed

src/rocq_elpi_HOAS.ml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,12 +693,15 @@ let in_elpiast_gr ~loc r =
693693
assert_in_elpi_gref_consistent ~poly:false r;
694694
A.mkAppGlobal ~loc globalc (in_elpiast_gref ~loc r) []
695695

696+
let in_elpi_pglobal t i =
697+
E.mkApp pglobalc t [i]
698+
696699
let in_elpi_poly_gr ~depth s r i =
697700
assert_in_elpi_gref_consistent ~poly:true r;
698701
let open API.Conversion in
699702
let s, t, gl = gref.embed ~depth s r in
700703
assert (gl = []);
701-
E.mkApp pglobalc t [i]
704+
in_elpi_pglobal t i
702705

703706
let in_elpiast_poly_gr ~loc r i =
704707
assert_in_elpi_gref_consistent ~poly:true r;

src/rocq_elpi_HOAS.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ val in_elpi_appl : depth:int -> term -> term list -> term
167167
val in_elpi_match : term -> term -> term list -> term
168168
val in_elpi_fix : Name.t -> int -> term -> term -> term
169169
val in_elpi_name : Name.t -> term
170+
val in_elpi_pglobal : term -> term -> term
170171

171172
val set_coq : Elpi.API.Ast.Scope.language -> unit
172173

src/rocq_elpi_builtins.ml

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,13 @@ let err_if_contains_alg_univ ~depth t =
540540
| Some l -> is_global_level env l in
541541
let rec aux ~depth (acc,acci) t =
542542
match E.look ~depth t with
543-
| E.CData c when isuinstance c -> (acc,acci+1)
543+
| E.App _ as x ->
544+
begin match is_global_or_pglobal ~depth t with
545+
| PGlobal(Some _, Some _) ->(acc,(1+acci))
546+
| _ -> Rocq_elpi_utils.fold_elpi_term aux (acc,acci) ~depth x
547+
end
548+
| E.CData c when isuinstance c ->
549+
err Pp.(strbrk "The hypothetical clause contains terms of universe instance")
544550
| E.CData c when isuniv c ->
545551
let u = univout c in
546552
if is_global u then acc, acci
@@ -556,48 +562,75 @@ let err_if_contains_alg_univ ~depth t =
556562
let univs = aux ~depth (Univ.Universe.Set.empty,0) t in
557563
univs
558564

565+
let coq_env_globalc = E.Constants.declare_global_symbol "coq.env.global"
566+
559567
let preprocess_clause ~depth clause =
568+
let origdepth = depth in
560569
let levels_to_abstract, instances_to_abstract = err_if_contains_alg_univ ~depth clause in
561-
let levels_to_abstract_no = Univ.Universe.Set.cardinal levels_to_abstract in
562-
let rec subst ~depth m mi t =
570+
let db2gr = ref Int.Map.empty in
571+
let rec subst ~depth m t =
563572
match E.look ~depth t with
564573
| E.CData c when isuniv c ->
565574
begin try E.mkBound (Univ.Universe.Map.find (univout c) m)
566575
with Not_found -> t end
567-
| E.CData c when isuinstance c ->
568-
decr mi; E.mkBound !mi
569576
| E.App(c,x,xs) ->
570-
E.mkApp c (subst ~depth m mi x) (List.map (subst ~depth m mi) xs)
577+
begin match is_global_or_pglobal ~depth t with
578+
| PGlobal(Some gr, Some _) ->
579+
let mi = Int.Map.cardinal !db2gr in
580+
db2gr := Int.Map.add mi gr !db2gr; in_elpi_pglobal gr (E.mkBound mi)
581+
| _ ->
582+
E.mkApp c (subst ~depth m x) (List.map (subst ~depth m) xs)
583+
end
571584
| E.Cons(x,xs) ->
572-
E.mkCons (subst ~depth m mi x) (subst ~depth m mi xs)
585+
E.mkCons (subst ~depth m x) (subst ~depth m xs)
573586
| E.Lam x ->
574-
E.mkLam (subst ~depth:(depth+1) m mi x)
587+
E.mkLam (subst ~depth:(depth+1) m x)
575588
| E.Builtin(c,xs) ->
576-
E.mkBuiltin c (List.map (subst ~depth m mi) xs)
589+
E.mkBuiltin c (List.map (subst ~depth m) xs)
577590
| E.UnifVar _ -> CErrors.user_err Pp.(str"The clause begin accumulated contains unification variables, this is forbidden. You must quantify them out using 'pi'.")
578591
| E.Const _ | E.Nil | E.CData _ -> t
579592
in
593+
let map2hyp map rest =
594+
let hyps =
595+
Int.Map.bindings map |> List.map @@ fun (i,gr) ->
596+
E.mkApp coq_env_globalc gr [in_elpi_pglobal gr (E.mkBound (origdepth+i))] in
597+
E.mkAppGlobalL E.Constants.andc (hyps@rest) in
598+
let rec add_premises depth t map =
599+
match E.look ~depth t with
600+
| E.App(c,hd,[pre]) when c == E.Constants.rimplc ->
601+
E.mkApp E.Constants.rimplc hd [map2hyp map [pre]]
602+
| E.App(c,lam,[]) when c == E.Constants.pic ->
603+
begin match E.look ~depth lam with
604+
| Lam t -> add_premises (depth+1) t map
605+
| _ -> assert false
606+
end
607+
| _ -> E.mkApp E.Constants.rimplc t [map2hyp map []] in
580608
let clause =
581-
let rec bind d (map : int Univ.Universe.Map.t) (mapi : int ref) = function
609+
let rec bind d (map : int Univ.Universe.Map.t) = function
582610
| [] ->
583-
subst ~depth:d map mapi
584-
(API.Utils.move ~from:depth ~to_:(depth + levels_to_abstract_no + !mapi) clause)
611+
let clause = API.Utils.move ~from:depth ~to_:d clause in
612+
let clause = subst ~depth:d map clause in
613+
if Int.Map.is_empty !db2gr then clause
614+
else add_premises d clause !db2gr
585615
| l :: ls ->
586616
E.mkApp E.Constants.pic (E.mkLam (* pi x\ *)
587-
(bind (d+1) (Univ.Universe.Map.add l d map) mapi ls)) []
588-
and bindi d (map : int Univ.Universe.Map.t) (mapi : int ref) ua n =
617+
(bind (d+1) (Univ.Universe.Map.add l d map) ls)) []
618+
and bindi d (map : int Univ.Universe.Map.t) ua n =
589619
if n = 0 then
590-
bind d map mapi ua
620+
bind d map ua
591621
else
592622
E.mkApp E.Constants.pic (E.mkLam (* pi x\ *)
593-
(bindi (d+1) map mapi ua (n-1))) []
623+
(bindi (d+1) map ua (n-1))) []
594624
in
595-
bindi depth Univ.Universe.Map.empty (ref (depth+instances_to_abstract))
625+
bindi depth Univ.Universe.Map.empty
596626
(Univ.Universe.Set.elements levels_to_abstract) instances_to_abstract
597627
in
598628
let vars = collect_term_variables ~depth clause in
629+
(* Format.eprintf "CLAUSE=%a\n%!" (Elpi.API.RawPp.term depth) clause; *)
599630
vars, clause
600631

632+
633+
601634
let argument_mode = let open Conv in let open API.AlgebraicData in declare {
602635
ty = TyName "argument_mode";
603636
doc = "Specify if a predicate argument is in input or output mode";

tests/test_HOAS.v

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ Elpi Query lp:{{
9090
u U, ut {{ ut@{foo} }} U
9191
}}.
9292

93-
stop
9493

9594
Axiom B : bool -> Type.
9695
Axiom N : nat -> Type.

tests/test_polymorphism.v

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,4 @@ Elpi Query lp:"
6565
".
6666
Print polydef.
6767
Print test_cumul_def.
68+
End test_cumul_def.

0 commit comments

Comments
 (0)