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

« back to all changes in this revision

Viewing changes to toplevel/class.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: class.ml 11343 2008-09-01 20:55:13Z herbelin $ *)
 
10
 
 
11
open Util
 
12
open Pp
 
13
open Names
 
14
open Nameops
 
15
open Term
 
16
open Termops
 
17
open Inductive
 
18
open Declarations
 
19
open Entries
 
20
open Environ
 
21
open Inductive
 
22
open Lib
 
23
open Classops
 
24
open Declare
 
25
open Libnames
 
26
open Nametab
 
27
open Decl_kinds
 
28
open Safe_typing
 
29
 
 
30
let strength_min l = if List.mem Local l then Local else Global
 
31
 
 
32
let id_of_varid c = match kind_of_term c with
 
33
  | Var id -> id
 
34
  | _ -> anomaly "class__id_of_varid"
 
35
 
 
36
(* Errors *)
 
37
 
 
38
type coercion_error_kind =
 
39
  | AlreadyExists
 
40
  | NotAFunction
 
41
  | NoSource of cl_typ option
 
42
  | ForbiddenSourceClass of cl_typ
 
43
  | NotUniform
 
44
  | NoTarget
 
45
  | WrongTarget of cl_typ * cl_typ
 
46
  | NotAClass of global_reference
 
47
  | NotEnoughClassArgs of cl_typ
 
48
 
 
49
exception CoercionError of coercion_error_kind
 
50
 
 
51
let explain_coercion_error g = function
 
52
  | AlreadyExists ->
 
53
      (Printer.pr_global g ++ str" is already a coercion")
 
54
  | NotAFunction ->
 
55
      (Printer.pr_global g ++ str" is not a function")
 
56
  | NoSource (Some cl) ->
 
57
      (str "Cannot recognize " ++ pr_class cl ++ str " as a source class of " 
 
58
       ++ Printer.pr_global g)
 
59
  | NoSource None ->
 
60
      (str ": cannot find the source class of " ++ Printer.pr_global g)
 
61
  | ForbiddenSourceClass cl ->
 
62
      pr_class cl ++ str " cannot be a source class"
 
63
  | NotUniform ->
 
64
      (Printer.pr_global g ++
 
65
         str" does not respect the inheritance uniform condition");
 
66
  | NoTarget ->
 
67
      (str"Cannot find the target class")
 
68
  | WrongTarget (clt,cl) ->
 
69
      (str"Found target class " ++ pr_class cl ++
 
70
       str " instead of " ++ pr_class clt)
 
71
  | NotAClass ref ->
 
72
      (str "Type of " ++ Printer.pr_global ref ++
 
73
         str " does not end with a sort")
 
74
  | NotEnoughClassArgs cl ->
 
75
      (str"Wrong number of parameters for " ++ pr_class cl)
 
76
 
 
77
(* Verifications pour l'ajout d'une classe *)
 
78
 
 
79
let check_reference_arity ref =
 
80
  if not (Reductionops.is_arity (Global.env()) Evd.empty (Global.type_of_global ref)) then
 
81
    raise (CoercionError (NotAClass ref))
 
82
 
 
83
let check_arity = function
 
84
  | CL_FUN | CL_SORT -> ()
 
85
  | CL_CONST cst -> check_reference_arity (ConstRef cst)
 
86
  | CL_SECVAR id -> check_reference_arity (VarRef id)
 
87
  | CL_IND kn -> check_reference_arity (IndRef kn)
 
88
 
 
89
(* Coercions *)
 
90
 
 
91
(* check that the computed target is the provided one *)
 
92
let check_target clt = function
 
93
  | Some cl when cl <> clt -> raise (CoercionError (WrongTarget(clt,cl)))
 
94
  | _ -> ()
 
