aboutsummaryrefslogtreecommitdiff
path: root/pretyping
diff options
context:
space:
mode:
Diffstat (limited to 'pretyping')
-rw-r--r--pretyping/typeclasses.ml57
1 files changed, 40 insertions, 17 deletions
diff --git a/pretyping/typeclasses.ml b/pretyping/typeclasses.ml
index 519aee85d7..1b3c2baea7 100644
--- a/pretyping/typeclasses.ml
+++ b/pretyping/typeclasses.ml
@@ -1,3 +1,4 @@
+(* -*- compile-command: "make -C .. bin/coqtop.byte" -*- *)
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
@@ -106,11 +107,17 @@ let gmap_merge old ne =
let cmap_union = Cmap.fold Cmap.add
let gmap_cmap_merge old ne =
- Gmap.fold (fun cl insts acc ->
- let oldinsts = try Gmap.find cl old with Not_found -> Cmap.empty in
- Gmap.add cl (cmap_union oldinsts insts) acc)
- Gmap.empty ne
-
+ let ne' =
+ Gmap.fold (fun cl insts acc ->
+ let oldinsts = try Gmap.find cl old with Not_found -> Cmap.empty in
+ Gmap.add cl (cmap_union oldinsts insts) acc)
+ Gmap.empty ne
+ in
+ Gmap.fold (fun cl insts acc ->
+ if Gmap.mem cl ne' then acc
+ else Gmap.add cl insts acc)
+ ne' old
+
let add_instance_hint_ref = ref (fun id pri -> assert false)
let register_add_instance_hint =
(:=) add_instance_hint_ref
@@ -172,20 +179,36 @@ let discharge (_,(cl,m,inst)) =
let discharge_named (cl, r) =
Option.smartmap (fun (gr, b) -> Lib.discharge_global gr, b) cl, r
in
- let subst_class cl =
- { cl with cl_impl = Lib.discharge_global cl.cl_impl;
- cl_context = list_smartmap discharge_named cl.cl_context;
- cl_projs = list_smartmap (fun (x, y) -> x, Lib.discharge_con y) cl.cl_projs }
+ let abs_context cl =
+ match cl.cl_impl with
+ | VarRef _ | ConstructRef _ -> assert false
+ | ConstRef cst -> Lib.section_segment_of_constant cst
+ | IndRef (ind,_) -> Lib.section_segment_of_mutual_inductive ind
in
- let classes = Gmap.map subst_class cl in
- let subst_inst insts =
- Cmap.fold (fun k is acc ->
- let impl = Lib.discharge_con is.is_impl in
- let is = { is with is_class = Lib.discharge_global is.is_class; is_impl = impl } in
- Cmap.add impl is acc)
- insts Cmap.empty;
+ let subst_class k cl acc =
+ let cl_impl' = Lib.discharge_global cl.cl_impl in
+ let cl' =
+ if cl_impl' == cl.cl_impl then cl
+ else
+ { cl with cl_impl = cl_impl';
+ cl_context =
+ List.map (fun x -> None, x) (abs_context cl) @
+ (list_smartmap discharge_named cl.cl_context);
+ cl_projs = list_smartmap (fun (x, y) -> x, Lib.discharge_con y) cl.cl_projs }
+ in Gmap.add cl_impl' cl' acc
in
- let instances = Gmap.map subst_inst inst in
+ let classes = Gmap.fold subst_class cl Gmap.empty in
+ let subst_inst k insts acc =
+ let k' = Lib.discharge_global k in
+ let insts' =
+ Cmap.fold (fun k is acc ->
+ let impl = Lib.discharge_con is.is_impl in
+ let is = { is with is_class = k'; is_impl = impl } in
+ Cmap.add impl is acc)
+ insts Cmap.empty
+ in Gmap.add k' insts' acc
+ in
+ let instances = Gmap.fold subst_inst inst Gmap.empty in
Some (classes, m, instances)
let rebuild (_,(cl,m,inst)) =