Finite list with unknown size - coq

I'm a bit confused trying to define some structures using the math-comp library. I want to define a structure that has a function ranging from a set of values and returning lists of other values. I'm trying to define this structure as finType but it is failing (I assume it is because I am returning a list of unknown size).
For example:
Section MySection.
Variables F V : finType.
Structure m := M {
f : {ffun F -> seq V};
...
}.
(* Using the PcanXXXMixin family of lemmas *)
Lemma can_m_of_prod : cancel prod_of_m m_of_prod.
Proof. by case. Qed.
...
Definition m_finMixin := CanFinMixin can_m_of_prod.
This throws the error Unable to unify.
I think the issue is that I am using seq and this is not finite. I am not sure how to describe that it will only return finite lists. I thought I might use n-tuples but this would require specifying a size beforehand (I could include the size along with the F value perhaps? I'm not sure how that would look in this notation).
Is there something I am missing or is there another approach that seems more adequate?
Thanks in advance!

I suggest you specify the bound function directly on the type. This is for example used in Stefania Dumbrava's PhD to bound the maximum arity of a signature and works well if you know the trick:
f : {ffun n -> (bound ...).-tuple A}
Usually bound := \max_S ..., so it works well with the rest of the theory.

Related

What is a concrete example of the type `Set` and what is the meaning of `Set`?

I've been trying to understand what Set is after encountering it in Adam Chlipala's book in addition to this great discussion in SO. His first example definition binary ops using Set:
Inductive binop : Set := Plus | Times.
in that book he says:
Second, there is the : Set fragment, which declares that we are defining a datatype that should be thought of as a constituent of programs.
Which confuses me. What does Adam mean here?
In addition, I thought that some additional concrete examples would help my understanding. I am not an expert of Coq so I am not sure what type of examples would help but something simple and very concrete/grounded might be useful.
Note, I have seen that Set is the first "type set" in a the type hierarchy e.g. Set = Type(0) <= Type = Type(1) <= Type(2) <= ... . I guess this sort of makes sense intuitively like I'd assume nat \in Type and all usual programming types to be in it but not sure what would be in Type that wouldn't be in Set. Perhaps recursive types? Not sure if that is the right example but I am trying to wrap my head around what this concept means and it's conceptual (& practical) usefulness.
Though Set and Type are different in Coq, this is mostly due to historical reasons. Nowadays, most developments do not rely on Set being different from Type. In particular, Adam's comment would also make sense if you replace Set by Type everywhere. The main point is that, when you want to define a datatype that you can compute with during execution (e.g. a number), you want to put it in Set or Type rather than Prop. This is because things that live in Prop are erased when you extract programs from Coq, so something defined in Prop would end up not computing anything.
As for your second question: Set is something that lives in Type, but not in Set, as the following snippet shows.
Check Set : Type. (* This works *)
Fail Check Set : Set.
(* The command has indeed failed with message: *)
(* The term "Set" has type "Type" while it is expected to have type *)
(* "Set" (universe inconsistency: Cannot enforce Set+1 <= Set). *)
This restriction is in place to prevent paradoxes in the theory. This is pretty much the only difference you see between Set and Type by default. You can also make them more different by invoking Coq with the -impredicative-set option:
(* Needs -impredicative-set; otherwise, the first line will also fail.*)
Check (forall A : Set, A -> A) : Set.
Universe u.
Fail Check (forall A : Type#{u}, A -> A) : Type#{u}.
(* The command has indeed failed with message: *)
(* The term "forall A : Type, A -> A" has type "Type#{u+1}" *)
(* while it is expected to have type "Type#{u}" (universe inconsistency: Cannot enforce *)
(* u < u because u = u). *)
Note that I had to add the Universe u. declaration to force the two occurrences of Type to be at the same level. Without this declaration, Coq would silently put the two Types at different universe levels, and the command would be accepted. (This would not mean that Type would have the same behavior as Set in this example, since Type#{u} and Type#{v} are different things when u and v are different!)
If you're wondering why this feature is useful, it is not by chance. The overwhelming majority of Coq developments does not rely on it. It is turned off by default because it is incompatible with a few axioms that are generally considered more useful in Coq developments, such as the strong law of the excluded middle:
forall A : Prop, {A} + {~ A}
With -impredicative-set turned on, this axiom yields a paradox, while it is safe to use by default.

instantiate parameters to evaluate function definitions

I'm working on a single .v file and I found it convenient to define things with parameters and definitions like this:
Parameter n : nat.
Definition n_plus_1 := n + 1.
rather than Definition n_plus_1 (n : nat) = n + 1.
My use cases are more complicated than this, but the idea is the same. Although defining things with parameters helped me write some proofs I'm interested in, sometimes I'd like to just test the definitions with actual values to make sure they actually compute what I intended. For example, with the example I just wrote, I can't do Compute n_plus_1 3. In some sense, I want to instantiate the parameter n. What'd be the best way to do it?
The quickest way is to use the Section mechanism [modules would also work]:
Section With_N.
Variable n : nat.
Definition n_plus_1 := n + 1.
End With_N.
Compute (n_plus_1 3).

Hint Rewrite Cannot Infer Parameter

I'm trying to create a Hint Rewrite database for a matrix library I've written. However when I write
Hint Rewrite kron_1_r : M_db
I get the following error:
Cannot infer the implicit parameter m of kron_1_r whose type is "nat".
kron_1_r has the type forall {m n : nat} (A : Matrix m n), A ⊗ Id 1 = A, so m and n should be inferred based on the context when autorewrite is called. I'm not sure why it wants a parameter here, or how to tell it to hold off.
You're running into the difference between maximally inserted implicit arguments and normal implicit arguments. The difference is exactly when you use a definition without giving any arguments, the way you are in Hint Rewrite kron_1_r. One solution is of course to use #kron_1_r, which gives the identifier without any implicit arguments.
Unfortunately there's no syntax when creating a definition to give it non-maximally inserted implicit arguments; you can only use {m : nat}. Instead, you'll need to use Arguments kron_1_r [m n] _. after creating kron_1_r to change the implicit behavior of the first two arguments (as suggested by Anton Trunov above).
It's often helpful to use About, which reports the status of implicit arguments (you get these with Print as well, but you usually get too much output when you print theorems since proof terms are large).

What exactly is a Set in Coq

I'm still puzzled what the sort Set means in Coq. When do I use Set and when do I use Type?
In Hott a Set is defined as a type, where identity proofs are unique.
But I think in Coq it has a different interpretation.
Set means rather different things in Coq and HoTT.
In Coq, every object has a type, including types themselves. Types of types are usually referred to as sorts, kinds or universes. In Coq, the (computationally relevant) universes are Set, and Type_i, where i ranges over natural numbers (0, 1, 2, 3, ...). We have the following inclusions:
Set <= Type_0 <= Type_1 <= Type_2 <= ...
These universes are typed as follows:
Set : Type_i for any i
Type_i : Type_j for any i < j
Like in Hott, this stratification is needed to ensure logical consistency. As Antal pointed out, Set behaves mostly like the smallest Type, with one exception: it can be made impredicative when you invoke coqtop with the -impredicative-set option. Concretely, this means that forall X : Set, A is of type Set whenever A is. In contrast, forall X : Type_i, A is of type Type_(i + 1), even when A has type Type_i.
The reason for this difference is that, due to logical paradoxes, only the lowest level of such a hierarchy can be made impredicative. You may then wonder then why Set is not made impredicative by default. This is because an impredicative Set is inconsistent with a strong form of the axiom of the excluded middle:
forall P : Prop, {P} + {~ P}.
What this axiom allows you to do is to write functions that can decide arbitrary propositions. Note that the {P} + {~ P} type lives in Set, and not Prop. The usual form of the excluded middle, forall P : Prop, P \/ ~ P, cannot be used in the same way, because things that live in Prop cannot be used in a computationally relevant way.
In addition to Arthur's answer:
From the fact that Set is located at the bottom of the hierarchy,
it follows that Set is the type of the “small” datatypes and function types, i.e. the ones whose values do not directly or indirectly involve types.
That means the following will fail:
Fail Inductive Ts : Set :=
| constrS : Set -> Ts.
with this error message:
Large non-propositional inductive types must be in Type.
As the message suggests, we can amend it by using Type:
Inductive Tt : Type :=
| constrT : Set -> Tt.
Reference:
The Essence of Coq as a Formal System by B. Jacobs (2013), pdf.

How do you define an ordered pair in Coq?

I am a programmer, but an ultra-newbie to Coq, and have tried to figure out the tutorials without much success. My question is very simple: How does one define an ordered pair (of natural numbers) in Coq?
Here was my attempt:
Variable node1 : nat.
Variable node2 : nat.
Inductive edge : type := node1 -> node2.
(Note that "edge" is the name I am using for ordered pair.) The third line gives a syntax error, suggesting that I need a '.' in the sentence somewhere.
I don't know what to do. Any help would be great! (Also, is there a tutorial that helps teach very basic Coq concepts better than the ones that are easily seen given a Google search for "Coq Tutorial" ?)
You can do this simply enough by just using a Coq definition:
Definition ordered_pair := (nat * nat) % type.
This introduces ordered_pair as a synonym for (nat * nat) % type (note that the % type is required to get Coq to interpret * in the scope of types, rather than naturals). The real power is in the use of *:
Inductive prod (A B:Type) : Type :=
pair : A -> B -> prod A B.
(From http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html)
You get all the necessary elimination principles, etc... from there.