
/*: Count number of bits in a number */
CountBits(value) :=
[
  Local(nbits);
  nbits:=0;
  Check(value>=0,"Value should be positive integer");
  While(value != 0)
  [
    nbits++;
    value := value >> 1;
  ];
  If(IsZero(nbits),nbits:=1);
  nbits;
];


/* this uses code borrowed from Bernhard Oemer, borrowed from OpenQuBit
 * project.
 */
/* Returns whether n is a prime */
IsPrime(n) :=
[
  Local(result);
  result:=True;
  If (n<=1,result:=False);
  Local(i,m);
  m:=MathFloor(MathSqrt(n));
  For(i:=2,i <= m And result = True,i++)
      If(Mod(n,i) = 0, result:=False);
  result;
];


/*code by Bernhard Oemer, borrowed from OpenQuBit
 * project.
 */
/* Returns whether n is a prime^m. */
IsPrimePower(n) :=
[
  Local(i,f,m,result);
  i:=2;
  f:=0;
  m:=MathFloor(MathSqrt(n));
  result:=False;
   While( (i<=m) And f=0)
      [
       If(((Mod(n,i))=0), f:=i);
       i++;
      ];

  m:=MathFloor(0.000001+N((CountBits(n)-1)/(CountBits(f)-1)));
  For(i:=2, (i<=m) And (result = False), i++)
      [
        If(f^i = n, result:=True);
      ];
  result;
];

/* factorize n into primes. */
RuleBase("Factors",{n});
Rule("Factors",1,0,IsInteger(n))
[
  Local(result,m);
  result:={};
  If(n<0,
     [
     result:={-1};
     n:= -n;
     ]
    );
  m:=MathFloor(MathSqrt(n));
  i:=2;
  While( (i<=m) And (n!=1) )
  [
    If(((Mod(n,i))=0),
	[
        DestructiveAppend(result,i);
        n:=Div(n,i);
        i--;
        ]
       );
    i++;
  ];
  If(n!=1,DestructiveAppend(result,n));

  result;
];


