Skip to content

Commit 860aa70

Browse files
committed
improved negative exponent pattern matching. now it matches also for expressions like (1/...)^(...)
1 parent 93c341e commit 860aa70

File tree

2 files changed

+13
-2
lines changed

2 files changed

+13
-2
lines changed

src/matchers.jl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@ function term_matcher_constructor(term, acSets)
136136
result = loop(data, bindings, matchers)
137137
result !== nothing && return success(result, 1)
138138

139+
# if data is of the alternative form (1/...)^(...), it might match with negative exponent
140+
if (operation(data) === ^) && iscall(arguments(data)[1]) && (operation(arguments(data)[1]) === /) && isequal(arguments(arguments(data)[1])[1], 1)
141+
one_over_smth = arguments(data)[1]
142+
T = symtype(one_over_smth)
143+
frankestein = Term{T}(^, [arguments(one_over_smth)[2], -arguments(data)[2]])
144+
result = loop(frankestein, bindings, matchers)
145+
result !== nothing && return success(result, 1)
146+
end
139147
# if data is of the alternative form 1/(...)^(...), it might match with negative exponent
140148
if (operation(data) === /) && isequal(arguments(data)[1], 1) && iscall(arguments(data)[2]) && (operation(arguments(data)[2]) === ^)
141149
denominator = arguments(data)[2]
@@ -200,7 +208,7 @@ function defslot_term_matcher_constructor(term, acSets)
200208

201209
function defslot_term_matcher(success, data, bindings)
202210
!islist(data) && return nothing # if data is not a list, return nothing
203-
# call the normal mathcer, with succes function foo1 that simply returns the bindings
211+
# call the normal matcher, with success function foo1 that simply returns the bindings
204212
# <--foo1-->
205213
result = normal_matcher((b,n) -> b, data, bindings)
206214
result !== nothing && return success(result, 1)

test/rewrite.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ end
109109
@test r_mixmix(exp(x)*sin(x+x^2)) === (1, 0, x)
110110
end
111111

112-
@testset "1/power matches power with exponent of opposite sign" begin
112+
@testset "power matcher with negative exponent" begin
113113
r1 = @rule (~x)^(~y) => (~x, ~y) # rule with slot as exponent
114114
@test r1(1/a^b) === (a, -b) # uses frankestein
115115
@test r1(1/a^(b+2c)) === (a, -b-2c) # uses frankestein
@@ -124,6 +124,9 @@ end
124124
@test r1defslot(1/a^(b+2c)) === (a, -b-2c) # uses frankestein
125125
@test r1defslot(1/a^2) === (a, -2) # uses opposite_sign_matcher
126126
@test r1defslot(a) === (a, 1)
127+
128+
r = @rule (~x + ~y)^(~m) => (~x, ~y, ~m) # rule to match (1/...)^(...)
129+
@test r((1/(a+b))^3) === (a,b,-3)
127130
end
128131

129132
using SymbolicUtils: @capture

0 commit comments

Comments
 (0)