(** * Satisfaction of specifications *)
(** The second additional results shows that if all executions of the source C program satisfies a given specification, then all executions of the produced Asm program satisfy this specification as well.  *)
(** The specifications we consider here are sets of observable behaviors, representing the good behaviors a program is expected to have.  A specification can be as simple as ``the program does not go wrong'' or as precise as ``the program prints a prime number then terminates with code 0''. As usual in Coq, sets of behaviors are represented as predicates [program_behavior -> Prop]. *)
Definition specification := program_behavior -> Prop.
(** A program satisfies a specification if all its observable behaviors are in the specification. *)
Definition c_program_satisfies_spec (p: Csyntax.program) (spec: specification): Prop :=
forall beh,  program_behaves (Csem.semantics p) beh -> spec beh.
Definition asm_program_satisfies_spec (p: Asm.program) (spec: specification): Prop :=
forall beh,  program_behaves (Asm.semantics p) beh -> spec beh.
(** It is not always the case that if the source program satisfies a specification, then the generated assembly code satisfies it as well.  For example, if the specification is ``the program goes wrong on an undefined behavior'', a C source that goes wrong satisfies this specification but can be compiled into Asm code that does not go wrong and therefore does not satisfy the specification.  For this reason, we restrict ourselves to safety-enforcing specifications: specifications that exclude ``going wrong'' behaviors and are satisfied only by programs that execute safely. *)
Definition safety_enforcing_specification (spec: specification): Prop :=
forall beh, spec beh -> not_wrong beh.
(** As the main result of this section, we show that CompCert compilation preserves safety-enforcing specifications: any such specification that is satisfied by the source C program is always satisfied by the generated assembly code. *)

(* Specifications: *)
Theorem transf_c_program_preserves_spec:
forall p tp spec,
transf_c_program p = OK tp ->
safety_enforcing_specification spec ->
c_program_satisfies_spec p spec ->
asm_program_satisfies_spec tp spec.