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

« back to all changes in this revision

Viewing changes to contrib/funind/rawtermops.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
open Pp 
 
2
open Rawterm
 
3
open Util
 
4
open Names
 
5
(* Ocaml 3.06 Map.S does not handle is_empty *)
 
6
let idmap_is_empty m = m = Idmap.empty
 
7
 
 
8
(* 
 
9
   Some basic functions to rebuild rawconstr
 
10
   In each of them the location is Util.dummy_loc
 
11
*)
 
12
let mkRRef ref = RRef(dummy_loc,ref)
 
13
let mkRVar id = RVar(dummy_loc,id)
 
14
let mkRApp(rt,rtl) = RApp(dummy_loc,rt,rtl)
 
15
let mkRLambda(n,t,b) = RLambda(dummy_loc,n,Explicit,t,b)
 
16
let mkRProd(n,t,b) = RProd(dummy_loc,n,Explicit,t,b)
 
17
let mkRLetIn(n,t,b) = RLetIn(dummy_loc,n,t,b)
 
18
let mkRCases(rto,l,brl) = RCases(dummy_loc,Term.RegularStyle,rto,l,brl)
 
19
let mkRSort s = RSort(dummy_loc,s)
 
20
let mkRHole () = RHole(dummy_loc,Evd.BinderType Anonymous)
 
21
let mkRCast(b,t) = RCast(dummy_loc,b,CastConv (Term.DEFAULTcast,t))
 
22
 
 
23
(*
 
24
  Some basic functions to decompose rawconstrs
 
25
  These are analogous to the ones constrs
 
26
*)
 
27
let raw_decompose_prod = 
 
28
  let rec raw_decompose_prod args = function 
 
29
  | RProd(_,n,k,t,b) -> 
 
30
      raw_decompose_prod ((n,t)::args) b 
 
31
  | rt -> args,rt
 
32
  in
 
33
  raw_decompose_prod []
 
34
 
 
35
let raw_decompose_prod_or_letin = 
 
36
  let rec raw_decompose_prod args = function 
 
37
  | RProd(_,n,k,t,b) -> 
 
38
      raw_decompose_prod ((n,None,Some t)::args) b 
 
39
  | RLetIn(_,n,t,b) -> 
 
40
      raw_decompose_prod ((n,Some t,None)::args) b 
 
41
  | rt -> args,rt
 
42
  in
 
43
  raw_decompose_prod []
 
44
 
 
45
let raw_compose_prod = 
 
46
  List.fold_left (fun b (n,t) -> mkRProd(n,t,b))
 
47
 
 
48
let raw_compose_prod_or_letin = 
 
49
  List.fold_left (
 
50
      fun concl decl -> 
 
51
        match decl with 
 
52
          | (n,None,Some t) -> mkRProd(n,t,concl)
 
53
          | (n,Some bdy,None) -> mkRLetIn(n,bdy,concl)
 
54
          | _ -> assert false)
 
55
 
 
56
let raw_decompose_prod_n n = 
 
57
  let rec raw_decompose_prod i args c = 
 
58
    if i<=0 then args,c
 
59
    else
 
60
      match c with
 
61
        | RProd(_,n,_,t,b) -> 
 
62
            raw_decompose_prod (i-1) ((n,t)::args) b 
 
63
        | rt -> args,rt
 
64
  in
 
65
  raw_decompose_prod n []
 
66
 
 
67
 
 
68
let raw_decompose_prod_or_letin_n n = 
 
69
  let rec raw_decompose_prod i args c = 
 
70
    if i<=0 then args,c
 
71
    else
 
72
      match c with
 
73
        | RProd(_,n,_,t,b) -> 
 
74
            raw_decompose_prod (i-1) ((n,None,Some t)::args) b 
 
75
        | RLetIn(_,n,t,b) -> 
 
76
            raw_decompose_prod (i-1) ((n,Some t,None)::args) b 
 
77
        | rt -> args,rt
 
78
  in
 
79
  raw_decompose_prod n []
 
80
 
 
81
 
 
82
let raw_decompose_app = 
 
83
  let rec decompose_rapp acc rt =
 
84
(*     msgnl (str "raw_decompose_app on : "++ Printer.pr_rawconstr rt); *)
 
85
    match rt with 
 
86
    | RApp(_,rt,rtl) -> 
 
87
        decompose_rapp (List.fold_left (fun y x -> x::y) acc rtl) rt
 
88
    | rt -> rt,List.rev acc
 
89
  in
 
90
  decompose_rapp [] 
 
