# Symbolics.jl - failing to simplify N-over-1 rational literals within expression

**URL:** <https://discourse.julialang.org/t/symbolics-jl-failing-to-simplify-n-over-1-rational-literals-within-expression/125446>\
**Category:** General Usage\
**Tags:** symbolics, symbolic-utils\
**Created:** [February 1, 2025, 5:24am UTC](https://discourse.julialang.org/t/symbolics-jl-failing-to-simplify-n-over-1-rational-literals-within-expression/125446 "2025-02-01T05:24:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jl\_enthusiast](https://avatars.discourse-cdn.com/v4/letter/j/7993a0/32.png) [@jl\_enthusiast](https://discourse.julialang.org/u/jl_enthusiast)\
**Post date:** [February 1, 2025, 5:24am UTC](https://discourse.julialang.org/t/symbolics-jl-failing-to-simplify-n-over-1-rational-literals-within-expression/125446/1 "2025-02-01T05:24:35Z")

</div>

Hi,

I am currently trying to write some custom simplification rules throughout different stages of a symbolic manipulation process.

One thing I noticed is that no matter how I try, I can’t come up with a rule that cancels literal rationals of the form `n//1` where n is a literal int. Later in the simplification process, the presence of this rational causes some breaking bugs (integer overflows during trying to apply some of the base rewrite rules), so I unfortunately need ot deal with this issue.

From reading the `src` files, it seems that this could be solved via using `is_literal_number()` and the `::()` match predicate in @rules as in the [docs](https://symbolicutils.juliasymbolics.org/rewrite/).

I have however failed to write a function like this. The bellow example illustrates my attempt.

A minimal reproducible example is:

```julia
using Symbolics
using SymbolicUtils: Chain, is_literal_number

@syms x

examp = x//1 + 3//1 + 2*x//1
sim_examp = simplify(examp)
#(3//1) + 3x

#sanity check, via custom rule. We don't expect this to work...
rw = @rule ~x//1 => ~x 
sim_examp2 = simplify(examp, rewriter = Chain([rw]))
#(3//1) + 3x

rw_literal = @rule ~x::(λ -> (is_literal_number(λ) && isa(λ,Rational) && (denominator(λ) == 1))) => numerator(~x)

sim_examp3 = simplify(examp, rewriter = Symbolics.Postwalk(rw_literal))
#(3//1) + 3x

#yet....
sim_examp4 = rw_literal(3//1)
# 3 (!!!!!)

#sanity check...
cprint(x) = println(x," : ", is_literal_number(x), " : ", isa(x,Rational) && denominator(x) == 1)
trick = SymbolicUtils.Postwalk(cprint) #this walks the expression and prints the predicate 
trick(examp)
#=
3//1 : true : true - ?
3 : true : false
x : false : false
3x : false : false
(3//1) + 3x : false : false
=#

```

I am especially confused why the rewrites fails to match into the literal (despite the subexpression meeting the predicate, as seen in the above Postwalk() debug).

Any help is greatly appreciated - I am new to SymbolicUtils.jl and CAS in general 🙂 .

---

<div class="post-metadata">

**Author:** ![jl\_enthusiast](https://avatars.discourse-cdn.com/v4/letter/j/7993a0/32.png) [@jl\_enthusiast](https://discourse.julialang.org/u/jl_enthusiast)\
**Post date:** [February 1, 2025, 11:28pm UTC](https://discourse.julialang.org/t/symbolics-jl-failing-to-simplify-n-over-1-rational-literals-within-expression/125446/2 "2025-02-01T23:28:05Z")

</div>

After some digging around in the base simplify rules, it seems that this issue can be partially resolved by wrapping the `Postwalk()` rewriter in `Passthrough()` to allow for the `rw_literal()`operations being applied “up” the graph.

```julia
#...
examp = x//1 + 3//1 + 2*x//1
f(λ) = (is_literal_number(λ) && isa(λ,Rational) && (denominator(λ) == 1))
rw_literal = @rule ~x::(λ -> f(λ)) => numerator(~x)
#In this case, Chain() also works
remove_trivials = PassThrough(Postwalk(RestartedChain([rw_literal])))

remove_trivials(examp)
#3 + 3x

```

However, this fails for complicated cases. My understanding is that in these cases `Fixpoint()` is preferred, but I can’t get it to work.

An example of this method failing on a more complicated expression:

```julia
@syms x, y, z

examp2 = y*z*(((1//1) + (2//1)*sqrt(x^2 + y^2 + z^2))^4)
remove_trivials(examp2)

#y*z*(((1//1) + (2//1)*sqrt(x^2 + y^2 + z^2))^4)

```

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [February 6, 2025, 3:26pm UTC](https://discourse.julialang.org/t/symbolics-jl-failing-to-simplify-n-over-1-rational-literals-within-expression/125446/3 "2025-02-06T15:26:40Z")

</div>

Open an issue if this is still the case. I think we just fixed a similar issue this week.

---

<div class="post-metadata">

**Author:** ![jl\_enthusiast](https://avatars.discourse-cdn.com/v4/letter/j/7993a0/32.png) [@jl\_enthusiast](https://discourse.julialang.org/u/jl_enthusiast)\
**Post date:** [February 6, 2025, 8:17pm UTC](https://discourse.julialang.org/t/symbolics-jl-failing-to-simplify-n-over-1-rational-literals-within-expression/125446/4 "2025-02-06T20:17:45Z")

</div>

Will check, unfortunately I might only be able to do it on Saturday.

On a slightly related note, when trying to write custom rewriters/simplifers, is there a prefered way of integrating them on top of the `default_simplifer()`? I don’t believe any of the Chains() that make it up get exported, so is it prefered to directly copy and mutate it instead?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [February 6, 2025, 9:28pm UTC](https://discourse.julialang.org/t/symbolics-jl-failing-to-simplify-n-over-1-rational-literals-within-expression/125446/5 "2025-02-06T21:28:54Z")

</div>

Yeah I don’t think it’s all exported public API, but maybe it should be
