1
(************************************************************************)
2
(* v * The Coq Proof Assistant / The Coq Development Team *)
3
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
4
(* \VV/ **************************************************************)
5
(* // * This file is distributed under the terms of the *)
6
(* * GNU Lesser General Public License Version 2.1 *)
7
(************************************************************************)
9
(* $Id: elim.ml 11739 2009-01-02 19:33:19Z herbelin $ *)
30
let introElimAssumsThen tac ba =
33
(fun acc b -> if b then acc+2 else acc+1)
36
let introElimAssums = tclDO nassums intro in
37
(tclTHEN introElimAssums (elim_on_ba tac ba))
39
let introCaseAssumsThen tac ba =
42
(List.map (function b -> if b then [false;true] else [false])
45
let n1 = List.length case_thin_sign in
46
let n2 = List.length ba.branchnames in
48
if n1 < n2 then list_chop n1 ba.branchnames, []
51
if n1 > n2 then snd (list_chop n2 case_thin_sign) else [] in
53
tclTHEN (intros_pattern no_move l1) (intros_clearing l3) in
54
(tclTHEN introCaseAssums (case_on_ba (tac l2) ba))
56
(* The following tactic Decompose repeatedly applies the
57
elimination(s) rule(s) of the types satisfying the predicate
58
``recognizer'' onto a certain hypothesis. For example :
62
Goal (y:nat){x:nat | (le O x)/\(le x y)}->{x:nat | (le O x)}.
64
Decompose [sig and] H;EAuto.
69
Goal (A,B,C:Prop)(A/\B/\C \/ B/\C \/ C/\A) -> C.
70
Intros A B C H; Decompose [and or] H; Assumption.
74
let elimHypThen tac id gl =
75
elimination_then tac ([],[]) (mkVar id) gl
77
let rec general_decompose_on_hyp recognizer =
78
ifOnHyp recognizer (general_decompose recognizer) (fun _ -> tclIDTAC)
80
and general_decompose recognizer id =
85
(tclMAP (general_decompose_on_hyp recognizer)
86
(ids_of_named_context bas.assums))))
89
(* Faudrait ajouter un COMPLETE pour que l'hypoth�se cr��e ne reste
90
pas si aucune �limination n'est possible *)
92
(* Meilleures strat�gies mais perte de compatibilit� *)
93
let tmphyp_name = id_of_string "_TmpHyp"
94
let up_to_delta = ref false (* true *)
96
let general_decompose recognizer c gl =
97
let typc = pf_type_of gl c in
99
[| tclTHEN (intro_using tmphyp_name)
101
(ifOnHyp recognizer (general_decompose recognizer)
102
(fun id -> clear [id])));
103
exact_no_check c |] gl
105
let head_in gls indl t =
109
then find_mrectype (pf_env gls) (project gls) t
110
else extract_mrectype t
112
with Not_found -> false
114
let inductive_of = function
117
errorlabstrm "Decompose"
118
(Printer.pr_global r ++ str " is not an inductive type.")
120
let decompose_these c l gls =
121
let indl = (*List.map inductive_of*) l in
122
general_decompose (fun (_,t) -> head_in gls indl t) c gls
124
let decompose_nonrec c gls =
126
(fun (_,t) -> is_non_recursive_type t)
129
let decompose_and c gls =
131
(fun (_,t) -> is_record t)
134
let decompose_or c gls =
136
(fun (_,t) -> is_disjunction t)
139
let inj_open c = (Evd.empty,c)
141
let h_decompose l c =
142
Refiner.abstract_tactic (TacDecompose (l,inj_open c)) (decompose_these c l)
144
let h_decompose_or c =
145
Refiner.abstract_tactic (TacDecomposeOr (inj_open c)) (decompose_or c)
147
let h_decompose_and c =
148
Refiner.abstract_tactic (TacDecomposeAnd (inj_open c)) (decompose_and c)
150
(* The tactic Double performs a double induction *)
152
let simple_elimination c gls =
153
simple_elimination_then (fun _ -> tclIDTAC) c gls
155
let induction_trailer abs_i abs_j bargs =
157
(tclDO (abs_j - abs_i) intro)
160
let idty = pf_type_of gls (mkVar id) in
161
let fvty = global_vars (pf_env gls) idty in
162
let possible_bring_hyps =
163
(List.tl (nLastHyps (abs_j - abs_i) gls)) @ bargs.assums
167
(fun (bring_ids,leave_ids) (cid,_,cidty as d) ->
168
if not (List.mem cid leave_ids)
169
then (d::bring_ids,leave_ids)
170
else (bring_ids,cid::leave_ids))
171
([],fvty) possible_bring_hyps
173
let ids = List.rev (ids_of_named_context hyps) in
175
[bring_hyps hyps; tclTRY (clear ids);
176
simple_elimination (mkVar id)])
179
let double_ind h1 h2 gls =
180
let abs_i = depth_of_quantified_hypothesis true h1 gls in
181
let abs_j = depth_of_quantified_hypothesis true h2 gls in
183
if abs_i < abs_j then (abs_i,abs_j) else
184
if abs_i > abs_j then (abs_j,abs_i) else
185
error "Both hypotheses are the same." in
186
(tclTHEN (tclDO abs_i intro)
190
(introElimAssumsThen (induction_trailer abs_i abs_j))
191
([],[]) (mkVar id)))) gls
193
let h_double_induction h1 h2 =
194
Refiner.abstract_tactic (TacDoubleInduction (h1,h2)) (double_ind h1 h2)