coq-club AT inria.fr
Subject: The Coq mailing list
List archive
- From: Gaëtan Gilbert <gaetan.gilbert AT skyskimmer.net>
- To: coq-club AT inria.fr
- Subject: Re: [Coq-Club] Simplify proofs with nested pattern matching (cases explosion)
- Date: Mon, 29 Jun 2020 17:39:23 +0200
- Authentication-results: mail3-smtp-sop.national.inria.fr; spf=None smtp.pra=gaetan.gilbert AT skyskimmer.net; spf=Pass smtp.mailfrom=gaetan.gilbert AT skyskimmer.net; spf=None smtp.helo=postmaster AT relay2-d.mail.gandi.net
- Ironport-phdr: 9a23:l6EzORVfvooa9fIvGOfFRj9fB1PV8LGtZVwlr6E/grcLSJyIuqrYbByFt8tkgFKBZ4jH8fUM07OQ7/m9HzVRsN3Y4DgrS99lb1c9k8IYnggtUoauKHbQC7rUVRE8B9lIT1R//nu2YgB/Ecf6YEDO8DXptWZBUhrwOhBoKevrB4Xck9q41/yo+53Ufg5EmCexbal9IRmrrQjdrNQajI9mJ6o+1xfEoWZDdvhLy29vOV+dhQv36N2q/J5k/SRQuvYh+NBFXK7nYak2TqFWASo/PWwt68LlqRfMTQ2U5nsBSWoWiQZHAxLE7B7hQJj8tDbxu/dn1ymbOc32Sq00WSin4qx2RhLklDsLOjgk+2zRl8d+jr9UoAi5qhJi3YDUboGbOvlwcKzTctwVR3ZOU91UVyBdGI6xdZcDAuQDMOtesoLzp0EOrRy7BQS0Be3g0CNPhmPs0q08y+svEADG3Ag7EN0QqnTUsMj+OaAdUe+v0qbI0S/Mb/VM1Tfy6YjIdgsuru+WXbJsasfR0kovFgPejlWTqIzlOjaV2foXs2SB6epvS/6vhnchpgpsrTeh2t0ihZPVhoIJ1F/E7yN5zZ4oKdGkVUJ2bt+pHZpOuyybOIV7QM0sT3xqtSs6ybAIuZC2cTYJxZg5yBPSauGKfomW7x//VOidPCt1iX1ldry/gRu57EuuyvXkW8WqzVpHrDBJn9vQunwXyhDe6caKRuFg8kql1juDzx7f5vxKLEwuiKbWK4AtzqQtmpcSr0jPBDL6lUrygaKQa04q4PKn6/79bbXjvpKcN5F7igX5Mqk2gMywH+A4PRIOXmSF4Oizyafv/UjjT7VLiv06iKbZv4rcJcsGp661GQlV3Zg/6xqnDjem1soXnWUfIV5bZR6KjZLlNlPSLPziEPuygFqhnC12y/3CMbDtGpDNIWLCkLflc7Z98UlcyA8rwNBQ/Z1bFK0BL+j1WkPru9zYDxs5PBeqzOb9FNVwzZgeWWGPA6+CM6PSsFqI5ucxLOmWfoMVvijyK+Q96/70kXA5gUMdfbWu3ZYPdH+4Ge1mL1yFbnron9cOCnwHvhE+TezvkF2NSyRfZ3e0X6Im5zE0EpiqDYnZRtPlvLvU1yCiW5ZSe2puC1aWEH6ueZ/Xde0LbXe9K0x9mzozermlQYI7yVn6uwb317NhaOXV/icVr47Lz9tk/O7SkBQ/73pyAtjLgDLFdH19gm5dH2x+56t4u0Eokg7fg5g9uORREJlo390MSh0zbMCO1O9rENPzXwfMZJGPRUr0Goz3UwF0dco4xpo1W2g4Htyjih7Z2C/zXe0OlK2QB50x96/GmX78O5QkkiuU5Owal1AjB/B3Gyimi6p4rVWBHYPNmlTD0qrscK0d2GjC/WGPzCyIsV0KCAM=
You may convert is_valid to an inductive type, that way it only has
constructors for the cases you want and you can destruct it directly.
see attached file for an example
Gaëtan Gilbert
On 29/06/2020 16:46, Blaudeau Clément wrote:
Hi Everyone,
I'm currently working to prove results on a fonction that uses several levels
of nested pattern matching and it generates *a lot* of trivial subgoals, to
the point that every proof takes several minutes to go through.
##### High level view of the problem
I have an inductive type with ~ 50 constructors, and nested pattern matching
on lists of that type. The nested pattern matching is translated into several
levels of normal pattern matching with one case that is interesting and 49
useless cases. To build proofs on my function, I would like to be able to
extract easily the interesting cases, and quickly drop all useless cases. Is
there automated ways of doing that ? Just destruct the match expressions and
using `congruence` is too slow.
##### More details
I have a function `is_valid : A -> bool`, and I want to prove results of the
form `is_valid a = true -> P`, where `A` is an inductive type of the form
```Coq
Inductive A := | N : B -> (list A) -> A . % N is the only constructor
```
And `B` is also an inductive type **with around 50 constructors**.
The problem is that, in the `is_valid` function, I have nested pattern
matching (on the list) like
```Coq
| N b1 (N b2 [])::(N b3 [])::_ => (f b1 b2 b3) % some property computed using
b1 b2 b3
```
generates huge patterns, because the internal translation of nested patterns
is to create several levels of patterns. As my type `B` has 50 constructors,
each level of pattern matching generates **a lot** of subgoals and slows down
the proofs.
Is there a simple way to say that if `is_valid a = true` then all the possible
cases are only the ones of the main pattern matching, without having to break all
sub-levels of matching using `congruence` everywhere ? Just doing an `unfold` of
the `is_valid` function takes ~2 min on my computer. The dream would be that
`is_valid a = true -> P` could be split into the few subgoals of the form `.. /\
(f b1 b2 b3) -> P /\ ...`
Thank you for your help !
Clément
PS: I could write a big theorem saying that for any property P, but I'm
looking for an automated way of doing it
Require Import Init.Byte. Definition is_valid b := match b with | x00 | xff => true | _ => false (* 254 cases hidden in this _ *) end. Lemma some_lemma : forall b, is_valid b = true -> b = x00 \/ b = xff. Proof. intros b v;destruct b;try discriminate v. (* 254 cases discriminated away *) - left;reflexivity. - right;reflexivity. Qed. Inductive is_valid' : byte -> Prop := | valid00 : is_valid' x00 | validff : is_valid' xff . Lemma some_lemma' : forall b, is_valid' b -> b = x00 \/ b = xff. Proof. intros b v;destruct v. - left;reflexivity. - right;reflexivity. Qed. (* If you want to recover decidability of validity you still can (here by hand, or you can use some ssr stuff for decidable properties) *) Definition valid'_checker (b:byte) : { v:bool | v=true <-> is_valid' b}. Proof. destruct b;try (exists true; split; intros _;constructor). (* 254 remaining cases *) all: exists false;split;[discriminate|intros v;inversion v]. (* note that each inversion builds a 2-cases match *) Defined.
- [Coq-Club] Simplify proofs with nested pattern matching (cases explosion), Blaudeau Clément, 06/29/2020
- Re: [Coq-Club] Simplify proofs with nested pattern matching (cases explosion), Gaëtan Gilbert, 06/29/2020
- Re: [Coq-Club] Simplify proofs with nested pattern matching (cases explosion), Xavier Leroy, 06/29/2020
- Re: [Coq-Club] Simplify proofs with nested pattern matching (cases explosion), Julien Forest, 06/29/2020
- Re: [Coq-Club] Simplify proofs with nested pattern matching (cases explosion), Xavier Leroy, 06/29/2020
- Re: [Coq-Club] Simplify proofs with nested pattern matching (cases explosion), Gaëtan Gilbert, 06/29/2020
Archive powered by MHonArc 2.6.19+.