Skip to content

Commit 98094b5

Browse files
author
Shashi Gowda
committed
Let's go!
Merge branch 's/terminterface1' into ale/terminterface-new
2 parents 9c6965e + dec6766 commit 98094b5

File tree

9 files changed

+57
-42
lines changed

9 files changed

+57
-42
lines changed

Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Setfield = "0.7, 0.8, 1"
4343
SpecialFunctions = "0.10, 1.0, 2"
4444
StaticArrays = "0.12, 1.0"
4545
SymbolicIndexingInterface = "0.3"
46+
TermInterface = "0.4"
4647
TimerOutputs = "0.5"
4748
Unityper = "0.1.2"
4849
julia = "1.3"

src/SymbolicUtils.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,23 @@ $(DocStringExtensions.README)
44
module SymbolicUtils
55

66
using DocStringExtensions
7+
78
export @syms, term, showraw, hasmetadata, getmetadata, setmetadata
89

910
using Unityper
10-
11-
# Sym, Term,
12-
# Add, Mul and Pow
11+
using TermInterface
1312
using DataStructures
1413
using Setfield
1514
import Setfield: PropertyLens
1615
using SymbolicIndexingInterface
1716
import Base: +, -, *, /, //, \, ^, ImmutableDict
1817
using ConstructionBase
1918
using TermInterface
20-
import TermInterface: iscall, isexpr, issym, symtype, head, children, operation, arguments, metadata
19+
import TermInterface: iscall, isexpr, issym, symtype, head, children,
20+
operation, arguments, metadata, maketerm
2121

22-
function similarterm end
22+
# Sym, Term,
23+
# Add, Mul and Pow
2324
include("types.jl")
2425
export similarterm
2526

src/inspect.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import AbstractTrees
22

33
const inspect_metadata = Ref{Bool}(false)
44
function AbstractTrees.nodevalue(x::Symbolic)
5-
iscall(x) ? operation(x) : x
5+
iscall(x) ? operation(x) : isexpr(x) ? head(x) : x
66
end
77

88
function AbstractTrees.nodevalue(x::BasicSymbolic)
@@ -27,7 +27,7 @@ function AbstractTrees.nodevalue(x::BasicSymbolic)
2727
end
2828

2929
function AbstractTrees.children(x::Symbolic)
30-
isexpr(x) ? arguments(x) : ()
30+
iscall(x) ? arguments(x) : isexpr(x) ? children(x) : ()
3131
end
3232

3333
"""

src/interface.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
"""
2-
istree(x)
2+
iscall(x)
33
44
Returns `true` if `x` is a term. If true, `operation`, `arguments`
55
must also be defined for `x` appropriately.
66
"""
7-
istree(x) = false
7+
iscall(x) = false
88

99
"""
1010
symtype(x)
@@ -29,7 +29,7 @@ issym(x) = false
2929
"""
3030
operation(x)
3131
32-
If `x` is a term as defined by `istree(x)`, `operation(x)` returns the
32+
If `x` is a term as defined by `iscall(x)`, `operation(x)` returns the
3333
head of the term if `x` represents a function call, for example, the head
3434
is the function being called.
3535
"""
@@ -38,14 +38,14 @@ function operation end
3838
"""
3939
arguments(x)
4040
41-
Get the arguments of `x`, must be defined if `istree(x)` is `true`.
41+
Get the arguments of `x`, must be defined if `iscall(x)` is `true`.
4242
"""
4343
function arguments end
4444

