I have the following function in Coq. Now I want to define an instance as below. In my case, equivalence [==] on type [nat] is defined but not on [StringMap.t String.t]. Please if you solve the Instace SC_Proper. Thanks.
Definition SC (u: nat) (zm: StringMap.t String.t):
StringMap.t String.t :=
match u with
| S p => match p with
| 2 => zm
| _ =>
match StringMap.find "S" zm with
| Some k => StringMap.empty
| _ => zm
end
end
| O => zm
end.
Instance SC_Proper
: Proper (equiv ==> equiv ==> equiv) SC.
Proof with o.
repeat red. intros u u' Hu zm1 zm2 Hzm.
Admitted.
Related
First and foremost, I'm not yet very familiar with Coq lingo, so I will use terms like e.g. 'expression' and 'variable' loosely, but they are probably not the correct Coq terms.
I'm trying to prove the following subgoal of a Theorem.
1 goal
b : bag
v, b' : nat
b'' : natlist
B : b = b' :: b''
IHb'' : b = b'' -> count v (add v b'') = count v b'' + 1
______________________________________(1/1)
S match v =? b' with
| true => S (count v b'')
| false => count v b''
end = match v =? b' with
| true => S (count v b'')
| false => count v b''
end + 1
You can ignore S and + 1, I'm basically looking for a way to assign
match v =? b' with
| true => S (count v b'')
| false => count v b''
end
to a variable of type nat because it occurs on both sides of the equation.
How can I do this? Or do I need to go through destroying v and b' and proving all cases separately?
Here are two possibilities. There may well be better ones.
You can use set to give a name to a term. All the occurrences of that term are replaced by the variable.
set (x := match v =? b' with
| true => S (count v b'')
| false => count v b''
end).
Sometimes you need to hide the definition of the variable, and only remember it as an equality that you invoke on demand. For that, use remember.
You can match the goal against a pattern using the context form of match goal and give a name to whatever's inside that pattern.
match goal with |- context [S ?_x = ?_x + 1] => set (x := _x) end.
If this is your real goal and not a simplified example, it's a simple arithmetic statement and you can just call lia and let Coq figure it out.
Require Import Lia.
…
lia.
Besides Gilles's suggestions you can use the ssreflect set to achieve this, in at least two ways illustrated here:
Require Import Arith ssreflect.
Variables v b' b'' : nat.
Variable count : nat -> nat -> nat.
Goal
S match v =? b' with
| true => S (count v b'')
| false => count v b''
end
= match v =? b' with
| true => S (count v b'')
| false => count v b''
end + 1.
Proof.
set t := (X in S X = X + _).
Undo.
set t := match _ with true => _ | false => _ end.
Abort.
The latter one also works with the regular set but it needs brackets:
set (t := match _ with true => _ | false => _ end).
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.
Can anyone tell me why the following projection function in COQ doesn't work?
Require Import Vector.
Require Import Fin.
Definition Proj {n:nat}{p:nat}(x:t p+{(exists m : nat, n=p+m)}):=
match x with
inleft y => y
|_ => F1
end.
I get the following error:
Error:
In environment
n : nat
p : nat
x : t p + {(exists m : nat, n = p + m)}
e : exists m : nat, n = p + m
The term "F1" has type "t (S ?6 (* [n, p, x, e, e] *))"
while it is expected to have type "t p".
On the other hand, using concrete values for p works fine:
Require Import Vector.
Require Import Fin.
Definition Proj {n:nat}(x:t 3 + {(exists m : nat, n=3+m)}):=
match x with
inleft y => y
|_ => F1
end.
Eval compute in (Proj (of_nat 2 3)) = FS (FS F1): t 3.
I'm assuming that you want Proj to return a value of type t p. That is impossible for p = 0 (because t 0 is the empty set), and that's why you cannot implement Proj for arbitrary p. If you extend you function to take a proof that p is not equal to 0, then you can implement it as follows. Read Adam's CPDT Chapter on Dependent Types to understand what is going on here.
Definition Proj {n:nat} {p:nat} (x:t p+{(exists m : nat, n=p+m)}) : p <> 0 -> t p :=
match x with
| inleft y => fun _ => y
| _ => match p with
| 0 => fun h => False_rect _ (h eq_refl)
| S _ => fun _ => F1
end
end.
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.
I am trying to develop a programming style that is based on preventing bad input as soon as possible. For example, instead of the following plausible definition for the predecessor function on the natural numbers:
Definition pred1 n :=
match n with
| O => None
| S n => Some n
end.
I want to write it as follows:
Theorem nope n (p : n = O) (q : n <> O) : False.
contradict q.
exact p.
Qed.
Definition pred2 n (q : n <> O) :=
match n with
| S n => n
| O =>
let p := _ in
match nope n p q with end
end.
But I have no idea what to replace _ with. My intuition suggests me that there must be some assumption : n = O available in the | O => branch. Does Coq indeed introduce such an assumption? If so, what is its name?
Coq doesn't automatically introduce such hypothesis, but you can introduce it explicitly by using the full form of the match construction:
Definition pred2 n (q : n <> O) :=
match n as n' return n = n' -> nat with
| S p => fun _ => p
| O => fun Heq => match q Heq with end
end (eq_refl n).
Explanations:
return introduces a type annotation with the type of the whole match ... end expression;
as introduces a variable name that can be used in this type annotation and will be substituted with the left hand side in each branch. Here,
in the first branch, the right hand side has type n = S p -> nat;
in the second branch, the right hand side has type n = O -> nat. Therefore, q Heq has type False and can be matched.
More information in the reference manual, in the chapter on Extended pattern-matching.