From c7ed001b310583b8087574cd64ab6bed9b321f86 Mon Sep 17 00:00:00 2001
From: Hugo Herbelin
Date: Wed, 8 Apr 2020 09:40:12 +0200
Subject: Small convenient code factorization in constrintern.ml.
No change of semantics.
---
interp/constrintern.ml | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index 45255609e0..75fda5d239 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -341,7 +341,7 @@ let impls_binder_list =
let impls_type_list n ?(args = []) =
let rec aux acc n c = match DAst.get c with
| GProd (na,bk,_,c) -> aux (build_impls n bk na acc) (n+1) c
- | _ -> (Variable,List.rev acc,[])
+ | _ -> List.rev acc
in aux args n
let impls_term_list n ?(args = []) =
@@ -351,7 +351,7 @@ let impls_term_list n ?(args = []) =
let nb = match fix_kind with |GFix (_, n) -> n | GCoFix n -> n in
let n,acc' = List.fold_left (fun (n,acc) (na, bk, _, _) -> (n+1,build_impls n bk na acc)) (n,acc) args.(nb) in
aux acc' n bds.(nb)
- |_ -> (Variable,List.rev acc,[])
+ |_ -> List.rev acc
in aux args n
(* Check if in binder "(x1 x2 .. xn : t)", none of x1 .. xn-1 occurs in t *)
@@ -432,7 +432,7 @@ let push_name_env ntnvars implargs env =
then error_ldots_var ?loc;
set_var_scope ?loc id false (env.tmp_scope,env.scopes) ntnvars;
Dumpglob.dump_binding ?loc id;
- pure_push_name_env (id,implargs) env
+ pure_push_name_env (id,(Variable,implargs,[])) env
let remember_binders_impargs env bl =
List.map_filter (fun (na,_,_,_) ->
@@ -463,7 +463,7 @@ let intern_generalized_binder intern_type ntnvars
let ty' = intern_type {env with ids = ids; unb = true} ty in
let fvs = Implicit_quantifiers.generalizable_vars_of_glob_constr ~bound:ids ~allowed:ids' ty' in
let env' = List.fold_left
- (fun env {loc;v=x} -> push_name_env ntnvars (Variable,[],[])(*?*) env (make ?loc @@ Name x))
+ (fun env {loc;v=x} -> push_name_env ntnvars [](*?*) env (make ?loc @@ Name x))
env fvs in
let b' = check_implicit_meaningful ?loc b' env in
let bl = List.map
@@ -530,7 +530,7 @@ let intern_cases_pattern_as_binder ?loc ntnvars env p =
user_err ?loc (str "Unsupported nested \"as\" clause.");
il,disjpat
in
- let env = List.fold_right (fun {loc;v=id} env -> push_name_env ntnvars (Variable,[],[]) env (make ?loc @@ Name id)) il env in
+ let env = List.fold_right (fun {loc;v=id} env -> push_name_env ntnvars [] env (make ?loc @@ Name id)) il env in
let na = alias_of_pat (List.hd disjpat) in
let ienv = Name.fold_right Id.Set.remove na env.ids in
let id = Namegen.next_name_away_with_default "pat" na ienv in
@@ -586,7 +586,7 @@ let intern_generalization intern env ntnvars loc bk ak c =
GLambda (Name id, bk, DAst.make ?loc:loc' @@ GHole (Evar_kinds.BinderType (Name id), IntroAnonymous, None), acc))
in
List.fold_right (fun ({loc;v=id} as lid) (env, acc) ->
- let env' = push_name_env ntnvars (Variable,[],[]) env CAst.(make @@ Name id) in
+ let env' = push_name_env ntnvars [] env CAst.(make @@ Name id) in
(env', abs lid acc)) fvs (env,c)
in c'
@@ -677,7 +677,7 @@ let traverse_binder intern_pat ntnvars (terms,_,binders,_ as subst) avoid (renam
if onlyident then
(* Do not try to interpret a variable as a constructor *)
let na = out_patvar pat in
- let env = push_name_env ntnvars (Variable,[],[]) env (make ?loc:pat.loc na) in
+ let env = push_name_env ntnvars [] env (make ?loc:pat.loc na) in
(renaming,env), None, na
else
(* Interpret as a pattern *)
@@ -2084,7 +2084,7 @@ let internalize globalenv env pattern_mode (_, ntnvars as lvar) c =
List.rev_append match_td matchs)
tms ([],Id.Set.empty,Id.Map.empty,[]) in
let env' = Id.Set.fold
- (fun var bli -> push_name_env ntnvars (Variable,[],[]) bli (CAst.make @@ Name var))
+ (fun var bli -> push_name_env ntnvars [] bli (CAst.make @@ Name var))
(Id.Set.union ex_ids as_in_vars)
(restart_lambda_binders env)
in
@@ -2122,17 +2122,17 @@ let internalize globalenv env pattern_mode (_, ntnvars as lvar) c =
(* "in" is None so no match to add *)
let ((b',(na',_)),_,_) = intern_case_item env' Id.Set.empty (b,na,None) in
let p' = Option.map (fun u ->
- let env'' = push_name_env ntnvars (Variable,[],[]) env'
+ let env'' = push_name_env ntnvars [] env'
(CAst.make na') in
intern_type (slide_binders env'') u) po in
DAst.make ?loc @@
GLetTuple (List.map (fun { CAst.v } -> v) nal, (na', p'), b',
- intern (List.fold_left (push_name_env ntnvars (Variable,[],[])) env nal) c)
+ intern (List.fold_left (push_name_env ntnvars []) env nal) c)
| CIf (c, (na,po), b1, b2) ->
let env' = reset_tmp_scope env in
let ((c',(na',_)),_,_) = intern_case_item env' Id.Set.empty (c,na,None) in (* no "in" no match to ad too *)
let p' = Option.map (fun p ->
- let env'' = push_name_env ntnvars (Variable,[],[]) env
+ let env'' = push_name_env ntnvars [] env
(CAst.make na') in
intern_type (slide_binders env'') p) po in
DAst.make ?loc @@
--
cgit v1.2.3
From 79ccbe6b2b73409d7ce5e0e5797320b6e2fd0dd2 Mon Sep 17 00:00:00 2001
From: Hugo Herbelin
Date: Wed, 8 Apr 2020 09:57:27 +0200
Subject: Making type interning_data abstract in constrintern.ml.
---
interp/constrintern.ml | 3 +++
interp/constrintern.mli | 16 +++++++++-------
vernac/comProgramFixpoint.ml | 7 ++++---
3 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index 75fda5d239..7431058849 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -186,6 +186,9 @@ let compute_internalization_env env sigma ?(impls=empty_internalization_env) ty
(fun map id typ impl -> Id.Map.add id (compute_internalization_data env sigma ty typ impl) map)
impls
+let extend_internalization_data (r, impls, scopes) impl scope =
+ (r, impls@[impl], scopes@[scope])
+
(**********************************************************************)
(* Contracting "{ _ }" in notations *)
diff --git a/interp/constrintern.mli b/interp/constrintern.mli
index 9f06f16258..efbe7ec910 100644
--- a/interp/constrintern.mli
+++ b/interp/constrintern.mli
@@ -43,13 +43,12 @@ type var_internalization_type =
| Method
| Variable
-type var_internalization_data =
- var_internalization_type *
- (* type of the "free" variable, for coqdoc, e.g. while typing the
- constructor of JMeq, "JMeq" behaves as a variable of type Inductive *)
-
- Impargs.implicit_status list * (* signature of impargs of the variable *)
- Notation_term.scope_name option list (* subscopes of the args of the variable *)
+(** This collects relevant information for interning local variables:
+ - their coqdoc kind (a recursive call in a inductive, fixpoint of class; or a bound variable)
+ e.g. while typing the constructor of JMeq, "JMeq" behaves as a variable of type Inductive
+ - their implicit arguments
+ - their argument scopes *)
+type var_internalization_data
(** A map of free variables to their implicit arguments and scopes *)
type internalization_env = var_internalization_data Id.Map.t
@@ -63,6 +62,9 @@ val compute_internalization_env : env -> evar_map -> ?impls:internalization_env
Id.t list -> types list -> Impargs.manual_implicits list ->
internalization_env
+val extend_internalization_data :
+ var_internalization_data -> Impargs.implicit_status -> scope_name option -> var_internalization_data
+
type ltac_sign = {
ltac_vars : Id.Set.t;
(** Variables of Ltac which may be bound to a term *)
diff --git a/vernac/comProgramFixpoint.ml b/vernac/comProgramFixpoint.ml
index 80e7e6ab96..5b29ab2092 100644
--- a/vernac/comProgramFixpoint.ml
+++ b/vernac/comProgramFixpoint.ml
@@ -195,13 +195,14 @@ let build_wellfounded (recname,pl,bl,arityc,body) poly r measure notation =
let lift_lets = lift_rel_context 1 letbinders in
let sigma, intern_body =
let ctx = LocalAssum (make_annot (Name recname) Sorts.Relevant, get_type curry_fun) :: binders_rel in
- let (r, impls, scopes) =
+ let interning_data =
Constrintern.compute_internalization_data env sigma
Constrintern.Recursive full_arity impls
in
let newimpls = Id.Map.singleton recname
- (r, impls @ [Some (ExplByName (Id.of_string "recproof"), Impargs.Manual, (true, false))],
- scopes @ [None]) in
+ (Constrintern.extend_internalization_data interning_data
+ (Some (ExplByName (Id.of_string "recproof"), Impargs.Manual, (true, false)))
+ None) in
interp_casted_constr_evars ~program_mode:true (push_rel_context ctx env) sigma
~impls:newimpls body (lift 1 top_arity)
in
--
cgit v1.2.3
From 3f2742b2c3fd48706d4bfd8bffdd4ae07a338bbd Mon Sep 17 00:00:00 2001
From: Hugo Herbelin
Date: Mon, 6 Apr 2020 10:04:42 +0200
Subject: Coqdoc: Exporting location and unique id for binding variables.
This provides linking, appropriate coloring and appropriate hovering
in coqdoc documents.
In particular, this fixes #7697.
---
interp/constrintern.ml | 29 +++++++++++++++++---------
interp/constrintern.mli | 2 +-
interp/dumpglob.ml | 5 +++--
interp/dumpglob.mli | 2 +-
plugins/funind/gen_principle.ml | 2 +-
test-suite/coqdoc/binder.html.out | 41 +++++++++++++++++++++++++++++++++++++
test-suite/coqdoc/binder.tex.out | 28 +++++++++++++++++++++++++
test-suite/coqdoc/binder.v | 3 +++
test-suite/coqdoc/bug11353.html.out | 6 +++---
test-suite/coqdoc/bug11353.tex.out | 6 +++---
test-suite/coqdoc/bug5648.html.out | 4 ++--
test-suite/coqdoc/bug5648.tex.out | 4 ++--
test-suite/coqdoc/links.html.out | 12 +++++------
test-suite/coqdoc/links.tex.out | 12 +++++------
tools/coqdoc/coqdoc.css | 4 ++++
tools/coqdoc/coqdoc.sty | 1 +
tools/coqdoc/index.ml | 3 +++
tools/coqdoc/index.mli | 1 +
tools/coqdoc/output.ml | 8 +++-----
vernac/comAssumption.ml | 2 +-
vernac/comProgramFixpoint.ml | 2 +-
vernac/record.ml | 2 +-
22 files changed, 134 insertions(+), 45 deletions(-)
create mode 100644 test-suite/coqdoc/binder.html.out
create mode 100644 test-suite/coqdoc/binder.tex.out
create mode 100644 test-suite/coqdoc/binder.v
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index 7431058849..b72802d911 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -53,6 +53,12 @@ type var_internalization_type =
| Method
| Variable
+type var_unique_id = string
+
+let var_uid =
+ let count = ref 0 in
+ fun id -> incr count; Id.to_string id ^ ":" ^ string_of_int !count
+
type var_internalization_data =
(* type of the "free" variable, for coqdoc, e.g. while typing the
constructor of JMeq, "JMeq" behaves as a variable of type Inductive *)
@@ -60,7 +66,9 @@ type var_internalization_data =
(* signature of impargs of the variable *)
Impargs.implicit_status list *
(* subscopes of the args of the variable *)
- scope_name option list
+ scope_name option list *
+ (* unique ID for coqdoc links *)
+ var_unique_id
type internalization_env =
(var_internalization_data) Id.Map.t
@@ -177,17 +185,17 @@ let parsing_explicit = ref false
let empty_internalization_env = Id.Map.empty
-let compute_internalization_data env sigma ty typ impl =
+let compute_internalization_data env sigma id ty typ impl =
let impl = compute_implicits_with_manual env sigma typ (is_implicit_args()) impl in
- (ty, impl, compute_arguments_scope sigma typ)
+ (ty, impl, compute_arguments_scope sigma typ, var_uid id)
let compute_internalization_env env sigma ?(impls=empty_internalization_env) ty =
List.fold_left3
- (fun map id typ impl -> Id.Map.add id (compute_internalization_data env sigma ty typ impl) map)
+ (fun map id typ impl -> Id.Map.add id (compute_internalization_data env sigma id ty typ impl) map)
impls
-let extend_internalization_data (r, impls, scopes) impl scope =
- (r, impls@[impl], scopes@[scope])
+let extend_internalization_data (r, impls, scopes, uid) impl scope =
+ (r, impls@[impl], scopes@[scope], uid)
(**********************************************************************)
(* Contracting "{ _ }" in notations *)
@@ -434,8 +442,9 @@ let push_name_env ntnvars implargs env =
if Id.Map.is_empty ntnvars && Id.equal id ldots_var
then error_ldots_var ?loc;
set_var_scope ?loc id false (env.tmp_scope,env.scopes) ntnvars;
- Dumpglob.dump_binding ?loc id;
- pure_push_name_env (id,(Variable,implargs,[])) env
+ let uid = var_uid id in
+ Dumpglob.dump_binding ?loc uid;
+ pure_push_name_env (id,(Variable,implargs,[],uid)) env
let remember_binders_impargs env bl =
List.map_filter (fun (na,_,_,_) ->
@@ -1007,9 +1016,9 @@ let intern_var env (ltacvars,ntnvars) namedctx loc id us =
else
(* Is [id] registered with implicit arguments *)
try
- let ty,impls,argsc = Id.Map.find id env.impls in
+ let ty,impls,argsc,uid = Id.Map.find id env.impls in
let tys = string_of_ty ty in
- Dumpglob.dump_reference ?loc "<>" (Id.to_string id) tys;
+ Dumpglob.dump_reference ?loc "<>" uid tys;
gvar (loc,id) us, make_implicits_list impls, argsc
with Not_found ->
(* Is [id] bound in current term or is an ltac var bound to constr *)
diff --git a/interp/constrintern.mli b/interp/constrintern.mli
index efbe7ec910..2eb96aad56 100644
--- a/interp/constrintern.mli
+++ b/interp/constrintern.mli
@@ -55,7 +55,7 @@ type internalization_env = var_internalization_data Id.Map.t
val empty_internalization_env : internalization_env
-val compute_internalization_data : env -> evar_map -> var_internalization_type ->
+val compute_internalization_data : env -> evar_map -> Id.t -> var_internalization_type ->
types -> Impargs.manual_implicits -> var_internalization_data
val compute_internalization_env : env -> evar_map -> ?impls:internalization_env -> var_internalization_type ->
diff --git a/interp/dumpglob.ml b/interp/dumpglob.ml
index e659a5ac5c..57ec708b07 100644
--- a/interp/dumpglob.ml
+++ b/interp/dumpglob.ml
@@ -246,8 +246,6 @@ let add_glob_kn ?loc kn =
let lib_dp = Lib.dp_of_mp (mp_of_kn kn) in
add_glob_gen ?loc sp lib_dp "syndef"
-let dump_binding ?loc id = ()
-
let dump_def ?loc ty secpath id = Option.iter (fun loc ->
if !glob_output = Feedback then
Feedback.feedback (Feedback.GlobDef (loc, id, secpath, ty))
@@ -275,3 +273,6 @@ let dump_notation (loc,(df,_)) sc sec = Option.iter (fun loc ->
let location = (Loc.make_loc (i, i+1)) in
dump_def ~loc:location "not" (Names.DirPath.to_string (Lib.current_dirpath sec)) (cook_notation df sc)
) loc
+
+let dump_binding ?loc uid =
+ dump_def ?loc "binder" "<>" uid
diff --git a/interp/dumpglob.mli b/interp/dumpglob.mli
index 5409b20472..14e5a81308 100644
--- a/interp/dumpglob.mli
+++ b/interp/dumpglob.mli
@@ -36,7 +36,7 @@ val dump_secvar : ?loc:Loc.t -> Names.Id.t -> unit
val dump_libref : ?loc:Loc.t -> Names.DirPath.t -> string -> unit
val dump_notation_location : (int * int) list -> Constrexpr.notation ->
(Notation.notation_location * Notation_term.scope_name option) -> unit
-val dump_binding : ?loc:Loc.t -> Names.Id.Set.elt -> unit
+val dump_binding : ?loc:Loc.t -> string -> unit
val dump_notation :
(Constrexpr.notation * Notation.notation_location) Loc.located ->
Notation_term.scope_name option -> bool -> unit
diff --git a/plugins/funind/gen_principle.ml b/plugins/funind/gen_principle.ml
index df147b3aa6..7626d6dbad 100644
--- a/plugins/funind/gen_principle.ml
+++ b/plugins/funind/gen_principle.ml
@@ -46,7 +46,7 @@ let build_newrecursive lnameargsardef =
Constrintern.interp_context_evars ~program_mode:false env evd binders
in
let impl =
- Constrintern.compute_internalization_data env0 evd
+ Constrintern.compute_internalization_data env0 evd recname
Constrintern.Recursive arity impls'
in
let open Context.Named.Declaration in
diff --git a/test-suite/coqdoc/binder.html.out b/test-suite/coqdoc/binder.html.out
new file mode 100644
index 0000000000..a8ec7ae033
--- /dev/null
+++ b/test-suite/coqdoc/binder.html.out
@@ -0,0 +1,41 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test-suite/coqdoc/binder.tex.out b/test-suite/coqdoc/binder.tex.out
new file mode 100644
index 0000000000..2b5648aee6
--- /dev/null
+++ b/test-suite/coqdoc/binder.tex.out
@@ -0,0 +1,28 @@
+\documentclass[12pt]{report}
+\usepackage[utf8x]{inputenc}
+
+%Warning: tipa declares many non-standard macros used by utf8x to
+%interpret utf8 characters but extra packages might have to be added
+%such as "textgreek" for Greek letters not already in tipa
+%or "stmaryrd" for mathematical symbols.
+%Utf8 codes missing a LaTeX interpretation can be defined by using
+%\DeclareUnicodeCharacter{code}{interpretation}.
+%Use coqdoc's option -p to add new packages or declarations.
+\usepackage{tipa}
+
+\usepackage[T1]{fontenc}
+\usepackage{fullpage}
+\usepackage{coqdoc}
+\usepackage{amsmath,amssymb}
+\usepackage{url}
+\begin{document}
+\coqlibrary{Coqdoc.binder}{Library }{Coqdoc.binder}
+
+\begin{coqdoccode}
+\end{coqdoccode}
+Link binders \begin{coqdoccode}
+\coqdocemptyline
+\coqdocnoindent
+\coqdockw{Definition} \coqdef{Coqdoc.binder.foo}{foo}{\coqdocdefinition{foo}} \coqdef{Coqdoc.binder.alpha:1}{alpha}{\coqdocbinder{alpha}} \coqdef{Coqdoc.binder.beta:2}{beta}{\coqdocbinder{beta}} := \coqref{Coqdoc.binder.alpha:1}{\coqdocvariable{alpha}} \coqexternalref{::nat scope:x '+' x}{http://coq.inria.fr/stdlib/Coq.Init.Peano}{\coqdocnotation{+}} \coqref{Coqdoc.binder.beta:2}{\coqdocvariable{beta}}.\coqdoceol
+\end{coqdoccode}
+\end{document}
diff --git a/test-suite/coqdoc/binder.v b/test-suite/coqdoc/binder.v
new file mode 100644
index 0000000000..283ef64ac5
--- /dev/null
+++ b/test-suite/coqdoc/binder.v
@@ -0,0 +1,3 @@
+(** Link binders *)
+
+Definition foo alpha beta := alpha + beta.
diff --git a/test-suite/coqdoc/bug11353.html.out b/test-suite/coqdoc/bug11353.html.out
index 0b4b4b6e37..7a1de45e6e 100644
--- a/test-suite/coqdoc/bug11353.html.out
+++ b/test-suite/coqdoc/bug11353.html.out
@@ -20,9 +20,9 @@