Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

############################################################################### 

# 

# Copyright (C) 2011 Simon King <simon.king@uni-jena.de> 

# Distributed under the terms of the GNU General Public License (GPL), 

# version 2 or any later version. The full text of the GPL is available at: 

# http://www.gnu.org/licenses/ 

# 

############################################################################### 

  

""" 

Homogeneous ideals of free algebras. 

  

For twosided ideals and when the base ring is a field, this 

implementation also provides Groebner bases and ideal containment 

tests. 

  

EXAMPLES:: 

  

sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace') 

sage: F 

Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F 

sage: I 

Twosided Ideal (x*y + y*z, x*x + x*y - y*x - y*y) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

  

One can compute Groebner bases out to a finite degree, can compute normal 

forms and can test containment in the ideal:: 

  

sage: I.groebner_basis(degbound=3) 

Twosided Ideal (y*y*y - y*y*z + y*z*y - y*z*z, y*y*x + y*y*z + y*z*x + y*z*z, x*y + y*z, x*x - y*x - y*y - y*z) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

sage: (x*y*z*y*x).normal_form(I) 

y*z*z*y*z + y*z*z*z*x + y*z*z*z*z 

sage: x*y*z*y*x - (x*y*z*y*x).normal_form(I) in I 

True 

  

AUTHOR: 

  

- Simon King (2011-03-22): See :trac:`7797`. 

  

""" 

  

from sage.rings.noncommutative_ideals import Ideal_nc 

from sage.libs.singular.function import lib, singular_function 

from sage.algebras.letterplace.free_algebra_letterplace cimport FreeAlgebra_letterplace 

from sage.algebras.letterplace.free_algebra_element_letterplace cimport FreeAlgebraElement_letterplace 

from sage.rings.infinity import Infinity 

  

##################### 

# Define some singular functions 

lib("freegb.lib") 

singular_system=singular_function("system") 

poly_reduce=singular_function("NF") 

  

class LetterplaceIdeal(Ideal_nc): 

