(* Submitted by Pierre Crégut *) (* Checks substitution of x *) Ltac f x := unfold x; idtac.
Lemma lem1 : 0 + 0 = 0.
f plus. reflexivity. Qed.
(* Submitted by Pierre Crégut *) (* Check syntactic correctness *) Ltac F x := idtac; G x with G y := idtac; F y.
(* Check that Match Context keeps a closure *) Ltac U := let a := constr:(I) in matchgoalwith
| |- _ => apply a end.
Lemma lem2 : True.
U. Qed.
(* Check that Match giving non-tactic arguments are evaluated at Let-time *)
Ltac B := let y := (matchgoalwith
| z:_ |- _ => z end) in
(intro H1; exact y).
Lemma lem3 : True -> False -> True -> False. intros H H0.
B. (* y is H0 if at let-time, H1 otherwise *) Qed.
(* Checks the matching order of hypotheses *) Ltac Y := matchgoalwith
| x:_,y:_ |- _ => apply x end. Ltac Z := matchgoalwith
| y:_,x:_ |- _ => apply x end.
Lemma lem4 : (True -> False) -> (False -> False) -> False. intros H H0.
Z. (* Apply H0 *)
Y. (* Apply H *) exact I. Qed.
(* Check context binding *) Ltac sym t := match constr:(t) with
| context C[(?X1 = ?X2)] => context C [X1 = X2] end.
Lemma sym : 0 <> 1 -> 1 <> 0. intro H. let t := sym type of H in assert t. exact H. intro H1. apply H. symmetry .
assumption. Qed.
(* Check context binding in match goal *) (* This wasn't working in V8.0pl1, as the list of matched hyps wasn't empty *) Ltac sym' := matchgoalwith
| _:True |- context C[(?X1 = ?X2)] => let t := context C [X2 = X1] in assert t end.
Lemma sym' : True -> 0 <> 1 -> 1 <> 0. intros Ht H.
sym'. exact H. intro H1. apply H. symmetry .
assumption. Qed.
(* Check that fails abort the current match context *) Lemmadecide : True \/ False. matchgoalwith
| _ => fail 1
| _ => right end || left. exact I. Qed.
(* Check that "match c with" backtracks on subterms *) Lemmarefl : 1 = 1. let t :=
(match constr:(1 = 2) with
| context [(S ?X1)] => constr:(refl_equal X1:1 = 1) end) in assert (H := t).
assumption. Qed.
(* Note that backtracking in "match c with" is only on type-checking not on evaluationoftactics.E.g.,thisdoesnotwork
Tactic Notation"pat" hyp(id) "occs" integer_list(l) := pattern id at l.
Goalforall x, x=0 -> x=x. intro x.
pat x occs 13. Abort.
Tactic Notation"revert" ne_hyp_list(l) := generalize l; clear l.
Goalforall a b c, a=0 -> b=c+a. intros.
revert a b c H. Abort.
(* Used to fail until revision 9280 because of a parasitic App node with
empty args *)
Goal True. match constr:(@None) with @None => exact I end. Abort.
(* Check second-order pattern unification *)
Ltac to_exist := matchgoalwith
|- forall x y, @?P x y => let Q := eval lazy beta in (exists x, forall y, P x y) in assert (Q->Q) end.
Goalforall x y : nat, x = y.
to_exist. exact (fun H => H). Abort.
(* Used to fail in V8.1 *)
Tactic Notation"test" constr(t) integer(n) := set (k := t) at n.
Goalforall x : nat, x = 1 -> x + x + x = 3. intros x H.
test x 2. Abort.
(* Utilisation de let rec sans arguments *)
Ltac is := let rec i := matchgoalwith |- ?A -> ?B => intro; i | _ => idtacend in
i.
Goal True -> True -> True.
is. exact I. Abort.
(* Interférence entre espaces des noms *)
Ltac O := intro. Ltac Z1 t := set (x:=t). Ltac Z2 t := t. Goal True -> True.
Z1 O.
Z2 ltac:(O). exact I. Qed.
(* Illegal application used to make Ltac loop. *)
Section LtacLoopTest. Ltac g x := idtac. Goal True.
Timeout 1try g()(). Abort. End LtacLoopTest.
(* Test binding of open terms *)
Ltac test_open_match z := match z with
(forall y x, ?h = 0) => assert (forall x y, h = x + y) end.
Goal True.
test_open_match (forall z y, y + z = 0). reflexivity. apply I. Qed.
(* Test binding of open terms with non linear matching *)
Ltac f_non_linear t := match t with
(forall x y, ?u = 0) -> (forall y x, ?u = 0) => assert (forall x y:nat, u = u) end.
Goal True.
f_non_linear ((forall x y, x+y = 0) -> (forall x y, y+x = 0)). reflexivity.
f_non_linear ((forall a b, a+b = 0) -> (forall a b, b+a = 0)). reflexivity.
f_non_linear ((forall a b, a+b = 0) -> (forall x y, y+x = 0)). reflexivity.
f_non_linear ((forall x y, x+y = 0) -> (forall a b, b+a = 0)). reflexivity.
f_non_linear ((forall x y, x+y = 0) -> (forall y x, x+y = 0)). reflexivity.
f_non_linear ((forall x y, x+y = 0) -> (forall y x, y+x = 0)) (* should fail *)
|| exact I. Qed.
(* Test regular failure when clear/intro breaks soundness of the
interpretation of terms in current environment *)
Ltac g y := clear y; assert (y=y). Goalforall x:nat, True. intro x.
Fail g x. Abort.
Ltac h y := assert (y=y). Goalforall x:nat, True. intro x.
Fail clear x; f x. Abort.
(* Do not consider evars as unification holes in Ltac matching (and at leastnotasholesunrelatedtotheoriginalevars) [ExampleadaptedfromYnotcode]
*)
Ltac not_eq e1 e2 := match e1 with
| e2 => fail 1
| _ => idtac end.
Goal True.
evar(foo:nat). let evval := evalcompute in foo in not_eq evval 1. let evval := evalcompute in foo in not_eq 1 evval. Abort.
(* Check instantiation of binders using ltac names *)
Goal True. let x := ipattern:(y) in assert (forall x y, x = y + 0). intro. destruct y. (* Check that the name is y here *) Abort.
(* An example suggested by Jason (see #4317) showing the intended semantics *) (* Order of binders is reverted because y is just told to depend on x *)
Goal1=1. let T := constr:(fun a b : nat => a) in
lazymatch T with
| (fun x z => ?y) => pose ((fun x x => y) 21) end. exact (eq_refl n). Qed.
(* A variant of #2602 which was wrongly succeeding because "a", bound to
"?m", was then internally turned into a "_" in the second matching *)
Goalexists m, S m > 0.
eexists.
Fail matchgoalwith
| |- context [ S ?a ] => matchgoalwith
| |- S a > a => idtac end end. Abort.
(* Test evar syntax *)
Goal True.
evar (0=0). Abort.
(* Test location of hypothesis in "symmetry in H". This was broken in 8.6whereH,whentheoldesthyp,wasmovedattheplaceofmost
recent hypothesis *)
Goal0=1 -> True -> True. intros H H0. symmetry in H. (* H should be the first hypothesis *) matchgoalwith h:_ |- _ => assert (h=h) end. (* h should be H0 *) exact (eq_refl H0). Abort.
(* Check that internal names used in "match" compilation to push "term
to match" on the environment are not interpreted as ltac variables *)
Module ToMatchNames. Ltac g c := let r := constr:(match c return _ with a => 1end) in idtac. Goal True.
g 1. Abort. End ToMatchNames.
(* An example where internal names used to build the return predicate (here"n"because"a"isboundto"nil"and"n"isthefirstletter
of "nil") by small inversion should be taken distinct from Ltac names. *)
Module LtacNames. Inductive t (A : Type) : nat -> Type :=
nil : t A 0 | cons : A -> forall n : nat, t A n -> t A (S n).
Ltac f a n := let x := constr:(match a with nil _ => true | cons _ _ _ _ => I end) in assert (x=x/\n=n).
Goalforall (y:t nat 0), True. intros.
f y true. Abort.
End LtacNames.
(* Test binding of the name of existential variables in Ltac *)
Module EvarNames.
Ltac pick x := eexists ?[x]. Goalexists y, y = 0.
pick foo.
[foo]:exact0. auto. Qed.
Ltacgoal x := refine ?[x].
Goalforall n, n + 0 = n. Proof. induction n; [ goal Base | goal Rec ].
[Base]: {
easy.
}
[Rec]: { simpl. now f_equal.
} Qed.
Section S. Variable f : False.
Fail GlobalLtac thetac' ::= exact f. Ltac thetac' ::= exact f. Goal False. Proof. thetac'. Qed. End S. Goal False. Proof.
thetac'.
Fail Qed. Abort. End LocalRedef.
Module MatchCastInPattern.
Goallet x := True in True. Proof. intro x.
lazymatch goalwith
| [ H := ?v : ?T |- _ ] => constr_eq T Prop end.
Fail lazymatch goalwith
| [ H := ?v <: ?T |- _ ] => constr_eq T Prop end. (* Warning: Casts are ignored in patterns [cast-in-pattern,automation] *)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.