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

« back to all changes in this revision

Viewing changes to pretyping/unification.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: unification.ml 12163 2009-06-06 17:36:47Z herbelin $ *)
 
10
 
 
11
open Pp
 
12
open Util
 
13
open Names
 
14
open Nameops
 
15
open Term
 
16
open Termops
 
17
open Sign
 
18
open Environ
 
19
open Evd
 
20
open Reduction
 
21
open Reductionops
 
22
open Rawterm
 
23
open Pattern
 
24
open Evarutil
 
25
open Pretype_errors
 
26
open Retyping
 
27
open Coercion.Default
 
28
 
 
29
(* if lname_typ is [xn,An;..;x1,A1] and l is a list of terms,
 
30
   gives [x1:A1]..[xn:An]c' such that c converts to ([x1:A1]..[xn:An]c' l) *)
 
31
 
 
32
let abstract_scheme env c l lname_typ =
 
33
  List.fold_left2 
 
34
    (fun t (locc,a) (na,_,ta) ->
 
35
       let na = match kind_of_term a with Var id -> Name id | _ -> na in
 
36
(* [occur_meta ta] test removed for support of eelim/ecase but consequences
 
37
   are unclear...
 
38
       if occur_meta ta then error "cannot find a type for the generalisation"
 
39
       else *) if occur_meta a then lambda_name env (na,ta,t)
 
40
       else lambda_name env (na,ta,subst_term_occ locc a t))
 
41
    c
 
42
    (List.rev l)
 
43
    lname_typ
 
44
 
 
45
let abstract_list_all env evd typ c l =
 
46
  let ctxt,_ = decomp_n_prod env (evars_of evd) (List.length l) typ in
 
47
  let l_with_all_occs = List.map (function a -> (all_occurrences,a)) l in
 
48
  let p = abstract_scheme env c l_with_all_occs ctxt in 
 
49
  try 
 
50
    if is_conv_leq env (evars_of evd) (Typing.mtype_of env evd p) typ then p
 
51
    else error "abstract_list_all"
 
52
  with UserError _ | Type_errors.TypeError _ ->
 
53
    error_cannot_find_well_typed_abstraction env (evars_of evd) p l
 
54
 
 
55
(**)
 
56
 
 
57
(* A refinement of [conv_pb]: the integers tells how many arguments
 
58
   were applied in the context of the conversion problem; if the number
 
59
   is non zero, steps of eta-expansion will be allowed
 
60
*)
 
61
 
 
62
type conv_pb_up_to_eta = Cumul | ConvUnderApp of int * int
 
63
 
 
64
let topconv = ConvUnderApp (0,0)
 
65
let of_conv_pb = function CONV -> topconv | CUMUL -> Cumul
 
66
let conv_pb_of = function ConvUnderApp _ -> CONV | Cumul -> CUMUL
 
67
let prod_pb = function ConvUnderApp _ -> topconv | pb -> pb
 
68
 
 
69
let opp_status = function
 
70
  | IsSuperType -> IsSubType
 
71
  | IsSubType -> IsSuperType
 
72
  | ConvUpToEta _ | UserGiven as x -> x
 
73
 
 
74
let add_type_status (x,y) = ((x,TypeNotProcessed),(y,TypeNotProcessed))
 
75
 
 
76
let extract_instance_status = function
 
77
  | Cumul -> add_type_status (IsSubType, IsSuperType)
 
78
  | ConvUnderApp (n1,n2) -> add_type_status (ConvUpToEta n1, ConvUpToEta n2)
 
79
 
 
80
let rec assoc_pair x = function
 
81
    [] -> raise Not_found
 
82
  | (a,b,_)::l -> if compare a x = 0 then b else assoc_pair x l
 
83
 
 
84
let rec subst_meta_instances bl c =
 
85
  match kind_of_term c with
 
86
    | Meta i -> (try assoc_pair i bl with Not_found -> c)
 
87
    | _ -> map_constr (subst_meta_instances bl) c
 
88
 
 
89
let solve_pattern_eqn_array (env,nb) sigma f l c (metasubst,evarsubst) =
 
90
  match kind_of_term f with
 
91
    | Meta k -> 
 
92
        let c = solve_pattern_eqn env (Array.to_list l) c in
 
93
        let n = Array.length l - List.length (fst (decompose_lam c)) in
 
94
        let pb = (ConvUpToEta n,TypeNotProcessed) in
 
95
          if noccur_between 1 nb c then
 
96
            (k,lift (-nb) c,pb)::metasubst,evarsubst
 
97
          else error_cannot_unify_local env sigma (mkApp (f, l),c,c)
 
98
    | Evar ev ->
 
99
      (* Currently unused: incompatible with eauto/eassumption backtracking *)
 
100
        metasubst,(ev,solve_pattern_eqn env (Array.to_list l) c)::evarsubst
 
101
    | _ -> assert false
 
102
 
 
103
let push d (env,n) = (push_rel_assum d env,n+1)
 
104
 
 
105
(*******************************)
 
106
 
 
107
(* Unification � l'ordre 0 de m et n: [unify_0 env sigma cv_pb m n]
 
108
   renvoie deux listes:
 
109
 
 
110
   metasubst:(int*constr)list    r�colte les instances des (Meta k)
 
111
   evarsubst:(constr*constr)list r�colte les instances des (Const "?k")
 
112
 
 
113
   Attention : pas d'unification entre les diff�rences instances d'une
 
114
   m�me meta ou evar, il peut rester des doublons *)
 
