Coq: How are the equality tacticts symmetry and transitivity defined? - coq

I'm interested in how the Coq tactics symmetry and transitivity actually work. I've read the Coq manual but this only describes what they do, not how they operate on a proof and change the proof states. As an example of what I'm looking for, in Interactive Theorem Proving and Program Development, the authors state that
"The reflexivity tactic actually is synonymous with apply refl_equal" (p. 124).
But, the author refers the reader to the reference manual for symmetry and transitivity. I haven't found a good description of things that these two tactics are synonymous with in the same way.
For clarification, the reason why I ask is that I have defined a path space paths {A : UU} : A -> A -> UU notated a = b (like in UniMath) which acts like an equivalence relation except for that a = b is not a proposition but a type. For this reason I was unable to add this relation as an equivalence relation using Add Parametric Relation. I'm trying to cook up a version of symmetry and transitivity with Ltac for this path space relation but I don't know how to change the proof state; knowing how symmetry and transitivity actually work might help.

These tactics only apply the lemmas corresponding to symmetry and transitivity of the relation it finds in the goal.
These are found using the type classes mechanism.
For instance you could declare
From Coq Require Import RelationClasses.
Instance trans : Transitive R.
which would ask you to prove R is transitive and then you would be able to use the tactic transitivity to prove R x y.

Related

Why does this coq program not run?

I'm a beginner of Coq and learning how to make codes with video https://www.youtube.com/watch?v=oJm5TH0GdSo&list=PLt7hcIEdZLAnCoZePG60qgVP4ddP0s3WZ&index=2 .
I made a program following that video (one that starts from almost 29 minutes in video) but it doesn't run as I expected. Could you please tell me why does that happen? I always get stuck in Case.
Program I made is given below:
Theorem shugouonajidesho :
forall P Q : Prop,
P/\Q->Q/\P.
Proof.
intros P Q H. split.
Case "Q".
inversion H as [HP HQ]. imply HQ.
Case "P". inversion H as {HP HQ]. imply HP.
Qed.
There are three problems in your proof, but they're mostly syntactic.
The Case "Q" and Case "P" syntax comes from Software Foundations. You'd need to import some particular library to be able to use it. If you don't want to do that, it's not necessary. To focus goals, you can use bullets (typically -, + or *). There are other ways too, but this is the most typical.
The imply tactic doesn't exist (at least in the standard library). The way you're using it, though, makes me think that you meant apply.
In inversion H as {HP HQ]., both brackets should be square brackets.
Making those changes allows the theorem to work, but I'd also suggest a few changes for idiomaticity.
Using inversion is probably overkill here. All you're doing is destructing a conjunction into its parts, so destruct H as [HP HQ]. would work just as well.
I would also highly recommend separating your proof with line breaks, rather than just putting everything on one line (this might have just been an artifact of how you formatted your question. If so, ignore this). It's fine to put some tactics on the same line, but it should be grouped into logical sections.
Finally, a minor one: I'd suggest putting spaces around ->. It just makes things a little easier to read.
Theorem shugouonajidesho: forall P Q : Prop, P/\Q -> Q/\P.
Proof.
intros P Q H.
split.
- inversion H as [HP HQ].
apply HQ.
- inversion H as [HP HQ].
apply HP.
Qed.

What is the difference between Lemma and Theorem in Coq

I can't tell in which situations I should use Theorem over Lemma or the opposite. Is there any difference (despite syntactical) between this
Theorem l : 2 = 2.
trivial.
Qed.
and this
Lemma l : 2 = 2.
trivial.
Qed.
?
There is no difference between Theorem and Lemma as far as the language is concerned. The reasons to choose one over another are purely psychological.
You can also use Remark, Fact, Corollary, Proposition according to the importance you attribute to the result. Here is the relevant link in the Coq reference manual.
Some projects' code style guides only allow one keyword to be used for uniformity. This might help reading source code and allow using simple grep-like tools to extract some statistics from it.

Ltac position argument for instantiate

The tactic instantiate can take and ident or a num as:
instantiate (ident:= term)
instantiate (num := term)
Now I want to use the second one inside a tactic definition. For example:
Ltac my_instantiate n x:=
instantiate(n:=x).
Unfortunately, this gives the following error:
Ltac variable n is bound to 1 which cannot be coerced to a fresh
identifier.
I suspect that ltac is trying to use the first use of instantiate. How do I tell coq to instantiate by position, or how do I pass the argumetn correctly?
Here is a minimal example:
Ltac my_instantiate n x:=
instantiate(n:=x).
Goal exists x, x = 2.
eexists.
my_instantiate 1 2.
(* Fails with: Ltac variable n is bound to 1 which
cannot be coerced to a fresh identifier. *)
Note: I know that instantiating by position is discouraged, but I'm only using my tactic for exploration purposes.
Maybe what you are looking for can be expressed in terms of a Tactic Notation?
reference manual - tactic notations

What's the difference between Program Fixpoint and Function in Coq?

They seem to serve similar purposes. The one difference I've noticed so far is that while Program Fixpoint will accept a compound measure like {measure (length l1 + length l2) }, Function seems to reject this and will only allow {measure length l1}.
Is Program Fixpoint strictly more powerful than Function, or are they better suited for different use cases?
This may not be a complete list, but it is what I have found so far:
As you already mentioned, Program Fixpoint allows the measure to look at more than one argument.
Function creates a foo_equation lemma that can be used to rewrite calls to foo with its RHS. Very useful to avoid problems like Coq simpl for Program Fixpoint.
In some (simple?) cases, Function can define a foo_ind lemma to perform induction along the structure of recursive calls of foo. Again, very useful to prove things about foo without effectively repeating the termination argument in the proof.
Program Fixpoint can be tricked into supporting nested recursion, see https://stackoverflow.com/a/46859452/946226. This is also why Program Fixpoint can define the Ackermann function when Function cannot.

Mix-up of bool and Datatypes.bool after Require Import Omega

I'm going through software foundations and ran into an error.
ERROR : The term "true" has type "bool" while it is expected to have type "Datatypes.bool"
for the proof below.
Theorem beq_nat_true : forall n m,
beq_nat n m = true -> n = m.
I found out that this is happening when I use Require Import Omega.
Any tips, suggestions or explanations of what Omega introduces into the environment?
The Omega module indirectly imports many definitions of the standard library that manipulate natural numbers, some of which end up shadowing parts of Software Foundations. The beq_nat function is one of them. The problem arises because the version of the standard library for beq_nat returns standard booleans, whereas the one of SF returns its redefined booleans.
We noticed this problem a while ago, and have already fixed it in the current version. If you don't want to redownload everything (or if you have imported Omega yourself), you can also just qualify beq_nat to use the right version. My guess is that Basics.beq_nat should work.