(* This is a tactic for structuring proofs that was added to the Coq wiki by user JeffVaughan: http://coq.inria.fr/cocorico/Case%20(tactic) It is licensed as follows, according to http://coq.inria.fr/cocorico/Cocorico!WikiLicense By contributing to Cocorico!, you agree that you hold the copyright and you agree to license your contribution under the license below or you agree that you have permission to distribute your contribution under the license below. Permission is hereby granted, free of charge, to any person obtaining this work (the "Work"), to deal in the Work without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Work, and to permit persons to whom the Work is furnished to do so. THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER DEALINGS IN THE WORK. *) Require Export String. Open Scope string_scope. Ltac move_to_top x := match reverse goal with | H : _ |- _ => try move x after H end. Tactic Notation "assert_eq" ident(x) constr(v) := let H := fresh in assert (x = v) as H by reflexivity; clear H. Tactic Notation "Case_aux" ident(x) constr(name) := first [ set (x := name); move_to_top x | assert_eq x name | fail 1 "because we are working on a different case." ]. Ltac Case name := Case_aux case name. Ltac SCase name := Case_aux subcase name. Ltac SSCase name := Case_aux subsubcase name. Ltac SSSCase name := Case_aux subsubsubcase name. Ltac S4Case name := Case_aux s4case name. Ltac S5Case name := Case_aux s5case name. Ltac S6Case name := Case_aux s6case name.