Skip to content

Commit 20b28e0

Browse files
committed
New vernacular command: theory aliases
Syntax this: `theory T = Path.To.Theory` Theory aliases allow giving alternate names to theories - mainly for readability issues. They are purely syntactic sugar and are fully resolved (desugared) during typing. The pretty-printer uses them when printing path, using a longest-then-lastly-introduced strategy.
1 parent 8debf27 commit 20b28e0

16 files changed

Lines changed: 181 additions & 37 deletions

src/ecCommands.ml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ module HiPrinting = struct
291291
let ppe = EcPrinting.PPEnv.ofenv env in
292292

293293
let pp_path =
294-
EcPrinting.pp_shorten_path
294+
EcPrinting.pp_shorten_path ppe
295295
(fun (p : EcPath.path) (q : EcSymbols.qsymbol) ->
296296
Option.equal EcPath.p_equal
297297
(Some p)
@@ -594,6 +594,11 @@ and process_th_clone (scope : EcScope.scope) thcl =
594594
EcScope.Cloning.clone scope (Pragma.get ()).pm_check thcl
595595

596596
(* -------------------------------------------------------------------- *)
597+
and process_th_alias (scope : EcScope.scope) (thcl : psymbol * pqsymbol) =
598+
EcScope.check_state `InTop "theory alias" scope;
599+
EcScope.Theory.alias scope thcl
600+
601+
(* -------------------------------------------------------------------- *)
597602
and process_mod_import (scope : EcScope.scope) mods =
598603
EcScope.check_state `InTop "module var import" scope;
599604
List.fold_left EcScope.Mod.import scope mods
@@ -768,6 +773,7 @@ and process (ld : Loader.loader) (scope : EcScope.scope) g =
768773
| GthImport name -> `Fct (fun scope -> process_th_import scope name)
769774
| GthExport name -> `Fct (fun scope -> process_th_export scope name)
770775
| GthClone thcl -> `Fct (fun scope -> process_th_clone scope thcl)
776+
| GthAlias als -> `Fct (fun scope -> process_th_alias scope als)
771777
| GModImport mods -> `Fct (fun scope -> process_mod_import scope mods)
772778
| GsctOpen name -> `Fct (fun scope -> process_sct_open scope name)
773779
| GsctClose name -> `Fct (fun scope -> process_sct_close scope name)

src/ecCorePrinting.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ module type PrinterAPI = sig
5454
val pp_tyname : PPEnv.t -> path pp
5555
val pp_axname : PPEnv.t -> path pp
5656
val pp_tcname : PPEnv.t -> path pp
57-
val pp_thname : PPEnv.t -> path pp
57+
val pp_thname : ?alias:bool -> PPEnv.t -> path pp
5858

5959
val pp_mem : PPEnv.t -> EcIdent.t pp
6060
val pp_memtype : PPEnv.t -> EcMemory.memtype pp
@@ -63,9 +63,9 @@ module type PrinterAPI = sig
6363
val pp_path : path pp
6464

6565
(* ------------------------------------------------------------------ *)
66-
val shorten_path : (path -> qsymbol -> bool) -> path -> qsymbol * qsymbol option
66+
val shorten_path : PPEnv.t -> (path -> qsymbol -> bool) -> path -> qsymbol * qsymbol option
6767

68-
val pp_shorten_path : (path -> qsymbol -> bool) -> path pp
68+
val pp_shorten_path : PPEnv.t -> (path -> qsymbol -> bool) -> path pp
6969

7070
(* ------------------------------------------------------------------ *)
7171
val pp_codepos1 : PPEnv.t -> EcMatching.Position.codepos1 pp

src/ecEnv.ml

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ type preenv = {
184184
env_atbase : atbase Msym.t;
185185
env_redbase : mredinfo;
186186
env_ntbase : ntbase Mop.t;
187+
env_albase : path Mp.t; (* theory aliases *)
187188
env_modlcs : Sid.t; (* declared modules *)
188189
env_item : theory_item list; (* in reverse order *)
189190
env_norm : env_norm ref;
@@ -312,6 +313,7 @@ let empty gstate =
312313
env_atbase = Msym.empty;
313314
env_redbase = Mrd.empty;
314315
env_ntbase = Mop.empty;
316+
env_albase = Mp.empty;
315317
env_modlcs = Sid.empty;
316318
env_item = [];
317319
env_norm = ref empty_norm_cache;
@@ -636,9 +638,9 @@ module MC = struct
636638
(IPPath (root env))
637639
env.env_comps; }
638640

639-
let import up p obj env =
640-
let name = ibasename p in
641-
{ env with env_current = up env.env_current name (p, obj) }
641+
let import ?name up p obj env =
642+
let name = odfl (ibasename p) name in
643+
{ env with env_current = up env.env_current name (p, obj) }
642644

643645
(* -------------------------------------------------------------------- *)
644646
let lookup_var qnx env =
@@ -976,20 +978,20 @@ module MC = struct
976978
| None -> lookup_error (`QSymbol qnx)
977979
| Some (p, (args, obj)) -> (_downpath_for_th env p args, obj)
978980

