Given the args of a term and a list of possible rewrites for terms with the same top function symbol, tries each of the rewrites until one matches.
(sexpr-rewrite-try-rules args rewrites) → (mv successp rhs sigma)
Returns (mv successp rhs sigma), where successp indicates that there was a rule that matched, rhs is the right-hand side of that rule, and sigma is the substitution alist, such that the composition of rhs and sigma is equivalent to some (implicit) function applied to the args.
Regarding the function symbol: Rewrite rules are stored by leading LHS function symbol, and omit this function symbol from the LHS. So the LHS is just represented as a list of arguments. A rewrite rule is correct if that (implicit) function symbol applied to the LHS args is sexpr-equivalent to the corresponding RHS.
Function:
(defun sexpr-rewrite-try-rules (args rewrites) (declare (xargs :guard t)) (let ((__function__ 'sexpr-rewrite-try-rules)) (declare (ignorable __function__)) (b* (((when (atom rewrites)) (mv nil nil nil)) ((when (atom (car rewrites))) (sexpr-rewrite-try-rules args (cdr rewrites))) ((mv ok subst) (sexpr-unify-list (caar rewrites) args nil)) ((when ok) (mv t (cdar rewrites) subst))) (sexpr-rewrite-try-rules args (cdr rewrites)))))
Function:
(defun 4v-sexpr-fn-rewritesp (fn rewrites) (if (atom rewrites) t (and (consp (car rewrites)) (4v-sexpr-equiv (cons fn (caar rewrites)) (cdar rewrites)) (4v-sexpr-fn-rewritesp fn (cdr rewrites)))))
Theorem:
(defthm sexpr-rewrite-try-rules-correct (mv-let (successp rhs subst) (sexpr-rewrite-try-rules args rewrites) (implies (and successp (4v-sexpr-fn-rewritesp fn rewrites)) (4v-sexpr-equiv (4v-sexpr-compose rhs subst) (cons fn args)))))
Theorem:
(defthm sexpr-rewrite-try-rules-vars (b* (((mv ?successp ?rhs subst) (sexpr-rewrite-try-rules args rewrites))) (implies (not (member v (4v-sexpr-vars-list args))) (not (member v (4v-sexpr-vars-list (alist-vals subst)))))))