Skip to content

Commit ebf039f

Browse files
committed
New API to get instance priority
1 parent cbdb206 commit ebf039f

File tree

4 files changed

+52
-30
lines changed

4 files changed

+52
-30
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- Change `tc-instance`, now the type is `gref -> tc-priority -> tc-instance` i.e. the priority is not an integer anymore
1313
- New `coq.ltac.fresh-id` to generate fresh names in the proof context
1414
- New `@no-tc!` attribute supported by `coq.ltac.call-ltac1`
15+
- New `coq.TC.get-inst-prio` returns the `tc-priority` of an instance
1516

1617
### Apps
1718
- New `tc` app providing an implementation of a type class solver written in elpi.

apps/tc/elpi/tc_aux.elpi

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
% cannot be compiled
66

77
% returns the TC from the type of an instance
8+
% TODO: This gould be replaced with an api
9+
% coq.TC.get-class-of-inst i:gref, o:gref
810
pred get-TC-of-inst-type i:term, o:gref.
911
get-TC-of-inst-type (prod _ _ A) GR:-
1012
pi x\ get-TC-of-inst-type (A x) GR.
@@ -93,23 +95,20 @@ make-tc _IsHead Ty Inst Hyp Clause :-
9395
(Hyp = [Hd]) (Clause = (Q :- Hd))
9496
(Clause = (Q :- Hyp)).
9597

98+
pred unwrap-prio i:tc-priority, o:int.
99+
unwrap-prio (tc-priority-given Prio) Prio.
100+
unwrap-prio (tc-priority-computed Prio) Prio.
101+
96102
% returns the priority of an instance from the gref of an instance
97103
pred get-inst-prio i:gref, o:int.
98-
get-inst-prio InstGr Prio :-
99-
coq.env.typeof InstGr InstTy,
100-
get-TC-of-inst-type InstTy TC,
101-
find-opt {coq.TC.db-for TC}
102-
(x\ tc-instance InstGr (tc-priority-given Prio) = x ;
103-
tc-instance InstGr (tc-priority-computed Prio) = x)
104-
(some _), !.
105-
get-inst-prio _ 0.
106-
107-
% TODO: @FissoreD improve this method complexity
104+
get-inst-prio InstGR Prio :-
105+
coq.env.typeof InstGR InstTy,
106+
get-TC-of-inst-type InstTy ClassGR,
107+
unwrap-prio {coq.TC.get-inst-prio ClassGR InstGR} Prio.
108+
108109
pred get-full-path i:gref, o:string.
109-
% :if "get-full-path"
110110
get-full-path Gr Res' :-
111111
coq.gref->string Gr Path,
112112
coq.env.current-section-path SectionPath,
113113
std.fold SectionPath "" (e\acc\r\ r is acc ^ "." ^ e) Res,
114114
Res' is Res ^ Path.
115-
% get-full-path _ _.

coq-builtin.elpi

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,10 @@ external pred coq.TC.db-tc o:list gref.
11541154
% Instances are in their precedence order.
11551155
external pred coq.TC.db-for i:gref, o:list tc-instance.
11561156

1157+
% [coq.TC.get-inst-prio ClassGR InstGR InstPrio] reads the priority of an
1158+
% instance
1159+
external pred coq.TC.get-inst-prio i:gref, i:gref, o:tc-priority.
1160+
11571161
% [coq.TC.class? GR] checks if GR is a class
11581162
external pred coq.TC.class? i:gref.
11591163

src/coq_elpi_builtins.ml

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,31 @@ let get_instance_prio gr env sigma (hint_priority : int option) : tc_priority =
511511
let hyps = nb_hyp sigma' cty in
512512
Computed (hyps + nmiss)
513513

