In Coq, sig
is defined as
Inductive sig (A:Type) (P:A -> Prop) : Type :=
exist : forall x:A, P x -> sig P.
Which I read as
"A sig P is a type, where P is a function taking an A and returning a Prop. The type is defined such that an element x of type A is of type sig P if P x holds."
proj1_sig
is defined as
Definition proj1_sig (e:sig P) := match e with
| exist _ a b => a
end.
I'm not sure what to make of that. Could somebody provide a more intuitive understanding?
Non-dependent pairs vs.
sig
That is not entirely correct : we can't say
x : sig A P
. An inhabitante
of typesig A P
is essentially a pair of an elementx : A
and a proof thatP x
holds (this is called a dependent pair).x
andP x
are "wrapped" together using the data constructorexist
.To see this let us first consider the non-dependent pair type
prod
, which is defined as follows:prod
's inhabitants are pairs, likepair 1 true
(or, using notations,(1, true)
), where the types of both components are independent of each other.Since
A -> B
in Coq is just syntactic sugar forforall _ : A, B
(defined here), the definition ofprod
can be desugared intoThe above definition, perhaps, can help to see that elements of
sig A P
are (dependent) pairs.What we can derive from implementation and type of
proj1_sig
From the implementation we can see that
proj1_sig e
unpacks the pair and returns the first component, viz.x
, throwing away the proof ofP x
.The
Coq.Init.Specif
module contains the following comment:If we look at the type of
proj1_sig
we will see that
proj1_sig
gives us a way of recovering an element of a supersetA
from its subset{x : A | P x}
.Analogue between
fst
andproj1_sig
Also, we can say that in some sense
proj1_sig
is analogous to thefst
function, which returns the first component of a pair:There is a trivial property of
fst
:We can formulate a similar statement for
proj1_sig
: