Skip to content

Instantly share code, notes, and snippets.

@davidagold
Last active Oct 7, 2018
Embed
What would you like to do?
Simplify arithmetic expressions
function simplify(e::Expr)
_simplify(e)
end
_simplify(e) = e
function _simplify(e::Expr)
# apply the following only to expressions that call a function on arguments
if e.head == :call
op = e.args[1] # in such expressions, `args[1]` is the called function
simplified_args = [ _simplify(arg) for arg in e.args[2:end] ]
if op == :(*)
in(0, e.args[2:end]) && return 0 # return 0 if any args are 0
simplified_args = simplified_args[simplified_args .!= 1] # remove 1s
elseif op == :(+)
simplified_args = simplified_args[simplified_args .!= 0] # remove 0s
end
length(simplified_args) == 0 ? 0 :
length(simplified_args) == 1 ? simplified_args[1] :
return Expr(:call, op, simplified_args...)
end
end
@davidagold
Copy link
Author

davidagold commented Aug 3, 2015

The above can be used to simplify the original expression in this post:

# wrapping code between `:(` and `)` parses the code into an Expr object
julia> e = :( (1 + 0 * x) * 3 + 12 )
:((1 + 0x) * 3 + 12)

julia> simplify(e)
:(+1 * 3 + 12)

julia> eval(ans)
15

But it will also simplify expressions in which arbitrarily complex function calls are passed to + or *:

julia> simplify(:( (0 * f(g(x))) + 2 + (3 * h(x, y)) ))
:(2 + 3 * h(x,y))

@J-Sarnoff
Copy link

J-Sarnoff commented Aug 20, 2015

Julia, you will do work for me so easily!? That is are all kinds of refreshing.
(regards to your friend, david)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment