Skip to content

Commit b6528af

Browse files
committed
Hide definition of tacvalue in tacinterp
1 parent ac03def commit b6528af

File tree

5 files changed

+89
-57
lines changed

5 files changed

+89
-57
lines changed

plugins/ltac/pptactic.ml

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,24 +1400,13 @@ let () =
14001400
register_basic_print0 Stdarg.wit_pre_ident str str str;
14011401
register_basic_print0 Stdarg.wit_string qstring qstring qstring
14021402

1403-
let pr_tacvalue env = function
1404-
| VFun (a,_,loc,ids,l,tac) ->
1405-
let open Pp in
1406-
let tac = if List.is_empty l then tac else CAst.make ?loc @@ Tacexpr.TacFun (l,tac) in
1407-
let pr_env env =
1408-
if Id.Map.is_empty ids then mt ()
1409-
else
1410-
cut () ++ str "where" ++
1411-
Id.Map.fold (fun id c pp ->
1412-
cut () ++ Id.print id ++ str " := " ++ pr_value ltop c ++ pp)
1413-
ids (mt ())
1414-
in
1415-
v 0 (hov 0 (pr_glob_tactic env tac) ++ pr_env env)
1416-
| VRec _ -> str "<tactic closure>"
1403+
let pr_tacvalue_ref = ref (fun _ _ : Pp.t -> assert false)
1404+
1405+
let pr_tacvalue env v = !pr_tacvalue_ref env v
14171406

14181407
let () =
14191408
let printer env sigma _ _ prtac = prtac env sigma in
1420-
let top_print env sigma _ _ _ _ = pr_tacvalue env in
1409+
let top_print env sigma _ _ _ _ v = pr_tacvalue env v in
14211410
declare_extra_genarg_pprule_with_level wit_tactic printer printer top_print
14221411
ltop (LevelLe 0)
14231412

@@ -1451,3 +1440,7 @@ let () =
14511440
in
14521441
Gentactic.register_print wit_ltac (printer pr_raw_tactic_level)
14531442
(printer (fun env _sigma n x -> pr_glob_tactic_level env n x))
1443+
1444+
module Internal = struct
1445+
let pr_tacvalue_ref = pr_tacvalue_ref
1446+
end

plugins/ltac/pptactic.mli

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,7 @@ val make_constr_printer : (env -> Evd.evar_map -> entry_relative_level -> 'a ->
165165
'a Genprint.top_printer
166166

167167
val ssr_loaded : unit -> bool
168+
169+
module Internal : sig
170+
val pr_tacvalue_ref : (env -> Tacarg.tacvalue -> Pp.t) ref
171+
end

plugins/ltac/tacarg.ml

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
open Genarg
1414
open Geninterp
1515
open Tacexpr
16-
open Names
1716

1817
let make0 ?dyn name =
1918
let wit = Genarg.make0 name in
@@ -28,17 +27,8 @@ let wit_open_constr_with_bindings = make0 "open_constr_with_bindings"
2827
let wit_bindings = make0 "bindings"
2928
let wit_quantified_hypothesis = wit_quant_hyp
3029

31-
32-
(** Abstract application, to print ltac functions *)
33-
type appl =
34-
| UnnamedAppl (** For generic applications: nothing is printed *)
35-
| GlbAppl of (Names.KerName.t * Geninterp.Val.t list) list
36-
(** For calls to global constants, some may alias other. *)
37-
38-
type tacvalue =
39-
| VFun of appl * ltac_trace * Loc.t option * Geninterp.Val.t Id.Map.t *
40-
Name.t list * glob_tactic_expr
41-
| VRec of Geninterp.Val.t Id.Map.t ref * glob_tactic_expr
30+
(* we can put ocaml closures (through geninterp vals) in tacvalues so no need to be marshallable *)
31+
type tacvalue = ..
4232

4333
let wit_tactic : (raw_tactic_expr, glob_tactic_expr, tacvalue) genarg_type =
4434
make0 "tactic"
@@ -49,3 +39,18 @@ let wit_ltac = Gentactic.make "ltac"
4939

5040
let wit_destruction_arg =
5141
make0 "destruction_arg"
42+
43+
module Internal = struct
44+
let defined_tacvalue = ref false
45+
46+
let define_tacvalue (type a) () =
47+
assert (not !defined_tacvalue);
48+
defined_tacvalue := true;
49+
let module M = (struct type tacvalue += V of a end) in
50+
let of_v x = M.V x in
51+
let to_v = function
52+
| M.V x -> x
53+
| _ -> assert false
54+
in
55+
of_v, to_v
56+
end

plugins/ltac/tacarg.mli

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ open Constrexpr
1414
open Genintern
1515
open Tactypes
1616
open Tacexpr
17-
open Names
1817

1918
(** Tactic related witnesses, could also live in tactics/ if other users *)
2019

@@ -43,16 +42,7 @@ val wit_quantified_hypothesis : quantified_hypothesis uniform_genarg_type
4342

4443
(** Generic arguments based on Ltac. *)
4544

46-
(** Abstract application, to print ltac functions *)
47-
type appl =
48-
| UnnamedAppl (** For generic applications: nothing is printed *)
49-
| GlbAppl of (Names.KerName.t * Geninterp.Val.t list) list
50-
(** For calls to global constants, some may alias other. *)
51-
52-
type tacvalue =
53-
| VFun of appl * ltac_trace * Loc.t option * Geninterp.Val.t Id.Map.t *
54-
Name.t list * glob_tactic_expr
55-
| VRec of Geninterp.Val.t Id.Map.t ref * glob_tactic_expr
45+
type tacvalue
5646

5747
val wit_tactic : (raw_tactic_expr, glob_tactic_expr, tacvalue) genarg_type
5848

@@ -68,3 +58,8 @@ val wit_destruction_arg :
6858
glob_constr_and_expr with_bindings Tactics.destruction_arg,
6959
delayed_open_constr_with_bindings Tactics.destruction_arg) genarg_type
7060

