Skip to Content.
Sympa Menu

coq-club - Re: [Coq-Club] Not enough information to resolve this refine goal

coq-club AT inria.fr

Subject: The Coq mailing list

List archive

Re: [Coq-Club] Not enough information to resolve this refine goal


Chronological Thread 
  • From: Maximilian Wuttke <mwuttke97 AT posteo.de>
  • To: coq-club AT inria.fr
  • Subject: Re: [Coq-Club] Not enough information to resolve this refine goal
  • Date: Wed, 30 Sep 2020 22:01:22 +0200
  • Authentication-results: mail3-smtp-sop.national.inria.fr; spf=None smtp.pra=mwuttke97 AT posteo.de; spf=Pass smtp.mailfrom=mwuttke97 AT posteo.de; spf=None smtp.helo=postmaster AT mout01.posteo.de
  • Ironport-phdr: 9a23:7Vm2yhLWZrAb0NosF9mcpTZWNBhigK39O0sv0rFitYgeK/XxwZ3uMQTl6Ol3ixeRBMOHsq0C0LCd6vuxEUU7or+5+EgYd5JNUxJXwe43pCcHRPC/NEvgMfTxZDY7FskRHHVs/nW8LFQHUJ2mPw6arXK99yMdFQviPgRpOOv1BpTSj8Oq3Oyu5pHfeQpFiCe/bL9oIhi6swrdutQYjIZmN6081gbHrnxUdupM2GhmP0iTnxHy5sex+J5s7SFdsO8/+sBDTKv3Yb02QaRXAzo6PW814tbrtQTYQguU+nQcSGQWnQFWDAXD8Rr3Q43+sir+tup6xSmaIcj7Rq06VDi+86tmTgLjhSEaPDA77W7XkNR9grxVoByhuhJxwIDab4+aO/V8YqzTcsgXRXZCU8tLSyBNHo2xYokJAuEcPehYtY79p14WoBW5HwatC+LvyjpJhn/y3K01yeIhGhzG0ww9A9IOrHfUo8voP6oVVOC0wrTIzSnfb/NVxzjw7IrFfws5ofGLRrJwbdTeyU41GwzYkFqdsIroNC6a2eoRqWaU9fZgVf6xhG49rQF8uiWiy8gxh4XUmo4YxVDK+yV5zosxO9G1SE92b96kHpVfqyyXKZV7T8w8Tm12tig3yL8LtIKmcCUUyJkq2RDSZv2BfoOV4RzjTP6cLSp7iX9lYr6yhhS//VKux+D9TMW50VZHojJGn9TIrHwByhPe58mdRvdj4EutxSyD2x3d5+1YJ00/iLDVJIQ7wrEqk5oeqUTDETHymEXxlKKWc0Ik+vW06+j7f7nqvIecN4hvigHiLKsundazDvkmPQQWXmib//qz1KH78EHkQ7hHjuc6n6jbvZzAK8kWp7S1Dg5V34o77hawFTam0NAWnXkdK1JFfQqKj43nOlHTPPD4EfS/jEqonTpp3P3GJrrhAo7RLnfdl7ftZ6ty5FBExAop0d9f/45UCq0GIP/rRkDxs8XYAgYlPAyw3uboE85w1pgeWGKKGq+WKrnesV6O5uI1IumDfpUZuDjnK6tt2/m7hngg3FQZYKOB3J0NaXn+EO41DV+eZC/Ji8cAFGYOvwM4BNP3lEGBXHYHYmmvQ74/62BkIJqhFpvOQcahjerSj2+AApRKazUeWRi3GnDyetDcAqZeWGepOsZk1wc8e/2kQo4l2wupsVajmaJgNfbZ/WsUuMC6jYUn16jojRg3sAdMIYGd3mWKFjEmm2QVW2dvmrh4ulBwzRGP3Pog2qAKJZlo//pMFzwCG9vE1eUjUoLqXRndc9DPRFv0Gtg=

On 30/09/2020 21:38, Agnishom Chattopadhyay wrote:
> Fixpoint fromList (l : list A) (lgt0 : length l > 0) : nonEmpty A.
>     refine (match l with
>             | nil => _
>             | (cons x nil) => singleton x
>             | (cons x xs) => consNE x (fromList xs _ )
>             end).
>
> I am not sure how to prove these goals because of the same reasons.

First of all, you have to use the convoy pattern, that means that you
introduce the proof of 'length l > 0' *after* you make the case
distinction on l. Let me do this for you, and then we can even prove the
goals:

```
Fixpoint fromList (l : list A) : length l > 0 -> nonEmpty A.
refine (match l with
| nil => fun (H : length nil > 0) => _
| (cons x nil) => fun (_ : length (cons x nil) > 0) => singleton x
| (cons x xs) => fun (H : length (cons x xs) > 0) => consNE x
(fromList xs _ )
end).
- cbn in H. (* H: 0 > 0 *) exfalso. abstract omega.
- subst xs. cbn. abstract omega.
Fail Defined.
```

Outch, the last command gave an error message. What was the problem?

The problem is that the function is not guarded, even though all goals
have been solved. (Exercise: Write an unguarded 'proof' for `False`.)
You can use the command `Guarded.` to check if your definition is guarded.

Let's look at the unsuggared version of the term.


```
Set Printing All.
Show Proof.

(fix fromList (l : list A) : forall _ : gt (@length A l) O, nonEmpty A :=
match l as l0 return (forall _ : gt (@length A l0) O, nonEmpty A) with
| nil =>
fun H : gt (@length A (@nil A)) O =>
False_rect (nonEmpty A) (fromList_subproof H) : nonEmpty A
| cons x xs =>
match xs as xs0 return (forall _ : gt (@length A (@cons A x xs0))
O, nonEmpty A) with
| nil => fun _ : gt (@length A (@cons A x (@nil A))) O =>
@singleton A x
| cons a l0 =>
let xs0 : list A := @cons A a l0 in
fun H : gt (@length A (@cons A x xs0)) O =>
@consNE A x
(fromList xs0
((fromList_subproof0 x a l0 H : gt (@length A (@cons A a
l0)) O)
:
gt (@length A xs0) O))
end
end)
```

As you can see, the last recursive call is on `xs0`, not `xs`. This is a
common problem if you use the 'complex pattern' syntactic sugar like

```
match l with
| nil => ...
| (cons x nil) => ...
| (cons x xs) => ...
end
```

Instead, it is almost always better (when dealing with dependent types),
to have two nested matches:

```
Fixpoint fromList (l : list A) : length l > 0 -> nonEmpty A.
refine (match l with
| nil => fun (H : length nil > 0) => _
| cons x l' =>
fun (_ : length (cons x l') > 0) => (* We can already forget
the proof here that [l] is not empty *)
match l' with
| nil => singleton x
| cons y l'' => consNE x (fromList l' _)
end
end).
- cbn in H. (* H: 0 > 0 *) exfalso. abstract omega.
- (* ??? *)
```

Now, the function is guarded, but we can't prove the second obligation.

See my other mail for the solution for this (using the function
`list_nil_or_not_empty`).



Archive powered by MHonArc 2.6.19+.

Top of Page