4545
"""
4646
unsorted_arguments(x::T)
4747
48-
If x is a term satisfying `istree(x)` and your term type `T` provides
48+
If x is a term satisfying `iscall(x)` and your term type `T` provides
4949
an optimized implementation for storing the arguments, this function can
5050
be used to retrieve the arguments when the order of arguments does not matter
5151
but the speed of the operation does.

src/matchers.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# 3. Callback: takes arguments Dictionary × Number of elements matched
77
#
88
function matcher(val::Any)
9-
isexpr(val) && return term_matcher(val)
9+
iscall(val) && return term_matcher(val)
1010
function literal_matcher(next, data, bindings)
1111
islist(data) && isequal(car(data), val) ? next(bindings, 1) : nothing
1212
end

src/polyform.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ using Bijections
66
77
Abstracts a [MultivariatePolynomials.jl](https://juliaalgebra.github.io/MultivariatePolynomials.jl/stable/) as a SymbolicUtils expression and vice-versa.
88
9-
The SymbolicUtils term interface (`isexpr`, `operation, and `arguments`) works on PolyForm lazily:
9+
The SymbolicUtils term interface (`isexpr`/`iscall`, `operation, and `arguments`) works on PolyForm lazily:
1010
the `operation` and `arguments` are created by converting one level of arguments into SymbolicUtils expressions. They may further contain PolyForm within them.
1111
We use this to hold polynomials in memory while doing `simplify_fractions`.
1212
@@ -175,7 +175,6 @@ isexpr(x::PolyForm) = true
175175
iscall(x::Type{<:PolyForm}) = true
176176
iscall(x::PolyForm) = true
177177

178-
179178
function similarterm(t::PolyForm, f, args, symtype; metadata=nothing)
180179
basic_similarterm(t, f, args, symtype; metadata=metadata)
181180
end

src/rule.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ end
120120
getdepth(r::Rule) = r.depth
121121

122122
function rule_depth(rule, d=0, maxdepth=0)
123-
if isexpr(rule)
123+
if iscall(rule)
124124
maxdepth = reduce(max, (rule_depth(r, d+1, maxdepth) for r in arguments(rule)), init=1)
125125
elseif rule isa Slot || rule isa Segment
126126
maxdepth = max(d, maxdepth)
@@ -389,7 +389,7 @@ Base.show(io::IO, acr::ACRule) = print(io, "ACRule(", acr.rule, ")")
389389

390390
function (acr::ACRule)(term)
391391
r = Rule(acr)
392-
if !isexpr(term)
392+
if !iscall(term)
393393
r(term)
394394
else
395395
f = operation(term)

src/types.jl

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ symtype(x::Number) = typeof(x)
113113
_ => error_on_type()
114114
end
115115
end
116+
116117
@inline head(x::BasicSymbolic) = BasicSymbolic
117118

118119
function arguments(x::BasicSymbolic)
@@ -159,7 +160,7 @@ function unsorted_arguments(x::BasicSymbolic)
159160
if isadd(x)
160161
for (k, v) in x.dict
161162
push!(args, applicable(*,k,v) ? k*v :
162-
similarterm(k, *, [k, v]))
163+
maketerm(k, *, [k, v]))
163164
end
164165
else # MUL
165166
for (k, v) in x.dict
@@ -187,6 +188,7 @@ end
187188

188189
isexpr(s::BasicSymbolic) = !issym(s)
189190
iscall(s::BasicSymbolic) = isexpr(s)
191+
190192
@inline isa_SymType(T::Val{S}, x) where {S} = x isa BasicSymbolic ? Unityper.isa_type_fun(Val(SymbolicUtils.BasicSymbolic), T, x) : false
191193
issym(x::BasicSymbolic) = isa_SymType(Val(:Sym), x)
192194
isterm(x) = isa_SymType(Val(:Term), x)
@@ -531,30 +533,12 @@ end
531533

532534
unflatten(t) = t
533535

534-
"""
535-
similarterm(t, f, args, symtype; metadata=nothing)
536-
537-
Create a term that is similar in type to `t`. Extending this function allows packages
538-
using their own expression types with SymbolicUtils to define how new terms should
539-
be created. Note that `similarterm` may return an object that has a
540-
different type than `t`, because `f` also influences the result.
536+
function TermInterface.maketerm(::Type{<:BasicSymbolic}, head, args, type, metadata)
537+
basicsymbolic(first(args), args[2:end], type, metadata)
538+
end
541539