91
 
 
92
 
 
93
 
 
94
 
 
95
(* [raw_make_eq t1 t2] build the rawconstr corresponding to [t2 = t1] *) 
 
96
let raw_make_eq ?(typ= mkRHole ()) t1 t2  = 
 
97
  mkRApp(mkRRef (Lazy.force Coqlib.coq_eq_ref),[typ;t2;t1])
 
98
 
 
99
(* [raw_make_neq t1 t2] build the rawconstr corresponding to [t1 <> t2] *) 
 
100
let raw_make_neq t1 t2 = 
 
101
  mkRApp(mkRRef (Lazy.force Coqlib.coq_not_ref),[raw_make_eq t1 t2])
 
102
 
 
103
(* [raw_make_or P1 P2] build the rawconstr corresponding to [P1 \/ P2] *) 
 
104
let raw_make_or t1 t2 = mkRApp (mkRRef(Lazy.force Coqlib.coq_or_ref),[t1;t2])
 
105
 
 
106
(* [raw_make_or_list [P1;...;Pn]] build the rawconstr corresponding 
 
107
   to [P1 \/ ( .... \/ Pn)] 
 
108
*) 
 
109
let rec raw_make_or_list = function  
 
110
  | [] -> raise (Invalid_argument "mk_or")
 
111
  | [e] -> e
 
112
  | e::l -> raw_make_or e (raw_make_or_list l)
 
113
 
 
114
  
 
115
let remove_name_from_mapping mapping na = 
 
116
  match na with 
 
117
    | Anonymous -> mapping 
 
118
    | Name id -> Idmap.remove id mapping
 
119
 
 
120
let change_vars = 
 
121
  let rec change_vars mapping rt = 
 
122
    match rt with 
 
123
      | RRef _ -> rt 
 
124
      | RVar(loc,id) ->  
 
125
          let new_id = 
 
126
            try 
 
127
              Idmap.find id mapping 
 
128
            with Not_found -> id 
 
129
          in
 
130
          RVar(loc,new_id)
 
131
      | REvar _ -> rt 
 
132
      | RPatVar _ -> rt 
 