95
 
 
96
(* condition d'heritage uniforme *)
 
97
 
 
98
let uniform_cond nargs lt = 
 
99
  let rec aux = function
 
100
    | (0,[]) -> true
 
101
    | (n,t::l) -> (strip_outer_cast t = mkRel n) & (aux ((n-1),l))
 
102
    | _ -> false
 
103
  in 
 
104
  aux (nargs,lt)
 
105
 
 
106
let id_of_cl  = function
 
107
  | CL_FUN -> id_of_string "FUNCLASS"
 
108
  | CL_SORT -> id_of_string "SORTCLASS"
 
109
  | CL_CONST kn -> id_of_label (con_label kn)
 
110
  | CL_IND ind ->
 
111
      let (_,mip) = Global.lookup_inductive ind in
 
112
      mip.mind_typename
 
113
  | CL_SECVAR id -> id
 
114
 
 
115
let class_of_global = function
 
116
  | ConstRef sp -> CL_CONST sp
 
117
  | IndRef sp -> CL_IND sp
 
118
  | VarRef id -> CL_SECVAR id
 
119
  | ConstructRef _ as c -> 
 
120
      errorlabstrm "class_of_global"
 
121
        (str "Constructors, such as " ++ Printer.pr_global c ++ 
 
122
           str ", cannot be used as a class.")
 
123
 
 
124
(* 
 
125
lp est la liste (inverse'e) des arguments de la coercion
 
126
ids est le nom de la classe source
 
127
sps_opt est le sp de la classe source dans le cas des structures
 
128
retourne:
 
129
la classe source
 
130
nbre d'arguments de la classe
 
131
le constr de la class
 
132
la liste des variables dont depend la classe source
 
133
l'indice de la classe source dans la liste lp
 
134
*)
 
135
 
 
136
let get_source lp source =
 
137
  match source with
 
138
    | None ->
 
139
        let (cl1,lv1) =
 
140
          match lp with
 
141
            | [] -> raise Not_found
 
142
            | t1::_ -> find_class_type (Global.env()) Evd.empty t1
 
143
        in 
 
144
        (cl1,lv1,1)
 
145
    | Some cl ->
 
146
        let rec aux = function
 
147
          | [] -> raise Not_found
 
148
          | t1::lt ->
 
149
              try 
 
150
                let cl1,lv1 = find_class_type (Global.env()) Evd.empty t1 in
 
151
                if cl = cl1 then cl1,lv1,(List.length lt+1)
 
152
                else raise Not_found
 
153
              with Not_found -> aux lt
 
154
        in aux (List.rev lp)
 
155
 
 
156
let get_target t ind =
 
157
  if (ind > 1) then 
 
158
    CL_FUN
 
159
  else 
 
160
    fst (find_class_type (Global.env()) Evd.empty t)
 
161
 
 
162
let prods_of t = 
 
163
  let rec aux acc d = match kind_of_term d with
 
164
    | Prod (_,c1,c2) -> aux (c1::acc) c2
 
165
    | Cast (c,_,_) -> aux acc c
 
166
    | _ -> (d,acc)
 
167
  in 
 
168
  aux [] t
 
169
 
 
170
let strength_of_cl = function 
 
171
  | CL_CONST kn -> Global
 
172
  | CL_SECVAR id -> Local
 
173
  | _ -> Global
 
174
 
 
175
let get_strength stre ref cls clt =
 
176
  let stres = strength_of_cl cls in
 
177
  let stret = strength_of_cl clt in
 
178
  let stref = strength_of_global ref in
 
179
  strength_min [stre;stres;stret;stref]
 
180
 
 
181
let ident_key_of_class = function
 
182
  | CL_FUN -> "Funclass"
 
183
  | CL_SORT -> "Sortclass"
 
184
  | CL_CONST sp -> string_of_label (con_label sp)
 
185
  | CL_IND (sp,_) -> string_of_label (label sp)
 
186
  | CL_SECVAR id -> string_of_id id
 
187
 
 
188
(* coercion identit� *)
 
189
 
 
190
let error_not_transparent source =
 
191
  errorlabstrm "build_id_coercion"
 
192
    (pr_class source ++ str " must be a transparent constant.")
 
193
 
 
194
let build_id_coercion idf_opt source =
 
195
  let env = Global.env () in
 
196
  let vs = match source with
 
197
    | CL_CONST sp -> mkConst sp
 
198
    | _ -> error_not_transparent source in
 
199
  let c = match constant_opt_value env (destConst vs) with
 
200
    | Some c -> c
 
201
    | None -> error_not_transparent source in
 
202
  let lams,t = Sign.decompose_lam_assum c in
 
203
  let val_f =
 
204
    it_mkLambda_or_LetIn
 
205
      (mkLambda (Name (id_of_string "x"),
 
206
                 applistc vs (extended_rel_list 0 lams),
 
207
                 mkRel 1))
 
208
       lams
 
209
  in
 
210
  let typ_f =
 
211
    it_mkProd_wo_LetIn
 
212
      (mkProd (Anonymous, applistc vs (extended_rel_list 0 lams), lift 1 t))
 
213
      lams
 
214
  in
 
215
  (* juste pour verification *)
 
216
  let _ = 
 
217
    if not
 
218
      (Reductionops.is_conv_leq env Evd.empty
 
219
        (Typing.type_of env Evd.empty val_f) typ_f)
 
220
    then
 
221
      errorlabstrm "" (strbrk
 
222
        "Cannot be defined as coercion (maybe a bad number of arguments).")
 
223
  in
 
224
  let idf =
 
225
    match idf_opt with
 
226
      | Some idf -> idf
 
227
      | None ->
 
228
          let cl,_ = find_class_type (Global.env()) Evd.empty t in
 
229
          id_of_string ("Id_"^(ident_key_of_class source)^"_"^
 
230
                        (ident_key_of_class cl))
 
231
  in
 
232
  let constr_entry = (* Cast is necessary to express [val_f] is identity *)
 
233
    DefinitionEntry
 
234
      { const_entry_body = mkCast (val_f, DEFAULTcast, typ_f);
 
235
        const_entry_type = Some typ_f;
 
236
        const_entry_opaque = false;
 
237
        const_entry_boxed = Flags.boxed_definitions()} in
 
238
  let kn = declare_constant idf (constr_entry,IsDefinition IdentityCoercion) in
 
239
  ConstRef kn
 
240
 
 
241
let check_source = function
 
242
| Some (CL_FUN|CL_SORT as s) -> raise (CoercionError (ForbiddenSourceClass s))
 
243
| _ -> ()
 
244
 
 
245
(* 
 
246
nom de la fonction coercion
 
247
strength de f
 
248
nom de la classe source (optionnel)
 
249
sp de la classe source (dans le cas des structures)
 
250
nom de la classe target (optionnel)
 
251
booleen "coercion identite'?"
 
252
 
 
253
lorque source est None alors target est None aussi.
 
254
*)
 
255
 
 
256
let add_new_coercion_core coef stre source target isid =
 
257
  check_source source;
 
258
  let t = Global.type_of_global coef in
 
259
  if coercion_exists coef then raise (CoercionError AlreadyExists);
 
260
  let tg,lp = prods_of t in
 
261
  let llp = List.length lp in
 
262
  if llp = 0 then raise (CoercionError NotAFunction);
 
263
  let (cls,lvs,ind) =
 
264
    try 
 
265
      get_source lp source
 
266
    with Not_found ->
 
267
      raise (CoercionError (NoSource source))
 
268
  in
 
269
  check_source (Some cls);
 
270
  if not (uniform_cond (llp-ind) lvs) then
 
271
    raise (CoercionError NotUniform);
 
272
  let clt =
 
273
    try
 
274
      get_target tg ind 
 
275
    with Not_found ->
 
276
      raise (CoercionError NoTarget)
 
277
  in
 
278
  check_target clt target;
 
279
  check_arity cls;
 
280
  check_arity clt;
 
281
  let stre' = get_strength stre coef cls clt in
 
282
  declare_coercion coef stre' isid cls clt (List.length lvs)
 
283
 
 
284
let try_add_new_coercion_core ref b c d e =
 
285
  try add_new_coercion_core ref b c d e
 
286
  with CoercionError e ->
 
287
      errorlabstrm "try_add_new_coercion_core"
 
288
        (explain_coercion_error ref e ++ str ".")
 
289
 
 
290
let try_add_new_coercion ref stre =
 
291
  try_add_new_coercion_core ref stre None None false
 
292
 
 
293
let try_add_new_coercion_subclass cl stre =
 
294
  let coe_ref = build_id_coercion None cl in
 
295
  try_add_new_coercion_core coe_ref stre (Some cl) None true
 
296
 
 
297
let try_add_new_coercion_with_target ref stre ~source ~target =
 
298
  try_add_new_coercion_core ref stre (Some source) (Some target) false
 
299
 
 
300
let try_add_new_identity_coercion id stre ~source ~target =
 
301
  let ref = build_id_coercion (Some id) source in
 
302
  try_add_new_coercion_core ref stre (Some source) (Some target) true
 
303
 
 
304
let try_add_new_coercion_with_source ref stre ~source =
 
305
  try_add_new_coercion_core ref stre (Some source) None false
 
306
 
 
307
let add_coercion_hook stre ref = 
 
308
  try_add_new_coercion ref stre;
 
309
  Flags.if_verbose message
 
310
    (string_of_qualid (shortest_qualid_of_global Idset.empty ref)
 
311
    ^ " is now a coercion")
 
312
 
 
313
let add_subclass_hook stre ref =
 
314
  let cl = class_of_global ref in
 
315
  try_add_new_coercion_subclass cl stre