let prop_binop mem binop tr e1 t1 e2 t2 =
match binop with
| IndexPI | PlusPI ->
let te = Ctypes.object_of_pointed (Ctypes.object_of t1) in
let loc = loc_of_value (!expr_rec mem e1) in
let idx = int_of_value (!expr_rec mem e2) in
prop_of_loc (M.shift loc te idx)
| MinusPI ->
let te = Ctypes.object_of_pointed (Ctypes.object_of t1) in
let loc = loc_of_value (!expr_rec mem e1) in
let neg_idx = int_of_value (!expr_rec mem e2) in
let idx = F.e_ineg neg_idx in
prop_of_loc (M.shift loc te idx)
| MinusPP ->
prop_of_integer
(M.minus_loc
(loc_of_value (!expr_rec mem e1))
(loc_of_value (!expr_rec mem e2)))
| (Eq | Ne | Ge | Le | Gt | Lt) ->
prop_cmp mem binop t1 e1 t2 e2
| PlusA | MinusA | Mult | Div | Mod
| BAnd | BXor | BOr | Shiftlt | Shiftrt ->
let ct1 = Ctypes.object_of t1 in
let ct2 = Ctypes.object_of t2 in
let ctr = Ctypes.object_of tr in
begin
match ctr , ct1 , ct2 with
| C_int ir , C_int i1 , C_int i2 ->
prop_of_int (expr_int_operator mem ir binop i1 e1 i2 e2)
| C_float fr, C_float f1, C_float f2 ->
prop_of_float
(expr_float_operator mem fr binop f1 e1 f2 e2)
| _ -> WpLog.fatal "non arithmetics arguments"
end
| LAnd -> F.p_and (!prop_rec mem e1) (!prop_rec mem e2)
| LOr -> F.p_or (!prop_rec mem e1) (!prop_rec mem e2)