Align bound variables to their expressions.
(align-let-vars-values vars value) → (mv okp var-names var-types values)
A Syntheto binding expression binds a single expression to a list of variables. There must be at least one variable, otherwise it is an error. If there is exactly one variable, the (value of the) expression is bound to it. If there are two or more variables, the expression must return multiple values, whose number must match the number of variables, and these values are bound to the variables, in order.
Statically, we can ``align'' the expression with the variable as follows. When there is an empty list of variables, it is an error. When there is exactly one variable, it aligns with the whole expression. Where there are two or more variables, each aligns with a component of the expression, i.e. with a component expression whose subexpression is the original expression bound to the variable list.
This ACL2 function carries out this ``alignment''. It returns a list of expressions, as many as the variables, each of which corresponds to a variable. It also decomposes the typed variables into names and types. Furthermore, it ensures that there is at least one variable, returning an error indication if that is not the case. This function is called by check-bind-expression; see that function for further details.
Function:
(defun align-let-vars-values-aux (vars index value) (declare (xargs :guard (and (typed-variable-listp vars) (natp index) (expressionp value)))) (let ((__function__ 'align-let-vars-values-aux)) (declare (ignorable __function__)) (b* (((when (endp vars)) (mv nil nil nil)) (var (car vars)) (name (typed-variable->name var)) (type (typed-variable->type var)) (val (make-expression-component :multi value :index index)) ((mv names types vals) (align-let-vars-values-aux (cdr vars) (1+ (nfix index)) value))) (mv (cons name names) (cons type types) (cons val vals)))))
Theorem:
(defthm identifier-listp-of-align-let-vars-values-aux.var-names (b* (((mv ?var-names ?var-types common-lisp::?values) (align-let-vars-values-aux vars index value))) (identifier-listp var-names)) :rule-classes :rewrite)
Theorem:
(defthm type-listp-of-align-let-vars-values-aux.var-types (b* (((mv ?var-names ?var-types common-lisp::?values) (align-let-vars-values-aux vars index value))) (type-listp var-types)) :rule-classes :rewrite)
Theorem:
(defthm expression-listp-of-align-let-vars-values-aux.values (b* (((mv ?var-names ?var-types common-lisp::?values) (align-let-vars-values-aux vars index value))) (expression-listp values)) :rule-classes :rewrite)
Theorem:
(defthm len-of-align-let-vars-values-aux.names (b* (((mv ?var-names ?var-types common-lisp::?values) (align-let-vars-values-aux vars index value))) (equal (len var-names) (len vars))))
Theorem:
(defthm len-of-align-let-vars-values-aux.types (b* (((mv ?var-names ?var-types common-lisp::?values) (align-let-vars-values-aux vars index value))) (equal (len var-types) (len vars))))
Theorem:
(defthm len-of-align-let-vars-values-aux.values (b* (((mv ?var-names ?var-types common-lisp::?values) (align-let-vars-values-aux vars index value))) (equal (len values) (len vars))))
Theorem:
(defthm align-let-vars-values-aux-of-typed-variable-list-fix-vars (equal (align-let-vars-values-aux (typed-variable-list-fix vars) index value) (align-let-vars-values-aux vars index value)))
Theorem:
(defthm align-let-vars-values-aux-typed-variable-list-equiv-congruence-on-vars (implies (typed-variable-list-equiv vars vars-equiv) (equal (align-let-vars-values-aux vars index value) (align-let-vars-values-aux vars-equiv index value))) :rule-classes :congruence)
Theorem:
(defthm align-let-vars-values-aux-of-nfix-index (equal (align-let-vars-values-aux vars (nfix index) value) (align-let-vars-values-aux vars index value)))
Theorem:
(defthm align-let-vars-values-aux-nat-equiv-congruence-on-index (implies (nat-equiv index index-equiv) (equal (align-let-vars-values-aux vars index value) (align-let-vars-values-aux vars index-equiv value))) :rule-classes :congruence)
Theorem:
(defthm align-let-vars-values-aux-of-expression-fix-value (equal (align-let-vars-values-aux vars index (expression-fix value)) (align-let-vars-values-aux vars index value)))
Theorem:
(defthm align-let-vars-values-aux-expression-equiv-congruence-on-value (implies (expression-equiv value value-equiv) (equal (align-let-vars-values-aux vars index value) (align-let-vars-values-aux vars index value-equiv))) :rule-classes :congruence)
Function:
(defun align-let-vars-values (vars value) (declare (xargs :guard (and (typed-variable-listp vars) (expressionp value)))) (let ((__function__ 'align-let-vars-values)) (declare (ignorable __function__)) (cond ((endp vars) (mv nil nil nil nil)) ((endp (cdr vars)) (mv t (typed-variable-list->name-list vars) (typed-variable-list->type-list vars) (list (expression-fix value)))) (t (b* (((mv names types values) (align-let-vars-values-aux vars 0 value))) (mv t names types values))))))
Theorem:
(defthm booleanp-of-align-let-vars-values.okp (b* (((mv ?okp ?var-names ?var-types common-lisp::?values) (align-let-vars-values vars value))) (booleanp okp)) :rule-classes :rewrite)
Theorem:
(defthm identifier-listp-of-align-let-vars-values.var-names (b* (((mv ?okp ?var-names ?var-types common-lisp::?values) (align-let-vars-values vars value))) (identifier-listp var-names)) :rule-classes :rewrite)
Theorem:
(defthm type-listp-of-align-let-vars-values.var-types (b* (((mv ?okp ?var-names ?var-types common-lisp::?values) (align-let-vars-values vars value))) (type-listp var-types)) :rule-classes :rewrite)
Theorem:
(defthm expression-listp-of-align-let-vars-values.values (b* (((mv ?okp ?var-names ?var-types common-lisp::?values) (align-let-vars-values vars value))) (expression-listp values)) :rule-classes :rewrite)
Theorem:
(defthm len-of-align-let-vars-values.names (b* (((mv ?okp ?var-names ?var-types common-lisp::?values) (align-let-vars-values vars value))) (equal (len var-names) (len vars))))
Theorem:
(defthm len-of-align-let-vars-values.types (b* (((mv ?okp ?var-names ?var-types common-lisp::?values) (align-let-vars-values vars value))) (equal (len var-types) (len vars))))
Theorem:
(defthm len-of-align-let-vars-values.values (b* (((mv ?okp ?var-names ?var-types common-lisp::?values) (align-let-vars-values vars value))) (equal (len values) (len vars))))
Theorem:
(defthm align-let-vars-values-of-typed-variable-list-fix-vars (equal (align-let-vars-values (typed-variable-list-fix vars) value) (align-let-vars-values vars value)))
Theorem:
(defthm align-let-vars-values-typed-variable-list-equiv-congruence-on-vars (implies (typed-variable-list-equiv vars vars-equiv) (equal (align-let-vars-values vars value) (align-let-vars-values vars-equiv value))) :rule-classes :congruence)
Theorem:
(defthm align-let-vars-values-of-expression-fix-value (equal (align-let-vars-values vars (expression-fix value)) (align-let-vars-values vars value)))
Theorem:
(defthm align-let-vars-values-expression-equiv-congruence-on-value (implies (expression-equiv value value-equiv) (equal (align-let-vars-values vars value) (align-let-vars-values vars value-equiv))) :rule-classes :congruence)