]> matita.cs.unibo.it Git - helm.git/blob - helm/ocaml/cic_unification/cicMetaSubst.ml
Final answer: the local context MUST be normalized w.r.t. the canonical
[helm.git] / helm / ocaml / cic_unification / cicMetaSubst.ml
1
2 open Printf
3
4 exception AssertFailure of string
5 exception MetaSubstFailure of string
6
7 let debug_print = prerr_endline
8
9 type substitution = (int * Cic.term) list
10
11 let ppsubst subst =
12   String.concat "\n"
13     (List.map
14       (fun (idx, term) -> Printf.sprintf "?%d := %s" idx (CicPp.ppterm term))
15       subst)
16
17 (**** DELIFT ****)
18 (* the delift function takes in input a metavariable index, an ordered list of
19  * optional terms [t1,...,tn] and a term t, and substitutes every tk = Some
20  * (rel(nk)) with rel(k).  Typically, the list of optional terms is the explicit
21  * substitution that is applied to a metavariable occurrence and the result of
22  * the delift function is a term the implicit variable can be substituted with
23  * to make the term [t] unifiable with the metavariable occurrence.  In general,
24  * the problem is undecidable if we consider equivalence in place of alpha
25  * convertibility. Our implementation, though, is even weaker than alpha
26  * convertibility, since it replace the term [tk] if and only if [tk] is a Rel
27  * (missing all the other cases). Does this matter in practice?
28  * The metavariable index is the index of the metavariable that must not occur
29  * in the term (for occur check).
30  *)
31
32 exception NotInTheList;;
33
34 let position n =
35   let rec aux k =
36    function 
37        [] -> raise NotInTheList
38      | (Some (Cic.Rel m))::_ when m=n -> k
39      | _::tl -> aux (k+1) tl in
40   aux 1
41 ;;
42
43 exception Occur;;
44
45 let rec force_does_not_occur subst to_be_restricted t =
46  let module C = Cic in
47  let more_to_be_restricted = ref [] in
48  let rec aux k = function
49       C.Rel r when List.mem (r - k) to_be_restricted -> raise Occur
50     | C.Rel _
51     | C.Sort _ as t -> t
52     | C.Implicit -> assert false
53     | C.Meta (n, l) ->
54        (* we do not retrieve the term associated to ?n in subst since *)
55        (* in this way we can restrict if something goes wrong         *)
56        let l' =
57          let i = ref 0 in
58          List.map
59            (function t ->
60              incr i ;
61              match t with
62                 None -> None
63               | Some t ->
64                  try
65                    Some (aux k t)
66                  with Occur ->
67                    more_to_be_restricted := (n,!i) :: !more_to_be_restricted;
68                    None)
69            l
70        in
71         C.Meta (n, l')
72     | C.Cast (te,ty) -> C.Cast (aux k te, aux k ty)
73     | C.Prod (name,so,dest) -> C.Prod (name, aux k so, aux (k+1) dest)
74     | C.Lambda (name,so,dest) -> C.Lambda (name, aux k so, aux (k+1) dest)
75     | C.LetIn (name,so,dest) -> C.LetIn (name, aux k so, aux (k+1) dest)
76     | C.Appl l -> C.Appl (List.map (aux k) l)
77     | C.Var (uri,exp_named_subst) ->
78         let exp_named_subst' =
79           List.map (fun (uri,t) -> (uri, aux k t)) exp_named_subst
80         in
81         C.Var (uri, exp_named_subst')
82     | C.Const (uri, exp_named_subst) ->
83         let exp_named_subst' =
84           List.map (fun (uri,t) -> (uri, aux k t)) exp_named_subst
85         in
86         C.Const (uri, exp_named_subst')
87     | C.MutInd (uri,tyno,exp_named_subst) ->
88         let exp_named_subst' =
89           List.map (fun (uri,t) -> (uri, aux k t)) exp_named_subst
90         in
91         C.MutInd (uri, tyno, exp_named_subst')
92     | C.MutConstruct (uri,tyno,consno,exp_named_subst) ->
93         let exp_named_subst' =
94           List.map (fun (uri,t) -> (uri, aux k t)) exp_named_subst
95         in
96         C.MutConstruct (uri, tyno, consno, exp_named_subst')
97     | C.MutCase (uri,tyno,out,te,pl) ->
98         C.MutCase (uri, tyno, aux k out, aux k te, List.map (aux k) pl)
99     | C.Fix (i,fl) ->
100        let len = List.length fl in
101        let k_plus_len = k + len in
102        let fl' =
103          List.map
104           (fun (name,j,ty,bo) -> (name, j, aux k ty, aux k_plus_len bo)) fl
105        in
106        C.Fix (i, fl')
107     | C.CoFix (i,fl) ->
108        let len = List.length fl in
109        let k_plus_len = k + len in
110        let fl' =
111          List.map
112           (fun (name,ty,bo) -> (name, aux k ty, aux k_plus_len bo)) fl
113        in
114        C.CoFix (i, fl')
115  in
116  let res = aux 0 t in
117  (!more_to_be_restricted, res)
118  
119 let rec restrict subst to_be_restricted metasenv =
120   let names_of_context_indexes context indexes =
121     String.concat ", "
122       (List.map
123         (fun i ->
124           try
125            match List.nth context i with
126            | None -> assert false
127            | Some (n, _) -> CicPp.ppname n
128           with
129            Failure _ -> assert false
130         ) indexes)
131   in
132   let force_does_not_occur_in_context to_be_restricted = function
133     | None -> [], None
134     | Some (name, Cic.Decl t) ->
135         let (more_to_be_restricted, t') =
136           force_does_not_occur subst to_be_restricted t
137         in
138         more_to_be_restricted, Some (name, Cic.Decl t')
139     | Some (name, Cic.Def (bo, ty)) ->
140         let (more_to_be_restricted, bo') =
141           force_does_not_occur subst to_be_restricted bo
142         in
143         let more_to_be_restricted, ty' =
144           match ty with
145           | None ->  more_to_be_restricted, None
146           | Some ty ->
147               let more_to_be_restricted', ty' =
148                 force_does_not_occur subst to_be_restricted ty
149               in
150               more_to_be_restricted @ more_to_be_restricted',
151               Some ty'
152         in
153         more_to_be_restricted, Some (name, Cic.Def (bo', ty'))
154   in
155   let rec erase i to_be_restricted n = function
156     | [] -> [], to_be_restricted, []
157     | hd::tl ->
158         let more_to_be_restricted,restricted,tl' =
159          erase (i+1) to_be_restricted n tl
160         in
161         let restrict_me = List.mem i restricted in
162         if restrict_me then
163          more_to_be_restricted, restricted, None:: tl'
164         else
165           (try
166             let more_to_be_restricted', hd' =
167               let delifted_restricted =
168                let rec aux =
169                 function
170                    [] -> []
171                  | j::tl when j > i -> (j - i)::aux tl
172                  | _::tl -> aux tl
173                in
174                 aux restricted
175               in
176                force_does_not_occur_in_context delifted_restricted hd
177             in
178              more_to_be_restricted @ more_to_be_restricted',
179              restricted, hd' :: tl'
180           with Occur ->
181             more_to_be_restricted, (i :: restricted), None :: tl')
182   in
183   let (more_to_be_restricted, metasenv, subst) =
184     List.fold_right
185       (fun (n, context, t) (more, metasenv, subst) ->
186         let to_be_restricted =
187           List.map snd (List.filter (fun (m, _) -> m = n) to_be_restricted)
188         in
189         let (more_to_be_restricted, restricted, context') =
190          (* just an optimization *)
191          if to_be_restricted = [] then
192           [],[],context
193          else
194           erase 1 to_be_restricted n context
195         in
196         try
197           let more_to_be_restricted', t' =
198             force_does_not_occur subst restricted t
199           in
200           let metasenv' = (n, context', t') :: metasenv in
201           (try
202             let s = List.assoc n subst in
203             try
204               let more_to_be_restricted'', s' =
205                 force_does_not_occur subst restricted s
206               in
207               let subst' = (n, s') :: (List.remove_assoc n subst) in
208               let more =
209                 more @ more_to_be_restricted @ more_to_be_restricted' @
210                   more_to_be_restricted''
211               in
212               (more, metasenv', subst')
213             with Occur ->
214               raise (MetaSubstFailure (sprintf
215                 "Cannot restrict the context of the metavariable ?%d over the hypotheses %s since ?%d is already instantiated with %s and at least one of the hypotheses occurs in the substituted term"
216                 n (names_of_context_indexes context to_be_restricted) n
217                 (CicPp.ppterm s)))
218            with Not_found -> (more @ more_to_be_restricted @ more_to_be_restricted', metasenv', subst))
219         with Occur ->
220           raise (MetaSubstFailure (sprintf
221             "Cannot restrict the context of the metavariable ?%d over the hypotheses %s since metavariable's type depends on at least one of them"
222             n (names_of_context_indexes context to_be_restricted))))
223       metasenv ([], [], subst)
224   in
225   match more_to_be_restricted with
226   | [] -> (metasenv, subst)
227   | _ -> restrict subst more_to_be_restricted metasenv
228 ;;
229
230 (*CSC: maybe we should rename delift in abstract, as I did in my dissertation *)
231 let delift n subst context metasenv l t =
232  let module S = CicSubstitution in
233   let l =
234    let (_, canonical_context, _) = CicUtil.lookup_meta n metasenv in
235    List.map2 (fun ct lt ->
236      match (ct, lt) with
237      | None, _ -> None
238      | Some _, _ -> lt)
239      canonical_context l
240   in
241   let to_be_restricted = ref [] in
242   let rec deliftaux k =
243    let module C = Cic in
244     function
245        C.Rel m -> 
246          if m <=k then
247           C.Rel m   (*CSC: che succede se c'e' un Def? Dovrebbe averlo gia' *)
248                     (*CSC: deliftato la regola per il LetIn                 *)
249                     (*CSC: FALSO! La regola per il LetIn non lo fa          *)
250          else
251           (match List.nth context (m-k-1) with
252             Some (_,C.Def (t,_)) ->
253              (*CSC: Hmmm. This bit of reduction is not in the spirit of    *)
254              (*CSC: first order unification. Does it help or does it harm? *)
255              deliftaux k (S.lift m t)
256           | Some (_,C.Decl t) ->
257              (*CSC: The following check seems to be wrong!             *)
258              (*CSC: B:Set |- ?2 : Set                                  *)
259              (*CSC: A:Set ; x:?2[A/B] |- ?1[x/A] =?= x                 *)
260              (*CSC: Why should I restrict ?2 over B? The instantiation *)
261              (*CSC: ?1 := A is perfectly reasonable and well-typed.    *)
262              (*CSC: Thus I comment out the following two lines that    *)
263              (*CSC: are the incriminated ones.                         *)
264              (*(* It may augment to_be_restricted *)
265                ignore (deliftaux k (S.lift m t)) ;*)
266              (*CSC: end of bug commented out                           *)
267              C.Rel ((position (m-k) l) + k)
268           | None -> raise (MetaSubstFailure "RelToHiddenHypothesis"))
269      | C.Var (uri,exp_named_subst) ->
270         let exp_named_subst' =
271          List.map (function (uri,t) -> uri,deliftaux k t) exp_named_subst
272         in
273          C.Var (uri,exp_named_subst')
274      | C.Meta (i, l1) as t -> 
275         if i = n then
276           raise (MetaSubstFailure (sprintf
277             "Cannot unify the metavariable ?%d with a term that has as subterm %s in which the same metavariable occurs (occur check)"
278             i (CicPp.ppterm t)))
279         else
280          (* I do not consider the term associated to ?i in subst since *)
281          (* in this way I can restrict if something goes wrong.        *)
282           let rec deliftl j =
283            function
284               [] -> []
285             | None::tl -> None::(deliftl (j+1) tl)
286             | (Some t)::tl ->
287                let l1' = (deliftl (j+1) tl) in
288                 try
289                  Some (deliftaux k t)::l1'
290                 with
291                    NotInTheList
292                  | MetaSubstFailure _ ->
293                     to_be_restricted := (i,j)::!to_be_restricted ; None::l1'
294           in
295            let l' = deliftl 1 l1 in
296             C.Meta(i,l')
297      | C.Sort _ as t -> t
298      | C.Implicit as t -> t
299      | C.Cast (te,ty) -> C.Cast (deliftaux k te, deliftaux k ty)
300      | C.Prod (n,s,t) -> C.Prod (n, deliftaux k s, deliftaux (k+1) t)
301      | C.Lambda (n,s,t) -> C.Lambda (n, deliftaux k s, deliftaux (k+1) t)
302      | C.LetIn (n,s,t) -> C.LetIn (n, deliftaux k s, deliftaux (k+1) t)
303      | C.Appl l -> C.Appl (List.map (deliftaux k) l)
304      | C.Const (uri,exp_named_subst) ->
305         let exp_named_subst' =
306          List.map (function (uri,t) -> uri,deliftaux k t) exp_named_subst
307         in
308          C.Const (uri,exp_named_subst')
309      | C.MutInd (uri,typeno,exp_named_subst) ->
310         let exp_named_subst' =
311          List.map (function (uri,t) -> uri,deliftaux k t) exp_named_subst
312         in
313          C.MutInd (uri,typeno,exp_named_subst')
314      | C.MutConstruct (uri,typeno,consno,exp_named_subst) ->
315         let exp_named_subst' =
316          List.map (function (uri,t) -> uri,deliftaux k t) exp_named_subst
317         in
318          C.MutConstruct (uri,typeno,consno,exp_named_subst')
319      | C.MutCase (sp,i,outty,t,pl) ->
320         C.MutCase (sp, i, deliftaux k outty, deliftaux k t,
321          List.map (deliftaux k) pl)
322      | C.Fix (i, fl) ->
323         let len = List.length fl in
324         let liftedfl =
325          List.map
326           (fun (name, i, ty, bo) ->
327            (name, i, deliftaux k ty, deliftaux (k+len) bo))
328            fl
329         in
330          C.Fix (i, liftedfl)
331      | C.CoFix (i, fl) ->
332         let len = List.length fl in
333         let liftedfl =
334          List.map
335           (fun (name, ty, bo) -> (name, deliftaux k ty, deliftaux (k+len) bo))
336            fl
337         in
338          C.CoFix (i, liftedfl)
339   in
340    let res =
341     try
342      deliftaux 0 t
343     with
344      NotInTheList ->
345       (* This is the case where we fail even first order unification. *)
346       (* The reason is that our delift function is weaker than first  *)
347       (* order (in the sense of alpha-conversion). See comment above  *)
348       (* related to the delift function.                              *)
349 debug_print "!!!!!!!!!!! First Order UnificationFailure, but maybe it could have been successful even in a first order setting (no conversion, only alpha convertibility)! Please, implement a better delift function !!!!!!!!!!!!!!!!" ;
350       raise (MetaSubstFailure (sprintf
351         "Error trying to abstract %s over [%s]: the algorithm only tried to abstract over bound variables"
352         (CicPp.ppterm t)
353         (String.concat "; "
354           (List.map
355             (function Some t -> CicPp.ppterm t | None -> "_")
356             l))))
357    in
358    let (metasenv, subst) = restrict subst !to_be_restricted metasenv in
359     res, metasenv, subst
360 ;;
361
362 (**** END OF DELIFT ****)
363
364 let apply_subst_gen ~appl_fun subst term =
365  let rec um_aux =
366   let module C = Cic in
367   let module S = CicSubstitution in 
368    function
369       C.Rel _ as t -> t
370     | C.Var _  as t -> t
371     | C.Meta (i, l) -> 
372         (try
373           let t = List.assoc i subst in
374           um_aux (S.lift_meta l t)
375         with Not_found -> (* not constrained variable, i.e. free in subst*)
376           let l' =
377             List.map (function None -> None | Some t -> Some (um_aux t)) l
378           in
379            C.Meta (i,l'))
380     | C.Sort _ as t -> t
381     | C.Implicit -> assert false
382     | C.Cast (te,ty) -> C.Cast (um_aux te, um_aux ty)
383     | C.Prod (n,s,t) -> C.Prod (n, um_aux s, um_aux t)
384     | C.Lambda (n,s,t) -> C.Lambda (n, um_aux s, um_aux t)
385     | C.LetIn (n,s,t) -> C.LetIn (n, um_aux s, um_aux t)
386     | C.Appl (hd :: tl) -> appl_fun um_aux hd tl
387     | C.Appl _ -> assert false
388     | C.Const (uri,exp_named_subst) ->
389        let exp_named_subst' =
390          List.map (fun (uri, t) -> (uri, um_aux t)) exp_named_subst
391        in
392        C.Const (uri, exp_named_subst')
393     | C.MutInd (uri,typeno,exp_named_subst) ->
394        let exp_named_subst' =
395          List.map (fun (uri, t) -> (uri, um_aux t)) exp_named_subst
396        in
397        C.MutInd (uri,typeno,exp_named_subst')
398     | C.MutConstruct (uri,typeno,consno,exp_named_subst) ->
399        let exp_named_subst' =
400          List.map (fun (uri, t) -> (uri, um_aux t)) exp_named_subst
401        in
402        C.MutConstruct (uri,typeno,consno,exp_named_subst')
403     | C.MutCase (sp,i,outty,t,pl) ->
404        let pl' = List.map um_aux pl in
405        C.MutCase (sp, i, um_aux outty, um_aux t, pl')
406     | C.Fix (i, fl) ->
407        let fl' =
408          List.map (fun (name, i, ty, bo) -> (name, i, um_aux ty, um_aux bo)) fl
409        in
410        C.Fix (i, fl')
411     | C.CoFix (i, fl) ->
412        let fl' =
413          List.map (fun (name, ty, bo) -> (name, um_aux ty, um_aux bo)) fl
414        in
415        C.CoFix (i, fl')
416  in
417  um_aux term
418
419 let apply_subst =
420   let appl_fun um_aux he tl =
421     let tl' = List.map um_aux tl in
422       begin
423        match um_aux he with
424           Cic.Appl l -> Cic.Appl (l@tl')
425         | he' -> Cic.Appl (he'::tl')
426       end
427   in
428   apply_subst_gen ~appl_fun
429
430 let ppterm subst term = CicPp.ppterm (apply_subst subst term)
431
432 (* apply_subst_reducing subst (Some (mtr,reductions_no)) t              *)
433 (* performs as (apply_subst subst t) until it finds an application of   *)
434 (* (META [meta_to_reduce]) that, once unwinding is performed, creates   *)
435 (* a new beta-redex; in this case up to [reductions_no] consecutive     *)
436 (* beta-reductions are performed.                                       *)
437 (* Hint: this function is usually called when [reductions_no]           *)
438 (*  eta-expansions have been performed and the head of the new          *)
439 (*  application has been unified with (META [meta_to_reduce]):          *)
440 (*  during the unwinding the eta-expansions are undone.                 *)
441
442 let apply_subst_reducing meta_to_reduce =
443   let appl_fun um_aux he tl =
444     let tl' = List.map um_aux tl in
445     let t' =
446      match um_aux he with
447         Cic.Appl l -> Cic.Appl (l@tl')
448       | he' -> Cic.Appl (he'::tl')
449     in
450      begin
451       match meta_to_reduce, he with
452          Some (mtr,reductions_no), Cic.Meta (m,_) when m = mtr ->
453           let rec beta_reduce =
454            function
455               (n,(Cic.Appl (Cic.Lambda (_,_,t)::he'::tl'))) when n > 0 ->
456                 let he'' = CicSubstitution.subst he' t in
457                  if tl' = [] then
458                   he''
459                  else
460                   beta_reduce (n-1,Cic.Appl(he''::tl'))
461             | (_,t) -> t
462           in
463            beta_reduce (reductions_no,t')
464        | _,_ -> t'
465      end
466   in
467   apply_subst_gen ~appl_fun
468
469 let rec apply_subst_context subst context =
470   List.fold_right
471     (fun item context ->
472       match item with
473       | Some (n, Cic.Decl t) ->
474           let t' = apply_subst subst t in
475           Some (n, Cic.Decl t') :: context
476       | Some (n, Cic.Def (t, ty)) ->
477           let ty' =
478             match ty with
479             | None -> None
480             | Some ty -> Some (apply_subst subst ty)
481           in
482           let t' = apply_subst subst t in
483           Some (n, Cic.Def (t', ty')) :: context
484       | None -> None :: context)
485     context []
486
487 let apply_subst_metasenv subst metasenv =
488   List.map
489     (fun (n, context, ty) ->
490       (n, apply_subst_context subst context, apply_subst subst ty))
491     (List.filter
492       (fun (i, _, _) -> not (List.exists (fun (j, _) -> (j = i)) subst))
493       metasenv)
494
495 let ppterm subst term = CicPp.ppterm (apply_subst subst term)
496
497 let ppterm_in_context subst term name_context =
498  CicPp.pp (apply_subst subst term) name_context
499
500 let ppcontext' ?(sep = "\n") subst context =
501  let separate s = if s = "" then "" else s ^ sep in
502   List.fold_right 
503    (fun context_entry (i,name_context) ->
504      match context_entry with
505         Some (n,Cic.Decl t) ->
506          sprintf "%s%s : %s" (separate i) (CicPp.ppname n)
507           (ppterm_in_context subst t name_context), (Some n)::name_context
508       | Some (n,Cic.Def (bo,ty)) ->
509          sprintf "%s%s : %s := %s" (separate i) (CicPp.ppname n)
510           (match ty with
511               None -> "_"
512             | Some ty -> ppterm_in_context subst ty name_context)
513           (ppterm_in_context subst bo name_context), (Some n)::name_context
514        | None ->
515           sprintf "%s_ :? _" (separate i), None::name_context
516     ) context ("",[])
517
518 let ppcontext ?sep subst context = fst (ppcontext' ?sep subst context)
519
520 let ppmetasenv ?(sep = "\n") metasenv subst =
521   String.concat sep
522     (List.map
523       (fun (i, c, t) ->
524         let context,name_context = ppcontext' ~sep:"; " subst c in
525          sprintf "%s |- ?%d: %s" context i
526           (ppterm_in_context subst t name_context))
527       (List.filter
528         (fun (i, _, _) -> not (List.exists (fun (j, _) -> (j = i)) subst))
529         metasenv))
530
531 (* UNWIND THE MGU INSIDE THE MGU *)
532 (*
533 let unwind_subst metasenv subst =
534   List.fold_left
535    (fun (unwinded,metasenv) (i,_) ->
536      let (_,canonical_context,_) = CicUtil.lookup_meta i metasenv in
537      let identity_relocation_list =
538       CicMkImplicit.identity_relocation_list_for_metavariable canonical_context
539      in
540       let (_,metasenv',subst') =
541        unwind metasenv subst unwinded (Cic.Meta (i,identity_relocation_list))
542       in
543        subst',metasenv'
544    ) ([],metasenv) subst
545 *)
546
547 (* From now on we recreate a kernel abstraction where substitutions are part of
548  * the calculus *)
549
550 let lift subst n term =
551   let term = apply_subst subst term in
552   try
553     CicSubstitution.lift n term
554   with e ->
555     raise (MetaSubstFailure ("Lift failure: " ^ Printexc.to_string e))
556
557 let subst subst t1 t2 =
558   let t1 = apply_subst subst t1 in
559   let t2 = apply_subst subst t2 in
560   try
561     CicSubstitution.subst t1 t2
562   with e ->
563     raise (MetaSubstFailure ("Subst failure: " ^ Printexc.to_string e))
564
565 let whd subst context term =
566   let term = apply_subst subst term in
567   let context = apply_subst_context subst context in
568   try
569     CicReduction.whd context term
570   with e ->
571     raise (MetaSubstFailure ("Weak head reduction failure: " ^
572       Printexc.to_string e))
573
574 let are_convertible subst context t1 t2 =
575   let context = apply_subst_context subst context in
576   let t1 = apply_subst subst t1 in
577   let t2 = apply_subst subst t2 in
578   CicReduction.are_convertible context t1 t2
579
580 let tempi_type_of_aux_subst = ref 0.0;;
581 let tempi_type_of_aux = ref 0.0;;
582
583 let type_of_aux' metasenv subst context term =
584 let time1 = Unix.gettimeofday () in
585   let term = apply_subst subst term in
586   let context = apply_subst_context subst context in
587   let metasenv =
588     List.map
589       (fun (i, c, t) -> (i, apply_subst_context subst c, apply_subst subst t))
590       (List.filter
591         (fun (i, _, _) -> not (List.exists (fun (j, _) -> (j = i)) subst))
592         metasenv)
593   in
594 let time2 = Unix.gettimeofday () in
595 let res =
596   try
597     CicTypeChecker.type_of_aux' metasenv context term
598   with CicTypeChecker.TypeCheckerFailure msg ->
599     raise (MetaSubstFailure ("Type checker failure: " ^ msg))
600 in
601 let time3 = Unix.gettimeofday () in
602  tempi_type_of_aux_subst := !tempi_type_of_aux_subst +. time3 -. time1 ; 
603  tempi_type_of_aux := !tempi_type_of_aux +. time2 -. time1 ; 
604  res