Module VSF := FSetFacts.Facts(VSet).Module VSP := FSetProperties.Properties(VSet).Definition match_prog (p tp: program) : Prop :=
    match_program (fun ctx f tf => transf_fundef f = OK tf) eq p tp
 /\ prog_types tp = prog_types p.

(* Specifications: *)
Lemma match_transf_program: forall p tp, transf_program p = OK tp -> match_prog p tp.
Lemma comp_env_preserved: genv_cenv tge = genv_cenv ge.
Lemma symbols_preserved: forall (s: ident), Genv.find_symbol tge s = Genv.find_symbol ge s.
Lemma senv_preserved: Senv.equiv ge tge.
Lemma functions_translated: forall (v: val) (f: fundef), Genv.find_funct ge v = Some f -> exists tf, Genv.find_funct tge v = Some tf /\ transf_fundef f = OK tf.
Lemma function_ptr_translated: forall (b: block) (f: fundef), Genv.find_funct_ptr ge b = Some f -> exists tf, Genv.find_funct_ptr tge b = Some tf /\ transf_fundef f = OK tf.
Lemma type_of_fundef_preserved: forall fd tfd, transf_fundef fd = OK tfd -> type_of_fundef tfd = type_of_fundef fd.
Lemma match_envs_invariant: forall f cenv e le m lo hi te tle tlo thi f' m', match_envs f cenv e le m lo hi te tle tlo thi -> (forall b chunk v, f b = None -> Ple lo b /\ Plt b hi -> Mem.load chunk m b 0 = Some v -> Mem.load chunk m' b 0 = Some v) -> inject_incr f f' -> (forall b, Ple lo b /\ Plt b hi -> f' b = f b) -> (forall b b' delta, f' b = Some(b', delta) -> Ple tlo b' /\ Plt b' thi -> f' b = f b) -> match_envs f' cenv e le m' lo hi te tle tlo thi.
Lemma match_envs_extcall: forall f cenv e le m lo hi te tle tlo thi tm f' m', match_envs f cenv e le m lo hi te tle tlo thi -> Mem.unchanged_on (loc_unmapped f) m m' -> inject_incr f f' -> inject_separated f f' m tm -> Ple hi (Mem.nextblock m) -> Ple thi (Mem.nextblock tm) -> match_envs f' cenv e le m' lo hi te tle tlo thi.
Lemma val_casted_load_result: forall v ty chunk, val_casted v ty -> access_mode ty = By_value chunk -> Val.load_result chunk v = v.
Lemma val_casted_inject: forall f v v' ty, Val.inject f v v' -> val_casted v ty -> val_casted v' ty.
Lemma forall2_val_casted_inject: forall f vl vl', Val.inject_list f vl vl' -> forall tyl, list_forall2 val_casted vl tyl -> list_forall2 val_casted vl' tyl.