My function foo has an implicit argument coming from its section :
Section Foosec.
Context {A: Type}.
Parameter foo : nat -> A -> A.
End Foosec.
Outside of the section, #foo has type ∀ A : Type, ℕ → A → A. Is there a way to tell Coq to generate a function of type ℕ → ∀ A : Type, A → A instead? i.e. to insert the implicit argument as late as possible? It would make the definition of partial applications much simpler.
Or, with a more pragmatic approach, is there something like #(foo 1)?
As far as I am aware, there is no way of swapping the order of the arguments generated by the section mechanism in Coq. Maybe if you tried to give more details about how you want to use this partially applied function we could find ways of circumvent this limitation...
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'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
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.
Suppose that I have a set of functions, each of which can depend on one or two implicit variables A B: Type. How can I specify this? I.e. add these variables to their variable list and set them as implicit.
The most obvious way is to add {A B: Type} to their definitions. However, in real life and moderately complicated developments such shared lists of implicits can easily be 6-10 entries long and include complicated types, thus making function definitions hard to read and even harder to understand their similarity or make change to mentioned types. Thus this solution is not applicable.
I could include all functions in a section or module and write Variables (A B: Type) etc in the beginning, but that would not make variables implicit and I would have to manually set arguments for all functions at the end of section. Even worse, that would make all variables shared. I.e. if I declare
Section sect.
Variable A B: Type.
Definition f (t: A -> Type) := (..).
Definition g (t: A -> Type) (s: B -> Type) := G (f t) (f s).
End sect.
(G is some two-variable function) then g would not be accepted, since s is not in A -> Type, even though essentially f requires only an arbitrary type family.
I could make a section and declare Context {A B: Type}. That would make those variables implicit for all functions, but the sharing problem like in previous case would still remain. Thus I would have to arbitrarily split my functions into several sections so that I could call functions from Sect.1 with different values of their implicit arguments. This works, but is ugly, and I can easily imagine a situation where each section would have to be 2-3 functions long just so that I could call them properly.
Is there a better solution?
There are two things you can do that are less difficult:
Generalizable All Variables.
Definition g `(t: A -> Type) `(s: B -> Type) := G (f t) (f s).
Now you can use backtick, and it will automatically insert the implicit variables you need to make the definition valid. This is the most common way that I introduce implicits.
The other way is to follow your section with:
Arguments g : default implicits.
You'll need to repeat this for every defined term, but at least you don't need to name all of the arguments.