Library Scat.Renaming

Handling of variables (frames, renaming) for conditions


Require Import Coq.FSets.FMapPositive.
Require Import Coq.Structures.OrderedTypeEx.
Require Import PArith.
Require Import PArith.POrderedType.

Require Export Conditions.

We introduce a notion of "frame bound". Hence, tbounds bound t means that all variables of t are lower than bound

Fixpoint tbounds (bound: positive) (t: term): Prop :=
 match t with
 | tvar xZpos (vid x) < Zpos bound
 | tcte cTrue
 | tbin op tl trtbounds bound tl tbounds bound tr
 | told ttbounds bound t
 | tapp f ttbounds bound t
 end.

Lemma tbounds_Zle t bound1:
   tbounds bound1 t bound2:positive, (Zpos bound1) (Zpos bound2)tbounds bound2 t.
Proof.
  induction t; simpl; intuition.
Qed.

Hint Resolve tbounds_Zle: echecker.

frameeq bound1 bound2 s s' means that s and s' coincide on interval bound1 .. bound2-1.

Definition frameeq (bound1: Z) (bound2: positive) (s s': state) : Prop
 := x, bound1 (Zpos x) < Zpos bound2(s x)=(s' x).
Hint Unfold frameeq: checker.

Lemma frameeq_Zle bound1 bound2 bound3 s s':
  (frameeq bound1 bound3 s s') → Zpos bound2 Zpos bound3
   → frameeq bound1 bound2 s s'.
Proof.
  unfold frameeq; intuition.
Qed.

Lemma frameeq_sym bound1 bound2 s1 s2:
  (frameeq bound1 bound2 s1 s2) → (frameeq bound1 bound2 s2 s1).
Proof.
  unfold frameeq; intros; symmetry; auto.
Qed.

Lemma frameeq_trans bound1 bound2 s1 s2 s3:
  (frameeq bound1 bound2 s1 s2) → (frameeq bound1 bound2 s2 s3) → (frameeq bound1 bound2 s1 s3).
Proof.
  unfold frameeq; intros; eapply eq_trans.
  eapply H; eauto.
  auto.
Qed.

Lemma frameeq_glue bound1 bound2 bound3 s1 s2:
  (frameeq bound1 bound2 s1 s2) → (frameeq (Zpos bound2) bound3 s1 s2) → (frameeq bound1 bound3 s1 s2).
Proof.
  unfold frameeq; intros H1 H2 x H3.
  case (Z_le_dec (Zpos bound2) (Zpos x)); intros.
  apply H2; omega.
  apply H1; omega.
Qed.

Lemma frameeq_teval (t: term): bound s s',
   tbounds bound t
    frameeq 0 bound s s'
      teval t s = teval t s'.
Proof.
  unfold frameeq; induction t; simpl; intuition.
  erewrite IHt1; eauto.
  erewrite IHt2; eauto.
  erewrite IHt; eauto.
Qed.

Hint Resolve frameeq_teval frameeq_Zle frameeq_trans frameeq_glue: echecker.

Lemma add_morphism bound1 bound2 x val1 val2 c1 c2:
  val1=val2frameeq bound1 bound2 c1 c2frameeq bound1 bound2 (add x val1 c1) (add x val2 c2).
Proof.
  unfold frameeq; intros H H0 x0 H1.
  unfold add. case (Positive_as_DT.eq_dec x x0); auto.
Qed.

Hint Resolve add_morphism: checker.

Lemma add_frameeq_out_1 bound1 bound2 s x y : Zpos x < bound1frameeq bound1 bound2 (add x y s) s.
Proof.
  unfold frameeq; intros H.
  intros; rewrite add_out; auto.
  omega.
Qed.

Lemma add_frameeq_out_2 bound1 bound2 s x y : Zpos bound2 Zpos xframeeq bound1 bound2 (add x y s) s.
Proof.
  unfold frameeq; intros H.
  intros; rewrite add_out; auto.
  omega.
Qed.

Hint Resolve add_frameeq_out_1 add_frameeq_out_2: checker2.

Renaming of x1 by x2 in t
Fixpoint trename (t:term) (x1 x2: positive) : term
  := match t with
     | tvar xif Positive_as_DT.eq_dec x1 (vid x) then tvar (mkvar (vtag x) x2) else t
     | tcte ct
     | tbin op tl trtbin op (trename tl x1 x2) (trename tr x1 x2)
     | told ttrename t x1 x2
     | tapp f ttapp f (trename t x1 x2)
     end.

Lemma Psucc_lift n: Zpos (n+1)=(Zpos n)+1.
Proof.
  auto.
Qed.
Hint Rewrite Psucc_lift: rchecker.

Lemma Zpos_Psucc_lt n: Zpos n < Zpos (n+1).
Proof.
  autorewrite with rchecker. omega.
Qed.
Hint Resolve Zpos_Psucc_lt: checker.
Hint Resolve Zlt_trans: echecker2.

Lemma Zpos_Psucc_le n: Zpos n Zpos (n+1).
Proof.
  autorewrite with rchecker. omega.
Qed.
Hint Resolve Zpos_Psucc_le: echecker.

Lemma tbounds_trename t: x1 x2, tbounds x2 t
  tbounds (x2+1) (trename t x1 x2).
Proof.
  induction t; simpl; try (intuition; fail).
  unfold trename.
  case x; clear x; intros s x x1 x2; simpl.
  case (Positive_as_DT.eq_dec x1 x); simpl; eauto with checker echecker2.
Qed.
Hint Resolve tbounds_trename: checker.

Lemma trename_tbounds t: x1 x2 s dummy, tbounds x2 t
  teval (trename t x1 x2) (add x2 (s x1) (add x1 dummy s)) = teval t s.
Proof.
  unfold teval; induction t; simpl; try (intuition; fail).
  unfold trename.
  case x; clear x; intros s x x1 x2; simpl.
  case (Positive_as_DT.eq_dec x1 x); simpl.
  intros; subst. auto with checker.
  intros; rewrite add_out; auto with checker.
  omega.
  simpl; intuition; rewrite IHt1; auto.
  rewrite IHt2; auto.
  intros; erewrite IHt; auto.
Qed.
Hint Rewrite trename_tbounds: rchecker.

Frame bound for conditions
Fixpoint cbounds (bound: positive) (c:cond): Prop :=
 match c with
 | basic bTrue
 | atom oc tl trtbounds bound tl tbounds bound tr
 | bin og cl crcbounds bound cl cbounds bound cr
 | not ccbounds bound c
 end.

Lemma cbounds_Zle c bound1:
   cbounds bound1 c bound2:positive, (Zpos bound1) (Zpos bound2)cbounds bound2 c.
Proof.
  induction c; simpl; intuition eauto with echecker.
Qed.

Hint Resolve cbounds_Zle: echecker.

Lemma frameeq_eval c: bound s s',
 frameeq 0 bound s s'
   cbounds bound c
     eval c s = eval c s'.
Proof.
  induction c; simpl; intuition.
  erewrite frameeq_teval; eauto.
  erewrite frameeq_teval with (s:=s); eauto.
  erewrite IHc1; eauto.
  erewrite IHc2; eauto.
  erewrite IHc; eauto.
Qed.

Lemma frameeq_eval_imp c bound s s':
   cbounds bound c
     eval c s
       frameeq 0 bound s s'
         eval c s'.
Proof.
  intros; erewrite frameeq_eval in × |- ; eauto.
Qed.
Hint Resolve frameeq_eval_imp: echecker.

Lemma frameeq_eval_imp_s c bound s s':
   cbounds bound c
     eval c s
      frameeq 0 bound s' s
         eval c s'.
Proof.
  intros; erewrite frameeq_eval; eauto.
Qed.
Hint Resolve frameeq_eval_imp_s: echecker.

Definition extend (c: cond) (bound1 bound2: positive) (s s': state): Prop :=
   sf, eval c sf (frameeq 0 bound1 sf s') (frameeq (Zpos bound1) bound2 sf s).

Fixpoint rename (c:cond) (x1 x2: positive) : cond
  := match c with
     | atom oc tl tratom oc (trename tl x1 x2) (trename tr x1 x2)
     | bin og cl crbin og (rename cl x1 x2) (rename cr x1 x2)
     | not cnot (rename c x1 x2)
     | _c
     end.

Lemma rename_cbounds c: x1 x2 s dummy, cbounds x2 c
  eval (rename c x1 x2) (add x2 (s x1) (add x1 dummy s)) = eval c s.
Proof.
  induction c; simpl; intuition auto with checker.
  autorewrite with rchecker; auto.
  rewrite IHc1; auto.
  rewrite IHc2; auto.
  rewrite IHc; auto.
Qed.
Hint Rewrite rename_cbounds: rchecker.

Lemma cbounds_rename c: x1 x2, cbounds x2 c
  cbounds (x2+1) (rename c x1 x2).
Proof.
  induction c; try (simpl; intuition; fail).
Qed.
Hint Resolve cbounds_rename: checker.

Computations on frame bounds
Lemma Zle_Pmax_l n1 n2: (Zpos n1) Zpos (Pmax n1 n2).
Proof.
  intros; rewrite Zpos_max.
  apply Zle_max_l.
Qed.

Lemma Zle_Pmax_r n1 n2: (Zpos n2) Zpos (Pmax n1 n2).
Proof.
  intros; rewrite Zpos_max.
  apply Zle_max_r.
Qed.

Hint Resolve Zle_Pmax_r Zle_Pmax_l: echecker.
Hint Resolve Zle_refl: checker.
Hint Resolve Zle_trans: echecker.
Hint Resolve Zlt_le_trans: echecker2.

Fixpoint tbound (t:term) (bound: positive): positive :=
 match t with
 | tvar xPmax bound ((vid x)+1)%positive
 | tcte cbound
 | tbin op tl trtbound tl (tbound tr bound)
 | told ttbound t bound
 | tapp f ttbound t bound
 end.

Lemma tbound_monotonic t: bound, (Zpos bound) Zpos (tbound t bound).
Proof.
  induction t; simpl; intros; eauto with checker echecker.
Qed.

Hint Resolve tbound_monotonic: checker.

Lemma tbound_tbounds t: bound, (tbounds (tbound t bound) t).
Proof.
  induction t; simpl; intros; eauto with checker echecker echecker2.
Qed.

Hint Resolve tbound_tbounds: checker.

Fixpoint cbound (c:cond) (bound: positive): positive :=
 match c with
 | basic bbound
 | atom oc tl trtbound tl (tbound tr bound)
 | bin og cl crcbound cl (cbound cr bound)
 | not ccbound c bound
 end.

Lemma cbound_monotonic c: bound, (Zpos bound) Zpos (cbound c bound).
Proof.
  induction c; simpl; intros; eauto with checker echecker.
Qed.

Hint Resolve cbound_monotonic: checker.

Lemma cbound_cbounds c: bound, (cbounds (cbound c bound) c).
Proof.
  induction c; simpl; intuition eauto with checker echecker.
Qed.

Hint Resolve cbound_cbounds: checker.

Renaming using fresh variable

Record renaming := {
  rmap: PositiveMap.t var ;
  rbound: positive
}.

Definition rbounds bound (r: renaming) :=
 Zpos bound Zpos (rbound r)
  x, try (PositiveMap.find x (rmap r)) (fun (x:var) ⇒ Zpos bound Zpos (vid x) < Zpos (rbound r)) True.

Lemma rbounds_rbound bound r : rbounds bound rZpos bound Zpos (rbound r).
Proof.
  unfold rbounds; intuition.
Qed.

Hint Resolve rbounds_rbound: checker.

Lemma rbounds_Zle bound1 bound2 r : rbounds bound2 rZpos bound1 Zpos bound2rbounds bound1 r.
Proof.
  unfold rbounds; intuition.
  eapply try_monotonic; eauto.
  simpl; intuition.
Qed.
Hint Resolve rbounds_Zle: echecker.

Definition rfind (x:var) (r: renaming) :=
 match PositiveMap.find (vid x) (rmap r) with
 | Some xx
 | Nonex
 end.

Lemma rbounds_rfind_up (x:var) r bound :
  rbounds bound rZpos (vid x) < Zpos (rbound r) → Zpos (vid (rfind x r)) < Zpos (rbound r).
Proof.
  unfold rbounds, rfind; intuition.
  generalize (H2 (vid x)).
  case (PositiveMap.find (vid x) (rmap r)); simpl; intuition.
Qed.

Lemma rbounds_rfind_down (x:var) r bound :
  rbounds bound rZpos (vid (rfind x r)) < Zpos bound(rfind x r)=x.
Proof.
  unfold rbounds, rfind; intuition.
  generalize H0 (H2 (vid x)); clear H0 H2.
  case (PositiveMap.find (vid x) (rmap r)); simpl; intuition.
  assert (Zpos (vid x) Zpos (vid x)).
  omega.
  case H.
  auto.
Qed.

Lemma vid_rfind (x y: var) r: (vid x)=(vid y)(vid (rfind x r))=(vid (rfind y r)).
Proof.
  unfold rfind. intros H. rewrite H.
  case (PositiveMap.find (vid y) (rmap r)); simpl; auto.
Qed.

Definition rlift (s:state) (r: renaming) : state :=
 fun x
 match PositiveMap.find x (rmap r) with
 | Some xs (vid x)
 | Nones x
 end.

Lemma rlift_rfind x s r: rlift s r (vid x) = s (vid (rfind x r)).
Proof.
  unfold rlift, rfind. case (PositiveMap.find (vid x) (rmap r)); simpl; auto.
Qed.

Hint Rewrite rlift_rfind: rchecker.

Lemma rlift_frameeq bound s1 s2 r x :
  frameeq 0 bound (rlift s1 r) s2Zpos (vid x) < Zpos bound
   s1 (vid (rfind x r)) = s2 (vid x).
Proof.
  unfold frameeq; intros H H1. rewrite <- H; intuition.
  autorewrite with rchecker.
  auto.
Qed.

Lemma rlift_add_out_2 bound x y s r: rbounds bound r
  Zpos (rbound r) Zpos xframeeq 0 (rbound r) (rlift (add x y s) r) (rlift s r).
Proof.
  unfold rbounds, rlift, frameeq. intuition.
  generalize (H2 x0).
  case (PositiveMap.find x0 (rmap r)); simpl; auto.
  intros; rewrite add_out; auto.
  omega.
  intros; rewrite add_out; auto.
  omega.
Qed.

Definition rempty (bound: positive): renaming :=
 {| rmap:=PositiveMap.empty _ ;
    rbound:=bound
   |}.

Lemma rempty_rbounds bound: rbounds bound (rempty bound).
Proof.
  unfold rbounds. simpl. intuition. rewrite PositiveMap.gempty; simpl; auto.
Qed.

Lemma rempty_rfind x bound : rfind x (rempty bound)=x.
Proof.
  unfold rempty, rfind; simpl.
  rewrite PositiveMap.gempty; simpl; auto.
Qed.

Hint Rewrite rempty_rfind: rchecker.

Lemma rempty_rlift s bound x: rlift s (rempty bound) x = s x.
Proof.
  unfold rempty, rlift; simpl. rewrite PositiveMap.gempty; simpl; auto.
Qed.

Hint Rewrite rempty_rlift: rchecker.

Definition fresh (x:var) (r: renaming): renaming :=
  let bound:=rbound r in
  {| rmap:= PositiveMap.add (vid x) (mkvar (vtag x) bound) (rmap r) ;
     rbound:= (bound+1)%positive
  |}.

Lemma fresh_rbounds bound x r: rbounds bound rrbounds bound (fresh x r).
Proof.
  unfold rbounds, fresh; simpl; intuition.
  eauto with echecker.
  rewrite PositiveMapAdditionalFacts.gsspec.
  case (PositiveMap.E.eq_dec x0 (vid x)).
  intros; subst; simpl; intuition auto with checker.
  intros; eapply try_monotonic; eauto.
  simpl; intuition eauto with checker echecker2.
Qed.

Hint Resolve rbounds_rfind_up rbounds_rfind_down: echecker.
Hint Resolve rempty_rbounds fresh_rbounds: checker.

Lemma rfind_fresh_in x r: rfind x (fresh x r) = mkvar (vtag x) (rbound r).
Proof.
  unfold rfind, fresh; simpl.
  rewrite PositiveMap.add_1; auto.
  unfold PositiveMap.E.eq; auto.
Qed.

Hint Rewrite rfind_fresh_in: rchecker.

Lemma rfind_fresh r (x x':var): rfind x' (fresh x r) =
  if (PositiveMap.E.eq_dec (vid x') (vid x)) then mkvar (vtag x) (rbound r) else rfind x' r.
Proof.
 unfold rfind, fresh; simpl.
 rewrite PositiveMapAdditionalFacts.gsspec.
 case (PositiveMap.E.eq_dec (vid x') (vid x)); simpl; auto.
Qed.

Lemma rlift_fresh r (x1:var) s x2: rlift s (fresh x1 r) x2 = add (vid x1) (s (rbound r)) (rlift s r) x2.
Proof.
 unfold rlift, fresh; simpl.
 rewrite PositiveMapAdditionalFacts.gsspec.
 case (PositiveMap.E.eq_dec x2 (vid x1)); simpl.
 intros; subst; rewrite add_in; auto.
 intros; rewrite add_out2; auto.
Qed.

Lemma rlift_fresh_tech:
   bound r x dummy s, (rbounds bound r) →
   Zpos (vid x) < Zpos bound
   frameeq 0 (rbound r)
    (rlift (add (rbound r) (s (vid (rfind x r))) (add (vid x) dummy s)) (fresh x r))
    (rlift s r).
Proof.
  unfold frameeq; intros.
  rewrite rlift_fresh.
  rewrite add_in.
  case (PositiveMap.E.eq_dec x0 (vid x)).
  intros; subst.
  rewrite add_in.
  autorewrite with rchecker; auto.
  intros; rewrite add_out2; auto.
  eapply eq_trans.
  eapply rlift_add_out_2; eauto with checker.
  unfold rlift, rbounds in × |- ×.
  intuition.
  generalize (H3 x0); clear H3.
  case (PositiveMap.find x0 (rmap r)); simpl.
  intros; rewrite add_out; auto.
  omega.
  intros; rewrite add_out2; auto.
Qed.


Fixpoint trsubst (t:term) r: term :=
  match t with
  | tvar xtvar (rfind x r)
  | tcte ct
  | tbin op tl trtbin op (trsubst tl r) (trsubst tr r)
  | told ttrsubst t r
  | tapp f ttapp f (trsubst t r)
  end.

Lemma tbounds_trsubst t: bound r, rbounds bound rtbounds (rbound r) t
  tbounds (rbound r) (trsubst t r).
Proof.
  induction t; simpl; intuition eauto with echecker.
Qed.
Hint Resolve tbounds_trsubst: echecker.

Lemma trsubst_teval_rlift t: r s,
  teval (trsubst t r) s = teval t (rlift s r).
Proof.
  induction t; simpl; auto.
  intros; autorewrite with rchecker; auto.
  intros r s; rewrite IHt1. rewrite IHt2.
  auto.
  intros; rewrite IHt; auto.
Qed.
Hint Rewrite <- trsubst_teval_rlift: rchecker.

Lemma trsubst_rempty t: s bound,
  teval (trsubst t (rempty bound)) s = teval t s.
Proof.
  induction t; simpl; intuition.
  autorewrite with rchecker; auto.
  rewrite IHt1. rewrite IHt2; auto.
  rewrite IHt; auto.
Qed.
Hint Rewrite trsubst_rempty: rchecker.

Fixpoint rsubst (c:cond) r : cond
  := match c with
     | atom oc tl tratom oc (trsubst tl r) (trsubst tr r)
     | bin og cl crbin og (rsubst cl r) (rsubst cr r)
     | not cnot (rsubst c r)
     | _c
     end.

Lemma cbounds_rsubst c: bound r, rbounds bound rcbounds (rbound r) c
  cbounds (rbound r) (rsubst c r).
Proof.
  induction c; simpl; intuition; eauto with echecker.
Qed.
Hint Resolve cbounds_rsubst: echecker.

Lemma rsubst_rempty c: s bound,
  eval (rsubst c (rempty bound)) s = eval c s.
Proof.
  induction c; simpl; intuition.
  autorewrite with rchecker; auto.
  rewrite IHc1. rewrite IHc2; auto.
  rewrite IHc. auto.
Qed.
Hint Rewrite rsubst_rempty: rchecker.

Lemma rsubst_eval_rlift c: r s,
  eval (rsubst c r) s = eval c (rlift s r).
Proof.
  induction c; simpl; intuition.
  autorewrite with rchecker; auto.
  rewrite IHc1; rewrite IHc2; auto.
  erewrite IHc; auto.
Qed.
Hint Rewrite <- rsubst_eval_rlift: rchecker.

Lemma rsubst_fresh_cbounds c: bound r (x:var) dummy s, (rbounds bound r) → cbounds (rbound r) c
  Zpos (vid x) < Zpos bound
  eval (rsubst c (fresh x r)) (add (rbound r) (s (vid (rfind x r))) (add (vid x) dummy s)) = eval (rsubst c r) s.
Proof.
  intros. rewrite rsubst_eval_rlift. rewrite rsubst_eval_rlift.
  eapply frameeq_eval; eauto.
  eapply rlift_fresh_tech; eauto.
Qed.

Handling of "old"

Lemma frameeq_oteval (t: term): bound old new old' new',
   tbounds bound t
   tbounds bound t
    frameeq 0 bound old old'
     frameeq 0 bound new new'
      oteval t old new = oteval t old' new'.
Proof.
  unfold frameeq; induction t; simpl; intuition.
  erewrite IHt1; eauto.
  erewrite IHt2; eauto.
  eauto with echecker.
  erewrite IHt; eauto.
Qed.

Lemma frameeq_oeval c: bound old new old' new',
    frameeq 0 bound old old'
     frameeq 0 bound new new'
      cbounds bound c
      cbounds bound c
       oeval c old new = oeval c old' new'.
Proof.
  induction c; simpl; intuition.
  erewrite frameeq_oteval; eauto.
  erewrite frameeq_oteval with (new:=new); eauto.
  erewrite IHc1; eauto.
  erewrite IHc2; eauto.
  erewrite IHc; eauto.
Qed.

Fixpoint otrsubst (t:term) r: term :=
  match t with
  | tbin op tl trtbin op (otrsubst tl r) (otrsubst tr r)
  | told ttrsubst t r
  | tapp f ttapp f (otrsubst t r)
  | _t
  end.

Lemma tbounds_otrsubst t: bound r, rbounds bound rtbounds (rbound r) t
  tbounds (rbound r) (otrsubst t r).
Proof.
  induction t; simpl; intuition eauto with echecker.
Qed.
Hint Resolve tbounds_otrsubst: echecker.

Lemma otrsubst_rempty t: s bound,
  teval (otrsubst t (rempty bound)) s = teval t s.
Proof.
  induction t; simpl; intuition.
  rewrite IHt1. rewrite IHt2; auto.
  autorewrite with rchecker; auto.
  rewrite IHt; auto.
Qed.
Hint Rewrite otrsubst_rempty: rchecker.

Lemma otrsubst_eval_rlift t: r s,
  teval (otrsubst t r) s = oteval t (rlift s r) s.
Proof.
  induction t; simpl; intuition.
  rewrite IHt1; rewrite IHt2; auto.
  autorewrite with rchecker; auto.
  rewrite IHt; auto.
Qed.
Hint Rewrite <- otrsubst_eval_rlift: rchecker.

Fixpoint orsubst (c:cond) r : cond
  := match c with
     | atom oc tl tratom oc (otrsubst tl r) (otrsubst tr r)
     | bin og cl crbin og (orsubst cl r) (orsubst cr r)
     | not cnot (orsubst c r)
     | _c
     end.

Lemma cbounds_orsubst c: bound r, rbounds bound rcbounds (rbound r) c
  cbounds (rbound r) (orsubst c r).
Proof.
  induction c; simpl; intuition; eauto with echecker.
Qed.
Hint Resolve cbounds_orsubst: echecker.

Lemma orsubst_rempty c: s bound,
  eval (orsubst c (rempty bound)) s = eval c s.
Proof.
  induction c; simpl; intuition.
  autorewrite with rchecker; auto.
  rewrite IHc1. rewrite IHc2; auto.
  rewrite IHc; auto.
Qed.
Hint Rewrite orsubst_rempty: rchecker.

Lemma orsubst_eval_rlift c: r s,
  eval (orsubst c r) s = oeval c (rlift s r) s.
Proof.
  induction c; simpl; intuition.
  rewrite otrsubst_eval_rlift; rewrite otrsubst_eval_rlift; auto.
  rewrite IHc1; rewrite IHc2; eauto.
  rewrite IHc; auto.
Qed.

Swap of two variables
Definition swap (x y: var) bound :renaming :=
  {| rmap:= PositiveMap.add (vid x) y (PositiveMap.add (vid y) x (PositiveMap.empty _));
     rbound:= bound
  |}.

Lemma swap_rbounds bound1 bound2 (x y: var): Zpos bound1 Zpos (vid x) < Zpos bound2Zpos bound1 Zpos (vid y) < Zpos bound2rbounds bound1 (swap x y bound2).
Proof.
  unfold rbounds, swap; simpl; intuition.
  rewrite PositiveMapAdditionalFacts.gsspec.
  case (PositiveMap.E.eq_dec x0 (vid x)); simpl; auto.
  intros; rewrite PositiveMapAdditionalFacts.gsspec.
  case (PositiveMap.E.eq_dec x0 (vid y)); simpl; auto.
  intros; rewrite PositiveMap.gempty; simpl; auto.
Qed.

Lemma swap_rfind x y z bound:
  rfind z (swap x y bound) =
   if PositiveMap.E.eq_dec (vid z) (vid x)
   then y
   else if PositiveMap.E.eq_dec (vid z) (vid y)
   then x
   else z.
Proof.
  unfold swap, rfind; simpl.
  rewrite PositiveMapAdditionalFacts.gsspec.
  case (PositiveMap.E.eq_dec (vid z) (vid x)); auto.
  rewrite PositiveMapAdditionalFacts.gsspec.
  case (PositiveMap.E.eq_dec (vid z) (vid y)); auto.
  intros; rewrite PositiveMap.gempty; intuition.
Qed.

Lemma swap_rfind_1 x y bound: rfind x (swap x y bound)=y.
Proof.
  unfold swap, rfind; simpl.
  rewrite PositiveMap.add_1; intuition.
Qed.

Lemma swap_rfind_2 x y bound: (vid y)<>(vid x)rfind y (swap x y bound)=x.
Proof.
  intros H; rewrite swap_rfind.
  case (PositiveMap.E.eq_dec (vid y) (vid x)).
  intros; case H; auto.
  case (PositiveMap.E.eq_dec (vid y) (vid y)); auto.
  intros H0; case H0; auto.
Qed.

Hint Rewrite swap_rfind_1 swap_rfind_2: rchecker.

Lemma swap_rfind_3 x y bound z: (vid z)<>(vid x)(vid z)<>(vid y)rfind z (swap x y bound)=z.
Proof.
  intros H H0; rewrite swap_rfind.
  case (PositiveMap.E.eq_dec (vid z) (vid x)).
  intros; case H; auto.
  case (PositiveMap.E.eq_dec (vid z) (vid y)).
  intros; case H0; auto.
  auto.
Qed.

Lemma swap_rlift s x y z bound: rlift s (swap x y bound) z = add (vid x) (s (vid y)) (add (vid y) (s (vid x)) s) z.
Proof.
  unfold rlift, swap; simpl.
 rewrite PositiveMapAdditionalFacts.gsspec.
 case (PositiveMap.E.eq_dec z (vid x)).
 intros; subst; rewrite add_in; auto.
 intros; rewrite add_out2; auto.
 rewrite PositiveMapAdditionalFacts.gsspec.
 case (PositiveMap.E.eq_dec z (vid y)).
 intros; subst; rewrite add_in; auto.
 intros; rewrite add_out2; auto.
 rewrite PositiveMap.gempty; simpl; auto.
Qed.