Validate a binary expression, given the type of the sub-expression.
The
The
The
The
The
The
The
The
The
The
The
The
The
The
Function:
(defun valid-binary (expr op type-arg1 type-arg2 ienv) (declare (xargs :guard (and (exprp expr) (binopp op) (typep type-arg1) (typep type-arg2) (ienvp ienv)))) (declare (xargs :guard (expr-case expr :binary))) (let ((__function__ 'valid-binary)) (declare (ignorable __function__)) (b* (((reterr) (irr-type)) ((when (or (type-case type-arg1 :unknown) (type-case type-arg2 :unknown))) (retok (type-unknown))) (msg (msg "In the binary expression ~x0, ~ the sub-expressiona have types ~x1 and ~x2." (expr-fix expr) (type-fix type-arg1) (type-fix type-arg2)))) (case (binop-kind op) ((:mul :div) (b* (((unless (and (type-arithmeticp type-arg1) (type-arithmeticp type-arg2))) (reterr msg))) (retok (type-uaconvert type-arg1 type-arg2 ienv)))) (:rem (b* (((unless (and (type-arithmeticp type-arg1) (type-arithmeticp type-arg2))) (reterr msg))) (retok (type-uaconvert type-arg1 type-arg2 ienv)))) (:add (b* ((type1 (type-apconvert type-arg1)) (type2 (type-apconvert type-arg2))) (cond ((and (type-arithmeticp type1) (type-arithmeticp type2)) (retok (type-uaconvert type1 type2 ienv))) ((or (and (type-integerp type1) (type-case type2 :pointer)) (and (type-case type1 :pointer) (type-integerp type2))) (retok (type-pointer))) (t (reterr msg))))) (:sub (b* ((type1 (type-apconvert type-arg1)) (type2 (type-apconvert type-arg2))) (cond ((and (type-arithmeticp type1) (type-arithmeticp type2)) (retok (type-uaconvert type1 type2 ienv))) ((and (type-case type1 :pointer) (type-case type2 :pointer)) (retok (type-unknown))) ((and (type-case type1 :pointer) (type-integerp type2)) (retok (type-pointer))) (t (reterr msg))))) ((:shl :shr) (b* (((unless (and (type-integerp type-arg1) (type-integerp type-arg2))) (reterr msg))) (retok (type-promote type-arg1 ienv)))) ((:lt :gt :le :ge) (b* ((type1 (type-apconvert type-arg1)) (type2 (type-apconvert type-arg2)) ((unless (or (and (type-realp type1) (type-realp type2)) (and (type-case type1 :pointer) (type-case type2 :pointer)))) (reterr msg))) (retok (type-sint)))) ((:eq :ne) (b* ((type1 (type-fpconvert (type-apconvert type-arg1))) (type2 (type-fpconvert (type-apconvert type-arg2))) ((unless (or (and (type-arithmeticp type1) (type-arithmeticp type2)) (and (type-case type1 :pointer) (type-case type2 :pointer)))) (reterr msg))) (retok (type-sint)))) ((:bitand :bitxor :bitior) (b* (((unless (and (type-integerp type-arg1) (type-integerp type-arg2))) (reterr msg))) (retok (type-uaconvert type-arg1 type-arg2 ienv)))) ((:logand :logor) (b* ((type1 (type-fpconvert (type-apconvert type-arg1))) (type2 (type-fpconvert (type-apconvert type-arg2))) ((unless (and (type-scalarp type1) (type-scalarp type2))) (reterr msg))) (retok (type-sint)))) (:asg (b* ((type1 type-arg1) (type2 (type-fpconvert (type-apconvert type-arg2))) ((unless (or (and (type-arithmeticp type1) (type-arithmeticp type2)) (and (type-case type1 :struct) (type-case type2 :struct)) (and (type-case type1 :union) (type-case type2 :union)) (and (or (type-case type1 :pointer) (type-case type1 :bool)) (type-case type2 :pointer)))) (reterr msg))) (retok (type-fix type-arg1)))) ((:asg-mul :asg-div) (b* (((unless (and (type-arithmeticp type-arg1) (type-arithmeticp type-arg2))) (reterr msg))) (retok (type-fix type-arg1)))) (:asg-rem (b* (((unless (and (type-integerp type-arg1) (type-integerp type-arg2))) (reterr msg))) (retok (type-fix type-arg1)))) ((:asg-add :asg-sub) (b* ((type1 (type-fpconvert (type-apconvert type-arg1))) (type2 (type-fpconvert (type-apconvert type-arg2))) ((unless (or (and (type-arithmeticp type1) (type-arithmeticp type2)) (and (type-case type1 :pointer) (type-integerp type2)))) (reterr msg))) (retok (type-fix type-arg1)))) ((:asg-shl :asg-shr :asg-and :asg-xor :asg-ior) (b* (((unless (and (type-integerp type-arg1) (type-integerp type-arg2))) (reterr msg))) (retok (type-fix type-arg1)))) (t (prog2$ (impossible) (reterr t)))))))
Theorem:
(defthm typep-of-valid-binary.type (b* (((mv acl2::?erp ?type) (valid-binary expr op type-arg1 type-arg2 ienv))) (typep type)) :rule-classes :rewrite)
Theorem:
(defthm valid-binary-of-expr-fix-expr (equal (valid-binary (expr-fix expr) op type-arg1 type-arg2 ienv) (valid-binary expr op type-arg1 type-arg2 ienv)))
Theorem:
(defthm valid-binary-expr-equiv-congruence-on-expr (implies (expr-equiv expr expr-equiv) (equal (valid-binary expr op type-arg1 type-arg2 ienv) (valid-binary expr-equiv op type-arg1 type-arg2 ienv))) :rule-classes :congruence)
Theorem:
(defthm valid-binary-of-binop-fix-op (equal (valid-binary expr (binop-fix op) type-arg1 type-arg2 ienv) (valid-binary expr op type-arg1 type-arg2 ienv)))
Theorem:
(defthm valid-binary-binop-equiv-congruence-on-op (implies (binop-equiv op op-equiv) (equal (valid-binary expr op type-arg1 type-arg2 ienv) (valid-binary expr op-equiv type-arg1 type-arg2 ienv))) :rule-classes :congruence)
Theorem:
(defthm valid-binary-of-type-fix-type-arg1 (equal (valid-binary expr op (type-fix type-arg1) type-arg2 ienv) (valid-binary expr op type-arg1 type-arg2 ienv)))
Theorem:
(defthm valid-binary-type-equiv-congruence-on-type-arg1 (implies (type-equiv type-arg1 type-arg1-equiv) (equal (valid-binary expr op type-arg1 type-arg2 ienv) (valid-binary expr op type-arg1-equiv type-arg2 ienv))) :rule-classes :congruence)
Theorem:
(defthm valid-binary-of-type-fix-type-arg2 (equal (valid-binary expr op type-arg1 (type-fix type-arg2) ienv) (valid-binary expr op type-arg1 type-arg2 ienv)))
Theorem:
(defthm valid-binary-type-equiv-congruence-on-type-arg2 (implies (type-equiv type-arg2 type-arg2-equiv) (equal (valid-binary expr op type-arg1 type-arg2 ienv) (valid-binary expr op type-arg1 type-arg2-equiv ienv))) :rule-classes :congruence)
Theorem:
(defthm valid-binary-of-ienv-fix-ienv (equal (valid-binary expr op type-arg1 type-arg2 (ienv-fix ienv)) (valid-binary expr op type-arg1 type-arg2 ienv)))
Theorem:
(defthm valid-binary-ienv-equiv-congruence-on-ienv (implies (ienv-equiv ienv ienv-equiv) (equal (valid-binary expr op type-arg1 type-arg2 ienv) (valid-binary expr op type-arg1 type-arg2 ienv-equiv))) :rule-classes :congruence)