<> <> DIRECTORY Rope, Basics, Atom, Ascii, Convert, IO, RemoteAlgebra, MathExpr, MathConstructors, AlgebraClasses, Structures, Variables, Sets, Ints, <> Sequences, VariableSequences, DistribPolys, Matrices, Polynomials; PolynomialsImpl: CEDAR PROGRAM IMPORTS Rope, Convert, IO, RemoteAlgebra, MathConstructors, AlgebraClasses, Structures, Variables, Sets, Ints, Sequences, VariableSequences, DistribPolys, Matrices EXPORTS Polynomials = BEGIN OPEN AC: AlgebraClasses, VARS: Variables, VARSEQ: VariableSequences, SEQ: Sequences, DP: DistribPolys, MAT: Matrices, Polynomials; <> ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; Object: TYPE = AC.Object; Method: TYPE = AC.Method; <> SyntaxError: PUBLIC ERROR [reason: ATOM] = CODE; BadElementStructure: PUBLIC ERROR [elementStructure: Object] = CODE; CantInvertError: PUBLIC ERROR [elementStructure: Object] = CODE; TypeError: PUBLIC ERROR [message: ATOM _ $Unspecified] = CODE; OperationError: PUBLIC ERROR [message: ATOM _ $Unspecified] = CODE; <> MakePolynomialStructure: PUBLIC AC.PolynomialStructureConstructor ~ { baseCoeffRing, strictCoeffRing: Object; strictVariable: VARS.Variable; allVariables: VARSEQ.VariableSequence; polynomialRingData: PolynomialRingData; vData: SEQ.SequenceData _ NARROW[variableSeq.data]; IF vData.lengthPlus1 - 1 > 1 THEN { strictCoeffRing _ MakePolynomialStructure[coeffRing, SEQ.DeleteLast[variableSeq] ]; strictVariable _ SEQ.Last[variableSeq]; } ELSE { strictCoeffRing _ coeffRing; strictVariable _ SEQ.First[variableSeq]; }; IF IsPolynomialStructure[strictCoeffRing] THEN { -- polynomials over polynomials, or not? data: PolynomialRingData _ NARROW[strictCoeffRing.data]; baseCoeffRing _ data.baseCoeffRing; allVariables _ SEQ.Append[data.allVariables, strictVariable] } ELSE { baseCoeffRing _ strictCoeffRing; allVariables _ SEQ.MakeSequence[LIST[strictVariable], VARSEQ.VariableSequences]; }; polynomialRingData _ NEW[PolynomialRingDataRec _ [ coeffRing: strictCoeffRing, variable: strictVariable, baseCoeffRing: baseCoeffRing, allVariables: allVariables ] ]; polynomialStructure _ NEW[AC.ObjectRec _ [ flavor: Structure, class: NIL, data: polynomialRingData ] ]; polynomialStructure.name _ ShortPrintName[polynomialStructure]; SELECT TRUE FROM AC.IsCategory[strictCoeffRing, ring] => polynomialStructure.class _ polynomialsOverCommRingClass; AC.IsCategory[strictCoeffRing, algebra] => polynomialStructure.class _ polynomialsOverCommRingClass; AC.IsCategory[strictCoeffRing, field] => polynomialStructure.class _ polynomialsOverOrderedCommFieldClass; AC.IsCategory[strictCoeffRing, divisionAlgebra] => polynomialStructure.class _ polynomialsOverOrderedCommFieldClass; -- probably wrong, since probably the divisionAlgebra is noncommutative ENDCASE => polynomialStructure.class _ polynomialClass; }; <> <> <> <<"Polynomials in ",>> <> <<" over ",>> <> <<] ];>> <<};>> ShortPrintName: PUBLIC AC.PrintNameProc = { data: PolynomialRingData _ NARROW[structure.data]; shortPrintNameMethod: Method _ AC.LookupMethodInStructure[$shortPrintName, data.baseCoeffRing]; RETURN[Rope.Concat[ NARROW[AC.ApplyNoLkpNoRecastRef[shortPrintNameMethod,LIST[data.baseCoeffRing] ] ], Sequences.ToRope[data.allVariables] ] ]; }; <> <> <> <<}; >> IsPolynomialStructure: PUBLIC AC.UnaryPredicate = { IF ~arg.flavor = Structure THEN RETURN[FALSE]; RETURN[ AC.LookupMethodInStructure[$polynomialStructure, arg]#NIL ] }; <> Recast: PUBLIC AC.BinaryOp = { <> 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; <> <> IF AC.StructureEqual[sourceStructure, destPolyRing] THEN RETURN[firstArg]; <> IF Sets.IsVariable[firstArg] THEN { -- recast as an element of Variables Structure variable _ Sets.UnderlyingSetUniverseEltFromSSSElt[firstArg]; sourceStructure _ variable.class; }; <<>> <> IF VARS.IsVariables[sourceStructure] THEN { <<>> <> sourceVarsSubset: BOOL _ SEQ.IsSubset[SEQ.MakeSequence[LIST[variable], VARSEQ.VariableSequences], destPolyRingData.allVariables]; IF NOT sourceVarsSubset THEN RETURN[NIL]; <> sourceRope _ NARROW[AC.ApplyLkpNoRecastRef[$toRope, sourceStructure, LIST[variable]]]; RETURN[AC.ApplyFromRopeMethod[destFromRopeMethod, sourceRope, destPolyRing] ]; }; <> IF IsPolynomialStructure[sourceStructure] THEN { sourcePolyRingData: PolynomialRingData _ NARROW[sourceStructure.data]; sourceBaseCoeffRing: Object _ sourcePolyRingData.baseCoeffRing; <> sourceVarsSubset: BOOL _ Sequences.IsSubset[sourcePolyRingData.allVariables, destPolyRingData.allVariables]; IF NOT sourceVarsSubset THEN RETURN[NIL]; <> refBOOL _ NARROW[AC.ApplyNoLkpNoRecastRef[destBaseCanRecastMethod, LIST[sourceBaseCoeffRing, destBaseCoeffRing] ] ]; IF NOT refBOOL^ THEN RETURN[NIL]; <> sourceRope _ NARROW[AC.ApplyLkpNoRecastRef[$toRope, sourceStructure, LIST[firstArg]]]; RETURN[AC.ApplyFromRopeMethod[destFromRopeMethod, sourceRope, destPolyRing] ]; }; <> 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 >> <> <> <<-- >> <> RETURN[NIL]; }; CanRecast: PUBLIC AC.BinaryPredicate = { <> 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 <> 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]; } <> 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; }; <<>> <> IF VARS.IsVariables[sourceStructure] THEN { <> 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]; }; <> IF IsPolynomialStructure[sourceStructure] THEN { sourcePolyRingData: PolynomialRingData _ NARROW[sourceStructure.data]; sourceBaseCoeffRing: Object _ sourcePolyRingData.baseCoeffRing; <> sourceVarsSubset: BOOL _ Sequences.IsSubset[sourcePolyRingData.allVariables, destPolyRingData.allVariables]; IF NOT sourceVarsSubset THEN RETURN[FALSE]; <> refBOOL _ NARROW[AC.ApplyNoLkpNoRecastRef[destBaseCanRecastMethod, LIST[sourceBaseCoeffRing, destBaseCoeffRing] ] ]; RETURN[refBOOL^]; }; <> 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 = { <> 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]; }; <> <> <<};>> <<>> 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]; }; <> Monomial: PUBLIC AC.BinaryImbedOp = { structureData: PolynomialRingData _ NARROW[structure.data]; coeffRing: Object _ structureData.coeffRing; refExp: REF CARDINAL _ NARROW[data2]; exp: CARDINAL _ refExp^; equalMethod: Method _ AC.LookupMethodInStructure[$eqFormula, coeffRing]; zero: AC.Object _ AC.ApplyLkpNoRecastObject[$zero, coeffRing, LIST[coeffRing] ]; IF NOT AC.StructureEqual[data1.class, coeffRing] THEN TypeError[]; -- check that we really are constructing an element of polynomialRing IF AC.ApplyPredNoLkpNoRecast[equalMethod, LIST[data1, zero] ] THEN -- check for zero coeff RETURN[ NEW[AC.ObjectRec _ [ flavor: StructureElement, class: structure, data: NIL ] ] ] ELSE { outTerm: Term _ NEW[TermRec _ [exponent: exp, coefficient: data1] ]; outTerms: LIST OF Term _ LIST[outTerm]; RETURN[ NEW[AC.ObjectRec _ [ flavor: StructureElement, class: structure, data: outTerms ] ] ]; }; }; <> LeadingCoefficient: PUBLIC AC.UnaryOp ~ { data: PolynomialRingData _ NARROW[arg.class.data]; coeffRing: Object _ data.coeffRing; polyData: PolynomialData; IF IsZero[arg] THEN RETURN[AC.ApplyLkpNoRecastObject[$zero, coeffRing, LIST[coeffRing] ]]; polyData _ NARROW[arg.data]; RETURN[polyData.first.coefficient]; }; <<>> Degree: PUBLIC AC.ElementRankOp ~ { polyData: PolynomialData; IF IsZero[arg] THEN RETURN[0]; polyData _ NARROW[arg.data]; RETURN[polyData.first.exponent]; }; Reductum: PUBLIC AC.UnaryOp ~ { polyData: PolynomialData; IF IsZero[arg] THEN RETURN[arg]; polyData _ NARROW[arg.data]; RETURN[ NEW[AC.ObjectRec _ [flavor: StructureElement, class: arg.class, data: polyData.rest] ] ]; }; <> 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 ] ] ELSE termToAdd _ FALSE; 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 ~ { <> 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 ~ { <> <> 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] ]; <> 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 ~ { <> <> <> <> 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 <> WHILE inTerms # NIL AND (inTerms.first.exponent > 0 OR 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 ]; }; <> <> <> <> <> <> <> <> <> <> <> <> <<};>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<};>> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<};>> <<>> 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]; }; <> Equal: PUBLIC AC.EqualityOp ~ { RETURN[IsZero[Subtract[firstArg, secondArg] ] ]; }; IsZero: PUBLIC AC.UnaryPredicate ~ { RETURN[AC.HasProperty[arg.class, $polynomialStructure] AND arg.data = NIL] }; <> <> <> <> <> <> <> <<};>> <<>> <> <> <> <<};>> <<>> <> <> <> <<};>> <> ObjectAndVariableDesired: PUBLIC AC.UnaryToListOp ~ { RETURN[ LIST[arg, Variables.Variables] ]; -- arg assumed to be a polynomial Structure }; NewMainVariable: PUBLIC AC.BinaryOp ~ { <> polyRingData: PolynomialRingData _ NARROW[firstArg.class.data]; allVars: VARSEQ.VariableSequence _ polyRingData.allVariables; reorderedVars: VARSEQ.VariableSequence _ VARSEQ.NewMainVariable[allVars, secondArg]; newStruct: Object _ MakePolynomialStructure[polyRingData.baseCoeffRing, reorderedVars]; RETURN[ Recast[firstArg, newStruct] ]; }; <> <> <> <> <> <> <> <> <<] ];>> <<>> polynomialClass: AC.Object _ AC.MakeClass["polynomialClass", NIL, NIL]; polynomialsOverCommRingClass: AC.Object _ AC.MakeClass["polynomialsOverCommRingClass", polynomialClass, NIL]; <> polynomialsOverOrderedCommRingClass: AC.Object _ AC.MakeClass["polynomialsOverOrderedCommRingClass", polynomialsOverCommRingClass, NIL]; <> polynomialsOverOrderedCommFieldClass: AC.Object _ AC.MakeClass["polynomialsOverOrderedCommFieldClass", polynomialsOverOrderedCommRingClass, NIL]; <> polynomialsOverNonCommRingClass: AC.Object _ AC.MakeClass["polynomialsOverNonCommRingClass", polynomialClass, NIL]; <> 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"]; <> <> 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[$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]; END.