I'm trying to define a function on a weakly-specified type in Coq. Specifically, I have a type that is defined inductively by a set of recursive constructors, and I want to define a function that is only defined when the argument has been constructed using a subset of these.
To be more concrete, I have the following type definition:
Inductive Example : Set :=
| Example_cons0 : nat -> Example
| Example_cons1 : Example -> Example
.
Now, I have a function that only applies to the ground case. (The following definition will not work obviously, but is meant to suggest my intent.)
Definition example (x:Example) : nat :=
match x with
| Example_cons0 n => n
end.
Ideally, I'd like to communicate that my argument, x, has been constructed using a subset of the general type constructors, in this case, Example_cons0. I thought that I could do this by defining a predicate that states this fact and passing a proof of the predicate as an argument. For example:
Definition example_pred (x:Example) : Prop :=
match x with
| Example_cons0 _ => True
| _ => False
end.
And then (following the recommendation given by Robin Green) something like,
Definition example2 (x:Example) : example_pred x -> nat :=
(use proof to define example2?)
Unfortunately, I'm not sure how I would go about doing any of this. I'm not even sure that this is the correct way to define restricted functions on weakly-specified types.
Any guidance, hints, or suggestions would be strongly appreciated! - Lee
Update:
Following recommendations by jozefg, the example function can be defined as:
Definition example (x:Example) : example_pred x -> nat :=
match x with
| Example_cons0 n => fun _ => n
| _ => fun proof => match proof with end
end.
See his comments for details. This function can be evaluated using the following syntax, which also demonstrates how proof terms are represented in Coq:
Coq < Eval compute in Example.example (Example.Example_cons0 0) (I : Example.example_pred (Example.Example_cons0 0)).
= 0
: nat
Here's how I'd write this as a simplified example
Consider a simple data type
And now we define a helpful function
And finally what you want to write:
This has the type
forall f : Foo, bar f -> nat. This works by making sure that in the case thatexamplewas not supplied aBar, that the user must supply a proof of false (impossible).This can be called like this
But the problem is, you may have to manually prove some term is constructed by
Bar, otherwise how is Coq supposed to know?