Here is some Scheme code to deal with multivariate polynomials (mvps). A polynomial can be represented as a list of the numbers which serve as the coefficients of the successive powers of the single variable. (3 5 2 8) thus represents λx(3 + 5x + 2x2 + 8x3). Note that the variable is not named. For a polynomial in two variables, we allow each member of our list to itself be a polynomial of a single variable. Thus (3 5 (4 6) 8) represents λyλx(3 + 5x + (4 + 6y)x2 + 8x3). Given an ordered list of number values for the unnamed variables, an mvp may be evaluated to a number. See function ep below.

0 is a member of the ring of polynomials of a single variable. How many terms does it have, however? In line with omitting high order terms with 0 coefficients, we choose here to view it is having 0 terms and represent it thus: () rather than (0). Since each coefficient is a potential polynomial we code all 0’s as (). 1 + x2 is thus represented as (1 () 1). Note that 3 as a polynomial in one variable is represented the same as 3 as a polynomial in two variables. We conflate 3, λx3 and λyλx3. 3, (3) and ((3)) are all equivalent. (1 2) differs from ((1 2)) however for the 2 is a coefficient of different variables in the two cases.

Roughly an mvp is a non zero number or a list of mvps. There are conflicting principles however.

This confusion arises when a zot and a list of zots are the same syntactic category. Ultimately an mvp means whatever routine ep says it means.

This code tests for numbers on the way down for it does not know from context how deep they are. It sheds neither unneeded depth nor breadth yet. It sheds breadth if input is shorn.

(define (add a b) (let add ((a a)(b b))
    (cond ((null? a) b) ((null? b) a)
      ((number? a) (if (number? b)
         (let ((z (+ a b))) (if (zero? z) '() z))
      (cons (add a (car b)) (cdr b))))
      ((number? b) (cons (add b (car a)) (cdr a)))
      (#t (cons (add (car a) (car b)) (add (cdr a) (cdr b)))))))
; tests
(add '() '()) ; ()
(add '() 3) ; 3
(add 4 '()) ; 4
(add 3 5) ; 8
(add '(1 3) '(-1 -3)) ; ()
(add '(0 3) '((0 3))) ; ((() 3) 3)
; test rig
(map (lambda (x) (equal? (add (caar x) (cdar x)) (cdr x))) (quote
(((() . ()) . ())
((() . 3) . 3)
((4 . ()) . 4)
((3 . 5) . 8)
(((1 3) . (-1 -3)) . ())
(((0 3) . ((0 3))) . ((() 3) 3))

Better test

Include routine add above and definition of Do and grc4.
; (define x (lambda (note w)(write (list note w))(newline) w))
(define (gmvp s) (let ((rn (grc4 s)))
(lambda () (let gd () (if (< 160 (rn 1)) (+ (modulo (rn 1) 10) 1)
     (cons (gd) (if (< 50 (rn 1)) '() (gd))))))))

; (define g (gmvp "fundlebrat"))
; (g)
(define (ep x v)(cond
  ((number? x) x)
  ((null? x) 0)
  (#t (if (null? v)(begin (write "Too deep")(newline)))
  (+ (ep (car x) (cdr v)) (* (car v) (ep (cdr x) v))))))

(define (depth p)(if (null? p) 0 (if (number? p) 0
  (max (+ 1 (depth (car p))) (depth (cdr p))))))

; (let ((a (g))) (cons a (depth a)))

(let ((g (gmvp "fuyx"))(rn (grc4 "Flif"))) (Do 10000 (lambda(dm)
 (let* ((a (g))(b (g))
  (v (let gv ((k (max (depth a)(depth b))))
  (if (zero? k) '() (cons (+ 1 (modulo (rn 1) 9)) (gv (- k 1)))))))
  (let ((lf (ep (add a b) v))(rt (+ (ep a v)(ep b v))))
  (if (not (= lf rt)) (begin (write (list a b v lf rt))(newline))))))))
To multiply mvps we introduce an auxiliary function, mx, that transforms w into λx(xw), an mvp in one additional variable. Also we multiply an mvp by a number with sm.
(define (mx w)(cons '() w))
(define (sm n a) (cond
  ((null? a) '())
  ((number? a) (* n a))
  (#t (cons (sm n (car a))(sm n (cdr a))))))
Now to multiply we note that ...
(define (mul a b) (cond
  ((or (null? a)(null? b)) '())
  ((number? a) (sm a b))
  ((number? b) (sm b a))
  (#t (let ((z (cons (mul (car a) (car b))
      (cons (add (mul (car a)(cdr b))(mul (cdr a)(car b)))
       (mul (cdr a)(cdr b))))))
  (if (> (depth z) (max (depth a)(depth b))) (begin (write (list
   "fizz" a b z))(newline)))
; => ("fizz" ((1) ((7))) (3) ((3) (((21)))))

(let ((g (gmvp "fuyx"))(rn (grc4 "Flif"))) (Do 100 (lambda(dm)
 (let* ((a (g))(b (g))
  (v (let gv ((k (max (depth a)(depth b))))
  (if (zero? k) '() (cons (+ 1 (modulo (rn 1) 9)) (gv (- k 1)))))))
  (let ((lf (ep (mul a b) v))(rt (* (ep a v)(ep b v))))
  (if (not (= lf rt)) (begin (write (list a b (mul a b) v lf rt))(newline))))))))
; => ((((7) 9)) 8 (3 8 5) 272 632)

(define (mul a b) (cond
  ((null? a) '())
  ((number? a) (sm a b))
  (#t (add (mul (car a) b) (mx (mul (cdr a) b))))))
; (mul (car a) b) above is bad because it mismatches variables!

I have qualms about mvps not being proper lists. I explore the alternative here.
older stuff