(* Lemma match_program_implies: forall (A B V W: Type) (LA: Linker A) (LV: Linker V) (match_fundef1 match_fundef2: program A V -> A -> B -> Prop) (match_varinfo1 match_varinfo2: V -> W -> Prop) p p', match_program match_fundef1 match_varinfo1 p p' -> (forall cu a b, match_fundef1 cu a b -> linkorder cu p -> match_fundef2 cu a b) -> (forall v w, match_varinfo1 v w -> match_varinfo2 v w) -> match_program match_fundef2 match_varinfo2 p p'. *)
(** Relation between the program transformation functions from [AST] and the [match_program] predicate. *)

(* Specifications: *)
Theorem match_transform_partial_program2:
forall {C F1 V1 F2 V2: Type} {LC: Linker C} {LF: Linker F1} {LV: Linker V1}
(match_fundef: C -> F1 -> F2 -> Prop)
(match_varinfo: V1 -> V2 -> Prop)
(transf_fun: ident -> F1 -> res F2)
(transf_var: ident -> V1 -> res V2)
(ctx: C) (p: program F1 V1) (tp: program F2 V2),
transform_partial_program2 transf_fun transf_var p = OK tp ->
(forall i f tf, transf_fun i f = OK tf -> match_fundef ctx f tf) ->
(forall i v tv, transf_var i v = OK tv -> match_varinfo v tv) ->
match_program_gen match_fundef match_varinfo ctx p tp.
Theorem match_transform_partial_program_contextual:
forall {A B V: Type} {LA: Linker A} {LV: Linker V}
(match_fundef: program A V -> A -> B -> Prop)
(transf_fun: A -> res B)
(p: program A V) (tp: program B V),
transform_partial_program transf_fun p = OK tp ->
(forall f tf, transf_fun f = OK tf -> match_fundef p f tf) ->
match_program match_fundef eq p tp.
Theorem match_transform_program_contextual:
forall {A B V: Type} {LA: Linker A} {LV: Linker V}
(match_fundef: program A V -> A -> B -> Prop)
(transf_fun: A -> B)
(p: program A V),
(forall f, match_fundef p f (transf_fun f)) ->
match_program match_fundef eq p (transform_program transf_fun p).
Theorem match_transform_partial_program2:
forall {C F1 V1 F2 V2: Type} {LC: Linker C} {LF: Linker F1} {LV: Linker V1}
(match_fundef: C -> F1 -> F2 -> Prop)
(match_varinfo: V1 -> V2 -> Prop)
(transf_fun: ident -> F1 -> res F2)
(transf_var: ident -> V1 -> res V2)
(ctx: C) (p: program F1 V1) (tp: program F2 V2),
transform_partial_program2 transf_fun transf_var p = OK tp ->
(forall i f tf, transf_fun i f = OK tf -> match_fundef ctx f tf) ->
(forall i v tv, transf_var i v = OK tv -> match_varinfo v tv) ->
match_program_gen match_fundef match_varinfo ctx p tp.
Theorem match_transform_partial_program_contextual:
forall {A B V: Type} {LA: Linker A} {LV: Linker V}
(match_fundef: program A V -> A -> B -> Prop)
(transf_fun: A -> res B)
(p: program A V) (tp: program B V),
transform_partial_program transf_fun p = OK tp ->
(forall f tf, transf_fun f = OK tf -> match_fundef p f tf) ->
match_program match_fundef eq p tp.
Theorem match_transform_program_contextual:
forall {A B V: Type} {LA: Linker A} {LV: Linker V}
(match_fundef: program A V -> A -> B -> Prop)
(transf_fun: A -> B)
(p: program A V),
(forall f, match_fundef p f (transf_fun f)) ->
match_program match_fundef eq p (transform_program transf_fun p).