Proofs about constructors matched with _ - coq

Assume I have the following Set:
Inductive Many : Set :=
| aa: Many
| bb: Many
| cc: Many
(* | ... many more constructors *)
.
How can I proof in the _ match, that y<>aa?
match x with
| aa => true
| _ as y => (* how can i proof that y <> aa ? *)

Unfortunately, it does not seem possible to get such a proof without some more work in pure Gallina. What you would like to write is:
match x with
| aa => true
| y =>
let yNOTaa : y <> aa := fun yaa =>
eq_ind y (fun e => match e with aa => False | _ => True end) I aa yaa
in false
end
But that does not work quite well in Gallina, as it does not expand the wildcard into all possible cases, leaving y abstract in the eq_ind invocation. It does however work in tactic mode:
refine (
match x with
| aa => true
| y =>
let yNOTaa : y <> aa := fun yaa =>
eq_ind y (fun e => match e with aa => False | _ => True end) I aa yaa
in false
end
).
But it actually builds the expanded term with all the branches.
I just found out that there is a way to have the Vernacular build the same term that the refine tactic would build. To do so, you have to force a return annotation mentioning the discriminee, like so:
Definition foo (x : many) : bool :=
match x return (fun _ => bool) x with
| aa => true
| y =>
let yNOTaa : y <> aa := fun yaa : y = aa =>
#eq_ind many y (fun e => match e with aa => False | _ => True end) I aa yaa
in false
end
.
My guess is that the term elaboration differs whether the match is dependent or not...

Related

Coq - Assign expression to variable

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

how to code in coq a function that sum the integers represented by the 2 lists and boolean representing a holdback?

I want to set the recursive function badd_r: list bool -> list bool -> bool -> list bool that sum the integers represented by the 2 lists and boolean representing a holdback.
I need to use these two functions b1add_r(sum of two lists), bsucc(successor of a binary number represented by a list of booleans).
Here are the two functions:
Fixpoint bsucc (l: list bool): list bool :=
match l with
| [] =>[true]
| true::r => false:: (bsucc r)
| false::r => true::r
end.
Definition b1add_r b1 b2 r :=
match b1,b2 with
true, true => (r,true)
| true,false => (negb r, r)
| false, true => (negb r,r)
| false,false => (r, false)
end.
I have no idea how to code this function in coq and how to prove it...
Lemma badd_rOK: forall l1 l2 r,
value (badd_r l1 l2 r) = value l1 + value l2 + (if r then 1 else 0).
Fixpoint value (l: list bool) :=
match l with
| [] => 0
| true :: r => 1 + 2 * value r
| false :: r => 2 * value r
end.
Any help would be appreciated!
Your function may have the following form:
Fixpoint badd_r (l1 l2:list bool) (r : bool) : list bool :=
match l1, l2 with
nil, nil => (* base case 1 *)
| a::r1, nil => (* base case 2 *)
| nil, b::r2 => (* base case 3 *)
| a::r1, b:: r2 => let (c, r') := b1add_r a b r
in (* recursive case *)
end.
In order to fill the holes/comments, and plan to prove correctness, you may relate arithmetic properties with the possible cases.
For instance, the equality (1+2*x)+(0+2*y)+1= 0+2(x+y+1) corresponds to the case add_r (true::r) (false::s) true = false :: (add_r r s true)

Instance of Ord typeclass for option

In volume 4 of Software foundations "QuickChick" we have the following excercise:
Class Ord A `{Eq A} : Type :=
{
le : A -> A -> bool
}.
(* Define [Ord] instances for options and pairs. *)
(* So I am trying to do it *)
Instance optionOrd {A : Type} `{Ord A} `{Eq (option A)} : Ord (option A) :=
{
le := fun (opt1 opt2 : option A) =>
match opt1 with
| None => match opt2 with
| None => true
| Some a => true
end
| Some a1 => match opt2 with
| None => false
| Some a2 => le a1 a2
end
end.
}.
But get an error:
Error: Syntax error: '}' expected after [constr:record_declaration]
(in [vernac:gallina_ext]).
And it highlights match opt1 with.
Maybe, my solution is quite primitive: it just pattern matches all possible cases. Is there anything better?
What causes this syntax error?
Just remove the . after the last end.

How to match a "match" expression?

I am trying to write a rule for hypotheses, formulated with a help of match construction:
Goal forall x:nat, (match x with | 1 => 5 | _ => 10 end = 5 -> x = 1)%nat.
intros.
x : nat
H : match x with
| 0%nat => 10%nat
| 1%nat => 5%nat
| S (S _) => 10%nat
end = 5%nat
============================
x = 1%nat
How can I match such hypotheses ? The following straight forward method fails:
match goal with
|[H:match ?e with | ?a => ?x | ?b => ?y | ?c => ?z end = ?b] => idtac
end.
> Syntax error: 'end' expected after [branches] (in [match_constr]).
Pattern-matching on match statements is somewhat weird.
The first thing you should know is that, inside Coq, there's no such thing as a match on several variables or with deep matching: everything is translated in terms of simpler match statements. Thus, the term you wrote is actually syntax sugar for the following term:
match x with
| 0 => 10
| S x' =>
match x' with
| 0 => 5
| S x'' => 10
end
end
which is what Coq is hinting at when it prints your proof state. The problem is that this syntax sugar doesn't work on Ltac patterns: thus, when writing an Ltac pattern that mentions a match, you should always try to match it as if it were a one-level match.
The second problem is that you can't bind the pattern part of a match: something like
match goal with
| H : match ?x => _ | ?y => _ end = 5 |- _ => (* ... *)
end
doesn't really make sense in Ltac.
You have two choices for solving your problem, then:
Write down the match you expect with the exact list of constructors of your type on the pattern part, e.g.
match goal with
| H : match x with 0 => _ | S _ => _ end = 5 |- _ => (* ... *)
end
Use the special match (* ... *) with _ => _ end syntax, which matches any match whatsoever:
match goal with
| H : match x with _ => _ end = 5 |- _ => (* ... *)
end
Often, as in your case, one still wants to consider all branches of match, including deep ones. This idiom often comes in handy in that case:
repeat match goal with
| H : match ?x with _ => _ end = _ |- _ =>
destruct x; try solve [inversion H]
end.

Morphism - Setoid on non-convertible terms in Coq

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.