1 (* Copyright (C) 2000, HELM Team.
3 * This file is part of HELM, an Hypertextual, Electronic
4 * Library of Mathematics, developed at the Computer Science
5 * Department, University of Bologna, Italy.
7 * HELM is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * HELM is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with HELM; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22 * For details, see the HELM World-Wide-Web page,
23 * http://cs.unibo.it/helm/.
26 exception CannotSubstInMeta;;
27 exception RelToHiddenHypothesis;;
28 exception ReferenceToVariable;;
29 exception ReferenceToConstant;;
30 exception ReferenceToCurrentProof;;
31 exception ReferenceToInductiveDefinition;;
32 exception DeliftingWouldCaptureAFreeVariable;;
34 let debug_print = fun _ -> ()
45 | C.Var (uri,exp_named_subst) ->
46 let exp_named_subst' =
47 List.map (function (uri,t) -> (uri,liftaux k t)) exp_named_subst
49 C.Var (uri,exp_named_subst')
55 | Some t -> Some (liftaux k t)
60 | C.Implicit _ as t -> t
61 | C.Cast (te,ty) -> C.Cast (liftaux k te, liftaux k ty)
62 | C.Prod (n,s,t) -> C.Prod (n, liftaux k s, liftaux (k+1) t)
63 | C.Lambda (n,s,t) -> C.Lambda (n, liftaux k s, liftaux (k+1) t)
64 | C.LetIn (n,s,t) -> C.LetIn (n, liftaux k s, liftaux (k+1) t)
65 | C.Appl l -> C.Appl (List.map (liftaux k) l)
66 | C.Const (uri,exp_named_subst) ->
67 let exp_named_subst' =
68 List.map (function (uri,t) -> (uri,liftaux k t)) exp_named_subst
70 C.Const (uri,exp_named_subst')
71 | C.MutInd (uri,tyno,exp_named_subst) ->
72 let exp_named_subst' =
73 List.map (function (uri,t) -> (uri,liftaux k t)) exp_named_subst
75 C.MutInd (uri,tyno,exp_named_subst')
76 | C.MutConstruct (uri,tyno,consno,exp_named_subst) ->
77 let exp_named_subst' =
78 List.map (function (uri,t) -> (uri,liftaux k t)) exp_named_subst
80 C.MutConstruct (uri,tyno,consno,exp_named_subst')
81 | C.MutCase (sp,i,outty,t,pl) ->
82 C.MutCase (sp, i, liftaux k outty, liftaux k t,
83 List.map (liftaux k) pl)
85 let len = List.length fl in
88 (fun (name, i, ty, bo) -> (name, i, liftaux k ty, liftaux (k+len) bo))
93 let len = List.length fl in
96 (fun (name, ty, bo) -> (name, liftaux k ty, liftaux (k+len) bo))
110 (* delifts a term t of n levels strating from k, that is changes (Rel m)
111 * to (Rel (m - n)) when m > (k + n). if k <= m < k + n delift fails
113 let delift_from k n =
115 let module C = Cic in
120 else if m < k + n then
121 raise DeliftingWouldCaptureAFreeVariable
124 | C.Var (uri,exp_named_subst) ->
125 let exp_named_subst' =
126 List.map (function (uri,t) -> (uri,liftaux k t)) exp_named_subst
128 C.Var (uri,exp_named_subst')
134 | Some t -> Some (liftaux k t)
139 | C.Implicit _ as t -> t
140 | C.Cast (te,ty) -> C.Cast (liftaux k te, liftaux k ty)
141 | C.Prod (n,s,t) -> C.Prod (n, liftaux k s, liftaux (k+1) t)
142 | C.Lambda (n,s,t) -> C.Lambda (n, liftaux k s, liftaux (k+1) t)
143 | C.LetIn (n,s,t) -> C.LetIn (n, liftaux k s, liftaux (k+1) t)
144 | C.Appl l -> C.Appl (List.map (liftaux k) l)
145 | C.Const (uri,exp_named_subst) ->
146 let exp_named_subst' =
147 List.map (function (uri,t) -> (uri,liftaux k t)) exp_named_subst
149 C.Const (uri,exp_named_subst')
150 | C.MutInd (uri,tyno,exp_named_subst) ->
151 let exp_named_subst' =
152 List.map (function (uri,t) -> (uri,liftaux k t)) exp_named_subst
154 C.MutInd (uri,tyno,exp_named_subst')
155 | C.MutConstruct (uri,tyno,consno,exp_named_subst) ->
156 let exp_named_subst' =
157 List.map (function (uri,t) -> (uri,liftaux k t)) exp_named_subst
159 C.MutConstruct (uri,tyno,consno,exp_named_subst')
160 | C.MutCase (sp,i,outty,t,pl) ->
161 C.MutCase (sp, i, liftaux k outty, liftaux k t,
162 List.map (liftaux k) pl)
164 let len = List.length fl in
167 (fun (name, i, ty, bo) -> (name, i, liftaux k ty, liftaux (k+len) bo))
172 let len = List.length fl in
175 (fun (name, ty, bo) -> (name, liftaux k ty, liftaux (k+len) bo))
178 C.CoFix (i, liftedfl)
187 let module C = Cic in
191 n when n = k -> lift (k - 1) arg
195 | C.Var (uri,exp_named_subst) ->
196 let exp_named_subst' =
197 List.map (function (uri,t) -> (uri,substaux k t)) exp_named_subst
199 C.Var (uri,exp_named_subst')
200 | C.Meta (i, l) as t ->
205 | Some t -> Some (substaux k t)
210 | C.Implicit _ as t -> t
211 | C.Cast (te,ty) -> C.Cast (substaux k te, substaux k ty)
212 | C.Prod (n,s,t) -> C.Prod (n, substaux k s, substaux (k + 1) t)
213 | C.Lambda (n,s,t) -> C.Lambda (n, substaux k s, substaux (k + 1) t)
214 | C.LetIn (n,s,t) -> C.LetIn (n, substaux k s, substaux (k + 1) t)
216 (* Invariant: no Appl applied to another Appl *)
217 let tl' = List.map (substaux k) tl in
219 match substaux k he with
220 C.Appl l -> C.Appl (l@tl')
221 | _ as he' -> C.Appl (he'::tl')
223 | C.Appl _ -> assert false
224 | C.Const (uri,exp_named_subst) ->
225 let exp_named_subst' =
226 List.map (function (uri,t) -> (uri,substaux k t)) exp_named_subst
228 C.Const (uri,exp_named_subst')
229 | C.MutInd (uri,typeno,exp_named_subst) ->
230 let exp_named_subst' =
231 List.map (function (uri,t) -> (uri,substaux k t)) exp_named_subst
233 C.MutInd (uri,typeno,exp_named_subst')
234 | C.MutConstruct (uri,typeno,consno,exp_named_subst) ->
235 let exp_named_subst' =
236 List.map (function (uri,t) -> (uri,substaux k t)) exp_named_subst
238 C.MutConstruct (uri,typeno,consno,exp_named_subst')
239 | C.MutCase (sp,i,outt,t,pl) ->
240 C.MutCase (sp,i,substaux k outt, substaux k t,
241 List.map (substaux k) pl)
243 let len = List.length fl in
246 (fun (name,i,ty,bo) -> (name, i, substaux k ty, substaux (k+len) bo))
249 C.Fix (i, substitutedfl)
251 let len = List.length fl in
254 (fun (name,ty,bo) -> (name, substaux k ty, substaux (k+len) bo))
257 C.CoFix (i, substitutedfl)
262 (*CSC: i controlli di tipo debbono essere svolti da destra a *)
263 (*CSC: sinistra: i{B/A;b/a} ==> a{B/A;b/a} ==> a{b/a{B/A}} ==> b *)
264 (*CSC: la sostituzione ora e' implementata in maniera simultanea, ma *)
265 (*CSC: dovrebbe diventare da sinistra verso destra: *)
266 (*CSC: t{a=a/A;b/a} ==> \H:a=a.H{b/a} ==> \H:b=b.H *)
267 (*CSC: per la roba che proviene da Coq questo non serve! *)
268 let subst_vars exp_named_subst =
270 debug_print ("@@@POSSIBLE BUG: SUBSTITUTION IS NOT SIMULTANEOUS") ;
273 let module C = Cic in
276 | C.Var (uri,exp_named_subst') ->
280 (function (varuri,_) -> UriManager.eq uri varuri) exp_named_subst
286 let obj,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
288 C.Constant _ -> raise ReferenceToConstant
289 | C.Variable (_,_,_,params,_) -> params
290 | C.CurrentProof _ -> raise ReferenceToCurrentProof
291 | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
295 debug_print "\n\n---- BEGIN " ;
296 debug_print ("----params: " ^ String.concat " ; " (List.map UriManager.string_of_uri params)) ;
297 debug_print ("----S(" ^ UriManager.string_of_uri uri ^ "): " ^ String.concat " ; " (List.map (function (uri,_) -> UriManager.string_of_uri uri) exp_named_subst)) ;
298 debug_print ("----P: " ^ String.concat " ; " (List.map (function (uri,_) -> UriManager.string_of_uri uri) exp_named_subst')) ;
300 let exp_named_subst'' =
301 substaux_in_exp_named_subst uri k exp_named_subst' params
304 debug_print ("----D: " ^ String.concat " ; " (List.map (function (uri,_) -> UriManager.string_of_uri uri) exp_named_subst'')) ;
305 debug_print "---- END\n\n " ;
307 C.Var (uri,exp_named_subst'')
309 | C.Meta (i, l) as t ->
314 | Some t -> Some (substaux k t)
319 | C.Implicit _ as t -> t
320 | C.Cast (te,ty) -> C.Cast (substaux k te, substaux k ty)
321 | C.Prod (n,s,t) -> C.Prod (n, substaux k s, substaux (k + 1) t)
322 | C.Lambda (n,s,t) -> C.Lambda (n, substaux k s, substaux (k + 1) t)
323 | C.LetIn (n,s,t) -> C.LetIn (n, substaux k s, substaux (k + 1) t)
325 (* Invariant: no Appl applied to another Appl *)
326 let tl' = List.map (substaux k) tl in
328 match substaux k he with
329 C.Appl l -> C.Appl (l@tl')
330 | _ as he' -> C.Appl (he'::tl')
332 | C.Appl _ -> assert false
333 | C.Const (uri,exp_named_subst') ->
335 let obj,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
337 C.Constant (_,_,_,params,_) -> params
338 | C.Variable _ -> raise ReferenceToVariable
339 | C.CurrentProof (_,_,_,_,params,_) -> params
340 | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
343 let exp_named_subst'' =
344 substaux_in_exp_named_subst uri k exp_named_subst' params
346 C.Const (uri,exp_named_subst'')
347 | C.MutInd (uri,typeno,exp_named_subst') ->
349 let obj,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
351 C.Constant _ -> raise ReferenceToConstant
352 | C.Variable _ -> raise ReferenceToVariable
353 | C.CurrentProof _ -> raise ReferenceToCurrentProof
354 | C.InductiveDefinition (_,params,_,_) -> params
357 let exp_named_subst'' =
358 substaux_in_exp_named_subst uri k exp_named_subst' params
360 C.MutInd (uri,typeno,exp_named_subst'')
361 | C.MutConstruct (uri,typeno,consno,exp_named_subst') ->
363 let obj,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
365 C.Constant _ -> raise ReferenceToConstant
366 | C.Variable _ -> raise ReferenceToVariable
367 | C.CurrentProof _ -> raise ReferenceToCurrentProof
368 | C.InductiveDefinition (_,params,_,_) -> params
371 let exp_named_subst'' =
372 substaux_in_exp_named_subst uri k exp_named_subst' params
374 C.MutConstruct (uri,typeno,consno,exp_named_subst'')
375 | C.MutCase (sp,i,outt,t,pl) ->
376 C.MutCase (sp,i,substaux k outt, substaux k t,
377 List.map (substaux k) pl)
379 let len = List.length fl in
382 (fun (name,i,ty,bo) -> (name, i, substaux k ty, substaux (k+len) bo))
385 C.Fix (i, substitutedfl)
387 let len = List.length fl in
390 (fun (name,ty,bo) -> (name, substaux k ty, substaux (k+len) bo))
393 C.CoFix (i, substitutedfl)
394 and substaux_in_exp_named_subst uri k exp_named_subst' params =
395 (*CSC: invece di concatenare sarebbe meglio rispettare l'ordine dei params *)
396 (*CSC: e' vero???? una veloce prova non sembra confermare la teoria *)
397 let rec filter_and_lift =
402 (function (uri',_) -> not (UriManager.eq uri uri')) exp_named_subst'
406 (uri,lift (k-1) t)::(filter_and_lift tl)
407 | _::tl -> filter_and_lift tl
410 debug_print ("---- SKIPPO " ^ UriManager.string_of_uri uri) ;
411 if List.for_all (function (uri',_) -> not (UriManager.eq uri uri'))
412 exp_named_subst' then debug_print "---- OK1" ;
413 debug_print ("++++ uri " ^ UriManager.string_of_uri uri ^ " not in " ^ String.concat " ; " (List.map UriManager.string_of_uri params)) ;
414 if List.mem uri params then debug_print "---- OK2" ;
418 List.map (function (uri,t) -> (uri,substaux k t)) exp_named_subst' @
419 (filter_and_lift exp_named_subst)
424 (* subst_meta [t_1 ; ... ; t_n] t *)
425 (* returns the term [t] where [Rel i] is substituted with [t_i] *)
426 (* [t_i] is lifted as usual when it crosses an abstraction *)
428 let module C = Cic in
429 if l = [] then t else
430 let rec aux k = function
432 if n <= k then t else
434 match List.nth l (n-k-1) with
435 None -> raise RelToHiddenHypothesis
438 (Failure _) -> assert false
440 | C.Var (uri,exp_named_subst) ->
441 let exp_named_subst' =
442 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
444 C.Var (uri,exp_named_subst')
454 RelToHiddenHypothesis -> None
459 | C.Implicit _ as t -> t
460 | C.Cast (te,ty) -> C.Cast (aux k te, aux k ty) (*CSC ??? *)
461 | C.Prod (n,s,t) -> C.Prod (n, aux k s, aux (k + 1) t)
462 | C.Lambda (n,s,t) -> C.Lambda (n, aux k s, aux (k + 1) t)
463 | C.LetIn (n,s,t) -> C.LetIn (n, aux k s, aux (k + 1) t)
464 | C.Appl l -> C.Appl (List.map (aux k) l)
465 | C.Const (uri,exp_named_subst) ->
466 let exp_named_subst' =
467 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
469 C.Const (uri,exp_named_subst')
470 | C.MutInd (uri,typeno,exp_named_subst) ->
471 let exp_named_subst' =
472 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
474 C.MutInd (uri,typeno,exp_named_subst')
475 | C.MutConstruct (uri,typeno,consno,exp_named_subst) ->
476 let exp_named_subst' =
477 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
479 C.MutConstruct (uri,typeno,consno,exp_named_subst')
480 | C.MutCase (sp,i,outt,t,pl) ->
481 C.MutCase (sp,i,aux k outt, aux k t, List.map (aux k) pl)
483 let len = List.length fl in
486 (fun (name,i,ty,bo) -> (name, i, aux k ty, aux (k+len) bo))
489 C.Fix (i, substitutedfl)
491 let len = List.length fl in
494 (fun (name,ty,bo) -> (name, aux k ty, aux (k+len) bo))
497 C.CoFix (i, substitutedfl)