Using sets as hyphotesis and goal in COQ - coq

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

Related

Decide equality with some predicate

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.

How to get the type of a subterm when you're building a match

My general question is: is there an easy way to incrementally build up a definition in Coq when I'm not familiar with the type of what I'm working with?
Consider one definition of the natural numbers in Coq, from Coq.Narith.BinNat
Definition discr n : { p:positive | n = pos p } + { n = 0 }.
Now, to me it's a little confusing what this term looks like. Suppose I'm trying to extract this positive p from the definition. My first try failed:
Require Import Coq.Narith.BinNat.
Fail Definition NToPos (x : N) : positive :=
match N.discr x with
| inright HO => 1
| inleft Hpos => Hpos
end.
(*
Error:
In environment
x : N
Hpos : {p : positive | x = N.pos p}
The term "Hpos" has type "{p : positive | x = N.pos p}"
while it is expected to have type "positive".
*)
Well... okay. Now I know my basic misunderstanding is with the notation {p : positive | x = N.pos p}, but where do I go from here?
My question is, is there a better way to understand a definition such as N.discr? What I think I want is the following:
Definition NToPos (x : N) : positive :=
match N.discr x with
| inright HO => 1
| inleft Hpos => (* Please tell me how to further destruct Hpos *)
end.
In general, to decipher a notation, you can ask something like
Locate "{ x | p }".
In this case, this figures out what { p : positive | n = pos p } means (you replace the "replaceable" parts of the notation with (meta)variables). It gives
Notation "{ x | P }" := sig (fun x => P)
Now the name sig can be used to get more information.
Print sig.
(*
Inductive sig (A : Type) (P : A -> Prop) : Type :=
exist : forall x : A,
P x -> {x : A | P x}
Arguments exist [A]%type_scope _%function_scope
*)
Which tells you that you need to match Hpos against exist _ p Hpos (the Arguments say that A is implicit and that P is explicit, but P (as a parameter) is already fixed by the type of the scrutinee and must be ignored, and the remaining arguments, x : A and the P x, need to be named).
Alternatively,
Unset Printing Notations. (* In CoqIDE, you're told to set this from the view menu instead *)
Check N.discr.
(* Shows you that the notation stands for sig *)
And then continue as before.
I eventually figured this out by checking Print N.discr and observing:
N.discr =
fun n : N =>
match n as n0 return ({p : positive | n0 = N.pos p} + {n0 = 0%N}) with
| 0%N => inright eq_refl
| N.pos p =>
inleft (exist (fun p0 : positive => N.pos p = N.pos p0) p eq_refl)
end
: forall n : N, {p : positive | n = N.pos p} + {n = 0%N}
and seeing that the case I want is exist (fun p0 : positive => N.pos p = N.pos p0) p eq_refl. Then, exist is the key function. From that I was able to correctly guess inleft (exists p Hpos) would work:
Definition NToPos (x : N) : positive :=
match N.discr x with
| inright HO => 1
| inleft (exist p Hpos) => p
end.

Confused about pattern matching in Record constructions in Coq

I've been using Coq for a very short time and I still bump into walls with some things. I've defined a set with a Record construction. Now I need to do some pattern matching to use it, but I'm having issues properly using it. First, these are my elements.
Inductive element : Set :=
| empty : element
.
.
.
| fun_m : element -> element -> element
| n_fun : nat -> element -> element
.
I pick the elements with certain characteristic to make a subset of them the next way:
Inductive esp_char : elements -> Prop :=
| esp1 : esp_char empty
| esp2 : forall (n : nat )(E : element), esp_char E -> esp_char (n_fun n E).
Record especial : Set := mk_esp{ E : element ; C : (esp_char E)}.
Now, I need to use definition and fix point on the 'especial' elements, just the two that I picked. I have read the documentation on Record and what I get is that I'd need to do something like this:
Fixpoint Size (E : especial): nat :=
match E with
|{|E := empty |} => 0
|{|E := n_fun n E0|} => (Size E0) + 1
end.
Of course this tells me that I'm missing everything on the inductive part of elements so I add {|E := _ |}=> 0, or anything, just to make the induction full. Even doing this, I then find this problem:
|{|E := n_fun n E0|} => (Size E0) + 1
Error:
In environment
Size : especial -> nat
E : especial
f : element
i : esp_char f
n : nat
E0 : element
The term "E0" has type "element" while it is expected to have type "especial".
What I have been unable to do is fix that last thing, I have a lemma proving that if n_fun n E0 is 'especial' then E0 is especial, but I can't build it as so inside the Fixpoint. I also defined the size for "all elements" and then just picked the "especial" ones in a definition, but I want to be able to do direct pattern matching directly on the set "especial". Thank you for your input.
EDIT: Forgot to mention that I also have a coercion to always send especial to elements.
EDIT: This is the approach I had before posting:
Fixpoint ElementSize (E : element): nat :=
match E with
| n_fun n E0 => (ElementSize E0) + 1
| _ => 0
end.
Definition Size (E : especial) := ElementSize E.
I'd have tried to do:
Lemma mk_especial_proof n E : esp_char (n_fun n E) -> esp_char E.
Proof. now intros U; inversion U. Qed.
Fixpoint Size (E : especial): nat :=
match E with
|{|E := empty |} => 0
|{|E := n_fun n E0; C := P |} => (Size (mk_esp E0 (mk_especial_proof _ _ P))) + 1
|{|E := fun_m E1 E2 |} => 0
end.
However this will fail the termination check. I'm not familiar with how to overcome this problem with records. I'd definitively follow the approach I mentioned in the comments (using a fixpoint over the base datatype).
EDIT: Added single fixpoint solution.
Fixpoint size_e e :=
match e with
| empty => 0
| fun_m e1 e2 => 0
| n_fun _ e => 1 + size_e e
end.
Definition size_esp e := size_e (E e).
I reduced your example to this, but you can easily go back to your definition. We have a set, and a subset defined by an inductive predicate. Often one uses sigma types for this, with the notation {b | Small b}, but it is actually the same as the Record definition used in your example, so never mind :-).
Inductive Big : Set := (* a big set *)
| A
| B (b0 b1:Big)
| C (b: Big).
Inductive Small : Big -> Prop := (* a subset *)
| A' : Small A
| C' (b:Big) : Small b -> Small (C b).
Record small := mk_small { b:Big ; P:Small b }.
Here is a solution.
Lemma Small_lemma: forall b, Small (C b) -> Small b.
Proof. intros b H; now inversion H. Qed.
Fixpoint size (b : Big) : Small b -> nat :=
match b with
| A => fun _ => 0
| B _ _ => fun _ => 0
| C b' => fun H => 1 + size b' (Small_lemma _ H)
end.
Definition Size (s:small) : nat :=
let (b,H) := s in size b H.
To be able to use the hypothesis H in the match-branches, it is sent into the branch as a function argument. Otherwise the destruction of b is not performed on the H term, and Coq can't prove that we do a structural recursion on H.

Coq: how to apply one hypothesis to another

Assume I have two hypotheses in the context, a_b : A -> B and a : A. I should be able to apply a_b to a to gain a further hypothesis, b : B.
That is, given the following state:
1 subgoal
A : Prop
B : Prop
C : Prop
a_b : A -> B
a : A
______________________________________(1/1)
C
There should be some tactic, foo (a_b a), to transform this into the following state:
1 subgoal
A : Prop
B : Prop
C : Prop
a_b : A -> B
a : A
b : B
______________________________________(1/1)
C
But I don't know what foo is.
One thing I can do is this:
assert B as b.
apply a_b.
exact a.
but this is rather long-winded, and scales badly if instead of a_b a I have some larger expression.
Another thing I can do is:
specialize (a_b a).
but this replaces the a_b hypothesis, which I don't want to do.
pose proof (a_b a) as B.
should do what you want.
You can just use "apply a_b in a."

coq change premise 'negation of not equal' to 'equal'

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.