Welcome to the forum @GiorgioSimonini ![]()
I actually had the same issue right now (I wanted to test whether I implemented an algorithm correctly using some symbolic variables, but had some leftover floats of size ~machine precision in there) and found your post. It might be too late for you, but maybe it helps someone else looking for a solution.
I think your rule is correct in principle (the combination of Prewalk/Postwalk and PassThrough), but there is a little pitfall when using the symbolic types from the package.
As described here, one can use the rules directly on a symbolic expression, but only if they involve the correct low-level type of symbols (e.g. created with @syms y z). The rule doesn’t work directly on the variables of type Num which are created with @variables. For that, we need the higher-level simplify function, which is documented here.
Here’s an example based on what you wrote (note that the condition can be written directly in the rule, it’s just a bit shorter but should be equivalent to your code)
using Symbolics
using Symbolics.SymbolicUtils.Rewriters
rule_too_small = @rule ~x::(xs -> xs isa AbstractFloat && abs(xs) < 1e-15) => 0
rule = Prewalk(PassThrough(rule_too_small))
@variables y, z
x = 1e-16
eq = (x*y+z)^2
rule(eq) # still returns (1.0e-16y + z)^2 since y and z are `Num`s
simplify(eq; rewriter=rule) # returns z^2
Hope that helps!
EDIT: I forgot to wrap the float in an abs just to make sure that it doesn’t replace negative values.