int main( ) { FPGroup G; cout << "Enter nilpotentcy class first then group "; int NilpotentcyClass; cin >> NilpotentcyClass; Chars errMsg = cin >> G; if (errMsg.length()>0) return 1; NilpotentGroup ng(G.namesOfGenerators(), NilpotentcyClass,makeVectorOf(G.getRelators())); ng.initialize(); VectorOf<Word> vw; Word w; for (int i=1;true;i++){ cout << endl << "Enter the "<<i<<" generator of subgroup"<< endl; cout << "Empty word to finish: "; w = G.readWord(cin,errMsg); if (w.length()==0) break; if (errMsg.length()>0) return 1; vw.append(w); } SGOfNilpotentGroup sg(ng,vw); sg.initBasis(); sg.printBasis(cout); cout << "The Hirsch number :" << sg.theHirschNumber() << endl; cout << "Index in parent group :" << sg.index() << endl; cout << "Is Trivial :" << sg.isTrivial() << endl; cout << "Is Central :" << sg.isCentral() << endl; cout << "Is normal :" << sg.isNormal() << endl; cout << "Is abelian :" << sg.isAbelian() << endl; cout << "Subgroup class :" << sg.subgroupClass() << endl; cout << "Generators of normal closure :" << endl; vw = sg.normalClosureGens(); for (int i=0;i<vw.length();i++){ G.printWord(cout,vw[i]); cout << endl; } PresentationForSNG sgp = sg.makePresentation(); cout << "Presentation of subgroup :" << endl; sgp.print(cout); cout << endl << "Enter the word :"; errMsg = ""; w = G.readWord(cin,errMsg); if (errMsg.length()>0){ cout << errMsg; return 1; } cout << endl << "Does subgroup contain the word :" << sg.contains(w) << endl; PolyWord result; if (sg.decompose(ng.decompose(w),result)) cout << "Decomposition in sg basis :" << sg.asDecomposition(result); else cout << "Subgroup does not contain this word"; }
VectorOf<Chars> PresentationParser::parseGeneratorList( Chars& errMesg ) { VectorOf<Chars> result; if ( curToken == INIT ) getToken(); while ( curToken == GENERATOR ) { Chars name(tokenName); // Check for duplication and presence of inverses. if ( result.indexOf(name) >= 0 ) { parseError("Duplicate generator"); errMesg = parseErrorMessage; return result; } else { invertName(tokenName); if ( result.indexOf(Chars(tokenName)) >= 0 ) { parseError("Duplicate generator: formal inverse"); errMesg = parseErrorMessage; return result; } } result.append(name); // Ok, it's inefficient, but time is $$ getToken(); if ( curToken == COMMA ) { getToken(); if ( curToken == DOT ) { if (!getGeneratorRange(name,result,errMesg)) return result; } else { if ( curToken != GENERATOR ) { parseError("Expected a generator here"); errMesg = parseErrorMessage; return result; } } } } return result; }
//@njz:default value removed. defined in .h file //void AbelianEquationsSolver::findSolutions( File& file , bool out = true ) void AbelianEquationsSolver::findSolutions( File& file , bool out) // { haveSol = 0; if( !A.haveCyclicDecomposition() ) A.computeCyclicDecomposition(); if( !A.havePrimaryDecomposition() ) A.findPrimaryBasis(); if( !rawA.haveCyclicDecomposition() ) rawA.computeCyclicDecomposition(); if( !rawA.havePrimaryDecomposition() ) rawA.findPrimaryBasis(); makeSystem(); if( out ) { if( system.length() > 1 ) file << "The system of equations: " << endl << endl; else file << "The equation: " << endl << endl; printRawSystem( file ); file << endl << "can be transformed to the one: " << endl << endl; printSystem( file ); if( system.length() > 1 ) file << endl << "Finding solutions of this system ..." << endl << endl; else file << endl << "Finding solutions of this equation ..." << endl << endl; } //@njz // int **matrix = new (int*)[ system.length() ]; int **matrix = new int*[ system.length() ]; // int i,j,k,i1,j1; for( i = 0 ; i < system.length() ; i++ ) { matrix[i] = new int[ numberOfVariables ]; for( j = 0 ; j < numberOfVariables ; j++ ) { Integer u = (AbelianWord( numberOfVariables , system[i] ))[j]; matrix[i][j] = u.as_long(); } } VectorOf< VectorOf<int> > transform; VectorOf<int> trans(3); // diagonalization of the matrix sysRank = 0; for( i = 0 ; ( i < numberOfVariables && i < system.length() ) ; i++ ) { bool flag = false; for( j = i ; j < system.length() ; j++ ) { for( k = i ; k < numberOfVariables ; k++ ) if( matrix[j][k] ) { flag = true; break; } if( flag ) break; } if( k == numberOfVariables && j == system.length() ) { if( sysRank ) break; int q; for( q = 0 ; q < b.length() ; q++ ) if( !A.isTrivial( Word( b[q] ) ) ) { haveSol = -1; if( out ) if( system.length() > 1 ) file << "while computing the canonical form of the system it was found that this system has no solutions." << endl; else file << "while computing the canonical form of the equation it was found that this equation has no solutions." << endl; return; } haveSol = 0; if( out ) if( system.length() > 1 ) file << "while computing the canonical form of the system it was found that this system has all group as a set of solutions." << endl; else file << "while computing the canonical form of the equation it was found that this equation has all group as a set of solutions." << endl; return; } int *tmp = matrix[i]; matrix[i] = matrix[j]; matrix[j] = tmp; Word r = b[i]; b[i] = b[j]; b[j] = r; for( j = 0 ; j < system.length() ; j++ ) { int t = matrix[j][i]; matrix[j][i] = matrix[j][k]; matrix[j][k] = t; } if( i != k ) { trans[0] = i; trans[1] = k; trans[2] = 0; transform.append( trans ); } while( true ) { bool check; bool flag; int z; bool done = false; int count = i + 1; while( !done ) { for( j = count ; j < system.length() ; j++ ) if( matrix[j][i] && abs(matrix[i][i]) != abs(matrix[j][i]) ) break; if( j == system.length() ) break; count = j + 1; flag = false; while( !flag ) { if( abs(matrix[i][i]) > abs(matrix[j][i]) ) { z = matrix[i][i] / matrix[j][i]; for( k = i ; k < numberOfVariables ; k++ ) matrix[i][k] = matrix[i][k] - matrix[j][k] * z; b[i] = b[i] * A.getFPGroup().raiseToPower(b[j],-z); } else { z = matrix[j][i] / matrix[i][i]; for( k = i ; k < numberOfVariables ; k++ ) matrix[j][k] = matrix[j][k] - matrix[i][k] * z; b[j] = b[j] * A.getFPGroup().raiseToPower(b[i],-z); } if( !matrix[i][i] || !matrix[j][i] ) { if( matrix[i][i] == 0 ) { tmp = matrix[i]; matrix[i] = matrix[j]; matrix[j] = tmp; r = b[i]; b[i] = b[j]; b[j] = r; } flag = true; } } if( count == system.length() ) done = true; } check = true; for( j = i + 1 ; j < numberOfVariables ; j++ ) if( matrix[i][j] % matrix[i][i] ) { check = false; break; } if( check ) break; done = false; count = i + 1; while( !done ) { for( j = count ; j < numberOfVariables ; j++ ) if( matrix[i][j] && abs(matrix[i][i]) != abs(matrix[i][j]) ) break; if( j == numberOfVariables ) break; count = j + 1; flag = false; while( !flag ) { if( abs(matrix[i][i]) > abs(matrix[i][j]) ) { z = matrix[i][i] / matrix[i][j]; for( k = i ; k < system.length() ; k++ ) matrix[k][i] = matrix[k][i] - matrix[k][j] * z; trans[0] = j; trans[1] = i; trans[2] = -z; transform.append( trans ); } else { z = matrix[i][j] / matrix[i][i]; for( k = i ; k < system.length() ; k++ ) matrix[k][j] = matrix[k][j] - matrix[k][i] * z; trans[0] = i; trans[1] = j; trans[2] = -z; transform.append( trans ); } if( !matrix[i][i] || !matrix[i][j] ) { if( matrix[i][i] == 0 ) { for( k = i ; k < system.length() ; k++ ) { int a = matrix[k][i]; matrix[k][i] = matrix[k][j]; matrix[k][j] = a; } if( i != j ) { trans[0] = i; trans[1] = j; trans[2] = 0; transform.append( trans ); } } flag = true; } } if( count == numberOfVariables ) done = true; } check = true; for( j = i + 1 ; j < system.length() ; j++ ) if( matrix[j][i] % matrix[i][i] ) { check = false; break; } if( check ) break; } for( j = i + 1 ; j < system.length() ; j++ ) if( matrix[j][i] ) { int z = matrix[j][i] / matrix[i][i]; for( k = i ; k < numberOfVariables ; k++ ) matrix[j][k] = matrix[j][k] - matrix[i][k] * z; b[j] = b[j] * A.getFPGroup().raiseToPower(b[i],-z); } for( j = i + 1 ; j < numberOfVariables ; j++ ) if( matrix[i][j] ) { int z = matrix[i][j] / matrix[i][i]; for( k = i ; k < system.length() ; k++ ) matrix[k][j] = matrix[k][j] - matrix[k][i] * z; trans[0] = i; trans[1] = j; trans[2] = -z; transform.append( trans ); } sysRank++; } for( i = sysRank ; i < system.length() ; i++ ) { if( !A.isTrivial( Word( b[i] ) ) ) { haveSol = -1; if( out ) if( system.length() > 1 ) file << "while computing the canonical form of the system it was found that this system has no solutions." << endl; else file << "while computing the canonical form of the equation it was found that this equation has no solutions." << endl; return; } } // finding solutions and output in file if( out ) { file << "The canonical form: "; file << endl << endl; } for( int p = 0 ; p < sysRank ; p++ ) { if( out ) { file << "x" << p + 1; if( matrix[p][p] != 1 ) file << "^" << matrix[p][p]; file << " = "; } AbelianWord w = A.oldInAbelianForm( b[p] ); w = A.oldToNewGens( w ); w = A.newToOldGens( w ); b[p] = w.getWord().freelyReduce(); if( out ) { A.getFPGroup().printWord( file , b[p] ); file << endl; } } VectorOf<int> xNums( numberOfVariables ); for( i = 0 ; i < sysRank ; i++ ) if( root( b[i] , matrix[i][i] ) ) { x[i] = b[i]; xNums[i] = i; if( !A.isFree() ) { VectorOf<int> tmp(2); tmp[0] = ( matrix[i][i] > 0 ) ? matrix[i][i] : -matrix[i][i]; tmp[1] = 1; torsion[i].append( tmp ); } } else { haveSol = -1; if( out ) { if( system.length() > 1 ) file << endl << "The system is unsolvable because there are no solutions for: " << endl << endl; else file << endl << "The equation is unsolvable because there are no solutions for: " << endl << endl; file << "x" << i + 1; if( matrix[i][i] != 1 ) file << "^" << matrix[i][i]; file << " = "; A.getFPGroup().printWord( file , b[i].freelyReduce() ); } return; } for( j = sysRank ; j < numberOfVariables ; j++ ) { x[j] = Word(); xNums[j] = j; VectorOf<int> tmp(2); tmp[0] = j - sysRank + 1; tmp[1] = 1; params[j].append( tmp ); } for( i = transform.length() - 1 ; i >= 0 ; i-- ) { trans = transform[i]; if( !trans[2] ) { int ind1 = xNums.indexOf( trans[0] ); int ind2 = xNums.indexOf( trans[1] ); xNums[ind1] = trans[1]; xNums[ind2] = trans[0]; } else { int ind1 = xNums.indexOf( trans[0] ); int ind2 = xNums.indexOf( trans[1] ); x[ind1] *= A.getFPGroup().raiseToPower( x[ind2] , trans[2] ); int len = torsion[ind1].length(); for( j = 0 ; j < torsion[ind2].length() ; j++ ) { bool f = false; for( k = 0 ; k < len ; k++ ) if( torsion[ind1][k][0] == torsion[ind2][j][0] ) { f = true; break; } if( f ) torsion[ind1][k][1] += torsion[ind2][j][1] * trans[2]; else { VectorOf<int> tmp = torsion[ind2][j]; tmp[1] *= trans[2]; torsion[ind1].append( tmp ); } } len = params[ind1].length(); for( j = 0 ; j < params[ind2].length() ; j++ ) { bool f = false; for( k = 0 ; k < len ; k++ ) if( params[ind1][k][0] == params[ind2][j][0] ) { f = true; break; } if( f ) params[ind1][k][1] += params[ind2][j][1] * trans[2]; else { VectorOf<int> tmp = params[ind2][j]; tmp[1] *= trans[2]; params[ind1].append( tmp ); } } } } for( i = 0 ; i < x.length() ; i++ ) { AbelianWord w = A.oldInAbelianForm( x[i] ); w = A.oldToNewGens( w ); w = A.newToOldGens( w ); x[i] = w.getWord(); } // output in file if( out ) { file << endl << "The set of solutions can be presented as follows: " << endl << endl; FPGroup G = rawA.getFPGroup(); FPGroup G1 = A.getFPGroup(); for( i = 0 ; i < numberOfVariables ; i++ ) { int n = xNums.indexOf( i ); bool flag = false; G.printWord( file , Generator( i + 1 ) ); file << " -> "; if( x[n].length() ) { G1.printWord( file , x[n].freelyReduce() ); flag = true; } for( j = 0 ; j < torsion[n].length() ; j++ ) { VectorOf<int> tmp = torsion[n][j]; int z = tmp[1] % tmp[0]; if( z ) if( tmp[1] > 0 ) { if( flag ) file << " + "; if( tmp[1] != 1 ) file << tmp[1] << " p( " << tmp[0] << " )"; else file << "p( " << tmp[0] << " )"; flag = true; } else { file << " - "; if( tmp[1] != -1 ) file << -tmp[1] << " p( " << tmp[0] << " )"; else file << "p( " << tmp[0] << " )"; flag = true; } } for( j = 0 ; j < params[n].length() ; j++ ) { VectorOf<int> tmp = params[n][j]; if( tmp[1] ) if( tmp[1] > 0 ) { if( flag ) file << " + "; if( tmp[1] != 1 ) file << tmp[1] << " t" << tmp[0]; else file << "t" << tmp[0]; flag = true; } else { file << " - "; if( tmp[1] != -1 ) file << -tmp[1] << " t" << tmp[0]; else file << "t" << tmp[0]; flag = true; } } if( !flag ) file << "1 "; if( i != numberOfVariables ) file << ","; file << endl; } file << endl << "where p( n ) is any element of n-heigth and t_i - any element of the group." << endl; } VectorOf< VectorOf< VectorOf<int> > > t( numberOfVariables ); VectorOf< VectorOf< VectorOf<int> > > p( numberOfVariables ); VectorOf<Word> x1( numberOfVariables ); for( i = 0 ; i < numberOfVariables ; i++ ) { int n = xNums.indexOf( i ); x1[i] = x[n]; t[i] = torsion[n]; p[i] = params[n]; } torsion = t; params = p; x = x1; for( i = 0 ; i < system.length() ; i++ ) delete [] matrix[i]; delete [] matrix; }
main() { FPGroup G; VectorOf<int> order; cin >> G; char ch; cin >> ch; if (ch != '[') { cerr << "Unexpected input, aborted"<<endl; exit(1);} do { int i; cin >> i; order.append(i); cin>> ch; if (ch==']') break; else if (ch!=','){ cerr << "Unexpected input, aborted"<<endl; exit(1);} } while (ch==','); WordOrder word_order("ShortLex",order); KBmagPackage kbmag(G.namesOfGenerators(),G.getRelators(),word_order,20); if ( !kbmag.sanityCheck() ) { error("kbmag failed sanity check.\n"); } if (kbmag.autgroup()==yes){ cout << "Group "<< G << " is proved shortlex automatic"<<endl; GroupDFSA WA = kbmag.wordAcceptor(); WA.setName("Word_acceptor"); WA.printOn(); GenMult GM = kbmag.generalMultiplier(); GM.setName("General_multiplier"); GM.printOn(); DiffMachine D1 = kbmag.differenceMachine(1); D1.setName("1stDiffMachine"); D1.printOn(); DiffMachine D2 = kbmag.differenceMachine(2); D2.setName("2ndDiffMachine"); D2.printOn(); } else cout << "Group "<< G << " is not proved shortlex automatic"<<endl; cout << endl; FPGroup G2; cin >> G2; KBmagPackage kbmag2(G2.namesOfGenerators(),G2.getRelators()); if ( !kbmag2.sanityCheck() ) { error("kbmag2 failed sanity check.\n"); } if (kbmag2.kbprog()==yes && kbmag2.gpmakefsa()==yes && kbmag2.gpaxioms()==yes){ cout << "Group "<< G2 << " is proved shortlex automatic"<<endl; GroupDFSA WA = kbmag2.wordAcceptor(); WA.setName("Word_acceptor"); WA.printOn(); GenMult GM = kbmag2.generalMultiplier(); GM.setName("General_multiplier"); GM.printOn(); DiffMachine D1 = kbmag2.differenceMachine(1); D1.setName("1stDiffMachine"); D1.printOn(); DiffMachine D2 = kbmag2.differenceMachine(2); D2.setName("2ndDiffMachine"); D2.printOn(); } else cout << "Group "<< G2 << " is not proved shortlex automatic"<<endl; cout << endl; FPGroup G3; cin >> G3; KBmagPackage kbmag3(G3.namesOfGenerators(),G3.getRelators()); if ( !kbmag3.sanityCheck() ) { error("kbmag3 failed sanity check.\n"); } if (kbmag3.kbprog()>0){ Bool abort=NO; int loop=0; do { loop++; cout << "Trying to built automata."<< endl; if (loop>1) cout << "Pass no. " << loop <<" though loop."<< endl; if (kbmag3.gpwa()!=yes || kbmag3.gpgenmult()!=yes) abort=YES; if (abort){ cout << "Failed, giving up!"<< endl; break;} GroupDFSA WA = kbmag3.wordAcceptor(); WA.setName("Word_acceptor"); WA.printOn(); GenMult GM = kbmag3.generalMultiplier(); GM.setName("GeneralMultiplier"); GM.printOn(); DiffMachine D1 = kbmag3.differenceMachine(1); D1.setName("1stDiffMachine"); D1.printOn(); DiffMachineRep D2 = kbmag3.differenceMachineRep(2); D2.setName("2ndDiffMachine"); D2.printOn(); } while (kbmag3.gpcheckmult()==no); if (abort==NO && kbmag3.gpaxioms()==yes) cout << "Group "<< G3 << " is proved shortlex automatic"<<endl; else cout << "Group "<< G3 << " is not proved shortlex automatic"<<endl; } GroupDFSARep WA2 = kbmag3.wordAcceptorRep(); DiffMachineRep D3 = kbmag3.differenceMachineRep(2); KBmagPackage kbmag4(G3.namesOfGenerators(),G3.getRelators()); kbmag4.setWordAcceptor(WA2); kbmag4.setDifferenceMachine(D3,2); kbmag4.gpgenmult(); DFSA F; F.readFrom(); kbmag4.minimize(F); F.printOn(); GroupDFSARep F2; F2.readFrom(); kbmag4.minimize(F2); F2.printOn(); GroupDFSA M1; M1.readFrom(); GroupDFSA M2; M2.readFrom(); GroupDFSA M3; kbmag4.gpcomp(M1,M2,M3); M3.printOn(); GroupDFSARep N1; N1.readFrom(); GroupDFSARep N2; N2.readFrom(); GroupDFSARep N3; kbmag4.gpcomp(N1,N2,N3); N3.printOn(); }