WBLogic.heap_lang_trace_examples.sequential_trace_alt
From stdpp Require Import list.
From WBLogic.heap_lang_trace Require Import notation.
From WBLogic.heap_lang_trace_examples Require Import very_awkward.
Inductive sequential_full_trace : list val → Prop :=
| sequential_full_trace_nil : sequential_full_trace []
| sequential_full_trace_wrap tag t :
sequential_full_trace t →
sequential_full_trace ((tag, #"(")%V :: t ++ (tag, #")")%V :: nil)
| sequential_full_trace_app t t' :
sequential_full_trace t →
sequential_full_trace t' →
sequential_full_trace (t ++ t').
Definition sequential_trace_alt (t: list val) :=
∃ t', sequential_full_trace t' ∧ t `prefix_of` t'.
Lemma sequential_call tag :
sequential_full_trace [(tag, #"(")%V ; (tag, #")")%V].
Proof. apply (sequential_full_trace_wrap tag _ sequential_full_trace_nil). Qed.
Lemma sequential_full_trace_call_middle tag t t' :
sequential_full_trace (t ++ t') →
sequential_full_trace (t ++ (tag, #"(")%V :: (tag, #")")%V :: t').
Proof.
set tt := t ++ t'. intros Htt. assert (tt = t ++ t') as HH by done. revert HH; clearbody tt.
revert t t'. induction Htt as [| tag' |].
{ intros ? ? [-> ->]%eq_sym%app_eq_nil. cbn. apply sequential_call. }
{ intros t1 t2 HH. rewrite app_comm_cons in HH.
apply app_eq_inv in HH as [HH|HH].
{ destruct HH as [? [Ht1 Ht2]]. subst.
destruct t1.
{ cbn in *. subst. cbn.
pose proof (sequential_full_trace_app _ _ (sequential_call tag)
(sequential_full_trace_wrap tag' t Htt)). done. }
{ cbn in *. inversion Ht1; subst. specialize (IHHtt _ _ eq_refl).
pose proof (sequential_full_trace_wrap tag' _ IHHtt). rewrite -app_assoc // in H. } }
{ destruct HH as [? [Ht1 Ht2]]. subst. apply eq_sym, app_eq_unit in Ht2.
destruct_or!; destruct_and!; subst; cbn.
{ rewrite app_nil_r /=.
pose proof (sequential_full_trace_app _ _ Htt (sequential_call tag)) as HH.
pose proof (sequential_full_trace_wrap tag' _ HH). rewrite -app_assoc // in H. }
{ apply (sequential_full_trace_app _ _
(sequential_full_trace_wrap tag' _ Htt) (sequential_call tag)). } } }
{ intros t1 t2 Ht1t2. apply app_eq_inv in Ht1t2 as [HH|HH].
{ destruct HH as [? [-> ->]]. specialize (IHHtt1 _ _ eq_refl).
pose proof (sequential_full_trace_app _ _ IHHtt1 Htt2) as HH. rewrite -app_assoc // in HH. }
{ destruct HH as [? [-> ->]]. specialize (IHHtt2 _ _ eq_refl).
pose proof (sequential_full_trace_app _ _ Htt1 IHHtt2) as HH. rewrite -app_assoc //. } }
Qed.
Lemma sequential_with_opened_sequential o t :
sequential_with_opened o t →
sequential_trace_alt t.
Proof.
set closing : list val → list val := map (λ tag, (tag, #")")%V).
enough (Hind: sequential_with_opened o t → sequential_full_trace (t ++ closing o)).
{ intros Ho. specialize (Hind Ho). eexists. split; eauto.
by apply prefix_app_r. }
induction 1 as [| ? ? ? Ho Ht|].
{ rewrite /=. constructor. }
{ rewrite /=. eapply (sequential_full_trace_call_middle tag) in Ht. rewrite -app_assoc//. }
{ cbn in *. rewrite -app_assoc //. }
Qed.
Lemma prefix_snoc_inv {A} (l1 l2: list A) x :
l1 `prefix_of` (l2 ++ [x]) →
l1 = l2 ++ [x] ∨ l1 `prefix_of` l2.
Proof.
revert l1 x. induction l2 as [| y l2].
{ cbn. intros ? ? HH. destruct l1. right; done.
pose proof (prefix_cons_inv_1 _ _ _ _ HH) as ->.
apply (prefix_cons_inv_2), prefix_nil_inv in HH. subst. by left. }
{ cbn. intros ? ? HH. destruct l1. right; by apply prefix_nil.
pose proof (prefix_cons_inv_1 _ _ _ _ HH) as ->.
apply (prefix_cons_inv_2), IHl2 in HH as [->|HH]. by left.
right. by apply prefix_cons. }
Qed.
Lemma sequential_with_opened_open_front o t tag :
sequential_with_opened o t →
sequential_with_opened (o ++ [tag]) ((tag, #"(")%V :: t).
Proof.
induction 1; cbn.
{ rewrite (_: [(tag, #"(")%V] = [] ++ (tag, #"(")%V :: nil) //.
econstructor. constructor. }
{ rewrite (_: ∀ x, (tag, #"(")%V :: t ++ x = ((tag, #"(")%V :: t) ++ x) //.
by econstructor. }
{ rewrite (_: ∀ x, (tag, #"(")%V :: t ++ x = ((tag, #"(")%V :: t) ++ x) //.
by econstructor. }
Qed.
Lemma sequential_with_opened_app o t o' t' :
sequential_with_opened o t →
sequential_with_opened o' t' →
sequential_with_opened (o' ++ o) (t ++ t').
Proof.
intros H1 H2. revert o t H1. induction H2.
{ intros. rewrite app_nil_r //=. }
{ intros o1 t1 Hot1. cbn. rewrite app_assoc. econstructor.
eauto. }
{ intros o1 t1 Hot1. rewrite app_assoc. econstructor. eauto. }
Qed.
Lemma sequential_full_trace_with_opened_nil t :
sequential_full_trace t →
sequential_with_opened [] t.
Proof.
induction 1.
{ constructor. }
{ rewrite (_: ∀ x, (tag, #"(")%V :: t ++ x = ((tag, #"(")%V :: t) ++ x) //.
econstructor.
rewrite (_: [tag] = [] ++ [tag]) //.
by eapply sequential_with_opened_open_front. }
{ rewrite (_: [] = [] ++ []) //. by eapply sequential_with_opened_app. }
Qed.
Lemma sequential_with_opened_prefix o t t' :
sequential_with_opened o t →
t' `prefix_of` t →
∃ o', sequential_with_opened o' t'.
Proof.
revert o t'. induction t using rev_ind.
{ intros ? ? ? ->%prefix_nil_inv. eexists. econstructor. }
{ intros ? ? Hseq. inversion Hseq; simplify_list_eq.
{ exfalso. destruct t; simplify_list_eq. }
{ intros [->|Hpre]%prefix_snoc_inv; eauto. }
{ intros [->|Hpre]%prefix_snoc_inv; eauto. } }
Qed.
Lemma sequential_with_opened_of_sequential t :
sequential_trace_alt t →
∃ o, sequential_with_opened o t.
Proof.
intros [t' [Ht' Htt']].
apply sequential_full_trace_with_opened_nil in Ht'.
eapply sequential_with_opened_prefix in Ht'; eauto.
Qed.
Lemma sequential_trace_alt_iff t :
sequential_trace t ↔ sequential_trace_alt t.
Proof.
split.
{ by intros [? ?%sequential_with_opened_sequential]. }
{ by intros ?%sequential_with_opened_of_sequential. }
Qed.
From WBLogic.heap_lang_trace Require Import notation.
From WBLogic.heap_lang_trace_examples Require Import very_awkward.
Inductive sequential_full_trace : list val → Prop :=
| sequential_full_trace_nil : sequential_full_trace []
| sequential_full_trace_wrap tag t :
sequential_full_trace t →
sequential_full_trace ((tag, #"(")%V :: t ++ (tag, #")")%V :: nil)
| sequential_full_trace_app t t' :
sequential_full_trace t →
sequential_full_trace t' →
sequential_full_trace (t ++ t').
Definition sequential_trace_alt (t: list val) :=
∃ t', sequential_full_trace t' ∧ t `prefix_of` t'.
Lemma sequential_call tag :
sequential_full_trace [(tag, #"(")%V ; (tag, #")")%V].
Proof. apply (sequential_full_trace_wrap tag _ sequential_full_trace_nil). Qed.
Lemma sequential_full_trace_call_middle tag t t' :
sequential_full_trace (t ++ t') →
sequential_full_trace (t ++ (tag, #"(")%V :: (tag, #")")%V :: t').
Proof.
set tt := t ++ t'. intros Htt. assert (tt = t ++ t') as HH by done. revert HH; clearbody tt.
revert t t'. induction Htt as [| tag' |].
{ intros ? ? [-> ->]%eq_sym%app_eq_nil. cbn. apply sequential_call. }
{ intros t1 t2 HH. rewrite app_comm_cons in HH.
apply app_eq_inv in HH as [HH|HH].
{ destruct HH as [? [Ht1 Ht2]]. subst.
destruct t1.
{ cbn in *. subst. cbn.
pose proof (sequential_full_trace_app _ _ (sequential_call tag)
(sequential_full_trace_wrap tag' t Htt)). done. }
{ cbn in *. inversion Ht1; subst. specialize (IHHtt _ _ eq_refl).
pose proof (sequential_full_trace_wrap tag' _ IHHtt). rewrite -app_assoc // in H. } }
{ destruct HH as [? [Ht1 Ht2]]. subst. apply eq_sym, app_eq_unit in Ht2.
destruct_or!; destruct_and!; subst; cbn.
{ rewrite app_nil_r /=.
pose proof (sequential_full_trace_app _ _ Htt (sequential_call tag)) as HH.
pose proof (sequential_full_trace_wrap tag' _ HH). rewrite -app_assoc // in H. }
{ apply (sequential_full_trace_app _ _
(sequential_full_trace_wrap tag' _ Htt) (sequential_call tag)). } } }
{ intros t1 t2 Ht1t2. apply app_eq_inv in Ht1t2 as [HH|HH].
{ destruct HH as [? [-> ->]]. specialize (IHHtt1 _ _ eq_refl).
pose proof (sequential_full_trace_app _ _ IHHtt1 Htt2) as HH. rewrite -app_assoc // in HH. }
{ destruct HH as [? [-> ->]]. specialize (IHHtt2 _ _ eq_refl).
pose proof (sequential_full_trace_app _ _ Htt1 IHHtt2) as HH. rewrite -app_assoc //. } }
Qed.
Lemma sequential_with_opened_sequential o t :
sequential_with_opened o t →
sequential_trace_alt t.
Proof.
set closing : list val → list val := map (λ tag, (tag, #")")%V).
enough (Hind: sequential_with_opened o t → sequential_full_trace (t ++ closing o)).
{ intros Ho. specialize (Hind Ho). eexists. split; eauto.
by apply prefix_app_r. }
induction 1 as [| ? ? ? Ho Ht|].
{ rewrite /=. constructor. }
{ rewrite /=. eapply (sequential_full_trace_call_middle tag) in Ht. rewrite -app_assoc//. }
{ cbn in *. rewrite -app_assoc //. }
Qed.
Lemma prefix_snoc_inv {A} (l1 l2: list A) x :
l1 `prefix_of` (l2 ++ [x]) →
l1 = l2 ++ [x] ∨ l1 `prefix_of` l2.
Proof.
revert l1 x. induction l2 as [| y l2].
{ cbn. intros ? ? HH. destruct l1. right; done.
pose proof (prefix_cons_inv_1 _ _ _ _ HH) as ->.
apply (prefix_cons_inv_2), prefix_nil_inv in HH. subst. by left. }
{ cbn. intros ? ? HH. destruct l1. right; by apply prefix_nil.
pose proof (prefix_cons_inv_1 _ _ _ _ HH) as ->.
apply (prefix_cons_inv_2), IHl2 in HH as [->|HH]. by left.
right. by apply prefix_cons. }
Qed.
Lemma sequential_with_opened_open_front o t tag :
sequential_with_opened o t →
sequential_with_opened (o ++ [tag]) ((tag, #"(")%V :: t).
Proof.
induction 1; cbn.
{ rewrite (_: [(tag, #"(")%V] = [] ++ (tag, #"(")%V :: nil) //.
econstructor. constructor. }
{ rewrite (_: ∀ x, (tag, #"(")%V :: t ++ x = ((tag, #"(")%V :: t) ++ x) //.
by econstructor. }
{ rewrite (_: ∀ x, (tag, #"(")%V :: t ++ x = ((tag, #"(")%V :: t) ++ x) //.
by econstructor. }
Qed.
Lemma sequential_with_opened_app o t o' t' :
sequential_with_opened o t →
sequential_with_opened o' t' →
sequential_with_opened (o' ++ o) (t ++ t').
Proof.
intros H1 H2. revert o t H1. induction H2.
{ intros. rewrite app_nil_r //=. }
{ intros o1 t1 Hot1. cbn. rewrite app_assoc. econstructor.
eauto. }
{ intros o1 t1 Hot1. rewrite app_assoc. econstructor. eauto. }
Qed.
Lemma sequential_full_trace_with_opened_nil t :
sequential_full_trace t →
sequential_with_opened [] t.
Proof.
induction 1.
{ constructor. }
{ rewrite (_: ∀ x, (tag, #"(")%V :: t ++ x = ((tag, #"(")%V :: t) ++ x) //.
econstructor.
rewrite (_: [tag] = [] ++ [tag]) //.
by eapply sequential_with_opened_open_front. }
{ rewrite (_: [] = [] ++ []) //. by eapply sequential_with_opened_app. }
Qed.
Lemma sequential_with_opened_prefix o t t' :
sequential_with_opened o t →
t' `prefix_of` t →
∃ o', sequential_with_opened o' t'.
Proof.
revert o t'. induction t using rev_ind.
{ intros ? ? ? ->%prefix_nil_inv. eexists. econstructor. }
{ intros ? ? Hseq. inversion Hseq; simplify_list_eq.
{ exfalso. destruct t; simplify_list_eq. }
{ intros [->|Hpre]%prefix_snoc_inv; eauto. }
{ intros [->|Hpre]%prefix_snoc_inv; eauto. } }
Qed.
Lemma sequential_with_opened_of_sequential t :
sequential_trace_alt t →
∃ o, sequential_with_opened o t.
Proof.
intros [t' [Ht' Htt']].
apply sequential_full_trace_with_opened_nil in Ht'.
eapply sequential_with_opened_prefix in Ht'; eauto.
Qed.
Lemma sequential_trace_alt_iff t :
sequential_trace t ↔ sequential_trace_alt t.
Proof.
split.
{ by intros [? ?%sequential_with_opened_sequential]. }
{ by intros ?%sequential_with_opened_of_sequential. }
Qed.