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