@@ -168,24 +168,31 @@ function Base.isapprox(α, q::RationalPoly{C}; kwargs...) where {C}
168168 return isapprox (constant_term (α, q. den), q; kwargs... )
169169end
170170
171+ # TODO refer to the parallel with `mstructure(p)(e1, e2)` which gives the result
172+ # of multiplying the monomials corresponding to the exponent vectors `e1`
173+ # and `e2`.
171174"""
172175 abstract type AbstractMonomialOrdering end
173176
174177Abstract type for monomial ordering as defined in [CLO13, Definition 2.2.1, p. 55]
175178
179+ Given an ordering `ordering::AbstractMonomialOrdering` and vector of exponents `e1`
180+ and `e2`, `cmp(ordering, e1, e2)` returns a negative number if `e1` is before `e2`
181+ in the ordering, a positive number if `e2` is before `e1` and 0 if they are equal.
182+ For convenience, `ordering(e1, e2)` returns a `Bool` indicating whether
183+ `cmp(ordering, e1, e2)` is negative.
184+
176185[CLO13] Cox, D., Little, J., & OShea, D.
177186*Ideals, varieties, and algorithms: an introduction to computational algebraic geometry and commutative algebra*.
178187Springer Science & Business Media, **2013**.
179188"""
180189abstract type AbstractMonomialOrdering end
181190
182- """
183- compare(a, b, order::Type{<:AbstractMonomialOrdering})
184-
185- Returns a negative number if `a < b`, a positive number if `a > b` and zero if `a == b`.
186- The comparison is done according to `order`.
187- """
188- function compare end
191+ # We can't write this with a type instead of an instance so this motivates
192+ # why we work with instances and not types even if they don't have any data
193+ # that's not already in the type.
194+ # This is also to be consistent with `StarAlgebras.MultiplicativeStructure`
195+ (ordering:: AbstractMonomialOrdering )(i, j) = cmp (ordering, i, j) < 0
189196
190197"""
191198 struct LexOrder <: AbstractMonomialOrdering end
@@ -202,8 +209,8 @@ struct LexOrder <: AbstractMonomialOrdering end
202209
203210const _TupleOrVector = Union{Tuple,AbstractVector}
204211
205- function compare (exp1 :: _TupleOrVector , exp2 :: _TupleOrVector , :: Type{LexOrder} )
206- return Base . cmp (exp1, exp2)
212+ function Base . cmp ( :: LexOrder , exp1 :: _TupleOrVector , exp2 :: _TupleOrVector )
213+ return cmp (exp1, exp2)
207214end
208215
209216"""
@@ -228,12 +235,8 @@ struct InverseLexOrder <: AbstractMonomialOrdering end
228235# so not `cmp` methods is defined for it.
229236_rev (v:: AbstractVector ) = view (v, lastindex (v): - 1 : firstindex (v))
230237_rev (t:: Tuple ) = reverse (t)
231- function compare (
232- exp1:: _TupleOrVector ,
233- exp2:: _TupleOrVector ,
234- :: Type{InverseLexOrder} ,
235- )
236- return compare (_rev (exp1), _rev (exp2), LexOrder)
238+ function Base. cmp (:: InverseLexOrder , exp1:: _TupleOrVector , exp2:: _TupleOrVector )
239+ return cmp (_rev (exp1), _rev (exp2))
237240end
238241
239242"""
@@ -248,30 +251,13 @@ Monomial ordering defined by:
248251struct Graded{O<: AbstractMonomialOrdering } <: AbstractMonomialOrdering
249252 same_degree_ordering:: O
250253end
254+ Graded {O} () where {O<: AbstractMonomialOrdering } = Graded {O} (O ())
251255
252- function compare (
253- a:: _TupleOrVector ,
254- b:: _TupleOrVector ,
255- :: Type{Graded{O}} ,
256- ) where {O}
256+ function Base. cmp (ordering:: Graded , a:: _TupleOrVector , b:: _TupleOrVector )
257257 deg_a = sum (a)
258258 deg_b = sum (b)
259259 if deg_a == deg_b
260- return compare (a, b, O)
261- else
262- return deg_a - deg_b
263- end
264- end
265- # TODO Backward compat, remove
266- function compare (
267- a:: AbstractMonomial ,
268- b:: AbstractMonomial ,
269- :: Type{Graded{O}} ,
270- ) where {O}
271- deg_a = degree (a)
272- deg_b = degree (b)
273- if deg_a == deg_b
274- return compare (a, b, O)
260+ return cmp (ordering. same_degree_ordering, a, b)
275261 else
276262 return deg_a - deg_b
277263 end
283269 end
284270
285271Monomial ordering defined by
286- `compare(a, b, ::Type{Reverse{O}} ) where {O} = compare(b, a, O )`.
272+ `cmp(o::Reverse, a, b ) where {O} = cmp(o.reverse_order, b, a )`.
287273
288274Reverse Lex Order defined in [CLO13, Exercise 2.2.9, p. 61] where it is abbreviated as *rinvlex*.
289275can be obtained as `Reverse{InverseLexOrder}`.
@@ -298,27 +284,18 @@ Springer Science & Business Media, **2013**.
298284struct Reverse{O<: AbstractMonomialOrdering } <: AbstractMonomialOrdering
299285 reverse_ordering:: O
300286end
287+ Reverse {O} () where {O<: AbstractMonomialOrdering } = Reverse {O} (O ())
301288
302- function compare (
303- a:: _TupleOrVector ,
304- b:: _TupleOrVector ,
305- :: Type{Reverse{O}} ,
306- ) where {O}
307- return compare (b, a, O)
308- end
309- # TODO Backward compat, remove
310- function compare (
311- a:: AbstractMonomial ,
312- b:: AbstractMonomial ,
313- :: Type{Reverse{O}} ,
314- ) where {O}
315- return compare (b, a, O)
289+ function Base. cmp (ordering:: Reverse , a:: _TupleOrVector , b:: _TupleOrVector )
290+ return cmp (ordering. reverse_ordering, b, a)
316291end
317292
293+ # TODO (breaking) Return an instance, not a type
318294"""
319- ordering(p::AbstractPolynomialLike)
295+ ordering(p::AbstractPolynomialLike)::Type{<:AbstractMonomialOrdering}
320296
321- Returns the [`AbstractMonomialOrdering`](@ref) used for the monomials of `p`.
297+ Returns the [`AbstractMonomialOrdering`](@ref) type to be used to compare
298+ exponent vectors for the monomials of `p`.
322299"""
323300function ordering end
324301
@@ -330,10 +307,10 @@ ordering(p::AbstractPolynomialLike) = ordering(typeof(p))
330307# of x < y is equal to the result of Monomial(x) < Monomial(y)
331308# Without `Base.@pure`, TypedPolynomials allocates on Julia v1.6
332309# with `promote(x * y, x)`
333- Base. @pure function compare (
310+ Base. @pure function Base. cmp (
311+ :: AbstractMonomialOrdering ,
334312 v1:: AbstractVariable ,
335313 v2:: AbstractVariable ,
336- :: Type{<:AbstractMonomialOrdering} ,
337314)
338315 return - cmp (name (v1), name (v2))
339316end
@@ -344,7 +321,7 @@ function compare(
344321 :: Type{O} ,
345322) where {O<: AbstractMonomialOrdering }
346323 s1, s2 = promote_variables (m1, m2)
347- return compare ( exponents (s1), exponents (s2), O )
324+ return cmp ( O (), exponents (s1), exponents (s2))
348325end
349326
350327# Implement this to make coefficients be compared with terms.
@@ -358,25 +335,23 @@ end
358335# less than `b`, they are considered sort of equal.
359336_cmp_coefficient (a, b) = 0
360337
361- function compare (
338+ function Base. cmp (
339+ ordering:: O ,
362340 t1:: AbstractTermLike ,
363341 t2:: AbstractTermLike ,
364- :: Type{O} ,
365342) where {O<: AbstractMonomialOrdering }
366- Δ = compare ( monomial (t1), monomial (t2), O )
343+ Δ = cmp (ordering, monomial (t1), monomial (t2))
367344 if iszero (Δ)
368345 return _cmp_coefficient (coefficient (t1), coefficient (t2))
369346 end
370347 return Δ
371348end
372349
373350function Base. cmp (t1:: AbstractTermLike , t2:: AbstractTermLike )
374- return compare (t1, t2, ordering (t1) )
351+ return cmp ( ordering (t1)(), t1, t2 )
375352end
376- # TODO for backward compat, remove in next breaking release
377- compare (t1:: AbstractTermLike , t2:: AbstractTermLike ) = cmp (t1, t2)
378353
379- Base. isless (t1:: AbstractTermLike , t2:: AbstractTermLike ) = cmp (t1, t2) < 0
354+ Base. isless (t1:: AbstractTermLike , t2:: AbstractTermLike ) = compare (t1, t2) < 0
380355
381356_last_lex_index (n, :: Type{LexOrder} ) = n
382357_prev_lex_index (i, :: Type{LexOrder} ) = i - 1
@@ -573,3 +548,62 @@ function Base.iterate(it::ExponentsIterator, state)
573548 end
574549 return state[1 ], state
575550end
551+
552+ # TODO Backward compat, remove the following in next breaking release
553+ """
554+ compare(a, b, order::Type{<:AbstractMonomialOrdering})
555+
556+ Returns a negative number if `a < b`, a positive number if `a > b` and zero if `a == b`.
557+ The comparison is done according to `order`.
558+
559+ **Warning** This is deprecated, use `cmp(order(), a, b)` instead.
560+ """
561+ function compare end
562+
563+ function compare (t1:: AbstractTermLike , t2:: AbstractTermLike )
564+ return compare (t1, t2, ordering (t1))
565+ end
566+
567+ function compare (
568+ e1:: _TupleOrVector ,
569+ e2:: _TupleOrVector ,
570+ :: Type{O} ,
571+ ) where {O<: AbstractMonomialOrdering }
572+ return cmp (O (), e1, e2)
573+ end
574+
575+ function compare (
576+ t1:: AbstractTermLike ,
577+ t2:: AbstractTermLike ,
578+ :: Type{O} ,
579+ ) where {O<: AbstractMonomialOrdering }
580+ Δ = compare (monomial (t1), monomial (t2), O)
581+ if iszero (Δ)
582+ return _cmp_coefficient (coefficient (t1), coefficient (t2))
583+ end
584+ return Δ
585+ end
586+
587+ function compare (
588+ a:: AbstractMonomial ,
589+ b:: AbstractMonomial ,
590+ :: Type{Graded{O}} ,
591+ ) where {O}
592+ deg_a = degree (a)
593+ deg_b = degree (b)
594+ if deg_a == deg_b
595+ return compare (a, b, O)
596+ else
597+ return deg_a - deg_b
598+ end
599+ end
600+
601+ function compare (
602+ a:: AbstractMonomial ,
603+ b:: AbstractMonomial ,
604+ :: Type{Reverse{O}} ,
605+ ) where {O}
606+ return compare (b, a, O)
607+ end
608+
609+ Base. isless (v1:: AbstractVariable , v2:: AbstractVariable ) = cmp (v1, v2) < 0
0 commit comments