1 // Copyright (c) 2009 Anna Bigatti and Bjarke Hammersholt Roune 2 3 // This file is part of the source of CoCoALib, the CoCoA Library. 4 5 // CoCoALib is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 10 // CoCoALib is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 15 // You should have received a copy of the GNU General Public License 16 // along with CoCoALib. If not, see <http://www.gnu.org/licenses/>. 17 18 #include "CoCoA/library.H" 19 20 #ifdef CoCoA_WITH_FROBBY 21 #include "CoCoA4io.H" 22 #include "ServerOp.H" 23 24 // #include <iostream> 25 using std::endl; 26 using std::clog; 27 #include <sstream> 28 using std::stringstream; 29 // #include <memory> 30 using std::unique_ptr; 31 // #include <string> 32 using std::string; 33 // #include <vector> 34 using std::vector; 35 36 namespace CoCoA 37 { 38 // sublibrary of CoCoALib for integration with Frobby 39 // by Bjarke Hammersholt Roune. CoCoALib_frobby()40 const ServerOpBase::LibraryInfo& CoCoALib_frobby() 41 { 42 static const ServerOpBase::LibraryInfo 43 UniqueValue("CoCoALib", BuildInfo::version(), "frobby"); 44 return UniqueValue; 45 } 46 47 // ---- CoCoA/ExternalLibs-Frobby.H by Bjarke Hammersholt Roune 48 49 // Common base class for Frobby operations. Contains some code that is 50 // useful for Frobby operations. 51 class FrobbyOpBase : public ServerOpBase { 52 public: FrobbyOpBase()53 FrobbyOpBase(): ServerOpBase(CoCoALib_frobby()) { 54 } 55 56 protected: 57 unique_ptr<ideal> myReadMonomialIdeal 58 (std::istream& in, const SparsePolyRing& ring); 59 unique_ptr<PPMonoidElem> myReadMonomial 60 (std::istream& in, const SparsePolyRing& ring); 61 }; 62 myReadMonomialIdeal(std::istream & in,const SparsePolyRing & ring)63 unique_ptr<ideal> FrobbyOpBase::myReadMonomialIdeal 64 (std::istream& in, const SparsePolyRing& ring) { 65 PolyList polyList; 66 ReadPolyList(in, polyList, ring, GetTag); 67 return unique_ptr<ideal>(new ideal(ring, polyList)); 68 } 69 myReadMonomial(std::istream & in,const SparsePolyRing & ring)70 unique_ptr<PPMonoidElem> FrobbyOpBase::myReadMonomial 71 (std::istream& in, const SparsePolyRing& ring) { 72 PolyList polyList; 73 ReadPolyList(in, polyList, ring, GetTag); 74 75 if (polyList.size() != 1 || !IsMonomial(polyList.front())) 76 CoCoA_ERROR("Expected a single monomial", "FrobbyBaseOp::myReadMonomial"); 77 78 return unique_ptr<PPMonoidElem>(new PPMonoidElem(LPP(polyList.front()))); 79 } 80 81 #ifdef CoCoA_WITH_FROBBY 82 83 class AlexanderDualOp : public FrobbyOpBase 84 { 85 public: 86 void myOutputSelf(std::ostream& out) const; 87 void myReadArgs(std::istream& in, int NumArgs); 88 void myCompute(); 89 void myWriteResult(std::ostream& out) const; 90 void myClear(); 91 92 private: 93 unique_ptr<ideal> myIdeal; 94 unique_ptr<PPMonoidElem> myPP; 95 unique_ptr<ideal> myDual; 96 }; 97 myOutputSelf(std::ostream & out)98 void AlexanderDualOp::myOutputSelf(std::ostream& out) const { 99 out << "AlexanderDualFrobby"; 100 } 101 myReadArgs(std::istream & in,int NumArgs)102 void AlexanderDualOp::myReadArgs(std::istream& in, int NumArgs) 103 { 104 CoCoA_ASSERT(NumArgs == 3); // ring, ideal, pp 105 const SparsePolyRing ring(ReadPolyRing(in, GetTag)); 106 myIdeal = myReadMonomialIdeal(in, ring); 107 myPP = myReadMonomial(in, ring); 108 } 109 myCompute()110 void AlexanderDualOp::myCompute() { 111 myDual.reset(new ideal(FrbAlexanderDual(*myIdeal, *myPP))); 112 } 113 myWriteResult(std::ostream & out)114 void AlexanderDualOp::myWriteResult(std::ostream& out) const 115 { 116 WritePolyListInVar(out, ourVarName4, gens(*myDual)); 117 } 118 myClear()119 void AlexanderDualOp::myClear() { 120 myIdeal.reset(); 121 myPP.reset(); 122 myDual.reset(); 123 } 124 125 class IrreducibleDecomOp : public FrobbyOpBase 126 { 127 public: 128 void myOutputSelf(std::ostream& out) const; 129 void myReadArgs(std::istream& in, int NumArgs); 130 void myCompute(); 131 void myWriteResult(std::ostream& out) const; 132 void myClear(); 133 134 private: 135 unique_ptr<ideal> myIdeal; 136 unique_ptr<vector<ideal> > myDecom; 137 }; 138 myOutputSelf(std::ostream & out)139 void IrreducibleDecomOp::myOutputSelf(std::ostream& out) const { 140 out << "IrreducibleDecom"; 141 } 142 myReadArgs(std::istream & in,int NumArgs)143 void IrreducibleDecomOp::myReadArgs(std::istream& in, int NumArgs) 144 { 145 CoCoA_ASSERT(NumArgs == 2); // ring and ideal 146 const SparsePolyRing ring(ReadPolyRing(in, GetTag)); 147 myIdeal = myReadMonomialIdeal(in, ring); 148 } 149 myCompute()150 void IrreducibleDecomOp::myCompute() { 151 myDecom.reset(new vector<ideal>()); 152 FrbIrreducibleDecomposition(*myDecom, *myIdeal); 153 } 154 myWriteResult(std::ostream & out)155 void IrreducibleDecomOp::myWriteResult(std::ostream& out) const 156 { 157 out << ourVarName4 << " := [];\n"; 158 for (size_t component = 0; component < myDecom->size(); ++component) { 159 WritePolyListInVar(out, "Tmp", gens((*myDecom)[component])); 160 out << "Append(" << ourVarName4 << ", Tmp);\n"; 161 } 162 } 163 myClear()164 void IrreducibleDecomOp::myClear() { 165 myIdeal.reset(); 166 myDecom.reset(); 167 } 168 169 class MaximalStandardMonomialsOp : public FrobbyOpBase 170 { 171 public: 172 void myOutputSelf(std::ostream& out) const; 173 void myReadArgs(std::istream& in, int NumArgs); 174 void myCompute(); 175 void myWriteResult(std::ostream& out) const; 176 void myClear(); 177 178 private: 179 unique_ptr<ideal> myIdeal; 180 unique_ptr<ideal> myMsms; 181 }; 182 myOutputSelf(std::ostream & out)183 void MaximalStandardMonomialsOp::myOutputSelf(std::ostream& out) const { 184 out << "MaximalStandardMonomials"; 185 } 186 myReadArgs(std::istream & in,int NumArgs)187 void MaximalStandardMonomialsOp::myReadArgs(std::istream& in, int NumArgs) 188 { 189 CoCoA_ASSERT(NumArgs == 2); // ring and ideal 190 const SparsePolyRing ring(ReadPolyRing(in, GetTag)); 191 myIdeal = myReadMonomialIdeal(in, ring); 192 } 193 myCompute()194 void MaximalStandardMonomialsOp::myCompute() { 195 myMsms.reset(new ideal(FrbMaximalStandardMonomials(*myIdeal))); 196 } 197 myWriteResult(std::ostream & out)198 void MaximalStandardMonomialsOp::myWriteResult(std::ostream& out) const 199 { 200 WritePolyListInVar(out, ourVarName4, gens(*myMsms)); 201 } 202 myClear()203 void MaximalStandardMonomialsOp::myClear() { 204 myIdeal.reset(); 205 myMsms.reset(); 206 } 207 208 class PrimaryDecomOp : public FrobbyOpBase 209 { 210 public: 211 void myOutputSelf(std::ostream& out) const; 212 void myReadArgs(std::istream& in, int NumArgs); 213 void myCompute(); 214 void myWriteResult(std::ostream& out) const; 215 void myClear(); 216 217 private: 218 unique_ptr<ideal> myIdeal; 219 unique_ptr<vector<ideal> > myDecom; 220 }; 221 myOutputSelf(std::ostream & out)222 void PrimaryDecomOp::myOutputSelf(std::ostream& out) const { 223 out << "PrimaryDecompositionFrobby"; 224 } 225 myReadArgs(std::istream & in,int NumArgs)226 void PrimaryDecomOp::myReadArgs(std::istream& in, int NumArgs) 227 { 228 CoCoA_ASSERT(NumArgs == 2); // ring and ideal 229 const SparsePolyRing ring(ReadPolyRing(in, GetTag)); 230 myIdeal = myReadMonomialIdeal(in, ring); 231 } 232 myCompute()233 void PrimaryDecomOp::myCompute() { 234 myDecom.reset(new vector<ideal>()); 235 FrbPrimaryDecomposition(*myDecom, *myIdeal); 236 } 237 myWriteResult(std::ostream & out)238 void PrimaryDecomOp::myWriteResult(std::ostream& out) const 239 { 240 out << ourVarName4 << " := [];\n"; 241 for (size_t component = 0; component < myDecom->size(); ++component) { 242 WritePolyListInVar(out, "Tmp", gens((*myDecom)[component])); 243 out << "Append(" << ourVarName4 << ", Tmp);\n"; 244 } 245 } 246 myClear()247 void PrimaryDecomOp::myClear() { 248 myIdeal.reset(); 249 myDecom.reset(); 250 } 251 252 class AssociatedPrimesOp : public FrobbyOpBase 253 { 254 public: 255 void myOutputSelf(std::ostream& out) const; 256 void myReadArgs(std::istream& in, int NumArgs); 257 void myCompute(); 258 void myWriteResult(std::ostream& out) const; 259 void myClear(); 260 261 private: 262 unique_ptr<ideal> myIdeal; 263 unique_ptr<vector<ideal> > myPrimes; 264 }; 265 myOutputSelf(std::ostream & out)266 void AssociatedPrimesOp::myOutputSelf(std::ostream& out) const { 267 out << "AssociatedPrimes"; 268 } 269 myReadArgs(std::istream & in,int NumArgs)270 void AssociatedPrimesOp::myReadArgs(std::istream& in, int NumArgs) 271 { 272 CoCoA_ASSERT(NumArgs == 2); // ring and ideal 273 const SparsePolyRing ring(ReadPolyRing(in, GetTag)); 274 myIdeal = myReadMonomialIdeal(in, ring); 275 } 276 myCompute()277 void AssociatedPrimesOp::myCompute() { 278 myPrimes.reset(new vector<ideal>()); 279 FrbAssociatedPrimes(*myPrimes, *myIdeal); 280 } 281 myWriteResult(std::ostream & out)282 void AssociatedPrimesOp::myWriteResult(std::ostream& out) const 283 { 284 out << ourVarName4 << " := [];\n"; 285 for (size_t component = 0; component < myPrimes->size(); ++component) { 286 WritePolyListInVar(out, "Tmp", gens((*myPrimes)[component])); 287 out << "Append(" << ourVarName4 << ", Tmp);\n"; 288 } 289 } 290 myClear()291 void AssociatedPrimesOp::myClear() { 292 myIdeal.reset(); 293 myPrimes.reset(); 294 } 295 296 class DimensionOp : public FrobbyOpBase 297 { 298 public: 299 DimensionOp(); 300 301 void myOutputSelf(std::ostream& out) const; 302 void myReadArgs(std::istream& in, int NumArgs); 303 void myCompute(); 304 void myWriteResult(std::ostream& out) const; 305 void myClear(); 306 307 private: 308 unique_ptr<ideal> myIdeal; 309 long myDimension; 310 }; 311 DimensionOp()312 DimensionOp::DimensionOp(): 313 myDimension(0) { 314 } 315 myOutputSelf(std::ostream & out)316 void DimensionOp::myOutputSelf(std::ostream& out) const { 317 out << "Dimension"; 318 } 319 myReadArgs(std::istream & in,int NumArgs)320 void DimensionOp::myReadArgs(std::istream& in, int NumArgs) 321 { 322 CoCoA_ASSERT(NumArgs == 2); // ring and ideal 323 const SparsePolyRing ring(ReadPolyRing(in, GetTag)); 324 myIdeal = myReadMonomialIdeal(in, ring); 325 } 326 myCompute()327 void DimensionOp::myCompute() { 328 myDimension = FrbDimension(*myIdeal); 329 } 330 myWriteResult(std::ostream & out)331 void DimensionOp::myWriteResult(std::ostream& out) const 332 { 333 out << ourVarName4 << " := " << myDimension << ";\n"; 334 } 335 myClear()336 void DimensionOp::myClear() { 337 myIdeal.reset(); 338 myDimension = 0; 339 } 340 #else // if no Frobby 341 class NoFrobbyErrorOp : public FrobbyOpBase 342 { 343 public: myOutputSelf(std::ostream & out)344 void myOutputSelf(std::ostream& out) const {myError();} myReadArgs(std::istream & in,int NumArgs)345 void myReadArgs(std::istream& in, int NumArgs) {myError();} myCompute()346 void myCompute() {myError();} myWriteResult(std::ostream & out)347 void myWriteResult(std::ostream& out) const {myError();} myClear()348 void myClear() {myError();} 349 350 private: myError()351 void myError() const { 352 CoCoA_ERROR("Frobby not present. Build CoCoA with Frobby to enable " 353 "this function.", "NoFRobbyErrorOp"); 354 } 355 }; 356 357 typedef NoFrobbyErrorOp AlexanderDualOp; 358 typedef NoFrobbyErrorOp DimensionOp; 359 typedef NoFrobbyErrorOp IrreducibleDecomOp; 360 typedef NoFrobbyErrorOp PrimaryDecomOp; 361 typedef NoFrobbyErrorOp MaximalStandardMonomialsOp; 362 typedef NoFrobbyErrorOp AssociatedPrimesOp; 363 364 #endif 365 366 //---------------------------------------------------------------------- 367 368 namespace CoCoAServerOperationsFromFrobby 369 { RegisterOps()370 bool RegisterOps() 371 { 372 // integration with Frobby 373 RegisterOp("AlexanderDual_Frobby", ServerOp(new AlexanderDualOp())); 374 RegisterOp("Dimension_Frobby", ServerOp(new DimensionOp())); 375 RegisterOp("IrreducibleDecom_Frobby", ServerOp(new IrreducibleDecomOp())); 376 RegisterOp("PrimaryDecom_Frobby", ServerOp(new PrimaryDecomOp())); 377 RegisterOp("MaximalStandardMonomials_Frobby", 378 ServerOp(new MaximalStandardMonomialsOp())); 379 RegisterOp("AssociatedPrimes_Frobby", ServerOp(new AssociatedPrimesOp())); 380 381 return true; 382 } 383 384 RegisterOpsOnce()385 bool RegisterOpsOnce() 386 { 387 static bool EvalOnce = RegisterOps(); 388 return EvalOnce; 389 } 390 } 391 } 392 #endif 393