I would like to prove that equality is decidable for those a that satisfy some predicate P:
Variable C: Type.
Inductive A: Type:=
| A0: C -> A.
Variable P: A -> Prop.
Variable P_dec: forall a: A, {P a} + {~ P a}.
Definition A_dec: forall a b, {a = b} + {a <> b} + {~ P a}.
But using decide equality, I lose the information that a satisfies P:
intros. destruct (P_dec a). left. decide equality.
I get
a, b: A
p: P a
c, c0: C
----------
{c = c0} + {c <> c0}
and I cannot use the fact that we have P (A0 c). It seems to me that somehow I am legitimate to assume that a = P c - how can I proceed to get this information?
Do you have any hypothesis on C? For instance :
Variable Ceqdec : forall c c':C, {c = c'}+{c <> c'}.
Some types don't have this possibility (e.g; C = nat->nat)
About your other question :
You may start your proof with intros [c] [c0] in order to decompose aand b.
Related
I was going through Adam Chlipala's book on Coq and it defined the inductive type:
Inductive unit : Set :=
| tt.
I was trying to understand its induction principle:
Check unit_ind.
(* unit_ind
: forall P : unit -> Prop, P tt -> forall u : unit, P u *)
I am not sure if I understand what the output of Coq means.
1) So check gives me a look at the type of "objects" right? So unit_ind has type:
forall P : unit -> Prop, P tt -> forall u : unit, P u
Right?
2) How does one read that type? I am having trouble understanding where to put the parenthesis or something...For the first thing before the comma, it doesn't make sense to me to read it as:
IF "for all P of type unit" THEN " Prop "
since the hypothesis is not really something true or false. So I assume the real way to real the first thing is this way:
forall P : (unit -> Prop), ...
so P is just a function of type unit to prop. Is this correct?
I wish this was correct but under that interpretation I don't know how to read the part after the first comma:
P tt -> forall u : unit, P u
I would have expected all the quantifications of variables in existence to be defined at the beginning of the proposition but thats not how its done, so I am not sure what is going on...
Can someone help me read this proposition both formally and intuitively? I also want to understand conceptually what it's trying to say and not only get bugged down by the details of it.
Let me put some extra (not really necessary) parentheses:
forall P : unit -> Prop, P tt -> (forall u : unit, P u)
I would translate it as "For any predicate P over the unit type, if P holds of tt, then P holds of any term of type unit".
Intuitively, since tt is the only value of type unit, it makes sense to only prove P for this unique value.
You can check if this intuition works for you by trying to interpret the induction principle for the bool type in the same manner.
Check bool_ind.
bool_ind
: forall P : bool -> Prop, P true -> P false -> (forall b : bool, P b)
Consider this section:
Section MyMap.
Variables D R : Type.
Fixpoint mymap (f : D -> R) (l : list D) : list R :=
match l with
| nil => nil
| d :: t => f d :: mymap f t
end.
End MyMap.
Here I've used Variables to declare my domain and range types. As a sanity check on the definition of my function, I would like to include an Example:
Example example_map_S : mymap S [0; 1; 2] = [1; 2; 3].
Proof.
simpl; trivial.
Qed.
However it seems I can't do so within my section. Instead I get:
Error: The term "S" has type "nat -> nat" while it is expected to have type "D -> R".
That's not too surprising, so let's try it another way:
Example example_map_S : #mymap nat nat S [0; 1; 2] = [1; 2; 3].
Proof.
simpl; trivial.
Qed.
Which produces:
Error: The term "nat" has type "Set" while it is expected to have type "D -> R".
I suppose that's fair, section-ized Variables aren't the same thing as implicit arguments. But it still leaves the question!
How can I supply concrete Variables to a term before closing the section, in order to create useful Examples?
Section MyMap.
...
If we check the type of mymap inside the section, we get
Check mymap.
(* mymap : (D -> R) -> list D -> list R *)
Of course, we can't unify D and R with nat, since D and R are some locally postulated types.
However, we can sort of simulate your example in this generalized setting, showing the expected property of the mymap function:
Example example_nil (f : D -> R) :
mymap f [] = [] := eq_refl.
Example example_3elems (f : D -> R) (d0 d1 d2 : D) :
mymap f [d0; d1; d2] = [f d0; f d1; f d2] := eq_refl.
End MyMap.
Let's say I have again a small problem with my datatype with an existential quantified component. This time I want to define when two values of type ext are equal.
Inductive ext (A: Set) :=
| ext_ : forall (X: Set), option X -> ext A.
Fail Definition ext_eq (A: Set) (x y: ext A) : Prop :=
match x with
| ext_ _ ox => match y with
| ext_ _ oy => (* only when they have the same types *)
ox = oy
end
end.
What I'd like to do is somehow distinguish between the cases where the existential type is actually same and where it's not. Is this a case for JMeq or is there some other way to accomplish such a case distinction?
I googled a lot, but unfortunately I mostly stumbled upon posts about dependent pattern matching.
I also tried to generate a (boolean) scheme with Scheme Equality for ext, but this wasn't successful because of the type argument.
What I'd like to do is somehow distinguish between the cases where the existential type is actually same and where it's not.
This is not possible as Coq's logic is compatible with the univalence axiom which says that isomorphic types are equal. So even though (unit * unit) and unit are syntactically distinct, they cannot be distinguished by Coq's logic.
A possible work-around is to have a datatype of codes for the types you are interested in and store that as an existential. Something like this:
Inductive Code : Type :=
| Nat : Code
| List : Code -> Code.
Fixpoint meaning (c : Code) := match c with
| Nat => nat
| List c' => list (meaning c')
end.
Inductive ext (A: Set) :=
| ext_ : forall (c: Code), option (meaning c) -> ext A.
Lemma Code_eq_dec : forall (c d : Code), { c = d } + { c <> d }.
Proof.
intros c; induction c; intros d; destruct d.
- left ; reflexivity.
- right ; inversion 1.
- right ; inversion 1.
- destruct (IHc d).
+ left ; congruence.
+ right; inversion 1; contradiction.
Defined.
Definition ext_eq (A: Set) (x y: ext A) : Prop.
refine(
match x with | #ext_ _ c ox =>
match y with | #ext_ _ d oy =>
match Code_eq_dec c d with
| left eq => _
| right neq => False
end end end).
subst; exact (ox = oy).
Defined.
However this obviously limits quite a lot the sort of types you can pack in an ext. Other, more powerful, languages (e.g. equipped with Induction-recursion) would give you more expressive power.
How exactly could a proof like the following be completed?
1 subgoals
IHt1 : {t' : some_type | something_using t'}
IHt2 : {t' : some_type | something_else_using t'}
______________________________________(1/1)
{t' : some_type | another_thing_involving t'}
I do understand that the {x|P x} notation is a shorthand for the sig definition but I really cannot understand how to use it.
{x : D | P x} is intuitively speaking the subset of the domain D containing the elements that satisfy the predicate P. As a proposition, it is true if that subset is non-empty, i.e. if there is a witness x0 in D such that P x0 is true.
An object of type {x : D | P x} is a pair containing an element x0 : D and a proof of P x0. This is visible when you look at the definition of {x : D | P x}, which is syntactic sugar for sig (fun x:D => P x)
Inductive sig (D:Type) (P:D -> Prop) : Type :=
exist : forall x:D, P x -> sig P.
The type of the constructor is a dependent pair type; the first element of the pair has the type D and the second element has the type P x in which x is the first element.
To make use of a hypothesis of the form {x : D | P x}, the most basic way is to use the destruct tactic to break it down into its two components: a witness x0 : D and a proof H : P x0.
destruct IHt1.
1 subgoals
t' : some_type
H : something_using t'
IHt2 : {t'0 : some_type | something_else_using t'0}
______________________________________(1/1)
{t'0 : some_type | another_thing_involving t'0}
To prove a goal of the form {x : D | P x}, the most basic is to use the exist tactic to introduce the intended witness. This leaves one subgoal which is to prove that the witness has the desired property.
exists u.
⋮
______________________________________(1/1)
another_thing_involving u
Suppose I have a premise like this:
H2: ~ a b c <> a b c
And I wish to change it to:
a b c = a b c
Where
a is Term -> Term -> Term
b and c are both Term
How can I do it? Thanks!
If you unfold the definitions of ~ and <>, you hypothesis has the following type:
H2: (a b c = a b c -> False) -> False
Therefore, what you wish to achieve is what logicians usually call "double negation elimination". It is not an intuitionistically-provable theorem, and is therefore defined in the Classical module of Coq (see http://coq.inria.fr/distrib/V8.4/stdlib/Coq.Logic.Classical_Prop.html for details):
Classical.NNPP : forall (p : Prop), ~ ~ p -> p
I assume your actual problem is more involved than a b c = a b c, but for the sake of mentioning it, if you really care about obtaining that particular hypothesis, you can safely prove it without even looking at H2:
assert (abc_refl : a b c = a b c) by reflexivity.
If your actual example is not immediately reflexive and the equality is actually false, maybe you want to turn your goal into showing that H2 is absurd. You can do so by eliminating H2 (elim H2., which is basically doing a cut on the False type), and you will end up in the context:
H2 : ~ a b c <> a b c
EQ : a b c = a b c
=====================
False
I'm not sure whether all of this helps, but you might have oversimplified your problem so that I cannot provide more insight on what your real problem is.
Just a little thought to add to Ptival's answer - if your desired goal was not trivially solved by reflexivity, you could still make progress provided you had decidable equality on your Term, for example by applying this little lemma:
Section S.
Parameter T : Type.
Parameter T_eq_dec : forall (x y : T), {x = y} + {x <> y}.
Lemma not_ne : forall (x y : T), ~ (x <> y) -> x = y.
Proof.
intros.
destruct (T_eq_dec x y); auto.
unfold not in *.
assert False.
apply (H n).
contradiction.
Qed.
End S.