Definition beq_int (i1 i2 : Integers.int) : bool :=
Zbool.Zeq_bool (Int.intval i1) (Int.intval i2).
Hint Resolve beq_int_true : expr_beq.
Hint Resolve beq_int_refl : expr_beq.
Hint Rewrite beq_int_refl : expr_beq.
Definition beq_long (i1 i2 : int64) : bool :=
Zeq_bool (Int64.intval i1) (Int64.intval i2).
Hint Resolve beq_long_refl : expr_beq.
Hint Rewrite beq_long_refl : expr_beq.
Hint Resolve beq_long_true : expr_beq.
Definition beq_float_dec a b:= if Float.eq_dec a b then true else false.
intros.  unfold beq_float_dec in *. destruct (Float.eq_dec a b); congruence.
Qed. (*If things are slow, this may be the culprit *)
Hint Resolve beq_float_refl : expr_beq.
Hint Rewrite beq_float_refl : expr_beq.
Hint Resolve beq_float_dec_true : expr_beq.
Definition beq_float32_dec a b:= if Float32.eq_dec a b then true else false.
intros.  unfold beq_float32_dec in *. destruct (Float32.eq_dec a b); congruence.
Qed. (*If things are slow, this may be the culprit *)
Hint Resolve beq_float32_refl : expr_beq.
Hint Rewrite beq_float32_refl : expr_beq.
Hint Resolve beq_float32_dec_true : expr_beq.
Definition unary_op_beq a b :=
match a, b with
| Onotbool, Onotbool
| Onotint, Onotint
| Oneg, Oneg
| Oabsfloat, Oabsfloat => true
| _, _ => false
end.
destruct a, b; simpl in *; try congruence; auto.
Qed.
destruct a; auto.
Qed.
Hint Resolve unary_op_beq_refl : expr_beq.
Hint Rewrite unary_op_beq_refl : expr_beq.
Hint Resolve unary_op_beq_sound: expr_beq.
Definition binary_op_beq a b :=
match a, b with
Oadd, Oadd
| Osub, Osub
| Omul, Omul
| Odiv, Odiv
| Omod, Omod
| Oand, Oand
| Oor, Oor
| Oxor, Oxor
| Oshl, Oshl
| Oshr, Oshr
| Oeq, Oeq
| One, One
| Olt, Olt
| Ogt, Ogt
| Ole, Ole
| Oge, Oge => true
| _, _ => false
end.

Lemma binary_op_beq_sound : forall a b, binary_op_beq a b = true -> a = b .