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

« back to all changes in this revision

Viewing changes to pretyping/vnorm.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
(*i $Id: vnorm.ml 11424 2008-09-30 12:10:28Z jforest $ i*)
 
10
 
 
11
open Names
 
12
open Declarations
 
13
open Term
 
14
open Environ
 
15
open Inductive
 
16
open Reduction 
 
17
open Vm
 
18
 
 
19
(*******************************************)
 
20
(* Calcul de la forme normal d'un terme    *)
 
21
(*******************************************)
 
22
 
 
23
let crazy_type =  mkSet 
 
24
 
 
25
let decompose_prod env t =
 
26
  let (name,dom,codom as res) = destProd (whd_betadeltaiota env t) in
 
27
  if name = Anonymous then (Name (id_of_string "x"),dom,codom)
 
28
  else res
 
29
 
 
30
exception Find_at of int
 
31
 
 
32
(* rend le numero du constructeur correspondant au tag [tag],
 
33
   [cst] = true si c'est un constructeur constant *)
 
34
 
 
35
let invert_tag cst tag reloc_tbl =
 
36
  try 
 
37
    for j = 0 to Array.length reloc_tbl - 1 do
 
38
      let tagj,arity = reloc_tbl.(j) in
 
39
      if tag = tagj && (cst && arity = 0 || not(cst || arity = 0)) then
 
40
        raise (Find_at j)
 
41
      else ()
 
42
    done;raise Not_found 
 
43
  with Find_at j -> (j+1)   
 
44
             (* Argggg, ces constructeurs de ... qui commencent a 1*)
 
45
 
 
46
let find_rectype_a env c =
 
47
  let (t, l) = 
 
48
    let t = whd_betadeltaiota env c in
 
49
    try destApp t with _ -> (t,[||]) in
 
50
  match kind_of_term t with
 
51
  | Ind ind -> (ind, l)
 
52
  | _ -> raise Not_found
 
53
 
 
54
(* Instantiate inductives and parameters in constructor type *)
 
55
 
 
56
let type_constructor mind mib typ params = 
 
57
  let s = ind_subst mind mib in
 
58
  let ctyp = substl s typ in
 
59
  let nparams = Array.length params in
 
60
  if nparams = 0 then ctyp
 
61
  else
 
62
    let _,ctyp = decompose_prod_n nparams ctyp in   
 
63
    substl (List.rev (Array.to_list params)) ctyp
 
64
 
 
65
 
 
66
 
 
67
let construct_of_constr const env tag typ =
 
68
  let (mind,_ as ind), allargs = find_rectype_a env typ in
 
69
  (* spiwack : here be a branch for specific decompilation handled by retroknowledge *)
 
70
  try
 
71
    if const then
 
72
      ((retroknowledge Retroknowledge.get_vm_decompile_constant_info env (Ind ind) tag),
 
73
       typ) (*spiwack: this may need to be changed in case there are parameters in the
 
74
                       type which may cause a constant value to have an arity.
 
75
                       (type_constructor seems to be all about parameters actually)
 
76
                       but it shouldn't really matter since constant values don't use
 
77
                       their ctyp in the rest of the code.*)
 
78
    else
 
79
      raise Not_found (* No retroknowledge function (yet) for block decompilation *)
 
80
  with Not_found ->
 
81
    let mib,mip = lookup_mind_specif env ind in
 
82
    let nparams = mib.mind_nparams in
 
83
    let i = invert_tag const tag mip.mind_reloc_tbl in
 
84
    let params = Array.sub allargs 0 nparams in
 
85
    let ctyp = type_constructor mind mib (mip.mind_nf_lc.(i-1)) params in
 
86
      (mkApp(mkConstruct(ind,i), params), ctyp)
 
87
 
 
88
let construct_of_constr_const env tag typ = 
 
89
  fst (construct_of_constr true env tag typ)
 
90
 
 
91
let construct_of_constr_block = construct_of_constr false
 
92
 
 
93
let constr_type_of_idkey env idkey =
 
94
  match idkey with
 
95
  | ConstKey cst ->
 
96
      mkConst cst, Typeops.type_of_constant env cst
 
97
  | VarKey id -> 
 
98
      let (_,_,ty) = lookup_named id env in 
 
99
      mkVar id, ty
 
100
  | RelKey i -> 
 
101
      let n = (nb_rel env - i) in
 
102
      let (_,_,ty) = lookup_rel n env in
 
103
      mkRel n, lift n ty
 
104
 
 
105
let type_of_ind env ind = 
 
106
  type_of_inductive env (Inductive.lookup_mind_specif env ind)
 
107
 
 
108
let build_branches_type env (mind,_ as _ind) mib mip params dep p =
 
109
  let rtbl = mip.mind_reloc_tbl in
 
110
  (* [build_one_branch i cty] construit le type de la ieme branche (commence
 
111
     a 0) et les lambda correspondant aux realargs *)
 
112
  let build_one_branch i cty =
 
113
    let typi = type_constructor mind mib cty params in
 
114
    let decl,indapp = Term.decompose_prod typi in
 
115
    let ind,cargs = find_rectype_a env indapp in
 
116
    let nparams = Array.length params in
 
117
    let carity = snd (rtbl.(i)) in
 
118
    let crealargs = Array.sub cargs nparams (Array.length cargs - nparams) in
 
119
    let codom = 
 
120
      let papp = mkApp(p,crealargs) in
 
121
      if dep then
 
122
        let cstr = ith_constructor_of_inductive ind (i+1) in
 
123
        let relargs = Array.init carity (fun i -> mkRel (carity-i)) in
 
124
        let dep_cstr = mkApp(mkApp(mkConstruct cstr,params),relargs) in
 
125
        mkApp(papp,[|dep_cstr|])
 
126
      else papp
 
127
    in 
 
128
    decl, codom
 
129
  in Array.mapi build_one_branch mip.mind_nf_lc
 
130
 
 
131
let build_case_type dep p realargs c = 
 
132
  if dep then mkApp(mkApp(p, realargs), [|c|])
 
133
  else mkApp(p, realargs)
 
134
 
 
135
(* La fonction de normalisation *)
 
136
 
 
137
let rec nf_val env v t = nf_whd env (whd_val v) t 
 
138
 
 
139
and nf_vtype env v =  nf_val env v crazy_type
 
140
 
 
141
and nf_whd env whd typ =
 
142
  match whd with
 
143
  | Vsort s -> mkSort s
 
144
  | Vprod p ->
 
145
      let dom = nf_vtype env (dom p) in
 
146
      let name = Name (id_of_string "x") in
 
147
      let vc = body_of_vfun (nb_rel env) (codom p) in
 
148
      let codom = nf_vtype (push_rel (name,None,dom) env) vc  in      
 
149
      mkProd(name,dom,codom)      
 
150
  | Vfun f -> nf_fun env f typ
 
151
  | Vfix(f,None) -> nf_fix env f
 
152
  | Vfix(f,Some vargs) -> fst (nf_fix_app env f vargs)
 
153
  | Vcofix(cf,_,None) -> nf_cofix env cf 
 
154
  | Vcofix(cf,_,Some vargs) -> 
 
155
      let cfd = nf_cofix env cf in
 
156
      let i,(_,ta,_) = destCoFix cfd in
 
157
      let t = ta.(i) in
 
158
      let _, args = nf_args env vargs t in
 
159
      mkApp(cfd,args) 
 
160
  | Vconstr_const n -> construct_of_constr_const env n typ
 
161
  | Vconstr_block b ->
 
162
      let capp,ctyp = construct_of_constr_block env (btag b) typ in
 
163
      let args = nf_bargs env b ctyp in
 
164
      mkApp(capp,args)
 
165
  | Vatom_stk(Aid idkey, stk) ->
 
166
      let c,typ = constr_type_of_idkey env idkey in
 
167
      nf_stk env c typ stk
 
168
  | Vatom_stk(Aiddef(idkey,v), stk) ->
 
169
      nf_whd env (whd_stack v stk) typ
 
170
  | Vatom_stk(Aind ind, stk) ->
 
171
      nf_stk env (mkInd ind) (type_of_ind env ind) stk 
 
172
        
 
173
and nf_stk env c t stk  =
 
174
  match stk with
 
175
  | [] -> c
 
176
  | Zapp vargs :: stk ->
 
177
      let t, args = nf_args env vargs t in
 
178
      nf_stk env (mkApp(c,args)) t stk 
 
179
  | Zfix (f,vargs) :: stk ->  
 
180
      let fa, typ = nf_fix_app env f vargs in
 
181
      let _,_,codom = try decompose_prod env typ with _ -> exit 120 in
 
182
      nf_stk env (mkApp(fa,[|c|])) (subst1 c codom) stk
 
183
  | Zswitch sw :: stk -> 
 
184
      let (mind,_ as ind),allargs = find_rectype_a env t in
 
185
      let (mib,mip) = Inductive.lookup_mind_specif env ind in
 
186
      let nparams = mib.mind_nparams in
 
187
      let params,realargs = Util.array_chop nparams allargs in
 
188
      let pT = 
 
189
        hnf_prod_applist env (type_of_ind env ind) (Array.to_list params) in
 
190
      let pT = whd_betadeltaiota env pT in
 
191
      let dep, p = nf_predicate env ind mip params (type_of_switch sw) pT in
 
192
      (* Calcul du type des branches *)
 
193
      let btypes = build_branches_type env ind mib mip params dep p in
 
194
      (* calcul des branches *)
 
195
      let bsw = branch_of_switch (nb_rel env) sw in
 
196
      let mkbranch i (n,v) =
 
197
        let decl,codom = btypes.(i) in
 
198
        let env = 
 
199
          List.fold_right 
 
200
            (fun (name,t) env -> push_rel (name,None,t) env) decl env in
 
201
        let b = nf_val env v codom in
 
202
        compose_lam decl b 
 
203
      in 
 
204
      let branchs = Array.mapi mkbranch bsw in
 
205
      let tcase = build_case_type dep p realargs c in
 
206
      let ci = case_info sw in
 
207
      nf_stk env (mkCase(ci, p, c, branchs)) tcase stk
 
208
 
 
209
and nf_predicate env ind mip params v pT =
 
210
  match whd_val v, kind_of_term pT with
 
211
  | Vfun f, Prod _ ->
 
212
      let k = nb_rel env in
 
213
      let vb = body_of_vfun k f in
 
214
      let name,dom,codom = try decompose_prod env pT with _ -> exit 121 in
 
215
      let dep,body = 
 
216
        nf_predicate (push_rel (name,None,dom) env) ind mip params vb codom in
 
217
      dep, mkLambda(name,dom,body)
 
218
  | Vfun f, _ -> 
 
219
      let k = nb_rel env in
 
220
      let vb = body_of_vfun k f in
 
221
      let name = Name (id_of_string "c") in
 
222
      let n = mip.mind_nrealargs in
 
223
      let rargs = Array.init n (fun i -> mkRel (n-i)) in
 
224
      let params = if n=0 then params else Array.map (lift n) params in
 
225
      let dom = mkApp(mkInd ind,Array.append params rargs) in
 
226
      let body = nf_vtype (push_rel (name,None,dom) env) vb in
 
227
      true, mkLambda(name,dom,body)
 
228
  | _, _ -> false, nf_val env v crazy_type
 
229
        
 
230
and nf_args env vargs t =
 
231
  let t = ref t in
 
232
  let len = nargs vargs in
 
233
  let args = 
 
234
    Array.init len 
 
235
      (fun i ->
 
236
        let _,dom,codom = try decompose_prod env !t with _ -> exit 123 in
 
237
        let c = nf_val env (arg vargs i) dom in
 
238
        t := subst1 c codom; c) in
 
239
  !t,args
 
240
 
 
241
and nf_bargs env b t =
 
242
  let t = ref t in
 
243
  let len = bsize b in
 
244
  let args =
 
245
    Array.init len 
 
246
      (fun i -> 
 
247
        let _,dom,codom = try decompose_prod env !t with _ -> exit 124 in
 
248
        let c = nf_val env (bfield b i) dom in
 
249
        t := subst1 c codom; c) in
 
250
  args
 
251
 
 
252
and nf_fun env f typ =
 
253
  let k = nb_rel env in
 
254
  let vb = body_of_vfun k f in
 
255
  let name,dom,codom = 
 
256
    try decompose_prod env typ
 
257
    with _ ->
 
258
      raise (Type_errors.TypeError(env,Type_errors.ReferenceVariables typ))
 
259
  in
 
260
  let body = nf_val (push_rel (name,None,dom) env) vb codom in
 
261
  mkLambda(name,dom,body)
 
262
 
 
263
and nf_fix env f =
 
264
  let init = current_fix f in
 
265
  let rec_args = rec_args f in
 
266
  let k = nb_rel env in
 
267
  let vb, vt = reduce_fix k f in
 
268
  let ndef = Array.length vt in
 
269
  let ft = Array.map (fun v -> nf_val env v crazy_type) vt in
 
270
  let name = Array.init ndef (fun _ -> (Name (id_of_string "Ffix"))) in
 
271
  let env = push_rec_types (name,ft,ft) env in 
 
272
  let fb = Util.array_map2 (fun v t -> nf_fun env v t) vb ft in
 
273
  mkFix ((rec_args,init),(name,ft,fb))
 
274
      
 
275
and nf_fix_app env f vargs =
 
276
  let fd = nf_fix env f in
 
277
  let (_,i),(_,ta,_) = destFix fd in
 
278
  let t = ta.(i) in
 
279
  let t, args = nf_args env vargs t in
 
280
  mkApp(fd,args),t
 
281
  
 
282
and nf_cofix env cf =
 
283
  let init = current_cofix cf in
 
284
  let k = nb_rel env in
 
285
  let vb,vt = reduce_cofix k cf in
 
286
  let ndef = Array.length vt in
 
287
  let cft = Array.map (fun v -> nf_val env v crazy_type) vt in
 
288
  let name = Array.init ndef (fun _ -> (Name (id_of_string "Fcofix"))) in
 
289
  let env = push_rec_types (name,cft,cft) env in 
 
290
  let cfb = Util.array_map2 (fun v t -> nf_val env v t) vb cft in
 
291
  mkCoFix (init,(name,cft,cfb))
 
292
  
 
293
let cbv_vm env c t  =
 
294
  let transp = transp_values () in
 
295
  if not transp then set_transp_values true; 
 
296
  let v = Vconv.val_of_constr env c in
 
297
  let c = nf_val env v t in
 
298
  if not transp then set_transp_values false; 
 
299
  c
 
300