Definition option_list_to_list {A} (x: option (list A)) : list A :=
match x with Some al => al | None => nil end.
Inductive builtin_event: external_function -> mem -> list val -> list mem_event -> Prop :=
BE_malloc: forall m n m'' b m'
(ALLOC: Mem.alloc m (-size_chunk Mptr) (Ptrofs.unsigned n) = (m'', b))
(ALGN : (align_chunk Mptr | (-size_chunk Mptr)))
(ST: Mem.storebytes m'' b (-size_chunk Mptr) (encode_val Mptr (Vptrofs n)) = Some m'),
builtin_event EF_malloc m [Vptrofs n]
[Alloc b (-size_chunk Mptr) (Ptrofs.unsigned n);
Write b (-size_chunk Mptr) (encode_val Mptr (Vptrofs n))]
| BE_free: forall m b lo bytes sz m'
(POS: Ptrofs.unsigned sz > 0)
(LB : Mem.loadbytes m b (Ptrofs.unsigned lo - size_chunk Mptr) (size_chunk Mptr) = Some bytes)
(FR: Mem.free m b (Ptrofs.unsigned lo - size_chunk Mptr) (Ptrofs.unsigned lo + Ptrofs.unsigned sz) = Some m')
(ALGN : (align_chunk Mptr | Ptrofs.unsigned lo - size_chunk Mptr))
(SZ : Vptrofs sz = decode_val Mptr bytes),
builtin_event EF_free m [Vptr b lo]
[Read b (Ptrofs.unsigned lo - size_chunk Mptr) (size_chunk Mptr) bytes;
Free [(b,Ptrofs.unsigned lo - size_chunk Mptr, Ptrofs.unsigned lo + Ptrofs.unsigned sz)]]
| BE_memcpy: forall m al bsrc bdst sz bytes osrc odst m'
(AL: al = 1 \/ al = 2 \/ al = 4 \/ al = 8)
(POS : sz >= 0)
(DIV : (al | sz))
(OSRC : sz > 0 -> (al | Ptrofs.unsigned osrc))
(ODST: sz > 0 -> (al | Ptrofs.unsigned odst))
(RNG: bsrc <> bdst \/
Ptrofs.unsigned osrc = Ptrofs.unsigned odst \/
Ptrofs.unsigned osrc + sz <= Ptrofs.unsigned odst \/ Ptrofs.unsigned odst + sz <= Ptrofs.unsigned osrc)
(LB: Mem.loadbytes m bsrc (Ptrofs.unsigned osrc) sz = Some bytes)
(ST: Mem.storebytes m bdst (Ptrofs.unsigned odst) bytes = Some m'),
builtin_event (EF_memcpy sz al) m [Vptr bdst odst; Vptr bsrc osrc]
[Read bsrc (Ptrofs.unsigned osrc) sz bytes;
Write bdst (Ptrofs.unsigned odst) bytes]
(*| BE_EFexternal: forall name sg m vargs, (*        I64Helpers.is_I64_helperS name sg ->*)
builtin_event (EF_external name sg) m vargs []
| BE_EFbuiltin: forall name sg m vargs, (*is_I64_builtinS name sg ->*)
builtin_event (EF_builtin name sg) m vargs []*)
| BE_other: forall ef m vargs,
match ef with EF_malloc | EF_free | EF_memcpy _ _ => False | _ => True end ->
builtin_event ef m vargs [].

Lemma builtin_event_determ ef m vargs T1 (BE1: builtin_event ef m vargs T1) T2 (BE2: builtin_event ef m vargs T2): T1=T2.
inversion BE1; inv BE2; try discriminate; try contradiction; simpl in *; trivial.