The Local Tactics Library |
Open Scope J_Scope.
elimAndelimAnd is used mainly to eliminate and within the hypothesis. For the goals the preferred tactic is still split. |
Ltac
genclear H := generalize H;clear H.
Ltac
map_hyp Tac :=
repeat match goal with
| [ H : _ |- _ ] => try (Tac H);genclear H
end; intros.
Inductive
Plist : Prop :=
| Pnil : Plist
| Pcons : Prop -> Plist -> Plist.
Ltac
build_imp Pl C :=
match Pl with
| Pnil => constr:C
| Pcons ?A ?Pl' =>
let C' := constr:(A->C) in
build_imp Pl' C'
end.
Inductive
PPlProd : Prop :=
| PPlPair : Plist -> Prop -> PPlProd.
Ltac
elim_aT Pl T :=
match T with
| ?A /\ ?B =>
let A' := elim_aT Pl A in
let B' := elim_aT Pl B in
constr:(A' /\ B')
| ?A => build_imp Pl T
end.
Ltac
elim_iaT Pl T :=
match T with
| (?B /\ ?C) =>
let P := elim_aT Pl T in
constr:(PPlPair Pl P)
| (?A -> ?D) =>
let Pl' := constr:(Pcons A Pl) in
elim_iaT Pl' D
end.
Ltac
splitAndH H :=
match type of H with
| ?A /\ ?B =>
case H;clear H;
let H1 := fresh "H" in
let H2 := fresh "H" in
(intros H1 H2; splitAndH H1; splitAndH H2)
| _ => idtac
end.
Ltac
introPl Pl H :=
match Pl with
| Pnil => splitAndH H
| Pcons _ ?pl =>
let H1 := fresh "H" in
let H2 := fresh "H" in
(intro H1;assert (H2:= H H1);introPl pl H2)
end.
Ltac
splitAnd :=
match goal with
| [|- ?A /\ ?B] => split;splitAnd
| _ => idtac
end.
Ltac
elimAnd :=
match goal with
| [H : ? A /\ ?B |- _ ] =>
case H;clear H;
let H1 := fresh "H" in
let H2 := fresh "H" in
intros H1 H2; elimAnd
| [H : ?HT|- _ ] =>
let pair := elim_iaT Pnil HT in
match pair with
| PPlPair ?Pl ?newT =>
assert newT;
[splitAnd; introPl Pl H;trivial
| clear H;elimAnd]
end
| [H: _ |- _ ] => genclear H;elimAnd
| _ => intros; repeat match goal with [H: _ |- _ /\ _] => split end
end.
SolveIncSolveInc was once used to solve trivial incrementations and some arithmetic stuff; it is a bit like a light j_omega |
Lemma
j_le_inc_sup : forall n m v, (Zle 0 n) -> (j_le m v) -> (j_le m (j_add v n)).
unfold j_le, j_add in *; intros.
replace m with (((m - n)+ n)%Z).
apply Zplus_le_compat_r. assert (((m - n) <= m)%Z).
omega.
apply Zle_trans with m...
omega.
Qed
.
Lemma
j_le_inc_inf : forall m v, (j_lt v m) -> (j_le (j_add v 1) m).
unfold j_le, j_lt, j_add in *; intros.
replace (v + 1)%Z with (Zsucc v). apply Zlt_le_succ...
omega.
Qed
.
Lemma
j_ge_le: forall n m, (j_le m n) -> (j_ge n m).
unfold j_ge, j_le; intros.
apply Zle_ge...
Qed
.
Lemma
j_le_ge: forall n m, (j_ge m n) -> (j_le n m).
unfold j_ge, j_le; intros.
apply Zge_le...
Qed
.
Lemma
j_gt_lt: forall n m, (j_lt m n) -> (j_gt n m).
unfold j_gt, j_lt; intros.
apply Zlt_gt...
Qed
.
Lemma
j_lt_gt: forall n m, (j_gt m n) -> (j_lt n m).
unfold j_gt, j_lt; intros.
apply Zgt_lt...
Qed
.
Lemma
j_not_gt_hyp: forall n m, (~ (j_gt m n)) -> (j_le m n).
unfold j_gt, j_le; intros; apply Znot_gt_le...
Qed
.
Lemma
j_not_gt: forall n m, (j_le m n) -> (~ (j_gt m n)).
unfold j_gt, j_le; intros; apply Zle_not_gt...
Qed
.
Lemma
j_not_ge_hyp: forall n m, (~ (j_ge m n)) -> (j_lt m n).
unfold j_ge, j_lt; intros; apply Znot_ge_lt...
Qed
.
Lemma
j_not_ge: forall n m, (j_lt m n) -> (~ (j_ge m n)).
unfold j_ge, j_lt.
intros n m H1 H2. apply H2. assumption.
Qed
.
Lemma
j_not_lt_hyp: forall n m, (~ (j_lt m n)) -> (j_ge m n).
unfold j_lt, j_ge; intros; apply Znot_lt_ge...
Qed
.
Lemma
j_not_lt: forall n m, (j_ge m n) -> (~ (j_lt m n)).
unfold j_lt, j_ge; intros n m H1 H2; apply H1; assumption.
Qed
.
Lemma
j_not_le_hyp: forall n m, (~ (j_le m n)) -> (j_gt m n).
unfold j_le, j_gt; intros; apply Znot_le_gt...
Qed
.
Lemma
j_not_le: forall n m, (j_gt m n) -> (~ (j_le m n)).
unfold j_le, j_gt; intros n m H1 H2. apply H2. assumption.
Qed
.
Lemma
j_le_dec_sup : forall m v, (j_lt m v) -> (j_le (j_sub v 1) m) -> m = (j_sub v 1).
unfold j_le, j_lt, j_sub in *; intros m v h1 h2.
assert (h3:(v <= m + 1)%Z).
rewrite <- (Zplus_0_r v). rewrite <- (Zplus_opp_l 1). rewrite Zplus_assoc.
apply Zplus_le_compat_r. assumption.
replace (m + 1)%Z with (Zsucc m) in h3.
assert(h4 : (Zsucc m <= v)%Z).
apply Zlt_le_succ...
apply Zle_antisym; omega. omega.
Qed
.
Ltac
solve_hyp f t H m n :=
let H1 := fresh "H" in (assert (H1: f m n) ; [(apply t; assumption; clear H)|clear H]).
Ltac
solveInc :=
repeat match goal with
| [H: (j_lt ?v ?w) |- (j_le (j_add ?v 1) ?w)] => apply j_le_inc_inf;apply H
| [H1: (j_le ?m ?n), H2: j_le ?n ?m |- _] =>
let H := fresh "H" in (assert (H: m = n);
[(apply Zle_antisym; auto; clear H1; clear H2) | (clear H1; clear H2)])
| [H: (j_ge ?n ?m) |- _] => solve_hyp j_le j_le_ge H m n
| [H: _ |- (j_ge ?n ?m)] => apply j_ge_le
| [H: (j_gt ?n ?m) |- _] => solve_hyp j_lt j_lt_gt H m n
| [H: _ |- (j_gt ?n ?m)] => apply j_gt_lt
| [H: ~ (j_gt ?n ?m) |- _] => solve_hyp j_le j_not_gt_hyp H n m
| [H: _ |- ~ (j_gt ?n ?m)] => apply j_not_gt
| [H: ~ (j_ge ?n ?m) |- _] => solve_hyp j_lt j_not_ge_hyp H n m
| [H: _ |- ~ (j_ge ?n ?m)] => apply j_not_ge
| [H: ~ (j_lt ?n ?m) |- _] => solve_hyp j_ge j_not_lt_hyp H n m
| [H: _ |- ~ (j_lt ?n ?m)] => apply j_not_lt
| [H: ~ (j_le ?n ?m) |- _] => solve_hyp j_gt j_not_le_hyp H n m
| [H: _ |- ~ (j_le ?n ?m)] => apply j_not_le
| [H: _ |- j_le ?n ?n] => unfold j_le; apply Zle_refl
end.
elimNorThis tactic is used to remove the not in front of a or (in the hypothesis), turning~ (A \/ B) into (~ A) /\ (~ B) .
|
Definition
distr_or : forall A B, ~ (A \/ B) -> ~ A.
Definition
distr_or_inv : forall A B, ~ (A \/ B) -> ~B.
Ltac
elimNorCons a b := let H1 := fresh "H" in
assert (H1 : ~ (a)); cut (~(a \/ b)) ; auto;
let H2 := fresh "H" in
assert (H2 : ~ (b)); cut (~(a \/ b)); auto.
Ltac
elimNor :=
repeat match goal with
| [H: ~ (?a \/ ?b) |- _ ] => elimNorCons a b; clear H; let H0 := fresh "H" in (let H1 := fresh "H" in (intros H0 H1; clear H0 H1))
end.
overriding; elimIFThese tactics are more for internal use; eliminating overriding constructions and the hypothesis using REFeq and Zeq. |
Ltac
elimREFeq x y :=
let H1 := fresh "H" in
let H2 := fresh "H" in
let H3:= fresh "H" in
(assert (H1:= REFeq_eq x y);
assert (H2:= REFeq_false_not_eq x y);
destruct (REFeq x y);
[assert (H3:= H1 (refl_equal true));clear H1 H2; try (subst x)
| assert (H3:= H2 (refl_equal false));clear H1 H2]).
Ltac
overriding :=
match goal with
| [H : ?a <> ?c |- overridingCoupleRef ?T ?f ?a ?b ?c = ?f ?c] =>
apply overridingCoupleRef_diff; apply H
| [H : ?a = ?c |- overridingCoupleRef ?T ?f ?a ?b ?c = ?b] =>
apply overridingCoupleRef_eq; apply H
| [H : ?a <> ?c |- overridingCoupleZ ?T ?f ?a ?b ?c = ?f ?c] =>
apply overridingCoupleZ_diff; apply H
| [H : ?a = ?c |- overridingCoupleZ ?T ?f ?a ?b ?c = ?b] =>
apply overridingCoupleZ_eq; apply H
end.
Ltac
EQ_is_eq :=
repeat match goal with
| [H : REFeq ?x ?y = true |- _ ] =>
let H1 := fresh "H" in
(assert (H1:= REFeq_eq x y H);clear H)
| [H : REFeq ?x ?y = false |- _ ] =>
let H1 := fresh "H" in
(assert (H1:= REFeq_false_not_eq x y H); clear H)
| [H : Zeq ?x ?y = true |- _ ] =>
let H1 := fresh "H" in
(assert (H1:= Zeq_eq x y H);clear H)
| [H : Zeq ?x ?y = false |- _ ] =>
let H1 := fresh "H" in
(assert (H1:= Zeq_false_not_eq x y H); clear H)
end.
Ltac
generalize_all x :=
match goal with
| [H : context [x] |- _ ] => generalize H;clear H; generalize_all x
| _ => idtac
end.
Ltac
gendestruct x :=
generalize_all x;
generalize (refl_equal x);
pattern x at -1;
case x.
Ltac
elimIF :=
repeat match goal with
| [H : context [REFeq ?x ?x] |- _ ] => rewrite (REFeq_refl x) in H
| [H1 : REFeq ?x ?y = false, H2 : context [if (REFeq ?x ?y) then _ else _] |- _] =>
rewrite H1 in H2
| [H1 : REFeq ?x ?y = true, H2 : context [if (REFeq ?x ?y) then _ else _] |- _] =>
rewrite H1 in H2
| [H : context [Zeq ?x ?x] |- _ ] => rewrite (Zeq_refl x) in H
| [H1 : Zeq ?x ?y = false, H2 : context [if (Zeq ?x ?y) then _ else _] |- _] =>
rewrite H1 in H2
| [H1 : Zeq ?x ?y = true, H2 : context [if (Zeq ?x ?y) then _ else _] |- _] =>
rewrite H1 in H2
| [H : context [if ?b then _ else _ ]|- _] => gendestruct b;intros
| [|- context [if ?b then _ else _]] => gendestruct b;intros
end;EQ_is_eq;subst.
Array ThingsOld Tactics used in the tactic arrtac. |
Ltac
unfoldRefArrAx array pos := let H:= fresh "H" in (assert(H:= refelementsDom (refelements array pos) array pos);
let H1 := fresh "H" in (assert (H1 : refelements array pos = null \/ instances (refelements array pos));
[apply H; trivial | clear H])).
Ltac
unfoldArrayTypeAx arr := match goal with
[H: (subtypes (typeof ?arr) (array (class ?c) ?n)) |- _] =>
let H1:= fresh "H" in (assert(H1:= ArrayTypeAx arr c n);
let H2 := fresh "H" in (assert (H2:= H1 H); clear H))
end.
Ltac
solveRefElm := match goal with
| [h : _ |- instances (refelements ?array ?pos)] =>
unfoldRefArrAx array pos
end.
CleansingTo clean up the mess (sometimes). |
Ltac
clean_up :=
repeat match goal with
| [H1: ?a, H2: ?a |- _] => clear H2| [H1: ?a = ?a |- _ ] => clear H1| [H1: ?a < ?b, H2: ?a <= ?b |- _] => clear H2
end.
AbsurdWhen there is a contradiction absurdJack can often solve it. It is mainly used through autoJack. |
Ltac
absurdJack :=
match goal with
| [H : true = false |- _] => inversion H
| [H : false = true |- _] => inversion H
| [H : ?x <> ?x |- _ ] => elim H;trivial
| [H1 : ?x <> ?y, H2 : ?x = ?y |- _] => elim (H1 H2)
| [H: Zpos _ < 0 |- _] => discriminate H
| [H: Zpos _ <= 0 |- _]=> elim H;trivial
| [H : subtypes _ _ |- _ ] => simpl in H; match type of H with False => elim H end
| [H1 : arraylength ?x = _, H2 : context [j_sub (arraylength ?x) _] |- _] =>
rewrite H1 in H2;simpl in H2;absurdJack
| [H : ?x -> subtypes _ _ |- _ ] =>
simpl in H;
match type of H with _ -> False => elim H; auto end
| _ => try discriminate
end.
Ltac
absurdJackTougher :=
match goal with
| [H : ?x -> subtypes _ _ |- _ ] =>
simpl in H;
match type of H with _ -> False => elim H; auto end
| _ => idtac
end.
Some Macrosj_omegait is used for arithmetic solving on java types.solveOverit is used to simplify overriding constructions. |
Ltac
j_omega := try (unfold j_le, j_add, j_mul, j_lt, j_sub in *; omega).
Ltac
solveOver :=
unfold overridingCoupleZ, overridingCoupleRef in *; elimIF.
Ltac
autoJack :=
auto;
try overriding;
try absurdJack;
try (solveOver;auto;absurdJack).
Ltac
tryApply :=
match goal with
| [ H : _ |- _ ] => ((intros;apply H;autoJack) || (generalize H;clear H;tryApply))
| _ => intros
end.
Ltac
Folie := do 2 (elimIF; tryApply; autoJack; intuition; autoJack).
Ltac
lightStartJack := intros; unfold singleton, union, functionEquals, interval in *; elimAnd; elimNor.
Ltac
lightAutoJack := lightStartJack; autoJack; try j_omega.
Ltac
toughAutoJack := lightStartJack; Folie.
Ltac
startJack := lightStartJack; solveInc; clean_up.
destrJltUsed to destruct loops: when you havei <= b and you want to have two cases:
i < b and i = b .
|
Ltac
destrJlt n :=
let H := fresh "H" in (assert (H: n); [j_omega | idtac]; destruct (j_le_lt_or_eq _ _ H); auto).
Ltac
arrlen :=
eapply arraylenAx; eauto.
Ltac
arrtype := eapply ArrayTypeAx; eauto.
Ltac
arrelm := solveRefElm; autoJack.
Ltac
find_subtype_array t T :=
match T with
| subtypes (typeof t) (array _ _) => constr:T
| ?A -> ?B => find_subtype_array t B
end.
Ltac
assertsubtypes_array t :=
match goal with
| [H: ?T |- _] =>
match find_subtype_array t T with
| ?res => assert (res); [apply H | intros;arrlen]
end
end.
Ltac
le_arraylength :=
match goal with
| [|- 0 <= arraylength ?t] =>
assertsubtypes_array t
end.
Ltac
array_tac :=
match goal with
| [|- instances (refelements _ _)] => arrelm
| [|- subtypes (typeof (refelements _ _)) _] => arrtype
| [|- 0 <= arraylength ?t] =>
assertsubtypes_array t; try array_tac
| _ => idtac
end.
Ltac
arrtac := array_tac.