115
 
 
116
(* Unification order: *)
 
117
(* Left to right: unifies first argument and then the other arguments *)
 
118
(*let unify_l2r x = List.rev x
 
119
(* Right to left: unifies last argument and then the other arguments *)
 
120
let unify_r2l x = x
 
121
 
 
122
let sort_eqns = unify_r2l
 
123
*)
 
124
 
 
125
type unify_flags = { 
 
126
  modulo_conv_on_closed_terms : Names.transparent_state option;
 
127
  use_metas_eagerly : bool;
 
128
  modulo_delta : Names.transparent_state;
 
129
}
 
130
 
 
131
let default_unify_flags = {
 
132
  modulo_conv_on_closed_terms = Some full_transparent_state;
 
133
  use_metas_eagerly = true;
 
134
  modulo_delta = full_transparent_state;
 
135
}
 
136
 
 
137
let default_no_delta_unify_flags = {
 
138
  modulo_conv_on_closed_terms = Some full_transparent_state;
 
139
  use_metas_eagerly = true;
 
140
  modulo_delta = empty_transparent_state;
 
141
}
 
142
 
 
143
let expand_key env = function
 
144
  | Some (ConstKey cst) -> constant_opt_value env cst
 
145
  | Some (VarKey id) -> named_body id env
 
146
  | Some (RelKey _) -> None
 
147
  | None -> None
 
148
      
 
149
let key_of flags f =
 
150
  match kind_of_term f with
 
151
  | Const cst when is_transparent (ConstKey cst) &&
 
152
        Cpred.mem cst (snd flags.modulo_delta) ->
 
153
      Some (ConstKey cst) 
 
154
  | Var id when is_transparent (VarKey id) &&
 
155
        Idpred.mem id (fst flags.modulo_delta) ->
 
156
      Some (VarKey id)
 
157
  | _ -> None
 
158
      
 
159
let oracle_order env cf1 cf2 =
 
160
  match cf1 with
 
161
  | None ->
 
162
      (match cf2 with 
 
163
      | None -> None
 
164
      | Some k2 -> Some false)
 
165
  | Some k1 -> 
 
166
      match cf2 with
 
167
      | None -> Some true
 
168
      | Some k2 -> Some (Conv_oracle.oracle_order k1 k2)
 
169
            
 
170
let unify_0_with_initial_metas subst conv_at_top env sigma cv_pb flags m n =
 
171
  let trivial_unify curenv pb (metasubst,_) m n =
 
172
    let subst = if flags.use_metas_eagerly then metasubst else fst subst in
 
173
    match subst_defined_metas subst m with
 
174
    | Some m1 ->
 
175
        if (match flags.modulo_conv_on_closed_terms with
 
176
            Some flags ->
 
177
              is_trans_fconv (conv_pb_of pb) flags env sigma m1 n
 
178
          | None -> false) then true else
 
179
        if (not (is_ground_term (create_evar_defs sigma) m1))
 
180
            || occur_meta_or_existential n then false else
 
181
               error_cannot_unify curenv sigma (m, n)
 
182
    | _ -> false in
 
183
  let rec unirec_rec (curenv,nb as curenvnb) pb b ((metasubst,evarsubst) as substn) curm curn =
 
184
    let cM = Evarutil.whd_castappevar sigma curm
 
185
    and cN = Evarutil.whd_castappevar sigma curn in 
 
186
      match (kind_of_term cM,kind_of_term cN) with
 
187
        | Meta k1, Meta k2 ->
 
188
            let stM,stN = extract_instance_status pb in
 
189
            if k1 < k2 
 
190
            then (k1,cN,stN)::metasubst,evarsubst
 
191
            else if k1 = k2 then substn
 
192
            else (k2,cM,stM)::metasubst,evarsubst
 
193
        | Meta k, _ when not (dependent cM cN) -> 
 
194
            (* Here we check that [cN] does not contain any local variables *)
 
195
            if nb = 0 then
 
196
              (k,cN,snd (extract_instance_status pb))::metasubst,evarsubst
 
197
            else if noccur_between 1 nb cN then
 
198
              (k,lift (-nb) cN,snd (extract_instance_status pb))::metasubst,
 
199
              evarsubst
 
200
            else error_cannot_unify_local curenv sigma (m,n,cN)
 
201
        | _, Meta k when not (dependent cN cM) -> 
 
202
            (* Here we check that [cM] does not contain any local variables *)
 
203
            if nb = 0 then
 
204
              (k,cM,snd (extract_instance_status pb))::metasubst,evarsubst
 
205
            else if noccur_between 1 nb cM
 
206
            then
 
207
              (k,lift (-nb) cM,fst (extract_instance_status pb))::metasubst,
 
208
              evarsubst
 
209
            else error_cannot_unify_local curenv sigma (m,n,cM)
 
210
        | Evar ev, _ -> metasubst,((ev,cN)::evarsubst)
 
211
        | _, Evar ev -> metasubst,((ev,cM)::evarsubst)
 
212
        | Lambda (na,t1,c1), Lambda (_,t2,c2) ->
 
213
            unirec_rec (push (na,t1) curenvnb) topconv true
 
214
              (unirec_rec curenvnb topconv true substn t1 t2) c1 c2
 
215
        | Prod (na,t1,c1), Prod (_,t2,c2) ->
 
216
            unirec_rec (push (na,t1) curenvnb) (prod_pb pb) true
 
