I have next definitions (code can be compiled):
From mathcomp Require Import all_ssreflect.
Set Implicit Arguments.
Set Asymmetric Patterns.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Inductive val : Set := VConst of nat | VPair of val & val.
Inductive type : Set := TNat | TPair of type & type.
Inductive tjudgments_val : val -> type -> Prop :=
| TJV_nat n :
tjudgments_val (VConst n) TNat
| TJV_pair v1 t1 v2 t2 :
tjudgments_val v1 t1 ->
tjudgments_val v2 t2 ->
tjudgments_val (VPair v1 v2) (TPair t1 t2).
And I would like to prove the following lemma:
Lemma tjexp_pair v1 t1 v2 t2 (H : tjudgments_val (VPair v1 v2) (TPair t1 t2)) :
tjudgments_val v1 t1 /\ tjudgments_val v2 t2.
Proof.
case E: _ _ / H => // [v1' t1' v2' t2' jv1 jv2].
(* case E: _ / H => // [v1' t1' v2' t2' jv1 jv2]. *)
The case E: _ _ / H => // [v1' t1' v2' t2' jv1 jv2]. leaves me with E : VPair v1 v2 = VPair v1' v2'.
The case E: _ / H => // [v1' t1' v2' t2TPair t1 t2 = TPair t1' t2'' jv1 jv2]. leaves me with E : TPair t1 t2 = TPair t1' t2'.
But it looks to me like I need both of them together. How to?
There is a way of using inversion's power with ssreflect tactics.
Derive Inversion tjudgments_val_inv with (forall v t, tjudgments_val v t).
You can use it with elim/tjudgments_val_inv: H.
The proof is straightforward after this.
In such a case, you can use the very handy inversion tactic an enhancement of the case tactic, which automatically does the kind of work of indices you are manually trying to do. Here inversion H is almost enough to finish the proof.
Related
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.
All
I am trying to complete the last execrise in the StlcProp of Software Foundations Vol2.
But I got stuck at defining step, in the rule ST_SuccNat.
Inductive step : tm -> tm -> Prop :=
| ST_AppAbs : forall x T2 t1 v2,
value v2 ->
<{(\x:T2, t1) v2}> --> <{ [x:=v2]t1 }>
| ST_App1 : forall t1 t1' t2,
t1 --> t1' ->
<{t1 t2}> --> <{t1' t2}>
| ST_App2 : forall v1 t2 t2',
value v1 ->
t2 --> t2' ->
<{v1 t2}> --> <{v1 t2'}>
| ST_SuccNat: forall n:nat,
<{succ n}> --> <{ S n }> (* <----- stuck here *)
Coq complains as below
In environment
step : tm -> tm -> Prop
n : nat
The term "S" has type "nat -> nat" while it is expected to have type "tm".
How can I tell Coq the S n in the form of "tm" ?
Thanks
I think you can do
<{succ n}> --> S n
(* which desugars to succ (tm_const n) --> tm_const (S n) *)
The <{ }> brackets change the interpretation of application. Here you want the regular function application, so don't use the brackets.
I am experimenting with possibility of embedding of HOL4 proofs in Coq.
In HOL it is possible to give definition like
fun ALPHA t1 t2 = TRANS (REFL t1) (REFL t2)
Is it possible to somehow define this function in Coq in similar way? My attempt fails on the last line due to
The term "REFL t2" has type "t2 == t2"
while it is expected to have type "t1 == ?t3" (cannot unify
"t2" and "t1").
The code:
Axiom EQ : forall {aa:Type}, aa -> aa -> Prop.
Notation " x == y " := (#EQ _ x y) (at level 80).
Axiom REFL : forall {aa:Type} (a:aa), a == a.
Axiom TRANS :forall {T:Type}{t1 t2 t3:T},
(t1 == t2) -> (t2 == t3) -> (t1 == t3).
Definition ALPHA t1 t2 := TRANS (REFL t1) (REFL t2).
ADDED:
Maybe there is a method of defining ALPHA such that we can assume that t1=t2? (I mean indeed, in Coq's standard sense of equality). I cann add assumption (H:t1=t2), but then I need to have matching somehow. How to do the matching with equality?
Definition ALPHA (t1 t2:T) (H:t1=t2) : t1==t2 :=
match H with
| eq_refl _ => TRANS (REFL t1) (REFL t2)
end
. (*fails*)
Can you say more about how this definition is supposed to work in HOL? If I'm guessing correctly, ALPHA is supposed to be a thing that fails to typecheck if its arguments are not alpha-convertible? In Coq, you can use
Notation ALPHA t1 t2 := (TRANS (REFL t1) (REFL t2)).
You could also do
Notation ALPHA t1 t2 := (REFL t1 : t1 == t2).
or
Notation ALPHA t1 t2 := (eq_refl : t1 = t2).
Then you can write things like Check ALPHA foo bar to see if two things are convertible. But I don't think this will be useful in most situations. If you're looking for tactic programming, perhaps you're looking for the unify tactic or the constr_eq tactic?
Alternatively, if you want your match statement to work, you can write
Definition ALPHA {T:Type} (t1 t2 : T) (H : t1 = t2) : t1 == t2 :=
match H with eq_refl => REFL _ end.
This is not a unification problem, it really is a typing problem.
REFL t1 has type t1 == t1 and REFL t2 has type t2 == t2 as the error message is telling you. Transitivity would only work if somehow t1 and t2 were the same, but this is a priori not the case.
Perhaps what you wrote is not what you think you wrote.
If we were using only t1, then TRANS (REFL t1) (REFL t1) has type t1 == t1. Were you expecting ALPHA t1 t2 to have type t1 == t2?
If it is the case, then your EQ relation would be total.
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.
Suppose I have a nested existential statement H : exists ( a : A ) ( b : B ) ( c : C ) ... ( z : Z ), P a b c ... z in the context. What is the best way instantiate H and obtain a new hypothesis H' : P a b c ... z? Doing so by repeated inversion takes a long time and leaves all the unwanted intermediate steps like H0 : exists ( b : B ) ( c : C ) ... ( z : Z ), P a b c ... z.
My previous question is very similar to this one. Maybe there's some way to use pose proof or generalize to make this one work as well.
What you want to do is not called "instantiation." You can instantiate a universally quantified hypothesis and you can instantiate an existentially quantified conclusion, but not vice versa. I'm thinking the proper name is "introduction". You can introduce existential quantification in a hypothesis and you can introduce universal quantification in the conclusion. If it seems like you're "eliminating" instead, that's because, when proving something, you start at the bottom of a sequent calculus deriviation, and work your way backwards to the top.
Anyway, use the tactic firstorder. Also, use the command Set Firstorder Depth 0 to turn off proof search if you only want to simplify your goal.
If your goal has higher order elements though, you'll probably get an error message. In that case, you can use something like simplify.
Ltac simplify := repeat
match goal with
| h1 : False |- _ => destruct h1
| |- True => constructor
| h1 : True |- _ => clear h1
| |- ~ _ => intro
| h1 : ~ ?p1, h2 : ?p1 |- _ => destruct (h1 h2)
| h1 : _ \/ _ |- _ => destruct h1
| |- _ /\ _ => constructor
| h1 : _ /\ _ |- _ => destruct h1
| h1 : exists _, _ |- _ => destruct h1
| |- forall _, _ => intro
| _ : ?x1 = ?x2 |- _ => subst x2 || subst x1
end.