""" 

Graded homogeneous ideals in free algebras. 

  

In the two-sided case over a field, one can compute Groebner bases 

up to a degree bound, normal forms of graded homogeneous elements 

of the free algebra, and ideal containment. 

  

EXAMPLES:: 

  

sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace') 

sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F 

sage: I 

Twosided Ideal (x*y + y*z, x*x + x*y - y*x - y*y) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

sage: I.groebner_basis(2) 

Twosided Ideal (x*y + y*z, x*x - y*x - y*y - y*z) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

sage: I.groebner_basis(4) 

Twosided Ideal (y*z*y*y - y*z*y*z + y*z*z*y - y*z*z*z, y*z*y*x + y*z*y*z + y*z*z*x + y*z*z*z, y*y*z*y - y*y*z*z + y*z*z*y - y*z*z*z, y*y*z*x + y*y*z*z + y*z*z*x + y*z*z*z, y*y*y - y*y*z + y*z*y - y*z*z, y*y*x + y*y*z + y*z*x + y*z*z, x*y + y*z, x*x - y*x - y*y - y*z) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

  

Groebner bases are cached. If one has computed a Groebner basis 

out to a high degree then it will also be returned if a Groebner 

basis with a lower degree bound is requested:: 

  

sage: I.groebner_basis(2) 

Twosided Ideal (y*z*y*y - y*z*y*z + y*z*z*y - y*z*z*z, y*z*y*x + y*z*y*z + y*z*z*x + y*z*z*z, y*y*z*y - y*y*z*z + y*z*z*y - y*z*z*z, y*y*z*x + y*y*z*z + y*z*z*x + y*z*z*z, y*y*y - y*y*z + y*z*y - y*z*z, y*y*x + y*y*z + y*z*x + y*z*z, x*y + y*z, x*x - y*x - y*y - y*z) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

  

Of course, the normal form of any element has to satisfy the following:: 

  

sage: x*y*z*y*x - (x*y*z*y*x).normal_form(I) in I 

True 

  

Left and right ideals can be constructed, but only twosided ideals provide 

Groebner bases:: 

  

sage: JL = F*[x*y+y*z,x^2+x*y-y*x-y^2]; JL 

Left Ideal (x*y + y*z, x*x + x*y - y*x - y*y) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

sage: JR = [x*y+y*z,x^2+x*y-y*x-y^2]*F; JR 

Right Ideal (x*y + y*z, x*x + x*y - y*x - y*y) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

sage: JR.groebner_basis(2) 

Traceback (most recent call last): 

... 

TypeError: This ideal is not two-sided. We can only compute two-sided Groebner bases 

sage: JL.groebner_basis(2) 

Traceback (most recent call last): 

... 

TypeError: This ideal is not two-sided. We can only compute two-sided Groebner bases 

  

Also, it is currently not possible to compute a Groebner basis when the base 

ring is not a field:: 

  

sage: FZ.<a,b,c> = FreeAlgebra(ZZ, implementation='letterplace') 

sage: J = FZ*[a^3-b^3]*FZ 

sage: J.groebner_basis(2) 

Traceback (most recent call last): 

... 

TypeError: Currently, we can only compute Groebner bases if the ring of coefficients is a field 

  

The letterplace implementation of free algebras also provides integral degree weights 

for the generators, and we can compute Groebner bases for twosided graded homogeneous 

ideals:: 

  

sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace',degrees=[1,2,3]) 

sage: I = F*[x*y+z-y*x,x*y*z-x^6+y^3]*F 

sage: I.groebner_basis(Infinity) 

Twosided Ideal (x*z*z - y*x*x*z - y*x*y*y + y*x*z*x + y*y*y*x + z*x*z + z*y*y - z*z*x, 

x*y - y*x + z, 

x*x*x*x*z*y*y + x*x*x*z*y*y*x - x*x*x*z*y*z - x*x*z*y*x*z + x*x*z*y*y*x*x + 

x*x*z*y*y*y - x*x*z*y*z*x - x*z*y*x*x*z - x*z*y*x*z*x + 

x*z*y*y*x*x*x + 2*x*z*y*y*y*x - 2*x*z*y*y*z - x*z*y*z*x*x - 

x*z*y*z*y + y*x*z*x*x*x*x*x - 4*y*x*z*x*x*z - 4*y*x*z*x*z*x + 

4*y*x*z*y*x*x*x + 3*y*x*z*y*y*x - 4*y*x*z*y*z + y*y*x*x*x*x*z + 

y*y*x*x*x*z*x - 3*y*y*x*x*z*x*x - y*y*x*x*z*y + 

5*y*y*x*z*x*x*x + 4*y*y*x*z*y*x - 4*y*y*y*x*x*z + 

4*y*y*y*x*z*x + 3*y*y*y*y*z + 4*y*y*y*z*x*x + 6*y*y*y*z*y + 

y*y*z*x*x*x*x + y*y*z*x*z + 7*y*y*z*y*x*x + 7*y*y*z*y*y - 

7*y*y*z*z*x - y*z*x*x*x*z - y*z*x*x*z*x + 3*y*z*x*z*x*x + 

y*z*x*z*y + y*z*y*x*x*x*x - 3*y*z*y*x*z + 7*y*z*y*y*x*x + 

3*y*z*y*y*y - 3*y*z*y*z*x - 5*y*z*z*x*x*x - 4*y*z*z*y*x + 

4*y*z*z*z - z*y*x*x*x*z - z*y*x*x*z*x - z*y*x*z*x*x - 

z*y*x*z*y + z*y*y*x*x*x*x - 3*z*y*y*x*z + 3*z*y*y*y*x*x + 

z*y*y*y*y - 3*z*y*y*z*x - z*y*z*x*x*x - 2*z*y*z*y*x + 

2*z*y*z*z - z*z*x*x*x*x*x + 4*z*z*x*x*z + 4*z*z*x*z*x - 

4*z*z*y*x*x*x - 3*z*z*y*y*x + 4*z*z*y*z + 4*z*z*z*x*x + 

2*z*z*z*y, 

x*x*x*x*x*z + x*x*x*x*z*x + x*x*x*z*x*x + x*x*z*x*x*x + x*z*x*x*x*x + 

y*x*z*y - y*y*x*z + y*z*z + z*x*x*x*x*x - z*z*y, 

x*x*x*x*x*x - y*x*z - y*y*y + z*z) 

of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

  

Again, we can compute normal forms:: 

  

sage: (z*I.0-I.1).normal_form(I) 

0 

sage: (z*I.0-x*y*z).normal_form(I) 

-y*x*z + z*z 

  

""" 

def __init__(self, ring, gens, coerce=True, side = "twosided"): 

