Reputation: 133
Require Import Arith.
Require Import Ascii.
Require Import Coq.Arith.PeanoNat.
Require Import Coq.Lists.List.
Require Import Coq.Program.Program.
Require Import Coq.Strings.Byte.
Require Import Coq.Strings.String.
Import ListNotations.
Definition parser (A : Type) : Type := string -> option (A * string).
Definition isLt {A : Type} (p : parser A) : Prop :=
forall s : string,
match p s with
| None => True
| Some (x, s') => length s' < length s
end.
#[program]
Fixpoint some {A : Type} (p1 : parser A) (p1_isLt : isLt p1) (s : string) {measure (length s)} : option (list A * string) :=
match p1 s with
| None => None
| Some (x, s') =>
match some p1 p1_isLt s' with
| None => Some ([x], s')
| Some (xs, s'') => Some (x :: xs, s'')
end
end.
Next Obligation. pose proof (p1_isLt s) as H. rewrite <- Heq_anonymous in H. assumption. Defined.
Lemma some_unfold {A : Type} (p1 : parser A) (p1_isLt : isLt p1) (s : string) :
some p1 p1_isLt s =
match p1 s with
| None => None
| Some (x, s') =>
match some p1 p1_isLt s' with
| None => Some ([x], s')
| Some (xs, s'') => Some (x :: xs, s'')
end
end.
Proof.
unfold some at 1. unfold some_func. rewrite fix_sub_eq.
{ destruct (p s) as [[x s'] | ] eqn: OBS_p_s; simpl.
- rewrite OBS_p_s. destruct (some p p_isLt s') as [[xs s''] | ] eqn: OBS_some_p_s'.
+ unfold some in OBS_some_p_s'. unfold some_func in OBS_some_p_s'.
rewrite OBS_some_p_s'. reflexivity.
+ unfold some in OBS_some_p_s'. unfold some_func in OBS_some_p_s'.
rewrite OBS_some_p_s'. reflexivity.
- rewrite OBS_p_s. reflexivity.
}
{ intros [_A [_p [_p_isLt _s]]] f g f_eq_g; simpl.
admit. (* because `destruct (_p _s).` fails *)
}
Admitted.
How can I prove the lemma some_unfold
?
I proved an unfold lemma for other program fixpoint:
rewrite fix_sub_eq
.H
; eauto.
But this problem is slightly different from the above.Upvotes: 0
Views: 77
Reputation: 133
Require Import Coq.Program.Wf.
Lemma some_unfold {A : Type} (p1 : parser A) (p1_isLt : isLt p1) (s : string) :
some p1 p1_isLt s =
match p1 s with
| None => None
| Some (x, s') =>
match some p1 p1_isLt s' with
| None => Some ([x], s')
| Some (xs, s'') => Some (x :: xs, s'')
end
end.
Proof.
unfold some at 1. unfold some_func. rewrite WfExtensionality.fix_sub_eq_ext.
destruct (p s) as [[x s'] | ] eqn: OBS_p_s; simpl.
- rewrite OBS_p_s. destruct (some p p_isLt s') as [[xs s''] | ] eqn: OBS_some_p_s'.
+ unfold some in OBS_some_p_s'. unfold some_func in OBS_some_p_s'.
rewrite OBS_some_p_s'. reflexivity.
+ unfold some in OBS_some_p_s'. unfold some_func in OBS_some_p_s'.
rewrite OBS_some_p_s'. reflexivity.
- rewrite OBS_p_s. reflexivity.
Qed.
Upvotes: 0