Validate a conditional expression, given types for its operands.
The first operand must have scalar type [C:6.5.15/2]. In our currently approximate type system, the other two operands must have both arithmetic type, or both the structure type, or both the union type, or both the void type, or both the pointer type [C:6.5.15/3]. The type of the result is the one from the usual arithmetic converions in the first case, and the common type in the other cases [C:6.5.15/5]. Since pointers may be involved, we need to perform array-to-pointer and function-to-pointer conversions.
Function:
(defun valid-cond (expr type-test type-then type-else ienv) (declare (xargs :guard (and (exprp expr) (typep type-test) (typep type-then) (typep type-else) (ienvp ienv)))) (declare (xargs :guard (expr-case expr :cond))) (let ((__function__ 'valid-cond)) (declare (ignorable __function__)) (b* (((reterr) (irr-type)) ((when (or (type-case type-test :unknown) (type-case type-then :unknown) (type-case type-else :unknown))) (retok (type-unknown))) (type1 (type-fpconvert (type-apconvert type-test))) (type2 (type-fpconvert (type-apconvert type-then))) (type3 (type-fpconvert (type-apconvert type-else))) ((unless (type-scalarp type1)) (reterr (msg "In the conditional expression ~x0, ~ the first operand has type ~x1." (expr-fix expr) (type-fix type-test)))) ((when (and (type-arithmeticp type2) (type-arithmeticp type3))) (retok (type-uaconvert type2 type3 ienv))) ((when (and (type-case type2 :struct) (type-case type3 :struct))) (retok (type-struct))) ((when (and (type-case type2 :union) (type-case type3 :union))) (retok (type-union))) ((when (and (type-case type2 :pointer) (type-case type3 :pointer))) (retok (type-pointer)))) (reterr (msg "In the conditional expression ~x0, ~ the second operand has type ~x1 ~ and the third operand has type ~x2." (expr-fix expr) (type-fix type-then) (type-fix type-else))))))
Theorem:
(defthm typep-of-valid-cond.type (b* (((mv acl2::?erp ?type) (valid-cond expr type-test type-then type-else ienv))) (typep type)) :rule-classes :rewrite)
Theorem:
(defthm valid-cond-of-expr-fix-expr (equal (valid-cond (expr-fix expr) type-test type-then type-else ienv) (valid-cond expr type-test type-then type-else ienv)))
Theorem:
(defthm valid-cond-expr-equiv-congruence-on-expr (implies (expr-equiv expr expr-equiv) (equal (valid-cond expr type-test type-then type-else ienv) (valid-cond expr-equiv type-test type-then type-else ienv))) :rule-classes :congruence)
Theorem:
(defthm valid-cond-of-type-fix-type-test (equal (valid-cond expr (type-fix type-test) type-then type-else ienv) (valid-cond expr type-test type-then type-else ienv)))
Theorem:
(defthm valid-cond-type-equiv-congruence-on-type-test (implies (type-equiv type-test type-test-equiv) (equal (valid-cond expr type-test type-then type-else ienv) (valid-cond expr type-test-equiv type-then type-else ienv))) :rule-classes :congruence)
Theorem:
(defthm valid-cond-of-type-fix-type-then (equal (valid-cond expr type-test (type-fix type-then) type-else ienv) (valid-cond expr type-test type-then type-else ienv)))
Theorem:
(defthm valid-cond-type-equiv-congruence-on-type-then (implies (type-equiv type-then type-then-equiv) (equal (valid-cond expr type-test type-then type-else ienv) (valid-cond expr type-test type-then-equiv type-else ienv))) :rule-classes :congruence)
Theorem:
(defthm valid-cond-of-type-fix-type-else (equal (valid-cond expr type-test type-then (type-fix type-else) ienv) (valid-cond expr type-test type-then type-else ienv)))
Theorem:
(defthm valid-cond-type-equiv-congruence-on-type-else (implies (type-equiv type-else type-else-equiv) (equal (valid-cond expr type-test type-then type-else ienv) (valid-cond expr type-test type-then type-else-equiv ienv))) :rule-classes :congruence)
Theorem:
(defthm valid-cond-of-ienv-fix-ienv (equal (valid-cond expr type-test type-then type-else (ienv-fix ienv)) (valid-cond expr type-test type-then type-else ienv)))
Theorem:
(defthm valid-cond-ienv-equiv-congruence-on-ienv (implies (ienv-equiv ienv ienv-equiv) (equal (valid-cond expr type-test type-then type-else ienv) (valid-cond expr type-test type-then type-else ienv-equiv))) :rule-classes :congruence)