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

« back to all changes in this revision

Viewing changes to pretyping/evarutil.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: evarutil.ml 12107 2009-04-25 19:58:24Z herbelin $ *)
 
10
 
 
11
open Util
 
12
open Pp
 
13
open Names
 
14
open Nameops
 
15
open Univ
 
16
open Term
 
17
open Termops
 
18
open Sign
 
19
open Pre_env
 
20
open Environ
 
21
open Evd
 
22
open Reductionops
 
23
open Pretype_errors
 
24
open Retyping
 
25
 
 
26
(* Expanding existential variables (pretyping.ml) *)
 
27
(* 1- whd_ise fails if an existential is undefined *)
 
28
 
 
29
exception Uninstantiated_evar of existential_key
 
30
 
 
31
let rec whd_ise sigma c =
 
32
  match kind_of_term c with
 
33
    | Evar (evk,args as ev) when Evd.mem sigma evk ->
 
34
        if Evd.is_defined sigma evk then
 
35
          whd_ise sigma (existential_value sigma ev)
 
36
        else raise (Uninstantiated_evar evk)
 
37
  | _ -> c
 
38
 
 
39
 
 
40
(* Expand evars, possibly in the head of an application *)
 
41
let whd_castappevar_stack sigma c = 
 
42
  let rec whrec (c, l as s) =
 
43
    match kind_of_term c with
 
44
      | Evar (evk,args as ev) when Evd.mem sigma evk & Evd.is_defined sigma evk
 
45
          -> whrec (existential_value sigma ev, l)
 
46
      | Cast (c,_,_) -> whrec (c, l)
 
47
      | App (f,args) -> whrec (f, Array.fold_right (fun a l -> a::l) args l)
 
48
      | _ -> s
 
49
  in 
 
50
  whrec (c, [])
 
51
 
 
52
let whd_castappevar sigma c = applist (whd_castappevar_stack sigma c)
 
53
 
 
54
let nf_evar = Pretype_errors.nf_evar
 
55
let j_nf_evar = Pretype_errors.j_nf_evar
 
56
let jl_nf_evar = Pretype_errors.jl_nf_evar
 
57
let jv_nf_evar = Pretype_errors.jv_nf_evar
 
58
let tj_nf_evar = Pretype_errors.tj_nf_evar
 
59
 
 
60
let nf_named_context_evar sigma ctx = 
 
61
  Sign.map_named_context (Reductionops.nf_evar sigma) ctx
 
62
 
 
63
let nf_rel_context_evar sigma ctx = 
 
64
  Sign.map_rel_context (Reductionops.nf_evar sigma) ctx
 
65
    
 
66
let nf_env_evar sigma env = 
 
67
  let nc' = nf_named_context_evar sigma (Environ.named_context env) in
 
68
  let rel' = nf_rel_context_evar sigma (Environ.rel_context env) in
 
69
    push_rel_context rel' (reset_with_named_context (val_of_named_context nc') env)
 
70
 
 
71
let nf_evar_info evc info =
 
72
  { info with 
 
73
    evar_concl = Reductionops.nf_evar evc info.evar_concl;
 
74
    evar_hyps = map_named_val (Reductionops.nf_evar evc) info.evar_hyps}
 
75
 
 
76
let nf_evars evm = Evd.fold (fun ev evi evm' -> Evd.add evm' ev (nf_evar_info evm evi))
 
77
                     evm Evd.empty
 
78
 
 
79
let nf_evar_defs evd = Evd.evars_reset_evd (nf_evars (Evd.evars_of evd)) evd
 
80
 
 
81
let nf_isevar evd = nf_evar (Evd.evars_of evd)
 
82
let j_nf_isevar evd = j_nf_evar (Evd.evars_of evd)
 
83
let jl_nf_isevar evd = jl_nf_evar (Evd.evars_of evd)
 
84
let jv_nf_isevar evd = jv_nf_evar (Evd.evars_of evd)
 
85
let tj_nf_isevar evd = tj_nf_evar (Evd.evars_of evd)
 
86
 
 
87
(**********************)
 
88
(* Creating new metas *)
 
89
(**********************)
 
90
 
 
91
(* Generator of metavariables *)
 
92
let new_meta =
 
93
  let meta_ctr = ref 0 in
 
94
  fun () -> incr meta_ctr; !meta_ctr
 
95
 
 
96
let mk_new_meta () = mkMeta(new_meta())
 
97
 
 
98
let collect_evars emap c =
 
99
  let rec collrec acc c =
 
100
    match kind_of_term c with
 
101
      | Evar (evk,_) ->
 
102
          if Evd.mem emap evk & not (Evd.is_defined emap evk) then evk::acc
 
103
          else (* No recursion on the evar instantiation *) acc
 
104
      | _         ->
 
105
          fold_constr collrec acc c in
 
106
  list_uniquize (collrec [] c)
 
107
 
 
108
let push_dependent_evars sigma emap =
 
