2 ||M|| This file is part of HELM, an Hypertextual, Electronic
3 ||A|| Library of Mathematics, developed at the Computer Science
4 ||T|| Department, University of Bologna, Italy.
6 ||T|| HELM is free software; you can redistribute it and/or
7 ||A|| modify it under the terms of the GNU General Public License
8 \ / version 2 or (at your option) any later version.
9 \ / This software is distributed as is, NO WARRANTY.
10 V_______________________________________________________________ *)
16 module T = NCicTypeChecker
22 (* internal functions *******************************************************)
27 X.error ("anticipate: malformed term: " ^ s)
30 X.log ("anticipate: ok " ^ s)
32 let typeof c t = K.whd c (K.typeof c t)
34 let not_prop1 c u = match typeof c u with
35 | C.Sort (C.Prop) -> false
39 let not_prop2 c t = not_prop1 c (K.typeof c t)
43 let w = K.typeof c v in
44 P.sprintf "%s%u" !G.proc_id !fresh, w, v, C.Rel K.fst_var
46 let initial = None, []
48 let proc_arg c i (d, rtts) t = match d with
49 | Some _ -> d, (t :: rtts)
51 if K.is_atomic t || not_prop2 c t then d, (t :: rtts) else
52 let s, w, v, tt = anticipate c t in
53 Some (i, s, w, v), (tt :: rtts)
55 let lift_arg ri i tts t =
56 if ri = i then t :: tts
57 else K.lift K.fst_var 1 t :: tts
59 let rec proc_term c t = match t with
62 | C.Implicit _ -> malformed "2"
67 | C.Lambda (s, w, t) ->
68 let tt = shift_term (K.add_dec s w c) t in
70 | C.LetIn (s, w, v, t) ->
72 let dt, tt = proc_term (K.add_def s w v c) t in
73 dt @ K.add_def s w v [], tt
75 let dv, vv = proc_term c v in
76 let l = L.length dv in
78 let w = K.lift K.fst_var l w in
79 let t = K.lift K.snd_var l t in
80 let dt, tt = proc_term (K.add_def s w vv c) t in
81 dt @ (K.add_def s w vv dv), tt
82 | C.Appl [t] -> proc_term c t
83 | C.Appl (C.Appl ts :: vs) -> proc_term c (C.Appl (ts @ vs))
84 | C.Appl ts -> proc_appl c t ts
85 | C.Match (w, u, v, ts) -> proc_case c t w u v ts
87 and proc_appl c t ts = match X.foldi_left (proc_arg c) 1 initial ts with
89 | Some (i, s, w, v), rtts ->
90 let ri = L.length rtts - i in
91 let tts = X.foldi_left (lift_arg ri) 0 [] rtts in
92 proc_term c (K.letin s w v (C.Appl tts))
94 and proc_case c t w u v ts = match X.foldi_left (proc_arg c) 1 initial ts with
96 if K.is_atomic v || not_prop1 c (C.Const w) then [], t else
97 let s, w0, v0, vv = anticipate c v in
98 let u = K.lift K.fst_var 1 u in
99 let ts = K.lifts K.fst_var 1 ts in
100 proc_term c (K.letin s w0 v0 (K.case w u vv ts))
101 | Some (i, s, w0, v0), rtts ->
102 let ri = L.length rtts - i in
103 let u = K.lift K.fst_var 1 u in
104 let v = K.lift K.fst_var 1 v in
105 let tts = X.foldi_left (lift_arg ri) 0 [] rtts in
106 proc_term c (K.letin s w0 v0 (K.case w u v tts))
109 let d, tt = proc_term c t in
112 let shift_named s c t =
115 let tt = shift_term c t in
116 if !G.test then begin
117 let _ = K.typeof c tt in
122 | T.TypeCheckerFailure s
123 | T.AssertFailure s -> malformed (Lazy.force s)
126 let r, s, i, u, t = c in
127 if not_prop1 [] u then c else
128 r, s, i, u, shift_named s [] t
130 let proc_obj obj = match obj with
132 | C.Constant (_, _, None, _, _) -> obj
133 | C.Constant (r, s, Some t, u, a) ->
134 if not_prop1 [] u then obj else
135 let tt = shift_named s [] t in
136 C.Constant (r, s, Some tt, u, a)
137 | C.Fixpoint (b, cs, a) ->
138 C.Fixpoint (b, L.map proc_fun cs, a)
140 (* interface functions ******************************************************)
146 let process_top_term s t = shift_named s [] t
148 let process_obj obj = proc_obj obj