coqltac

Can the injection tactic modify the end goal, or add extraneous assumptions?


Consider the following development, an isolated part of Adam Chlipala's simplHyp:

(** Fail if H is in context *)
Ltac notInCtx H := assert H; [ assumption | fail 1 ] || idtac.

Ltac injectionInCtx :=
  match goal with
  (* Is matching on G strictly necessary? *)
  | [ H : ?F ?X = ?F ?Y |- ?G ] =>
    (* fail early if it wouldn't progress *)
    notInCtx (X = Y); 
    injection H;
    match goal with
      (* G is used here *)
      | [ |- X = Y -> G ] =>
        try clear H; intros; try subst
    end
  end.

Goal forall (x y : nat), S x = S y -> x = y.
  intros x y H.
  injectionInCtx.
  exact eq_refl.
Qed.

See the comments inline - G is matched at the outset, and eventually used to verify that the end goal remains the same. Is this to preclude the possibility that injection H might modify the goal or add extraneous assumptions?


Solution

  • I do not think you can modify G, but you can craft an hypothesis from which injection will generate more than one equality.

    We define injectionInCtx2 which is identical to injectionInCtx except that it does not use G.

    Ltac injectionInCtx2 :=
      match goal with
      | [ H : ?F ?X = ?F ?Y |- _ ] =>
        (* fail early if it wouldn't progress *)
        notInCtx (X = Y);
        injection H;
        match goal with
        | [ |- X = Y -> _ ] =>
          try clear H; intros; try subst
        end
      end.
    
    Definition make_pair {A} (n:A) := (n, n).
    
    Goal forall (x y : nat), make_pair x = make_pair y -> x = y.
    Proof.
      intros x y H.
      (* [injection H] gives [x = y -> x = y -> x = y] *)
      Fail injectionInCtx.
      injectionInCtx2.
      reflexivity.
    Qed.