(* Copyright (C) 2002, HELM Team. * * This file is part of HELM, an Hypertextual, Electronic * Library of Mathematics, developed at the Computer Science * Department, University of Bologna, Italy. * * HELM is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * HELM is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HELM; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. * * For details, see the HELM World-Wide-Web page, * http://cs.unibo.it/helm/. *) module C = Cic module DTI = DoubleTypeInference module ET = EqualityTactics module HEL = HExtlib module LO = LibraryObjects module PEH = ProofEngineHelpers module PESR = ProofEngineStructuralRules module PET = ProofEngineTypes module S = CicSubstitution module T = Tacticals module TC = CicTypeChecker (* FG: This should be replaced by T.try_tactic *) let try_tactic ~tactic = let try_tactic status = try PET.apply_tactic tactic status with | PET.Fail _ -> PET.apply_tactic T.id_tac status in PET.mk_tactic try_tactic let rec lift_rewrite_tac ~context ~direction ~pattern equality = let lift_rewrite_tac status = let (proof, goal) = status in let (_, metasenv, _, _, _) = proof in let _, new_context, _ = CicUtil.lookup_meta goal metasenv in let n = List.length new_context - List.length context in let equality = if n > 0 then S.lift n equality else equality in PET.apply_tactic (ET.rewrite_tac ~direction ~pattern equality []) status in PET.mk_tactic lift_rewrite_tac let msg0 = lazy "Subst: not found in context" let msg1 = lazy "Subst: not a simple equality" let msg2 = lazy "Subst: recursive equation" let subst_tac ~hyp = let hole = C.Implicit (Some `Hole) in let subst_tac status = let (proof, goal) = status in let (_, metasenv, _, _, _) = proof in let _, context, _ = CicUtil.lookup_meta goal metasenv in let what = match PEH.get_rel context hyp with | Some t -> t | None -> raise (PET.Fail msg0) in let ty, _ = TC.type_of_aux' metasenv context what CicUniv.empty_ugraph in let direction, i, t = match ty with | (C.Appl [(C.MutInd (uri, 0, [])); _; C.Rel i; t]) when LO.is_eq_URI uri -> `LeftToRight, i, t | (C.Appl [(C.MutInd (uri, 0, [])); _; t; C.Rel i]) when LO.is_eq_URI uri -> `RightToLeft, i, t | _ -> raise (PET.Fail msg1) in let rewrite pattern = let tactic = lift_rewrite_tac ~context ~direction ~pattern what in try_tactic ~tactic in let var = match PEH.get_name context i with | Some name -> name | None -> raise (PET.Fail msg0) in if DTI.does_not_occur i t then () else raise (PET.Fail msg2); let map self = function | Some (C.Name s, _) when s <> self -> Some (rewrite (None, [(s, hole)], None)) | _ -> None in let rew_hips = HEL.list_rev_map_filter (map hyp) context in let rew_concl = rewrite (None, [], Some hole) in let clear = PESR.clear ~hyps:[hyp; var] in let tactics = List.rev_append (rew_concl :: rew_hips) [clear] in PET.apply_tactic (T.seq ~tactics) status in PET.mk_tactic subst_tac let subst_tac = let subst hyp = try_tactic ~tactic:(subst_tac hyp) in let map = function | Some (C.Name s, _) -> Some (subst s) | _ -> None in let subst_tac status = let (proof, goal) = status in let (_, metasenv, _, _, _) = proof in let _, context, _ = CicUtil.lookup_meta goal metasenv in let tactics = HEL.list_rev_map_filter map context in PET.apply_tactic (T.seq ~tactics) status in PET.mk_tactic subst_tac