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').

(* Specifications: *)
Lemma Forall2_trans_rel (A : Type) (R1 R2 : A -> A -> Prop) (l1 l2 : list A) : (forall x y, R1 x y -> R2 x y) -> Forall2 R1 l1 l2 -> Forall2 R2 l1 l2.
Lemma Forall2_product (A : Type) (R : A -> A -> Prop) (ls lt : list A) : ls <> [] -> Forall2 R ls lt -> product R ls lt.
Lemma Forall2_eq A (l1 l2 : list A) : Forall2 eq l1 l2 -> l1 = l2.
Lemma evaluates_unique t v1 v2 : evaluates t v1 -> evaluates t v2 -> v1 = v2.
Lemma evaluates_value v : evaluates (term_from_value _ _ v) v.
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).
Lemma evaluates_sound' (t : term) (v : value): evaluates t v -> max_arity_term t <= max_arity -> exists p, wf p /\ proj_right p = v /\ proj_left p = t.