aboutsummaryrefslogtreecommitdiff
path: root/src/Util/Tactics.v
diff options
context:
space:
mode:
authorGravatar jadep <jade.philipoom@gmail.com>2016-08-11 17:00:30 -0400
committerGravatar jadep <jade.philipoom@gmail.com>2016-08-11 17:00:30 -0400
commit8c106350250c61b06afeb64d580212abd6c63ab2 (patch)
tree413d9de63372be4a8ea0173778ea31a75be435e9 /src/Util/Tactics.v
parent0556410ac98783bf1fd3179c57532078ac103514 (diff)
parent5ce52a9498f66e0ac62b9ff981b09f16d64d0f4c (diff)
merge
Diffstat (limited to 'src/Util/Tactics.v')
-rw-r--r--src/Util/Tactics.v43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/Util/Tactics.v b/src/Util/Tactics.v
index 8ddfecb5f..4559a1757 100644
--- a/src/Util/Tactics.v
+++ b/src/Util/Tactics.v
@@ -342,3 +342,46 @@ Ltac revert_last_nondep :=
end.
Ltac reverse_nondep := repeat revert_last_nondep.
+
+Ltac simplify_repeated_ifs_step :=
+ match goal with
+ | [ |- context G[if ?b then ?x else ?y] ]
+ => let x' := match x with
+ | context x'[b] => let x'' := context x'[true] in x''
+ end in
+ let G' := context G[if b then x' else y] in
+ cut G'; [ destruct b; exact (fun z => z) | cbv iota ]
+ | [ |- context G[if ?b then ?x else ?y] ]
+ => let y' := match y with
+ | context y'[b] => let y'' := context y'[false] in y''
+ end in
+ let G' := context G[if b then x else y'] in
+ cut G'; [ destruct b; exact (fun z => z) | cbv iota ]
+ end.
+Ltac simplify_repeated_ifs := repeat simplify_repeated_ifs_step.
+
+(** Like [specialize] but allows holes that get filled with evars. *)
+Tactic Notation "especialize" open_constr(H) := specialize H.
+
+(** [forward H] specializes non-dependent binders in a hypothesis [H]
+ with side-conditions. Side-conditions come after the main goal,
+ like with [replace] and [rewrite].
+
+ [eforward H] is like [forward H], but also specializes dependent
+ binders with evars.
+
+ Both tactics do nothing on hypotheses they cannot handle. *)
+Ltac forward_step H :=
+ match type of H with
+ | ?A -> ?B => let a := fresh in cut A; [ intro a; specialize (H a); clear a | ]
+ end.
+Ltac eforward_step H :=
+ match type of H with
+ | _ => forward_step H
+ | forall x : ?A, _
+ => let x_or_fresh := fresh x in
+ evar (x_or_fresh : A);
+ specialize (H x_or_fresh); subst x_or_fresh
+ end.
+Ltac forward H := try (forward_step H; [ forward H | .. ]).
+Ltac eforward H := try (eforward_step H; [ eforward H | .. ]).