1 (* Copyright (C) 2002, HELM Team.
3 * This file is part of HELM, an Hypertextual, Electronic
4 * Library of Mathematics, developed at the Computer Science
5 * Department, University of Bologna, Italy.
7 * HELM is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * HELM is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with HELM; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22 * For details, see the HELM World-Wide-Web page,
23 * http://cs.unibo.it/helm/.
29 module P = PrimitiveTactics
31 module S = ProofEngineStructuralRules
32 module F = FreshNamesGenerator
33 module E = ProofEngineTypes
34 module H = ProofEngineHelpers
36 (* unexported tactics *******************************************************)
38 let rec scan_tac ~old_context_length ~index ~tactic =
40 let (proof, goal) = status in
41 let _, metasenv, _, _ = proof in
42 let _, context, _ = CicUtil.lookup_meta goal metasenv in
43 let context_length = List.length context in
45 match H.get_name context index with
46 | _ when index <= 0 -> (proof, [goal])
47 | None -> aux (pred index)
49 let tac = T.then_ ~start:(tactic ~what)
50 ~continuation:(scan_tac ~old_context_length:context_length ~index ~tactic)
52 try E.apply_tactic tac status
53 with E.Fail _ -> aux (pred index)
54 in aux (index + context_length - old_context_length - 1)
58 let rec check_inductive_types types = function
59 | C.MutInd (uri, typeno, _) -> List.mem (uri, typeno) types
60 | C.Appl (hd :: tl) -> check_inductive_types types hd
63 let elim_clear_tac ~mk_fresh_name_callback ~types ~what =
64 let elim_clear_tac status =
65 let (proof, goal) = status in
66 let _, metasenv, _, _ = proof in
67 let _, context, _ = CicUtil.lookup_meta goal metasenv in
68 let index, ty = H.lookup_type metasenv context what in
69 if check_inductive_types types ty then
70 let tac = T.then_ ~start:(P.elim_intros_tac ~mk_fresh_name_callback (C.Rel index))
71 ~continuation:(S.clear [what])
73 E.apply_tactic tac status
74 else raise (E.Fail (lazy "unexported elim_clear: not an eliminable type"))
76 E.mk_tactic elim_clear_tac
78 (* elim type ****************************************************************)
80 let elim_type_tac ?(mk_fresh_name_callback = F.mk_fresh_name ~subst:[]) ?depth
84 P.elim_intros_simpl_tac ?using ?depth ~mk_fresh_name_callback what
86 let elim_type_tac status =
88 T.thens ~start: (P.cut_tac what) ~continuations:[elim (C.Rel 1); T.id_tac]
90 E.apply_tactic tac status
92 E.mk_tactic elim_type_tac
94 (* decompose ****************************************************************)
96 (* robaglia --------------------------------------------------------------- *)
98 (** perform debugging output? *)
100 let debug_print = fun _ -> ()
102 (** debugging print *)
103 let warn s = debug_print (lazy ("DECOMPOSE: " ^ (Lazy.force s)))
105 (* search in term the Inductive Types and return a list of uris as triples like this: (uri,typeno,exp_named_subst) *)
106 let search_inductive_types ty =
107 let rec aux types = function
108 | C.MutInd (uri, typeno, _) when (not (List.mem (uri, typeno) types)) ->
109 (uri, typeno) :: types
110 | C.Appl applist -> List.fold_left aux types applist
114 (* N.B: in un caso tipo (and A forall C:Prop.(or B C)) l'or *non* viene selezionato! *)
116 (* roba seria ------------------------------------------------------------- *)
118 let decompose_tac ?(mk_fresh_name_callback = F.mk_fresh_name ~subst:[])
119 ?(user_types=[]) ?what ~dbd =
120 let decompose_tac status =
121 let (proof, goal) = status in
122 let _, metasenv,_,_ = proof in
123 let _, context, _ = CicUtil.lookup_meta goal metasenv in
124 let types = List.rev_append user_types (FwdQueries.decomposables dbd) in
125 let tactic = elim_clear_tac ~mk_fresh_name_callback ~types in
126 let old_context_length = List.length context in
127 let tac = match what with
129 T.then_ ~start:(tactic ~what)
130 ~continuation:(scan_tac ~old_context_length ~index:1 ~tactic)
132 scan_tac ~old_context_length ~index:old_context_length ~tactic
134 E.apply_tactic tac status
136 E.mk_tactic decompose_tac