Coq how to pretty-print a term constructed using tactics?
I'm new to Coq and am doing some exercises to get more familiar with it. My understanding is that proving a proposition in Coq "really" is writing down a type in Gallina and then showing that it's inhabited using tactics to combine terms together in deterministic ways. I'm wondering if there's a way to get a pretty-printed representation of the actual term, with all the tactics removed. In the example below, an anonymous term of type plus_comm (x y : N) : plus x y = plus y x is ultimately produced... I think. What should I do if I want to look at it? In a certain sense, I'm curious what the tactics "desugar" to. Here's the code in question, lifted essentially verbatim from a tutorial on YouTube https://www.youtube.com/watch?v=OaIn7g8BAIc. Inductive N : Type := | O : N | S : N -> N . Fixpoint plus (x y : N) : N := match x with | O => y | S x' => S (plus x' y) end. Lemma plus_0 (x : N) : plus x O = x. Proof. induction x. - simpl. reflexivity. - simpl. rewrite IHx. reflexivity. Qed. Lemma plus_S (x y : N) : plus x (S y) = S(plus x y). Proof. induction x. - simpl. reflexivity. - simpl. rewrite IHx. reflexivity. Qed. Lemma plus_comm (x y : N) : plus x y = plus y x. Proof. induction x. - simpl. rewrite plus_0. reflexivity. - simpl. rewrite IHx. rewrite plus_S. reflexivity. Qed.
First of all, plus_comm is not a part of the type. You get a term named plus_comm of type forall x y : N, plus x y = plus y x. You can check it using the following command Check plus_comm. So, an alternative way of defining the plus_comm lemma is Lemma plus_comm : forall x y : N, plus x y = plus y x. As a side note: in this case you'll need to add intros x y. (or just intros.) after the Proof. part. Tactics (and the means to glue them together) are a metalanguage called Ltac, because they are used to produce terms of another language, called Gallina, which is the specification language of Coq. For example, forall x y : N, plus x y = plus y x is an instance of Gallina sentence as well as the body of the plus function. To obtain the term attached to plus_comm use the Print command: Print plus_comm. plus_comm = fun x y : N => N_ind (fun x0 : N => plus x0 y = plus y x0) (eq_ind_r (fun n : N => y = n) eq_refl (plus_0 y)) (fun (x0 : N) (IHx : plus x0 y = plus y x0) => eq_ind_r (fun n : N => S n = plus y (S x0)) (eq_ind_r (fun n : N => S (plus y x0) = n) eq_refl (plus_S y x0)) IHx) x : forall x y : N, plus x y = plus y x It is not an easy read, but with some experience you'll be able to understand it. Incidentally, here is how we could have proved the lemma not using tactics: Definition plus_comm : forall x y : N, plus x y = plus y x := fix IH (x y : N) := match x return plus x y = plus y x with | O => eq_sym (plus_0 y) | S x => eq_ind _ (fun p => S p = plus y (S x)) (eq_sym (plus_S y x)) _ (eq_sym (IH x y)) end. To explain a few things: fix is the means of defining recursive functions, eq_sym is used to change x = y into y = x, and eq_ind corresponds to the rewrite tactic.
How to print all the defined symbols in Coq?
How can we use relational definition in proofs in Coq?
Stuck on a simple proof about regular expressions
How to prove the arithmetic equality `3 * S (i + j) + 1 = S (3 * i + 1) + S (3 * j + 1)` in Coq?
How to apply a rewrite to the right side of a conditional without splitting on it?
All-quantified type variable in (value) constructor cannot be explicitly typed as wanted
Coq: Remove all (nested) parentheses from a sum
How to prove binary commutavity with a different definition of bin?
Coq's mathematical proof language: Rewriting in if condition
Unfolding a proof term in Coq
Is it possible to rewrite the silly2 example from the Tactics chapter of the SF book using 'rewrite' instead of 'apply'?
How do Structures with Inheritance (:>) work in Coq?
How to understand Setoid definition of category?
Compatibility of impredicative Set and function extensionality
Combining two Coq hypotheses
Relationship between existential and universal quantifier in an inductive Coq definition