From d02c17b3faf6ef8822c6ce9c3bb24bce2b99caef Mon Sep 17 00:00:00 2001
From: Jean-Christophe Filliatre <Jean-Christophe.Filliatre@lri.fr>
Date: Tue, 14 Feb 2017 11:40:03 +0100
Subject: [PATCH] use mod_inst in module cloning

---
 src/mlw/pinterp.ml   |  2 +-
 src/mlw/pmodule.ml   | 41 ++++++++++++++++++++----------
 src/mlw/pmodule.mli  |  5 +++-
 src/parser/typing.ml | 59 ++++++++++++++++++++++----------------------
 4 files changed, 63 insertions(+), 44 deletions(-)

diff --git a/src/mlw/pinterp.ml b/src/mlw/pinterp.ml
index f8cae6f012..5dba33372b 100644
--- a/src/mlw/pinterp.ml
+++ b/src/mlw/pinterp.ml
@@ -22,7 +22,7 @@ open Ity
 open Expr
 
 
-module Nummap = Map.Make(BigInt)
+(* module Nummap = Map.Make(BigInt) *)
 
 type value =
   | Vconstr of rsymbol * field list
diff --git a/src/mlw/pmodule.ml b/src/mlw/pmodule.ml
index 956b66081e..f44dfe1cd5 100644
--- a/src/mlw/pmodule.ml
+++ b/src/mlw/pmodule.ml
@@ -113,11 +113,24 @@ and mod_inst = {
   mi_ts  : itysymbol Mts.t;
   mi_ls  : lsymbol Mls.t;
   mi_pr  : prsymbol Mpr.t;
+  mi_pk  : prop_kind Mpr.t;
   mi_pv  : pvsymbol Mvs.t;
   mi_rs  : rsymbol Mrs.t;
   mi_xs  : xsymbol Mexn.t;
 }
 