514-
let get_instances (env: Environ.env) (emap: Evd.evar_map) tc : type_class_instance list =
514+
(* TODO: this algorithm is quite inefficient since we have not yet the
515+
possibility to get the implementation of an instance from its gref in
516+
coq. Currently we have to get all the instances of the tc and the find
517+
its implementation.
518+
NOTE: if we have coq's API to retrieve this implementation from the GlobRef of
519+
the instance the parameter tc will be useless
520+
*)
521+
let get_instance (env: Environ.env) (sigma: Evd.evar_map) (tc : GlobRef.t) (instance : GlobRef.t) : type_class_instance =
522+
let inst_of_tc = (* contains all the instances of a type class *)
523+
Typeclasses.instances_exn env sigma tc |>
524+
List.fold_left (fun m i -> GlobRef.Map.add i.Typeclasses.is_impl i m) GlobRef.Map.empty in
525+
let instances_grefs2istance inst_gr : type_class_instance =
526+
let open Typeclasses in
527+
let user_hint_prio =
528+
(* Note: in general we deal with an instance I of a type class. Here we
529+
look if the user has given a priority to I. However, external
530+
hints are not in the inst_of_tc (the Not_found exception) *)
531+
try (GlobRef.Map.find inst_gr inst_of_tc).is_info.hint_priority
532+
with Not_found -> None in
533+
let priority = get_instance_prio inst_gr env sigma user_hint_prio in
534+
{ implementation = inst_gr; priority }
535+
in
536+
instances_grefs2istance instance
537+
538+
let get_instances (env: Environ.env) (sigma: Evd.evar_map) tc : type_class_instance list =
515539
let hint_db = Hints.searchtable_map "typeclass_instances" in
516540
let secvars : Names.Id.Pred.t = Names.Id.Pred.full in
517541
let full_hints = Hints.Hint_db.map_all ~secvars:secvars tc hint_db in
@@ -523,8 +547,6 @@ let get_instances (env: Environ.env) (emap: Evd.evar_map) tc : type_class_instan
523547
| Give_exact a -> Some a
524548
| Res_pf_THEN_trivial_fail e -> Some e
525549
| Unfold_nth e -> None) hint_asts in
526-
let sigma, _ =
527-
let env = Global.env () in Evd.(from_env env, env) in
528550
let constrs = List.map (fun a -> Hints.hint_as_term a |> snd) hints in
529551
(* Printer.pr_global tc |> Pp.string_of_ppcmds |> Printf.printf "%s\n"; *)
530552
let instances_grefs = List.filter_map (fun e ->
@@ -533,21 +555,7 @@ let get_instances (env: Environ.env) (emap: Evd.evar_map) tc : type_class_instan
533555
| Constr.Const (a, _) -> Some (Names.GlobRef.ConstRef a)
534556
| Constr.Construct (a, _) -> Some (Names.GlobRef.ConstructRef a)
535557
| _ -> None) constrs in
536-
let inst_of_tc = (* contains all the instances of a type class *)
537-
Typeclasses.instances_exn env emap tc |>
538-
List.fold_left (fun m i -> GlobRef.Map.add i.Typeclasses.is_impl i m) GlobRef.Map.empty in
539-
let instances_grefs2istance inst_gr : type_class_instance =
540-
let open Typeclasses in
541-
let user_hint_prio =
542-
(* Note: in general we deal with an instance I of a type class. Here we look if
543-
the user has given a priority to I. However, external hints are
544-
not in the inst_of_tc (the Not_found exception)*)
545-
try (GlobRef.Map.find inst_gr inst_of_tc).is_info.hint_priority
546-
with Not_found -> None in
547-
let priority = get_instance_prio inst_gr env sigma user_hint_prio in
548-
{ implementation = inst_gr; priority }
549-
in
550-
List.map instances_grefs2istance instances_grefs
558+
List.map (get_instance env sigma tc) instances_grefs
551559

552560
type scope = ExecutionSite | CurrentModule | Library
553561

@@ -2836,6 +2844,16 @@ Supported attributes:
28362844
(fun gr _ ~depth { env } _ state -> !: (get_instances env (get_sigma state) gr))),
28372845
DocAbove);
28382846

2847+
MLCode(Pred("coq.TC.get-inst-prio",
2848+
In(gref, "ClassGR",
2849+
In(gref, "InstGR",
2850+
Out(tc_priority, "InstPrio",
2851+
Read (global, "reads the priority of an instance")))),
2852+
(fun class_gr inst_gr _ ~depth { env } _ state ->
2853+
let {priority} = get_instance env (get_sigma state) class_gr inst_gr in
2854+
!: priority)),
2855+
DocAbove);
2856+
28392857
MLCode(Pred("coq.TC.class?",
28402858
In(gref, "GR",
28412859
Easy "checks if GR is a class"),

0 commit comments

Comments
 (0)