1#############################################################################
2##
3#W  z_pi.gi               GAP4 Package `Resclasses'               Stefan Kohl
4##
5##  This file contains implementations of methods for computing with the
6##  semilocalizations Z_(pi) of the ring of integers.
7##
8#############################################################################
9
10#############################################################################
11##
12#M  Z_piCons( <filter>, <pi> ) . . . . . . . . . . . . . . . . . . . . Z_(pi)
13##
14##  Returns the semilocalization Z_(pi) of the ring of integers,
15##  for given prime set <pi>.
16##
17InstallMethod( Z_piCons, "natural Z_pi (ResClasses)", true,
18               [ IsRing, IsList ], 0,
19
20  function ( filter, pi )
21
22    local  R, piStr;
23
24    R := Objectify( NewType( FamilyObj( Integers ),
25                             IsRing and IsAttributeStoringRep ),
26                    rec( primes := Immutable( pi ) ) );
27    SetIsTrivial( R, false );
28    SetIsZ_pi( R, true );
29    SetZero( R, 0 ); SetOne( R, 1 );
30    SetIsFinite( R, false ); SetSize( R, infinity );
31    SetIsAssociative( R, true ); SetIsCommutative( R, true );
32    SetRepresentative( R, 1/Minimum(Difference(List(pi,NextPrimeInt),pi)) );
33    SetElementsFamily( R, FamilyObj( 1 ) );
34    SetNoninvertiblePrimes( R, R!.primes );
35    piStr := String(pi);
36    return R;
37  end );
38
39#############################################################################
40##
41#F  Z_pi( <pi> ) . . . . . . . . . semilocalization Z_(pi) for prime set <pi>
42##
43InstallGlobalFunction( Z_pi,
44
45  function ( arg )
46
47    local  pi;
48
49    if IsInt( arg[1] ) then pi := arg; else pi := arg[1]; fi;
50    if not IsList( pi ) or not ForAll( pi, IsPrimeInt )
51    then Error( "Z_pi( <pi> ): <pi> must be a set of primes.\n" ); fi;
52    return Z_piCons( IsRing, Set( pi ) );
53  end );
54
55#############################################################################
56##
57#M  IsZ_pi( <obj> ) . . . . . . . . . . . . . . . . . . . . . . . . .  Z_(pi)
58##
59##  Return false, if the contrary is not known explicitly.
60##
61InstallOtherMethod( IsZ_pi, "for non-Z_(pi) (ResClasses)", true,
62                    [ IsObject ], 0, ReturnFalse );
63
64#############################################################################
65##
66#M  ViewString( <R> ) . . . . . . . . . . . . . . . . . . . . . .  for Z_(pi)
67##
68InstallMethod( ViewString,
69               "for Z_(pi) (ResClasses)", ReturnTrue, [ IsZ_pi ], 0,
70
71 function ( R )
72
73   local  pistr;
74
75   pistr := String(NoninvertiblePrimes(R));
76   return Concatenation( "Z_(", pistr{[2..Length(pistr)-1]}, ")" );
77 end );
78
79#############################################################################
80##
81#M  ViewObj( <R> ) . . . . . . . . . . . . . . . . . . . . . . . . for Z_(pi)
82##
83InstallMethod( ViewObj, "for Z_(pi) (ResClasses)", ReturnTrue, [ IsZ_pi ], 0,
84               function ( R ) Print(ViewString(R)); end );
85
86#############################################################################
87##
88#M  PrintObj( <R> ) . . . . . . . . . . . . . . . . . . . . . . .  for Z_(pi)
89##
90InstallMethod( PrintObj,
91               "for Z_(pi) (ResClasses)", ReturnTrue, [ IsZ_pi ], 0,
92               function ( R ) Print( String( R ) ); end );
93
94#############################################################################
95##
96#M  String( <R> ) . . . . . . . . . . . . . . . . . . . . . . . .  for Z_(pi)
97##
98InstallMethod( String,
99               "for Z_(pi) (ResClasses)", ReturnTrue, [ IsZ_pi ], 0,
100
101  R -> Concatenation( "Z_pi( ", String( NoninvertiblePrimes( R ) ), " )" ) );
102
103#############################################################################
104##
105#M  \=( <R>, <S> ) . . . . . . . . . . . . . . . . . . . . . . . for Z_(pi)'s
106##
107InstallMethod( \=,
108               "for Z_(pi)'s (ResClasses)", ReturnTrue,
109               [ IsZ_pi, IsZ_pi ], 0,
110
111  function ( R, S ) return R!.primes = S!.primes; end );
112
113#############################################################################
114##
115#M  \in( <x>, <R> ) . . . . . . . . . . . . . . . . . . for object and Z_(pi)
116##
117InstallMethod( \in,
118               "for object and Z_(pi) (ResClasses)", ReturnTrue,
119               [ IsObject, IsZ_pi ], 0,
120
121  function ( x, R )
122
123    if not IsRat(x) then return false; fi;
124    return Intersection(Set(Factors(DenominatorRat(x))),R!.primes) = [];
125  end );
126
127#############################################################################
128##
129#M  Intersection2( <R>, <S> ) . . . . . . . . . . . . . . . . .  for Z_(pi)'s
130##
131InstallMethod( Intersection2,
132               "for Z_(pi)'s (ResClasses)", ReturnTrue,
133               [ IsZ_pi, IsZ_pi ], 0,
134
135  function ( R, S )
136
137    return Z_pi( Union( R!.primes, S!.primes ) );
138  end );
139
140#############################################################################
141##
142#M  Intersection2( Rationals, <R> ) . . . . . . . .  for Rationals and Z_(pi)
143##
144InstallMethod( Intersection2,
145               "for Rationals and Z_(pi) (ResClasses)", ReturnTrue,
146               [ IsRationals, IsZ_pi ], 0,
147  function ( Rat, R ) return R; end );
148
149#############################################################################
150##
151#M  Intersection2( <R>, Rationals ) . . . . . . . .  for Z_(pi) and Rationals
152##
153InstallMethod( Intersection2,
154               "for Z_(pi) and Rationals (ResClasses)", ReturnTrue,
155               [ IsZ_pi, IsRationals ], 0,
156  function ( R, Rat ) return R; end );
157
158#############################################################################
159##
160#M  IsSubset( <R>, <S> ) . . . . . . . . . . . . . . . . . . . . for Z_(pi)'s
161##
162InstallMethod( IsSubset,
163               "for Z_(pi)'s (ResClasses)", ReturnTrue,
164               [ IsZ_pi, IsZ_pi ], 0,
165
166  function ( R, S ) return IsSubset( S!.primes, R!.primes ); end );
167
168#############################################################################
169##
170#M  IsSubset( Rationals, <R> ) . . . . . . . . . . . for Rationals and Z_(pi)
171##
172InstallMethod( IsSubset,
173               "for Rationals and Z_(pi) (ResClasses)", ReturnTrue,
174               [ IsRationals, IsZ_pi ], 0, ReturnTrue );
175
176#############################################################################
177##
178#M  IsSubset( <R>, Integers ) . . . . . . . . . . . . for Z_(pi) and Integers
179##
180InstallMethod( IsSubset,
181               "for Z_(pi) and Integers (ResClasses)", ReturnTrue,
182               [ IsZ_pi, IsIntegers ], 0, ReturnTrue );
183
184#############################################################################
185##
186#M  StandardAssociate( <R>, <x> ) . . . . . for Z_(pi) and an element thereof
187##
188InstallMethod( StandardAssociate,
189               "for Z_(pi) and an element thereof (ResClasses)", ReturnTrue,
190               [ IsZ_pi, IsRat ], 0,
191
192  function ( R, x )
193
194    local  pi;
195
196    if not x in R then return fail; fi; if x = 0 then return 0; fi;
197    pi := NoninvertiblePrimes( R );
198    return Product( Filtered( Factors( AbsInt( NumeratorRat( x ) ) ),
199                              p -> p in pi ) );
200  end );
201
202#############################################################################
203##
204#M  GcdOp( <R>, <x>, <y> ) . . . . . . .  for Z_(pi) and two elements thereof
205##
206InstallMethod( GcdOp,
207               "for Z_(pi) and two elements thereof (ResClasses)",
208               ReturnTrue, [ IsZ_pi, IsRat, IsRat ], 0,
209
210  function ( R, x, y )
211    if not x in R or not y in R then return fail; fi;
212    return Gcd( StandardAssociate( R, x ), StandardAssociate( R, y ) );
213  end );
214
215#############################################################################
216##
217#M  LcmOp( <R>, <x>, <y> ) . . . . . . .  for Z_(pi) and two elements thereof
218##
219InstallMethod( LcmOp,
220               "for Z_(pi) and two elements thereof (ResClasses)",
221               ReturnTrue, [ IsZ_pi, IsRat, IsRat ], 0,
222
223  function ( R, x, y )
224    if not x in R or not y in R then return fail; fi;
225    return Lcm( StandardAssociate( R, x ), StandardAssociate( R, y ) );
226  end );
227
228#############################################################################
229##
230#M  Factors( <R>, <x> ) . . . . . . . . . . for Z_(pi) and an element thereof
231##
232InstallMethod( Factors,
233               "for Z_(pi) and an element thereof (ResClasses)", ReturnTrue,
234               [ IsZ_pi, IsRat ], 0,
235
236  function ( R, x )
237
238    local  pi, p;
239
240    if not x in R then return fail; fi;
241    pi := NoninvertiblePrimes( R );
242    p := Filtered( Factors( AbsInt( NumeratorRat( x ) ) ), q -> q in pi );
243    if   x = Product( p ) then return p;
244    else return Concatenation( [ x / Product(p) ], p ); fi;
245  end );
246
247#############################################################################
248##
249#M  IsUnit( <R>, <x> ) . . . . . . . . . .  for Z_(pi) and an element thereof
250##
251InstallMethod( IsUnit,
252               "for Z_(pi) and an element thereof (ResClasses)", ReturnTrue,
253               [ IsZ_pi, IsRat ], 0,
254
255  function ( R, x )
256
257    local  pi;
258
259    if not x in R then return fail; fi; if x = 0 then return false; fi;
260    pi := NoninvertiblePrimes( R );
261    return Intersection( Factors( AbsInt( NumeratorRat( x ) ) ), pi ) = [ ];
262  end );
263
264#############################################################################
265##
266#M  IsIrreducibleRingElement( <R>, <x> ) .  for Z_(pi) and an element thereof
267##
268InstallMethod( IsIrreducibleRingElement,
269               "for Z_(pi) and an element thereof (ResClasses)", ReturnTrue,
270               [ IsZ_pi, IsRat ], 0,
271
272  function ( R, x )
273
274    local  pi;
275
276    if not x in R then return fail; fi;
277    pi := NoninvertiblePrimes( R );
278    return Length( Filtered( Factors( AbsInt( NumeratorRat( x ) ) ),
279                             q -> q in pi ) ) = 1;
280  end );
281
282#############################################################################
283##
284#E  z_pi.gi . . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here