217
              (unirec_rec curenvnb topconv true substn t1 t2) c1 c2
 
218
        | LetIn (_,a,_,c), _ -> unirec_rec curenvnb pb b substn (subst1 a c) cN
 
219
        | _, LetIn (_,a,_,c) -> unirec_rec curenvnb pb b substn cM (subst1 a c)
 
220
            
 
221
        | Case (_,p1,c1,cl1), Case (_,p2,c2,cl2) ->
 
222
            array_fold_left2 (unirec_rec curenvnb topconv true)
 
223
              (unirec_rec curenvnb topconv true
 
224
                  (unirec_rec curenvnb topconv true substn p1 p2) c1 c2) cl1 cl2
 
225
 
 
226
        | App (f1,l1), _ when
 
227
            isMeta f1 & is_unification_pattern curenvnb f1 l1 cN &
 
228
            not (dependent f1 cN) ->
 
229
              solve_pattern_eqn_array curenvnb sigma f1 l1 cN substn
 
230
 
 
231
        | _, App (f2,l2) when
 
232
            isMeta f2 & is_unification_pattern curenvnb f2 l2 cM &
 
233
            not (dependent f2 cM) ->
 
234
              solve_pattern_eqn_array curenvnb sigma f2 l2 cM substn
 
235
 
 
236
        | App (f1,l1), App (f2,l2) ->
 
237
              let len1 = Array.length l1
 
238
              and len2 = Array.length l2 in
 
239
              (try
 
240
                  let (f1,l1,f2,l2) =
 
241
                    if len1 = len2 then (f1,l1,f2,l2)
 
242
                    else if len1 < len2 then
 
243
                      let extras,restl2 = array_chop (len2-len1) l2 in 
 
244
                      (f1, l1, appvect (f2,extras), restl2)
 
245
                    else 
 
246
                      let extras,restl1 = array_chop (len1-len2) l1 in 
 
247
                      (appvect (f1,extras), restl1, f2, l2) in
 
248
                  let pb = ConvUnderApp (len1,len2) in
 
249
                  array_fold_left2 (unirec_rec curenvnb topconv true)
 
250
                    (unirec_rec curenvnb pb true substn f1 f2) l1 l2
 
251
                with ex when precatchable_exception ex ->
 
252
                  expand curenvnb pb b substn cM f1 l1 cN f2 l2)
 
253
                
 
254
        | _ ->
 
255
            if constr_cmp (conv_pb_of cv_pb) cM cN then substn else
 
256
            let (f1,l1) = 
 
257
              match kind_of_term cM with App (f,l) -> (f,l) | _ -> (cM,[||]) in
 
258
            let (f2,l2) =
 
259
              match kind_of_term cN with App (f,l) -> (f,l) | _ -> (cN,[||]) in
 
260
            expand curenvnb pb b substn cM f1 l1 cN f2 l2
 
261
 
 
262
  and expand (curenv,_ as curenvnb) pb b substn cM f1 l1 cN f2 l2 =
 
263
    if trivial_unify curenv pb substn cM cN then substn
 
264
    else if b then
 
265
      let cf1 = key_of flags f1 and cf2 = key_of flags f2 in
 
266
        match oracle_order curenv cf1 cf2 with
 
267
        | None -> error_cannot_unify curenv sigma (cM,cN)
 
268
        | Some true -> 
 
269
            (match expand_key curenv cf1 with
 
270
            | Some c ->
 
271
                unirec_rec curenvnb pb b substn
 
272
                  (whd_betaiotazeta sigma (mkApp(c,l1))) cN
 
273
            | None ->
 
274
                (match expand_key curenv cf2 with
 
275
                | Some c ->
 
276
                    unirec_rec curenvnb pb b substn cM
 
277
                      (whd_betaiotazeta sigma (mkApp(c,l2)))
 
278
                | None ->
 
279
                    error_cannot_unify curenv sigma (cM,cN)))
 
280
        | Some false ->
 
281
            (match expand_key curenv cf2 with
 
282
            | Some c ->
 
283
                unirec_rec curenvnb pb b substn cM
 
284
                  (whd_betaiotazeta sigma (mkApp(c,l2)))
 
285
            | None ->
 
286
                (match expand_key curenv cf1 with
 
287
                | Some c ->
 
288
                    unirec_rec curenvnb pb b substn
 
289
                      (whd_betaiotazeta sigma (mkApp(c,l1))) cN
 
290
                | None ->
 
291
                    error_cannot_unify curenv sigma (cM,cN)))
 
292
    else
 
293
      error_cannot_unify curenv sigma (cM,cN)
 
294
 
 
295
  in
 
296
    if (if occur_meta m then false else
 
297
       if (match flags.modulo_conv_on_closed_terms with
 
298
          Some flags ->
 
299
            is_trans_fconv (conv_pb_of cv_pb) flags env sigma m n
 
300
        | None -> constr_cmp (conv_pb_of cv_pb) m n) then true else
 
301
      if (not (is_ground_term (create_evar_defs sigma) m))
 
302
          || occur_meta_or_existential n then false else
 
303
      if (match flags.modulo_conv_on_closed_terms, flags.modulo_delta with
 
304
            | Some (cv_id, cv_k), (dl_id, dl_k) ->
 
305
                Idpred.subset dl_id cv_id && Cpred.subset dl_k cv_k
 
306
            | None,(dl_id, dl_k) ->
 
307
                Idpred.is_empty dl_id && Cpred.is_empty dl_k)
 
308
      then error_cannot_unify env sigma (m, n) else false) 
 
