@@ -397,96 +397,56 @@ let cs_instance = let open Conv in let open API.AlgebraicData in let open Struct
397
397
} |> CConv. (! < )
398
398
399
399
400
- type tc_priority = Computed of int | UserGiven of int
401
-
402
- let tc_priority = let open Conv in let open API.AlgebraicData in declare {
403
- ty = TyName " tc-priority" ;
404
- doc = " Type class instance priority" ;
405
- pp = (fun fmt _ -> Format. fprintf fmt " <todo>" );
406
- constructors = [
407
- K (" tc-priority-given" ," User given priority" ,A (int ,N ),
408
- B (fun i -> UserGiven i),
409
- M (fun ~ok ~ko -> function UserGiven i -> ok i | _ -> ko () ));
410
- K (" tc-priority-computed" ," Coq computed priority" , A (int ,N ),
411
- B (fun i -> Computed i),
412
- M (fun ~ok ~ko -> function Computed i -> ok i | _ -> ko () ));
413
- ]} |> CConv. (! < )
414
-
415
400
type type_class_instance = {
416
401
implementation : GlobRef .t ;
417
- priority : tc_priority ;
402
+ priority : int ;
418
403
}
419
404
420
405
let tc_instance = let open Conv in let open API.AlgebraicData in declare {
421
406
ty = TyName " tc-instance" ;
422
407
doc = " Type class instance with priority" ;
423
408
pp = (fun fmt _ -> Format. fprintf fmt " <todo>" );
424
409
constructors = [
425
- K (" tc-instance" ," " ,A (gref,A (tc_priority ,N )),
410
+ K (" tc-instance" ," " ,A (gref,A (int ,N )),
426
411
B (fun implementation priority -> { implementation; priority }),
427
412
M (fun ~ok ~ko { implementation; priority } -> ok implementation priority));
428
413
]} |> CConv. (! < )
429
414
430
- [%% if coq = " 8.20" ]
431
- let clenv_missing sigma ce cty =
432
- let rec nb_hyp sigma c = match EConstr. kind sigma c with
433
- | Prod (_ ,_ ,c2 ) -> if EConstr.Vars. noccurn sigma 1 c2 then 1 + (nb_hyp sigma c2) else nb_hyp sigma c2
434
- | _ -> 0 in
435
- let miss = Clenv. clenv_missing ce in
436
- let nmiss = List. length miss in
437
- let hyps = nb_hyp sigma cty in
438
- nmiss, hyps
439
- [%% else ]
440
- let clenv_missing _ ce _ =
441
- let miss, hyps = Clenv. clenv_missing ce in
442
- List. length miss, hyps
443
- [%% endif]
444
-
445
- let get_instance_prio gr env sigma (hint_priority : int option ) : tc_priority =
446
- match hint_priority with
447
- | Some p -> UserGiven p
448
- | None ->
449
- let merge_context_set_opt sigma ctx =
450
- match ctx with
451
- | None -> sigma
452
- | Some ctx -> Evd. merge_sort_context_set Evd. univ_flexible sigma ctx
453
- in
454
- let fresh_global_or_constr env sigma =
455
- let (c, ctx) = UnivGen. fresh_global_instance env gr in
456
- let ctx = if Environ. is_polymorphic env gr then Some ctx else None in
457
- (EConstr. of_constr c, ctx) in
458
- let c, ctx = fresh_global_or_constr env sigma in
459
- let cty = Retyping. get_type_of env sigma c in
460
- let cty = Reductionops. nf_betaiota env sigma cty in
461
- let sigma' = merge_context_set_opt sigma ctx in
462
- let ce = Clenv. mk_clenv_from env sigma' (c,cty) in
463
- let nmiss, nhyps = clenv_missing sigma' ce cty in
464
- Computed (nhyps + nmiss)
465
-
466
- (* TODO: this algorithm is quite inefficient since we have not yet the
467
- possibility to get the implementation of an instance from its gref in
468
- coq. Currently we have to get all the instances of the tc and the find
469
- its implementation.
470
- *)
471
- let get_isntances_of_tc env sigma (tc : GlobRef.t ) =
472
- let inst_of_tc = (* contains all the instances of a type class *)
473
- Typeclasses. instances_exn env sigma tc |>
474
- List. fold_left (fun m i -> GlobRef.Map. add i.Typeclasses. is_impl i m) GlobRef.Map. empty in
475
- inst_of_tc
476
-
477
- let get_instance env sigma inst_of_tc instance : type_class_instance =
478
- let instances_grefs2istance inst_gr : type_class_instance =
479
- let open Typeclasses in
480
- let user_hint_prio =
481
- (* Note: in general we deal with an instance I of a type class. Here we
482
- look if the user has given a priority to I. However, external
483
- hints are not in the inst_of_tc (the Not_found exception) *)
484
- try (GlobRef.Map. find inst_gr inst_of_tc).is_info.hint_priority
485
- with Not_found -> None in
486
- let priority = get_instance_prio inst_gr env sigma user_hint_prio in
487
- { implementation = inst_gr; priority }
488
- in
489
- instances_grefs2istance instance
415
+ let get_instance_prio env class_gr inst_gr =
416
+ let exception STOP in
417
+ (* db contains the hints stored in the typeclassses_db *)
418
+ let db = Hints. searchtable_map Class_tactics. typeclasses_db in
419
+ (* full_hint is the **list** of hints for a typeclass *)
420
+ let full_hint = ref None in
421
+ (try
422
+ (* since we have not a "find" API in Hints.Hint_db to get the value associated to a class gref
423
+ we iterate over the list until finding the wanted result *)
424
+ (* complexity: O(N) where N is the number of typeclasses *)
425
+ Hints.Hint_db. iter (fun gro _ fh ->
426
+ Option. iter (fun gr ->
427
+ if Environ.QGlobRef. equal env gr class_gr then
428
+ (full_hint := Some fh; raise STOP )) gro) db;
429
+ with STOP -> () );
430
+ match ! full_hint with
431
+ (* None means that we cannot find the class gref in the db *)
432
+ | None -> err Pp. (str" Cannot find the gref" ++ GlobRef. print class_gr ++ str" in typeclass_instances: is it a valid typeclass?" )
433
+ | Some full_hint ->
434
+ let same_inst e =
435
+ match Hints.FullHint. name e with
436
+ | Some hint_name when Environ.QGlobRef. equal env hint_name inst_gr -> Some (Hints.FullHint. priority e)
437
+ | _ -> None
438
+ in
439
+ (* We look in the list of hint for the one associated to inst_gr, if it does not exists: error *)
440
+ (* complexity: O(N) where N is the number of instances of class_gr *)
441
+ match List. find_map same_inst full_hint with
442
+ | None -> err Pp. (str" Cannot find the priority of " ++ GlobRef. print inst_gr ++
443
+ str" : either it is not an instance of " ++ GlobRef. print class_gr ++
444
+ str" or it is not stored as a hint in typeclasses_instances" )
445
+ | Some e -> e
446
+
447
+ let get_instance env class_gr inst_gr : type_class_instance =
448
+ let priority = get_instance_prio env class_gr inst_gr in
449
+ { implementation = inst_gr; priority }
490
450
491
451
let warning_tc_hints = CWarnings. create ~name: " elpi.TC.hints" ~category: elpi_cat Pp. str
492
452
@@ -515,8 +475,7 @@ let get_instances (env: Environ.env) (sigma: Evd.evar_map) tc : type_class_insta
515
475
| Constr. Const (a , _ ) -> Some (Names.GlobRef. ConstRef a)
516
476
| Constr. Construct (a , _ ) -> Some (Names.GlobRef. ConstructRef a)
517
477
| _ -> None ) constrs in
518
- let isnt_of_tc = get_isntances_of_tc env sigma tc in
519
- List. map (get_instance env sigma isnt_of_tc) instances_grefs
478
+ List. map (get_instance env tc) instances_grefs
520
479
521
480
let set_accumulate_to_db_interp, get_accumulate_to_db_interp =
522
481
let f = ref (fun _ -> assert false ) in
@@ -2771,7 +2730,6 @@ Supported attributes:
2771
2730
!: topo_sort )),
2772
2731
DocAbove);
2773
2732
2774
- MLData tc_priority ;
2775
2733
MLData tc_instance ;
2776
2734
2777
2735
MLCode(Pred("coq.TC.declare-instance" ,
@@ -2817,13 +2775,10 @@ Supported attributes:
2817
2775
MLCode(Pred("coq.TC.get-inst-prio" ,
2818
2776
In(gref , "ClassGR" ,
2819
2777
In(gref , "InstGR" ,
2820
- Out(tc_priority , "InstPrio" ,
2778
+ Out(int , "InstPrio" ,
2821
2779
Read (global , "reads the priority of an instance" )))),
2822
2780
(fun class_gr inst_gr _ ~depth { env } _ state ->
2823
- let sigma = get_sigma state in
2824
- let inst_of_tc = get_isntances_of_tc env sigma class_gr in
2825
- let {priority} = get_instance env sigma inst_of_tc inst_gr in
2826
- !: priority )),
2781
+ !: (get_instance_prio env class_gr inst_gr ))),
2827
2782
DocAbove);
2828
2783
2829
2784
MLCode(Pred("coq.TC.class?" ,
0 commit comments