3

This is kind of a follow up on a previous question I asked, but now I'm just trying to implement my own induction principle for the equality type, which I'm not sure how to do without some kind of pattern matching. I'm avoiding using the induction tactic in the below definition, as this obviously leads to a kind of chicken vs. egg conundrum. Is there any possible way to do this with some basic tactics except indction, as well as via the vanilla Definition J2 := ...?

(* define a similair induction principle from this agda code*)
J2 : {A : Set} → (D : (x y : A) → (I A x y) →  Set)
  →  (d : (a : A) → (D a a r )) → (x y : A) → (p : I A x y) → D x y p
J2 D d x .x r = d x
Theorem J2 {A} :
  forall (D : forall (x y : A), Id A x y -> Prop), 
  forall (d : forall (a : A), (D a a (refl A a))),
  forall (x y : A) (p : Id A x y), D x y p.
Proof.
  intros.
  inversion p.
  subst.
  apply D y.

This yields the following error, and I'm not sure how to indicate that p must be a refl without the induction tactic.

1 subgoal (ID 34)

  A : Type
  D : forall x y : A, Id A x y -> Prop
  d : forall a : A, D a a (refl A a)
  y : A
  p : Id A y y
  ============================
  D y y p

Which yields the following error.

Error:
In environment
A : Type
D : forall x y : A, Id A x y -> Prop
d : forall a : A, D a a (refl A a)
y : A
p : Id A y y
Unable to unify "D y y (refl A y)" with "D y y p".

Finally, a somewhat adjoint error, when I try writing apply d in y I get the following error.

Error:
Unable to apply lemma of type "forall a : A, D a a (refl A a)"
on hypothesis of type "A".

Why isn't the typechecker happy?

  • In case you didn't know, you can disable the generation of induction principles with `Unset Elimination Schemes.` – Li-yao Xia Apr 27 '20 at 12:57

2 Answers2

2

Instead of inversion p, use destruct p, which does pattern-matching in a straightforward way.

inversion is only meant to work on assumptions whose proof terms are not used in the goal. Here p is used in the goal.

Li-yao Xia
  • 31,896
  • 2
  • 33
  • 56
  • There's a [`dependent inversion`](https://coq.inria.fr/refman/proof-engine/tactics.html#coq:tacv.dependent-inversion) that might work. But `inversion` is generally a bit of hot mess anyway... – HTNW Apr 27 '20 at 13:01
2

Is there any possible way to do this with some basic tactics except indction, as well as via the vanilla Definition J2 := ...?

Let me answer to the second part of your question:

Inductive Id (A : Type) (x : A) : A -> Type :=
  | refl : Id A x x.

Definition J2 {A} :
  forall
    (D : forall (x y : A), Id A x y -> Prop)
    (d : forall (a : A), (D a a (refl A a)))
    (x y : A) (p : Id A x y),
    D x y p
:=
  fun D d x y p =>
    match p in Id _ _ y
            return D x y p
    with
    | refl _ _ => d x
    end.
Anton Trunov
  • 15,074
  • 2
  • 23
  • 43
  • 1
    As an extra comment to this great answer by @AntonTrunov, one should always remember that tactics are only helper on top of the basic language of the calculus of constructions. So many of the Agda programs have an equivalent in Coq syntax, without using tactics. – Yves Apr 28 '20 at 06:37
  • @Yves are there any publications or resources generally which give a thorough account of the desugaring from tactics to the raw Coc syntax in Coq? For example, how can you view the proof term generated by a proof given via some sequence of tactics. –  Apr 28 '20 at 12:48
  • 1
    While the proof is in progress, you can call the command `Show Proof.` When the proof is over and saved (using `Defined` or `Qed`), you can use `Print *name-of-thm*.` To see the term in the calculus of constructions. – Yves Apr 28 '20 at 16:13