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.
Related
I was looking at IndProp and I saw:
Fail Inductive wrong_ev (n : nat) : Prop :=
| wrong_ev_0 : wrong_ev 0
| wrong_ev_SS : ∀ n, wrong_ev n → wrong_ev (S (S n)).
(* ===> Error: A parameter of an inductive type n is not
allowed to be used as a bound variable in the type
of its constructor. *)
except that it seems to behave exactly as if it was taking an argument but it seems to throw an error. Why is this?
The text provides some explanation but I don't understand it:
what I don't understand specifically it. The part I don't understand is the part it says:
it is allowed to take different values in the types
why is it saying "in the types"? Types are NOT the input, values are. Why is it saying this? It seems extremely confusing. I know (extremely vaguely) that there is such a thing as "dependent types" but is that what it's referring too? Shouldn't it be arguments? Don't constructors take value or "stuff" and return an object of some type?
Why does it seem that the signature of the Inductive type (which really I just view it as a function that builds things are returns objects of some type) missing the arguments?
More context from text where explanation seems to appear:
This definition is different in one crucial respect from previous uses of Inductive: its result is not a Type, but rather a function from nat to Prop — that is, a property of numbers. Note that we've already seen other inductive definitions that result in functions, such as list, whose type is Type → Type. What is new here is that, because the nat argument of ev appears unnamed, to the right of the colon, it is allowed to take different values in the types of different constructors: 0 in the type of ev_0 and S (S n) in the type of ev_SS.
In contrast, the definition of list names the X parameter globally, to the left of the colon, forcing the result of nil and cons to be the same (list X). Had we tried to bring nat to the left in defining ev, we would have seen an error ... We can think of the definition of ev as defining a Coq property ev : nat → Prop, together with primitive theorems ev_0 : ev 0 and ev_SS : ∀n, ev n → ev (S (S n)).
Such "constructor theorems" have the same status as proven theorems.
why is it saying "in the types"? Types are NOT the input, values are
You need to read the whole expression: "in the types of different constructors".
And, indeed, the natural number is different in the return type of the two constructors:
It is 0 for ev_0
And it is S (S n) for ev_SS
I am reading http://adam.chlipala.net/cpdt/html/Hoas.html and I am trying to understand this Coq code regarding parametric HOAS (Higher Order Abstract Syntax):
Inductive Closed : forall t, Exp t -> Prop :=
| CConst : forall n,
Closed (Const n)
| CPlus : forall E1 E2,
Closed E1
-> Closed E2
-> Closed (Plus E1 E2)
| CApp : forall dom ran (E1 : Exp (dom --> ran)) E2,
Closed E1
-> Closed E2
-> Closed (App E1 E2)
| CAbs : forall dom ran (E1 : Exp1 dom ran),
Closed (Abs E1).
I have several questions regarding it:
How it is possible to repeat the type name Closed inside the bodies of constructors? Is this some kind of recursive declaration (without the starting of ending condition?)? Or maybe Inductive definitions come in two flavours: 1) usual type definitions; 2) some kind of statement about type? And this code is statement about type, not definition.
What is meant by this type Closed? Usually I can imagine that parametric HOAS is about enhancing of initial types. So, I expect, that Closed is more enhanced type and I could define constant John : Closed. But actually it is derived from Exp t -> Prop and so, it seems to me, that this is not enhancement of initial type but this is statement (predicate) about expressions of initial type. And the structure of this predicate reflects the structure of the terms of initial type and that is why it can be somehow used for structural induction.
I am also reading https://coq.inria.fr/distrib/current/refman/language/gallina-specification-language.html#coq:cmd.definition chapter "Simple annotated inductive types" but I can not understand how it is possible to use type name inside the constructors.
Repeating the name of the type is perfectly fine in Coq; this is simply defining a recursive data type. Consider the definition of the natural numbers in the standard library:
Inductive nat : Type :=
| O : nat
| S : nat -> nat.
This says that the nat type is generated by two constructors O and S. The recursive occurrence in the type of S means that we can use previously built natural numbers to construct other natural numbers; e.g.
Definition zero : nat := O.
Definition one : nat := S zero.
Definition two : nat := S one.
etc. The example that you gave, Closed, is a bit different, because it defines an inductive family of propositions instead of a typical data type like natural numbers or lists. This family is indexed by terms of type Exp t for any t. Besides these differences, the recursive occurrences behave pretty much the same as the case of nat. For instance, the CPlus constructor says that, in order to show that Closed (Plus E1 E2) holds, we need to show that Closed E1 and Closed E2 hold.
I do not understand what you mean by "enhancing a type" or "initial type", but as far as I can tell Closed E is a proposition stating that the expression E : Exp t does not have free variables.
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.
What does the keyword/command "Some" mean in coq?
Furthermore, how can I look up its definition? Using coq some doesn't really help much given popularity of the word some.
Some is a type constructor of the option type. You can get some infos about such constructor by Checking or Printing them, to get their type or their full implementation.
Edit: what is the option type.
It is a type defined in Coq's prelude (again, use Check or Print to get info on this type). The type is used to state facts about the optional presence of a type: for any type A, None : option A means that there is no value, and Some A: option A means that there is a value (of type A).
Here is an example with the predecessor of a natural number:
Definition myPred (n:nat) : option nat := match n with
| S p => Some p
| O => None
end.
In this example, if you try to compute the predecessor of O, you'll get None (there is no such natural number). Otherwise, you get Some p such that S p = n.
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.