Evaluate an expression, given an assignment and a prime field.
(eval-expr expr asg p) → nat
In effect, this extends the assignment from variables to expressions.
If a variable is not in the assignment,
it is an error, indicated by
Function:
(defun eval-expr (expr asg p) (declare (xargs :guard (and (expressionp expr) (assignmentp asg) (primep p)))) (declare (xargs :guard (assignment-wfp asg p))) (let ((__function__ 'eval-expr)) (declare (ignorable __function__)) (expression-case expr :const (mod expr.value p) :var (b* ((pair (omap::in expr.name (assignment-fix asg)))) (if (consp pair) (nfix (cdr pair)) (reserr nil))) :add (b* (((ok val1) (eval-expr expr.arg1 asg p)) ((ok val2) (eval-expr expr.arg2 asg p))) (add val1 val2 p)) :mul (b* (((ok val1) (eval-expr expr.arg1 asg p)) ((ok val2) (eval-expr expr.arg2 asg p))) (mul val1 val2 p)))))
Theorem:
(defthm nat-resultp-of-eval-expr (implies (primep p) (b* ((nat (eval-expr expr asg p))) (nat-resultp nat))) :rule-classes :rewrite)
Theorem:
(defthm fep-of-eval-expr (implies (and (primep p) (assignmentp asg) (assignment-wfp asg p) (not (reserrp (eval-expr expr asg p)))) (fep (eval-expr expr asg p) p)))
Theorem:
(defthm eval-expr-of-expression-fix-expr (equal (eval-expr (expression-fix expr) asg p) (eval-expr expr asg p)))
Theorem:
(defthm eval-expr-expression-equiv-congruence-on-expr (implies (expression-equiv expr expr-equiv) (equal (eval-expr expr asg p) (eval-expr expr-equiv asg p))) :rule-classes :congruence)
Theorem:
(defthm eval-expr-of-assignment-fix-asg (equal (eval-expr expr (assignment-fix asg) p) (eval-expr expr asg p)))
Theorem:
(defthm eval-expr-assignment-equiv-congruence-on-asg (implies (assignment-equiv asg asg-equiv) (equal (eval-expr expr asg p) (eval-expr expr asg-equiv p))) :rule-classes :congruence)