~ubuntu-branches/ubuntu/wily/coq-doc/wily

« back to all changes in this revision

Viewing changes to pretyping/clenv.ml

  • Committer: Bazaar Package Importer
  • Author(s): Stéphane Glondu, Stéphane Glondu, Samuel Mimram
  • Date: 2010-01-07 22:50:39 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100107225039-n3cq82589u0qt0s2
Tags: 8.2pl1-1
[ Stéphane Glondu ]
* New upstream release (Closes: #563669)
  - remove patches
* Packaging overhaul:
  - use git, advertise it in Vcs-* fields of debian/control
  - use debhelper 7 and dh with override
  - use source format 3.0 (quilt)
* debian/control:
  - set Maintainer to d-o-m, set Uploaders to Sam and myself
  - add Homepage field
  - bump Standards-Version to 3.8.3
* Register PDF documentation into doc-base
* Add debian/watch
* Update debian/copyright

[ Samuel Mimram ]
* Change coq-doc's description to mention that it provides documentation in
  pdf format, not postscript, closes: #543545.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
(************************************************************************)
 
2
(*  v      *   The Coq Proof Assistant  /  The Coq Development Team     *)
 
3
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
 
4
(*   \VV/  **************************************************************)
 
5
(*    //   *      This file is distributed under the terms of the       *)
 
6
(*         *       GNU Lesser General Public License Version 2.1        *)
 
7
(************************************************************************)
 
8
 
 
9
(* $Id: clenv.ml 11897 2009-02-09 19:28:02Z barras $ *)
 
10
 
 
11
open Pp
 
12
open Util
 
13
open Names
 
14
open Nameops
 
15
open Term
 
16
open Termops
 
17
open Sign
 
18
open Environ
 
19
open Evd
 
20
open Reduction
 
21
open Reductionops
 
22
open Rawterm
 
23
open Pattern
 
24
open Tacred
 
25
open Pretype_errors
 
26
open Evarutil
 
27
open Unification
 
28
open Mod_subst
 
29
open Coercion.Default
 
30
 
 
31
(* Abbreviations *)
 
32
 
 
33
let pf_env gls = Global.env_of_context gls.it.evar_hyps
 
34
let pf_type_of gls c  = Typing.type_of (pf_env gls) gls.sigma c
 
35
let pf_hnf_constr gls c = hnf_constr (pf_env gls) gls.sigma c
 
36
let pf_concl gl = gl.it.evar_concl
 
37
 
 
38
(******************************************************************)
 
39
(* Clausal environments *)
 
40
 
 
41
type clausenv = {
 
42
  env      : env;
 
43
  evd      : evar_defs;
 
44
  templval : constr freelisted;
 
45
  templtyp : constr freelisted }
 
46
 
 
47
let cl_env ce = ce.env
 
48
let cl_sigma ce = evars_of ce.evd
 
49
 
 
50
let subst_clenv sub clenv = 
 
51
  { templval = map_fl (subst_mps sub) clenv.templval;
 
52
    templtyp = map_fl (subst_mps sub) clenv.templtyp;
 
53
    evd = subst_evar_defs_light sub clenv.evd;
 
54
    env = clenv.env }
 
55
 
 
56
let clenv_nf_meta clenv c = nf_meta clenv.evd c
 
57
let clenv_term clenv c = meta_instance clenv.evd c
 
58
let clenv_meta_type clenv mv = Typing.meta_type clenv.evd mv
 
59
let clenv_value clenv = meta_instance clenv.evd clenv.templval
 
60
let clenv_type clenv = meta_instance clenv.evd clenv.templtyp
 
61
 
 
62
 
 
63
let clenv_hnf_constr ce t = hnf_constr (cl_env ce) (cl_sigma ce) t
 
64
 
 
65
let clenv_get_type_of ce c =
 
66
  Retyping.get_type_of_with_meta (cl_env ce) (cl_sigma ce) (metas_of ce.evd) c
 
67
 
 
68
exception NotExtensibleClause
 
69
 
 
70
let clenv_push_prod cl =
 
71
  let typ = whd_betadeltaiota (cl_env cl) (cl_sigma cl) (clenv_type cl) in
 
72
  let rec clrec typ = match kind_of_term typ with
 
73
    | Cast (t,_,_) -> clrec t
 
74
    | Prod (na,t,u) ->
 
75
        let mv = new_meta () in
 
76
        let dep = dependent (mkRel 1) u in
 
77
        let na' = if dep then na else Anonymous in
 
78
        let e' = meta_declare mv t ~name:na' cl.evd in
 
79
        let concl = if dep then subst1 (mkMeta mv) u else u in
 
80
        let def = applist (cl.templval.rebus,[mkMeta mv]) in
 
81
        { templval = mk_freelisted def;
 
82
          templtyp = mk_freelisted concl;
 
83
          evd = e';
 
84
          env = cl.env }
 
85
    | _ -> raise NotExtensibleClause
 
86
  in clrec typ
 
87
 
 
88
(* Instantiate the first [bound] products of [t] with metas (all products if
 
89
   [bound] is [None]; unfold local defs *)
 
90
 
 
91
let clenv_environments evd bound t =
 
92
  let rec clrec (e,metas) n t =
 
93
    match n, kind_of_term t with
 
94
      | (Some 0, _) -> (e, List.rev metas, t)
 
95
      | (n, Cast (t,_,_)) -> clrec (e,metas) n t
 
96
      | (n, Prod (na,t1,t2)) ->
 
97
          let mv = new_meta () in
 
98
          let dep = dependent (mkRel 1) t2 in
 
99
          let na' = if dep then na else Anonymous in
 
100
          let e' = meta_declare mv t1 ~name:na' e in
 
101
          clrec (e', (mkMeta mv)::metas) (Option.map ((+) (-1)) n)
 
102
            (if dep then (subst1 (mkMeta mv) t2) else t2)
 
103
      | (n, LetIn (na,b,_,t)) -> clrec (e,metas) n (subst1 b t)
 
104
      | (n, _) -> (e, List.rev metas, t)
 
105
  in 
 
106
  clrec (evd,[]) bound t
 
107
 
 
108
(* Instantiate the first [bound] products of [t] with evars (all products if
 
109
   [bound] is [None]; unfold local defs *)
 
110
 
 
111
let clenv_environments_evars env evd bound t =
 
112
  let rec clrec (e,ts) n t =
 
113
    match n, kind_of_term t with
 
114
      | (Some 0, _) -> (e, List.rev ts, t)
 
115
      | (n, Cast (t,_,_)) -> clrec (e,ts) n t
 
116
      | (n, Prod (na,t1,t2)) ->
 
117
          let e',constr = Evarutil.new_evar e env t1 in
 
118
          let dep = dependent (mkRel 1) t2 in
 
119
          clrec (e', constr::ts) (Option.map ((+) (-1)) n)
 
120
            (if dep then (subst1 constr t2) else t2)
 
121
      | (n, LetIn (na,b,_,t)) -> clrec (e,ts) n (subst1 b t)
 
122
      | (n, _) -> (e, List.rev ts, t)
 
123
  in 
 
124
  clrec (evd,[]) bound t
 
125
 
 
126
let clenv_conv_leq env sigma t c bound =
 
127
  let ty = Retyping.get_type_of env sigma c in
 
128
  let evd = Evd.create_goal_evar_defs sigma in
 
129
  let evars,args,_ = clenv_environments_evars env evd (Some bound) ty in
 
130
  let evars = Evarconv.the_conv_x_leq env t (applist (c,args)) evars in
 
131
  let evars,_ = Evarconv.consider_remaining_unif_problems env evars in
 
132
  let args = List.map (whd_evar (Evd.evars_of evars)) args in
 
133
  check_evars env sigma evars (applist (c,args));
 
134
  args
 
135
 
 
136
let mk_clenv_from_env environ sigma n (c,cty) =
 
137
  let evd = create_goal_evar_defs sigma in
 
138
  let (env,args,concl) = clenv_environments evd n cty in
 
139
  { templval = mk_freelisted (match args with [] -> c | _ -> applist (c,args));
 
140
    templtyp = mk_freelisted concl;
 
141
    evd = env;
 
142
    env = environ }
 
143
 
 
144
let mk_clenv_from_n gls n (c,cty) =
 
145
  mk_clenv_from_env (Global.env_of_context gls.it.evar_hyps) gls.sigma n (c, cty)
 
146
 
 
147
let mk_clenv_from gls = mk_clenv_from_n gls None
 
148
 
 
149
let mk_clenv_rename_from_n gls n (c,t) = 
 
150
  mk_clenv_from_n gls n (c,rename_bound_var (pf_env gls) [] t)
 
151
 
 
152
let mk_clenv_type_of gls t = mk_clenv_from gls (t,pf_type_of gls t)
 
153
 
 
154
(******************************************************************)
 
155
 
 
156
(* [mentions clenv mv0 mv1] is true if mv1 is defined and mentions
 
157
 * mv0, or if one of the free vars on mv1's freelist mentions
 
158
 * mv0 *)
 
159
 
 
160
let mentions clenv mv0 =
 
161
  let rec menrec mv1 =
 
162
    mv0 = mv1 ||
 
163
    let mlist =
 
164
      try match meta_opt_fvalue clenv.evd mv1 with
 
165
      | Some (b,_) -> b.freemetas
 
166
      | None -> Metaset.empty
 
167
      with Not_found -> Metaset.empty in
 
168
    meta_exists menrec mlist
 
169
  in menrec
 
170
 
 
171
let clenv_defined clenv mv = meta_defined clenv.evd mv
 
172
 
 
173
let error_incompatible_inst clenv mv  =
 
174
  let na = meta_name clenv.evd mv in
 
175
  match na with
 
176
      Name id ->
 
177
        errorlabstrm "clenv_assign"
 
178
          (str "An incompatible instantiation has already been found for " ++ 
 
179
           pr_id id)
 
180
    | _ ->
 
181
        anomaly "clenv_assign: non dependent metavar already assigned"
 
182
 
 
183
(* TODO: replace by clenv_unify (mkMeta mv) rhs ? *)                  
 
184
let clenv_assign mv rhs clenv =
 
185
  let rhs_fls = mk_freelisted rhs in 
 
186
  if meta_exists (mentions clenv mv) rhs_fls.freemetas then
 
187
    error "clenv_assign: circularity in unification";
 
188
  try
 
189
    if meta_defined clenv.evd mv then
 
190
      if not (eq_constr (fst (meta_fvalue clenv.evd mv)).rebus rhs) then
 
191
        error_incompatible_inst clenv mv
 
192
      else
 
193
        clenv
 
194
    else 
 
195
      let st = (ConvUpToEta 0,TypeNotProcessed) in
 
196
      {clenv with evd = meta_assign mv (rhs_fls.rebus,st) clenv.evd}
 
197
  with Not_found -> 
 
198
    error "clenv_assign: undefined meta"
 
199
 
 
200
 
 
201
let clenv_wtactic f clenv = {clenv with evd = f clenv.evd }
 
202
 
 
203
 
 
204
(* [clenv_dependent hyps_only clenv]
 
205
 * returns a list of the metavars which appear in the template of clenv,
 
206
 * and which are dependent, This is computed by taking the metavars in cval,
 
207
 * in right-to-left order, and collecting the metavars which appear
 
208
 * in their types, and adding in all the metavars appearing in the
 
209
 * type of clenv.
 
210
 * If [hyps_only] then metavariables occurring in the type are _excluded_ *)
 
211
 
 
212
(* [clenv_metavars clenv mv]
 
213
 * returns a list of the metavars which appear in the type of
 
214
 * the metavar mv.  The list is unordered. *)
 
215
 
 
216
let clenv_metavars evd mv =
 
217
  (mk_freelisted (meta_instance evd (meta_ftype evd mv))).freemetas
 
218
 
 
219
let dependent_metas clenv mvs conclmetas =
 
220
  List.fold_right
 
221
    (fun mv deps ->
 
222
       Metaset.union deps (clenv_metavars clenv.evd mv))
 
223
    mvs conclmetas
 
224
 
 
225
let duplicated_metas c = 
 
226
  let rec collrec (one,more as acc) c =
 
227
    match kind_of_term c with
 
228
    | Meta mv -> if List.mem mv one then (one,mv::more) else (mv::one,more)
 
229
    | _       -> fold_constr collrec acc c
 
230
  in
 
231
  snd (collrec ([],[]) c)
 
232
 
 
233
let clenv_dependent hyps_only clenv =
 
234
  let mvs = undefined_metas clenv.evd in
 
235
  let ctyp_mvs = (mk_freelisted (clenv_type clenv)).freemetas in
 
236
  let deps = dependent_metas clenv mvs ctyp_mvs in
 
237
  let nonlinear = duplicated_metas (clenv_value clenv) in
 
238
  (* Make the assumption that duplicated metas have internal dependencies *)
 
239
  List.filter
 
240
    (fun mv -> (Metaset.mem mv deps &&
 
241
                not (hyps_only && Metaset.mem mv ctyp_mvs))
 
242
               or List.mem mv nonlinear) 
 
243
    mvs
 
244
 
 
245
let clenv_missing ce = clenv_dependent true ce
 
246
 
 
247
(******************************************************************)
 
248
 
 
249
let clenv_unify allow_K ?(flags=default_unify_flags) cv_pb t1 t2 clenv =
 
250
  { clenv with
 
251
      evd = w_unify allow_K ~flags:flags clenv.env cv_pb t1 t2 clenv.evd }
 
252
 
 
253
let clenv_unify_meta_types ?(flags=default_unify_flags) clenv =
 
254
  { clenv with evd = w_unify_meta_types ~flags:flags clenv.env clenv.evd }
 
255
 
 
256
let clenv_unique_resolver allow_K ?(flags=default_unify_flags) clenv gl =
 
257
  if isMeta (fst (whd_stack (evars_of clenv.evd) clenv.templtyp.rebus)) then
 
258
    clenv_unify allow_K CUMUL ~flags:flags (clenv_type clenv) (pf_concl gl)
 
259
      (clenv_unify_meta_types ~flags:flags clenv)
 
260
  else
 
261
    clenv_unify allow_K CUMUL ~flags:flags
 
262
      (meta_reducible_instance clenv.evd clenv.templtyp) (pf_concl gl) clenv
 
263
 
 
264
(* [clenv_pose_metas_as_evars clenv dep_mvs]
 
265
 * For each dependent evar in the clause-env which does not have a value,
 
266
 * pose a value for it by constructing a fresh evar.  We do this in
 
267
 * left-to-right order, so that every evar's type is always closed w.r.t.
 
268
 * metas. 
 
269
 
 
270
 * Node added 14/4/08 [HH]: before this date, evars were collected in
 
271
   clenv_dependent by collect_metas in the fold_constr order which is
 
272
   (almost) the left-to-right order of dependencies in term. However,
 
273
   due to K-redexes, collect_metas was sometimes missing some metas.
 
274
   The call to collect_metas has been replaced by a call to
 
275
   undefined_metas, but then the order was the one of definition of
 
276
   the metas (numbers in increasing order) which is _not_ the
 
277
   dependency order when a clenv_fchain occurs (because clenv_fchain
 
278
   plugs a term with a list of consecutive metas in place of a - a priori -
 
279
   arbitrary metavariable belonging to another sequence of consecutive metas:
 
280
   e.g., clenv_fchain may plug (H ?1 ?2) at the position ?6 of 
 
281
   (nat_ind ?3 ?4 ?5 ?6), leading to a dependency order 3<4<5<1<2).
 
282
   To ensure the dependency order, we check that the type of each meta
 
283
   to pose is already meta-free, otherwise we postpone the transformation,
 
284
   hoping that no cycle may happen.
 
285
 
 
286
   Another approach could have been to use decimal numbers for metas so that
 
287
   in the example above, (H ?1 ?2) would have been renumbered (H ?6.1 ?6.2)
 
288
   then making the numeric order match the dependency order.
 
289
*)
 
290
 
 
291
let clenv_pose_metas_as_evars clenv dep_mvs =
 
292
  let rec fold clenv = function
 
293
  | [] -> clenv
 
294
  | mv::mvs -> 
 
295
      let ty = clenv_meta_type clenv mv in
 
296
      (* Postpone the evar-ization if dependent on another meta *)
 
297
      (* This assumes no cycle in the dependencies - is it correct ? *)
 
298
      if occur_meta ty then fold clenv (mvs@[mv])
 
299
      else
 
300
        let (evd,evar) = 
 
301
          new_evar clenv.evd (cl_env clenv) ~src:(dummy_loc,GoalEvar) ty in
 
302
        let clenv = clenv_assign mv evar {clenv with evd=evd} in
 
303
        fold clenv mvs in
 
304
  fold clenv dep_mvs
 
305
 
 
306
let evar_clenv_unique_resolver = clenv_unique_resolver
 
307
 
 
308
(******************************************************************)
 
309
 
 
310
let connect_clenv gls clenv =
 
311
  { clenv with
 
312
    evd = evars_reset_evd gls.sigma clenv.evd;
 
313
    env = Global.env_of_context gls.it.evar_hyps }
 
314
 
 
315
(* [clenv_fchain mv clenv clenv']
 
316
 *
 
317
 * Resolves the value of "mv" (which must be undefined) in clenv to be
 
318
 * the template of clenv' be the value "c", applied to "n" fresh
 
319
 * metavars, whose types are chosen by destructing "clf", which should
 
320
 * be a clausale forme generated from the type of "c".  The process of
 
321
 * resolution can cause unification of already-existing metavars, and
 
322
 * of the fresh ones which get created.  This operation is a composite
 
323
 * of operations which pose new metavars, perform unification on
 
324
 * terms, and make bindings. 
 
325
 
 
326
   Otherwise said, from 
 
327
 
 
328
     [clenv] = [env;sigma;metas |- c:T]
 
329
     [clenv'] = [env';sigma';metas' |- d:U]
 
330
     [mv] = [mi] of type [Ti] in [metas]
 
331
 
 
332
   then, if the unification of [Ti] and [U] produces map [rho], the
 
333
   chaining is [env';sigma';rho'(metas),rho(metas') |- c:rho'(T)] for
 
334
   [rho'] being [rho;mi:=d].
 
335
 
 
336
   In particular, it assumes that [env'] and [sigma'] extend [env] and [sigma].
 
337
*)
 
338
let clenv_fchain ?(allow_K=true) ?(flags=default_unify_flags) mv clenv nextclenv =
 
339
  (* Add the metavars of [nextclenv] to [clenv], with their name-environment *)
 
340
  let clenv' =
 
341
    { templval = clenv.templval;
 
342
      templtyp = clenv.templtyp;
 
343
      evd = 
 
344
        evar_merge (meta_merge clenv.evd nextclenv.evd) (evars_of clenv.evd);
 
345
      env = nextclenv.env } in
 
346
  (* unify the type of the template of [nextclenv] with the type of [mv] *)
 
347
  let clenv'' =
 
348
    clenv_unify allow_K ~flags:flags CUMUL
 
349
      (clenv_term clenv' nextclenv.templtyp)
 
350
      (clenv_meta_type clenv' mv)
 
351
      clenv' in
 
352
  (* assign the metavar *)
 
353
  let clenv''' =
 
354
    clenv_assign mv (clenv_term clenv' nextclenv.templval) clenv''
 
355
  in 
 
356
  clenv'''
 
357
 
 
358
(***************************************************************)
 
359
(* Bindings *)
 
360
 
 
361
type arg_bindings = open_constr explicit_bindings
 
362
 
 
363
(* [clenv_independent clenv]
 
364
 * returns a list of metavariables which appear in the term cval,
 
365
 * and which are not dependent.  That is, they do not appear in
 
366
 * the types of other metavars which are in cval, nor in the type
 
367
 * of cval, ctyp. *)
 
368
 
 
369
let clenv_independent clenv =
 
370
  let mvs = collect_metas (clenv_value clenv) in
 
371
  let ctyp_mvs = (mk_freelisted (clenv_type clenv)).freemetas in
 
372
  let deps = dependent_metas clenv mvs ctyp_mvs in
 
373
  List.filter (fun mv -> not (Metaset.mem mv deps)) mvs
 
374
 
 
375
let check_bindings bl =
 
376
  match list_duplicates (List.map pi2 bl) with
 
377
    | NamedHyp s :: _ -> 
 
378
        errorlabstrm ""
 
379
          (str "The variable " ++ pr_id s ++ 
 
380
           str " occurs more than once in binding list.");
 
381
    | AnonHyp n :: _ ->
 
382
        errorlabstrm ""
 
383
          (str "The position " ++ int n ++
 
384
           str " occurs more than once in binding list.")
 
385
    | [] -> ()
 
386
 
 
387
let meta_of_binder clause loc mvs = function
 
388
  | NamedHyp s -> meta_with_name clause.evd s
 
389
  | AnonHyp n ->
 
390
      try List.nth mvs (n-1)
 
391
      with (Failure _|Invalid_argument _) ->
 
392
        errorlabstrm "" (str "No such binder.")
 
393
 
 
394
let error_already_defined b =
 
395
  match b with
 
396
    | NamedHyp id ->
 
397
        errorlabstrm ""
 
398
          (str "Binder name \"" ++ pr_id id ++
 
399
           str"\" already defined with incompatible value.")
 
400
    | AnonHyp n ->
 
401
        anomalylabstrm ""
 
402
          (str "Position " ++ int n ++ str" already defined.")
 
403
 
 
404
let clenv_unify_binding_type clenv c t u =
 
405
  if isMeta (fst (whd_stack (evars_of clenv.evd) u)) then
 
406
    (* Not enough information to know if some subtyping is needed *)
 
407
    CoerceToType, clenv, c
 
408
  else
 
409
    (* Enough information so as to try a coercion now *)
 
410
    try
 
411
      let evd,c = w_coerce_to_type (cl_env clenv) clenv.evd c t u in
 
412
      TypeProcessed, { clenv with evd = evd }, c
 
413
    with e when precatchable_exception e ->
 
414
      TypeNotProcessed, clenv, c
 
415
 
 
416
let clenv_assign_binding clenv k (sigma,c) =
 
417
  let k_typ = clenv_hnf_constr clenv (clenv_meta_type clenv k) in
 
418
  let clenv' = { clenv with evd = evar_merge clenv.evd sigma} in
 
419
  let c_typ = nf_betaiota (evars_of clenv'.evd) (clenv_get_type_of clenv' c) in
 
420
  let status,clenv'',c = clenv_unify_binding_type clenv' c c_typ k_typ in
 
421
  { clenv'' with evd = meta_assign k (c,(UserGiven,status)) clenv''.evd }
 
422
 
 
423
let clenv_match_args bl clenv =
 
424
  if bl = [] then
 
425
    clenv
 
426
  else
 
427
    let mvs = clenv_independent clenv in
 
428
    check_bindings bl;
 
429
    List.fold_left
 
430
      (fun clenv (loc,b,(sigma,c as sc)) ->
 
431
        let k = meta_of_binder clenv loc mvs b in
 
432
        if meta_defined clenv.evd k then
 
433
          if eq_constr (fst (meta_fvalue clenv.evd k)).rebus c then clenv
 
434
          else error_already_defined b
 
435
        else
 
436
          clenv_assign_binding clenv k sc)
 
437
      clenv bl
 
438
 
 
439
let clenv_constrain_last_binding c clenv =
 
440
  let all_mvs = collect_metas clenv.templval.rebus in
 
441
  let k =
 
442
    try list_last all_mvs 
 
443
    with Failure _ -> anomaly "clenv_constrain_with_bindings" in
 
444
  clenv_assign_binding clenv k (Evd.empty,c)
 
445
 
 
446
let clenv_constrain_dep_args hyps_only bl clenv =
 
447
  if bl = [] then
 
448
    clenv
 
449
  else
 
450
    let occlist = clenv_dependent hyps_only clenv in
 
451
    if List.length occlist = List.length bl then
 
452
      List.fold_left2 clenv_assign_binding clenv occlist bl
 
453
    else 
 
454
      errorlabstrm "" 
 
455
        (strbrk "Not the right number of missing arguments (expected " ++
 
456
         int (List.length occlist) ++ str ").")
 
457
 
 
458
(****************************************************************)
 
459
(* Clausal environment for an application *)
 
460
 
 
461
let make_clenv_binding_gen hyps_only n gls (c,t) = function
 
462
  | ImplicitBindings largs ->
 
463
      let clause = mk_clenv_from_n gls n (c,t) in
 
464
      clenv_constrain_dep_args hyps_only largs clause
 
465
  | ExplicitBindings lbind ->
 
466
      let clause = mk_clenv_rename_from_n gls n (c,t) in
 
467
      clenv_match_args lbind clause
 
468
  | NoBindings ->
 
469
      mk_clenv_from_n gls n (c,t)
 
470
 
 
471
let make_clenv_binding_apply gls n = make_clenv_binding_gen true n gls
 
472
let make_clenv_binding = make_clenv_binding_gen false None
 
473
 
 
474
(****************************************************************)
 
475
(* Pretty-print *)
 
476
 
 
477
let pr_clenv clenv =
 
478
  h 0
 
479
    (str"TEMPL: " ++ print_constr clenv.templval.rebus ++
 
480
     str" : " ++ print_constr clenv.templtyp.rebus ++ fnl () ++
 
481
     pr_evar_defs clenv.evd)