""" 

INPUT: 

  

- ``ring``: A free algebra in letterplace implementation. 

- ``gens``: List, tuple or sequence of generators. 

- ``coerce`` (optional bool, default ``True``): 

Shall ``gens`` be coerced first? 

- ``side``: optional string, one of ``"twosided"`` (default), 

``"left"`` or ``"right"``. Determines whether the ideal 

is a left, right or twosided ideal. Groebner bases or 

only supported in the twosided case. 

  

TESTS:: 

  

sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace') 

sage: from sage.algebras.letterplace.letterplace_ideal import LetterplaceIdeal 

sage: LetterplaceIdeal(F,x) 

Twosided Ideal (x) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

sage: LetterplaceIdeal(F,[x,y],side='left') 

Left Ideal (x, y) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

  

It is not correctly detected that this class inherits from an 

extension class. Therefore, we have to skip one item of the 

test suite:: 

  

sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F 

sage: TestSuite(I).run(skip=['_test_category'],verbose=True) 

running ._test_eq() . . . pass 

running ._test_new() . . . pass 

running ._test_not_implemented_methods() . . . pass 

running ._test_pickling() . . . pass 

  

""" 

Ideal_nc.__init__(self, ring, gens, coerce=coerce, side=side) 

self.__GB = self 

self.__uptodeg = 0 

def groebner_basis(self, degbound=None): 

""" 

Twosided Groebner basis with degree bound. 

  

INPUT: 

  

- ``degbound`` (optional integer, or Infinity): If it is provided, 

a Groebner basis at least out to that degree is returned. By 

default, the current degree bound of the underlying ring is used. 

  

ASSUMPTIONS: 

  

Currently, we can only compute Groebner bases for twosided 

ideals, and the ring of coefficients must be a field. A 

`TypeError` is raised if one of these conditions is violated. 

  

NOTES: 

  

- The result is cached. The same Groebner basis is returned 

if a smaller degree bound than the known one is requested. 

- If the degree bound Infinity is requested, it is attempted to 

compute a complete Groebner basis. But we can not guarantee 

that the computation will terminate, since not all twosided 

homogeneous ideals of a free algebra have a finite Groebner 

basis. 

  

EXAMPLES:: 

  

sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace') 

sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F 

  

Since `F` was cached and since its degree bound can not be 

decreased, it may happen that, as a side effect of other tests, 

it already has a degree bound bigger than 3. So, we can not 

test against the output of ``I.groebner_basis()``:: 

  

sage: F.set_degbound(3) 

sage: I.groebner_basis() # not tested 

Twosided Ideal (y*y*y - y*y*z + y*z*y - y*z*z, y*y*x + y*y*z + y*z*x + y*z*z, x*y + y*z, x*x - y*x - y*y - y*z) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

sage: I.groebner_basis(4) 

Twosided Ideal (y*z*y*y - y*z*y*z + y*z*z*y - y*z*z*z, y*z*y*x + y*z*y*z + y*z*z*x + y*z*z*z, y*y*z*y - y*y*z*z + y*z*z*y - y*z*z*z, y*y*z*x + y*y*z*z + y*z*z*x + y*z*z*z, y*y*y - y*y*z + y*z*y - y*z*z, y*y*x + y*y*z + y*z*x + y*z*z, x*y + y*z, x*x - y*x - y*y - y*z) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

sage: I.groebner_basis(2) is I.groebner_basis(4) 

True 

sage: G = I.groebner_basis(4) 

sage: G.groebner_basis(3) is G 

True 

  

If a finite complete Groebner basis exists, we can compute 

it as follows:: 

  

sage: I = F*[x*y-y*x,x*z-z*x,y*z-z*y,x^2*y-z^3,x*y^2+z*x^2]*F 

sage: I.groebner_basis(Infinity) 

Twosided Ideal (z*z*z*y*y + z*z*z*z*x, z*x*x*x + z*z*z*y, y*z - z*y, y*y*x + z*x*x, y*x*x - z*z*z, x*z - z*x, x*y - y*x) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

  

Since the commutators of the generators are contained in the ideal, 

we can verify the above result by a computation in a polynomial ring 

in negative lexicographic order:: 

  

sage: P.<c,b,a> = PolynomialRing(QQ,order='neglex') 

sage: J = P*[a^2*b-c^3,a*b^2+c*a^2] 

sage: J.groebner_basis() 

[b*a^2 - c^3, b^2*a + c*a^2, c*a^3 + c^3*b, c^3*b^2 + c^4*a] 

  

Aparently, the results are compatible, by sending `a` to `x`, `b` 

to `y` and `c` to `z`. 

  

""" 