109
  Evd.fold (fun ev {evar_concl = ccl} (sigma',emap') ->
 
110
    List.fold_left 
 
111
      (fun (sigma',emap') ev -> 
 
112
        (Evd.add sigma' ev (Evd.find emap' ev),Evd.remove emap' ev))
 
113
      (sigma',emap') (collect_evars emap' ccl))
 
114
    emap (sigma,emap)
 
115
 
 
116
(* replaces a mapping of existentials into a mapping of metas.
 
117
   Problem if an evar appears in the type of another one (pops anomaly) *)
 
118
let evars_to_metas sigma (emap, c) =
 
119
  let emap = nf_evars emap in
 
120
  let sigma',emap' = push_dependent_evars sigma emap in
 
121
  let change_exist evar =
 
122
    let ty = nf_betaiota emap (existential_type emap evar) in
 
123
    let n = new_meta() in
 
124
    mkCast (mkMeta n, DEFAULTcast, ty) in
 
125
  let rec replace c =
 
126
    match kind_of_term c with
 
127
      | Evar (evk,_ as ev) when Evd.mem emap' evk -> change_exist ev
 
128
      | _ -> map_constr replace c in
 
129
  (sigma', replace c)
 
130
 
 
131
(* The list of non-instantiated existential declarations *)
 
132
 
 
133
let non_instantiated sigma = 
 
134
  let listev = to_list sigma in
 
135
  List.fold_left 
 
136
    (fun l (ev,evi) -> 
 
137
       if evi.evar_body = Evar_empty then 
 
138
         ((ev,nf_evar_info sigma evi)::l) else l)
 
139
    [] listev
 
140
 
 
141
(**********************)
 
142
(* Creating new evars *)
 
143
(**********************)
 
144
 
 
145
(* Generator of existential names *)
 
146
let new_untyped_evar =
 
147
  let evar_ctr = ref 0 in
 
148
  fun () -> incr evar_ctr; existential_of_int !evar_ctr
 
149
 
 
150
(*------------------------------------*
 
151
 * functional operations on evar sets *
 
152
 *------------------------------------*)
 
153
 
 
154
let new_evar_instance sign evd typ ?(src=(dummy_loc,InternalHole)) ?filter instance =
 
155
  let instance =
 
156
    match filter with
 
157
    | None -> instance
 
158
    | Some filter -> snd (list_filter2 (fun b c -> b) (filter,instance)) in
 
159
  assert
 
160
    (let ctxt = named_context_of_val sign in
 
161
     list_distinct (ids_of_named_context ctxt));
 
162
  let newevk = new_untyped_evar() in
 
163
  let evd = evar_declare sign newevk typ ~src:src ?filter evd in
 
164
  (evd,mkEvar (newevk,Array.of_list instance))
 
165
 
 
166
(* Knowing that [Gamma |- ev : T] and that [ev] is applied to [args],
 
167
 * [make_projectable_subst ev args] builds the substitution [Gamma:=args].
 
168
 * If a variable and an alias of it are bound to the same instance, we skip
 
169
 * the alias (we just use eq_constr -- instead of conv --, since anyway,
 
170
 * only instances that are variables -- or evars -- are later considered;
 
171
 * morever, we can bet that similar instances came at some time from
 
172
 * the very same substitution. The removal of aliased duplicates is
 
173
 * useful to ensure the uniqueness of a projection.
 
174
*)
 
175
 
 
176
let make_projectable_subst sigma evi args =
 
177
  let sign = evar_filtered_context evi in
 
178
  let rec alias_of_var id = 
 
179
    match pi2 (Sign.lookup_named id sign) with
 
180
    | Some t when isVar t -> alias_of_var (destVar t)
 
181
    | _ -> id in
 
182
  snd (List.fold_right
 
183
    (fun (id,b,c) (args,l) ->
 
184
      match b,args with
 
185
        | Some c, a::rest when
 
186
            isVar c & (try eq_constr a (snd (List.assoc (destVar c) l)) with Not_found -> false) -> (rest,l)
 
187
        | _, a::rest -> (rest, (id, (alias_of_var id,whd_evar sigma a))::l)
 
188
        | _ -> anomaly "Instance does not match its signature")
 
189
    sign (List.rev (Array.to_list args),[]))
 
190
 
 
191
let make_pure_subst evi args =
 
192
  snd (List.fold_right
 
193
    (fun (id,b,c) (args,l) ->
 
194
      match args with
 
195
        | a::rest -> (rest, (id,a)::l)
 
196
        | _ -> anomaly "Instance does not match its signature")
 
197
    (evar_filtered_context evi) (List.rev (Array.to_list args),[]))
 
198
 
 
199
(* [push_rel_context_to_named_context] builds the defining context and the
 
200
 * initial instance of an evar. If the evar is to be used in context
 
201
 * 
 
202
 * Gamma =  a1     ...    an xp      ...       x1
 
203
 *          \- named part -/ \- de Bruijn part -/
 
204
 * 
 
205
 * then the x1...xp are turned into variables so that the evar is declared in
 
206
 * context 
 
207
 *
 
208
 *          a1     ...    an xp      ...       x1
 
209
 *          \----------- named part ------------/
 
210
 *
 
211
 * but used applied to the initial instance "a1 ... an Rel(p) ... Rel(1)"
 
212
 * so that ev[a1:=a1 ... an:=an xp:=Rel(p) ... x1:=Rel(1)] is correctly typed
 
213
 * in context Gamma.
 
214
 * 
 
215
 * Remark 1: The instance is reverted in practice (i.e. Rel(1) comes first)
 
216
 * Remark 2: If some of the ai or xj are definitions, we keep them in the
 
217
 *   instance. This is necessary so that no unfolding of local definitions
 
218
 *   happens when inferring implicit arguments (consider e.g. the problem
 
219
 *   "x:nat; x':=x; f:forall x, x=x -> Prop |- f _ (refl_equal x')"
 
220
 *   we want the hole to be instantiated by x', not by x (which would have the
 
221
 *   case in [invert_instance] if x' had disappear of the instance).
 
222
 *   Note that at any time, if, in some context env, the instance of
 
223
 *   declaration x:A is t and the instance of definition x':=phi(x) is u, then 
 
224
 *   we have the property that u and phi(t) are convertible in env.
 
225
 *)
 
226
 
 
227
let push_rel_context_to_named_context env typ =
 
228
  (* compute the instances relative to the named context and rel_context *)
 
229
  let ids = List.map pi1 (named_context env) in
 
230
  let inst_vars = List.map mkVar ids in
 
231
  let inst_rels = List.rev (rel_list 0 (nb_rel env)) in
 
232
  (* move the rel context to a named context and extend the named instance *)
 
233
  (* with vars of the rel context *)
 
234
  (* We do keep the instances corresponding to local definition (see above) *)
 
235
  let (subst, _, env) =
 
236
    Sign.fold_rel_context
 
237
      (fun (na,c,t) (subst, avoid, env) ->
 
238
        let id = next_name_away na avoid in
 
239
        let d = (id,Option.map (substl subst) c,substl subst t) in
 
240
        (mkVar id :: subst, id::avoid, push_named d env))
 
241
      (rel_context env) ~init:([], ids, env) in
 
242
  (named_context_val env, substl subst typ, inst_rels@inst_vars)
 
243
      
 
244
(* [new_evar] declares a new existential in an env env with type typ *)
 
245
(* Converting the env into the sign of the evar to define *)
 
246
 
 
247
let new_evar evd env ?(src=(dummy_loc,InternalHole)) ?filter typ =
 
248
  let sign,typ',instance = push_rel_context_to_named_context env typ in
 
249
  new_evar_instance sign evd typ' ~src:src ?filter instance
 
250
 
 
251
  (* The same using side-effect *)
 
252
let e_new_evar evdref env ?(src=(dummy_loc,InternalHole)) ?filter ty =
 
253
  let (evd',ev) = new_evar !evdref env ~src:src ?filter ty in
 
254
  evdref := evd';
 
255
  ev
 
256
 
 
257
(*------------------------------------*
 
258
 * operations on the evar constraints *
 
259
 *------------------------------------*)
 
260
 
 
261
let is_pattern inst =
 
262
  array_for_all (fun a -> isRel a || isVar a) inst &&
 
263
  array_distinct inst
 
264
 
 
265
(* Pb: defined Rels and Vars should not be considered as a pattern... *)
 
266
(*
 
267
let is_pattern inst =
 
268
  let rec is_hopat l = function
 
269
      [] -> true
 
270
    | t :: tl ->
 
271
        (isRel t or isVar t) && not (List.mem t l) && is_hopat (t::l) tl in
 
272
  is_hopat [] (Array.to_list inst)
 
273
*)
 
274
 
 
275
let evar_well_typed_body evd ev evi body =
 
276
  try
 
277
    let env = evar_unfiltered_env evi in
 
278
    let ty = evi.evar_concl in
 
279
    Typing.check env (evars_of evd) body ty;
 
280
    true
 
281
  with e ->
 
282
    pperrnl
 
283
      (str "Ill-typed evar instantiation: " ++ fnl() ++
 
284
       pr_evar_defs evd ++ fnl() ++
 
285
       str "----> " ++ int ev ++ str " := " ++
 
286
       print_constr body);
 
287
    false
 
288
 
 
289
(* We have x1..xq |- ?e1 and had to solve something like 
 
290
 * Σ; Γ |- ?e1[u1..uq] = (...\y1 ... \yk ... c), where c is typically some 
 
291
 * ?e2[v1..vn], hence flexible. We had to go through k binders and now 
 
292
 * virtually have x1..xq, y1..yk | ?e1' and the equation
 
293
 * Γ, y1..yk |- ?e1'[u1..uq y1..yk] = c.
 
294
 * What we do is to formally introduce ?e1' in context x1..xq, Γ, y1..yk,
 
295
 * but forbidding it to use the variables of Γ (otherwise said,
 
296
 * Γ is here only for ensuring the correct typing of ?e1').
 
297
 *
 
298
 * In fact, we optimize a little and try to compute a maximum
 
299
 * common subpart of x1..xq and Γ. This is done by detecting the
 
300
 * longest subcontext x1..xp such that Γ = x1'..xp' z1..zm and 
 
301
 * u1..up = x1'..xp'.
 
302
 *
 
303
 * At the end, we return ?e1'[x1..xn z1..zm y1..yk] so that ?e1 can be 
 
304
 * instantiated by (...\y1 ... \yk ... ?e1[x1..xn z1..zm y1..yk]) and the
 
305
 * new problem is Σ; Γ, y1..yk |- ?e1'[u1..un z1..zm y1..yk] = c,
 
306
 * making the z1..zm unavailable.
 
307
 *
 
308
 * This is what [extend_evar Γ evd k (?e1[u1..uq]) c] does.
 
309
 *)
 
310
 
 
311
let shrink_context env subst ty =
 
312
  let rev_named_sign = List.rev (named_context env) in
 
313
  let rel_sign = rel_context env in
 
314
  (* We merge the contexts (optimization) *)
 
315
  let rec shrink_rel i subst rel_subst rev_rel_sign =
 
316
    match subst,rev_rel_sign with
 
317
    | (id,c)::subst,_::rev_rel_sign when c = mkRel i -> 
 
318
        shrink_rel (i-1) subst (mkVar id::rel_subst) rev_rel_sign
 
319
    | _ ->
 
320
        substl_rel_context rel_subst (List.rev rev_rel_sign), 
 
321
        substl rel_subst ty
 
322
  in
 
323
  let rec shrink_named subst named_subst rev_named_sign =
 
324
    match subst,rev_named_sign with
 
325
    | (id,c)::subst,(id',b',t')::rev_named_sign when c = mkVar id' ->
 
326
        shrink_named subst ((id',mkVar id)::named_subst) rev_named_sign
 
327
    | _::_, [] ->
 
328
        let nrel = List.length rel_sign in
 
329
        let rel_sign, ty = shrink_rel nrel subst [] (List.rev rel_sign) in
 
330
        [], map_rel_context (replace_vars named_subst) rel_sign,
 
331
        replace_vars named_subst ty
 
332
    | _ ->
 
333
        map_named_context (replace_vars named_subst) (List.rev rev_named_sign),
 
334
        rel_sign, ty
 
335
  in
 
336
  shrink_named subst [] rev_named_sign
 
337
 
 
338
let extend_evar env evdref k (evk1,args1) c =
 
339
  let ty = get_type_of env (evars_of !evdref) c in
 
340
  let overwrite_first v1 v2 =
 
341
    let v = Array.copy v1 in
 
342
    let n = Array.length v - Array.length v2 in
 
343
    for i = 0 to Array.length v2 - 1 do v.(n+i) <- v2.(i) done;
 
344
    v in
 
345
  let evi1 = Evd.find (evars_of !evdref) evk1 in
 
346
  let named_sign',rel_sign',ty =
 
347
    if k = 0 then [], [], ty
 
348
    else shrink_context env (List.rev (make_pure_subst evi1 args1)) ty in
 
349
  let extenv =
 
350
    List.fold_right push_rel rel_sign'
 
351
      (List.fold_right push_named named_sign' (evar_unfiltered_env evi1)) in
 
352
  let nb_to_hide = rel_context_length rel_sign' - k in
 
353
  let rel_filter = list_map_i (fun i _ -> i > nb_to_hide) 1 rel_sign' in
 
354
  let named_filter1 = List.map (fun _ -> true) (evar_context evi1) in
 
355
  let named_filter2 = List.map (fun _ -> false) named_sign' in
 
356
  let filter = rel_filter@named_filter2@named_filter1 in
 
357
  let evar1' = e_new_evar evdref extenv ~filter:filter ty in
 
358
  let evk1',args1'_in_env = destEvar evar1' in
 
359
  let args1'_in_extenv = Array.map (lift k) (overwrite_first args1'_in_env args1) in
 
360
  (evar1',(evk1',args1'_in_extenv))
 
361
 
 
362
let subfilter p filter l =
 
363
  let (filter,_,l) =
 
364
    List.fold_left (fun (filter,l,newl) b ->
 
365
      if b then 
 
366
        let a,l' = match l with a::args -> a,args | _ -> assert false in
 
367
        if p a then (true::filter,l',a::newl) else (false::filter,l',newl)
 
368
      else (false::filter,l,newl))
 
369
      ([],l,[]) filter in
 
370
  (List.rev filter,List.rev l)
 
371
 
 
372
let restrict_upon_filter evd evi evk p args =
 
373
  let filter = evar_filter evi in
 
374
  let newfilter,newargs = subfilter p filter args in
 
375
  if newfilter <> filter then
 
376
    let (evd,newev) = new_evar evd (evar_unfiltered_env evi) ~src:(evar_source evk evd)
 
377
        ~filter:newfilter evi.evar_concl in
 
378
    let evd = Evd.evar_define evk newev evd in
 
379
    evd,fst (destEvar newev),newargs
 
380
  else
 
381
    evd,evk,args
 
382
 
 
383
let collect_vars c =
 
384
  let rec collrec acc c =
 
385
    match kind_of_term c with
 
386
    | Var id -> list_add_set id acc
 
387
    | _      -> fold_constr collrec acc c
 
388
  in
 
389
  collrec [] c
 
390
 
 
391
type clear_dependency_error =
 
392
| OccurHypInSimpleClause of identifier option
 
393
| EvarTypingBreak of existential
 
394
 
 
395
exception ClearDependencyError of identifier * clear_dependency_error
 
396
 
 
397
let rec check_and_clear_in_constr evdref err ids c =
 
398
  (* returns a new constr where all the evars have been 'cleaned'
 
399
     (ie the hypotheses ids have been removed from the contexts of
 
400
     evars) *)
 
401
  let check id' = 
 
402
    if List.mem id' ids then
 
403
      raise (ClearDependencyError (id',err))
 
404
  in 
 
405
    match kind_of_term c with
 
406
      | Var id' ->
 
407
          check id'; c
 
408
 
 
409
      | ( Const _ | Ind _ | Construct _ ) ->
 
410
          let vars = Environ.vars_of_global (Global.env()) c in
 
411
            List.iter check vars; c
 
412
 
 
413
      | Evar (evk,l as ev) -> 
 
414
          if Evd.is_defined_evar !evdref ev then
 
415
            (* If evk is already defined we replace it by its definition *)
 
416
            let nc = whd_evar (evars_of !evdref) c in 
 
417
              (check_and_clear_in_constr evdref err ids nc)
 
418
          else 
 
419
            (* We check for dependencies to elements of ids in the
 
420
               evar_info corresponding to e and in the instance of
 
421
               arguments. Concurrently, we build a new evar
 
422
               corresponding to e where hypotheses of ids have been
 
423
               removed *)
 
424
            let evi = Evd.find (evars_of !evdref) evk in
 
425
            let ctxt = Evd.evar_filtered_context evi in
 
426
            let (nhyps,nargs,rids) =
 
427
              List.fold_right2 
 
428
                (fun (rid,ob,c as h) a (hy,ar,ri) ->
 
429
                  (* Check if some id to clear occurs in the instance
 
430
                     a of rid in ev and remember the dependency *)
 
431
                  match 
 
432
                    List.filter (fun id -> List.mem id ids) (collect_vars a)
 
433
                  with
 
434
                  | id :: _ -> (hy,ar,(rid,id)::ri)
 
435
                  | _ ->
 
436
                  (* Check if some rid to clear in the context of ev
 
437
                     has dependencies in another hyp of the context of ev
 
438
                     and transitively remember the dependency *)
 
439
                  match List.filter (fun (id,_) -> occur_var_in_decl (Global.env()) id h) ri with
 
440
                  | (_,id') :: _ -> (hy,ar,(rid,id')::ri)
 
441
                  | _ ->
 
442
                  (* No dependency at all, we can keep this ev's context hyp *)
 
443
                      (h::hy,a::ar,ri))
 
444
                ctxt (Array.to_list l) ([],[],[]) in
 
445
            (* Check if some rid to clear in the context of ev has dependencies
 
446
               in the type of ev and adjust the source of the dependency *)
 
447
            let nconcl =
 
448
              try check_and_clear_in_constr evdref (EvarTypingBreak ev)
 
449
                    (List.map fst rids) (evar_concl evi) 
 
450
              with ClearDependencyError (rid,err) -> 
 
451
                raise (ClearDependencyError (List.assoc rid rids,err)) in
 
452
 
 
453
            let env = Sign.fold_named_context push_named nhyps ~init:(empty_env) in
 
454
            let ev'= e_new_evar evdref env ~src:(evar_source evk !evdref) nconcl in
 
455
              evdref := Evd.evar_define evk ev' !evdref;
 
456
              let (evk',_) = destEvar ev' in
 
457
                mkEvar(evk', Array.of_list nargs)
 
458
 
 
459
      | _ -> map_constr (check_and_clear_in_constr evdref err ids) c
 
460
 
 
461
let clear_hyps_in_evi evdref hyps concl ids =
 
462
  (* clear_hyps_in_evi erases hypotheses ids in hyps, checking if some
 
463
     hypothesis does not depend on a element of ids, and erases ids in
 
464
     the contexts of the evars occuring in evi *)
 
465
  let nconcl =
 
466
    check_and_clear_in_constr evdref (OccurHypInSimpleClause None) ids concl in
 
467
  let nhyps = 
 
468
    let check_context (id,ob,c) =
 
469
      let err = OccurHypInSimpleClause (Some id) in
 
470
      (id, Option.map (check_and_clear_in_constr evdref err ids) ob,
 
471
        check_and_clear_in_constr evdref err ids c)
 
472
    in
 
473
    let check_value vk =
 
474
      match !vk with
 
475
        | VKnone -> vk
 
476
        | VKvalue (v,d) ->
 
477
            if (List.for_all (fun e -> not (Idset.mem e d)) ids) then
 
478
              (* v does depend on any of ids, it's ok *)
 
479
              vk
 
480
            else
 
481
              (* v depends on one of the cleared hyps: we forget the computed value *)
 
482
              ref VKnone
 
483
    in
 
484
      remove_hyps ids check_context check_value hyps
 
485
  in
 
486
  (nhyps,nconcl)
 
487
 
 
488
 
 
489
(* Expand rels and vars that are bound to other rels or vars so that 
 
490
   dependencies in variables are canonically associated to the most ancient
 
491
   variable in its family of aliased variables *)
 
492
 
 
493
let expand_var_once env x = match kind_of_term x with
 
494
  | Rel n ->
 
495
      begin match pi2 (lookup_rel n env) with
 
496
      | Some t when isRel t or isVar t -> lift n t
 
497
      | _ -> raise Not_found
 
498
      end
 
499
  | Var id ->
 
500
      begin match pi2 (lookup_named id env) with
 
501
      | Some t when isVar t -> t
 
502
      | _ -> raise Not_found
 
503
      end
 
504
  | _ ->
 
505
      raise Not_found
 
506
 
 
507
let rec expand_var_at_least_once env x =
 
508
  let t = expand_var_once env x in
 
509
  try expand_var_at_least_once env t
 
510
  with Not_found -> t
 
511
 
 
512
let expand_var env x =
 
513
  try expand_var_at_least_once env x with Not_found -> x
 
514
  
 
515
let expand_var_opt env x =
 
516
  try Some (expand_var_at_least_once env x) with Not_found -> None
 
517
 
 
518
let rec expand_vars_in_term env t = match kind_of_term t with
 
519
  | Rel _ | Var _ -> expand_var env t
 
520
  | _ -> map_constr_with_full_binders push_rel expand_vars_in_term env t
 
521
 
 
522
let rec expansions_of_var env x =
 
523
  try 
 
524
    let t = expand_var_once env x in
 
525
    t :: expansions_of_var env t
 
526
  with Not_found ->
 
527
    [x]
 
528
 
 
529
(* [find_projectable_vars env sigma y subst] finds all vars of [subst]
 
530
 * that project on [y]. It is able to find solutions to the following
 
531
 * two kinds of problems:
 
532
 *
 
533
 * - ?n[...;x:=y;...] = y
 
534
 * - ?n[...;x:=?m[args];...] = y with ?m[args] = y recursively solvable
 
535
 *   
 
536
 * (see test-suite/success/Fixpoint.v for an example of application of
 
537
 * the second kind of problem).
 
538
 *
 
539
 * The seek for [y] is up to variable aliasing.  In case of solutions that
 
540
 * differ only up to aliasing, the binding that requires the less
 
541
 * steps of alias reduction is kept. At the end, only one solution up
 
542
 * to aliasing is kept.
 
543
 *
 
544
 * [find_projectable_vars] also unifies against evars that themselves mention
 
545
 * [y] and recursively.
 
546
 *
 
547
 * In short, the following situations give the following solutions:
 
548
 *
 
549
 * problem                        evar ctxt   soluce remark
 
550
 * z1; z2:=z1 |- ?ev[z1;z2] = z1  y1:A; y2:=y1  y1  \ thanks to defs kept in
 
551
 * z1; z2:=z1 |- ?ev[z1;z2] = z2  y1:A; y2:=y1  y2  / subst and preferring =
 
552
 * z1; z2:=z1 |- ?ev[z1]    = z2  y1:A          y1  thanks to expand_var
 
553
 * z1; z2:=z1 |- ?ev[z2]    = z1  y1:A          y1  thanks to expand_var
 
554
 * z3         |- ?ev[z3;z3] = z3  y1:A; y2:=y1  y2  see make_projectable_subst
 
555
 *
 
556
 * Remark: [find_projectable_vars] assumes that identical instances of
 
557
 * variables in the same set of aliased variables are already removed (see
 
558
 * [make_projectable_subst])
 
559
 *)
 
560
 
 
561
exception NotUnique
 
562
 
 
563
type evar_projection = 
 
564
| ProjectVar 
 
565
| ProjectEvar of existential * evar_info * identifier * evar_projection
 
566
 
 
567
let rec find_projectable_vars with_evars env sigma y subst =
 
568
  let is_projectable (id,(idc,y')) =
 
569
    let y' = whd_evar sigma y' in
 
570
    if y = y' or expand_var env y = expand_var env y'
 
571
    then (idc,(y'=y,(id,ProjectVar)))
 
572
    else if with_evars & isEvar y' then
 
573
      let (evk,argsv as t) = destEvar y' in
 
574
      let evi = Evd.find sigma evk in
 
575
      let subst = make_projectable_subst sigma evi argsv in
 
576
      let l = find_projectable_vars with_evars env sigma y subst in
 
577
      match l with 
 
578
      | [id',p] -> (idc,(true,(id,ProjectEvar (t,evi,id',p))))
 
579
      | _ -> failwith ""
 
580
    else failwith "" in
 
581
  let l = map_succeed is_projectable subst in
 
582
  let l = list_partition_by (fun (idc,_) (idc',_) -> idc = idc') l in
 
583
  let l = List.map (List.map snd) l in
 
584
  List.map (fun l -> try List.assoc true l with Not_found -> snd (List.hd l)) l
 
585
 
 
586
(* [filter_solution] checks if one and only one possible projection exists
 
587
 * among a set of solutions to a projection problem *)
 
588
 
 
589
let filter_solution = function
 
590
  | [] -> raise Not_found
 
591
  | (id,p)::_::_ -> raise NotUnique
 
592
  | [id,p] -> (mkVar id, p)
 
593
 
 
594
let project_with_effects env sigma effects t subst =
 
595
  let c, p = filter_solution (find_projectable_vars false env sigma t subst) in
 
596
  effects := p :: !effects;
 
597
  c
 
598
 
 
599
(* In case the solution to a projection problem requires the instantiation of
 
600
 * subsidiary evars, [do_projection_effects] performs them; it
 
601
 * also try to instantiate the type of those subsidiary evars if their
 
602
 * type is an evar too.
 
603
 *
 
604
 * Note: typing creates new evar problems, which induces a recursive dependency
 
605
 * with [evar_define]. To avoid a too large set of recursive functions, we
 
606
 * pass [evar_define] to [do_projection_effects] as a parameter.
 
607
 *)
 
608
 
 
609
let rec do_projection_effects define_fun env ty evd = function
 
610
  | ProjectVar -> evd
 
611
  | ProjectEvar ((evk,argsv),evi,id,p) ->
 
612
      let evd = Evd.evar_define evk (mkVar id) evd in
 
613
      (* TODO: simplify constraints involving evk *)
 
614
      let evd = do_projection_effects define_fun env ty evd p in
 
615
      let ty = whd_betadeltaiota env (evars_of evd) (Lazy.force ty) in
 
616
      if not (isSort ty) then
 
617
        (* Don't try to instantiate if a sort because if evar_concl is an
 
618
           evar it may commit to a univ level which is not the right
 
619
           one (however, regarding coercions, because t is obtained by
 
620
           unif, we know that no coercion can be inserted) *)
 
621
        let subst = make_pure_subst evi argsv in
 
622
        let ty' = replace_vars subst evi.evar_concl in
 
623
        let ty' = whd_evar (evars_of evd) ty' in
 
624
        if isEvar ty' then define_fun env (destEvar ty') ty evd else evd
 
625
      else
 
626
        evd
 
627
 
 
628
(* Assuming Σ; Γ, y1..yk |- c, [invert_subst Γ k Σ [x1:=u1;...;xn:=un] c]
 
629
 * tries to return φ(x1..xn) such that equation φ(u1..un) = c is valid. 
 
630
 * The strategy is to imitate the structure of c and then to invert
 
631
 * the variables of c (i.e. rels or vars of Γ) using the algorithm
 
632
 * implemented by project_with_effects/find_projectable_vars.
 
633
 * It returns either a unique solution or says whether 0 or more than
 
634
 * 1 solutions is found.
 
635
 *
 
636
 * Precondition:  Σ; Γ, y1..yk |- c /\ Σ; Γ |- u1..un
 
637
 * Postcondition: if φ(x1..xn) is returned then 
 
638
 *                Σ; Γ, y1..yk |- φ(u1..un) = c /\ x1..xn |- φ(x1..xn)
 
639
 *
 
640
 * The effects correspond to evars instantiated while trying to project.
 
641
 *
 
642
 * [invert_subst] is used on instances of evars. Since the evars are flexible,
 
643
 * these instances are potentially erasable. This is why we don't investigate
 
644
 * whether evars in the instances of evars are unifiable, to the contrary of 
 
645
 * [invert_definition].
 
646
 *)
 
647
 
 
648
type projectibility_kind =
 
649
  | NoUniqueProjection
 
650
  | UniqueProjection of constr * evar_projection list
 
651
 
 
652
type projectibility_status =
 
653
  | CannotInvert
 
654
  | Invertible of projectibility_kind
 
655
 
 
656
let invert_arg_from_subst env k sigma subst_in_env c_in_env_extended_with_k_binders =
 
657
  let effects = ref [] in
 
658
  let rec aux k t =
 
659
    let t = whd_evar sigma t in
 
660
    match kind_of_term t with
 
661
    | Rel i when i>k ->
 
662
        project_with_effects env sigma effects (mkRel (i-k)) subst_in_env
 
663
    | Var id ->
 
664
        project_with_effects env sigma effects t subst_in_env
 
665
    | _ ->
 
666
        map_constr_with_binders succ aux k t in
 
667
  try 
 
668
    let c = aux k c_in_env_extended_with_k_binders in
 
669
    Invertible (UniqueProjection (c,!effects))
 
670
  with
 
671
    | Not_found -> CannotInvert
 
672
    | NotUnique -> Invertible NoUniqueProjection
 
673
 
 
674
let invert_arg env k sigma (evk,args_in_env) c_in_env_extended_with_k_binders =
 
675
  let subst_in_env = make_projectable_subst sigma (Evd.find sigma evk) args_in_env in
 
676
  let res = invert_arg_from_subst env k sigma subst_in_env c_in_env_extended_with_k_binders in
 
677
  match res with
 
678
  | Invertible (UniqueProjection (c,_)) when occur_evar evk c -> CannotInvert
 
679
  | _ -> res
 
680
 
 
681
 
 
682
let effective_projections =
 
683
  map_succeed (function Invertible c -> c | _ -> failwith"")
 
684
 
 
685
let instance_of_projection f env t evd projs =
 
686
  let ty = lazy (Retyping.get_type_of env (evars_of evd) t) in
 
687
  match projs with
 
688
  | NoUniqueProjection -> raise NotUnique
 
689
  | UniqueProjection (c,effects) ->
 
690
      (List.fold_left (do_projection_effects f env ty) evd effects, c)
 
691
 
 
692
let filter_of_projection = function CannotInvert -> false | _ -> true
 
693
 
 
694
let filter_along f projs v =
 
695
  let l = Array.to_list v in
 
696
  let _,l = list_filter2 (fun b c -> f b) (projs,l) in
 
697
  Array.of_list l
 
698
 
 
699
(* Redefines an evar with a smaller context (i.e. it may depend on less
 
700
 * variables) such that c becomes closed.
 
701
 * Example: in "fun (x:?1) (y:list ?2[x]) => x = y :> ?3[x,y] /\ x = nil bool"
 
702
 * ?3 <-- ?1          no pb: env of ?3 is larger than ?1's
 
703
 * ?1 <-- list ?2     pb: ?2 may depend on x, but not ?1.
 
704
 * What we do is that ?2 is defined by a new evar ?4 whose context will be
 
705
 * a prefix of ?2's env, included in ?1's env.
 
706
 *
 
707
 * If "hyps |- ?e : T" and "filter" selects a subset hyps' of hyps then
 
708
 * [do_restrict_hyps evd ?e filter] sets ?e:=?e'[hyps'] and returns ?e'
 
709
 * such that "hyps' |- ?e : T"
 
710
 *)
 
711
 
 
712
let do_restrict_hyps_virtual evd evk filter =
 
713
    (* What to do with dependencies?
 
714
       Assume we have x:A, y:B(x), z:C(x,y) |- ?e:T(x,y,z) and restrict on y.
 
715
       - If y is in a non-erasable position in C(x,y) (i.e. it is not below an
 
716
         occurrence of x in the hnf of C), then z should be removed too.
 
717
       - If y is in a non-erasable position in T(x,y,z) then the problem is
 
718
         unsolvable.
 
719
       Computing whether y is erasable or not may be costly and the 
 
720
       interest for this early detection in practice is not obvious. We let
 
721
       it for future work. In any case, thanks to the use of filters, the whole
 
722
       (unrestricted) context remains consistent. *)
 
723
    let evi = Evd.find (evars_of evd) evk in
 
724
    let env = evar_unfiltered_env evi in
 
725
    let oldfilter = evar_filter evi in
 
726
    let filter,_ = List.fold_right (fun oldb (l,filter) ->
 
727
      if oldb then List.hd filter::l,List.tl filter else (false::l,filter))
 
728
      oldfilter ([],List.rev filter) in
 
729
    new_evar evd env ~src:(evar_source evk evd)
 
730
      ~filter:filter evi.evar_concl
 
731
 
 
732
let do_restrict_hyps evd evk projs =
 
733
  let filter = List.map filter_of_projection projs in
 
734
  if List.for_all (fun x -> x) filter then
 
735
    evd,evk
 
736
  else
 
737
    let evd,nc = do_restrict_hyps_virtual evd evk filter in
 
738
    let evd = Evd.evar_define evk nc evd in
 
739
    let evk',_ = destEvar nc in
 
740
    evd,evk'
 
741
 
 
742
(* [postpone_evar_term] postpones an equation of the form ?e[σ] = c *)
 
743
 
 
744
let postpone_evar_term env evd (evk,argsv) rhs =
 
745
  let rhs = expand_vars_in_term env rhs in
 
746
  let evi = Evd.find (evars_of evd) evk in
 
747
  let evd,evk,args =
 
748
    restrict_upon_filter evd evi evk
 
749
      (* Keep only variables that depends in rhs *)
 
750
      (* This is not safe: is the variable is a local def, its body *)
 
751
      (* may contain references to variables that are removed, leading to *)
 
752
      (* a ill-formed context. We would actually need a notion of filter *)
 
753
      (* that says that the body is hidden. Note that expand_vars_in_term *)
 
754
      (* expands only rels and vars aliases, not rels or vars bound to an *)
 
755
      (* arbitrary complex term *)
 
756
      (fun a -> not (isRel a || isVar a) || dependent a rhs)
 
757
      (Array.to_list argsv) in
 
758
  let args = Array.of_list args in
 
759
  let pb = (Reduction.CONV,env,mkEvar(evk,args),rhs) in
 
760
  Evd.add_conv_pb pb evd
 
761
 
 
762
(* [postpone_evar_evar] postpones an equation of the form ?e1[σ1] = ?e2[σ2] *)
 
763
 
 
764
let postpone_evar_evar env evd projs1 (evk1,args1) projs2 (evk2,args2) =
 
765
  (* Leave an equation between (restrictions of) ev1 andv ev2 *)
 
766
  let args1' = filter_along filter_of_projection projs1 args1 in
 
767
  let evd,evk1' = do_restrict_hyps evd evk1 projs1 in
 
768
  let args2' = filter_along filter_of_projection projs2 args2 in
 
769
  let evd,evk2' = do_restrict_hyps evd evk2 projs2 in
 
770
  let pb = (Reduction.CONV,env,mkEvar(evk1',args1'),mkEvar (evk2',args2')) in
 
771
  add_conv_pb pb evd
 
772
 
 
773
(* [solve_evar_evar f Γ Σ ?e1[u1..un] ?e2[v1..vp]] applies an heuristic 
 
774
 * to solve the equation Σ; Γ ⊢ ?e1[u1..un] = ?e2[v1..vp]:
 
775
 * - if there are at most one φj for each vj s.t. vj = φj(u1..un), 
 
776
 *   we first restrict ?2 to the subset v_k1..v_kq of the vj that are 
 
777
 *   inversible and we set ?1[x1..xn] := ?2[φk1(x1..xn)..φkp(x1..xn)]
 
778
 * - symmetrically if there are at most one ψj for each uj s.t. 
 
779
 *   uj = ψj(v1..vp), 
 
780
 * - otherwise, each position i s.t. ui does not occur in v1..vp has to
 
781
 *   be restricted and similarly for the vi, and we leave the equation
 
782
 *   as an open equation (performed by [postpone_evar])
 
783
 *
 
784
 * Warning: the notion of unique φj is relative to some given class
 
785
 * of unification problems
 
786
 *
 
787
 * Note: argument f is the function used to instantiate evars.
 
788
 *)
 
789
 
 
790
exception CannotProject of projectibility_status list
 
791
 
 
792
let solve_evar_evar_l2r f env evd (evk1,args1) (evk2,_ as ev2) =
 
793
  let proj1 = array_map_to_list (invert_arg env 0 (evars_of evd) ev2) args1 in
 
794
  try
 
795
    (* Instantiate ev2 with (a restriction of) ev1 if uniquely projectable *)
 
796
    let proj1' = effective_projections proj1 in
 
797
    let evd,args1' =
 
798
      list_fold_map (instance_of_projection f env (mkEvar ev2)) evd proj1' in
 
799
    let evd,evk1' = do_restrict_hyps evd evk1 proj1 in
 
800
    Evd.evar_define evk2 (mkEvar(evk1',Array.of_list args1')) evd
 
801
  with NotUnique ->
 
802
    raise (CannotProject proj1)
 
803
 
 
804
let solve_evar_evar f env evd ev1 ev2 =
 
805
  try solve_evar_evar_l2r f env evd ev1 ev2
 
806
  with CannotProject projs1 ->
 
807
  try solve_evar_evar_l2r f env evd ev2 ev1
 
808
  with CannotProject projs2 ->
 
809
  postpone_evar_evar env evd projs1 ev1 projs2 ev2
 
810
 
 
811
let expand_rhs env sigma subst rhs =
 
812
  let d = (named_hd env rhs Anonymous,Some rhs,get_type_of env sigma rhs) in
 
813
  let rhs' = lift 1 rhs in
 
814
  let f (id,(idc,t)) = (id,(idc,replace_term rhs' (mkRel 1) (lift 1 t))) in
 
815
  push_rel d env, List.map f subst, mkRel 1
 
816
 
 
817
(* We try to instantiate the evar assuming the body won't depend
 
818
 * on arguments that are not Rels or Vars, or appearing several times
 
819
 * (i.e. we tackle a generalization of Miller-Pfenning patterns unification) 
 
820
 *
 
821
 * 1) Let "env |- ?ev[hyps:=args] = rhs" be the unification problem
 
822
 * 2) We limit it to a patterns unification problem "env |- ev[subst] = rhs"
 
823
 *    where only Rel's and Var's are relevant in subst
 
824
 * 3) We recur on rhs, "imitating" the term, and failing if some Rel/Var is 
 
825
 *    not in the scope of ?ev. For instance, the problem
 
826
 *    "y:nat |- ?x[] = y" where "|- ?1:nat" is not satisfiable because
 
827
 *    ?1 would be instantiated by y which is not in the scope of ?1.
 
828
 * 4) We try to "project" the term if the process of imitation fails
 
829
 *    and that only one projection is possible
 
830
 *
 
831
 * Note: we don't assume rhs in normal form, it may fail while it would
 
832
 * have succeeded after some reductions.
 
833
 *
 
834
 * This is the work of [invert_definition Γ Σ ?ev[hyps:=args] 
 
835
 * Precondition:  Σ; Γ, y1..yk |- c /\ Σ; Γ |- u1..un
 
836
 * Postcondition: if φ(x1..xn) is returned then 
 
837
 *                Σ; Γ, y1..yk |- φ(u1..un) = c /\ x1..xn |- φ(x1..xn)
 
838
 *)
 
839
 
 
840
exception NotInvertibleUsingOurAlgorithm of constr
 
841
exception NotEnoughInformationToProgress
 
842
 
 
843
let rec invert_definition choose env evd (evk,argsv as ev) rhs =
 
844
  let evdref = ref evd in
 
845
  let progress = ref false in
 
846
  let evi = Evd.find (evars_of evd) evk in
 
847
  let subst = make_projectable_subst (evars_of evd) evi argsv in
 
848
 
 
849
  (* Projection *)
 
850
  let project_variable t =
 
851
    (* Evar/Var problem: unifiable iff variable projectable from ev subst *)
 
852
    try 
 
853
      let sols = find_projectable_vars true env (evars_of !evdref) t subst in
 
854
      let c, p = match sols with
 
855
        | [] -> raise Not_found
 
856
        | [id,p] -> (mkVar id, p)
 
857
        | (id,p)::_::_ -> if choose then (mkVar id, p) else raise NotUnique
 
858
      in
 
859
      let ty = lazy (Retyping.get_type_of env (evars_of !evdref) t) in
 
860
      let evd = do_projection_effects evar_define env ty !evdref p in
 
861
      evdref := evd;
 
862
      c
 
863
    with
 
864
      | Not_found -> raise (NotInvertibleUsingOurAlgorithm t)
 
865
      | NotUnique ->
 
866
          if not !progress then raise NotEnoughInformationToProgress;
 
867
          (* No unique projection but still restrict to where it is possible *)
 
868
          let ts = expansions_of_var env t in
 
869
          let test c = isEvar c or List.mem c ts in
 
870
          let filter = array_map_to_list test argsv in
 
871
          let args' = filter_along (fun x -> x) filter argsv in
 
872
          let evd,evar = do_restrict_hyps_virtual !evdref evk filter in
 
873
          let evk',_ = destEvar evar in
 
874
          let pb = (Reduction.CONV,env,mkEvar(evk',args'),t) in
 
875
          evdref := Evd.add_conv_pb pb evd;
 
876
          evar in
 
877
 
 
878
  let rec imitate (env',k as envk) t =
 
879
    let t = whd_evar (evars_of !evdref) t in
 
880
    match kind_of_term t with
 
881
    | Rel i when i>k -> project_variable (mkRel (i-k))
 
882
    | Var id -> project_variable t
 
883
    | Evar (evk',args' as ev') ->
 
884
        if evk = evk' then error_occur_check env (evars_of evd) evk rhs;
 
885
        (* Evar/Evar problem (but left evar is virtual) *)
 
886
        let projs' =
 
887
          array_map_to_list
 
888
            (invert_arg_from_subst env k (evars_of !evdref) subst) args'
 
889
        in
 
890
        (try
 
891
          (* Try to project (a restriction of) the right evar *)
 
892
          let eprojs' = effective_projections projs' in
 
893
          let evd,args' = 
 
894
            list_fold_map (instance_of_projection evar_define env' t)
 
895
              !evdref eprojs' in
 
896
          let evd,evk' = do_restrict_hyps evd evk' projs' in
 
897
          evdref := evd;
 
898
          mkEvar (evk',Array.of_list args')
 
899
        with NotUnique ->
 
900
          assert !progress;
 
901
          (* Make the virtual left evar real *)
 
902
          let (evar'',ev'') = extend_evar env' evdref k ev t in
 
903
          let evd =
 
904
            (* Try to project (a restriction of) the left evar ... *)
 
905
            try solve_evar_evar_l2r evar_define env' !evdref ev'' ev'
 
906
            with CannotProject projs'' ->
 
907
            (* ... or postpone the problem *)
 
908
            postpone_evar_evar env' !evdref projs'' ev'' projs' ev' in
 
909
          evdref := evd;
 
910
          evar'')
 
911
    | _ ->
 
912
        progress := true;
 
913
        (* Evar/Rigid problem (or assimilated if not normal): we "imitate" *)
 
914
        map_constr_with_full_binders (fun d (env,k) -> push_rel d env, k+1)
 
915
          imitate envk t in
 
916
 
 
917
  let rhs = whd_beta (evars_of evd) rhs (* heuristic *) in
 
918
  let body = imitate (env,0) rhs in
 
919
  (!evdref,body)
 
920
 
 
921
(* [evar_define] tries to solve the problem "?ev[args] = rhs" when "?ev" is
 
922
 * an (uninstantiated) evar such that "hyps |- ?ev : typ". Otherwise said,
 
923
 * [evar_define] tries to find an instance lhs such that
 
924
 * "lhs [hyps:=args]" unifies to rhs. The term "lhs" must be closed in
 
925
 * context "hyps" and not referring to itself.
 
926
 *)
 
927
 
 
928
and occur_existential evm c =
 
929
  let rec occrec c = match kind_of_term c with
 
930
    | Evar (e, _) -> if not (is_defined evm e) then raise Occur
 
931
    | _ -> iter_constr occrec c
 
932
  in try occrec c; false with Occur -> true
 
933
 
 
934
and evar_define ?(choose=false) env (evk,_ as ev) rhs evd =
 
935
  try
 
936
    let (evd',body) = invert_definition choose env evd ev rhs in
 
937
    if occur_meta body then error "Meta cannot occur in evar body.";
 
938
    (* invert_definition may have instantiate some evars of rhs with evk *)
 
939
    (* so we recheck acyclicity *)
 
940
    if occur_evar evk body then error_occur_check env (evars_of evd) evk body;
 
941
    (* needed only if an inferred type *)
 
942
    let body = refresh_universes body in
 
943
(* Cannot strictly type instantiations since the unification algorithm
 
944
 * does not unify applications from left to right.
 
945
 * e.g problem f x == g y yields x==y and f==g (in that order) 
 
946
 * Another problem is that type variables are evars of type Type
 
947
   let _ =
 
948
      try
 
949
        let env = evar_env evi in
 
950
        let ty = evi.evar_concl in
 
951
        Typing.check env (evars_of evd') body ty
 
952
      with e ->
 
953
        pperrnl
 
954
          (str "Ill-typed evar instantiation: " ++ fnl() ++
 
955
           pr_evar_defs evd' ++ fnl() ++
 
956
           str "----> " ++ int ev ++ str " := " ++
 
957
           print_constr body);
 
958
        raise e in*)
 
959
    Evd.evar_define evk body evd'
 
960
  with
 
961
    | NotEnoughInformationToProgress ->
 
962
        postpone_evar_term env evd ev rhs
 
963
    | NotInvertibleUsingOurAlgorithm t -> 
 
964
        error_not_clean env (evars_of evd) evk t (evar_source evk evd)
 
965
 
 
966
(*-------------------*)
 
967
(* Auxiliary functions for the conversion algorithms modulo evars
 
968
 *)
 
969
 
 
970
let has_undefined_evars evd t =
 
971
  let evm = evars_of evd in
 
972
  let rec has_ev t =
 
973
    match kind_of_term t with
 
974
        Evar (ev,args) ->
 
975
          (match evar_body (Evd.find evm ev) with
 
976
            | Evar_defined c ->
 
977
                has_ev c; Array.iter has_ev args
 
978
            | Evar_empty ->
 
979
                raise NotInstantiatedEvar)
 
980
      | _ -> iter_constr has_ev t in
 
981
  try let _ = has_ev t in false
 
982
  with (Not_found | NotInstantiatedEvar) -> true
 
983
 
 
984
let is_ground_term evd t =
 
985
  not (has_undefined_evars evd t)
 
986
 
 
987
let is_ground_env evd env =
 
988
  let is_ground_decl = function
 
989
      (_,Some b,_) -> is_ground_term evd b
 
990
    | _ -> true in
 
991
  List.for_all is_ground_decl (rel_context env) &&
 
992
  List.for_all is_ground_decl (named_context env)
 
993
(* Memoization is safe since evar_map and environ are applicative
 
994
   structures *)
 
995
let is_ground_env = memo1_2 is_ground_env
 
996
 
 
997
let head_evar = 
 
998
  let rec hrec c = match kind_of_term c with
 
999
    | Evar (evk,_)   -> evk
 
1000
    | Case (_,_,c,_) -> hrec c
 
1001
    | App (c,_)      -> hrec c
 
1002
    | Cast (c,_,_)   -> hrec c
 
1003
    | _              -> failwith "headconstant"
 
1004
  in 
 
1005
  hrec 
 
1006
 
 
1007
(* Check if an applied evar "?X[args] l" is a Miller's pattern; note
 
1008
   that we don't care whether args itself contains Rel's or even Rel's
 
1009
   distinct from the ones in l *)
 
1010
 
 
1011
let rec expand_and_check_vars env = function
 
1012
  | [] -> []
 
1013
  | a::l ->
 
1014
      if isRel a or isVar a then
 
1015
        let l = expand_and_check_vars env l in
 
1016
        match expand_var_opt env a with
 
1017
        | None -> a :: l
 
1018
        | Some a' when isRel a' or isVar a' -> list_add_set a' l
 
1019
        | _ -> raise Exit
 
1020
      else
 
1021
        raise Exit
 
1022
 
 
1023
let is_unification_pattern_evar env (_,args) l t =
 
1024
  List.for_all (fun x -> isRel x || isVar x) l (* common failure case *)
 
1025
  &&
 
1026
    let l' = Array.to_list args @ l in
 
1027
    let l'' = try Some (expand_and_check_vars env l') with Exit -> None in
 
1028
    match l'' with
 
1029
    | Some l ->
 
1030
        let deps =
 
1031
          if occur_meta_or_existential t then
 
1032
            (* Probably no restrictions on allowed vars in presence of evars *)
 
1033
            l
 
1034
          else
 
1035
            (* Probably strong restrictions coming from t being evar-closed *)
 
1036
            let t = expand_vars_in_term env t in
 
1037
            let fv_rels = free_rels t in
 
1038
            let fv_ids = global_vars env t in
 
1039
            List.filter (fun c ->
 
1040
              match kind_of_term c with
 
1041
              | Var id -> List.mem id fv_ids
 
1042
              | Rel n -> Intset.mem n fv_rels
 
1043
              | _ -> assert false) l in
 
1044
        list_distinct deps
 
1045
    | None -> false
 
1046
 
 
1047
let is_unification_pattern (env,nb) f l t =
 
1048
  match kind_of_term f with
 
1049
    | Meta _ ->
 
1050
        array_for_all (fun c -> isRel c && destRel c <= nb) l
 
1051
        && array_distinct l
 
1052
    | Evar ev ->
 
1053
        is_unification_pattern_evar env ev (Array.to_list l) t
 
1054
    | _ ->
 
1055
        false
 
1056
 
 
1057
(* From a unification problem "?X l1 = term1 l2" such that l1 is made
 
1058
   of distinct rel's, build "\x1...xn.(term1 l2)" (patterns unification) *)
 
1059
 
 
1060
let solve_pattern_eqn env l1 c =
 
1061
  let l1 = List.map (expand_var env) l1 in
 
1062
  let c' = List.fold_right (fun a c ->
 
1063
    let c' = subst_term (lift 1 a) (lift 1 c) in
 
1064
    match kind_of_term a with
 
1065
      (* Rem: if [a] links to a let-in, do as if it were an assumption *)
 
1066
      | Rel n -> let (na,_,t) = lookup_rel n env in mkLambda (na,lift n t,c')
 
1067
      | Var id -> let (id,_,t) = lookup_named id env in mkNamedLambda id t c'
 
1068
      | _ -> assert false) 
 
1069
    l1 c in
 
1070
  (* Warning: we may miss some opportunity to eta-reduce more since c'
 
1071
     is not in normal form *)
 
1072
  whd_eta c'
 
1073
 
 
1074
(* This code (i.e. solve_pb, etc.) takes a unification
 
1075
 * problem, and tries to solve it. If it solves it, then it removes
 
1076
 * all the conversion problems, and re-runs conversion on each one, in
 
1077
 * the hopes that the new solution will aid in solving them.
 
1078
 *
 
1079
 * The kinds of problems it knows how to solve are those in which
 
1080
 * the usable arguments of an existential var are all themselves
 
1081
 * universal variables.
 
1082
 * The solution to this problem is to do renaming for the Var's,
 
1083
 * to make them match up with the Var's which are found in the
 
1084
 * hyps of the existential, to do a "pop" for each Rel which is
 
1085
 * not an argument of the existential, and a subst1 for each which
 
1086
 * is, again, with the corresponding variable. This is done by
 
1087
 * evar_define
 
1088
 *
 
1089
 * Thus, we take the arguments of the existential which we are about
 
1090
 * to assign, and zip them with the identifiers in the hypotheses.
 
1091
 * Then, we process all the Var's in the arguments, and sort the
 
1092
 * Rel's into ascending order.  Then, we just march up, doing
 
1093
 * subst1's and pop's.
 
1094
 *
 
1095
 * NOTE: We can do this more efficiently for the relative arguments,
 
1096
 * by building a long substituend by hand, but this is a pain in the
 
1097
 * ass.
 
1098
 *)
 
1099
 
 
1100
let status_changed lev (pbty,_,t1,t2) =
 
1101
  try 
 
1102
    List.mem (head_evar t1) lev or List.mem (head_evar t2) lev
 
1103
  with Failure _ ->
 
1104
    try List.mem (head_evar t2) lev with Failure _ -> false
 
1105
 
 
1106
(* Solve pbs (?i x1..xn) = (?i y1..yn) which arises often in fixpoint
 
1107
 * definitions. We try to unify the xi with the yi pairwise. The pairs
 
1108
 * that don't unify are discarded (i.e. ?i is redefined so that it does not
 
1109
 * depend on these args). *)
 
1110
 
 
1111
let solve_refl conv_algo env evd evk argsv1 argsv2 =
 
1112
  if argsv1 = argsv2 then evd else
 
1113
  let evi = Evd.find (evars_of evd) evk in
 
1114
  (* Filter and restrict if needed *)
 
1115
  let evd,evk,args =
 
1116
    restrict_upon_filter evd evi evk
 
1117
      (fun (a1,a2) -> snd (conv_algo env evd Reduction.CONV a1 a2))
 
1118
      (List.combine (Array.to_list argsv1) (Array.to_list argsv2)) in
 
1119
  (* Leave a unification problem *)
 
1120
  let args1,args2 = List.split args in
 
1121
  let argsv1 = Array.of_list args1 and argsv2 = Array.of_list args2 in
 
1122
  let pb = (Reduction.CONV,env,mkEvar(evk,argsv1),mkEvar(evk,argsv2)) in
 
1123
  Evd.add_conv_pb pb evd
 
1124
 
 
1125
(* Tries to solve problem t1 = t2.
 
1126
 * Precondition: t1 is an uninstantiated evar
 
1127
 * Returns an optional list of evars that were instantiated, or None
 
1128
 * if the problem couldn't be solved. *)
 
1129
 
 
1130
(* Rq: uncomplete algorithm if pbty = CONV_X_LEQ ! *)
 
1131
let solve_simple_eqn conv_algo ?(choose=false) env evd (pbty,(evk1,args1 as ev1),t2) =
 
1132
  try
 
1133
    let t2 = whd_evar (evars_of evd) t2 in
 
1134
    let evd = match kind_of_term t2 with
 
1135
      | Evar (evk2,args2 as ev2) ->
 
1136
          if evk1 = evk2 then
 
1137
            solve_refl conv_algo env evd evk1 args1 args2
 
1138
          else
 
1139
            if pbty = Reduction.CONV 
 
1140
            then solve_evar_evar evar_define env evd ev1 ev2
 
1141
            else add_conv_pb (pbty,env,mkEvar ev1,t2) evd
 
1142
      | _ ->
 
1143
          let evd = evar_define ~choose env ev1 t2 evd in
 
1144
          let evm = evars_of evd in
 
1145
          let evi = Evd.find evm evk1 in
 
1146
            if occur_existential evm evi.evar_concl then
 
1147
              let evenv = evar_env evi in
 
1148
              let evc = nf_isevar evd evi.evar_concl in
 
1149
                match evi.evar_body with 
 
1150
                | Evar_defined body -> 
 
1151
                    let ty = nf_isevar evd (Retyping.get_type_of_with_meta evenv evm (metas_of evd) body) in
 
1152
                      add_conv_pb (Reduction.CUMUL,evenv,ty,evc) evd
 
1153
                | Evar_empty -> (* Resulted in a constraint *) 
 
1154
                    evd
 
1155
            else evd
 
1156
    in
 
1157
    let (evd,pbs) = extract_changed_conv_pbs evd status_changed in
 
1158
      List.fold_left
 
1159
        (fun (evd,b as p) (pbty,env,t1,t2) ->
 
1160
          if b then conv_algo env evd pbty t1 t2 else p) (evd,true)
 
1161
        pbs
 
1162
  with e when precatchable_exception e ->
 
1163
    (evd,false)
 
1164
 
 
1165
let evars_of_term c = 
 
1166
  let rec evrec acc c =
 
1167
    match kind_of_term c with
 
1168
    | Evar (n, _) -> Intset.add n acc
 
1169
    | _ -> fold_constr evrec acc c
 
1170
  in 
 
1171
    evrec Intset.empty c
 
1172
 
 
1173
let evars_of_named_context nc =
 
1174
  List.fold_right (fun (_, b, t) s ->
 
1175
    Option.fold_left (fun s t -> 
 
1176
      Intset.union s (evars_of_term t))
 
1177
      s b) nc Intset.empty
 
1178
 
 
1179
let evars_of_evar_info evi =
 
1180
  Intset.union (evars_of_term evi.evar_concl)
 
1181
    (Intset.union 
 
1182
        (match evi.evar_body with 
 
1183
        | Evar_empty -> Intset.empty
 
1184
        | Evar_defined b -> evars_of_term b)
 
1185
        (evars_of_named_context (named_context_of_val evi.evar_hyps)))
 
1186
    
 
1187
(* [check_evars] fails if some unresolved evar remains *)
 
1188
(* it assumes that the defined existentials have already been substituted *)
 
1189
 
 
1190
let check_evars env initial_sigma evd c =
 
1191
  let sigma = evars_of evd in
 
1192
  let c = nf_evar sigma c in
 
1193
  let rec proc_rec c =
 
1194
    match kind_of_term c with
 
1195
      | Evar (evk,args) ->
 
1196
          assert (Evd.mem sigma evk);
 
1197
          if not (Evd.mem initial_sigma evk) then
 
1198
            let (loc,k) = evar_source evk evd in
 
1199
            let evi = nf_evar_info sigma (Evd.find sigma evk) in
 
1200
            error_unsolvable_implicit loc env sigma evi k None
 
1201
      | _ -> iter_constr proc_rec c
 
1202
  in proc_rec c
 
1203
 
 
1204
(* Operations on value/type constraints *)
 
1205
 
 
1206
type type_constraint_type = (int * int) option * constr
 
1207
type type_constraint = type_constraint_type option
 
1208
 
 
1209
type val_constraint = constr option
 
1210
 
 
1211
(* Old comment...
 
1212
 * Basically, we have the following kind of constraints (in increasing
 
1213
 * strength order):
 
1214
 *   (false,(None,None)) -> no constraint at all
 
1215
 *   (true,(None,None))  -> we must build a judgement which _TYPE is a kind
 
1216
 *   (_,(None,Some ty))  -> we must build a judgement which _TYPE is ty
 
1217
 *   (_,(Some v,_))      -> we must build a judgement which _VAL is v
 
1218
 * Maybe a concrete datatype would be easier to understand.
 
1219
 * We differentiate (true,(None,None)) from (_,(None,Some Type))
 
1220
 * because otherwise Case(s) would be misled, as in
 
1221
 * (n:nat) Case n of bool [_]nat end  would infer the predicate Type instead
 
1222
 * of Set.
 
1223
 *)
 
1224
 
 
1225
(* The empty type constraint *)
 
1226
let empty_tycon = None
 
1227
 
 
1228
let mk_tycon_type c = (None, c)
 
1229
let mk_abstr_tycon_type n c = (Some (n, n), c) (* First component is initial abstraction, second
 
1230
                                                  is current abstraction *)
 
1231
 
 
1232
(* Builds a type constraint *)
 
1233
let mk_tycon ty = Some (mk_tycon_type ty)
 
1234
 
 
1235
let mk_abstr_tycon n ty = Some (mk_abstr_tycon_type n ty)
 
1236
 
 
1237
(* Constrains the value of a type *)
 
1238
let empty_valcon = None
 
1239
 
 
1240
(* Builds a value constraint *)
 
1241
let mk_valcon c = Some c
 
1242
 
 
1243
(* Refining an evar to a product or a sort *)
 
1244
 
 
1245
(* Declaring any type to be in the sort Type shouldn't be harmful since
 
1246
   cumulativity now includes Prop and Set in Type...
 
1247
   It is, but that's not too bad *)
 
1248
let define_evar_as_abstraction abs evd (ev,args) =
 
1249
  let evi = Evd.find (evars_of evd) ev in
 
1250
  let evenv = evar_unfiltered_env evi in
 
1251
  let (evd1,dom) = new_evar evd evenv (new_Type()) ~filter:(evar_filter evi) in
 
1252
  let nvar =
 
1253
    next_ident_away (id_of_string "x")
 
1254
      (ids_of_named_context (evar_context evi)) in
 
1255
  let newenv = push_named (nvar, None, dom) evenv in
 
1256
  let (evd2,rng) =
 
1257
    new_evar evd1 newenv ~src:(evar_source ev evd1) (new_Type()) 
 
1258
      ~filter:(true::evar_filter evi) in
 
1259
  let prod = abs (Name nvar, dom, subst_var nvar rng) in
 
1260
  let evd3 = Evd.evar_define ev prod evd2 in
 
1261
  let evdom = fst (destEvar dom), args in
 
1262
  let evrng =
 
1263
    fst (destEvar rng), array_cons (mkRel 1) (Array.map (lift 1) args) in
 
1264
  let prod' = abs (Name nvar, mkEvar evdom, mkEvar evrng) in
 
1265
    (evd3,prod')
 
1266
      
 
1267
let define_evar_as_product evd (ev,args) =
 
1268
  define_evar_as_abstraction (fun t -> mkProd t) evd (ev,args)
 
1269
 
 
1270
let define_evar_as_lambda evd (ev,args) =
 
1271
  define_evar_as_abstraction (fun t -> mkLambda t) evd (ev,args)
 
1272
 
 
1273
let define_evar_as_sort evd (ev,args) =
 
1274
  let s = new_Type () in
 
1275
  Evd.evar_define ev s evd, destSort s
 
1276
 
 
1277
(* We don't try to guess in which sort the type should be defined, since
 
1278
   any type has type Type. May cause some trouble, but not so far... *)
 
1279
 
 
1280
let judge_of_new_Type () = Typeops.judge_of_type (new_univ ())
 
1281
 
 
1282
(* Propagation of constraints through application and abstraction:
 
1283
   Given a type constraint on a functional term, returns the type
 
1284
   constraint on its domain and codomain. If the input constraint is
 
1285
   an evar instantiate it with the product of 2 new evars. *)
 
1286
 
 
1287
let split_tycon loc env evd tycon = 
 
1288
  let rec real_split evd c = 
 
1289
    let t = whd_betadeltaiota env (Evd.evars_of evd) c in
 
1290
      match kind_of_term t with
 
1291
        | Prod (na,dom,rng) -> evd, (na, dom, rng)
 
1292
        | Evar ev when not (Evd.is_defined_evar evd ev) ->
 
1293
            let (evd',prod) = define_evar_as_product evd ev in
 
1294
            let (_,dom,rng) = destProd prod in
 
1295
              evd',(Anonymous, dom, rng)
 
1296
        | _ -> error_not_product_loc loc env (Evd.evars_of evd) c
 
1297
  in
 
1298
    match tycon with
 
1299
      | None -> evd,(Anonymous,None,None)
 
1300
      | Some (abs, c) ->
 
1301
          (match abs with
 
1302
               None -> 
 
1303
                 let evd', (n, dom, rng) = real_split evd c in
 
1304
                   evd', (n, mk_tycon dom, mk_tycon rng)
 
1305
             | Some (init, cur) ->
 
1306
                 if cur = 0 then 
 
1307
                   let evd', (x, dom, rng) = real_split evd c in
 
1308
                     evd, (Anonymous, 
 
1309
                          Some (None, dom), 
 
1310
                          Some (None, rng))
 
1311
                 else
 
1312
                   evd, (Anonymous, None, 
 
1313
                        Some (if cur = 1 then None,c else Some (init, pred cur), c)))
 
1314
            
 
1315
let valcon_of_tycon x = 
 
1316
  match x with
 
1317
    | Some (None, t) -> Some t
 
1318
    | _ -> None
 
1319
        
 
1320
let lift_abstr_tycon_type n (abs, t) =
 
1321
  match abs with 
 
1322
      None -> raise (Invalid_argument "lift_abstr_tycon_type: not an abstraction")
 
1323
    | Some (init, abs) ->
 
1324
        let abs' = abs + n in 
 
1325
          if abs' < 0 then raise (Invalid_argument "lift_abstr_tycon_type")
 
1326
          else (Some (init, abs'), t)
 
1327
 
 
1328
let lift_tycon_type n (abs, t) = (abs, lift n t)
 
1329
let lift_tycon n = Option.map (lift_tycon_type n)
 
1330
 
 
1331
let pr_tycon_type env (abs, t) =
 
1332
  match abs with 
 
1333
      None -> Termops.print_constr_env env t
 
1334
    | Some (init, cur) -> str "Abstract (" ++ int init ++ str ","  ++ int cur ++ str ") " ++ Termops.print_constr_env env t
 
1335
        
 
1336
let pr_tycon env = function
 
1337
    None -> str "None"
 
1338
  | Some t -> pr_tycon_type env t
 
1339