Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify promotion #68

Merged
merged 1 commit into from
Apr 10, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 4 additions & 46 deletions src/promotion.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# We mark `isless()` as `@pure` because it's used in computing the correct
# (sorted) monomial order during type promotion, so its results must be
# assumed to be hyper-pure. Overloading this method in user code would be
# a bad idea.
# a bad idea.
@pure function isless(::Type{V1}, ::Type{V2}) where {V1 <: Variable, V2 <: Variable}
name(V1) < name(V2)
end

# We should be able to get rid of this method as the fallback just
# redirects to `promote_rule(monomialtype(V1), monomialtype(V2))`
# but we should check first the implications with this `@pure` thing.
function promote_rule(::Type{V1}, ::Type{V2}) where {V1 <: Variable, V2 <: Variable}
if V1 < V2
Monomial{(V1(), V2()), 2}
Expand All @@ -14,16 +17,6 @@ function promote_rule(::Type{V1}, ::Type{V2}) where {V1 <: Variable, V2 <: Varia
end
end

function promote_rule(::Type{M}, ::Type{V}) where {V <: Variable, M <: Monomial}
promote_rule(Monomial{(V(),), 1}, M)
end
promote_rule(V::Type{<:Variable}, M::Type{<:Monomial}) = promote_rule(M, V)

function promote_rule(::Type{Term{T, M}}, ::Type{V}) where {V <: Variable, T, M <: Monomial}
Term{T, promote_type(V, M)}
end
promote_rule(V::Type{<:Variable}, T::Type{<:Term}) = promote_rule(T, V)

function _promote_monomial_noncommutative(::Type{Monomial{V1, N1}}, ::Type{Monomial{V2, N2}}) where {N1, V1, N2, V2}
if V1 > V2
_promote_monomial(Monomial{V2, N2}, Monomial{V1, N1})
Expand Down Expand Up @@ -57,38 +50,3 @@ end
vars = merge(V1, V2...)
Monomial{vars, length(vars)}
end

function promote_rule(::Type{Term{T, M2}}, ::Type{M1}) where {M1 <: Monomial, T, M2 <: Monomial}
Term{T, promote_type(M1, M2)}
end
promote_rule(M::Type{<:Monomial}, T::Type{<:Term}) = promote_rule(T, M)

promote_rule(::Type{Term{T1, M1}}, ::Type{Term{T2, M2}}) where {T1, M1 <: Monomial, T2, M2 <: Monomial} = Term{promote_type(T1, T2), promote_type(M1, M2)}

function promote_rule(::Type{<:Polynomial{<:Any, T2}}, ::Type{T1}) where {T1 <: TermLike, T2 <: Term}
T = promote_type(T1, T2)
Polynomial{coefficienttype(T), T, Vector{T}}
end
promote_rule(T::Type{Term{T1, M1}}, P::Type{<:Polynomial}) where {T1, M1 <: Monomial} = promote_rule(P, T)
promote_rule(T::Type{<:Monomial}, P::Type{<:Polynomial}) = promote_rule(P, T)
promote_rule(T::Type{<:Variable}, P::Type{<:Polynomial}) = promote_rule(P, T)

function promote_rule(::Type{<:Polynomial{<:Any, T1}}, ::Type{<:Polynomial{<:Any, T2}}) where {T1 <: TermLike, T2 <: TermLike}
T = promote_type(T1, T2)
Polynomial{coefficienttype(T), T, Vector{T}}
end

function MP.promote_rule_constant(::Type{S}, ::Type{V}) where {S, V <: Variable}
Term{S, Monomial{(V(),), 1}}
end

function MP.promote_rule_constant(::Type{S}, ::Type{M}) where {S, M <: Monomial}
Term{S, M}
end

MP.promote_rule_constant(::Type{S}, t::Type{Term{T, M}}) where {T, M <: Monomial, S} = Term{promote_type(S, T), M}

function MP.promote_rule_constant(::Type{S}, ::Type{<:Polynomial{<:Any, T}}) where {S, T <: TermLike}
R = promote_type(S, T)
Polynomial{coefficienttype(R), R, Vector{R}}
end