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

« back to all changes in this revision

Viewing changes to interp/constrintern.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: constrintern.ml 11739 2009-01-02 19:33:19Z herbelin $ *)
 
10
 
 
11
open Pp
 
12
open Util
 
13
open Flags
 
14
open Names
 
15
open Nameops
 
16
open Libnames
 
17
open Impargs
 
18
open Rawterm
 
19
open Pattern
 
20
open Pretyping
 
21
open Cases
 
22
open Topconstr
 
23
open Nametab
 
24
open Notation
 
25
open Inductiveops
 
26
 
 
27
open Decl_kinds
 
28
 
 
29
let type_of_logical_kind = 
 
30
  function
 
31
  | IsDefinition def -> 
 
32
      (match def with
 
33
      | Definition -> "def"
 
34
      | Coercion -> "coe"
 
35
      | SubClass -> "subclass"
 
36
      | CanonicalStructure -> "canonstruc"
 
37
      | Example -> "ex"
 
38
      | Fixpoint -> "def"
 
39
      | CoFixpoint -> "def"
 
40
      | Scheme -> "scheme"
 
41
      | StructureComponent -> "proj"
 
42
      | IdentityCoercion -> "coe"
 
43
      | Instance -> "inst"
 
44
      | Method -> "meth")
 
45
  | IsAssumption a ->
 
46
      (match a with
 
47
      | Definitional -> "defax"
 
48
      | Logical -> "prfax"
 
49
      | Conjectural -> "prfax")
 
50
  | IsProof th ->
 
51
      (match th with
 
52
      | Theorem
 
53
      | Lemma
 
54
      | Fact
 
55
      | Remark
 
56
      | Property
 
57
      | Proposition
 
58
      | Corollary -> "thm")
 
59
 
 
60
let type_of_global_ref gr =
 
61
  if Typeclasses.is_class gr then
 
62
    "class"
 
63
  else
 
64
    match gr with
 
65
    | ConstRef cst -> 
 
66
        type_of_logical_kind (Decls.constant_kind cst)
 
67
    | VarRef v ->
 
68
        "var" ^ type_of_logical_kind (Decls.variable_kind v)
 
69
    | IndRef ind ->
 
70
        let (mib,oib) = Inductive.lookup_mind_specif (Global.env ()) ind in
 
71
          if mib.Declarations.mind_record then
 
72
            if mib.Declarations.mind_finite then "rec"
 
73
            else "corec"
 
74
          else if mib.Declarations.mind_finite then "ind"
 
75
          else "coind"
 
76
    | ConstructRef _ -> "constr"
 
77
 
 
78
(* To interpret implicits and arg scopes of recursive variables in
 
79
   inductive types and recursive definitions *)
 
80
type var_internalisation_type = Inductive | Recursive | Method
 
81
 
 
82
type var_internalisation_data =
 
83
  var_internalisation_type * identifier list * Impargs.implicits_list * scope_name option list
 
84
 
 
85
type implicits_env = (identifier * var_internalisation_data) list
 
86
type full_implicits_env = identifier list * implicits_env
 
87
 
 
88
type raw_binder = (name * binding_kind * rawconstr option * rawconstr)
 
89
 
 
90
let interning_grammar = ref false
 
91
 
 
92
(* Historically for parsing grammar rules, but in fact used only for
 
93
   translator, v7 parsing, and unstrict tactic internalisation *)
 
94
let for_grammar f x =
 
95
  interning_grammar := true;
 
96
  let a = f x in
 
97
    interning_grammar := false;
 
98
    a
 
99
 
 
100
(**********************************************************************)
 
101
(* Internalisation errors                                             *)
 
102
 
 
103
type internalisation_error =
 
104
  | VariableCapture of identifier
 
105
  | WrongExplicitImplicit
 
106
  | IllegalMetavariable
 
107
  | NotAConstructor of reference
 
108
  | UnboundFixName of bool * identifier
 
109
  | NonLinearPattern of identifier
 
110
  | BadPatternsNumber of int * int
 
111
  | BadExplicitationNumber of explicitation * int option
 
112
 
 
113
exception InternalisationError of loc * internalisation_error
 
114
 
 
115
let explain_variable_capture id =
 
116
  str "The variable " ++ pr_id id ++ str " occurs in its type"
 
117
 
 
118
let explain_wrong_explicit_implicit =
 
119
  str "Found an explicitly given implicit argument but was expecting" ++
 
120
  fnl () ++ str "a regular one"
 
121
 
 
122
let explain_illegal_metavariable =
 
123
  str "Metavariables allowed only in patterns"
 
124
 
 
125
let explain_not_a_constructor ref =
 
126
  str "Unknown constructor: " ++ pr_reference ref
 
127
 
 
128
let explain_unbound_fix_name is_cofix id =
 
129
  str "The name" ++ spc () ++ pr_id id ++ 
 
130
  spc () ++ str "is not bound in the corresponding" ++ spc () ++
 
131
  str (if is_cofix then "co" else "") ++ str "fixpoint definition"
 
132
 
 
133
let explain_non_linear_pattern id =
 
134
  str "The variable " ++ pr_id id ++ str " is bound several times in pattern"
 
135
 
 
136
let explain_bad_patterns_number n1 n2 =
 
137
  str "Expecting " ++ int n1 ++ str (plural n1 " pattern") ++
 
138
  str " but found " ++ int n2
 
139
 
 
140
let explain_bad_explicitation_number n po =
 
141
  match n with
 
142
  | ExplByPos (n,_id) ->
 
143
      let s = match po with
 
144
        | None -> str "a regular argument"
 
145
        | Some p -> int p in
 
146
      str "Bad explicitation number: found " ++ int n ++ 
 
147
      str" but was expecting " ++ s
 
148
  | ExplByName id ->
 
149
      let s = match po with
 
150
        | None -> str "a regular argument"
 
151
        | Some p -> (*pr_id (name_of_position p) in*) failwith "" in
 
152
      str "Bad explicitation name: found " ++ pr_id id ++ 
 
153
      str" but was expecting " ++ s
 
154
 
 
155
let explain_internalisation_error e =
 
156
  let pp = match e with
 
157
  | VariableCapture id -> explain_variable_capture id
 
158
  | WrongExplicitImplicit -> explain_wrong_explicit_implicit
 
159
  | IllegalMetavariable -> explain_illegal_metavariable
 
160
  | NotAConstructor ref -> explain_not_a_constructor ref
 
161
  | UnboundFixName (iscofix,id) -> explain_unbound_fix_name iscofix id
 
162
  | NonLinearPattern id -> explain_non_linear_pattern id
 
163
  | BadPatternsNumber (n1,n2) -> explain_bad_patterns_number n1 n2
 
164
  | BadExplicitationNumber (n,po) -> explain_bad_explicitation_number n po in
 
165
  pp ++ str "."
 
166
 
 
167
let error_unbound_patvar loc n =
 
168
  user_err_loc
 
169
    (loc,"glob_qualid_or_patvar", str "?" ++ pr_patvar n ++ 
 
170
      str " is unbound.")
 
171
 
 
172
let error_bad_inductive_type loc =
 
173
  user_err_loc (loc,"",str 
 
174
    "This should be an inductive type applied to names or \"_\".")
 
175
 
 
176
let error_inductive_parameter_not_implicit loc =
 
177
  user_err_loc (loc,"", str
 
178
   ("The parameters of inductive types do not bind in\n"^
 
179
    "the 'return' clauses; they must be replaced by '_' in the 'in' clauses."))
 
180
 
 
181
(**********************************************************************)
 
182
(* Contracting "{ _ }" in notations *)
 
183
 
 
184
let rec wildcards ntn n =
 
185
  if n = String.length ntn then []
 
186
  else let l = spaces ntn (n+1) in if ntn.[n] = '_' then n::l else l
 
187
and spaces ntn n =
 
188
  if n = String.length ntn then []
 
189
  else if ntn.[n] = ' ' then wildcards ntn (n+1) else spaces ntn (n+1)
 
190
 
 
191
let expand_notation_string ntn n =
 
192
  let pos = List.nth (wildcards ntn 0) n in
 
193
  let hd = if pos = 0 then "" else String.sub ntn 0 pos in
 
194
  let tl = 
 
195
    if pos = String.length ntn then "" 
 
196
    else String.sub ntn (pos+1) (String.length ntn - pos -1) in
 
197
  hd ^ "{ _ }" ^ tl
 
198
 
 
199
(* This contracts the special case of "{ _ }" for sumbool, sumor notations *)
 
200
(* Remark: expansion of squash at definition is done in metasyntax.ml *)
 
201
let contract_notation ntn (l,ll) =
 
202
  let ntn' = ref ntn in
 
203
  let rec contract_squash n = function
 
204
    | [] -> []
 
205
    | CNotation (_,"{ _ }",([a],[])) :: l -> 
 
206
        ntn' := expand_notation_string !ntn' n;
 
207
        contract_squash n (a::l)
 
208
    | a :: l ->
 
209
        a::contract_squash (n+1) l in
 
210
  let l = contract_squash 0 l in
 
