2016-11-19 10:16:45 +00:00
# include "thickenings.h"
2016-11-20 22:19:08 +00:00
# include "weyl.h"
2016-07-26 08:09:34 +00:00
# include "queue.h"
2016-11-19 10:16:45 +00:00
# include <strings.h>
# include <stdio.h>
2016-11-23 19:58:05 +00:00
char stringbuffer [ 100 ] ;
char stringbuffer2 [ 100 ] ;
typedef struct {
node_t * graph ;
int cosets ;
int rank ;
int order ;
int hyperplanes ;
semisimple_type_t type ;
unsigned long left_invariance ;
unsigned long right_invariance ;
const char * alphabet ;
int * buffer ;
2016-12-02 09:31:31 +00:00
int level ;
2016-11-23 19:58:05 +00:00
} info_t ;
int shorten ( int i , unsigned long left , unsigned long right , node_t * graph , int rank )
{
int other , shorter = i ;
do {
i = shorter ;
for ( int j = 0 ; j < rank ; j + + ) {
other = graph [ shorter ] . left [ j ] ;
if ( left & ( 1 < < j ) & &
graph [ other ] . wordlength < graph [ shorter ] . wordlength )
shorter = other ;
other = graph [ shorter ] . right [ j ] ;
if ( right & ( 1 < < j ) & &
graph [ other ] . wordlength < graph [ shorter ] . wordlength )
shorter = other ;
}
} while ( shorter ! = i ) ;
return shorter ;
}
2016-11-19 10:16:45 +00:00
void balanced_thickening_callback ( const bitvec_t * pos , int size , void * data )
{
static long totcount = 0 ;
2016-11-23 19:58:05 +00:00
if ( data ) {
info_t * info = ( info_t * ) data ;
unsigned long right_invariance = FIRSTBITS ( info - > rank ) ;
unsigned long left_invariance = FIRSTBITS ( info - > rank ) ;
int bit1 , bit2left , bit2right , left , right ;
for ( int i = 0 ; i < size ; i + + ) {
bit1 = i < size / 2 ? bv_get_bit ( pos , i ) : ! bv_get_bit ( pos , size - 1 - i ) ;
for ( int j = 0 ; j < info - > rank ; j + + ) {
left = info - > graph [ i ] . left [ j ] ;
right = info - > graph [ i ] . right [ j ] ;
bit2left = left < size / 2 ? bv_get_bit ( pos , left ) : ! bv_get_bit ( pos , size - 1 - left ) ;
bit2right = right < size / 2 ? bv_get_bit ( pos , right ) : ! bv_get_bit ( pos , size - 1 - right ) ;
if ( bit1 ! = bit2left )
left_invariance & = ~ BIT ( j ) ;
if ( bit1 ! = bit2right )
right_invariance & = ~ BIT ( j ) ;
}
}
2016-12-02 09:31:31 +00:00
printf ( " %4d left: " , totcount + + ) ;
2016-11-23 19:58:05 +00:00
for ( int j = 0 ; j < info - > rank ; j + + )
printf ( " %c " , left_invariance & ( 1 < < j ) ? info - > alphabet [ j ] : ' ' ) ;
printf ( " right: " ) ;
for ( int j = 0 ; j < info - > rank ; j + + )
printf ( " %c " , right_invariance & ( 1 < < j ) ? info - > alphabet [ j ] : ' ' ) ;
if ( info - > buffer ) {
printf ( " generators: " ) ;
queue_t queue ;
int current , left , right , shortest ;
int * buffer = info - > buffer ;
for ( int i = 0 ; i < size / 2 ; i + + ) {
buffer [ i ] = bv_get_bit ( pos , i ) ;
buffer [ size - 1 - i ] = ! buffer [ i ] ;
}
for ( int i = size - 1 ; i > = 0 ; i - - ) {
if ( buffer [ i ] ) {
int shortest = shorten ( i , left_invariance , right_invariance , info - > graph , info - > rank ) ;
printf ( " %s " , alphabetize ( info - > graph [ shortest ] . word ,
info - > graph [ shortest ] . wordlength ,
info - > alphabet ,
stringbuffer ) ) ;
buffer [ i ] = 0 ;
queue_init ( & queue ) ;
queue_put ( & queue , i ) ;
while ( ( current = queue_get ( & queue ) ) ! = - 1 ) {
for ( edgelist_t * edge = info - > graph [ current ] . bruhat_lower ; edge ! = ( edgelist_t * ) 0 ; edge = edge - > next ) {
if ( buffer [ edge - > to ] ) {
buffer [ edge - > to ] = 0 ;
queue_put ( & queue , edge - > to ) ;
}
}
for ( int j = 0 ; j < info - > rank ; j + + ) {
left = info - > graph [ current ] . left [ j ] ;
if ( left_invariance & ( 1 < < j ) & &
info - > graph [ left ] . wordlength < info - > graph [ current ] . wordlength & &
buffer [ left ] ) {
buffer [ left ] = 0 ;
queue_put ( & queue , left ) ;
}
right = info - > graph [ current ] . left [ j ] ;
if ( right_invariance & ( 1 < < j ) & &
info - > graph [ right ] . wordlength < info - > graph [ current ] . wordlength & &
buffer [ right ] ) {
buffer [ right ] = 0 ;
queue_put ( & queue , right ) ;
}
}
}
}
}
2016-12-02 09:31:31 +00:00
if ( info - > level > = 5 ) {
printf ( " ids: [0 " ) ;
for ( int i = 1 ; i < size / 2 ; i + + )
if ( bv_get_bit ( pos , i ) )
printf ( " , %d " , info - > graph [ i ] . id ) ;
for ( int i = 0 ; i < size / 2 ; i + + )
if ( ! bv_get_bit ( pos , i ) )
printf ( " , %d " , info - > graph [ size - 1 - i ] . id ) ;
printf ( " ] " ) ;
}
2016-11-23 19:58:05 +00:00
}
printf ( " \n " ) ;
}
2016-12-02 09:31:31 +00:00
}
2016-11-23 19:58:05 +00:00
2016-12-02 09:31:31 +00:00
void balanced_thickening_simple_callback ( const bitvec_t * pos , int size , void * data )
{
long * count = ( long * ) data ;
if ( ( + + ( * count ) ) % 100000000 = = 0 ) {
2016-11-19 10:16:45 +00:00
bv_print ( stderr , pos , size / 2 ) ;
fprintf ( stderr , " \n " ) ;
2016-12-02 09:31:31 +00:00
}
2016-11-19 10:16:45 +00:00
}
2016-07-26 08:09:34 +00:00
int main ( int argc , const char * argv [ ] )
{
semisimple_type_t type ;
2016-11-11 16:07:45 +00:00
unsigned long right_invariance , left_invariance ;
int rank , order , hyperplanes , cosets ;
2016-11-14 10:54:52 +00:00
int fixpoints ;
2016-07-26 08:09:34 +00:00
node_t * graph ;
char string_buffer1 [ 1000 ] ;
const char * alphabet = " abcdefghijklmnopqrstuvwxyz " ;
2016-11-11 16:07:45 +00:00
// read arguments
2016-07-26 08:09:34 +00:00
ERROR ( argc < 2 , " Too few arguments! \n " ) ;
2016-11-11 16:07:45 +00:00
type . n = 0 ;
2016-07-26 08:09:34 +00:00
for ( int i = 0 ; i < argc - 1 ; i + + ) {
2016-11-11 16:07:45 +00:00
if ( argv [ i + 1 ] [ 0 ] < ' A ' | | argv [ i + 1 ] [ 0 ] > ' I ' )
break ;
type . n + + ;
}
type . factors = ( simple_type_t * ) malloc ( type . n * sizeof ( simple_type_t ) ) ;
for ( int i = 0 ; i < type . n ; i + + ) {
2016-07-26 08:09:34 +00:00
type . factors [ i ] . series = argv [ i + 1 ] [ 0 ] ;
type . factors [ i ] . rank = argv [ i + 1 ] [ 1 ] - ' 0 ' ;
ERROR ( argv [ i + 1 ] [ 0 ] < ' A ' | | argv [ i + 1 ] [ 0 ] > ' I ' | | argv [ i + 1 ] [ 1 ] < ' 1 ' | | argv [ i + 1 ] [ 1 ] > ' 9 ' , " Arguments must be Xn with X out of A-I and n out of 0-9 \n " ) ;
}
2016-11-11 16:07:45 +00:00
left_invariance = right_invariance = 0 ;
2016-07-26 08:09:34 +00:00
2016-11-11 16:07:45 +00:00
if ( argc - type . n > = 3 ) {
if ( strcmp ( argv [ type . n + 1 ] , " - " ) ! = 0 )
for ( int i = 0 ; i < strlen ( argv [ type . n + 1 ] ) ; i + + )
left_invariance | = ( 1 < < ( argv [ type . n + 1 ] [ i ] - ' a ' ) ) ;
if ( strcmp ( argv [ type . n + 2 ] , " - " ) ! = 0 )
for ( int i = 0 ; i < strlen ( argv [ type . n + 2 ] ) ; i + + )
right_invariance | = ( 1 < < ( argv [ type . n + 2 ] [ i ] - ' a ' ) ) ;
2016-07-26 08:09:34 +00:00
}
// generate graph
2016-11-11 16:07:45 +00:00
graph = graph_alloc ( type ) ;
cosets = prepare_simplified_graph ( type , left_invariance , right_invariance , graph ) ;
2016-11-20 22:19:08 +00:00
ERROR ( cosets < 0 , " The left invariance is not preserved by the opposition involution! \n " ) ;
2016-07-26 08:09:34 +00:00
// print stuff
2016-11-23 19:58:05 +00:00
int output_level = 2 ;
if ( getenv ( " OUTPUT_LEVEL " ) )
output_level = atoi ( getenv ( " OUTPUT_LEVEL " ) ) ;
2016-11-20 22:19:08 +00:00
rank = weyl_rank ( type ) ; // number of simple roots
order = weyl_order ( type ) ; // number of Weyl group elements
hyperplanes = weyl_hyperplanes ( type ) ; // number of positive roots
2016-07-26 08:09:34 +00:00
2016-11-23 19:58:05 +00:00
if ( output_level > = 1 ) {
if ( left_invariance ) {
printf ( " < " ) ;
for ( int j = 0 ; j < rank ; j + + )
if ( left_invariance & BIT ( j ) )
fputc ( alphabet [ j ] , stdout ) ;
printf ( " > \\ " ) ;
}
for ( int i = 0 ; i < type . n ; i + + )
printf ( " %s%c%d " , i = = 0 ? " " : " x " , type . factors [ i ] . series , type . factors [ i ] . rank ) ;
2016-11-19 10:16:45 +00:00
2016-11-23 19:58:05 +00:00
if ( right_invariance ) {
printf ( " / < " ) ;
for ( int j = 0 ; j < rank ; j + + )
if ( right_invariance & BIT ( j ) )
fputc ( alphabet [ j ] , stdout ) ;
printf ( " > " ) ;
}
fprintf ( stdout , " \n " ) ;
fprintf ( stdout , " Rank: %d \t Order: %d \t Positive Roots: %d \t Cosets: %d \n \n " , rank , order , hyperplanes , cosets ) ;
}
if ( output_level > = 3 ) {
fprintf ( stdout , " Shortest coset representatives: \n " ) ;
for ( int i = 0 , wl = 0 ; i < cosets ; i + + ) {
if ( i = = 0 ) {
fprintf ( stdout , " 1 " ) ;
} else if ( graph [ i ] . wordlength > wl ) {
fprintf ( stdout , " \n %s " , alphabetize ( graph [ i ] . word , graph [ i ] . wordlength , alphabet , string_buffer1 ) ) ;
wl = graph [ i ] . wordlength ;
} else
fprintf ( stdout , " %s " , alphabetize ( graph [ i ] . word , graph [ i ] . wordlength , alphabet , string_buffer1 ) ) ;
}
fprintf ( stdout , " \n \n " ) ;
}
if ( output_level > = 4 ) {
edgelist_t * edge ;
fprintf ( stdout , " Bruhat order in graphviz format: \n " ) ;
fprintf ( stdout , " digraph test123 { \n " ) ;
for ( int i = 0 ; i < cosets ; i + + ) {
edge = graph [ i ] . bruhat_lower ;
while ( edge ) {
fprintf ( stdout , " %s -> %s; \n " ,
alphabetize ( graph [ i ] . word , graph [ i ] . wordlength , alphabet , stringbuffer ) ,
alphabetize ( graph [ edge - > to ] . word , graph [ edge - > to ] . wordlength , alphabet , stringbuffer2 ) ) ;
edge = edge - > next ;
}
}
fprintf ( stdout , " } \n \n " ) ;
}
if ( output_level > = 4 ) {
fprintf ( stdout , " Opposites: \n " ) ;
for ( int i = 0 ; i < cosets ; i + + ) {
fprintf ( stdout , " %s <-> %s \n " ,
alphabetize ( graph [ i ] . word , graph [ i ] . wordlength , alphabet , stringbuffer ) ,
alphabetize ( graph [ graph [ i ] . opposite ] . word , graph [ graph [ i ] . opposite ] . wordlength , alphabet , stringbuffer2 ) ) ;
}
fprintf ( stdout , " \n " ) ;
2016-07-26 08:09:34 +00:00
}
2016-11-14 10:54:52 +00:00
fixpoints = 0 ;
for ( int i = 0 ; i < cosets ; i + + )
if ( graph [ i ] . opposite = = i ) {
2016-11-23 19:58:05 +00:00
if ( output_level > = 1 ) {
if ( fixpoints = = 0 )
fprintf ( stdout , " No thickenings since the longest element fixes the following cosets: %s " , alphabetize ( graph [ i ] . word , graph [ i ] . wordlength , alphabet , string_buffer1 ) ) ;
else
fprintf ( stdout , " %s " , alphabetize ( graph [ i ] . word , graph [ i ] . wordlength , alphabet , string_buffer1 ) ) ;
}
2016-11-14 10:54:52 +00:00
fixpoints + + ;
}
2016-11-23 19:58:05 +00:00
if ( output_level > = 1 & & fixpoints )
fprintf ( stdout , " \n \n " ) ;
if ( ! fixpoints ) {
int * buffer = ( int * ) malloc ( cosets * sizeof ( int ) ) ;
2016-11-14 10:54:52 +00:00
2016-11-23 19:58:05 +00:00
info_t info ;
info . graph = graph ;
info . cosets = cosets ;
info . rank = rank ;
info . order = order ;
info . hyperplanes = hyperplanes ;
info . type = type ;
info . left_invariance = left_invariance ;
info . right_invariance = right_invariance ;
info . alphabet = alphabet ;
info . buffer = buffer ;
2016-12-02 09:31:31 +00:00
info . level = output_level ;
2016-11-23 19:58:05 +00:00
long count ;
if ( output_level > = 2 ) {
fprintf ( stdout , " Balanced ideals: \n " , count ) ;
count = enumerate_balanced_thickenings ( graph , cosets , balanced_thickening_callback , & info ) ;
fprintf ( stdout , " \n " , count ) ;
2016-12-02 09:31:31 +00:00
} else {
long outputcount = 0 ;
count = enumerate_balanced_thickenings ( graph , cosets , balanced_thickening_simple_callback , & outputcount ) ;
2016-11-23 19:58:05 +00:00
}
2016-11-14 10:54:52 +00:00
2016-11-23 19:58:05 +00:00
if ( output_level > = 1 )
fprintf ( stdout , " Found %ld balanced ideal%s \n " , count , count = = 1 ? " " : " s " ) ;
2016-11-14 10:54:52 +00:00
}
2016-07-26 08:09:34 +00:00
2016-11-11 16:07:45 +00:00
graph_free ( type , graph ) ;
2016-07-26 08:09:34 +00:00
free ( type . factors ) ;
return 0 ;
}