+let empty_mod_inst m = {
+  mi_mod = m;
+  mi_ty  = Mts.empty;
+  mi_ts  = Mts.empty;
+  mi_ls  = Mls.empty;
+  mi_pr  = Mpr.empty;
+  mi_pk  = Mpr.empty;
+  mi_pv  = Mvs.empty;
+  mi_rs  = Mrs.empty;
+  mi_xs  = Mexn.empty;
+}
+
 (** {2 Module under construction} *)
 
 type pmodule_uc = {
@@ -456,7 +469,7 @@ let cl_find_xs cl xs =
   else Mexn.find xs cl.xs_table
 
 let clone_ls inst cl ls =
-  if Mls.mem ls inst.inst_ls then raise (CannotInstantiate ls.ls_name);
+  if Mls.mem ls inst.mi_ls then raise (CannotInstantiate ls.ls_name);
   let constr = ls.ls_constr in
   let id = id_clone ls.ls_name in
   let at = List.map (clone_ty cl) ls.ls_args in
@@ -465,16 +478,16 @@ let clone_ls inst cl ls =
   cl.ls_table <- Mls.add ls ls' cl.ls_table;
   ls'
 
-let cl_init_ty cl ({ts_name = id} as ts) ty =
-  let its = restore_its ts and ity = ity_of_ty ty in
+let cl_init_ty cl ({ts_name = id} as ts) ity =
+  let its = restore_its ts in
   if not (Sid.mem id cl.cl_local) then raise (NonLocal id);
   let stv = Stv.of_list ts.ts_args in
   if not (Stv.subset (ity_freevars Stv.empty ity) stv &&
     its_pure its && ity_immutable ity) then raise (BadInstance id);
   cl.ty_table <- Mts.add ts ity cl.ty_table
 
-let cl_init_ts cl ({ts_name = id} as ts) ts' =
-  let its = restore_its ts and its' = restore_its ts' in
+let cl_init_ts cl ({ts_name = id} as ts) its' =
+  let its = restore_its ts and ts' = its'.its_ts in
   if not (Sid.mem id cl.cl_local) then raise (NonLocal id);
   if not (List.length ts.ts_args = List.length ts'.ts_args &&
     its_pure its && its_pure its') then raise (BadInstance id);
@@ -497,10 +510,10 @@ let cl_init_pr cl {pr_name = id} _ =
 
 let cl_init m inst =
   let cl = empty_clones m in
-  Mts.iter (cl_init_ty cl) inst.inst_ty;
-  Mts.iter (cl_init_ts cl) inst.inst_ts;
-  Mls.iter (cl_init_ls cl) inst.inst_ls;
-  Mpr.iter (cl_init_pr cl) inst.inst_pr;
+  Mts.iter (cl_init_ty cl) inst.mi_ty;
+  Mts.iter (cl_init_ts cl) inst.mi_ts;
+  Mls.iter (cl_init_ls cl) inst.mi_ls;
+  Mpr.iter (cl_init_pr cl) inst.mi_pk;
   cl
 
 (* clone declarations *)
@@ -508,7 +521,7 @@ let cl_init m inst =
 let clone_decl inst cl uc d = match d.d_node with
   | Dtype _ | Ddata _ -> assert false (* impossible *)
   | Dparam ls ->
-      if Mls.mem ls inst.inst_ls then uc else
+      if Mls.mem ls inst.mi_ls then uc else
       let d = create_param_decl (clone_ls inst cl ls) in
       add_pdecl ~vc:false uc (create_pure_decl d)
   | Dlogic ldl ->
@@ -521,7 +534,7 @@ let clone_decl inst cl uc d = match d.d_node with
   | Dind (s, idl) ->
       let get_ls (ls,_) = clone_ls inst cl ls in
       let get_case (pr,f) =
-        if Mpr.mem pr inst.inst_pr then raise (CannotInstantiate pr.pr_name);
+        if Mpr.mem pr inst.mi_pk then raise (CannotInstantiate pr.pr_name);
         let pr' = create_prsymbol (id_clone pr.pr_name) in
         cl.pr_table <- Mpr.add pr pr' cl.pr_table;
         pr', clone_fmla cl f in
@@ -530,7 +543,7 @@ let clone_decl inst cl uc d = match d.d_node with
       let d = create_ind_decl s (List.map2 get_ind lls idl) in
       add_pdecl ~vc:false uc (create_pure_decl d)
   | Dprop (k,pr,f) ->
-      let skip, k' = match k, Mpr.find_opt pr inst.inst_pr with
+      let skip, k' = match k, Mpr.find_opt pr inst.mi_pk with
         | Pgoal, _ -> true, Pgoal
         | Plemma, Some Pgoal -> true, Pgoal
         | Plemma, _ -> false, Plemma
@@ -567,7 +580,7 @@ let clone_type_decl inst cl tdl =
     if not (Hits.mem htd s) then
     let alg = Sits.add s alg in
     let id' = id_clone id in
-    let cloned = Mts.mem ts inst.inst_ts || Mts.mem ts inst.inst_ty in
+    let cloned = Mts.mem ts inst.mi_ts || Mts.mem ts inst.mi_ty in
     let conv_pj v = create_pvsymbol
       (id_clone v.pv_vs.vs_name) ~ghost:v.pv_ghost (conv_ity alg v.pv_ity) in
     let save_itd itd =
@@ -896,6 +909,7 @@ let clone_export uc m inst =
           mi_ts = Mts.map (cl_find_its cl) mi.mi_ts;
           mi_ls = Mls.map (cl_find_ls cl) mi.mi_ls;
           mi_pr = Mpr.map (cl_find_pr cl) mi.mi_pr;
+          mi_pk = mi.mi_pk;
           mi_pv = Mvs.map (cl_find_pv cl) mi.mi_pv;
           mi_rs = Mrs.map (cl_find_rs cl) mi.mi_rs;
           mi_xs = Mexn.map (cl_find_xs cl) mi.mi_xs}
@@ -919,6 +933,7 @@ let clone_export uc m inst =
     mi_ts  = cl.ts_table;
     mi_ls  = cl.ls_table;
     mi_pr  = cl.pr_table;
+    mi_pk  = inst.mi_pk;
     mi_pv  = cl.pv_table;
     mi_rs  = cl.rs_table;
     mi_xs  = cl.xs_table} in
