Definition rule_subst_of_cbv_update ( subst_default : variable -> value) (proof_tree : cbv) : nat * (variable -> value) :=
  match proof_tree with
  | cbv_update i s _ _ _ _ _ => (i, s)
  | _ => (0, subst_default) (* impossible case *)
  end.Definition proj_left (proof_tree : cbv) : term :=
  match proof_tree with
    | cbv_constr _ _ t _ _ => t
    | cbv_split _ _ _ t _ _ => t
    | cbv_update _ _ _ _ t _ _ => t
    | cbv_read _ t _ => t
  end.Definition proj_right (proof_tree : cbv) : value :=
  match proof_tree with
    | cbv_constr _ _ _ _ v => v
    | cbv_split _ _ _ _ _ v => v
    | cbv_update _ _ _ _ _ _ v => v
    | cbv_read _ _ v => v
  end.Definition cache_left (proof_tree : cbv) : cache :=
  match proof_tree with
    | cbv_constr _ c _ _ _ => c
    | cbv_split _ _ c _ _ _ => c
    | cbv_update _ _ _ c _ _ _ => c
    | cbv_read c _ _ => c
  end.Definition cache_right (proof_tree : cbv) : cache :=
  match proof_tree with
    | cbv_constr _ _ _ c _ => c
    | cbv_split _ _ _ _ c _ => c
    | cbv_update _ _ _ _ _ c _ => c
    | cbv_read c _ _ => c
  end.Fixpoint cache_path (C C' : cache)(l : list cbv) : bool :=
  match l with
  | nil => cache_beq C C' 
  | p :: l' => cache_beq C (cache_left p) && cache_path (cache_right p) C' l'
  end.

(* Specifications: *)
Lemma cache_path_cons c1 c2 p lp : cache_path c1 c2 (p :: lp) = true <-> cache_path c1 (cache_right p) [p] = true /\ cache_path (cache_right p) c2 lp = true.
Lemma cache_path_app c1 c2 lp p lp' : cache_path c1 c2 (lp ++ p :: lp') = true <-> cache_path c1 (cache_left p) lp = true /\ cache_path (cache_left p) c2 (p :: lp') = true.
Lemma cache_path_ind (P : cache -> cache -> list cbv -> Prop) C : (P C C []) -> (forall p lp, cache_path (cache_left p) C (p :: lp) = true -> P (cache_right p) C lp -> P (cache_left p) C (p :: lp)) -> forall lp C', cache_path C' C lp = true -> P C' C lp.
Lemma cache_path_revflatten c1 c2 lp Clp : cache_path c1 c2 lp = true -> Forall2 (fun p C => cache_right p = C ++ cache_left p) lp Clp -> c2 = revflatten Clp ++ c1.
Lemma cache_path_transitivity_left c c' l: forall P:cache-> Prop, cache_path c c' l = true -> P c ->(forall p, In p l -> P (cache_left p) -> P (cache_right p)) -> (forall p, In p l -> P (cache_left p)).
Lemma cache_path_transitivity c c' l: forall P:cache-> Prop, cache_path c c' l = true -> P c ->(forall p, In p l -> P (cache_left p) -> P (cache_right p)) -> P c'.