Inductive Forall2' (A B : Type) (R : A -> B -> Type) : list A -> list B -> Type :=
    Forall2'_nil : Forall2' R [] []
  | Forall2'_cons : forall (x : A) (y : B) (l : list A) (l' : list B),
                   R x y -> Forall2' R l l' -> Forall2' R (x :: l) (y :: l').Inductive Forall2' (A B : Type) (R : A -> B -> Type) : list A -> list B -> Type :=
    Forall2'_nil : Forall2' R [] []
  | Forall2'_cons : forall (x : A) (y : B) (l : list A) (l' : list B),
                   R x y -> Forall2' R l l' -> Forall2' R (x :: l) (y :: l').Inductive Forall2' (A B : Type) (R : A -> B -> Type) : list A -> list B -> Type :=
    Forall2'_nil : Forall2' R [] []
  | Forall2'_cons : forall (x : A) (y : B) (l : list A) (l' : list B),
                   R x y -> Forall2' R l l' -> Forall2' R (x :: l) (y :: l').

Lemma evaluates_sound t v c: (forall (t0 : term) (v0 : value), assoc_cache t0 c = Some v0 -> evaluates t0 v0 /\ max_arity_term (term_from_value variable function v0) <= max_arity) -> evaluates t v -> max_arity_term t <= max_arity -> exists p, wf p /\ proj_right p = v /\ proj_left p = t /\ cache_left p = c /\ max_arity_term (term_from_value variable function v) <= max_arity /\ (forall t0 v0, assoc_cache t0 (cache_right p) = Some v0 -> evaluates t0 v0 /\ max_arity_term (term_from_value variable function v0) <= max_arity).