Instance CompSpecs : compspecs. make_compspecs prog. Defined.
Definition Vprog : varspecs. mk_varspecs prog. Defined.
Definition putchar_spec := DECLARE _putchar putchar_spec.
Definition getchar_spec := DECLARE _getchar getchar_spec.
Definition getchar_blocking_spec :=
DECLARE _getchar_blocking
WITH k : byte -> IO_itree
PRE [ ]
PROP ()
LOCAL ()
SEP (ITREE (r <- read stdin;; k r))
POST [ tint ]
EX i : byte,
PROP ()
LOCAL (temp ret_temp (Vubyte i))
SEP (ITREE (k i)).
Definition putchar_blocking_spec :=
DECLARE _putchar_blocking
WITH c : byte, k : IO_itree
PRE [ _c OF tint ]
PROP ()
LOCAL (temp _c (Vubyte c))
SEP (ITREE (r <- write stdout c ;; k))
POST [ tint ]
PROP ()
LOCAL (temp ret_temp (Vubyte c))
SEP (ITREE k).
Program Fixpoint chars_of_Z (n : Z) { measure (Z.to_nat n) } : list byte :=
let n' := n / 10 in
match n' <=? 0 with true => [Byte.repr (n + char0)] | false => chars_of_Z n' ++ [Byte.repr (n mod 10 + char0)] end.
Next Obligation.
Opaque Nat.div Nat.modulo.
Definition ext_link := ext_link_prog prog.
Instance Espec : OracleKind := IO_Espec ext_link.
Definition init_mem := proj1_sig init_mem_exists.
Definition main_block_exists : {b | Genv.find_symbol (Genv.globalenv prog) (prog_main prog) = Some b}.
Definition main_block := proj1_sig main_block_exists.

(* correctness down to OS traces, with relationship between syscall events and actual external reads/writes *)
Theorem prog_OS_correct : forall {H : io_os_specs.ThreadsConfigurationOps},
exists q : Clight_new.corestate,
semantics.initial_core (Clight_new.cl_core_sem (globalenv prog)) 0 init_mem q init_mem (Vptr main_block Ptrofs.zero) [] /\
forall n s0, s0.(io_log) = [] -> s0.(console) = {| cons_buf := []; rpos := 0 |} ->
exists traces, OS_safeN_trace prog n Traces.TEnd traces main_itree s0 q init_mem /\
forall t s, Ensembles.In _ traces (t, s) -> exists z', consume_trace main_itree z' t /\ t = trace_of_ostrace s.(io_log) /\
valid_trace_user s.(io_log).