Skip to content

Commit 3dc5e53

Browse files
Merge pull request #774 from Bumblebee00/rule_returns_matches_ditionary
added functionality to return matches dictionary
2 parents 65daf4b + 2c0cff4 commit 3dc5e53

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

docs/src/manual/rewrite.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,23 @@ Notice that the expression was autosimplified before application of the rule.
9797
2(2w + α + β)
9898
```
9999

100+
Note that writing a single tilde `~` as consequent, will make the rule return a dictionary of [slot variable, expression matched].
101+
102+
```jldoctest rewrite
103+
r = @rule (~x + (~y)^(~m)) => ~
104+
105+
r(z+w^α)
106+
107+
# output
108+
Base.ImmutableDict{Symbol, Any} with 5 entries:
109+
:MATCH => z + w^α
110+
:m => α
111+
:y => w
112+
:x => z
113+
:____ => nothing
114+
115+
```
116+
100117
### Predicates for matching
101118

102119
Matcher pattern may contain slot variables with attached predicates, written as `~x::f` where `f` is a function that takes a matched expression and returns a boolean value. Such a slot will be considered a match only if `f` returns true.

src/rule.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ function makeconsequent(expr)
163163
else
164164
return Expr(expr.head, map(makeconsequent, expr.args)...)
165165
end
166+
elseif expr===:(~)
167+
return :(__MATCHES__)
166168
else
167169
# treat as a literal
168170
return esc(expr)
@@ -241,6 +243,24 @@ If an expression matches LHS entirely, then it is rewritten to the pattern in th
241243
Segment (`~x`) and slot variables (`~~x`) on the RHS will substitute the result of the
242244
matches found for these variables in the LHS.
243245
246+
If the RHS is a single tilde `~`, then the rule returns a a dictionary of
247+
[slot variable, expression matched].
248+
249+
_Example:_
250+
251+
```julia
252+
julia> r = @rule (~x + (~y)^(~m)) => ~
253+
~x + (~y) ^ ~m => (~)
254+
255+
julia> r(a + b^2)
256+
Base.ImmutableDict{Symbol, Any} with 5 entries:
257+
:MATCH => a + b^2
258+
:m => 2
259+
:y => b
260+
:x => a
261+
:____ => nothing
262+
```
263+
244264
**Slot**:
245265
246266
A Slot variable is written as `~x` and matches a single expression. `x` is the name of the variable. If a slot appears more than once in an LHS expression then expression matched at every such location must be equal (as shown by `isequal`).

test/rewrite.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,22 @@ end
8282
@test r_mix((a + b)) === 2 #1+1
8383
end
8484

85+
@testset "Return the matches dictionary" begin
86+
r = @rule (~x + (~y)^2) => ~
87+
res = r(a + b^2)
88+
@test isa(res, Base.ImmutableDict)
89+
@test res[:x] === a
90+
@test res[:y] === b
91+
92+
r2 = @rule (~x + (~y)^(~m)) => (~) where ~m===2
93+
@test isa(r2(a + b^2), Base.ImmutableDict)
94+
@test r2(a + b^3)===nothing
95+
96+
r3 = @rule (~x + (~y)^(~m)) => ~m===2 ? (~) : ~x
97+
@test isa(r3(a + b^2), Base.ImmutableDict)
98+
@test r3(a + b^3)===a
99+
end
100+
85101
using SymbolicUtils: @capture
86102

87103
@testset "Capture form" begin

0 commit comments

Comments
 (0)