4

I am having trouble understanding the difference between an equality and a local definition. For example, when reading the documentation about the set tactic:

remember term as ident

This behaves as set ( ident := term ) in * and using a logical (Leibniz’s) equality instead of a local definition

Indeed,

  1. set (ca := c + a) in *. e.g. generates ca := c + a : Z in the context, while

  2. remember (c + a ) as ca. generates Heqca : ca = c + a in the context.

In case 2. I can make use of the generated hypothesis like rewrite Heqca., while in case 1., I cannot use rewrite ca.

What's the purpose of case 1. and how is it different from case 2. in terms of practical usage?

Also, if the difference between the two is fundamental, why is remember described as a variant of set in the documentation (8.5p1)?

thor
  • 21,418
  • 31
  • 87
  • 173

2 Answers2

2

You could think of set a := b + b in H as rewriting H to be:

(fun a => H[b+b/a]) (b+b)

or

let a := b + b in
H[b+b/a]

That is, it replaces all matched patterns b+b by a fresh variable a, which is then instantiated to the value of the pattern. In this regard, both H and the rewrited hypotheses remain equal by "conversion".

Indeed, remember is in a sense a variant of set, however its implications are very different. In this case, remember will introduce a new proof of equality eq_refl: b + b = b + b, then it will abstract away the left part. This is convenient for having enough freedom in pattern matching etc... This is remember in terms of more atomic tactics:

Lemma U b c : b + b = c + c.
Proof.
assert (b + b = b + b). reflexivity.
revert H.
generalize (b+b) at 1 3.
intros n H.
ejgallego
  • 6,709
  • 1
  • 14
  • 29
2

In addition to @ejgallego's answer.

Yes, you cannot rewrite a (local) definition, but you can unfold it:

set (ca := c + a) in *.    
unfold ca. 

As for the differences in their practical use -- they are quite different. For example, see this answer by @eponier. It relies on the remember tactic so that induction works as we'd like to. But, if we replace remember with set it fails:

Inductive good : nat -> Prop :=
  | g1 : good 1
  | g3 : forall n, good n -> good (n * 3)
  | g5 : forall n, good n -> good (n + 5).

Require Import Omega.

The variant with remember works:

Goal ~ good 0.
  remember 0 as n.
  intro contra. induction contra; try omega.
  apply IHcontra; omega.
Qed.

and the variant with set doesn't (because we didn't introduce any free variables to work with):

Goal ~ good 0.
  set (n := 0). intro contra.
  induction contra; try omega.
  Fail apply IHcontra; omega.
Abort.
Community
  • 1
  • 1
Anton Trunov
  • 15,074
  • 2
  • 23
  • 43