cdef FreeAlgebra_letterplace A = self.ring() 

cdef FreeAlgebraElement_letterplace x 

if degbound is None: 

degbound = A.degbound() 

if self.__uptodeg >= degbound: 

return self.__GB 

if not A.base().is_field(): 

raise TypeError("Currently, we can only compute Groebner bases if the ring of coefficients is a field") 

if self.side()!='twosided': 

raise TypeError("This ideal is not two-sided. We can only compute two-sided Groebner bases") 

if degbound == Infinity: 

while self.__uptodeg<Infinity: 

test_bound = 2*max([x._poly.degree() for x in self.__GB.gens()]) 

self.groebner_basis(test_bound) 

return self.__GB 

# Set the options required by letterplace 

from sage.libs.singular.option import LibSingularOptions 

libsingular_options = LibSingularOptions() 

bck = (libsingular_options['redTail'],libsingular_options['redSB']) 

libsingular_options['redTail'] = True 

libsingular_options['redSB'] = True 

A.set_degbound(degbound) 

P = A._current_ring 

out = [FreeAlgebraElement_letterplace(A,X,check=False) for X in 

singular_system("freegb",P.ideal([x._poly for x in self.__GB.gens()]), 

degbound,A.__ngens, ring = P)] 

libsingular_options['redTail'] = bck[0] 

libsingular_options['redSB'] = bck[1] 

self.__GB = A.ideal(out,side='twosided',coerce=False) 

if degbound >= 2*max([x._poly.degree() for x in out]): 

degbound = Infinity 

self.__uptodeg = degbound 

self.__GB.__uptodeg = degbound 

return self.__GB 

  

def __contains__(self,x): 

""" 

The containment test is based on a normal form computation. 

  

EXAMPLES:: 

  

sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace') 

sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F 

sage: x*I.0-I.1*y+I.0*y in I # indirect doctest 

True 

sage: 1 in I 

False 

  

""" 

R = self.ring() 

return (x in R) and R(x).normal_form(self).is_zero() 

  

def reduce(self, G): 

""" 

Reduction of this ideal by another ideal, 

or normal form of an algebra element with respect to this ideal. 

  

INPUT: 

  

- ``G``: A list or tuple of elements, an ideal, 

the ambient algebra, or a single element. 

  

OUTPUT: 

  

- The normal form of ``G`` with respect to this ideal, if 

``G`` is an element of the algebra. 

- The reduction of this ideal by the elements resp. generators 

of ``G``, if ``G`` is a list, tuple or ideal. 

- The zero ideal, if ``G`` is the algebra containing this ideal. 

  

EXAMPLES:: 

  

sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace') 

sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F 

sage: I.reduce(F) 

Twosided Ideal (0) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

sage: I.reduce(x^3) 

-y*z*x - y*z*y - y*z*z 

sage: I.reduce([x*y]) 

Twosided Ideal (y*z, x*x - y*x - y*y) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

sage: I.reduce(F*[x^2+x*y,y^2+y*z]*F) 

Twosided Ideal (x*y + y*z, -y*x + y*z) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field 

  

""" 

P = self.ring() 

if not isinstance(G,(list,tuple)): 

if G==P: 

return P.ideal([P.zero()]) 

if G in P: 

return G.normal_form(self) 

G = G.gens() 

C = P.current_ring() 

sI = C.ideal([C(X.letterplace_polynomial()) for X in self.gens()], coerce=False) 

selfdeg = max([x.degree() for x in sI.gens()]) 

gI = P._reductor_(G, selfdeg) 

from sage.libs.singular.option import LibSingularOptions 

libsingular_options = LibSingularOptions() 

bck = (libsingular_options['redTail'],libsingular_options['redSB']) 

libsingular_options['redTail'] = True 

libsingular_options['redSB'] = True 

sI = poly_reduce(sI,gI, ring=C, attributes={gI:{"isSB":1}}) 

libsingular_options['redTail'] = bck[0] 

libsingular_options['redSB'] = bck[1] 

return P.ideal([FreeAlgebraElement_letterplace(P,x,check=False) for x in sI], coerce=False)