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: Agnishom Chattopadhyay <agnishom AT cmi.ac.in>
  • To: coq-club AT inria.fr
  • Subject: Re: [Coq-Club] Not enough information to resolve this refine goal
  • Date: Wed, 30 Sep 2020 16:00:07 -0500
  • Authentication-results: mail3-smtp-sop.national.inria.fr; spf=None smtp.pra=agnishom AT cmi.ac.in; spf=Pass smtp.mailfrom=agnishom AT cmi.ac.in; spf=None smtp.helo=postmaster AT mail.cmi.ac.in
  • Ironport-phdr: 9a23:CzftQx0IgE/O+SRNsmDT+DRfVm0co7zxezQtwd8ZseIUI/ad9pjvdHbS+e9qxAeQG9mCtLQf0aGP7vmocFdDyK7JiGoFfp1IWk1NouQttCtkPvS4D1bmJuXhdS0wEZcKflZk+3amLRodQ56mNBXdrXKo8DEdBAj0OxZrKeTpAI7SiNm82/yv95HJbAhEmTiwbal8IRmoogndq8kbjZZ/Iast1xXFpWdFdf5Lzm1yP1KTmBj85sa0/JF99ilbpuws+c1dX6jkZqo0VbNXAigoPGAz/83rqALMTRCT6XsGU2UZiQRHDg7Y5xznRJjxsy/6tu1g2CmGOMD9UL45VSi+46ptVRTljjoMOTwk/2HNksF/g6xbrxChqRJxwIDafZ+bO+Zlc6zHYd8XX3BMUtpNWyFDBI63cosBD/AGPeZdt4Twu1QOrR2/BQm3BOPvzTpIjWLo0K06yeshDR3G3As4H90UrXvUrNX0O70SUOuoy6TH1zrDb/VX2Tfm6IjIdRUhrOqQUrJ1cMrd01MgGB/fglWRr4zoJjWY3fkCvGaH9eRvT/6vi3I5pAFrpDii3scih5TVio4JxV3J8Th1zYY6KNCkTEN3f96pHpRNuy+UOYZ7RsMvTn9otSg6yrAIuYC2cTYUxZg6xhPSavKKfouO7xn+V+iROS91iG94dL+/nRq+70etx+7mWsWqzVpGtDdJn9rQunwVyRDf9syKRuF+80qhwzqDygHe5+BeLUwpl6fWKpgsyaMqmJUJq0TMBCr2lV32jKCIckUk/fCl6+H9bbXnop+QLZN7igT/Mqg0gMOwHf40MgkIX2SD+OS80qPs/VHhTblXk/E7krPVvI7VKMkYvKK1HRJZ3pw+5xu8EzuqyNEYkmMGLFJBdhKHlY/pO1TWLf/iAve/hVWskCxrx/DBO73sGYnCLn3CkLv7Z7ly91RQyAs1zdxH/ZJbFqkBIO7vWk/2rNHXEhg5MxWtz+n7DNV9y5gRVHmUAq6ZNaPSqUWH6vguI+mKfo8VuSzyJ+Ir5/703jcFngoWerDs1p8KYli5GO5nKgOXeynCmNAERE4FuAslTOvvwHaCWCJPYG67U6It7yBzXIupC4bYRoeoqLeE3WGyFdtXYDYVWRi3DX70etDcCL83YyWIL5o5y2FWZf2aU4YkkCqWmkr6xr5gd7SG/yQZsdTo0dkz7uaVlBdgrWUoXfTY6HmESiRPpk1NXyU/hfktqkl8jF6Il6l+0aQBRI5joshRWwJ/DqbyiulzCtT8QAXEJ47bQ1OnBNytRzA3HIs8

Thank You. This is the version that finally worked:

  Definition list_nil_dec (l : list A) :
    {l = nil} + {l <> nil}.
  Proof.
    destruct l.
    - left. reflexivity.
    - right. discriminate.
  Qed.

  Fixpoint fromList' (l : list A) : (l <> nil) -> nonEmpty A.
    refine (match l with
            | nil => fun (H : nil <> nil) => _
            | (cons x xs) =>
              fun (_ : (cons x xs) <> nil) =>
              match (list_nil_dec xs) with
              | left _ => singleton x
              | right pr => consNE x (fromList' xs pr )
              end
            end).
    - exfalso. apply H. reflexivity.
  Defined.

I personally find the unguarded a bit mysterious. It seems like a limitation of Coq in not being able to see that a term is smaller than another.

On Wed, Sep 30, 2020 at 3:01 PM Maximilian Wuttke <mwuttke97 AT posteo.de> wrote:
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