diff --git a/src/mlw/pmodule.mli b/src/mlw/pmodule.mli
index ea61b4a10b..7b2067769e 100644
--- a/src/mlw/pmodule.mli
+++ b/src/mlw/pmodule.mli
@@ -66,11 +66,14 @@ and mod_inst = {
   mi_ts  : itysymbol Mts.t;
   mi_ls  : lsymbol Mls.t;
   mi_pr  : prsymbol Mpr.t;
+  mi_pk  : prop_kind Mpr.t;
   mi_pv  : pvsymbol Mvs.t;
   mi_rs  : rsymbol Mrs.t;
   mi_xs  : xsymbol Mexn.t;
 }
 
+val empty_mod_inst: pmodule -> mod_inst
+
 (** {2 Module under construction} *)
 
 type pmodule_uc = private {
@@ -106,7 +109,7 @@ val restore_module : theory -> pmodule
 
 val use_export : pmodule_uc -> pmodule -> pmodule_uc
 
-val clone_export : pmodule_uc -> pmodule -> Theory.th_inst -> pmodule_uc
+val clone_export : pmodule_uc -> pmodule -> mod_inst -> pmodule_uc
 
 (** {2 Logic decls} *)
 
diff --git a/src/parser/typing.ml b/src/parser/typing.ml
index bb840457ba..6da04ccf5d 100644
--- a/src/parser/typing.ml
+++ b/src/parser/typing.ml
@@ -997,62 +997,63 @@ let find_module env file q =
   if Debug.test_flag Glob.flag then Glob.use (qloc_last q) m.mod_theory.th_name;
   m
 
-let type_inst ({muc_theory = tuc} as _muc) {mod_theory = t} s =
+let type_inst ({muc_theory = tuc} as muc) ({mod_theory = t} as m) s =
   let add_inst s = function
     | CStsym (p,[],PTtyapp (q,[])) ->
         let ts1 = find_tysymbol_ns t.th_export p in
-        let ts2 = find_tysymbol tuc q in
-        if Mts.mem ts1 s.inst_ty then Loc.error ~loc:(qloc p)
+        let ts2 = find_itysymbol muc q in
+        if Mts.mem ts1 s.mi_ty then Loc.error ~loc:(qloc p)
           (ClashSymbol ts1.ts_name.id_string);
-        { s with inst_ts = Loc.try4 ~loc:(qloc p) Mts.add_new
-            (ClashSymbol ts1.ts_name.id_string) ts1 ts2 s.inst_ts }
+        { s with mi_ts = Loc.try4 ~loc:(qloc p) Mts.add_new
+            (ClashSymbol ts1.ts_name.id_string) ts1 ts2 s.mi_ts }
     | CStsym (p,tvl,pty) ->
         let ts1 = find_tysymbol_ns t.th_export p in
         let tvl = List.map (fun id -> tv_of_string id.id_str) tvl in
-        let ts2 = Loc.try3 ~loc:(qloc p) create_tysymbol
-          (id_clone ts1.ts_name) tvl (Some (ty_of_pty tuc pty)) in
-        let ty2 = ty_app ts2 (List.map ty_var ts1.ts_args) in
-        let check v ty = match ty.ty_node with
-          | Tyvar u -> tv_equal u v | _ -> false in
-        begin match ty2.ty_node with
-        | Tyapp (ts2, tyl) when Lists.equal check tvl tyl ->
-            if Mts.mem ts1 s.inst_ty then Loc.error ~loc:(qloc p)
+        let ts2 = Loc.try3 ~loc:(qloc p) create_alias_itysymbol
+          (id_clone ts1.ts_name) tvl (ity_of_pty muc pty) in
+        let ty2 = ity_app ts2 (List.map ity_var ts1.ts_args) [] in
+        let check v ty = match ty.ity_node with
+          | Ityvar (u, _) -> tv_equal u v | _ -> false in
+        begin match ty2.ity_node with
+        | Ityapp (ts2, tyl, _) | Ityreg { reg_its = ts2; reg_args = tyl }
+          when Lists.equal check tvl tyl ->
+            if Mts.mem ts1 s.mi_ty then Loc.error ~loc:(qloc p)
               (ClashSymbol ts1.ts_name.id_string);
-            { s with inst_ts = Loc.try4 ~loc:(qloc p) Mts.add_new
-                (ClashSymbol ts1.ts_name.id_string) ts1 ts2 s.inst_ts }
+            { s with mi_ts = Loc.try4 ~loc:(qloc p) Mts.add_new
+                (ClashSymbol ts1.ts_name.id_string) ts1 ts2 s.mi_ts }
         | _ ->
-            if Mts.mem ts1 s.inst_ts then Loc.error ~loc:(qloc p)
+            if Mts.mem ts1 s.mi_ts then Loc.error ~loc:(qloc p)
               (ClashSymbol ts1.ts_name.id_string);
-            { s with inst_ty = Loc.try4 ~loc:(qloc p) Mts.add_new
-                (ClashSymbol ts1.ts_name.id_string) ts1 ty2 s.inst_ty }
+            { s with mi_ty = Loc.try4 ~loc:(qloc p) Mts.add_new
+                (ClashSymbol ts1.ts_name.id_string) ts1 ty2 s.mi_ty }
         end
     | CSfsym (p,q) ->
         let ls1 = find_fsymbol_ns t.th_export p in
         let ls2 = find_fsymbol tuc q in
-        { s with inst_ls = Loc.try4 ~loc:(qloc p) Mls.add_new
-            (ClashSymbol ls1.ls_name.id_string) ls1 ls2 s.inst_ls }
+        { s with mi_ls = Loc.try4 ~loc:(qloc p) Mls.add_new
+            (ClashSymbol ls1.ls_name.id_string) ls1 ls2 s.mi_ls }
     | CSpsym (p,q) ->
         let ls1 = find_psymbol_ns t.th_export p in
         let ls2 = find_psymbol tuc q in
-        { s with inst_ls = Loc.try4 ~loc:(qloc p) Mls.add_new
-            (ClashSymbol ls1.ls_name.id_string) ls1 ls2 s.inst_ls }
+        { s with mi_ls = Loc.try4 ~loc:(qloc p) Mls.add_new
+            (ClashSymbol ls1.ls_name.id_string) ls1 ls2 s.mi_ls }
     | CSvsym (p,_) ->
         Loc.errorm ~loc:(qloc p)
           "program symbol instantiation is not supported yet" (* TODO *)
     | CSaxiom p ->
         let pr = find_prop_ns t.th_export p in
-        { s with inst_pr = Loc.try4 ~loc:(qloc p) Mpr.add_new
-            (ClashSymbol pr.pr_name.id_string) pr Paxiom s.inst_pr }
+        { s with mi_pk = Loc.try4 ~loc:(qloc p) Mpr.add_new
+            (ClashSymbol pr.pr_name.id_string) pr Paxiom s.mi_pk }
     | CSlemma p ->
         let pr = find_prop_ns t.th_export p in
-        { s with inst_pr = Loc.try4 ~loc:(qloc p) Mpr.add_new
-            (ClashSymbol pr.pr_name.id_string) pr Plemma s.inst_pr }
+        { s with mi_pk = Loc.try4 ~loc:(qloc p) Mpr.add_new
+            (ClashSymbol pr.pr_name.id_string) pr Plemma s.mi_pk }
     | CSgoal p ->
         let pr = find_prop_ns t.th_export p in
-        { s with inst_pr = Loc.try4 ~loc:(qloc p) Mpr.add_new
-            (ClashSymbol pr.pr_name.id_string) pr Pgoal s.inst_pr }
+        { s with mi_pk = Loc.try4 ~loc:(qloc p) Mpr.add_new
+            (ClashSymbol pr.pr_name.id_string) pr Pgoal s.mi_pk }
   in
-  List.fold_left add_inst empty_inst s
+  List.fold_left add_inst (empty_mod_inst m) s
 
 let add_decl muc env file d =
   let vc = muc.muc_theory.uc_path = [] &&
-- 
GitLab