diff --git a/theories/gmultiset.v b/theories/gmultiset.v index 1b4a156809fef2675ab475bb430c2b1388add631..a6782d0efbfafb590d3fcaaccec30f105cf7ef82 100644 --- a/theories/gmultiset.v +++ b/theories/gmultiset.v @@ -254,19 +254,10 @@ Ltac multiset_instantiate := let e := fresh in evar (e:A); let e' := eval unfold e in e in clear e; lazymatch constr:(P e') with - | context [ {[ ?y ]} ] => - (* Use [unless] to avoid creating a new hypothesis [H y : P y] if [P y] - already exists. *) - unify y e'; unless (P y) by assumption; pose proof (H y) + | context [ {[ ?y ]} ] => unify y e'; learn_hyp (H y) end - | H : (∀ x : ?A, @?P x), _ : context [multiplicity ?y _] |- _ => - (* Use [unless] to avoid creating a new hypothesis [H y : P y] if [P y] - already exists. *) - unless (P y) by assumption; pose proof (H y) - | H : (∀ x : ?A, @?P x) |- context [multiplicity ?y _] => - (* Use [unless] to avoid creating a new hypothesis [H y : P y] if [P y] - already exists. *) - unless (P y) by assumption; pose proof (H y) + | H : (∀ x : ?A, _), _ : context [multiplicity ?y _] |- _ => learn_hyp (H y) + | H : (∀ x : ?A, _) |- context [multiplicity ?y _] => learn_hyp (H y) end. (** Step 4: simplify singletons *) diff --git a/theories/tactics.v b/theories/tactics.v index f7bd6468da050c2ecd803a24a408c2b70675177b..39543e5f097147d56fba9df46c77d4ee212dd6f0 100644 --- a/theories/tactics.v +++ b/theories/tactics.v @@ -525,6 +525,18 @@ Definition block {A : Type} (a : A) := a. Ltac block_goal := match goal with [ |- ?T ] => change (block T) end. Ltac unblock_goal := unfold block in *. +(** [learn_hyp p as H] and [learn_hyp p], where [p] is a proof of [P], +add [P] to the context and fail if [P] already exists in the context. +This is a simple form of the learning pattern. These tactics are +inspired by [Program.Tactics.add_hypothesis]. *) +Tactic Notation "learn_hyp" constr(p) "as" ident(H') := + let P := type of p in + match goal with + | H : P |- _ => fail 1 + | _ => pose proof p as H' + end. +Tactic Notation "learn_hyp" constr(p) := + let H := fresh in learn_hyp p as H. (** The tactic [select pat tac] finds the last (i.e., bottommost) hypothesis matching [pat] and passes it to the continuation [tac]. Its main advantage over