Conversion and IO
Recast:
PUBLIC AC.BinaryOp = {
Args are a StructureElement and a Structure
destPolyRing: Object ← secondArg;
destPolyRingData: PolynomialRingData ← NARROW[destPolyRing.data];
destFromRopeMethod: Method ← AC.LookupMethodInStructure[$fromRope, destPolyRing];
destBaseCoeffRing: Object ← destPolyRingData.baseCoeffRing;
destBaseCanRecastMethod: Method ← AC.LookupMethodInStructure[$canRecast, destBaseCoeffRing];
destBaseRecastMethod: Method ← AC.LookupMethodInStructure[$recast, destBaseCoeffRing];
refBOOL: REF BOOL;
sourceStructure: Object ← firstArg.class;
variable: Object ← firstArg;
sourceRope: ROPE;
reCastSource: Object;
Already in this structure
IF AC.StructureEqual[sourceStructure, destPolyRing] THEN RETURN[firstArg];
Source Object to recast is a variable as an elt of a SingleSetStructure
IF Sets.IsVariable[firstArg]
THEN {
-- recast as an element of Variables Structure
variable ← Sets.UnderlyingSetUniverseEltFromSSSElt[firstArg];
sourceStructure ← variable.class;
};
Source Object to recast is a variable as an elt of VARS.IsVariables
IF VARS.IsVariables[sourceStructure] THEN {
Check that variable occurs in destination Structure's allVars
sourceVarsSubset: BOOL ← SEQ.IsSubset[SEQ.MakeSequence[LIST[variable], VARSEQ.VariableSequences], destPolyRingData.allVariables];
IF NOT sourceVarsSubset THEN RETURN[NIL];
Do secondArg.class.FromRope[firstArg.class.ToRope[firstArg] ]; avoids having to get into firstArg's internals and possibly introduce new variables
sourceRope ← NARROW[AC.ApplyLkpNoRecastRef[$toRope, sourceStructure, LIST[variable]]];
RETURN[AC.ApplyFromRopeMethod[destFromRopeMethod, sourceRope, destPolyRing] ];
};
Object to recast is a polynomial
IF IsPolynomialStructure[sourceStructure]
THEN {
sourcePolyRingData: PolynomialRingData ← NARROW[sourceStructure.data];
sourceBaseCoeffRing: Object ← sourcePolyRingData.baseCoeffRing;
Check that sourceStructure's allVars are a subset of destination Structure's allVars
sourceVarsSubset: BOOL ← Sequences.IsSubset[sourcePolyRingData.allVariables, destPolyRingData.allVariables];
IF NOT sourceVarsSubset THEN RETURN[NIL];
Check that canRecast source baseCoeffRing to dest baseCoeffRing
refBOOL ← NARROW[AC.ApplyNoLkpNoRecastRef[destBaseCanRecastMethod, LIST[sourceBaseCoeffRing, destBaseCoeffRing] ] ];
IF NOT refBOOL^ THEN RETURN[NIL];
Do secondArg.class.FromRope[firstArg.class.ToRope[firstArg] ]; avoids having to get into firstArg's internals and possibly reorder, possibly introduce new variables
sourceRope ← NARROW[AC.ApplyLkpNoRecastRef[$toRope, sourceStructure, LIST[firstArg]]];
RETURN[AC.ApplyFromRopeMethod[destFromRopeMethod, sourceRope, destPolyRing] ];
};
Source Object to recast NOT a polynomial; Check if canRecast sourceStructure to dest baseCoeffRing; If so, do it, and return as a constant monomial
refBOOL ← NARROW[AC.ApplyNoLkpNoRecastRef[destBaseCanRecastMethod, LIST[sourceStructure, destBaseCoeffRing] ] ];
IF refBOOL^
THEN
{
sourceRope ← NARROW[AC.ApplyLkpNoRecastRef[$toRope, sourceStructure, LIST[firstArg]]];
RETURN[AC.ApplyFromRopeMethod[destFromRopeMethod, sourceRope, destPolyRing] ];
};
-- This way works for univariate, but not multivariate, polynomials
reCastSource ← AC.ApplyNoLkpNoRecastObject[destBaseRecastMethod, LIST[firstArg, destBaseCoeffRing] ];
RETURN[ Monomial[reCastSource, NEW[CARDINAL ← 0], destPolyRing] ];
--
Can't do it
RETURN[NIL];
};
CanRecast:
PUBLIC AC.BinaryPredicate = {
Args are either [Structure, Structure] or [StructureElement, Structure]
destPolyRing: Object ← secondArg;
destPolyRingData: PolynomialRingData ← NARROW[destPolyRing.data];
destBaseCoeffRing: Object ← destPolyRingData.baseCoeffRing;
destBaseCanRecastMethod: Method ← AC.LookupMethodInStructure[$canRecast, destBaseCoeffRing];
refBOOL: REF BOOL;
sourceStructure: Object ← IF firstArg.flavor = StructureElement THEN firstArg.class ELSE IF firstArg.flavor = Structure THEN firstArg ELSE ERROR;
variable: Object ← firstArg;
variableList: LIST OF Object ← NIL;
IF AC.StructureEqual[sourceStructure, destPolyRing] THEN RETURN[TRUE]; -- nothing to do
Source Object to recast is a variable as an elt of a SingleSetStructure
IF firstArg.flavor=StructureElement
AND Sets.IsVariable[firstArg]
THEN {
-- recast as an element of Variables Structure
variable ← Sets.UnderlyingSetUniverseEltFromSSSElt[firstArg];
sourceStructure ← variable.class;
variableList← LIST[variable];
}
Source Object to recast is a SingleSetStructure; check whether underlying set consists of a single variable; if so, make it the arg
ELSE IF firstArg.flavor=Structure
AND Sets.IsSingleSetStructure[firstArg]
THEN {
thisSetStructureData: Sets.SingleSetStructureData ← NARROW[firstArg.data];
thisSetStructureUnderlyingSet: Object ← thisSetStructureData.underlyingSet;
underlyingSetData: Sets.SetData;
IF NOT AC.StructureEqual[thisSetStructureUnderlyingSet.class, Sets.VariableSets] THEN RETURN[FALSE];
underlyingSetData ← NARROW[thisSetStructureUnderlyingSet.data];
variableList← underlyingSetData;
variable ← underlyingSetData.first;
sourceStructure ← variable.class;
};
Source Object to recast is one or more variables
IF
VARS.IsVariables[sourceStructure]
THEN {
Check that variable occurs in destination Structure's allVars
sourceVarsSubset: BOOL;
IF variable.flavor # StructureElement THEN RETURN[FALSE]; -- can't check since don't have any concrete variables, i.e.VARS.Variables is not recastable to a particular poly ring
IF variableList=NIL THEN variableList ← LIST[variable];
sourceVarsSubset ← Sequences.IsSubset[SEQ.MakeSequence[variableList, VARSEQ.VariableSequences], destPolyRingData.allVariables];
RETURN[sourceVarsSubset];
};
Source Object to recast is a polynomial
IF IsPolynomialStructure[sourceStructure]
THEN {
sourcePolyRingData: PolynomialRingData ← NARROW[sourceStructure.data];
sourceBaseCoeffRing: Object ← sourcePolyRingData.baseCoeffRing;
Check that source Structure's allVars are a subset of destination Structure's allVars
sourceVarsSubset: BOOL ← Sequences.IsSubset[sourcePolyRingData.allVariables, destPolyRingData.allVariables];
IF NOT sourceVarsSubset THEN RETURN[FALSE];
Check that canRecast source baseCoeffRing to dest baseCoeffRing
refBOOL ← NARROW[AC.ApplyNoLkpNoRecastRef[destBaseCanRecastMethod, LIST[sourceBaseCoeffRing, destBaseCoeffRing] ] ];
RETURN[refBOOL^];
};
Source Object to recast NOT a polynomial; Check if canRecast sourceStructure to dest baseCoeffRing
refBOOL ← NARROW[AC.ApplyNoLkpNoRecastRef[destBaseCanRecastMethod, LIST[sourceStructure, destBaseCoeffRing] ] ];
RETURN[refBOOL^];
};
ToExpr:
PUBLIC
AC.ToExprOp = {
data: PolynomialRingData ← NARROW[in.class.data];
dIn: DP.DPolynomial ← DPolyFromPoly[in];
addend, sum: MathExpr.EXPR;
V: VARSEQ.VariableSequence ← data.allVariables;
coeffRing: Object ← data.baseCoeffRing;
firstTerm: BOOL ← TRUE;
trivialMonomial, firstOccurringVar: BOOL;
thisVar: MathExpr.EXPR;
coeff, coeffAbs: AC.Object;
degreeVec: DP.DegreeVector;
coeffSign: Basics.Comparison;
exponent, index: CARDINAL;
one: AC.Object ← AC.ApplyLkpNoRecastObject[$one, coeffRing, LIST[coeffRing] ];
equalMethod: Method ← AC.LookupMethodInStructure[$eqFormula, coeffRing];
toExprMethod: Method ← AC.LookupMethodInStructure[$toExpr, coeffRing];
isOrdered: BOOL ← AC.HasProperty[coeffRing, $ordered];
signMethod, absMethod: Method;
CreateDTerm:
PROC[firstTerm:
BOOL] ~ {
[coeff, degreeVec] ← dIn.first;
IF isOrdered
THEN {
coeffSign ← AC.ApplyCompareToZeroMethod[signMethod, coeff];
coeffAbs ← AC.ApplyNoLkpNoRecastObject[absMethod, LIST[coeff] ]
}
ELSE {
-- for unordered coeffRing, act as though coeff is positive
coeffSign ← greater;
coeffAbs ← coeff;
};
trivialMonomial ← TRUE;
firstOccurringVar ← TRUE;
degreeVec ← DP.DVReverse[degreeVec];
WHILE degreeVec#
NIL
DO
trivialMonomial ← FALSE;
exponent ← degreeVec.first; degreeVec ← degreeVec.rest;
index ← degreeVec.first; degreeVec ← degreeVec.rest;
IF exponent>1
THEN
thisVar ← MathConstructors.MakePow[
VARS.ToExpr[SEQ.Select[V, Ints.FromINT[index] ] ],
MathConstructors.MakeInt[Convert.RopeFromCard[exponent]]
]
ELSE
thisVar ← VARS.ToExpr[SEQ.Select[V, Ints.FromINT[index] ] ];
IF firstOccurringVar
THEN addend ← thisVar
ELSE
addend ← MathConstructors.MakeProduct[addend, thisVar];
firstOccurringVar ← FALSE;
ENDLOOP;
IF
NOT trivialMonomial
THEN {
IF
NOT
AC.ApplyPredNoLkpNoRecast[equalMethod,
LIST[coeffAbs, one] ]
THEN
addend ← MathConstructors.MakeProduct[NARROW[AC.ApplyNoLkpNoRecastRef[toExprMethod, LIST[coeffAbs] ] ], addend]
}
ELSE addend ← NARROW[AC.ApplyNoLkpNoRecastRef[toExprMethod, LIST[coeffAbs] ] ];
IF firstTerm
AND coeffSign = less
THEN
addend ← MathConstructors.MakeNegation[addend];
};
IF isOrdered
THEN {
signMethod ← AC.LookupMethodInStructure[$sign, coeffRing];
absMethod ← AC.LookupMethodInStructure[$abs, coeffRing];
};
IF dIn = DP.ZeroDPoly THEN RETURN[MathConstructors.MakeInt["0"] ];
CreateDTerm[TRUE]; -- first term
sum ← addend;
dIn ← dIn.rest;
WHILE dIn #
NIL
DO
CreateDTerm[FALSE]; -- not first term
IF coeffSign = greater
THEN
sum ← MathConstructors.MakeSum[sum, addend] -- (((a+b)+c)+d)+ ...
ELSE
sum ← MathConstructors.MakeDifference[sum, addend];
dIn ← dIn.rest;
ENDLOOP;
RETURN[sum];
};
LegalFirstChar:
PUBLIC AC.LegalFirstCharOp = {
Legal first char of polynomial is either legal first char of coefficient, or first char of some variable (this all with reference to distributed rep)
data: PolynomialRingData ← NARROW[structure.data];
firstCharMethod: Method ← AC.LookupMethodInStructure[$legalFirstChar, data.baseCoeffRing];
IF AC.ApplyLegalFirstCharMethod[firstCharMethod, char, data.baseCoeffRing] THEN RETURN[TRUE];
RETURN[VARSEQ.VariableFirstChar[char, data.allVariables] ];
};
Read:
PUBLIC
AC.ReadOp = {
data: PolynomialRingData ← NARROW[structure.data];
dPoly: DP.DPolynomial;
termChar: CHAR;
[dPoly, termChar] ← DP.ReadDPoly[in, data.allVariables, data.baseCoeffRing];
RETURN[ PolyFromDPoly[dPoly, structure] ];
};
FromRope:
PUBLIC
AC.FromRopeOp = {
stream: IO.STREAM ← IO.RIS[in];
out ← Read[stream, structure];
};
ToRope:
PUBLIC AC.ToRopeOp ~ {
data: PolynomialRingData ← NARROW[in.class.data];
out ← DP.DPolyToRope[DPolyFromPoly[in], data.allVariables, data.baseCoeffRing, NIL];
};
ToIndexRope: PUBLIC AC.ToRopeOp ~ {
out ← "Pol";
};
Write:
PUBLIC AC.WriteOp ~ {
IO.PutRope[ stream, ToRope[in] ]
};
PolyToRope:
PUBLIC
PROC [in: Polynomial, termRope: Rope.
ROPE ←
NIL]
RETURNS [out: Rope.
ROPE] = {
data: PolynomialRingData ← NARROW[in.class.data];
out ← DP.DPolyToRope[DPolyFromPoly[in], data.allVariables, data.baseCoeffRing, termRope];
};
WritePoly:
PUBLIC
PROC [in: Polynomial, out:
IO.
STREAM, termRope: Rope.
ROPE ←
NIL] = {
out.PutF["\n %g \n", IO.rope[PolyToRope[in, termRope]] ];
};
PolyFromDPoly:
PUBLIC
PROC [in:
DP.DPolynomial, polynomialRing: Object]
RETURNS [out: Polynomial] = {
polyRingData: PolynomialRingData ← NARROW[polynomialRing.data];
coeffRing: Object ← polyRingData.coeffRing;
zero: AC.Object ← AC.ApplyLkpNoRecastObject[$zero, polynomialRing, LIST[polynomialRing] ];
allVarsData: SEQ.SequenceData ← NARROW[polyRingData.allVariables.data];
numVars: CARDINAL = allVarsData.lengthPlus1 - 1;
termDegree: CARDINAL; -- degree in main variable of current (output) term
outTermDCoefficient: DP.DPolynomial; -- output term coefficient, still in DP rep
outTermCoefficient: AC.Object; -- output term coefficient, converted to P rep
outTerm: Term; -- completed output term
outTerms, outTermsPointer: LIST OF Term ← NIL;
IF in = DP.ZeroDPoly THEN RETURN[zero];
WHILE in#
NIL
DO
termDegree ← DP.DVDegree[in.first.degreeVector, numVars]; -- degree in main variable
IF numVars > 1
THEN {
outTermDCoefficient ← LIST[ [in.first.coefficient, DP.DVRemoveMainVariablePower[in.first.degreeVector, numVars] ] ];
in ← in.rest;
WHILE in#
NIL
AND
DP.DVDegree[in.first.degreeVector, numVars] = termDegree
DO
outTermDCoefficient ← CONS[ [in.first.coefficient, DP.DVRemoveMainVariablePower[in.first.degreeVector, numVars] ], outTermDCoefficient];
in ← in.rest;
ENDLOOP;
outTermDCoefficient ← DP.DPReverse[ outTermDCoefficient ];
outTermCoefficient ← PolyFromDPoly[ outTermDCoefficient, coeffRing ];
}
ELSE {
outTermCoefficient ← in.first.coefficient;
in ← in.rest;
};
outTerm ←
NEW[TermRec ← [
exponent: termDegree,
coefficient: outTermCoefficient
] ];
IF outTerms #
NIL
THEN outTermsPointer ← outTermsPointer.rest ←
LIST[outTerm]
ELSE outTerms ← outTermsPointer ← LIST[outTerm];
ENDLOOP;
RETURN[ NEW[AC.ObjectRec ← [flavor: StructureElement, class: polynomialRing, data: outTerms]] ]
};
DPolyFromPoly:
PUBLIC
PROC [in: Polynomial]
RETURNS [out:
DP.DPolynomial] ~ {
polyRingData: PolynomialRingData ← NARROW[in.class.data];
allVarsData: SEQ.SequenceData ← NARROW[polyRingData.allVariables.data];
numVars: CARDINAL = allVarsData.lengthPlus1 - 1;
inTerms: LIST OF Term ← NARROW[in.data];
inTermDegree: CARDINAL; -- degree in main variable of current (input) term
inTermDPolynomial: DP.DPolynomial;
singleVariableIndex: CARDINAL = 1;
ok: BOOL;
degreeVec: DP.DegreeVector;
IF IsZero[in] THEN RETURN[DP.ZeroDPoly];
out ← DP.ZeroDPoly;
WHILE inTerms #
NIL
DO
inTermDegree ← inTerms.first.exponent;
IF numVars > 1
THEN {
inTermDPolynomial ← DPolyFromPoly[NARROW[inTerms.first.coefficient, Polynomial]];
WHILE inTermDPolynomial#
NIL
DO
out ← CONS[ [ inTermDPolynomial.first.coefficient, DP.DVAddMainVariablePower[inTermDPolynomial.first.degreeVector, numVars, inTermDegree] ], out];
inTermDPolynomial ← inTermDPolynomial.rest;
ENDLOOP;
}
ELSE {
[ok, degreeVec] ← DP.DVInsertVariablePower[singleVariableIndex, inTermDegree, NIL];
IF NOT ok THEN ERROR;
out ← CONS[ [inTerms.first.coefficient, degreeVec], out];
};
inTerms ← inTerms.rest;
ENDLOOP;
out ← DP.DPReverse[out];
};
Arithmetic
Zero:
PUBLIC AC.NullaryOp = {
RETURN[ NEW[ AC.ObjectRec ← [flavor: StructureElement, class: structure, data: NIL]] ]
};
One:
PUBLIC AC.NullaryOp = {
data: PolynomialRingData ← NARROW[structure.data];
RETURN[ Monomial[AC.ApplyLkpNoRecastObject[$one, data.coeffRing, LIST[data.coeffRing] ], NEW[CARDINAL ← 0], structure] ];
};
Add:
PUBLIC
AC.BinaryOp ~ {
data: PolynomialRingData ← NARROW[firstArg.class.data];
coeffRing: Object ← data.coeffRing;
zero: AC.Object ← AC.ApplyLkpNoRecastObject[$zero, coeffRing, LIST[coeffRing] ];
addMethod: Method ← AC.LookupMethodInStructure[$sum, coeffRing];
equalMethod: Method ← AC.LookupMethodInStructure[$eqFormula, coeffRing];
inTerms1: LIST OF Term ← NARROW[firstArg.data];
inTerms2: LIST OF Term ← NARROW[secondArg.data];
outTerms, outTermsPointer, tail: LIST OF Term ← NIL;
outTerm: Term;
termToAdd: BOOL;
IF IsZero[firstArg] THEN RETURN[secondArg];
IF IsZero[secondArg] THEN RETURN[firstArg];
WHILE inTerms1 #
NIL
AND inTerms2 #
NIL
DO
termToAdd ← TRUE;
SELECT inTerms1.first.exponent
FROM
< inTerms2.first.exponent => {
outTerm ← inTerms2.first;
inTerms2 ← inTerms2.rest;
};
> inTerms2.first.exponent => {
outTerm ← inTerms1.first;
inTerms1 ← inTerms1.rest;
};
= inTerms2.first.exponent => {
coeff: AC.Object ← AC.ApplyNoLkpNoRecastObject[addMethod, LIST[inTerms1.first.coefficient, inTerms2.first.coefficient] ];
IF
NOT
AC.ApplyPredNoLkpNoRecast[equalMethod,
LIST[coeff, zero] ]
THEN
outTerm ←
NEW[TermRec ← [
exponent: inTerms2.first.exponent,
coefficient: coeff
] ]
inTerms1 ← inTerms1.rest;
inTerms2 ← inTerms2.rest;
};
ENDCASE;
IF termToAdd
THEN {
IF outTerms # NIL THEN outTermsPointer ← outTermsPointer.rest ← LIST[outTerm]
ELSE outTerms ← outTermsPointer ← LIST[outTerm];
};
ENDLOOP;
IF inTerms1 = NIL THEN tail ← inTerms2 ELSE tail ← inTerms1;
IF outTerms #
NIL
THEN outTermsPointer.rest ← tail
ELSE outTerms ← tail;
RETURN[ NEW[AC.ObjectRec ← [flavor: StructureElement, class: firstArg.class, data: outTerms] ] ];
};
Negate:
PUBLIC
AC.UnaryOp ~ {
data: PolynomialRingData ← NARROW[arg.class.data];
coeffRing: Object ← data.coeffRing;
negateMethod: Method ← AC.LookupMethodInStructure[$negation, coeffRing];
inTerms: LIST OF Term ← NARROW[arg.data];
outTerms, outTermsPointer: LIST OF Term ← NIL;
outTerm: Term;
IF IsZero[arg] THEN RETURN[arg];
WHILE inTerms #
NIL
DO
outTerm ←
NEW[TermRec ← [
exponent: inTerms.first.exponent,
coefficient: AC.ApplyNoLkpNoRecastObject[negateMethod, LIST[inTerms.first.coefficient] ]
] ];
IF outTerms #
NIL
THEN outTermsPointer ← outTermsPointer.rest ←
LIST[outTerm]
ELSE outTerms ← outTermsPointer ← LIST[outTerm];
inTerms ← inTerms.rest;
ENDLOOP;
RETURN[ NEW[AC.ObjectRec ← [flavor: StructureElement, class: arg.class, data: outTerms] ] ];
};
Subtract:
PUBLIC
AC.BinaryOp ~ {
RETURN[ Add[ firstArg, Negate[ secondArg] ] ];
};
Multiply:
PUBLIC
AC.BinaryOp ~ {
Does not assume that coefficient multiplication is commutative
data: PolynomialRingData ← NARROW[firstArg.class.data];
coeffRing: Object ← data.coeffRing;
zeroPoly: AC.Object ← AC.ApplyLkpNoRecastObject[$zero, firstArg.class, LIST[firstArg.class] ];
productMethod: Method ← AC.LookupMethodInStructure[$product, coeffRing];
inTerms1: LIST OF Term ← NARROW[firstArg.data];
inTerms2: LIST OF Term ← NARROW[secondArg.data];
outSummand: Polynomial;
outSummandTerms, outSummandTermsPointer: LIST OF Term;
outSummandTerm: Term;
scratchInTerms1: LIST OF Term;
result ← zeroPoly;
IF IsZero[firstArg] OR IsZero[secondArg] THEN RETURN[result];
WHILE inTerms2 #
NIL
DO
outSummandTerms ← outSummandTermsPointer ← NIL;
scratchInTerms1 ← inTerms1;
WHILE scratchInTerms1 #
NIL
DO
coeff:
AC.Object ←
AC.ApplyNoLkpNoRecastObject[productMethod,
LIST[
scratchInTerms1.first.coefficient,
inTerms2.first.coefficient
] ];
outSummandTerm ←
NEW[TermRec ← [
exponent: scratchInTerms1.first.exponent + inTerms2.first.exponent,
coefficient: coeff
] ];
IF outSummandTerms #
NIL
THEN outSummandTermsPointer ← outSummandTermsPointer.rest ←
LIST[outSummandTerm]
ELSE outSummandTerms ← outSummandTermsPointer ← LIST[outSummandTerm];
scratchInTerms1 ← scratchInTerms1.rest;
ENDLOOP;
outSummand ← NEW[AC.ObjectRec ← [flavor: StructureElement, class: firstArg.class, data: outSummandTerms]];
result ← Add[result, outSummand];
inTerms2 ← inTerms2.rest;
ENDLOOP;
};
ObjectAndIntDesired:
PUBLIC
AC.UnaryToListOp ~ {
RETURN[ LIST[arg, Ints.Ints] ]; -- arg assumed to be a Structure
};
Power:
PUBLIC
AC.BinaryOp ~ {
-- this simple algorithm is Structure independent
power: INT ← Ints.ToINT[secondArg];
structure: Object ← firstArg.class;
one: Object ← AC.ApplyLkpNoRecastObject[$one, structure, LIST[structure] ];
productMethod: Method ← AC.LookupMethodInStructure[$product, structure];
IF power < 0
THEN {
invertMethod: Method ← AC.LookupMethodInStructure[$invert, structure];
temp: Object;
IF invertMethod = NIL THEN ERROR;
temp ← Power[firstArg, Ints.FromINT[ABS[power] ] ];
RETURN[AC.ApplyNoLkpNoRecastObject[invertMethod, LIST[temp] ] ];
};
IF power = 0 THEN RETURN[one];
result ← firstArg;
FOR i:
INT
IN [2..power]
DO
result ← AC.ApplyNoLkpNoRecastObject[productMethod, LIST[firstArg, result] ];
ENDLOOP;
};
Differentiate:
PUBLIC
AC.BinaryOp ~ {
Simple or partial differentiation. firstArg is polynomial, secondArg is variable. firstArg is reordered to make secondArg its main variable, then partially differentiated, then result reordered back to original firstArg Structure.
Assumes that CARDINAL exponent values can be imbedded in coeffRing, in particular, that coeffRing.class.fromRope[Convert.RopeFromCard[arg.data.first.exponent]] works.
reorderedArg: Object ← NewMainVariable[firstArg, secondArg];
data: PolynomialRingData ← NARROW[reorderedArg.class.data];
coeffRing: Object ← data.coeffRing;
fromRopeMethod: Method ← AC.LookupMethodInStructure[$fromRope, coeffRing];
productMethod: Method ← AC.LookupMethodInStructure[$product, coeffRing];
inTerms: LIST OF Term ← NARROW[reorderedArg.data];
outTerms, outTermsPointer: LIST OF Term ← NIL;
outTerm: Term;
reorderedResult: Object;
IF Degree[reorderedArg] = 0 THEN RETURN[Zero[firstArg.class] ];
If we are here, variable of diff occurs in both firstArg and reorderedArg, result of diff will be nonzero, and we know we can recast back into firstArg Structure
WHILE inTerms #
NIL
AND inTerms.first.exponent > 0
DO
imbeddedExp: AC.Object ← AC.ApplyFromRopeMethod[fromRopeMethod, Convert.RopeFromCard[inTerms.first.exponent,10, FALSE], coeffRing];
newCoeff: AC.Object ← AC.ApplyNoLkpNoRecastObject[productMethod, LIST[imbeddedExp, inTerms.first.coefficient] ];
outTerm ← NEW[TermRec ← [exponent: inTerms.first.exponent-1, coefficient: newCoeff] ];
IF outTerms #
NIL
THEN outTermsPointer ← outTermsPointer.rest ←
LIST[outTerm]
ELSE outTerms ← outTermsPointer ← LIST[outTerm];
inTerms ← inTerms.rest;
ENDLOOP;
reorderedResult ← NEW[AC.ObjectRec ← [flavor: StructureElement, class: reorderedArg.class, data: outTerms] ];
RETURN[ Recast[reorderedResult, firstArg.class] ];
};
IndefIntegrate:
PUBLIC
AC.BinaryOp ~ {
Indefinite integration. firstArg is polynomial, secondArg is variable. firstArg is reordered to make secondArg its main variable, then integrated, then result reordered back to original firstArg Structure.
Constant of integration set to zero.
Currently (some superClass of) coeffRing must have a fraction method, i.e. be a field, and its DesiredArgStructures proc must be able to recast elements of coeffRing. I.e. current proc won't work for multivariate integrands.
Assumes that CARDINAL exponent values can be imbedded in coeffRing, in particular, that coeffRing.class.fromRope[Convert.RopeFromCard[arg.data.first.exponent]] works.
reorderedArg: Object ← NewMainVariable[firstArg, secondArg];
data: PolynomialRingData ← NARROW[reorderedArg.class.data];
coeffRing: Object ← data.coeffRing;
variable: Object ← data.variable;
fromRopeMethod: Method ← AC.LookupMethodInStructure[$fromRope, coeffRing];
fractionMethod: Method ← AC.LookupMethodInStructure[$fraction, coeffRing];
inTerms: LIST OF Term ← NARROW[reorderedArg.data];
outTerms, outTermsPointer: LIST OF Term ← NIL;
newCoeff: AC.Object;
outTerm: Term;
reorderedResult: Object;
IF Degree[reorderedArg] = 0 THEN RETURN[Zero[firstArg.class] ];
IF fractionMethod=NIL THEN RETURN[firstArg]; -- do nothing if no fraction method
If we are here, variable of int occurs in both firstArg and reorderedArg, result of int will be nonzero, and we know we can recast back into firstArg Structure
WHILE inTerms #
NIL
AND inTerms.first.exponent >= 0
DO
imbeddedExp: AC.Object ← AC.ApplyFromRopeMethod[fromRopeMethod, Convert.RopeFromCard[inTerms.first.exponent+1,10, FALSE], coeffRing];
newCoeff ← AC.ApplyNoLkpRecastObject[fractionMethod, coeffRing, LIST[inTerms.first.coefficient, imbeddedExp] ]; -- Recast since fraction method may be coming from superClass; if so, coeffRing arg will be bogus, but need the placeholder
outTerm ← NEW[TermRec ← [exponent: inTerms.first.exponent+1, coefficient: newCoeff] ];
IF outTerms #
NIL
THEN outTermsPointer ← outTermsPointer.rest ←
LIST[outTerm]
ELSE outTerms ← outTermsPointer ← LIST[outTerm];
inTerms ← inTerms.rest;
ENDLOOP;
reorderedResult ←
NEW[
AC.ObjectRec ← [
flavor: StructureElement,
class: MakePolynomialStructure[newCoeff.class, SEQ.MakeSequence[LIST[variable], VARSEQ.VariableSequences] ],
data: outTerms
] ]; -- pick up possible new quotient structure for (new) coefficients
RETURN[ reorderedResult ]; -- return with possibly reordered variables
};
MainVarEval:
PUBLIC
AC.BinaryOp ~ {
data: PolynomialRingData ← NARROW[firstArg.class.data];
productMethod: Method ← AC.LookupMethodInStructure[$product, coeffRing];
sumMethod: Method ← AC.LookupMethodInStructure[$sum, coeffRing];
coeffRing: Object ← data.coeffRing;
zero: AC.Object ← AC.ApplyLkpNoRecastObject[$zero, coeffRing, LIST[coeffRing] ];
inTerms: LIST OF Term ← NARROW[firstArg.data];
IF NOT AC.StructureEqual[secondArg.class, coeffRing] THEN TypeError[];
IF IsZero[firstArg] THEN RETURN[zero];
result ← inTerms.first.coefficient;
WHILE inTerms.rest #
NIL
DO
degreeDelta: CARDINAL ← DegreeDelta[inTerms];
newAddend: AC.Object ← AC.ApplyNoLkpNoRecastObject[productMethod, LIST[result, Power[secondArg, Ints.FromINT[degreeDelta] ] ] ];
inTerms ← inTerms.rest;
result ← AC.ApplyNoLkpNoRecastObject[sumMethod, LIST[newAddend, inTerms.first.coefficient] ];
ENDLOOP;
result ← AC.ApplyNoLkpNoRecastObject[productMethod, LIST[result, Power[secondArg, Ints.FromINT[inTerms.first.exponent] ] ] ];
RETURN[ result ];
};
AllVarEval: PUBLIC AC.BinaryOp ~ {
data: PolynomialRingData ← NARROW[firstArg.class.data];
baseCoeffRing: Object ← data.baseCoeffRing;
removeMain: Points.Point;
mainCood: AC.Object;
pointData: Points.PointData ← NARROW[secondArg.data];
inTerms: LIST OF Term ← NARROW[firstArg.data];
coeff: Polynomial;
IF NOT pointData.dimensionPlus1 = data.allVariables.lengthPlus1 THEN OperationError[$BadPointLength];
IF pointData.dimensionPlus1 - 1 = 1 THEN {
at: AC.Object ← NARROW[secondArg.data, Points.PointData][1];
RETURN[MainVarEval[firstArg, at] ];
};
removeMain ← Points.RemoveMainCood[secondArg];
mainCood ← Points.MainCood[secondArg]; -- element of baseCoeffRing
IF NOT baseCoeffRing.class.isElementOf[mainCood, baseCoeffRing] THEN TypeError[];
IF IsZero[firstArg] THEN RETURN[baseCoeffRing.class.zero[baseCoeffRing] ];
coeff ← NARROW[inTerms.first.coefficient];
result ← AllVarEval[coeff, removeMain]; -- element of baseCoeffRing
WHILE inTerms.rest # NIL DO
degreeDelta: CARDINAL ← DegreeDelta[inTerms];
newAddend: AC.Object ← baseCoeffRing.class.multiply[result, Power[mainCood, Ints.FromINT[degreeDelta] ] ];
inTerms ← inTerms.rest;
coeff ← NARROW[inTerms.first.coefficient];
result ← baseCoeffRing.class.add[newAddend, AllVarEval[coeff, removeMain] ];
ENDLOOP;
result ← baseCoeffRing.class.multiply[result, Power[mainCood, Ints.FromINT[inTerms.first.exponent] ] ];
RETURN[ result ];
};
Subst: PUBLIC AC.BinaryOp ~ {
polyRing: Object ← firstArg.class;
data: PolynomialRingData ← NARROW[polyRing.data];
inTerms: LIST OF Term ← NARROW[firstArg.data];
IF NOT polyRing.class.isElementOf[secondArg, polyRing] THEN TypeError[];
IF IsZero[firstArg] THEN RETURN[firstArg];
result ← Monomial[inTerms.first.coefficient, NEW[CARDINAL ← 0], polyRing]; -- lift coefficient
WHILE inTerms.rest # NIL DO
degreeDelta: CARDINAL ← DegreeDelta[inTerms];
trailCoeff: Polynomial;
newAddend: Polynomial ← NARROW[polyRing.class.multiply[result, Power[secondArg, Ints.FromINT[degreeDelta] ] ] ];
inTerms ← inTerms.rest;
trailCoeff ← Monomial[inTerms.first.coefficient, NEW[CARDINAL ← 0], polyRing]; -- lift
result ← NARROW[ polyRing.class.add[newAddend, trailCoeff] ];
ENDLOOP;
result ← NARROW[ polyRing.class.multiply[result, Power[secondArg, Ints.FromINT[inTerms.first.exponent] ] ] ];
RETURN[ result ];
};
DegreeDelta:
PUBLIC
PROC [terms:
LIST
OF Term]
RETURNS [
CARDINAL] ~ {
IF terms = NIL THEN RETURN[0];
IF terms.rest = NIL THEN RETURN[terms.first.exponent];
RETURN[terms.first.exponent - terms.rest.first.exponent];
};
SylvesterMatrix:
PUBLIC
AC.BinaryOp ~ {
data: PolynomialRingData ← NARROW[firstArg.class.data];
coeffRing: Object ← data.coeffRing;
degree1: CARDINAL ← Degree[firstArg];
degree2: CARDINAL ← Degree[secondArg];
size: CARDINAL ← degree1 + degree2;
rows: MAT.RowSeq ← NEW[MAT.RowSeqRec[size]];
zero: AC.Object ← AC.ApplyLkpNoRecastObject[$zero, coeffRing, LIST[coeffRing] ];
matrixStructure: Object ← MAT.MakeMatrixStructure[coeffRing, size, size];
IF degree1 = 0 AND degree2 = 0 THEN RETURN[NIL]; -- undefined in this case
IF degree1 = 0
THEN {
IF IsZero[firstArg]
THEN
RETURN[NARROW[MAT.DiagonalMatrix[zero, matrixStructure] ] ]
ELSE {
polyData: PolynomialData ← NARROW[firstArg.data];
RETURN[NARROW[MAT.DiagonalMatrix[polyData.first.coefficient, matrixStructure] ] ];
};
};
IF degree2 = 0
THEN {
IF IsZero[secondArg]
THEN
RETURN[NARROW[MAT.DiagonalMatrix[zero, matrixStructure] ] ]
ELSE {
polyData: PolynomialData ← NARROW[secondArg.data];
RETURN[NARROW[MAT.DiagonalMatrix[polyData.first.coefficient, matrixStructure] ] ];
};
};
FOR i:
NAT
IN [1..degree2]
DO
row: Matrices.Row ← NEW[Matrices.RowRec[size]];
in1Terms: LIST OF Term ← NARROW[firstArg.data];
FOR j:
NAT
IN [1..i-1]
DO
row[j] ← zero;
ENDLOOP;
row[i] ← in1Terms.first.coefficient;
WHILE in1Terms.rest #
NIL
DO
degreeDelta: CARDINAL ← DegreeDelta[in1Terms];
FOR j:
NAT
IN [1..degreeDelta-1]
DO
row[i+degree1-in1Terms.first.exponent+j] ← zero;
ENDLOOP;
in1Terms ← in1Terms.rest;
row[i+degree1-in1Terms.first.exponent] ← in1Terms.first.coefficient;
ENDLOOP;
FOR j:
NAT
IN [1..in1Terms.first.exponent+(degree2-i)]
DO
row[size+1-j] ← zero;
ENDLOOP;
rows[i] ← row;
ENDLOOP;
FOR i:
NAT
IN [1..degree1]
DO
row: Matrices.Row ← NEW[Matrices.RowRec[size]];
in2Terms: LIST OF Term ← NARROW[secondArg.data];
FOR j:
NAT
IN [1..i-1]
DO
row[j] ← zero;
ENDLOOP;
row[i] ← in2Terms.first.coefficient;
WHILE in2Terms.rest #
NIL
DO
degreeDelta: CARDINAL ← DegreeDelta[in2Terms];
FOR j:
NAT
IN [1..degreeDelta-1]
DO
row[i+degree2-in2Terms.first.exponent+j] ← zero;
ENDLOOP;
in2Terms ← in2Terms.rest;
row[i+degree2-in2Terms.first.exponent] ← in2Terms.first.coefficient;
ENDLOOP;
FOR j:
NAT
IN [1..in2Terms.first.exponent+(degree1-i)]
DO
row[size+1-j] ← zero;
ENDLOOP;
rows[degree2+i] ← row;
ENDLOOP;
result ← NEW[AC.ObjectRec ← [flavor: StructureElement, class: matrixStructure, data: rows] ];
};
Resultant:
PUBLIC
AC.BinaryOp ~ {
sylvesterMatrix: MAT.Matrix ← SylvesterMatrix[firstArg, secondArg];
RETURN[MAT.Determinant[sylvesterMatrix] ];
};
GCD:
PUBLIC
AC.BinaryOp ~ {
polyRingData: PolynomialRingData ← NARROW[firstArg.class.data];
allVariables: Object ← polyRingData.allVariables;
varRope: ROPE ← NARROW[AC.ApplyLkpNoRecastRef[$toRope, allVariables.class, LIST[allVariables] ] ];
resultStream: IO.STREAM ← RemoteAlgebra.SAC2PolynomialBinaryOp[varRope, ToRope[firstArg], ToRope[secondArg] ];
RETURN[Read[resultStream, firstArg.class] ];
};
Remainder:
PUBLIC
AC.BinaryOp ~ {
newDividend: Polynomial ← firstArg;
polyRingData: PolynomialRingData ← NARROW[firstArg.class.data];
coeffRing: Object ← polyRingData.coeffRing;
fractionMethod: Method ← AC.LookupMethodInStructure[$fraction, coeffRing];
IF NOT AC.IsCategory[coeffRing, field] AND AC.IsCategory[coeffRing, divisionAlgebra] THEN TypeError[];
WHILE Degree[newDividend] >= Degree[secondArg]
DO
coeff: AC.Object ← AC.ApplyNoLkpNoRecastObject[fractionMethod, LIST[LeadingCoefficient[newDividend], LeadingCoefficient[secondArg] ] ];
degreeDelta: CARDINAL ← Degree[newDividend] - Degree[secondArg];
multiplier: Polynomial ← Monomial[coeff, NEW[CARDINAL ← degreeDelta], firstArg.class];
product: Polynomial ← Multiply[multiplier, secondArg];
newDividend ← Subtract[newDividend, product];
ENDLOOP;
RETURN[newDividend];
};
Start Code
polynomialsOverCommOrderedRingClass: PUBLIC AC.StructureClass ** Old ** NEW[AC.StructureClassRec ← [
characteristic: ClassCharacteristic,
isElementOf: AC.defaultElementOfProc,
integralDomain: TRUE, -- not necessarily accurate; need separate classrecs
gcdDomain: FALSE, -- not necessarily accurate; need separate classrecs
gcd: NIL, -- should have a poly gcd proc here when appropriate
euclideanDomain: FALSE,
] ];
polynomialClass:
AC.Object ←
AC.MakeClass["polynomialClass",
NIL,
NIL];
polynomialsOverCommRingClass:
AC.Object ←
AC.MakeClass["polynomialsOverCommRingClass", polynomialClass,
NIL];
subclass[polynomialClass]
polynomialsOverOrderedCommRingClass:
AC.Object ←
AC.MakeClass["polynomialsOverOrderedCommRingClass", polynomialsOverCommRingClass,
NIL];
subclass[polynomialsOverCommRingClass]
polynomialsOverOrderedCommFieldClass:
AC.Object ←
AC.MakeClass["polynomialsOverOrderedCommFieldClass", polynomialsOverOrderedCommRingClass,
NIL];
subclass[polynomialsOverOrderedCommRingClass]
polynomialsOverNonCommRingClass:
AC.Object ←
AC.MakeClass["polynomialsOverNonCommRingClass", polynomialClass,
NIL];
subclass[polynomialClass]; this is e.g. for polynomials with matrix coefficients
polynomialStructureMethod: Method ← AC.MakeMethod[Value, FALSE, NIL, NIL, "polynomialStructure"];
groupCategoryMethod: Method ← AC.MakeMethod[Value, FALSE, NEW[AC.Category ← group], NIL, "group"];
ringCategoryMethod: Method ← AC.MakeMethod[Value, FALSE, NEW[AC.Category ← ring], NIL, "ring"];
euclideanDomainMethod: Method ← AC.MakeMethod[Value, FALSE, NIL, NIL, "euclideanDomain"];
orderedMethod: Method ← AC.MakeMethod[Value, FALSE, NIL, NIL, "ordered"];
commutativeMethod: Method ← AC.MakeMethod[Value, FALSE, NIL, NIL, "commutative"];
shortPrintNameMethod: Method ← AC.MakeMethod[ToRopeOp, FALSE, NEW[AC.ToRopeOp ← ShortPrintName], NIL, "shortPrintName"];
recastMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Recast], NIL, "recast"];
canRecastMethod: Method ← AC.MakeMethod[BinaryPredicate, TRUE, NEW[AC.BinaryPredicate ← CanRecast], NIL, "canRecast"];
toExprMethod: Method ← AC.MakeMethod[ToExprOp, FALSE, NEW[AC.ToExprOp ← ToExpr], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "toExpr"];
fromRopeMethod: Method ← AC.MakeMethod[FromRopeOp, TRUE, NEW[AC.FromRopeOp ← FromRope], NIL, "fromRope"];
readMethod: Method ← AC.MakeMethod[ReadOp, FALSE, NEW[AC.ReadOp ← Read], NIL, "read"];
toRopeMethod: Method ← AC.MakeMethod[ToRopeOp, FALSE, NEW[AC.ToRopeOp ← ToRope], NIL, "toRope"];
monomialMethod: Method ← AC.MakeMethod[BinaryImbedOp, FALSE, NEW[AC.BinaryImbedOp ← Monomial], NIL, "monomial"];
leadingCoeffMethod: Method ← AC.MakeMethod[UnaryOp, TRUE, NEW[AC.UnaryOp ← LeadingCoefficient], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "leadingCoeff"];
degreeMethod: Method ← AC.MakeMethod[ElementRankOp, TRUE, NEW[AC.ElementRankOp ← Degree], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "degree"];
reductumMethod: Method ← AC.MakeMethod[UnaryOp, TRUE, NEW[AC.UnaryOp ← Reductum], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "reductum"];
parenMethod: Method ← AC.MakeMethod[UnaryOp, FALSE, NEW[AC.UnaryOp ← AC.Copy], NIL, "paren"];
zeroMethod: Method ← AC.MakeMethod[NullaryOp, FALSE, NEW[AC.NullaryOp ← Zero], NIL, "zero"];
oneMethod: Method ← AC.MakeMethod[NullaryOp, FALSE, NEW[AC.NullaryOp ← One], NIL, "one"];
sumMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Add], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "sum"];
negationMethod: Method ← AC.MakeMethod[UnaryOp, TRUE, NEW[AC.UnaryOp ← Negate], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "negation"];
differenceMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Subtract], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "difference"];
productMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Multiply], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "product"];
powerMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Power], NEW[AC.UnaryToListOp ← ObjectAndIntDesired], "power"];
derivativeMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Differentiate], NEW[AC.UnaryToListOp ← ObjectAndVariableDesired], "derivative"];
partialDerivativeMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Differentiate], NEW[AC.UnaryToListOp ← ObjectAndVariableDesired], "partialDerivative"];
indefIntMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← IndefIntegrate], NEW[AC.UnaryToListOp ← ObjectAndVariableDesired], "indefiniteIntegrate"];
newMainVariableMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← NewMainVariable], NEW[AC.UnaryToListOp ← ObjectAndVariableDesired], "newMainVarialbe"];
mainVarEvalMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← MainVarEval], NIL, "mainVarEval"];
allVarEvalMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← AllVarEval], NIL, "allVarEval"];
substMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Subst], NIL, "substitute"];
sylvesterMatrixMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← SylvesterMatrix], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "sylvesterMatrix"];
resultantMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Resultant], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "resultant"];
gcdMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← GCD], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "gcd"];
remainderMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Remainder], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "remainder"];
equalMethod: Method ← AC.MakeMethod[BinaryPredicate, TRUE, NEW[AC.BinaryPredicate ← Equal], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "equals"];
makePolynomialStructureMethod: Method ← AC.MakeMethod[PolynomialStructureConstructor, FALSE, NEW[AC.PolynomialStructureConstructor ← MakePolynomialStructure], NIL, "makePolynomialStructure"];
AC.AddMethodToClass[$polynomialStructure, polynomialStructureMethod, polynomialClass];
AC.AddMethodToClass[$category, groupCategoryMethod, polynomialClass];
AC.AddMethodToClass[$shortPrintName, shortPrintNameMethod, polynomialClass];
AC.AddMethodToClass[$recast, recastMethod, polynomialClass];
AC.AddMethodToClass[$canRecast, canRecastMethod, polynomialClass];
AC.AddMethodToClass[$toExpr, toExprMethod, polynomialClass];
AC.AddMethodToClass[$fromRope, fromRopeMethod, polynomialClass];
AC.AddMethodToClass[$read, readMethod, polynomialClass];
AC.AddMethodToClass[$toRope, toRopeMethod, polynomialClass];
AC.AddMethodToClass[$monomial, monomialMethod, polynomialClass];
AC.AddMethodToClass[$leadingCoeff, leadingCoeffMethod, polynomialClass];
AC.AddMethodToClass[$degree, degreeMethod, polynomialClass];
AC.AddMethodToClass[$reductum, reductumMethod, polynomialClass];
AC.AddMethodToClass[$paren, parenMethod, polynomialClass];
AC.AddMethodToClass[$zero, zeroMethod, polynomialClass];
AC.AddMethodToClass[$one, oneMethod, polynomialClass];
AC.AddMethodToClass[$sum, sumMethod, polynomialClass];
AC.AddMethodToClass[$negation, negationMethod, polynomialClass];
AC.AddMethodToClass[$difference, differenceMethod, polynomialClass];
AC.AddMethodToClass[$eqFormula, equalMethod, polynomialClass];
AC.AddMethodToClass[$newMainVariable, newMainVariableMethod, polynomialClass];
AC.AddMethodToClass[$category, ringCategoryMethod, polynomialsOverCommRingClass];
AC.AddMethodToClass[$commutative, commutativeMethod, polynomialsOverCommRingClass];
AC.AddMethodToClass[$product, productMethod, polynomialsOverCommRingClass];
AC.AddMethodToClass[$pow, powerMethod, polynomialsOverCommRingClass];
AC.AddMethodToClass[$dDx, derivativeMethod, polynomialsOverCommRingClass];
AC.AddMethodToClass[$partialDeriv, partialDerivativeMethod, polynomialsOverCommRingClass];
AC.AddMethodToClass[$indefInt, indefIntMethod, polynomialsOverCommRingClass];
AC.AddMethodToClass[$mainVarEval, mainVarEvalMethod, polynomialsOverCommRingClass];
AC.AddMethodToClass[$allVarEval, allVarEvalMethod, polynomialsOverCommRingClass];
AC.AddMethodToClass[$subst, substMethod, polynomialsOverCommRingClass];
AC.AddMethodToClass[$sylvesterMatrix, sylvesterMatrixMethod, polynomialsOverCommRingClass];
AC.AddMethodToClass[$resultant, resultantMethod, polynomialsOverCommRingClass];
AC.AddMethodToClass[$gcd, gcdMethod, polynomialsOverCommRingClass];
AC.AddMethodToClass[$ordered, orderedMethod, polynomialsOverOrderedCommRingClass];
AC.AddMethodToClass[$euclideanDomain, euclideanDomainMethod, polynomialsOverOrderedCommFieldClass];
AC.AddMethodToClass[$remainder, remainderMethod, polynomialsOverOrderedCommFieldClass];
AC.AddMethodToClass[$makePolynomialStructure, makePolynomialStructureMethod, Structures.StructuresClass];
AC.AddMethodToClass[$Polynomials, makePolynomialStructureMethod, Structures.StructuresClass];