5

After proving tens of lemmas in propositional and predicate calculus (some more challenging than others but generally still provable on an intro-apply-destruct autopilot) I hit one starting w/ ~forall and was immediately snagged. Clearly, my understanding and knowledge of Coq was lacking. So, I'm asking for a low-level Coq technique for proving statements of the general form

~forall A [B].., C -> D.  
exists A [B].., ~(C -> D).

In words, I'm hoping for a general Coq recipy for setting up and firing counterexamples. (The main reason for quantifying over functions above is that it's a (or the) primitive connective in Coq.) If you want examples, I suggest e.g.

~forall P Q: Prop, P -> Q.
~forall P: Prop, P -> ~P.

There is a related question which neither posed nor answered mine, so I suppose it's not a duplicate.

Community
  • 1
  • 1
jaam
  • 900
  • 4
  • 23

1 Answers1

6

Recall that ~ P is defined as P -> False. In other words, to show such a statement, it suffices to assume P and derive a contradiction. The crucial point is that you are allowed to use P as a hypothesis in any way you like. In the particular case of universally quantified statements, the specialize tactic might come in handy. This tactic allows us to instantiate a universally quantified variable with a particular value. For instance,

Goal ~ forall P Q, P -> Q.
Proof.
  intros contra.
  specialize (contra True False). (* replace the hypothesis 
                                     by [True -> False] *)
  apply contra. (* At this point the goal becomes [True] *)
  trivial.
Qed. 
Arthur Azevedo De Amorim
  • 23,012
  • 3
  • 33
  • 39
  • 1
    Thanks, `specialize` it was (solved my original problem as well). Are there any other less common (than `intro`, `apply`, `destruct`..) tactics frequently useful in proofs by counterexample? – jaam Mar 01 '16 at 19:11
  • 2
    You don't "need" `specialize`, in the sense that it does something special that you couldn't do already. In the solution above `contra` is a function of three arguments of type `forall P Q, P->Q`. You can just use it to construct a value that you can apply. So in this case you can solve it all with `intro C; apply (C True False I).` or even (using Coq's type inference) `intro C; apply (C _ _ I).` where `I` is the constructor for `True`. – larsr Mar 02 '16 at 09:19
  • @jaam the basic set of tactics that is shipped with Coq is not very orthogonal, and there are many tactics that could be useful in proofs by counterexample, such as `contradiction`, `discriminate`... But note that you can in principle solve all of those by using very few tactics. As larsr pointed out, for example, you could just have used `apply`. You could also use `assert` to build intermediate results with proof scripts, without building a proof object by hand. – Arthur Azevedo De Amorim Mar 02 '16 at 13:07
  • Thanks. So, referring @larsr above, with the goal `C : forall P Q : Prop, P -> Q ├ False`, the 1st `_` is inferred from `I` and the second from conclusion `False`? – jaam Mar 03 '16 at 08:31
  • @jaam When I started using Coq, I often used `exfalso` to "force" the current goal to `False`, then `apply H`, where `H` is the hypothesis of the form `~ P`, that is, `P -> False`. It suits a linear, traditional backward-proof style. It's not necessary but it can be easier to follow. – anol Mar 07 '16 at 13:50