979-
let import_theory p th env =
980-
import (_up_theory true) (IPPath p) th env
981+
let import_theory ?name p th env =
982+
import ?name (_up_theory true) (IPPath p) th env
981983

982984
(* -------------------------------------------------------------------- *)
983-
let _up_mc candup mc p =
984-
let name = ibasename p in
985+
let _up_mc ?name candup mc p =
986+
let name = odfl (ibasename p) name in
985987
if not candup && MMsym.last name mc.mc_components <> None then
986988
raise (DuplicatedBinding name);
987989
{ mc with mc_components =
988990
MMsym.add name p mc.mc_components }
989991

990-
let import_mc p env =
991-
let mc = _up_mc true env.env_current p in
992-
{ env with env_current = mc }
992+
let import_mc ?name p env =
993+
let mc = _up_mc ?name true env.env_current p in
994+
{ env with env_current = mc }
993995

994996
(* ------------------------------------------------------------------ *)
995997
let rec mc_of_module_r (p1, args, p2, lc) me =
@@ -1109,6 +1111,10 @@ module MC = struct
11091111
| Th_baserw (x, _) ->
11101112
(add2mc _up_rwbase x (expath x) mc, None)
11111113

1114+
| Th_alias _ ->
1115+
(* FIXME:ALIAS *)
1116+
(mc, None)
1117+
11121118
| Th_export _ | Th_addrw _ | Th_instance _
11131119
| Th_auto _ | Th_reduction _ ->
11141120
(mc, None)
@@ -2886,6 +2892,25 @@ module Theory = struct
28862892
else
28872893
Option.get (Mp.find_opt p env.env_thenvs)
28882894
2895+
(* ------------------------------------------------------------------ *)
2896+
let rebind_alias (name : symbol) (path : path) (env : env) =
2897+
let th = by_path path env in
2898+
let src = EcPath.pqname (root env) name in
2899+
let env = MC.import_theory ~name path th env in
2900+
let env = MC.import_mc ~name (IPPath path) env in
2901+
let env = { env with env_albase = Mp.add path src env.env_albase } in
2902+
env
2903+
2904+
(* ------------------------------------------------------------------ *)
2905+
let alias ?(import = import0) (name : symbol) (path : path) (env : env) =
2906+
let env =
2907+
if import.im_immediate then rebind_alias name path env else env in
2908+
{ env with env_item = mkitem import (Th_alias (name, path)) :: env.env_item }
2909+
2910+
(* ------------------------------------------------------------------ *)
2911+
let aliases (env : env) =
2912+
env.env_albase
2913+
28892914
(* ------------------------------------------------------------------ *)
28902915
let rec bind_instance_th path inst cth =
28912916
List.fold_left (bind_instance_th_item path) inst cth
@@ -3088,6 +3113,9 @@ module Theory = struct
30883113
| Th_baserw (x, _) ->
30893114
MC.import_rwbase (xpath x) env
30903115
3116+
| Th_alias (name, path) ->
3117+
rebind_alias name path env
3118+
30913119
| Th_addrw _ | Th_instance _ | Th_auto _ | Th_reduction _ ->
30923120
env
30933121

src/ecEnv.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,9 @@ module Theory : sig
293293
-> EcTypes.is_local
294294
-> EcTheory.thmode
295295
-> env -> compiled_theory option
296+
297+
val alias : ?import:import -> symbol -> path -> env -> env
298+
val aliases : env -> path Mp.t
296299
end
297300

298301
(* -------------------------------------------------------------------- *)

src/ecParser.mly

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1984,7 +1984,7 @@ theory_clear_items:
19841984
| xs=theory_clear_item1* { xs }
19851985

19861986
theory_open:
1987-
| loca=is_local b=boption(ABSTRACT) THEORY x=uident
1987+
| loca=is_local b=iboption(ABSTRACT) THEORY x=uident
19881988
{ (loca, b, x) }
19891989

19901990
theory_close:
@@ -3655,6 +3655,13 @@ realize:
36553655
| REALIZE x=qident BY bracket(empty)
36563656
{ { pr_name = x; pr_proof = Some None; } }
36573657

