Search code examples
racketsimplifyarithmetic-expressions

Racket: simplify arithmetic expressions with variables


I am trying to implement a function

; (simplify expr)
;
; where expr is one of the following
; - a number
; - a symbol
; - a list of the form '(a operator b) where a and b are arithmetic expressions

The function is NOT supposed to simplify the arithmetic expression as far as possible, I just need it to simplify the subexpressions without variables:

examples:

(simplify '(3 + a))                  => '(3 + a)
(simplify '(((2 + (3 * 4)) * a) + 2) => '((14 * a) + 2)
(simplify '((2 + (3 - a)) * 2)       => '((2 + (3 - a)) * 2) 

I already implemented a function that evaluates an arithmetic expression:

(define (eval t)
  (cond
    [(number? t) t]
    [else ((cond
            [(equal? (second t) '+) +]
            [(equal? (second t) '-) -]
            [(equal? (second t) '*) *]
            [(equal? (second t) '/) /])
           (eval (first t)) (eval (third t)))])) 

This is what I have so far, but aside from the fact that it does not even work properly, I guess that there is a much better way.

(define (simplify t)
  (cond
    [(number? t) t]
    [(equal? 'a (first t)) `(,(first t) ,(second t) ,(simplify (third t))) ]
    [(equal? 'a (third t)) `(,(simplify (first t)) ,(second t) ,(third t)) ]
    [else ((cond
           [(equal? (second t) '+) +]
            [(equal? (second t) '-) -]
            [(equal? (second t) '*) *]
            [(equal? (second t) '/) /])
           (simplify (first t)) (simplify (third t)))]))

Any help is greatly appreciated!


Solution

  • The key insight is that

     (number operation number) 
    

    can be simplified to

    the result of evaluating (number operation number)
    

    So add a clause in simplify that checks for the pattern (number operation number) then use your eval function to find the result.