Remove All Double Negations in Coq - logic

I would like to systematically remove all double negations which can appear in my hypotheses and goals. I know that ~~A -> Ais not a part of intuitionist logic, but the course I am taking is classical, so I don't mind.
I am aware that the mentioned axiom can be accessed by Coq.Logic.Classical_Prop.NNPPbut this axiom doesn't help removing double negation from more complex sentences such as say
H : ~ ~ A \/ (B /\ ~ C)
Preferably I would like to be able to apply a Ltac tactic to Hso it would transform into
H1 : A \/ (B /\ ~C).
Any help writing such a tactic or any other suggestions are much appreciated.

You can use the rewrite tactic, because it can rewrite with logical equivalences in logical contexts, i.e. it can do setoid rewriting. First, you'd need the following simple lemma:
From Coq Require Import Classical_Prop.
Lemma NNP_iff_P (P : Prop) : ~~ P <-> P.
Proof. split; [apply NNPP | intuition]. Qed.
Now, you can use NNP_iff_P to achieve what you want:
Section Example.
Context (A B C D : Prop).
Context (H : ~ ~ A \/ (B /\ ~ C)).
Goal ~~ A.
rewrite !NNP_iff_P in *.
Abort.
End Example.
! means "rewrite zero or many times, until no rewrites are possible" and in * means "apply the tactic in the context and to the goal".

Related

How to prove in Coq ~~(P \/ ~P)

I want to prove ~~(P \/ ~P) in Coq, which sounds somehow trivial... However I do not know where to go since there is not any single hypothesis.
I have written the following code which is not working, since it is giving the following exception [ltac_use_default] expected after [tactic] (in [tactic_command]).
Parameter P: Prop.
Section r20.
Lemma regra1: ~~(P \/ ~P).
Proof.
intro.
- cut P.
- cut ~P
Qed.
End r20.
It is little tricky one. Here is one way to prove it.
Parameter P : Prop.
Section r20.
Lemma regra1: ~~(P \/ ~P).
Proof.
unfold not. intros H1.
apply H1. right.
intros H2.
apply H1. left.
exact H2.
Qed.
End r20.

Expanding all definitions in Isabelle lemma

How can I tell Isabelle to expand all my definitions, please, because that way the proof is trivial? Unfortunately there is no default expansion or simplification happens, and basically I get back the original expression as the subgoal.
Example:
theory Test
imports Main
begin
definition b0 :: "nat⇒nat"
where "b0 n ≡ (n mod 2)"
definition b1 :: "nat⇒nat"
where "b1 n ≡ (n div 2)"
lemma "(a::nat)≤3 ∧ (b::nat)≤3 ⟶
2*(b1 a)+(b0 a)+2*(b1 b)+(b0 b) = a+b"
apply auto
oops
end
Respose before oops:
proof (prove)
goal (1 subgoal):
1. a ≤ 3 ⟹
b ≤ 3 ⟹ 2 * b1 a + b0 a + 2 * b1 b + b0 b = a + b
My recommendation: unfolding
There is a special keyword unfolding for unpacking definitions at the start of proofs. For your example this would read:
unfolding b0_def b1_def by simp
I consider unfolding the most elegant way. It also helps while writing the proofs. Internally, this is (mostly?) equivalent to using the unfold-method:
apply (unfold b0_def b1_def) by simp
This will recursively (!) use the set of equalities you supply to rewrite the proof goal. (Due to the recursion, you should rather not supply a set of equalities that could generate cycles...)
Alternative: Using the simplifier
In cases with possible loops, the simplifier might be able to reach a nice unfolding without running into these cycles, maybe by interleaving with other simplifications. In such cases, by (simp add: b0_def b1_def), as you've suggested, is great!
Alternative definition: Maybe it's just an abbreviation (and no definition)?
If you find yourself unfolding a definition in every single instance, you could consider, using abbreviation instead of definition. Then, some Isabelle magic will do the packing/unpacking for you without further hints. abbeviation does only affect how the user communicates with Isabelle. It does not introduce new symbols at the object level, and consequently, there would be no b1_def facts and the like.
abbreviation b0 :: "nat⇒nat"
where "b0 n ≡ (n mod 2)"
Usually not recommended: Building something like an abbreviation using the simplifier
If you (for whatever reason) want to have a defined name at the object level, but unfold it in almost every instance, you can also feed the defining equality directly into the simplifier.
definition b0 :: "nat⇒nat"
where [simp]: "b0 n ≡ (n mod 2)"
(Usually there should be little reason for the last option.)
Yes, I keep forgetting that definitions are not used in simplifications by default.
Adding the definitions explicitly to the simplification rules solves this problem:
lemma "(a::nat)≤3 ∧ (b::nat)≤3 ⟶
2*(b1 a)+(b0 a)+2*(b1 b)+(b0 b) = a+b"
by (simp add: b0_def b1_def)
This way the definitions (b0, b1) are correctly used.

How to easily prove the following in Coq such as using only assumptions?

