I am trying to define Fibonacci numbers using coq. This is my code:
Fixpoint fibonacci (n:nat) : nat :=
match n with
| O => 1
| S O => 1
| S (S n') => fibonacci (S n') + fibonacci n
end.
I met the error message:
Recursive definition of fibonacci is ill-formed. In environment
fibonacci : nat -> nat n : nat n0 : nat n' : nat Recursive call to
fibonacci has principal argument equal to "S n'" instead of one of
the following variables: "n0" "n'". Recursive definition is: "fun n :
nat => match n with | S (S n') => fibonacci (S n') + fibonacci n |
_ => 1 end".
I am wondering why this is wrong. Parenthetically, in the third clause of the match, I did not define the property of n' (e.g. n': nat), what would be the default of the property of n'?
Thanks in advance!
All arguments of a recursive call must be structurally decreasing, that is you must strip away one constructor symbol in the match. In your case the (S n') argument is in fact structurally decreasing, but Coq doesn't detect that (which is a bit silly) because you add another constructor S, which is not allowed. The second argument is wrong and should probably be n'. Besides one usually defines this such that fibonacci 0 = 0.
To get around the issue of (S n') one gives it a separate name with as as in:
Require Import List.
Fixpoint fibonacci (n:nat) : nat :=
match n with
| O => 0
| S O => 1
| S (S O) => 1
| S ((S n'') as n')=> fibonacci n' + fibonacci n''
end.
Eval cbv in map fibonacci (seq 0 10).
Related
In Software Foundations, they discuss how to build you own proof objects for induction:
https://softwarefoundations.cis.upenn.edu/lf-current/IndPrinciples.html#nat_ind2
Definition nat_ind2 :
∀ (P : nat → Prop),
P 0 →
P 1 →
(∀ n : nat, P n → P (S(S n))) →
∀ n : nat , P n :=
fun P ⇒ fun P0 ⇒ fun P1 ⇒ fun PSS ⇒
fix f (n:nat) := match n with
0 ⇒ P0
| 1 ⇒ P1
| S (S n') ⇒ PSS n' (f n')
end.
I experimented with this definition by commenting out "| 1 ⇒ P1". Coq then gives an error: "Non exhaustive pattern-matching: no clause found for pattern 1." I was expecting an error, of course. But I don't know how Coq figures out there is an error.
I would like to know how Coq does the exhaustiveness matching to know that 1 needs to be checked, since 1 isn't part of the constructor for nat. Roughly what algorithm is Coq following?
I'm not sure it answers fully your question, but you may look at the way "extended" matching are dealt with (see for instance https://coq.inria.fr/distrib/current/refman/language/extensions/match.html#mult-match ).
Let's look at a simple example.
Definition f (n: nat): nat :=
match n with
2 => 2
| 1 => 23
| _ => S n
end.
With the following command, I can see how f is expressed through simple pattern matchings.
Unset Printing Matching.
Print f.
(*
f =
fun n : nat =>
match n with
| 0 => S n
| S n0 =>
match n0 with
| 0 => 23
| S n1 => match n1 with
| 0 => 2
| S _ => S n
end
end
end
: nat -> nat
*)
If you remove the clause for 1 from your example, it seems impossible to
convert your match into nested simple 0 | S _ matchings `.
I was going through the Coq book from the maths perspective. I was trying to define a dependently typed function that returned a length list with n trues depending on the number trues we want.
Coq complains that things don't have the right type but when I see it if it were to unfold my definitions when doing the type comparison it should have worked but it doesn't. Why?
Code:
Module playing_with_types2.
Inductive Vector {A: Type} : nat -> Type :=
| vnil: Vector 0
| vcons: forall n : nat, A -> Vector n -> Vector (S n).
Definition t {A: Type} (n : nat) : Type :=
match n with
| 0 => #Vector A 0
| S n' => #Vector A (S n')
end.
Check t. (* nat -> Type *)
Check #t. (* Type -> nat -> Type *)
(* meant to mimic Definition g : forall n: nat, t n. *)
Fixpoint g (n : nat) : t n :=
match n with
| 0 => vnil
| S n' => vcons n' true (g n')
end.
End playing_with_types2.
Coq's error:
In environment
g : forall n : nat, t n
n : nat
The term "vnil" has type "Vector 0" while it is expected to have type
"t ?n#{n1:=0}".
Not in proof mode.
i.e. t ?n#{n1:=0} is Vector 0...no?
In this case, it looks like Coq does not manage to infer the return type of the match expression, so the best thing to do is to give it explicitly:
Fixpoint g (n : nat) : t n :=
match n return t n with
| 0 => vnil
| S n' => vcons n' true (g n')
end.
Note the added return clause.
Then the real error message appears:
In environment
g : forall n : nat, t n
n : nat
n' : nat
The term "g n'" has type "t n'" while it is expected to have type "Vector n'".
And this time it is true that in general t n' is not the same as Vector n' because t n' is stuck (it does not know yet whether n' is 0 or some S n'').
Suppose I write a Fixpoint algorithm in Coq that sums up all the "halves" of a number:
Fixpoint sum_of_halves (a : nat) : nat :=
match a with
| 0 => 0
| 2 * k => a + (sum_of_halves k)
| S (2 * k) => a + (sum_of_halves k)
end.
Trying to evaluate the algorithm would get: Error: Invalid notation for pattern.
How can I get Coq to recognize that a is either an even or an odd number, and match it with either 2 * k or S (2 * k)?
Coq can only match on constructors. nat has two constructors, O and S, so you cannot match on 2 * k. You will have to use a non-match construct or a non-nat type or a different algorithm.
You need to prove that there are only three cases for a given natural number a. Either a is 0, either a is the double of another number k and k < a, or a is the double k + 1 and k < a, that the three cases are exclusive (this is important, otherwise making pattern matching possible would lead to an inconistency).
Fortunately, all this can be done. It is a bit advanced Coq programming, but it is somehow already done in ZArith. Here is a solution.
First note that the other number is already provided by one of the functions in the Coq library, div2.
Require Import Arith Nat.
Definition cases_div2 (a : nat) :
{k : nat | a = 2 * k /\ k < a}+{k : nat | a = S (2 * k) /\ k < a}+{a=0}.
destruct a as [ | a'].
right; reflexivity.
case_eq (odd (S a')); intros odd_a.
left; right; exists (div2 (S a')); rewrite (div2_odd (S a')) at 1.
split.
rewrite odd_a; simpl b2n; ring.
apply lt_div2; auto with arith.
left; left; exists (div2 (S a')); rewrite (div2_odd (S a')) at 1.
split.
rewrite odd_a; simpl b2n; ring.
apply lt_div2; auto with arith.
Defined.
Now, you can pattern match on your number a using cases_div2, but it is still not enough to define your function, because recursion using Fixpoint relies on recursive calls happening on the predecessor, and here k cannot be written as a predecessor pattern that will work for any input a. You need a stronger kind of recursion. I usually rely on Function or Fix for this kind of strong recursion. Here is an example with Fix
Definition sum_of_halves : nat -> nat :=
Fix Arith.Wf_nat.lt_wf (fun _ => nat)
(fun a (sum_of_halves' : forall y, y < a -> nat) =>
match cases_div2 a with
| inright h => 0
| inleft (inl (exist _ k (conj keq klt))) =>
a + sum_of_halves' k klt
| inleft (inr (exist _ k (conj keq klt))) =>
a + sum_of_halves' k klt
end).
Then to reason about sum_of_halves you will need to reason by well founded induction and use Fix_eq.
This is one possibility.
I was going through the book Software foundations to learn Coq and I got stuck on Numbers. In this Type definition
Inductive nat : Type :=
| O : nat
| S : nat -> nat.
How does O becomes 0 when we use it in definition of
Definition pred (n : nat) : nat :=
match n with
| O => O
| S n' => n'
end.
I only understood that O represents natural numbers and S takes a natural number and return another natural number. What I do not get is when our defined nat data type is used in pred definition how does O represent 0? And how does S n' patter match gives us predecessor of n.
The Peano numbers
nat represents the natural numbers via the unary numeral system. The inhabitants (values) of the nat type are O, S O, S (S O), S (S (S O)), ..., S (S (S (S ... O)...).
We interpret the symbol O as the natural number zero. And S represents a single "tick" in unary representation, i.e. we interpret S as a constructor (it has nothing to do with object-oriented programming) which takes a natural number and yields the next natural number.
The predecessor function
pred is actually is not a very well-behaved function in a sense.
First of all, there is no predecessor of zero when we are talking about the natural numbers. But all functions in Coq must return a value, so if we want to keep the type of pred (which is nat -> nat) we must do something about pred O. It feels natural to just return O and get it over with. This gives us the first branch of the pattern-mathing expression (O => O).
Next, what do we return when we call pred on the number representing 1? Let's recall that we write 1 in Coq as S O. This is easy -- pred (S O) should return O. Now let's try 2: pred (S (S O)) should return S O. You see the pattern here? If we have a bunch of S's in front of an O, we strip one S off -- simple as that. The second branch of the pattern-matching expression (S n' => n') does exactly this: it takes a (non-zero) number of the form S n' and turns it into n' (not changing the original, of course).
Let me give an example. Let's calculate the predecessor of the number 3 step-by-step:
pred (S (S (S O)))
Unfold the definition of pred, substitute S (S (S O)) for n:
match S (S (S O)) with
| O => O
| S n' => n'
end
S (S (S O)) has form S n' (it starts with S), so we take the 2nd branch, binding n' to S (S O). How do we check that we didn't make a mistake here? If we substitute the definition of n' into S n' we should get back the original n: S n' = S (S (S O)) = n.
Now, we just return n':
S (S O)
As expected, we got 2 as the result!
Notations
There is a distinction between 0, 0, and O. The first zero (0) is a meta-level numeral for the natural number zero (it's how we designate zero in our metalanguage, e.g. English in this case). 0 is a notation for O, in other words 0 is syntactic sugar for O. As the Coq reference manual says (§1.2.4):
Numerals have no definite semantics in the calculus. They are mere notations that can be bound to objects through the notation mechanism (see Chapter 12 for details). Initially, numerals are bound to Peano’s representation of natural numbers (see 3.1.3).
It's easy to illustrate:
Check 0. (* 0 : nat *)
Check 5. (* 5 : nat *)
Unset Printing Notations. (* Print terms as is, no syntactic sugar *)
Check 0. (* O : nat *)
Check 5. (* S (S (S (S (S O)))) : nat *)
You can overload numerals, here is an example with integers:
Set Printing Notations.
Require Import Coq.ZArith.ZArith.
Open Scope Z.
Check 0. (* 0 : Z *)
Check 5. (* 5 : Z *)
Unset Printing Notations.
Check 0. (* Z0 : Z *)
Check 5. (* Zpos (xI (xO xH)) : Z *)
Upshot: the same notation can be tied to different terms. Coq defines some default notations, e.g. for such ubiquitous things as numbers.
If you wanted to define your own type to represent the natural numbers (my_nat) with possibly different names for O and S (like stop and tick), you'd have to write a plugin to map Coq numerals onto the terms of my_nat (see here).
1) I believe that it is possible to use inductive types without pattern matching. (using _rec,_rect,_ind only). It is opaque, complicated, but possible.
2) Is it possible to use coinductive types withous pattern matching?
There exist a function from coinductive type to union of constructors' domains of coinductive type.
Does Coq generate it explicitly?
If yes, how to rewrite 'hd' ?
Section stream.
Variable A : Type.
CoInductive stream : Type :=
| Cons : A -> stream -> stream.
End stream.
Definition hd A (s : stream A) : A :=
match s with
| Cons x _ => x
end.
Although it is possible to use inductive types without directly resorting to pattern matching, this is only superficially true: the _rec, _rect and _ind combinators generated by Coq are all defined in terms of match. For instance:
Print nat_rect.
nat_rect =
fun (P : nat -> Type) (f : P 0) (f0 : forall n : nat, P n -> P (S n)) =>
fix F (n : nat) : P n :=
match n as n0 return (P n0) with
| 0 => f
| S n0 => f0 n0 (F n0)
end
: forall P : nat -> Type,
P 0 -> (forall n : nat, P n -> P (S n)) -> forall n : nat, P n
Furthermore, there are many cases where replacing pattern matching by an eliminator would result in a term with different computational behavior. Consider the following function, which divides a nat by two:
Fixpoint div2 (n : nat) :=
match n with
| 0 | 1 => 0
| S (S n') => S (div2 n')
end.
It is possible to rewrite this function using nat_rec, but the recursive call on n - 2 makes it a bit complicated (try it!).
Now, back to your main question, Coq does not automatically generate similar elimination principles for coinductive types. The Paco library helps deriving more useful principles for reasoning about coinductive data. But as far as I am aware, there is nothing similar for writing plain functions.
It is worth pointing out that your proposed approach is different from what Coq does for inductive data types, in that nat_rect and friends allow writing recursive functions and proofs by induction. One of the reasons providing these combinators is that they are used by the induction tactic. Something of type nat -> unit + nat, which more or less corresponds to what you proposed, wouldn't suffice.