From 707645eed65ee80b66b7cb0c59291de6d952ef9e Mon Sep 17 00:00:00 2001
From: Amin Timany <amintimany@gmail.com>
Date: Thu, 31 Oct 2019 16:50:23 +0100
Subject: [PATCH] Add two useful lemmas

---
 theories/list.v      | 33 ++++++++++++++++++++-------------
 theories/relations.v | 14 ++++++++++++++
 2 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/theories/list.v b/theories/list.v
index be912f56..722c20ff 100644
--- a/theories/list.v
+++ b/theories/list.v
@@ -730,10 +730,28 @@ Lemma elem_of_list_singleton x y : x ∈ [y] ↔ x = y.
 Proof. rewrite elem_of_cons, elem_of_nil. tauto. Qed.
 Global Instance elem_of_list_permutation_proper x : Proper ((≡ₚ) ==> iff) (x ∈.).
 Proof. induction 1; rewrite ?elem_of_nil, ?elem_of_cons; intuition. Qed.
+Lemma elem_of_list_lookup_1 l x : x ∈ l → ∃ i, l !! i = Some x.
+Proof.
+  induction 1 as [|???? IH]; [by exists 0 |].
+  destruct IH as [i ?]; auto. by exists (S i).
+Qed.
+Lemma elem_of_list_lookup_2 l i x : l !! i = Some x → x ∈ l.
+Proof.
+  revert i. induction l; intros [|i] ?; simplify_eq/=; constructor; eauto.
+Qed.
+Lemma elem_of_list_lookup l x : x ∈ l ↔ ∃ i, l !! i = Some x.
+Proof. firstorder eauto using elem_of_list_lookup_1, elem_of_list_lookup_2. Qed.
+Lemma elem_of_list_split_length l i x :
+  l !! i = Some x → ∃ l1 l2, l = l1 ++ x :: l2 ∧ i = length l1.
+Proof.
+  revert i; induction l as [|y l IH]; intros [|i] Hl; simplify_eq/=.
+  - exists []; eauto.
+  - destruct (IH _ Hl) as (?&?&?&?); simplify_eq/=.
+    eexists (y :: _); eauto.
+Qed.
 Lemma elem_of_list_split l x : x ∈ l → ∃ l1 l2, l = l1 ++ x :: l2.
 Proof.
-  induction 1 as [x l|x y l ? [l1 [l2 ->]]]; [by eexists [], l|].
-  by exists (y :: l1), l2.
+  intros [? (?&?&?&_)%elem_of_list_split_length]%elem_of_list_lookup_1; eauto.
 Qed.
 Lemma elem_of_list_split_l `{EqDecision A} l x :
   x ∈ l → ∃ l1 l2, l = l1 ++ x :: l2 ∧ x ∉ l1.
@@ -757,17 +775,6 @@ Proof.
     exists l1, (l2 ++ [y]).
     rewrite elem_of_app, elem_of_list_singleton, <-(assoc_L (++)). naive_solver.
 Qed.
-Lemma elem_of_list_lookup_1 l x : x ∈ l → ∃ i, l !! i = Some x.
-Proof.
-  induction 1 as [|???? IH]; [by exists 0 |].
-  destruct IH as [i ?]; auto. by exists (S i).
-Qed.
-Lemma elem_of_list_lookup_2 l i x : l !! i = Some x → x ∈ l.
-Proof.
-  revert i. induction l; intros [|i] ?; simplify_eq/=; constructor; eauto.
-Qed.
-Lemma elem_of_list_lookup l x : x ∈ l ↔ ∃ i, l !! i = Some x.
-Proof. firstorder eauto using elem_of_list_lookup_1, elem_of_list_lookup_2. Qed.
 Lemma elem_of_list_omap {B} (f : A → option B) l (y : B) :
   y ∈ omap f l ↔ ∃ x, x ∈ l ∧ f x = Some y.
 Proof.
diff --git a/theories/relations.v b/theories/relations.v
index 2684b647..a7869ac6 100644
--- a/theories/relations.v
+++ b/theories/relations.v
@@ -149,6 +149,20 @@ Section closure.
   Lemma rtc_nsteps x y : rtc R x y → ∃ n, nsteps R n x y.
   Proof. induction 1; firstorder eauto. Qed.
 
+  Lemma nsteps_plus_inv n m x z :
+    nsteps R (n + m) x z → ∃ y, nsteps R n x y ∧ nsteps R m y z.
+  Proof.
+    revert x.
+    induction n as [|n IH]; intros x Hx; simpl; [by eauto|].
+    inversion Hx; naive_solver.
+  Qed.
+
+  Lemma nsteps_inv_r n x z : nsteps R (S n) x z → ∃ y, nsteps R n x y ∧ R y z.
+  Proof.
+    rewrite <- PeanoNat.Nat.add_1_r.
+    intros (?&?&?%nsteps_once_inv)%nsteps_plus_inv; eauto.
+  Qed.
+
   Lemma bsteps_once n x y : R x y → bsteps R (S n) x y.
   Proof. eauto. Qed.
   Lemma bsteps_plus_r n m x y :
-- 
GitLab