133
      | RApp(loc,rt',rtl) -> 
 
134
          RApp(loc,
 
135
               change_vars mapping rt',
 
136
               List.map (change_vars mapping) rtl
 
137
              )
 
138
      | RLambda(loc,name,k,t,b) -> 
 
139
          RLambda(loc,
 
140
                  name,
 
141
                  k,
 
142
                  change_vars mapping t,
 
143
                  change_vars (remove_name_from_mapping mapping name) b
 
144
                 )
 
145
      | RProd(loc,name,k,t,b) -> 
 
146
          RProd(loc,
 
147
                  name,
 
148
                  k,
 
149
                  change_vars mapping t,
 
150
                  change_vars (remove_name_from_mapping mapping name) b
 
151
                 )
 
152
      | RLetIn(loc,name,def,b) -> 
 
153
          RLetIn(loc,
 
154
                 name,
 
155
                 change_vars mapping def,
 
156
                 change_vars (remove_name_from_mapping mapping name) b
 
157
                )
 
158
      | RLetTuple(loc,nal,(na,rto),b,e) -> 
 
159
          let new_mapping = List.fold_left remove_name_from_mapping mapping nal in 
 
160
          RLetTuple(loc,
 
161
                    nal,
 
162
                    (na, Option.map (change_vars mapping) rto), 
 
163
                    change_vars mapping b, 
 
164
                    change_vars new_mapping e
 
165
                   )
 
166
      | RCases(loc,sty,infos,el,brl) -> 
 
167
          RCases(loc,sty,
 
168
                 infos,
 
169
                 List.map (fun (e,x) -> (change_vars mapping e,x)) el, 
 
170
                 List.map (change_vars_br mapping) brl
 
171
                )
 
172
      | RIf(loc,b,(na,e_option),lhs,rhs) -> 
 
173
          RIf(loc,
 
174
              change_vars mapping b,
 
175
              (na,Option.map (change_vars mapping) e_option),
 
176
              change_vars mapping lhs,
 
177
              change_vars mapping rhs
 
178
             )
 
179
      | RRec _ -> error "Local (co)fixes are not supported"
 
180
      | RSort _ -> rt 
 
181
      | RHole _ -> rt 
 
182
      | RCast(loc,b,CastConv (k,t)) -> 
 
183
          RCast(loc,change_vars mapping b, CastConv (k,change_vars mapping t))
 
184
      | RCast(loc,b,CastCoerce) -> 
 
185
          RCast(loc,change_vars mapping b,CastCoerce)
 
186
      | RDynamic _ -> error "Not handled RDynamic"
 
187
  and change_vars_br mapping ((loc,idl,patl,res) as br) = 
 
188
    let new_mapping = List.fold_right Idmap.remove idl mapping in 
 
189
    if idmap_is_empty new_mapping 
 
190
    then br 
 
191
    else (loc,idl,patl,change_vars new_mapping res)
 
192
  in
 
193
  change_vars 
 
194
 
 
195
 
 
196
 
 
197
let rec alpha_pat excluded pat = 
 
198
  match pat with 
 
199
    | PatVar(loc,Anonymous) -> 
 
200
        let new_id = Indfun_common.fresh_id excluded "_x" in 
 
201
        PatVar(loc,Name new_id),(new_id::excluded),Idmap.empty
 
202
    | PatVar(loc,Name id) -> 
 
203
        if List.mem id excluded 
 
204
        then 
 
205
          let new_id = Nameops.next_ident_away id excluded in 
 
206
          PatVar(loc,Name new_id),(new_id::excluded),
 
207
        (Idmap.add id new_id Idmap.empty)
 
208
        else pat,excluded,Idmap.empty
 
209
    | PatCstr(loc,constr,patl,na) -> 
 
210
        let new_na,new_excluded,map = 
 
211
          match na with 
 
212
            | Name id when List.mem id excluded -> 
 
213
                let new_id = Nameops.next_ident_away id excluded in 
 
214
                Name new_id,new_id::excluded, Idmap.add id new_id Idmap.empty
 
215
            | _ -> na,excluded,Idmap.empty
 
216
        in 
 
217
        let new_patl,new_excluded,new_map = 
 
218
          List.fold_left 
 
219
            (fun (patl,excluded,map) pat -> 
 
220
               let new_pat,new_excluded,new_map = alpha_pat excluded pat in 
 
221
               (new_pat::patl,new_excluded,Idmap.fold Idmap.add new_map map)
 
222
            )
 
223
            ([],new_excluded,map)
 
224
            patl
 
225
        in 
 
226
        PatCstr(loc,constr,List.rev new_patl,new_na),new_excluded,new_map
 
227
 
 
228
let alpha_patl excluded patl  = 
 
229
  let patl,new_excluded,map = 
 
230
    List.fold_left 
 
231
      (fun (patl,excluded,map) pat -> 
 
232
         let new_pat,new_excluded,new_map = alpha_pat excluded pat in 
 
233
         new_pat::patl,new_excluded,(Idmap.fold Idmap.add new_map map)
 
234
      )
 
235
      ([],excluded,Idmap.empty)
 
236
      patl
 
237
  in 
 
238
  (List.rev patl,new_excluded,map)
 
239
 
 
240
 
 
241
 
 
242
  
 
243
let raw_get_pattern_id pat acc = 
 
244
  let rec get_pattern_id pat = 
 
245
    match pat with 
 
246
      | PatVar(loc,Anonymous) -> assert false
 
247
      | PatVar(loc,Name id) -> 
 
248
          [id]
 
249
      | PatCstr(loc,constr,patternl,_) -> 
 
250
          List.fold_right 
 
251
          (fun pat idl -> 
 
252
             let idl' = get_pattern_id pat in 
 
253
             idl'@idl
 
254
          )
 
255
            patternl 
 
256
            []
 
257
  in
 
258
  (get_pattern_id pat)@acc
 
259
 
 
260
let get_pattern_id pat = raw_get_pattern_id pat []
 
261
              
 
262
let rec alpha_rt excluded rt = 
 
263
  let new_rt = 
 
264
    match rt with   
 
265
      | RRef _ | RVar _ | REvar _ | RPatVar _ -> rt
 
266
      | RLambda(loc,Anonymous,k,t,b) -> 
 
267
          let new_id = Nameops.next_ident_away (id_of_string "_x") excluded in 
 
268
          let new_excluded = new_id :: excluded in 
 
269
          let new_t = alpha_rt new_excluded t in 
 
270
          let new_b = alpha_rt new_excluded b in 
 
271
          RLambda(loc,Name new_id,k,new_t,new_b)
 
272
      | RProd(loc,Anonymous,k,t,b) -> 
 
273
        let new_t = alpha_rt excluded t in 
 
274
        let new_b = alpha_rt excluded b in 
 
275
        RProd(loc,Anonymous,k,new_t,new_b)
 
276
    | RLetIn(loc,Anonymous,t,b) -> 
 
277
        let new_t = alpha_rt excluded t in 
 
278
        let new_b = alpha_rt excluded b in 
 
279
        RLetIn(loc,Anonymous,new_t,new_b)
 
280
    | RLambda(loc,Name id,k,t,b) -> 
 
281
        let new_id = Nameops.next_ident_away id excluded in 
 
282
        let t,b = 
 
283
          if new_id = id 
 
284
          then t,b
 
285
          else 
 
286
            let replace = change_vars (Idmap.add id new_id Idmap.empty) in 
 
287
            (t,replace b)
 
288
        in
 
289
        let new_excluded = new_id::excluded in 
 
290
        let new_t = alpha_rt new_excluded t in 
 
291
        let new_b = alpha_rt new_excluded b in 
 
292
        RLambda(loc,Name new_id,k,new_t,new_b)
 
293
    | RProd(loc,Name id,k,t,b) -> 
 
294
        let new_id = Nameops.next_ident_away id excluded in 
 
295
        let new_excluded = new_id::excluded in 
 
296
        let t,b = 
 
297
          if new_id = id 
 
298
          then t,b
 
299
          else 
 
300
            let replace = change_vars (Idmap.add id new_id Idmap.empty) in 
 
301
            (t,replace b)
 
302
        in
 
303
        let new_t = alpha_rt new_excluded t in 
 
304
        let new_b = alpha_rt new_excluded b in 
 
305
        RProd(loc,Name new_id,k,new_t,new_b)
 
306
    | RLetIn(loc,Name id,t,b) -> 
 
307
        let new_id = Nameops.next_ident_away id excluded in 
 
308
        let t,b = 
 
309
          if new_id = id 
 
310
          then t,b
 
311
          else 
 
312
            let replace = change_vars (Idmap.add id new_id Idmap.empty) in 
 
313
            (t,replace b)
 
314
        in
 
315
        let new_excluded = new_id::excluded in 
 
316
        let new_t = alpha_rt new_excluded t in 
 
317
        let new_b = alpha_rt new_excluded b in 
 
318
        RLetIn(loc,Name new_id,new_t,new_b)
 
319
 
 
320
 
 
321
    | RLetTuple(loc,nal,(na,rto),t,b) -> 
 
322
        let rev_new_nal,new_excluded,mapping = 
 
323
          List.fold_left 
 
324
            (fun (nal,excluded,mapping) na -> 
 
325
               match na with 
 
326
                 | Anonymous -> (na::nal,excluded,mapping)
 
327
                 | Name id ->  
 
328
                     let new_id = Nameops.next_ident_away id excluded in 
 
329
                     if new_id = id 
 
330
                     then 
 
331
                       na::nal,id::excluded,mapping 
 
332
                     else 
 
333
                       (Name new_id)::nal,id::excluded,(Idmap.add id new_id mapping)
 
334
            )
 
335
            ([],excluded,Idmap.empty)
 
336
            nal
 
337
        in
 
338
        let new_nal = List.rev rev_new_nal in 
 
339
        let new_rto,new_t,new_b = 
 
340
          if idmap_is_empty mapping
 
341
          then rto,t,b
 
342
          else let replace = change_vars mapping in 
 
343
          (Option.map replace rto, t,replace b)
 
344
        in
 
345
        let new_t = alpha_rt new_excluded new_t in 
 
346
        let new_b = alpha_rt new_excluded new_b in 
 
347
        let new_rto = Option.map (alpha_rt new_excluded) new_rto  in
 
348
        RLetTuple(loc,new_nal,(na,new_rto),new_t,new_b)
 
349
    | RCases(loc,sty,infos,el,brl) -> 
 
350
        let new_el = 
 
351
          List.map (function (rt,i) -> alpha_rt excluded rt, i) el 
 
352
        in 
 
353
        RCases(loc,sty,infos,new_el,List.map (alpha_br excluded) brl) 
 
354
    | RIf(loc,b,(na,e_o),lhs,rhs) -> 
 
355
        RIf(loc,alpha_rt excluded b,
 
356
            (na,Option.map (alpha_rt excluded) e_o),
 
357
            alpha_rt excluded lhs,
 
358
            alpha_rt excluded rhs
 
359
           )
 
360
    | RRec _ -> error "Not handled RRec"
 
361
    | RSort _ -> rt 
 
362
    | RHole _ -> rt 
 
363
    | RCast (loc,b,CastConv (k,t)) -> 
 
364
        RCast(loc,alpha_rt excluded b,CastConv(k,alpha_rt excluded t))
 
365
    | RCast (loc,b,CastCoerce) -> 
 
366
        RCast(loc,alpha_rt excluded b,CastCoerce)
 
367
    | RDynamic _ -> error "Not handled RDynamic"
 
368
    | RApp(loc,f,args) -> 
 
369
        RApp(loc,
 
370
             alpha_rt excluded f,
 
371
             List.map (alpha_rt excluded) args
 
372
            )
 
373
  in 
 
374
  new_rt
 
375
 
 
376
and alpha_br excluded (loc,ids,patl,res) = 
 
377
  let new_patl,new_excluded,mapping = alpha_patl excluded patl in 
 
378
  let new_ids = List.fold_right raw_get_pattern_id new_patl [] in 
 
379
  let new_excluded = new_ids@excluded in 
 
380
  let renamed_res = change_vars mapping res in 
 
381
  let new_res = alpha_rt new_excluded renamed_res in 
 
382
  (loc,new_ids,new_patl,new_res)
 
383
    
 
384
(* 
 
385
   [is_free_in id rt] checks if [id] is a free variable in [rt]
 
386
*)
 
387
let is_free_in id =
 
388
  let rec is_free_in = function
 
389
    | RRef _ ->  false
 
390
    | RVar(_,id') -> id_ord id' id == 0
 
391
    | REvar _ -> false
 
392
    | RPatVar _ -> false
 
393
    | RApp(_,rt,rtl) -> List.exists is_free_in (rt::rtl)
 
394
    | RLambda(_,n,_,t,b) | RProd(_,n,_,t,b) | RLetIn(_,n,t,b) ->
 
395
        let check_in_b =
 
396
          match n with
 
397
            | Name id' -> id_ord id' id <> 0
 
398
            | _ -> true
 
399
        in
 
400
        is_free_in t || (check_in_b && is_free_in b)
 
401
    | RCases(_,_,_,el,brl) ->
 
402
        (List.exists (fun (e,_) -> is_free_in e) el) ||
 
403
          List.exists is_free_in_br brl
 
404
    | RLetTuple(_,nal,_,b,t) -> 
 
405
        let check_in_nal = 
 
406
          not (List.exists (function Name id' -> id'= id | _ -> false) nal) 
 
407
        in 
 
408
        is_free_in t  || (check_in_nal && is_free_in b)
 
409
          
 
410
    | RIf(_,cond,_,br1,br2) ->
 
411
        is_free_in cond || is_free_in br1 || is_free_in br2
 
412
    | RRec _ -> raise (UserError("",str "Not handled RRec"))
 
413
    | RSort _ -> false
 
414
    | RHole _ -> false
 
415
    | RCast (_,b,CastConv (_,t)) -> is_free_in b || is_free_in t
 
416
    | RCast (_,b,CastCoerce) -> is_free_in b
 
417
    | RDynamic _ -> raise (UserError("",str "Not handled RDynamic"))
 
418
  and is_free_in_br (_,ids,_,rt) =
 
419
    (not (List.mem id ids)) && is_free_in rt
 
420
  in
 
421
  is_free_in
 
422
      
 
423
 
 
424
 
 
425
let rec pattern_to_term  = function
 
426
  | PatVar(loc,Anonymous) -> assert false
 
427
  | PatVar(loc,Name id) ->
 
428
        mkRVar id
 
429
  | PatCstr(loc,constr,patternl,_) ->
 
430
      let cst_narg =
 
431
        Inductiveops.mis_constructor_nargs_env
 
432
          (Global.env ())
 
433
          constr
 
434
      in
 
435
      let implicit_args =
 
436
        Array.to_list
 
437
          (Array.init
 
438
             (cst_narg - List.length patternl)
 
439
             (fun _ -> mkRHole ())
 
440
          )
 
441
      in
 
442
      let patl_as_term =
 
443
        List.map pattern_to_term patternl
 
444
      in
 
445
      mkRApp(mkRRef(Libnames.ConstructRef constr),
 
446
             implicit_args@patl_as_term
 
447
            )
 
448
 
 
449
  
 
450
 
 
451
let replace_var_by_term x_id term = 
 
452
  let rec replace_var_by_pattern rt = 
 
453
    match rt with 
 
454
      | RRef _ -> rt 
 
455
      | RVar(_,id) when id_ord id x_id == 0 -> term
 
456
      | RVar _ -> rt 
 
457
      | REvar _ -> rt 
 
458
      | RPatVar _ -> rt 
 
459
      | RApp(loc,rt',rtl) -> 
 
460
          RApp(loc,
 
461
               replace_var_by_pattern rt',
 
462
               List.map replace_var_by_pattern rtl
 
463
              )
 
464
      | RLambda(_,Name id,_,_,_) when id_ord id x_id == 0 -> rt
 
465
      | RLambda(loc,name,k,t,b) -> 
 
466
          RLambda(loc,
 
467
                  name,
 
468
                  k,
 
469
                  replace_var_by_pattern t,
 
470
                  replace_var_by_pattern b
 
471
                 )
 
472
      | RProd(_,Name id,_,_,_) when id_ord id x_id == 0 -> rt
 
473
      | RProd(loc,name,k,t,b) -> 
 
474
          RProd(loc,
 
475
                  name,
 
476
                  k,
 
477
                  replace_var_by_pattern t,
 
478
                  replace_var_by_pattern b
 
479
                 )
 
480
      | RLetIn(_,Name id,_,_) when id_ord id x_id == 0 -> rt
 
481
      | RLetIn(loc,name,def,b) -> 
 
482
          RLetIn(loc,
 
483
                 name,
 
484
                 replace_var_by_pattern def,
 
485
                 replace_var_by_pattern b
 
486
                )
 
487
      | RLetTuple(_,nal,_,_,_) 
 
488
          when List.exists (function Name id -> id = x_id | _ -> false) nal  ->  
 
489
          rt
 
490
      | RLetTuple(loc,nal,(na,rto),def,b) -> 
 
491
          RLetTuple(loc,
 
492
                    nal,
 
493
                    (na,Option.map replace_var_by_pattern rto),
 
494
                    replace_var_by_pattern def,
 
495
                    replace_var_by_pattern b
 
496
                   )
 
497
      | RCases(loc,sty,infos,el,brl) -> 
 
498
          RCases(loc,sty,
 
499
                 infos,
 
500
                 List.map (fun (e,x) -> (replace_var_by_pattern e,x)) el, 
 
501
                 List.map replace_var_by_pattern_br brl
 
502
                )
 
503
      | RIf(loc,b,(na,e_option),lhs,rhs) -> 
 
504
          RIf(loc, replace_var_by_pattern b,
 
505
              (na,Option.map replace_var_by_pattern e_option),
 
506
              replace_var_by_pattern lhs,
 
507
              replace_var_by_pattern rhs
 
508
             )
 
509
      | RRec _ -> raise (UserError("",str "Not handled RRec"))
 
510
      | RSort _ -> rt 
 
511
      | RHole _ -> rt 
 
512
      | RCast(loc,b,CastConv(k,t)) -> 
 
513
          RCast(loc,replace_var_by_pattern b,CastConv(k,replace_var_by_pattern t))
 
514
      | RCast(loc,b,CastCoerce) -> 
 
515
          RCast(loc,replace_var_by_pattern b,CastCoerce)
 
516
      | RDynamic _ -> raise (UserError("",str "Not handled RDynamic"))
 
517
  and replace_var_by_pattern_br ((loc,idl,patl,res) as br) = 
 
518
    if List.exists (fun id -> id_ord id x_id == 0) idl 
 
519
    then br 
 
520
    else (loc,idl,patl,replace_var_by_pattern res)
 
521
  in
 
522
  replace_var_by_pattern 
 
523
 
 
524
 
 
525
 
 
526
 
 
527
(* checking unifiability of patterns *) 
 
528
exception NotUnifiable  
 
529
 
 
530
let rec are_unifiable_aux  = function 
 
531
  | [] -> () 
 
532
  | eq::eqs -> 
 
533
      match eq with 
 
534
         | PatVar _,_ | _,PatVar _ -> are_unifiable_aux eqs 
 
535
         | PatCstr(_,constructor1,cpl1,_),PatCstr(_,constructor2,cpl2,_) -> 
 
536
             if constructor2 <> constructor1 
 
537
             then raise NotUnifiable
 
538
             else 
 
539
               let eqs' = 
 
540
                 try  ((List.combine cpl1 cpl2)@eqs)
 
541
                 with _ -> anomaly "are_unifiable_aux" 
 
542
               in
 
543
               are_unifiable_aux eqs'
 
544
                 
 
545
let are_unifiable pat1 pat2 = 
 
546
  try 
 
547
    are_unifiable_aux [pat1,pat2];
 
548
    true
 
549
  with NotUnifiable -> false
 
550
 
 
551
 
 
552
let rec eq_cases_pattern_aux  = function 
 
553
  | [] -> () 
 
554
  | eq::eqs -> 
 
555
      match eq with 
 
556
         | PatVar _,PatVar _ -> eq_cases_pattern_aux eqs 
 
557
         | PatCstr(_,constructor1,cpl1,_),PatCstr(_,constructor2,cpl2,_) -> 
 
558
             if constructor2 <> constructor1 
 
559
             then raise NotUnifiable
 
560
             else 
 
561
               let eqs' = 
 
562
                 try  ((List.combine cpl1 cpl2)@eqs)
 
563
                 with _ -> anomaly "eq_cases_pattern_aux" 
 
564
               in
 
565
               eq_cases_pattern_aux eqs'
 
566
         | _ -> raise NotUnifiable
 
567
 
 
568
let eq_cases_pattern pat1 pat2 = 
 
569
  try
 
570
    eq_cases_pattern_aux [pat1,pat2];
 
571
    true
 
572
  with NotUnifiable -> false
 
573
 
 
574
 
 
575
 
 
576
let ids_of_pat = 
 
577
  let rec ids_of_pat ids = function 
 
578
    | PatVar(_,Anonymous) -> ids 
 
579
    | PatVar(_,Name id) -> Idset.add id ids 
 
580
    | PatCstr(_,_,patl,_) -> List.fold_left ids_of_pat ids patl
 
581
  in
 
582
  ids_of_pat Idset.empty 
 
583
  
 
584
let id_of_name = function 
 
585
  | Names.Anonymous -> id_of_string "x" 
 
586
  | Names.Name x -> x
 
587
 
 
588
(* TODO: finish Rec caes *)
 
589
let ids_of_rawterm c = 
 
590
  let rec ids_of_rawterm acc c = 
 
591
    let idof = id_of_name in
 
592
    match c with
 
593
      | RVar (_,id) -> id::acc
 
594
      | RApp (loc,g,args) -> 
 
595
          ids_of_rawterm [] g @ List.flatten (List.map (ids_of_rawterm []) args) @ acc
 
596
      | RLambda (loc,na,k,ty,c) -> idof na :: ids_of_rawterm [] ty @ ids_of_rawterm [] c @ acc
 
597
      | RProd (loc,na,k,ty,c) -> idof na :: ids_of_rawterm [] ty @ ids_of_rawterm [] c @ acc
 
598
      | RLetIn (loc,na,b,c) -> idof na :: ids_of_rawterm [] b @ ids_of_rawterm [] c @ acc
 
599
      | RCast (loc,c,CastConv(k,t)) -> ids_of_rawterm [] c @ ids_of_rawterm [] t @ acc
 
600
      | RCast (loc,c,CastCoerce) -> ids_of_rawterm [] c @ acc
 
601
      | RIf (loc,c,(na,po),b1,b2) -> ids_of_rawterm [] c @ ids_of_rawterm [] b1 @ ids_of_rawterm [] b2 @ acc
 
602
      | RLetTuple (_,nal,(na,po),b,c) -> 
 
603
          List.map idof nal @ ids_of_rawterm [] b @ ids_of_rawterm [] c @ acc
 
604
      | RCases (loc,sty,rtntypopt,tml,brchl) -> 
 
605
          List.flatten (List.map (fun (_,idl,patl,c) -> idl @ ids_of_rawterm [] c) brchl)
 
606
      | RRec _ -> failwith "Fix inside a constructor branch"
 
607
      | (RSort _ | RHole _ | RRef _ | REvar _ | RPatVar _ | RDynamic _) -> []
 
608
  in
 
609
  (* build the set *)
 
610
  List.fold_left (fun acc x -> Idset.add x acc) Idset.empty (ids_of_rawterm [] c)
 
611
  
 
612
 
 
613
 
 
614
 
 
615
 
 
616
let zeta_normalize = 
 
617
  let rec zeta_normalize_term rt = 
 
618
    match rt with 
 
619
      | RRef _ -> rt 
 
620
      | RVar _ -> rt 
 
621
      | REvar _ -> rt 
 
622
      | RPatVar _ -> rt 
 
623
      | RApp(loc,rt',rtl) -> 
 
624
          RApp(loc,
 
625
               zeta_normalize_term rt',
 
626
               List.map zeta_normalize_term rtl
 
627
              )
 
628
      | RLambda(loc,name,k,t,b) -> 
 
629
          RLambda(loc,
 
630
                  name,
 
631
                  k,
 
632
                  zeta_normalize_term t,
 
633
                  zeta_normalize_term b
 
634
                 )
 
635
      | RProd(loc,name,k,t,b) -> 
 
636
          RProd(loc,
 
637
                name,           
 
638
                k,
 
639
                zeta_normalize_term t,
 
640
                zeta_normalize_term b
 
641
                 )
 
642
      | RLetIn(_,Name id,def,b) -> 
 
643
          zeta_normalize_term (replace_var_by_term id def b)
 
644
      | RLetIn(loc,Anonymous,def,b) -> zeta_normalize_term b
 
645
      | RLetTuple(loc,nal,(na,rto),def,b) -> 
 
646
          RLetTuple(loc,
 
647
                    nal,
 
648
                    (na,Option.map zeta_normalize_term rto),
 
649
                    zeta_normalize_term def,
 
650
                    zeta_normalize_term b
 
651
                   )
 
652
      | RCases(loc,sty,infos,el,brl) -> 
 
653
          RCases(loc,sty,
 
654
                 infos,
 
655
                 List.map (fun (e,x) -> (zeta_normalize_term e,x)) el, 
 
656
                 List.map zeta_normalize_br brl
 
657
                )
 
658
      | RIf(loc,b,(na,e_option),lhs,rhs) -> 
 
659
          RIf(loc, zeta_normalize_term b,
 
660
              (na,Option.map zeta_normalize_term e_option),
 
661
              zeta_normalize_term lhs,
 
662
              zeta_normalize_term rhs
 
663
             )
 
664
      | RRec _ -> raise (UserError("",str "Not handled RRec"))
 
665
      | RSort _ -> rt 
 
666
      | RHole _ -> rt 
 
667
      | RCast(loc,b,CastConv(k,t)) -> 
 
668
          RCast(loc,zeta_normalize_term b,CastConv(k,zeta_normalize_term t))
 
669
      | RCast(loc,b,CastCoerce) -> 
 
670
          RCast(loc,zeta_normalize_term b,CastCoerce)
 
671
      | RDynamic _ -> raise (UserError("",str "Not handled RDynamic"))
 
672
  and zeta_normalize_br (loc,idl,patl,res) = 
 
673
    (loc,idl,patl,zeta_normalize_term res)
 
674
  in
 
675
  zeta_normalize_term 
 
676
 
 
677
 
 
678
 
 
679
 
 
680
let expand_as = 
 
681
  
 
682
  let rec add_as map pat = 
 
683
    match pat with 
 
684
      | PatVar _ -> map 
 
685
      | PatCstr(_,_,patl,Name id) -> 
 
686
          Idmap.add id (pattern_to_term pat) (List.fold_left add_as map patl)
 
687
      | PatCstr(_,_,patl,_) -> List.fold_left add_as map patl
 
688
  in 
 
689
  let rec expand_as map rt = 
 
690
    match rt with 
 
691
      | RRef _ | REvar _ | RPatVar _ | RSort _ | RHole _ -> rt 
 
692
      | RVar(_,id) -> 
 
693
          begin
 
694
            try 
 
695
              Idmap.find id map
 
696
            with Not_found -> rt 
 
697
          end
 
698
      | RApp(loc,f,args) -> RApp(loc,expand_as map f,List.map (expand_as map) args)
 
699
      | RLambda(loc,na,k,t,b) -> RLambda(loc,na,k,expand_as map t, expand_as map b)
 
700
      | RProd(loc,na,k,t,b) -> RProd(loc,na,k,expand_as map t, expand_as map b)
 
701
      | RLetIn(loc,na,v,b) -> RLetIn(loc,na, expand_as map v,expand_as map b)
 
702
      | RLetTuple(loc,nal,(na,po),v,b) ->
 
703
          RLetTuple(loc,nal,(na,Option.map (expand_as map) po),
 
704
                    expand_as map v, expand_as map b)
 
705
      | RIf(loc,e,(na,po),br1,br2) ->
 
706
          RIf(loc,expand_as map e,(na,Option.map (expand_as map) po),
 
707
              expand_as map br1, expand_as map br2)
 
708
      | RRec _ ->  error "Not handled RRec"
 
709
      | RDynamic _ -> error "Not handled RDynamic"
 
710
      | RCast(loc,b,CastConv(kind,t)) -> RCast(loc,expand_as map b,CastConv(kind,expand_as map t))
 
711
      | RCast(loc,b,CastCoerce) -> RCast(loc,expand_as map b,CastCoerce)
 
712
      | RCases(loc,sty,po,el,brl) ->
 
713
          RCases(loc, sty, Option.map (expand_as map) po, List.map (fun (rt,t) -> expand_as map rt,t) el,
 
714
                List.map (expand_as_br map) brl)
 
715
  and expand_as_br map (loc,idl,cpl,rt) = 
 
716
    (loc,idl,cpl, expand_as (List.fold_left add_as map cpl) rt)
 
717
  in
 
718
  expand_as Idmap.empty