Skip to content

Commit a9cb3e9

Browse files
committed
Print type parameters of operators when not inferrable from arguments
When an operator has type parameters that cannot be inferred from the types of its provided arguments, the pretty-printer now automatically displays the type instantiation (e.g., `card<:bool>` instead of `card`). A `PP:showtvi` flag (toggled via `pragma +PP:showtvi`) forces display of type parameters even when they are inferrable.
1 parent 6d48cc1 commit a9cb3e9

4 files changed

Lines changed: 49 additions & 6 deletions

File tree

src/ecCommands.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,8 @@ and process_pragma (scope : EcScope.scope) opt =
668668
(* -------------------------------------------------------------------- *)
669669
and process_option (scope : EcScope.scope) (name, value) =
670670
match value with
671-
| `Bool value when EcLocation.unloc name = EcGState.old_mem_restr ->
671+
| `Bool value when EcLocation.unloc name = EcGState.old_mem_restr
672+
|| EcLocation.unloc name = EcGState.pp_showtvi ->
672673
let gs = EcEnv.gstate (EcScope.env scope) in
673674
EcGState.setflag (unloc name) value gs; scope
674675

src/ecGState.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ let old_mem_restr = "old_mem_restr"
6464
let get_old_mem_restr (g : gstate) : bool =
6565
getflag ~default:false old_mem_restr g
6666

67+
(* -------------------------------------------------------------------- *)
68+
let pp_showtvi = "PP:showtvi"
69+
70+
let get_pp_showtvi (g : gstate) : bool =
71+
getflag ~default:false pp_showtvi g
72+
6773
(* -------------------------------------------------------------------- *)
6874
let add_notifier (notifier : loglevel -> string Lazy.t -> unit) (gs : gstate) =
6975
let notifier = { nt_id = EcUid.unique (); nt_cb = notifier; } in

src/ecGState.mli

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ val setflag : string -> bool -> gstate -> unit
2828
val old_mem_restr : string
2929
val get_old_mem_restr : gstate -> bool
3030

31+
(* --------------------------------------------------------------------- *)
32+
val pp_showtvi : string
33+
val get_pp_showtvi : gstate -> bool
34+
3135
(* --------------------------------------------------------------------- *)
3236
type nid_t
3337
type loglevel = [`Debug | `Info | `Warning | `Critical]

src/ecPrinting.ml

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,25 @@ module PPEnv = struct
3636
ppe_univar : (symbol Mint.t * Ssym.t) ref;
3737
ppe_fb : Sp.t;
3838
ppe_width : int;
39+
ppe_showtvi : bool;
3940
}
4041

4142
let ofenv (env : EcEnv.env) =
43+
let gs = EcEnv.gstate env in
44+
4245
let width =
4346
EcGState.asint ~default:80
44-
(EcGState.getvalue "PP:width" (EcEnv.gstate env)) in
47+
(EcGState.getvalue "PP:width" gs) in
48+
49+
let showtvi = EcGState.get_pp_showtvi gs in
4550

4651
{ ppe_env = env;
4752
ppe_locals = Mid.empty;
4853
ppe_inuse = Ssym.empty;
4954
ppe_univar = ref (Mint.empty, Ssym.empty);
5055
ppe_fb = Sp.empty;
51-
ppe_width = max 20 width; }
56+
ppe_width = max 20 width;
57+
ppe_showtvi = showtvi; }
5258

5359
let enter_theory (ppe : t) (p : EcPath.path) =
5460
let ppe_env = EcEnv.Theory.env_of_theory p ppe.ppe_env in
@@ -936,7 +942,7 @@ let pp_opname_with_tvi
936942
| Some tvi ->
937943
Format.fprintf fmt "%a<:%a>"
938944
pp_opname (nm, op)
939-
(pp_list "@, " (pp_type ppe)) tvi
945+
(pp_list ",@ " (pp_type ppe)) tvi
940946

941947
(* -------------------------------------------------------------------- *)
942948
let pp_if_form (type v)
@@ -1084,6 +1090,22 @@ let pp_app (type v1 v2)
10841090
in
10851091
maybe_paren outer e_app_prio pp fmt ()
10861092

1093+
(* -------------------------------------------------------------------- *)
1094+
(* [tvi_dominated env op nargs] checks whether all type parameters of [op]
1095+
can be inferred from the types of the first [nargs] arguments. *)
1096+
let tvi_dominated (env : EcEnv.env) (op : EcPath.path) (nargs : int) : bool =
1097+
match EcEnv.Op.by_path_opt op env with
1098+
| None -> false
1099+
| Some opdecl ->
1100+
let tparams = opdecl.op_tparams in
1101+
let dom, _ = tyfun_flat opdecl.op_ty in
1102+
let arg_tys = List.take nargs dom in
1103+
let covered =
1104+
List.fold_left
1105+
(fun acc ty -> Sid.union acc (EcTypes.Tvar.fv ty))
1106+
Sid.empty arg_tys in
1107+
List.for_all (fun id -> Sid.mem id covered) tparams
1108+
10871109
(* -------------------------------------------------------------------- *)
10881110
let pp_opapp
10891111
(ppe : PPEnv.t)
@@ -1158,13 +1180,23 @@ let pp_opapp
11581180
in fun () -> doit fmt es
11591181

11601182
with E.PrintAsPlain ->
1183+
let tvi_opt =
1184+
if List.is_empty tvi then None
1185+
else
1186+
let dominated =
1187+
tvi_dominated ppe.PPEnv.ppe_env op (List.length es) in
1188+
if dominated && not ppe.PPEnv.ppe_showtvi
1189+
then None else Some tvi
1190+
in
1191+
11611192
fun () ->
11621193
match es with
11631194
| [] ->
1164-
pp_opname fmt (nm, opname)
1195+
pp_opname_with_tvi ppe fmt (nm, opname, tvi_opt)
11651196

11661197
| _ ->
1167-
let pp_first = (fun _ _ -> pp_opname) in
1198+
let pp_first = fun _ _ fmt op ->
1199+
pp_opname_with_tvi ppe fmt (fst op, snd op, tvi_opt) in
11681200
let pp fmt () = pp_app ppe ~pp_first ~pp_sub outer fmt ((nm, opname), es) in
11691201
maybe_paren outer max_op_prec pp fmt ()
11701202

0 commit comments

Comments
 (0)