How to Create Ensemble in Coq - coq

How do I create a set of elements in Coq?
I have looked at the documentation for Ensembles but I don't see any way to construct one. For example, in Haskell I'd use the "Data.Set.fromList [1..10]" to create a set with 10 elements. What's the equivalent in Coq?
Thanks.

As explained here, you can for example do something like
Require Import List Ensembles.
Fixpoint list_to_set {A:Type} (l : list A) {struct l}: Ensemble A :=
match l with
| nil => Empty_set A
| hd :: tl => Add A (list_to_set tl) hd
end.

Related

How to solve the very simple Syntax error: 'end' expected after [branches] (in [term_match]). in Coq? (in Gallina and not ltac)

I was trying to write a very simple program to sum nats in a list (copy pasted from here):
Fixpoint sum (l : list nat) : nat :=
match l with
| [] => 0
| x :: xs => x + sum xs
end.
but my local Coq and jsCoq complain:
Syntax error: 'end' expected after [branches] (in [term_match]).
Why is this? (note I didn't even implement this but my implementation looks the same pretty much)
I've implemented recursive functions before:
Inductive my_nat : Type :=
| O : my_nat
| S : my_nat -> my_nat.
Fixpoint add_left (n m : my_nat) : my_nat :=
match n with
| O => m
| S n' => S (add_left n' m)
end.
which doesn't complain...
I did see this question How to match a "match" expression? but it seems to address some special issue in ltac and I am not using ltac.
The location of the error is on the [], which suggests that Coq does not understand that notation. Upon finding undefined notation, the parser has no idea what to do and produces an essentially meaningless error message.
To have standard list notation be defined, you need to import it from the standard library via:
Require Import List.
Import ListNotations.
The stdlib module List contains the module ListNotations, which defines [] (and more generally [ x ; y ; .. ; z ]). List also defines the notation x :: xs.
when picking up excerpts from a development, you also have to find what are the syntax changing commands that have an effect on this exceprts: Module importation, scope opening, argument declarations (for implicits), Notations, and coercions". In the current case, the file is actually provided by the author of the exercises through this pointer.

Add ltac expression as hint to autorewrite?

I am trying to rewrite an environment using autorewrite. For simplicity we can assume it is a list (but in reality the type is more complex, has multiple cons constructors, and rewrite rules use equivalence rather than equality).
The normal form I want to get to is a concatenation of variables or singleton lists, i.e. x1 :: x2 :: xs ++ y :: ys to [x1] ++ [x2] ++ xs ++ [y] ++ ys. So far I had success rewriting other stuff by defining hints for autorewrite. However, the hint forall x xs, xs :: x = xs ++ [x] does not work, since [x] = x : [] which then can be rewritten to [x] ++ [] which gives an endless loop.
I don't have too much experience with writing custom Ltac expressions, but it seems like I would be able to define something like:
Ltac norm_cons :=
match goal with
| H: ?X : [] => idtac
| H: ?X : ?XS => (* actual rewrite *)
end.
This way we catch the [] in the first pattern and skip rewriting, and otherwise perform the rewrite. Maybe this needs a falltrough case, but this is not the point: how do I give (something like) this as a hint to autorewrite? I have tried to define the above as a separate tactic (where maybe I can define normalize as (norm_cons; autorewrite with blablabla).) but it then complains about none of the branches in the match matching to my goal. Does this do a recursive search? Or do I have to add this myself (i.e. matching ?XS ++ ?YS and recursively rewriting the lhs and rhs?)
It seems like you only want to rewrite lists with at least two elements. Perhaps you could rewrite with
forall x y xs, x :: y :: xs = [x] ++ y::xs

How can I match on a specific value in Coq?

I'm trying to implement a function that simply counts the number of occurrences of some nat in a bag (just a synonym for a list).
This is what I want to do, but it doesn't work:
Require Import Coq.Lists.List.
Import ListNotations.
Definition bag := list nat.
Fixpoint count (v:nat) (s:bag) : nat :=
match s with
| nil => O
| v :: t => S (count v t)
| _ :: t => count v t
end.
Coq says that the final clause is redundant, i.e., it just treats v as a name for the head instead of the specific v that is passed to the call of count. Is there any way to pattern match on values passed as function arguments? If not, how should I instead write the function?
I got this to work:
Fixpoint count (v:nat) (s:bag) : nat :=
match s with
| nil => O
| h :: t => if (beq_nat v h) then S (count v t) else count v t
end.
But I don't like it. I'd rather pattern match if possible.
Pattern matching is a different construction from equality, meant to discriminate data encoded in form of "inductives", as standard in functional programming.
In particular, pattern matching falls short in many cases, such as when you need potentially infinite patterns.
That being said, a more sensible type for count is the one available in the math-comp library:
count : forall T : Type, pred T -> seq T -> nat
Fixpoint count s := if s is x :: s' then a x + count s' else 0.
You can then build your function as count (pred1 x) where pred1 : forall T : eqType, T -> pred T , that is to say, the unary equality predicate for a fixed element of a type with decidable (computable) equality; pred1 x y <-> x = y.
I found in another exercise that it's OK to open up a match clause on the output of a function. In that case, it was "evenb" from "Basics". In this case, try "eqb".
Well, as v doesn't work in the match, I thought that maybe I could ask whether the head of the list was equal to v. And yes, it worked. This is the code:
Fixpoint count (v : nat) (s : bag) : nat :=
match s with
| nil => 0
| x :: t =>
match x =? v with
| true => S ( count v t )
| false => count v t
end
end.

Idiomatically expressing "The Following Are Equivalent" in Coq