542-
## Arguments
543540

544-
- `t` the reference term to use to create similar terms
545-
- `f` is the operation of the term
546-
- `args` is the arguments
547-
- The `symtype` of the resulting term. Best effort will be made to set the symtype of the
548-
resulting similar term to this type.
549-
"""
550-
similarterm(t::Symbolic, f, args; metadata=nothing) =
551-
maketerm(typeof(t), f, args, _promote_symtype(f, args); metadata)
552-
similarterm(t::BasicSymbolic, f, args, symtype; metadata=nothing) =
553-
maketerm(typeof(t), f, args, symtype; metadata=metadata)
554-
maketerm(T::Type{<:Symbolic}, f, args, symtype; metadata=nothing) =
555-
basic_similarterm(T, f, args, symtype; metadata=metadata)
556-
557-
function basic_similarterm(t, f, args, stype; metadata=nothing)
541+
function basicsymbolic(f, args, stype, metadata)
558542
if f isa Symbol
559543
error("$f must not be a Symbol")
560544
end
@@ -564,7 +548,7 @@ function basic_similarterm(t, f, args, stype; metadata=nothing)
564548
end
565549
if T <: LiteralReal
566550
Term{T}(f, args, metadata=metadata)
567-
elseif stype <: Number && (f in (+, *) || (f in (/, ^) && length(args) == 2)) && all(x->symtype(x) <: Number, args)
551+
elseif T <: Number && (f in (+, *) || (f in (/, ^) && length(args) == 2)) && all(x->symtype(x) <: Number, args)
568552
res = f(args...)
569553
if res isa Symbolic
570554
@set! res.metadata = metadata
@@ -653,6 +637,36 @@ function to_symbolic(x)
653637
x
654638
end
655639

640+
"""
641+
similarterm(x, op, args, symtype=nothing; metadata=nothing)
642+
643+
"""
644+
function similarterm(x, op, args, symtype=nothing; metadata=nothing)
645+
Base.depwarn("""`similarterm` is deprecated, use `maketerm` instead.
646+
See https://github.com/JuliaSymbolics/TermInterface.jl for details.
647+
The present call can be replaced by
648+
`maketerm(typeof(x), $(head(x)), [op, args...], symtype, metadata)`""", :similarterm)
649+
650+
TermInterface.maketerm(typeof(x), callhead(x), [op, args...], symtype, metadata)
651+
end
652+
653+
# Old fallback
654+
function similarterm(T::Type, op, args, symtype=nothing; metadata=nothing)
655+
Base.depwarn("`similarterm` is deprecated, use `maketerm` instead." *
656+
"See https://github.com/JuliaSymbolics/TermInterface.jl for details.", :similarterm)
657+
op(args...)
658+
end
659+
660+
export similarterm
661+
662+
663+
"""
664+
callhead(x)
665+
Used in this deprecation cycle of `similarterm` to find the `head` argument to
666+
`maketerm`. Do not implement this, or use `similarterm` if you're using this package.
667+
"""
668+
callhead(x) = typeof(x)
669+
656670
###
657671
### Pretty printing
658672
###

src/utils.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,8 @@ macro matchable(expr)
218218
get_name(e::Expr) = (@assert(e.head == :(::)); e.args[1])
219219
fields = map(get_name, fields)
220220
quote
221+
# TODO: fix this to be not a call. Make pattern matcher work for these
221222
$expr
222-
SymbolicUtils.iscall(::$name) = true
223223
SymbolicUtils.head(::$name) = $name
224224
SymbolicUtils.operation(::$name) = $name
225225
SymbolicUtils.arguments(x::$name) = getfield.((x,), ($(QuoteNode.(fields)...),))

0 commit comments

Comments
 (0)