Exemplo n.º 1
0
bool PImport::GetValue(PolyWord *result)
{
    int ch = getc(f);
    if (ch == '@')
    {
        /* Address of an object. */
        POLYUNSIGNED obj;
        fscanf(f, "%" POLYUFMT, &obj);
        ASSERT(obj < nObjects);
        *result = objMap[obj];
    }
    else if (ch == '$')
    {
        /* Code address. */
        POLYUNSIGNED obj, offset;
        fscanf(f, "%" POLYUFMT "+%" POLYUFMT, &obj, &offset);
        ASSERT(obj < nObjects);
        PolyObject *q = objMap[obj];
        ASSERT(q->IsCodeObject());
        *result = PolyWord::FromCodePtr((PolyWord(q)).AsCodePtr() + offset); /* The offset is in bytes. */
    }
    else if ((ch >= '0' && ch <= '9') || ch == '-')
    {
        /* Tagged integer. */
        POLYSIGNED j;
        ungetc(ch, f);
        fscanf(f, "%" POLYSFMT, &j);
        /* The assertion may be false if we are porting to a machine
           with a shorter tagged representation. */
        ASSERT(j >= -MAXTAGGED-1 && j <= MAXTAGGED);
        *result = TAGGED(j);
    }
    else if (ch == 'I')
    {
        /* IO entry number. */
        POLYUNSIGNED j;
        fscanf(f, "%" POLYUFMT, &j);
        ASSERT(j < POLY_SYS_vecsize);
        *result = (PolyObject*)&gMem.ioSpace->bottom[j * IO_SPACING];
    }
    else if (ch == 'J')
    {
        /* IO entry number with offset. */
        POLYUNSIGNED j, offset;
        fscanf(f, "%" POLYUFMT "+%" POLYUFMT, &j, &offset);
        ASSERT(j < POLY_SYS_vecsize);
        PolyWord base = (PolyObject*)&gMem.ioSpace->bottom[j * IO_SPACING];
        *result = PolyWord::FromCodePtr(base.AsCodePtr() + offset);
    }
    else
    {
        fprintf(stderr, "Unexpected character in stream");
        return false;
    }
    return true;
}
Exemplo n.º 2
0
bool MalcevSet::decomposeWord(const PolyWord& w, PolyWord& decomp) const {

  if( ! isBasis )
    error("Attempt to use MalcevSet::decomposeWord before the set is full.");

  PolyWord remainder = theCollector.collect(w);
  decomp = PolyWord();

  // try to decompose the remainder

  while( ! remainder.isEmpty() && theSet.bound( leader(remainder) ) ) {
    PolyWord divisor = theSet.valueOf( leader(remainder) );
    if( absPower(remainder) % absPower(divisor) != 0 ) 
      break;

    // The remainder can be reduced. Do it.
    int divPower = power(remainder) / power(divisor);
    decomp.append( Letter( leader(remainder), divPower ) );

    if( divPower < 0 ) {
      divPower = - divPower;
    }
    else {
      divisor = theCollector.inverse(divisor);
    }

    for(int i = 0; i < divPower; i++) {
      remainder = theCollector.multiply(divisor, remainder);
    }

  }

  // if the remainder cannot be decomposed

  if( ! remainder.isEmpty() ) {
    decomp = PolyWord();
    return false;
  }
  
  // if the remainder initially was empty

  if( decomp.isEmpty() ) return true;

  // initially decomp is a series of letters (gen, power),
  // where gen is a leader of decomposition component and
  // power is its power

  // now translate decomp to Malcev basis terms: replace
  // gen with index of basis word having leader gen

  int curElement = 0;   // index of current basis element

  PolyWordIterator iter(decomp);
  iter.startFromLeft();

  for( int c = 1; c <= theCollector.commutators().theHirschNumber(); c++ ) {
    Generator theLeader(c);
    if( ! theSet.bound(theLeader) ) continue;
    ++curElement;

    if( iter.thisLetter().gen == theLeader ) {
      iter.thisLetter().gen = Generator(curElement);
      iter.stepRight();
      if( iter.done() ) break;
    }
  }
  return true;
}