1

Using this definition of a group:

Structure group :=
  {
    G :> Set;

    id : G;
    op : G -> G -> G;
    inv : G -> G;

    op_assoc_def : forall (x y z : G), op x (op y z) = op (op x y) z;
    op_inv_l : forall (x : G), id = op (inv x) x;
    op_id_l : forall (x : G), x = op id x
  }.

(** Set implicit arguments *)
Arguments id {g}.
Arguments op {g} _ _.
Arguments inv {g} _.

Notation "x # y" := (op x y) (at level 50, left associativity).

And having proven this theorem:

Theorem mult_both_sides (G : group) : forall (a b c : G),
    a = b <-> c # a = c # b.

How do I write an Ltac that automates the process of left multiplying a given equality (either the goal itself or a hypothesis) by a given term?

Ideally, using this Ltac in a proof would look like this:

left_mult (arbitrary expression).
left_mult (arbitrary expression) in (hypothesis).
ekad
  • 14,436
  • 26
  • 44
  • 46

2 Answers2

2

Building on the answer given by larsr, you can use Tactic Notations to write

Tactic Notation "left_mult" uconstr(arbitrary_expression) :=
  apply (mult_both_sides _ _ _ arbitrary_expression).
Tactic Notation "left_mult" uconstr(arbitrary_expression) "in" hyp(hypothesis) :=
  apply (mult_both_sides _ _ _ arbitrary_expression) in hypothesis.

Using uconstr says "delay typechecking of this term until we plug it into apply". (Other options include constr ("typecheck this at the call site") and open_constr ("typecheck this at the call site and fill in holes with evars").)

Jason Gross
  • 5,928
  • 1
  • 26
  • 53
1

Do you really need a specific tactic for this? If you just use apply to this

Goal forall (G:group) (a b c: G), a = b.
  intros.
  apply (mult_both_sides _ _ _ c).

Now your goal is

  G0 : group
  a, b, c : G0
  ============================
  c # a = c # b

If you want to modify a hypothesis H, then just do apply ... in H.

larsr
  • 5,447
  • 19
  • 38
  • 2
    And declare `G`, `a` and `b` as implicit parameters, so that you do not need to type the 3 underscores. – eponier Jan 29 '18 at 14:08
  • That seems to do what I needed. However, I still would like to know how to make a tactic that uses the "in" keyword in the way that the "rewrite" or "apply" tactics do. – firstname gklsodascb Jan 30 '18 at 01:46