I'm getting a type error in the last line of the following program:
Require Import List.
Import ListNotations.
(* This computes to 10 *)
Compute (fold_right plus 0 [1;2;3;4]).
(* I want this to compute to [5;6;7;8] but it gives a type error instead *)
Compute (fold_right app [] [[5;6]; [7;8]]).
This is the error I get:
Error:
The term "app" has type "forall A : Type, list A -> list A -> list A" while it is expected to have type
"Type -> ?A -> ?A" (cannot instantiate "?A" because "A" is not in its scope).
I don't really understand why I am getting this error. What is different between app and plus here?. Does it have to do with app being polymorphic while plus is a monomorphic nat -> nat -> nat function?
In case that matters, my version of Coq is 8.5.
You guessed it right: it does have something to do with app being polymorphic. The problem is that Coq allows implicit arguments to be inferred differently depending on whether the corresponding term is applied to arguments or not. More precisely, non-maximal implicits are only inserted when the term is applied to something, but not inserted if the term is used on its own, like your app. There are two ways to remedy the situation:
1- Force Coq to infer something for that instance, as in fold_right (#app _) [] [[5; 6]; [7; 8]].
2- Use a global declaration that will make the type argument maximally inserted: Arguments app {_} _ _.. For more details on what this is doing, check the reference manual
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 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'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 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 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.