6 type metas_context = (int * Cic.term) list;;
8 type context = (binder_type * Cic.name * Cic.term) list;;
10 type sequent = context * Cic.term;;
12 let proof = ref (None : (metas_context * Cic.term * Cic.term) option);;
13 (*CSC: Quando facciamo Clear di una ipotesi, cosa succede? *)
14 (* Note: the sequent is redundant: it can be computed from the type of the *)
15 (* metavariable and its context in the proof. We keep it just for efficiency *)
16 (* because computing the context of a term may be quite expensive. *)
17 let goal = ref (None : (int * sequent) option);;
19 exception NotImplemented
21 (*CSC: Funzione che deve sparire!!! *)
22 let cic_context_of_context =
26 | Definition,_,_ -> raise NotImplemented
30 let refine_meta meta term newmetasenv =
31 let (metasenv,bo,ty) =
34 | Some (metasenv,bo,ty) -> metasenv,bo,ty
36 let metasenv' = newmetasenv @ (List.remove_assoc meta metasenv) in
42 | C.Meta meta' when meta=meta' -> term
45 | C.Implicit as t -> t
46 | C.Cast (te,ty) -> C.Cast (aux te, aux ty)
47 | C.Prod (n,s,t) -> C.Prod (n, aux s, aux t)
48 | C.Lambda (n,s,t) -> C.Lambda (n, aux s, aux t)
49 | C.LetIn (n,s,t) -> C.LetIn (n, aux s, aux t)
50 | C.Appl l -> C.Appl (List.map aux l)
53 | C.MutInd _ as t -> t
54 | C.MutConstruct _ as t -> t
55 | C.MutCase (sp,cookingsno,i,outt,t,pl) ->
56 C.MutCase (sp,cookingsno,i,aux outt, aux t,
61 (fun (name,i,ty,bo) -> (name, i, aux ty, aux bo))
64 C.Fix (i, substitutedfl)
68 (fun (name,ty,bo) -> (name, aux ty, aux bo))
71 C.CoFix (i, substitutedfl)
73 let metasenv'' = List.map (function i,ty -> i,(aux ty)) metasenv' in
75 proof := Some (metasenv'',bo',ty)
78 (* Returns the first meta whose number is above the number of the higher meta. *)
83 | Some (metasenv,_,_) -> metasenv
89 | None,(n,_)::tl -> aux (Some n,tl)
90 | Some m,(n,_)::tl -> if n > m then aux (Some n,tl) else aux (Some m,tl)
92 1 + aux (None,metasenv)
95 (* metas_in_term term *)
96 (* Returns the ordered list of the metas that occur in [term]. *)
97 (* Duplicates are removed. The implementation is not very efficient. *)
98 let metas_in_term term =
107 | C.Cast (te,ty) -> (aux te) @ (aux ty)
108 | C.Prod (_,s,t) -> (aux s) @ (aux t)
109 | C.Lambda (_,s,t) -> (aux s) @ (aux t)
110 | C.LetIn (_,s,t) -> (aux s) @ (aux t)
111 | C.Appl l -> List.fold_left (fun i t -> i @ (aux t)) [] l
115 | C.MutConstruct _ -> []
116 | C.MutCase (sp,cookingsno,i,outt,t,pl) ->
117 (aux outt) @ (aux t) @
118 (List.fold_left (fun i t -> i @ (aux t)) [] pl)
120 List.fold_left (fun i (_,_,ty,bo) -> i @ (aux bo) @ (aux ty)) [] fl
122 List.fold_left (fun i (_,ty,bo) -> i @ (aux bo) @ (aux ty)) [] fl
124 let metas = aux term in
125 let rec elim_duplicates =
129 he::(elim_duplicates (List.filter (function el -> he <> el) tl))
131 elim_duplicates metas
134 (* perforate context term ty *)
135 (* replaces the term [term] in the proof with a new metavariable whose type *)
136 (* is [ty]. [context] must be the context of [term] in the whole proof. This *)
137 (* could be easily computed; so the only reasons to have it as an argument *)
138 (* are efficiency reasons. *)
139 let perforate context term ty =
140 let module C = Cic in
141 let newmeta = new_meta () in
144 | Some (metasenv,bo,gty) ->
145 (* We push the new meta at the end of the list for pretty-printing *)
146 (* purposes: in this way metas are ordered. *)
147 let metasenv' = metasenv@[newmeta,ty] in
150 (* Is == strong enough? *)
151 t when t == term -> C.Meta newmeta
156 | C.Implicit as t -> t
157 | C.Cast (te,ty) -> C.Cast (aux te, aux ty)
158 | C.Prod (n,s,t) -> C.Prod (n, aux s, aux t)
159 | C.Lambda (n,s,t) -> C.Lambda (n, aux s, aux t)
160 | C.LetIn (n,s,t) -> C.LetIn (n, aux s, aux t)
161 | C.Appl l -> C.Appl (List.map aux l)
162 | C.Const _ as t -> t
164 | C.MutInd _ as t -> t
165 | C.MutConstruct _ as t -> t
166 | C.MutCase (sp,cookingsno,i,outt,t,pl) ->
167 C.MutCase (sp,cookingsno,i,aux outt, aux t,
172 (fun (name,i,ty,bo) -> (name, i, aux ty, aux bo))
175 C.Fix (i, substitutedfl)
179 (fun (name,ty,bo) -> (name, aux ty, aux bo))
182 C.CoFix (i, substitutedfl)
185 (* It may be possible that some metavariables occurred only in *)
186 (* the term we are perforating and they now occurs no more. We *)
187 (* get rid of them, collecting the really useful metavariables *)
189 let newmetas = metas_in_term bo' in
191 List.filter (function (n,_) -> List.mem n newmetas) metasenv'
193 proof := Some (metasenv'',bo',gty) ;
194 goal := Some (newmeta,(context,ty)) ;
198 (************************************************************)
199 (* Some easy tactics. *)
200 (************************************************************)
202 exception Fail of string;;
205 let module C = Cic in
206 let module R = CicReduction in
210 | Some (metasenv,_,_) -> metasenv
212 let (metano,context,ty) =
215 | Some (metano,(context,ty)) -> metano,context,ty
217 let newmeta = new_meta () in
218 let rec collect_context =
220 C.Cast (te,_) -> collect_context te
222 let (ctx,ty,bo) = collect_context t in
223 ((Declaration,n,s)::ctx,ty,C.Lambda(n,s,bo))
225 let (ctx,ty,bo) = collect_context t in
226 ((Definition,n,s)::ctx,ty,C.LetIn(n,s,bo))
227 | _ as t -> [], t, (C.Meta newmeta)
229 let revcontext',ty',bo' = collect_context ty in
230 let context'' = (List.rev revcontext') @ context in
231 refine_meta metano bo' [newmeta,ty'] ;
232 goal := Some (newmeta,(context'',ty'))
235 (* The term bo must be closed in the current context *)
237 let module T = CicTypeChecker in
238 let module R = CicReduction in
242 | Some (metasenv,_,_) -> metasenv
244 let (metano,context,ty) =
247 | Some (metano,(context,ty)) ->
248 assert (ty = List.assoc metano metasenv) ;
249 (* Invariant: context is the actual context of the meta in the proof *)
252 (*CSC: deve sparire! *)
253 let context = cic_context_of_context context in
254 if R.are_convertible (T.type_of_aux' metasenv context bo) ty then
256 refine_meta metano bo [] ;
260 raise (Fail "The type of the provided term is not the one expected.")
263 (* The term bo must be closed in the current context *)
265 let module T = CicTypeChecker in
266 let module R = CicReduction in
267 let module C = Cic in
271 | Some (metasenv,_,_) -> metasenv
273 let (metano,context,ty) =
276 | Some (metano,(context,ty)) ->
277 assert (ty = List.assoc metano metasenv) ;
278 (* Invariant: context is the actual context of the meta in the proof *)
281 (*CSC: deve sparire! *)
282 let ciccontext = cic_context_of_context context in
283 let mgu,mgut = CicUnification.apply metasenv ciccontext term ty in
284 let mgul = Array.to_list mgu in
285 let mgutl = Array.to_list mgut in
286 let applymetas_to_metas =
287 let newmeta = new_meta () in
288 (* WARNING: here we are using the invariant that above the most *)
289 (* recente new_meta() there are no used metas. *)
290 Array.init (List.length mgul) (function i -> newmeta + i) in
291 (* WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!! *)
292 (* Here we assume that either a META has been instantiated with *)
293 (* a close term or with itself. *)
294 let uninstantiatedmetas =
296 (fun bo ty newmetas ->
299 let newmeta = applymetas_to_metas.(i) in
300 (*CSC: se ty contiene metas, queste hanno il numero errato!!! *)
301 let ty_with_newmetas =
302 (* Substitues (META n) with (META (applymetas_to_metas.(n))) *)
307 | C.Meta n -> C.Meta (applymetas_to_metas.(n))
309 | C.Implicit as t -> t
310 | C.Cast (te,ty) -> C.Cast (aux te, aux ty)
311 | C.Prod (n,s,t) -> C.Prod (n, aux s, aux t)
312 | C.Lambda (n,s,t) -> C.Lambda (n, aux s, aux t)
313 | C.LetIn (n,s,t) -> C.LetIn (n, aux s, aux t)
314 | C.Appl l -> C.Appl (List.map aux l)
315 | C.Const _ as t -> t
316 | C.Abst _ -> assert false
318 | C.MutConstruct _ as t -> t
319 | C.MutCase (sp,cookingsno,i,outt,t,pl) ->
320 C.MutCase (sp,cookingsno,i,aux outt, aux t,
325 (fun (name,i,ty,bo) -> (name, i, aux ty, aux bo))
328 C.Fix (i, substitutedfl)
332 (fun (name,ty,bo) -> (name, aux ty, aux bo))
335 C.CoFix (i, substitutedfl)
339 (newmeta,ty_with_newmetas)::newmetas
346 Cic.Meta i -> Cic.Meta (applymetas_to_metas.(i))
350 if List.length mgul' = 0 then
353 Cic.Appl (term::mgul')
355 refine_meta metano bo' uninstantiatedmetas ;
356 match uninstantiatedmetas with
357 (n,ty)::tl -> goal := Some (n,(context,ty))