+(* 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/.
+ *)
+
+
+let constructor_tac ~n ~status:(proof, goal) =
+ let module C = Cic in
+ let module R = CicReduction in
+ let (_,metasenv,_,_) = proof in
+ let metano,context,ty = List.find (function (m,_,_) -> m=goal) metasenv in
+ match (R.whd context ty) with
+ (C.MutInd (uri,typeno,exp_named_subst))
+ | (C.Appl ((C.MutInd (uri,typeno,exp_named_subst))::_)) ->
+ PrimitiveTactics.apply_tac ~status:(proof,goal)
+ ~term: (C.MutConstruct (uri, typeno, n, exp_named_subst))
+ | _ -> raise (ProofEngineTypes.Fail "Constructor failed")
+;;
+
+
+let exists_tac ~status =
+ constructor_tac ~n:1 ~status
+;;
+
+
+let split_tac ~status =
+ constructor_tac ~n:1 ~status
+;;
+
+
+let left_tac ~status =
+ constructor_tac ~n:1 ~status
+;;
+
+
+let right_tac ~status =
+ constructor_tac ~n:2 ~status
+;;
+
+
+let reflexivity_tac =
+ constructor_tac ~n:1
+;;
+
+
+let symmetry_tac ~status:(proof, goal) =
+ let module C = Cic in
+ let module R = CicReduction in
+ let module U = UriManager in
+ let (_,metasenv,_,_) = proof in
+ let metano,context,ty = List.find (function (m,_,_) -> m=goal) metasenv in
+ match (R.whd context ty) with
+ (C.Appl [(C.MutInd (uri, 0, [])); _; _; _]) when (U.eq uri (U.uri_of_string "cic:/Coq/Init/Logic/Equality/eq.ind")) ->
+ PrimitiveTactics.apply_tac ~status:(proof,goal)
+ ~term: (C.Const (U.uri_of_string "cic:/Coq/Init/Logic/Logic_lemmas/equality/sym_eq.con", []))
+
+ | (C.Appl [(C.MutInd (uri, 0, [])); _; _; _]) when (U.eq uri (U.uri_of_string "cic:/Coq/Init/Logic_Type/eqT.ind")) ->
+ PrimitiveTactics.apply_tac ~status:(proof,goal)
+ ~term: (C.Const (U.uri_of_string "cic:/Coq/Init/Logic_Type/Equality_is_a_congruence/sym_eqT.con", []))
+
+ | _ -> raise (ProofEngineTypes.Fail "Symmetry failed")
+;;
+
+
+let transitivity_tac ~term ~status:((proof, goal) as status) =
+ let module C = Cic in
+ let module R = CicReduction in
+ let module U = UriManager in
+ let module Tl = Tacticals in
+ let (_,metasenv,_,_) = proof in
+ let metano,context,ty = List.find (function (m,_,_) -> m=goal) metasenv in
+ match (R.whd context ty) with
+ (C.Appl [(C.MutInd (uri, 0, [])); _; _; _]) when (uri = (U.uri_of_string "cic:/Coq/Init/Logic/Equality/eq.ind")) ->
+ Tl.thens
+ ~start:(PrimitiveTactics.apply_tac
+ ~term: (C.Const (U.uri_of_string "cic:/Coq/Init/Logic/Logic_lemmas/equality/trans_eq.con", [])))
+ ~continuations: [(PrimitiveTactics.exact_tac ~term); Tl.id_tac; Tl.id_tac]
+ ~status
+
+ | (C.Appl [(C.MutInd (uri, 0, [])); _; _; _]) when (uri = (U.uri_of_string "cic:/Coq/Init/Logic_Type/eqT.ind")) ->
+ Tl.thens
+ ~start:(PrimitiveTactics.apply_tac
+ ~term: (C.Const (U.uri_of_string "cic:/Coq/Init/Logic_Type/Equality_is_a_congruence/trans_eqT.con", [])))
+ ~continuations: [(PrimitiveTactics.exact_tac ~term); Tl.id_tac; Tl.id_tac]
+ ~status
+
+ | _ -> raise (ProofEngineTypes.Fail "Transitivity failed")
+;;
+
+
+(* TODO se ce n'e' piu' di una, prende la prima che trova... sarebbe meglio chiedere *)
+
+let assumption_tac ~status:((proof,goal) as status) =
+ let module C = Cic in
+ let module R = CicReduction in
+ let module T = CicTypeChecker in
+ let _,metasenv,_,_ = proof in
+ let _,context,ty = List.find (function (m,_,_) -> m=goal) metasenv in
+ let rec find n = function
+ hd::tl ->
+(* (let hdd = hd in
+ match hdd with
+ Some (name, termine) -> prerr_endline("####" ^ name ^ CicPp.ppterm termine)
+ | None -> prerr_endline("#### None")
+ );
+*) (match hd with
+ (Some (_, C.Decl t)) when (R.are_convertible context t ty) -> n
+ | (Some (_, C.Def t)) when (R.are_convertible context (T.type_of_aux' metasenv context t) ty) -> n
+ | _ -> find (n+1) tl
+ )
+ | [] -> raise (ProofEngineTypes.Fail "No such assumption")
+ in PrimitiveTactics.apply_tac ~status ~term:(C.Rel (find 1 context))
+;;
+
+(*
+let generalize_tac ~term ~status:((proof,goal) as status) =
+ let module C = Cic in
+ let module R = CicReduction in
+ let module T = CicTypeChecker in
+ let module P = PrimitiveTactics in
+ let module Tl = Tacticals in
+ let _,metasenv,_,_ = proof in
+ let _,context,_ = List.find (function (m,_,_) -> m=goal) metasenv in
+ Tl.thens
+ ~start:(P.cut_tac ~term:(C.Lambda ("dummy_for_gen", (T.type_of_aux' metasenv context term), (R.replace ?????? (C.Name "dummy_for_gen") term )))
+ ~continuations: [(P.apply_tac (C.Appl [(C.Rel 1); term])); Tl.id_tac] (* in quest'ordine o viceversa? provare *)
+ ~status
+;;
+
+
+let absurd_tac ~term ~status:((proof,goal) as status) =
+ PrimitiveTactics.cut_tac
+;;
+*)
+