예제 #1
0
// adds w to the set
// returns true iff the set was changed
bool MalcevSet::addWord( const PolyWord& pw ) {

  bool wasChanged = false;
  PolyWord remainder = collect(pw);

  while( ! remainder.isEmpty() ) {
    Generator key = leader(remainder);

    // if there is no word with the same leader, include the remainder to the set

    if( ! theSet.bound(key) ) {
      theSet.bind( key, remainder );
      isBasis = false;
      isNormal = dontknow;
      return true;
    }

    // reduce the remainder

    PolyWord currentWord = theSet.valueOf(key);

    if( reduceWords( currentWord, remainder) ) {
      theSet.bind( key, currentWord );
      isBasis = false;
      isNormal = dontknow;
      wasChanged = true;
    }
  }
  return wasChanged;
}
예제 #2
0
bool MalcevSet::isNormalClosure() const {

  if( isNormal != dontknow ) return isNormal;

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

  const BasicCommutators& BC = theCollector.commutators();
  MalcevSet* This = (MalcevSet *)this;    // to break physical constness

  //the subgroup is normal iff any w^x is in the set

  for(int i = 1; i < BC.theFirstOfWeight(BC.nilpotencyClass() ); i++) {

    if( ! theSet.bound( Generator(i) ) ) continue;
    PolyWord W = theSet.valueOf( Generator(i) );
    
    for(int j = 1; j <= BC.numberOfGenerators(); j++) {

      PolyWord conj = collect( Letter(j, -1) * W * Letter(j, 1) );

      checkMembership(conj);

      if(! conj.isEmpty() ) {
	This->isNormal = no;
	return false;
      }
    }
  }
  This->isNormal = yes;
  return true;
}
예제 #3
0
void MalcevSet::checkMembership(PolyWord& remainder) const {

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

    // The rest can be reduced. Do it.
    reduceWords( curWord, remainder );
  }
}
예제 #4
0
bool MalcevSet::reduceWords(PolyWord& pw1, PolyWord& pw2) const {

  if(pw1.isEmpty() || pw2.isEmpty())
    error("MalcevSet::reduceWords: empty argument");

  bool firstChanged = false;

  int power1 = absPower(pw1);
  int power2 = absPower(pw2);

  // make both PolyWords to be of distinct signs

  if( sign(pw1) ^ sign(pw2) == 0)  // if they have the same sign
    pw2 = pw2.inverse();

  // in fact, this is Euclid algorithm for finding GCD
    
  do {

    if( power1 > power2 ) {
      // swapping two words
      PolyWord tmp = pw1;
      pw1 = pw2;
      pw2 = tmp;
      int t = power1;
      power1 = power2;
      power2 = t;	
      firstChanged = true;
    }      

    power2 -= power1;
    pw2 = theCollector.multiply(pw1, pw2);
 
  } while(power2 != 0);

  return firstChanged;
}  
예제 #5
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;
}
예제 #6
0
bool MalcevSet::contains(const Word& w) const {
  PolyWord pw = theCollector.collect(w);
  checkMembership(pw);
  return pw.isEmpty();
}