source: git/libpolys/coeffs/flintcf_Q.cc @ 5ae803

spielwiese
Last change on this file since 5ae803 was 5ae803, checked in by Hans Schoenemann <hannes@…>, 5 years ago
add: KillChar for flintQ, flintZn
  • Property mode set to 100644
File size: 15.7 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT: flint: fmpq_poly
6*/
7#include <ctype.h> /* isdigit*/
8
9#include "misc/auxiliary.h"
10
11#ifdef HAVE_FLINT
12
13#include <flint/flint.h>
14#include <flint/fmpq_poly.h>
15#include "factory/factory.h"
16
17#include "omalloc/omalloc.h"
18#include "coeffs/coeffs.h"
19
20#include "coeffs/numbers.h"
21#include "coeffs/longrat.h"
22
23typedef fmpq_poly_struct *fmpq_poly_ptr;
24typedef fmpz *fmpz_ptr;
25/*2
26* extracts a long integer from s, returns the rest
27*/
28static char * nlEatLong(char *s, mpz_ptr i)
29{
30  const char * start=s;
31
32  while (*s >= '0' && *s <= '9') s++;
33  if (*s=='\0')
34  {
35    mpz_set_str(i,start,10);
36  }
37  else
38  {
39    char c=*s;
40    *s='\0';
41    mpz_set_str(i,start,10);
42    *s=c;
43  }
44  return s;
45}
46
47static BOOLEAN CoeffIsEqual(const coeffs r, n_coeffType n, void * parameter)
48{
49  return (r->type==n);
50}
51static void SetChar(const coeffs r)
52{
53  // dummy
54}
55static number Mult(number a, number b, const coeffs c)
56{
57  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
58  fmpq_poly_init(res);
59  fmpq_poly_mul(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
60  return (number)res;
61}
62static number Sub(number a, number b, const coeffs c)
63{
64  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
65  fmpq_poly_init(res);
66  fmpq_poly_sub(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
67  return (number)res;
68}
69static number Add(number a, number b, const coeffs c)
70{
71  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
72  fmpq_poly_init(res);
73  fmpq_poly_add(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
74  return (number)res;
75}
76static number Div(number a, number b, const coeffs c)
77{
78  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
79  fmpq_poly_init(res);
80  if(fmpq_poly_is_zero((fmpq_poly_ptr)b))
81  {
82     WerrorS(nDivBy0);
83  }
84  else
85  {
86    fmpq_poly_div(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
87    fmpq_poly_t mod;
88    fmpq_poly_init(mod);
89    fmpq_poly_rem(mod,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
90    if (!fmpq_poly_is_zero((fmpq_poly_ptr)mod))
91    {
92      WerrorS("cannot divide");
93    }
94    fmpq_poly_clear(mod);
95  }
96  return (number)res;
97}
98static number ExactDiv(number a, number b, const coeffs c)
99{
100  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
101  fmpq_poly_init(res);
102  if(fmpq_poly_is_zero((fmpq_poly_ptr)b))
103  {
104     WerrorS(nDivBy0);
105  }
106  else
107    fmpq_poly_div(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
108  return (number)res;
109}
110static number IntMod(number a, number b, const coeffs c)
111{
112  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
113  fmpq_poly_init(res);
114  fmpq_poly_rem(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
115  return (number)res;
116}
117static number Init (long i, const coeffs r)
118{
119  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
120  fmpq_poly_init(res);
121  fmpq_poly_set_si(res,i);
122  return (number)res;
123}
124static number InitMPZ (mpz_t i, const coeffs r)
125{
126  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
127  fmpq_poly_init(res);
128  fmpq_poly_set_mpz(res,i);
129  return (number)res;
130}
131static int Size (number n, const coeffs r)
132{
133  return fmpq_poly_degree((fmpq_poly_ptr)n);
134}
135static long Int (number &n, const coeffs r)
136{
137  if (fmpq_poly_degree((fmpq_poly_ptr)n)==0)
138  {
139    mpq_t m;
140    mpq_init(m);
141    fmpq_poly_get_coeff_mpq(m,(fmpq_poly_ptr)n,0);
142    mpz_t num,den;
143    mpz_init(num);
144    mpz_init(den);
145    mpq_get_num(num,m);
146    mpq_get_den(den,m);
147    long nl=mpz_get_si(num);
148    if (mpz_cmp_si(num,nl)!=0) nl=0;
149    long dl=mpz_get_si(den);
150    if ((dl!=1)||(mpz_cmp_si(den,dl)!=0)) nl=0;
151    mpz_clear(num);
152    mpz_clear(den);
153    mpq_clear(m);
154    return nl;
155  }
156  return 0;
157}
158static void MPZ(mpz_t result, number &n, const coeffs r)
159{
160  mpz_init(result);
161  if (fmpq_poly_degree((fmpq_poly_ptr)n)==0)
162  {
163    mpq_t m;
164    mpq_init(m);
165    fmpq_poly_get_coeff_mpq(m,(fmpq_poly_ptr)n,0);
166    mpz_t den;
167    mpz_init(den);
168    mpq_get_num(result,m);
169    mpq_get_den(den,m);
170    int dl=(int)mpz_get_si(den);
171    if ((dl!=1)||(mpz_cmp_si(den,(long)dl)!=0)) mpz_set_ui(result,0);
172    mpz_clear(den);
173    mpq_clear(m);
174  }
175}
176static number Neg(number a, const coeffs r)
177{
178  fmpq_poly_neg((fmpq_poly_ptr)a,(fmpq_poly_ptr)a);
179  return a;
180}
181static number Invers(number a, const coeffs r)
182{
183  if(fmpq_poly_is_zero((fmpq_poly_ptr)a))
184  {
185    WerrorS(nDivBy0);
186    return NULL;
187  }
188  if (fmpq_poly_degree((fmpq_poly_ptr)a)==0)
189  {
190    fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
191    fmpq_poly_init(res);
192    fmpq_poly_inv(res,(fmpq_poly_ptr)a);
193    return (number)res;
194  }
195  else
196  {
197    WerrorS("not invertable");
198    return NULL;
199  }
200}
201static number Copy(number a, const coeffs r)
202{
203 fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
204 fmpq_poly_init(res);
205 fmpq_poly_set(res,(fmpq_poly_ptr)a);
206 return (number)res;
207}
208//static number RePart(number a, const coeffs r)
209//{
210//}
211//static number ImPart(number a, const coeffs r)
212//{
213//}
214static BOOLEAN IsOne (number a, const coeffs r);
215static BOOLEAN IsZero (number a, const coeffs r);
216//static void WriteLong(number &a, const coeffs r)
217//{
218//}
219static void WriteShort(number a, const coeffs r)
220{
221  //fmpq_poly_print_pretty((fmpq_poly_ptr)a,r->pParameterNames[0]);
222  if (IsOne(a,r)) StringAppendS("1");
223  else if (IsZero(a,r)) StringAppendS("0");
224  else
225  {
226  StringAppendS("(");
227  mpq_t m;
228  mpq_init(m);
229  mpz_t num,den;
230  mpz_init(num);
231  mpz_init(den);
232  BOOLEAN need_plus=FALSE;
233  for(int i=fmpq_poly_length((fmpq_poly_ptr)a);i>=0;i--)
234  {
235    fmpq_poly_get_coeff_mpq(m,(fmpq_poly_ptr)a,i);
236    mpq_get_num(num,m);
237    mpq_get_den(den,m);
238    if (mpz_sgn1(num)!=0)
239    {
240      if (need_plus && (mpz_sgn1(num)>0))
241        StringAppendS("+");
242      need_plus=TRUE;
243      int l=mpz_sizeinbase(num,10);
244      l=si_max(l,(int)mpz_sizeinbase(den,10));
245      l+=2;
246      char *s=(char*)omAlloc(l);
247      char *z=mpz_get_str(s,10,num);
248      if ((i==0)
249      ||(mpz_cmp_si(num,1)!=0)
250      ||(mpz_cmp_si(den,1)!=0))
251      {
252        StringAppendS(z);
253        if (mpz_cmp_si(den,1)!=0)
254        {
255          StringAppendS("/");
256          z=mpz_get_str(s,10,den);
257          StringAppendS(z);
258        }
259        if (i!=0) StringAppendS("*");
260      }
261      if (i>1)
262        StringAppend("%s^%d",r->pParameterNames[0],i);
263      else if (i==1)
264        StringAppend("%s",r->pParameterNames[0]);
265    }
266  }
267  mpz_clear(den);
268  mpz_clear(num);
269  mpq_clear(m);
270  StringAppendS(")");
271  }
272}
273static const char* Read(const char * st, number * a, const coeffs r)
274{
275// we only read "monomials" (i.e. [-][digits][parameter]),
276// everythings else (+,*,^,()) is left to the singular interpreter
277  char *s=(char *)st;
278  *a=(number)omAlloc(sizeof(fmpq_poly_t));
279  fmpq_poly_init((fmpq_poly_ptr)(*a));
280  BOOLEAN neg=FALSE;
281  if (*s=='-') { neg=TRUE; s++;}
282  if (isdigit(*s))
283  {
284    mpz_t z;
285    mpz_init(z);
286    s=nlEatLong((char *)s, z);
287    fmpq_poly_set_mpz((fmpq_poly_ptr)(*a),z);
288    if (*s == '/')
289    {
290      s++;
291      s=nlEatLong((char *)s, z);
292      fmpq_poly_scalar_div_mpz((fmpq_poly_ptr)(*a),(fmpq_poly_ptr)(*a),z);
293    }
294    mpz_clear(z);
295  }
296  else if(strncmp(s,r->pParameterNames[0],strlen(r->pParameterNames[0]))==0)
297  {
298    fmpq_poly_set_coeff_si((fmpq_poly_ptr)(*a),1,1);
299    s+=strlen(r->pParameterNames[0]);
300    if(isdigit(*s))
301    {
302      int i=1;
303      s=nEati(s,&i,0);
304      if (i!=1)
305      {
306        fmpq_poly_set_coeff_si((fmpq_poly_ptr)(*a),1,0);
307        fmpq_poly_set_coeff_si((fmpq_poly_ptr)(*a),i,1);
308      }
309    }
310  }
311  if (neg)
312    fmpq_poly_neg((fmpq_poly_ptr)(*a),(fmpq_poly_ptr)(*a));
313  return s;
314}
315static void Normalize(number &a, const coeffs r)
316{
317  fmpq_poly_canonicalise((fmpq_poly_ptr)a);
318}
319static BOOLEAN Greater (number a, number b, const coeffs r)
320{
321  return (fmpq_poly_cmp((fmpq_poly_ptr)a,(fmpq_poly_ptr)b)>0);
322}
323static BOOLEAN Equal (number a, number b, const coeffs r)
324{
325  return (fmpq_poly_equal((fmpq_poly_ptr)a,(fmpq_poly_ptr)b));
326}
327static BOOLEAN IsZero (number a, const coeffs r)
328{
329  return fmpq_poly_is_zero((fmpq_poly_ptr)a);
330}
331static BOOLEAN IsOne (number a, const coeffs r)
332{
333  return fmpq_poly_is_one((fmpq_poly_ptr)a);
334}
335static BOOLEAN IsMOne (number k, const coeffs r)
336{
337  if (fmpq_poly_length((fmpq_poly_ptr)k)>0) return FALSE;
338  fmpq_poly_canonicalise((fmpq_poly_ptr)k);
339  mpq_t m;
340  mpq_init(m);
341  fmpq_poly_get_coeff_mpq(m,(fmpq_poly_ptr)k,0);
342  mpz_t num,den;
343  mpz_init(num);
344  mpq_get_num(num,m);
345  BOOLEAN result=TRUE;
346  if (mpz_cmp_si(num,(long)-1)!=0) result=FALSE;
347  else
348  {
349    mpz_init(den);
350    mpq_get_den(den,m);
351    int dl=(int)mpz_get_si(den);
352    if ((dl!=1)||(mpz_cmp_si(den,(long)dl)!=0)) result=FALSE;
353    mpz_clear(den);
354  }
355  mpz_clear(num);
356  mpq_clear(m);
357  return (result);
358}
359static BOOLEAN GreaterZero (number k, const coeffs r)
360{
361  // does it have a leading sign?
362  // no: 0 and 1 do not have, everything else is in (...)
363  return TRUE;
364}
365static void Power(number a, int i, number * result, const coeffs r)
366{
367  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
368  fmpq_poly_init(res);
369  *result=(number)res;
370  fmpq_poly_pow((fmpq_poly_ptr)(*result),(fmpq_poly_ptr)a,i);
371}
372static number GetDenom(number &n, const coeffs r)
373{
374 fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
375 fmpq_poly_init(res);
376 fmpz_ptr den=fmpq_poly_denref(res);
377 fmpq_poly_set_fmpz(res,den);
378 return (number)res;
379}
380static number GetNumerator(number &n, const coeffs r)
381{
382 fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
383 fmpq_poly_init(res);
384 fmpq_poly_set(res,(fmpq_poly_ptr)n);
385 fmpz_ptr den=fmpq_poly_denref(res);
386 fmpq_poly_scalar_mul_fmpz(res,res,den);
387 return (number)res;
388}
389static number Gcd(number a, number b, const coeffs r)
390{
391  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
392  fmpq_poly_init(res);
393  fmpq_poly_gcd(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
394  return (number)res;
395}
396static number ExtGcd(number a, number b, number *s, number *t,const coeffs r)
397{
398  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
399  fmpq_poly_init(res);
400  fmpq_poly_init((fmpq_poly_ptr)*s);
401  fmpq_poly_init((fmpq_poly_ptr)*t);
402  fmpq_poly_xgcd(res,(fmpq_poly_ptr)*s,(fmpq_poly_ptr)*t,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
403  return (number)res;
404}
405static number Lcm(number a, number b, const coeffs r)
406{
407  WerrorS("not yet: Lcm");
408}
409static void Delete(number * a, const coeffs r)
410{
411  if ((*a)!=NULL)
412  {
413    fmpq_poly_clear((fmpq_poly_ptr)*a);
414    omFree(*a);
415    *a=NULL;
416  }
417}
418static nMapFunc SetMap(const coeffs src, const coeffs dst)
419{
420  WerrorS("not yet: SetMap");
421  return NULL;
422}
423//static void InpMult(number &a, number b, const coeffs r)
424//{
425//}
426//static void InpAdd(number &a, number b, const coeffs r)
427//{
428//}
429static number Init_bigint(number i, const coeffs dummy, const coeffs dst)
430{
431  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
432  fmpq_poly_init(res);
433  if (SR_HDL(i) & SR_INT)
434  {
435    fmpq_poly_set_si(res,SR_TO_INT(i));
436  }
437  else
438    fmpq_poly_set_mpz(res,i->z);
439  return (number)res;
440}
441static number Farey(number p, number n, const coeffs)
442{
443  WerrorS("not yet: Farey");
444}
445static number ChineseRemainder(number *x, number *q,int rl, BOOLEAN sym,CFArray &inv_cache,const coeffs)
446{
447  WerrorS("not yet: ChineseRemainder");
448}
449static int ParDeg(number x,const coeffs r)
450{
451  return fmpq_poly_degree((fmpq_poly_ptr)x);
452}
453static number Parameter(const int i, const coeffs r)
454{
455  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
456  fmpq_poly_init(res);
457  fmpq_poly_set_coeff_si(res,1,1);
458  return (number)res;
459}
460static void WriteFd(number a, const ssiInfo *d, const coeffs)
461{
462  // format: len a_len(num den) .. a_0
463  fmpq_poly_ptr aa=(fmpq_poly_ptr)a;
464  int l=fmpq_poly_length(aa);
465  fprintf(d->f_write,"%d ",l);
466  mpq_t m;
467  mpq_init(m);
468  mpz_t num,den;
469  mpz_init(num);
470  mpz_init(den);
471  for(int i=l; i>=0; i--)
472  {
473    fmpq_poly_get_coeff_mpq(m,(fmpq_poly_ptr)a,i);
474    mpq_get_num(num,m);
475    mpq_get_den(den,m);
476    mpz_out_str (d->f_write,SSI_BASE, num);
477    fputc(' ',d->f_write);
478    mpz_out_str (d->f_write,SSI_BASE, den);
479    fputc(' ',d->f_write);
480  }
481  mpz_clear(den);
482  mpz_clear(num);
483  mpq_clear(m);
484}
485static number ReadFd(const ssiInfo *d, const coeffs)
486{
487  // format: len a_len .. a_0
488  fmpq_poly_ptr aa=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
489  fmpq_poly_init(aa);
490  int l=s_readint(d->f_read);
491  mpz_t nm;
492  mpz_init(nm);
493  mpq_t m;
494  mpq_init(m);
495  for (int i=l;i>=0;i--)
496  {
497
498    s_readmpz_base (d->f_read,nm, SSI_BASE);
499    mpq_set_num(m,nm);
500    s_readmpz_base (d->f_read,nm, SSI_BASE);
501    mpq_set_den(m,nm);
502    fmpq_poly_set_coeff_mpq(aa,i,m);
503  }
504  mpz_clear(nm);
505  mpq_clear(m);
506  return (number)aa;
507}
508// cfClearContent
509// cfClearDenominators
510static number ConvFactoryNSingN( const CanonicalForm n, const coeffs r)
511{
512  WerrorS("not yet: ConvFactoryNSingN");
513}
514static CanonicalForm ConvSingNFactoryN( number n, BOOLEAN setChar, const coeffs r )
515{
516  WerrorS("not yet: ConvSingNFactoryN");
517}
518char * CoeffName(const coeffs r)
519{
520  static char CoeffName_flint_Q[20];
521  sprintf(CoeffName_flint_Q,"flint:QQ[%s]",r->pParameterNames[0]);
522  return (char*)CoeffName_flint_Q;
523
524}
525static char* CoeffString(const coeffs r)
526{
527  char *buf=(char*)omAlloc(12+strlen(r->pParameterNames[0]));
528  sprintf(buf,"flintQ(\"%s\")",r->pParameterNames[0]);
529  return buf;
530}
531static void CoeffWrite(const coeffs r, BOOLEAN details)
532{
533  PrintS(CoeffName(r));
534}
535coeffs flintQInitCfByName(char *s,n_coeffType n)
536{
537  const char start[]="flint:QQ[";
538  const int start_len=strlen(start);
539  if (strncmp(s,start,start_len)==0)
540  {
541    s+=start_len;
542    char st[10];
543    int l=sscanf(s,"%s",st);
544    if (l==1)
545    {
546      while (st[strlen(st)-1]==']') st[strlen(st)-1]='\0';
547      return nInitChar(n,(void*)st);
548    }
549  }
550  return NULL;
551}
552#ifdef LDEBUG
553static BOOLEAN DBTest(number a, const char *f, const int l, const coeffs r)
554{
555  return TRUE;
556}
557#endif
558static void KillChar(coeffs cf)
559{
560  omFree(cf->pParameterNames[0]);
561  omFreeSize(cf->pParameterNames,sizeof(char*));
562}
563BOOLEAN flintQ_InitChar(coeffs cf, void * infoStruct)
564{
565  char *pp=(char*)infoStruct;
566  cf->cfCoeffString  = CoeffString;
567  cf->cfCoeffName    = CoeffName;
568  cf->cfCoeffWrite   = CoeffWrite;
569  cf->nCoeffIsEqual  = CoeffIsEqual;
570  cf->cfKillChar     = KillChar;
571  cf->cfSetChar      = SetChar;
572  cf->ch=0; //char 0
573  cf->cfMult         = Mult;
574  cf->cfSub          = Sub;
575  cf->cfAdd          = Add;
576  cf->cfDiv          = Div;
577  cf->cfExactDiv     = ExactDiv; // ???
578  cf->cfInit         =Init;
579  cf->cfInitMPZ      =InitMPZ;
580  cf->cfSize         = Size;
581  cf->cfInt          = Int;
582  cf->cfMPZ          = MPZ;
583  cf->cfInpNeg       = Neg;
584  cf->cfInvers       = Invers;
585  cf->cfCopy         = Copy;
586  cf->cfRePart       = Copy;
587  // default: cf->cfImPart       = ndReturn0;
588  cf->cfWriteLong    = WriteShort; //WriteLong;
589  cf->cfWriteShort = WriteShort;
590  cf->cfRead         = Read;
591  cf->cfNormalize    = Normalize;
592
593  //cf->cfDivComp=
594  //cf->cfIsUnit=
595  //cf->cfGetUnit=
596  //cf->cfDivBy=
597
598  cf->cfGreater=Greater;
599  cf->cfEqual  =Equal;
600  cf->cfIsZero =IsZero;
601  cf->cfIsOne  =IsOne;
602  cf->cfIsMOne =IsMOne;
603  cf->cfGreaterZero=GreaterZero;
604
605  cf->cfPower        = Power;
606  cf->cfGetDenom     = GetDenom;
607  cf->cfGetNumerator = GetNumerator;
608  cf->cfGcd          = Gcd;
609  cf->cfExtGcd         = ExtGcd;
610  cf->cfLcm          = Lcm;
611  cf->cfDelete       = Delete;
612  cf->cfSetMap       = SetMap;
613  // default: cf->cfInpMult
614  // default: cf->cfInpAdd
615  cf->cfFarey        =Farey;
616  cf->cfChineseRemainder=ChineseRemainder;
617  cf->cfParDeg = ParDeg;
618  cf->cfParameter = Parameter;
619  //  cf->cfClearContent = ClearContent;
620  //  cf->cfClearDenominators = ClearDenominators;
621  cf->convFactoryNSingN=ConvFactoryNSingN;
622  cf->convSingNFactoryN=ConvSingNFactoryN;
623  cf->cfWriteFd  = WriteFd;
624  cf->cfReadFd = ReadFd;
625#ifdef LDEBUG
626  cf->cfDBTest       = DBTest;
627#endif
628
629  cf->iNumberOfParameters = 1;
630  char **pn=(char**)omAlloc0(sizeof(char*));
631  pn[0]=omStrDup(pp);
632  cf->pParameterNames = (const char **)pn;
633  cf->has_simple_Inverse= FALSE;
634  cf->has_simple_Alloc= FALSE;
635  cf->is_field=FALSE;
636
637  return FALSE;
638}
639#endif
Note: See TracBrowser for help on using the repository browser.