1 (* type naif_indexing =
2 (Cic.term * ((bool * Inference.equality) list)) list
5 type pos = Left | Right ;;
7 let head_of_term = function
8 | Cic.Appl (hd::tl) -> hd
14 let _, (_, l, r, ordering), _, _ = eq in
15 let hl = head_of_term l in
16 let hr = head_of_term r in
18 let x_entry = try Hashtbl.find table x with Not_found -> [] in
19 Hashtbl.replace table x ((pos, eq)::x_entry)
27 | _ -> index hl Left; index hr Right
35 let remove_index table eq =
36 let _, (_, l, r, ordering), _, _ = eq in
37 let hl = head_of_term l
38 and hr = head_of_term r in
39 let remove_index x pos =
40 let x_entry = try Hashtbl.find table x with Not_found -> [] in
41 let newentry = List.filter (fun e -> e <> (pos, eq)) x_entry in
42 Hashtbl.replace table x newentry
45 remove_index hr Right;
50 let rec find_matches unif_fun metasenv context ugraph lift_amount term =
52 let module U = Utils in
53 let module S = CicSubstitution in
54 let module M = CicMetaSubst in
55 let module HL = HelmLibraryObjects in
56 let cmp = !Utils.compare_terms in
57 let names = Utils.names_of_context context in
58 (* Printf.printf "CHIAMO find_matches (%s) su: %s\n" *)
59 (* (if unif_fun == Inference.matching then "MATCHING" *)
60 (* else if unif_fun == CicUnification.fo_unif then "UNIFICATION" *)
61 (* else "??????????") *)
62 (* (CicPp.pp term names); *)
66 let pos, (proof, (ty, left, right, o), metas, args) = candidate in
67 let do_match c other eq_URI =
68 (* Printf.printf "provo con %s: %s, %s\n\n" *)
69 (* (if unif_fun == Inference.matching then "MATCHING" *)
70 (* else if unif_fun == CicUnification.fo_unif then "UNIFICATION" *)
71 (* else "??????????") *)
72 (* (CicPp.pp term names) *)
73 (* (CicPp.pp (S.lift lift_amount c) names); *)
74 let subst', metasenv', ugraph' =
75 (* Inference.matching (metasenv @ metas) context term *)
76 (* (S.lift lift_amount c) ugraph *)
77 unif_fun (metasenv @ metas) context
78 term (S.lift lift_amount c) ugraph
80 (* let names = U.names_of_context context in *)
81 (* Printf.printf "MATCH FOUND: %s, %s\n" *)
82 (* (CicPp.pp term names) (CicPp.pp (S.lift lift_amount c) names); *)
83 Some (C.Rel (1 + lift_amount), subst', metasenv', ugraph',
85 (* (proof, ty, c, other, eq_URI)) *)
87 let c, other, eq_URI =
88 if pos = Left then left, right, HL.Logic.eq_ind_URI
89 else right, left, HL.Logic.eq_ind_r_URI
91 if o <> U.Incomparable then
93 (* print_endline "SONO QUI!"; *)
94 let res = do_match c other eq_URI in
95 (* print_endline "RITORNO RES"; *)
98 (* Printf.printf "ERRORE!: %s\n" (Printexc.to_string e); *)
99 find_matches unif_fun metasenv context ugraph lift_amount term tl
101 let res = try do_match c other eq_URI with e -> None in
103 | Some (_, s, _, _, _) ->
104 let c' = M.apply_subst s c
105 and other' = M.apply_subst s other in
106 let order = cmp c' other' in
107 let names = U.names_of_context context in
108 (* Printf.printf "c': %s\nother': %s\norder: %s\n\n" *)
109 (* (CicPp.pp c' names) (CicPp.pp other' names) *)
110 (* (U.string_of_comparison order); *)
111 (* if cmp (M.apply_subst s c) (M.apply_subst s other) = U.Gt then *)
115 find_matches unif_fun metasenv context ugraph
118 find_matches unif_fun metasenv context ugraph lift_amount term tl
122 let rec demodulate_term metasenv context ugraph table lift_amount term =
123 let module C = Cic in
124 let module S = CicSubstitution in
125 let module M = CicMetaSubst in
126 let module HL = HelmLibraryObjects in
127 let hd_term = head_of_term term in
128 let candidates = try Hashtbl.find table hd_term with Not_found -> [] in
133 find_matches Inference.matching metasenv context ugraph
134 lift_amount term candidates
145 (res, tl @ [S.lift 1 t])
148 demodulate_term metasenv context ugraph table
152 | None -> (None, tl @ [S.lift 1 t])
153 | Some (rel, _, _, _, _) -> (r, tl @ [rel]))
158 | Some (_, subst, menv, ug, eq_found) ->
159 Some (C.Appl ll, subst, menv, ug, eq_found)
161 | C.Prod (nn, s, t) ->
163 demodulate_term metasenv context ugraph table lift_amount s in (
167 demodulate_term metasenv
168 ((Some (nn, C.Decl s))::context) ugraph
169 table (lift_amount+1) t
173 | Some (t', subst, menv, ug, eq_found) ->
174 Some (C.Prod (nn, (S.lift 1 s), t'),
175 subst, menv, ug, eq_found)
177 | Some (s', subst, menv, ug, eq_found) ->
178 Some (C.Prod (nn, s', (S.lift 1 t)),
179 subst, menv, ug, eq_found)
182 (* Printf.printf "Ne` Appl ne` Prod: %s\n" *)
183 (* (CicPp.pp t (Utils.names_of_context context)); *)
188 let rec demodulation newmeta env table target =
189 let module C = Cic in
190 let module S = CicSubstitution in
191 let module M = CicMetaSubst in
192 let module HL = HelmLibraryObjects in
193 let metasenv, context, ugraph = env in
194 let proof, (eq_ty, left, right, order), metas, args = target in
196 (* let names = Utils.names_of_context context in *)
197 (* Printf.printf "demodulation %s = %s\n" *)
198 (* (CicPp.pp left names) (CicPp.pp right names) *)
200 let metasenv' = metasenv @ metas in
201 let build_newtarget is_left (t, subst, menv, ug, (eq_found, eq_URI)) =
202 let pos, (proof', (ty, what, other, _), menv', args') = eq_found in
203 let what, other = if pos = Left then what, other else other, what in
204 let newterm, newproof =
205 let bo = M.apply_subst subst (S.subst other t) in
207 C.Appl ([C.MutInd (HL.Logic.eq_URI, 0, []);
209 if is_left then [bo; S.lift 1 right] else [S.lift 1 left; bo])
211 let t' = C.Lambda (C.Anonymous, ty, bo'') in
213 M.apply_subst subst (C.Appl [C.Const (eq_URI, []); ty; what; t';
214 proof; other; proof'])
216 let left, right = if is_left then newterm, right else left, newterm in
218 (Inference.metas_of_term left) @ (Inference.metas_of_term right)
220 let newmetasenv = List.filter (fun (i, _, _) -> List.mem i m) metas
223 (function C.Meta (i, _) -> List.mem i m | _ -> assert false)
226 let ordering = !Utils.compare_terms left right in
227 newmeta, (newproof, (eq_ty, left, right, ordering), newmetasenv, newargs)
229 let res = demodulate_term metasenv' context ugraph table 0 left in
232 let newmeta, newtarget = build_newtarget true t in
233 if (Inference.is_identity (metasenv', context, ugraph) newtarget) ||
234 (Inference.meta_convertibility_eq target newtarget) then
237 (* Printf.printf "Going on 1:\ntarget: %s\nnewtarget: %s\n%s\n\n" *)
238 (* (Inference.string_of_equality ~env target) *)
239 (* (Inference.string_of_equality ~env newtarget) *)
240 (* (string_of_bool (target = newtarget)); *)
241 demodulation newmeta env table newtarget
244 let res = demodulate_term metasenv' context ugraph table 0 right in
247 let newmeta, newtarget = build_newtarget false t in
248 if (Inference.is_identity (metasenv', context, ugraph) newtarget) ||
249 (Inference.meta_convertibility_eq target newtarget) then
252 (* Printf.printf "Going on 2:\ntarget: %s\nnewtarget: %s\n\n" *)
253 (* (Inference.string_of_equality ~env target) *)
254 (* (Inference.string_of_equality ~env newtarget); *)
255 demodulation newmeta env table newtarget
262 let rec find_all_matches metasenv context ugraph lift_amount term =
263 let module C = Cic in
264 let module U = Utils in
265 let module S = CicSubstitution in
266 let module M = CicMetaSubst in
267 let module HL = HelmLibraryObjects in
268 let cmp = !Utils.compare_terms in
269 let names = Utils.names_of_context context in
273 let pos, (proof, (ty, left, right, o), metas, args) = candidate in
274 let do_match c other eq_URI =
275 let subst', metasenv', ugraph' =
276 CicUnification.fo_unif (metasenv @ metas) context
277 term (S.lift lift_amount c) ugraph
279 (C.Rel (1 + lift_amount), subst', metasenv', ugraph',
282 let c, other, eq_URI =
283 if pos = Left then left, right, HL.Logic.eq_ind_URI
284 else right, left, HL.Logic.eq_ind_r_URI
286 if o <> U.Incomparable then
288 let res = do_match c other eq_URI in
289 res::(find_all_matches metasenv context ugraph lift_amount term tl)
291 find_all_matches metasenv context ugraph lift_amount term tl
294 let res = do_match c other eq_URI in
297 let c' = M.apply_subst s c
298 and other' = M.apply_subst s other in
299 let order = cmp c' other' in
300 let names = U.names_of_context context in
301 if order <> U.Lt && order <> U.Le then
302 res::(find_all_matches metasenv context ugraph
305 find_all_matches metasenv context ugraph lift_amount term tl
307 find_all_matches metasenv context ugraph lift_amount term tl
311 let rec betaexpand_term metasenv context ugraph table lift_amount term =
312 let module C = Cic in
313 let module S = CicSubstitution in
314 let module M = CicMetaSubst in
315 let module HL = HelmLibraryObjects in
316 let hd_term = head_of_term term in
317 let candidates = try Hashtbl.find table hd_term with Not_found -> [] in
318 let res, lifted_term =
323 (fun arg (res, lifted_tl) ->
326 let arg_res, lifted_arg =
327 betaexpand_term metasenv context ugraph table
331 (fun (t, s, m, ug, eq_found) ->
332 (Some t)::lifted_tl, s, m, ug, eq_found)
337 (fun (l, s, m, ug, eq_found) ->
338 (Some lifted_arg)::l, s, m, ug, eq_found)
340 (Some lifted_arg)::lifted_tl)
343 (fun (r, s, m, ug, eq_found) ->
344 None::r, s, m, ug, eq_found) res,
350 (fun (l, s, m, ug, eq_found) ->
351 (C.Meta (i, l), s, m, ug, eq_found)) l'
353 e, C.Meta (i, lifted_l)
356 [], if m <= lift_amount then C.Rel m else C.Rel (m+1)
358 | C.Prod (nn, s, t) ->
360 betaexpand_term metasenv context ugraph table lift_amount s in
362 betaexpand_term metasenv ((Some (nn, C.Decl s))::context) ugraph
363 table (lift_amount+1) t in
366 (fun (t, s, m, ug, eq_found) ->
367 C.Prod (nn, t, lifted_t), s, m, ug, eq_found) l1
370 (fun (t, s, m, ug, eq_found) ->
371 C.Prod (nn, lifted_s, t), s, m, ug, eq_found) l2 in
372 l1' @ l2', C.Prod (nn, lifted_s, lifted_t)
377 (fun arg (res, lifted_tl) ->
378 let arg_res, lifted_arg =
379 betaexpand_term metasenv context ugraph table lift_amount arg
383 (fun (a, s, m, ug, eq_found) ->
384 a::lifted_tl, s, m, ug, eq_found)
389 (fun (r, s, m, ug, eq_found) ->
390 lifted_arg::r, s, m, ug, eq_found)
392 lifted_arg::lifted_tl)
396 (fun (l, s, m, ug, eq_found) -> (C.Appl l, s, m, ug, eq_found)) l',
399 | t -> [], (S.lift lift_amount t)
402 | C.Meta _ -> res, lifted_term
404 (* let names = Utils.names_of_context context in *)
405 (* Printf.printf "CHIAMO find_all_matches su: %s\n" (CicPp.pp term names); *)
407 find_all_matches metasenv context ugraph lift_amount term candidates
411 (* find_all_matches metasenv context ugraph lift_amount term candidates *)
413 (* | None -> res, lifted_term *)
415 (* r::res, lifted_term *)
419 let superposition_left (metasenv, context, ugraph) table target =
420 let module C = Cic in
421 let module S = CicSubstitution in
422 let module M = CicMetaSubst in
423 let module HL = HelmLibraryObjects in
424 let module CR = CicReduction in
425 let module U = Utils in
426 (* print_endline "superposition_left"; *)
427 let proof, (eq_ty, left, right, ordering), _, _ = target in
429 let term = if ordering = U.Gt then left else right in
430 betaexpand_term metasenv context ugraph table 0 term
432 let build_new (bo, s, m, ug, (eq_found, eq_URI)) =
433 let pos, (proof', (ty, what, other, _), menv', args') = eq_found in
434 let what, other = if pos = Left then what, other else other, what in
435 let newgoal, newproof =
436 let bo' = M.apply_subst s (S.subst other bo) in
439 [C.MutInd (HL.Logic.eq_URI, 0, []);
441 if ordering = U.Gt then [bo'; S.lift 1 right]
442 else [S.lift 1 left; bo'])
444 let t' = C.Lambda (C.Anonymous, ty, bo'') in
447 (C.Appl [C.Const (eq_URI, []); ty; what; t';
448 proof; other; proof'])
451 if ordering = U.Gt then newgoal, right else left, newgoal in
452 let neworder = !Utils.compare_terms left right in
453 (newproof, (eq_ty, left, right, neworder), [], [])
455 List.map build_new expansions
459 let superposition_right newmeta (metasenv, context, ugraph) table target =
460 let module C = Cic in
461 let module S = CicSubstitution in
462 let module M = CicMetaSubst in
463 let module HL = HelmLibraryObjects in
464 let module CR = CicReduction in
465 let module U = Utils in
466 (* print_endline "superposition_right"; *)
467 let eqproof, (eq_ty, left, right, ordering), newmetas, args = target in
468 let metasenv' = metasenv @ newmetas in
469 let maxmeta = ref newmeta in
472 | U.Gt -> fst (betaexpand_term metasenv' context ugraph table 0 left), []
473 | U.Lt -> [], fst (betaexpand_term metasenv' context ugraph table 0 right)
477 (fun (_, subst, _, _, _) ->
478 let subst = M.apply_subst subst in
479 let o = !Utils.compare_terms (subst l) (subst r) in
480 o <> U.Lt && o <> U.Le)
481 (fst (betaexpand_term metasenv' context ugraph table 0 l))
483 (res left right), (res right left)
485 let build_new ordering (bo, s, m, ug, (eq_found, eq_URI)) =
486 let pos, (proof', (ty, what, other, _), menv', args') = eq_found in
487 let what, other = if pos = Left then what, other else other, what in
488 let newgoal, newproof =
489 let bo' = M.apply_subst s (S.subst other bo) in
492 [C.MutInd (HL.Logic.eq_URI, 0, []); S.lift 1 eq_ty] @
493 if ordering = U.Gt then [bo'; S.lift 1 right]
494 else [S.lift 1 left; bo'])
496 let t' = C.Lambda (C.Anonymous, ty, bo'') in
499 (C.Appl [C.Const (eq_URI, []); ty; what; t';
500 eqproof; other; proof'])
502 let newmeta, newequality =
504 if ordering = U.Gt then newgoal, M.apply_subst s right
505 else M.apply_subst s left, newgoal in
506 let neworder = !Utils.compare_terms left right
507 and newmenv = newmetas @ menv'
508 and newargs = args @ args' in
509 let eq' = (newproof, (eq_ty, left, right, neworder), newmenv, newargs)
510 and env = (metasenv, context, ugraph) in
511 (* Printf.printf "eq' prima di fix_metas: %s\n" *)
512 (* (Inference.string_of_equality eq' ~env); *)
513 let newm, eq' = Inference.fix_metas !maxmeta eq' in
514 (* Printf.printf "eq' dopo fix_metas: %s\n" *)
515 (* (Inference.string_of_equality eq' ~env); *)
521 let new1 = List.map (build_new U.Gt) res1
522 and new2 = List.map (build_new U.Lt) res2 in
524 | _, (_, left, right, _), _, _ ->
525 not (fst (CR.are_convertible context left right ugraph))
528 (List.filter ok (new1 @ new2)))