3658+
3659+
(* -------------------------------------------------------------------- *)
3660+
(* Theory aliasing *)
3661+
3662+
theory_alias: (* FIXME: THEORY ALIAS -> S/R conflict *)
3663+
| THEORY name=uident EQ target=uqident { (name, target) }
3664+
36583665
(* -------------------------------------------------------------------- *)
36593666
(* Printing *)
36603667
phint:
@@ -3792,6 +3799,7 @@ global_action:
37923799
| theory_export { GthExport $1 }
37933800
| theory_clone { GthClone $1 }
37943801
| theory_clear { GthClear $1 }
3802+
| theory_alias { GthAlias $1 }
37953803
| module_import { GModImport $1 }
37963804
| section_open { GsctOpen $1 }
37973805
| section_close { GsctClose $1 }

src/ecParsetree.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,6 +1293,7 @@ type global_action =
12931293
| GthImport of pqsymbol list
12941294
| GthExport of pqsymbol list
12951295
| GthClone of theory_cloning
1296+
| GthAlias of (psymbol * pqsymbol)
12961297
| GModImport of pmsymbol located list
12971298
| GsctOpen of osymbol_r
12981299
| GsctClose of osymbol_r

src/ecPrinting.ml

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,25 @@ module PPEnv = struct
143143
(fun env x -> EcEnv.Mod.bind_param x mty env)
144144
ppe.ppe_env xs; }
145145

146-
let p_shorten cond (nm, x) =
146+
let reverse_theory_alias (ppe : t) (path : P.path) : P.path =
147+
let aliases = EcEnv.Theory.aliases ppe.ppe_env in
148+
149+
let rec reverse (suffix : symbol list) (p : P.path option) =
150+
Option.bind p (fun prefix ->
151+
match P.Mp.find_opt prefix aliases with
152+
| None -> reverse (P.basename prefix :: suffix) (P.prefix prefix)
153+
| Some prefix -> Some (EcPath.extend prefix suffix)
154+
)
155+
in Option.value ~default:path (reverse [] (Some path))
156+
157+
let p_shorten
158+
?(alias = true)
159+
?(istheory = false)
160+
(ppe : t)
161+
(cond : qsymbol -> bool)
162+
(p : qsymbol)
163+
: qsymbol
164+
=
147165
let rec shorten prefix (nm, x) =
148166
match cond (nm, x) with
149167
| true -> (nm, x)
@@ -154,35 +172,46 @@ module PPEnv = struct
154172
end
155173
in
156174

175+
let p = EcPath.fromqsymbol p in
176+
let p =
177+
if alias then begin
178+
if istheory then
179+
reverse_theory_alias ppe p
180+
else
181+
let thpath, base = P.prefix p, P.basename p in
182+
let thpath = Option.map (reverse_theory_alias ppe) thpath in
183+
P.pqoname thpath base
184+
end else p in
185+
let (nm, x) = EcPath.toqsymbol p in
157186
shorten (List.rev nm) ([], x)
158187

159188
let ty_symb (ppe : t) p =
160-
let exists sm =
189+
let exists sm =
161190
try EcPath.p_equal (EcEnv.Ty.lookup_path ~unique:true sm ppe.ppe_env) p
162191
with EcEnv.LookupFailure _ -> false
163192
in
164-
p_shorten exists (P.toqsymbol p)
193+
p_shorten ppe exists (P.toqsymbol p)
165194

166195
let tc_symb (ppe : t) p =
167-
let exists sm =
196+
let exists sm =
168197
try EcPath.p_equal (EcEnv.TypeClass.lookup_path sm ppe.ppe_env) p
169198
with EcEnv.LookupFailure _ -> false
170199
in
171-
p_shorten exists (P.toqsymbol p)
200+
p_shorten ppe exists (P.toqsymbol p)
172201

173202
let rw_symb (ppe : t) p =
174-
let exists sm =
203+
let exists sm =
175204
try EcPath.p_equal (EcEnv.BaseRw.lookup_path sm ppe.ppe_env) p
176205
with EcEnv.LookupFailure _ -> false
177206
in
178-
p_shorten exists (P.toqsymbol p)
207+
p_shorten ppe exists (P.toqsymbol p)
179208

180209
let ax_symb (ppe : t) p =
181-
let exists sm =
210+
let exists sm =
182211
try EcPath.p_equal (EcEnv.Ax.lookup_path sm ppe.ppe_env) p
183212
with EcEnv.LookupFailure _ -> false
184213
in
185-
p_shorten exists (P.toqsymbol p)
214+
p_shorten ppe exists (P.toqsymbol p)
186215