211
  (* side effect; don't inline *)
 
212
  !ntn',(l,ll)
 
213
 
 
214
let contract_pat_notation ntn (l,ll) =
 
215
  let ntn' = ref ntn in
 
216
  let rec contract_squash n = function
 
217
    | [] -> []
 
218
    | CPatNotation (_,"{ _ }",([a],[])) :: l -> 
 
219
        ntn' := expand_notation_string !ntn' n;
 
220
        contract_squash n (a::l)
 
221
    | a :: l ->
 
222
        a::contract_squash (n+1) l in
 
223
  let l = contract_squash 0 l in
 
224
  (* side effect; don't inline *)
 
225
  !ntn',(l,ll)
 
226
 
 
227
(**********************************************************************)
 
228
(* Remembering the parsing scope of variables in notations            *)
 
229
 
 
230
let make_current_scope (tmp_scope,scopes) = Option.List.cons tmp_scope scopes
 
231
 
 
232
let set_var_scope loc id (_,_,scopt,scopes) varscopes =
 
233
  let idscopes = List.assoc id varscopes in
 
234
  if !idscopes <> None & 
 
235
    make_current_scope (Option.get !idscopes)
 
236
    <> make_current_scope (scopt,scopes) then
 
237
      user_err_loc (loc,"set_var_scope",
 
238
      pr_id id ++ str " already occurs in a different scope.")
 
239
  else
 
240
    idscopes := Some (scopt,scopes)
 
241
 
 
242
(**********************************************************************)
 
243
(* Syntax extensions                                                  *)
 
244
 
 
245
let traverse_binder (subst,substlist) (renaming,(ids,unb,tmpsc,scopes as env)) id =
 
246
  try
 
247
    (* Binders bound in the notation are considered first-order objects *)
 
248
    let _,id' = coerce_to_id (fst (List.assoc id subst)) in
 
249
    (renaming,(Idset.add id' ids,unb,tmpsc,scopes)), id'
 
250
  with Not_found ->
 
251
    (* Binders not bound in the notation do not capture variables *)
 
252
    (* outside the notation (i.e. in the substitution) *)
 
253
    let fvs1 = List.map (fun (_,(c,_)) -> free_vars_of_constr_expr c) subst in
 
254
    let fvs2 = List.flatten (List.map (fun (_,(l,_)) -> List.map free_vars_of_constr_expr l) substlist) in
 
255
    let fvs3 = List.map snd renaming in
 
256
    let fvs = List.flatten (List.map Idset.elements (fvs1@fvs2)) @ fvs3 in
 
257
    let id' = next_ident_away id fvs in
 
258
    let renaming' = if id=id' then renaming else (id,id')::renaming in
 
259
    (renaming',env), id'
 
260
 
 
261
let rec subst_iterator y t = function
 
262
  | RVar (_,id) as x -> if id = y then t else x
 
263
  | x -> map_rawconstr (subst_iterator y t) x
 
264
 
 
265
let rec subst_aconstr_in_rawconstr loc interp (subst,substlist as sub) infos c =
 
266
  let (renaming,(ids,unb,_,scopes)) = infos in
 
267
  let subinfos = renaming,(ids,unb,None,scopes) in
 
268
  match c with
 
269
  | AVar id ->
 
270
      begin
 
271
        (* subst remembers the delimiters stack in the interpretation *)
 
272
        (* of the notations *)
 
273
        try 
 
274
          let (a,(scopt,subscopes)) = List.assoc id subst in
 
275
          interp (ids,unb,scopt,subscopes@scopes) a
 
276
        with Not_found -> 
 
277
        try 
 
278
          RVar (loc,List.assoc id renaming)
 
279
        with Not_found -> 
 
280
          (* Happens for local notation joint with inductive/fixpoint defs *)
 
281
          RVar (loc,id)
 
282
      end
 
283
  | AList (x,_,iter,terminator,lassoc) ->
 
284
      (try 
 
285
        (* All elements of the list are in scopes (scopt,subscopes) *)
 
286
        let (l,(scopt,subscopes)) = List.assoc x substlist in
 
287
        let termin = 
 
288
          subst_aconstr_in_rawconstr loc interp sub subinfos terminator in
 
289
        List.fold_right (fun a t -> 
 
290
          subst_iterator ldots_var t
 
291
            (subst_aconstr_in_rawconstr loc interp 
 
292
              ((x,(a,(scopt,subscopes)))::subst,substlist) subinfos iter))
 
293
            (if lassoc then List.rev l else l) termin
 
294
      with Not_found -> 
 
295
          anomaly "Inconsistent substitution of recursive notation")
 
296
  | t ->
 
297
      rawconstr_of_aconstr_with_binders loc (traverse_binder sub)
 
298
      (subst_aconstr_in_rawconstr loc interp sub) subinfos t
 
299
 
 
300
let intern_notation intern (_,_,tmp_scope,scopes as env) loc ntn fullargs =
 
301
  let ntn,(args,argslist) = contract_notation ntn fullargs in
 
302
  let (((ids,idsl),c),df) = interp_notation loc ntn (tmp_scope,scopes) in
 
303
    Dumpglob.dump_notation_location (Topconstr.ntn_loc loc args ntn) df;
 
304
    let subst = List.map2 (fun (id,scl) a -> (id,(a,scl))) ids args in
 
305
    let substlist = List.map2 (fun (id,scl) a -> (id,(a,scl))) idsl argslist in
 
306
      subst_aconstr_in_rawconstr loc intern (subst,substlist) ([],env) c
 
307
 
 
308
let set_type_scope (ids,unb,tmp_scope,scopes) =
 
309
  (ids,unb,Some Notation.type_scope,scopes)
 
310
 
 
311
let reset_tmp_scope (ids,unb,tmp_scope,scopes) =
 
312
  (ids,unb,None,scopes)
 
313
 
 
314
let rec it_mkRProd env body =
 
315
  match env with
 
316
      (na, bk, _, t) :: tl -> it_mkRProd tl (RProd (dummy_loc, na, bk, t, body))
 
317
    | [] -> body
 
318
 
 
319
let rec it_mkRLambda env body =
 
320
  match env with
 
321
      (na, bk, _, t) :: tl -> it_mkRLambda tl (RLambda (dummy_loc, na, bk, t, body))
 
322
    | [] -> body
 
323
 
 
324
(**********************************************************************)
 
325
(* Discriminating between bound variables and global references       *)
 
326
 
 
327
(* [vars1] is a set of name to avoid (used for the tactic language);
 
328
   [vars2] is the set of global variables, env is the set of variables
 
329
   abstracted until this point *)
 
330
 
 
331
let string_of_ty = function
 
332
  | Inductive -> "ind"
 
333
  | Recursive -> "def"
 
334
  | Method -> "meth"
 
335
 
 
336
let intern_var (env,unbound_vars,_,_ as genv) (ltacvars,vars2,vars3,(_,impls)) loc id =
 
337
  let (vars1,unbndltacvars) = ltacvars in
 
338
  (* Is [id] an inductive type potentially with implicit *)
 
339
  try
 
340
    let ty, l,impl,argsc = List.assoc id impls in
 
341
    let l = List.map 
 
342
      (fun id -> CRef (Ident (loc,id)), Some (loc,ExplByName id)) l in
 
343
    let tys = string_of_ty ty in
 
344
      Dumpglob.dump_reference loc "<>" (string_of_id id) tys;
 
345
      RVar (loc,id), impl, argsc, l
 
346
  with Not_found ->
 
347
  (* Is [id] bound in current env or is an ltac var bound to constr *)
 
348
  if Idset.mem id env or List.mem id vars1
 
349
  then
 
350
    RVar (loc,id), [], [], []
 
351
  (* Is [id] a notation variable *)
 
352
  else if List.mem_assoc id vars3
 
353
  then
 
354
    (set_var_scope loc id genv vars3; RVar (loc,id), [], [], [])
 
355
  else
 
356
 
 
357
  (* Is [id] bound to a free name in ltac (this is an ltac error message) *)
 
358
  try
 
359
    match List.assoc id unbndltacvars with
 
360
      | None -> user_err_loc (loc,"intern_var",
 
361
          str "variable " ++ pr_id id ++ str " should be bound to a term.")
 
362
      | Some id0 -> Pretype_errors.error_var_not_found_loc loc id0
 
363
  with Not_found ->
 
364
    (* Is [id] a goal or section variable *)
 
365
    let _ = Sign.lookup_named id vars2 in
 
366
      try
 
367
        (* [id] a section variable *)
 
368
        (* Redundant: could be done in intern_qualid *)
 
369
        let ref = VarRef id in
 
370
          RRef (loc, ref), implicits_of_global ref, find_arguments_scope ref, []
 
371
      with _ ->
 
372
        (* [id] a goal variable *)
 
373
        RVar (loc,id), [], [], []
 
374
            
 
375
let find_appl_head_data (_,_,_,(_,impls)) = function
 
376
  | RRef (_,ref) as x -> x,implicits_of_global ref,find_arguments_scope ref,[]
 
377
  | x -> x,[],[],[]
 
378
 
 
379
let error_not_enough_arguments loc =
 
380
  user_err_loc (loc,"",str "Abbreviation is not applied enough.")
 
381
 
 
382
let check_no_explicitation l =
 
383
  let l = List.filter (fun (a,b) -> b <> None) l in
 
384
  if l <> [] then
 
385
    let loc = fst (Option.get (snd (List.hd l))) in
 
386
    user_err_loc
 
387
     (loc,"",str"Unexpected explicitation of the argument of an abbreviation.")
 
388
 
 
389
(* Is it a global reference or a syntactic definition? *)
 
390
let intern_qualid loc qid intern env args =
 
391
  try match Nametab.extended_locate qid with
 
392
  | TrueGlobal ref ->
 
393
      Dumpglob.add_glob loc ref;
 
394
      RRef (loc, ref), args
 
395
  | SyntacticDef sp ->
 
396
      Dumpglob.add_glob_kn loc sp;
 
397
      let (ids,c) = Syntax_def.search_syntactic_definition loc sp in
 
398
      let nids = List.length ids in
 
399
      if List.length args < nids then error_not_enough_arguments loc;
 
400
      let args1,args2 = list_chop nids args in
 
401
      check_no_explicitation args1;
 
402
      let subst = List.map2 (fun (id,scl) a -> (id,(fst a,scl))) ids args1 in
 
403
      subst_aconstr_in_rawconstr loc intern (subst,[]) ([],env) c, args2
 
404
  with Not_found ->
 
405
    error_global_not_found_loc loc qid
 
406
 
 
407
(* Rule out section vars since these should have been found by intern_var *)
 
408
let intern_non_secvar_qualid loc qid intern env args =
 
409
  match intern_qualid loc qid intern env args with
 
410
    | RRef (loc, VarRef id),_ -> error_global_not_found_loc loc qid
 
411
    | r -> r
 
412
 
 
413
let intern_applied_reference intern (_, unb, _, _ as env) lvar args = function
 
414
  | Qualid (loc, qid) ->
 
415
      let r,args2 = intern_qualid loc qid intern env args in
 
416
        find_appl_head_data lvar r, args2
 
417
  | Ident (loc, id) ->
 
418
      try intern_var env lvar loc id, args
 
419
      with Not_found -> 
 
420
      let qid = make_short_qualid id in
 
421
      try
 
422
        let r,args2 = intern_non_secvar_qualid loc qid intern env args in
 
423
        find_appl_head_data lvar r, args2
 
424
      with e ->
 
425
        (* Extra allowance for non globalizing functions *)
 
426
        if !interning_grammar || unb then
 
427
          (RVar (loc,id), [], [], []),args
 
428
        else raise e
 
429
          
 
430
let interp_reference vars r =
 
431
  let (r,_,_,_),_ =
 
432
    intern_applied_reference (fun _ -> error_not_enough_arguments dummy_loc)
 
433
      (Idset.empty,false,None,[]) (vars,[],[],([],[])) [] r
 
434
  in r
 
435
 
 
436
let apply_scope_env (ids,unb,_,scopes) = function
 
437
  | [] -> (ids,unb,None,scopes), []
 
438
  | sc::scl -> (ids,unb,sc,scopes), scl
 
439
 
 
440
let rec adjust_scopes env scopes = function
 
441
  | [] -> []
 
442
  | a::args ->
 
443
      let (enva,scopes) = apply_scope_env env scopes in
 
444
      enva :: adjust_scopes env scopes args
 
445
 
 
446
let rec simple_adjust_scopes n = function
 
447
  | [] -> if n=0 then [] else None :: simple_adjust_scopes (n-1) []
 
448
  | sc::scopes -> sc :: simple_adjust_scopes (n-1) scopes
 
449
 
 
450
let find_remaining_constructor_scopes pl1 pl2 (ind,j as cstr) =
 
451
  let (mib,mip) = Inductive.lookup_mind_specif (Global.env()) ind in
 
452
  let npar = mib.Declarations.mind_nparams in
 
453
  snd (list_chop (List.length pl1 + npar)
 
454
    (simple_adjust_scopes (npar + List.length pl2)
 
455
      (find_arguments_scope (ConstructRef cstr))))
 
456
 
 
457
(**********************************************************************)
 
458
(* Cases                                                              *)
 
459
 
 
460
let product_of_cases_patterns ids idspl =
 
461
  List.fold_right (fun (ids,pl) (ids',ptaill) ->
 
462
    (ids@ids',
 
463
    (* Cartesian prod of the or-pats for the nth arg and the tail args *)
 
464
    List.flatten (
 
465
    List.map (fun (subst,p) ->
 
466
      List.map (fun (subst',ptail) -> (subst@subst',p::ptail)) ptaill) pl)))
 
467
    idspl (ids,[[],[]])
 
468
 
 
469
let simple_product_of_cases_patterns pl =
 
470
  List.fold_right (fun pl ptaill ->
 
471
    List.flatten (List.map (fun (subst,p) ->
 
472
      List.map (fun (subst',ptail) -> (subst@subst',p::ptail)) ptaill) pl))
 
473
    pl [[],[]]
 
474
 
 
475
(* Check linearity of pattern-matching *)
 
476
let rec has_duplicate = function 
 
477
  | [] -> None
 
478
  | x::l -> if List.mem x l then (Some x) else has_duplicate l
 
479
 
 
480
let loc_of_lhs lhs = 
 
481
 join_loc (fst (List.hd lhs)) (fst (list_last lhs))
 
482
 
 
483
let check_linearity lhs ids =
 
484
  match has_duplicate ids with
 
485
    | Some id ->
 
486
        raise (InternalisationError (loc_of_lhs lhs,NonLinearPattern id))
 
487
    | None ->
 
488
        ()
 
489
 
 
490
(* Match the number of pattern against the number of matched args *)
 
491
let check_number_of_pattern loc n l =
 
492
  let p = List.length l in
 
493
  if n<>p then raise (InternalisationError (loc,BadPatternsNumber (n,p)))
 
494
 
 
495
let check_or_pat_variables loc ids idsl =
 
496
  if List.exists (fun ids' -> not (list_eq_set ids ids')) idsl then
 
497
    user_err_loc (loc, "", str 
 
498
    "The components of this disjunctive pattern must bind the same variables.")
 
499
 
 
500
let check_constructor_length env loc cstr pl pl0 =
 
501
  let n = List.length pl + List.length pl0 in
 
502
  let nargs = Inductiveops.constructor_nrealargs env cstr in
 
503
  let nhyps = Inductiveops.constructor_nrealhyps env cstr in
 
504
  if n <> nargs && n <> nhyps (* i.e. with let's *) then
 
505
    error_wrong_numarg_constructor_loc loc env cstr nargs
 
506
 
 
507
(* Manage multiple aliases *)
 
508
 
 
509
  (* [merge_aliases] returns the sets of all aliases encountered at this
 
510
     point and a substitution mapping extra aliases to the first one *)
 
511
let merge_aliases (ids,asubst as _aliases) id =
 
512
  ids@[id], if ids=[] then asubst else (id, List.hd ids)::asubst
 
513
 
 
514
let alias_of = function
 
515
  | ([],_) -> Anonymous
 
516
  | (id::_,_) -> Name id
 
517
 
 
518
let message_redundant_alias (id1,id2) =
 
519
  if_verbose warning 
 
520
   ("Alias variable "^(string_of_id id1)^" is merged with "^(string_of_id id2))
 
521
 
 
522
(* Expanding notations *)
 
523
 
 
524
let error_invalid_pattern_notation loc =
 
525
  user_err_loc (loc,"",str "Invalid notation for pattern.")
 
526
 
 
527
let chop_aconstr_constructor loc (ind,k) args =
 
528
  let nparams = (fst (Global.lookup_inductive ind)).Declarations.mind_nparams in
 
529
  let params,args = list_chop nparams args in
 
530
  List.iter (function AHole _ -> ()
 
531
    | _ -> error_invalid_pattern_notation loc) params;
 
532
  args
 
533
 
 
534
let rec subst_pat_iterator y t (subst,p) = match p with
 
535
  | PatVar (_,id) as x ->
 
536
      if id = Name y then t else [subst,x]
 
537
  | PatCstr (loc,id,l,alias) ->
 
538
      let l' = List.map (fun a -> (subst_pat_iterator y t ([],a))) l in
 
539
      let pl = simple_product_of_cases_patterns l' in
 
540
      List.map (fun (subst',pl) -> subst'@subst,PatCstr (loc,id,pl,alias)) pl
 
541
 
 
542
let subst_cases_pattern loc alias intern fullsubst scopes a =
 
543
  let rec aux alias (subst,substlist as fullsubst) = function
 
544
  | AVar id ->
 
545
      begin
 
546
        (* subst remembers the delimiters stack in the interpretation *)
 
547
        (* of the notations *)
 
548
        try 
 
549
          let (a,(scopt,subscopes)) = List.assoc id subst in
 
550
            intern (subscopes@scopes) ([],[]) scopt a
 
551
        with Not_found -> 
 
552
          if id = ldots_var then [], [[], PatVar (loc,Name id)] else
 
553
          anomaly ("Unbound pattern notation variable: "^(string_of_id id))
 
554
          (*
 
555
          (* Happens for local notation joint with inductive/fixpoint defs *)
 
556
          if aliases <> ([],[]) then
 
557
            anomaly "Pattern notation without constructors";
 
558
          [[id],[]], PatVar (loc,Name id)
 
559
          *)
 
560
      end
 
561
  | ARef (ConstructRef c) ->
 
562
      ([],[[], PatCstr (loc,c, [], alias)])
 
563
  | AApp (ARef (ConstructRef cstr),args) ->
 
564
      let args = chop_aconstr_constructor loc cstr args in
 
565
      let idslpll = List.map (aux Anonymous fullsubst) args in
 
566
      let ids',pll = product_of_cases_patterns [] idslpll in
 
567
      let pl' = List.map (fun (asubst,pl) -> 
 
568
        asubst,PatCstr (loc,cstr,pl,alias)) pll in
 
569
        ids', pl'
 
570
  | AList (x,_,iter,terminator,lassoc) ->
 
571
      (try 
 
572
        (* All elements of the list are in scopes (scopt,subscopes) *)
 
573
        let (l,(scopt,subscopes)) = List.assoc x substlist in
 
574
        let termin = aux Anonymous fullsubst terminator in
 
575
        let idsl,v =
 
576
          List.fold_right (fun a (tids,t) -> 
 
577
            let uids,u = aux Anonymous ((x,(a,(scopt,subscopes)))::subst,substlist) iter in
 
578
            let pll = List.map (subst_pat_iterator ldots_var t) u in
 
579
            tids@uids, List.flatten pll)
 
580
            (if lassoc then List.rev l else l) termin in
 
581
        idsl, List.map (fun ((asubst, pl) as x) ->
 
582
          match pl with PatCstr (loc, c, pl, Anonymous) -> (asubst, PatCstr (loc, c, pl, alias)) | _ -> x) v
 
583
      with Not_found -> 
 
584
          anomaly "Inconsistent substitution of recursive notation")
 
585
  | t -> error_invalid_pattern_notation loc
 
586
  in aux alias fullsubst a
 
587
 
 
588
(* Differentiating between constructors and matching variables *)
 
589
type pattern_qualid_kind =
 
590
  | ConstrPat of constructor * (identifier list * 
 
591
      ((identifier * identifier) list * cases_pattern) list) list
 
592
  | VarPat of identifier
 
593
 
 
594
let find_constructor ref f aliases pats scopes =
 
595
  let (loc,qid) = qualid_of_reference ref in
 
596
  let gref =
 
597
    try extended_locate qid
 
598
    with Not_found -> raise (InternalisationError (loc,NotAConstructor ref)) in
 
599
  match gref with
 
600
  | SyntacticDef sp ->
 
601
      let (vars,a) = Syntax_def.search_syntactic_definition loc sp in
 
602
      (match a with
 
603
       | ARef (ConstructRef cstr) ->
 
604
           assert (vars=[]);
 
605
           cstr, [], pats
 
606
       | AApp (ARef (ConstructRef cstr),args) ->
 
607
           let args = chop_aconstr_constructor loc cstr args in
 
608
           let nvars = List.length vars in
 
609
           if List.length pats < nvars then error_not_enough_arguments loc;
 
610
           let pats1,pats2 = list_chop nvars pats in
 
611
           let subst = List.map2 (fun (id,scl) a -> (id,(a,scl))) vars pats1 in
 
612
           let idspl1 = List.map (subst_cases_pattern loc (alias_of aliases) f (subst,[]) scopes) args in
 
613
           cstr, idspl1, pats2
 
614
       | _ -> raise Not_found)
 
615
      
 
616
  | TrueGlobal r ->
 
617
      let rec unf = function
 
618
        | ConstRef cst ->
 
619
            let v = Environ.constant_value (Global.env()) cst in
 
620
            unf (global_of_constr v)
 
621
        | ConstructRef cstr -> 
 
622
            Dumpglob.add_glob loc r; 
 
623
            cstr, [], pats
 
624
        | _ -> raise Not_found
 
625
      in unf r
 
626
 
 
627
let find_pattern_variable = function
 
628
  | Ident (loc,id) -> id
 
629
  | Qualid (loc,_) as x -> raise (InternalisationError(loc,NotAConstructor x))
 
630
 
 
631
let maybe_constructor ref f aliases scopes =
 
632
  try
 
633
    let c,idspl1,pl2 = find_constructor ref f aliases [] scopes in
 
634
    assert (pl2 = []);
 
635
    ConstrPat (c,idspl1)
 
636
  with
 
637
      (* patt var does not exists globally *)
 
638
    | InternalisationError _ -> VarPat (find_pattern_variable ref)
 
639
      (* patt var also exists globally but does not satisfy preconditions *)
 
640
    | (Environ.NotEvaluableConst _ | Not_found) ->
 
641
        if_verbose msg_warning (str "pattern " ++ pr_reference ref ++
 
642
              str " is understood as a pattern variable");
 
643
        VarPat (find_pattern_variable ref)
 
644
 
 
645
let mustbe_constructor loc ref f aliases patl scopes = 
 
646
  try find_constructor ref f aliases patl scopes
 
647
  with (Environ.NotEvaluableConst _ | Not_found) ->
 
648
    raise (InternalisationError (loc,NotAConstructor ref))
 
649
 
 
650
let rec intern_cases_pattern genv scopes (ids,asubst as aliases) tmp_scope pat=
 
651
  let intern_pat = intern_cases_pattern genv in 
 
652
  match pat with
 
653
  | CPatAlias (loc, p, id) ->
 
654
      let aliases' = merge_aliases aliases id in
 
655
      intern_pat scopes aliases' tmp_scope p
 
656
  | CPatCstr (loc, head, pl) ->
 
657
      let c,idslpl1,pl2 = mustbe_constructor loc head intern_pat aliases pl scopes in
 
658
      check_constructor_length genv loc c idslpl1 pl2;
 
659
      let argscs2 = find_remaining_constructor_scopes idslpl1 pl2 c in
 
660
      let idslpl2 = List.map2 (intern_pat scopes ([],[])) argscs2 pl2 in
 
661
      let (ids',pll) = product_of_cases_patterns ids (idslpl1@idslpl2) in
 
662
      let pl' = List.map (fun (asubst,pl) ->
 
663
        (asubst, PatCstr (loc,c,pl,alias_of aliases))) pll in
 
664
      ids',pl'
 
665
  | CPatNotation (loc,"- _",([CPatPrim(_,Numeral p)],[]))
 
666
      when Bigint.is_strictly_pos p ->
 
667
      intern_pat scopes aliases tmp_scope (CPatPrim(loc,Numeral(Bigint.neg p)))
 
668
  | CPatNotation (_,"( _ )",([a],[])) ->
 
669
      intern_pat scopes aliases tmp_scope a
 
670
  | CPatNotation (loc, ntn, fullargs) ->
 
671
      let ntn,(args,argsl) = contract_pat_notation ntn fullargs in
 
672
      let (((ids',idsl'),c),df) = Notation.interp_notation loc ntn (tmp_scope,scopes) in
 
673
      Dumpglob.dump_notation_location (Topconstr.patntn_loc loc args ntn) df;
 
674
      let subst = List.map2 (fun (id,scl) a -> (id,(a,scl))) ids' args in
 
675
      let substlist = List.map2 (fun (id,scl) a -> (id,(a,scl))) idsl' argsl in
 
676
      let ids'',pl =
 
677
        subst_cases_pattern loc (alias_of aliases) intern_pat (subst,substlist)
 
678
          scopes c
 
679
      in ids@ids'', pl
 
680
  | CPatPrim (loc, p) ->
 
681
      let a = alias_of aliases in
 
682
      let (c,df) = Notation.interp_prim_token_cases_pattern loc p a 
 
683
        (tmp_scope,scopes) in
 
684
      Dumpglob.dump_notation_location (fst (unloc loc)) df;
 
685
      (ids,[asubst,c])
 
686
  | CPatDelimiters (loc, key, e) ->
 
687
      intern_pat (find_delimiters_scope loc key::scopes) aliases None e
 
688
  | CPatAtom (loc, Some head) ->
 
689
      (match maybe_constructor head intern_pat aliases scopes with
 
690
         | ConstrPat (c,idspl) ->
 
691
             check_constructor_length genv loc c idspl [];
 
692
             let (ids',pll) = product_of_cases_patterns ids idspl in
 
693
             (ids,List.map (fun (asubst,pl) ->
 
694
               (asubst, PatCstr (loc,c,pl,alias_of aliases))) pll)
 
695
         | VarPat id ->
 
696
             let ids,asubst = merge_aliases aliases id in
 
697
             (ids,[asubst, PatVar (loc,alias_of (ids,asubst))]))
 
698
  | CPatAtom (loc, None) ->
 
699
      (ids,[asubst, PatVar (loc,alias_of aliases)])
 
700
  | CPatOr (loc, pl) ->
 
701
      assert (pl <> []);
 
702
      let pl' = List.map (intern_pat scopes aliases tmp_scope) pl in
 
703
      let (idsl,pl') = List.split pl' in
 
704
      let ids = List.hd idsl in
 
705
      check_or_pat_variables loc ids (List.tl idsl);
 
706
      (ids,List.flatten pl')
 
707
 
 
708
(**********************************************************************)
 
709
(* Fix and CoFix                                                      *)
 
710
 
 
711
(**********************************************************************)
 
712
(* Utilities for binders                                              *)
 
713
 
 
714
let check_capture loc ty = function
 
715
  | Name id when occur_var_constr_expr id ty ->
 
716
      raise (InternalisationError (loc,VariableCapture id))
 
717
  | _ ->
 
718
      ()
 
719
 
 
720
let locate_if_isevar loc na = function
 
721
  | RHole _ -> 
 
722
      (try match na with
 
723
        | Name id ->  Reserve.find_reserved_type id
 
724
        | Anonymous -> raise Not_found 
 
725
      with Not_found -> RHole (loc, Evd.BinderType na))
 
726
  | x -> x
 
727
 
 
728
let check_hidden_implicit_parameters id (_,_,_,(indnames,_)) =
 
729
  if List.mem id indnames then
 
730
    errorlabstrm "" (strbrk "A parameter or name of an inductive type " ++
 
731
    pr_id id ++ strbrk " must not be used as a bound variable in the type \
 
732
of its constructor.")
 
733
 
 
734
let push_name_env ?(fail_anonymous=false) lvar (ids,unb,tmpsc,scopes as env) = function
 
735
  | Anonymous -> 
 
736
      if fail_anonymous then errorlabstrm "" (str "Anonymous variables not allowed");
 
737
      env
 
738
  | Name id -> 
 
739
      check_hidden_implicit_parameters id lvar;
 
740
      (Idset.add id ids, unb,tmpsc,scopes)
 
741
 
 
742
let push_loc_name_env ?(fail_anonymous=false) lvar (ids,unb,tmpsc,scopes as env) loc = function
 
743
  | Anonymous -> 
 
744
      if fail_anonymous then user_err_loc (loc,"", str "Anonymous variables not allowed");
 
745
      env
 
746
  | Name id -> 
 
747
      check_hidden_implicit_parameters id lvar;
 
748
      Dumpglob.dump_binding loc id;
 
749
      (Idset.add id ids,unb,tmpsc,scopes)
 
750
 
 
751
let intern_generalized_binder ?(fail_anonymous=false) intern_type lvar
 
752
    (ids,unb,tmpsc,sc as env) bl (loc, na) b b' t ty =
 
753
  let ty = 
 
754
    if t then ty else
 
755
      Implicit_quantifiers.implicit_application ids
 
756
        Implicit_quantifiers.combine_params_freevar ty
 
757
  in
 
758
  let ty' = intern_type (ids,true,tmpsc,sc) ty in
 
759
  let fvs = Implicit_quantifiers.free_vars_of_rawconstr ~bound:ids ty' in
 
760
  let env' = List.fold_left (fun env (x, l) -> push_loc_name_env ~fail_anonymous lvar env l (Name x)) env fvs in
 
761
  let bl = List.map (fun (id, loc) -> (Name id, b, None, RHole (loc, Evd.BinderType (Name id)))) fvs in
 
762
  let na = match na with
 
763
    | Anonymous -> 
 
764
        if fail_anonymous then na 
 
765
        else
 
766
          let name = 
 
767
            let id = 
 
768
              match ty with
 
769
              | CApp (_, (_, CRef (Ident (loc,id))), _) -> id
 
770
              | _ -> id_of_string "H"
 
771
            in Implicit_quantifiers.make_fresh ids (Global.env ()) id
 
772
          in Name name
 
773
    | _ -> na
 
774
  in (push_loc_name_env ~fail_anonymous lvar env' loc na), (na,b',None,ty') :: List.rev bl
 
775
 
 
776
let intern_local_binder_aux ?(fail_anonymous=false) intern intern_type lvar ((ids,unb,ts,sc as env),bl) = function
 
777
  | LocalRawAssum(nal,bk,ty) ->
 
778
      (match bk with
 
779
      | Default k ->
 
780
          let (loc,na) = List.hd nal in
 
781
          (* TODO: fail if several names with different implicit types *)
 
782
          let ty = locate_if_isevar loc na (intern_type env ty) in
 
783
            List.fold_left
 
784
              (fun ((ids,unb,ts,sc),bl) (_,na) ->
 
785
                ((name_fold Idset.add na ids,unb,ts,sc), (na,k,None,ty)::bl))
 
786
              (env,bl) nal
 
787
      | Generalized (b,b',t) ->
 
788
          let env, b = intern_generalized_binder ~fail_anonymous intern_type lvar env bl (List.hd nal) b b' t ty in
 
789
            env, b @ bl)
 
790
  | LocalRawDef((loc,na),def) ->
 
791
      ((name_fold Idset.add na ids,unb,ts,sc),
 
792
      (na,Explicit,Some(intern env def),RHole(loc,Evd.BinderType na))::bl)
 
793
 
 
794
let intern_generalization intern (ids,unb,tmp_scope,scopes as env) lvar loc bk ak c =
 
795
  let c = intern (ids,true,tmp_scope,scopes) c in
 
796
  let fvs = Implicit_quantifiers.free_vars_of_rawconstr ~bound:ids c in
 
797
  let env', c' = 
 
798
    let abs = 
 
799
      let pi = 
 
800
        match ak with
 
801
        | Some AbsPi -> true
 
802
        | None when tmp_scope = Some Notation.type_scope 
 
803
            || List.mem Notation.type_scope scopes -> true
 
804
        | _ -> false
 
805
      in 
 
806
        if pi then
 
807
          (fun (id, loc') acc ->
 
808
            RProd (join_loc loc' loc, Name id, bk, RHole (loc', Evd.BinderType (Name id)), acc))
 
809
        else
 
810
          (fun (id, loc') acc -> 
 
811
            RLambda (join_loc loc' loc, Name id, bk, RHole (loc', Evd.BinderType (Name id)), acc))
 
812
    in
 
813
      List.fold_right (fun (id, loc as lid) (env, acc) -> 
 
814
        let env' = push_loc_name_env lvar env loc (Name id) in
 
815
          (env', abs lid acc)) fvs (env,c) 
 
816
  in c'
 
817
 
 
818
(**********************************************************************)
 
819
(* Utilities for application                                          *)
 
820
 
 
821
let merge_impargs l args =
 
822
  List.fold_right (fun a l ->
 
823
    match a with 
 
824
      | (_,Some (_,(ExplByName id as x))) when 
 
825
          List.exists (function (_,Some (_,y)) -> x=y | _ -> false) args -> l
 
826
      | _ -> a::l)
 
827
    l args 
 
828
 
 
829
let check_projection isproj nargs r = 
 
830
  match (r,isproj) with
 
831
  | RRef (loc, ref), Some _ ->
 
832
      (try
 
833
        let n = Recordops.find_projection_nparams ref + 1 in
 
834
        if nargs <> n then
 
835
          user_err_loc (loc,"",str "Projection has not the right number of explicit parameters.");
 
836
      with Not_found -> 
 
837
        user_err_loc
 
838
        (loc,"",pr_global_env Idset.empty ref ++ str " is not a registered projection."))
 
839
  | _, Some _ -> user_err_loc (loc_of_rawconstr r, "", str "Not a projection.")
 
840
  | _, None -> ()
 
841
 
 
842
let get_implicit_name n imps =
 
843
  Some (Impargs.name_of_implicit (List.nth imps (n-1)))
 
844
 
 
845
let set_hole_implicit i = function
 
846
  | RRef (loc,r) -> (loc,Evd.ImplicitArg (r,i))
 
847
  | RVar (loc,id) -> (loc,Evd.ImplicitArg (VarRef id,i))
 
848
  | _ -> anomaly "Only refs have implicits"
 
849
 
 
850
let exists_implicit_name id =
 
851
  List.exists (fun imp -> is_status_implicit imp & id = name_of_implicit imp)
 
852
 
 
853
let extract_explicit_arg imps args =
 
854
  let rec aux = function
 
855
  | [] -> [],[]
 
856
  | (a,e)::l ->
 
857
      let (eargs,rargs) = aux l in
 
858
      match e with
 
859
      | None -> (eargs,a::rargs)
 
860
      | Some (loc,pos) ->
 
861
          let id = match pos with
 
862
          | ExplByName id ->
 
863
              if not (exists_implicit_name id imps) then
 
864
                user_err_loc
 
865
                  (loc,"",str "Wrong argument name: " ++ pr_id id ++ str ".");
 
866
              if List.mem_assoc id eargs then
 
867
                user_err_loc (loc,"",str "Argument name " ++ pr_id id
 
868
                ++ str " occurs more than once.");
 
869
              id
 
870
          | ExplByPos (p,_id) ->
 
871
              let id =
 
872
                try 
 
873
                  let imp = List.nth imps (p-1) in
 
874
                  if not (is_status_implicit imp) then failwith "imp";
 
875
                  name_of_implicit imp
 
876
                with Failure _ (* "nth" | "imp" *) ->
 
877
                  user_err_loc
 
878
                    (loc,"",str"Wrong argument position: " ++ int p ++ str ".")
 
879
              in
 
880
              if List.mem_assoc id eargs then
 
881
                user_err_loc (loc,"",str"Argument at position " ++ int p ++
 
882
                  str " is mentioned more than once.");
 
883
              id in
 
884
          ((id,(loc,a))::eargs,rargs)
 
885
  in aux args
 
886
 
 
887
(**********************************************************************)
 
888
(* Main loop                                                          *)
 
889
 
 
890
let internalise sigma globalenv env allow_patvar lvar c =
 
891
  let rec intern (ids,unb,tmp_scope,scopes as env) = function
 
892
    | CRef ref as x ->
 
893
        let (c,imp,subscopes,l),_ =
 
894
          intern_applied_reference intern env lvar [] ref in
 
895
        (match intern_impargs c env imp subscopes l with
 
896
          | [] -> c
 
897
          | l -> RApp (constr_loc x, c, l))
 
898
    | CFix (loc, (locid,iddef), dl) ->
 
899
        let lf = List.map (fun ((_, id),_,_,_,_) -> id) dl in
 
900
        let dl = Array.of_list dl in
 
901
        let n =
 
902
          try list_index0 iddef lf
 
903
          with Not_found ->
 
904
            raise (InternalisationError (locid,UnboundFixName (false,iddef)))
 
905
        in
 
906
        let idl = Array.map
 
907
          (fun (id,(n,order),bl,ty,bd) ->
 
908
             let intern_ro_arg c f =
 
909
               let idx = 
 
910
                 match n with
 
911
                     Some (loc, n) -> list_index0 (Name n) (List.map snd (names_of_local_assums bl))
 
912
                   | None -> 0
 
913
               in
 
914
               let before, after = list_chop idx bl in
 
915
               let ((ids',_,_,_) as env',rbefore) =
 
916
                 List.fold_left intern_local_binder (env,[]) before in
 
917
               let ro =
 
918
                 match c with 
 
919
                   | None -> RStructRec 
 
920
                   | Some c' -> f (intern (ids', unb, tmp_scope, scopes) c') 
 
921
               in 
 
922
               let n' = Option.map (fun _ -> List.length before) n in
 
923
                 n', ro, List.fold_left intern_local_binder (env',rbefore) after
 
924
             in
 
925
             let n, ro, ((ids',_,_,_),rbl) =
 
926
               (match order with
 
927
                 | CStructRec -> 
 
928
                     intern_ro_arg None (fun _ -> RStructRec)
 
929
                 | CWfRec c ->
 
930
                     intern_ro_arg (Some c) (fun r -> RWfRec r)
 
931
                 | CMeasureRec c ->
 
932
                     intern_ro_arg (Some c) (fun r -> RMeasureRec r))
 
933
             in
 
934
             let ids'' = List.fold_right Idset.add lf ids' in
 
935
             ((n, ro), List.rev rbl, 
 
936
             intern_type (ids',unb,tmp_scope,scopes) ty,
 
937
             intern (ids'',unb,None,scopes) bd)) dl in
 
938
        RRec (loc,RFix 
 
939
              (Array.map (fun (ro,_,_,_) -> ro) idl,n),
 
940
              Array.of_list lf,
 
941
              Array.map (fun (_,bl,_,_) -> bl) idl,
 
942
              Array.map (fun (_,_,ty,_) -> ty) idl,
 
943
              Array.map (fun (_,_,_,bd) -> bd) idl)
 
944
    | CCoFix (loc, (locid,iddef), dl) ->
 
945
        let lf = List.map (fun ((_, id),_,_,_) -> id) dl in
 
946
        let dl = Array.of_list dl in
 
947
        let n =
 
948
          try list_index0 iddef lf
 
949
          with Not_found ->
 
950
            raise (InternalisationError (locid,UnboundFixName (true,iddef)))
 
951
        in
 
952
        let idl = Array.map
 
953
          (fun (id,bl,ty,bd) ->
 
954
            let ((ids',_,_,_),rbl) =
 
955
              List.fold_left intern_local_binder (env,[]) bl in
 
956
            let ids'' = List.fold_right Idset.add lf ids' in
 
957
            (List.rev rbl,
 
958
             intern_type (ids',unb,tmp_scope,scopes) ty,
 
959
             intern (ids'',unb,None,scopes) bd)) dl in
 
960
        RRec (loc,RCoFix n,
 
961
              Array.of_list lf,
 
962
              Array.map (fun (bl,_,_) -> bl) idl,
 
963
              Array.map (fun (_,ty,_) -> ty) idl,
 
964
              Array.map (fun (_,_,bd) -> bd) idl)
 
965
    | CArrow (loc,c1,c2) ->
 
966
        RProd (loc, Anonymous, Explicit, intern_type env c1, intern_type env c2)
 
967
    | CProdN (loc,[],c2) ->
 
968
        intern_type env c2
 
969
    | CProdN (loc,(nal,bk,ty)::bll,c2) ->
 
970
        iterate_prod loc env bk ty (CProdN (loc, bll, c2)) nal
 
971
    | CLambdaN (loc,[],c2) ->
 
972
        intern env c2
 
973
    | CLambdaN (loc,(nal,bk,ty)::bll,c2) ->
 
974
        iterate_lam loc (reset_tmp_scope env) bk ty (CLambdaN (loc, bll, c2)) nal
 
975
    | CLetIn (loc,(loc1,na),c1,c2) ->
 
976
        RLetIn (loc, na, intern (reset_tmp_scope env) c1,
 
977
          intern (push_loc_name_env lvar env loc1 na) c2)
 
978
    | CNotation (loc,"- _",([CPrim (_,Numeral p)],[]))
 
979
        when Bigint.is_strictly_pos p -> 
 
980
        intern env (CPrim (loc,Numeral (Bigint.neg p)))
 
981
    | CNotation (_,"( _ )",([a],[])) -> intern env a
 
982
    | CNotation (loc,ntn,args) ->
 
983
        intern_notation intern env loc ntn args
 
984
    | CGeneralization (loc,b,a,c) ->
 
985
        intern_generalization intern env lvar loc b a c
 
986
    | CPrim (loc, p) ->
 
987
        let c,df = Notation.interp_prim_token loc p (tmp_scope,scopes) in
 
988
        Dumpglob.dump_notation_location (fst (unloc loc)) df;
 
989
        c
 
990
    | CDelimiters (loc, key, e) ->
 
991
        intern (ids,unb,None,find_delimiters_scope loc key::scopes) e
 
992
    | CAppExpl (loc, (isproj,ref), args) ->
 
993
        let (f,_,args_scopes,_),args =
 
994
          let args = List.map (fun a -> (a,None)) args in
 
995
          intern_applied_reference intern env lvar args ref in
 
996
        check_projection isproj (List.length args) f;
 
997
        RApp (loc, f, intern_args env args_scopes (List.map fst args))
 
998
    | CApp (loc, (isproj,f), args) ->
 
999
        let isproj,f,args = match f with
 
1000
          (* Compact notations like "t.(f args') args" *)
 
1001
          | CApp (_,(Some _,f), args') when isproj=None -> isproj,f,args'@args
 
1002
          (* Don't compact "(f args') args" to resolve implicits separately *)
 
1003
          | _ -> isproj,f,args in
 
1004
        let (c,impargs,args_scopes,l),args =
 
1005
          match f with
 
1006
            | CRef ref -> intern_applied_reference intern env lvar args ref
 
1007
            | CNotation (loc,ntn,([],[])) ->
 
1008
                let c = intern_notation intern env loc ntn ([],[]) in
 
1009
                find_appl_head_data lvar c, args
 
1010
            | x -> (intern env f,[],[],[]), args in
 
1011
        let args = 
 
1012
          intern_impargs c env impargs args_scopes (merge_impargs l args) in
 
1013
        check_projection isproj (List.length args) c;
 
1014
        (match c with 
 
1015
          (* Now compact "(f args') args" *)
 
1016
          | RApp (loc', f', args') -> RApp (join_loc loc' loc, f',args'@args)
 
1017
          | _ -> RApp (loc, c, args))
 
1018
    | CRecord (loc, w, fs) ->
 
1019
        let id, _ = List.hd fs in
 
1020
        let record = 
 
1021
          let (id,_,_,_),_ = intern_applied_reference intern env lvar [] (Ident id) in
 
1022
            match id with
 
1023
            | RRef (loc, ref) -> 
 
1024
                (try Recordops.find_projection ref
 
1025
                  with Not_found -> user_err_loc (loc, "intern", str"Not a projection"))
 
1026
            | c -> user_err_loc (loc_of_rawconstr id, "intern", str"Not a projection")
 
1027
        in
 
1028
        let args =
 
1029
          let pars = list_make record.Recordops.s_EXPECTEDPARAM (CHole (loc, None)) in      
 
1030
          let fields, rest = 
 
1031
            List.fold_left (fun (args, rest as acc) (na, b) ->
 
1032
              if b then 
 
1033
                try 
 
1034
                  let id = out_name na in
 
1035
                  let _, t = List.assoc id rest in
 
1036
                    t :: args, List.remove_assoc id rest
 
1037
                with _ -> CHole (loc, Some (Evd.QuestionMark (Evd.Define true))) :: args, rest
 
1038
              else acc) ([], List.map (fun ((loc, id), t) -> id, (loc, t)) fs) record.Recordops.s_PROJKIND
 
1039
          in 
 
1040
            if rest <> [] then 
 
1041
              let id, (loc, t) = List.hd rest in
 
1042
                user_err_loc (loc,"intern",(str "Unknown field name " ++ pr_id id))
 
1043
            else pars @ List.rev fields
 
1044
        in
 
1045
        let constrname = 
 
1046
          Qualid (loc, shortest_qualid_of_global Idset.empty (ConstructRef record.Recordops.s_CONST)) 
 
1047
        in
 
1048
        let app = CAppExpl (loc, (None, constrname), args) in
 
1049
          intern env app
 
1050
 
 
1051
    | CCases (loc, sty, rtnpo, tms, eqns) ->
 
1052
        let tms,env' = List.fold_right
 
1053
          (fun citm (inds,env) ->
 
1054
            let (tm,ind),nal = intern_case_item env citm in
 
1055
            (tm,ind)::inds,List.fold_left (push_name_env lvar) env nal)
 
1056
          tms ([],env) in
 
1057
        let rtnpo = Option.map (intern_type env') rtnpo in
 
1058
        let eqns' = List.map (intern_eqn (List.length tms) env) eqns in
 
1059
        RCases (loc, sty, rtnpo, tms, List.flatten eqns')
 
1060
    | CLetTuple (loc, nal, (na,po), b, c) ->
 
1061
        let env' = reset_tmp_scope env in
 
1062
        let ((b',(na',_)),ids) = intern_case_item env' (b,(na,None)) in
 
1063
        let env'' = List.fold_left (push_name_env lvar) env ids in
 
1064
        let p' = Option.map (intern_type env'') po in
 
1065
        RLetTuple (loc, nal, (na', p'), b',
 
1066
                   intern (List.fold_left (push_name_env lvar) env nal) c)
 
1067
    | CIf (loc, c, (na,po), b1, b2) ->
 
1068
        let env' = reset_tmp_scope env in
 
1069
        let ((c',(na',_)),ids) = intern_case_item env' (c,(na,None)) in
 
1070
        let env'' = List.fold_left (push_name_env lvar) env ids in
 
1071
        let p' = Option.map (intern_type env'') po in
 
1072
        RIf (loc, c', (na', p'), intern env b1, intern env b2)
 
1073
    | CHole (loc, k) -> 
 
1074
        RHole (loc, match k with Some k -> k | None -> Evd.QuestionMark (Evd.Define true))
 
1075
    | CPatVar (loc, n) when allow_patvar ->
 
1076
        RPatVar (loc, n)
 
1077
    | CPatVar (loc, _) ->
 
1078
        raise (InternalisationError (loc,IllegalMetavariable))
 
1079
    | CEvar (loc, n, l) ->
 
1080
        REvar (loc, n, Option.map (List.map (intern env)) l)
 
1081
    | CSort (loc, s) ->
 
1082
        RSort(loc,s)
 
1083
    | CCast (loc, c1, CastConv (k, c2)) ->
 
1084
        RCast (loc,intern env c1, CastConv (k, intern_type env c2))
 
1085
    | CCast (loc, c1, CastCoerce) ->
 
1086
        RCast (loc,intern env c1, CastCoerce)
 
1087
 
 
1088
    | CDynamic (loc,d) -> RDynamic (loc,d)
 
1089
 
 
1090
  and intern_type env = intern (set_type_scope env)
 
1091
 
 
1092
  and intern_local_binder env bind = 
 
1093
    intern_local_binder_aux intern intern_type lvar env bind
 
1094
 
 
1095
  (* Expands a multiple pattern into a disjunction of multiple patterns *)
 
1096
  and intern_multiple_pattern scopes n (loc,pl) =
 
1097
    let idsl_pll = 
 
1098
      List.map (intern_cases_pattern globalenv scopes ([],[]) None) pl in
 
1099
    check_number_of_pattern loc n pl;
 
1100
    product_of_cases_patterns [] idsl_pll
 
1101
 
 
1102
  (* Expands a disjunction of multiple pattern *)
 
1103
  and intern_disjunctive_multiple_pattern scopes loc n mpl =
 
1104
    assert (mpl <> []);
 
1105
    let mpl' = List.map (intern_multiple_pattern scopes n) mpl in
 
1106
    let (idsl,mpl') = List.split mpl' in
 
1107
    let ids = List.hd idsl in
 
1108
    check_or_pat_variables loc ids (List.tl idsl);
 
1109
    (ids,List.flatten mpl')
 
1110
 
 
1111
  (* Expands a pattern-matching clause [lhs => rhs] *)
 
1112
  and intern_eqn n (ids,unb,tmp_scope,scopes) (loc,lhs,rhs) =
 
1113
    let eqn_ids,pll = intern_disjunctive_multiple_pattern scopes loc n lhs in
 
1114
    (* Linearity implies the order in ids is irrelevant *)
 
1115
    check_linearity lhs eqn_ids;
 
1116
    let env_ids = List.fold_right Idset.add eqn_ids ids in
 
1117
    List.map (fun (asubst,pl) ->
 
1118
      let rhs = replace_vars_constr_expr asubst rhs in
 
1119
      List.iter message_redundant_alias asubst;
 
1120
      let rhs' = intern (env_ids,unb,tmp_scope,scopes) rhs in
 
1121
      (loc,eqn_ids,pl,rhs')) pll
 
1122
 
 
1123
  and intern_case_item (vars,unb,_,scopes as env) (tm,(na,t)) =
 
1124
    let tm' = intern env tm in
 
1125
    let ids,typ = match t with
 
1126
    | Some t -> 
 
1127
        let tids = ids_of_cases_indtype t in
 
1128
        let tids = List.fold_right Idset.add tids Idset.empty in
 
1129
        let t = intern_type (tids,unb,None,scopes) t in
 
1130
        let loc,ind,l = match t with
 
1131
            | RRef (loc,IndRef ind) -> (loc,ind,[])
 
1132
            | RApp (loc,RRef (_,IndRef ind),l) -> (loc,ind,l)
 
1133
            | _ -> error_bad_inductive_type (loc_of_rawconstr t) in
 
1134
        let nparams, nrealargs = inductive_nargs globalenv ind in
 
1135
        let nindargs = nparams + nrealargs in
 
1136
        if List.length l <> nindargs then
 
1137
          error_wrong_numarg_inductive_loc loc globalenv ind nindargs;
 
1138
        let nal = List.map (function
 
1139
          | RHole loc -> Anonymous
 
1140
          | RVar (_,id) -> Name id
 
1141
          | c -> user_err_loc (loc_of_rawconstr c,"",str "Not a name.")) l in
 
1142
        let parnal,realnal = list_chop nparams nal in
 
1143
        if List.exists ((<>) Anonymous) parnal then
 
1144
          error_inductive_parameter_not_implicit loc;
 
1145
        realnal, Some (loc,ind,nparams,realnal)
 
1146
    | None -> 
 
1147
        [], None in
 
1148
    let na = match tm', na with
 
1149
      | RVar (_,id), None when Idset.mem id vars -> Name id
 
1150
      | _, None -> Anonymous
 
1151
      | _, Some na -> na in
 
1152
    (tm',(na,typ)), na::ids
 
1153
      
 
1154
  and iterate_prod loc2 env bk ty body nal =
 
1155
    let rec default env bk = function
 
1156
    | (loc1,na)::nal ->
 
1157
        if nal <> [] then check_capture loc1 ty na;
 
1158
        let body = default (push_loc_name_env lvar env loc1 na) bk nal in
 
1159
        let ty = locate_if_isevar loc1 na (intern_type env ty) in
 
1160
          RProd (join_loc loc1 loc2, na, bk, ty, body)
 
1161
    | [] -> intern_type env body
 
1162
    in
 
1163
      match bk with
 
1164
        | Default b -> default env b nal
 
1165
        | Generalized (b,b',t) -> 
 
1166
            let env, ibind = intern_generalized_binder intern_type lvar
 
1167
              env [] (List.hd nal) b b' t ty in
 
1168
            let body = intern_type env body in
 
1169
              it_mkRProd ibind body
 
1170
                                           
 
1171
  and iterate_lam loc2 env bk ty body nal = 
 
1172
    let rec default env bk = function 
 
1173
      | (loc1,na)::nal ->
 
1174
          if nal <> [] then check_capture loc1 ty na;
 
1175
          let body = default (push_loc_name_env lvar env loc1 na) bk nal in
 
1176
          let ty = locate_if_isevar loc1 na (intern_type env ty) in
 
1177
            RLambda (join_loc loc1 loc2, na, bk, ty, body)
 
1178
      | [] -> intern env body
 
1179
    in match bk with
 
1180
      | Default b -> default env b nal
 
1181
      | Generalized (b, b', t) ->         
 
1182
          let env, ibind = intern_generalized_binder intern_type lvar
 
1183
            env [] (List.hd nal) b b' t ty in
 
1184
          let body = intern env body in
 
1185
            it_mkRLambda ibind body
 
1186
              
 
1187
  and intern_impargs c env l subscopes args =
 
1188
    let eargs, rargs = extract_explicit_arg l args in
 
1189
    let rec aux n impl subscopes eargs rargs =
 
1190
      let (enva,subscopes') = apply_scope_env env subscopes in
 
1191
      match (impl,rargs) with
 
1192
      | (imp::impl', rargs) when is_status_implicit imp ->
 
1193
          begin try 
 
1194
            let id = name_of_implicit imp in
 
1195
            let (_,a) = List.assoc id eargs in
 
1196
            let eargs' = List.remove_assoc id eargs in
 
1197
            intern enva a :: aux (n+1) impl' subscopes' eargs' rargs
 
1198
          with Not_found ->
 
1199
          if rargs=[] & eargs=[] & not (maximal_insertion_of imp) then
 
1200
            (* Less regular arguments than expected: complete *)
 
1201
            (* with implicit arguments if maximal insertion is set *)
 
1202
            []
 
1203
          else
 
1204
            RHole (set_hole_implicit (n,get_implicit_name n l) c) :: 
 
1205
              aux (n+1) impl' subscopes' eargs rargs
 
1206
          end
 
1207
      | (imp::impl', a::rargs') ->
 
1208
          intern enva a :: aux (n+1) impl' subscopes' eargs rargs'
 
1209
      | (imp::impl', []) -> 
 
1210
          if eargs <> [] then 
 
1211
            (let (id,(loc,_)) = List.hd eargs in
 
1212
               user_err_loc (loc,"",str "Not enough non implicit
 
1213
            arguments to accept the argument bound to " ++ 
 
1214
                 pr_id id ++ str"."));
 
1215
          []
 
1216
      | ([], rargs) ->
 
1217
          assert (eargs = []);
 
1218
          intern_args env subscopes rargs
 
1219
    in aux 1 l subscopes eargs rargs
 
1220
 
 
1221
  and intern_args env subscopes = function
 
1222
    | [] -> []
 
1223
    | a::args ->
 
1224
        let (enva,subscopes) = apply_scope_env env subscopes in
 
1225
        (intern enva a) :: (intern_args env subscopes args)
 
1226
 
 
1227
  in 
 
1228
  try 
 
1229
    intern env c
 
1230
  with
 
1231
      InternalisationError (loc,e) ->
 
1232
        user_err_loc (loc,"internalize",explain_internalisation_error e)
 
1233
 
 
1234
(**************************************************************************)
 
1235
(* Functions to translate constr_expr into rawconstr                       *)
 
1236
(**************************************************************************)
 
1237
 
 
1238
let extract_ids env =
 
1239
  List.fold_right Idset.add 
 
1240
    (Termops.ids_of_rel_context (Environ.rel_context env))
 
1241
    Idset.empty
 
1242
 
 
1243
let intern_gen isarity sigma env
 
1244
               ?(impls=([],[])) ?(allow_patvar=false) ?(ltacvars=([],[]))
 
1245
               c =
 
1246
  let tmp_scope = 
 
1247
    if isarity then Some Notation.type_scope else None in
 
1248
    internalise sigma env (extract_ids env, false, tmp_scope,[])
 
1249
      allow_patvar (ltacvars,Environ.named_context env, [], impls) c
 
1250
      
 
1251
let intern_constr sigma env c = intern_gen false sigma env c 
 
1252
 
 
1253
let intern_type sigma env c = intern_gen true sigma env c 
 
1254
 
 
1255
let intern_pattern env patt =
 
1256
  try
 
1257
    intern_cases_pattern env [] ([],[]) None patt 
 
1258
  with 
 
1259
      InternalisationError (loc,e) ->
 
1260
        user_err_loc (loc,"internalize",explain_internalisation_error e)
 
1261
 
 
1262
 
 
1263
let intern_ltac isarity ltacvars sigma env c =
 
1264
  intern_gen isarity sigma env ~ltacvars:ltacvars c
 
1265
 
 
1266
type manual_implicits = (explicitation * (bool * bool)) list
 
1267
 
 
1268
(*********************************************************************)
 
1269
(* Functions to parse and interpret constructions *)
 
1270
 
 
1271
let interp_gen kind sigma env 
 
1272
               ?(impls=([],[])) ?(allow_patvar=false) ?(ltacvars=([],[]))
 
1273
               c =
 
1274
  let c = intern_gen (kind=IsType) ~impls ~allow_patvar ~ltacvars sigma env c in
 
1275
    Default.understand_gen kind sigma env c
 
1276
 
 
1277
let interp_constr sigma env c =
 
1278
  interp_gen (OfType None) sigma env c
 
1279
 
 
1280
let interp_type sigma env ?(impls=([],[])) c =
 
1281
  interp_gen IsType sigma env ~impls c
 
1282
 
 
1283
let interp_casted_constr sigma env ?(impls=([],[])) c typ =
 
1284
  interp_gen (OfType (Some typ)) sigma env ~impls c 
 
1285
 
 
1286
let interp_open_constr sigma env c =
 
1287
  Default.understand_tcc sigma env (intern_constr sigma env c)
 
1288
 
 
1289
let interp_constr_judgment sigma env c =
 
1290
  Default.understand_judgment sigma env (intern_constr sigma env c)
 
1291
 
 
1292
let interp_constr_evars_gen_impls ?evdref
 
1293
    env ?(impls=([],[])) kind c =
 
1294
  match evdref with 
 
1295
    | None -> 
 
1296
        let c = intern_gen (kind=IsType) ~impls Evd.empty env c in
 
1297
        let imps = Implicit_quantifiers.implicits_of_rawterm c in
 
1298
          Default.understand_gen kind Evd.empty env c, imps
 
1299
    | Some evdref ->
 
1300
        let c = intern_gen (kind=IsType) ~impls (Evd.evars_of !evdref) env c in
 
1301
        let imps = Implicit_quantifiers.implicits_of_rawterm c in
 
1302
          Default.understand_tcc_evars evdref env kind c, imps
 
1303
 
 
1304
let interp_constr_evars_gen evdref env ?(impls=([],[])) kind c =
 
1305
  let c = intern_gen (kind=IsType) ~impls (Evd.evars_of !evdref) env c in
 
1306
    Default.understand_tcc_evars evdref env kind c
 
1307
      
 
1308
let interp_casted_constr_evars_impls ?evdref
 
1309
    env ?(impls=([],[])) c typ =
 
1310
  interp_constr_evars_gen_impls ?evdref env ~impls (OfType (Some typ)) c
 
1311
 
 
1312
let interp_type_evars_impls ?evdref env ?(impls=([],[])) c =
 
1313
  interp_constr_evars_gen_impls ?evdref env IsType ~impls c
 
1314
 
 
1315
let interp_constr_evars_impls ?evdref env ?(impls=([],[])) c =
 
1316
  interp_constr_evars_gen_impls ?evdref env (OfType None) ~impls c
 
1317
 
 
1318
let interp_casted_constr_evars evdref env ?(impls=([],[])) c typ =
 
1319
  interp_constr_evars_gen evdref env ~impls (OfType (Some typ)) c
 
1320
 
 
1321
let interp_type_evars evdref env ?(impls=([],[])) c =
 
1322
  interp_constr_evars_gen evdref env IsType ~impls c
 
1323
 
 
1324
let interp_constr_judgment_evars evdref env c =
 
1325
  Default.understand_judgment_tcc evdref env
 
1326
    (intern_constr (Evd.evars_of !evdref) env c)
 
1327
 
 
1328
type ltac_sign = identifier list * unbound_ltac_var_map
 
1329
 
 
1330
let intern_constr_pattern sigma env ?(as_type=false) ?(ltacvars=([],[])) c =
 
1331
  let c = intern_gen as_type ~allow_patvar:true ~ltacvars sigma env c in
 
1332
  pattern_of_rawconstr c
 
1333
 
 
1334
let interp_aconstr impls (vars,varslist) a =
 
1335
  let env = Global.env () in
 
1336
  (* [vl] is intended to remember the scope of the free variables of [a] *)
 
1337
  let vl = List.map (fun id -> (id,ref None)) (vars@varslist) in
 
1338
  let c = internalise Evd.empty (Global.env()) (extract_ids env, false, None, [])
 
1339
    false (([],[]),Environ.named_context env,vl,([],impls)) a in
 
1340
  (* Translate and check that [c] has all its free variables bound in [vars] *)
 
1341
  let a = aconstr_of_rawconstr vars c in
 
1342
  (* Returns [a] and the ordered list of variables with their scopes *)
 
1343
  (* Variables occurring in binders have no relevant scope since bound *)
 
1344
  let vl = List.map (fun (id,r) -> 
 
1345
    (id,match !r with None -> None,[] | Some (a,l) -> a,l)) vl in
 
1346
  list_chop (List.length vars) vl, a
 
1347
 
 
1348
(* Interpret binders and contexts  *)
 
1349
 
 
1350
let interp_binder sigma env na t =
 
1351
  let t = intern_gen true sigma env t in
 
1352
  let t' = locate_if_isevar (loc_of_rawconstr t) na t in
 
1353
  Default.understand_type sigma env t'
 
1354
 
 
1355
let interp_binder_evars evdref env na t =
 
1356
  let t = intern_gen true (Evd.evars_of !evdref) env t in
 
1357
  let t' = locate_if_isevar (loc_of_rawconstr t) na t in
 
1358
  Default.understand_tcc_evars evdref env IsType t'
 
1359
 
 
1360
open Environ
 
1361
open Term
 
1362
 
 
1363
let my_intern_constr sigma env lvar acc c =
 
1364
  internalise sigma env acc false lvar c
 
1365
 
 
1366
let my_intern_type sigma env lvar acc c = my_intern_constr sigma env lvar (set_type_scope acc) c
 
1367
 
 
1368
let intern_context fail_anonymous sigma env params =
 
1369
  let lvar = (([],[]),Environ.named_context env, [], ([], [])) in
 
1370
    snd (List.fold_left
 
1371
            (intern_local_binder_aux ~fail_anonymous (my_intern_constr sigma env lvar) (my_intern_type sigma env lvar) lvar)
 
1372
            ((extract_ids env,false,None,[]), []) params)
 
1373
 
 
1374
let interp_context_gen understand_type understand_judgment env bl = 
 
1375
  let (env, par, _, impls) =
 
1376
    List.fold_left
 
1377
      (fun (env,params,n,impls) (na, k, b, t) ->
 
1378
        match b with
 
1379
            None ->
 
1380
              let t' = locate_if_isevar (loc_of_rawconstr t) na t in
 
1381
              let t = understand_type env t' in
 
1382
              let d = (na,None,t) in
 
1383
              let impls = 
 
1384
                if k = Implicit then
 
1385
                  let na = match na with Name n -> Some n | Anonymous -> None in
 
1386
                    (ExplByPos (n, na), (true, true)) :: impls
 
1387
                else impls
 
1388
              in
 
1389
                (push_rel d env, d::params, succ n, impls)
 
1390
          | Some b ->
 
1391
              let c = understand_judgment env b in
 
1392
              let d = (na, Some c.uj_val, c.uj_type) in
 
1393
                (push_rel d env, d::params, succ n, impls))
 
1394
      (env,[],1,[]) (List.rev bl)
 
1395
  in (env, par), impls
 
1396
 
 
1397
let interp_context ?(fail_anonymous=false) sigma env params = 
 
1398
  let bl = intern_context fail_anonymous sigma env params in
 
1399
    interp_context_gen (Default.understand_type sigma) 
 
1400
      (Default.understand_judgment sigma) env bl
 
1401
    
 
1402
let interp_context_evars ?(fail_anonymous=false) evdref env params =
 
1403
  let bl = intern_context fail_anonymous (Evd.evars_of !evdref) env params in
 
1404
    interp_context_gen (fun env t -> Default.understand_tcc_evars evdref env IsType t)
 
1405
      (Default.understand_judgment_tcc evdref) env bl
 
1406
    
 
1407
(**********************************************************************)
 
1408
(* Locating reference, possibly via an abbreviation *)
 
1409
 
 
1410
let locate_reference qid =
 
1411
  match Nametab.extended_locate qid with
 
1412
    | TrueGlobal ref -> ref
 
1413
    | SyntacticDef kn -> 
 
1414
        match Syntax_def.search_syntactic_definition dummy_loc kn with
 
1415
          | [],ARef ref -> ref
 
1416
          | _ -> raise Not_found
 
1417
 
 
1418
let is_global id =
 
1419
  try 
 
1420
    let _ = locate_reference (make_short_qualid id) in true
 
1421
  with Not_found -> 
 
1422
    false
 
1423
 
 
1424
let global_reference id = 
 
1425
  constr_of_global (locate_reference (make_short_qualid id))
 
1426
 
 
1427
let construct_reference ctx id =
 
1428
  try
 
1429
    Term.mkVar (let _ = Sign.lookup_named id ctx in id)
 
1430
  with Not_found ->
 
1431
    global_reference id
 
1432
 
 
1433
let global_reference_in_absolute_module dir id = 
 
1434
  constr_of_global (Nametab.absolute_reference (Libnames.make_path dir id))
 
1435