Search code examples
coqcoq-tactic

How does elim work in Coq on /\ and \/?


In Coq Tutorial, section 1.3.1 and 1.3.2, there are two elim applications: The first one:

1 subgoal

  A : Prop
  B : Prop
  C : Prop
  H : A /\ B
  ============================
   B /\ A

after applying elim H,

Coq < elim H.
1 subgoal

  A : Prop
  B : Prop
  C : Prop
  H : A /\ B
  ============================
   A -> B -> B /\ A

The second one:

1 subgoal

  H : A \/ B
  ============================
   B \/ A

After applying elim H,

Coq < elim H.
2 subgoals

  H : A \/ B
  ============================
   A -> B \/ A

subgoal 2 is:
 B -> B \/ A

There are three questions. First, in the second example, I don't understand what inference rule (or, logical identity) is applied to the goal to generate the two subgoals. It is clear to me for the first example, though.

The second question, according to the manual of Coq, elim is related to inductive types. Therefore, it appears that elim cannot be applied here at all, because I feel that there are no inductive types in the two examples (forgive me for not knowing the definition of inductive types). Why can elim be applied here?

Third, what does elim do in general? The two examples here don't show a common pattern for elim. The official manual seems to be designed for very advanced users, since they define a term upon several other terms that are defined by even more terms, and their language is ambiguous.

Thank you so much for answering!


Solution

  • Jian, first let me note that the manual is open source and available at https://github.com/coq/coq ; if you feel that the wording / definition order could be improved please open an issue there or feel free to submit a pull request.

    Regarding your questions, I think you would benefit from reading some more comprehensive introduction to Coq such as "Coq'art", "Software Foundations" or "Programs and Proofs" among others.

    In particular, the elim tactic tries to apply the so called "elimination principle" for a particular type. It is called elimination because in a sense, the rule allows you to "get rid" of that particular object, allowing you to continue on the proof [I recommend reading Dummett for a more throughout discussion of the origins of logical connectives]

    In particular, the elimination rule for the ∨ connective is usually written by logicians as follows:

              A   B
              ⋮  ⋮
     A ∨ B    C   C
    ────────────────
           C
    

    that is to say, if we can derive C independently from A and B, then we can derive it from A ∨ B. This looks obvious, doesn't it?

    Going back to Coq, it turns out that this rule has a computational interpretation thanks to the "Curry-Howard-Kolmogorov" equivalence. In fact, Coq doesn't provide most of the standard logical connectives as a built in, but it allow us to define them by means of "Inductive" datatypes, similar to those in Haskell or OCaml.

    In particular, the definition of ∨ is:

    Inductive or (A B : Prop) : Prop :=
      | or_introl : A -> A \/ B
      | or_intror : B -> A \/ B
    

    that is to say, or A B is the piece of data that either contains an A or a B, together with a "tag", that allows us to "match" to know which one do we really have.

    Now, the "elimination principle for or" has type:

    or_ind : forall A B P : Prop, (A -> P) -> (B -> P) -> A \/ B -> P
    

    The great thing of Coq is that such principle is not a "built-in", just a regular program! Think, could you write the code of the or_ind function? I'll give you a hint:

    Definition or_ind A B P (hA : A -> P) (hB : B -> P) (orW : A ‌\/ B) :=
      match orW with
      | or_introl aW => ?
      | or_intror bW => ?
      end.
    

    Once this function is defined, all that elim does, is to apply it, properly instantiating the variable P.

    Exercise: solve your second example using apply and ord_ind instead of elim. Good luck!