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
35 module R = ReductionTactics
38 (* search in term the Inductive Types and return a list of uris as triples like this: (uri,typeno,exp_named_subst) *)
39 let search_inductive_types ty =
40 let rec aux types = function
41 | C.MutInd (uri, typeno, _) when (not (List.mem (uri, typeno) types)) ->
42 (uri, typeno) :: types
43 | C.Appl applist -> List.fold_left aux types applist
47 (* N.B: in un caso tipo (and A forall C:Prop.(or B C)) l'or *non* viene selezionato! *)
50 (* unexported tactics *******************************************************)
52 type type_class = Other
56 let premise_pattern what = None, [what, C.Implicit (Some `Hole)], None
58 let rec scan_tac ~old_context_length ~index ~tactic =
60 let (proof, goal) = status in
61 let _, metasenv, _, _, _ = proof in
62 let _, context, _ = CicUtil.lookup_meta goal metasenv in
63 let context_length = List.length context in
65 match H.get_name context index with
66 | _ when index <= 0 -> (proof, [goal])
67 | None -> aux (pred index)
69 let tac = T.then_ ~start:(tactic ~what)
70 ~continuation:(scan_tac ~old_context_length:context_length ~index ~tactic)
72 try E.apply_tactic tac status
73 with E.Fail _ -> aux (pred index)
74 in aux (index + context_length - old_context_length)
78 let rec check_types types = function
79 | C.MutInd (uri, typeno, _) ->
80 if List.mem (uri, Some typeno) types then Ind else Other
81 | C.Const (uri, _) as t ->
82 if List.mem (uri, None) types then Con (E.const_lazy_term t) else Other
83 | C.Appl (hd :: tl) -> check_types types hd
86 let elim_clear_unfold_tac ~mk_fresh_name_callback ~types ~what =
87 let elim_clear_unfold_tac status =
88 let (proof, goal) = status in
89 let _, metasenv, _, _, _ = proof in
90 let _, context, _ = CicUtil.lookup_meta goal metasenv in
91 let index, ty = H.lookup_type metasenv context what in
92 match check_types types ty with
94 let tac = T.then_ ~start:(P.elim_intros_tac ~mk_fresh_name_callback (C.Rel index))
95 ~continuation:(S.clear [what])
97 E.apply_tactic tac status
99 let tac = R.unfold_tac (Some t) ~pattern:(premise_pattern what) in
100 E.apply_tactic tac status
102 raise (E.Fail (lazy "unexported elim_clear: not an eliminable type"))
104 E.mk_tactic elim_clear_unfold_tac
106 (* elim type ****************************************************************)
108 let elim_type_tac ?(mk_fresh_name_callback = F.mk_fresh_name ~subst:[]) ?depth
112 P.elim_intros_simpl_tac ?using ?depth ~mk_fresh_name_callback what
114 let elim_type_tac status =
116 T.thens ~start: (P.cut_tac what) ~continuations:[elim (C.Rel 1); T.id_tac]
118 E.apply_tactic tac status
120 E.mk_tactic elim_type_tac
122 (* decompose ****************************************************************)
124 (* robaglia --------------------------------------------------------------- *)
126 (** perform debugging output? *)
128 let debug_print = fun _ -> ()
130 (** debugging print *)
131 let warn s = debug_print (lazy ("DECOMPOSE: " ^ (Lazy.force s)))
133 (* roba seria ------------------------------------------------------------- *)
135 let decompose_tac ?(mk_fresh_name_callback = F.mk_fresh_name ~subst:[])
136 ?(user_types=[]) ?what ~dbd =
137 let decompose_tac status =
138 let (proof, goal) = status in
139 let _, metasenv,_,_, _ = proof in
140 let _, context, _ = CicUtil.lookup_meta goal metasenv in
141 let types = List.rev_append user_types (FwdQueries.decomposables dbd) in
142 let tactic = elim_clear_unfold_tac ~mk_fresh_name_callback ~types in
143 let old_context_length = List.length context in
144 let tac = match what with
146 T.then_ ~start:(tactic ~what)
147 ~continuation:(scan_tac ~old_context_length ~index:1 ~tactic)
149 scan_tac ~old_context_length ~index:old_context_length ~tactic
151 E.apply_tactic tac status
153 E.mk_tactic decompose_tac