187216
let op_symb (ppe : t) p info =
188217
let specs = [1, EcPath.pqoname (EcPath.prefix EcCoreLib.CI_Bool.p_eq) "<>"] in
@@ -220,21 +249,21 @@ module PPEnv = struct
220249
(* FIXME: for special operators, do check `info` *)
221250
if List.exists (fun (_, sp) -> EcPath.p_equal sp p) specs
222251
then ([], EcPath.basename p)
223-
else p_shorten exists (P.toqsymbol p)
252+
else p_shorten ppe exists (P.toqsymbol p)
224253

225254
let ax_symb (ppe : t) p =
226255
let exists sm =
227256
try EcPath.p_equal (EcEnv.Ax.lookup_path sm ppe.ppe_env) p
228257
with EcEnv.LookupFailure _ -> false
229258
in
230-
p_shorten exists (P.toqsymbol p)
259+
p_shorten ppe exists (P.toqsymbol p)
231260

232-
let th_symb (ppe : t) p =
261+
let th_symb ?alias (ppe : t) p =
233262
let exists sm =
234263
try EcPath.p_equal (EcEnv.Theory.lookup_path sm ppe.ppe_env) p
235264
with EcEnv.LookupFailure _ -> false
236265
in
237-
p_shorten exists (P.toqsymbol p)
266+
p_shorten ?alias ~istheory:true ppe exists (P.toqsymbol p)
238267

239268
let rec mod_symb (ppe : t) mp : EcSymbols.msymbol =
240269
let (nm, x, p2) =
@@ -360,13 +389,18 @@ module PPEnv = struct
360389
end
361390

362391
(* -------------------------------------------------------------------- *)
363-
let shorten_path (cond : P.path -> qsymbol -> bool) (p : P.path) : qsymbol * qsymbol option =
392+
let shorten_path
393+
(ppe : PPEnv.t)
394+
(cond : P.path -> qsymbol -> bool)
395+
(p : P.path)
396+
: qsymbol * qsymbol option
397+
=
364398
let (nm, x) = EcPath.toqsymbol p in
365399
let nm =
366400
match nm with
367401
| top :: nm when top = EcCoreLib.i_top -> nm
368402
| _ -> nm in
369-
let nm', x' = PPEnv.p_shorten (cond p) (nm, x) in
403+
let nm', x' = PPEnv.p_shorten ppe (cond p) (nm, x) in
370404
let plong, pshort = (nm, x), (nm', x') in
371405

372406
(plong, if plong = pshort then None else Some pshort)
@@ -445,8 +479,13 @@ let pp_path fmt p =
445479
Format.fprintf fmt "%s" (P.tostring p)
446480

447481
(* -------------------------------------------------------------------- *)
448-
let pp_shorten_path (cond : P.path -> qsymbol -> bool) (fmt : Format.formatter) (p : P.path) =
449-
let plong, pshort = shorten_path cond p in
482+
let pp_shorten_path
483+
(ppe : PPEnv.t)
484+
(cond : P.path -> qsymbol -> bool)
485+
(fmt : Format.formatter)
486+
(p : P.path)
487+
=
488+
let plong, pshort = shorten_path ppe cond p in
450489

451490
match pshort with
452491
| None ->
@@ -507,8 +546,8 @@ let pp_axhnt ppe fmt (p, b) =
507546
Format.fprintf fmt "%a%s" (pp_axname ppe) p b
508547

509548
(* -------------------------------------------------------------------- *)
510-
let pp_thname ppe fmt p =
511-
EcSymbols.pp_qsymbol fmt (PPEnv.th_symb ppe p)
549+
let pp_thname ?alias ppe fmt p =
550+
EcSymbols.pp_qsymbol fmt (PPEnv.th_symb ?alias ppe p)
512551

513552
(* -------------------------------------------------------------------- *)
514553
let pp_funname (ppe : PPEnv.t) fmt p =
@@ -3565,6 +3604,9 @@ let rec pp_theory ppe (fmt : Format.formatter) (path, cth) =
35653604
level (odfl "" base)
35663605
(pp_list "@ " (pp_axhnt ppe)) axioms
35673606

3607+
| EcTheory.Th_alias (name, target) ->
3608+
Format.fprintf fmt "theory %s = %a." name (pp_thname ~alias:false ppe) target
3609+
35683610
(* -------------------------------------------------------------------- *)
35693611
let pp_stmt_with_nums (ppe : PPEnv.t) fmt stmt =
35703612
let ppnode = collect2_s ppe stmt.s_node [] in

0 commit comments

Comments
 (0)