While trying to prove some equality in ssreflect, I got to the following:
WTS: forall (a b: ~ false), a = b
which is basically
WTS: forall (a b: false <> true), a = b.
Knowing that the following holds constructively,
bool_irrelevance (b: bool): (x y: b), x = y
I got to wonder if it is possible to prove WTS constructively.
Since the decidable equality required for is given as {x = y} + {x <> y}, I think it might be provable without axioms. Is this provable?
Also, is it possible to prove proof irrelevance for the prop False -> False?
Note, I am indeed fine with using proof irrelevance axiom. Simply asking if there is a way to avoid using the axiom.
Related
~ (exists x:D, ~ R x)->(forall y:D, R y)
I have worked on it for quite a long time, but it seems that I cannot use the left part of the implication well.
This is the first part of my code:
Parameter D: Set.
Parameter x: D.
Parameter y: D.
Parameter R: D->Prop.
Lemma b: ~(exists x:D, ~ (R x))->(forall y:D, (R y)).
Can anyone help me figure out how to write the rest of of the code?
Your question is a bit vague, as you don't specify what D and R are, and where you are stuck in your proof. Try providing a minimal working example, with an explicit fail tactic for where you're stuck in the proof.
In classical logic (the one you're use to in maths), as you have the excluded middle rule, you can always do a case analysis on whether something is true or false. In vanilla Coq, built for intuitionistic logic, it's not the case. Your result is actually not provable if the predicate R is not decidable (if it's not either true or false on every input : forall (x:D), R x \/ ~R x), if the type D is not empty.
Try adding the decidability of R as an hypothesis and reprove it. It should follow more or less this structure (the key being the case analysis on whether (R y) is true or false) :
Parameter D: Set.
Parameter R: D -> Prop.
Lemma yourGoal :
(forall x, R x \/ ~ R x) -> (* Decidability of R *)
~ ( exists x, ~ (R x) )->
forall y, (R y).
Proof.
intros Hdec Hex y. (* naming the hypothesis for convenience *)
specialize (Hdec y).
destruct Hdec as [H_Ry_is_true | H_Ry_is_false]. (* case analysis, creates two goals *)
+ (* (R y) is true, which is our goal. *)
assumption.
+ (* (R y) is false, which contradicts Hex *)
exfalso. (* transform your goal into False *)
apply Hex.
(* should be easy from here, using the [exists] tactic *)
Qed.
Ps: this exact result (and its link with excluded middle) is mentioned in Software foundations, which is a great resource to learn Coq and logic : https://softwarefoundations.cis.upenn.edu/lf-current/Logic.html#not_exists_dist
Given the definition:
Definition cast (a b:Type) (p:a = b) (x:a) : b :=
match p with
| eq_refl _ => x
end.
I was hoping that the following lemma would be provable:
Lemma cast_cast_is_id : forall (a b:Type) (x:a) (p:a = b) (q:b = a),
cast b a q (cast a b p x) = x.
However, I do not seem to be able to carry out a proof for this. I can destruct p successfully, but cannot destruct q after that. Replacing the lemma's statement with eq_sym p instead of arbitrary q does not help me either it seems.
I fear I have unwittingly stumbled into some subtle point of HoTT.
Can anyone prove this lemma or is it known to be unprovable without further axioms?
I am not completely sure, but it seems to me that what you are trying to prove is no different from forall a (p:a=a), p = eq_refl. If so, you cannot prove it in Coq, unless you know something about a, e.g., decidable equality. In that case, you can use the results on UIP (unicity of identity proofs) from the standard library.
Suppose we're trying to formalize some (semi)group-theoretic properties, like this:
Section Group.
Variable A: Type.
Variable op: A -> A -> A.
Definition is_left_neutral (e: A) := forall x: A, (op e x) = x.
Definition is_right_neutral (e: A) := forall x: A, x = (op x e).
Lemma uniqueness_of_neutral:
forall a b: A, (is_left_neutral a) -> (is_right_neutral b) -> (a = b).
Proof.
intro; intro.
intros lna rnb.
elim lna with b; elim rnb with a.
reflexivity.
Qed.
End Group.
It works just fine, but, if we reverse the equation in either of the above definitions, i.e. replace the definitions with
Definition is_left_neutral (e: A) := forall x: A, x = (op e x).
and
Definition is_right_neutral (e: A) := forall x: A, (op x e) = x.
respectively, the proof fails at reflexivity, since one or both of the elim applications do nothing.
Sure there is a workaround for it, based on assert, but that's... too much effort and simply annoying...
Is there a reason why the involved Coq tactics (elim, case, etc.) are so much sensitive to the order? I suppose, it shouldn't slow down the tactics any noticeably (<< 2 times).
Is there a way to make them apply symmetry automatically, where needed, without bothering me about it every time? Couldn't find any mention of this issue in the manual.
First, using elim to manipulate equality is cumbersome. Here is how I would write your proof, using rewrite, and changing the definition of is_left_neutral.
Section Group.
Variable A: Type.
Variable op: A -> A -> A.
Definition is_left_neutral (e: A) := forall x: A, op e x = x.
Definition is_right_neutral (e: A) := forall x: A, op x e = x.
Lemma uniqueness_of_neutral:
forall a b: A, is_left_neutral a -> is_right_neutral b -> a = b.
Proof.
intros a b lna rnb.
now rewrite <- (lna b), rnb.
Qed.
End Group.
Notice the <- in the first rewrite: it tells Coq to rewrite from right-to-left insead of left-to-right. When you use elim, you can essentially only rewrite in one direction (right-to-left), which leads to the behavior that you saw.
I can't think right now of a reason for only trying one direction in the rewrite tactic, but I do not think it is for performance reasons. In any case, you can define your own variant of rewrite, which tries to rewrite left-to-right, and then right-to-left, if that does not work:
Section Group.
Variable A: Type.
Variable op: A -> A -> A.
Definition is_left_neutral (e: A) := forall x: A, op e x = x.
Definition is_right_neutral (e: A) := forall x: A, op x e = x.
Ltac my_rewrite t :=
first [ rewrite t | rewrite <- t ].
Lemma uniqueness_of_neutral:
forall a b: A, is_left_neutral a -> is_right_neutral b -> a = b.
Proof.
intros a b lna rnb.
now my_rewrite (lna b); my_rewrite rnb.
Qed.
End Group.
I am thinking about proof irrelevance in COQ.
One provable statement says:
If equality of a type is decidable then there can be only one proof for the equality statement, namely reflexivity.
I wonder if its possible to construct types with more than one equality proof in COQ. Therefore I ask if the following construct is consistent?
(*it is known that f=g is undecidable in COQ *)
Definition f(n:nat) := n.
Definition g(n:nat) := n+0.
Axiom p1: f=g.
Axiom p2: f=g.
Axiom nonirrelevance:p1<>p2.
What me puzzles here is the fact that by introducing p1 I made the equality f=g decidable and therefore it should only have one proof! What is my error in reasoning here?
Is that all a pure COQ behaviour or is it similar in HOTT?
I think you're confusing several things.
The provable statement you are speaking of can be found in https://coq.inria.fr/library/Coq.Logic.Eqdep_dec.html and is
Theorem eq_proofs_unicity A (eq_dec : forall x y : A, x = y \/ x <> y) (x : A) :
forall (y:A) (p1 p2:x = y), p1 = p2.
Now what is quite interesting is the type of eq_dec. First of all, it doesn't even really ask for equality to be decidable, it just asks for it to be true or false which is way less stronger than {x = y} + {x <> y}
Then notice that it doesn't ask this just for the x and y to prove the equality irrevelance of, it ask this property for all functions.
So you would need to prove your contradiction that forall (f g : nat -> nat), f = g \/ f <> g which you cannot. p1 is just a proof that f = g \/ f <> g for your specific f and g.
Notice though that if you could, it would just mean that there is no way to build a system in which you can compare functions and yet have multiple ways which are provably different to check them.
Finally, for P to be undecidable only means that there is no constructible functions over {P} + {~P} yet, it doesn't mean that adding one as an axiom leads to a contradiction. Just adding that in case it wasn't clear.
In Software Foundations IndProp.v one is asked to prove the pigeonhole principle, and one may use excluded middle, but it is mentioned that it is not strictly necessary. I've been trying to prove it without EM, but my brain seems to be wired classically.
Q: How would one prove the theorem without using excluded middle? How should one generally approach proofs for types without decidable equality, where one can't easily reason by cases?
I'd be very happy for a complete proof to look at, but please avoid posting it "in the clear", so as to not spoil the exercise in the Software Foundations course.
The definition uses two inductive predicates, In and repeats.
Require Import Lists.List.
Import ListNotations.
Section Pigeon.
Variable (X:Type).
Implicit Type (x:X).
Fixpoint In x l : Prop := (*** In ***)
match l with
| nil => False
| (x'::l') => x' = x \/ In x l'
end.
Hypothesis in_split : forall x l, In x l -> exists l1 l2, l = l1 ++ x :: l2.
Hypothesis in_app: forall x l1 l2, In x (l1++l2) <-> In x l1 \/ In x l2.
Inductive repeats : list X -> Prop := (*** repeats ***)
repeats_hd l x : In x l -> repeats (x::l)
| repeats_tl l x : repeats l -> repeats (x::l).
Theorem pigeonhole_principle_NO_EM: (*** pigeonhole ***)
forall l1 l2,
length l2 < length l1 -> (* There are more pigeons than nests *)
(forall x, In x l1 -> In x l2) -> (* All pigeons are in some nest *)
repeats l1. (* Thus, some pigeons share nest *)
Proof.
(* ??? *)
I'll describe the thought process that led me to a solution, in case it helps. We may apply induction and it is straightforward to reduce to the case l1 = a::l1', l2 = a::l2'. Now l1' is a subset of a::l2'. My EM-trained intuition is that one of the following holds:
a is in l1'.
a is not in l1'.
In the latter case, each element of l1' is in a::l2' but differs from a, and therefore must be in l2'. Thus l1' is a subset of l2', and we can apply the inductive hypothesis.
Unfortunately if In is not decidable, the above can't be directly formalized. In particular if equality is not decidable for the given type, it's difficult to prove elements are unequal, and therefore difficult to prove a negative statement like ~(In a l1'). However, we wanted to use that negative statement to prove a positive one, namely
forall x, In x l1' -> In x l2'
By analogy, suppose we wanted to prove
P \/ Q
Q -> R
------
P \/ R
The above intuitive argument is like starting from P \/ ~P, and using ~P -> Q -> R in the second case. We can use a direct proof to avoid EM.
Quantifying over the list l1' makes this a bit more complicated, but still we can construct a direct proof using the following lemma, which can be proven by induction.
Lemma split_or {X} (l : list X) (P Q : X -> Prop) :
(forall x, In x l -> (P x \/ Q x)) ->
(exists x, In x l /\ P x) \/ (forall x, In x l -> Q x).
Finally note that the intuitive pigeonhole principle could also be formalized as the following way, which cannot be proven when the type has undecidable equality (note that it has a negative statement in the conclusion):
Definition pigeon2 {X} : Prop := forall (l1 l2 : list X),
length l2 < length l1 ->
(exists x, In x l1 /\ ~(In x l2)) \/ repeats l1.
A possible constructive proof goes like this:
We prove pigeonhole_principle_NO_EM by induction on l1. Only the non-empty case is possible because of the length constraint. So, assume l1 = x :: l1'. Now, check whether there is some element of l1' which is mapped by f : (forall x, In x l1 -> In x l2) to the same membership proof as x. If there is such an x' element, then it follows that x = x', therefore l1 repeats. If there is no such element, then we can get l2' by removing the element that x is mapped to from l2, and apply the induction hypothesis to l2' and the appropriate f' : forall x, In x l1' -> In x l2' function.
That's it, but I note that actually formalizing this proof is not easy with the definitions given, because we need to prove heterogeneous or dependent equalities, since we have to compare membership proofs for possibly different elements.
As to the question of getting the hang of constructive proofs in general, an important skill or habit is always examining what kind of data we have, not just what kind of logical facts we know. In this case, membership proofs are actually indices pointing into lists, bundled together with proofs that the pointed-to elements equal certain values. If membership proofs didn't tell where exactly elements are located then this proof would not be possible constructively.