Is there an easy way to prove the following in Coq such as using only assumptions?
(P -> (Q /\ R)) -> (~Q) -> ~P
The question is a bit vague... Do you wonder if it is possible (yes), what the answer is (see Arthur's comment above), or how to think about solving these problems?
In the latter case, remember that the goal is to create a "lambda-term" with the specified type. You can either use "tactics" which are helping you construct the term "from the outside and inwards. It is good to do it by hand a couple of times to understand what is going on and what the tactics really do, which I think is why you are given this exercise.
If you look at your example,
(P -> (Q /\ R)) -> (~Q) -> ~P
you can see that it is a function of three (!) arguments. It is because the last type ~P really means P -> False, so the types of the arguments to the function that you need to create are
P -> (Q /\ R)
Q -> False
P
and the function should construct a term of type
False
You can create a term fun A B C => _ where A, B, C has the types above, (this is what the tactic intros does), and you need to come up with a term that should go into the hole _ by combining the terms A, B, C and the raw gallina constructions.
In this case, when you have managed to create a term of type Q /\ R you will have to "destruct" it to get the term of type Q, (Hint: for that you will have to use the match construction).
Hope this helps without spoiling the fun!

Can you prove Excluded Middle is wrong in Coq if I do not import classical logic

I know excluded middle is impossible in the logic of construction. However, I am stuck when I try to show it in Coq.
Theorem em: forall P : Prop, ~P \/ P -> False.
My approach is:
intros P H.
unfold not in H.
intuition.
The system says following:
2 subgoals
P : Prop
H0 : P -> False
______________________________________(1/2)
False
______________________________________(2/2)
False
How should I proceed?
Thanks
What you are trying to construct is not the negation of LEM, which would say "there exists some P such that EM doesn't hold", but the claim that says that no proposition is decidable, which of course leads to a trivial inconsistency:
Axiom not_lem : forall (P : Prop), ~ (P \/ ~ P).
Goal False.
now apply (not_lem True); left.
No need to use the fancy double-negation lemma; as this is obviously inconsistent [imagine it would hold!]
The "classical" negation of LEM is indeed:
Axiom not_lem : exists (P : Prop), ~ (P \/ ~ P).
and it is not provable [otherwise EM wouldn't be admissible], but you can assume it safely; however it won't be of much utility for you.
One cannot refute the law of excluded middle (LEM) in Coq.
Let's suppose you proved your refutation of LEM. We model this kind of situation by postulating it as an axiom:
Axiom not_lem : forall (P : Prop), ~ (P \/ ~ P).
But then we also have a weaker version (double-negated) of LEM:
Lemma not_not_lem (P : Prop) :
~ ~ (P \/ ~ P).
Proof.
intros nlem. apply nlem.
right. intros p. apply nlem.
left. exact p.
Qed.
These two facts together would make Coq's logic inconsistent:
Lemma Coq_would_be_inconsistent :
False.
Proof.
apply (not_not_lem True).
apply not_lem.
Qed.
I'm coming from mathoverflow, but I don't have permission to comment on #Anton Trunov's answer. I think his answer is unjust, or at least incomplete: he hides the following "folklore":
Coq + Impredicative Set + Weak Excluded-middle -> False
This folklore is a variation of the following facts:
proof irrelevance + large elimination -> false
And Coq + Impredicative Set is canonical, soundness, strong normalization, So it is consistent.
Coq + Impredicative Set is the old version of Coq. I think this at least shows that the defense of the LEM based on double negative translation is not that convincing.
If you want to get information about the solutions, you can get it from here https://github.com/FStarLang/FStar/issues/360
On the other hand, you may be interested in the story of how Coq-HoTT+UA went against LEM∞...
=====================================================
Ok, let's have some solutions.
use command-line flag -impredicative-set, or the install old version(<8.0) of coq.
excluded-middle -> proof-irrelevance
proof-irrelevance -> False
Or you can work with standard coq + coq-hott.
install coq-hott
Univalence + Global Excluded-middle (LEM∞) -> False
It is not recommended that you directly click on the code in question without grasping the specific concept.
I skipped a lot about meta-theoretic implementations, such as Univalence not being computable in Coq-HoTT but only in Agda-CuTT, such as the consistency proof for Coq+Impredicative Set/Coq-HoTT.
However, metatheoretical considerations are important. If we just want to get an Anti-LEM model and don't care about metatheory, then we can use "Boolean-valued forcing" in coq to wreak havoc on things that only LEM can introduce, such as "every function about real set is continuous", Dedekind infinite...
But this answer ends there.

Is it possible to represent a context-free grammar with first-order logic?

Briefly, I have a EBNF grammar and so a parse-tree, but I do not know if there is a procedure to translate it in First Order Logic.
For example:
DR ::= E and P
P ::= B | (and P)* | (or P)*
B ::= L | P (and L P)
L ::= a
Yes, there is. The general pattern for translating a production of the form
A ::= B C ... D
is to paraphrase is declaratively as saying
A sequence of terminals s is an A (or: A generates the sequence s, if you prefer that formulation) if:
s is the concatenation of s_1, s_2, ... s_n, and
s_1 is a B / B generates the sequence s_1, and
s_2 is a C / C generates the sequence s_2, and
...
s_n is a D / D generates the sequence s_n.
Assuming we write these in the obvious way using a generates predicate, and that we can write concatenation using a || operator, your first rule becomes (if I am right to guess that E and P are non-terminals and "and" is a terminal symbol) something like
generates(DR,s) ⊃ generates(E,s1)
∧ generates(and,s2)
∧ generates(P,s3)
∧ s = s1 || s2 || s3
To establish the consequent (i.e. prove that s is an A), prove the antecedents. As long as the grammar does actually generate some sentences, and as long as you have some premises defining the "generates" relation for terminal symbols, the proof will be straightforward.
Prolog definite-clause grammars are a beautiful instantiation of this pattern. It takes some of us a while to understand and appreciate the use of difference lists in DCGs, but they handle the partitioning of s into subsequences and the association of the subsequences with the different parts of the right hand side much more elegantly than the simple translation into logic given above.

Resources