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; }
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; }