Coq: how to apply one hypothesis to another - coq

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."

Related

How does the induction principle for the singleton type unit in Coq work?

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)

How does elim work in Coq on /\ and \/?

In Coq Tutorial, section 1.3.1 and 1.3.2, there are two elim applications:
The first one:
1 subgoal
A : Prop
B : Prop
C : Prop
H : A /\ B
============================
B /\ A
after applying elim H,
Coq < elim H.
1 subgoal
A : Prop
B : Prop
C : Prop
H : A /\ B
============================
A -> B -> B /\ A
The second one:
1 subgoal
H : A \/ B
============================
B \/ A
After applying elim H,
Coq < elim H.
2 subgoals
H : A \/ B
============================
A -> B \/ A
subgoal 2 is:
B -> B \/ A
There are three questions. First, in the second example, I don't understand what inference rule (or, logical identity) is applied to the goal to generate the two subgoals. It is clear to me for the first example, though.
The second question, according to the manual of Coq, elim is related to inductive types. Therefore, it appears that elim cannot be applied here at all, because I feel that there are no inductive types in the two examples (forgive me for not knowing the definition of inductive types). Why can elim be applied here?
Third, what does elim do in general? The two examples here don't show a common pattern for elim. The official manual seems to be designed for very advanced users, since they define a term upon several other terms that are defined by even more terms, and their language is ambiguous.
Thank you so much for answering!
Jian, first let me note that the manual is open source and available at https://github.com/coq/coq ; if you feel that the wording / definition order could be improved please open an issue there or feel free to submit a pull request.
Regarding your questions, I think you would benefit from reading some more comprehensive introduction to Coq such as "Coq'art", "Software Foundations" or "Programs and Proofs" among others.
In particular, the elim tactic tries to apply the so called "elimination principle" for a particular type. It is called elimination because in a sense, the rule allows you to "get rid" of that particular object, allowing you to continue on the proof [I recommend reading Dummett for a more throughout discussion of the origins of logical connectives]
In particular, the elimination rule for the ∨ connective is usually written by logicians as follows:
A B
⋮ ⋮
A ∨ B C C
────────────────
C
that is to say, if we can derive C independently from A and B, then we can derive it from A ∨ B. This looks obvious, doesn't it?
Going back to Coq, it turns out that this rule has a computational interpretation thanks to the "Curry-Howard-Kolmogorov" equivalence. In fact, Coq doesn't provide most of the standard logical connectives as a built in, but it allow us to define them by means of "Inductive" datatypes, similar to those in Haskell or OCaml.
In particular, the definition of ∨ is:
Inductive or (A B : Prop) : Prop :=
| or_introl : A -> A \/ B
| or_intror : B -> A \/ B
that is to say, or A B is the piece of data that either contains an A or a B, together with a "tag", that allows us to "match" to know which one do we really have.
Now, the "elimination principle for or" has type:
or_ind : forall A B P : Prop, (A -> P) -> (B -> P) -> A \/ B -> P
The great thing of Coq is that such principle is not a "built-in", just a regular program! Think, could you write the code of the or_ind function? I'll give you a hint:
Definition or_ind A B P (hA : A -> P) (hB : B -> P) (orW : A ‌\/ B) :=
match orW with
| or_introl aW => ?
| or_intror bW => ?
end.
Once this function is defined, all that elim does, is to apply it, properly instantiating the variable P.
Exercise: solve your second example using apply and ord_ind instead of elim. Good luck!

Construct Sets in Coq

How to construct elements of the following set(assuming A : Set)?
A -> A + A
My answer is following:
Definition set : A -> A + A :=
fun a => match a with
| inl l => a
| inr r => a
end.
And it returns:
Error: In environment
P, Q, R : Prop
A, B, C : Set
a : A
The term "a" has type "A" while it is expected to have type "?T + ?T0".
I don't know if I understand your problem correctly, but here's a solution.
Definition mkset {A : Set}: A -> A + A.
intro a.
left.
assumption.
Defined.
The idea is to use tactics to build a function of type A -> A + A. Tactic intro corresponds to abstraction of parameter a. Tactic left allows us to choose to prove just the left hand side of A + A. Finally, assumption search the hypothesis for a proposition that fits the current goal and finish it, if such hypothesis exists in context.

Using sets as hyphotesis and goal in 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

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.