coq-club AT inria.fr
Subject: The Coq mailing list
List archive
- From: Jason Gross <jasongross9 AT gmail.com>
- To: Dan Krejsa <dan.krejsa AT gmail.com>
- Cc: AUGER Cédric <sedrikov AT gmail.com>, coq-club AT inria.fr
- Subject: Re: [Coq-Club] Can one pull a 'let' outside a 'match'?
- Date: Mon, 4 Feb 2013 18:37:59 -0500
If you're ok with copy/paste, you can use the [change] tactic. If you want to remove the let entirely, you can do something like [cbv beta iota].
Automatically saving the things which are [let] is harder. The following tactic should work, assuming that [let pattern1 := term1 in E] doesn't appear anywhere else in the goal, and assuming that it is a simple let pattern (i.e., pattern1 is just a variable name). Someone with more ltac knowledge than I might have an idea of how to take care of the more general case; [let] is just syntactic sugar for a [match], but I don't know how to talk about the cases of a match without knowing the names of the constructors.
Goal match (let x := 2 in (x + x)%nat) with
| O => True
| S n => n = n
end.
match goal with
| [ |- match (let x := ?term1 in @?E term1) with _ => _ end ] =>
match goal with
| [ |- context G[let x := term1 in @?E term1] ] =>
let term1' := fresh in
pose term1 as term1';
let G' := context G[E term1'] in
change G'; revert term1'
end
end.
More generally, you could do
Goal match (let (x, y) := (2, 3) in (x + y)%nat) with
| O => True
| S n => n = n
end.
Ltac fun_app_to_let term tac :=
match term with
| ?f ?x => let x' := fresh in
pose x as x';
fun_app_to_let f ltac:(fun term' =>
let term'' := constr:(term' x') in
tac term'';
try revert x')
| (fun _ => _) => tac term
end.
Ltac move_let :=
cbv iota;
match goal with
| [ |- match ?E with _ => _ end ] =>
match goal with
| [ |- context G[E] ] =>
fun_app_to_let E ltac:(fun x =>
let G' := context G[x] in
change G')
end
end.
move_let.
This doesn't preserve the patterns of the [let] (i.e., it turns [let (x, y) := (2, 3)] into [let x := 2 in let y := 3], and it destroys all your other [let]s (with [cbv iota]), but it moves them outside the match so you can, e.g., intro them.
-Jason
On Mon, Feb 4, 2013 at 4:12 PM, Dan Krejsa <dan.krejsa AT gmail.com> wrote:
Hi Cédric,On Mon, Feb 4, 2013 at 1:01 PM, AUGER Cédric <sedrikov AT gmail.com> wrote:
Maybe, you would be interested in the "case_eq" tactic.
case_eq term1.
match (let pattern1 := term1 in E) [in ... return ...] with
| pat1 => v1
| pat2 => v2
...
end
⇓
∀ x1…xn, pattern1 <using x1…xn> = term1 →
match E [in ... return ...] withwhich is similar to what you wanted (but not the same…).
| pat1 => v1
| pat2 => v2
...
end
Yes, case_eq works for what I needed, thanks much!
By the way, the origin of the 'let (x1, x2) := x in ...' _expression_ was one of
my definitions, and I was able to rewrite the definition to avoid the 'let',
which allowed me to avoid the later difficulty in the proof. Still, it's good to have
case_eq in my arsenal!
- Dan
- [Coq-Club] Can one pull a 'let' outside a 'match'?, Dan Krejsa, 02/04/2013
- Re: [Coq-Club] Can one pull a 'let' outside a 'match'?, AUGER Cédric, 02/04/2013
- Re: [Coq-Club] Can one pull a 'let' outside a 'match'?, Dan Krejsa, 02/04/2013
- Re: [Coq-Club] Can one pull a 'let' outside a 'match'?, Jason Gross, 02/05/2013
- Re: [Coq-Club] Can one pull a 'let' outside a 'match'?, Dan Krejsa, 02/04/2013
- Re: [Coq-Club] Can one pull a 'let' outside a 'match'?, AUGER Cédric, 02/04/2013
Archive powered by MHonArc 2.6.18.