61+
module Internal : sig
62+
63+
val define_tacvalue : unit -> ('a -> tacvalue) * (tacvalue -> 'a)
64+
65+
end

plugins/ltac/tacinterp.ml

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ open Ltac_pretype
4242

4343
module TacStore = Tacenv.TacStore
4444

45+
(** Abstract application, to print ltac functions *)
46+
type appl =
47+
| UnnamedAppl (** For generic applications: nothing is printed *)
48+
| GlbAppl of (Names.KerName.t * Geninterp.Val.t list) list
49+
(** For calls to global constants, some may alias other. *)
50+
51+
type tacvalue_v =
52+
| VFun of appl * ltac_trace * Loc.t option * Geninterp.Val.t Id.Map.t *
53+
Name.t list * glob_tactic_expr
54+
| VRec of Geninterp.Val.t Id.Map.t ref * glob_tactic_expr
55+
4556
(* Signature for interpretation: val_interp and interpretation functions *)
4657
type interp_sign = Tacenv.interp_sign =
4758
{ lfun : Geninterp.Val.t Id.Map.t
@@ -138,6 +149,30 @@ let combine_appl appl1 appl2 =
138149
let of_tacvalue = Value.of_tacvalue
139150
let to_tacvalue = Value.to_tacvalue
140151

152+
let (of_tacvalue_v : tacvalue_v -> tacvalue), to_tacvalue_v = Tacarg.Internal.define_tacvalue ()
153+
154+
let pr_tacvalue env v = match to_tacvalue_v v with
155+
| VFun (a,_,loc,ids,l,tac) ->
156+
let open Pp in
157+
let tac = if List.is_empty l then tac else CAst.make ?loc @@ Tacexpr.TacFun (l,tac) in
158+
let pr_env env =
159+
if Id.Map.is_empty ids then mt ()
160+
else
161+
cut () ++ str "where" ++
162+
Id.Map.fold (fun id c pp ->
163+
cut () ++ Id.print id ++ str " := " ++ Pptactic.pr_value Pptactic.ltop c ++ pp)
164+
ids (mt ())
165+
in
166+
v 0 (hov 0 (Pptactic.pr_glob_tactic env tac) ++ pr_env env)
167+
| VRec _ -> str "<tactic closure>"
168+
169+
let () =
170+
Pptactic.Internal.pr_tacvalue_ref := fun env v ->
171+
pr_tacvalue env v
172+
173+
let to_tacvalue_val v = Option.map to_tacvalue_v @@ to_tacvalue v
174+
let of_tacvalue_val v = of_tacvalue @@ of_tacvalue_v v
175+
141176
(* Debug reference *)
142177
let debug = ref DebugOff
143178

@@ -154,9 +189,9 @@ let is_traced () =
154189

155190
(** More naming applications *)
156191
let name_vfun appl vle =
157-
match to_tacvalue vle with
192+
match to_tacvalue_val vle with
158193
| Some (VFun (appl0,trace,loc,lfun,vars,t)) ->
159-
of_tacvalue (VFun (combine_appl appl0 appl,trace,loc,lfun,vars,t))
194+
of_tacvalue_val (VFun (combine_appl appl0 appl,trace,loc,lfun,vars,t))
160195
| Some (VRec _) | None -> vle
161196

162197
let f_avoid_ids : Id.Set.t TacStore.field = TacStore.field "f_avoid_ids"
@@ -261,7 +296,7 @@ let pr_closure env ist body =
261296
let pr_inspect env expr result =
262297
let pp_expr = Pptactic.pr_glob_tactic env expr in
263298
let pp_result =
264-
match to_tacvalue result with
299+
match to_tacvalue_val result with
265300
| Some (VFun (_, _, _, ist, ul, b)) ->
266301
let body = if List.is_empty ul then b else CAst.make (TacFun (ul, b)) in
267302
str "a closure with body " ++ fnl() ++ pr_closure env ist body
@@ -286,7 +321,7 @@ let push_trace call ist =
286321
else [],[]
287322

288323
let propagate_trace ist loc id v =
289-
match to_tacvalue v with
324+
match to_tacvalue_val v with
290325
| None -> Proofview.tclUNIT v
291326
| Some tacv ->
292327
match tacv with
@@ -299,21 +334,21 @@ let propagate_trace ist loc id v =
299334
let t = if List.is_empty it then b else CAst.make (TacFun (it,b)) in
300335
let trace = push_trace(loc,LtacVarCall (kn,id,t)) ist in
301336
let ans = VFun (appl,trace,loc,lfun,it,b) in
302-
Proofview.tclUNIT (of_tacvalue ans)
337+
Proofview.tclUNIT (of_tacvalue_val ans)
303338
| VRec _ -> Proofview.tclUNIT v
304339

305340
let append_trace trace v =
306-
match to_tacvalue v with
307-
| Some (VFun (appl,trace',loc,lfun,it,b)) -> of_tacvalue (VFun (appl,trace',loc,lfun,it,b))
341+
match to_tacvalue_val v with
342+
| Some (VFun (appl,trace',loc,lfun,it,b)) -> of_tacvalue_val (VFun (appl,trace',loc,lfun,it,b))
308343
| _ -> v
309344

310345
(* Dynamically check that an argument is a tactic *)
311346
let coerce_to_tactic loc id v =
312347
let fail () = user_err ?loc
313348
(str "Variable " ++ Id.print id ++ str " should be bound to a tactic.")
314349
in
315-
match to_tacvalue v with
316-
| Some (VFun (appl,trace,_,lfun,it,b)) -> of_tacvalue (VFun (appl,trace,loc,lfun,it,b))
350+
match to_tacvalue_val v with
351+
| Some (VFun (appl,trace,_,lfun,it,b)) -> of_tacvalue_val (VFun (appl,trace,loc,lfun,it,b))
317352
| _ -> fail ()
318353

319354
let intro_pattern_of_ident id = CAst.make @@ IntroNaming (IntroIdentifier id)
@@ -1151,15 +1186,15 @@ let rec val_interp ist ?(appl=UnnamedAppl) (tac:glob_tactic_expr) : Val.t Ftacti
11511186
let value_interp ist =
11521187
match tac2 with
11531188
| TacFun (it, body) ->
1154-
Ftactic.return (of_tacvalue (VFun (UnnamedAppl, extract_trace ist, extract_loc ist, ist.lfun, it, body)))
1189+
Ftactic.return (of_tacvalue_val (VFun (UnnamedAppl, extract_trace ist, extract_loc ist, ist.lfun, it, body)))
11551190
| TacLetIn (true,l,u) -> interp_letrec ist l u
11561191
| TacLetIn (false,l,u) -> interp_letin ist l u
11571192
| TacMatchGoal (lz,lr,lmr) -> interp_match_goal ist lz lr lmr
11581193
| TacMatch (lz,c,lmr) -> interp_match ist lz c lmr
11591194
| TacArg v -> interp_tacarg ist v
11601195
| _ ->
11611196
(* Delayed evaluation *)
1162-
Ftactic.return (of_tacvalue (VFun (UnnamedAppl, extract_trace ist, extract_loc ist, ist.lfun, [], tac)))
1197+
Ftactic.return (of_tacvalue_val (VFun (UnnamedAppl, extract_trace ist, extract_loc ist, ist.lfun, [], tac)))
11631198
in
11641199
let open Ftactic in
11651200
Control.check_for_interrupt ();
@@ -1305,7 +1340,7 @@ and eval_tactic_ist ist tac : unit Proofview.tactic =
13051340
Ftactic.run args tac
13061341

13071342
and force_vrec ist v : Val.t Ftactic.t =
1308-
match to_tacvalue v with
1343+
match to_tacvalue_val v with
13091344
| Some (VRec (lfun,body)) -> val_interp {ist with lfun = !lfun} body
13101345
| _ -> Ftactic.return v
13111346

@@ -1385,7 +1420,7 @@ and interp_tacarg ist arg : Val.t Ftactic.t =
13851420
and interp_app loc ist fv largs : Val.t Ftactic.t =
13861421
Proofview.tclProofInfo [@ocaml.warning "-3"] >>= fun (_name, poly) ->
13871422
let (>>=) = Ftactic.bind in
1388-
match to_tacvalue fv with
1423+
match to_tacvalue_val fv with
13891424
| None | Some (VRec _) -> Tacticals.tclZEROMSG (str "Illegal tactic application.")
13901425
(* if var=[] and body has been delayed by val_interp, then body
13911426
is not a tactic that expects arguments.
@@ -1432,7 +1467,7 @@ and interp_app loc ist fv largs : Val.t Ftactic.t =
14321467
end <*>
14331468
if List.is_empty lval then Ftactic.return v else interp_app loc ist v lval
14341469
else
1435-
Ftactic.return (of_tacvalue (VFun(push_appl appl largs,trace,loc,newlfun,lvar,body)))
1470+
Ftactic.return (of_tacvalue_val (VFun(push_appl appl largs,trace,loc,newlfun,lvar,body)))
14361471
| Some (VFun(appl,trace,_,olfun,[],body)) ->
14371472
let extra_args = List.length largs in
14381473
let info = Exninfo.reify () in
@@ -1454,7 +1489,7 @@ and tactic_of_value ist vle =
14541489
let info = Exninfo.reify () in
14551490
Tacticals.tclZEROMSG ~info (str "Expression does not evaluate to a tactic (got a " ++ str name ++ str ").")
14561491

1457-
and tactic_of_tacvalue ist = function
1492+
and tactic_of_tacvalue ist v = match to_tacvalue_v v with
14581493
| VFun (appl,trace,loc,lfun,[],t) ->
14591494
Proofview.tclProofInfo [@ocaml.warning "-3"] >>= fun (_name, poly) ->
14601495
let ist = {
@@ -1506,7 +1541,7 @@ and interp_letrec ist llc u =
15061541
Proofview.tclUNIT () >>= fun () -> (* delay for the effects of [lref], just in case. *)
15071542
let lref = ref ist.lfun in
15081543
let fold accu ({v=na}, b) =
1509-
let v = of_tacvalue (VRec (lref, CAst.make (TacArg b))) in
1544+
let v = of_tacvalue_val (VRec (lref, CAst.make (TacArg b))) in
15101545
Name.fold_right (fun id -> Id.Map.add id v) na accu
15111546
in
15121547
let lfun = List.fold_left fold ist.lfun llc in
@@ -1536,7 +1571,7 @@ and interp_match_success ist { Tactic_matching.subst ; context ; terms ; lhs } =
15361571
let lfun = extend_values_with_bindings subst (lctxt +++ hyp_subst +++ ist.lfun) in
15371572
let ist = { ist with lfun } in
15381573
val_interp ist lhs >>= fun v ->
1539-
match to_tacvalue v with
1574+
match to_tacvalue_val v with
15401575
| Some (VFun (appl,trace,loc,lfun,[],t)) ->
15411576
let ist =
15421577
{ lfun = lfun
@@ -1547,7 +1582,7 @@ and interp_match_success ist { Tactic_matching.subst ; context ; terms ; lhs } =
15471582
let dummy = VFun (appl, extract_trace ist, loc, Id.Map.empty, [],
15481583
CAst.make (TacId [])) in
15491584
let (stack, _) = trace in
1550-
catch_error_tac stack (tac <*> Ftactic.return (of_tacvalue dummy))
1585+
catch_error_tac stack (tac <*> Ftactic.return (of_tacvalue_val dummy))
15511586
| _ -> Ftactic.return v
15521587

15531588

@@ -2000,7 +2035,7 @@ module Value = struct
20002035
include Taccoerce.Value
20012036

20022037
let closure ist tac =
2003-
VFun (UnnamedAppl, extract_trace ist, None, ist.lfun, [], tac)
2038+
of_tacvalue_v @@ VFun (UnnamedAppl, extract_trace ist, None, ist.lfun, [], tac)
20042039

20052040
let of_closure ist tac =
20062041
let closure = closure ist tac in

0 commit comments

Comments
 (0)