What is the tactic that does nothing? - coq

Sometimes it is useful to have a tactic which does nothing. I've tried to search "empty tactic" or "null tactic" but these do not give me the answer.

The tactic you are looking for is idtac, short for "identity tactic"
Tactic idtac (ident ​| string​ | natural)*
Leaves the proof unchanged and prints the given tokens. Strings and naturals are printed literally. If ident is an Ltac variable, its contents are printed; if not, it is an error. source
You can give idtac arguments, which are useful for debugging.

Related

What does `Control.refine` do in Ltac2?

I'm learning Ltac2 and reading the official documentation of coq 8.13.2.
I do not get what role Control.refine play in the evaluation inside of quotations, as there doesn't seem to be a lot of explanations to this function.
For example, using variables in tactic expressions inside a constr quotation should be done by: constr:(... $x ...), where $x is the syntactic sugar of ltac2:(Control.refine (fun () => x)).
Why does, say simply, ltac2:(x) not work? (and it indeed doesn't, as coq gives an error of Error: Cannot infer an existential variable of type ..., at the position where the constr represented by x should be inserted).
So my questions are:
What does Control.refine do in general?
It seems to be an idiom to sometimes do this: constr:( ... ltac2:(Control.refine (fun () => ...) ...), in what situation where such anti-quotation idiom should (or shouldn't) be used?
Thanks.
The ltac2:(...) in-term quotation expects an Ltac2 term of type unit, not of type constr. Actually, your example should trigger a warning because of this.
Since the content of the quotation has type unit, it means that it can only act through side-effects. The warning tells you that the value returned by the quotation will be discarded. In particular, it cannot be used to fill the hole.
Rather, the semantics of the quotation is to evaluate its content inside a goal Γ ⊢ A where Γ is the current list of hypotheses, and A the inferred type of the hole. It is expected that doing this will solve the goal, and the resulting partial proof will be used as the Coq term filler for that hole. This is precisely the rôle of Control.refine : (unit -> constr) -> unit. It takes a (for technical reasons, thunked) term as an argument and uses it to solve the goal(s) under focus.
What happens in your example is that you provide a term that is just ignored, the goal is left untouched and the quotation rightfully complains that it was not solved.
Regarding your second point, I cannot really tell. It depends on what you want do do. But in general, if you stick to antiquotations $x I would consider this more readable. It is not always possible to do so, though, e.g. if the term being built depends on a context introduced in the constr:(...) quotation.

Finding rewrite rules

I have a hard time finding the available rewrite rules for my situation. As I don't want to bother you with each rewrite question, I was wondering do you have some tips for finding suitable rewrite rules?
Do you have any tips on how to solve and or search for rewriting the following example:
1 subgoal
H: P
H0: Q
__________
R
And say I have Lemma Join: P /\ Q = R
In order to do this rewrite, I suppose I need to get H and H0 first rewritten into P /\ Q.
So how would you solve or find the rewrite rules for such a case?
Another example
H: a <= b
____________
b < a
I am confident there should exists some commutativity rewrite rule for this, but how can I best find this rule?
Many thanks in advance!
First a tip so you don't run into this problem later: Don't confuse equality of types for logical equivalence. What you usually mean in your first example above is that P/\Q <-> R, not that the type P/\Q is definitionally the same type as R.
With regards to your question about finding lemmas in the library; yes, it is very important to be able to find things there. Coq's Search command lets you find all (Required) lemmas that contain a certain pattern somewhere in it, or some particular string. The latter is useful because the library tends to have a somewhat predicable naming scheme, for instance the names for lemmas about decidability often contains then string "dec", commutativity lemmas often are called something with "comm" etc.
Try for example to search for decidability lemmas about integers, i.e. lemmas that have the term Z somewhere inside them, and the name contains the string "dec".
Require Import ZArith.
Search "dec" Z.
Back to your question; in your case you want to find a lemma that ends with "something and something", so you can use the pattern ( _ /\ _ )
Search ( _ /\ _ ).
However, you get awfully many hits, because many lemmas ends with "something and something".
In your particular case, you perhaps want to narrow the search to
Search (?a -> ?b -> ?a /\ ?b).
but be careful when you are using pattern variables, because perhaps the lemma you was looking for had the arguments in the other order.
In this particular case you found the lemma
conj: forall [A B : Prop], A -> B -> A /\ B
which is not really a lemma but the actual constructor for the inductive type. It is just a function. And remember, every theorem/lemma etc. in type theory is "just a function". Even rewriting is just function application.
Anyway, take seriously the task of learning to find lemmas, and to read the output from Search. It will help you a lot.
Btw, the pattern matching syntax is like the term syntax but with holes or variables, which you will also use when you are writing Ltac tactics, so it is useful to know for many reasons.

Current required number of arguments for unfolding by `simpl`

The Coq Reference Manual details how to use the Arguments directive with a / to mark a constant to be unfolded by the simpl tactic only if enough arguments are supplied.
Is there a way to see how many arguments arguments a constant currently requires to be unfolded?
Similarly, is there a way to see if a constant was flagged to never be simplified by simpl?
The About vernacular gives this information (and other useful things):
Definition foo (n:nat) := n.
Arguments foo n/.
About foo.
Arguments foo/.
About foo.
Arguments foo : simpl never.
About foo.
Specifically the output includes "The reduction tactics unfold foo when applied to 1 argument", "...always unfold foo", and "never unfold foo".

Coq: viewing proof term during proof script writing

So, I've got a proof that looks like this:
induction t; intros; inversion H ; crush.
It solves all my goals, but when I do Qed, I get the following error:
Cannot guess decreasing argument of fix.
So somewhere in the generated proof term, there's non-well-founded recursion. The problem is, I have no idea where.
Is there a way to debug this kind of error, or to see the (possibly non halting) proof term that the tactics script generates?
You can use Show Proof. to view the proof term so far.
Another command that can help with seeing where the recursion went wrong is Guarded., which runs the termination checker on the proof term so far. You'll need to break apart the tactic script into independent sentences to use it, though. Here's an example:
Fixpoint f (n:nat) : nat.
Proof.
apply plus.
exact (f n).
Guarded.
(* fails with:
Error:
Recursive definition of f is ill-formed.
...
*)
Defined.
You can use the Show Proof. command inside proof mode to print the proof term produced so far.
In addition to the other excellent answers, I also want to point out that using induction inside an interactive-mode Fixpoint is usually a mistake, because you're recursing twice. Writing fixpoints in interactive mode is often tricky because most automation tools will happily make a recursive call at every possible opportunity, even when it would be ill-founded.
I would advise to use Definition instead of Fixpoint and use induction in the proof script. This invokes the explicit recursor, which allows for much better control of automation. The disadvantage is decreased flexibility since fixpoints have fewer restrictions than recursors - but as we've seen, that is both a blessing and a curse.

How to partition Coq code to feed Coq ideslave (XML protocol)?

I thought the "Add" call of Coq ideslave (also known as Coq XML protocol) takes one chunk of code at a time, partitioned by periods (.). I still believe this to be true in most cases. For example,
Inductive or (A B:Prop) : Prop :=
| or_introl : A -> A \/ B
| or_intror : B -> A \/ B
where "A \/ B" := (or A B) : type_scope.
Despite this code block has several lines, it should be fed in by one "Add" call, since only the last line has a period.
However, this isn't the case when bullets (+, -, *, {, and }) are present. For example,
- intros [H _]; exact H.
should be fed in by two "Add" calls, - and intros [H _]; exact H. In another case,
{ destruct Hl; [ right | destruct Fl | ]; assumption. }
should be fed in as three parts, {, destruct Hl; [ right | destruct Fl | ]; assumption., and }. I observed these behaviors in CoqIDE, which I think uses Coq ideslave internally.
My first question: are these the complete rules for partitioning a .v file into chunks for the use of "Add" calls? If no, what are the complete rules?
Second question: if I only use the "partitioned-by-period" rule, say if I try to feed { destruct Hl; [ right | destruct Fl | ]; assumption. } as one "Add" call instead of three, the XML won't raise an error immediately. However, after several proof steps, it could raise an error (This proof is focused, but cannot be unfocused this way) which never appear in Coq IDE, and I cannot undo the error by
<call val="Edit_at">
<state_id val="..."/>
</call>
If I try to undo the error, the Coq XML gives the same error message. Is this error related to feeding the bullets as one chunk? If yes, why won't the Coq XML complain about this once I feed the chunk?
An additional question: I would like to try SerAPI in the near future. Does SerAPI share the same rules of feeding code chunks?
Thank you so much for helping!
Jim, in fact, splitting Coq commands is a non-trivial task, I'd say that the de-facto method is the one that CoqIDE uses, see CoqIDE's lexer, also this mail, Emacs' regexp, and CodeMirror's tokenizer.
For the Add call of the protocol, you should send a single sentence! The rest is ignored, and indeed, sentences do include braces. That is where your problem originated.
SerAPI does indeed include additional support to help tools with splitting. The most important differences are:
when you submit a single sentence, SerAPI will reply with the actual end of sentence location. Thus, you can parse a Coq document accurately by letting SerAPI do the splitting.
SerAPI can parse a complete Coq document in one go (and will reply back with the splitting locations).
There are some more technical details regarding the full-document support, but these should be better addressed at the project's page.