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.
Related
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.
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.
I'm a little bit new to Coq, and I'm trying to do some formalization on regular grammars within Coq. Let's say I have an inductive type as follows:
Inductive rules : non_terminal -> list(non_terminal + terminal) -> Type :=
rule1 : rules S [inr a; inl S]
| rule2 : rules S [inr b;inl S]
| rule3 : rules S [].
Which represents the (a* b*) grammar's derivation rules. Let's say I want to extract them for some later use. Is there any way I could do this and store it in a list of lists? e.g., I'd like a procedure that would return me [[S [inr a; inl S];S [inr b;inl S];[]]. Any other idea will be appreciated.
Thanks in advance.
You could try using Ltac2, which can programmatically get information about inductive types? You can also use the template-coq package/plugin. These are probably not actually what you want to be doing here, though, since it's a bit convoluted.
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.
I am trying to defined an inductive data type to hold pair of natural numbers. Here is what I have done
Definition ordered_pair := (nat * nat) % type.
Inductive nat_pair(A B:nat):ordered_pair:=
|pair :ordered_pair->ordered_pair.
It generates exception
Anomaly: Uncaught exception Reduction.NotArity. Please report.
Does anyone know there?
This inductive definition just does not make sense.
The type ordered_pair you have defined is already a type for pairs of natural numbers.
It is defined as the pair type, applied to arguments of type nat, so to build such a pair you could do:
Definition p : ordered_pair := (23, 42).
Now if you wanted to define a "similar" (but not "identical") type inductively, the syntax would be:
Inductive nat_pair : Set :=
| pair : nat -> nat -> nat_pair
.
Notice that you don't take natural numbers as parameters in the type, but rather the constructor contains two such numbers.
You seem to have some misunderstanding of inductive definitions, so I'd suggest reading more about them.