309
    then
 
310
      subst
 
311
    else 
 
312
      unirec_rec (env,0) cv_pb conv_at_top subst m n
 
313
 
 
314
let unify_0 = unify_0_with_initial_metas ([],[]) true
 
315
 
 
316
let left = true
 
317
let right = false
 
318
 
 
319
let pop k = if k=0 then 0 else k-1
 
320
 
 
321
let rec unify_with_eta keptside flags env sigma k1 k2 c1 c2 =
 
322
  (* Reason up to limited eta-expansion: ci is allowed to start with ki lam *)
 
323
  (* Question: try whd_betadeltaiota on ci if ki>0 ? *)
 
324
  match kind_of_term c1, kind_of_term c2 with
 
325
  | (Lambda (na,t1,c1'), Lambda (_,t2,c2')) ->
 
326
      let env' = push_rel_assum (na,t1) env in
 
327
      let metas,evars = unify_0 env sigma topconv flags t1 t2 in
 
328
      let side,status,(metas',evars') =
 
329
        unify_with_eta keptside flags env' sigma (pop k1) (pop k2) c1' c2'
 
330
      in (side,status,(metas@metas',evars@evars'))
 
331
  | (Lambda (na,t,c1'),_) when k2 > 0 ->
 
332
      let env' = push_rel_assum (na,t) env in
 
333
      let side = left in (* expansion on the right: we keep the left side *)
 
334
      unify_with_eta side flags env' sigma (pop k1) (k2-1) 
 
335
        c1' (mkApp (lift 1 c2,[|mkRel 1|]))
 
336
  | (_,Lambda (na,t,c2')) when k1 > 0 ->
 
337
      let env' = push_rel_assum (na,t) env in
 
338
      let side = right in (* expansion on the left: we keep the right side *)
 
339
      unify_with_eta side flags env' sigma (k1-1) (pop k2) 
 
340
        (mkApp (lift 1 c1,[|mkRel 1|])) c2'
 
341
  | _ ->
 
342
      (keptside,ConvUpToEta(min k1 k2),
 
343
       unify_0 env sigma topconv flags c1 c2)
 
344
 
 
345
(* We solved problems [?n =_pb u] (i.e. [u =_(opp pb) ?n]) and [?n =_pb' u'],
 
346
   we now compute the problem on [u =? u'] and decide which of u or u' is kept
 
347
 
 
348
   Rem: the upper constraint is lost in case u <= ?n <= u' (and symmetrically
 
349
   in the case u' <= ?n <= u)
 
350
 *)
 
351
 
 
352
let merge_instances env sigma flags st1 st2 c1 c2 =
 
353
  match (opp_status st1, st2) with
 
354
  | (UserGiven, ConvUpToEta n2) ->
 
355
      unify_with_eta left flags env sigma 0 n2 c1 c2
 
356
  | (ConvUpToEta n1, UserGiven) ->
 
357
      unify_with_eta right flags env sigma n1 0 c1 c2
 
358
  | (ConvUpToEta n1, ConvUpToEta n2) ->
 
359
      let side = left (* arbitrary choice, but agrees with compatibility *) in
 
360
      unify_with_eta side flags env sigma n1 n2 c1 c2
 
361
  | ((IsSubType | ConvUpToEta _ | UserGiven as oppst1),
 
362
     (IsSubType | ConvUpToEta _ | UserGiven)) ->
 
363
      let res = unify_0 env sigma Cumul flags c2 c1 in
 
364
      if oppst1=st2 then (* arbitrary choice *) (left, st1, res)
 
365
      else if st2=IsSubType or st1=UserGiven then (left, st1, res)
 
366
      else (right, st2, res)
 
367
  | ((IsSuperType | ConvUpToEta _ | UserGiven as oppst1),
 
368
     (IsSuperType | ConvUpToEta _ | UserGiven)) ->
 
369
      let res = unify_0 env sigma Cumul flags c1 c2 in
 
370
      if oppst1=st2 then (* arbitrary choice *) (left, st1, res)
 
371
      else if st2=IsSuperType or st1=UserGiven then (left, st1, res)
 
372
      else (right, st2, res)
 
373
  | (IsSuperType,IsSubType) ->
 
374
      (try (left, IsSubType, unify_0 env sigma Cumul flags c2 c1)
 
375
       with _ -> (right, IsSubType, unify_0 env sigma Cumul flags c1 c2))
 
376
  | (IsSubType,IsSuperType) ->
 
377
      (try (left, IsSuperType, unify_0 env sigma Cumul flags c1 c2)
 
378
       with _ -> (right, IsSuperType, unify_0 env sigma Cumul flags c2 c1))
 
379
 
 
380
(* Unification
 
381
 *
 
382
 * Procedure:
 
383
 * (1) The function [unify mc wc M N] produces two lists:
 
384
 *     (a) a list of bindings Meta->RHS
 
385
 *     (b) a list of bindings EVAR->RHS
 
386
 *
 
387
 * The Meta->RHS bindings cannot themselves contain
 
388
 * meta-vars, so they get applied eagerly to the other
 
389
 * bindings.  This may or may not close off all RHSs of
 
390
 * the EVARs.  For each EVAR whose RHS is closed off,
 
391
 * we can just apply it, and go on.  For each which
 
392
 * is not closed off, we need to do a mimick step -
 
393
 * in general, we have something like:
 
394
 *
 
395
 *      ?X == (c e1 e2 ... ei[Meta(k)] ... en)
 
396
 *
 
397
 * so we need to do a mimick step, converting ?X
 
398
 * into
 
399
 *
 
400
 *      ?X -> (c ?z1 ... ?zn)
 
401
 *
 
402
 * of the proper types.  Then, we can decompose the
 
403
 * equation into
 
404
 *
 
405
 *      ?z1 --> e1
 
406
 *          ...
 
407
 *      ?zi --> ei[Meta(k)]
 
408
 *          ...
 
409
 *      ?zn --> en
 
410
 *
 
411
 * and keep on going.  Whenever we find that a R.H.S.
 
412
 * is closed, we can, as before, apply the constraint
 
413
 * directly.  Whenever we find an equation of the form:
 
414
 *
 
415
 *      ?z -> Meta(n)
 
416
 *
 
417
 * we can reverse the equation, put it into our metavar
 
418
 * substitution, and keep going.
 
419
 *
 
420
 * The most efficient mimick possible is, for each
 
421
 * Meta-var remaining in the term, to declare a
 
422
 * new EVAR of the same type.  This is supposedly
 
423
 * determinable from the clausale form context -
 
424
 * we look up the metavar, take its type there,
 
425
 * and apply the metavar substitution to it, to
 
426
 * close it off.  But this might not always work,
 
427
 * since other metavars might also need to be resolved. *)
 
428
 
 
429
let applyHead env evd n c  = 
 
430
  let rec apprec n c cty evd =
 
431
    if n = 0 then 
 
432
      (evd, c)
 
433
    else 
 
434
      match kind_of_term (whd_betadeltaiota env (evars_of evd) cty) with
 
435
        | Prod (_,c1,c2) ->
 
436
            let (evd',evar) = 
 
437
              Evarutil.new_evar evd env ~src:(dummy_loc,GoalEvar) c1 in
 
438
            apprec (n-1) (mkApp(c,[|evar|])) (subst1 evar c2) evd'
 
439
        | _ -> error "Apply_Head_Then"
 
440
  in 
 
441
  apprec n c (Typing.type_of env (evars_of evd) c) evd
 
442
 
 
443
let is_mimick_head f =
 
444
  match kind_of_term f with
 
445
      (Const _|Var _|Rel _|Construct _|Ind _) -> true
 
446
    | _ -> false
 
447
 
 
448
let pose_all_metas_as_evars env evd t =
 
449
  let evdref = ref evd in
 
450
  let rec aux t = match kind_of_term t with
 
451
  | Meta mv ->
 
452
      (match Evd.meta_opt_fvalue !evdref mv with
 
453
       | Some ({rebus=c},_) -> c
 
454
       | None ->
 
455
        let {rebus=ty;freemetas=mvs} = Evd.meta_ftype evd mv in
 
456
        let ty = if mvs = Evd.Metaset.empty then ty else aux ty in
 
457
        let ev = Evarutil.e_new_evar evdref env ~src:(dummy_loc,GoalEvar) ty in
 
458
        evdref := meta_assign mv (ev,(ConvUpToEta 0,TypeNotProcessed)) !evdref;
 
459
        ev)
 
460
  | _ ->
 
461
      map_constr aux t in
 
462
  let c = aux t in
 
463
  (* side-effect *)
 
464
  (!evdref, c)
 
465
 
 
466
let try_to_coerce env evd c cty tycon =
 
467
  let j = make_judge c cty in
 
468
  let (evd',j') = inh_conv_coerce_rigid_to dummy_loc env evd j tycon in
 
469
  let (evd',b) = Evarconv.consider_remaining_unif_problems env evd' in
 
470
  if b then
 
471
    let evd' = Evd.map_metas_fvalue (nf_evar (evars_of evd')) evd' in
 
472
    (evd',j'.uj_val)
 
473
  else
 
474
    error "Cannot solve unification constraints"
 
475
 
 
476
let w_coerce_to_type env evd c cty mvty =
 
477
  let evd,mvty = pose_all_metas_as_evars env evd mvty in
 
478
  let tycon = mk_tycon_type mvty in
 
479
  try try_to_coerce env evd c cty tycon
 
480
  with e when precatchable_exception e ->
 
481
    (* inh_conv_coerce_rigid_to should have reasoned modulo reduction 
 
482
       but there are cases where it though it was not rigid (like in
 
483
       fst (nat,nat)) and stops while it could have seen that it is rigid *)
 
484
    let cty = Tacred.hnf_constr env (evars_of evd) cty in
 
485
    try_to_coerce env evd c cty tycon
 
486
 
 
487
let w_coerce env evd mv c =
 
488
  let cty = get_type_of_with_meta env (evars_of evd) (metas_of evd) c in
 
489
  let mvty = Typing.meta_type evd mv in
 
490
  w_coerce_to_type env evd c cty mvty
 
491
 
 
492
let unify_to_type env evd flags c u =
 
493
  let sigma = evars_of evd in
 
494
  let c = refresh_universes c in
 
495
  let t = get_type_of_with_meta env sigma (List.map (on_snd (nf_meta evd)) (metas_of evd)) (nf_meta evd c) in
 
496
  let t = Tacred.hnf_constr env sigma (nf_betaiota sigma (nf_meta evd t)) in
 
497
  let u = Tacred.hnf_constr env sigma u in
 
498
  try unify_0 env sigma Cumul flags t u
 
499
  with e when precatchable_exception e -> ([],[])
 
500
 
 
501
let unify_type env evd flags mv c =
 
502
  let mvty = Typing.meta_type evd mv in
 
503
  if occur_meta_or_existential mvty or is_arity env (evars_of evd) mvty then
 
504
    unify_to_type env evd flags c mvty
 
505
  else ([],[])
 
506
 
 
507
(* Move metas that may need coercion at the end of the list of instances *)
 
508
 
 
509
let order_metas metas =
 
510
  let rec order latemetas = function
 
511
  | [] -> List.rev latemetas
 
512
  | (_,_,(status,to_type) as meta)::metas ->
 
513
      if to_type = CoerceToType then order (meta::latemetas) metas
 
514
      else meta :: order latemetas metas
 
515
  in order [] metas
 
516
 
 
517
(* Solve an equation ?n[x1=u1..xn=un] = t where ?n is an evar *)
 
518
 
 
519
let solve_simple_evar_eqn env evd ev rhs =
 
520
  let evd,b = solve_simple_eqn Evarconv.evar_conv_x env evd (CONV,ev,rhs) in
 
521
  if not b then error_cannot_unify env (evars_of evd) (mkEvar ev,rhs);
 
522
  let (evd,b) = Evarconv.consider_remaining_unif_problems env evd in
 
523
  if not b then error "Cannot solve unification constraints";
 
524
  evd
 
525
 
 
526
(* [w_merge env sigma b metas evars] merges common instances in metas
 
527
   or in evars, possibly generating new unification problems; if [b]
 
528
   is true, unification of types of metas is required *)
 
529
 
 
530
let w_merge env with_types flags (metas,evars) evd =
 
531
  let rec w_merge_rec evd metas evars eqns =
 
532
 
 
533
    (* Process evars *)
 
534
    match evars with
 
535
    | ((evn,_ as ev),rhs)::evars' ->
 
536
        if is_defined_evar evd ev then
 
537
          let v = Evd.existential_value (evars_of evd) ev in
 
538
          let (metas',evars'') =
 
539
            unify_0 env (evars_of evd) topconv flags rhs v in
 
540
          w_merge_rec evd (metas'@metas) (evars''@evars') eqns
 
541
        else begin
 
542
          let rhs' = subst_meta_instances metas rhs in
 
543
          match kind_of_term rhs with
 
544
          | App (f,cl) when is_mimick_head f & occur_meta rhs' ->
 
545
              if occur_evar evn rhs' then
 
546
                error_occur_check env (evars_of evd) evn rhs';
 
547
              let evd' = mimick_evar evd flags f (Array.length cl) evn in
 
548
              w_merge_rec evd' metas evars eqns
 
549
          | _ ->
 
550
              w_merge_rec (solve_simple_evar_eqn env evd ev rhs')
 
551
                metas evars' eqns
 
552
        end
 
553
    | [] -> 
 
554
 
 
555
    (* Process metas *)
 
556
    match metas with
 
557
    | (mv,c,(status,to_type))::metas ->
 
558
        let ((evd,c),(metas'',evars'')),eqns =
 
559
          if with_types & to_type <> TypeProcessed then
 
560
            if to_type = CoerceToType then
 
561
              (* Some coercion may have to be inserted *)
 
562
              (w_coerce env evd mv c,([],[])),[]
 
563
            else
 
564
              (* No coercion needed: delay the unification of types *)
 
565
              ((evd,c),([],[])),(mv,c)::eqns
 
566
          else 
 
567
            ((evd,c),([],[])),eqns in
 
568
        if meta_defined evd mv then
 
569
          let {rebus=c'},(status',_) = meta_fvalue evd mv in
 
570
          let (take_left,st,(metas',evars')) =
 
571
            merge_instances env (evars_of evd) flags status' status c' c
 
572
          in
 
573
          let evd' = 
 
574
            if take_left then evd 
 
575
            else meta_reassign mv (c,(st,TypeProcessed)) evd 
 
576
          in
 
577
          w_merge_rec evd' (metas'@metas@metas'') (evars'@evars'') eqns
 
578
        else
 
579
          let evd' = meta_assign mv (c,(status,TypeProcessed)) evd in
 
580
          w_merge_rec evd' (metas@metas'') evars'' eqns
 
581
    | [] -> 
 
582
 
 
583
    (* Process type eqns *)
 
584
    match eqns with
 
585
    | (mv,c)::eqns ->
 
586
        let (metas,evars) = unify_type env evd flags mv c in 
 
587
        w_merge_rec evd metas evars eqns
 
588
    | [] -> evd
 
589
                
 
590
  and mimick_evar evd flags hdc nargs sp =
 
591
    let ev = Evd.find (evars_of evd) sp in
 
592
    let sp_env = Global.env_of_context ev.evar_hyps in
 
593
    let (evd', c) = applyHead sp_env evd nargs hdc in
 
594
    let (mc,ec) =
 
595
      unify_0 sp_env (evars_of evd') Cumul flags
 
596
        (Retyping.get_type_of_with_meta sp_env (evars_of evd') (metas_of evd') c) ev.evar_concl in
 
597
    let evd'' = w_merge_rec evd' mc ec [] in
 
598
    if (evars_of evd') == (evars_of evd'')
 
599
    then Evd.evar_define sp c evd''
 
600
    else Evd.evar_define sp (Evarutil.nf_evar (evars_of evd'') c) evd'' in
 
601
 
 
602
  (* merge constraints *)
 
603
  w_merge_rec evd (order_metas metas) evars []
 
604
 
 
605
let w_unify_meta_types env ?(flags=default_unify_flags) evd =
 
606
  let metas,evd = retract_coercible_metas evd in
 
607
  w_merge env true flags (metas,[]) evd
 
608
 
 
609
(* [w_unify env evd M N]
 
610
   performs a unification of M and N, generating a bunch of
 
611
   unification constraints in the process.  These constraints
 
612
   are processed, one-by-one - they may either generate new
 
613
   bindings, or, if there is already a binding, new unifications,
 
614
   which themselves generate new constraints.  This continues
 
615
   until we get failure, or we run out of constraints.
 
616
   [clenv_typed_unify M N clenv] expects in addition that expected
 
617
   types of metavars are unifiable with the types of their instances    *)
 
618
 
 
619
let check_types env evd flags subst m n =
 
620
  let sigma = evars_of evd in
 
621
  if isEvar (fst (whd_stack sigma m)) or isEvar (fst (whd_stack sigma n)) then
 
622
    unify_0_with_initial_metas subst true env (evars_of evd) topconv 
 
623
      flags
 
624
      (Retyping.get_type_of_with_meta env sigma (metas_of evd) m)
 
625
      (Retyping.get_type_of_with_meta env sigma (metas_of evd) n)
 
626
  else
 
627
    subst
 
628
 
 
629
let w_unify_core_0 env with_types cv_pb flags m n evd =
 
630
  let (mc1,evd') = retract_coercible_metas evd in
 
631
  let subst1 = check_types env evd flags (mc1,[]) m n in
 
632
  let subst2 =
 
633
     unify_0_with_initial_metas subst1 true env (evars_of evd') cv_pb flags m n
 
634
  in 
 
635
  w_merge env with_types flags subst2 evd'
 
636
 
 
637
let w_unify_0 env = w_unify_core_0 env false
 
638
let w_typed_unify env = w_unify_core_0 env true
 
639
 
 
640
 
 
641
(* takes a substitution s, an open term op and a closed term cl
 
642
   try to find a subterm of cl which matches op, if op is just a Meta
 
643
   FAIL because we cannot find a binding *)
 
644
 
 
645
let iter_fail f a =
 
646
  let n = Array.length a in 
 
647
  let rec ffail i =
 
648
    if i = n then error "iter_fail" 
 
649
    else
 
650
      try f a.(i) 
 
651
      with ex when precatchable_exception ex -> ffail (i+1)
 
652
  in ffail 0
 
653
 
 
654
(* Tries to find an instance of term [cl] in term [op].
 
655
   Unifies [cl] to every subterm of [op] until it finds a match.
 
656
   Fails if no match is found *)
 
657
let w_unify_to_subterm env ?(flags=default_unify_flags) (op,cl) evd =
 
658
  let rec matchrec cl =
 
659
    let cl = strip_outer_cast cl in
 
660
    (try 
 
661
       if closed0 cl 
 
662
       then w_unify_0 env topconv flags op cl evd,cl
 
663
       else error "Bound 1"
 
664
     with ex when precatchable_exception ex ->
 
665
       (match kind_of_term cl with 
 
666
          | App (f,args) ->
 
667
              let n = Array.length args in
 
668
              assert (n>0);
 
669
              let c1 = mkApp (f,Array.sub args 0 (n-1)) in
 
670
              let c2 = args.(n-1) in
 
671
              (try 
 
672
                 matchrec c1
 
673
               with ex when precatchable_exception ex -> 
 
674
                 matchrec c2)
 
675
          | Case(_,_,c,lf) -> (* does not search in the predicate *)
 
676
               (try 
 
677
                 matchrec c
 
678
               with ex when precatchable_exception ex -> 
 
679
                 iter_fail matchrec lf)
 
680
          | LetIn(_,c1,_,c2) -> 
 
681
               (try 
 
682
                 matchrec c1
 
683
               with ex when precatchable_exception ex -> 
 
684
                 matchrec c2)
 
685
 
 
686
          | Fix(_,(_,types,terms)) -> 
 
687
               (try 
 
688
                 iter_fail matchrec types
 
689
               with ex when precatchable_exception ex -> 
 
690
                 iter_fail matchrec terms)
 
691
        
 
692
          | CoFix(_,(_,types,terms)) -> 
 
693
               (try 
 
694
                 iter_fail matchrec types
 
695
               with ex when precatchable_exception ex -> 
 
696
                 iter_fail matchrec terms)
 
697
 
 
698
          | Prod (_,t,c) ->
 
699
              (try 
 
700
                 matchrec t 
 
701
               with ex when precatchable_exception ex -> 
 
702
                 matchrec c)
 
703
          | Lambda (_,t,c) ->
 
704
              (try 
 
705
                 matchrec t 
 
706
               with ex when precatchable_exception ex -> 
 
707
                 matchrec c)
 
708
          | _ -> error "Match_subterm")) 
 
709
  in 
 
710
  try matchrec cl
 
711
  with ex when precatchable_exception ex ->
 
712
    raise (PretypeError (env,NoOccurrenceFound (op, None)))
 
713
 
 
714
let w_unify_to_subterm_list env flags allow_K oplist t evd = 
 
715
  List.fold_right 
 
716
    (fun op (evd,l) ->
 
717
      if isMeta op then
 
718
        if allow_K then (evd,op::l)
 
719
        else error "Match_subterm"
 
720
      else if occur_meta_or_existential op then
 
721
        let (evd',cl) =
 
722
          try 
 
723
            (* This is up to delta for subterms w/o metas ... *)
 
724
            w_unify_to_subterm env ~flags (strip_outer_cast op,t) evd
 
725
          with PretypeError (env,NoOccurrenceFound _) when allow_K -> (evd,op)
 
726
        in 
 
727
        (evd',cl::l)
 
728
      else if allow_K or dependent op t then
 
729
        (evd,op::l)
 
730
      else
 
731
        (* This is not up to delta ... *)
 
732
        raise (PretypeError (env,NoOccurrenceFound (op, None))))
 
733
    oplist 
 
734
    (evd,[])
 
735
 
 
736
let secondOrderAbstraction env flags allow_K typ (p, oplist) evd =
 
737
  (* Remove delta when looking for a subterm *)
 
738
  let flags = { flags with modulo_delta = (fst flags.modulo_delta, Cpred.empty) } in
 
739
  let (evd',cllist) =
 
740
    w_unify_to_subterm_list env flags allow_K oplist typ evd in
 
741
  let typp = Typing.meta_type evd' p in
 
742
  let pred = abstract_list_all env evd' typp typ cllist in
 
743
  w_merge env false flags ([p,pred,(ConvUpToEta 0,TypeProcessed)],[]) evd'
 
744
 
 
745
let w_unify2 env flags allow_K cv_pb ty1 ty2 evd =
 
746
  let c1, oplist1 = whd_stack (evars_of evd) ty1 in
 
747
  let c2, oplist2 = whd_stack (evars_of evd) ty2 in
 
748
  match kind_of_term c1, kind_of_term c2 with
 
749
    | Meta p1, _ ->
 
750
        (* Find the predicate *)
 
751
        let evd' =
 
752
          secondOrderAbstraction env flags allow_K ty2 (p1,oplist1) evd in 
 
753
        (* Resume first order unification *)
 
754
        w_unify_0 env cv_pb flags (nf_meta evd' ty1) ty2 evd'
 
755
    | _, Meta p2 ->
 
756
        (* Find the predicate *)
 
757
        let evd' =
 
758
          secondOrderAbstraction env flags allow_K ty1 (p2, oplist2) evd in 
 
759
        (* Resume first order unification *)
 
760
        w_unify_0 env cv_pb flags ty1 (nf_meta evd' ty2) evd'
 
761
    | _ -> error "w_unify2"
 
762
 
 
763
(* The unique unification algorithm works like this: If the pattern is
 
764
   flexible, and the goal has a lambda-abstraction at the head, then
 
765
   we do a first-order unification.
 
766
 
 
767
   If the pattern is not flexible, then we do a first-order
 
768
   unification, too.
 
769
 
 
770
   If the pattern is flexible, and the goal doesn't have a
 
771
   lambda-abstraction head, then we second-order unification. *)
 
772
 
 
773
(* We decide here if first-order or second-order unif is used for Apply *)
 
774
(* We apply a term of type (ai:Ai)C and try to solve a goal C'          *)
 
775
(* The type C is in clenv.templtyp.rebus with a lot of Meta to solve    *)
 
776
 
 
777
(* 3-4-99 [HH] New fo/so choice heuristic :
 
778
   In case we have to unify (Meta(1) args) with ([x:A]t args')
 
779
   we first try second-order unification and if it fails first-order.
 
780
   Before, second-order was used if the type of Meta(1) and [x:A]t was
 
781
   convertible and first-order otherwise. But if failed if e.g. the type of
 
782
   Meta(1) had meta-variables in it. *)
 
783
let w_unify allow_K env cv_pb ?(flags=default_unify_flags) ty1 ty2 evd =
 
784
  let cv_pb = of_conv_pb cv_pb in
 
785
  let hd1,l1 = whd_stack (evars_of evd) ty1 in
 
786
  let hd2,l2 = whd_stack (evars_of evd) ty2 in
 
787
    match kind_of_term hd1, l1<>[], kind_of_term hd2, l2<>[] with
 
788
      (* Pattern case *)
 
789
      | (Meta _, true, Lambda _, _ | Lambda _, _, Meta _, true)
 
790
          when List.length l1 = List.length l2 ->
 
791
          (try 
 
792
              w_typed_unify env cv_pb flags ty1 ty2 evd
 
793
            with ex when precatchable_exception ex -> 
 
794
              try 
 
795
                w_unify2 env flags allow_K cv_pb ty1 ty2 evd
 
796
              with PretypeError (env,NoOccurrenceFound _) as e -> raise e)
 
797
            
 
798
      (* Second order case *)
 
799
      | (Meta _, true, _, _ | _, _, Meta _, true) -> 
 
800
          (try 
 
801
              w_unify2 env flags allow_K cv_pb ty1 ty2 evd
 
802
            with PretypeError (env,NoOccurrenceFound _) as e -> raise e
 
803
              | ex when precatchable_exception ex -> 
 
804
                  try 
 
805
                    w_typed_unify env cv_pb flags ty1 ty2 evd
 
806
                  with ex' when precatchable_exception ex' ->
 
807
                    raise ex)
 
808
            
 
809
      (* General case: try first order *)
 
810
      | _ -> w_typed_unify env cv_pb flags ty1 ty2 evd