Exercise 6.7 in Coq'Art, or the final exercise of the Logic chapter in Software Foundations: show that the following are equivalent.
Definition peirce := forall P Q:Prop, ((P->Q)->P)->P.
Definition classic := forall P:Prop, ~~P -> P.
Definition excluded_middle := forall P:Prop, P\/~P.
Definition de_morgan_not_and_not := forall P Q:Prop, ~(~P/\~Q)->P\/Q.
Definition implies_to_or := forall P Q:Prop, (P->Q)->(~P\/Q).
The solution set expresses this by a circular chain of implications, using five separate lemmas. But "TFAE" proofs are common enough in mathematics that I'd like to have an idiom to express them. Is there one in Coq?
This type of pattern is very easy to express in Coq, although setting up the infrastructure to do so might take some effort.
First, we define a proposition that expresses that all propositions in a list are equivalent:
Require Import Coq.Lists.List. Import ListNotations.
Definition all_equivalent (Ps : list Prop) : Prop :=
forall n m : nat, nth n Ps False -> nth m Ps True.
Next, we want to capture the standard pattern for proving this kind of result: if each proposition in the list implies the next one, and the last implies the first, we know they are all equivalent. (We could also have a more general pattern, where we replace a straight list of implications with a graph of implications between the propositions, whose transitive closure generates a complete graph. We'll avoid that in the interest of simplicity.) The premise of this pattern is easy to express; it is just a code transcription of the English explanation above.
Fixpoint all_equivalent'_aux
(first current : Prop) (rest : list Prop) : Prop :=
match rest with
| [] => current -> first
| P :: rest' => (current -> P) /\ all_equivalent'_aux first P rest'
end.
Definition all_equivalent' (Ps : list Prop) : Prop :=
match Ps with
| first :: second :: rest =>
(first -> second) /\ all_equivalent' first second rest
| _ => True
end.
The difficult part is showing that this premise implies the conclusion we want:
Lemma all_equivalentP Ps : all_equivalent' Ps -> all_equivalent Ps.
Showing that this lemma holds probably requires some ingenuity to find a strong enough inductive generalization. I can't quite prove it right now, but might add a solution later to the answer if you want.

Counting number of different elements in a list in Coq

I'm trying to write a function that takes a list of natural numbers and returns as output the amount of different elements in it. For example, if I have the list [1,2,2,4,1], my function DifElem should output "3". I've tried many things, the closest I've gotten is this:
Fixpoint DifElem (l : list nat) : nat :=
match l with
| [] => 0
| m::tm =>
let n := listWidth tm in
if (~ In m tm) then S n else n
end.
My logic is this: if m is not in the tail of the list then add one to the counter. If it is, do not add to the counter, so I'll only be counting once: when it's the last time it appears. I get the error:
Error: The term "~ In m tm" has type "Prop"
which is not a (co-)inductive type.
In is part of Coq's list standard library Coq.Lists.List. It is defined there as:
Fixpoint In (a:A) (l:list A) : Prop :=
match l with
| [] => False
| b :: m => b = a \/ In a m
end.
I think I don't understand well enough how to use If then statements in definitions, Coq's documentation was not helpful enough.
I also tried this definition with nodup from the same library:
Definition Width (A : list nat ) := length (nodup ( A ) ).
In this case what I get as error is:
The term "A" has type "list nat" while it is expected to have
type "forall x y : ?A0, {x = y} + {x <> y}".
And I'm quiet confused as to what's going on here. I'd appreciate your help to solve this issue.
You seem to be confusing propositions (Prop) and booleans (bool). I'll try to explain in simple terms: a proposition is something you prove (according to Martin-Lof's interpretation it is a set of proofs), and a boolean is a datatype which can hold only 2 values (true / false). Booleans can be useful in computations, when there are only two possible outcomes and no addition information is not needed. You can find more on this topic in this answer by #Ptival or a thorough section on this in the Software Foundations book by B.C. Pierce et al. (see Propositions and Booleans section).
Actually, nodup is the way to go here, but Coq wants you to provide a way of deciding on equality of the elements of the input list. If you take a look at the definition of nodup:
Hypothesis decA: forall x y : A, {x = y} + {x <> y}.
Fixpoint nodup (l : list A) : list A :=
match l with
| [] => []
| x::xs => if in_dec decA x xs then nodup xs else x::(nodup xs)
end.
you'll notice a hypothesis decA, which becomes an additional argument to the nodup function, so you need to pass eq_nat_dec (decidable equality fot nats), for example, like this: nodup eq_nat_dec l.
So, here is a possible solution:
Require Import Coq.Arith.Arith.
Require Import Coq.Lists.List.
Import ListNotations.
Definition count_uniques (l : list nat) : nat :=
length (nodup eq_nat_dec l).
Eval compute in count_uniques [1; 2; 2; 4; 1].
(* = 3 : nat *)
Note: The nodup function works since Coq v8.5.
In addition to Anton's solution using the standard library I'd like to remark that mathcomp provides specially good support for this use case along with a quite complete theory on count and uniq. Your function becomes:
From mathcomp Require Import ssreflect ssrfun ssrbool eqtype ssrnat seq.
Definition count_uniques (T : eqType) (s : seq T) := size (undup s).
In fact, I think the count_uniques name is redundant, I'd prefer to directly use size (undup s) where needed.
Using sets:
Require Import MSets.
Require List. Import ListNotations.
Module NatSet := Make Nat_as_OT.
Definition no_dup l := List.fold_left (fun s x => NatSet.add x s) l NatSet.empty.
Definition count_uniques l := NatSet.cardinal (no_dup l).
Eval compute in count_uniques [1; 2; 2; 4; 1].