-
-let matching metasenv1 metasenv2 context t1 t2 ugraph =
- let subst, metasenv, ugraph =
- try
- unification metasenv1 metasenv2 context t1 t2 ugraph
- with
- CicUtil.Meta_not_found _ as exn ->
- Printf.eprintf "t1 == %s\nt2 = %s\nmetasenv == %s\n%!"
- (CicPp.ppterm t1) (CicPp.ppterm t2)
- (CicMetaSubst.ppmetasenv [] (metasenv1@metasenv2));
- raise exn
- | CicUnification.UnificationFailure _
- | CicUnification.Uncertain _ ->
- raise MatchingFailure
- in
- if Utils.debug_res then
- ignore(check_disjoint_invariant subst metasenv "qua-2");
- (* let us unfold subst *)
- if metasenv = metasenv1 then
- subst, metasenv, ugraph (* everything is fine *)
- else
- (* let us unfold subst *)
- let subst =
- List.map
- (fun (i, (context, term, ty)) ->
- let context = CicMetaSubst.apply_subst_context subst context in
- let term = CicMetaSubst.apply_subst subst term in
- let ty = CicMetaSubst.apply_subst subst ty in
- (i, (context, term, ty))) subst in
- (* let us revert Meta-Meta in subst privileging metasenv1 *)
- let subst, metasenv =
- List.fold_left
- (fun
- (subst,metasenv) s ->
- match s with
- | (i, (c, Cic.Meta (j, lc), ty))
- when (List.exists (fun (x, _, _) -> x=i) metasenv1) &&
- not (List.exists (fun (x, _) -> x=j) subst) ->
- let metasenv' =
- List.filter (fun (x, _, _) -> x<>j) metasenv
- in
- ((j, (c, Cic.Meta (i, lc), ty))::subst,
- (i,c,ty)::metasenv')
- |_ -> s::subst,metasenv) ([],metasenv) subst
- in
- (* finally, let us chek again that metasenv = metasenv1 *)
- if metasenv = metasenv1 then
- subst, metasenv, ugraph
- else raise MatchingFailure
-;;
-
-let check_eq context msg eq =
- let w, proof, (eq_ty, left, right, order), metas, args = eq in
- if not (fst (CicReduction.are_convertible ~metasenv:metas context eq_ty
- (fst (CicTypeChecker.type_of_aux' metas context left CicUniv.empty_ugraph))
- CicUniv.empty_ugraph))
- then
- begin
- prerr_endline msg;
- assert false;
- end
- else ()
-;;
-
-let find_equalities context proof =
- let module C = Cic in
- let module S = CicSubstitution in
- let module T = CicTypeChecker in
- let eq_uri = LibraryObjects.eq_URI () in
- let newmeta = ProofEngineHelpers.new_meta_of_proof ~proof in
- let ok_types ty menv =
- List.for_all (fun (_, _, mt) -> mt = ty) menv
- in
- let rec aux index newmeta = function
- | [] -> [], newmeta
- | (Some (_, C.Decl (term)))::tl ->
- let do_find context term =
- match term with
- | C.Prod (name, s, t) ->
- let (head, newmetas, args, newmeta) =
- ProofEngineHelpers.saturate_term newmeta []
- context (S.lift index term) 0
- in
- let p =
- if List.length args = 0 then
- C.Rel index
- else
- C.Appl ((C.Rel index)::args)
- in (
- match head with
- | C.Appl [C.MutInd (uri, _, _); ty; t1; t2]
- when (UriManager.eq uri eq_uri) && (ok_types ty newmetas) ->
- debug_print
- (lazy
- (Printf.sprintf "OK: %s" (CicPp.ppterm term)));
- let o = !Utils.compare_terms t1 t2 in
- let w = compute_equality_weight ty t1 t2 in
- let proof = BasicProof p in
- let e = (w, proof, (ty, t1, t2, o), newmetas, args) in
- Some e, (newmeta+1)
- | _ -> None, newmeta
- )
- | C.Appl [C.MutInd (uri, _, _); ty; t1; t2]
- when UriManager.eq uri eq_uri ->
- let ty = S.lift index ty in
- let t1 = S.lift index t1 in
- let t2 = S.lift index t2 in
- let o = !Utils.compare_terms t1 t2 in
- let w = compute_equality_weight ty t1 t2 in
- let e = (w, BasicProof (C.Rel index), (ty, t1, t2, o), [], []) in
- Some e, (newmeta+1)
- | _ -> None, newmeta
- in (
- match do_find context term with
- | Some p, newmeta ->
- let tl, newmeta' = (aux (index+1) newmeta tl) in
- if newmeta' < newmeta then
- prerr_endline "big trouble";
- (index, p)::tl, newmeta' (* max???? *)
- | None, _ ->
- aux (index+1) newmeta tl
- )
- | _::tl ->
- aux (index+1) newmeta tl
- in
- let il, maxm = aux 1 newmeta context in
- let indexes, equalities = List.split il in
- ignore (List.iter (check_eq context "find") equalities);
- indexes, equalities, maxm
-;;
-
-
-(*
-let equations_blacklist =
- List.fold_left
- (fun s u -> UriManager.UriSet.add (UriManager.uri_of_string u) s)
- UriManager.UriSet.empty [
- "cic:/Coq/Init/Logic/eq.ind#xpointer(1/1/1)";
- "cic:/Coq/Init/Logic/trans_eq.con";
- "cic:/Coq/Init/Logic/f_equal.con";
- "cic:/Coq/Init/Logic/f_equal2.con";
- "cic:/Coq/Init/Logic/f_equal3.con";
- "cic:/Coq/Init/Logic/f_equal4.con";
- "cic:/Coq/Init/Logic/f_equal5.con";
- "cic:/Coq/Init/Logic/sym_eq.con";
- "cic:/Coq/Init/Logic/eq_ind.con";
- "cic:/Coq/Init/Logic/eq_ind_r.con";
- "cic:/Coq/Init/Logic/eq_rec.con";
- "cic:/Coq/Init/Logic/eq_rec_r.con";
- "cic:/Coq/Init/Logic/eq_rect.con";
- "cic:/Coq/Init/Logic/eq_rect_r.con";
- "cic:/Coq/Logic/Eqdep/UIP.con";
- "cic:/Coq/Logic/Eqdep/UIP_refl.con";
- "cic:/Coq/Logic/Eqdep_dec/eq2eqT.con";
- "cic:/Coq/ZArith/Zcompare/rename.con";
- (* ALB !!!! questo e` imbrogliare, ma x ora lo lasciamo cosi`...
- perche' questo cacchio di teorema rompe le scatole :'( *)
- "cic:/Rocq/SUBST/comparith/mult_n_2.con";
-
- "cic:/matita/logic/equality/eq_f.con";
- "cic:/matita/logic/equality/eq_f2.con";
- "cic:/matita/logic/equality/eq_rec.con";
- "cic:/matita/logic/equality/eq_rect.con";
- ]
-;;
-*)
-let equations_blacklist = UriManager.UriSet.empty;;
-
-
-let find_library_equalities dbd context status maxmeta =
- let module C = Cic in
- let module S = CicSubstitution in
- let module T = CicTypeChecker in
- let blacklist =
- List.fold_left
- (fun s u -> UriManager.UriSet.add u s)
- equations_blacklist
- [eq_XURI (); sym_eq_URI (); trans_eq_URI (); eq_ind_URI ();
- eq_ind_r_URI ()]
- in
- let candidates =
- List.fold_left
- (fun l uri ->
- if UriManager.UriSet.mem uri blacklist then
- l
- else
- let t = CicUtil.term_of_uri uri in
- let ty, _ =
- CicTypeChecker.type_of_aux' [] context t CicUniv.empty_ugraph
- in
- (uri, t, ty)::l)
- []
- (let t1 = Unix.gettimeofday () in
- let eqs = (MetadataQuery.equations_for_goal ~dbd status) in
- let t2 = Unix.gettimeofday () in
- (debug_print
- (lazy
- (Printf.sprintf "Tempo di MetadataQuery.equations_for_goal: %.9f\n"
- (t2 -. t1))));
- eqs)
- in
- let eq_uri1 = eq_XURI ()
- and eq_uri2 = LibraryObjects.eq_URI () in
- let iseq uri =
- (UriManager.eq uri eq_uri1) || (UriManager.eq uri eq_uri2)
- in
- let ok_types ty menv =
- List.for_all (fun (_, _, mt) -> mt = ty) menv
- in
- let rec has_vars = function
- | C.Meta _ | C.Rel _ | C.Const _ -> false
- | C.Var _ -> true
- | C.Appl l -> List.exists has_vars l
- | C.Prod (_, s, t) | C.Lambda (_, s, t)
- | C.LetIn (_, s, t) | C.Cast (s, t) ->
- (has_vars s) || (has_vars t)
- | _ -> false
- in
- let rec aux newmeta = function
- | [] -> [], newmeta
- | (uri, term, termty)::tl ->
- debug_print
- (lazy
- (Printf.sprintf "Examining: %s (%s)"
- (CicPp.ppterm term) (CicPp.ppterm termty)));
- let res, newmeta =
- match termty with
- | C.Prod (name, s, t) when not (has_vars termty) ->
- let head, newmetas, args, newmeta =
- ProofEngineHelpers.saturate_term newmeta [] context termty 0
- in
- let p =
- if List.length args = 0 then
- term
- else
- C.Appl (term::args)
- in (
- match head with
- | C.Appl [C.MutInd (uri, _, _); ty; t1; t2]
- when (iseq uri) && (ok_types ty newmetas) ->
- debug_print
- (lazy
- (Printf.sprintf "OK: %s" (CicPp.ppterm term)));
- let o = !Utils.compare_terms t1 t2 in
- let w = compute_equality_weight ty t1 t2 in
- let proof = BasicProof p in
- let e = (w, proof, (ty, t1, t2, o), newmetas, args) in
- Some e, (newmeta+1)
- | _ -> None, newmeta
- )
- | C.Appl [C.MutInd (uri, _, _); ty; t1; t2]
- when iseq uri && not (has_vars termty) ->
- let o = !Utils.compare_terms t1 t2 in
- let w = compute_equality_weight ty t1 t2 in
- let e = (w, BasicProof term, (ty, t1, t2, o), [], []) in
- Some e, (newmeta+1)
- | _ -> None, newmeta
- in
- match res with
- | Some e ->
- let tl, newmeta' = aux newmeta tl in
- if newmeta' < newmeta then
- prerr_endline "big trouble";
- (uri, e)::tl, newmeta' (* max???? *)
- | None ->
- aux newmeta tl
- in
- let found, maxm = aux maxmeta candidates in
- let uriset, eqlist =
- (List.fold_left
- (fun (s, l) (u, e) ->
- if List.exists (meta_convertibility_eq e) (List.map snd l) then (
- debug_print
- (lazy
- (Printf.sprintf "NO!! %s already there!"
- (string_of_equality e)));
- (UriManager.UriSet.add u s, l)
- ) else (UriManager.UriSet.add u s, (u, e)::l))
- (UriManager.UriSet.empty, []) found)
- in
- uriset, eqlist, maxm
-;;
-
-
-let find_library_theorems dbd env status equalities_uris =
- let module C = Cic in
- let module S = CicSubstitution in
- let module T = CicTypeChecker in
- let blacklist =
- let refl_equal =
- UriManager.uri_of_string "cic:/Coq/Init/Logic/eq.ind#xpointer(1/1/1)" in
- let s =
- UriManager.UriSet.remove refl_equal
- (UriManager.UriSet.union equalities_uris equations_blacklist)
- in
- List.fold_left
- (fun s u -> UriManager.UriSet.add u s)
- s [eq_XURI () ;sym_eq_URI (); trans_eq_URI (); eq_ind_URI ();
- eq_ind_r_URI ()]
- in
- let metasenv, context, ugraph = env in
- let candidates =
- List.fold_left
- (fun l uri ->
- if UriManager.UriSet.mem uri blacklist then l
- else
- let t = CicUtil.term_of_uri uri in
- let ty, _ = CicTypeChecker.type_of_aux' metasenv context t ugraph in
- (t, ty, [])::l)
- [] (MetadataQuery.signature_of_goal ~dbd status)
- in
- let refl_equal =
- let u = eq_XURI () in
- let t = CicUtil.term_of_uri u in
- let ty, _ = CicTypeChecker.type_of_aux' [] [] t CicUniv.empty_ugraph in
- (t, ty, [])
- in
- refl_equal::candidates
-;;
-
-
-let find_context_hypotheses env equalities_indexes =
- let metasenv, context, ugraph = env in
- let _, res =
- List.fold_left
- (fun (n, l) entry ->
- match entry with
- | None -> (n+1, l)
- | Some _ ->
- if List.mem n equalities_indexes then
- (n+1, l)
- else
- let t = Cic.Rel n in
- let ty, _ =
- CicTypeChecker.type_of_aux' metasenv context t ugraph in
- (n+1, (t, ty, [])::l))
- (1, []) context
- in
- res
-;;
-
-
-let fix_metas_old newmeta (w, p, (ty, left, right, o), menv, args) =
- let table = Hashtbl.create (List.length args) in
-
- let newargs, newmeta =
- List.fold_right
- (fun t (newargs, index) ->
- match t with
- | Cic.Meta (i, l) ->
- if Hashtbl.mem table i then
- let idx = Hashtbl.find table i in
- ((Cic.Meta (idx, l))::newargs, index+1)
- else
- let _ = Hashtbl.add table i index in
- ((Cic.Meta (index, l))::newargs, index+1)
- | _ -> assert false)
- args ([], newmeta+1)
- in
-
- let repl where =
- ProofEngineReduction.replace ~equality:(=) ~what:args ~with_what:newargs
- ~where
- in
- let menv' =
- List.fold_right
- (fun (i, context, term) menv ->
- try
- let index = Hashtbl.find table i in
- (index, context, term)::menv
- with Not_found ->
- (i, context, term)::menv)
- menv []
- in
- let ty = repl ty
- and left = repl left
- and right = repl right in
- let metas =
- (metas_of_term left) @
- (metas_of_term right) @
- (metas_of_term ty) @ (metas_of_proof p) in
- let menv' = List.filter (fun (i, _, _) -> List.mem i metas) menv' in
- let newargs =
- List.filter
- (function Cic.Meta (i, _) -> List.mem i metas | _ -> assert false) newargs
- in
- let _ =
- if List.length metas > 0 then
- let first = List.hd metas in
- (* this new equality might have less variables than its parents: here
- we fill the gap with a dummy arg. Example:
- with (f X Y) = X we can simplify
- (g X) = (f X Y) in
- (g X) = X.
- So the new equation has only one variable, but it still has type like
- \lambda X,Y:..., so we need to pass a dummy arg for Y
- (I hope this makes some sense...)
- *)
- Hashtbl.iter
- (fun k v ->
- if not (List.exists
- (function Cic.Meta (i, _) -> i = v | _ -> assert false)
- newargs) then
- Hashtbl.replace table k first)
- (Hashtbl.copy table)
- in
- let rec fix_proof = function
- | NoProof -> NoProof
- | BasicProof term -> BasicProof (repl term)
- | ProofBlock (subst, eq_URI, namety, bo, (pos, eq), p) ->
- let subst' =
- List.fold_left
- (fun s arg ->
- match arg with
- | Cic.Meta (i, l) -> (
- try
- let j = Hashtbl.find table i in
- if List.mem_assoc i subst then
- s
- else
- let _, context, ty = CicUtil.lookup_meta i menv in
- (i, (context, Cic.Meta (j, l), ty))::s
- with Not_found | CicUtil.Meta_not_found _ ->
- s
- )
- | _ -> assert false)
- [] args
- in
- ProofBlock (subst' @ subst, eq_URI, namety, bo(* t' *), (pos, eq), p)
- | p -> assert false
- in
- let neweq = (w, fix_proof p, (ty, left, right, o), menv', newargs) in
- (newmeta +1, neweq)
-;;
-
-
-let relocate newmeta menv =
- let subst, metasenv, newmeta =
- List.fold_right
- (fun (i, context, ty) (subst, menv, maxmeta) ->
- let irl=CicMkImplicit.identity_relocation_list_for_metavariable context in
- let newsubst = (i, (context, (Cic.Meta (maxmeta, irl)), ty)) in
- let newmeta = maxmeta, context, ty in
- newsubst::subst, newmeta::menv, maxmeta+1)
- menv ([], [], newmeta+1)
- in
- let metasenv = CicMetaSubst.apply_subst_metasenv subst metasenv in
- let subst =
- List.map
- (fun (i, (context, term, ty)) ->
- let context = CicMetaSubst.apply_subst_context subst context in
- let term = CicMetaSubst.apply_subst subst term in
- let ty = CicMetaSubst.apply_subst subst ty in
- (i, (context, term, ty))) subst in
- subst, metasenv, newmeta
-
-
-let fix_metas newmeta (w, p, (ty, left, right, o), menv, args) =
- (*
- let metas = (metas_of_term left)@(metas_of_term right)
- @(metas_of_term ty)@(metas_of_proof p) in
- let menv = List.filter (fun (i, _, _) -> List.mem i metas) menv in
- *)
- (* debug
- let _ , eq =
- fix_metas_old newmeta (w, p, (ty, left, right, o), menv, args) in
- prerr_endline (string_of_equality eq); *)
- let subst, metasenv, newmeta = relocate newmeta menv in
- let ty = CicMetaSubst.apply_subst subst ty in
- let left = CicMetaSubst.apply_subst subst left in
- let right = CicMetaSubst.apply_subst subst right in
- let args = List.map (CicMetaSubst.apply_subst subst) args in
- let rec fix_proof = function
- | NoProof -> NoProof
- | BasicProof term -> BasicProof (CicMetaSubst.apply_subst subst term)
- | ProofBlock (subst', eq_URI, namety, bo, (pos, eq), p) ->
- (*
- let newsubst =
- List.map
- (fun (i, (context, term, ty)) ->
- let context = CicMetaSubst.apply_subst_context subst context in
- let term = CicMetaSubst.apply_subst subst term in
- let ty = CicMetaSubst.apply_subst subst ty in
- (i, (context, term, ty))) subst' in *)
- ProofBlock (subst@subst', eq_URI, namety, bo, (pos, eq), p)
- | p -> assert false
- in
- let p = fix_proof p in
- (*
- let metas = (metas_of_term left)@(metas_of_term right)
- @(metas_of_term ty)@(metas_of_proof p) in
- let metasenv = List.filter (fun (i, _, _) -> List.mem i metas) metasenv in
- *)
- let eq = (w, p, (ty, left, right, o), metasenv, args) in
- (* debug prerr_endline (string_of_equality eq); *)
- newmeta+1, eq
-
-let term_is_equality term =
- let iseq uri = UriManager.eq uri (LibraryObjects.eq_URI ()) in
- match term with
- | Cic.Appl [Cic.MutInd (uri, _, _); _; _; _] when iseq uri -> true
- | _ -> false
-;;
-
-
-exception TermIsNotAnEquality;;
-
-let equality_of_term proof term =
- let eq_uri = LibraryObjects.eq_URI () in
- let iseq uri = UriManager.eq uri eq_uri in
- match term with
- | Cic.Appl [Cic.MutInd (uri, _, _); ty; t1; t2] when iseq uri ->
- let o = !Utils.compare_terms t1 t2 in
- let w = compute_equality_weight ty t1 t2 in
- let e = (w, BasicProof proof, (ty, t1, t2, o), [], []) in
- e
- | _ ->
- raise TermIsNotAnEquality
-;;
-
-
-type environment = Cic.metasenv * Cic.context * CicUniv.universe_graph;;
-
-let is_weak_identity (metasenv, context, ugraph) = function
- | (_, _, (ty, left, right, _), menv, _) ->
- (left = right ||
- (meta_convertibility left right))
- (* the test below is not a good idea since it stops
- demodulation too early *)
- (* (fst (CicReduction.are_convertible
- ~metasenv:(metasenv @ menv) context left right ugraph)))*)